Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesPull RequestsActionsSecurityInsightsSettings
✨ AI
More
Blame · Line-by-line history

codex.err

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

codex.errBlame39097 lines · 1 contributor
4fc7860Test User1��node.exe : Reading additional input from stdin...
2At C:\Users\ccant\AppData\Roaming\npm\codex.ps1:22 char:14
3+ ... $input | & "node$exe" "$basedir/node_modules/@openai/codex/bin/co ...
4+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 + CategoryInfo : NotSpecified: (Reading additional input from stdin...:String) [], RemoteException
6 + FullyQualifiedErrorId : NativeCommandError
7
8OpenAI Codex v0.144.4
9--------
10workdir: C:\Users\ccant\gluecron.com
11model: gpt-5.6-sol
12provider: openai
13approval: never
14sandbox: danger-full-access
15reasoning effort: none
16reasoning summaries: none
17session id: 019f6eb7-a557-7361-9e27-7c134c6f0e5b
18--------
19user
20Apply the cyan accent decision (owner-approved) to Gluecron's marketing surface, plus two small pieces of Phase 2 design work. Four changes:
21
221. In src/views/landing-pro.tsx, swap the brand accent CSS custom properties from indigo to cyan: change --lp-brand from #4353c9 to #0891b2, and --lp-brand-h (its hover shade) from #3848b6 to #0a7288. Also
23update the icon() helper's default color parameter (currently defaults to '#4353c9') to '#0891b2' so icons using the default color pick up the new accent. Do NOT change the --lp-violet (#7c3aed, used for the
24AI icon) or other functional icon colors (green/amber/slate/cyan/red/teal in the ICONS map) -- icon-palette consolidation is a separate future task, not part of this change. Do not touch typography, radius,
25shadows, layout, or copy.
26
272. In src/views/ui.tsx, extend the existing Badge component with three new variants: 'live', 'soon', 'preview'. Follow the existing variant pattern in that file exactly (look at how the current variants like
28'open'/'closed'/'merged'/'success'/'danger'/'warning' are implemented as a class-name map). Style them for a white canvas using the new cyan accent (#0891b2): 'live' = solid cyan background with white text,
29'soon' = outlined neutral gray border with muted text, no fill, 'preview' = dashed border in a muted cyan tint with cyan text, no fill. Add the corresponding CSS rules to src/views/layout.tsx's existing
30badge CSS block (find where the other .badge-* variant classes are defined and add .badge-live, .badge-soon, .badge-preview alongside them, matching the existing badge class naming convention in that file).
31
323. Delete src/views/landing-v2.tsx. First verify it has zero references anywhere in src/ (grep for 'landing-v2' -- it should only match its own file). This file is confirmed dead code containing leftover
33pre-detox glow CSS (.lv-hero-glow, .lv-cta-glow) that isn't used anywhere.
34
354. Check whether src/views/landing.tsx has any importers other than src/routes/web.tsx (where it's imported as 'LandingPage' but immediately voided via 'void LandingPage;' at web.tsx line 1950 and never
36rendered). If landing.tsx has no other importers, delete it, then remove the now-dead 'void LandingPage; void Landing2030Page;' lines and their now-unused imports (LandingPage, Landing2030Page) from
37src/routes/web.tsx. If landing.tsx DOES have other importers (a helper type or function used elsewhere), leave landing.tsx alone and only report that finding -- do not delete it in that case.
38
39Run the existing test suite and confirm nothing that imports landing-pro.tsx, ui.tsx, layout.tsx, landing-v2.tsx, landing.tsx, or web.tsx breaks. Do not touch any other files.
40codex
41I ll verify the dead-code references and existing badge patterns first, then make only the requested file changes and run the repository s existing tests.
f8614f3Test User42exec
43"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "rg -n \"landing-v2|landing\\.tsx|LandingPage|Landing2030Page|badge-(open|closed|merged|success|danger|warning)|function icon|const
44icon|--lp-brand\" src; Get-Content src/views/ui.tsx; rg -n -C 4 \"\\.badge-(open|closed|merged|success|danger|warning)\" src/views/layout.tsx; Get-Content package.json" in C:\Users\ccant\gluecron.com
45codex
46The combined inspection is taking a little longer than expected; I m waiting for it to finish before editing so the deletion decision is evidence-based.
472026-07-17T06:16:33.530016Z ERROR codex_core::tools::router: error=Exit code: 124
48Wall time: 14.1 seconds
49Output:
50command timed out after 14073 milliseconds
51
52 exited 124 in 14073ms:
53exec
54"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command 'rg -n -C 12 "type Badge|function Badge|export.*Badge|variants|open:|closed:|merged:|success:|danger:|warning:" src/views/ui.tsx' in
55C:\Users\ccant\gluecron.com
56exec
57"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "rg -n --glob '"'!src/views/landing-v2.tsx'"' \"landing-v2\" src; rg -n \"from
58['\\\"]["'^'"'\\\"]*landing['\\\"]|require\\(['\\\"]["'^'"'\\\"]*landing['\\\"]\\)|LandingPage|Landing2030Page\" src" in C:\Users\ccant\gluecron.com
59exec
60"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "rg -n -C 3 \"\\.badge-(open|closed|merged|success|danger|warning)\" src/views/layout.tsx" in C:\Users\ccant\gluecron.com
61exec
62"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command 'rg -n -C 2 -- "--lp-brand|function icon|const icon" src/views/landing-pro.tsx; Get-Content package.json -TotalCount 120' in
63C:\Users\ccant\gluecron.com
64 succeeded in 2334ms:
65221-};
66222-
67223-export const EmptyState: FC<
68224- PropsWithChildren<{ title?: string; icon?: string }>
69225-> = ({ children, title, icon }) => (
70226- <div class="empty-state">
71227- {icon && <div style="font-size:48px;margin-bottom:12px">{icon}</div>}
72228- {title && <h2>{title}</h2>}
73229- {children}
74230- </div>
75231-);
76232-
77233:export const Badge: FC<
78234- PropsWithChildren<{
79235- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
80236- style?: string;
81237- }>
82238-> = ({ children, variant = "default", style }) => {
83239- const cls =
84240- variant === "open" ? "badge-open" :
85241- variant === "closed" ? "badge-closed" :
86242- variant === "merged" ? "badge-merged" :
87243- variant === "success" ? "badge-success" :
88244- variant === "danger" ? "badge-danger" :
89245- variant === "warning" ? "badge-warning" :
90
91 succeeded in 2278ms:
923153- font-weight: 500;
933154- line-height: 1.4;
943155- }
953156: .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
963157: .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
973158: .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
983159- .state-merged { color: var(--accent); }
993160- .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
1003161-
101
1022026-07-17T06:16:42.420969Z ERROR codex_core::tools::router: error=Exit code: 1
103Wall time: 2.4 seconds
104Output:
105rg: regex parse error:
106 (?:from ['" ] [^"]*landing[\]|require\(['\][^"]*landing[\]\)|LandingPage|Landing2030Page src)
107 ^
108error: unclosed character class
109
110 exited 1 in 2402ms:
111rg: regex parse error:
112 (?:from ['" ] [^"]*landing[\]|require\(['\][^"]*landing[\]\)|LandingPage|Landing2030Page src)
113 ^
114error: unclosed character class
115
116exec
117"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "rg -n -C 3 '\\.badge-(open|closed|merged|success|danger|warning)' src/views/layout.tsx" in C:\Users\ccant\gluecron.com
118exec
119"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "rg -n -C 12 'type Badge|function Badge|export.*Badge|open:|closed:|merged:|success:|danger:|warning:' src/views/ui.tsx" in
120C:\Users\ccant\gluecron.com
121exec
122"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "rg -n --glob '"'!src/views/landing-v2.tsx'"' 'landing-v2' src; rg -n 'LandingPage|Landing2030Page' src; rg -n 'views/landing' src"
123in C:\Users\ccant\gluecron.com
124exec
125"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "rg -n -C 2 -- '--lp-brand|function icon|const icon' src/views/landing-pro.tsx; Get-Content package.json -TotalCount 120" in
126C:\Users\ccant\gluecron.com
127 succeeded in 1760ms:
128221-};
129222-
130223-export const EmptyState: FC<
131224- PropsWithChildren<{ title?: string; icon?: string }>
132225-> = ({ children, title, icon }) => (
133226- <div class="empty-state">
134227- {icon && <div style="font-size:48px;margin-bottom:12px">{icon}</div>}
135228- {title && <h2>{title}</h2>}
136229- {children}
137230- </div>
138231-);
139232-
140233:export const Badge: FC<
141234- PropsWithChildren<{
142235- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
143236- style?: string;
144237- }>
145238-> = ({ children, variant = "default", style }) => {
146239- const cls =
147240- variant === "open" ? "badge-open" :
148241- variant === "closed" ? "badge-closed" :
149242- variant === "merged" ? "badge-merged" :
150243- variant === "success" ? "badge-success" :
151244- variant === "danger" ? "badge-danger" :
152245- variant === "warning" ? "badge-warning" :
153
154 succeeded in 1894ms:
1553153- font-weight: 500;
1563154- line-height: 1.4;
1573155- }
1583156: .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
1593157: .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
1603158: .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
1613159- .state-merged { color: var(--accent); }
1623160- .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
1633161-
164
165 succeeded in 1918ms:
16643-// %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16744-
16845:function icon(paths: string, color = "#4353c9", size = 20) {
16946- return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
17047-}
171--
172948-/* %% tokens %% */
173949-:root{
174950: --lp-brand:#4353c9;--lp-brand-h:#3848b6;
175951- --lp-bg:#ffffff;--lp-soft:#fafafb;
176952- --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
177--
178976-.lp-h2{font-family:'Inter Tight','Inter',sans-serif;font-weight:700;font-size:clamp(30px,4vw,50px);line-height:1.08;letter-spacing:-.022em;color:var(--lp-ink)}
179977-.lp-h2-tight{font-size:clamp(26px,3.2vw,40px)}
180978:.lp-kicker{font-size:12.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--lp-brand);margin-bottom:12px}
181979-.lp-sub{font-size:18px;color:var(--lp-ink-2);line-height:1.65;max-width:60ch}
182980:.lp-text-link{color:var(--lp-brand);font-size:15px;font-weight:500}
183981:.lp-text-link:hover{color:var(--lp-brand-h);text-decoration:underline}
184982-code{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:.86em;background:rgba(0,0,0,.05);padding:2px 5px;border-radius:4px}
185983-
186--
1871013-.lp-logo{display:inline-flex;align-items:center;gap:9px;font-family:'Inter Tight',sans-serif;font-weight:700;font-size:18px;letter-spacing:-.02em;color:var(--lp-ink)}
1881014-.lp-logo-light{color:rgba(255,255,255,.9)}
1891015:.lp-logo-mark{width:18px;height:18px;border-radius:6px;background:var(--lp-brand);display:inline-block;flex-shrink:0}
1901016-.lp-nav-links{display:flex;gap:24px;margin-left:10px}
1911017-.lp-nav-links a{font-size:15px;font-weight:500;color:var(--lp-ink-2);transition:color .15s}
192--
1931028-.lp-hero-ctas{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
1941029-.lp-hero-links{display:flex;gap:10px;align-items:center;margin-top:14px;font-size:14px;color:var(--lp-muted)}
1951030:.lp-hero-links a{color:var(--lp-brand);font-weight:500}
1961031-.lp-hero-links span{color:var(--lp-border)}
1971032-.lp-hero-stats{display:flex;gap:28px;margin-top:32px;padding-top:24px;border-top:1px solid var(--lp-border);list-style:none;flex-wrap:wrap}
198--
1991059-/* inline comment */
2001060-.lp-inline-comment{display:flex;gap:10px;padding:12px 16px;background:rgba(67,83,201,.04);border-bottom:1px solid rgba(67,83,201,.12)}
2011061:.lp-ic-ava{width:26px;height:26px;border-radius:50%;background:var(--lp-brand);color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1p
202x}
2031062-.lp-ic-head{font-size:12px;font-weight:600;color:var(--lp-ink-2);margin-bottom:3px}
2041063:.lp-ic-loc{color:var(--lp-brand);font-family:'JetBrains Mono',monospace;font-size:11px}
2051064-.lp-ic-text{font-size:13px;color:var(--lp-ink-2);line-height:1.5}
2061065-/* gates */
207--
2081067-.lp-gate{font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:20px}
2091068-.lp-gate-ok{color:var(--lp-green);background:rgba(5,150,105,.09)}
2101069:.lp-gate-spin{color:var(--lp-brand);background:rgba(67,83,201,.09)}
2111070-/* auto-merge banner */
2121071:.lp-automerge-bar{background:var(--lp-brand);color:#fff;font-size:12px;font-weight:600;text-align:center;padding:8px;letter-spacing:.01em}
2131072-
2141073-/* %% trust strip %% */
215--
2161081-.lp-impact-stat{text-align:center;padding:0 60px;display:flex;flex-direction:column;align-items:center;gap:6px}
2171082-.lp-impact-n{font-family:'Inter Tight',sans-serif;font-size:clamp(40px,6vw,68px);font-weight:800;color:var(--lp-ink);letter-spacing:-.03em;line-height:1}
2181083:.lp-impact-x{color:var(--lp-brand);font-size:.7em}
2191084-.lp-impact-label{font-size:13.5px;color:var(--lp-muted);font-weight:500}
2201085-.lp-impact-sep{width:1px;height:64px;background:var(--lp-border);flex-shrink:0}
221--
2221091-
2231092-/* %% live-now %% */
2241093:.lp-live-dot{color:var(--lp-brand);font-size:9px;margin-right:4px}
2251094-.lp-live-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:32px}
2261095-@media(max-width:1000px){.lp-live-grid{grid-template-columns:repeat(2,1fr)}}
227--
2281106-.lp-live-row{display:flex;flex-direction:column;gap:3px;transition:background .3s}
2291107-.lp-live-link{font-size:13.5px;color:var(--lp-ink);font-weight:500;line-height:1.4}
2301108:.lp-live-link:hover{color:var(--lp-brand)}
2311109-.lp-live-num{font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--lp-muted)}
2321110-.lp-live-meta{font-size:12px;color:var(--lp-muted)}
233--
2341116-.lp-feed-kind{font-size:11.5px;font-weight:600;padding:2px 6px;border-radius:4px}
2351117-.lp-feed-kind-auto_merge-merged{color:var(--lp-green);background:rgba(5,150,105,.09)}
2361118:.lp-feed-kind-ai_build-dispatched{color:var(--lp-brand);background:rgba(67,83,201,.09)}
2371119-.lp-feed-kind-ai_review-posted{color:var(--lp-violet);background:rgba(124,58,237,.09)}
2381120-.lp-live-cta{display:flex;align-items:center;gap:16px}
239--
2401168-.lp-rm-time{padding:8px 16px;font-size:11.5px;color:var(--lp-muted);border-top:1px solid var(--lp-border);font-family:'JetBrains Mono',monospace}
2411169-.lp-rm-comment{display:flex;gap:10px;padding:12px 16px;background:rgba(67,83,201,.03)}
2421170:.lp-rm-ava{width:28px;height:28px;border-radius:50%;background:var(--lp-brand);color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2p
243x}
2441171-.lp-rm-bubble{flex:1;font-size:13px;color:var(--lp-ink-2);line-height:1.5}
2451172:.lp-rm-file{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--lp-brand);margin-bottom:4px}
2461173-.lp-rm-verdict{padding:10px 16px;border-top:1px solid var(--lp-border)}
2471174-.lp-rm-v-ok{font-size:13px;font-weight:600;color:var(--lp-green)}
248--
2491205-.lp-eco-card:hover{transform:translateY(-3px);box-shadow:var(--lp-shadow-lg)}
2501206-.lp-eco-title{font-size:15px;font-weight:700;color:var(--lp-ink)}
2511207:.lp-eco-sub{font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--lp-brand)}
2521208-.lp-eco-body{font-size:13.5px;color:var(--lp-ink-2);line-height:1.6;flex:1}
2531209-
254--
2551227-.lp-price-card{background:#fff;border:1px solid
256var(--lp-border);border-radius:14px;padding:28px;box-shadow:var(--lp-shadow);display:flex;flex-direction:column;gap:0;position:relative;transition:transform .18s,box-shadow .2s}
2571228-.lp-price-card:hover{transform:translateY(-3px);box-shadow:var(--lp-shadow-lg)}
2581229:.lp-price-hl{border-color:var(--lp-brand);box-shadow:0 0 0 1px var(--lp-brand),var(--lp-shadow)}
2591230:.lp-price-badge{position:absolute;top:-13px;left:50%;transform:translateX(-50%);background:var(--lp-brand);color:#fff;font-size:11.5px;font-weight:700;padding:4px 14px;border-radius:999px}
2601231:.lp-price-tier{font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--lp-brand);margin-bottom:12px}
2611232-.lp-price-amount{display:flex;align-items:baseline;gap:6px;margin-bottom:12px}
2621233-.lp-price-num{font-family:'Inter Tight',sans-serif;font-size:36px;font-weight:800;color:var(--lp-ink);letter-spacing:-.02em}
263--
2641250-.lp-term-body{padding:16px;display:flex;flex-direction:column;gap:8px}
2651251-.lp-term-line{display:flex;align-items:center;gap:10px;font-family:'JetBrains Mono',monospace;font-size:13px}
2661252:.lp-term-prompt{color:var(--lp-brand);font-weight:500}
2671253-.lp-term-out{font-family:'JetBrains Mono',monospace;font-size:12.5px;color:var(--lp-muted);padding-left:20px}
2681254-.lp-term-ok{color:var(--lp-green)}
269{
270 "name": "gluecron",
271 "version": "0.1.0",
272 "description": "AI-native code intelligence platform ��  git hosting, automated CI, and green ecosystem enforcement",
273 "license": "MIT",
274 "repository": {
275 "type": "git",
276 "url": "https://gluecron.com/ccantynz/Gluecron.com.git"
277 },
278 "engines": {
279 "node": ">=20"
280 },
281 "type": "module",
282 "scripts": {
283 "dev": "bun run --hot src/index.ts",
284 "start": "bun run src/index.ts",
285 "db:generate": "drizzle-kit generate",
286 "db:migrate": "bun run src/db/migrate.ts",
287 "db:studio": "drizzle-kit studio",
288 "test": "bun test",
289 "typecheck": "tsc --noEmit",
290 "preflight": "bun scripts/preflight.ts",
291 "doctor": "bun scripts/doctor.ts",
292 "e2e": "playwright test --config=e2e/playwright.config.ts"
293 },
294 "dependencies": {
295 "@anthropic-ai/sdk": "^0.96.0",
296 "@neondatabase/serverless": "^1.1.0",
297 "@simplewebauthn/server": "^13.3.0",
298 "drizzle-orm": "^0.45.2",
299 "highlight.js": "^11.11.0",
300 "hono": "^4.12.18",
301 "marked": "^18.0.3",
302 "postgres": "^3.4.9",
303 "sanitize-html": "^2.13.0",
304 "ssh2": "^1.16.0"
305 },
306 "optionalDependencies": {
307 "cpu-features": "*",
308 "sshcrypto": "*"
309 },
310 "devDependencies": {
311 "@playwright/test": "^1.49.0",
312 "@types/bun": "^1.3.14",
313 "@types/k6": "^2.0.0",
314 "drizzle-kit": "^0.31.10",
315 "typescript": "^5.7.0"
316 }
317}
318
319 succeeded in 2577ms:
320src\views\landing.tsx:70:export interface LandingPageProps {
321src\views\landing.tsx:90:export const LandingHero: FC<LandingPageProps> = ({
322src\views\landing.tsx:1626:// Backwards-compatible default  web.tsx imports `LandingPage`.
323src\views\landing.tsx:1630:export const LandingPage: FC<LandingPageProps> = (props) => (
324src\views\landing.tsx:1634:export default LandingPage;
325src\views\landing-v2.tsx:3:export interface LandingPageProps {
326src\views\landing-v2.tsx:107:export const LandingPageV2: FC<LandingPageProps> = (_props) => {
327src\views\landing-v2.tsx:415:export const LandingPage = LandingPageV2;
328src\views\landing-v2.tsx:416:export default LandingPageV2;
329src\__tests__\dxt-extension.test.ts:162: // reboot (GET / now serves the self-contained Landing2030Page). The
330src\views\landing-2030.tsx:84:export const Landing2030Page: FC<Landing2030Props> = () => {
331src\views\landing-2030.tsx:322:export default Landing2030Page;
332src\__tests__\green-ecosystem.test.ts:315: // 2026-06-10: "/" now serves the self-contained Landing2030Page;
333src\__tests__\landing-live-feed.test.ts:22: LandingPage,
334src\__tests__\landing-live-feed.test.ts:150:// `LandingPage` is a JSX function component; calling it directly returns
335src\__tests__\landing-live-feed.test.ts:161: const node: any = await (LandingPage as any)(props);
336src\__tests__\landing-live-feed.test.ts:322: // 2026-06-10: GET / now serves the self-contained Landing2030Page;
337src\__tests__\landing-live-feed.test.ts:323: // the legacy LandingPage (and its Live-now block, covered above at the
338src\routes\web.tsx:67:import { LandingPage, type LandingLiveFeed } from "../views/landing";
339src\routes\web.tsx:68:import { Landing2030Page } from "../views/landing-2030";
340src\routes\web.tsx:1950: void LandingPage;
341src\routes\web.tsx:1951: void Landing2030Page;
342src\__tests__\pwa.test.ts:95: // Landing2030Page which carries no Layout scripts at all.
343src\__tests__\u-polish.test.ts:5: * `Landing2030Page` (src/views/landing-2030.tsx)  the legacy
344src\__tests__\u-polish.test.ts:6: * `LandingPage` + master Layout CSS no longer render on the home route.
345src\__tests__\visual-coherence.test.tsx:8: * route now serves the self-contained Landing2030Page without the
346src\__tests__\landing-hero.test.ts:100: const { buildSocialProofTiles } = await import("../views/landing");
347src\__tests__\landing-live-feed.test.ts:24:} from "../views/landing";
348src\__tests__\playground.test.ts:765: new URL("../views/landing.tsx", import.meta.url),
349src\__tests__\public-stats.test.ts:27:import { buildSocialProofTiles } from "../views/landing";
350src\routes\web.tsx:67:import { LandingPage, type LandingLiveFeed } from "../views/landing";
351src\routes\web.tsx:68:import { Landing2030Page } from "../views/landing-2030";
352src\routes\web.tsx:69:import { LandingProPage } from "../views/landing-pro";
353src\__tests__\u-polish.test.ts:5: * `Landing2030Page` (src/views/landing-2030.tsx)  the legacy
354src\__tests__\u-polish.test.ts:42: // Home `/` renders LandingProPage (src/views/landing-pro.tsx). These
355
356codex
357Reference checks confirm `landing-v2.tsx` has no consumers. `landing.tsx` does have other importers several tests import its component/helpers so per your condition I ll leave both it and `web.tsx` unchanged
358and report that finding. I m proceeding with the accent, badge additions, and `landing-v2.tsx` deletion only.
359exec
360"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "Get-Content src/views/ui.tsx | Select-Object -Skip 228 -First 32; rg -n -C 2 'badge-success|badge-danger|badge-warning|\\.badge \\{'
361src/views/layout.tsx; git status --short" in C:\Users\ccant\gluecron.com
362 succeeded in 2182ms:
363 {children}
364 </div>
365);
366
367export const Badge: FC<
368 PropsWithChildren<{
369 variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
370 style?: string;
371 }>
372> = ({ children, variant = "default", style }) => {
373 const cls =
374 variant === "open" ? "badge-open" :
375 variant === "closed" ? "badge-closed" :
376 variant === "merged" ? "badge-merged" :
377 variant === "success" ? "badge-success" :
378 variant === "danger" ? "badge-danger" :
379 variant === "warning" ? "badge-warning" :
380 "badge";
381 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
382};
383
384// � � � � � � Card Components � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �
385
386/**
387 * Card ��  the canonical panel primitive.
388 *
389 * Block O3: extended with `padding` and `variant` props so every "panel"
390 * style across the app maps to a single CSS contract.
391 */
392export const Card: FC<
393 PropsWithChildren<{
394 padding?: "none" | "sm" | "md" | "lg";
3952870- /* Badges */
3962871- /* ============================================================ */
3972872: .badge {
3982873- display: inline-flex;
3992874- align-items: center;
400--
4013405-
4023406- /* Badges + commit-sha: smoother transition */
4033407: .commit-sha, .badge { transition: all 120ms cubic-bezier(0.16,1,0.3,1); }
4043408-
4053409- /* Gradient text utility  kept for back-compat, renders as plain accent color. */
406 M STATUS.md
407 M scripts/doctor.ts
408?? .agent/
409
410exec
411"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "Get-Content src/views/layout.tsx | Select-Object -Skip 2866 -First 42; Get-Content src/views/layout.tsx | Select-Object -Skip 3144
412-First 22; rg -n 'badge-success|badge-danger|badge-warning' src" in C:\Users\ccant\gluecron.com
413 succeeded in 2084ms:
414 }
415
416 /* ============================================================ */
417 /* Badges */
418 /* ============================================================ */
419 .badge {
420 display: inline-flex;
421 align-items: center;
422 gap: 4px;
423 padding: 2px 9px;
424 border-radius: var(--r-full);
425 font-size: var(--t-xs);
426 font-weight: 500;
427 background: var(--bg-tertiary);
428 border: 1px solid var(--border);
429 color: var(--text-muted);
430 line-height: 1.5;
431 }
432
433 /* ============================================================ */
434 /* Branch dropdown */
435 /* ============================================================ */
436 .branch-selector {
437 display: inline-flex;
438 align-items: center;
439 gap: 6px;
440 padding: 6px 12px;
441 background: var(--bg-elevated);
442 border: 1px solid var(--border);
443 border-radius: var(--r-sm);
444 font-size: var(--t-sm);
445 color: var(--text);
446 margin-bottom: 12px;
447 transition: border-color var(--t-fast) var(--ease);
448 }
449 .branch-selector:hover { border-color: var(--border-strong); }
450
451 .branch-dropdown {
452 position: relative;
453 display: inline-block;
454 margin-bottom: 12px;
455 }
456
457 .issue-badge {
458 display: inline-flex;
459 align-items: center;
460 gap: 6px;
461 padding: 4px 12px;
462 border-radius: var(--r-full);
463 font-size: var(--t-sm);
464 font-weight: 500;
465 line-height: 1.4;
466 }
467 .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
468 .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
469 .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
470 .state-merged { color: var(--accent); }
471 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
472
473 .issue-detail { max-width: 920px; }
474 .issue-comment-box {
475 border: 1px solid var(--border);
476 border-radius: var(--r-md);
477 margin-bottom: 16px;
478src\routes\import-bulk.tsx:417: .import-bulk-badge-success {
479src\routes\import-bulk.tsx:422: .import-bulk-badge-success .import-bulk-badge-dot {
480src\routes\import-bulk.tsx:996: ? "import-bulk-badge-success"
481src\views\ui.tsx:243: variant === "success" ? "badge-success" :
482src\views\ui.tsx:244: variant === "danger" ? "badge-danger" :
483src\views\ui.tsx:245: variant === "warning" ? "badge-warning" :
484
485apply patch
486patch: completed
487C:\Users\ccant\gluecron.com\src\views\landing-pro.tsx
488C:\Users\ccant\gluecron.com\src\views\landing-v2.tsx
489C:\Users\ccant\gluecron.com\src\views\layout.tsx
490C:\Users\ccant\gluecron.com\src\views\ui.tsx
491diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
492index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
493--- a/src/views/landing-pro.tsx
494+++ b/src/views/landing-pro.tsx
495@@ -42,7 +42,7 @@
496
497 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498
499-function icon(paths: string, color = "#4353c9", size = 20) {
500+function icon(paths: string, color = "#0891b2", size = 20) {
501 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
502 }
503
504@@ -947,7 +947,7 @@
505 const css = `
506 /* %% tokens %% */
507 :root{
508- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
509+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
510 --lp-bg:#ffffff;--lp-soft:#fafafb;
511 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
512 --lp-border:rgba(0,0,0,.08);
513diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
514deleted file mode 100644
515index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
516--- a/src/views/landing-v2.tsx
517+++ /dev/null
518@@ -1,1447 +0,0 @@
519-import type { FC } from "hono/jsx";
520-
521-export interface LandingPageProps {
522- stats?: {
523- publicRepos?: number;
524- users?: number;
525- };
526-}
527-
528-const demoAllEvents = [
529- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
530- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
531- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
532- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
533- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
534-];
535-
536-const tickerItems = [
537- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
538- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
539- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
540- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
541- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
542- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
543- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
544- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
545- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
546- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
547- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
548- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
549- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
550- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
551- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
552- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
553-];
554-
555-const stageData = [
556- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
557- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
558- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
559- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
560- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
561- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
562-];
563-
564-const heroFeatures = [
565- {
566- href: "/",
567- eyebrow: "01 � The autonomous repair loop",
568- title: "Failures fix themselves  and show their work.",
569- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
570failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
571- cta: "Watch a live repair session",
572- mock: [
573- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
574- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
575- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
576- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
577- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
578- ],
579- },
580- {
581- href: "/",
582- eyebrow: "02 � Live sandbox isolation",
583- title: "Every PR gets its own instant, disposable environment.",
584- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
585same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
586- cta: "See a PR with its sandbox",
587- mock: [
588- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
589- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
590- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
591- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
592- ],
593- },
594- {
595- href: "/",
596- eyebrow: "03 � Multiplayer IDE workspaces",
597- title: "You and the agent, side by side, in your editor.",
598- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
599agent into a silent reviewer in your gutter. The browser becomes optional.",
600- cta: "See the editor session",
601- mock: [
602- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
603- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
604- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
605- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
606- ],
607- },
608-];
609-
610-const capabilities = [
611- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
612- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
613- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
614- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
615- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
616- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
617- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
618- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
619-];
620-
621-const sovereignLayerNames = [
622- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
623- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
624- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
625- "Availability & recovery",
626-];
627-
628-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
629- return (
630- <>
631- <style dangerouslySetInnerHTML={{ __html: css }} />
632-
633- {/* Nav */}
634- <header class="lv-nav">
635- <div class="lv-nav-inner">
636- <a href="/" class="lv-logo">
637- <span class="lv-logo-mark"></span>gluecron
638- </a>
639- <nav class="lv-nav-links">
640- <a href="#loop" class="lv-nav-link">The loop</a>
641- <a href="#platform" class="lv-nav-link">Platform</a>
642- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
643- <a href="/trust" class="lv-nav-link">Trust</a>
644- </nav>
645- <div class="lv-nav-ctas">
646- <a href="/login" class="lv-btn-secondary">Sign in</a>
647- <a href="/register" class="lv-btn-primary">Start building</a>
648- </div>
649- </div>
650- </header>
651-
652- {/* Hero */}
653- <section class="lv-hero">
654- <div class="lv-hero-glow"></div>
655- <div class="lv-hero-inner">
656- <div class="lv-hero-badge">
657- <span class="lv-dot lv-dot-green lv-pulse"></span>
658- Live: a repair loop converged on pr-218 while you read this
659- </div>
660- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
661- <p class="lv-hero-sub">
662- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
663failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
664- </p>
665- <div class="lv-hero-actions">
666- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
667- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
668- </div>
669- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
670-
671- {/* Live product window */}
672- <div class="lv-demo-window">
673- <div class="lv-demo-bar">
674- <span class="lv-demo-dot"></span>
675- <span class="lv-demo-dot"></span>
676- <span class="lv-demo-dot"></span>
677- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
678- <span class="lv-demo-live">
679- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
680- LIVE
681- </span>
682- </div>
683- <div class="lv-demo-body" id="lv-demo-body">
684- {/* Events rendered by JS */}
685- {demoAllEvents.slice(0, 1).map((e, i) => (
686- <div class="lv-demo-event" key={i}>
687- <div class="lv-demo-event-track">
688- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
689- <span class="lv-demo-line" style="display:none"></span>
690- </div>
691- <div class="lv-demo-event-content">
692- <div class="lv-demo-event-header">
693- <span class="lv-demo-event-title">{e.title}</span>
694- <span class="lv-demo-event-time">{e.time}</span>
695- </div>
696- <div class="lv-demo-event-body">{e.body}</div>
697- </div>
698- </div>
699- ))}
700- </div>
701- </div>
702- </div>
703-
704- {/* Activity ticker */}
705- <div class="lv-ticker-wrap">
706- <div class="lv-ticker-track">
707- {tickerItems.map((t, i) => (
708- <span class="lv-ticker-item" key={i}>
709- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
710- {t.text}
711- </span>
712- ))}
713- </div>
714- </div>
715- </section>
716-
717- {/* Stat band */}
718- <section class="lv-stats">
719- <div class="lv-stats-inner">
720- <div class="lv-stat">
721- <div class="lv-stat-num">Sonnet 5</div>
722- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
723- </div>
724- <div class="lv-stat">
725- <div class="lv-stat-num">93.5%</div>
726- <div class="lv-stat-label">of failures self-repair without a human</div>
727- </div>
728- <div class="lv-stat">
729- <div class="lv-stat-num">1.9%</div>
730- <div class="lv-stat-label">AI merges reverted  published live</div>
731- </div>
732- <div class="lv-stat">
733- <div class="lv-stat-num">0</div>
734- <div class="lv-stat-label">irreversible actions taken autonomously</div>
735- </div>
736- </div>
737- </section>
738-
739- {/* The loop */}
740- <section id="loop" class="lv-loop">
741- <div class="lv-loop-inner">
742- <div class="lv-section-header">
743- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
744- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
745- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
746- </div>
747- <div class="lv-stages" id="lv-stages">
748- {stageData.map((s, i) => (
749- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
750- <div class="lv-stage-header">
751- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
752- <span class="lv-stage-n">0{i + 1}</span>
753- </div>
754- <div class="lv-stage-name">{s.name}</div>
755- <div class="lv-stage-desc">{s.desc}</div>
756- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
757- </div>
758- ))}
759- </div>
760- </div>
761- </section>
762-
763- {/* Three heroes */}
764- <section class="lv-heroes">
765- <div class="lv-heroes-inner">
766- <div class="lv-heroes-header">
767- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
768- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
769- </div>
770- <div class="lv-heroes-list">
771- {heroFeatures.map((h, i) => (
772- <a href={h.href} class="lv-hero-card" key={i}>
773- <div class="lv-hero-card-left">
774- <div class="lv-eyebrow">{h.eyebrow}</div>
775- <h3 class="lv-hero-card-title">{h.title}</h3>
776- <p class="lv-hero-card-body">{h.body}</p>
777- <span class="lv-hero-card-cta">{h.cta} �!</span>
778- </div>
779- <div class="lv-terminal">
780- {h.mock.map((m, j) => (
781- <div class="lv-terminal-line" key={j}>
782- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
783- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
784- </div>
785- ))}
786- </div>
787- </a>
788- ))}
789- </div>
790- </div>
791- </section>
792-
793- {/* Everything grid */}
794- <section id="platform" class="lv-platform">
795- <div class="lv-platform-inner">
796- <div class="lv-section-header lv-section-header-center">
797- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
798- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
799- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
800- </div>
801- <div class="lv-cap-grid">
802- {capabilities.map((c, i) => (
803- <div class="lv-cap-col" key={i}>
804- <div class="lv-cap-group">{c.group}</div>
805- <div class="lv-cap-items">
806- {c.items.map((item, j) => (
807- <div class="lv-cap-item" key={j}>{item}</div>
808- ))}
809- </div>
810- </div>
811- ))}
812- </div>
813- </div>
814- </section>
815-
816- {/* Sovereignty band */}
817- <section id="sovereign" class="lv-sovereign">
818- <div class="lv-sovereign-grid-bg"></div>
819- <div class="lv-sovereign-inner">
820- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
821- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
822- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
823- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
824to private cloud, or run fully air-gapped on bare metal.</p>
825- </div>
826- <div class="lv-layers-grid">
827- {sovereignLayerNames.map((name, i) => (
828- <div class="lv-layer-chip" key={i}>
829- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
830- <div class="lv-layer-name">{name}</div>
831- </div>
832- ))}
833- <a href="/" class="lv-layer-chip lv-layer-cta">
834- <div class="lv-layer-cta-text">All self-owned �!</div>
835- </a>
836- </div>
837- <div class="lv-sovereign-feats">
838- <div class="lv-sovereign-feat">
839- <div class="lv-sovereign-feat-title">Local inference first</div>
840- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
841- </div>
842- <div class="lv-sovereign-feat">
843- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
844- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
845- </div>
846- <div class="lv-sovereign-feat">
847- <div class="lv-sovereign-feat-title">Self-healing infra</div>
848- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
849- </div>
850- </div>
851- </div>
852- </section>
853-
854- {/* Manual-first + reversibility */}
855- <section class="lv-twin">
856- <div class="lv-twin-inner">
857- <div class="lv-twin-card">
858- <div class="lv-eyebrow">Manual-first, always</div>
859- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
860- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
861fallback. Developers who never touch AI get the best git host they've ever used.</p>
862- </div>
863- <div class="lv-twin-card">
864- <div class="lv-eyebrow">The reversibility guarantee</div>
865- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
866- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
867 policy, not promise. Our quality numbers are published live, unedited.</p>
868- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
869- </div>
870- </div>
871- </section>
872-
873- {/* Quote */}
874- <section class="lv-quote">
875- <div class="lv-quote-inner">
876- <p class="lv-quote-text">
877- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
878- Gluecron is where code gets <em class="lv-em">finished</em>."
879- </p>
880- </div>
881- </section>
882-
883- {/* CTA */}
884- <section class="lv-cta-section">
885- <div class="lv-cta-card">
886- <div class="lv-cta-glow"></div>
887- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
888- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
889- <div class="lv-cta-actions">
890- <a href="/register" class="lv-cta-primary">Create your account �!</a>
891- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
892- </div>
893- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
894- </div>
895- </section>
896-
897- {/* Footer */}
898- <footer class="lv-footer">
899- <div class="lv-footer-inner">
900- <div class="lv-footer-brand">
901- <a href="/" class="lv-logo">
902- <span class="lv-logo-mark"></span>gluecron
903- </a>
904- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
905- </div>
906- <div class="lv-footer-cols">
907- <div class="lv-footer-col">
908- <h4 class="lv-footer-col-head">Product</h4>
909- <a href="/" class="lv-footer-link">Agent workspace</a>
910- <a href="/" class="lv-footer-link">Fleet refactors</a>
911- <a href="/" class="lv-footer-link">Org memory</a>
912- <a href="/" class="lv-footer-link">IDE extensions</a>
913- </div>
914- <div class="lv-footer-col">
915- <h4 class="lv-footer-col-head">Platform</h4>
916- <a href="/" class="lv-footer-link">Production layers</a>
917- <a href="/trust" class="lv-footer-link">Trust report</a>
918- <a href="/" class="lv-footer-link">Docs</a>
919- <a href="/" class="lv-footer-link">Status</a>
920- </div>
921- <div class="lv-footer-col">
922- <h4 class="lv-footer-col-head">Company</h4>
923- <a href="/" class="lv-footer-link">About</a>
924- <a href="/" class="lv-footer-link">Pricing</a>
925- <a href="/" class="lv-footer-link">Enterprise</a>
926- </div>
927- </div>
928- </div>
929- <div class="lv-footer-bar">
930- <span>� 2026 Gluecron</span>
931- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
932- </div>
933- </footer>
934-
935- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
936- </>
937- );
938-};
939-
940-export const LandingPage = LandingPageV2;
941-export default LandingPageV2;
942-
943-const clientScript = `
944-(function() {
945- var demoAll = [
946- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
947- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
948- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
949- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
950- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
951- ];
952-
953- var demoStep = 0;
954- var stage = 0;
955-
956- function renderDemo() {
957- var container = document.getElementById('lv-demo-body');
958- if (!container) return;
959- var visible = demoAll.slice(0, demoStep + 1);
960- container.innerHTML = visible.map(function(e, i) {
961- var isLast = i === visible.length - 1;
962- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
963- return '<div class="lv-demo-event">' +
964- '<div class="lv-demo-event-track">' +
965- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
966- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
967- '</div>' +
968- '<div class="lv-demo-event-content">' +
969- '<div class="lv-demo-event-header">' +
970- '<span class="lv-demo-event-title">' + e.title + '</span>' +
971- '<span class="lv-demo-event-time">' + e.time + '</span>' +
972- '</div>' +
973- '<div class="lv-demo-event-body">' + e.body + '</div>' +
974- '</div>' +
975- '</div>';
976- }).join('');
977- }
978-
979- function renderStages() {
980- var cards = document.querySelectorAll('.lv-stage-card');
981- cards.forEach(function(card, i) {
982- var dot = card.querySelector('.lv-dot');
983- var meta = card.querySelector('.lv-stage-meta');
984- if (i === stage) {
985- card.classList.add('lv-stage-active');
986- if (dot) {
987- dot.classList.remove('lv-dot-idle');
988- dot.classList.add('lv-dot-indigo', 'lv-pulse');
989- }
990- if (meta) meta.classList.add('lv-stage-meta-active');
991- } else {
992- card.classList.remove('lv-stage-active');
993- if (dot) {
994- dot.classList.add('lv-dot-idle');
995- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
996- }
997- if (meta) meta.classList.remove('lv-stage-meta-active');
998- }
999- });
1000- }
1001-
1002- renderDemo();
1003-
1004- setInterval(function() {
1005- demoStep = (demoStep + 1) % 5;
1006- renderDemo();
1007- }, 3600);
1008-
1009- setInterval(function() {
1010- stage = (stage + 1) % 6;
1011- renderStages();
1012- }, 2200);
1013-})();
1014-`;
1015-
1016-const css = `
1017-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
1018-
1019-*, *::before, *::after { box-sizing: border-box; }
1020-
1021-body {
1022- margin: 0;
1023- background: #fcfcfd;
1024- -webkit-font-smoothing: antialiased;
1025- text-rendering: optimizeLegibility;
1026- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
1027- font-size: 15px;
1028- line-height: 1.6;
1029- letter-spacing: -0.008em;
1030- color: #16181d;
1031-}
1032-
1033-@keyframes gcPulse {
1034- 0%, 100% { opacity: 1; }
1035- 50% { opacity: 0.35; }
1036-}
1037-
1038-@keyframes gcTicker {
1039- 0% { transform: translateX(0); }
1040- 100% { transform: translateX(-50%); }
1041-}
1042-
1043-/* Shared utilities */
1044-.lv-dot {
1045- display: inline-block;
1046- border-radius: 50%;
1047-}
1048-.lv-dot-green { background: #1e7f5c; }
1049-.lv-dot-indigo { background: #4353c9; }
1050-.lv-dot-idle { background: #c4c6cf; }
1051-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
1052-
1053-.lv-strong { color: #16181d; font-weight: 600; }
1054-
1055-.lv-eyebrow {
1056- font-family: 'JetBrains Mono', monospace;
1057- font-size: 11px;
1058- letter-spacing: 0.12em;
1059- text-transform: uppercase;
1060- color: #8a8d99;
1061- font-weight: 500;
1062- margin-bottom: 12px;
1063-}
1064-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
1065-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
1066-
1067-.lv-h1 {
1068- font-family: 'Inter Tight', sans-serif;
1069- font-weight: 700;
1070- letter-spacing: -0.035em;
1071- font-size: clamp(44px, 7vw, 84px);
1072- line-height: 0.98;
1073- margin: 30px auto 0;
1074- max-width: 14ch;
1075- color: #111318;
1076-}
1077-
1078-.lv-h2 {
1079- font-family: 'Inter Tight', sans-serif;
1080- font-weight: 700;
1081- letter-spacing: -0.028em;
1082- font-size: clamp(30px, 4.4vw, 48px);
1083- line-height: 1.05;
1084- margin: 0;
1085- color: #111318;
1086-}
1087-
1088-.lv-h2-dark {
1089- font-family: 'Inter Tight', sans-serif;
1090- font-weight: 700;
1091- letter-spacing: -0.028em;
1092- font-size: clamp(30px, 4.6vw, 52px);
1093- line-height: 1.05;
1094- margin: 0;
1095- color: #fff;
1096-}
1097-
1098-.lv-section-header {
1099- max-width: 640px;
1100- margin: 0 auto 56px;
1101-}
1102-
1103-.lv-section-header-center {
1104- text-align: center;
1105-}
1106-
1107-.lv-section-sub {
1108- color: #6b7080;
1109- font-size: 17px;
1110- margin: 18px auto 0;
1111- max-width: 52ch;
1112-}
1113-
1114-.lv-section-sub-dark {
1115- color: rgba(255,255,255,0.72);
1116- font-size: 17px;
1117- margin: 18px auto 0;
1118- max-width: 56ch;
1119-}
1120-
1121-/* Nav */
1122-.lv-nav {
1123- position: sticky;
1124- top: 0;
1125- z-index: 60;
1126- backdrop-filter: saturate(180%) blur(14px);
1127- -webkit-backdrop-filter: saturate(180%) blur(14px);
1128- background: rgba(252,252,253,0.8);
1129- border-bottom: 1px solid rgba(22,24,29,0.07);
1130-}
1131-
1132-.lv-nav-inner {
1133- max-width: 1200px;
1134- margin: 0 auto;
1135- padding: 14px 28px;
1136- display: flex;
1137- align-items: center;
1138- gap: 28px;
1139-}
1140-
1141-.lv-logo {
1142- display: inline-flex;
1143- align-items: center;
1144- gap: 9px;
1145- font-family: 'Inter Tight', sans-serif;
1146- font-weight: 700;
1147- font-size: 17px;
1148- letter-spacing: -0.02em;
1149- color: #16181d;
1150- text-decoration: none;
1151-}
1152-
1153-.lv-logo-mark {
1154- width: 17px;
1155- height: 17px;
1156- border-radius: 5px;
1157- background: #4353c9;
1158- display: inline-block;
1159- flex-shrink: 0;
1160-}
1161-
1162-.lv-nav-links {
1163- display: flex;
1164- gap: 24px;
1165- font-size: 13.5px;
1166- font-weight: 500;
1167-}
1168-
1169-.lv-nav-link {
1170- color: #6b7080;
1171- text-decoration: none;
1172- transition: color 0.15s;
1173-}
1174-.lv-nav-link:hover { color: #16181d; }
1175-
1176-.lv-nav-ctas {
1177- margin-left: auto;
1178- display: flex;
1179- align-items: center;
1180- gap: 10px;
1181-}
1182-
1183-.lv-btn-secondary {
1184- padding: 8px 15px;
1185- border-radius: 8px;
1186- font-size: 13.5px;
1187- font-weight: 500;
1188- color: #16181d;
1189- border: 1px solid rgba(22,24,29,0.12);
1190- background: #ffffff;
1191- text-decoration: none;
1192- white-space: nowrap;
1193- transition: border-color 0.15s;
1194-}
1195-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
1196-
1197-.lv-btn-primary {
1198- padding: 8px 15px;
1199- border-radius: 8px;
1200- font-size: 13.5px;
1201- font-weight: 600;
1202- background: #16181d;
1203- color: #fff;
1204- text-decoration: none;
1205- white-space: nowrap;
1206- transition: box-shadow 0.15s;
1207-}
1208-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
1209-
1210-/* Hero */
1211-.lv-hero {
1212- position: relative;
1213- overflow: hidden;
1214- padding: 88px 0 0;
1215-}
1216-
1217-.lv-hero-glow {
1218- position: absolute;
1219- inset: -10% 0 auto 0;
1220- height: 640px;
1221- pointer-events: none;
1222- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
1223-}
1224-
1225-.lv-hero-inner {
1226- position: relative;
1227- max-width: 1200px;
1228- margin: 0 auto;
1229- padding: 0 28px;
1230- text-align: center;
1231-}
1232-
1233-.lv-hero-badge {
1234- display: inline-flex;
1235- align-items: center;
1236- gap: 9px;
1237- font-size: 12.5px;
1238- font-weight: 600;
1239- color: #3a3d45;
1240- background: #ffffff;
1241- border: 1px solid rgba(22,24,29,0.10);
1242- border-radius: 9999px;
1243- padding: 7px 16px;
1244- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
1245-}
1246-
1247-.lv-hero-sub {
1248- font-size: clamp(16px, 2vw, 19px);
1249- color: #6b7080;
1250- max-width: 60ch;
1251- margin: 24px auto 0;
1252- font-weight: 450;
1253- line-height: 1.65;
1254-}
1255-
1256-.lv-hero-actions {
1257- display: flex;
1258- gap: 12px;
1259- justify-content: center;
1260- flex-wrap: wrap;
1261- margin-top: 32px;
1262-}
1263-
1264-.lv-cta-primary {
1265- padding: 13px 24px;
1266- border-radius: 11px;
1267- font-size: 15.5px;
1268- font-weight: 600;
1269- background: #16181d;
1270- color: #fff;
1271- text-decoration: none;
1272- white-space: nowrap;
1273- transition: box-shadow 0.15s;
1274-}
1275-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
1276-
1277-.lv-cta-secondary {
1278- padding: 13px 24px;
1279- border-radius: 11px;
1280- font-size: 15.5px;
1281- font-weight: 600;
1282- color: #16181d;
1283- border: 1px solid rgba(22,24,29,0.14);
1284- background: #ffffff;
1285- text-decoration: none;
1286- white-space: nowrap;
1287- transition: border-color 0.15s;
1288-}
1289-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
1290-
1291-.lv-hero-tag {
1292- margin-top: 18px;
1293- font-family: 'JetBrains Mono', monospace;
1294- font-size: 11.5px;
1295- letter-spacing: 0.08em;
1296- text-transform: uppercase;
1297- color: #8a8d99;
1298-}
1299-
1300-/* Demo window */
1301-.lv-demo-window {
1302- margin: 56px auto 0;
1303- max-width: 860px;
1304- text-align: left;
1305- background: #ffffff;
1306- border: 1px solid rgba(22,24,29,0.09);
1307- border-radius: 18px;
1308- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
1309- overflow: hidden;
1310-}
1311-
1312-.lv-demo-bar {
1313- display: flex;
1314- align-items: center;
1315- gap: 7px;
1316- padding: 12px 18px;
1317- border-bottom: 1px solid rgba(22,24,29,0.07);
1318- background: #fcfcfd;
1319-}
1320-
1321-.lv-demo-dot {
1322- width: 10px;
1323- height: 10px;
1324- border-radius: 50%;
1325- background: #e4e5ea;
1326-}
1327-
1328-.lv-demo-url {
1329- margin-left: 10px;
1330- font-family: 'JetBrains Mono', monospace;
1331- font-size: 12px;
1332- color: #6b7080;
1333-}
1334-
1335-.lv-demo-live {
1336- margin-left: auto;
1337- display: inline-flex;
1338- align-items: center;
1339- gap: 6px;
1340- font-size: 11px;
1341- font-weight: 600;
1342- color: #1e7f5c;
1343-}
1344-
1345-.lv-demo-body {
1346- padding: 22px 24px;
1347-}
1348-
1349-.lv-demo-event {
1350- display: grid;
1351- grid-template-columns: 18px minmax(0, 1fr);
1352- gap: 14px;
1353- padding-bottom: 20px;
1354- position: relative;
1355-}
1356-.lv-demo-event:last-child { padding-bottom: 0; }
1357-
1358-.lv-demo-event-track {
1359- display: flex;
1360- flex-direction: column;
1361- align-items: center;
1362-}
1363-
1364-.lv-demo-line {
1365- width: 1px;
1366- flex: 1;
1367- background: rgba(22,24,29,0.08);
1368- margin-top: 5px;
1369- min-height: 20px;
1370-}
1371-
1372-.lv-demo-event-content {}
1373-
1374-.lv-demo-event-header {
1375- display: flex;
1376- align-items: baseline;
1377- gap: 10px;
1378-}
1379-
1380-.lv-demo-event-title {
1381- font-size: 13.5px;
1382- font-weight: 600;
1383- color: #16181d;
1384-}
1385-
1386-.lv-demo-event-time {
1387- font-family: 'JetBrains Mono', monospace;
1388- font-size: 11px;
1389- color: #8a8d99;
1390-}
1391-
1392-.lv-demo-event-body {
1393- font-size: 13px;
1394- color: #6b7080;
1395- margin-top: 2px;
1396-}
1397-
1398-/* Ticker */
1399-.lv-ticker-wrap {
1400- border-top: 1px solid rgba(22,24,29,0.07);
1401- border-bottom: 1px solid rgba(22,24,29,0.07);
1402- background: #ffffff;
1403- margin-top: 64px;
1404- overflow: hidden;
1405- white-space: nowrap;
1406- position: relative;
1407-}
1408-
1409-.lv-ticker-track {
1410- display: inline-flex;
1411- animation: gcTicker 40s linear infinite;
1412- padding: 11px 0;
1413-}
1414-
1415-.lv-ticker-item {
1416- display: inline-flex;
1417- align-items: center;
1418- gap: 8px;
1419- font-family: 'JetBrains Mono', monospace;
1420- font-size: 11.5px;
1421- color: #6b7080;
1422- padding: 0 28px;
1423- border-right: 1px solid rgba(22,24,29,0.06);
1424-}
1425-
1426-/* Stats */
1427-.lv-stats {
1428- background: #fcfcfd;
1429-}
1430-
1431-.lv-stats-inner {
1432- max-width: 1200px;
1433- margin: 0 auto;
1434- display: grid;
1435- grid-template-columns: repeat(4, 1fr);
1436- gap: 24px;
1437- padding: 52px 28px;
1438-}
1439-
1440-.lv-stat {
1441- text-align: center;
1442-}
1443-
1444-.lv-stat-num {
1445- font-family: 'Inter Tight', sans-serif;
1446- font-weight: 700;
1447- font-size: clamp(30px, 4vw, 44px);
1448- letter-spacing: -0.025em;
1449- color: #111318;
1450-}
1451-
1452-.lv-stat-label {
1453- font-size: 13px;
1454- color: #6b7080;
1455- margin-top: 4px;
1456-}
1457-
1458-/* Loop */
1459-.lv-loop {
1460- padding: 96px 0;
1461- background: #ffffff;
1462- border-top: 1px solid rgba(22,24,29,0.07);
1463- border-bottom: 1px solid rgba(22,24,29,0.07);
1464-}
1465-
1466-.lv-loop-inner {
1467- max-width: 1200px;
1468- margin: 0 auto;
1469- padding: 0 28px;
1470-}
1471-
1472-.lv-stages {
1473- display: grid;
1474- grid-template-columns: repeat(6, 1fr);
1475- gap: 12px;
1476-}
1477-
1478-.lv-stage-card {
1479- border: 1px solid rgba(22,24,29,0.08);
1480- border-radius: 14px;
1481- background: #ffffff;
1482- padding: 20px 18px;
1483- transition: border-color 0.3s, background 0.3s;
1484-}
1485-
1486-.lv-stage-card.lv-stage-active {
1487- border-color: rgba(67,83,201,0.45);
1488- background: rgba(67,83,201,0.03);
1489-}
1490-
1491-.lv-stage-header {
1492- display: flex;
1493- align-items: center;
1494- gap: 8px;
1495- margin-bottom: 10px;
1496-}
1497-
1498-.lv-stage-n {
1499- font-family: 'JetBrains Mono', monospace;
1500- font-size: 10.5px;
1501- letter-spacing: 0.1em;
1502- text-transform: uppercase;
1503- color: #8a8d99;
1504-}
1505-
1506-.lv-stage-name {
1507- font-family: 'Inter Tight', sans-serif;
1508- font-size: 16px;
1509- font-weight: 600;
1510- letter-spacing: -0.01em;
1511- color: #16181d;
1512- margin-bottom: 5px;
1513-}
1514-
1515-.lv-stage-desc {
1516- font-size: 12px;
1517- color: #6b7080;
1518- line-height: 1.55;
1519-}
1520-
1521-.lv-stage-meta {
1522- font-family: 'JetBrains Mono', monospace;
1523- font-size: 10.5px;
1524- color: #8a8d99;
1525- margin-top: 10px;
1526- transition: color 0.3s;
1527-}
1528-
1529-.lv-stage-meta.lv-stage-meta-active {
1530- color: #4353c9;
1531-}
1532-
1533-/* Heroes */
1534-.lv-heroes {
1535- padding: 96px 0;
1536- background: #fcfcfd;
1537-}
1538-
1539-.lv-heroes-inner {
1540- max-width: 1200px;
1541- margin: 0 auto;
1542- padding: 0 28px;
1543-}
1544-
1545-.lv-heroes-header {
1546- max-width: 640px;
1547- margin-bottom: 56px;
1548-}
1549-
1550-.lv-heroes-list {
1551- display: flex;
1552- flex-direction: column;
1553- gap: 20px;
1554-}
1555-
1556-.lv-hero-card {
1557- display: grid;
1558- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
1559- gap: 48px;
1560- align-items: center;
1561- border: 1px solid rgba(22,24,29,0.08);
1562- border-radius: 20px;
1563- background: #ffffff;
1564- padding: 44px 48px;
1565- text-decoration: none;
1566- transition: border-color 0.2s, box-shadow 0.2s;
1567-}
1568-.lv-hero-card:hover {
1569- border-color: rgba(22,24,29,0.22);
1570- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
1571-}
1572-
1573-.lv-hero-card-left {}
1574-
1575-.lv-hero-card-title {
1576- font-family: 'Inter Tight', sans-serif;
1577- font-size: 26px;
1578- font-weight: 600;
1579- letter-spacing: -0.022em;
1580- line-height: 1.15;
1581- color: #16181d;
1582- margin: 0 0 12px;
1583-}
1584-
1585-.lv-hero-card-body {
1586- font-size: 14.5px;
1587- color: #6b7080;
1588- margin: 0 0 18px;
1589- line-height: 1.65;
1590-}
1591-
1592-.lv-hero-card-cta {
1593- font-size: 13.5px;
1594- font-weight: 600;
1595- color: #4353c9;
1596-}
1597-
1598-.lv-terminal {
1599- border: 1px solid rgba(22,24,29,0.07);
1600- border-radius: 14px;
1601- background: #fcfcfd;
1602- padding: 20px 22px;
1603- font-family: 'JetBrains Mono', monospace;
1604- font-size: 12px;
1605- line-height: 1.9;
1606- overflow: hidden;
1607-}
1608-
1609-.lv-terminal-line {
1610- display: flex;
1611- align-items: center;
1612- gap: 10px;
1613- white-space: nowrap;
1614- overflow: hidden;
1615- text-overflow: ellipsis;
1616-}
1617-
1618-/* Platform */
1619-.lv-platform {
1620- padding: 96px 0;
1621- background: #ffffff;
1622- border-top: 1px solid rgba(22,24,29,0.07);
1623-}
1624-
1625-.lv-platform-inner {
1626- max-width: 1200px;
1627- margin: 0 auto;
1628- padding: 0 28px;
1629-}
1630-
1631-.lv-cap-grid {
1632- display: grid;
1633- grid-template-columns: repeat(4, 1fr);
1634- gap: 24px 32px;
1635-}
1636-
1637-.lv-cap-col {}
1638-
1639-.lv-cap-group {
1640- font-family: 'JetBrains Mono', monospace;
1641- font-size: 10.5px;
1642- letter-spacing: 0.12em;
1643- text-transform: uppercase;
1644- color: #8a8d99;
1645- font-weight: 500;
1646- margin-bottom: 12px;
1647- padding-bottom: 8px;
1648- border-bottom: 1px solid rgba(22,24,29,0.07);
1649-}
1650-
1651-.lv-cap-items {
1652- display: flex;
1653- flex-direction: column;
1654- gap: 7px;
1655-}
1656-
1657-.lv-cap-item {
1658- font-size: 12.5px;
1659- color: #3a3d45;
1660- line-height: 1.45;
1661-}
1662-
1663-/* Sovereignty */
1664-.lv-sovereign {
1665- position: relative;
1666- overflow: hidden;
1667- padding: 104px 0;
1668- color: #fff;
1669- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
1670-}
1671-
1672-.lv-sovereign-grid-bg {
1673- position: absolute;
1674- inset: 0;
1675- opacity: 0.4;
1676- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
1677- background-size: 56px 56px;
1678- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
1679- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
1680-}
1681-
1682-.lv-sovereign-inner {
1683- position: relative;
1684- max-width: 1200px;
1685- margin: 0 auto;
1686- padding: 0 28px;
1687-}
1688-
1689-.lv-section-header-dark {
1690- max-width: 680px;
1691- margin: 0 auto 48px;
1692- text-align: center;
1693-}
1694-
1695-.lv-layers-grid {
1696- display: grid;
1697- grid-template-columns: repeat(4, 1fr);
1698- gap: 10px;
1699- max-width: 980px;
1700- margin: 0 auto;
1701-}
1702-
1703-.lv-layer-chip {
1704- border: 1px solid rgba(255,255,255,0.10);
1705- border-radius: 10px;
1706- padding: 12px 16px;
1707- background: rgba(255,255,255,0.03);
1708-}
1709-
1710-.lv-layer-cta {
1711- border-color: rgba(169,180,238,0.30);
1712- background: rgba(169,180,238,0.06);
1713- display: flex;
1714- align-items: center;
1715- text-decoration: none;
1716- transition: background 0.15s;
1717-}
1718-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
1719-
1720-.lv-layer-cta-text {
1721- font-size: 13px;
1722- font-weight: 500;
1723- color: #a9b4ee;
1724-}
1725-
1726-.lv-layer-n {
1727- font-family: 'JetBrains Mono', monospace;
1728- font-size: 10px;
1729- color: rgba(255,255,255,0.4);
1730- margin-bottom: 3px;
1731-}
1732-
1733-.lv-layer-name {
1734- font-size: 13px;
1735- font-weight: 500;
1736- color: rgba(255,255,255,0.92);
1737-}
1738-
1739-.lv-sovereign-feats {
1740- display: flex;
1741- gap: 44px;
1742- justify-content: center;
1743- flex-wrap: wrap;
1744- margin-top: 52px;
1745- text-align: center;
1746-}
1747-
1748-.lv-sovereign-feat {}
1749-
1750-.lv-sovereign-feat-title {
1751- font-family: 'Inter Tight', sans-serif;
1752- font-size: 20px;
1753- font-weight: 700;
1754- color: #fff;
1755-}
1756-
1757-.lv-sovereign-feat-sub {
1758- color: rgba(255,255,255,0.55);
1759- font-size: 13px;
1760- margin-top: 2px;
1761-}
1762-
1763-/* Twin cards */
1764-.lv-twin {
1765- padding: 96px 0;
1766- background: #fcfcfd;
1767-}
1768-
1769-.lv-twin-inner {
1770- max-width: 1200px;
1771- margin: 0 auto;
1772- padding: 0 28px;
1773- display: grid;
1774- grid-template-columns: 1fr 1fr;
1775- gap: 24px;
1776-}
1777-
1778-.lv-twin-card {
1779- border: 1px solid rgba(22,24,29,0.08);
1780- border-radius: 20px;
1781- background: #ffffff;
1782- padding: 44px 48px;
1783-}
1784-
1785-.lv-twin-title {
1786- font-family: 'Inter Tight', sans-serif;
1787- font-size: 24px;
1788- font-weight: 600;
1789- letter-spacing: -0.02em;
1790- line-height: 1.2;
1791- margin: 0 0 12px;
1792- color: #16181d;
1793-}
1794-
1795-.lv-twin-body {
1796- font-size: 14.5px;
1797- color: #6b7080;
1798- margin: 0 0 16px;
1799- line-height: 1.7;
1800-}
1801-
1802-.lv-twin-link {
1803- font-size: 13.5px;
1804- font-weight: 600;
1805- color: #4353c9;
1806- text-decoration: none;
1807-}
1808-.lv-twin-link:hover { text-decoration: underline; }
1809-
1810-/* Quote */
1811-.lv-quote {
1812- padding: 40px 0 96px;
1813- background: #fcfcfd;
1814-}
1815-
1816-.lv-quote-inner {
1817- max-width: 980px;
1818- margin: 0 auto;
1819- padding: 0 28px;
1820- text-align: center;
1821-}
1822-
1823-.lv-quote-text {
1824- font-family: 'Inter Tight', sans-serif;
1825- font-weight: 600;
1826- font-size: clamp(26px, 3.8vw, 42px);
1827- line-height: 1.2;
1828- letter-spacing: -0.025em;
1829- margin: 0;
1830- color: #111318;
1831-}
1832-
1833-.lv-em {
1834- font-style: normal;
1835- color: #4353c9;
1836-}
1837-
1838-/* CTA */
1839-.lv-cta-section {
1840- padding: 0 0 104px;
1841- background: #fcfcfd;
1842-}
1843-
1844-.lv-cta-card {
1845- max-width: 820px;
1846- margin: 0 auto;
1847- padding: 64px 40px;
1848- text-align: center;
1849- background: #ffffff;
1850- border: 1px solid rgba(22,24,29,0.08);
1851- border-radius: 26px;
1852- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
1853- position: relative;
1854- overflow: hidden;
1855-}
1856-
1857-.lv-cta-glow {
1858- position: absolute;
1859- inset: -40% 0 auto 0;
1860- height: 280px;
1861- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
1862- pointer-events: none;
1863-}
1864-
1865-.lv-cta-h2 {
1866- font-family: 'Inter Tight', sans-serif;
1867- font-weight: 700;
1868- letter-spacing: -0.028em;
1869- font-size: clamp(30px, 4.6vw, 48px);
1870- margin: 0;
1871- position: relative;
1872- color: #111318;
1873-}
1874-
1875-.lv-cta-sub {
1876- color: #6b7080;
1877- font-size: 17px;
1878- margin: 16px 0 30px;
1879- position: relative;
1880-}
1881-
1882-.lv-cta-actions {
1883- display: flex;
1884- gap: 12px;
1885- justify-content: center;
1886- flex-wrap: wrap;
1887- position: relative;
1888-}
1889-
1890-.lv-cta-fine {
1891- margin-top: 20px;
1892- font-family: 'JetBrains Mono', monospace;
1893- font-size: 11px;
1894- color: #8a8d99;
1895- position: relative;
1896-}
1897-
1898-/* Footer */
1899-.lv-footer {
1900- border-top: 1px solid rgba(22,24,29,0.07);
1901- background: #ffffff;
1902- padding: 56px 0 30px;
1903-}
1904-
1905-.lv-footer-inner {
1906- max-width: 1200px;
1907- margin: 0 auto;
1908- padding: 0 28px;
1909- display: flex;
1910- gap: 48px;
1911- flex-wrap: wrap;
1912- justify-content: space-between;
1913-}
1914-
1915-.lv-footer-brand {}
1916-
1917-.lv-footer-tagline {
1918- color: #6b7080;
1919- font-size: 13.5px;
1920- margin: 12px 0 0;
1921- max-width: 32ch;
1922- line-height: 1.6;
1923-}
1924-
1925-.lv-footer-cols {
1926- display: flex;
1927- gap: 64px;
1928- flex-wrap: wrap;
1929-}
1930-
1931-.lv-footer-col {
1932- display: flex;
1933- flex-direction: column;
1934- gap: 9px;
1935-}
1936-
1937-.lv-footer-col-head {
1938- font-family: 'JetBrains Mono', monospace;
1939- font-size: 11px;
1940- text-transform: uppercase;
1941- letter-spacing: 0.1em;
1942- color: #8a8d99;
1943- margin: 0 0 4px;
1944- font-weight: 500;
1945-}
1946-
1947-.lv-footer-link {
1948- color: #3a3d45;
1949- font-size: 13.5px;
1950- text-decoration: none;
1951- transition: color 0.15s;
1952-}
1953-.lv-footer-link:hover { color: #16181d; }
1954-
1955-.lv-footer-bar {
1956- max-width: 1200px;
1957- margin: 44px auto 0;
1958- padding: 22px 28px 0;
1959- border-top: 1px solid rgba(22,24,29,0.06);
1960- display: flex;
1961- justify-content: space-between;
1962- flex-wrap: wrap;
1963- gap: 8px;
1964- color: #8a8d99;
1965- font-size: 12.5px;
1966-}
1967-
1968-.lv-footer-stack {
1969- font-family: 'JetBrains Mono', monospace;
1970- font-size: 11px;
1971-}
1972-`;
1973diff --git a/src/views/layout.tsx b/src/views/layout.tsx
1974index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
1975--- a/src/views/layout.tsx
1976+++ b/src/views/layout.tsx
1977@@ -3153,9 +3153,12 @@
1978 font-weight: 500;
1979 line-height: 1.4;
1980 }
1981- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
1982- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
1983- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
1984+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
1985+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
1986+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
1987+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
1988+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
1989+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
1990 .state-merged { color: var(--accent); }
1991 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
1992
1993diff --git a/src/views/ui.tsx b/src/views/ui.tsx
1994index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
1995--- a/src/views/ui.tsx
1996+++ b/src/views/ui.tsx
1997@@ -232,7 +232,7 @@
1998
1999 export const Badge: FC<
2000 PropsWithChildren<{
2001- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
2002+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
2003 style?: string;
2004 }>
2005 > = ({ children, variant = "default", style }) => {
2006@@ -241,9 +241,12 @@
2007 variant === "closed" ? "badge-closed" :
2008 variant === "merged" ? "badge-merged" :
2009 variant === "success" ? "badge-success" :
2010- variant === "danger" ? "badge-danger" :
2011- variant === "warning" ? "badge-warning" :
2012- "badge";
2013+ variant === "danger" ? "badge-danger" :
2014+ variant === "warning" ? "badge-warning" :
2015+ variant === "live" ? "badge-live" :
2016+ variant === "soon" ? "badge-soon" :
2017+ variant === "preview" ? "badge-preview" :
2018+ "badge";
2019 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
2020 };
2021
2022
2023diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
2024index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
2025--- a/src/views/landing-pro.tsx
2026+++ b/src/views/landing-pro.tsx
2027@@ -42,7 +42,7 @@
2028
2029 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2030
2031-function icon(paths: string, color = "#4353c9", size = 20) {
2032+function icon(paths: string, color = "#0891b2", size = 20) {
2033 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
2034 }
2035
2036@@ -947,7 +947,7 @@
2037 const css = `
2038 /* %% tokens %% */
2039 :root{
2040- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
2041+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
2042 --lp-bg:#ffffff;--lp-soft:#fafafb;
2043 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
2044 --lp-border:rgba(0,0,0,.08);
2045diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
2046deleted file mode 100644
2047index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
2048--- a/src/views/landing-v2.tsx
2049+++ /dev/null
2050@@ -1,1447 +0,0 @@
2051-import type { FC } from "hono/jsx";
2052-
2053-export interface LandingPageProps {
2054- stats?: {
2055- publicRepos?: number;
2056- users?: number;
2057- };
2058-}
2059-
2060-const demoAllEvents = [
2061- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
2062- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
2063- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
2064- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
2065- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
2066-];
2067-
2068-const tickerItems = [
2069- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
2070- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
2071- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
2072- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
2073- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
2074- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
2075- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
2076- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
2077- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
2078- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
2079- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
2080- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
2081- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
2082- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
2083- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
2084- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
2085-];
2086-
2087-const stageData = [
2088- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
2089- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
2090- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
2091- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
2092- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
2093- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
2094-];
2095-
2096-const heroFeatures = [
2097- {
2098- href: "/",
2099- eyebrow: "01 � The autonomous repair loop",
2100- title: "Failures fix themselves  and show their work.",
2101- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
2102failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
2103- cta: "Watch a live repair session",
2104- mock: [
2105- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
2106- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
2107- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
2108- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
2109- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
2110- ],
2111- },
2112- {
2113- href: "/",
2114- eyebrow: "02 � Live sandbox isolation",
2115- title: "Every PR gets its own instant, disposable environment.",
2116- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
2117same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
2118- cta: "See a PR with its sandbox",
2119- mock: [
2120- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
2121- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
2122- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
2123- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
2124- ],
2125- },
2126- {
2127- href: "/",
2128- eyebrow: "03 � Multiplayer IDE workspaces",
2129- title: "You and the agent, side by side, in your editor.",
2130- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
2131agent into a silent reviewer in your gutter. The browser becomes optional.",
2132- cta: "See the editor session",
2133- mock: [
2134- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
2135- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
2136- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
2137- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
2138- ],
2139- },
2140-];
2141-
2142-const capabilities = [
2143- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
2144- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
2145- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
2146- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
2147- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
2148- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
2149- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
2150- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
2151-];
2152-
2153-const sovereignLayerNames = [
2154- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
2155- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
2156- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
2157- "Availability & recovery",
2158-];
2159-
2160-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
2161- return (
2162- <>
2163- <style dangerouslySetInnerHTML={{ __html: css }} />
2164-
2165- {/* Nav */}
2166- <header class="lv-nav">
2167- <div class="lv-nav-inner">
2168- <a href="/" class="lv-logo">
2169- <span class="lv-logo-mark"></span>gluecron
2170- </a>
2171- <nav class="lv-nav-links">
2172- <a href="#loop" class="lv-nav-link">The loop</a>
2173- <a href="#platform" class="lv-nav-link">Platform</a>
2174- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
2175- <a href="/trust" class="lv-nav-link">Trust</a>
2176- </nav>
2177- <div class="lv-nav-ctas">
2178- <a href="/login" class="lv-btn-secondary">Sign in</a>
2179- <a href="/register" class="lv-btn-primary">Start building</a>
2180- </div>
2181- </div>
2182- </header>
2183-
2184- {/* Hero */}
2185- <section class="lv-hero">
2186- <div class="lv-hero-glow"></div>
2187- <div class="lv-hero-inner">
2188- <div class="lv-hero-badge">
2189- <span class="lv-dot lv-dot-green lv-pulse"></span>
2190- Live: a repair loop converged on pr-218 while you read this
2191- </div>
2192- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
2193- <p class="lv-hero-sub">
2194- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
2195failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
2196- </p>
2197- <div class="lv-hero-actions">
2198- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
2199- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
2200- </div>
2201- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
2202-
2203- {/* Live product window */}
2204- <div class="lv-demo-window">
2205- <div class="lv-demo-bar">
2206- <span class="lv-demo-dot"></span>
2207- <span class="lv-demo-dot"></span>
2208- <span class="lv-demo-dot"></span>
2209- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
2210- <span class="lv-demo-live">
2211- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
2212- LIVE
2213- </span>
2214- </div>
2215- <div class="lv-demo-body" id="lv-demo-body">
2216- {/* Events rendered by JS */}
2217- {demoAllEvents.slice(0, 1).map((e, i) => (
2218- <div class="lv-demo-event" key={i}>
2219- <div class="lv-demo-event-track">
2220- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
2221- <span class="lv-demo-line" style="display:none"></span>
2222- </div>
2223- <div class="lv-demo-event-content">
2224- <div class="lv-demo-event-header">
2225- <span class="lv-demo-event-title">{e.title}</span>
2226- <span class="lv-demo-event-time">{e.time}</span>
2227- </div>
2228- <div class="lv-demo-event-body">{e.body}</div>
2229- </div>
2230- </div>
2231- ))}
2232- </div>
2233- </div>
2234- </div>
2235-
2236- {/* Activity ticker */}
2237- <div class="lv-ticker-wrap">
2238- <div class="lv-ticker-track">
2239- {tickerItems.map((t, i) => (
2240- <span class="lv-ticker-item" key={i}>
2241- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
2242- {t.text}
2243- </span>
2244- ))}
2245- </div>
2246- </div>
2247- </section>
2248-
2249- {/* Stat band */}
2250- <section class="lv-stats">
2251- <div class="lv-stats-inner">
2252- <div class="lv-stat">
2253- <div class="lv-stat-num">Sonnet 5</div>
2254- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
2255- </div>
2256- <div class="lv-stat">
2257- <div class="lv-stat-num">93.5%</div>
2258- <div class="lv-stat-label">of failures self-repair without a human</div>
2259- </div>
2260- <div class="lv-stat">
2261- <div class="lv-stat-num">1.9%</div>
2262- <div class="lv-stat-label">AI merges reverted  published live</div>
2263- </div>
2264- <div class="lv-stat">
2265- <div class="lv-stat-num">0</div>
2266- <div class="lv-stat-label">irreversible actions taken autonomously</div>
2267- </div>
2268- </div>
2269- </section>
2270-
2271- {/* The loop */}
2272- <section id="loop" class="lv-loop">
2273- <div class="lv-loop-inner">
2274- <div class="lv-section-header">
2275- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
2276- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
2277- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
2278- </div>
2279- <div class="lv-stages" id="lv-stages">
2280- {stageData.map((s, i) => (
2281- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
2282- <div class="lv-stage-header">
2283- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
2284- <span class="lv-stage-n">0{i + 1}</span>
2285- </div>
2286- <div class="lv-stage-name">{s.name}</div>
2287- <div class="lv-stage-desc">{s.desc}</div>
2288- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
2289- </div>
2290- ))}
2291- </div>
2292- </div>
2293- </section>
2294-
2295- {/* Three heroes */}
2296- <section class="lv-heroes">
2297- <div class="lv-heroes-inner">
2298- <div class="lv-heroes-header">
2299- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
2300- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
2301- </div>
2302- <div class="lv-heroes-list">
2303- {heroFeatures.map((h, i) => (
2304- <a href={h.href} class="lv-hero-card" key={i}>
2305- <div class="lv-hero-card-left">
2306- <div class="lv-eyebrow">{h.eyebrow}</div>
2307- <h3 class="lv-hero-card-title">{h.title}</h3>
2308- <p class="lv-hero-card-body">{h.body}</p>
2309- <span class="lv-hero-card-cta">{h.cta} �!</span>
2310- </div>
2311- <div class="lv-terminal">
2312- {h.mock.map((m, j) => (
2313- <div class="lv-terminal-line" key={j}>
2314- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
2315- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
2316- </div>
2317- ))}
2318- </div>
2319- </a>
2320- ))}
2321- </div>
2322- </div>
2323- </section>
2324-
2325- {/* Everything grid */}
2326- <section id="platform" class="lv-platform">
2327- <div class="lv-platform-inner">
2328- <div class="lv-section-header lv-section-header-center">
2329- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
2330- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
2331- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
2332- </div>
2333- <div class="lv-cap-grid">
2334- {capabilities.map((c, i) => (
2335- <div class="lv-cap-col" key={i}>
2336- <div class="lv-cap-group">{c.group}</div>
2337- <div class="lv-cap-items">
2338- {c.items.map((item, j) => (
2339- <div class="lv-cap-item" key={j}>{item}</div>
2340- ))}
2341- </div>
2342- </div>
2343- ))}
2344- </div>
2345- </div>
2346- </section>
2347-
2348- {/* Sovereignty band */}
2349- <section id="sovereign" class="lv-sovereign">
2350- <div class="lv-sovereign-grid-bg"></div>
2351- <div class="lv-sovereign-inner">
2352- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
2353- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
2354- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
2355- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
2356to private cloud, or run fully air-gapped on bare metal.</p>
2357- </div>
2358- <div class="lv-layers-grid">
2359- {sovereignLayerNames.map((name, i) => (
2360- <div class="lv-layer-chip" key={i}>
2361- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
2362- <div class="lv-layer-name">{name}</div>
2363- </div>
2364- ))}
2365- <a href="/" class="lv-layer-chip lv-layer-cta">
2366- <div class="lv-layer-cta-text">All self-owned �!</div>
2367- </a>
2368- </div>
2369- <div class="lv-sovereign-feats">
2370- <div class="lv-sovereign-feat">
2371- <div class="lv-sovereign-feat-title">Local inference first</div>
2372- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
2373- </div>
2374- <div class="lv-sovereign-feat">
2375- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
2376- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
2377- </div>
2378- <div class="lv-sovereign-feat">
2379- <div class="lv-sovereign-feat-title">Self-healing infra</div>
2380- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
2381- </div>
2382- </div>
2383- </div>
2384- </section>
2385-
2386- {/* Manual-first + reversibility */}
2387- <section class="lv-twin">
2388- <div class="lv-twin-inner">
2389- <div class="lv-twin-card">
2390- <div class="lv-eyebrow">Manual-first, always</div>
2391- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
2392- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
2393fallback. Developers who never touch AI get the best git host they've ever used.</p>
2394- </div>
2395- <div class="lv-twin-card">
2396- <div class="lv-eyebrow">The reversibility guarantee</div>
2397- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
2398- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
2399 policy, not promise. Our quality numbers are published live, unedited.</p>
2400- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
2401- </div>
2402- </div>
2403- </section>
2404-
2405- {/* Quote */}
2406- <section class="lv-quote">
2407- <div class="lv-quote-inner">
2408- <p class="lv-quote-text">
2409- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
2410- Gluecron is where code gets <em class="lv-em">finished</em>."
2411- </p>
2412- </div>
2413- </section>
2414-
2415- {/* CTA */}
2416- <section class="lv-cta-section">
2417- <div class="lv-cta-card">
2418- <div class="lv-cta-glow"></div>
2419- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
2420- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
2421- <div class="lv-cta-actions">
2422- <a href="/register" class="lv-cta-primary">Create your account �!</a>
2423- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
2424- </div>
2425- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
2426- </div>
2427- </section>
2428-
2429- {/* Footer */}
2430- <footer class="lv-footer">
2431- <div class="lv-footer-inner">
2432- <div class="lv-footer-brand">
2433- <a href="/" class="lv-logo">
2434- <span class="lv-logo-mark"></span>gluecron
2435- </a>
2436- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
2437- </div>
2438- <div class="lv-footer-cols">
2439- <div class="lv-footer-col">
2440- <h4 class="lv-footer-col-head">Product</h4>
2441- <a href="/" class="lv-footer-link">Agent workspace</a>
2442- <a href="/" class="lv-footer-link">Fleet refactors</a>
2443- <a href="/" class="lv-footer-link">Org memory</a>
2444- <a href="/" class="lv-footer-link">IDE extensions</a>
2445- </div>
2446- <div class="lv-footer-col">
2447- <h4 class="lv-footer-col-head">Platform</h4>
2448- <a href="/" class="lv-footer-link">Production layers</a>
2449- <a href="/trust" class="lv-footer-link">Trust report</a>
2450- <a href="/" class="lv-footer-link">Docs</a>
2451- <a href="/" class="lv-footer-link">Status</a>
2452- </div>
2453- <div class="lv-footer-col">
2454- <h4 class="lv-footer-col-head">Company</h4>
2455- <a href="/" class="lv-footer-link">About</a>
2456- <a href="/" class="lv-footer-link">Pricing</a>
2457- <a href="/" class="lv-footer-link">Enterprise</a>
2458- </div>
2459- </div>
2460- </div>
2461- <div class="lv-footer-bar">
2462- <span>� 2026 Gluecron</span>
2463- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
2464- </div>
2465- </footer>
2466-
2467- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
2468- </>
2469- );
2470-};
2471-
2472-export const LandingPage = LandingPageV2;
2473-export default LandingPageV2;
2474-
2475-const clientScript = `
2476-(function() {
2477- var demoAll = [
2478- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
2479- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
2480- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
2481- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
2482- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
2483- ];
2484-
2485- var demoStep = 0;
2486- var stage = 0;
2487-
2488- function renderDemo() {
2489- var container = document.getElementById('lv-demo-body');
2490- if (!container) return;
2491- var visible = demoAll.slice(0, demoStep + 1);
2492- container.innerHTML = visible.map(function(e, i) {
2493- var isLast = i === visible.length - 1;
2494- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
2495- return '<div class="lv-demo-event">' +
2496- '<div class="lv-demo-event-track">' +
2497- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
2498- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
2499- '</div>' +
2500- '<div class="lv-demo-event-content">' +
2501- '<div class="lv-demo-event-header">' +
2502- '<span class="lv-demo-event-title">' + e.title + '</span>' +
2503- '<span class="lv-demo-event-time">' + e.time + '</span>' +
2504- '</div>' +
2505- '<div class="lv-demo-event-body">' + e.body + '</div>' +
2506- '</div>' +
2507- '</div>';
2508- }).join('');
2509- }
2510-
2511- function renderStages() {
2512- var cards = document.querySelectorAll('.lv-stage-card');
2513- cards.forEach(function(card, i) {
2514- var dot = card.querySelector('.lv-dot');
2515- var meta = card.querySelector('.lv-stage-meta');
2516- if (i === stage) {
2517- card.classList.add('lv-stage-active');
2518- if (dot) {
2519- dot.classList.remove('lv-dot-idle');
2520- dot.classList.add('lv-dot-indigo', 'lv-pulse');
2521- }
2522- if (meta) meta.classList.add('lv-stage-meta-active');
2523- } else {
2524- card.classList.remove('lv-stage-active');
2525- if (dot) {
2526- dot.classList.add('lv-dot-idle');
2527- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
2528- }
2529- if (meta) meta.classList.remove('lv-stage-meta-active');
2530- }
2531- });
2532- }
2533-
2534- renderDemo();
2535-
2536- setInterval(function() {
2537- demoStep = (demoStep + 1) % 5;
2538- renderDemo();
2539- }, 3600);
2540-
2541- setInterval(function() {
2542- stage = (stage + 1) % 6;
2543- renderStages();
2544- }, 2200);
2545-})();
2546-`;
2547-
2548-const css = `
2549-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
2550-
2551-*, *::before, *::after { box-sizing: border-box; }
2552-
2553-body {
2554- margin: 0;
2555- background: #fcfcfd;
2556- -webkit-font-smoothing: antialiased;
2557- text-rendering: optimizeLegibility;
2558- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
2559- font-size: 15px;
2560- line-height: 1.6;
2561- letter-spacing: -0.008em;
2562- color: #16181d;
2563-}
2564-
2565-@keyframes gcPulse {
2566- 0%, 100% { opacity: 1; }
2567- 50% { opacity: 0.35; }
2568-}
2569-
2570-@keyframes gcTicker {
2571- 0% { transform: translateX(0); }
2572- 100% { transform: translateX(-50%); }
2573-}
2574-
2575-/* Shared utilities */
2576-.lv-dot {
2577- display: inline-block;
2578- border-radius: 50%;
2579-}
2580-.lv-dot-green { background: #1e7f5c; }
2581-.lv-dot-indigo { background: #4353c9; }
2582-.lv-dot-idle { background: #c4c6cf; }
2583-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
2584-
2585-.lv-strong { color: #16181d; font-weight: 600; }
2586-
2587-.lv-eyebrow {
2588- font-family: 'JetBrains Mono', monospace;
2589- font-size: 11px;
2590- letter-spacing: 0.12em;
2591- text-transform: uppercase;
2592- color: #8a8d99;
2593- font-weight: 500;
2594- margin-bottom: 12px;
2595-}
2596-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
2597-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
2598-
2599-.lv-h1 {
2600- font-family: 'Inter Tight', sans-serif;
2601- font-weight: 700;
2602- letter-spacing: -0.035em;
2603- font-size: clamp(44px, 7vw, 84px);
2604- line-height: 0.98;
2605- margin: 30px auto 0;
2606- max-width: 14ch;
2607- color: #111318;
2608-}
2609-
2610-.lv-h2 {
2611- font-family: 'Inter Tight', sans-serif;
2612- font-weight: 700;
2613- letter-spacing: -0.028em;
2614- font-size: clamp(30px, 4.4vw, 48px);
2615- line-height: 1.05;
2616- margin: 0;
2617- color: #111318;
2618-}
2619-
2620-.lv-h2-dark {
2621- font-family: 'Inter Tight', sans-serif;
2622- font-weight: 700;
2623- letter-spacing: -0.028em;
2624- font-size: clamp(30px, 4.6vw, 52px);
2625- line-height: 1.05;
2626- margin: 0;
2627- color: #fff;
2628-}
2629-
2630-.lv-section-header {
2631- max-width: 640px;
2632- margin: 0 auto 56px;
2633-}
2634-
2635-.lv-section-header-center {
2636- text-align: center;
2637-}
2638-
2639-.lv-section-sub {
2640- color: #6b7080;
2641- font-size: 17px;
2642- margin: 18px auto 0;
2643- max-width: 52ch;
2644-}
2645-
2646-.lv-section-sub-dark {
2647- color: rgba(255,255,255,0.72);
2648- font-size: 17px;
2649- margin: 18px auto 0;
2650- max-width: 56ch;
2651-}
2652-
2653-/* Nav */
2654-.lv-nav {
2655- position: sticky;
2656- top: 0;
2657- z-index: 60;
2658- backdrop-filter: saturate(180%) blur(14px);
2659- -webkit-backdrop-filter: saturate(180%) blur(14px);
2660- background: rgba(252,252,253,0.8);
2661- border-bottom: 1px solid rgba(22,24,29,0.07);
2662-}
2663-
2664-.lv-nav-inner {
2665- max-width: 1200px;
2666- margin: 0 auto;
2667- padding: 14px 28px;
2668- display: flex;
2669- align-items: center;
2670- gap: 28px;
2671-}
2672-
2673-.lv-logo {
2674- display: inline-flex;
2675- align-items: center;
2676- gap: 9px;
2677- font-family: 'Inter Tight', sans-serif;
2678- font-weight: 700;
2679- font-size: 17px;
2680- letter-spacing: -0.02em;
2681- color: #16181d;
2682- text-decoration: none;
2683-}
2684-
2685-.lv-logo-mark {
2686- width: 17px;
2687- height: 17px;
2688- border-radius: 5px;
2689- background: #4353c9;
2690- display: inline-block;
2691- flex-shrink: 0;
2692-}
2693-
2694-.lv-nav-links {
2695- display: flex;
2696- gap: 24px;
2697- font-size: 13.5px;
2698- font-weight: 500;
2699-}
2700-
2701-.lv-nav-link {
2702- color: #6b7080;
2703- text-decoration: none;
2704- transition: color 0.15s;
2705-}
2706-.lv-nav-link:hover { color: #16181d; }
2707-
2708-.lv-nav-ctas {
2709- margin-left: auto;
2710- display: flex;
2711- align-items: center;
2712- gap: 10px;
2713-}
2714-
2715-.lv-btn-secondary {
2716- padding: 8px 15px;
2717- border-radius: 8px;
2718- font-size: 13.5px;
2719- font-weight: 500;
2720- color: #16181d;
2721- border: 1px solid rgba(22,24,29,0.12);
2722- background: #ffffff;
2723- text-decoration: none;
2724- white-space: nowrap;
2725- transition: border-color 0.15s;
2726-}
2727-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
2728-
2729-.lv-btn-primary {
2730- padding: 8px 15px;
2731- border-radius: 8px;
2732- font-size: 13.5px;
2733- font-weight: 600;
2734- background: #16181d;
2735- color: #fff;
2736- text-decoration: none;
2737- white-space: nowrap;
2738- transition: box-shadow 0.15s;
2739-}
2740-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
2741-
2742-/* Hero */
2743-.lv-hero {
2744- position: relative;
2745- overflow: hidden;
2746- padding: 88px 0 0;
2747-}
2748-
2749-.lv-hero-glow {
2750- position: absolute;
2751- inset: -10% 0 auto 0;
2752- height: 640px;
2753- pointer-events: none;
2754- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
2755-}
2756-
2757-.lv-hero-inner {
2758- position: relative;
2759- max-width: 1200px;
2760- margin: 0 auto;
2761- padding: 0 28px;
2762- text-align: center;
2763-}
2764-
2765-.lv-hero-badge {
2766- display: inline-flex;
2767- align-items: center;
2768- gap: 9px;
2769- font-size: 12.5px;
2770- font-weight: 600;
2771- color: #3a3d45;
2772- background: #ffffff;
2773- border: 1px solid rgba(22,24,29,0.10);
2774- border-radius: 9999px;
2775- padding: 7px 16px;
2776- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
2777-}
2778-
2779-.lv-hero-sub {
2780- font-size: clamp(16px, 2vw, 19px);
2781- color: #6b7080;
2782- max-width: 60ch;
2783- margin: 24px auto 0;
2784- font-weight: 450;
2785- line-height: 1.65;
2786-}
2787-
2788-.lv-hero-actions {
2789- display: flex;
2790- gap: 12px;
2791- justify-content: center;
2792- flex-wrap: wrap;
2793- margin-top: 32px;
2794-}
2795-
2796-.lv-cta-primary {
2797- padding: 13px 24px;
2798- border-radius: 11px;
2799- font-size: 15.5px;
2800- font-weight: 600;
2801- background: #16181d;
2802- color: #fff;
2803- text-decoration: none;
2804- white-space: nowrap;
2805- transition: box-shadow 0.15s;
2806-}
2807-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
2808-
2809-.lv-cta-secondary {
2810- padding: 13px 24px;
2811- border-radius: 11px;
2812- font-size: 15.5px;
2813- font-weight: 600;
2814- color: #16181d;
2815- border: 1px solid rgba(22,24,29,0.14);
2816- background: #ffffff;
2817- text-decoration: none;
2818- white-space: nowrap;
2819- transition: border-color 0.15s;
2820-}
2821-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
2822-
2823-.lv-hero-tag {
2824- margin-top: 18px;
2825- font-family: 'JetBrains Mono', monospace;
2826- font-size: 11.5px;
2827- letter-spacing: 0.08em;
2828- text-transform: uppercase;
2829- color: #8a8d99;
2830-}
2831-
2832-/* Demo window */
2833-.lv-demo-window {
2834- margin: 56px auto 0;
2835- max-width: 860px;
2836- text-align: left;
2837- background: #ffffff;
2838- border: 1px solid rgba(22,24,29,0.09);
2839- border-radius: 18px;
2840- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
2841- overflow: hidden;
2842-}
2843-
2844-.lv-demo-bar {
2845- display: flex;
2846- align-items: center;
2847- gap: 7px;
2848- padding: 12px 18px;
2849- border-bottom: 1px solid rgba(22,24,29,0.07);
2850- background: #fcfcfd;
2851-}
2852-
2853-.lv-demo-dot {
2854- width: 10px;
2855- height: 10px;
2856- border-radius: 50%;
2857- background: #e4e5ea;
2858-}
2859-
2860-.lv-demo-url {
2861- margin-left: 10px;
2862- font-family: 'JetBrains Mono', monospace;
2863- font-size: 12px;
2864- color: #6b7080;
2865-}
2866-
2867-.lv-demo-live {
2868- margin-left: auto;
2869- display: inline-flex;
2870- align-items: center;
2871- gap: 6px;
2872- font-size: 11px;
2873- font-weight: 600;
2874- color: #1e7f5c;
2875-}
2876-
2877-.lv-demo-body {
2878- padding: 22px 24px;
2879-}
2880-
2881-.lv-demo-event {
2882- display: grid;
2883- grid-template-columns: 18px minmax(0, 1fr);
2884- gap: 14px;
2885- padding-bottom: 20px;
2886- position: relative;
2887-}
2888-.lv-demo-event:last-child { padding-bottom: 0; }
2889-
2890-.lv-demo-event-track {
2891- display: flex;
2892- flex-direction: column;
2893- align-items: center;
2894-}
2895-
2896-.lv-demo-line {
2897- width: 1px;
2898- flex: 1;
2899- background: rgba(22,24,29,0.08);
2900- margin-top: 5px;
2901- min-height: 20px;
2902-}
2903-
2904-.lv-demo-event-content {}
2905-
2906-.lv-demo-event-header {
2907- display: flex;
2908- align-items: baseline;
2909- gap: 10px;
2910-}
2911-
2912-.lv-demo-event-title {
2913- font-size: 13.5px;
2914- font-weight: 600;
2915- color: #16181d;
2916-}
2917-
2918-.lv-demo-event-time {
2919- font-family: 'JetBrains Mono', monospace;
2920- font-size: 11px;
2921- color: #8a8d99;
2922-}
2923-
2924-.lv-demo-event-body {
2925- font-size: 13px;
2926- color: #6b7080;
2927- margin-top: 2px;
2928-}
2929-
2930-/* Ticker */
2931-.lv-ticker-wrap {
2932- border-top: 1px solid rgba(22,24,29,0.07);
2933- border-bottom: 1px solid rgba(22,24,29,0.07);
2934- background: #ffffff;
2935- margin-top: 64px;
2936- overflow: hidden;
2937- white-space: nowrap;
2938- position: relative;
2939-}
2940-
2941-.lv-ticker-track {
2942- display: inline-flex;
2943- animation: gcTicker 40s linear infinite;
2944- padding: 11px 0;
2945-}
2946-
2947-.lv-ticker-item {
2948- display: inline-flex;
2949- align-items: center;
2950- gap: 8px;
2951- font-family: 'JetBrains Mono', monospace;
2952- font-size: 11.5px;
2953- color: #6b7080;
2954- padding: 0 28px;
2955- border-right: 1px solid rgba(22,24,29,0.06);
2956-}
2957-
2958-/* Stats */
2959-.lv-stats {
2960- background: #fcfcfd;
2961-}
2962-
2963-.lv-stats-inner {
2964- max-width: 1200px;
2965- margin: 0 auto;
2966- display: grid;
2967- grid-template-columns: repeat(4, 1fr);
2968- gap: 24px;
2969- padding: 52px 28px;
2970-}
2971-
2972-.lv-stat {
2973- text-align: center;
2974-}
2975-
2976-.lv-stat-num {
2977- font-family: 'Inter Tight', sans-serif;
2978- font-weight: 700;
2979- font-size: clamp(30px, 4vw, 44px);
2980- letter-spacing: -0.025em;
2981- color: #111318;
2982-}
2983-
2984-.lv-stat-label {
2985- font-size: 13px;
2986- color: #6b7080;
2987- margin-top: 4px;
2988-}
2989-
2990-/* Loop */
2991-.lv-loop {
2992- padding: 96px 0;
2993- background: #ffffff;
2994- border-top: 1px solid rgba(22,24,29,0.07);
2995- border-bottom: 1px solid rgba(22,24,29,0.07);
2996-}
2997-
2998-.lv-loop-inner {
2999- max-width: 1200px;
3000- margin: 0 auto;
3001- padding: 0 28px;
3002-}
3003-
3004-.lv-stages {
3005- display: grid;
3006- grid-template-columns: repeat(6, 1fr);
3007- gap: 12px;
3008-}
3009-
3010-.lv-stage-card {
3011- border: 1px solid rgba(22,24,29,0.08);
3012- border-radius: 14px;
3013- background: #ffffff;
3014- padding: 20px 18px;
3015- transition: border-color 0.3s, background 0.3s;
3016-}
3017-
3018-.lv-stage-card.lv-stage-active {
3019- border-color: rgba(67,83,201,0.45);
3020- background: rgba(67,83,201,0.03);
3021-}
3022-
3023-.lv-stage-header {
3024- display: flex;
3025- align-items: center;
3026- gap: 8px;
3027- margin-bottom: 10px;
3028-}
3029-
3030-.lv-stage-n {
3031- font-family: 'JetBrains Mono', monospace;
3032- font-size: 10.5px;
3033- letter-spacing: 0.1em;
3034- text-transform: uppercase;
3035- color: #8a8d99;
3036-}
3037-
3038-.lv-stage-name {
3039- font-family: 'Inter Tight', sans-serif;
3040- font-size: 16px;
3041- font-weight: 600;
3042- letter-spacing: -0.01em;
3043- color: #16181d;
3044- margin-bottom: 5px;
3045-}
3046-
3047-.lv-stage-desc {
3048- font-size: 12px;
3049- color: #6b7080;
3050- line-height: 1.55;
3051-}
3052-
3053-.lv-stage-meta {
3054- font-family: 'JetBrains Mono', monospace;
3055- font-size: 10.5px;
3056- color: #8a8d99;
3057- margin-top: 10px;
3058- transition: color 0.3s;
3059-}
3060-
3061-.lv-stage-meta.lv-stage-meta-active {
3062- color: #4353c9;
3063-}
3064-
3065-/* Heroes */
3066-.lv-heroes {
3067- padding: 96px 0;
3068- background: #fcfcfd;
3069-}
3070-
3071-.lv-heroes-inner {
3072- max-width: 1200px;
3073- margin: 0 auto;
3074- padding: 0 28px;
3075-}
3076-
3077-.lv-heroes-header {
3078- max-width: 640px;
3079- margin-bottom: 56px;
3080-}
3081-
3082-.lv-heroes-list {
3083- display: flex;
3084- flex-direction: column;
3085- gap: 20px;
3086-}
3087-
3088-.lv-hero-card {
3089- display: grid;
3090- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
3091- gap: 48px;
3092- align-items: center;
3093- border: 1px solid rgba(22,24,29,0.08);
3094- border-radius: 20px;
3095- background: #ffffff;
3096- padding: 44px 48px;
3097- text-decoration: none;
3098- transition: border-color 0.2s, box-shadow 0.2s;
3099-}
3100-.lv-hero-card:hover {
3101- border-color: rgba(22,24,29,0.22);
3102- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
3103-}
3104-
3105-.lv-hero-card-left {}
3106-
3107-.lv-hero-card-title {
3108- font-family: 'Inter Tight', sans-serif;
3109- font-size: 26px;
3110- font-weight: 600;
3111- letter-spacing: -0.022em;
3112- line-height: 1.15;
3113- color: #16181d;
3114- margin: 0 0 12px;
3115-}
3116-
3117-.lv-hero-card-body {
3118- font-size: 14.5px;
3119- color: #6b7080;
3120- margin: 0 0 18px;
3121- line-height: 1.65;
3122-}
3123-
3124-.lv-hero-card-cta {
3125- font-size: 13.5px;
3126- font-weight: 600;
3127- color: #4353c9;
3128-}
3129-
3130-.lv-terminal {
3131- border: 1px solid rgba(22,24,29,0.07);
3132- border-radius: 14px;
3133- background: #fcfcfd;
3134- padding: 20px 22px;
3135- font-family: 'JetBrains Mono', monospace;
3136- font-size: 12px;
3137- line-height: 1.9;
3138- overflow: hidden;
3139-}
3140-
3141-.lv-terminal-line {
3142- display: flex;
3143- align-items: center;
3144- gap: 10px;
3145- white-space: nowrap;
3146- overflow: hidden;
3147- text-overflow: ellipsis;
3148-}
3149-
3150-/* Platform */
3151-.lv-platform {
3152- padding: 96px 0;
3153- background: #ffffff;
3154- border-top: 1px solid rgba(22,24,29,0.07);
3155-}
3156-
3157-.lv-platform-inner {
3158- max-width: 1200px;
3159- margin: 0 auto;
3160- padding: 0 28px;
3161-}
3162-
3163-.lv-cap-grid {
3164- display: grid;
3165- grid-template-columns: repeat(4, 1fr);
3166- gap: 24px 32px;
3167-}
3168-
3169-.lv-cap-col {}
3170-
3171-.lv-cap-group {
3172- font-family: 'JetBrains Mono', monospace;
3173- font-size: 10.5px;
3174- letter-spacing: 0.12em;
3175- text-transform: uppercase;
3176- color: #8a8d99;
3177- font-weight: 500;
3178- margin-bottom: 12px;
3179- padding-bottom: 8px;
3180- border-bottom: 1px solid rgba(22,24,29,0.07);
3181-}
3182-
3183-.lv-cap-items {
3184- display: flex;
3185- flex-direction: column;
3186- gap: 7px;
3187-}
3188-
3189-.lv-cap-item {
3190- font-size: 12.5px;
3191- color: #3a3d45;
3192- line-height: 1.45;
3193-}
3194-
3195-/* Sovereignty */
3196-.lv-sovereign {
3197- position: relative;
3198- overflow: hidden;
3199- padding: 104px 0;
3200- color: #fff;
3201- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
3202-}
3203-
3204-.lv-sovereign-grid-bg {
3205- position: absolute;
3206- inset: 0;
3207- opacity: 0.4;
3208- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
3209- background-size: 56px 56px;
3210- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
3211- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
3212-}
3213-
3214-.lv-sovereign-inner {
3215- position: relative;
3216- max-width: 1200px;
3217- margin: 0 auto;
3218- padding: 0 28px;
3219-}
3220-
3221-.lv-section-header-dark {
3222- max-width: 680px;
3223- margin: 0 auto 48px;
3224- text-align: center;
3225-}
3226-
3227-.lv-layers-grid {
3228- display: grid;
3229- grid-template-columns: repeat(4, 1fr);
3230- gap: 10px;
3231- max-width: 980px;
3232- margin: 0 auto;
3233-}
3234-
3235-.lv-layer-chip {
3236- border: 1px solid rgba(255,255,255,0.10);
3237- border-radius: 10px;
3238- padding: 12px 16px;
3239- background: rgba(255,255,255,0.03);
3240-}
3241-
3242-.lv-layer-cta {
3243- border-color: rgba(169,180,238,0.30);
3244- background: rgba(169,180,238,0.06);
3245- display: flex;
3246- align-items: center;
3247- text-decoration: none;
3248- transition: background 0.15s;
3249-}
3250-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
3251-
3252-.lv-layer-cta-text {
3253- font-size: 13px;
3254- font-weight: 500;
3255- color: #a9b4ee;
3256-}
3257-
3258-.lv-layer-n {
3259- font-family: 'JetBrains Mono', monospace;
3260- font-size: 10px;
3261- color: rgba(255,255,255,0.4);
3262- margin-bottom: 3px;
3263-}
3264-
3265-.lv-layer-name {
3266- font-size: 13px;
3267- font-weight: 500;
3268- color: rgba(255,255,255,0.92);
3269-}
3270-
3271-.lv-sovereign-feats {
3272- display: flex;
3273- gap: 44px;
3274- justify-content: center;
3275- flex-wrap: wrap;
3276- margin-top: 52px;
3277- text-align: center;
3278-}
3279-
3280-.lv-sovereign-feat {}
3281-
3282-.lv-sovereign-feat-title {
3283- font-family: 'Inter Tight', sans-serif;
3284- font-size: 20px;
3285- font-weight: 700;
3286- color: #fff;
3287-}
3288-
3289-.lv-sovereign-feat-sub {
3290- color: rgba(255,255,255,0.55);
3291- font-size: 13px;
3292- margin-top: 2px;
3293-}
3294-
3295-/* Twin cards */
3296-.lv-twin {
3297- padding: 96px 0;
3298- background: #fcfcfd;
3299-}
3300-
3301-.lv-twin-inner {
3302- max-width: 1200px;
3303- margin: 0 auto;
3304- padding: 0 28px;
3305- display: grid;
3306- grid-template-columns: 1fr 1fr;
3307- gap: 24px;
3308-}
3309-
3310-.lv-twin-card {
3311- border: 1px solid rgba(22,24,29,0.08);
3312- border-radius: 20px;
3313- background: #ffffff;
3314- padding: 44px 48px;
3315-}
3316-
3317-.lv-twin-title {
3318- font-family: 'Inter Tight', sans-serif;
3319- font-size: 24px;
3320- font-weight: 600;
3321- letter-spacing: -0.02em;
3322- line-height: 1.2;
3323- margin: 0 0 12px;
3324- color: #16181d;
3325-}
3326-
3327-.lv-twin-body {
3328- font-size: 14.5px;
3329- color: #6b7080;
3330- margin: 0 0 16px;
3331- line-height: 1.7;
3332-}
3333-
3334-.lv-twin-link {
3335- font-size: 13.5px;
3336- font-weight: 600;
3337- color: #4353c9;
3338- text-decoration: none;
3339-}
3340-.lv-twin-link:hover { text-decoration: underline; }
3341-
3342-/* Quote */
3343-.lv-quote {
3344- padding: 40px 0 96px;
3345- background: #fcfcfd;
3346-}
3347-
3348-.lv-quote-inner {
3349- max-width: 980px;
3350- margin: 0 auto;
3351- padding: 0 28px;
3352- text-align: center;
3353-}
3354-
3355-.lv-quote-text {
3356- font-family: 'Inter Tight', sans-serif;
3357- font-weight: 600;
3358- font-size: clamp(26px, 3.8vw, 42px);
3359- line-height: 1.2;
3360- letter-spacing: -0.025em;
3361- margin: 0;
3362- color: #111318;
3363-}
3364-
3365-.lv-em {
3366- font-style: normal;
3367- color: #4353c9;
3368-}
3369-
3370-/* CTA */
3371-.lv-cta-section {
3372- padding: 0 0 104px;
3373- background: #fcfcfd;
3374-}
3375-
3376-.lv-cta-card {
3377- max-width: 820px;
3378- margin: 0 auto;
3379- padding: 64px 40px;
3380- text-align: center;
3381- background: #ffffff;
3382- border: 1px solid rgba(22,24,29,0.08);
3383- border-radius: 26px;
3384- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
3385- position: relative;
3386- overflow: hidden;
3387-}
3388-
3389-.lv-cta-glow {
3390- position: absolute;
3391- inset: -40% 0 auto 0;
3392- height: 280px;
3393- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
3394- pointer-events: none;
3395-}
3396-
3397-.lv-cta-h2 {
3398- font-family: 'Inter Tight', sans-serif;
3399- font-weight: 700;
3400- letter-spacing: -0.028em;
3401- font-size: clamp(30px, 4.6vw, 48px);
3402- margin: 0;
3403- position: relative;
3404- color: #111318;
3405-}
3406-
3407-.lv-cta-sub {
3408- color: #6b7080;
3409- font-size: 17px;
3410- margin: 16px 0 30px;
3411- position: relative;
3412-}
3413-
3414-.lv-cta-actions {
3415- display: flex;
3416- gap: 12px;
3417- justify-content: center;
3418- flex-wrap: wrap;
3419- position: relative;
3420-}
3421-
3422-.lv-cta-fine {
3423- margin-top: 20px;
3424- font-family: 'JetBrains Mono', monospace;
3425- font-size: 11px;
3426- color: #8a8d99;
3427- position: relative;
3428-}
3429-
3430-/* Footer */
3431-.lv-footer {
3432- border-top: 1px solid rgba(22,24,29,0.07);
3433- background: #ffffff;
3434- padding: 56px 0 30px;
3435-}
3436-
3437-.lv-footer-inner {
3438- max-width: 1200px;
3439- margin: 0 auto;
3440- padding: 0 28px;
3441- display: flex;
3442- gap: 48px;
3443- flex-wrap: wrap;
3444- justify-content: space-between;
3445-}
3446-
3447-.lv-footer-brand {}
3448-
3449-.lv-footer-tagline {
3450- color: #6b7080;
3451- font-size: 13.5px;
3452- margin: 12px 0 0;
3453- max-width: 32ch;
3454- line-height: 1.6;
3455-}
3456-
3457-.lv-footer-cols {
3458- display: flex;
3459- gap: 64px;
3460- flex-wrap: wrap;
3461-}
3462-
3463-.lv-footer-col {
3464- display: flex;
3465- flex-direction: column;
3466- gap: 9px;
3467-}
3468-
3469-.lv-footer-col-head {
3470- font-family: 'JetBrains Mono', monospace;
3471- font-size: 11px;
3472- text-transform: uppercase;
3473- letter-spacing: 0.1em;
3474- color: #8a8d99;
3475- margin: 0 0 4px;
3476- font-weight: 500;
3477-}
3478-
3479-.lv-footer-link {
3480- color: #3a3d45;
3481- font-size: 13.5px;
3482- text-decoration: none;
3483- transition: color 0.15s;
3484-}
3485-.lv-footer-link:hover { color: #16181d; }
3486-
3487-.lv-footer-bar {
3488- max-width: 1200px;
3489- margin: 44px auto 0;
3490- padding: 22px 28px 0;
3491- border-top: 1px solid rgba(22,24,29,0.06);
3492- display: flex;
3493- justify-content: space-between;
3494- flex-wrap: wrap;
3495- gap: 8px;
3496- color: #8a8d99;
3497- font-size: 12.5px;
3498-}
3499-
3500-.lv-footer-stack {
3501- font-family: 'JetBrains Mono', monospace;
3502- font-size: 11px;
3503-}
3504-`;
3505diff --git a/src/views/layout.tsx b/src/views/layout.tsx
3506index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
3507--- a/src/views/layout.tsx
3508+++ b/src/views/layout.tsx
3509@@ -3153,9 +3153,12 @@
3510 font-weight: 500;
3511 line-height: 1.4;
3512 }
3513- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
3514- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
3515- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
3516+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
3517+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
3518+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
3519+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
3520+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
3521+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
3522 .state-merged { color: var(--accent); }
3523 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
3524
3525diff --git a/src/views/ui.tsx b/src/views/ui.tsx
3526index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
3527--- a/src/views/ui.tsx
3528+++ b/src/views/ui.tsx
3529@@ -232,7 +232,7 @@
3530
3531 export const Badge: FC<
3532 PropsWithChildren<{
3533- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
3534+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
3535 style?: string;
3536 }>
3537 > = ({ children, variant = "default", style }) => {
3538@@ -241,9 +241,12 @@
3539 variant === "closed" ? "badge-closed" :
3540 variant === "merged" ? "badge-merged" :
3541 variant === "success" ? "badge-success" :
3542- variant === "danger" ? "badge-danger" :
3543- variant === "warning" ? "badge-warning" :
3544- "badge";
3545+ variant === "danger" ? "badge-danger" :
3546+ variant === "warning" ? "badge-warning" :
3547+ variant === "live" ? "badge-live" :
3548+ variant === "soon" ? "badge-soon" :
3549+ variant === "preview" ? "badge-preview" :
3550+ "badge";
3551 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
3552 };
3553
3554
3555codex
3556The requested edits are now applied. I preserved the existing functional icon palette and violet token, and did not alter `landing.tsx`/`web.tsx` because the test imports make the conditional deletion
3557inapplicable. Next I m checking the exact diff, then running typecheck and the full Bun test suite.
3558exec
3559"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command "git diff -- src/views/landing-pro.tsx src/views/ui.tsx src/views/layout.tsx src/views/landing-v2.tsx src/views/landing.tsx
3560src/routes/web.tsx; rg -n --glob '"'!src/views/landing-v2.tsx'"' 'landing-v2' src; rg -n '#4353c9|#3848b6|--lp-violet|const ICONS|ICONS' src/views/landing-pro.tsx" in C:\Users\ccant\gluecron.com
3561 succeeded in 2295ms:
3562diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
3563index bc7c9ec..cdccec1 100644
3564--- a/src/views/landing-pro.tsx
3565+++ b/src/views/landing-pro.tsx
3566@@ -42,7 +42,7 @@ export function relTime(
3567
3568 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3569
3570-function icon(paths: string, color = "#4353c9", size = 20) {
3571+function icon(paths: string, color = "#0891b2", size = 20) {
3572 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
3573 }
3574
3575@@ -947,7 +947,7 @@ try{
3576 const css = `
3577 /* %% tokens %% */
3578 :root{
3579- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
3580+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
3581 --lp-bg:#ffffff;--lp-soft:#fafafb;
3582 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
3583 --lp-border:rgba(0,0,0,.08);
3584diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
3585deleted file mode 100644
3586index a446b27..0000000
3587--- a/src/views/landing-v2.tsx
3588+++ /dev/null
3589@@ -1,1447 +0,0 @@
3590-import type { FC } from "hono/jsx";
3591-
3592-export interface LandingPageProps {
3593- stats?: {
3594- publicRepos?: number;
3595- users?: number;
3596- };
3597-}
3598-
3599-const demoAllEvents = [
3600- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
3601- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
3602- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
3603- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
3604- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
3605-];
3606-
3607-const tickerItems = [
3608- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
3609- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
3610- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
3611- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
3612- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
3613- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
3614- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
3615- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
3616- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
3617- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
3618- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
3619- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
3620- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
3621- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
3622- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
3623- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
3624-];
3625-
3626-const stageData = [
3627- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
3628- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
3629- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
3630- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
3631- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
3632- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
3633-];
3634-
3635-const heroFeatures = [
3636- {
3637- href: "/",
3638- eyebrow: "01 � The autonomous repair loop",
3639- title: "Failures fix themselves  and show their work.",
3640- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
3641failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
3642- cta: "Watch a live repair session",
3643- mock: [
3644- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
3645- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
3646- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
3647- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
3648- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
3649- ],
3650- },
3651- {
3652- href: "/",
3653- eyebrow: "02 � Live sandbox isolation",
3654- title: "Every PR gets its own instant, disposable environment.",
3655- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
3656same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
3657- cta: "See a PR with its sandbox",
3658- mock: [
3659- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
3660- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
3661- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
3662- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
3663- ],
3664- },
3665- {
3666- href: "/",
3667- eyebrow: "03 � Multiplayer IDE workspaces",
3668- title: "You and the agent, side by side, in your editor.",
3669- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
3670agent into a silent reviewer in your gutter. The browser becomes optional.",
3671- cta: "See the editor session",
3672- mock: [
3673- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
3674- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
3675- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
3676- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
3677- ],
3678- },
3679-];
3680-
3681-const capabilities = [
3682- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
3683- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
3684- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
3685- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
3686- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
3687- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
3688- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
3689- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
3690-];
3691-
3692-const sovereignLayerNames = [
3693- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
3694- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
3695- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
3696- "Availability & recovery",
3697-];
3698-
3699-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
3700- return (
3701- <>
3702- <style dangerouslySetInnerHTML={{ __html: css }} />
3703-
3704- {/* Nav */}
3705- <header class="lv-nav">
3706- <div class="lv-nav-inner">
3707- <a href="/" class="lv-logo">
3708- <span class="lv-logo-mark"></span>gluecron
3709- </a>
3710- <nav class="lv-nav-links">
3711- <a href="#loop" class="lv-nav-link">The loop</a>
3712- <a href="#platform" class="lv-nav-link">Platform</a>
3713- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
3714- <a href="/trust" class="lv-nav-link">Trust</a>
3715- </nav>
3716- <div class="lv-nav-ctas">
3717- <a href="/login" class="lv-btn-secondary">Sign in</a>
3718- <a href="/register" class="lv-btn-primary">Start building</a>
3719- </div>
3720- </div>
3721- </header>
3722-
3723- {/* Hero */}
3724- <section class="lv-hero">
3725- <div class="lv-hero-glow"></div>
3726- <div class="lv-hero-inner">
3727- <div class="lv-hero-badge">
3728- <span class="lv-dot lv-dot-green lv-pulse"></span>
3729- Live: a repair loop converged on pr-218 while you read this
3730- </div>
3731- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
3732- <p class="lv-hero-sub">
3733- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
3734failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
3735- </p>
3736- <div class="lv-hero-actions">
3737- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
3738- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
3739- </div>
3740- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
3741-
3742- {/* Live product window */}
3743- <div class="lv-demo-window">
3744- <div class="lv-demo-bar">
3745- <span class="lv-demo-dot"></span>
3746- <span class="lv-demo-dot"></span>
3747- <span class="lv-demo-dot"></span>
3748- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
3749- <span class="lv-demo-live">
3750- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
3751- LIVE
3752- </span>
3753- </div>
3754- <div class="lv-demo-body" id="lv-demo-body">
3755- {/* Events rendered by JS */}
3756- {demoAllEvents.slice(0, 1).map((e, i) => (
3757- <div class="lv-demo-event" key={i}>
3758- <div class="lv-demo-event-track">
3759- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
3760- <span class="lv-demo-line" style="display:none"></span>
3761- </div>
3762- <div class="lv-demo-event-content">
3763- <div class="lv-demo-event-header">
3764- <span class="lv-demo-event-title">{e.title}</span>
3765- <span class="lv-demo-event-time">{e.time}</span>
3766- </div>
3767- <div class="lv-demo-event-body">{e.body}</div>
3768- </div>
3769- </div>
3770- ))}
3771- </div>
3772- </div>
3773- </div>
3774-
3775- {/* Activity ticker */}
3776- <div class="lv-ticker-wrap">
3777- <div class="lv-ticker-track">
3778- {tickerItems.map((t, i) => (
3779- <span class="lv-ticker-item" key={i}>
3780- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
3781- {t.text}
3782- </span>
3783- ))}
3784- </div>
3785- </div>
3786- </section>
3787-
3788- {/* Stat band */}
3789- <section class="lv-stats">
3790- <div class="lv-stats-inner">
3791- <div class="lv-stat">
3792- <div class="lv-stat-num">Sonnet 5</div>
3793- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
3794- </div>
3795- <div class="lv-stat">
3796- <div class="lv-stat-num">93.5%</div>
3797- <div class="lv-stat-label">of failures self-repair without a human</div>
3798- </div>
3799- <div class="lv-stat">
3800- <div class="lv-stat-num">1.9%</div>
3801- <div class="lv-stat-label">AI merges reverted  published live</div>
3802- </div>
3803- <div class="lv-stat">
3804- <div class="lv-stat-num">0</div>
3805- <div class="lv-stat-label">irreversible actions taken autonomously</div>
3806- </div>
3807- </div>
3808- </section>
3809-
3810- {/* The loop */}
3811- <section id="loop" class="lv-loop">
3812- <div class="lv-loop-inner">
3813- <div class="lv-section-header">
3814- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
3815- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
3816- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
3817- </div>
3818- <div class="lv-stages" id="lv-stages">
3819- {stageData.map((s, i) => (
3820- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
3821- <div class="lv-stage-header">
3822- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
3823- <span class="lv-stage-n">0{i + 1}</span>
3824- </div>
3825- <div class="lv-stage-name">{s.name}</div>
3826- <div class="lv-stage-desc">{s.desc}</div>
3827- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
3828- </div>
3829- ))}
3830- </div>
3831- </div>
3832- </section>
3833-
3834- {/* Three heroes */}
3835- <section class="lv-heroes">
3836- <div class="lv-heroes-inner">
3837- <div class="lv-heroes-header">
3838- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
3839- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
3840- </div>
3841- <div class="lv-heroes-list">
3842- {heroFeatures.map((h, i) => (
3843- <a href={h.href} class="lv-hero-card" key={i}>
3844- <div class="lv-hero-card-left">
3845- <div class="lv-eyebrow">{h.eyebrow}</div>
3846- <h3 class="lv-hero-card-title">{h.title}</h3>
3847- <p class="lv-hero-card-body">{h.body}</p>
3848- <span class="lv-hero-card-cta">{h.cta} �!</span>
3849- </div>
3850- <div class="lv-terminal">
3851- {h.mock.map((m, j) => (
3852- <div class="lv-terminal-line" key={j}>
3853- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
3854- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
3855- </div>
3856- ))}
3857- </div>
3858- </a>
3859- ))}
3860- </div>
3861- </div>
3862- </section>
3863-
3864- {/* Everything grid */}
3865- <section id="platform" class="lv-platform">
3866- <div class="lv-platform-inner">
3867- <div class="lv-section-header lv-section-header-center">
3868- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
3869- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
3870- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
3871- </div>
3872- <div class="lv-cap-grid">
3873- {capabilities.map((c, i) => (
3874- <div class="lv-cap-col" key={i}>
3875- <div class="lv-cap-group">{c.group}</div>
3876- <div class="lv-cap-items">
3877- {c.items.map((item, j) => (
3878- <div class="lv-cap-item" key={j}>{item}</div>
3879- ))}
3880- </div>
3881- </div>
3882- ))}
3883- </div>
3884- </div>
3885- </section>
3886-
3887- {/* Sovereignty band */}
3888- <section id="sovereign" class="lv-sovereign">
3889- <div class="lv-sovereign-grid-bg"></div>
3890- <div class="lv-sovereign-inner">
3891- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
3892- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
3893- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
3894- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
3895to private cloud, or run fully air-gapped on bare metal.</p>
3896- </div>
3897- <div class="lv-layers-grid">
3898- {sovereignLayerNames.map((name, i) => (
3899- <div class="lv-layer-chip" key={i}>
3900- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
3901- <div class="lv-layer-name">{name}</div>
3902- </div>
3903- ))}
3904- <a href="/" class="lv-layer-chip lv-layer-cta">
3905- <div class="lv-layer-cta-text">All self-owned �!</div>
3906- </a>
3907- </div>
3908- <div class="lv-sovereign-feats">
3909- <div class="lv-sovereign-feat">
3910- <div class="lv-sovereign-feat-title">Local inference first</div>
3911- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
3912- </div>
3913- <div class="lv-sovereign-feat">
3914- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
3915- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
3916- </div>
3917- <div class="lv-sovereign-feat">
3918- <div class="lv-sovereign-feat-title">Self-healing infra</div>
3919- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
3920- </div>
3921- </div>
3922- </div>
3923- </section>
3924-
3925- {/* Manual-first + reversibility */}
3926- <section class="lv-twin">
3927- <div class="lv-twin-inner">
3928- <div class="lv-twin-card">
3929- <div class="lv-eyebrow">Manual-first, always</div>
3930- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
3931- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
3932fallback. Developers who never touch AI get the best git host they've ever used.</p>
3933- </div>
3934- <div class="lv-twin-card">
3935- <div class="lv-eyebrow">The reversibility guarantee</div>
3936- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
3937- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
3938 policy, not promise. Our quality numbers are published live, unedited.</p>
3939- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
3940- </div>
3941- </div>
3942- </section>
3943-
3944- {/* Quote */}
3945- <section class="lv-quote">
3946- <div class="lv-quote-inner">
3947- <p class="lv-quote-text">
3948- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
3949- Gluecron is where code gets <em class="lv-em">finished</em>."
3950- </p>
3951- </div>
3952- </section>
3953-
3954- {/* CTA */}
3955- <section class="lv-cta-section">
3956- <div class="lv-cta-card">
3957- <div class="lv-cta-glow"></div>
3958- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
3959- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
3960- <div class="lv-cta-actions">
3961- <a href="/register" class="lv-cta-primary">Create your account �!</a>
3962- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
3963- </div>
3964- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
3965- </div>
3966- </section>
3967-
3968- {/* Footer */}
3969- <footer class="lv-footer">
3970- <div class="lv-footer-inner">
3971- <div class="lv-footer-brand">
3972- <a href="/" class="lv-logo">
3973- <span class="lv-logo-mark"></span>gluecron
3974- </a>
3975- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
3976- </div>
3977- <div class="lv-footer-cols">
3978- <div class="lv-footer-col">
3979- <h4 class="lv-footer-col-head">Product</h4>
3980- <a href="/" class="lv-footer-link">Agent workspace</a>
3981- <a href="/" class="lv-footer-link">Fleet refactors</a>
3982- <a href="/" class="lv-footer-link">Org memory</a>
3983- <a href="/" class="lv-footer-link">IDE extensions</a>
3984- </div>
3985- <div class="lv-footer-col">
3986- <h4 class="lv-footer-col-head">Platform</h4>
3987- <a href="/" class="lv-footer-link">Production layers</a>
3988- <a href="/trust" class="lv-footer-link">Trust report</a>
3989- <a href="/" class="lv-footer-link">Docs</a>
3990- <a href="/" class="lv-footer-link">Status</a>
3991- </div>
3992- <div class="lv-footer-col">
3993- <h4 class="lv-footer-col-head">Company</h4>
3994- <a href="/" class="lv-footer-link">About</a>
3995- <a href="/" class="lv-footer-link">Pricing</a>
3996- <a href="/" class="lv-footer-link">Enterprise</a>
3997- </div>
3998- </div>
3999- </div>
4000- <div class="lv-footer-bar">
4001- <span>� 2026 Gluecron</span>
4002- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
4003- </div>
4004- </footer>
4005-
4006- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
4007- </>
4008- );
4009-};
4010-
4011-export const LandingPage = LandingPageV2;
4012-export default LandingPageV2;
4013-
4014-const clientScript = `
4015-(function() {
4016- var demoAll = [
4017- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
4018- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
4019- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
4020- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
4021- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
4022- ];
4023-
4024- var demoStep = 0;
4025- var stage = 0;
4026-
4027- function renderDemo() {
4028- var container = document.getElementById('lv-demo-body');
4029- if (!container) return;
4030- var visible = demoAll.slice(0, demoStep + 1);
4031- container.innerHTML = visible.map(function(e, i) {
4032- var isLast = i === visible.length - 1;
4033- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
4034- return '<div class="lv-demo-event">' +
4035- '<div class="lv-demo-event-track">' +
4036- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
4037- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
4038- '</div>' +
4039- '<div class="lv-demo-event-content">' +
4040- '<div class="lv-demo-event-header">' +
4041- '<span class="lv-demo-event-title">' + e.title + '</span>' +
4042- '<span class="lv-demo-event-time">' + e.time + '</span>' +
4043- '</div>' +
4044- '<div class="lv-demo-event-body">' + e.body + '</div>' +
4045- '</div>' +
4046- '</div>';
4047- }).join('');
4048- }
4049-
4050- function renderStages() {
4051- var cards = document.querySelectorAll('.lv-stage-card');
4052- cards.forEach(function(card, i) {
4053- var dot = card.querySelector('.lv-dot');
4054- var meta = card.querySelector('.lv-stage-meta');
4055- if (i === stage) {
4056- card.classList.add('lv-stage-active');
4057- if (dot) {
4058- dot.classList.remove('lv-dot-idle');
4059- dot.classList.add('lv-dot-indigo', 'lv-pulse');
4060- }
4061- if (meta) meta.classList.add('lv-stage-meta-active');
4062- } else {
4063- card.classList.remove('lv-stage-active');
4064- if (dot) {
4065- dot.classList.add('lv-dot-idle');
4066- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
4067- }
4068- if (meta) meta.classList.remove('lv-stage-meta-active');
4069- }
4070- });
4071- }
4072-
4073- renderDemo();
4074-
4075- setInterval(function() {
4076- demoStep = (demoStep + 1) % 5;
4077- renderDemo();
4078- }, 3600);
4079-
4080- setInterval(function() {
4081- stage = (stage + 1) % 6;
4082- renderStages();
4083- }, 2200);
4084-})();
4085-`;
4086-
4087-const css = `
4088-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
4089-
4090-*, *::before, *::after { box-sizing: border-box; }
4091-
4092-body {
4093- margin: 0;
4094- background: #fcfcfd;
4095- -webkit-font-smoothing: antialiased;
4096- text-rendering: optimizeLegibility;
4097- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
4098- font-size: 15px;
4099- line-height: 1.6;
4100- letter-spacing: -0.008em;
4101- color: #16181d;
4102-}
4103-
4104-@keyframes gcPulse {
4105- 0%, 100% { opacity: 1; }
4106- 50% { opacity: 0.35; }
4107-}
4108-
4109-@keyframes gcTicker {
4110- 0% { transform: translateX(0); }
4111- 100% { transform: translateX(-50%); }
4112-}
4113-
4114-/* Shared utilities */
4115-.lv-dot {
4116- display: inline-block;
4117- border-radius: 50%;
4118-}
4119-.lv-dot-green { background: #1e7f5c; }
4120-.lv-dot-indigo { background: #4353c9; }
4121-.lv-dot-idle { background: #c4c6cf; }
4122-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
4123-
4124-.lv-strong { color: #16181d; font-weight: 600; }
4125-
4126-.lv-eyebrow {
4127- font-family: 'JetBrains Mono', monospace;
4128- font-size: 11px;
4129- letter-spacing: 0.12em;
4130- text-transform: uppercase;
4131- color: #8a8d99;
4132- font-weight: 500;
4133- margin-bottom: 12px;
4134-}
4135-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
4136-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
4137-
4138-.lv-h1 {
4139- font-family: 'Inter Tight', sans-serif;
4140- font-weight: 700;
4141- letter-spacing: -0.035em;
4142- font-size: clamp(44px, 7vw, 84px);
4143- line-height: 0.98;
4144- margin: 30px auto 0;
4145- max-width: 14ch;
4146- color: #111318;
4147-}
4148-
4149-.lv-h2 {
4150- font-family: 'Inter Tight', sans-serif;
4151- font-weight: 700;
4152- letter-spacing: -0.028em;
4153- font-size: clamp(30px, 4.4vw, 48px);
4154- line-height: 1.05;
4155- margin: 0;
4156- color: #111318;
4157-}
4158-
4159-.lv-h2-dark {
4160- font-family: 'Inter Tight', sans-serif;
4161- font-weight: 700;
4162- letter-spacing: -0.028em;
4163- font-size: clamp(30px, 4.6vw, 52px);
4164- line-height: 1.05;
4165- margin: 0;
4166- color: #fff;
4167-}
4168-
4169-.lv-section-header {
4170- max-width: 640px;
4171- margin: 0 auto 56px;
4172-}
4173-
4174-.lv-section-header-center {
4175- text-align: center;
4176-}
4177-
4178-.lv-section-sub {
4179- color: #6b7080;
4180- font-size: 17px;
4181- margin: 18px auto 0;
4182- max-width: 52ch;
4183-}
4184-
4185-.lv-section-sub-dark {
4186- color: rgba(255,255,255,0.72);
4187- font-size: 17px;
4188- margin: 18px auto 0;
4189- max-width: 56ch;
4190-}
4191-
4192-/* Nav */
4193-.lv-nav {
4194- position: sticky;
4195- top: 0;
4196- z-index: 60;
4197- backdrop-filter: saturate(180%) blur(14px);
4198- -webkit-backdrop-filter: saturate(180%) blur(14px);
4199- background: rgba(252,252,253,0.8);
4200- border-bottom: 1px solid rgba(22,24,29,0.07);
4201-}
4202-
4203-.lv-nav-inner {
4204- max-width: 1200px;
4205- margin: 0 auto;
4206- padding: 14px 28px;
4207- display: flex;
4208- align-items: center;
4209- gap: 28px;
4210-}
4211-
4212-.lv-logo {
4213- display: inline-flex;
4214- align-items: center;
4215- gap: 9px;
4216- font-family: 'Inter Tight', sans-serif;
4217- font-weight: 700;
4218- font-size: 17px;
4219- letter-spacing: -0.02em;
4220- color: #16181d;
4221- text-decoration: none;
4222-}
4223-
4224-.lv-logo-mark {
4225- width: 17px;
4226- height: 17px;
4227- border-radius: 5px;
4228- background: #4353c9;
4229- display: inline-block;
4230- flex-shrink: 0;
4231-}
4232-
4233-.lv-nav-links {
4234- display: flex;
4235- gap: 24px;
4236- font-size: 13.5px;
4237- font-weight: 500;
4238-}
4239-
4240-.lv-nav-link {
4241- color: #6b7080;
4242- text-decoration: none;
4243- transition: color 0.15s;
4244-}
4245-.lv-nav-link:hover { color: #16181d; }
4246-
4247-.lv-nav-ctas {
4248- margin-left: auto;
4249- display: flex;
4250- align-items: center;
4251- gap: 10px;
4252-}
4253-
4254-.lv-btn-secondary {
4255- padding: 8px 15px;
4256- border-radius: 8px;
4257- font-size: 13.5px;
4258- font-weight: 500;
4259- color: #16181d;
4260- border: 1px solid rgba(22,24,29,0.12);
4261- background: #ffffff;
4262- text-decoration: none;
4263- white-space: nowrap;
4264- transition: border-color 0.15s;
4265-}
4266-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
4267-
4268-.lv-btn-primary {
4269- padding: 8px 15px;
4270- border-radius: 8px;
4271- font-size: 13.5px;
4272- font-weight: 600;
4273- background: #16181d;
4274- color: #fff;
4275- text-decoration: none;
4276- white-space: nowrap;
4277- transition: box-shadow 0.15s;
4278-}
4279-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
4280-
4281-/* Hero */
4282-.lv-hero {
4283- position: relative;
4284- overflow: hidden;
4285- padding: 88px 0 0;
4286-}
4287-
4288-.lv-hero-glow {
4289- position: absolute;
4290- inset: -10% 0 auto 0;
4291- height: 640px;
4292- pointer-events: none;
4293- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
4294-}
4295-
4296-.lv-hero-inner {
4297- position: relative;
4298- max-width: 1200px;
4299- margin: 0 auto;
4300- padding: 0 28px;
4301- text-align: center;
4302-}
4303-
4304-.lv-hero-badge {
4305- display: inline-flex;
4306- align-items: center;
4307- gap: 9px;
4308- font-size: 12.5px;
4309- font-weight: 600;
4310- color: #3a3d45;
4311- background: #ffffff;
4312- border: 1px solid rgba(22,24,29,0.10);
4313- border-radius: 9999px;
4314- padding: 7px 16px;
4315- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
4316-}
4317-
4318-.lv-hero-sub {
4319- font-size: clamp(16px, 2vw, 19px);
4320- color: #6b7080;
4321- max-width: 60ch;
4322- margin: 24px auto 0;
4323- font-weight: 450;
4324- line-height: 1.65;
4325-}
4326-
4327-.lv-hero-actions {
4328- display: flex;
4329- gap: 12px;
4330- justify-content: center;
4331- flex-wrap: wrap;
4332- margin-top: 32px;
4333-}
4334-
4335-.lv-cta-primary {
4336- padding: 13px 24px;
4337- border-radius: 11px;
4338- font-size: 15.5px;
4339- font-weight: 600;
4340- background: #16181d;
4341- color: #fff;
4342- text-decoration: none;
4343- white-space: nowrap;
4344- transition: box-shadow 0.15s;
4345-}
4346-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
4347-
4348-.lv-cta-secondary {
4349- padding: 13px 24px;
4350- border-radius: 11px;
4351- font-size: 15.5px;
4352- font-weight: 600;
4353- color: #16181d;
4354- border: 1px solid rgba(22,24,29,0.14);
4355- background: #ffffff;
4356- text-decoration: none;
4357- white-space: nowrap;
4358- transition: border-color 0.15s;
4359-}
4360-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
4361-
4362-.lv-hero-tag {
4363- margin-top: 18px;
4364- font-family: 'JetBrains Mono', monospace;
4365- font-size: 11.5px;
4366- letter-spacing: 0.08em;
4367- text-transform: uppercase;
4368- color: #8a8d99;
4369-}
4370-
4371-/* Demo window */
4372-.lv-demo-window {
4373- margin: 56px auto 0;
4374- max-width: 860px;
4375- text-align: left;
4376- background: #ffffff;
4377- border: 1px solid rgba(22,24,29,0.09);
4378- border-radius: 18px;
4379- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
4380- overflow: hidden;
4381-}
4382-
4383-.lv-demo-bar {
4384- display: flex;
4385- align-items: center;
4386- gap: 7px;
4387- padding: 12px 18px;
4388- border-bottom: 1px solid rgba(22,24,29,0.07);
4389- background: #fcfcfd;
4390-}
4391-
4392-.lv-demo-dot {
4393- width: 10px;
4394- height: 10px;
4395- border-radius: 50%;
4396- background: #e4e5ea;
4397-}
4398-
4399-.lv-demo-url {
4400- margin-left: 10px;
4401- font-family: 'JetBrains Mono', monospace;
4402- font-size: 12px;
4403- color: #6b7080;
4404-}
4405-
4406-.lv-demo-live {
4407- margin-left: auto;
4408- display: inline-flex;
4409- align-items: center;
4410- gap: 6px;
4411- font-size: 11px;
4412- font-weight: 600;
4413- color: #1e7f5c;
4414-}
4415-
4416-.lv-demo-body {
4417- padding: 22px 24px;
4418-}
4419-
4420-.lv-demo-event {
4421- display: grid;
4422- grid-template-columns: 18px minmax(0, 1fr);
4423- gap: 14px;
4424- padding-bottom: 20px;
4425- position: relative;
4426-}
4427-.lv-demo-event:last-child { padding-bottom: 0; }
4428-
4429-.lv-demo-event-track {
4430- display: flex;
4431- flex-direction: column;
4432- align-items: center;
4433-}
4434-
4435-.lv-demo-line {
4436- width: 1px;
4437- flex: 1;
4438- background: rgba(22,24,29,0.08);
4439- margin-top: 5px;
4440- min-height: 20px;
4441-}
4442-
4443-.lv-demo-event-content {}
4444-
4445-.lv-demo-event-header {
4446- display: flex;
4447- align-items: baseline;
4448- gap: 10px;
4449-}
4450-
4451-.lv-demo-event-title {
4452- font-size: 13.5px;
4453- font-weight: 600;
4454- color: #16181d;
4455-}
4456-
4457-.lv-demo-event-time {
4458- font-family: 'JetBrains Mono', monospace;
4459- font-size: 11px;
4460- color: #8a8d99;
4461-}
4462-
4463-.lv-demo-event-body {
4464- font-size: 13px;
4465- color: #6b7080;
4466- margin-top: 2px;
4467-}
4468-
4469-/* Ticker */
4470-.lv-ticker-wrap {
4471- border-top: 1px solid rgba(22,24,29,0.07);
4472- border-bottom: 1px solid rgba(22,24,29,0.07);
4473- background: #ffffff;
4474- margin-top: 64px;
4475- overflow: hidden;
4476- white-space: nowrap;
4477- position: relative;
4478-}
4479-
4480-.lv-ticker-track {
4481- display: inline-flex;
4482- animation: gcTicker 40s linear infinite;
4483- padding: 11px 0;
4484-}
4485-
4486-.lv-ticker-item {
4487- display: inline-flex;
4488- align-items: center;
4489- gap: 8px;
4490- font-family: 'JetBrains Mono', monospace;
4491- font-size: 11.5px;
4492- color: #6b7080;
4493- padding: 0 28px;
4494- border-right: 1px solid rgba(22,24,29,0.06);
4495-}
4496-
4497-/* Stats */
4498-.lv-stats {
4499- background: #fcfcfd;
4500-}
4501-
4502-.lv-stats-inner {
4503- max-width: 1200px;
4504- margin: 0 auto;
4505- display: grid;
4506- grid-template-columns: repeat(4, 1fr);
4507- gap: 24px;
4508- padding: 52px 28px;
4509-}
4510-
4511-.lv-stat {
4512- text-align: center;
4513-}
4514-
4515-.lv-stat-num {
4516- font-family: 'Inter Tight', sans-serif;
4517- font-weight: 700;
4518- font-size: clamp(30px, 4vw, 44px);
4519- letter-spacing: -0.025em;
4520- color: #111318;
4521-}
4522-
4523-.lv-stat-label {
4524- font-size: 13px;
4525- color: #6b7080;
4526- margin-top: 4px;
4527-}
4528-
4529-/* Loop */
4530-.lv-loop {
4531- padding: 96px 0;
4532- background: #ffffff;
4533- border-top: 1px solid rgba(22,24,29,0.07);
4534- border-bottom: 1px solid rgba(22,24,29,0.07);
4535-}
4536-
4537-.lv-loop-inner {
4538- max-width: 1200px;
4539- margin: 0 auto;
4540- padding: 0 28px;
4541-}
4542-
4543-.lv-stages {
4544- display: grid;
4545- grid-template-columns: repeat(6, 1fr);
4546- gap: 12px;
4547-}
4548-
4549-.lv-stage-card {
4550- border: 1px solid rgba(22,24,29,0.08);
4551- border-radius: 14px;
4552- background: #ffffff;
4553- padding: 20px 18px;
4554- transition: border-color 0.3s, background 0.3s;
4555-}
4556-
4557-.lv-stage-card.lv-stage-active {
4558- border-color: rgba(67,83,201,0.45);
4559- background: rgba(67,83,201,0.03);
4560-}
4561-
4562-.lv-stage-header {
4563- display: flex;
4564- align-items: center;
4565- gap: 8px;
4566- margin-bottom: 10px;
4567-}
4568-
4569-.lv-stage-n {
4570- font-family: 'JetBrains Mono', monospace;
4571- font-size: 10.5px;
4572- letter-spacing: 0.1em;
4573- text-transform: uppercase;
4574- color: #8a8d99;
4575-}
4576-
4577-.lv-stage-name {
4578- font-family: 'Inter Tight', sans-serif;
4579- font-size: 16px;
4580- font-weight: 600;
4581- letter-spacing: -0.01em;
4582- color: #16181d;
4583- margin-bottom: 5px;
4584-}
4585-
4586-.lv-stage-desc {
4587- font-size: 12px;
4588- color: #6b7080;
4589- line-height: 1.55;
4590-}
4591-
4592-.lv-stage-meta {
4593- font-family: 'JetBrains Mono', monospace;
4594- font-size: 10.5px;
4595- color: #8a8d99;
4596- margin-top: 10px;
4597- transition: color 0.3s;
4598-}
4599-
4600-.lv-stage-meta.lv-stage-meta-active {
4601- color: #4353c9;
4602-}
4603-
4604-/* Heroes */
4605-.lv-heroes {
4606- padding: 96px 0;
4607- background: #fcfcfd;
4608-}
4609-
4610-.lv-heroes-inner {
4611- max-width: 1200px;
4612- margin: 0 auto;
4613- padding: 0 28px;
4614-}
4615-
4616-.lv-heroes-header {
4617- max-width: 640px;
4618- margin-bottom: 56px;
4619-}
4620-
4621-.lv-heroes-list {
4622- display: flex;
4623- flex-direction: column;
4624- gap: 20px;
4625-}
4626-
4627-.lv-hero-card {
4628- display: grid;
4629- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
4630- gap: 48px;
4631- align-items: center;
4632- border: 1px solid rgba(22,24,29,0.08);
4633- border-radius: 20px;
4634- background: #ffffff;
4635- padding: 44px 48px;
4636- text-decoration: none;
4637- transition: border-color 0.2s, box-shadow 0.2s;
4638-}
4639-.lv-hero-card:hover {
4640- border-color: rgba(22,24,29,0.22);
4641- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
4642-}
4643-
4644-.lv-hero-card-left {}
4645-
4646-.lv-hero-card-title {
4647- font-family: 'Inter Tight', sans-serif;
4648- font-size: 26px;
4649- font-weight: 600;
4650- letter-spacing: -0.022em;
4651- line-height: 1.15;
4652- color: #16181d;
4653- margin: 0 0 12px;
4654-}
4655-
4656-.lv-hero-card-body {
4657- font-size: 14.5px;
4658- color: #6b7080;
4659- margin: 0 0 18px;
4660- line-height: 1.65;
4661-}
4662-
4663-.lv-hero-card-cta {
4664- font-size: 13.5px;
4665- font-weight: 600;
4666- color: #4353c9;
4667-}
4668-
4669-.lv-terminal {
4670- border: 1px solid rgba(22,24,29,0.07);
4671- border-radius: 14px;
4672- background: #fcfcfd;
4673- padding: 20px 22px;
4674- font-family: 'JetBrains Mono', monospace;
4675- font-size: 12px;
4676- line-height: 1.9;
4677- overflow: hidden;
4678-}
4679-
4680-.lv-terminal-line {
4681- display: flex;
4682- align-items: center;
4683- gap: 10px;
4684- white-space: nowrap;
4685- overflow: hidden;
4686- text-overflow: ellipsis;
4687-}
4688-
4689-/* Platform */
4690-.lv-platform {
4691- padding: 96px 0;
4692- background: #ffffff;
4693- border-top: 1px solid rgba(22,24,29,0.07);
4694-}
4695-
4696-.lv-platform-inner {
4697- max-width: 1200px;
4698- margin: 0 auto;
4699- padding: 0 28px;
4700-}
4701-
4702-.lv-cap-grid {
4703- display: grid;
4704- grid-template-columns: repeat(4, 1fr);
4705- gap: 24px 32px;
4706-}
4707-
4708-.lv-cap-col {}
4709-
4710-.lv-cap-group {
4711- font-family: 'JetBrains Mono', monospace;
4712- font-size: 10.5px;
4713- letter-spacing: 0.12em;
4714- text-transform: uppercase;
4715- color: #8a8d99;
4716- font-weight: 500;
4717- margin-bottom: 12px;
4718- padding-bottom: 8px;
4719- border-bottom: 1px solid rgba(22,24,29,0.07);
4720-}
4721-
4722-.lv-cap-items {
4723- display: flex;
4724- flex-direction: column;
4725- gap: 7px;
4726-}
4727-
4728-.lv-cap-item {
4729- font-size: 12.5px;
4730- color: #3a3d45;
4731- line-height: 1.45;
4732-}
4733-
4734-/* Sovereignty */
4735-.lv-sovereign {
4736- position: relative;
4737- overflow: hidden;
4738- padding: 104px 0;
4739- color: #fff;
4740- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
4741-}
4742-
4743-.lv-sovereign-grid-bg {
4744- position: absolute;
4745- inset: 0;
4746- opacity: 0.4;
4747- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
4748- background-size: 56px 56px;
4749- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
4750- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
4751-}
4752-
4753-.lv-sovereign-inner {
4754- position: relative;
4755- max-width: 1200px;
4756- margin: 0 auto;
4757- padding: 0 28px;
4758-}
4759-
4760-.lv-section-header-dark {
4761- max-width: 680px;
4762- margin: 0 auto 48px;
4763- text-align: center;
4764-}
4765-
4766-.lv-layers-grid {
4767- display: grid;
4768- grid-template-columns: repeat(4, 1fr);
4769- gap: 10px;
4770- max-width: 980px;
4771- margin: 0 auto;
4772-}
4773-
4774-.lv-layer-chip {
4775- border: 1px solid rgba(255,255,255,0.10);
4776- border-radius: 10px;
4777- padding: 12px 16px;
4778- background: rgba(255,255,255,0.03);
4779-}
4780-
4781-.lv-layer-cta {
4782- border-color: rgba(169,180,238,0.30);
4783- background: rgba(169,180,238,0.06);
4784- display: flex;
4785- align-items: center;
4786- text-decoration: none;
4787- transition: background 0.15s;
4788-}
4789-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
4790-
4791-.lv-layer-cta-text {
4792- font-size: 13px;
4793- font-weight: 500;
4794- color: #a9b4ee;
4795-}
4796-
4797-.lv-layer-n {
4798- font-family: 'JetBrains Mono', monospace;
4799- font-size: 10px;
4800- color: rgba(255,255,255,0.4);
4801- margin-bottom: 3px;
4802-}
4803-
4804-.lv-layer-name {
4805- font-size: 13px;
4806- font-weight: 500;
4807- color: rgba(255,255,255,0.92);
4808-}
4809-
4810-.lv-sovereign-feats {
4811- display: flex;
4812- gap: 44px;
4813- justify-content: center;
4814- flex-wrap: wrap;
4815- margin-top: 52px;
4816- text-align: center;
4817-}
4818-
4819-.lv-sovereign-feat {}
4820-
4821-.lv-sovereign-feat-title {
4822- font-family: 'Inter Tight', sans-serif;
4823- font-size: 20px;
4824- font-weight: 700;
4825- color: #fff;
4826-}
4827-
4828-.lv-sovereign-feat-sub {
4829- color: rgba(255,255,255,0.55);
4830- font-size: 13px;
4831- margin-top: 2px;
4832-}
4833-
4834-/* Twin cards */
4835-.lv-twin {
4836- padding: 96px 0;
4837- background: #fcfcfd;
4838-}
4839-
4840-.lv-twin-inner {
4841- max-width: 1200px;
4842- margin: 0 auto;
4843- padding: 0 28px;
4844- display: grid;
4845- grid-template-columns: 1fr 1fr;
4846- gap: 24px;
4847-}
4848-
4849-.lv-twin-card {
4850- border: 1px solid rgba(22,24,29,0.08);
4851- border-radius: 20px;
4852- background: #ffffff;
4853- padding: 44px 48px;
4854-}
4855-
4856-.lv-twin-title {
4857- font-family: 'Inter Tight', sans-serif;
4858- font-size: 24px;
4859- font-weight: 600;
4860- letter-spacing: -0.02em;
4861- line-height: 1.2;
4862- margin: 0 0 12px;
4863- color: #16181d;
4864-}
4865-
4866-.lv-twin-body {
4867- font-size: 14.5px;
4868- color: #6b7080;
4869- margin: 0 0 16px;
4870- line-height: 1.7;
4871-}
4872-
4873-.lv-twin-link {
4874- font-size: 13.5px;
4875- font-weight: 600;
4876- color: #4353c9;
4877- text-decoration: none;
4878-}
4879-.lv-twin-link:hover { text-decoration: underline; }
4880-
4881-/* Quote */
4882-.lv-quote {
4883- padding: 40px 0 96px;
4884- background: #fcfcfd;
4885-}
4886-
4887-.lv-quote-inner {
4888- max-width: 980px;
4889- margin: 0 auto;
4890- padding: 0 28px;
4891- text-align: center;
4892-}
4893-
4894-.lv-quote-text {
4895- font-family: 'Inter Tight', sans-serif;
4896- font-weight: 600;
4897- font-size: clamp(26px, 3.8vw, 42px);
4898- line-height: 1.2;
4899- letter-spacing: -0.025em;
4900- margin: 0;
4901- color: #111318;
4902-}
4903-
4904-.lv-em {
4905- font-style: normal;
4906- color: #4353c9;
4907-}
4908-
4909-/* CTA */
4910-.lv-cta-section {
4911- padding: 0 0 104px;
4912- background: #fcfcfd;
4913-}
4914-
4915-.lv-cta-card {
4916- max-width: 820px;
4917- margin: 0 auto;
4918- padding: 64px 40px;
4919- text-align: center;
4920- background: #ffffff;
4921- border: 1px solid rgba(22,24,29,0.08);
4922- border-radius: 26px;
4923- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
4924- position: relative;
4925- overflow: hidden;
4926-}
4927-
4928-.lv-cta-glow {
4929- position: absolute;
4930- inset: -40% 0 auto 0;
4931- height: 280px;
4932- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
4933- pointer-events: none;
4934-}
4935-
4936-.lv-cta-h2 {
4937- font-family: 'Inter Tight', sans-serif;
4938- font-weight: 700;
4939- letter-spacing: -0.028em;
4940- font-size: clamp(30px, 4.6vw, 48px);
4941- margin: 0;
4942- position: relative;
4943- color: #111318;
4944-}
4945-
4946-.lv-cta-sub {
4947- color: #6b7080;
4948- font-size: 17px;
4949- margin: 16px 0 30px;
4950- position: relative;
4951-}
4952-
4953-.lv-cta-actions {
4954- display: flex;
4955- gap: 12px;
4956- justify-content: center;
4957- flex-wrap: wrap;
4958- position: relative;
4959-}
4960-
4961-.lv-cta-fine {
4962- margin-top: 20px;
4963- font-family: 'JetBrains Mono', monospace;
4964- font-size: 11px;
4965- color: #8a8d99;
4966- position: relative;
4967-}
4968-
4969-/* Footer */
4970-.lv-footer {
4971- border-top: 1px solid rgba(22,24,29,0.07);
4972- background: #ffffff;
4973- padding: 56px 0 30px;
4974-}
4975-
4976-.lv-footer-inner {
4977- max-width: 1200px;
4978- margin: 0 auto;
4979- padding: 0 28px;
4980- display: flex;
4981- gap: 48px;
4982- flex-wrap: wrap;
4983- justify-content: space-between;
4984-}
4985-
4986-.lv-footer-brand {}
4987-
4988-.lv-footer-tagline {
4989- color: #6b7080;
4990- font-size: 13.5px;
4991- margin: 12px 0 0;
4992- max-width: 32ch;
4993- line-height: 1.6;
4994-}
4995-
4996-.lv-footer-cols {
4997- display: flex;
4998- gap: 64px;
4999- flex-wrap: wrap;
5000-}
5001-
5002-.lv-footer-col {
5003- display: flex;
5004- flex-direction: column;
5005- gap: 9px;
5006-}
5007-
5008-.lv-footer-col-head {
5009- font-family: 'JetBrains Mono', monospace;
5010- font-size: 11px;
5011- text-transform: uppercase;
5012- letter-spacing: 0.1em;
5013- color: #8a8d99;
5014- margin: 0 0 4px;
5015- font-weight: 500;
5016-}
5017-
5018-.lv-footer-link {
5019- color: #3a3d45;
5020- font-size: 13.5px;
5021- text-decoration: none;
5022- transition: color 0.15s;
5023-}
5024-.lv-footer-link:hover { color: #16181d; }
5025-
5026-.lv-footer-bar {
5027- max-width: 1200px;
5028- margin: 44px auto 0;
5029- padding: 22px 28px 0;
5030- border-top: 1px solid rgba(22,24,29,0.06);
5031- display: flex;
5032- justify-content: space-between;
5033- flex-wrap: wrap;
5034- gap: 8px;
5035- color: #8a8d99;
5036- font-size: 12.5px;
5037-}
5038-
5039-.lv-footer-stack {
5040- font-family: 'JetBrains Mono', monospace;
5041- font-size: 11px;
5042-}
5043-`;
5044diff --git a/src/views/layout.tsx b/src/views/layout.tsx
5045index c9fe4b7..0b49397 100644
5046--- a/src/views/layout.tsx
5047+++ b/src/views/layout.tsx
5048@@ -3156,6 +3156,9 @@ const css = `
5049 .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
5050 .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
5051 .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
5052+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
5053+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
5054+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
5055 .state-merged { color: var(--accent); }
5056 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
5057
5058diff --git a/src/views/ui.tsx b/src/views/ui.tsx
5059index 6885c64..9361812 100644
5060--- a/src/views/ui.tsx
5061+++ b/src/views/ui.tsx
5062@@ -232,7 +232,7 @@ export const EmptyState: FC<
5063
5064 export const Badge: FC<
5065 PropsWithChildren<{
5066- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
5067+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
5068 style?: string;
5069 }>
5070 > = ({ children, variant = "default", style }) => {
5071@@ -243,6 +243,9 @@ export const Badge: FC<
5072 variant === "success" ? "badge-success" :
5073 variant === "danger" ? "badge-danger" :
5074 variant === "warning" ? "badge-warning" :
5075+ variant === "live" ? "badge-live" :
5076+ variant === "soon" ? "badge-soon" :
5077+ variant === "preview" ? "badge-preview" :
5078 "badge";
5079 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
5080 };
508149:const ICONS: Record<string, string> = {
5082373: <PlatformGroup icon={ICONS.code} iconColor="#4353c9" title="Code hosting">
5083376: <PlatformGroup icon={ICONS.team} iconColor="#0d9488" title="Collaboration">
5084379: <PlatformGroup icon={ICONS.ai} iconColor="#7c3aed" title="AI suite">
5085382: <PlatformGroup icon={ICONS.shield} iconColor="#059669" title="Security">
5086385: <PlatformGroup icon={ICONS.workflow} iconColor="#b45309" title="CI / CD">
5087388: <PlatformGroup icon={ICONS.grid} iconColor="#475569" title="Platform">
5088391: <PlatformGroup icon={ICONS.chart} iconColor="#0891b2" title="Observability">
5089394: <PlatformGroup icon={ICONS.link} iconColor="#dc2626" title="Integrations">
5090956: --lp-green:#059669;--lp-red:#dc2626;--lp-violet:#7c3aed;--lp-amber:#b45309;
50911006:.lp-badge-ai{color:var(--lp-violet);background:rgba(124,58,237,.1)}
50921119:.lp-feed-kind-ai_review-posted{color:var(--lp-violet);background:rgba(124,58,237,.09)}
5093warning: in the working copy of 'src/views/landing-pro.tsx', LF will be replaced by CRLF the next time Git touches it
5094warning: in the working copy of 'src/views/layout.tsx', LF will be replaced by CRLF the next time Git touches it
5095warning: in the working copy of 'src/views/ui.tsx', LF will be replaced by CRLF the next time Git touches it
5096
5097diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
5098index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
5099--- a/src/views/landing-pro.tsx
5100+++ b/src/views/landing-pro.tsx
5101@@ -42,7 +42,7 @@
5102
5103 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5104
5105-function icon(paths: string, color = "#4353c9", size = 20) {
5106+function icon(paths: string, color = "#0891b2", size = 20) {
5107 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
5108 }
5109
5110@@ -947,7 +947,7 @@
5111 const css = `
5112 /* %% tokens %% */
5113 :root{
5114- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
5115+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
5116 --lp-bg:#ffffff;--lp-soft:#fafafb;
5117 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
5118 --lp-border:rgba(0,0,0,.08);
5119diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
5120deleted file mode 100644
5121index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
5122--- a/src/views/landing-v2.tsx
5123+++ /dev/null
5124@@ -1,1447 +0,0 @@
5125-import type { FC } from "hono/jsx";
5126-
5127-export interface LandingPageProps {
5128- stats?: {
5129- publicRepos?: number;
5130- users?: number;
5131- };
5132-}
5133-
5134-const demoAllEvents = [
5135- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
5136- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
5137- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
5138- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
5139- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
5140-];
5141-
5142-const tickerItems = [
5143- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
5144- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
5145- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
5146- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
5147- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
5148- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
5149- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
5150- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
5151- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
5152- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
5153- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
5154- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
5155- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
5156- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
5157- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
5158- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
5159-];
5160-
5161-const stageData = [
5162- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
5163- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
5164- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
5165- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
5166- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
5167- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
5168-];
5169-
5170-const heroFeatures = [
5171- {
5172- href: "/",
5173- eyebrow: "01 � The autonomous repair loop",
5174- title: "Failures fix themselves  and show their work.",
5175- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
5176failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
5177- cta: "Watch a live repair session",
5178- mock: [
5179- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
5180- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
5181- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
5182- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
5183- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
5184- ],
5185- },
5186- {
5187- href: "/",
5188- eyebrow: "02 � Live sandbox isolation",
5189- title: "Every PR gets its own instant, disposable environment.",
5190- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
5191same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
5192- cta: "See a PR with its sandbox",
5193- mock: [
5194- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
5195- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
5196- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
5197- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
5198- ],
5199- },
5200- {
5201- href: "/",
5202- eyebrow: "03 � Multiplayer IDE workspaces",
5203- title: "You and the agent, side by side, in your editor.",
5204- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
5205agent into a silent reviewer in your gutter. The browser becomes optional.",
5206- cta: "See the editor session",
5207- mock: [
5208- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
5209- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
5210- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
5211- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
5212- ],
5213- },
5214-];
5215-
5216-const capabilities = [
5217- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
5218- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
5219- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
5220- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
5221- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
5222- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
5223- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
5224- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
5225-];
5226-
5227-const sovereignLayerNames = [
5228- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
5229- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
5230- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
5231- "Availability & recovery",
5232-];
5233-
5234-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
5235- return (
5236- <>
5237- <style dangerouslySetInnerHTML={{ __html: css }} />
5238-
5239- {/* Nav */}
5240- <header class="lv-nav">
5241- <div class="lv-nav-inner">
5242- <a href="/" class="lv-logo">
5243- <span class="lv-logo-mark"></span>gluecron
5244- </a>
5245- <nav class="lv-nav-links">
5246- <a href="#loop" class="lv-nav-link">The loop</a>
5247- <a href="#platform" class="lv-nav-link">Platform</a>
5248- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
5249- <a href="/trust" class="lv-nav-link">Trust</a>
5250- </nav>
5251- <div class="lv-nav-ctas">
5252- <a href="/login" class="lv-btn-secondary">Sign in</a>
5253- <a href="/register" class="lv-btn-primary">Start building</a>
5254- </div>
5255- </div>
5256- </header>
5257-
5258- {/* Hero */}
5259- <section class="lv-hero">
5260- <div class="lv-hero-glow"></div>
5261- <div class="lv-hero-inner">
5262- <div class="lv-hero-badge">
5263- <span class="lv-dot lv-dot-green lv-pulse"></span>
5264- Live: a repair loop converged on pr-218 while you read this
5265- </div>
5266- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
5267- <p class="lv-hero-sub">
5268- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
5269failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
5270- </p>
5271- <div class="lv-hero-actions">
5272- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
5273- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
5274- </div>
5275- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
5276-
5277- {/* Live product window */}
5278- <div class="lv-demo-window">
5279- <div class="lv-demo-bar">
5280- <span class="lv-demo-dot"></span>
5281- <span class="lv-demo-dot"></span>
5282- <span class="lv-demo-dot"></span>
5283- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
5284- <span class="lv-demo-live">
5285- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
5286- LIVE
5287- </span>
5288- </div>
5289- <div class="lv-demo-body" id="lv-demo-body">
5290- {/* Events rendered by JS */}
5291- {demoAllEvents.slice(0, 1).map((e, i) => (
5292- <div class="lv-demo-event" key={i}>
5293- <div class="lv-demo-event-track">
5294- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
5295- <span class="lv-demo-line" style="display:none"></span>
5296- </div>
5297- <div class="lv-demo-event-content">
5298- <div class="lv-demo-event-header">
5299- <span class="lv-demo-event-title">{e.title}</span>
5300- <span class="lv-demo-event-time">{e.time}</span>
5301- </div>
5302- <div class="lv-demo-event-body">{e.body}</div>
5303- </div>
5304- </div>
5305- ))}
5306- </div>
5307- </div>
5308- </div>
5309-
5310- {/* Activity ticker */}
5311- <div class="lv-ticker-wrap">
5312- <div class="lv-ticker-track">
5313- {tickerItems.map((t, i) => (
5314- <span class="lv-ticker-item" key={i}>
5315- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
5316- {t.text}
5317- </span>
5318- ))}
5319- </div>
5320- </div>
5321- </section>
5322-
5323- {/* Stat band */}
5324- <section class="lv-stats">
5325- <div class="lv-stats-inner">
5326- <div class="lv-stat">
5327- <div class="lv-stat-num">Sonnet 5</div>
5328- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
5329- </div>
5330- <div class="lv-stat">
5331- <div class="lv-stat-num">93.5%</div>
5332- <div class="lv-stat-label">of failures self-repair without a human</div>
5333- </div>
5334- <div class="lv-stat">
5335- <div class="lv-stat-num">1.9%</div>
5336- <div class="lv-stat-label">AI merges reverted  published live</div>
5337- </div>
5338- <div class="lv-stat">
5339- <div class="lv-stat-num">0</div>
5340- <div class="lv-stat-label">irreversible actions taken autonomously</div>
5341- </div>
5342- </div>
5343- </section>
5344-
5345- {/* The loop */}
5346- <section id="loop" class="lv-loop">
5347- <div class="lv-loop-inner">
5348- <div class="lv-section-header">
5349- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
5350- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
5351- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
5352- </div>
5353- <div class="lv-stages" id="lv-stages">
5354- {stageData.map((s, i) => (
5355- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
5356- <div class="lv-stage-header">
5357- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
5358- <span class="lv-stage-n">0{i + 1}</span>
5359- </div>
5360- <div class="lv-stage-name">{s.name}</div>
5361- <div class="lv-stage-desc">{s.desc}</div>
5362- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
5363- </div>
5364- ))}
5365- </div>
5366- </div>
5367- </section>
5368-
5369- {/* Three heroes */}
5370- <section class="lv-heroes">
5371- <div class="lv-heroes-inner">
5372- <div class="lv-heroes-header">
5373- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
5374- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
5375- </div>
5376- <div class="lv-heroes-list">
5377- {heroFeatures.map((h, i) => (
5378- <a href={h.href} class="lv-hero-card" key={i}>
5379- <div class="lv-hero-card-left">
5380- <div class="lv-eyebrow">{h.eyebrow}</div>
5381- <h3 class="lv-hero-card-title">{h.title}</h3>
5382- <p class="lv-hero-card-body">{h.body}</p>
5383- <span class="lv-hero-card-cta">{h.cta} �!</span>
5384- </div>
5385- <div class="lv-terminal">
5386- {h.mock.map((m, j) => (
5387- <div class="lv-terminal-line" key={j}>
5388- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
5389- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
5390- </div>
5391- ))}
5392- </div>
5393- </a>
5394- ))}
5395- </div>
5396- </div>
5397- </section>
5398-
5399- {/* Everything grid */}
5400- <section id="platform" class="lv-platform">
5401- <div class="lv-platform-inner">
5402- <div class="lv-section-header lv-section-header-center">
5403- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
5404- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
5405- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
5406- </div>
5407- <div class="lv-cap-grid">
5408- {capabilities.map((c, i) => (
5409- <div class="lv-cap-col" key={i}>
5410- <div class="lv-cap-group">{c.group}</div>
5411- <div class="lv-cap-items">
5412- {c.items.map((item, j) => (
5413- <div class="lv-cap-item" key={j}>{item}</div>
5414- ))}
5415- </div>
5416- </div>
5417- ))}
5418- </div>
5419- </div>
5420- </section>
5421-
5422- {/* Sovereignty band */}
5423- <section id="sovereign" class="lv-sovereign">
5424- <div class="lv-sovereign-grid-bg"></div>
5425- <div class="lv-sovereign-inner">
5426- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
5427- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
5428- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
5429- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
5430to private cloud, or run fully air-gapped on bare metal.</p>
5431- </div>
5432- <div class="lv-layers-grid">
5433- {sovereignLayerNames.map((name, i) => (
5434- <div class="lv-layer-chip" key={i}>
5435- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
5436- <div class="lv-layer-name">{name}</div>
5437- </div>
5438- ))}
5439- <a href="/" class="lv-layer-chip lv-layer-cta">
5440- <div class="lv-layer-cta-text">All self-owned �!</div>
5441- </a>
5442- </div>
5443- <div class="lv-sovereign-feats">
5444- <div class="lv-sovereign-feat">
5445- <div class="lv-sovereign-feat-title">Local inference first</div>
5446- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
5447- </div>
5448- <div class="lv-sovereign-feat">
5449- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
5450- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
5451- </div>
5452- <div class="lv-sovereign-feat">
5453- <div class="lv-sovereign-feat-title">Self-healing infra</div>
5454- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
5455- </div>
5456- </div>
5457- </div>
5458- </section>
5459-
5460- {/* Manual-first + reversibility */}
5461- <section class="lv-twin">
5462- <div class="lv-twin-inner">
5463- <div class="lv-twin-card">
5464- <div class="lv-eyebrow">Manual-first, always</div>
5465- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
5466- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
5467fallback. Developers who never touch AI get the best git host they've ever used.</p>
5468- </div>
5469- <div class="lv-twin-card">
5470- <div class="lv-eyebrow">The reversibility guarantee</div>
5471- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
5472- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
5473 policy, not promise. Our quality numbers are published live, unedited.</p>
5474- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
5475- </div>
5476- </div>
5477- </section>
5478-
5479- {/* Quote */}
5480- <section class="lv-quote">
5481- <div class="lv-quote-inner">
5482- <p class="lv-quote-text">
5483- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
5484- Gluecron is where code gets <em class="lv-em">finished</em>."
5485- </p>
5486- </div>
5487- </section>
5488-
5489- {/* CTA */}
5490- <section class="lv-cta-section">
5491- <div class="lv-cta-card">
5492- <div class="lv-cta-glow"></div>
5493- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
5494- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
5495- <div class="lv-cta-actions">
5496- <a href="/register" class="lv-cta-primary">Create your account �!</a>
5497- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
5498- </div>
5499- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
5500- </div>
5501- </section>
5502-
5503- {/* Footer */}
5504- <footer class="lv-footer">
5505- <div class="lv-footer-inner">
5506- <div class="lv-footer-brand">
5507- <a href="/" class="lv-logo">
5508- <span class="lv-logo-mark"></span>gluecron
5509- </a>
5510- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
5511- </div>
5512- <div class="lv-footer-cols">
5513- <div class="lv-footer-col">
5514- <h4 class="lv-footer-col-head">Product</h4>
5515- <a href="/" class="lv-footer-link">Agent workspace</a>
5516- <a href="/" class="lv-footer-link">Fleet refactors</a>
5517- <a href="/" class="lv-footer-link">Org memory</a>
5518- <a href="/" class="lv-footer-link">IDE extensions</a>
5519- </div>
5520- <div class="lv-footer-col">
5521- <h4 class="lv-footer-col-head">Platform</h4>
5522- <a href="/" class="lv-footer-link">Production layers</a>
5523- <a href="/trust" class="lv-footer-link">Trust report</a>
5524- <a href="/" class="lv-footer-link">Docs</a>
5525- <a href="/" class="lv-footer-link">Status</a>
5526- </div>
5527- <div class="lv-footer-col">
5528- <h4 class="lv-footer-col-head">Company</h4>
5529- <a href="/" class="lv-footer-link">About</a>
5530- <a href="/" class="lv-footer-link">Pricing</a>
5531- <a href="/" class="lv-footer-link">Enterprise</a>
5532- </div>
5533- </div>
5534- </div>
5535- <div class="lv-footer-bar">
5536- <span>� 2026 Gluecron</span>
5537- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
5538- </div>
5539- </footer>
5540-
5541- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
5542- </>
5543- );
5544-};
5545-
5546-export const LandingPage = LandingPageV2;
5547-export default LandingPageV2;
5548-
5549-const clientScript = `
5550-(function() {
5551- var demoAll = [
5552- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
5553- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
5554- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
5555- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
5556- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
5557- ];
5558-
5559- var demoStep = 0;
5560- var stage = 0;
5561-
5562- function renderDemo() {
5563- var container = document.getElementById('lv-demo-body');
5564- if (!container) return;
5565- var visible = demoAll.slice(0, demoStep + 1);
5566- container.innerHTML = visible.map(function(e, i) {
5567- var isLast = i === visible.length - 1;
5568- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
5569- return '<div class="lv-demo-event">' +
5570- '<div class="lv-demo-event-track">' +
5571- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
5572- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
5573- '</div>' +
5574- '<div class="lv-demo-event-content">' +
5575- '<div class="lv-demo-event-header">' +
5576- '<span class="lv-demo-event-title">' + e.title + '</span>' +
5577- '<span class="lv-demo-event-time">' + e.time + '</span>' +
5578- '</div>' +
5579- '<div class="lv-demo-event-body">' + e.body + '</div>' +
5580- '</div>' +
5581- '</div>';
5582- }).join('');
5583- }
5584-
5585- function renderStages() {
5586- var cards = document.querySelectorAll('.lv-stage-card');
5587- cards.forEach(function(card, i) {
5588- var dot = card.querySelector('.lv-dot');
5589- var meta = card.querySelector('.lv-stage-meta');
5590- if (i === stage) {
5591- card.classList.add('lv-stage-active');
5592- if (dot) {
5593- dot.classList.remove('lv-dot-idle');
5594- dot.classList.add('lv-dot-indigo', 'lv-pulse');
5595- }
5596- if (meta) meta.classList.add('lv-stage-meta-active');
5597- } else {
5598- card.classList.remove('lv-stage-active');
5599- if (dot) {
5600- dot.classList.add('lv-dot-idle');
5601- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
5602- }
5603- if (meta) meta.classList.remove('lv-stage-meta-active');
5604- }
5605- });
5606- }
5607-
5608- renderDemo();
5609-
5610- setInterval(function() {
5611- demoStep = (demoStep + 1) % 5;
5612- renderDemo();
5613- }, 3600);
5614-
5615- setInterval(function() {
5616- stage = (stage + 1) % 6;
5617- renderStages();
5618- }, 2200);
5619-})();
5620-`;
5621-
5622-const css = `
5623-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
5624-
5625-*, *::before, *::after { box-sizing: border-box; }
5626-
5627-body {
5628- margin: 0;
5629- background: #fcfcfd;
5630- -webkit-font-smoothing: antialiased;
5631- text-rendering: optimizeLegibility;
5632- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
5633- font-size: 15px;
5634- line-height: 1.6;
5635- letter-spacing: -0.008em;
5636- color: #16181d;
5637-}
5638-
5639-@keyframes gcPulse {
5640- 0%, 100% { opacity: 1; }
5641- 50% { opacity: 0.35; }
5642-}
5643-
5644-@keyframes gcTicker {
5645- 0% { transform: translateX(0); }
5646- 100% { transform: translateX(-50%); }
5647-}
5648-
5649-/* Shared utilities */
5650-.lv-dot {
5651- display: inline-block;
5652- border-radius: 50%;
5653-}
5654-.lv-dot-green { background: #1e7f5c; }
5655-.lv-dot-indigo { background: #4353c9; }
5656-.lv-dot-idle { background: #c4c6cf; }
5657-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
5658-
5659-.lv-strong { color: #16181d; font-weight: 600; }
5660-
5661-.lv-eyebrow {
5662- font-family: 'JetBrains Mono', monospace;
5663- font-size: 11px;
5664- letter-spacing: 0.12em;
5665- text-transform: uppercase;
5666- color: #8a8d99;
5667- font-weight: 500;
5668- margin-bottom: 12px;
5669-}
5670-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
5671-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
5672-
5673-.lv-h1 {
5674- font-family: 'Inter Tight', sans-serif;
5675- font-weight: 700;
5676- letter-spacing: -0.035em;
5677- font-size: clamp(44px, 7vw, 84px);
5678- line-height: 0.98;
5679- margin: 30px auto 0;
5680- max-width: 14ch;
5681- color: #111318;
5682-}
5683-
5684-.lv-h2 {
5685- font-family: 'Inter Tight', sans-serif;
5686- font-weight: 700;
5687- letter-spacing: -0.028em;
5688- font-size: clamp(30px, 4.4vw, 48px);
5689- line-height: 1.05;
5690- margin: 0;
5691- color: #111318;
5692-}
5693-
5694-.lv-h2-dark {
5695- font-family: 'Inter Tight', sans-serif;
5696- font-weight: 700;
5697- letter-spacing: -0.028em;
5698- font-size: clamp(30px, 4.6vw, 52px);
5699- line-height: 1.05;
5700- margin: 0;
5701- color: #fff;
5702-}
5703-
5704-.lv-section-header {
5705- max-width: 640px;
5706- margin: 0 auto 56px;
5707-}
5708-
5709-.lv-section-header-center {
5710- text-align: center;
5711-}
5712-
5713-.lv-section-sub {
5714- color: #6b7080;
5715- font-size: 17px;
5716- margin: 18px auto 0;
5717- max-width: 52ch;
5718-}
5719-
5720-.lv-section-sub-dark {
5721- color: rgba(255,255,255,0.72);
5722- font-size: 17px;
5723- margin: 18px auto 0;
5724- max-width: 56ch;
5725-}
5726-
5727-/* Nav */
5728-.lv-nav {
5729- position: sticky;
5730- top: 0;
5731- z-index: 60;
5732- backdrop-filter: saturate(180%) blur(14px);
5733- -webkit-backdrop-filter: saturate(180%) blur(14px);
5734- background: rgba(252,252,253,0.8);
5735- border-bottom: 1px solid rgba(22,24,29,0.07);
5736-}
5737-
5738-.lv-nav-inner {
5739- max-width: 1200px;
5740- margin: 0 auto;
5741- padding: 14px 28px;
5742- display: flex;
5743- align-items: center;
5744- gap: 28px;
5745-}
5746-
5747-.lv-logo {
5748- display: inline-flex;
5749- align-items: center;
5750- gap: 9px;
5751- font-family: 'Inter Tight', sans-serif;
5752- font-weight: 700;
5753- font-size: 17px;
5754- letter-spacing: -0.02em;
5755- color: #16181d;
5756- text-decoration: none;
5757-}
5758-
5759-.lv-logo-mark {
5760- width: 17px;
5761- height: 17px;
5762- border-radius: 5px;
5763- background: #4353c9;
5764- display: inline-block;
5765- flex-shrink: 0;
5766-}
5767-
5768-.lv-nav-links {
5769- display: flex;
5770- gap: 24px;
5771- font-size: 13.5px;
5772- font-weight: 500;
5773-}
5774-
5775-.lv-nav-link {
5776- color: #6b7080;
5777- text-decoration: none;
5778- transition: color 0.15s;
5779-}
5780-.lv-nav-link:hover { color: #16181d; }
5781-
5782-.lv-nav-ctas {
5783- margin-left: auto;
5784- display: flex;
5785- align-items: center;
5786- gap: 10px;
5787-}
5788-
5789-.lv-btn-secondary {
5790- padding: 8px 15px;
5791- border-radius: 8px;
5792- font-size: 13.5px;
5793- font-weight: 500;
5794- color: #16181d;
5795- border: 1px solid rgba(22,24,29,0.12);
5796- background: #ffffff;
5797- text-decoration: none;
5798- white-space: nowrap;
5799- transition: border-color 0.15s;
5800-}
5801-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
5802-
5803-.lv-btn-primary {
5804- padding: 8px 15px;
5805- border-radius: 8px;
5806- font-size: 13.5px;
5807- font-weight: 600;
5808- background: #16181d;
5809- color: #fff;
5810- text-decoration: none;
5811- white-space: nowrap;
5812- transition: box-shadow 0.15s;
5813-}
5814-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
5815-
5816-/* Hero */
5817-.lv-hero {
5818- position: relative;
5819- overflow: hidden;
5820- padding: 88px 0 0;
5821-}
5822-
5823-.lv-hero-glow {
5824- position: absolute;
5825- inset: -10% 0 auto 0;
5826- height: 640px;
5827- pointer-events: none;
5828- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
5829-}
5830-
5831-.lv-hero-inner {
5832- position: relative;
5833- max-width: 1200px;
5834- margin: 0 auto;
5835- padding: 0 28px;
5836- text-align: center;
5837-}
5838-
5839-.lv-hero-badge {
5840- display: inline-flex;
5841- align-items: center;
5842- gap: 9px;
5843- font-size: 12.5px;
5844- font-weight: 600;
5845- color: #3a3d45;
5846- background: #ffffff;
5847- border: 1px solid rgba(22,24,29,0.10);
5848- border-radius: 9999px;
5849- padding: 7px 16px;
5850- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
5851-}
5852-
5853-.lv-hero-sub {
5854- font-size: clamp(16px, 2vw, 19px);
5855- color: #6b7080;
5856- max-width: 60ch;
5857- margin: 24px auto 0;
5858- font-weight: 450;
5859- line-height: 1.65;
5860-}
5861-
5862-.lv-hero-actions {
5863- display: flex;
5864- gap: 12px;
5865- justify-content: center;
5866- flex-wrap: wrap;
5867- margin-top: 32px;
5868-}
5869-
5870-.lv-cta-primary {
5871- padding: 13px 24px;
5872- border-radius: 11px;
5873- font-size: 15.5px;
5874- font-weight: 600;
5875- background: #16181d;
5876- color: #fff;
5877- text-decoration: none;
5878- white-space: nowrap;
5879- transition: box-shadow 0.15s;
5880-}
5881-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
5882-
5883-.lv-cta-secondary {
5884- padding: 13px 24px;
5885- border-radius: 11px;
5886- font-size: 15.5px;
5887- font-weight: 600;
5888- color: #16181d;
5889- border: 1px solid rgba(22,24,29,0.14);
5890- background: #ffffff;
5891- text-decoration: none;
5892- white-space: nowrap;
5893- transition: border-color 0.15s;
5894-}
5895-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
5896-
5897-.lv-hero-tag {
5898- margin-top: 18px;
5899- font-family: 'JetBrains Mono', monospace;
5900- font-size: 11.5px;
5901- letter-spacing: 0.08em;
5902- text-transform: uppercase;
5903- color: #8a8d99;
5904-}
5905-
5906-/* Demo window */
5907-.lv-demo-window {
5908- margin: 56px auto 0;
5909- max-width: 860px;
5910- text-align: left;
5911- background: #ffffff;
5912- border: 1px solid rgba(22,24,29,0.09);
5913- border-radius: 18px;
5914- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
5915- overflow: hidden;
5916-}
5917-
5918-.lv-demo-bar {
5919- display: flex;
5920- align-items: center;
5921- gap: 7px;
5922- padding: 12px 18px;
5923- border-bottom: 1px solid rgba(22,24,29,0.07);
5924- background: #fcfcfd;
5925-}
5926-
5927-.lv-demo-dot {
5928- width: 10px;
5929- height: 10px;
5930- border-radius: 50%;
5931- background: #e4e5ea;
5932-}
5933-
5934-.lv-demo-url {
5935- margin-left: 10px;
5936- font-family: 'JetBrains Mono', monospace;
5937- font-size: 12px;
5938- color: #6b7080;
5939-}
5940-
5941-.lv-demo-live {
5942- margin-left: auto;
5943- display: inline-flex;
5944- align-items: center;
5945- gap: 6px;
5946- font-size: 11px;
5947- font-weight: 600;
5948- color: #1e7f5c;
5949-}
5950-
5951-.lv-demo-body {
5952- padding: 22px 24px;
5953-}
5954-
5955-.lv-demo-event {
5956- display: grid;
5957- grid-template-columns: 18px minmax(0, 1fr);
5958- gap: 14px;
5959- padding-bottom: 20px;
5960- position: relative;
5961-}
5962-.lv-demo-event:last-child { padding-bottom: 0; }
5963-
5964-.lv-demo-event-track {
5965- display: flex;
5966- flex-direction: column;
5967- align-items: center;
5968-}
5969-
5970-.lv-demo-line {
5971- width: 1px;
5972- flex: 1;
5973- background: rgba(22,24,29,0.08);
5974- margin-top: 5px;
5975- min-height: 20px;
5976-}
5977-
5978-.lv-demo-event-content {}
5979-
5980-.lv-demo-event-header {
5981- display: flex;
5982- align-items: baseline;
5983- gap: 10px;
5984-}
5985-
5986-.lv-demo-event-title {
5987- font-size: 13.5px;
5988- font-weight: 600;
5989- color: #16181d;
5990-}
5991-
5992-.lv-demo-event-time {
5993- font-family: 'JetBrains Mono', monospace;
5994- font-size: 11px;
5995- color: #8a8d99;
5996-}
5997-
5998-.lv-demo-event-body {
5999- font-size: 13px;
6000- color: #6b7080;
6001- margin-top: 2px;
6002-}
6003-
6004-/* Ticker */
6005-.lv-ticker-wrap {
6006- border-top: 1px solid rgba(22,24,29,0.07);
6007- border-bottom: 1px solid rgba(22,24,29,0.07);
6008- background: #ffffff;
6009- margin-top: 64px;
6010- overflow: hidden;
6011- white-space: nowrap;
6012- position: relative;
6013-}
6014-
6015-.lv-ticker-track {
6016- display: inline-flex;
6017- animation: gcTicker 40s linear infinite;
6018- padding: 11px 0;
6019-}
6020-
6021-.lv-ticker-item {
6022- display: inline-flex;
6023- align-items: center;
6024- gap: 8px;
6025- font-family: 'JetBrains Mono', monospace;
6026- font-size: 11.5px;
6027- color: #6b7080;
6028- padding: 0 28px;
6029- border-right: 1px solid rgba(22,24,29,0.06);
6030-}
6031-
6032-/* Stats */
6033-.lv-stats {
6034- background: #fcfcfd;
6035-}
6036-
6037-.lv-stats-inner {
6038- max-width: 1200px;
6039- margin: 0 auto;
6040- display: grid;
6041- grid-template-columns: repeat(4, 1fr);
6042- gap: 24px;
6043- padding: 52px 28px;
6044-}
6045-
6046-.lv-stat {
6047- text-align: center;
6048-}
6049-
6050-.lv-stat-num {
6051- font-family: 'Inter Tight', sans-serif;
6052- font-weight: 700;
6053- font-size: clamp(30px, 4vw, 44px);
6054- letter-spacing: -0.025em;
6055- color: #111318;
6056-}
6057-
6058-.lv-stat-label {
6059- font-size: 13px;
6060- color: #6b7080;
6061- margin-top: 4px;
6062-}
6063-
6064-/* Loop */
6065-.lv-loop {
6066- padding: 96px 0;
6067- background: #ffffff;
6068- border-top: 1px solid rgba(22,24,29,0.07);
6069- border-bottom: 1px solid rgba(22,24,29,0.07);
6070-}
6071-
6072-.lv-loop-inner {
6073- max-width: 1200px;
6074- margin: 0 auto;
6075- padding: 0 28px;
6076-}
6077-
6078-.lv-stages {
6079- display: grid;
6080- grid-template-columns: repeat(6, 1fr);
6081- gap: 12px;
6082-}
6083-
6084-.lv-stage-card {
6085- border: 1px solid rgba(22,24,29,0.08);
6086- border-radius: 14px;
6087- background: #ffffff;
6088- padding: 20px 18px;
6089- transition: border-color 0.3s, background 0.3s;
6090-}
6091-
6092-.lv-stage-card.lv-stage-active {
6093- border-color: rgba(67,83,201,0.45);
6094- background: rgba(67,83,201,0.03);
6095-}
6096-
6097-.lv-stage-header {
6098- display: flex;
6099- align-items: center;
6100- gap: 8px;
6101- margin-bottom: 10px;
6102-}
6103-
6104-.lv-stage-n {
6105- font-family: 'JetBrains Mono', monospace;
6106- font-size: 10.5px;
6107- letter-spacing: 0.1em;
6108- text-transform: uppercase;
6109- color: #8a8d99;
6110-}
6111-
6112-.lv-stage-name {
6113- font-family: 'Inter Tight', sans-serif;
6114- font-size: 16px;
6115- font-weight: 600;
6116- letter-spacing: -0.01em;
6117- color: #16181d;
6118- margin-bottom: 5px;
6119-}
6120-
6121-.lv-stage-desc {
6122- font-size: 12px;
6123- color: #6b7080;
6124- line-height: 1.55;
6125-}
6126-
6127-.lv-stage-meta {
6128- font-family: 'JetBrains Mono', monospace;
6129- font-size: 10.5px;
6130- color: #8a8d99;
6131- margin-top: 10px;
6132- transition: color 0.3s;
6133-}
6134-
6135-.lv-stage-meta.lv-stage-meta-active {
6136- color: #4353c9;
6137-}
6138-
6139-/* Heroes */
6140-.lv-heroes {
6141- padding: 96px 0;
6142- background: #fcfcfd;
6143-}
6144-
6145-.lv-heroes-inner {
6146- max-width: 1200px;
6147- margin: 0 auto;
6148- padding: 0 28px;
6149-}
6150-
6151-.lv-heroes-header {
6152- max-width: 640px;
6153- margin-bottom: 56px;
6154-}
6155-
6156-.lv-heroes-list {
6157- display: flex;
6158- flex-direction: column;
6159- gap: 20px;
6160-}
6161-
6162-.lv-hero-card {
6163- display: grid;
6164- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
6165- gap: 48px;
6166- align-items: center;
6167- border: 1px solid rgba(22,24,29,0.08);
6168- border-radius: 20px;
6169- background: #ffffff;
6170- padding: 44px 48px;
6171- text-decoration: none;
6172- transition: border-color 0.2s, box-shadow 0.2s;
6173-}
6174-.lv-hero-card:hover {
6175- border-color: rgba(22,24,29,0.22);
6176- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
6177-}
6178-
6179-.lv-hero-card-left {}
6180-
6181-.lv-hero-card-title {
6182- font-family: 'Inter Tight', sans-serif;
6183- font-size: 26px;
6184- font-weight: 600;
6185- letter-spacing: -0.022em;
6186- line-height: 1.15;
6187- color: #16181d;
6188- margin: 0 0 12px;
6189-}
6190-
6191-.lv-hero-card-body {
6192- font-size: 14.5px;
6193- color: #6b7080;
6194- margin: 0 0 18px;
6195- line-height: 1.65;
6196-}
6197-
6198-.lv-hero-card-cta {
6199- font-size: 13.5px;
6200- font-weight: 600;
6201- color: #4353c9;
6202-}
6203-
6204-.lv-terminal {
6205- border: 1px solid rgba(22,24,29,0.07);
6206- border-radius: 14px;
6207- background: #fcfcfd;
6208- padding: 20px 22px;
6209- font-family: 'JetBrains Mono', monospace;
6210- font-size: 12px;
6211- line-height: 1.9;
6212- overflow: hidden;
6213-}
6214-
6215-.lv-terminal-line {
6216- display: flex;
6217- align-items: center;
6218- gap: 10px;
6219- white-space: nowrap;
6220- overflow: hidden;
6221- text-overflow: ellipsis;
6222-}
6223-
6224-/* Platform */
6225-.lv-platform {
6226- padding: 96px 0;
6227- background: #ffffff;
6228- border-top: 1px solid rgba(22,24,29,0.07);
6229-}
6230-
6231-.lv-platform-inner {
6232- max-width: 1200px;
6233- margin: 0 auto;
6234- padding: 0 28px;
6235-}
6236-
6237-.lv-cap-grid {
6238- display: grid;
6239- grid-template-columns: repeat(4, 1fr);
6240- gap: 24px 32px;
6241-}
6242-
6243-.lv-cap-col {}
6244-
6245-.lv-cap-group {
6246- font-family: 'JetBrains Mono', monospace;
6247- font-size: 10.5px;
6248- letter-spacing: 0.12em;
6249- text-transform: uppercase;
6250- color: #8a8d99;
6251- font-weight: 500;
6252- margin-bottom: 12px;
6253- padding-bottom: 8px;
6254- border-bottom: 1px solid rgba(22,24,29,0.07);
6255-}
6256-
6257-.lv-cap-items {
6258- display: flex;
6259- flex-direction: column;
6260- gap: 7px;
6261-}
6262-
6263-.lv-cap-item {
6264- font-size: 12.5px;
6265- color: #3a3d45;
6266- line-height: 1.45;
6267-}
6268-
6269-/* Sovereignty */
6270-.lv-sovereign {
6271- position: relative;
6272- overflow: hidden;
6273- padding: 104px 0;
6274- color: #fff;
6275- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
6276-}
6277-
6278-.lv-sovereign-grid-bg {
6279- position: absolute;
6280- inset: 0;
6281- opacity: 0.4;
6282- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
6283- background-size: 56px 56px;
6284- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
6285- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
6286-}
6287-
6288-.lv-sovereign-inner {
6289- position: relative;
6290- max-width: 1200px;
6291- margin: 0 auto;
6292- padding: 0 28px;
6293-}
6294-
6295-.lv-section-header-dark {
6296- max-width: 680px;
6297- margin: 0 auto 48px;
6298- text-align: center;
6299-}
6300-
6301-.lv-layers-grid {
6302- display: grid;
6303- grid-template-columns: repeat(4, 1fr);
6304- gap: 10px;
6305- max-width: 980px;
6306- margin: 0 auto;
6307-}
6308-
6309-.lv-layer-chip {
6310- border: 1px solid rgba(255,255,255,0.10);
6311- border-radius: 10px;
6312- padding: 12px 16px;
6313- background: rgba(255,255,255,0.03);
6314-}
6315-
6316-.lv-layer-cta {
6317- border-color: rgba(169,180,238,0.30);
6318- background: rgba(169,180,238,0.06);
6319- display: flex;
6320- align-items: center;
6321- text-decoration: none;
6322- transition: background 0.15s;
6323-}
6324-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
6325-
6326-.lv-layer-cta-text {
6327- font-size: 13px;
6328- font-weight: 500;
6329- color: #a9b4ee;
6330-}
6331-
6332-.lv-layer-n {
6333- font-family: 'JetBrains Mono', monospace;
6334- font-size: 10px;
6335- color: rgba(255,255,255,0.4);
6336- margin-bottom: 3px;
6337-}
6338-
6339-.lv-layer-name {
6340- font-size: 13px;
6341- font-weight: 500;
6342- color: rgba(255,255,255,0.92);
6343-}
6344-
6345-.lv-sovereign-feats {
6346- display: flex;
6347- gap: 44px;
6348- justify-content: center;
6349- flex-wrap: wrap;
6350- margin-top: 52px;
6351- text-align: center;
6352-}
6353-
6354-.lv-sovereign-feat {}
6355-
6356-.lv-sovereign-feat-title {
6357- font-family: 'Inter Tight', sans-serif;
6358- font-size: 20px;
6359- font-weight: 700;
6360- color: #fff;
6361-}
6362-
6363-.lv-sovereign-feat-sub {
6364- color: rgba(255,255,255,0.55);
6365- font-size: 13px;
6366- margin-top: 2px;
6367-}
6368-
6369-/* Twin cards */
6370-.lv-twin {
6371- padding: 96px 0;
6372- background: #fcfcfd;
6373-}
6374-
6375-.lv-twin-inner {
6376- max-width: 1200px;
6377- margin: 0 auto;
6378- padding: 0 28px;
6379- display: grid;
6380- grid-template-columns: 1fr 1fr;
6381- gap: 24px;
6382-}
6383-
6384-.lv-twin-card {
6385- border: 1px solid rgba(22,24,29,0.08);
6386- border-radius: 20px;
6387- background: #ffffff;
6388- padding: 44px 48px;
6389-}
6390-
6391-.lv-twin-title {
6392- font-family: 'Inter Tight', sans-serif;
6393- font-size: 24px;
6394- font-weight: 600;
6395- letter-spacing: -0.02em;
6396- line-height: 1.2;
6397- margin: 0 0 12px;
6398- color: #16181d;
6399-}
6400-
6401-.lv-twin-body {
6402- font-size: 14.5px;
6403- color: #6b7080;
6404- margin: 0 0 16px;
6405- line-height: 1.7;
6406-}
6407-
6408-.lv-twin-link {
6409- font-size: 13.5px;
6410- font-weight: 600;
6411- color: #4353c9;
6412- text-decoration: none;
6413-}
6414-.lv-twin-link:hover { text-decoration: underline; }
6415-
6416-/* Quote */
6417-.lv-quote {
6418- padding: 40px 0 96px;
6419- background: #fcfcfd;
6420-}
6421-
6422-.lv-quote-inner {
6423- max-width: 980px;
6424- margin: 0 auto;
6425- padding: 0 28px;
6426- text-align: center;
6427-}
6428-
6429-.lv-quote-text {
6430- font-family: 'Inter Tight', sans-serif;
6431- font-weight: 600;
6432- font-size: clamp(26px, 3.8vw, 42px);
6433- line-height: 1.2;
6434- letter-spacing: -0.025em;
6435- margin: 0;
6436- color: #111318;
6437-}
6438-
6439-.lv-em {
6440- font-style: normal;
6441- color: #4353c9;
6442-}
6443-
6444-/* CTA */
6445-.lv-cta-section {
6446- padding: 0 0 104px;
6447- background: #fcfcfd;
6448-}
6449-
6450-.lv-cta-card {
6451- max-width: 820px;
6452- margin: 0 auto;
6453- padding: 64px 40px;
6454- text-align: center;
6455- background: #ffffff;
6456- border: 1px solid rgba(22,24,29,0.08);
6457- border-radius: 26px;
6458- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
6459- position: relative;
6460- overflow: hidden;
6461-}
6462-
6463-.lv-cta-glow {
6464- position: absolute;
6465- inset: -40% 0 auto 0;
6466- height: 280px;
6467- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
6468- pointer-events: none;
6469-}
6470-
6471-.lv-cta-h2 {
6472- font-family: 'Inter Tight', sans-serif;
6473- font-weight: 700;
6474- letter-spacing: -0.028em;
6475- font-size: clamp(30px, 4.6vw, 48px);
6476- margin: 0;
6477- position: relative;
6478- color: #111318;
6479-}
6480-
6481-.lv-cta-sub {
6482- color: #6b7080;
6483- font-size: 17px;
6484- margin: 16px 0 30px;
6485- position: relative;
6486-}
6487-
6488-.lv-cta-actions {
6489- display: flex;
6490- gap: 12px;
6491- justify-content: center;
6492- flex-wrap: wrap;
6493- position: relative;
6494-}
6495-
6496-.lv-cta-fine {
6497- margin-top: 20px;
6498- font-family: 'JetBrains Mono', monospace;
6499- font-size: 11px;
6500- color: #8a8d99;
6501- position: relative;
6502-}
6503-
6504-/* Footer */
6505-.lv-footer {
6506- border-top: 1px solid rgba(22,24,29,0.07);
6507- background: #ffffff;
6508- padding: 56px 0 30px;
6509-}
6510-
6511-.lv-footer-inner {
6512- max-width: 1200px;
6513- margin: 0 auto;
6514- padding: 0 28px;
6515- display: flex;
6516- gap: 48px;
6517- flex-wrap: wrap;
6518- justify-content: space-between;
6519-}
6520-
6521-.lv-footer-brand {}
6522-
6523-.lv-footer-tagline {
6524- color: #6b7080;
6525- font-size: 13.5px;
6526- margin: 12px 0 0;
6527- max-width: 32ch;
6528- line-height: 1.6;
6529-}
6530-
6531-.lv-footer-cols {
6532- display: flex;
6533- gap: 64px;
6534- flex-wrap: wrap;
6535-}
6536-
6537-.lv-footer-col {
6538- display: flex;
6539- flex-direction: column;
6540- gap: 9px;
6541-}
6542-
6543-.lv-footer-col-head {
6544- font-family: 'JetBrains Mono', monospace;
6545- font-size: 11px;
6546- text-transform: uppercase;
6547- letter-spacing: 0.1em;
6548- color: #8a8d99;
6549- margin: 0 0 4px;
6550- font-weight: 500;
6551-}
6552-
6553-.lv-footer-link {
6554- color: #3a3d45;
6555- font-size: 13.5px;
6556- text-decoration: none;
6557- transition: color 0.15s;
6558-}
6559-.lv-footer-link:hover { color: #16181d; }
6560-
6561-.lv-footer-bar {
6562- max-width: 1200px;
6563- margin: 44px auto 0;
6564- padding: 22px 28px 0;
6565- border-top: 1px solid rgba(22,24,29,0.06);
6566- display: flex;
6567- justify-content: space-between;
6568- flex-wrap: wrap;
6569- gap: 8px;
6570- color: #8a8d99;
6571- font-size: 12.5px;
6572-}
6573-
6574-.lv-footer-stack {
6575- font-family: 'JetBrains Mono', monospace;
6576- font-size: 11px;
6577-}
6578-`;
6579diff --git a/src/views/layout.tsx b/src/views/layout.tsx
6580index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
6581--- a/src/views/layout.tsx
6582+++ b/src/views/layout.tsx
6583@@ -3153,9 +3153,12 @@
6584 font-weight: 500;
6585 line-height: 1.4;
6586 }
6587- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
6588- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
6589- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
6590+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
6591+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
6592+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
6593+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
6594+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
6595+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
6596 .state-merged { color: var(--accent); }
6597 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
6598
6599diff --git a/src/views/ui.tsx b/src/views/ui.tsx
6600index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
6601--- a/src/views/ui.tsx
6602+++ b/src/views/ui.tsx
6603@@ -232,7 +232,7 @@
6604
6605 export const Badge: FC<
6606 PropsWithChildren<{
6607- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
6608+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
6609 style?: string;
6610 }>
6611 > = ({ children, variant = "default", style }) => {
6612@@ -241,9 +241,12 @@
6613 variant === "closed" ? "badge-closed" :
6614 variant === "merged" ? "badge-merged" :
6615 variant === "success" ? "badge-success" :
6616- variant === "danger" ? "badge-danger" :
6617- variant === "warning" ? "badge-warning" :
6618- "badge";
6619+ variant === "danger" ? "badge-danger" :
6620+ variant === "warning" ? "badge-warning" :
6621+ variant === "live" ? "badge-live" :
6622+ variant === "soon" ? "badge-soon" :
6623+ variant === "preview" ? "badge-preview" :
6624+ "badge";
6625 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
6626 };
6627
6628
6629exec
6630"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command 'bun test' in C:\Users\ccant\gluecron.com
6631exec
6632"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command 'bun run typecheck' in C:\Users\ccant\gluecron.com
6633diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
6634index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
6635--- a/src/views/landing-pro.tsx
6636+++ b/src/views/landing-pro.tsx
6637@@ -42,7 +42,7 @@
6638
6639 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6640
6641-function icon(paths: string, color = "#4353c9", size = 20) {
6642+function icon(paths: string, color = "#0891b2", size = 20) {
6643 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
6644 }
6645
6646@@ -947,7 +947,7 @@
6647 const css = `
6648 /* %% tokens %% */
6649 :root{
6650- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
6651+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
6652 --lp-bg:#ffffff;--lp-soft:#fafafb;
6653 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
6654 --lp-border:rgba(0,0,0,.08);
6655diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
6656deleted file mode 100644
6657index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
6658--- a/src/views/landing-v2.tsx
6659+++ /dev/null
6660@@ -1,1447 +0,0 @@
6661-import type { FC } from "hono/jsx";
6662-
6663-export interface LandingPageProps {
6664- stats?: {
6665- publicRepos?: number;
6666- users?: number;
6667- };
6668-}
6669-
6670-const demoAllEvents = [
6671- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
6672- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
6673- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
6674- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
6675- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
6676-];
6677-
6678-const tickerItems = [
6679- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
6680- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
6681- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
6682- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
6683- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
6684- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
6685- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
6686- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
6687- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
6688- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
6689- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
6690- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
6691- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
6692- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
6693- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
6694- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
6695-];
6696-
6697-const stageData = [
6698- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
6699- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
6700- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
6701- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
6702- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
6703- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
6704-];
6705-
6706-const heroFeatures = [
6707- {
6708- href: "/",
6709- eyebrow: "01 � The autonomous repair loop",
6710- title: "Failures fix themselves  and show their work.",
6711- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
6712failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
6713- cta: "Watch a live repair session",
6714- mock: [
6715- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
6716- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
6717- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
6718- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
6719- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
6720- ],
6721- },
6722- {
6723- href: "/",
6724- eyebrow: "02 � Live sandbox isolation",
6725- title: "Every PR gets its own instant, disposable environment.",
6726- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
6727same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
6728- cta: "See a PR with its sandbox",
6729- mock: [
6730- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
6731- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
6732- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
6733- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
6734- ],
6735- },
6736- {
6737- href: "/",
6738- eyebrow: "03 � Multiplayer IDE workspaces",
6739- title: "You and the agent, side by side, in your editor.",
6740- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
6741agent into a silent reviewer in your gutter. The browser becomes optional.",
6742- cta: "See the editor session",
6743- mock: [
6744- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
6745- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
6746- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
6747- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
6748- ],
6749- },
6750-];
6751-
6752-const capabilities = [
6753- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
6754- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
6755- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
6756- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
6757- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
6758- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
6759- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
6760- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
6761-];
6762-
6763-const sovereignLayerNames = [
6764- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
6765- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
6766- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
6767- "Availability & recovery",
6768-];
6769-
6770-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
6771- return (
6772- <>
6773- <style dangerouslySetInnerHTML={{ __html: css }} />
6774-
6775- {/* Nav */}
6776- <header class="lv-nav">
6777- <div class="lv-nav-inner">
6778- <a href="/" class="lv-logo">
6779- <span class="lv-logo-mark"></span>gluecron
6780- </a>
6781- <nav class="lv-nav-links">
6782- <a href="#loop" class="lv-nav-link">The loop</a>
6783- <a href="#platform" class="lv-nav-link">Platform</a>
6784- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
6785- <a href="/trust" class="lv-nav-link">Trust</a>
6786- </nav>
6787- <div class="lv-nav-ctas">
6788- <a href="/login" class="lv-btn-secondary">Sign in</a>
6789- <a href="/register" class="lv-btn-primary">Start building</a>
6790- </div>
6791- </div>
6792- </header>
6793-
6794- {/* Hero */}
6795- <section class="lv-hero">
6796- <div class="lv-hero-glow"></div>
6797- <div class="lv-hero-inner">
6798- <div class="lv-hero-badge">
6799- <span class="lv-dot lv-dot-green lv-pulse"></span>
6800- Live: a repair loop converged on pr-218 while you read this
6801- </div>
6802- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
6803- <p class="lv-hero-sub">
6804- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
6805failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
6806- </p>
6807- <div class="lv-hero-actions">
6808- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
6809- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
6810- </div>
6811- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
6812-
6813- {/* Live product window */}
6814- <div class="lv-demo-window">
6815- <div class="lv-demo-bar">
6816- <span class="lv-demo-dot"></span>
6817- <span class="lv-demo-dot"></span>
6818- <span class="lv-demo-dot"></span>
6819- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
6820- <span class="lv-demo-live">
6821- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
6822- LIVE
6823- </span>
6824- </div>
6825- <div class="lv-demo-body" id="lv-demo-body">
6826- {/* Events rendered by JS */}
6827- {demoAllEvents.slice(0, 1).map((e, i) => (
6828- <div class="lv-demo-event" key={i}>
6829- <div class="lv-demo-event-track">
6830- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
6831- <span class="lv-demo-line" style="display:none"></span>
6832- </div>
6833- <div class="lv-demo-event-content">
6834- <div class="lv-demo-event-header">
6835- <span class="lv-demo-event-title">{e.title}</span>
6836- <span class="lv-demo-event-time">{e.time}</span>
6837- </div>
6838- <div class="lv-demo-event-body">{e.body}</div>
6839- </div>
6840- </div>
6841- ))}
6842- </div>
6843- </div>
6844- </div>
6845-
6846- {/* Activity ticker */}
6847- <div class="lv-ticker-wrap">
6848- <div class="lv-ticker-track">
6849- {tickerItems.map((t, i) => (
6850- <span class="lv-ticker-item" key={i}>
6851- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
6852- {t.text}
6853- </span>
6854- ))}
6855- </div>
6856- </div>
6857- </section>
6858-
6859- {/* Stat band */}
6860- <section class="lv-stats">
6861- <div class="lv-stats-inner">
6862- <div class="lv-stat">
6863- <div class="lv-stat-num">Sonnet 5</div>
6864- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
6865- </div>
6866- <div class="lv-stat">
6867- <div class="lv-stat-num">93.5%</div>
6868- <div class="lv-stat-label">of failures self-repair without a human</div>
6869- </div>
6870- <div class="lv-stat">
6871- <div class="lv-stat-num">1.9%</div>
6872- <div class="lv-stat-label">AI merges reverted  published live</div>
6873- </div>
6874- <div class="lv-stat">
6875- <div class="lv-stat-num">0</div>
6876- <div class="lv-stat-label">irreversible actions taken autonomously</div>
6877- </div>
6878- </div>
6879- </section>
6880-
6881- {/* The loop */}
6882- <section id="loop" class="lv-loop">
6883- <div class="lv-loop-inner">
6884- <div class="lv-section-header">
6885- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
6886- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
6887- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
6888- </div>
6889- <div class="lv-stages" id="lv-stages">
6890- {stageData.map((s, i) => (
6891- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
6892- <div class="lv-stage-header">
6893- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
6894- <span class="lv-stage-n">0{i + 1}</span>
6895- </div>
6896- <div class="lv-stage-name">{s.name}</div>
6897- <div class="lv-stage-desc">{s.desc}</div>
6898- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
6899- </div>
6900- ))}
6901- </div>
6902- </div>
6903- </section>
6904-
6905- {/* Three heroes */}
6906- <section class="lv-heroes">
6907- <div class="lv-heroes-inner">
6908- <div class="lv-heroes-header">
6909- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
6910- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
6911- </div>
6912- <div class="lv-heroes-list">
6913- {heroFeatures.map((h, i) => (
6914- <a href={h.href} class="lv-hero-card" key={i}>
6915- <div class="lv-hero-card-left">
6916- <div class="lv-eyebrow">{h.eyebrow}</div>
6917- <h3 class="lv-hero-card-title">{h.title}</h3>
6918- <p class="lv-hero-card-body">{h.body}</p>
6919- <span class="lv-hero-card-cta">{h.cta} �!</span>
6920- </div>
6921- <div class="lv-terminal">
6922- {h.mock.map((m, j) => (
6923- <div class="lv-terminal-line" key={j}>
6924- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
6925- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
6926- </div>
6927- ))}
6928- </div>
6929- </a>
6930- ))}
6931- </div>
6932- </div>
6933- </section>
6934-
6935- {/* Everything grid */}
6936- <section id="platform" class="lv-platform">
6937- <div class="lv-platform-inner">
6938- <div class="lv-section-header lv-section-header-center">
6939- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
6940- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
6941- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
6942- </div>
6943- <div class="lv-cap-grid">
6944- {capabilities.map((c, i) => (
6945- <div class="lv-cap-col" key={i}>
6946- <div class="lv-cap-group">{c.group}</div>
6947- <div class="lv-cap-items">
6948- {c.items.map((item, j) => (
6949- <div class="lv-cap-item" key={j}>{item}</div>
6950- ))}
6951- </div>
6952- </div>
6953- ))}
6954- </div>
6955- </div>
6956- </section>
6957-
6958- {/* Sovereignty band */}
6959- <section id="sovereign" class="lv-sovereign">
6960- <div class="lv-sovereign-grid-bg"></div>
6961- <div class="lv-sovereign-inner">
6962- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
6963- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
6964- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
6965- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
6966to private cloud, or run fully air-gapped on bare metal.</p>
6967- </div>
6968- <div class="lv-layers-grid">
6969- {sovereignLayerNames.map((name, i) => (
6970- <div class="lv-layer-chip" key={i}>
6971- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
6972- <div class="lv-layer-name">{name}</div>
6973- </div>
6974- ))}
6975- <a href="/" class="lv-layer-chip lv-layer-cta">
6976- <div class="lv-layer-cta-text">All self-owned �!</div>
6977- </a>
6978- </div>
6979- <div class="lv-sovereign-feats">
6980- <div class="lv-sovereign-feat">
6981- <div class="lv-sovereign-feat-title">Local inference first</div>
6982- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
6983- </div>
6984- <div class="lv-sovereign-feat">
6985- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
6986- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
6987- </div>
6988- <div class="lv-sovereign-feat">
6989- <div class="lv-sovereign-feat-title">Self-healing infra</div>
6990- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
6991- </div>
6992- </div>
6993- </div>
6994- </section>
6995-
6996- {/* Manual-first + reversibility */}
6997- <section class="lv-twin">
6998- <div class="lv-twin-inner">
6999- <div class="lv-twin-card">
7000- <div class="lv-eyebrow">Manual-first, always</div>
7001- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
7002- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
7003fallback. Developers who never touch AI get the best git host they've ever used.</p>
7004- </div>
7005- <div class="lv-twin-card">
7006- <div class="lv-eyebrow">The reversibility guarantee</div>
7007- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
7008- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
7009 policy, not promise. Our quality numbers are published live, unedited.</p>
7010- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
7011- </div>
7012- </div>
7013- </section>
7014-
7015- {/* Quote */}
7016- <section class="lv-quote">
7017- <div class="lv-quote-inner">
7018- <p class="lv-quote-text">
7019- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
7020- Gluecron is where code gets <em class="lv-em">finished</em>."
7021- </p>
7022- </div>
7023- </section>
7024-
7025- {/* CTA */}
7026- <section class="lv-cta-section">
7027- <div class="lv-cta-card">
7028- <div class="lv-cta-glow"></div>
7029- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
7030- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
7031- <div class="lv-cta-actions">
7032- <a href="/register" class="lv-cta-primary">Create your account �!</a>
7033- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
7034- </div>
7035- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
7036- </div>
7037- </section>
7038-
7039- {/* Footer */}
7040- <footer class="lv-footer">
7041- <div class="lv-footer-inner">
7042- <div class="lv-footer-brand">
7043- <a href="/" class="lv-logo">
7044- <span class="lv-logo-mark"></span>gluecron
7045- </a>
7046- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
7047- </div>
7048- <div class="lv-footer-cols">
7049- <div class="lv-footer-col">
7050- <h4 class="lv-footer-col-head">Product</h4>
7051- <a href="/" class="lv-footer-link">Agent workspace</a>
7052- <a href="/" class="lv-footer-link">Fleet refactors</a>
7053- <a href="/" class="lv-footer-link">Org memory</a>
7054- <a href="/" class="lv-footer-link">IDE extensions</a>
7055- </div>
7056- <div class="lv-footer-col">
7057- <h4 class="lv-footer-col-head">Platform</h4>
7058- <a href="/" class="lv-footer-link">Production layers</a>
7059- <a href="/trust" class="lv-footer-link">Trust report</a>
7060- <a href="/" class="lv-footer-link">Docs</a>
7061- <a href="/" class="lv-footer-link">Status</a>
7062- </div>
7063- <div class="lv-footer-col">
7064- <h4 class="lv-footer-col-head">Company</h4>
7065- <a href="/" class="lv-footer-link">About</a>
7066- <a href="/" class="lv-footer-link">Pricing</a>
7067- <a href="/" class="lv-footer-link">Enterprise</a>
7068- </div>
7069- </div>
7070- </div>
7071- <div class="lv-footer-bar">
7072- <span>� 2026 Gluecron</span>
7073- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
7074- </div>
7075- </footer>
7076-
7077- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
7078- </>
7079- );
7080-};
7081-
7082-export const LandingPage = LandingPageV2;
7083-export default LandingPageV2;
7084-
7085-const clientScript = `
7086-(function() {
7087- var demoAll = [
7088- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
7089- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
7090- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
7091- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
7092- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
7093- ];
7094-
7095- var demoStep = 0;
7096- var stage = 0;
7097-
7098- function renderDemo() {
7099- var container = document.getElementById('lv-demo-body');
7100- if (!container) return;
7101- var visible = demoAll.slice(0, demoStep + 1);
7102- container.innerHTML = visible.map(function(e, i) {
7103- var isLast = i === visible.length - 1;
7104- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
7105- return '<div class="lv-demo-event">' +
7106- '<div class="lv-demo-event-track">' +
7107- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
7108- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
7109- '</div>' +
7110- '<div class="lv-demo-event-content">' +
7111- '<div class="lv-demo-event-header">' +
7112- '<span class="lv-demo-event-title">' + e.title + '</span>' +
7113- '<span class="lv-demo-event-time">' + e.time + '</span>' +
7114- '</div>' +
7115- '<div class="lv-demo-event-body">' + e.body + '</div>' +
7116- '</div>' +
7117- '</div>';
7118- }).join('');
7119- }
7120-
7121- function renderStages() {
7122- var cards = document.querySelectorAll('.lv-stage-card');
7123- cards.forEach(function(card, i) {
7124- var dot = card.querySelector('.lv-dot');
7125- var meta = card.querySelector('.lv-stage-meta');
7126- if (i === stage) {
7127- card.classList.add('lv-stage-active');
7128- if (dot) {
7129- dot.classList.remove('lv-dot-idle');
7130- dot.classList.add('lv-dot-indigo', 'lv-pulse');
7131- }
7132- if (meta) meta.classList.add('lv-stage-meta-active');
7133- } else {
7134- card.classList.remove('lv-stage-active');
7135- if (dot) {
7136- dot.classList.add('lv-dot-idle');
7137- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
7138- }
7139- if (meta) meta.classList.remove('lv-stage-meta-active');
7140- }
7141- });
7142- }
7143-
7144- renderDemo();
7145-
7146- setInterval(function() {
7147- demoStep = (demoStep + 1) % 5;
7148- renderDemo();
7149- }, 3600);
7150-
7151- setInterval(function() {
7152- stage = (stage + 1) % 6;
7153- renderStages();
7154- }, 2200);
7155-})();
7156-`;
7157-
7158-const css = `
7159-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
7160-
7161-*, *::before, *::after { box-sizing: border-box; }
7162-
7163-body {
7164- margin: 0;
7165- background: #fcfcfd;
7166- -webkit-font-smoothing: antialiased;
7167- text-rendering: optimizeLegibility;
7168- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
7169- font-size: 15px;
7170- line-height: 1.6;
7171- letter-spacing: -0.008em;
7172- color: #16181d;
7173-}
7174-
7175-@keyframes gcPulse {
7176- 0%, 100% { opacity: 1; }
7177- 50% { opacity: 0.35; }
7178-}
7179-
7180-@keyframes gcTicker {
7181- 0% { transform: translateX(0); }
7182- 100% { transform: translateX(-50%); }
7183-}
7184-
7185-/* Shared utilities */
7186-.lv-dot {
7187- display: inline-block;
7188- border-radius: 50%;
7189-}
7190-.lv-dot-green { background: #1e7f5c; }
7191-.lv-dot-indigo { background: #4353c9; }
7192-.lv-dot-idle { background: #c4c6cf; }
7193-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
7194-
7195-.lv-strong { color: #16181d; font-weight: 600; }
7196-
7197-.lv-eyebrow {
7198- font-family: 'JetBrains Mono', monospace;
7199- font-size: 11px;
7200- letter-spacing: 0.12em;
7201- text-transform: uppercase;
7202- color: #8a8d99;
7203- font-weight: 500;
7204- margin-bottom: 12px;
7205-}
7206-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
7207-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
7208-
7209-.lv-h1 {
7210- font-family: 'Inter Tight', sans-serif;
7211- font-weight: 700;
7212- letter-spacing: -0.035em;
7213- font-size: clamp(44px, 7vw, 84px);
7214- line-height: 0.98;
7215- margin: 30px auto 0;
7216- max-width: 14ch;
7217- color: #111318;
7218-}
7219-
7220-.lv-h2 {
7221- font-family: 'Inter Tight', sans-serif;
7222- font-weight: 700;
7223- letter-spacing: -0.028em;
7224- font-size: clamp(30px, 4.4vw, 48px);
7225- line-height: 1.05;
7226- margin: 0;
7227- color: #111318;
7228-}
7229-
7230-.lv-h2-dark {
7231- font-family: 'Inter Tight', sans-serif;
7232- font-weight: 700;
7233- letter-spacing: -0.028em;
7234- font-size: clamp(30px, 4.6vw, 52px);
7235- line-height: 1.05;
7236- margin: 0;
7237- color: #fff;
7238-}
7239-
7240-.lv-section-header {
7241- max-width: 640px;
7242- margin: 0 auto 56px;
7243-}
7244-
7245-.lv-section-header-center {
7246- text-align: center;
7247-}
7248-
7249-.lv-section-sub {
7250- color: #6b7080;
7251- font-size: 17px;
7252- margin: 18px auto 0;
7253- max-width: 52ch;
7254-}
7255-
7256-.lv-section-sub-dark {
7257- color: rgba(255,255,255,0.72);
7258- font-size: 17px;
7259- margin: 18px auto 0;
7260- max-width: 56ch;
7261-}
7262-
7263-/* Nav */
7264-.lv-nav {
7265- position: sticky;
7266- top: 0;
7267- z-index: 60;
7268- backdrop-filter: saturate(180%) blur(14px);
7269- -webkit-backdrop-filter: saturate(180%) blur(14px);
7270- background: rgba(252,252,253,0.8);
7271- border-bottom: 1px solid rgba(22,24,29,0.07);
7272-}
7273-
7274-.lv-nav-inner {
7275- max-width: 1200px;
7276- margin: 0 auto;
7277- padding: 14px 28px;
7278- display: flex;
7279- align-items: center;
7280- gap: 28px;
7281-}
7282-
7283-.lv-logo {
7284- display: inline-flex;
7285- align-items: center;
7286- gap: 9px;
7287- font-family: 'Inter Tight', sans-serif;
7288- font-weight: 700;
7289- font-size: 17px;
7290- letter-spacing: -0.02em;
7291- color: #16181d;
7292- text-decoration: none;
7293-}
7294-
7295-.lv-logo-mark {
7296- width: 17px;
7297- height: 17px;
7298- border-radius: 5px;
7299- background: #4353c9;
7300- display: inline-block;
7301- flex-shrink: 0;
7302-}
7303-
7304-.lv-nav-links {
7305- display: flex;
7306- gap: 24px;
7307- font-size: 13.5px;
7308- font-weight: 500;
7309-}
7310-
7311-.lv-nav-link {
7312- color: #6b7080;
7313- text-decoration: none;
7314- transition: color 0.15s;
7315-}
7316-.lv-nav-link:hover { color: #16181d; }
7317-
7318-.lv-nav-ctas {
7319- margin-left: auto;
7320- display: flex;
7321- align-items: center;
7322- gap: 10px;
7323-}
7324-
7325-.lv-btn-secondary {
7326- padding: 8px 15px;
7327- border-radius: 8px;
7328- font-size: 13.5px;
7329- font-weight: 500;
7330- color: #16181d;
7331- border: 1px solid rgba(22,24,29,0.12);
7332- background: #ffffff;
7333- text-decoration: none;
7334- white-space: nowrap;
7335- transition: border-color 0.15s;
7336-}
7337-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
7338-
7339-.lv-btn-primary {
7340- padding: 8px 15px;
7341- border-radius: 8px;
7342- font-size: 13.5px;
7343- font-weight: 600;
7344- background: #16181d;
7345- color: #fff;
7346- text-decoration: none;
7347- white-space: nowrap;
7348- transition: box-shadow 0.15s;
7349-}
7350-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
7351-
7352-/* Hero */
7353-.lv-hero {
7354- position: relative;
7355- overflow: hidden;
7356- padding: 88px 0 0;
7357-}
7358-
7359-.lv-hero-glow {
7360- position: absolute;
7361- inset: -10% 0 auto 0;
7362- height: 640px;
7363- pointer-events: none;
7364- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
7365-}
7366-
7367-.lv-hero-inner {
7368- position: relative;
7369- max-width: 1200px;
7370- margin: 0 auto;
7371- padding: 0 28px;
7372- text-align: center;
7373-}
7374-
7375-.lv-hero-badge {
7376- display: inline-flex;
7377- align-items: center;
7378- gap: 9px;
7379- font-size: 12.5px;
7380- font-weight: 600;
7381- color: #3a3d45;
7382- background: #ffffff;
7383- border: 1px solid rgba(22,24,29,0.10);
7384- border-radius: 9999px;
7385- padding: 7px 16px;
7386- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
7387-}
7388-
7389-.lv-hero-sub {
7390- font-size: clamp(16px, 2vw, 19px);
7391- color: #6b7080;
7392- max-width: 60ch;
7393- margin: 24px auto 0;
7394- font-weight: 450;
7395- line-height: 1.65;
7396-}
7397-
7398-.lv-hero-actions {
7399- display: flex;
7400- gap: 12px;
7401- justify-content: center;
7402- flex-wrap: wrap;
7403- margin-top: 32px;
7404-}
7405-
7406-.lv-cta-primary {
7407- padding: 13px 24px;
7408- border-radius: 11px;
7409- font-size: 15.5px;
7410- font-weight: 600;
7411- background: #16181d;
7412- color: #fff;
7413- text-decoration: none;
7414- white-space: nowrap;
7415- transition: box-shadow 0.15s;
7416-}
7417-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
7418-
7419-.lv-cta-secondary {
7420- padding: 13px 24px;
7421- border-radius: 11px;
7422- font-size: 15.5px;
7423- font-weight: 600;
7424- color: #16181d;
7425- border: 1px solid rgba(22,24,29,0.14);
7426- background: #ffffff;
7427- text-decoration: none;
7428- white-space: nowrap;
7429- transition: border-color 0.15s;
7430-}
7431-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
7432-
7433-.lv-hero-tag {
7434- margin-top: 18px;
7435- font-family: 'JetBrains Mono', monospace;
7436- font-size: 11.5px;
7437- letter-spacing: 0.08em;
7438- text-transform: uppercase;
7439- color: #8a8d99;
7440-}
7441-
7442-/* Demo window */
7443-.lv-demo-window {
7444- margin: 56px auto 0;
7445- max-width: 860px;
7446- text-align: left;
7447- background: #ffffff;
7448- border: 1px solid rgba(22,24,29,0.09);
7449- border-radius: 18px;
7450- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
7451- overflow: hidden;
7452-}
7453-
7454-.lv-demo-bar {
7455- display: flex;
7456- align-items: center;
7457- gap: 7px;
7458- padding: 12px 18px;
7459- border-bottom: 1px solid rgba(22,24,29,0.07);
7460- background: #fcfcfd;
7461-}
7462-
7463-.lv-demo-dot {
7464- width: 10px;
7465- height: 10px;
7466- border-radius: 50%;
7467- background: #e4e5ea;
7468-}
7469-
7470-.lv-demo-url {
7471- margin-left: 10px;
7472- font-family: 'JetBrains Mono', monospace;
7473- font-size: 12px;
7474- color: #6b7080;
7475-}
7476-
7477-.lv-demo-live {
7478- margin-left: auto;
7479- display: inline-flex;
7480- align-items: center;
7481- gap: 6px;
7482- font-size: 11px;
7483- font-weight: 600;
7484- color: #1e7f5c;
7485-}
7486-
7487-.lv-demo-body {
7488- padding: 22px 24px;
7489-}
7490-
7491-.lv-demo-event {
7492- display: grid;
7493- grid-template-columns: 18px minmax(0, 1fr);
7494- gap: 14px;
7495- padding-bottom: 20px;
7496- position: relative;
7497-}
7498-.lv-demo-event:last-child { padding-bottom: 0; }
7499-
7500-.lv-demo-event-track {
7501- display: flex;
7502- flex-direction: column;
7503- align-items: center;
7504-}
7505-
7506-.lv-demo-line {
7507- width: 1px;
7508- flex: 1;
7509- background: rgba(22,24,29,0.08);
7510- margin-top: 5px;
7511- min-height: 20px;
7512-}
7513-
7514-.lv-demo-event-content {}
7515-
7516-.lv-demo-event-header {
7517- display: flex;
7518- align-items: baseline;
7519- gap: 10px;
7520-}
7521-
7522-.lv-demo-event-title {
7523- font-size: 13.5px;
7524- font-weight: 600;
7525- color: #16181d;
7526-}
7527-
7528-.lv-demo-event-time {
7529- font-family: 'JetBrains Mono', monospace;
7530- font-size: 11px;
7531- color: #8a8d99;
7532-}
7533-
7534-.lv-demo-event-body {
7535- font-size: 13px;
7536- color: #6b7080;
7537- margin-top: 2px;
7538-}
7539-
7540-/* Ticker */
7541-.lv-ticker-wrap {
7542- border-top: 1px solid rgba(22,24,29,0.07);
7543- border-bottom: 1px solid rgba(22,24,29,0.07);
7544- background: #ffffff;
7545- margin-top: 64px;
7546- overflow: hidden;
7547- white-space: nowrap;
7548- position: relative;
7549-}
7550-
7551-.lv-ticker-track {
7552- display: inline-flex;
7553- animation: gcTicker 40s linear infinite;
7554- padding: 11px 0;
7555-}
7556-
7557-.lv-ticker-item {
7558- display: inline-flex;
7559- align-items: center;
7560- gap: 8px;
7561- font-family: 'JetBrains Mono', monospace;
7562- font-size: 11.5px;
7563- color: #6b7080;
7564- padding: 0 28px;
7565- border-right: 1px solid rgba(22,24,29,0.06);
7566-}
7567-
7568-/* Stats */
7569-.lv-stats {
7570- background: #fcfcfd;
7571-}
7572-
7573-.lv-stats-inner {
7574- max-width: 1200px;
7575- margin: 0 auto;
7576- display: grid;
7577- grid-template-columns: repeat(4, 1fr);
7578- gap: 24px;
7579- padding: 52px 28px;
7580-}
7581-
7582-.lv-stat {
7583- text-align: center;
7584-}
7585-
7586-.lv-stat-num {
7587- font-family: 'Inter Tight', sans-serif;
7588- font-weight: 700;
7589- font-size: clamp(30px, 4vw, 44px);
7590- letter-spacing: -0.025em;
7591- color: #111318;
7592-}
7593-
7594-.lv-stat-label {
7595- font-size: 13px;
7596- color: #6b7080;
7597- margin-top: 4px;
7598-}
7599-
7600-/* Loop */
7601-.lv-loop {
7602- padding: 96px 0;
7603- background: #ffffff;
7604- border-top: 1px solid rgba(22,24,29,0.07);
7605- border-bottom: 1px solid rgba(22,24,29,0.07);
7606-}
7607-
7608-.lv-loop-inner {
7609- max-width: 1200px;
7610- margin: 0 auto;
7611- padding: 0 28px;
7612-}
7613-
7614-.lv-stages {
7615- display: grid;
7616- grid-template-columns: repeat(6, 1fr);
7617- gap: 12px;
7618-}
7619-
7620-.lv-stage-card {
7621- border: 1px solid rgba(22,24,29,0.08);
7622- border-radius: 14px;
7623- background: #ffffff;
7624- padding: 20px 18px;
7625- transition: border-color 0.3s, background 0.3s;
7626-}
7627-
7628-.lv-stage-card.lv-stage-active {
7629- border-color: rgba(67,83,201,0.45);
7630- background: rgba(67,83,201,0.03);
7631-}
7632-
7633-.lv-stage-header {
7634- display: flex;
7635- align-items: center;
7636- gap: 8px;
7637- margin-bottom: 10px;
7638-}
7639-
7640-.lv-stage-n {
7641- font-family: 'JetBrains Mono', monospace;
7642- font-size: 10.5px;
7643- letter-spacing: 0.1em;
7644- text-transform: uppercase;
7645- color: #8a8d99;
7646-}
7647-
7648-.lv-stage-name {
7649- font-family: 'Inter Tight', sans-serif;
7650- font-size: 16px;
7651- font-weight: 600;
7652- letter-spacing: -0.01em;
7653- color: #16181d;
7654- margin-bottom: 5px;
7655-}
7656-
7657-.lv-stage-desc {
7658- font-size: 12px;
7659- color: #6b7080;
7660- line-height: 1.55;
7661-}
7662-
7663-.lv-stage-meta {
7664- font-family: 'JetBrains Mono', monospace;
7665- font-size: 10.5px;
7666- color: #8a8d99;
7667- margin-top: 10px;
7668- transition: color 0.3s;
7669-}
7670-
7671-.lv-stage-meta.lv-stage-meta-active {
7672- color: #4353c9;
7673-}
7674-
7675-/* Heroes */
7676-.lv-heroes {
7677- padding: 96px 0;
7678- background: #fcfcfd;
7679-}
7680-
7681-.lv-heroes-inner {
7682- max-width: 1200px;
7683- margin: 0 auto;
7684- padding: 0 28px;
7685-}
7686-
7687-.lv-heroes-header {
7688- max-width: 640px;
7689- margin-bottom: 56px;
7690-}
7691-
7692-.lv-heroes-list {
7693- display: flex;
7694- flex-direction: column;
7695- gap: 20px;
7696-}
7697-
7698-.lv-hero-card {
7699- display: grid;
7700- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
7701- gap: 48px;
7702- align-items: center;
7703- border: 1px solid rgba(22,24,29,0.08);
7704- border-radius: 20px;
7705- background: #ffffff;
7706- padding: 44px 48px;
7707- text-decoration: none;
7708- transition: border-color 0.2s, box-shadow 0.2s;
7709-}
7710-.lv-hero-card:hover {
7711- border-color: rgba(22,24,29,0.22);
7712- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
7713-}
7714-
7715-.lv-hero-card-left {}
7716-
7717-.lv-hero-card-title {
7718- font-family: 'Inter Tight', sans-serif;
7719- font-size: 26px;
7720- font-weight: 600;
7721- letter-spacing: -0.022em;
7722- line-height: 1.15;
7723- color: #16181d;
7724- margin: 0 0 12px;
7725-}
7726-
7727-.lv-hero-card-body {
7728- font-size: 14.5px;
7729- color: #6b7080;
7730- margin: 0 0 18px;
7731- line-height: 1.65;
7732-}
7733-
7734-.lv-hero-card-cta {
7735- font-size: 13.5px;
7736- font-weight: 600;
7737- color: #4353c9;
7738-}
7739-
7740-.lv-terminal {
7741- border: 1px solid rgba(22,24,29,0.07);
7742- border-radius: 14px;
7743- background: #fcfcfd;
7744- padding: 20px 22px;
7745- font-family: 'JetBrains Mono', monospace;
7746- font-size: 12px;
7747- line-height: 1.9;
7748- overflow: hidden;
7749-}
7750-
7751-.lv-terminal-line {
7752- display: flex;
7753- align-items: center;
7754- gap: 10px;
7755- white-space: nowrap;
7756- overflow: hidden;
7757- text-overflow: ellipsis;
7758-}
7759-
7760-/* Platform */
7761-.lv-platform {
7762- padding: 96px 0;
7763- background: #ffffff;
7764- border-top: 1px solid rgba(22,24,29,0.07);
7765-}
7766-
7767-.lv-platform-inner {
7768- max-width: 1200px;
7769- margin: 0 auto;
7770- padding: 0 28px;
7771-}
7772-
7773-.lv-cap-grid {
7774- display: grid;
7775- grid-template-columns: repeat(4, 1fr);
7776- gap: 24px 32px;
7777-}
7778-
7779-.lv-cap-col {}
7780-
7781-.lv-cap-group {
7782- font-family: 'JetBrains Mono', monospace;
7783- font-size: 10.5px;
7784- letter-spacing: 0.12em;
7785- text-transform: uppercase;
7786- color: #8a8d99;
7787- font-weight: 500;
7788- margin-bottom: 12px;
7789- padding-bottom: 8px;
7790- border-bottom: 1px solid rgba(22,24,29,0.07);
7791-}
7792-
7793-.lv-cap-items {
7794- display: flex;
7795- flex-direction: column;
7796- gap: 7px;
7797-}
7798-
7799-.lv-cap-item {
7800- font-size: 12.5px;
7801- color: #3a3d45;
7802- line-height: 1.45;
7803-}
7804-
7805-/* Sovereignty */
7806-.lv-sovereign {
7807- position: relative;
7808- overflow: hidden;
7809- padding: 104px 0;
7810- color: #fff;
7811- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
7812-}
7813-
7814-.lv-sovereign-grid-bg {
7815- position: absolute;
7816- inset: 0;
7817- opacity: 0.4;
7818- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
7819- background-size: 56px 56px;
7820- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
7821- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
7822-}
7823-
7824-.lv-sovereign-inner {
7825- position: relative;
7826- max-width: 1200px;
7827- margin: 0 auto;
7828- padding: 0 28px;
7829-}
7830-
7831-.lv-section-header-dark {
7832- max-width: 680px;
7833- margin: 0 auto 48px;
7834- text-align: center;
7835-}
7836-
7837-.lv-layers-grid {
7838- display: grid;
7839- grid-template-columns: repeat(4, 1fr);
7840- gap: 10px;
7841- max-width: 980px;
7842- margin: 0 auto;
7843-}
7844-
7845-.lv-layer-chip {
7846- border: 1px solid rgba(255,255,255,0.10);
7847- border-radius: 10px;
7848- padding: 12px 16px;
7849- background: rgba(255,255,255,0.03);
7850-}
7851-
7852-.lv-layer-cta {
7853- border-color: rgba(169,180,238,0.30);
7854- background: rgba(169,180,238,0.06);
7855- display: flex;
7856- align-items: center;
7857- text-decoration: none;
7858- transition: background 0.15s;
7859-}
7860-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
7861-
7862-.lv-layer-cta-text {
7863- font-size: 13px;
7864- font-weight: 500;
7865- color: #a9b4ee;
7866-}
7867-
7868-.lv-layer-n {
7869- font-family: 'JetBrains Mono', monospace;
7870- font-size: 10px;
7871- color: rgba(255,255,255,0.4);
7872- margin-bottom: 3px;
7873-}
7874-
7875-.lv-layer-name {
7876- font-size: 13px;
7877- font-weight: 500;
7878- color: rgba(255,255,255,0.92);
7879-}
7880-
7881-.lv-sovereign-feats {
7882- display: flex;
7883- gap: 44px;
7884- justify-content: center;
7885- flex-wrap: wrap;
7886- margin-top: 52px;
7887- text-align: center;
7888-}
7889-
7890-.lv-sovereign-feat {}
7891-
7892-.lv-sovereign-feat-title {
7893- font-family: 'Inter Tight', sans-serif;
7894- font-size: 20px;
7895- font-weight: 700;
7896- color: #fff;
7897-}
7898-
7899-.lv-sovereign-feat-sub {
7900- color: rgba(255,255,255,0.55);
7901- font-size: 13px;
7902- margin-top: 2px;
7903-}
7904-
7905-/* Twin cards */
7906-.lv-twin {
7907- padding: 96px 0;
7908- background: #fcfcfd;
7909-}
7910-
7911-.lv-twin-inner {
7912- max-width: 1200px;
7913- margin: 0 auto;
7914- padding: 0 28px;
7915- display: grid;
7916- grid-template-columns: 1fr 1fr;
7917- gap: 24px;
7918-}
7919-
7920-.lv-twin-card {
7921- border: 1px solid rgba(22,24,29,0.08);
7922- border-radius: 20px;
7923- background: #ffffff;
7924- padding: 44px 48px;
7925-}
7926-
7927-.lv-twin-title {
7928- font-family: 'Inter Tight', sans-serif;
7929- font-size: 24px;
7930- font-weight: 600;
7931- letter-spacing: -0.02em;
7932- line-height: 1.2;
7933- margin: 0 0 12px;
7934- color: #16181d;
7935-}
7936-
7937-.lv-twin-body {
7938- font-size: 14.5px;
7939- color: #6b7080;
7940- margin: 0 0 16px;
7941- line-height: 1.7;
7942-}
7943-
7944-.lv-twin-link {
7945- font-size: 13.5px;
7946- font-weight: 600;
7947- color: #4353c9;
7948- text-decoration: none;
7949-}
7950-.lv-twin-link:hover { text-decoration: underline; }
7951-
7952-/* Quote */
7953-.lv-quote {
7954- padding: 40px 0 96px;
7955- background: #fcfcfd;
7956-}
7957-
7958-.lv-quote-inner {
7959- max-width: 980px;
7960- margin: 0 auto;
7961- padding: 0 28px;
7962- text-align: center;
7963-}
7964-
7965-.lv-quote-text {
7966- font-family: 'Inter Tight', sans-serif;
7967- font-weight: 600;
7968- font-size: clamp(26px, 3.8vw, 42px);
7969- line-height: 1.2;
7970- letter-spacing: -0.025em;
7971- margin: 0;
7972- color: #111318;
7973-}
7974-
7975-.lv-em {
7976- font-style: normal;
7977- color: #4353c9;
7978-}
7979-
7980-/* CTA */
7981-.lv-cta-section {
7982- padding: 0 0 104px;
7983- background: #fcfcfd;
7984-}
7985-
7986-.lv-cta-card {
7987- max-width: 820px;
7988- margin: 0 auto;
7989- padding: 64px 40px;
7990- text-align: center;
7991- background: #ffffff;
7992- border: 1px solid rgba(22,24,29,0.08);
7993- border-radius: 26px;
7994- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
7995- position: relative;
7996- overflow: hidden;
7997-}
7998-
7999-.lv-cta-glow {
8000- position: absolute;
8001- inset: -40% 0 auto 0;
8002- height: 280px;
8003- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
8004- pointer-events: none;
8005-}
8006-
8007-.lv-cta-h2 {
8008- font-family: 'Inter Tight', sans-serif;
8009- font-weight: 700;
8010- letter-spacing: -0.028em;
8011- font-size: clamp(30px, 4.6vw, 48px);
8012- margin: 0;
8013- position: relative;
8014- color: #111318;
8015-}
8016-
8017-.lv-cta-sub {
8018- color: #6b7080;
8019- font-size: 17px;
8020- margin: 16px 0 30px;
8021- position: relative;
8022-}
8023-
8024-.lv-cta-actions {
8025- display: flex;
8026- gap: 12px;
8027- justify-content: center;
8028- flex-wrap: wrap;
8029- position: relative;
8030-}
8031-
8032-.lv-cta-fine {
8033- margin-top: 20px;
8034- font-family: 'JetBrains Mono', monospace;
8035- font-size: 11px;
8036- color: #8a8d99;
8037- position: relative;
8038-}
8039-
8040-/* Footer */
8041-.lv-footer {
8042- border-top: 1px solid rgba(22,24,29,0.07);
8043- background: #ffffff;
8044- padding: 56px 0 30px;
8045-}
8046-
8047-.lv-footer-inner {
8048- max-width: 1200px;
8049- margin: 0 auto;
8050- padding: 0 28px;
8051- display: flex;
8052- gap: 48px;
8053- flex-wrap: wrap;
8054- justify-content: space-between;
8055-}
8056-
8057-.lv-footer-brand {}
8058-
8059-.lv-footer-tagline {
8060- color: #6b7080;
8061- font-size: 13.5px;
8062- margin: 12px 0 0;
8063- max-width: 32ch;
8064- line-height: 1.6;
8065-}
8066-
8067-.lv-footer-cols {
8068- display: flex;
8069- gap: 64px;
8070- flex-wrap: wrap;
8071-}
8072-
8073-.lv-footer-col {
8074- display: flex;
8075- flex-direction: column;
8076- gap: 9px;
8077-}
8078-
8079-.lv-footer-col-head {
8080- font-family: 'JetBrains Mono', monospace;
8081- font-size: 11px;
8082- text-transform: uppercase;
8083- letter-spacing: 0.1em;
8084- color: #8a8d99;
8085- margin: 0 0 4px;
8086- font-weight: 500;
8087-}
8088-
8089-.lv-footer-link {
8090- color: #3a3d45;
8091- font-size: 13.5px;
8092- text-decoration: none;
8093- transition: color 0.15s;
8094-}
8095-.lv-footer-link:hover { color: #16181d; }
8096-
8097-.lv-footer-bar {
8098- max-width: 1200px;
8099- margin: 44px auto 0;
8100- padding: 22px 28px 0;
8101- border-top: 1px solid rgba(22,24,29,0.06);
8102- display: flex;
8103- justify-content: space-between;
8104- flex-wrap: wrap;
8105- gap: 8px;
8106- color: #8a8d99;
8107- font-size: 12.5px;
8108-}
8109-
8110-.lv-footer-stack {
8111- font-family: 'JetBrains Mono', monospace;
8112- font-size: 11px;
8113-}
8114-`;
8115diff --git a/src/views/layout.tsx b/src/views/layout.tsx
8116index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
8117--- a/src/views/layout.tsx
8118+++ b/src/views/layout.tsx
8119@@ -3153,9 +3153,12 @@
8120 font-weight: 500;
8121 line-height: 1.4;
8122 }
8123- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
8124- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
8125- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
8126+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
8127+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
8128+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
8129+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
8130+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
8131+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
8132 .state-merged { color: var(--accent); }
8133 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
8134
8135diff --git a/src/views/ui.tsx b/src/views/ui.tsx
8136index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
8137--- a/src/views/ui.tsx
8138+++ b/src/views/ui.tsx
8139@@ -232,7 +232,7 @@
8140
8141 export const Badge: FC<
8142 PropsWithChildren<{
8143- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
8144+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
8145 style?: string;
8146 }>
8147 > = ({ children, variant = "default", style }) => {
8148@@ -241,9 +241,12 @@
8149 variant === "closed" ? "badge-closed" :
8150 variant === "merged" ? "badge-merged" :
8151 variant === "success" ? "badge-success" :
8152- variant === "danger" ? "badge-danger" :
8153- variant === "warning" ? "badge-warning" :
8154- "badge";
8155+ variant === "danger" ? "badge-danger" :
8156+ variant === "warning" ? "badge-warning" :
8157+ variant === "live" ? "badge-live" :
8158+ variant === "soon" ? "badge-soon" :
8159+ variant === "preview" ? "badge-preview" :
8160+ "badge";
8161 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
8162 };
8163
8164
8165codex
8166Typecheck and the full test suite are running concurrently. The source-level checks already show the deleted file has no remaining `src/` reference and the protected violet/functional icon colors remain
8167unchanged.
8168diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
8169index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
8170--- a/src/views/landing-pro.tsx
8171+++ b/src/views/landing-pro.tsx
8172@@ -42,7 +42,7 @@
8173
8174 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8175
8176-function icon(paths: string, color = "#4353c9", size = 20) {
8177+function icon(paths: string, color = "#0891b2", size = 20) {
8178 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
8179 }
8180
8181@@ -947,7 +947,7 @@
8182 const css = `
8183 /* %% tokens %% */
8184 :root{
8185- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
8186+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
8187 --lp-bg:#ffffff;--lp-soft:#fafafb;
8188 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
8189 --lp-border:rgba(0,0,0,.08);
8190diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
8191deleted file mode 100644
8192index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
8193--- a/src/views/landing-v2.tsx
8194+++ /dev/null
8195@@ -1,1447 +0,0 @@
8196-import type { FC } from "hono/jsx";
8197-
8198-export interface LandingPageProps {
8199- stats?: {
8200- publicRepos?: number;
8201- users?: number;
8202- };
8203-}
8204-
8205-const demoAllEvents = [
8206- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
8207- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
8208- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
8209- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
8210- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
8211-];
8212-
8213-const tickerItems = [
8214- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
8215- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
8216- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
8217- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
8218- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
8219- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
8220- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
8221- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
8222- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
8223- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
8224- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
8225- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
8226- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
8227- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
8228- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
8229- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
8230-];
8231-
8232-const stageData = [
8233- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
8234- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
8235- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
8236- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
8237- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
8238- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
8239-];
8240-
8241-const heroFeatures = [
8242- {
8243- href: "/",
8244- eyebrow: "01 � The autonomous repair loop",
8245- title: "Failures fix themselves  and show their work.",
8246- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
8247failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
8248- cta: "Watch a live repair session",
8249- mock: [
8250- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
8251- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
8252- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
8253- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
8254- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
8255- ],
8256- },
8257- {
8258- href: "/",
8259- eyebrow: "02 � Live sandbox isolation",
8260- title: "Every PR gets its own instant, disposable environment.",
8261- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
8262same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
8263- cta: "See a PR with its sandbox",
8264- mock: [
8265- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
8266- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
8267- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
8268- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
8269- ],
8270- },
8271- {
8272- href: "/",
8273- eyebrow: "03 � Multiplayer IDE workspaces",
8274- title: "You and the agent, side by side, in your editor.",
8275- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
8276agent into a silent reviewer in your gutter. The browser becomes optional.",
8277- cta: "See the editor session",
8278- mock: [
8279- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
8280- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
8281- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
8282- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
8283- ],
8284- },
8285-];
8286-
8287-const capabilities = [
8288- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
8289- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
8290- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
8291- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
8292- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
8293- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
8294- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
8295- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
8296-];
8297-
8298-const sovereignLayerNames = [
8299- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
8300- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
8301- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
8302- "Availability & recovery",
8303-];
8304-
8305-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
8306- return (
8307- <>
8308- <style dangerouslySetInnerHTML={{ __html: css }} />
8309-
8310- {/* Nav */}
8311- <header class="lv-nav">
8312- <div class="lv-nav-inner">
8313- <a href="/" class="lv-logo">
8314- <span class="lv-logo-mark"></span>gluecron
8315- </a>
8316- <nav class="lv-nav-links">
8317- <a href="#loop" class="lv-nav-link">The loop</a>
8318- <a href="#platform" class="lv-nav-link">Platform</a>
8319- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
8320- <a href="/trust" class="lv-nav-link">Trust</a>
8321- </nav>
8322- <div class="lv-nav-ctas">
8323- <a href="/login" class="lv-btn-secondary">Sign in</a>
8324- <a href="/register" class="lv-btn-primary">Start building</a>
8325- </div>
8326- </div>
8327- </header>
8328-
8329- {/* Hero */}
8330- <section class="lv-hero">
8331- <div class="lv-hero-glow"></div>
8332- <div class="lv-hero-inner">
8333- <div class="lv-hero-badge">
8334- <span class="lv-dot lv-dot-green lv-pulse"></span>
8335- Live: a repair loop converged on pr-218 while you read this
8336- </div>
8337- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
8338- <p class="lv-hero-sub">
8339- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
8340failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
8341- </p>
8342- <div class="lv-hero-actions">
8343- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
8344- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
8345- </div>
8346- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
8347-
8348- {/* Live product window */}
8349- <div class="lv-demo-window">
8350- <div class="lv-demo-bar">
8351- <span class="lv-demo-dot"></span>
8352- <span class="lv-demo-dot"></span>
8353- <span class="lv-demo-dot"></span>
8354- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
8355- <span class="lv-demo-live">
8356- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
8357- LIVE
8358- </span>
8359- </div>
8360- <div class="lv-demo-body" id="lv-demo-body">
8361- {/* Events rendered by JS */}
8362- {demoAllEvents.slice(0, 1).map((e, i) => (
8363- <div class="lv-demo-event" key={i}>
8364- <div class="lv-demo-event-track">
8365- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
8366- <span class="lv-demo-line" style="display:none"></span>
8367- </div>
8368- <div class="lv-demo-event-content">
8369- <div class="lv-demo-event-header">
8370- <span class="lv-demo-event-title">{e.title}</span>
8371- <span class="lv-demo-event-time">{e.time}</span>
8372- </div>
8373- <div class="lv-demo-event-body">{e.body}</div>
8374- </div>
8375- </div>
8376- ))}
8377- </div>
8378- </div>
8379- </div>
8380-
8381- {/* Activity ticker */}
8382- <div class="lv-ticker-wrap">
8383- <div class="lv-ticker-track">
8384- {tickerItems.map((t, i) => (
8385- <span class="lv-ticker-item" key={i}>
8386- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
8387- {t.text}
8388- </span>
8389- ))}
8390- </div>
8391- </div>
8392- </section>
8393-
8394- {/* Stat band */}
8395- <section class="lv-stats">
8396- <div class="lv-stats-inner">
8397- <div class="lv-stat">
8398- <div class="lv-stat-num">Sonnet 5</div>
8399- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
8400- </div>
8401- <div class="lv-stat">
8402- <div class="lv-stat-num">93.5%</div>
8403- <div class="lv-stat-label">of failures self-repair without a human</div>
8404- </div>
8405- <div class="lv-stat">
8406- <div class="lv-stat-num">1.9%</div>
8407- <div class="lv-stat-label">AI merges reverted  published live</div>
8408- </div>
8409- <div class="lv-stat">
8410- <div class="lv-stat-num">0</div>
8411- <div class="lv-stat-label">irreversible actions taken autonomously</div>
8412- </div>
8413- </div>
8414- </section>
8415-
8416- {/* The loop */}
8417- <section id="loop" class="lv-loop">
8418- <div class="lv-loop-inner">
8419- <div class="lv-section-header">
8420- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
8421- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
8422- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
8423- </div>
8424- <div class="lv-stages" id="lv-stages">
8425- {stageData.map((s, i) => (
8426- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
8427- <div class="lv-stage-header">
8428- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
8429- <span class="lv-stage-n">0{i + 1}</span>
8430- </div>
8431- <div class="lv-stage-name">{s.name}</div>
8432- <div class="lv-stage-desc">{s.desc}</div>
8433- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
8434- </div>
8435- ))}
8436- </div>
8437- </div>
8438- </section>
8439-
8440- {/* Three heroes */}
8441- <section class="lv-heroes">
8442- <div class="lv-heroes-inner">
8443- <div class="lv-heroes-header">
8444- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
8445- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
8446- </div>
8447- <div class="lv-heroes-list">
8448- {heroFeatures.map((h, i) => (
8449- <a href={h.href} class="lv-hero-card" key={i}>
8450- <div class="lv-hero-card-left">
8451- <div class="lv-eyebrow">{h.eyebrow}</div>
8452- <h3 class="lv-hero-card-title">{h.title}</h3>
8453- <p class="lv-hero-card-body">{h.body}</p>
8454- <span class="lv-hero-card-cta">{h.cta} �!</span>
8455- </div>
8456- <div class="lv-terminal">
8457- {h.mock.map((m, j) => (
8458- <div class="lv-terminal-line" key={j}>
8459- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
8460- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
8461- </div>
8462- ))}
8463- </div>
8464- </a>
8465- ))}
8466- </div>
8467- </div>
8468- </section>
8469-
8470- {/* Everything grid */}
8471- <section id="platform" class="lv-platform">
8472- <div class="lv-platform-inner">
8473- <div class="lv-section-header lv-section-header-center">
8474- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
8475- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
8476- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
8477- </div>
8478- <div class="lv-cap-grid">
8479- {capabilities.map((c, i) => (
8480- <div class="lv-cap-col" key={i}>
8481- <div class="lv-cap-group">{c.group}</div>
8482- <div class="lv-cap-items">
8483- {c.items.map((item, j) => (
8484- <div class="lv-cap-item" key={j}>{item}</div>
8485- ))}
8486- </div>
8487- </div>
8488- ))}
8489- </div>
8490- </div>
8491- </section>
8492-
8493- {/* Sovereignty band */}
8494- <section id="sovereign" class="lv-sovereign">
8495- <div class="lv-sovereign-grid-bg"></div>
8496- <div class="lv-sovereign-inner">
8497- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
8498- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
8499- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
8500- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
8501to private cloud, or run fully air-gapped on bare metal.</p>
8502- </div>
8503- <div class="lv-layers-grid">
8504- {sovereignLayerNames.map((name, i) => (
8505- <div class="lv-layer-chip" key={i}>
8506- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
8507- <div class="lv-layer-name">{name}</div>
8508- </div>
8509- ))}
8510- <a href="/" class="lv-layer-chip lv-layer-cta">
8511- <div class="lv-layer-cta-text">All self-owned �!</div>
8512- </a>
8513- </div>
8514- <div class="lv-sovereign-feats">
8515- <div class="lv-sovereign-feat">
8516- <div class="lv-sovereign-feat-title">Local inference first</div>
8517- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
8518- </div>
8519- <div class="lv-sovereign-feat">
8520- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
8521- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
8522- </div>
8523- <div class="lv-sovereign-feat">
8524- <div class="lv-sovereign-feat-title">Self-healing infra</div>
8525- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
8526- </div>
8527- </div>
8528- </div>
8529- </section>
8530-
8531- {/* Manual-first + reversibility */}
8532- <section class="lv-twin">
8533- <div class="lv-twin-inner">
8534- <div class="lv-twin-card">
8535- <div class="lv-eyebrow">Manual-first, always</div>
8536- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
8537- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
8538fallback. Developers who never touch AI get the best git host they've ever used.</p>
8539- </div>
8540- <div class="lv-twin-card">
8541- <div class="lv-eyebrow">The reversibility guarantee</div>
8542- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
8543- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
8544 policy, not promise. Our quality numbers are published live, unedited.</p>
8545- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
8546- </div>
8547- </div>
8548- </section>
8549-
8550- {/* Quote */}
8551- <section class="lv-quote">
8552- <div class="lv-quote-inner">
8553- <p class="lv-quote-text">
8554- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
8555- Gluecron is where code gets <em class="lv-em">finished</em>."
8556- </p>
8557- </div>
8558- </section>
8559-
8560- {/* CTA */}
8561- <section class="lv-cta-section">
8562- <div class="lv-cta-card">
8563- <div class="lv-cta-glow"></div>
8564- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
8565- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
8566- <div class="lv-cta-actions">
8567- <a href="/register" class="lv-cta-primary">Create your account �!</a>
8568- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
8569- </div>
8570- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
8571- </div>
8572- </section>
8573-
8574- {/* Footer */}
8575- <footer class="lv-footer">
8576- <div class="lv-footer-inner">
8577- <div class="lv-footer-brand">
8578- <a href="/" class="lv-logo">
8579- <span class="lv-logo-mark"></span>gluecron
8580- </a>
8581- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
8582- </div>
8583- <div class="lv-footer-cols">
8584- <div class="lv-footer-col">
8585- <h4 class="lv-footer-col-head">Product</h4>
8586- <a href="/" class="lv-footer-link">Agent workspace</a>
8587- <a href="/" class="lv-footer-link">Fleet refactors</a>
8588- <a href="/" class="lv-footer-link">Org memory</a>
8589- <a href="/" class="lv-footer-link">IDE extensions</a>
8590- </div>
8591- <div class="lv-footer-col">
8592- <h4 class="lv-footer-col-head">Platform</h4>
8593- <a href="/" class="lv-footer-link">Production layers</a>
8594- <a href="/trust" class="lv-footer-link">Trust report</a>
8595- <a href="/" class="lv-footer-link">Docs</a>
8596- <a href="/" class="lv-footer-link">Status</a>
8597- </div>
8598- <div class="lv-footer-col">
8599- <h4 class="lv-footer-col-head">Company</h4>
8600- <a href="/" class="lv-footer-link">About</a>
8601- <a href="/" class="lv-footer-link">Pricing</a>
8602- <a href="/" class="lv-footer-link">Enterprise</a>
8603- </div>
8604- </div>
8605- </div>
8606- <div class="lv-footer-bar">
8607- <span>� 2026 Gluecron</span>
8608- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
8609- </div>
8610- </footer>
8611-
8612- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
8613- </>
8614- );
8615-};
8616-
8617-export const LandingPage = LandingPageV2;
8618-export default LandingPageV2;
8619-
8620-const clientScript = `
8621-(function() {
8622- var demoAll = [
8623- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
8624- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
8625- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
8626- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
8627- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
8628- ];
8629-
8630- var demoStep = 0;
8631- var stage = 0;
8632-
8633- function renderDemo() {
8634- var container = document.getElementById('lv-demo-body');
8635- if (!container) return;
8636- var visible = demoAll.slice(0, demoStep + 1);
8637- container.innerHTML = visible.map(function(e, i) {
8638- var isLast = i === visible.length - 1;
8639- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
8640- return '<div class="lv-demo-event">' +
8641- '<div class="lv-demo-event-track">' +
8642- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
8643- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
8644- '</div>' +
8645- '<div class="lv-demo-event-content">' +
8646- '<div class="lv-demo-event-header">' +
8647- '<span class="lv-demo-event-title">' + e.title + '</span>' +
8648- '<span class="lv-demo-event-time">' + e.time + '</span>' +
8649- '</div>' +
8650- '<div class="lv-demo-event-body">' + e.body + '</div>' +
8651- '</div>' +
8652- '</div>';
8653- }).join('');
8654- }
8655-
8656- function renderStages() {
8657- var cards = document.querySelectorAll('.lv-stage-card');
8658- cards.forEach(function(card, i) {
8659- var dot = card.querySelector('.lv-dot');
8660- var meta = card.querySelector('.lv-stage-meta');
8661- if (i === stage) {
8662- card.classList.add('lv-stage-active');
8663- if (dot) {
8664- dot.classList.remove('lv-dot-idle');
8665- dot.classList.add('lv-dot-indigo', 'lv-pulse');
8666- }
8667- if (meta) meta.classList.add('lv-stage-meta-active');
8668- } else {
8669- card.classList.remove('lv-stage-active');
8670- if (dot) {
8671- dot.classList.add('lv-dot-idle');
8672- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
8673- }
8674- if (meta) meta.classList.remove('lv-stage-meta-active');
8675- }
8676- });
8677- }
8678-
8679- renderDemo();
8680-
8681- setInterval(function() {
8682- demoStep = (demoStep + 1) % 5;
8683- renderDemo();
8684- }, 3600);
8685-
8686- setInterval(function() {
8687- stage = (stage + 1) % 6;
8688- renderStages();
8689- }, 2200);
8690-})();
8691-`;
8692-
8693-const css = `
8694-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
8695-
8696-*, *::before, *::after { box-sizing: border-box; }
8697-
8698-body {
8699- margin: 0;
8700- background: #fcfcfd;
8701- -webkit-font-smoothing: antialiased;
8702- text-rendering: optimizeLegibility;
8703- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
8704- font-size: 15px;
8705- line-height: 1.6;
8706- letter-spacing: -0.008em;
8707- color: #16181d;
8708-}
8709-
8710-@keyframes gcPulse {
8711- 0%, 100% { opacity: 1; }
8712- 50% { opacity: 0.35; }
8713-}
8714-
8715-@keyframes gcTicker {
8716- 0% { transform: translateX(0); }
8717- 100% { transform: translateX(-50%); }
8718-}
8719-
8720-/* Shared utilities */
8721-.lv-dot {
8722- display: inline-block;
8723- border-radius: 50%;
8724-}
8725-.lv-dot-green { background: #1e7f5c; }
8726-.lv-dot-indigo { background: #4353c9; }
8727-.lv-dot-idle { background: #c4c6cf; }
8728-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
8729-
8730-.lv-strong { color: #16181d; font-weight: 600; }
8731-
8732-.lv-eyebrow {
8733- font-family: 'JetBrains Mono', monospace;
8734- font-size: 11px;
8735- letter-spacing: 0.12em;
8736- text-transform: uppercase;
8737- color: #8a8d99;
8738- font-weight: 500;
8739- margin-bottom: 12px;
8740-}
8741-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
8742-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
8743-
8744-.lv-h1 {
8745- font-family: 'Inter Tight', sans-serif;
8746- font-weight: 700;
8747- letter-spacing: -0.035em;
8748- font-size: clamp(44px, 7vw, 84px);
8749- line-height: 0.98;
8750- margin: 30px auto 0;
8751- max-width: 14ch;
8752- color: #111318;
8753-}
8754-
8755-.lv-h2 {
8756- font-family: 'Inter Tight', sans-serif;
8757- font-weight: 700;
8758- letter-spacing: -0.028em;
8759- font-size: clamp(30px, 4.4vw, 48px);
8760- line-height: 1.05;
8761- margin: 0;
8762- color: #111318;
8763-}
8764-
8765-.lv-h2-dark {
8766- font-family: 'Inter Tight', sans-serif;
8767- font-weight: 700;
8768- letter-spacing: -0.028em;
8769- font-size: clamp(30px, 4.6vw, 52px);
8770- line-height: 1.05;
8771- margin: 0;
8772- color: #fff;
8773-}
8774-
8775-.lv-section-header {
8776- max-width: 640px;
8777- margin: 0 auto 56px;
8778-}
8779-
8780-.lv-section-header-center {
8781- text-align: center;
8782-}
8783-
8784-.lv-section-sub {
8785- color: #6b7080;
8786- font-size: 17px;
8787- margin: 18px auto 0;
8788- max-width: 52ch;
8789-}
8790-
8791-.lv-section-sub-dark {
8792- color: rgba(255,255,255,0.72);
8793- font-size: 17px;
8794- margin: 18px auto 0;
8795- max-width: 56ch;
8796-}
8797-
8798-/* Nav */
8799-.lv-nav {
8800- position: sticky;
8801- top: 0;
8802- z-index: 60;
8803- backdrop-filter: saturate(180%) blur(14px);
8804- -webkit-backdrop-filter: saturate(180%) blur(14px);
8805- background: rgba(252,252,253,0.8);
8806- border-bottom: 1px solid rgba(22,24,29,0.07);
8807-}
8808-
8809-.lv-nav-inner {
8810- max-width: 1200px;
8811- margin: 0 auto;
8812- padding: 14px 28px;
8813- display: flex;
8814- align-items: center;
8815- gap: 28px;
8816-}
8817-
8818-.lv-logo {
8819- display: inline-flex;
8820- align-items: center;
8821- gap: 9px;
8822- font-family: 'Inter Tight', sans-serif;
8823- font-weight: 700;
8824- font-size: 17px;
8825- letter-spacing: -0.02em;
8826- color: #16181d;
8827- text-decoration: none;
8828-}
8829-
8830-.lv-logo-mark {
8831- width: 17px;
8832- height: 17px;
8833- border-radius: 5px;
8834- background: #4353c9;
8835- display: inline-block;
8836- flex-shrink: 0;
8837-}
8838-
8839-.lv-nav-links {
8840- display: flex;
8841- gap: 24px;
8842- font-size: 13.5px;
8843- font-weight: 500;
8844-}
8845-
8846-.lv-nav-link {
8847- color: #6b7080;
8848- text-decoration: none;
8849- transition: color 0.15s;
8850-}
8851-.lv-nav-link:hover { color: #16181d; }
8852-
8853-.lv-nav-ctas {
8854- margin-left: auto;
8855- display: flex;
8856- align-items: center;
8857- gap: 10px;
8858-}
8859-
8860-.lv-btn-secondary {
8861- padding: 8px 15px;
8862- border-radius: 8px;
8863- font-size: 13.5px;
8864- font-weight: 500;
8865- color: #16181d;
8866- border: 1px solid rgba(22,24,29,0.12);
8867- background: #ffffff;
8868- text-decoration: none;
8869- white-space: nowrap;
8870- transition: border-color 0.15s;
8871-}
8872-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
8873-
8874-.lv-btn-primary {
8875- padding: 8px 15px;
8876- border-radius: 8px;
8877- font-size: 13.5px;
8878- font-weight: 600;
8879- background: #16181d;
8880- color: #fff;
8881- text-decoration: none;
8882- white-space: nowrap;
8883- transition: box-shadow 0.15s;
8884-}
8885-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
8886-
8887-/* Hero */
8888-.lv-hero {
8889- position: relative;
8890- overflow: hidden;
8891- padding: 88px 0 0;
8892-}
8893-
8894-.lv-hero-glow {
8895- position: absolute;
8896- inset: -10% 0 auto 0;
8897- height: 640px;
8898- pointer-events: none;
8899- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
8900-}
8901-
8902-.lv-hero-inner {
8903- position: relative;
8904- max-width: 1200px;
8905- margin: 0 auto;
8906- padding: 0 28px;
8907- text-align: center;
8908-}
8909-
8910-.lv-hero-badge {
8911- display: inline-flex;
8912- align-items: center;
8913- gap: 9px;
8914- font-size: 12.5px;
8915- font-weight: 600;
8916- color: #3a3d45;
8917- background: #ffffff;
8918- border: 1px solid rgba(22,24,29,0.10);
8919- border-radius: 9999px;
8920- padding: 7px 16px;
8921- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
8922-}
8923-
8924-.lv-hero-sub {
8925- font-size: clamp(16px, 2vw, 19px);
8926- color: #6b7080;
8927- max-width: 60ch;
8928- margin: 24px auto 0;
8929- font-weight: 450;
8930- line-height: 1.65;
8931-}
8932-
8933-.lv-hero-actions {
8934- display: flex;
8935- gap: 12px;
8936- justify-content: center;
8937- flex-wrap: wrap;
8938- margin-top: 32px;
8939-}
8940-
8941-.lv-cta-primary {
8942- padding: 13px 24px;
8943- border-radius: 11px;
8944- font-size: 15.5px;
8945- font-weight: 600;
8946- background: #16181d;
8947- color: #fff;
8948- text-decoration: none;
8949- white-space: nowrap;
8950- transition: box-shadow 0.15s;
8951-}
8952-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
8953-
8954-.lv-cta-secondary {
8955- padding: 13px 24px;
8956- border-radius: 11px;
8957- font-size: 15.5px;
8958- font-weight: 600;
8959- color: #16181d;
8960- border: 1px solid rgba(22,24,29,0.14);
8961- background: #ffffff;
8962- text-decoration: none;
8963- white-space: nowrap;
8964- transition: border-color 0.15s;
8965-}
8966-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
8967-
8968-.lv-hero-tag {
8969- margin-top: 18px;
8970- font-family: 'JetBrains Mono', monospace;
8971- font-size: 11.5px;
8972- letter-spacing: 0.08em;
8973- text-transform: uppercase;
8974- color: #8a8d99;
8975-}
8976-
8977-/* Demo window */
8978-.lv-demo-window {
8979- margin: 56px auto 0;
8980- max-width: 860px;
8981- text-align: left;
8982- background: #ffffff;
8983- border: 1px solid rgba(22,24,29,0.09);
8984- border-radius: 18px;
8985- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
8986- overflow: hidden;
8987-}
8988-
8989-.lv-demo-bar {
8990- display: flex;
8991- align-items: center;
8992- gap: 7px;
8993- padding: 12px 18px;
8994- border-bottom: 1px solid rgba(22,24,29,0.07);
8995- background: #fcfcfd;
8996-}
8997-
8998-.lv-demo-dot {
8999- width: 10px;
9000- height: 10px;
9001- border-radius: 50%;
9002- background: #e4e5ea;
9003-}
9004-
9005-.lv-demo-url {
9006- margin-left: 10px;
9007- font-family: 'JetBrains Mono', monospace;
9008- font-size: 12px;
9009- color: #6b7080;
9010-}
9011-
9012-.lv-demo-live {
9013- margin-left: auto;
9014- display: inline-flex;
9015- align-items: center;
9016- gap: 6px;
9017- font-size: 11px;
9018- font-weight: 600;
9019- color: #1e7f5c;
9020-}
9021-
9022-.lv-demo-body {
9023- padding: 22px 24px;
9024-}
9025-
9026-.lv-demo-event {
9027- display: grid;
9028- grid-template-columns: 18px minmax(0, 1fr);
9029- gap: 14px;
9030- padding-bottom: 20px;
9031- position: relative;
9032-}
9033-.lv-demo-event:last-child { padding-bottom: 0; }
9034-
9035-.lv-demo-event-track {
9036- display: flex;
9037- flex-direction: column;
9038- align-items: center;
9039-}
9040-
9041-.lv-demo-line {
9042- width: 1px;
9043- flex: 1;
9044- background: rgba(22,24,29,0.08);
9045- margin-top: 5px;
9046- min-height: 20px;
9047-}
9048-
9049-.lv-demo-event-content {}
9050-
9051-.lv-demo-event-header {
9052- display: flex;
9053- align-items: baseline;
9054- gap: 10px;
9055-}
9056-
9057-.lv-demo-event-title {
9058- font-size: 13.5px;
9059- font-weight: 600;
9060- color: #16181d;
9061-}
9062-
9063-.lv-demo-event-time {
9064- font-family: 'JetBrains Mono', monospace;
9065- font-size: 11px;
9066- color: #8a8d99;
9067-}
9068-
9069-.lv-demo-event-body {
9070- font-size: 13px;
9071- color: #6b7080;
9072- margin-top: 2px;
9073-}
9074-
9075-/* Ticker */
9076-.lv-ticker-wrap {
9077- border-top: 1px solid rgba(22,24,29,0.07);
9078- border-bottom: 1px solid rgba(22,24,29,0.07);
9079- background: #ffffff;
9080- margin-top: 64px;
9081- overflow: hidden;
9082- white-space: nowrap;
9083- position: relative;
9084-}
9085-
9086-.lv-ticker-track {
9087- display: inline-flex;
9088- animation: gcTicker 40s linear infinite;
9089- padding: 11px 0;
9090-}
9091-
9092-.lv-ticker-item {
9093- display: inline-flex;
9094- align-items: center;
9095- gap: 8px;
9096- font-family: 'JetBrains Mono', monospace;
9097- font-size: 11.5px;
9098- color: #6b7080;
9099- padding: 0 28px;
9100- border-right: 1px solid rgba(22,24,29,0.06);
9101-}
9102-
9103-/* Stats */
9104-.lv-stats {
9105- background: #fcfcfd;
9106-}
9107-
9108-.lv-stats-inner {
9109- max-width: 1200px;
9110- margin: 0 auto;
9111- display: grid;
9112- grid-template-columns: repeat(4, 1fr);
9113- gap: 24px;
9114- padding: 52px 28px;
9115-}
9116-
9117-.lv-stat {
9118- text-align: center;
9119-}
9120-
9121-.lv-stat-num {
9122- font-family: 'Inter Tight', sans-serif;
9123- font-weight: 700;
9124- font-size: clamp(30px, 4vw, 44px);
9125- letter-spacing: -0.025em;
9126- color: #111318;
9127-}
9128-
9129-.lv-stat-label {
9130- font-size: 13px;
9131- color: #6b7080;
9132- margin-top: 4px;
9133-}
9134-
9135-/* Loop */
9136-.lv-loop {
9137- padding: 96px 0;
9138- background: #ffffff;
9139- border-top: 1px solid rgba(22,24,29,0.07);
9140- border-bottom: 1px solid rgba(22,24,29,0.07);
9141-}
9142-
9143-.lv-loop-inner {
9144- max-width: 1200px;
9145- margin: 0 auto;
9146- padding: 0 28px;
9147-}
9148-
9149-.lv-stages {
9150- display: grid;
9151- grid-template-columns: repeat(6, 1fr);
9152- gap: 12px;
9153-}
9154-
9155-.lv-stage-card {
9156- border: 1px solid rgba(22,24,29,0.08);
9157- border-radius: 14px;
9158- background: #ffffff;
9159- padding: 20px 18px;
9160- transition: border-color 0.3s, background 0.3s;
9161-}
9162-
9163-.lv-stage-card.lv-stage-active {
9164- border-color: rgba(67,83,201,0.45);
9165- background: rgba(67,83,201,0.03);
9166-}
9167-
9168-.lv-stage-header {
9169- display: flex;
9170- align-items: center;
9171- gap: 8px;
9172- margin-bottom: 10px;
9173-}
9174-
9175-.lv-stage-n {
9176- font-family: 'JetBrains Mono', monospace;
9177- font-size: 10.5px;
9178- letter-spacing: 0.1em;
9179- text-transform: uppercase;
9180- color: #8a8d99;
9181-}
9182-
9183-.lv-stage-name {
9184- font-family: 'Inter Tight', sans-serif;
9185- font-size: 16px;
9186- font-weight: 600;
9187- letter-spacing: -0.01em;
9188- color: #16181d;
9189- margin-bottom: 5px;
9190-}
9191-
9192-.lv-stage-desc {
9193- font-size: 12px;
9194- color: #6b7080;
9195- line-height: 1.55;
9196-}
9197-
9198-.lv-stage-meta {
9199- font-family: 'JetBrains Mono', monospace;
9200- font-size: 10.5px;
9201- color: #8a8d99;
9202- margin-top: 10px;
9203- transition: color 0.3s;
9204-}
9205-
9206-.lv-stage-meta.lv-stage-meta-active {
9207- color: #4353c9;
9208-}
9209-
9210-/* Heroes */
9211-.lv-heroes {
9212- padding: 96px 0;
9213- background: #fcfcfd;
9214-}
9215-
9216-.lv-heroes-inner {
9217- max-width: 1200px;
9218- margin: 0 auto;
9219- padding: 0 28px;
9220-}
9221-
9222-.lv-heroes-header {
9223- max-width: 640px;
9224- margin-bottom: 56px;
9225-}
9226-
9227-.lv-heroes-list {
9228- display: flex;
9229- flex-direction: column;
9230- gap: 20px;
9231-}
9232-
9233-.lv-hero-card {
9234- display: grid;
9235- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
9236- gap: 48px;
9237- align-items: center;
9238- border: 1px solid rgba(22,24,29,0.08);
9239- border-radius: 20px;
9240- background: #ffffff;
9241- padding: 44px 48px;
9242- text-decoration: none;
9243- transition: border-color 0.2s, box-shadow 0.2s;
9244-}
9245-.lv-hero-card:hover {
9246- border-color: rgba(22,24,29,0.22);
9247- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
9248-}
9249-
9250-.lv-hero-card-left {}
9251-
9252-.lv-hero-card-title {
9253- font-family: 'Inter Tight', sans-serif;
9254- font-size: 26px;
9255- font-weight: 600;
9256- letter-spacing: -0.022em;
9257- line-height: 1.15;
9258- color: #16181d;
9259- margin: 0 0 12px;
9260-}
9261-
9262-.lv-hero-card-body {
9263- font-size: 14.5px;
9264- color: #6b7080;
9265- margin: 0 0 18px;
9266- line-height: 1.65;
9267-}
9268-
9269-.lv-hero-card-cta {
9270- font-size: 13.5px;
9271- font-weight: 600;
9272- color: #4353c9;
9273-}
9274-
9275-.lv-terminal {
9276- border: 1px solid rgba(22,24,29,0.07);
9277- border-radius: 14px;
9278- background: #fcfcfd;
9279- padding: 20px 22px;
9280- font-family: 'JetBrains Mono', monospace;
9281- font-size: 12px;
9282- line-height: 1.9;
9283- overflow: hidden;
9284-}
9285-
9286-.lv-terminal-line {
9287- display: flex;
9288- align-items: center;
9289- gap: 10px;
9290- white-space: nowrap;
9291- overflow: hidden;
9292- text-overflow: ellipsis;
9293-}
9294-
9295-/* Platform */
9296-.lv-platform {
9297- padding: 96px 0;
9298- background: #ffffff;
9299- border-top: 1px solid rgba(22,24,29,0.07);
9300-}
9301-
9302-.lv-platform-inner {
9303- max-width: 1200px;
9304- margin: 0 auto;
9305- padding: 0 28px;
9306-}
9307-
9308-.lv-cap-grid {
9309- display: grid;
9310- grid-template-columns: repeat(4, 1fr);
9311- gap: 24px 32px;
9312-}
9313-
9314-.lv-cap-col {}
9315-
9316-.lv-cap-group {
9317- font-family: 'JetBrains Mono', monospace;
9318- font-size: 10.5px;
9319- letter-spacing: 0.12em;
9320- text-transform: uppercase;
9321- color: #8a8d99;
9322- font-weight: 500;
9323- margin-bottom: 12px;
9324- padding-bottom: 8px;
9325- border-bottom: 1px solid rgba(22,24,29,0.07);
9326-}
9327-
9328-.lv-cap-items {
9329- display: flex;
9330- flex-direction: column;
9331- gap: 7px;
9332-}
9333-
9334-.lv-cap-item {
9335- font-size: 12.5px;
9336- color: #3a3d45;
9337- line-height: 1.45;
9338-}
9339-
9340-/* Sovereignty */
9341-.lv-sovereign {
9342- position: relative;
9343- overflow: hidden;
9344- padding: 104px 0;
9345- color: #fff;
9346- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
9347-}
9348-
9349-.lv-sovereign-grid-bg {
9350- position: absolute;
9351- inset: 0;
9352- opacity: 0.4;
9353- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
9354- background-size: 56px 56px;
9355- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
9356- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
9357-}
9358-
9359-.lv-sovereign-inner {
9360- position: relative;
9361- max-width: 1200px;
9362- margin: 0 auto;
9363- padding: 0 28px;
9364-}
9365-
9366-.lv-section-header-dark {
9367- max-width: 680px;
9368- margin: 0 auto 48px;
9369- text-align: center;
9370-}
9371-
9372-.lv-layers-grid {
9373- display: grid;
9374- grid-template-columns: repeat(4, 1fr);
9375- gap: 10px;
9376- max-width: 980px;
9377- margin: 0 auto;
9378-}
9379-
9380-.lv-layer-chip {
9381- border: 1px solid rgba(255,255,255,0.10);
9382- border-radius: 10px;
9383- padding: 12px 16px;
9384- background: rgba(255,255,255,0.03);
9385-}
9386-
9387-.lv-layer-cta {
9388- border-color: rgba(169,180,238,0.30);
9389- background: rgba(169,180,238,0.06);
9390- display: flex;
9391- align-items: center;
9392- text-decoration: none;
9393- transition: background 0.15s;
9394-}
9395-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
9396-
9397-.lv-layer-cta-text {
9398- font-size: 13px;
9399- font-weight: 500;
9400- color: #a9b4ee;
9401-}
9402-
9403-.lv-layer-n {
9404- font-family: 'JetBrains Mono', monospace;
9405- font-size: 10px;
9406- color: rgba(255,255,255,0.4);
9407- margin-bottom: 3px;
9408-}
9409-
9410-.lv-layer-name {
9411- font-size: 13px;
9412- font-weight: 500;
9413- color: rgba(255,255,255,0.92);
9414-}
9415-
9416-.lv-sovereign-feats {
9417- display: flex;
9418- gap: 44px;
9419- justify-content: center;
9420- flex-wrap: wrap;
9421- margin-top: 52px;
9422- text-align: center;
9423-}
9424-
9425-.lv-sovereign-feat {}
9426-
9427-.lv-sovereign-feat-title {
9428- font-family: 'Inter Tight', sans-serif;
9429- font-size: 20px;
9430- font-weight: 700;
9431- color: #fff;
9432-}
9433-
9434-.lv-sovereign-feat-sub {
9435- color: rgba(255,255,255,0.55);
9436- font-size: 13px;
9437- margin-top: 2px;
9438-}
9439-
9440-/* Twin cards */
9441-.lv-twin {
9442- padding: 96px 0;
9443- background: #fcfcfd;
9444-}
9445-
9446-.lv-twin-inner {
9447- max-width: 1200px;
9448- margin: 0 auto;
9449- padding: 0 28px;
9450- display: grid;
9451- grid-template-columns: 1fr 1fr;
9452- gap: 24px;
9453-}
9454-
9455-.lv-twin-card {
9456- border: 1px solid rgba(22,24,29,0.08);
9457- border-radius: 20px;
9458- background: #ffffff;
9459- padding: 44px 48px;
9460-}
9461-
9462-.lv-twin-title {
9463- font-family: 'Inter Tight', sans-serif;
9464- font-size: 24px;
9465- font-weight: 600;
9466- letter-spacing: -0.02em;
9467- line-height: 1.2;
9468- margin: 0 0 12px;
9469- color: #16181d;
9470-}
9471-
9472-.lv-twin-body {
9473- font-size: 14.5px;
9474- color: #6b7080;
9475- margin: 0 0 16px;
9476- line-height: 1.7;
9477-}
9478-
9479-.lv-twin-link {
9480- font-size: 13.5px;
9481- font-weight: 600;
9482- color: #4353c9;
9483- text-decoration: none;
9484-}
9485-.lv-twin-link:hover { text-decoration: underline; }
9486-
9487-/* Quote */
9488-.lv-quote {
9489- padding: 40px 0 96px;
9490- background: #fcfcfd;
9491-}
9492-
9493-.lv-quote-inner {
9494- max-width: 980px;
9495- margin: 0 auto;
9496- padding: 0 28px;
9497- text-align: center;
9498-}
9499-
9500-.lv-quote-text {
9501- font-family: 'Inter Tight', sans-serif;
9502- font-weight: 600;
9503- font-size: clamp(26px, 3.8vw, 42px);
9504- line-height: 1.2;
9505- letter-spacing: -0.025em;
9506- margin: 0;
9507- color: #111318;
9508-}
9509-
9510-.lv-em {
9511- font-style: normal;
9512- color: #4353c9;
9513-}
9514-
9515-/* CTA */
9516-.lv-cta-section {
9517- padding: 0 0 104px;
9518- background: #fcfcfd;
9519-}
9520-
9521-.lv-cta-card {
9522- max-width: 820px;
9523- margin: 0 auto;
9524- padding: 64px 40px;
9525- text-align: center;
9526- background: #ffffff;
9527- border: 1px solid rgba(22,24,29,0.08);
9528- border-radius: 26px;
9529- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
9530- position: relative;
9531- overflow: hidden;
9532-}
9533-
9534-.lv-cta-glow {
9535- position: absolute;
9536- inset: -40% 0 auto 0;
9537- height: 280px;
9538- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
9539- pointer-events: none;
9540-}
9541-
9542-.lv-cta-h2 {
9543- font-family: 'Inter Tight', sans-serif;
9544- font-weight: 700;
9545- letter-spacing: -0.028em;
9546- font-size: clamp(30px, 4.6vw, 48px);
9547- margin: 0;
9548- position: relative;
9549- color: #111318;
9550-}
9551-
9552-.lv-cta-sub {
9553- color: #6b7080;
9554- font-size: 17px;
9555- margin: 16px 0 30px;
9556- position: relative;
9557-}
9558-
9559-.lv-cta-actions {
9560- display: flex;
9561- gap: 12px;
9562- justify-content: center;
9563- flex-wrap: wrap;
9564- position: relative;
9565-}
9566-
9567-.lv-cta-fine {
9568- margin-top: 20px;
9569- font-family: 'JetBrains Mono', monospace;
9570- font-size: 11px;
9571- color: #8a8d99;
9572- position: relative;
9573-}
9574-
9575-/* Footer */
9576-.lv-footer {
9577- border-top: 1px solid rgba(22,24,29,0.07);
9578- background: #ffffff;
9579- padding: 56px 0 30px;
9580-}
9581-
9582-.lv-footer-inner {
9583- max-width: 1200px;
9584- margin: 0 auto;
9585- padding: 0 28px;
9586- display: flex;
9587- gap: 48px;
9588- flex-wrap: wrap;
9589- justify-content: space-between;
9590-}
9591-
9592-.lv-footer-brand {}
9593-
9594-.lv-footer-tagline {
9595- color: #6b7080;
9596- font-size: 13.5px;
9597- margin: 12px 0 0;
9598- max-width: 32ch;
9599- line-height: 1.6;
9600-}
9601-
9602-.lv-footer-cols {
9603- display: flex;
9604- gap: 64px;
9605- flex-wrap: wrap;
9606-}
9607-
9608-.lv-footer-col {
9609- display: flex;
9610- flex-direction: column;
9611- gap: 9px;
9612-}
9613-
9614-.lv-footer-col-head {
9615- font-family: 'JetBrains Mono', monospace;
9616- font-size: 11px;
9617- text-transform: uppercase;
9618- letter-spacing: 0.1em;
9619- color: #8a8d99;
9620- margin: 0 0 4px;
9621- font-weight: 500;
9622-}
9623-
9624-.lv-footer-link {
9625- color: #3a3d45;
9626- font-size: 13.5px;
9627- text-decoration: none;
9628- transition: color 0.15s;
9629-}
9630-.lv-footer-link:hover { color: #16181d; }
9631-
9632-.lv-footer-bar {
9633- max-width: 1200px;
9634- margin: 44px auto 0;
9635- padding: 22px 28px 0;
9636- border-top: 1px solid rgba(22,24,29,0.06);
9637- display: flex;
9638- justify-content: space-between;
9639- flex-wrap: wrap;
9640- gap: 8px;
9641- color: #8a8d99;
9642- font-size: 12.5px;
9643-}
9644-
9645-.lv-footer-stack {
9646- font-family: 'JetBrains Mono', monospace;
9647- font-size: 11px;
9648-}
9649-`;
9650diff --git a/src/views/layout.tsx b/src/views/layout.tsx
9651index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
9652--- a/src/views/layout.tsx
9653+++ b/src/views/layout.tsx
9654@@ -3153,9 +3153,12 @@
9655 font-weight: 500;
9656 line-height: 1.4;
9657 }
9658- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
9659- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
9660- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
9661+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
9662+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
9663+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
9664+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
9665+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
9666+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
9667 .state-merged { color: var(--accent); }
9668 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
9669
9670diff --git a/src/views/ui.tsx b/src/views/ui.tsx
9671index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
9672--- a/src/views/ui.tsx
9673+++ b/src/views/ui.tsx
9674@@ -232,7 +232,7 @@
9675
9676 export const Badge: FC<
9677 PropsWithChildren<{
9678- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
9679+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
9680 style?: string;
9681 }>
9682 > = ({ children, variant = "default", style }) => {
9683@@ -241,9 +241,12 @@
9684 variant === "closed" ? "badge-closed" :
9685 variant === "merged" ? "badge-merged" :
9686 variant === "success" ? "badge-success" :
9687- variant === "danger" ? "badge-danger" :
9688- variant === "warning" ? "badge-warning" :
9689- "badge";
9690+ variant === "danger" ? "badge-danger" :
9691+ variant === "warning" ? "badge-warning" :
9692+ variant === "live" ? "badge-live" :
9693+ variant === "soon" ? "badge-soon" :
9694+ variant === "preview" ? "badge-preview" :
9695+ "badge";
9696 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
9697 };
9698
9699
9700diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
9701index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
9702--- a/src/views/landing-pro.tsx
9703+++ b/src/views/landing-pro.tsx
9704@@ -42,7 +42,7 @@
9705
9706 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9707
9708-function icon(paths: string, color = "#4353c9", size = 20) {
9709+function icon(paths: string, color = "#0891b2", size = 20) {
9710 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
9711 }
9712
9713@@ -947,7 +947,7 @@
9714 const css = `
9715 /* %% tokens %% */
9716 :root{
9717- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
9718+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
9719 --lp-bg:#ffffff;--lp-soft:#fafafb;
9720 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
9721 --lp-border:rgba(0,0,0,.08);
9722diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
9723deleted file mode 100644
9724index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
9725--- a/src/views/landing-v2.tsx
9726+++ /dev/null
9727@@ -1,1447 +0,0 @@
9728-import type { FC } from "hono/jsx";
9729-
9730-export interface LandingPageProps {
9731- stats?: {
9732- publicRepos?: number;
9733- users?: number;
9734- };
9735-}
9736-
9737-const demoAllEvents = [
9738- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
9739- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
9740- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
9741- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
9742- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
9743-];
9744-
9745-const tickerItems = [
9746- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
9747- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
9748- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
9749- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
9750- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
9751- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
9752- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
9753- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
9754- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
9755- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
9756- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
9757- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
9758- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
9759- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
9760- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
9761- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
9762-];
9763-
9764-const stageData = [
9765- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
9766- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
9767- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
9768- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
9769- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
9770- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
9771-];
9772-
9773-const heroFeatures = [
9774- {
9775- href: "/",
9776- eyebrow: "01 � The autonomous repair loop",
9777- title: "Failures fix themselves  and show their work.",
9778- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
9779failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
9780- cta: "Watch a live repair session",
9781- mock: [
9782- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
9783- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
9784- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
9785- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
9786- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
9787- ],
9788- },
9789- {
9790- href: "/",
9791- eyebrow: "02 � Live sandbox isolation",
9792- title: "Every PR gets its own instant, disposable environment.",
9793- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
9794same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
9795- cta: "See a PR with its sandbox",
9796- mock: [
9797- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
9798- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
9799- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
9800- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
9801- ],
9802- },
9803- {
9804- href: "/",
9805- eyebrow: "03 � Multiplayer IDE workspaces",
9806- title: "You and the agent, side by side, in your editor.",
9807- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
9808agent into a silent reviewer in your gutter. The browser becomes optional.",
9809- cta: "See the editor session",
9810- mock: [
9811- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
9812- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
9813- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
9814- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
9815- ],
9816- },
9817-];
9818-
9819-const capabilities = [
9820- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
9821- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
9822- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
9823- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
9824- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
9825- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
9826- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
9827- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
9828-];
9829-
9830-const sovereignLayerNames = [
9831- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
9832- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
9833- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
9834- "Availability & recovery",
9835-];
9836-
9837-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
9838- return (
9839- <>
9840- <style dangerouslySetInnerHTML={{ __html: css }} />
9841-
9842- {/* Nav */}
9843- <header class="lv-nav">
9844- <div class="lv-nav-inner">
9845- <a href="/" class="lv-logo">
9846- <span class="lv-logo-mark"></span>gluecron
9847- </a>
9848- <nav class="lv-nav-links">
9849- <a href="#loop" class="lv-nav-link">The loop</a>
9850- <a href="#platform" class="lv-nav-link">Platform</a>
9851- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
9852- <a href="/trust" class="lv-nav-link">Trust</a>
9853- </nav>
9854- <div class="lv-nav-ctas">
9855- <a href="/login" class="lv-btn-secondary">Sign in</a>
9856- <a href="/register" class="lv-btn-primary">Start building</a>
9857- </div>
9858- </div>
9859- </header>
9860-
9861- {/* Hero */}
9862- <section class="lv-hero">
9863- <div class="lv-hero-glow"></div>
9864- <div class="lv-hero-inner">
9865- <div class="lv-hero-badge">
9866- <span class="lv-dot lv-dot-green lv-pulse"></span>
9867- Live: a repair loop converged on pr-218 while you read this
9868- </div>
9869- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
9870- <p class="lv-hero-sub">
9871- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
9872failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
9873- </p>
9874- <div class="lv-hero-actions">
9875- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
9876- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
9877- </div>
9878- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
9879-
9880- {/* Live product window */}
9881- <div class="lv-demo-window">
9882- <div class="lv-demo-bar">
9883- <span class="lv-demo-dot"></span>
9884- <span class="lv-demo-dot"></span>
9885- <span class="lv-demo-dot"></span>
9886- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
9887- <span class="lv-demo-live">
9888- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
9889- LIVE
9890- </span>
9891- </div>
9892- <div class="lv-demo-body" id="lv-demo-body">
9893- {/* Events rendered by JS */}
9894- {demoAllEvents.slice(0, 1).map((e, i) => (
9895- <div class="lv-demo-event" key={i}>
9896- <div class="lv-demo-event-track">
9897- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
9898- <span class="lv-demo-line" style="display:none"></span>
9899- </div>
9900- <div class="lv-demo-event-content">
9901- <div class="lv-demo-event-header">
9902- <span class="lv-demo-event-title">{e.title}</span>
9903- <span class="lv-demo-event-time">{e.time}</span>
9904- </div>
9905- <div class="lv-demo-event-body">{e.body}</div>
9906- </div>
9907- </div>
9908- ))}
9909- </div>
9910- </div>
9911- </div>
9912-
9913- {/* Activity ticker */}
9914- <div class="lv-ticker-wrap">
9915- <div class="lv-ticker-track">
9916- {tickerItems.map((t, i) => (
9917- <span class="lv-ticker-item" key={i}>
9918- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
9919- {t.text}
9920- </span>
9921- ))}
9922- </div>
9923- </div>
9924- </section>
9925-
9926- {/* Stat band */}
9927- <section class="lv-stats">
9928- <div class="lv-stats-inner">
9929- <div class="lv-stat">
9930- <div class="lv-stat-num">Sonnet 5</div>
9931- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
9932- </div>
9933- <div class="lv-stat">
9934- <div class="lv-stat-num">93.5%</div>
9935- <div class="lv-stat-label">of failures self-repair without a human</div>
9936- </div>
9937- <div class="lv-stat">
9938- <div class="lv-stat-num">1.9%</div>
9939- <div class="lv-stat-label">AI merges reverted  published live</div>
9940- </div>
9941- <div class="lv-stat">
9942- <div class="lv-stat-num">0</div>
9943- <div class="lv-stat-label">irreversible actions taken autonomously</div>
9944- </div>
9945- </div>
9946- </section>
9947-
9948- {/* The loop */}
9949- <section id="loop" class="lv-loop">
9950- <div class="lv-loop-inner">
9951- <div class="lv-section-header">
9952- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
9953- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
9954- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
9955- </div>
9956- <div class="lv-stages" id="lv-stages">
9957- {stageData.map((s, i) => (
9958- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
9959- <div class="lv-stage-header">
9960- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
9961- <span class="lv-stage-n">0{i + 1}</span>
9962- </div>
9963- <div class="lv-stage-name">{s.name}</div>
9964- <div class="lv-stage-desc">{s.desc}</div>
9965- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
9966- </div>
9967- ))}
9968- </div>
9969- </div>
9970- </section>
9971-
9972- {/* Three heroes */}
9973- <section class="lv-heroes">
9974- <div class="lv-heroes-inner">
9975- <div class="lv-heroes-header">
9976- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
9977- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
9978- </div>
9979- <div class="lv-heroes-list">
9980- {heroFeatures.map((h, i) => (
9981- <a href={h.href} class="lv-hero-card" key={i}>
9982- <div class="lv-hero-card-left">
9983- <div class="lv-eyebrow">{h.eyebrow}</div>
9984- <h3 class="lv-hero-card-title">{h.title}</h3>
9985- <p class="lv-hero-card-body">{h.body}</p>
9986- <span class="lv-hero-card-cta">{h.cta} �!</span>
9987- </div>
9988- <div class="lv-terminal">
9989- {h.mock.map((m, j) => (
9990- <div class="lv-terminal-line" key={j}>
9991- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
9992- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
9993- </div>
9994- ))}
9995- </div>
9996- </a>
9997- ))}
9998- </div>
9999- </div>
10000- </section>
10001-
10002- {/* Everything grid */}
10003- <section id="platform" class="lv-platform">
10004- <div class="lv-platform-inner">
10005- <div class="lv-section-header lv-section-header-center">
10006- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
10007- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
10008- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
10009- </div>
10010- <div class="lv-cap-grid">
10011- {capabilities.map((c, i) => (
10012- <div class="lv-cap-col" key={i}>
10013- <div class="lv-cap-group">{c.group}</div>
10014- <div class="lv-cap-items">
10015- {c.items.map((item, j) => (
10016- <div class="lv-cap-item" key={j}>{item}</div>
10017- ))}
10018- </div>
10019- </div>
10020- ))}
10021- </div>
10022- </div>
10023- </section>
10024-
10025- {/* Sovereignty band */}
10026- <section id="sovereign" class="lv-sovereign">
10027- <div class="lv-sovereign-grid-bg"></div>
10028- <div class="lv-sovereign-inner">
10029- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
10030- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
10031- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
10032- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
10033to private cloud, or run fully air-gapped on bare metal.</p>
10034- </div>
10035- <div class="lv-layers-grid">
10036- {sovereignLayerNames.map((name, i) => (
10037- <div class="lv-layer-chip" key={i}>
10038- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
10039- <div class="lv-layer-name">{name}</div>
10040- </div>
10041- ))}
10042- <a href="/" class="lv-layer-chip lv-layer-cta">
10043- <div class="lv-layer-cta-text">All self-owned �!</div>
10044- </a>
10045- </div>
10046- <div class="lv-sovereign-feats">
10047- <div class="lv-sovereign-feat">
10048- <div class="lv-sovereign-feat-title">Local inference first</div>
10049- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
10050- </div>
10051- <div class="lv-sovereign-feat">
10052- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
10053- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
10054- </div>
10055- <div class="lv-sovereign-feat">
10056- <div class="lv-sovereign-feat-title">Self-healing infra</div>
10057- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
10058- </div>
10059- </div>
10060- </div>
10061- </section>
10062-
10063- {/* Manual-first + reversibility */}
10064- <section class="lv-twin">
10065- <div class="lv-twin-inner">
10066- <div class="lv-twin-card">
10067- <div class="lv-eyebrow">Manual-first, always</div>
10068- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
10069- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
10070fallback. Developers who never touch AI get the best git host they've ever used.</p>
10071- </div>
10072- <div class="lv-twin-card">
10073- <div class="lv-eyebrow">The reversibility guarantee</div>
10074- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
10075- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
10076 policy, not promise. Our quality numbers are published live, unedited.</p>
10077- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
10078- </div>
10079- </div>
10080- </section>
10081-
10082- {/* Quote */}
10083- <section class="lv-quote">
10084- <div class="lv-quote-inner">
10085- <p class="lv-quote-text">
10086- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
10087- Gluecron is where code gets <em class="lv-em">finished</em>."
10088- </p>
10089- </div>
10090- </section>
10091-
10092- {/* CTA */}
10093- <section class="lv-cta-section">
10094- <div class="lv-cta-card">
10095- <div class="lv-cta-glow"></div>
10096- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
10097- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
10098- <div class="lv-cta-actions">
10099- <a href="/register" class="lv-cta-primary">Create your account �!</a>
10100- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
10101- </div>
10102- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
10103- </div>
10104- </section>
10105-
10106- {/* Footer */}
10107- <footer class="lv-footer">
10108- <div class="lv-footer-inner">
10109- <div class="lv-footer-brand">
10110- <a href="/" class="lv-logo">
10111- <span class="lv-logo-mark"></span>gluecron
10112- </a>
10113- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
10114- </div>
10115- <div class="lv-footer-cols">
10116- <div class="lv-footer-col">
10117- <h4 class="lv-footer-col-head">Product</h4>
10118- <a href="/" class="lv-footer-link">Agent workspace</a>
10119- <a href="/" class="lv-footer-link">Fleet refactors</a>
10120- <a href="/" class="lv-footer-link">Org memory</a>
10121- <a href="/" class="lv-footer-link">IDE extensions</a>
10122- </div>
10123- <div class="lv-footer-col">
10124- <h4 class="lv-footer-col-head">Platform</h4>
10125- <a href="/" class="lv-footer-link">Production layers</a>
10126- <a href="/trust" class="lv-footer-link">Trust report</a>
10127- <a href="/" class="lv-footer-link">Docs</a>
10128- <a href="/" class="lv-footer-link">Status</a>
10129- </div>
10130- <div class="lv-footer-col">
10131- <h4 class="lv-footer-col-head">Company</h4>
10132- <a href="/" class="lv-footer-link">About</a>
10133- <a href="/" class="lv-footer-link">Pricing</a>
10134- <a href="/" class="lv-footer-link">Enterprise</a>
10135- </div>
10136- </div>
10137- </div>
10138- <div class="lv-footer-bar">
10139- <span>� 2026 Gluecron</span>
10140- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
10141- </div>
10142- </footer>
10143-
10144- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
10145- </>
10146- );
10147-};
10148-
10149-export const LandingPage = LandingPageV2;
10150-export default LandingPageV2;
10151-
10152-const clientScript = `
10153-(function() {
10154- var demoAll = [
10155- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
10156- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
10157- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
10158- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
10159- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
10160- ];
10161-
10162- var demoStep = 0;
10163- var stage = 0;
10164-
10165- function renderDemo() {
10166- var container = document.getElementById('lv-demo-body');
10167- if (!container) return;
10168- var visible = demoAll.slice(0, demoStep + 1);
10169- container.innerHTML = visible.map(function(e, i) {
10170- var isLast = i === visible.length - 1;
10171- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
10172- return '<div class="lv-demo-event">' +
10173- '<div class="lv-demo-event-track">' +
10174- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
10175- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
10176- '</div>' +
10177- '<div class="lv-demo-event-content">' +
10178- '<div class="lv-demo-event-header">' +
10179- '<span class="lv-demo-event-title">' + e.title + '</span>' +
10180- '<span class="lv-demo-event-time">' + e.time + '</span>' +
10181- '</div>' +
10182- '<div class="lv-demo-event-body">' + e.body + '</div>' +
10183- '</div>' +
10184- '</div>';
10185- }).join('');
10186- }
10187-
10188- function renderStages() {
10189- var cards = document.querySelectorAll('.lv-stage-card');
10190- cards.forEach(function(card, i) {
10191- var dot = card.querySelector('.lv-dot');
10192- var meta = card.querySelector('.lv-stage-meta');
10193- if (i === stage) {
10194- card.classList.add('lv-stage-active');
10195- if (dot) {
10196- dot.classList.remove('lv-dot-idle');
10197- dot.classList.add('lv-dot-indigo', 'lv-pulse');
10198- }
10199- if (meta) meta.classList.add('lv-stage-meta-active');
10200- } else {
10201- card.classList.remove('lv-stage-active');
10202- if (dot) {
10203- dot.classList.add('lv-dot-idle');
10204- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
10205- }
10206- if (meta) meta.classList.remove('lv-stage-meta-active');
10207- }
10208- });
10209- }
10210-
10211- renderDemo();
10212-
10213- setInterval(function() {
10214- demoStep = (demoStep + 1) % 5;
10215- renderDemo();
10216- }, 3600);
10217-
10218- setInterval(function() {
10219- stage = (stage + 1) % 6;
10220- renderStages();
10221- }, 2200);
10222-})();
10223-`;
10224-
10225-const css = `
10226-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
10227-
10228-*, *::before, *::after { box-sizing: border-box; }
10229-
10230-body {
10231- margin: 0;
10232- background: #fcfcfd;
10233- -webkit-font-smoothing: antialiased;
10234- text-rendering: optimizeLegibility;
10235- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
10236- font-size: 15px;
10237- line-height: 1.6;
10238- letter-spacing: -0.008em;
10239- color: #16181d;
10240-}
10241-
10242-@keyframes gcPulse {
10243- 0%, 100% { opacity: 1; }
10244- 50% { opacity: 0.35; }
10245-}
10246-
10247-@keyframes gcTicker {
10248- 0% { transform: translateX(0); }
10249- 100% { transform: translateX(-50%); }
10250-}
10251-
10252-/* Shared utilities */
10253-.lv-dot {
10254- display: inline-block;
10255- border-radius: 50%;
10256-}
10257-.lv-dot-green { background: #1e7f5c; }
10258-.lv-dot-indigo { background: #4353c9; }
10259-.lv-dot-idle { background: #c4c6cf; }
10260-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
10261-
10262-.lv-strong { color: #16181d; font-weight: 600; }
10263-
10264-.lv-eyebrow {
10265- font-family: 'JetBrains Mono', monospace;
10266- font-size: 11px;
10267- letter-spacing: 0.12em;
10268- text-transform: uppercase;
10269- color: #8a8d99;
10270- font-weight: 500;
10271- margin-bottom: 12px;
10272-}
10273-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
10274-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
10275-
10276-.lv-h1 {
10277- font-family: 'Inter Tight', sans-serif;
10278- font-weight: 700;
10279- letter-spacing: -0.035em;
10280- font-size: clamp(44px, 7vw, 84px);
10281- line-height: 0.98;
10282- margin: 30px auto 0;
10283- max-width: 14ch;
10284- color: #111318;
10285-}
10286-
10287-.lv-h2 {
10288- font-family: 'Inter Tight', sans-serif;
10289- font-weight: 700;
10290- letter-spacing: -0.028em;
10291- font-size: clamp(30px, 4.4vw, 48px);
10292- line-height: 1.05;
10293- margin: 0;
10294- color: #111318;
10295-}
10296-
10297-.lv-h2-dark {
10298- font-family: 'Inter Tight', sans-serif;
10299- font-weight: 700;
10300- letter-spacing: -0.028em;
10301- font-size: clamp(30px, 4.6vw, 52px);
10302- line-height: 1.05;
10303- margin: 0;
10304- color: #fff;
10305-}
10306-
10307-.lv-section-header {
10308- max-width: 640px;
10309- margin: 0 auto 56px;
10310-}
10311-
10312-.lv-section-header-center {
10313- text-align: center;
10314-}
10315-
10316-.lv-section-sub {
10317- color: #6b7080;
10318- font-size: 17px;
10319- margin: 18px auto 0;
10320- max-width: 52ch;
10321-}
10322-
10323-.lv-section-sub-dark {
10324- color: rgba(255,255,255,0.72);
10325- font-size: 17px;
10326- margin: 18px auto 0;
10327- max-width: 56ch;
10328-}
10329-
10330-/* Nav */
10331-.lv-nav {
10332- position: sticky;
10333- top: 0;
10334- z-index: 60;
10335- backdrop-filter: saturate(180%) blur(14px);
10336- -webkit-backdrop-filter: saturate(180%) blur(14px);
10337- background: rgba(252,252,253,0.8);
10338- border-bottom: 1px solid rgba(22,24,29,0.07);
10339-}
10340-
10341-.lv-nav-inner {
10342- max-width: 1200px;
10343- margin: 0 auto;
10344- padding: 14px 28px;
10345- display: flex;
10346- align-items: center;
10347- gap: 28px;
10348-}
10349-
10350-.lv-logo {
10351- display: inline-flex;
10352- align-items: center;
10353- gap: 9px;
10354- font-family: 'Inter Tight', sans-serif;
10355- font-weight: 700;
10356- font-size: 17px;
10357- letter-spacing: -0.02em;
10358- color: #16181d;
10359- text-decoration: none;
10360-}
10361-
10362-.lv-logo-mark {
10363- width: 17px;
10364- height: 17px;
10365- border-radius: 5px;
10366- background: #4353c9;
10367- display: inline-block;
10368- flex-shrink: 0;
10369-}
10370-
10371-.lv-nav-links {
10372- display: flex;
10373- gap: 24px;
10374- font-size: 13.5px;
10375- font-weight: 500;
10376-}
10377-
10378-.lv-nav-link {
10379- color: #6b7080;
10380- text-decoration: none;
10381- transition: color 0.15s;
10382-}
10383-.lv-nav-link:hover { color: #16181d; }
10384-
10385-.lv-nav-ctas {
10386- margin-left: auto;
10387- display: flex;
10388- align-items: center;
10389- gap: 10px;
10390-}
10391-
10392-.lv-btn-secondary {
10393- padding: 8px 15px;
10394- border-radius: 8px;
10395- font-size: 13.5px;
10396- font-weight: 500;
10397- color: #16181d;
10398- border: 1px solid rgba(22,24,29,0.12);
10399- background: #ffffff;
10400- text-decoration: none;
10401- white-space: nowrap;
10402- transition: border-color 0.15s;
10403-}
10404-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
10405-
10406-.lv-btn-primary {
10407- padding: 8px 15px;
10408- border-radius: 8px;
10409- font-size: 13.5px;
10410- font-weight: 600;
10411- background: #16181d;
10412- color: #fff;
10413- text-decoration: none;
10414- white-space: nowrap;
10415- transition: box-shadow 0.15s;
10416-}
10417-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
10418-
10419-/* Hero */
10420-.lv-hero {
10421- position: relative;
10422- overflow: hidden;
10423- padding: 88px 0 0;
10424-}
10425-
10426-.lv-hero-glow {
10427- position: absolute;
10428- inset: -10% 0 auto 0;
10429- height: 640px;
10430- pointer-events: none;
10431- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
10432-}
10433-
10434-.lv-hero-inner {
10435- position: relative;
10436- max-width: 1200px;
10437- margin: 0 auto;
10438- padding: 0 28px;
10439- text-align: center;
10440-}
10441-
10442-.lv-hero-badge {
10443- display: inline-flex;
10444- align-items: center;
10445- gap: 9px;
10446- font-size: 12.5px;
10447- font-weight: 600;
10448- color: #3a3d45;
10449- background: #ffffff;
10450- border: 1px solid rgba(22,24,29,0.10);
10451- border-radius: 9999px;
10452- padding: 7px 16px;
10453- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
10454-}
10455-
10456-.lv-hero-sub {
10457- font-size: clamp(16px, 2vw, 19px);
10458- color: #6b7080;
10459- max-width: 60ch;
10460- margin: 24px auto 0;
10461- font-weight: 450;
10462- line-height: 1.65;
10463-}
10464-
10465-.lv-hero-actions {
10466- display: flex;
10467- gap: 12px;
10468- justify-content: center;
10469- flex-wrap: wrap;
10470- margin-top: 32px;
10471-}
10472-
10473-.lv-cta-primary {
10474- padding: 13px 24px;
10475- border-radius: 11px;
10476- font-size: 15.5px;
10477- font-weight: 600;
10478- background: #16181d;
10479- color: #fff;
10480- text-decoration: none;
10481- white-space: nowrap;
10482- transition: box-shadow 0.15s;
10483-}
10484-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
10485-
10486-.lv-cta-secondary {
10487- padding: 13px 24px;
10488- border-radius: 11px;
10489- font-size: 15.5px;
10490- font-weight: 600;
10491- color: #16181d;
10492- border: 1px solid rgba(22,24,29,0.14);
10493- background: #ffffff;
10494- text-decoration: none;
10495- white-space: nowrap;
10496- transition: border-color 0.15s;
10497-}
10498-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
10499-
10500-.lv-hero-tag {
10501- margin-top: 18px;
10502- font-family: 'JetBrains Mono', monospace;
10503- font-size: 11.5px;
10504- letter-spacing: 0.08em;
10505- text-transform: uppercase;
10506- color: #8a8d99;
10507-}
10508-
10509-/* Demo window */
10510-.lv-demo-window {
10511- margin: 56px auto 0;
10512- max-width: 860px;
10513- text-align: left;
10514- background: #ffffff;
10515- border: 1px solid rgba(22,24,29,0.09);
10516- border-radius: 18px;
10517- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
10518- overflow: hidden;
10519-}
10520-
10521-.lv-demo-bar {
10522- display: flex;
10523- align-items: center;
10524- gap: 7px;
10525- padding: 12px 18px;
10526- border-bottom: 1px solid rgba(22,24,29,0.07);
10527- background: #fcfcfd;
10528-}
10529-
10530-.lv-demo-dot {
10531- width: 10px;
10532- height: 10px;
10533- border-radius: 50%;
10534- background: #e4e5ea;
10535-}
10536-
10537-.lv-demo-url {
10538- margin-left: 10px;
10539- font-family: 'JetBrains Mono', monospace;
10540- font-size: 12px;
10541- color: #6b7080;
10542-}
10543-
10544-.lv-demo-live {
10545- margin-left: auto;
10546- display: inline-flex;
10547- align-items: center;
10548- gap: 6px;
10549- font-size: 11px;
10550- font-weight: 600;
10551- color: #1e7f5c;
10552-}
10553-
10554-.lv-demo-body {
10555- padding: 22px 24px;
10556-}
10557-
10558-.lv-demo-event {
10559- display: grid;
10560- grid-template-columns: 18px minmax(0, 1fr);
10561- gap: 14px;
10562- padding-bottom: 20px;
10563- position: relative;
10564-}
10565-.lv-demo-event:last-child { padding-bottom: 0; }
10566-
10567-.lv-demo-event-track {
10568- display: flex;
10569- flex-direction: column;
10570- align-items: center;
10571-}
10572-
10573-.lv-demo-line {
10574- width: 1px;
10575- flex: 1;
10576- background: rgba(22,24,29,0.08);
10577- margin-top: 5px;
10578- min-height: 20px;
10579-}
10580-
10581-.lv-demo-event-content {}
10582-
10583-.lv-demo-event-header {
10584- display: flex;
10585- align-items: baseline;
10586- gap: 10px;
10587-}
10588-
10589-.lv-demo-event-title {
10590- font-size: 13.5px;
10591- font-weight: 600;
10592- color: #16181d;
10593-}
10594-
10595-.lv-demo-event-time {
10596- font-family: 'JetBrains Mono', monospace;
10597- font-size: 11px;
10598- color: #8a8d99;
10599-}
10600-
10601-.lv-demo-event-body {
10602- font-size: 13px;
10603- color: #6b7080;
10604- margin-top: 2px;
10605-}
10606-
10607-/* Ticker */
10608-.lv-ticker-wrap {
10609- border-top: 1px solid rgba(22,24,29,0.07);
10610- border-bottom: 1px solid rgba(22,24,29,0.07);
10611- background: #ffffff;
10612- margin-top: 64px;
10613- overflow: hidden;
10614- white-space: nowrap;
10615- position: relative;
10616-}
10617-
10618-.lv-ticker-track {
10619- display: inline-flex;
10620- animation: gcTicker 40s linear infinite;
10621- padding: 11px 0;
10622-}
10623-
10624-.lv-ticker-item {
10625- display: inline-flex;
10626- align-items: center;
10627- gap: 8px;
10628- font-family: 'JetBrains Mono', monospace;
10629- font-size: 11.5px;
10630- color: #6b7080;
10631- padding: 0 28px;
10632- border-right: 1px solid rgba(22,24,29,0.06);
10633-}
10634-
10635-/* Stats */
10636-.lv-stats {
10637- background: #fcfcfd;
10638-}
10639-
10640-.lv-stats-inner {
10641- max-width: 1200px;
10642- margin: 0 auto;
10643- display: grid;
10644- grid-template-columns: repeat(4, 1fr);
10645- gap: 24px;
10646- padding: 52px 28px;
10647-}
10648-
10649-.lv-stat {
10650- text-align: center;
10651-}
10652-
10653-.lv-stat-num {
10654- font-family: 'Inter Tight', sans-serif;
10655- font-weight: 700;
10656- font-size: clamp(30px, 4vw, 44px);
10657- letter-spacing: -0.025em;
10658- color: #111318;
10659-}
10660-
10661-.lv-stat-label {
10662- font-size: 13px;
10663- color: #6b7080;
10664- margin-top: 4px;
10665-}
10666-
10667-/* Loop */
10668-.lv-loop {
10669- padding: 96px 0;
10670- background: #ffffff;
10671- border-top: 1px solid rgba(22,24,29,0.07);
10672- border-bottom: 1px solid rgba(22,24,29,0.07);
10673-}
10674-
10675-.lv-loop-inner {
10676- max-width: 1200px;
10677- margin: 0 auto;
10678- padding: 0 28px;
10679-}
10680-
10681-.lv-stages {
10682- display: grid;
10683- grid-template-columns: repeat(6, 1fr);
10684- gap: 12px;
10685-}
10686-
10687-.lv-stage-card {
10688- border: 1px solid rgba(22,24,29,0.08);
10689- border-radius: 14px;
10690- background: #ffffff;
10691- padding: 20px 18px;
10692- transition: border-color 0.3s, background 0.3s;
10693-}
10694-
10695-.lv-stage-card.lv-stage-active {
10696- border-color: rgba(67,83,201,0.45);
10697- background: rgba(67,83,201,0.03);
10698-}
10699-
10700-.lv-stage-header {
10701- display: flex;
10702- align-items: center;
10703- gap: 8px;
10704- margin-bottom: 10px;
10705-}
10706-
10707-.lv-stage-n {
10708- font-family: 'JetBrains Mono', monospace;
10709- font-size: 10.5px;
10710- letter-spacing: 0.1em;
10711- text-transform: uppercase;
10712- color: #8a8d99;
10713-}
10714-
10715-.lv-stage-name {
10716- font-family: 'Inter Tight', sans-serif;
10717- font-size: 16px;
10718- font-weight: 600;
10719- letter-spacing: -0.01em;
10720- color: #16181d;
10721- margin-bottom: 5px;
10722-}
10723-
10724-.lv-stage-desc {
10725- font-size: 12px;
10726- color: #6b7080;
10727- line-height: 1.55;
10728-}
10729-
10730-.lv-stage-meta {
10731- font-family: 'JetBrains Mono', monospace;
10732- font-size: 10.5px;
10733- color: #8a8d99;
10734- margin-top: 10px;
10735- transition: color 0.3s;
10736-}
10737-
10738-.lv-stage-meta.lv-stage-meta-active {
10739- color: #4353c9;
10740-}
10741-
10742-/* Heroes */
10743-.lv-heroes {
10744- padding: 96px 0;
10745- background: #fcfcfd;
10746-}
10747-
10748-.lv-heroes-inner {
10749- max-width: 1200px;
10750- margin: 0 auto;
10751- padding: 0 28px;
10752-}
10753-
10754-.lv-heroes-header {
10755- max-width: 640px;
10756- margin-bottom: 56px;
10757-}
10758-
10759-.lv-heroes-list {
10760- display: flex;
10761- flex-direction: column;
10762- gap: 20px;
10763-}
10764-
10765-.lv-hero-card {
10766- display: grid;
10767- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
10768- gap: 48px;
10769- align-items: center;
10770- border: 1px solid rgba(22,24,29,0.08);
10771- border-radius: 20px;
10772- background: #ffffff;
10773- padding: 44px 48px;
10774- text-decoration: none;
10775- transition: border-color 0.2s, box-shadow 0.2s;
10776-}
10777-.lv-hero-card:hover {
10778- border-color: rgba(22,24,29,0.22);
10779- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
10780-}
10781-
10782-.lv-hero-card-left {}
10783-
10784-.lv-hero-card-title {
10785- font-family: 'Inter Tight', sans-serif;
10786- font-size: 26px;
10787- font-weight: 600;
10788- letter-spacing: -0.022em;
10789- line-height: 1.15;
10790- color: #16181d;
10791- margin: 0 0 12px;
10792-}
10793-
10794-.lv-hero-card-body {
10795- font-size: 14.5px;
10796- color: #6b7080;
10797- margin: 0 0 18px;
10798- line-height: 1.65;
10799-}
10800-
10801-.lv-hero-card-cta {
10802- font-size: 13.5px;
10803- font-weight: 600;
10804- color: #4353c9;
10805-}
10806-
10807-.lv-terminal {
10808- border: 1px solid rgba(22,24,29,0.07);
10809- border-radius: 14px;
10810- background: #fcfcfd;
10811- padding: 20px 22px;
10812- font-family: 'JetBrains Mono', monospace;
10813- font-size: 12px;
10814- line-height: 1.9;
10815- overflow: hidden;
10816-}
10817-
10818-.lv-terminal-line {
10819- display: flex;
10820- align-items: center;
10821- gap: 10px;
10822- white-space: nowrap;
10823- overflow: hidden;
10824- text-overflow: ellipsis;
10825-}
10826-
10827-/* Platform */
10828-.lv-platform {
10829- padding: 96px 0;
10830- background: #ffffff;
10831- border-top: 1px solid rgba(22,24,29,0.07);
10832-}
10833-
10834-.lv-platform-inner {
10835- max-width: 1200px;
10836- margin: 0 auto;
10837- padding: 0 28px;
10838-}
10839-
10840-.lv-cap-grid {
10841- display: grid;
10842- grid-template-columns: repeat(4, 1fr);
10843- gap: 24px 32px;
10844-}
10845-
10846-.lv-cap-col {}
10847-
10848-.lv-cap-group {
10849- font-family: 'JetBrains Mono', monospace;
10850- font-size: 10.5px;
10851- letter-spacing: 0.12em;
10852- text-transform: uppercase;
10853- color: #8a8d99;
10854- font-weight: 500;
10855- margin-bottom: 12px;
10856- padding-bottom: 8px;
10857- border-bottom: 1px solid rgba(22,24,29,0.07);
10858-}
10859-
10860-.lv-cap-items {
10861- display: flex;
10862- flex-direction: column;
10863- gap: 7px;
10864-}
10865-
10866-.lv-cap-item {
10867- font-size: 12.5px;
10868- color: #3a3d45;
10869- line-height: 1.45;
10870-}
10871-
10872-/* Sovereignty */
10873-.lv-sovereign {
10874- position: relative;
10875- overflow: hidden;
10876- padding: 104px 0;
10877- color: #fff;
10878- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
10879-}
10880-
10881-.lv-sovereign-grid-bg {
10882- position: absolute;
10883- inset: 0;
10884- opacity: 0.4;
10885- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
10886- background-size: 56px 56px;
10887- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
10888- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
10889-}
10890-
10891-.lv-sovereign-inner {
10892- position: relative;
10893- max-width: 1200px;
10894- margin: 0 auto;
10895- padding: 0 28px;
10896-}
10897-
10898-.lv-section-header-dark {
10899- max-width: 680px;
10900- margin: 0 auto 48px;
10901- text-align: center;
10902-}
10903-
10904-.lv-layers-grid {
10905- display: grid;
10906- grid-template-columns: repeat(4, 1fr);
10907- gap: 10px;
10908- max-width: 980px;
10909- margin: 0 auto;
10910-}
10911-
10912-.lv-layer-chip {
10913- border: 1px solid rgba(255,255,255,0.10);
10914- border-radius: 10px;
10915- padding: 12px 16px;
10916- background: rgba(255,255,255,0.03);
10917-}
10918-
10919-.lv-layer-cta {
10920- border-color: rgba(169,180,238,0.30);
10921- background: rgba(169,180,238,0.06);
10922- display: flex;
10923- align-items: center;
10924- text-decoration: none;
10925- transition: background 0.15s;
10926-}
10927-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
10928-
10929-.lv-layer-cta-text {
10930- font-size: 13px;
10931- font-weight: 500;
10932- color: #a9b4ee;
10933-}
10934-
10935-.lv-layer-n {
10936- font-family: 'JetBrains Mono', monospace;
10937- font-size: 10px;
10938- color: rgba(255,255,255,0.4);
10939- margin-bottom: 3px;
10940-}
10941-
10942-.lv-layer-name {
10943- font-size: 13px;
10944- font-weight: 500;
10945- color: rgba(255,255,255,0.92);
10946-}
10947-
10948-.lv-sovereign-feats {
10949- display: flex;
10950- gap: 44px;
10951- justify-content: center;
10952- flex-wrap: wrap;
10953- margin-top: 52px;
10954- text-align: center;
10955-}
10956-
10957-.lv-sovereign-feat {}
10958-
10959-.lv-sovereign-feat-title {
10960- font-family: 'Inter Tight', sans-serif;
10961- font-size: 20px;
10962- font-weight: 700;
10963- color: #fff;
10964-}
10965-
10966-.lv-sovereign-feat-sub {
10967- color: rgba(255,255,255,0.55);
10968- font-size: 13px;
10969- margin-top: 2px;
10970-}
10971-
10972-/* Twin cards */
10973-.lv-twin {
10974- padding: 96px 0;
10975- background: #fcfcfd;
10976-}
10977-
10978-.lv-twin-inner {
10979- max-width: 1200px;
10980- margin: 0 auto;
10981- padding: 0 28px;
10982- display: grid;
10983- grid-template-columns: 1fr 1fr;
10984- gap: 24px;
10985-}
10986-
10987-.lv-twin-card {
10988- border: 1px solid rgba(22,24,29,0.08);
10989- border-radius: 20px;
10990- background: #ffffff;
10991- padding: 44px 48px;
10992-}
10993-
10994-.lv-twin-title {
10995- font-family: 'Inter Tight', sans-serif;
10996- font-size: 24px;
10997- font-weight: 600;
10998- letter-spacing: -0.02em;
10999- line-height: 1.2;
11000- margin: 0 0 12px;
11001- color: #16181d;
11002-}
11003-
11004-.lv-twin-body {
11005- font-size: 14.5px;
11006- color: #6b7080;
11007- margin: 0 0 16px;
11008- line-height: 1.7;
11009-}
11010-
11011-.lv-twin-link {
11012- font-size: 13.5px;
11013- font-weight: 600;
11014- color: #4353c9;
11015- text-decoration: none;
11016-}
11017-.lv-twin-link:hover { text-decoration: underline; }
11018-
11019-/* Quote */
11020-.lv-quote {
11021- padding: 40px 0 96px;
11022- background: #fcfcfd;
11023-}
11024-
11025-.lv-quote-inner {
11026- max-width: 980px;
11027- margin: 0 auto;
11028- padding: 0 28px;
11029- text-align: center;
11030-}
11031-
11032-.lv-quote-text {
11033- font-family: 'Inter Tight', sans-serif;
11034- font-weight: 600;
11035- font-size: clamp(26px, 3.8vw, 42px);
11036- line-height: 1.2;
11037- letter-spacing: -0.025em;
11038- margin: 0;
11039- color: #111318;
11040-}
11041-
11042-.lv-em {
11043- font-style: normal;
11044- color: #4353c9;
11045-}
11046-
11047-/* CTA */
11048-.lv-cta-section {
11049- padding: 0 0 104px;
11050- background: #fcfcfd;
11051-}
11052-
11053-.lv-cta-card {
11054- max-width: 820px;
11055- margin: 0 auto;
11056- padding: 64px 40px;
11057- text-align: center;
11058- background: #ffffff;
11059- border: 1px solid rgba(22,24,29,0.08);
11060- border-radius: 26px;
11061- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
11062- position: relative;
11063- overflow: hidden;
11064-}
11065-
11066-.lv-cta-glow {
11067- position: absolute;
11068- inset: -40% 0 auto 0;
11069- height: 280px;
11070- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
11071- pointer-events: none;
11072-}
11073-
11074-.lv-cta-h2 {
11075- font-family: 'Inter Tight', sans-serif;
11076- font-weight: 700;
11077- letter-spacing: -0.028em;
11078- font-size: clamp(30px, 4.6vw, 48px);
11079- margin: 0;
11080- position: relative;
11081- color: #111318;
11082-}
11083-
11084-.lv-cta-sub {
11085- color: #6b7080;
11086- font-size: 17px;
11087- margin: 16px 0 30px;
11088- position: relative;
11089-}
11090-
11091-.lv-cta-actions {
11092- display: flex;
11093- gap: 12px;
11094- justify-content: center;
11095- flex-wrap: wrap;
11096- position: relative;
11097-}
11098-
11099-.lv-cta-fine {
11100- margin-top: 20px;
11101- font-family: 'JetBrains Mono', monospace;
11102- font-size: 11px;
11103- color: #8a8d99;
11104- position: relative;
11105-}
11106-
11107-/* Footer */
11108-.lv-footer {
11109- border-top: 1px solid rgba(22,24,29,0.07);
11110- background: #ffffff;
11111- padding: 56px 0 30px;
11112-}
11113-
11114-.lv-footer-inner {
11115- max-width: 1200px;
11116- margin: 0 auto;
11117- padding: 0 28px;
11118- display: flex;
11119- gap: 48px;
11120- flex-wrap: wrap;
11121- justify-content: space-between;
11122-}
11123-
11124-.lv-footer-brand {}
11125-
11126-.lv-footer-tagline {
11127- color: #6b7080;
11128- font-size: 13.5px;
11129- margin: 12px 0 0;
11130- max-width: 32ch;
11131- line-height: 1.6;
11132-}
11133-
11134-.lv-footer-cols {
11135- display: flex;
11136- gap: 64px;
11137- flex-wrap: wrap;
11138-}
11139-
11140-.lv-footer-col {
11141- display: flex;
11142- flex-direction: column;
11143- gap: 9px;
11144-}
11145-
11146-.lv-footer-col-head {
11147- font-family: 'JetBrains Mono', monospace;
11148- font-size: 11px;
11149- text-transform: uppercase;
11150- letter-spacing: 0.1em;
11151- color: #8a8d99;
11152- margin: 0 0 4px;
11153- font-weight: 500;
11154-}
11155-
11156-.lv-footer-link {
11157- color: #3a3d45;
11158- font-size: 13.5px;
11159- text-decoration: none;
11160- transition: color 0.15s;
11161-}
11162-.lv-footer-link:hover { color: #16181d; }
11163-
11164-.lv-footer-bar {
11165- max-width: 1200px;
11166- margin: 44px auto 0;
11167- padding: 22px 28px 0;
11168- border-top: 1px solid rgba(22,24,29,0.06);
11169- display: flex;
11170- justify-content: space-between;
11171- flex-wrap: wrap;
11172- gap: 8px;
11173- color: #8a8d99;
11174- font-size: 12.5px;
11175-}
11176-
11177-.lv-footer-stack {
11178- font-family: 'JetBrains Mono', monospace;
11179- font-size: 11px;
11180-}
11181-`;
11182diff --git a/src/views/layout.tsx b/src/views/layout.tsx
11183index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
11184--- a/src/views/layout.tsx
11185+++ b/src/views/layout.tsx
11186@@ -3153,9 +3153,12 @@
11187 font-weight: 500;
11188 line-height: 1.4;
11189 }
11190- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
11191- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
11192- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
11193+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
11194+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
11195+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
11196+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
11197+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
11198+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
11199 .state-merged { color: var(--accent); }
11200 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
11201
11202diff --git a/src/views/ui.tsx b/src/views/ui.tsx
11203index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
11204--- a/src/views/ui.tsx
11205+++ b/src/views/ui.tsx
11206@@ -232,7 +232,7 @@
11207
11208 export const Badge: FC<
11209 PropsWithChildren<{
11210- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
11211+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
11212 style?: string;
11213 }>
11214 > = ({ children, variant = "default", style }) => {
11215@@ -241,9 +241,12 @@
11216 variant === "closed" ? "badge-closed" :
11217 variant === "merged" ? "badge-merged" :
11218 variant === "success" ? "badge-success" :
11219- variant === "danger" ? "badge-danger" :
11220- variant === "warning" ? "badge-warning" :
11221- "badge";
11222+ variant === "danger" ? "badge-danger" :
11223+ variant === "warning" ? "badge-warning" :
11224+ variant === "live" ? "badge-live" :
11225+ variant === "soon" ? "badge-soon" :
11226+ variant === "preview" ? "badge-preview" :
11227+ "badge";
11228 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
11229 };
11230
11231
11232diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
11233index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
11234--- a/src/views/landing-pro.tsx
11235+++ b/src/views/landing-pro.tsx
11236@@ -42,7 +42,7 @@
11237
11238 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11239
11240-function icon(paths: string, color = "#4353c9", size = 20) {
11241+function icon(paths: string, color = "#0891b2", size = 20) {
11242 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
11243 }
11244
11245@@ -947,7 +947,7 @@
11246 const css = `
11247 /* %% tokens %% */
11248 :root{
11249- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
11250+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
11251 --lp-bg:#ffffff;--lp-soft:#fafafb;
11252 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
11253 --lp-border:rgba(0,0,0,.08);
11254diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
11255deleted file mode 100644
11256index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
11257--- a/src/views/landing-v2.tsx
11258+++ /dev/null
11259@@ -1,1447 +0,0 @@
11260-import type { FC } from "hono/jsx";
11261-
11262-export interface LandingPageProps {
11263- stats?: {
11264- publicRepos?: number;
11265- users?: number;
11266- };
11267-}
11268-
11269-const demoAllEvents = [
11270- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
11271- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
11272- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
11273- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
11274- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
11275-];
11276-
11277-const tickerItems = [
11278- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
11279- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
11280- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
11281- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
11282- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
11283- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
11284- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
11285- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
11286- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
11287- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
11288- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
11289- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
11290- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
11291- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
11292- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
11293- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
11294-];
11295-
11296-const stageData = [
11297- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
11298- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
11299- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
11300- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
11301- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
11302- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
11303-];
11304-
11305-const heroFeatures = [
11306- {
11307- href: "/",
11308- eyebrow: "01 � The autonomous repair loop",
11309- title: "Failures fix themselves  and show their work.",
11310- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
11311failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
11312- cta: "Watch a live repair session",
11313- mock: [
11314- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
11315- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
11316- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
11317- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
11318- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
11319- ],
11320- },
11321- {
11322- href: "/",
11323- eyebrow: "02 � Live sandbox isolation",
11324- title: "Every PR gets its own instant, disposable environment.",
11325- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
11326same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
11327- cta: "See a PR with its sandbox",
11328- mock: [
11329- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
11330- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
11331- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
11332- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
11333- ],
11334- },
11335- {
11336- href: "/",
11337- eyebrow: "03 � Multiplayer IDE workspaces",
11338- title: "You and the agent, side by side, in your editor.",
11339- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
11340agent into a silent reviewer in your gutter. The browser becomes optional.",
11341- cta: "See the editor session",
11342- mock: [
11343- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
11344- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
11345- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
11346- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
11347- ],
11348- },
11349-];
11350-
11351-const capabilities = [
11352- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
11353- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
11354- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
11355- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
11356- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
11357- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
11358- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
11359- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
11360-];
11361-
11362-const sovereignLayerNames = [
11363- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
11364- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
11365- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
11366- "Availability & recovery",
11367-];
11368-
11369-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
11370- return (
11371- <>
11372- <style dangerouslySetInnerHTML={{ __html: css }} />
11373-
11374- {/* Nav */}
11375- <header class="lv-nav">
11376- <div class="lv-nav-inner">
11377- <a href="/" class="lv-logo">
11378- <span class="lv-logo-mark"></span>gluecron
11379- </a>
11380- <nav class="lv-nav-links">
11381- <a href="#loop" class="lv-nav-link">The loop</a>
11382- <a href="#platform" class="lv-nav-link">Platform</a>
11383- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
11384- <a href="/trust" class="lv-nav-link">Trust</a>
11385- </nav>
11386- <div class="lv-nav-ctas">
11387- <a href="/login" class="lv-btn-secondary">Sign in</a>
11388- <a href="/register" class="lv-btn-primary">Start building</a>
11389- </div>
11390- </div>
11391- </header>
11392-
11393- {/* Hero */}
11394- <section class="lv-hero">
11395- <div class="lv-hero-glow"></div>
11396- <div class="lv-hero-inner">
11397- <div class="lv-hero-badge">
11398- <span class="lv-dot lv-dot-green lv-pulse"></span>
11399- Live: a repair loop converged on pr-218 while you read this
11400- </div>
11401- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
11402- <p class="lv-hero-sub">
11403- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
11404failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
11405- </p>
11406- <div class="lv-hero-actions">
11407- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
11408- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
11409- </div>
11410- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
11411-
11412- {/* Live product window */}
11413- <div class="lv-demo-window">
11414- <div class="lv-demo-bar">
11415- <span class="lv-demo-dot"></span>
11416- <span class="lv-demo-dot"></span>
11417- <span class="lv-demo-dot"></span>
11418- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
11419- <span class="lv-demo-live">
11420- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
11421- LIVE
11422- </span>
11423- </div>
11424- <div class="lv-demo-body" id="lv-demo-body">
11425- {/* Events rendered by JS */}
11426- {demoAllEvents.slice(0, 1).map((e, i) => (
11427- <div class="lv-demo-event" key={i}>
11428- <div class="lv-demo-event-track">
11429- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
11430- <span class="lv-demo-line" style="display:none"></span>
11431- </div>
11432- <div class="lv-demo-event-content">
11433- <div class="lv-demo-event-header">
11434- <span class="lv-demo-event-title">{e.title}</span>
11435- <span class="lv-demo-event-time">{e.time}</span>
11436- </div>
11437- <div class="lv-demo-event-body">{e.body}</div>
11438- </div>
11439- </div>
11440- ))}
11441- </div>
11442- </div>
11443- </div>
11444-
11445- {/* Activity ticker */}
11446- <div class="lv-ticker-wrap">
11447- <div class="lv-ticker-track">
11448- {tickerItems.map((t, i) => (
11449- <span class="lv-ticker-item" key={i}>
11450- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
11451- {t.text}
11452- </span>
11453- ))}
11454- </div>
11455- </div>
11456- </section>
11457-
11458- {/* Stat band */}
11459- <section class="lv-stats">
11460- <div class="lv-stats-inner">
11461- <div class="lv-stat">
11462- <div class="lv-stat-num">Sonnet 5</div>
11463- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
11464- </div>
11465- <div class="lv-stat">
11466- <div class="lv-stat-num">93.5%</div>
11467- <div class="lv-stat-label">of failures self-repair without a human</div>
11468- </div>
11469- <div class="lv-stat">
11470- <div class="lv-stat-num">1.9%</div>
11471- <div class="lv-stat-label">AI merges reverted  published live</div>
11472- </div>
11473- <div class="lv-stat">
11474- <div class="lv-stat-num">0</div>
11475- <div class="lv-stat-label">irreversible actions taken autonomously</div>
11476- </div>
11477- </div>
11478- </section>
11479-
11480- {/* The loop */}
11481- <section id="loop" class="lv-loop">
11482- <div class="lv-loop-inner">
11483- <div class="lv-section-header">
11484- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
11485- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
11486- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
11487- </div>
11488- <div class="lv-stages" id="lv-stages">
11489- {stageData.map((s, i) => (
11490- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
11491- <div class="lv-stage-header">
11492- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
11493- <span class="lv-stage-n">0{i + 1}</span>
11494- </div>
11495- <div class="lv-stage-name">{s.name}</div>
11496- <div class="lv-stage-desc">{s.desc}</div>
11497- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
11498- </div>
11499- ))}
11500- </div>
11501- </div>
11502- </section>
11503-
11504- {/* Three heroes */}
11505- <section class="lv-heroes">
11506- <div class="lv-heroes-inner">
11507- <div class="lv-heroes-header">
11508- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
11509- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
11510- </div>
11511- <div class="lv-heroes-list">
11512- {heroFeatures.map((h, i) => (
11513- <a href={h.href} class="lv-hero-card" key={i}>
11514- <div class="lv-hero-card-left">
11515- <div class="lv-eyebrow">{h.eyebrow}</div>
11516- <h3 class="lv-hero-card-title">{h.title}</h3>
11517- <p class="lv-hero-card-body">{h.body}</p>
11518- <span class="lv-hero-card-cta">{h.cta} �!</span>
11519- </div>
11520- <div class="lv-terminal">
11521- {h.mock.map((m, j) => (
11522- <div class="lv-terminal-line" key={j}>
11523- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
11524- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
11525- </div>
11526- ))}
11527- </div>
11528- </a>
11529- ))}
11530- </div>
11531- </div>
11532- </section>
11533-
11534- {/* Everything grid */}
11535- <section id="platform" class="lv-platform">
11536- <div class="lv-platform-inner">
11537- <div class="lv-section-header lv-section-header-center">
11538- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
11539- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
11540- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
11541- </div>
11542- <div class="lv-cap-grid">
11543- {capabilities.map((c, i) => (
11544- <div class="lv-cap-col" key={i}>
11545- <div class="lv-cap-group">{c.group}</div>
11546- <div class="lv-cap-items">
11547- {c.items.map((item, j) => (
11548- <div class="lv-cap-item" key={j}>{item}</div>
11549- ))}
11550- </div>
11551- </div>
11552- ))}
11553- </div>
11554- </div>
11555- </section>
11556-
11557- {/* Sovereignty band */}
11558- <section id="sovereign" class="lv-sovereign">
11559- <div class="lv-sovereign-grid-bg"></div>
11560- <div class="lv-sovereign-inner">
11561- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
11562- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
11563- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
11564- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
11565to private cloud, or run fully air-gapped on bare metal.</p>
11566- </div>
11567- <div class="lv-layers-grid">
11568- {sovereignLayerNames.map((name, i) => (
11569- <div class="lv-layer-chip" key={i}>
11570- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
11571- <div class="lv-layer-name">{name}</div>
11572- </div>
11573- ))}
11574- <a href="/" class="lv-layer-chip lv-layer-cta">
11575- <div class="lv-layer-cta-text">All self-owned �!</div>
11576- </a>
11577- </div>
11578- <div class="lv-sovereign-feats">
11579- <div class="lv-sovereign-feat">
11580- <div class="lv-sovereign-feat-title">Local inference first</div>
11581- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
11582- </div>
11583- <div class="lv-sovereign-feat">
11584- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
11585- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
11586- </div>
11587- <div class="lv-sovereign-feat">
11588- <div class="lv-sovereign-feat-title">Self-healing infra</div>
11589- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
11590- </div>
11591- </div>
11592- </div>
11593- </section>
11594-
11595- {/* Manual-first + reversibility */}
11596- <section class="lv-twin">
11597- <div class="lv-twin-inner">
11598- <div class="lv-twin-card">
11599- <div class="lv-eyebrow">Manual-first, always</div>
11600- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
11601- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
11602fallback. Developers who never touch AI get the best git host they've ever used.</p>
11603- </div>
11604- <div class="lv-twin-card">
11605- <div class="lv-eyebrow">The reversibility guarantee</div>
11606- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
11607- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
11608 policy, not promise. Our quality numbers are published live, unedited.</p>
11609- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
11610- </div>
11611- </div>
11612- </section>
11613-
11614- {/* Quote */}
11615- <section class="lv-quote">
11616- <div class="lv-quote-inner">
11617- <p class="lv-quote-text">
11618- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
11619- Gluecron is where code gets <em class="lv-em">finished</em>."
11620- </p>
11621- </div>
11622- </section>
11623-
11624- {/* CTA */}
11625- <section class="lv-cta-section">
11626- <div class="lv-cta-card">
11627- <div class="lv-cta-glow"></div>
11628- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
11629- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
11630- <div class="lv-cta-actions">
11631- <a href="/register" class="lv-cta-primary">Create your account �!</a>
11632- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
11633- </div>
11634- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
11635- </div>
11636- </section>
11637-
11638- {/* Footer */}
11639- <footer class="lv-footer">
11640- <div class="lv-footer-inner">
11641- <div class="lv-footer-brand">
11642- <a href="/" class="lv-logo">
11643- <span class="lv-logo-mark"></span>gluecron
11644- </a>
11645- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
11646- </div>
11647- <div class="lv-footer-cols">
11648- <div class="lv-footer-col">
11649- <h4 class="lv-footer-col-head">Product</h4>
11650- <a href="/" class="lv-footer-link">Agent workspace</a>
11651- <a href="/" class="lv-footer-link">Fleet refactors</a>
11652- <a href="/" class="lv-footer-link">Org memory</a>
11653- <a href="/" class="lv-footer-link">IDE extensions</a>
11654- </div>
11655- <div class="lv-footer-col">
11656- <h4 class="lv-footer-col-head">Platform</h4>
11657- <a href="/" class="lv-footer-link">Production layers</a>
11658- <a href="/trust" class="lv-footer-link">Trust report</a>
11659- <a href="/" class="lv-footer-link">Docs</a>
11660- <a href="/" class="lv-footer-link">Status</a>
11661- </div>
11662- <div class="lv-footer-col">
11663- <h4 class="lv-footer-col-head">Company</h4>
11664- <a href="/" class="lv-footer-link">About</a>
11665- <a href="/" class="lv-footer-link">Pricing</a>
11666- <a href="/" class="lv-footer-link">Enterprise</a>
11667- </div>
11668- </div>
11669- </div>
11670- <div class="lv-footer-bar">
11671- <span>� 2026 Gluecron</span>
11672- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
11673- </div>
11674- </footer>
11675-
11676- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
11677- </>
11678- );
11679-};
11680-
11681-export const LandingPage = LandingPageV2;
11682-export default LandingPageV2;
11683-
11684-const clientScript = `
11685-(function() {
11686- var demoAll = [
11687- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
11688- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
11689- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
11690- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
11691- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
11692- ];
11693-
11694- var demoStep = 0;
11695- var stage = 0;
11696-
11697- function renderDemo() {
11698- var container = document.getElementById('lv-demo-body');
11699- if (!container) return;
11700- var visible = demoAll.slice(0, demoStep + 1);
11701- container.innerHTML = visible.map(function(e, i) {
11702- var isLast = i === visible.length - 1;
11703- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
11704- return '<div class="lv-demo-event">' +
11705- '<div class="lv-demo-event-track">' +
11706- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
11707- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
11708- '</div>' +
11709- '<div class="lv-demo-event-content">' +
11710- '<div class="lv-demo-event-header">' +
11711- '<span class="lv-demo-event-title">' + e.title + '</span>' +
11712- '<span class="lv-demo-event-time">' + e.time + '</span>' +
11713- '</div>' +
11714- '<div class="lv-demo-event-body">' + e.body + '</div>' +
11715- '</div>' +
11716- '</div>';
11717- }).join('');
11718- }
11719-
11720- function renderStages() {
11721- var cards = document.querySelectorAll('.lv-stage-card');
11722- cards.forEach(function(card, i) {
11723- var dot = card.querySelector('.lv-dot');
11724- var meta = card.querySelector('.lv-stage-meta');
11725- if (i === stage) {
11726- card.classList.add('lv-stage-active');
11727- if (dot) {
11728- dot.classList.remove('lv-dot-idle');
11729- dot.classList.add('lv-dot-indigo', 'lv-pulse');
11730- }
11731- if (meta) meta.classList.add('lv-stage-meta-active');
11732- } else {
11733- card.classList.remove('lv-stage-active');
11734- if (dot) {
11735- dot.classList.add('lv-dot-idle');
11736- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
11737- }
11738- if (meta) meta.classList.remove('lv-stage-meta-active');
11739- }
11740- });
11741- }
11742-
11743- renderDemo();
11744-
11745- setInterval(function() {
11746- demoStep = (demoStep + 1) % 5;
11747- renderDemo();
11748- }, 3600);
11749-
11750- setInterval(function() {
11751- stage = (stage + 1) % 6;
11752- renderStages();
11753- }, 2200);
11754-})();
11755-`;
11756-
11757-const css = `
11758-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
11759-
11760-*, *::before, *::after { box-sizing: border-box; }
11761-
11762-body {
11763- margin: 0;
11764- background: #fcfcfd;
11765- -webkit-font-smoothing: antialiased;
11766- text-rendering: optimizeLegibility;
11767- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
11768- font-size: 15px;
11769- line-height: 1.6;
11770- letter-spacing: -0.008em;
11771- color: #16181d;
11772-}
11773-
11774-@keyframes gcPulse {
11775- 0%, 100% { opacity: 1; }
11776- 50% { opacity: 0.35; }
11777-}
11778-
11779-@keyframes gcTicker {
11780- 0% { transform: translateX(0); }
11781- 100% { transform: translateX(-50%); }
11782-}
11783-
11784-/* Shared utilities */
11785-.lv-dot {
11786- display: inline-block;
11787- border-radius: 50%;
11788-}
11789-.lv-dot-green { background: #1e7f5c; }
11790-.lv-dot-indigo { background: #4353c9; }
11791-.lv-dot-idle { background: #c4c6cf; }
11792-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
11793-
11794-.lv-strong { color: #16181d; font-weight: 600; }
11795-
11796-.lv-eyebrow {
11797- font-family: 'JetBrains Mono', monospace;
11798- font-size: 11px;
11799- letter-spacing: 0.12em;
11800- text-transform: uppercase;
11801- color: #8a8d99;
11802- font-weight: 500;
11803- margin-bottom: 12px;
11804-}
11805-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
11806-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
11807-
11808-.lv-h1 {
11809- font-family: 'Inter Tight', sans-serif;
11810- font-weight: 700;
11811- letter-spacing: -0.035em;
11812- font-size: clamp(44px, 7vw, 84px);
11813- line-height: 0.98;
11814- margin: 30px auto 0;
11815- max-width: 14ch;
11816- color: #111318;
11817-}
11818-
11819-.lv-h2 {
11820- font-family: 'Inter Tight', sans-serif;
11821- font-weight: 700;
11822- letter-spacing: -0.028em;
11823- font-size: clamp(30px, 4.4vw, 48px);
11824- line-height: 1.05;
11825- margin: 0;
11826- color: #111318;
11827-}
11828-
11829-.lv-h2-dark {
11830- font-family: 'Inter Tight', sans-serif;
11831- font-weight: 700;
11832- letter-spacing: -0.028em;
11833- font-size: clamp(30px, 4.6vw, 52px);
11834- line-height: 1.05;
11835- margin: 0;
11836- color: #fff;
11837-}
11838-
11839-.lv-section-header {
11840- max-width: 640px;
11841- margin: 0 auto 56px;
11842-}
11843-
11844-.lv-section-header-center {
11845- text-align: center;
11846-}
11847-
11848-.lv-section-sub {
11849- color: #6b7080;
11850- font-size: 17px;
11851- margin: 18px auto 0;
11852- max-width: 52ch;
11853-}
11854-
11855-.lv-section-sub-dark {
11856- color: rgba(255,255,255,0.72);
11857- font-size: 17px;
11858- margin: 18px auto 0;
11859- max-width: 56ch;
11860-}
11861-
11862-/* Nav */
11863-.lv-nav {
11864- position: sticky;
11865- top: 0;
11866- z-index: 60;
11867- backdrop-filter: saturate(180%) blur(14px);
11868- -webkit-backdrop-filter: saturate(180%) blur(14px);
11869- background: rgba(252,252,253,0.8);
11870- border-bottom: 1px solid rgba(22,24,29,0.07);
11871-}
11872-
11873-.lv-nav-inner {
11874- max-width: 1200px;
11875- margin: 0 auto;
11876- padding: 14px 28px;
11877- display: flex;
11878- align-items: center;
11879- gap: 28px;
11880-}
11881-
11882-.lv-logo {
11883- display: inline-flex;
11884- align-items: center;
11885- gap: 9px;
11886- font-family: 'Inter Tight', sans-serif;
11887- font-weight: 700;
11888- font-size: 17px;
11889- letter-spacing: -0.02em;
11890- color: #16181d;
11891- text-decoration: none;
11892-}
11893-
11894-.lv-logo-mark {
11895- width: 17px;
11896- height: 17px;
11897- border-radius: 5px;
11898- background: #4353c9;
11899- display: inline-block;
11900- flex-shrink: 0;
11901-}
11902-
11903-.lv-nav-links {
11904- display: flex;
11905- gap: 24px;
11906- font-size: 13.5px;
11907- font-weight: 500;
11908-}
11909-
11910-.lv-nav-link {
11911- color: #6b7080;
11912- text-decoration: none;
11913- transition: color 0.15s;
11914-}
11915-.lv-nav-link:hover { color: #16181d; }
11916-
11917-.lv-nav-ctas {
11918- margin-left: auto;
11919- display: flex;
11920- align-items: center;
11921- gap: 10px;
11922-}
11923-
11924-.lv-btn-secondary {
11925- padding: 8px 15px;
11926- border-radius: 8px;
11927- font-size: 13.5px;
11928- font-weight: 500;
11929- color: #16181d;
11930- border: 1px solid rgba(22,24,29,0.12);
11931- background: #ffffff;
11932- text-decoration: none;
11933- white-space: nowrap;
11934- transition: border-color 0.15s;
11935-}
11936-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
11937-
11938-.lv-btn-primary {
11939- padding: 8px 15px;
11940- border-radius: 8px;
11941- font-size: 13.5px;
11942- font-weight: 600;
11943- background: #16181d;
11944- color: #fff;
11945- text-decoration: none;
11946- white-space: nowrap;
11947- transition: box-shadow 0.15s;
11948-}
11949-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
11950-
11951-/* Hero */
11952-.lv-hero {
11953- position: relative;
11954- overflow: hidden;
11955- padding: 88px 0 0;
11956-}
11957-
11958-.lv-hero-glow {
11959- position: absolute;
11960- inset: -10% 0 auto 0;
11961- height: 640px;
11962- pointer-events: none;
11963- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
11964-}
11965-
11966-.lv-hero-inner {
11967- position: relative;
11968- max-width: 1200px;
11969- margin: 0 auto;
11970- padding: 0 28px;
11971- text-align: center;
11972-}
11973-
11974-.lv-hero-badge {
11975- display: inline-flex;
11976- align-items: center;
11977- gap: 9px;
11978- font-size: 12.5px;
11979- font-weight: 600;
11980- color: #3a3d45;
11981- background: #ffffff;
11982- border: 1px solid rgba(22,24,29,0.10);
11983- border-radius: 9999px;
11984- padding: 7px 16px;
11985- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
11986-}
11987-
11988-.lv-hero-sub {
11989- font-size: clamp(16px, 2vw, 19px);
11990- color: #6b7080;
11991- max-width: 60ch;
11992- margin: 24px auto 0;
11993- font-weight: 450;
11994- line-height: 1.65;
11995-}
11996-
11997-.lv-hero-actions {
11998- display: flex;
11999- gap: 12px;
12000- justify-content: center;
12001- flex-wrap: wrap;
12002- margin-top: 32px;
12003-}
12004-
12005-.lv-cta-primary {
12006- padding: 13px 24px;
12007- border-radius: 11px;
12008- font-size: 15.5px;
12009- font-weight: 600;
12010- background: #16181d;
12011- color: #fff;
12012- text-decoration: none;
12013- white-space: nowrap;
12014- transition: box-shadow 0.15s;
12015-}
12016-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
12017-
12018-.lv-cta-secondary {
12019- padding: 13px 24px;
12020- border-radius: 11px;
12021- font-size: 15.5px;
12022- font-weight: 600;
12023- color: #16181d;
12024- border: 1px solid rgba(22,24,29,0.14);
12025- background: #ffffff;
12026- text-decoration: none;
12027- white-space: nowrap;
12028- transition: border-color 0.15s;
12029-}
12030-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
12031-
12032-.lv-hero-tag {
12033- margin-top: 18px;
12034- font-family: 'JetBrains Mono', monospace;
12035- font-size: 11.5px;
12036- letter-spacing: 0.08em;
12037- text-transform: uppercase;
12038- color: #8a8d99;
12039-}
12040-
12041-/* Demo window */
12042-.lv-demo-window {
12043- margin: 56px auto 0;
12044- max-width: 860px;
12045- text-align: left;
12046- background: #ffffff;
12047- border: 1px solid rgba(22,24,29,0.09);
12048- border-radius: 18px;
12049- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
12050- overflow: hidden;
12051-}
12052-
12053-.lv-demo-bar {
12054- display: flex;
12055- align-items: center;
12056- gap: 7px;
12057- padding: 12px 18px;
12058- border-bottom: 1px solid rgba(22,24,29,0.07);
12059- background: #fcfcfd;
12060-}
12061-
12062-.lv-demo-dot {
12063- width: 10px;
12064- height: 10px;
12065- border-radius: 50%;
12066- background: #e4e5ea;
12067-}
12068-
12069-.lv-demo-url {
12070- margin-left: 10px;
12071- font-family: 'JetBrains Mono', monospace;
12072- font-size: 12px;
12073- color: #6b7080;
12074-}
12075-
12076-.lv-demo-live {
12077- margin-left: auto;
12078- display: inline-flex;
12079- align-items: center;
12080- gap: 6px;
12081- font-size: 11px;
12082- font-weight: 600;
12083- color: #1e7f5c;
12084-}
12085-
12086-.lv-demo-body {
12087- padding: 22px 24px;
12088-}
12089-
12090-.lv-demo-event {
12091- display: grid;
12092- grid-template-columns: 18px minmax(0, 1fr);
12093- gap: 14px;
12094- padding-bottom: 20px;
12095- position: relative;
12096-}
12097-.lv-demo-event:last-child { padding-bottom: 0; }
12098-
12099-.lv-demo-event-track {
12100- display: flex;
12101- flex-direction: column;
12102- align-items: center;
12103-}
12104-
12105-.lv-demo-line {
12106- width: 1px;
12107- flex: 1;
12108- background: rgba(22,24,29,0.08);
12109- margin-top: 5px;
12110- min-height: 20px;
12111-}
12112-
12113-.lv-demo-event-content {}
12114-
12115-.lv-demo-event-header {
12116- display: flex;
12117- align-items: baseline;
12118- gap: 10px;
12119-}
12120-
12121-.lv-demo-event-title {
12122- font-size: 13.5px;
12123- font-weight: 600;
12124- color: #16181d;
12125-}
12126-
12127-.lv-demo-event-time {
12128- font-family: 'JetBrains Mono', monospace;
12129- font-size: 11px;
12130- color: #8a8d99;
12131-}
12132-
12133-.lv-demo-event-body {
12134- font-size: 13px;
12135- color: #6b7080;
12136- margin-top: 2px;
12137-}
12138-
12139-/* Ticker */
12140-.lv-ticker-wrap {
12141- border-top: 1px solid rgba(22,24,29,0.07);
12142- border-bottom: 1px solid rgba(22,24,29,0.07);
12143- background: #ffffff;
12144- margin-top: 64px;
12145- overflow: hidden;
12146- white-space: nowrap;
12147- position: relative;
12148-}
12149-
12150-.lv-ticker-track {
12151- display: inline-flex;
12152- animation: gcTicker 40s linear infinite;
12153- padding: 11px 0;
12154-}
12155-
12156-.lv-ticker-item {
12157- display: inline-flex;
12158- align-items: center;
12159- gap: 8px;
12160- font-family: 'JetBrains Mono', monospace;
12161- font-size: 11.5px;
12162- color: #6b7080;
12163- padding: 0 28px;
12164- border-right: 1px solid rgba(22,24,29,0.06);
12165-}
12166-
12167-/* Stats */
12168-.lv-stats {
12169- background: #fcfcfd;
12170-}
12171-
12172-.lv-stats-inner {
12173- max-width: 1200px;
12174- margin: 0 auto;
12175- display: grid;
12176- grid-template-columns: repeat(4, 1fr);
12177- gap: 24px;
12178- padding: 52px 28px;
12179-}
12180-
12181-.lv-stat {
12182- text-align: center;
12183-}
12184-
12185-.lv-stat-num {
12186- font-family: 'Inter Tight', sans-serif;
12187- font-weight: 700;
12188- font-size: clamp(30px, 4vw, 44px);
12189- letter-spacing: -0.025em;
12190- color: #111318;
12191-}
12192-
12193-.lv-stat-label {
12194- font-size: 13px;
12195- color: #6b7080;
12196- margin-top: 4px;
12197-}
12198-
12199-/* Loop */
12200-.lv-loop {
12201- padding: 96px 0;
12202- background: #ffffff;
12203- border-top: 1px solid rgba(22,24,29,0.07);
12204- border-bottom: 1px solid rgba(22,24,29,0.07);
12205-}
12206-
12207-.lv-loop-inner {
12208- max-width: 1200px;
12209- margin: 0 auto;
12210- padding: 0 28px;
12211-}
12212-
12213-.lv-stages {
12214- display: grid;
12215- grid-template-columns: repeat(6, 1fr);
12216- gap: 12px;
12217-}
12218-
12219-.lv-stage-card {
12220- border: 1px solid rgba(22,24,29,0.08);
12221- border-radius: 14px;
12222- background: #ffffff;
12223- padding: 20px 18px;
12224- transition: border-color 0.3s, background 0.3s;
12225-}
12226-
12227-.lv-stage-card.lv-stage-active {
12228- border-color: rgba(67,83,201,0.45);
12229- background: rgba(67,83,201,0.03);
12230-}
12231-
12232-.lv-stage-header {
12233- display: flex;
12234- align-items: center;
12235- gap: 8px;
12236- margin-bottom: 10px;
12237-}
12238-
12239-.lv-stage-n {
12240- font-family: 'JetBrains Mono', monospace;
12241- font-size: 10.5px;
12242- letter-spacing: 0.1em;
12243- text-transform: uppercase;
12244- color: #8a8d99;
12245-}
12246-
12247-.lv-stage-name {
12248- font-family: 'Inter Tight', sans-serif;
12249- font-size: 16px;
12250- font-weight: 600;
12251- letter-spacing: -0.01em;
12252- color: #16181d;
12253- margin-bottom: 5px;
12254-}
12255-
12256-.lv-stage-desc {
12257- font-size: 12px;
12258- color: #6b7080;
12259- line-height: 1.55;
12260-}
12261-
12262-.lv-stage-meta {
12263- font-family: 'JetBrains Mono', monospace;
12264- font-size: 10.5px;
12265- color: #8a8d99;
12266- margin-top: 10px;
12267- transition: color 0.3s;
12268-}
12269-
12270-.lv-stage-meta.lv-stage-meta-active {
12271- color: #4353c9;
12272-}
12273-
12274-/* Heroes */
12275-.lv-heroes {
12276- padding: 96px 0;
12277- background: #fcfcfd;
12278-}
12279-
12280-.lv-heroes-inner {
12281- max-width: 1200px;
12282- margin: 0 auto;
12283- padding: 0 28px;
12284-}
12285-
12286-.lv-heroes-header {
12287- max-width: 640px;
12288- margin-bottom: 56px;
12289-}
12290-
12291-.lv-heroes-list {
12292- display: flex;
12293- flex-direction: column;
12294- gap: 20px;
12295-}
12296-
12297-.lv-hero-card {
12298- display: grid;
12299- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
12300- gap: 48px;
12301- align-items: center;
12302- border: 1px solid rgba(22,24,29,0.08);
12303- border-radius: 20px;
12304- background: #ffffff;
12305- padding: 44px 48px;
12306- text-decoration: none;
12307- transition: border-color 0.2s, box-shadow 0.2s;
12308-}
12309-.lv-hero-card:hover {
12310- border-color: rgba(22,24,29,0.22);
12311- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
12312-}
12313-
12314-.lv-hero-card-left {}
12315-
12316-.lv-hero-card-title {
12317- font-family: 'Inter Tight', sans-serif;
12318- font-size: 26px;
12319- font-weight: 600;
12320- letter-spacing: -0.022em;
12321- line-height: 1.15;
12322- color: #16181d;
12323- margin: 0 0 12px;
12324-}
12325-
12326-.lv-hero-card-body {
12327- font-size: 14.5px;
12328- color: #6b7080;
12329- margin: 0 0 18px;
12330- line-height: 1.65;
12331-}
12332-
12333-.lv-hero-card-cta {
12334- font-size: 13.5px;
12335- font-weight: 600;
12336- color: #4353c9;
12337-}
12338-
12339-.lv-terminal {
12340- border: 1px solid rgba(22,24,29,0.07);
12341- border-radius: 14px;
12342- background: #fcfcfd;
12343- padding: 20px 22px;
12344- font-family: 'JetBrains Mono', monospace;
12345- font-size: 12px;
12346- line-height: 1.9;
12347- overflow: hidden;
12348-}
12349-
12350-.lv-terminal-line {
12351- display: flex;
12352- align-items: center;
12353- gap: 10px;
12354- white-space: nowrap;
12355- overflow: hidden;
12356- text-overflow: ellipsis;
12357-}
12358-
12359-/* Platform */
12360-.lv-platform {
12361- padding: 96px 0;
12362- background: #ffffff;
12363- border-top: 1px solid rgba(22,24,29,0.07);
12364-}
12365-
12366-.lv-platform-inner {
12367- max-width: 1200px;
12368- margin: 0 auto;
12369- padding: 0 28px;
12370-}
12371-
12372-.lv-cap-grid {
12373- display: grid;
12374- grid-template-columns: repeat(4, 1fr);
12375- gap: 24px 32px;
12376-}
12377-
12378-.lv-cap-col {}
12379-
12380-.lv-cap-group {
12381- font-family: 'JetBrains Mono', monospace;
12382- font-size: 10.5px;
12383- letter-spacing: 0.12em;
12384- text-transform: uppercase;
12385- color: #8a8d99;
12386- font-weight: 500;
12387- margin-bottom: 12px;
12388- padding-bottom: 8px;
12389- border-bottom: 1px solid rgba(22,24,29,0.07);
12390-}
12391-
12392-.lv-cap-items {
12393- display: flex;
12394- flex-direction: column;
12395- gap: 7px;
12396-}
12397-
12398-.lv-cap-item {
12399- font-size: 12.5px;
12400- color: #3a3d45;
12401- line-height: 1.45;
12402-}
12403-
12404-/* Sovereignty */
12405-.lv-sovereign {
12406- position: relative;
12407- overflow: hidden;
12408- padding: 104px 0;
12409- color: #fff;
12410- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
12411-}
12412-
12413-.lv-sovereign-grid-bg {
12414- position: absolute;
12415- inset: 0;
12416- opacity: 0.4;
12417- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
12418- background-size: 56px 56px;
12419- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
12420- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
12421-}
12422-
12423-.lv-sovereign-inner {
12424- position: relative;
12425- max-width: 1200px;
12426- margin: 0 auto;
12427- padding: 0 28px;
12428-}
12429-
12430-.lv-section-header-dark {
12431- max-width: 680px;
12432- margin: 0 auto 48px;
12433- text-align: center;
12434-}
12435-
12436-.lv-layers-grid {
12437- display: grid;
12438- grid-template-columns: repeat(4, 1fr);
12439- gap: 10px;
12440- max-width: 980px;
12441- margin: 0 auto;
12442-}
12443-
12444-.lv-layer-chip {
12445- border: 1px solid rgba(255,255,255,0.10);
12446- border-radius: 10px;
12447- padding: 12px 16px;
12448- background: rgba(255,255,255,0.03);
12449-}
12450-
12451-.lv-layer-cta {
12452- border-color: rgba(169,180,238,0.30);
12453- background: rgba(169,180,238,0.06);
12454- display: flex;
12455- align-items: center;
12456- text-decoration: none;
12457- transition: background 0.15s;
12458-}
12459-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
12460-
12461-.lv-layer-cta-text {
12462- font-size: 13px;
12463- font-weight: 500;
12464- color: #a9b4ee;
12465-}
12466-
12467-.lv-layer-n {
12468- font-family: 'JetBrains Mono', monospace;
12469- font-size: 10px;
12470- color: rgba(255,255,255,0.4);
12471- margin-bottom: 3px;
12472-}
12473-
12474-.lv-layer-name {
12475- font-size: 13px;
12476- font-weight: 500;
12477- color: rgba(255,255,255,0.92);
12478-}
12479-
12480-.lv-sovereign-feats {
12481- display: flex;
12482- gap: 44px;
12483- justify-content: center;
12484- flex-wrap: wrap;
12485- margin-top: 52px;
12486- text-align: center;
12487-}
12488-
12489-.lv-sovereign-feat {}
12490-
12491-.lv-sovereign-feat-title {
12492- font-family: 'Inter Tight', sans-serif;
12493- font-size: 20px;
12494- font-weight: 700;
12495- color: #fff;
12496-}
12497-
12498-.lv-sovereign-feat-sub {
12499- color: rgba(255,255,255,0.55);
12500- font-size: 13px;
12501- margin-top: 2px;
12502-}
12503-
12504-/* Twin cards */
12505-.lv-twin {
12506- padding: 96px 0;
12507- background: #fcfcfd;
12508-}
12509-
12510-.lv-twin-inner {
12511- max-width: 1200px;
12512- margin: 0 auto;
12513- padding: 0 28px;
12514- display: grid;
12515- grid-template-columns: 1fr 1fr;
12516- gap: 24px;
12517-}
12518-
12519-.lv-twin-card {
12520- border: 1px solid rgba(22,24,29,0.08);
12521- border-radius: 20px;
12522- background: #ffffff;
12523- padding: 44px 48px;
12524-}
12525-
12526-.lv-twin-title {
12527- font-family: 'Inter Tight', sans-serif;
12528- font-size: 24px;
12529- font-weight: 600;
12530- letter-spacing: -0.02em;
12531- line-height: 1.2;
12532- margin: 0 0 12px;
12533- color: #16181d;
12534-}
12535-
12536-.lv-twin-body {
12537- font-size: 14.5px;
12538- color: #6b7080;
12539- margin: 0 0 16px;
12540- line-height: 1.7;
12541-}
12542-
12543-.lv-twin-link {
12544- font-size: 13.5px;
12545- font-weight: 600;
12546- color: #4353c9;
12547- text-decoration: none;
12548-}
12549-.lv-twin-link:hover { text-decoration: underline; }
12550-
12551-/* Quote */
12552-.lv-quote {
12553- padding: 40px 0 96px;
12554- background: #fcfcfd;
12555-}
12556-
12557-.lv-quote-inner {
12558- max-width: 980px;
12559- margin: 0 auto;
12560- padding: 0 28px;
12561- text-align: center;
12562-}
12563-
12564-.lv-quote-text {
12565- font-family: 'Inter Tight', sans-serif;
12566- font-weight: 600;
12567- font-size: clamp(26px, 3.8vw, 42px);
12568- line-height: 1.2;
12569- letter-spacing: -0.025em;
12570- margin: 0;
12571- color: #111318;
12572-}
12573-
12574-.lv-em {
12575- font-style: normal;
12576- color: #4353c9;
12577-}
12578-
12579-/* CTA */
12580-.lv-cta-section {
12581- padding: 0 0 104px;
12582- background: #fcfcfd;
12583-}
12584-
12585-.lv-cta-card {
12586- max-width: 820px;
12587- margin: 0 auto;
12588- padding: 64px 40px;
12589- text-align: center;
12590- background: #ffffff;
12591- border: 1px solid rgba(22,24,29,0.08);
12592- border-radius: 26px;
12593- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
12594- position: relative;
12595- overflow: hidden;
12596-}
12597-
12598-.lv-cta-glow {
12599- position: absolute;
12600- inset: -40% 0 auto 0;
12601- height: 280px;
12602- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
12603- pointer-events: none;
12604-}
12605-
12606-.lv-cta-h2 {
12607- font-family: 'Inter Tight', sans-serif;
12608- font-weight: 700;
12609- letter-spacing: -0.028em;
12610- font-size: clamp(30px, 4.6vw, 48px);
12611- margin: 0;
12612- position: relative;
12613- color: #111318;
12614-}
12615-
12616-.lv-cta-sub {
12617- color: #6b7080;
12618- font-size: 17px;
12619- margin: 16px 0 30px;
12620- position: relative;
12621-}
12622-
12623-.lv-cta-actions {
12624- display: flex;
12625- gap: 12px;
12626- justify-content: center;
12627- flex-wrap: wrap;
12628- position: relative;
12629-}
12630-
12631-.lv-cta-fine {
12632- margin-top: 20px;
12633- font-family: 'JetBrains Mono', monospace;
12634- font-size: 11px;
12635- color: #8a8d99;
12636- position: relative;
12637-}
12638-
12639-/* Footer */
12640-.lv-footer {
12641- border-top: 1px solid rgba(22,24,29,0.07);
12642- background: #ffffff;
12643- padding: 56px 0 30px;
12644-}
12645-
12646-.lv-footer-inner {
12647- max-width: 1200px;
12648- margin: 0 auto;
12649- padding: 0 28px;
12650- display: flex;
12651- gap: 48px;
12652- flex-wrap: wrap;
12653- justify-content: space-between;
12654-}
12655-
12656-.lv-footer-brand {}
12657-
12658-.lv-footer-tagline {
12659- color: #6b7080;
12660- font-size: 13.5px;
12661- margin: 12px 0 0;
12662- max-width: 32ch;
12663- line-height: 1.6;
12664-}
12665-
12666-.lv-footer-cols {
12667- display: flex;
12668- gap: 64px;
12669- flex-wrap: wrap;
12670-}
12671-
12672-.lv-footer-col {
12673- display: flex;
12674- flex-direction: column;
12675- gap: 9px;
12676-}
12677-
12678-.lv-footer-col-head {
12679- font-family: 'JetBrains Mono', monospace;
12680- font-size: 11px;
12681- text-transform: uppercase;
12682- letter-spacing: 0.1em;
12683- color: #8a8d99;
12684- margin: 0 0 4px;
12685- font-weight: 500;
12686-}
12687-
12688-.lv-footer-link {
12689- color: #3a3d45;
12690- font-size: 13.5px;
12691- text-decoration: none;
12692- transition: color 0.15s;
12693-}
12694-.lv-footer-link:hover { color: #16181d; }
12695-
12696-.lv-footer-bar {
12697- max-width: 1200px;
12698- margin: 44px auto 0;
12699- padding: 22px 28px 0;
12700- border-top: 1px solid rgba(22,24,29,0.06);
12701- display: flex;
12702- justify-content: space-between;
12703- flex-wrap: wrap;
12704- gap: 8px;
12705- color: #8a8d99;
12706- font-size: 12.5px;
12707-}
12708-
12709-.lv-footer-stack {
12710- font-family: 'JetBrains Mono', monospace;
12711- font-size: 11px;
12712-}
12713-`;
12714diff --git a/src/views/layout.tsx b/src/views/layout.tsx
12715index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
12716--- a/src/views/layout.tsx
12717+++ b/src/views/layout.tsx
12718@@ -3153,9 +3153,12 @@
12719 font-weight: 500;
12720 line-height: 1.4;
12721 }
12722- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
12723- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
12724- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
12725+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
12726+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
12727+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
12728+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
12729+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
12730+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
12731 .state-merged { color: var(--accent); }
12732 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
12733
12734diff --git a/src/views/ui.tsx b/src/views/ui.tsx
12735index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
12736--- a/src/views/ui.tsx
12737+++ b/src/views/ui.tsx
12738@@ -232,7 +232,7 @@
12739
12740 export const Badge: FC<
12741 PropsWithChildren<{
12742- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
12743+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
12744 style?: string;
12745 }>
12746 > = ({ children, variant = "default", style }) => {
12747@@ -241,9 +241,12 @@
12748 variant === "closed" ? "badge-closed" :
12749 variant === "merged" ? "badge-merged" :
12750 variant === "success" ? "badge-success" :
12751- variant === "danger" ? "badge-danger" :
12752- variant === "warning" ? "badge-warning" :
12753- "badge";
12754+ variant === "danger" ? "badge-danger" :
12755+ variant === "warning" ? "badge-warning" :
12756+ variant === "live" ? "badge-live" :
12757+ variant === "soon" ? "badge-soon" :
12758+ variant === "preview" ? "badge-preview" :
12759+ "badge";
12760 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
12761 };
12762
12763
12764codex
12765The suite is still active with no failure output yet. I m letting it reach its configured timeout/completion and will report exact pass/fail totals rather than treating silence as success.
127662026-07-17T06:19:21.473846Z ERROR codex_core::tools::router: error=Exit code: 124
12767Wall time: 124.1 seconds
12768Output:
12769command timed out after 124085 milliseconds
12770
12771 exited 124 in 124085ms:
127722026-07-17T06:19:21.542903Z ERROR codex_core::tools::router: error=Exit code: 124
12773Wall time: 124.1 seconds
12774Output:
12775command timed out after 124145 milliseconds
12776
12777 exited 124 in 124145ms:
12778diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
12779index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
12780--- a/src/views/landing-pro.tsx
12781+++ b/src/views/landing-pro.tsx
12782@@ -42,7 +42,7 @@
12783
12784 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12785
12786-function icon(paths: string, color = "#4353c9", size = 20) {
12787+function icon(paths: string, color = "#0891b2", size = 20) {
12788 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
12789 }
12790
12791@@ -947,7 +947,7 @@
12792 const css = `
12793 /* %% tokens %% */
12794 :root{
12795- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
12796+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
12797 --lp-bg:#ffffff;--lp-soft:#fafafb;
12798 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
12799 --lp-border:rgba(0,0,0,.08);
12800diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
12801deleted file mode 100644
12802index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
12803--- a/src/views/landing-v2.tsx
12804+++ /dev/null
12805@@ -1,1447 +0,0 @@
12806-import type { FC } from "hono/jsx";
12807-
12808-export interface LandingPageProps {
12809- stats?: {
12810- publicRepos?: number;
12811- users?: number;
12812- };
12813-}
12814-
12815-const demoAllEvents = [
12816- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
12817- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
12818- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
12819- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
12820- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
12821-];
12822-
12823-const tickerItems = [
12824- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
12825- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
12826- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
12827- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
12828- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
12829- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
12830- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
12831- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
12832- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
12833- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
12834- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
12835- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
12836- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
12837- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
12838- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
12839- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
12840-];
12841-
12842-const stageData = [
12843- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
12844- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
12845- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
12846- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
12847- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
12848- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
12849-];
12850-
12851-const heroFeatures = [
12852- {
12853- href: "/",
12854- eyebrow: "01 � The autonomous repair loop",
12855- title: "Failures fix themselves  and show their work.",
12856- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
12857failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
12858- cta: "Watch a live repair session",
12859- mock: [
12860- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
12861- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
12862- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
12863- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
12864- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
12865- ],
12866- },
12867- {
12868- href: "/",
12869- eyebrow: "02 � Live sandbox isolation",
12870- title: "Every PR gets its own instant, disposable environment.",
12871- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
12872same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
12873- cta: "See a PR with its sandbox",
12874- mock: [
12875- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
12876- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
12877- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
12878- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
12879- ],
12880- },
12881- {
12882- href: "/",
12883- eyebrow: "03 � Multiplayer IDE workspaces",
12884- title: "You and the agent, side by side, in your editor.",
12885- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
12886agent into a silent reviewer in your gutter. The browser becomes optional.",
12887- cta: "See the editor session",
12888- mock: [
12889- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
12890- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
12891- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
12892- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
12893- ],
12894- },
12895-];
12896-
12897-const capabilities = [
12898- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
12899- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
12900- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
12901- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
12902- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
12903- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
12904- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
12905- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
12906-];
12907-
12908-const sovereignLayerNames = [
12909- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
12910- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
12911- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
12912- "Availability & recovery",
12913-];
12914-
12915-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
12916- return (
12917- <>
12918- <style dangerouslySetInnerHTML={{ __html: css }} />
12919-
12920- {/* Nav */}
12921- <header class="lv-nav">
12922- <div class="lv-nav-inner">
12923- <a href="/" class="lv-logo">
12924- <span class="lv-logo-mark"></span>gluecron
12925- </a>
12926- <nav class="lv-nav-links">
12927- <a href="#loop" class="lv-nav-link">The loop</a>
12928- <a href="#platform" class="lv-nav-link">Platform</a>
12929- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
12930- <a href="/trust" class="lv-nav-link">Trust</a>
12931- </nav>
12932- <div class="lv-nav-ctas">
12933- <a href="/login" class="lv-btn-secondary">Sign in</a>
12934- <a href="/register" class="lv-btn-primary">Start building</a>
12935- </div>
12936- </div>
12937- </header>
12938-
12939- {/* Hero */}
12940- <section class="lv-hero">
12941- <div class="lv-hero-glow"></div>
12942- <div class="lv-hero-inner">
12943- <div class="lv-hero-badge">
12944- <span class="lv-dot lv-dot-green lv-pulse"></span>
12945- Live: a repair loop converged on pr-218 while you read this
12946- </div>
12947- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
12948- <p class="lv-hero-sub">
12949- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
12950failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
12951- </p>
12952- <div class="lv-hero-actions">
12953- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
12954- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
12955- </div>
12956- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
12957-
12958- {/* Live product window */}
12959- <div class="lv-demo-window">
12960- <div class="lv-demo-bar">
12961- <span class="lv-demo-dot"></span>
12962- <span class="lv-demo-dot"></span>
12963- <span class="lv-demo-dot"></span>
12964- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
12965- <span class="lv-demo-live">
12966- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
12967- LIVE
12968- </span>
12969- </div>
12970- <div class="lv-demo-body" id="lv-demo-body">
12971- {/* Events rendered by JS */}
12972- {demoAllEvents.slice(0, 1).map((e, i) => (
12973- <div class="lv-demo-event" key={i}>
12974- <div class="lv-demo-event-track">
12975- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
12976- <span class="lv-demo-line" style="display:none"></span>
12977- </div>
12978- <div class="lv-demo-event-content">
12979- <div class="lv-demo-event-header">
12980- <span class="lv-demo-event-title">{e.title}</span>
12981- <span class="lv-demo-event-time">{e.time}</span>
12982- </div>
12983- <div class="lv-demo-event-body">{e.body}</div>
12984- </div>
12985- </div>
12986- ))}
12987- </div>
12988- </div>
12989- </div>
12990-
12991- {/* Activity ticker */}
12992- <div class="lv-ticker-wrap">
12993- <div class="lv-ticker-track">
12994- {tickerItems.map((t, i) => (
12995- <span class="lv-ticker-item" key={i}>
12996- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
12997- {t.text}
12998- </span>
12999- ))}
13000- </div>
13001- </div>
13002- </section>
13003-
13004- {/* Stat band */}
13005- <section class="lv-stats">
13006- <div class="lv-stats-inner">
13007- <div class="lv-stat">
13008- <div class="lv-stat-num">Sonnet 5</div>
13009- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
13010- </div>
13011- <div class="lv-stat">
13012- <div class="lv-stat-num">93.5%</div>
13013- <div class="lv-stat-label">of failures self-repair without a human</div>
13014- </div>
13015- <div class="lv-stat">
13016- <div class="lv-stat-num">1.9%</div>
13017- <div class="lv-stat-label">AI merges reverted  published live</div>
13018- </div>
13019- <div class="lv-stat">
13020- <div class="lv-stat-num">0</div>
13021- <div class="lv-stat-label">irreversible actions taken autonomously</div>
13022- </div>
13023- </div>
13024- </section>
13025-
13026- {/* The loop */}
13027- <section id="loop" class="lv-loop">
13028- <div class="lv-loop-inner">
13029- <div class="lv-section-header">
13030- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
13031- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
13032- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
13033- </div>
13034- <div class="lv-stages" id="lv-stages">
13035- {stageData.map((s, i) => (
13036- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
13037- <div class="lv-stage-header">
13038- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
13039- <span class="lv-stage-n">0{i + 1}</span>
13040- </div>
13041- <div class="lv-stage-name">{s.name}</div>
13042- <div class="lv-stage-desc">{s.desc}</div>
13043- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
13044- </div>
13045- ))}
13046- </div>
13047- </div>
13048- </section>
13049-
13050- {/* Three heroes */}
13051- <section class="lv-heroes">
13052- <div class="lv-heroes-inner">
13053- <div class="lv-heroes-header">
13054- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
13055- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
13056- </div>
13057- <div class="lv-heroes-list">
13058- {heroFeatures.map((h, i) => (
13059- <a href={h.href} class="lv-hero-card" key={i}>
13060- <div class="lv-hero-card-left">
13061- <div class="lv-eyebrow">{h.eyebrow}</div>
13062- <h3 class="lv-hero-card-title">{h.title}</h3>
13063- <p class="lv-hero-card-body">{h.body}</p>
13064- <span class="lv-hero-card-cta">{h.cta} �!</span>
13065- </div>
13066- <div class="lv-terminal">
13067- {h.mock.map((m, j) => (
13068- <div class="lv-terminal-line" key={j}>
13069- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
13070- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
13071- </div>
13072- ))}
13073- </div>
13074- </a>
13075- ))}
13076- </div>
13077- </div>
13078- </section>
13079-
13080- {/* Everything grid */}
13081- <section id="platform" class="lv-platform">
13082- <div class="lv-platform-inner">
13083- <div class="lv-section-header lv-section-header-center">
13084- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
13085- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
13086- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
13087- </div>
13088- <div class="lv-cap-grid">
13089- {capabilities.map((c, i) => (
13090- <div class="lv-cap-col" key={i}>
13091- <div class="lv-cap-group">{c.group}</div>
13092- <div class="lv-cap-items">
13093- {c.items.map((item, j) => (
13094- <div class="lv-cap-item" key={j}>{item}</div>
13095- ))}
13096- </div>
13097- </div>
13098- ))}
13099- </div>
13100- </div>
13101- </section>
13102-
13103- {/* Sovereignty band */}
13104- <section id="sovereign" class="lv-sovereign">
13105- <div class="lv-sovereign-grid-bg"></div>
13106- <div class="lv-sovereign-inner">
13107- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
13108- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
13109- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
13110- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
13111to private cloud, or run fully air-gapped on bare metal.</p>
13112- </div>
13113- <div class="lv-layers-grid">
13114- {sovereignLayerNames.map((name, i) => (
13115- <div class="lv-layer-chip" key={i}>
13116- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
13117- <div class="lv-layer-name">{name}</div>
13118- </div>
13119- ))}
13120- <a href="/" class="lv-layer-chip lv-layer-cta">
13121- <div class="lv-layer-cta-text">All self-owned �!</div>
13122- </a>
13123- </div>
13124- <div class="lv-sovereign-feats">
13125- <div class="lv-sovereign-feat">
13126- <div class="lv-sovereign-feat-title">Local inference first</div>
13127- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
13128- </div>
13129- <div class="lv-sovereign-feat">
13130- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
13131- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
13132- </div>
13133- <div class="lv-sovereign-feat">
13134- <div class="lv-sovereign-feat-title">Self-healing infra</div>
13135- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
13136- </div>
13137- </div>
13138- </div>
13139- </section>
13140-
13141- {/* Manual-first + reversibility */}
13142- <section class="lv-twin">
13143- <div class="lv-twin-inner">
13144- <div class="lv-twin-card">
13145- <div class="lv-eyebrow">Manual-first, always</div>
13146- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
13147- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
13148fallback. Developers who never touch AI get the best git host they've ever used.</p>
13149- </div>
13150- <div class="lv-twin-card">
13151- <div class="lv-eyebrow">The reversibility guarantee</div>
13152- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
13153- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
13154 policy, not promise. Our quality numbers are published live, unedited.</p>
13155- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
13156- </div>
13157- </div>
13158- </section>
13159-
13160- {/* Quote */}
13161- <section class="lv-quote">
13162- <div class="lv-quote-inner">
13163- <p class="lv-quote-text">
13164- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
13165- Gluecron is where code gets <em class="lv-em">finished</em>."
13166- </p>
13167- </div>
13168- </section>
13169-
13170- {/* CTA */}
13171- <section class="lv-cta-section">
13172- <div class="lv-cta-card">
13173- <div class="lv-cta-glow"></div>
13174- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
13175- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
13176- <div class="lv-cta-actions">
13177- <a href="/register" class="lv-cta-primary">Create your account �!</a>
13178- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
13179- </div>
13180- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
13181- </div>
13182- </section>
13183-
13184- {/* Footer */}
13185- <footer class="lv-footer">
13186- <div class="lv-footer-inner">
13187- <div class="lv-footer-brand">
13188- <a href="/" class="lv-logo">
13189- <span class="lv-logo-mark"></span>gluecron
13190- </a>
13191- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
13192- </div>
13193- <div class="lv-footer-cols">
13194- <div class="lv-footer-col">
13195- <h4 class="lv-footer-col-head">Product</h4>
13196- <a href="/" class="lv-footer-link">Agent workspace</a>
13197- <a href="/" class="lv-footer-link">Fleet refactors</a>
13198- <a href="/" class="lv-footer-link">Org memory</a>
13199- <a href="/" class="lv-footer-link">IDE extensions</a>
13200- </div>
13201- <div class="lv-footer-col">
13202- <h4 class="lv-footer-col-head">Platform</h4>
13203- <a href="/" class="lv-footer-link">Production layers</a>
13204- <a href="/trust" class="lv-footer-link">Trust report</a>
13205- <a href="/" class="lv-footer-link">Docs</a>
13206- <a href="/" class="lv-footer-link">Status</a>
13207- </div>
13208- <div class="lv-footer-col">
13209- <h4 class="lv-footer-col-head">Company</h4>
13210- <a href="/" class="lv-footer-link">About</a>
13211- <a href="/" class="lv-footer-link">Pricing</a>
13212- <a href="/" class="lv-footer-link">Enterprise</a>
13213- </div>
13214- </div>
13215- </div>
13216- <div class="lv-footer-bar">
13217- <span>� 2026 Gluecron</span>
13218- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
13219- </div>
13220- </footer>
13221-
13222- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
13223- </>
13224- );
13225-};
13226-
13227-export const LandingPage = LandingPageV2;
13228-export default LandingPageV2;
13229-
13230-const clientScript = `
13231-(function() {
13232- var demoAll = [
13233- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
13234- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
13235- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
13236- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
13237- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
13238- ];
13239-
13240- var demoStep = 0;
13241- var stage = 0;
13242-
13243- function renderDemo() {
13244- var container = document.getElementById('lv-demo-body');
13245- if (!container) return;
13246- var visible = demoAll.slice(0, demoStep + 1);
13247- container.innerHTML = visible.map(function(e, i) {
13248- var isLast = i === visible.length - 1;
13249- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
13250- return '<div class="lv-demo-event">' +
13251- '<div class="lv-demo-event-track">' +
13252- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
13253- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
13254- '</div>' +
13255- '<div class="lv-demo-event-content">' +
13256- '<div class="lv-demo-event-header">' +
13257- '<span class="lv-demo-event-title">' + e.title + '</span>' +
13258- '<span class="lv-demo-event-time">' + e.time + '</span>' +
13259- '</div>' +
13260- '<div class="lv-demo-event-body">' + e.body + '</div>' +
13261- '</div>' +
13262- '</div>';
13263- }).join('');
13264- }
13265-
13266- function renderStages() {
13267- var cards = document.querySelectorAll('.lv-stage-card');
13268- cards.forEach(function(card, i) {
13269- var dot = card.querySelector('.lv-dot');
13270- var meta = card.querySelector('.lv-stage-meta');
13271- if (i === stage) {
13272- card.classList.add('lv-stage-active');
13273- if (dot) {
13274- dot.classList.remove('lv-dot-idle');
13275- dot.classList.add('lv-dot-indigo', 'lv-pulse');
13276- }
13277- if (meta) meta.classList.add('lv-stage-meta-active');
13278- } else {
13279- card.classList.remove('lv-stage-active');
13280- if (dot) {
13281- dot.classList.add('lv-dot-idle');
13282- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
13283- }
13284- if (meta) meta.classList.remove('lv-stage-meta-active');
13285- }
13286- });
13287- }
13288-
13289- renderDemo();
13290-
13291- setInterval(function() {
13292- demoStep = (demoStep + 1) % 5;
13293- renderDemo();
13294- }, 3600);
13295-
13296- setInterval(function() {
13297- stage = (stage + 1) % 6;
13298- renderStages();
13299- }, 2200);
13300-})();
13301-`;
13302-
13303-const css = `
13304-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
13305-
13306-*, *::before, *::after { box-sizing: border-box; }
13307-
13308-body {
13309- margin: 0;
13310- background: #fcfcfd;
13311- -webkit-font-smoothing: antialiased;
13312- text-rendering: optimizeLegibility;
13313- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
13314- font-size: 15px;
13315- line-height: 1.6;
13316- letter-spacing: -0.008em;
13317- color: #16181d;
13318-}
13319-
13320-@keyframes gcPulse {
13321- 0%, 100% { opacity: 1; }
13322- 50% { opacity: 0.35; }
13323-}
13324-
13325-@keyframes gcTicker {
13326- 0% { transform: translateX(0); }
13327- 100% { transform: translateX(-50%); }
13328-}
13329-
13330-/* Shared utilities */
13331-.lv-dot {
13332- display: inline-block;
13333- border-radius: 50%;
13334-}
13335-.lv-dot-green { background: #1e7f5c; }
13336-.lv-dot-indigo { background: #4353c9; }
13337-.lv-dot-idle { background: #c4c6cf; }
13338-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
13339-
13340-.lv-strong { color: #16181d; font-weight: 600; }
13341-
13342-.lv-eyebrow {
13343- font-family: 'JetBrains Mono', monospace;
13344- font-size: 11px;
13345- letter-spacing: 0.12em;
13346- text-transform: uppercase;
13347- color: #8a8d99;
13348- font-weight: 500;
13349- margin-bottom: 12px;
13350-}
13351-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
13352-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
13353-
13354-.lv-h1 {
13355- font-family: 'Inter Tight', sans-serif;
13356- font-weight: 700;
13357- letter-spacing: -0.035em;
13358- font-size: clamp(44px, 7vw, 84px);
13359- line-height: 0.98;
13360- margin: 30px auto 0;
13361- max-width: 14ch;
13362- color: #111318;
13363-}
13364-
13365-.lv-h2 {
13366- font-family: 'Inter Tight', sans-serif;
13367- font-weight: 700;
13368- letter-spacing: -0.028em;
13369- font-size: clamp(30px, 4.4vw, 48px);
13370- line-height: 1.05;
13371- margin: 0;
13372- color: #111318;
13373-}
13374-
13375-.lv-h2-dark {
13376- font-family: 'Inter Tight', sans-serif;
13377- font-weight: 700;
13378- letter-spacing: -0.028em;
13379- font-size: clamp(30px, 4.6vw, 52px);
13380- line-height: 1.05;
13381- margin: 0;
13382- color: #fff;
13383-}
13384-
13385-.lv-section-header {
13386- max-width: 640px;
13387- margin: 0 auto 56px;
13388-}
13389-
13390-.lv-section-header-center {
13391- text-align: center;
13392-}
13393-
13394-.lv-section-sub {
13395- color: #6b7080;
13396- font-size: 17px;
13397- margin: 18px auto 0;
13398- max-width: 52ch;
13399-}
13400-
13401-.lv-section-sub-dark {
13402- color: rgba(255,255,255,0.72);
13403- font-size: 17px;
13404- margin: 18px auto 0;
13405- max-width: 56ch;
13406-}
13407-
13408-/* Nav */
13409-.lv-nav {
13410- position: sticky;
13411- top: 0;
13412- z-index: 60;
13413- backdrop-filter: saturate(180%) blur(14px);
13414- -webkit-backdrop-filter: saturate(180%) blur(14px);
13415- background: rgba(252,252,253,0.8);
13416- border-bottom: 1px solid rgba(22,24,29,0.07);
13417-}
13418-
13419-.lv-nav-inner {
13420- max-width: 1200px;
13421- margin: 0 auto;
13422- padding: 14px 28px;
13423- display: flex;
13424- align-items: center;
13425- gap: 28px;
13426-}
13427-
13428-.lv-logo {
13429- display: inline-flex;
13430- align-items: center;
13431- gap: 9px;
13432- font-family: 'Inter Tight', sans-serif;
13433- font-weight: 700;
13434- font-size: 17px;
13435- letter-spacing: -0.02em;
13436- color: #16181d;
13437- text-decoration: none;
13438-}
13439-
13440-.lv-logo-mark {
13441- width: 17px;
13442- height: 17px;
13443- border-radius: 5px;
13444- background: #4353c9;
13445- display: inline-block;
13446- flex-shrink: 0;
13447-}
13448-
13449-.lv-nav-links {
13450- display: flex;
13451- gap: 24px;
13452- font-size: 13.5px;
13453- font-weight: 500;
13454-}
13455-
13456-.lv-nav-link {
13457- color: #6b7080;
13458- text-decoration: none;
13459- transition: color 0.15s;
13460-}
13461-.lv-nav-link:hover { color: #16181d; }
13462-
13463-.lv-nav-ctas {
13464- margin-left: auto;
13465- display: flex;
13466- align-items: center;
13467- gap: 10px;
13468-}
13469-
13470-.lv-btn-secondary {
13471- padding: 8px 15px;
13472- border-radius: 8px;
13473- font-size: 13.5px;
13474- font-weight: 500;
13475- color: #16181d;
13476- border: 1px solid rgba(22,24,29,0.12);
13477- background: #ffffff;
13478- text-decoration: none;
13479- white-space: nowrap;
13480- transition: border-color 0.15s;
13481-}
13482-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
13483-
13484-.lv-btn-primary {
13485- padding: 8px 15px;
13486- border-radius: 8px;
13487- font-size: 13.5px;
13488- font-weight: 600;
13489- background: #16181d;
13490- color: #fff;
13491- text-decoration: none;
13492- white-space: nowrap;
13493- transition: box-shadow 0.15s;
13494-}
13495-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
13496-
13497-/* Hero */
13498-.lv-hero {
13499- position: relative;
13500- overflow: hidden;
13501- padding: 88px 0 0;
13502-}
13503-
13504-.lv-hero-glow {
13505- position: absolute;
13506- inset: -10% 0 auto 0;
13507- height: 640px;
13508- pointer-events: none;
13509- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
13510-}
13511-
13512-.lv-hero-inner {
13513- position: relative;
13514- max-width: 1200px;
13515- margin: 0 auto;
13516- padding: 0 28px;
13517- text-align: center;
13518-}
13519-
13520-.lv-hero-badge {
13521- display: inline-flex;
13522- align-items: center;
13523- gap: 9px;
13524- font-size: 12.5px;
13525- font-weight: 600;
13526- color: #3a3d45;
13527- background: #ffffff;
13528- border: 1px solid rgba(22,24,29,0.10);
13529- border-radius: 9999px;
13530- padding: 7px 16px;
13531- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
13532-}
13533-
13534-.lv-hero-sub {
13535- font-size: clamp(16px, 2vw, 19px);
13536- color: #6b7080;
13537- max-width: 60ch;
13538- margin: 24px auto 0;
13539- font-weight: 450;
13540- line-height: 1.65;
13541-}
13542-
13543-.lv-hero-actions {
13544- display: flex;
13545- gap: 12px;
13546- justify-content: center;
13547- flex-wrap: wrap;
13548- margin-top: 32px;
13549-}
13550-
13551-.lv-cta-primary {
13552- padding: 13px 24px;
13553- border-radius: 11px;
13554- font-size: 15.5px;
13555- font-weight: 600;
13556- background: #16181d;
13557- color: #fff;
13558- text-decoration: none;
13559- white-space: nowrap;
13560- transition: box-shadow 0.15s;
13561-}
13562-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
13563-
13564-.lv-cta-secondary {
13565- padding: 13px 24px;
13566- border-radius: 11px;
13567- font-size: 15.5px;
13568- font-weight: 600;
13569- color: #16181d;
13570- border: 1px solid rgba(22,24,29,0.14);
13571- background: #ffffff;
13572- text-decoration: none;
13573- white-space: nowrap;
13574- transition: border-color 0.15s;
13575-}
13576-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
13577-
13578-.lv-hero-tag {
13579- margin-top: 18px;
13580- font-family: 'JetBrains Mono', monospace;
13581- font-size: 11.5px;
13582- letter-spacing: 0.08em;
13583- text-transform: uppercase;
13584- color: #8a8d99;
13585-}
13586-
13587-/* Demo window */
13588-.lv-demo-window {
13589- margin: 56px auto 0;
13590- max-width: 860px;
13591- text-align: left;
13592- background: #ffffff;
13593- border: 1px solid rgba(22,24,29,0.09);
13594- border-radius: 18px;
13595- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
13596- overflow: hidden;
13597-}
13598-
13599-.lv-demo-bar {
13600- display: flex;
13601- align-items: center;
13602- gap: 7px;
13603- padding: 12px 18px;
13604- border-bottom: 1px solid rgba(22,24,29,0.07);
13605- background: #fcfcfd;
13606-}
13607-
13608-.lv-demo-dot {
13609- width: 10px;
13610- height: 10px;
13611- border-radius: 50%;
13612- background: #e4e5ea;
13613-}
13614-
13615-.lv-demo-url {
13616- margin-left: 10px;
13617- font-family: 'JetBrains Mono', monospace;
13618- font-size: 12px;
13619- color: #6b7080;
13620-}
13621-
13622-.lv-demo-live {
13623- margin-left: auto;
13624- display: inline-flex;
13625- align-items: center;
13626- gap: 6px;
13627- font-size: 11px;
13628- font-weight: 600;
13629- color: #1e7f5c;
13630-}
13631-
13632-.lv-demo-body {
13633- padding: 22px 24px;
13634-}
13635-
13636-.lv-demo-event {
13637- display: grid;
13638- grid-template-columns: 18px minmax(0, 1fr);
13639- gap: 14px;
13640- padding-bottom: 20px;
13641- position: relative;
13642-}
13643-.lv-demo-event:last-child { padding-bottom: 0; }
13644-
13645-.lv-demo-event-track {
13646- display: flex;
13647- flex-direction: column;
13648- align-items: center;
13649-}
13650-
13651-.lv-demo-line {
13652- width: 1px;
13653- flex: 1;
13654- background: rgba(22,24,29,0.08);
13655- margin-top: 5px;
13656- min-height: 20px;
13657-}
13658-
13659-.lv-demo-event-content {}
13660-
13661-.lv-demo-event-header {
13662- display: flex;
13663- align-items: baseline;
13664- gap: 10px;
13665-}
13666-
13667-.lv-demo-event-title {
13668- font-size: 13.5px;
13669- font-weight: 600;
13670- color: #16181d;
13671-}
13672-
13673-.lv-demo-event-time {
13674- font-family: 'JetBrains Mono', monospace;
13675- font-size: 11px;
13676- color: #8a8d99;
13677-}
13678-
13679-.lv-demo-event-body {
13680- font-size: 13px;
13681- color: #6b7080;
13682- margin-top: 2px;
13683-}
13684-
13685-/* Ticker */
13686-.lv-ticker-wrap {
13687- border-top: 1px solid rgba(22,24,29,0.07);
13688- border-bottom: 1px solid rgba(22,24,29,0.07);
13689- background: #ffffff;
13690- margin-top: 64px;
13691- overflow: hidden;
13692- white-space: nowrap;
13693- position: relative;
13694-}
13695-
13696-.lv-ticker-track {
13697- display: inline-flex;
13698- animation: gcTicker 40s linear infinite;
13699- padding: 11px 0;
13700-}
13701-
13702-.lv-ticker-item {
13703- display: inline-flex;
13704- align-items: center;
13705- gap: 8px;
13706- font-family: 'JetBrains Mono', monospace;
13707- font-size: 11.5px;
13708- color: #6b7080;
13709- padding: 0 28px;
13710- border-right: 1px solid rgba(22,24,29,0.06);
13711-}
13712-
13713-/* Stats */
13714-.lv-stats {
13715- background: #fcfcfd;
13716-}
13717-
13718-.lv-stats-inner {
13719- max-width: 1200px;
13720- margin: 0 auto;
13721- display: grid;
13722- grid-template-columns: repeat(4, 1fr);
13723- gap: 24px;
13724- padding: 52px 28px;
13725-}
13726-
13727-.lv-stat {
13728- text-align: center;
13729-}
13730-
13731-.lv-stat-num {
13732- font-family: 'Inter Tight', sans-serif;
13733- font-weight: 700;
13734- font-size: clamp(30px, 4vw, 44px);
13735- letter-spacing: -0.025em;
13736- color: #111318;
13737-}
13738-
13739-.lv-stat-label {
13740- font-size: 13px;
13741- color: #6b7080;
13742- margin-top: 4px;
13743-}
13744-
13745-/* Loop */
13746-.lv-loop {
13747- padding: 96px 0;
13748- background: #ffffff;
13749- border-top: 1px solid rgba(22,24,29,0.07);
13750- border-bottom: 1px solid rgba(22,24,29,0.07);
13751-}
13752-
13753-.lv-loop-inner {
13754- max-width: 1200px;
13755- margin: 0 auto;
13756- padding: 0 28px;
13757-}
13758-
13759-.lv-stages {
13760- display: grid;
13761- grid-template-columns: repeat(6, 1fr);
13762- gap: 12px;
13763-}
13764-
13765-.lv-stage-card {
13766- border: 1px solid rgba(22,24,29,0.08);
13767- border-radius: 14px;
13768- background: #ffffff;
13769- padding: 20px 18px;
13770- transition: border-color 0.3s, background 0.3s;
13771-}
13772-
13773-.lv-stage-card.lv-stage-active {
13774- border-color: rgba(67,83,201,0.45);
13775- background: rgba(67,83,201,0.03);
13776-}
13777-
13778-.lv-stage-header {
13779- display: flex;
13780- align-items: center;
13781- gap: 8px;
13782- margin-bottom: 10px;
13783-}
13784-
13785-.lv-stage-n {
13786- font-family: 'JetBrains Mono', monospace;
13787- font-size: 10.5px;
13788- letter-spacing: 0.1em;
13789- text-transform: uppercase;
13790- color: #8a8d99;
13791-}
13792-
13793-.lv-stage-name {
13794- font-family: 'Inter Tight', sans-serif;
13795- font-size: 16px;
13796- font-weight: 600;
13797- letter-spacing: -0.01em;
13798- color: #16181d;
13799- margin-bottom: 5px;
13800-}
13801-
13802-.lv-stage-desc {
13803- font-size: 12px;
13804- color: #6b7080;
13805- line-height: 1.55;
13806-}
13807-
13808-.lv-stage-meta {
13809- font-family: 'JetBrains Mono', monospace;
13810- font-size: 10.5px;
13811- color: #8a8d99;
13812- margin-top: 10px;
13813- transition: color 0.3s;
13814-}
13815-
13816-.lv-stage-meta.lv-stage-meta-active {
13817- color: #4353c9;
13818-}
13819-
13820-/* Heroes */
13821-.lv-heroes {
13822- padding: 96px 0;
13823- background: #fcfcfd;
13824-}
13825-
13826-.lv-heroes-inner {
13827- max-width: 1200px;
13828- margin: 0 auto;
13829- padding: 0 28px;
13830-}
13831-
13832-.lv-heroes-header {
13833- max-width: 640px;
13834- margin-bottom: 56px;
13835-}
13836-
13837-.lv-heroes-list {
13838- display: flex;
13839- flex-direction: column;
13840- gap: 20px;
13841-}
13842-
13843-.lv-hero-card {
13844- display: grid;
13845- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
13846- gap: 48px;
13847- align-items: center;
13848- border: 1px solid rgba(22,24,29,0.08);
13849- border-radius: 20px;
13850- background: #ffffff;
13851- padding: 44px 48px;
13852- text-decoration: none;
13853- transition: border-color 0.2s, box-shadow 0.2s;
13854-}
13855-.lv-hero-card:hover {
13856- border-color: rgba(22,24,29,0.22);
13857- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
13858-}
13859-
13860-.lv-hero-card-left {}
13861-
13862-.lv-hero-card-title {
13863- font-family: 'Inter Tight', sans-serif;
13864- font-size: 26px;
13865- font-weight: 600;
13866- letter-spacing: -0.022em;
13867- line-height: 1.15;
13868- color: #16181d;
13869- margin: 0 0 12px;
13870-}
13871-
13872-.lv-hero-card-body {
13873- font-size: 14.5px;
13874- color: #6b7080;
13875- margin: 0 0 18px;
13876- line-height: 1.65;
13877-}
13878-
13879-.lv-hero-card-cta {
13880- font-size: 13.5px;
13881- font-weight: 600;
13882- color: #4353c9;
13883-}
13884-
13885-.lv-terminal {
13886- border: 1px solid rgba(22,24,29,0.07);
13887- border-radius: 14px;
13888- background: #fcfcfd;
13889- padding: 20px 22px;
13890- font-family: 'JetBrains Mono', monospace;
13891- font-size: 12px;
13892- line-height: 1.9;
13893- overflow: hidden;
13894-}
13895-
13896-.lv-terminal-line {
13897- display: flex;
13898- align-items: center;
13899- gap: 10px;
13900- white-space: nowrap;
13901- overflow: hidden;
13902- text-overflow: ellipsis;
13903-}
13904-
13905-/* Platform */
13906-.lv-platform {
13907- padding: 96px 0;
13908- background: #ffffff;
13909- border-top: 1px solid rgba(22,24,29,0.07);
13910-}
13911-
13912-.lv-platform-inner {
13913- max-width: 1200px;
13914- margin: 0 auto;
13915- padding: 0 28px;
13916-}
13917-
13918-.lv-cap-grid {
13919- display: grid;
13920- grid-template-columns: repeat(4, 1fr);
13921- gap: 24px 32px;
13922-}
13923-
13924-.lv-cap-col {}
13925-
13926-.lv-cap-group {
13927- font-family: 'JetBrains Mono', monospace;
13928- font-size: 10.5px;
13929- letter-spacing: 0.12em;
13930- text-transform: uppercase;
13931- color: #8a8d99;
13932- font-weight: 500;
13933- margin-bottom: 12px;
13934- padding-bottom: 8px;
13935- border-bottom: 1px solid rgba(22,24,29,0.07);
13936-}
13937-
13938-.lv-cap-items {
13939- display: flex;
13940- flex-direction: column;
13941- gap: 7px;
13942-}
13943-
13944-.lv-cap-item {
13945- font-size: 12.5px;
13946- color: #3a3d45;
13947- line-height: 1.45;
13948-}
13949-
13950-/* Sovereignty */
13951-.lv-sovereign {
13952- position: relative;
13953- overflow: hidden;
13954- padding: 104px 0;
13955- color: #fff;
13956- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
13957-}
13958-
13959-.lv-sovereign-grid-bg {
13960- position: absolute;
13961- inset: 0;
13962- opacity: 0.4;
13963- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
13964- background-size: 56px 56px;
13965- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
13966- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
13967-}
13968-
13969-.lv-sovereign-inner {
13970- position: relative;
13971- max-width: 1200px;
13972- margin: 0 auto;
13973- padding: 0 28px;
13974-}
13975-
13976-.lv-section-header-dark {
13977- max-width: 680px;
13978- margin: 0 auto 48px;
13979- text-align: center;
13980-}
13981-
13982-.lv-layers-grid {
13983- display: grid;
13984- grid-template-columns: repeat(4, 1fr);
13985- gap: 10px;
13986- max-width: 980px;
13987- margin: 0 auto;
13988-}
13989-
13990-.lv-layer-chip {
13991- border: 1px solid rgba(255,255,255,0.10);
13992- border-radius: 10px;
13993- padding: 12px 16px;
13994- background: rgba(255,255,255,0.03);
13995-}
13996-
13997-.lv-layer-cta {
13998- border-color: rgba(169,180,238,0.30);
13999- background: rgba(169,180,238,0.06);
14000- display: flex;
14001- align-items: center;
14002- text-decoration: none;
14003- transition: background 0.15s;
14004-}
14005-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
14006-
14007-.lv-layer-cta-text {
14008- font-size: 13px;
14009- font-weight: 500;
14010- color: #a9b4ee;
14011-}
14012-
14013-.lv-layer-n {
14014- font-family: 'JetBrains Mono', monospace;
14015- font-size: 10px;
14016- color: rgba(255,255,255,0.4);
14017- margin-bottom: 3px;
14018-}
14019-
14020-.lv-layer-name {
14021- font-size: 13px;
14022- font-weight: 500;
14023- color: rgba(255,255,255,0.92);
14024-}
14025-
14026-.lv-sovereign-feats {
14027- display: flex;
14028- gap: 44px;
14029- justify-content: center;
14030- flex-wrap: wrap;
14031- margin-top: 52px;
14032- text-align: center;
14033-}
14034-
14035-.lv-sovereign-feat {}
14036-
14037-.lv-sovereign-feat-title {
14038- font-family: 'Inter Tight', sans-serif;
14039- font-size: 20px;
14040- font-weight: 700;
14041- color: #fff;
14042-}
14043-
14044-.lv-sovereign-feat-sub {
14045- color: rgba(255,255,255,0.55);
14046- font-size: 13px;
14047- margin-top: 2px;
14048-}
14049-
14050-/* Twin cards */
14051-.lv-twin {
14052- padding: 96px 0;
14053- background: #fcfcfd;
14054-}
14055-
14056-.lv-twin-inner {
14057- max-width: 1200px;
14058- margin: 0 auto;
14059- padding: 0 28px;
14060- display: grid;
14061- grid-template-columns: 1fr 1fr;
14062- gap: 24px;
14063-}
14064-
14065-.lv-twin-card {
14066- border: 1px solid rgba(22,24,29,0.08);
14067- border-radius: 20px;
14068- background: #ffffff;
14069- padding: 44px 48px;
14070-}
14071-
14072-.lv-twin-title {
14073- font-family: 'Inter Tight', sans-serif;
14074- font-size: 24px;
14075- font-weight: 600;
14076- letter-spacing: -0.02em;
14077- line-height: 1.2;
14078- margin: 0 0 12px;
14079- color: #16181d;
14080-}
14081-
14082-.lv-twin-body {
14083- font-size: 14.5px;
14084- color: #6b7080;
14085- margin: 0 0 16px;
14086- line-height: 1.7;
14087-}
14088-
14089-.lv-twin-link {
14090- font-size: 13.5px;
14091- font-weight: 600;
14092- color: #4353c9;
14093- text-decoration: none;
14094-}
14095-.lv-twin-link:hover { text-decoration: underline; }
14096-
14097-/* Quote */
14098-.lv-quote {
14099- padding: 40px 0 96px;
14100- background: #fcfcfd;
14101-}
14102-
14103-.lv-quote-inner {
14104- max-width: 980px;
14105- margin: 0 auto;
14106- padding: 0 28px;
14107- text-align: center;
14108-}
14109-
14110-.lv-quote-text {
14111- font-family: 'Inter Tight', sans-serif;
14112- font-weight: 600;
14113- font-size: clamp(26px, 3.8vw, 42px);
14114- line-height: 1.2;
14115- letter-spacing: -0.025em;
14116- margin: 0;
14117- color: #111318;
14118-}
14119-
14120-.lv-em {
14121- font-style: normal;
14122- color: #4353c9;
14123-}
14124-
14125-/* CTA */
14126-.lv-cta-section {
14127- padding: 0 0 104px;
14128- background: #fcfcfd;
14129-}
14130-
14131-.lv-cta-card {
14132- max-width: 820px;
14133- margin: 0 auto;
14134- padding: 64px 40px;
14135- text-align: center;
14136- background: #ffffff;
14137- border: 1px solid rgba(22,24,29,0.08);
14138- border-radius: 26px;
14139- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
14140- position: relative;
14141- overflow: hidden;
14142-}
14143-
14144-.lv-cta-glow {
14145- position: absolute;
14146- inset: -40% 0 auto 0;
14147- height: 280px;
14148- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
14149- pointer-events: none;
14150-}
14151-
14152-.lv-cta-h2 {
14153- font-family: 'Inter Tight', sans-serif;
14154- font-weight: 700;
14155- letter-spacing: -0.028em;
14156- font-size: clamp(30px, 4.6vw, 48px);
14157- margin: 0;
14158- position: relative;
14159- color: #111318;
14160-}
14161-
14162-.lv-cta-sub {
14163- color: #6b7080;
14164- font-size: 17px;
14165- margin: 16px 0 30px;
14166- position: relative;
14167-}
14168-
14169-.lv-cta-actions {
14170- display: flex;
14171- gap: 12px;
14172- justify-content: center;
14173- flex-wrap: wrap;
14174- position: relative;
14175-}
14176-
14177-.lv-cta-fine {
14178- margin-top: 20px;
14179- font-family: 'JetBrains Mono', monospace;
14180- font-size: 11px;
14181- color: #8a8d99;
14182- position: relative;
14183-}
14184-
14185-/* Footer */
14186-.lv-footer {
14187- border-top: 1px solid rgba(22,24,29,0.07);
14188- background: #ffffff;
14189- padding: 56px 0 30px;
14190-}
14191-
14192-.lv-footer-inner {
14193- max-width: 1200px;
14194- margin: 0 auto;
14195- padding: 0 28px;
14196- display: flex;
14197- gap: 48px;
14198- flex-wrap: wrap;
14199- justify-content: space-between;
14200-}
14201-
14202-.lv-footer-brand {}
14203-
14204-.lv-footer-tagline {
14205- color: #6b7080;
14206- font-size: 13.5px;
14207- margin: 12px 0 0;
14208- max-width: 32ch;
14209- line-height: 1.6;
14210-}
14211-
14212-.lv-footer-cols {
14213- display: flex;
14214- gap: 64px;
14215- flex-wrap: wrap;
14216-}
14217-
14218-.lv-footer-col {
14219- display: flex;
14220- flex-direction: column;
14221- gap: 9px;
14222-}
14223-
14224-.lv-footer-col-head {
14225- font-family: 'JetBrains Mono', monospace;
14226- font-size: 11px;
14227- text-transform: uppercase;
14228- letter-spacing: 0.1em;
14229- color: #8a8d99;
14230- margin: 0 0 4px;
14231- font-weight: 500;
14232-}
14233-
14234-.lv-footer-link {
14235- color: #3a3d45;
14236- font-size: 13.5px;
14237- text-decoration: none;
14238- transition: color 0.15s;
14239-}
14240-.lv-footer-link:hover { color: #16181d; }
14241-
14242-.lv-footer-bar {
14243- max-width: 1200px;
14244- margin: 44px auto 0;
14245- padding: 22px 28px 0;
14246- border-top: 1px solid rgba(22,24,29,0.06);
14247- display: flex;
14248- justify-content: space-between;
14249- flex-wrap: wrap;
14250- gap: 8px;
14251- color: #8a8d99;
14252- font-size: 12.5px;
14253-}
14254-
14255-.lv-footer-stack {
14256- font-family: 'JetBrains Mono', monospace;
14257- font-size: 11px;
14258-}
14259-`;
14260diff --git a/src/views/layout.tsx b/src/views/layout.tsx
14261index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
14262--- a/src/views/layout.tsx
14263+++ b/src/views/layout.tsx
14264@@ -3153,9 +3153,12 @@
14265 font-weight: 500;
14266 line-height: 1.4;
14267 }
14268- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
14269- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
14270- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
14271+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
14272+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
14273+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
14274+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
14275+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
14276+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
14277 .state-merged { color: var(--accent); }
14278 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
14279
14280diff --git a/src/views/ui.tsx b/src/views/ui.tsx
14281index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
14282--- a/src/views/ui.tsx
14283+++ b/src/views/ui.tsx
14284@@ -232,7 +232,7 @@
14285
14286 export const Badge: FC<
14287 PropsWithChildren<{
14288- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
14289+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
14290 style?: string;
14291 }>
14292 > = ({ children, variant = "default", style }) => {
14293@@ -241,9 +241,12 @@
14294 variant === "closed" ? "badge-closed" :
14295 variant === "merged" ? "badge-merged" :
14296 variant === "success" ? "badge-success" :
14297- variant === "danger" ? "badge-danger" :
14298- variant === "warning" ? "badge-warning" :
14299- "badge";
14300+ variant === "danger" ? "badge-danger" :
14301+ variant === "warning" ? "badge-warning" :
14302+ variant === "live" ? "badge-live" :
14303+ variant === "soon" ? "badge-soon" :
14304+ variant === "preview" ? "badge-preview" :
14305+ "badge";
14306 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
14307 };
14308
14309
14310exec
14311"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command 'bun run typecheck' in C:\Users\ccant\gluecron.com
14312diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
14313index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
14314--- a/src/views/landing-pro.tsx
14315+++ b/src/views/landing-pro.tsx
14316@@ -42,7 +42,7 @@
14317
14318 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14319
14320-function icon(paths: string, color = "#4353c9", size = 20) {
14321+function icon(paths: string, color = "#0891b2", size = 20) {
14322 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
14323 }
14324
14325@@ -947,7 +947,7 @@
14326 const css = `
14327 /* %% tokens %% */
14328 :root{
14329- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
14330+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
14331 --lp-bg:#ffffff;--lp-soft:#fafafb;
14332 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
14333 --lp-border:rgba(0,0,0,.08);
14334diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
14335deleted file mode 100644
14336index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
14337--- a/src/views/landing-v2.tsx
14338+++ /dev/null
14339@@ -1,1447 +0,0 @@
14340-import type { FC } from "hono/jsx";
14341-
14342-export interface LandingPageProps {
14343- stats?: {
14344- publicRepos?: number;
14345- users?: number;
14346- };
14347-}
14348-
14349-const demoAllEvents = [
14350- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
14351- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
14352- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
14353- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
14354- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
14355-];
14356-
14357-const tickerItems = [
14358- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
14359- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
14360- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
14361- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
14362- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
14363- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
14364- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
14365- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
14366- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
14367- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
14368- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
14369- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
14370- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
14371- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
14372- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
14373- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
14374-];
14375-
14376-const stageData = [
14377- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
14378- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
14379- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
14380- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
14381- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
14382- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
14383-];
14384-
14385-const heroFeatures = [
14386- {
14387- href: "/",
14388- eyebrow: "01 � The autonomous repair loop",
14389- title: "Failures fix themselves  and show their work.",
14390- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
14391failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
14392- cta: "Watch a live repair session",
14393- mock: [
14394- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
14395- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
14396- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
14397- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
14398- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
14399- ],
14400- },
14401- {
14402- href: "/",
14403- eyebrow: "02 � Live sandbox isolation",
14404- title: "Every PR gets its own instant, disposable environment.",
14405- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
14406same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
14407- cta: "See a PR with its sandbox",
14408- mock: [
14409- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
14410- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
14411- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
14412- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
14413- ],
14414- },
14415- {
14416- href: "/",
14417- eyebrow: "03 � Multiplayer IDE workspaces",
14418- title: "You and the agent, side by side, in your editor.",
14419- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
14420agent into a silent reviewer in your gutter. The browser becomes optional.",
14421- cta: "See the editor session",
14422- mock: [
14423- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
14424- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
14425- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
14426- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
14427- ],
14428- },
14429-];
14430-
14431-const capabilities = [
14432- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
14433- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
14434- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
14435- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
14436- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
14437- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
14438- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
14439- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
14440-];
14441-
14442-const sovereignLayerNames = [
14443- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
14444- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
14445- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
14446- "Availability & recovery",
14447-];
14448-
14449-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
14450- return (
14451- <>
14452- <style dangerouslySetInnerHTML={{ __html: css }} />
14453-
14454- {/* Nav */}
14455- <header class="lv-nav">
14456- <div class="lv-nav-inner">
14457- <a href="/" class="lv-logo">
14458- <span class="lv-logo-mark"></span>gluecron
14459- </a>
14460- <nav class="lv-nav-links">
14461- <a href="#loop" class="lv-nav-link">The loop</a>
14462- <a href="#platform" class="lv-nav-link">Platform</a>
14463- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
14464- <a href="/trust" class="lv-nav-link">Trust</a>
14465- </nav>
14466- <div class="lv-nav-ctas">
14467- <a href="/login" class="lv-btn-secondary">Sign in</a>
14468- <a href="/register" class="lv-btn-primary">Start building</a>
14469- </div>
14470- </div>
14471- </header>
14472-
14473- {/* Hero */}
14474- <section class="lv-hero">
14475- <div class="lv-hero-glow"></div>
14476- <div class="lv-hero-inner">
14477- <div class="lv-hero-badge">
14478- <span class="lv-dot lv-dot-green lv-pulse"></span>
14479- Live: a repair loop converged on pr-218 while you read this
14480- </div>
14481- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
14482- <p class="lv-hero-sub">
14483- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
14484failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
14485- </p>
14486- <div class="lv-hero-actions">
14487- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
14488- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
14489- </div>
14490- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
14491-
14492- {/* Live product window */}
14493- <div class="lv-demo-window">
14494- <div class="lv-demo-bar">
14495- <span class="lv-demo-dot"></span>
14496- <span class="lv-demo-dot"></span>
14497- <span class="lv-demo-dot"></span>
14498- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
14499- <span class="lv-demo-live">
14500- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
14501- LIVE
14502- </span>
14503- </div>
14504- <div class="lv-demo-body" id="lv-demo-body">
14505- {/* Events rendered by JS */}
14506- {demoAllEvents.slice(0, 1).map((e, i) => (
14507- <div class="lv-demo-event" key={i}>
14508- <div class="lv-demo-event-track">
14509- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
14510- <span class="lv-demo-line" style="display:none"></span>
14511- </div>
14512- <div class="lv-demo-event-content">
14513- <div class="lv-demo-event-header">
14514- <span class="lv-demo-event-title">{e.title}</span>
14515- <span class="lv-demo-event-time">{e.time}</span>
14516- </div>
14517- <div class="lv-demo-event-body">{e.body}</div>
14518- </div>
14519- </div>
14520- ))}
14521- </div>
14522- </div>
14523- </div>
14524-
14525- {/* Activity ticker */}
14526- <div class="lv-ticker-wrap">
14527- <div class="lv-ticker-track">
14528- {tickerItems.map((t, i) => (
14529- <span class="lv-ticker-item" key={i}>
14530- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
14531- {t.text}
14532- </span>
14533- ))}
14534- </div>
14535- </div>
14536- </section>
14537-
14538- {/* Stat band */}
14539- <section class="lv-stats">
14540- <div class="lv-stats-inner">
14541- <div class="lv-stat">
14542- <div class="lv-stat-num">Sonnet 5</div>
14543- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
14544- </div>
14545- <div class="lv-stat">
14546- <div class="lv-stat-num">93.5%</div>
14547- <div class="lv-stat-label">of failures self-repair without a human</div>
14548- </div>
14549- <div class="lv-stat">
14550- <div class="lv-stat-num">1.9%</div>
14551- <div class="lv-stat-label">AI merges reverted  published live</div>
14552- </div>
14553- <div class="lv-stat">
14554- <div class="lv-stat-num">0</div>
14555- <div class="lv-stat-label">irreversible actions taken autonomously</div>
14556- </div>
14557- </div>
14558- </section>
14559-
14560- {/* The loop */}
14561- <section id="loop" class="lv-loop">
14562- <div class="lv-loop-inner">
14563- <div class="lv-section-header">
14564- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
14565- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
14566- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
14567- </div>
14568- <div class="lv-stages" id="lv-stages">
14569- {stageData.map((s, i) => (
14570- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
14571- <div class="lv-stage-header">
14572- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
14573- <span class="lv-stage-n">0{i + 1}</span>
14574- </div>
14575- <div class="lv-stage-name">{s.name}</div>
14576- <div class="lv-stage-desc">{s.desc}</div>
14577- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
14578- </div>
14579- ))}
14580- </div>
14581- </div>
14582- </section>
14583-
14584- {/* Three heroes */}
14585- <section class="lv-heroes">
14586- <div class="lv-heroes-inner">
14587- <div class="lv-heroes-header">
14588- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
14589- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
14590- </div>
14591- <div class="lv-heroes-list">
14592- {heroFeatures.map((h, i) => (
14593- <a href={h.href} class="lv-hero-card" key={i}>
14594- <div class="lv-hero-card-left">
14595- <div class="lv-eyebrow">{h.eyebrow}</div>
14596- <h3 class="lv-hero-card-title">{h.title}</h3>
14597- <p class="lv-hero-card-body">{h.body}</p>
14598- <span class="lv-hero-card-cta">{h.cta} �!</span>
14599- </div>
14600- <div class="lv-terminal">
14601- {h.mock.map((m, j) => (
14602- <div class="lv-terminal-line" key={j}>
14603- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
14604- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
14605- </div>
14606- ))}
14607- </div>
14608- </a>
14609- ))}
14610- </div>
14611- </div>
14612- </section>
14613-
14614- {/* Everything grid */}
14615- <section id="platform" class="lv-platform">
14616- <div class="lv-platform-inner">
14617- <div class="lv-section-header lv-section-header-center">
14618- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
14619- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
14620- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
14621- </div>
14622- <div class="lv-cap-grid">
14623- {capabilities.map((c, i) => (
14624- <div class="lv-cap-col" key={i}>
14625- <div class="lv-cap-group">{c.group}</div>
14626- <div class="lv-cap-items">
14627- {c.items.map((item, j) => (
14628- <div class="lv-cap-item" key={j}>{item}</div>
14629- ))}
14630- </div>
14631- </div>
14632- ))}
14633- </div>
14634- </div>
14635- </section>
14636-
14637- {/* Sovereignty band */}
14638- <section id="sovereign" class="lv-sovereign">
14639- <div class="lv-sovereign-grid-bg"></div>
14640- <div class="lv-sovereign-inner">
14641- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
14642- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
14643- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
14644- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
14645to private cloud, or run fully air-gapped on bare metal.</p>
14646- </div>
14647- <div class="lv-layers-grid">
14648- {sovereignLayerNames.map((name, i) => (
14649- <div class="lv-layer-chip" key={i}>
14650- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
14651- <div class="lv-layer-name">{name}</div>
14652- </div>
14653- ))}
14654- <a href="/" class="lv-layer-chip lv-layer-cta">
14655- <div class="lv-layer-cta-text">All self-owned �!</div>
14656- </a>
14657- </div>
14658- <div class="lv-sovereign-feats">
14659- <div class="lv-sovereign-feat">
14660- <div class="lv-sovereign-feat-title">Local inference first</div>
14661- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
14662- </div>
14663- <div class="lv-sovereign-feat">
14664- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
14665- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
14666- </div>
14667- <div class="lv-sovereign-feat">
14668- <div class="lv-sovereign-feat-title">Self-healing infra</div>
14669- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
14670- </div>
14671- </div>
14672- </div>
14673- </section>
14674-
14675- {/* Manual-first + reversibility */}
14676- <section class="lv-twin">
14677- <div class="lv-twin-inner">
14678- <div class="lv-twin-card">
14679- <div class="lv-eyebrow">Manual-first, always</div>
14680- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
14681- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
14682fallback. Developers who never touch AI get the best git host they've ever used.</p>
14683- </div>
14684- <div class="lv-twin-card">
14685- <div class="lv-eyebrow">The reversibility guarantee</div>
14686- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
14687- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
14688 policy, not promise. Our quality numbers are published live, unedited.</p>
14689- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
14690- </div>
14691- </div>
14692- </section>
14693-
14694- {/* Quote */}
14695- <section class="lv-quote">
14696- <div class="lv-quote-inner">
14697- <p class="lv-quote-text">
14698- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
14699- Gluecron is where code gets <em class="lv-em">finished</em>."
14700- </p>
14701- </div>
14702- </section>
14703-
14704- {/* CTA */}
14705- <section class="lv-cta-section">
14706- <div class="lv-cta-card">
14707- <div class="lv-cta-glow"></div>
14708- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
14709- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
14710- <div class="lv-cta-actions">
14711- <a href="/register" class="lv-cta-primary">Create your account �!</a>
14712- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
14713- </div>
14714- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
14715- </div>
14716- </section>
14717-
14718- {/* Footer */}
14719- <footer class="lv-footer">
14720- <div class="lv-footer-inner">
14721- <div class="lv-footer-brand">
14722- <a href="/" class="lv-logo">
14723- <span class="lv-logo-mark"></span>gluecron
14724- </a>
14725- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
14726- </div>
14727- <div class="lv-footer-cols">
14728- <div class="lv-footer-col">
14729- <h4 class="lv-footer-col-head">Product</h4>
14730- <a href="/" class="lv-footer-link">Agent workspace</a>
14731- <a href="/" class="lv-footer-link">Fleet refactors</a>
14732- <a href="/" class="lv-footer-link">Org memory</a>
14733- <a href="/" class="lv-footer-link">IDE extensions</a>
14734- </div>
14735- <div class="lv-footer-col">
14736- <h4 class="lv-footer-col-head">Platform</h4>
14737- <a href="/" class="lv-footer-link">Production layers</a>
14738- <a href="/trust" class="lv-footer-link">Trust report</a>
14739- <a href="/" class="lv-footer-link">Docs</a>
14740- <a href="/" class="lv-footer-link">Status</a>
14741- </div>
14742- <div class="lv-footer-col">
14743- <h4 class="lv-footer-col-head">Company</h4>
14744- <a href="/" class="lv-footer-link">About</a>
14745- <a href="/" class="lv-footer-link">Pricing</a>
14746- <a href="/" class="lv-footer-link">Enterprise</a>
14747- </div>
14748- </div>
14749- </div>
14750- <div class="lv-footer-bar">
14751- <span>� 2026 Gluecron</span>
14752- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
14753- </div>
14754- </footer>
14755-
14756- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
14757- </>
14758- );
14759-};
14760-
14761-export const LandingPage = LandingPageV2;
14762-export default LandingPageV2;
14763-
14764-const clientScript = `
14765-(function() {
14766- var demoAll = [
14767- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
14768- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
14769- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
14770- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
14771- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
14772- ];
14773-
14774- var demoStep = 0;
14775- var stage = 0;
14776-
14777- function renderDemo() {
14778- var container = document.getElementById('lv-demo-body');
14779- if (!container) return;
14780- var visible = demoAll.slice(0, demoStep + 1);
14781- container.innerHTML = visible.map(function(e, i) {
14782- var isLast = i === visible.length - 1;
14783- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
14784- return '<div class="lv-demo-event">' +
14785- '<div class="lv-demo-event-track">' +
14786- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
14787- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
14788- '</div>' +
14789- '<div class="lv-demo-event-content">' +
14790- '<div class="lv-demo-event-header">' +
14791- '<span class="lv-demo-event-title">' + e.title + '</span>' +
14792- '<span class="lv-demo-event-time">' + e.time + '</span>' +
14793- '</div>' +
14794- '<div class="lv-demo-event-body">' + e.body + '</div>' +
14795- '</div>' +
14796- '</div>';
14797- }).join('');
14798- }
14799-
14800- function renderStages() {
14801- var cards = document.querySelectorAll('.lv-stage-card');
14802- cards.forEach(function(card, i) {
14803- var dot = card.querySelector('.lv-dot');
14804- var meta = card.querySelector('.lv-stage-meta');
14805- if (i === stage) {
14806- card.classList.add('lv-stage-active');
14807- if (dot) {
14808- dot.classList.remove('lv-dot-idle');
14809- dot.classList.add('lv-dot-indigo', 'lv-pulse');
14810- }
14811- if (meta) meta.classList.add('lv-stage-meta-active');
14812- } else {
14813- card.classList.remove('lv-stage-active');
14814- if (dot) {
14815- dot.classList.add('lv-dot-idle');
14816- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
14817- }
14818- if (meta) meta.classList.remove('lv-stage-meta-active');
14819- }
14820- });
14821- }
14822-
14823- renderDemo();
14824-
14825- setInterval(function() {
14826- demoStep = (demoStep + 1) % 5;
14827- renderDemo();
14828- }, 3600);
14829-
14830- setInterval(function() {
14831- stage = (stage + 1) % 6;
14832- renderStages();
14833- }, 2200);
14834-})();
14835-`;
14836-
14837-const css = `
14838-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
14839-
14840-*, *::before, *::after { box-sizing: border-box; }
14841-
14842-body {
14843- margin: 0;
14844- background: #fcfcfd;
14845- -webkit-font-smoothing: antialiased;
14846- text-rendering: optimizeLegibility;
14847- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
14848- font-size: 15px;
14849- line-height: 1.6;
14850- letter-spacing: -0.008em;
14851- color: #16181d;
14852-}
14853-
14854-@keyframes gcPulse {
14855- 0%, 100% { opacity: 1; }
14856- 50% { opacity: 0.35; }
14857-}
14858-
14859-@keyframes gcTicker {
14860- 0% { transform: translateX(0); }
14861- 100% { transform: translateX(-50%); }
14862-}
14863-
14864-/* Shared utilities */
14865-.lv-dot {
14866- display: inline-block;
14867- border-radius: 50%;
14868-}
14869-.lv-dot-green { background: #1e7f5c; }
14870-.lv-dot-indigo { background: #4353c9; }
14871-.lv-dot-idle { background: #c4c6cf; }
14872-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
14873-
14874-.lv-strong { color: #16181d; font-weight: 600; }
14875-
14876-.lv-eyebrow {
14877- font-family: 'JetBrains Mono', monospace;
14878- font-size: 11px;
14879- letter-spacing: 0.12em;
14880- text-transform: uppercase;
14881- color: #8a8d99;
14882- font-weight: 500;
14883- margin-bottom: 12px;
14884-}
14885-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
14886-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
14887-
14888-.lv-h1 {
14889- font-family: 'Inter Tight', sans-serif;
14890- font-weight: 700;
14891- letter-spacing: -0.035em;
14892- font-size: clamp(44px, 7vw, 84px);
14893- line-height: 0.98;
14894- margin: 30px auto 0;
14895- max-width: 14ch;
14896- color: #111318;
14897-}
14898-
14899-.lv-h2 {
14900- font-family: 'Inter Tight', sans-serif;
14901- font-weight: 700;
14902- letter-spacing: -0.028em;
14903- font-size: clamp(30px, 4.4vw, 48px);
14904- line-height: 1.05;
14905- margin: 0;
14906- color: #111318;
14907-}
14908-
14909-.lv-h2-dark {
14910- font-family: 'Inter Tight', sans-serif;
14911- font-weight: 700;
14912- letter-spacing: -0.028em;
14913- font-size: clamp(30px, 4.6vw, 52px);
14914- line-height: 1.05;
14915- margin: 0;
14916- color: #fff;
14917-}
14918-
14919-.lv-section-header {
14920- max-width: 640px;
14921- margin: 0 auto 56px;
14922-}
14923-
14924-.lv-section-header-center {
14925- text-align: center;
14926-}
14927-
14928-.lv-section-sub {
14929- color: #6b7080;
14930- font-size: 17px;
14931- margin: 18px auto 0;
14932- max-width: 52ch;
14933-}
14934-
14935-.lv-section-sub-dark {
14936- color: rgba(255,255,255,0.72);
14937- font-size: 17px;
14938- margin: 18px auto 0;
14939- max-width: 56ch;
14940-}
14941-
14942-/* Nav */
14943-.lv-nav {
14944- position: sticky;
14945- top: 0;
14946- z-index: 60;
14947- backdrop-filter: saturate(180%) blur(14px);
14948- -webkit-backdrop-filter: saturate(180%) blur(14px);
14949- background: rgba(252,252,253,0.8);
14950- border-bottom: 1px solid rgba(22,24,29,0.07);
14951-}
14952-
14953-.lv-nav-inner {
14954- max-width: 1200px;
14955- margin: 0 auto;
14956- padding: 14px 28px;
14957- display: flex;
14958- align-items: center;
14959- gap: 28px;
14960-}
14961-
14962-.lv-logo {
14963- display: inline-flex;
14964- align-items: center;
14965- gap: 9px;
14966- font-family: 'Inter Tight', sans-serif;
14967- font-weight: 700;
14968- font-size: 17px;
14969- letter-spacing: -0.02em;
14970- color: #16181d;
14971- text-decoration: none;
14972-}
14973-
14974-.lv-logo-mark {
14975- width: 17px;
14976- height: 17px;
14977- border-radius: 5px;
14978- background: #4353c9;
14979- display: inline-block;
14980- flex-shrink: 0;
14981-}
14982-
14983-.lv-nav-links {
14984- display: flex;
14985- gap: 24px;
14986- font-size: 13.5px;
14987- font-weight: 500;
14988-}
14989-
14990-.lv-nav-link {
14991- color: #6b7080;
14992- text-decoration: none;
14993- transition: color 0.15s;
14994-}
14995-.lv-nav-link:hover { color: #16181d; }
14996-
14997-.lv-nav-ctas {
14998- margin-left: auto;
14999- display: flex;
15000- align-items: center;
15001- gap: 10px;
15002-}
15003-
15004-.lv-btn-secondary {
15005- padding: 8px 15px;
15006- border-radius: 8px;
15007- font-size: 13.5px;
15008- font-weight: 500;
15009- color: #16181d;
15010- border: 1px solid rgba(22,24,29,0.12);
15011- background: #ffffff;
15012- text-decoration: none;
15013- white-space: nowrap;
15014- transition: border-color 0.15s;
15015-}
15016-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
15017-
15018-.lv-btn-primary {
15019- padding: 8px 15px;
15020- border-radius: 8px;
15021- font-size: 13.5px;
15022- font-weight: 600;
15023- background: #16181d;
15024- color: #fff;
15025- text-decoration: none;
15026- white-space: nowrap;
15027- transition: box-shadow 0.15s;
15028-}
15029-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
15030-
15031-/* Hero */
15032-.lv-hero {
15033- position: relative;
15034- overflow: hidden;
15035- padding: 88px 0 0;
15036-}
15037-
15038-.lv-hero-glow {
15039- position: absolute;
15040- inset: -10% 0 auto 0;
15041- height: 640px;
15042- pointer-events: none;
15043- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
15044-}
15045-
15046-.lv-hero-inner {
15047- position: relative;
15048- max-width: 1200px;
15049- margin: 0 auto;
15050- padding: 0 28px;
15051- text-align: center;
15052-}
15053-
15054-.lv-hero-badge {
15055- display: inline-flex;
15056- align-items: center;
15057- gap: 9px;
15058- font-size: 12.5px;
15059- font-weight: 600;
15060- color: #3a3d45;
15061- background: #ffffff;
15062- border: 1px solid rgba(22,24,29,0.10);
15063- border-radius: 9999px;
15064- padding: 7px 16px;
15065- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
15066-}
15067-
15068-.lv-hero-sub {
15069- font-size: clamp(16px, 2vw, 19px);
15070- color: #6b7080;
15071- max-width: 60ch;
15072- margin: 24px auto 0;
15073- font-weight: 450;
15074- line-height: 1.65;
15075-}
15076-
15077-.lv-hero-actions {
15078- display: flex;
15079- gap: 12px;
15080- justify-content: center;
15081- flex-wrap: wrap;
15082- margin-top: 32px;
15083-}
15084-
15085-.lv-cta-primary {
15086- padding: 13px 24px;
15087- border-radius: 11px;
15088- font-size: 15.5px;
15089- font-weight: 600;
15090- background: #16181d;
15091- color: #fff;
15092- text-decoration: none;
15093- white-space: nowrap;
15094- transition: box-shadow 0.15s;
15095-}
15096-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
15097-
15098-.lv-cta-secondary {
15099- padding: 13px 24px;
15100- border-radius: 11px;
15101- font-size: 15.5px;
15102- font-weight: 600;
15103- color: #16181d;
15104- border: 1px solid rgba(22,24,29,0.14);
15105- background: #ffffff;
15106- text-decoration: none;
15107- white-space: nowrap;
15108- transition: border-color 0.15s;
15109-}
15110-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
15111-
15112-.lv-hero-tag {
15113- margin-top: 18px;
15114- font-family: 'JetBrains Mono', monospace;
15115- font-size: 11.5px;
15116- letter-spacing: 0.08em;
15117- text-transform: uppercase;
15118- color: #8a8d99;
15119-}
15120-
15121-/* Demo window */
15122-.lv-demo-window {
15123- margin: 56px auto 0;
15124- max-width: 860px;
15125- text-align: left;
15126- background: #ffffff;
15127- border: 1px solid rgba(22,24,29,0.09);
15128- border-radius: 18px;
15129- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
15130- overflow: hidden;
15131-}
15132-
15133-.lv-demo-bar {
15134- display: flex;
15135- align-items: center;
15136- gap: 7px;
15137- padding: 12px 18px;
15138- border-bottom: 1px solid rgba(22,24,29,0.07);
15139- background: #fcfcfd;
15140-}
15141-
15142-.lv-demo-dot {
15143- width: 10px;
15144- height: 10px;
15145- border-radius: 50%;
15146- background: #e4e5ea;
15147-}
15148-
15149-.lv-demo-url {
15150- margin-left: 10px;
15151- font-family: 'JetBrains Mono', monospace;
15152- font-size: 12px;
15153- color: #6b7080;
15154-}
15155-
15156-.lv-demo-live {
15157- margin-left: auto;
15158- display: inline-flex;
15159- align-items: center;
15160- gap: 6px;
15161- font-size: 11px;
15162- font-weight: 600;
15163- color: #1e7f5c;
15164-}
15165-
15166-.lv-demo-body {
15167- padding: 22px 24px;
15168-}
15169-
15170-.lv-demo-event {
15171- display: grid;
15172- grid-template-columns: 18px minmax(0, 1fr);
15173- gap: 14px;
15174- padding-bottom: 20px;
15175- position: relative;
15176-}
15177-.lv-demo-event:last-child { padding-bottom: 0; }
15178-
15179-.lv-demo-event-track {
15180- display: flex;
15181- flex-direction: column;
15182- align-items: center;
15183-}
15184-
15185-.lv-demo-line {
15186- width: 1px;
15187- flex: 1;
15188- background: rgba(22,24,29,0.08);
15189- margin-top: 5px;
15190- min-height: 20px;
15191-}
15192-
15193-.lv-demo-event-content {}
15194-
15195-.lv-demo-event-header {
15196- display: flex;
15197- align-items: baseline;
15198- gap: 10px;
15199-}
15200-
15201-.lv-demo-event-title {
15202- font-size: 13.5px;
15203- font-weight: 600;
15204- color: #16181d;
15205-}
15206-
15207-.lv-demo-event-time {
15208- font-family: 'JetBrains Mono', monospace;
15209- font-size: 11px;
15210- color: #8a8d99;
15211-}
15212-
15213-.lv-demo-event-body {
15214- font-size: 13px;
15215- color: #6b7080;
15216- margin-top: 2px;
15217-}
15218-
15219-/* Ticker */
15220-.lv-ticker-wrap {
15221- border-top: 1px solid rgba(22,24,29,0.07);
15222- border-bottom: 1px solid rgba(22,24,29,0.07);
15223- background: #ffffff;
15224- margin-top: 64px;
15225- overflow: hidden;
15226- white-space: nowrap;
15227- position: relative;
15228-}
15229-
15230-.lv-ticker-track {
15231- display: inline-flex;
15232- animation: gcTicker 40s linear infinite;
15233- padding: 11px 0;
15234-}
15235-
15236-.lv-ticker-item {
15237- display: inline-flex;
15238- align-items: center;
15239- gap: 8px;
15240- font-family: 'JetBrains Mono', monospace;
15241- font-size: 11.5px;
15242- color: #6b7080;
15243- padding: 0 28px;
15244- border-right: 1px solid rgba(22,24,29,0.06);
15245-}
15246-
15247-/* Stats */
15248-.lv-stats {
15249- background: #fcfcfd;
15250-}
15251-
15252-.lv-stats-inner {
15253- max-width: 1200px;
15254- margin: 0 auto;
15255- display: grid;
15256- grid-template-columns: repeat(4, 1fr);
15257- gap: 24px;
15258- padding: 52px 28px;
15259-}
15260-
15261-.lv-stat {
15262- text-align: center;
15263-}
15264-
15265-.lv-stat-num {
15266- font-family: 'Inter Tight', sans-serif;
15267- font-weight: 700;
15268- font-size: clamp(30px, 4vw, 44px);
15269- letter-spacing: -0.025em;
15270- color: #111318;
15271-}
15272-
15273-.lv-stat-label {
15274- font-size: 13px;
15275- color: #6b7080;
15276- margin-top: 4px;
15277-}
15278-
15279-/* Loop */
15280-.lv-loop {
15281- padding: 96px 0;
15282- background: #ffffff;
15283- border-top: 1px solid rgba(22,24,29,0.07);
15284- border-bottom: 1px solid rgba(22,24,29,0.07);
15285-}
15286-
15287-.lv-loop-inner {
15288- max-width: 1200px;
15289- margin: 0 auto;
15290- padding: 0 28px;
15291-}
15292-
15293-.lv-stages {
15294- display: grid;
15295- grid-template-columns: repeat(6, 1fr);
15296- gap: 12px;
15297-}
15298-
15299-.lv-stage-card {
15300- border: 1px solid rgba(22,24,29,0.08);
15301- border-radius: 14px;
15302- background: #ffffff;
15303- padding: 20px 18px;
15304- transition: border-color 0.3s, background 0.3s;
15305-}
15306-
15307-.lv-stage-card.lv-stage-active {
15308- border-color: rgba(67,83,201,0.45);
15309- background: rgba(67,83,201,0.03);
15310-}
15311-
15312-.lv-stage-header {
15313- display: flex;
15314- align-items: center;
15315- gap: 8px;
15316- margin-bottom: 10px;
15317-}
15318-
15319-.lv-stage-n {
15320- font-family: 'JetBrains Mono', monospace;
15321- font-size: 10.5px;
15322- letter-spacing: 0.1em;
15323- text-transform: uppercase;
15324- color: #8a8d99;
15325-}
15326-
15327-.lv-stage-name {
15328- font-family: 'Inter Tight', sans-serif;
15329- font-size: 16px;
15330- font-weight: 600;
15331- letter-spacing: -0.01em;
15332- color: #16181d;
15333- margin-bottom: 5px;
15334-}
15335-
15336-.lv-stage-desc {
15337- font-size: 12px;
15338- color: #6b7080;
15339- line-height: 1.55;
15340-}
15341-
15342-.lv-stage-meta {
15343- font-family: 'JetBrains Mono', monospace;
15344- font-size: 10.5px;
15345- color: #8a8d99;
15346- margin-top: 10px;
15347- transition: color 0.3s;
15348-}
15349-
15350-.lv-stage-meta.lv-stage-meta-active {
15351- color: #4353c9;
15352-}
15353-
15354-/* Heroes */
15355-.lv-heroes {
15356- padding: 96px 0;
15357- background: #fcfcfd;
15358-}
15359-
15360-.lv-heroes-inner {
15361- max-width: 1200px;
15362- margin: 0 auto;
15363- padding: 0 28px;
15364-}
15365-
15366-.lv-heroes-header {
15367- max-width: 640px;
15368- margin-bottom: 56px;
15369-}
15370-
15371-.lv-heroes-list {
15372- display: flex;
15373- flex-direction: column;
15374- gap: 20px;
15375-}
15376-
15377-.lv-hero-card {
15378- display: grid;
15379- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
15380- gap: 48px;
15381- align-items: center;
15382- border: 1px solid rgba(22,24,29,0.08);
15383- border-radius: 20px;
15384- background: #ffffff;
15385- padding: 44px 48px;
15386- text-decoration: none;
15387- transition: border-color 0.2s, box-shadow 0.2s;
15388-}
15389-.lv-hero-card:hover {
15390- border-color: rgba(22,24,29,0.22);
15391- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
15392-}
15393-
15394-.lv-hero-card-left {}
15395-
15396-.lv-hero-card-title {
15397- font-family: 'Inter Tight', sans-serif;
15398- font-size: 26px;
15399- font-weight: 600;
15400- letter-spacing: -0.022em;
15401- line-height: 1.15;
15402- color: #16181d;
15403- margin: 0 0 12px;
15404-}
15405-
15406-.lv-hero-card-body {
15407- font-size: 14.5px;
15408- color: #6b7080;
15409- margin: 0 0 18px;
15410- line-height: 1.65;
15411-}
15412-
15413-.lv-hero-card-cta {
15414- font-size: 13.5px;
15415- font-weight: 600;
15416- color: #4353c9;
15417-}
15418-
15419-.lv-terminal {
15420- border: 1px solid rgba(22,24,29,0.07);
15421- border-radius: 14px;
15422- background: #fcfcfd;
15423- padding: 20px 22px;
15424- font-family: 'JetBrains Mono', monospace;
15425- font-size: 12px;
15426- line-height: 1.9;
15427- overflow: hidden;
15428-}
15429-
15430-.lv-terminal-line {
15431- display: flex;
15432- align-items: center;
15433- gap: 10px;
15434- white-space: nowrap;
15435- overflow: hidden;
15436- text-overflow: ellipsis;
15437-}
15438-
15439-/* Platform */
15440-.lv-platform {
15441- padding: 96px 0;
15442- background: #ffffff;
15443- border-top: 1px solid rgba(22,24,29,0.07);
15444-}
15445-
15446-.lv-platform-inner {
15447- max-width: 1200px;
15448- margin: 0 auto;
15449- padding: 0 28px;
15450-}
15451-
15452-.lv-cap-grid {
15453- display: grid;
15454- grid-template-columns: repeat(4, 1fr);
15455- gap: 24px 32px;
15456-}
15457-
15458-.lv-cap-col {}
15459-
15460-.lv-cap-group {
15461- font-family: 'JetBrains Mono', monospace;
15462- font-size: 10.5px;
15463- letter-spacing: 0.12em;
15464- text-transform: uppercase;
15465- color: #8a8d99;
15466- font-weight: 500;
15467- margin-bottom: 12px;
15468- padding-bottom: 8px;
15469- border-bottom: 1px solid rgba(22,24,29,0.07);
15470-}
15471-
15472-.lv-cap-items {
15473- display: flex;
15474- flex-direction: column;
15475- gap: 7px;
15476-}
15477-
15478-.lv-cap-item {
15479- font-size: 12.5px;
15480- color: #3a3d45;
15481- line-height: 1.45;
15482-}
15483-
15484-/* Sovereignty */
15485-.lv-sovereign {
15486- position: relative;
15487- overflow: hidden;
15488- padding: 104px 0;
15489- color: #fff;
15490- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
15491-}
15492-
15493-.lv-sovereign-grid-bg {
15494- position: absolute;
15495- inset: 0;
15496- opacity: 0.4;
15497- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
15498- background-size: 56px 56px;
15499- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
15500- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
15501-}
15502-
15503-.lv-sovereign-inner {
15504- position: relative;
15505- max-width: 1200px;
15506- margin: 0 auto;
15507- padding: 0 28px;
15508-}
15509-
15510-.lv-section-header-dark {
15511- max-width: 680px;
15512- margin: 0 auto 48px;
15513- text-align: center;
15514-}
15515-
15516-.lv-layers-grid {
15517- display: grid;
15518- grid-template-columns: repeat(4, 1fr);
15519- gap: 10px;
15520- max-width: 980px;
15521- margin: 0 auto;
15522-}
15523-
15524-.lv-layer-chip {
15525- border: 1px solid rgba(255,255,255,0.10);
15526- border-radius: 10px;
15527- padding: 12px 16px;
15528- background: rgba(255,255,255,0.03);
15529-}
15530-
15531-.lv-layer-cta {
15532- border-color: rgba(169,180,238,0.30);
15533- background: rgba(169,180,238,0.06);
15534- display: flex;
15535- align-items: center;
15536- text-decoration: none;
15537- transition: background 0.15s;
15538-}
15539-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
15540-
15541-.lv-layer-cta-text {
15542- font-size: 13px;
15543- font-weight: 500;
15544- color: #a9b4ee;
15545-}
15546-
15547-.lv-layer-n {
15548- font-family: 'JetBrains Mono', monospace;
15549- font-size: 10px;
15550- color: rgba(255,255,255,0.4);
15551- margin-bottom: 3px;
15552-}
15553-
15554-.lv-layer-name {
15555- font-size: 13px;
15556- font-weight: 500;
15557- color: rgba(255,255,255,0.92);
15558-}
15559-
15560-.lv-sovereign-feats {
15561- display: flex;
15562- gap: 44px;
15563- justify-content: center;
15564- flex-wrap: wrap;
15565- margin-top: 52px;
15566- text-align: center;
15567-}
15568-
15569-.lv-sovereign-feat {}
15570-
15571-.lv-sovereign-feat-title {
15572- font-family: 'Inter Tight', sans-serif;
15573- font-size: 20px;
15574- font-weight: 700;
15575- color: #fff;
15576-}
15577-
15578-.lv-sovereign-feat-sub {
15579- color: rgba(255,255,255,0.55);
15580- font-size: 13px;
15581- margin-top: 2px;
15582-}
15583-
15584-/* Twin cards */
15585-.lv-twin {
15586- padding: 96px 0;
15587- background: #fcfcfd;
15588-}
15589-
15590-.lv-twin-inner {
15591- max-width: 1200px;
15592- margin: 0 auto;
15593- padding: 0 28px;
15594- display: grid;
15595- grid-template-columns: 1fr 1fr;
15596- gap: 24px;
15597-}
15598-
15599-.lv-twin-card {
15600- border: 1px solid rgba(22,24,29,0.08);
15601- border-radius: 20px;
15602- background: #ffffff;
15603- padding: 44px 48px;
15604-}
15605-
15606-.lv-twin-title {
15607- font-family: 'Inter Tight', sans-serif;
15608- font-size: 24px;
15609- font-weight: 600;
15610- letter-spacing: -0.02em;
15611- line-height: 1.2;
15612- margin: 0 0 12px;
15613- color: #16181d;
15614-}
15615-
15616-.lv-twin-body {
15617- font-size: 14.5px;
15618- color: #6b7080;
15619- margin: 0 0 16px;
15620- line-height: 1.7;
15621-}
15622-
15623-.lv-twin-link {
15624- font-size: 13.5px;
15625- font-weight: 600;
15626- color: #4353c9;
15627- text-decoration: none;
15628-}
15629-.lv-twin-link:hover { text-decoration: underline; }
15630-
15631-/* Quote */
15632-.lv-quote {
15633- padding: 40px 0 96px;
15634- background: #fcfcfd;
15635-}
15636-
15637-.lv-quote-inner {
15638- max-width: 980px;
15639- margin: 0 auto;
15640- padding: 0 28px;
15641- text-align: center;
15642-}
15643-
15644-.lv-quote-text {
15645- font-family: 'Inter Tight', sans-serif;
15646- font-weight: 600;
15647- font-size: clamp(26px, 3.8vw, 42px);
15648- line-height: 1.2;
15649- letter-spacing: -0.025em;
15650- margin: 0;
15651- color: #111318;
15652-}
15653-
15654-.lv-em {
15655- font-style: normal;
15656- color: #4353c9;
15657-}
15658-
15659-/* CTA */
15660-.lv-cta-section {
15661- padding: 0 0 104px;
15662- background: #fcfcfd;
15663-}
15664-
15665-.lv-cta-card {
15666- max-width: 820px;
15667- margin: 0 auto;
15668- padding: 64px 40px;
15669- text-align: center;
15670- background: #ffffff;
15671- border: 1px solid rgba(22,24,29,0.08);
15672- border-radius: 26px;
15673- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
15674- position: relative;
15675- overflow: hidden;
15676-}
15677-
15678-.lv-cta-glow {
15679- position: absolute;
15680- inset: -40% 0 auto 0;
15681- height: 280px;
15682- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
15683- pointer-events: none;
15684-}
15685-
15686-.lv-cta-h2 {
15687- font-family: 'Inter Tight', sans-serif;
15688- font-weight: 700;
15689- letter-spacing: -0.028em;
15690- font-size: clamp(30px, 4.6vw, 48px);
15691- margin: 0;
15692- position: relative;
15693- color: #111318;
15694-}
15695-
15696-.lv-cta-sub {
15697- color: #6b7080;
15698- font-size: 17px;
15699- margin: 16px 0 30px;
15700- position: relative;
15701-}
15702-
15703-.lv-cta-actions {
15704- display: flex;
15705- gap: 12px;
15706- justify-content: center;
15707- flex-wrap: wrap;
15708- position: relative;
15709-}
15710-
15711-.lv-cta-fine {
15712- margin-top: 20px;
15713- font-family: 'JetBrains Mono', monospace;
15714- font-size: 11px;
15715- color: #8a8d99;
15716- position: relative;
15717-}
15718-
15719-/* Footer */
15720-.lv-footer {
15721- border-top: 1px solid rgba(22,24,29,0.07);
15722- background: #ffffff;
15723- padding: 56px 0 30px;
15724-}
15725-
15726-.lv-footer-inner {
15727- max-width: 1200px;
15728- margin: 0 auto;
15729- padding: 0 28px;
15730- display: flex;
15731- gap: 48px;
15732- flex-wrap: wrap;
15733- justify-content: space-between;
15734-}
15735-
15736-.lv-footer-brand {}
15737-
15738-.lv-footer-tagline {
15739- color: #6b7080;
15740- font-size: 13.5px;
15741- margin: 12px 0 0;
15742- max-width: 32ch;
15743- line-height: 1.6;
15744-}
15745-
15746-.lv-footer-cols {
15747- display: flex;
15748- gap: 64px;
15749- flex-wrap: wrap;
15750-}
15751-
15752-.lv-footer-col {
15753- display: flex;
15754- flex-direction: column;
15755- gap: 9px;
15756-}
15757-
15758-.lv-footer-col-head {
15759- font-family: 'JetBrains Mono', monospace;
15760- font-size: 11px;
15761- text-transform: uppercase;
15762- letter-spacing: 0.1em;
15763- color: #8a8d99;
15764- margin: 0 0 4px;
15765- font-weight: 500;
15766-}
15767-
15768-.lv-footer-link {
15769- color: #3a3d45;
15770- font-size: 13.5px;
15771- text-decoration: none;
15772- transition: color 0.15s;
15773-}
15774-.lv-footer-link:hover { color: #16181d; }
15775-
15776-.lv-footer-bar {
15777- max-width: 1200px;
15778- margin: 44px auto 0;
15779- padding: 22px 28px 0;
15780- border-top: 1px solid rgba(22,24,29,0.06);
15781- display: flex;
15782- justify-content: space-between;
15783- flex-wrap: wrap;
15784- gap: 8px;
15785- color: #8a8d99;
15786- font-size: 12.5px;
15787-}
15788-
15789-.lv-footer-stack {
15790- font-family: 'JetBrains Mono', monospace;
15791- font-size: 11px;
15792-}
15793-`;
15794diff --git a/src/views/layout.tsx b/src/views/layout.tsx
15795index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
15796--- a/src/views/layout.tsx
15797+++ b/src/views/layout.tsx
15798@@ -3153,9 +3153,12 @@
15799 font-weight: 500;
15800 line-height: 1.4;
15801 }
15802- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
15803- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
15804- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
15805+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
15806+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
15807+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
15808+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
15809+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
15810+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
15811 .state-merged { color: var(--accent); }
15812 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
15813
15814diff --git a/src/views/ui.tsx b/src/views/ui.tsx
15815index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
15816--- a/src/views/ui.tsx
15817+++ b/src/views/ui.tsx
15818@@ -232,7 +232,7 @@
15819
15820 export const Badge: FC<
15821 PropsWithChildren<{
15822- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
15823+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
15824 style?: string;
15825 }>
15826 > = ({ children, variant = "default", style }) => {
15827@@ -241,9 +241,12 @@
15828 variant === "closed" ? "badge-closed" :
15829 variant === "merged" ? "badge-merged" :
15830 variant === "success" ? "badge-success" :
15831- variant === "danger" ? "badge-danger" :
15832- variant === "warning" ? "badge-warning" :
15833- "badge";
15834+ variant === "danger" ? "badge-danger" :
15835+ variant === "warning" ? "badge-warning" :
15836+ variant === "live" ? "badge-live" :
15837+ variant === "soon" ? "badge-soon" :
15838+ variant === "preview" ? "badge-preview" :
15839+ "badge";
15840 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
15841 };
15842
15843
15844diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
15845index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
15846--- a/src/views/landing-pro.tsx
15847+++ b/src/views/landing-pro.tsx
15848@@ -42,7 +42,7 @@
15849
15850 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15851
15852-function icon(paths: string, color = "#4353c9", size = 20) {
15853+function icon(paths: string, color = "#0891b2", size = 20) {
15854 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
15855 }
15856
15857@@ -947,7 +947,7 @@
15858 const css = `
15859 /* %% tokens %% */
15860 :root{
15861- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
15862+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
15863 --lp-bg:#ffffff;--lp-soft:#fafafb;
15864 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
15865 --lp-border:rgba(0,0,0,.08);
15866diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
15867deleted file mode 100644
15868index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
15869--- a/src/views/landing-v2.tsx
15870+++ /dev/null
15871@@ -1,1447 +0,0 @@
15872-import type { FC } from "hono/jsx";
15873-
15874-export interface LandingPageProps {
15875- stats?: {
15876- publicRepos?: number;
15877- users?: number;
15878- };
15879-}
15880-
15881-const demoAllEvents = [
15882- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
15883- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
15884- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
15885- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
15886- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
15887-];
15888-
15889-const tickerItems = [
15890- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
15891- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
15892- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
15893- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
15894- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
15895- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
15896- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
15897- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
15898- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
15899- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
15900- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
15901- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
15902- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
15903- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
15904- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
15905- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
15906-];
15907-
15908-const stageData = [
15909- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
15910- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
15911- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
15912- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
15913- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
15914- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
15915-];
15916-
15917-const heroFeatures = [
15918- {
15919- href: "/",
15920- eyebrow: "01 � The autonomous repair loop",
15921- title: "Failures fix themselves  and show their work.",
15922- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
15923failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
15924- cta: "Watch a live repair session",
15925- mock: [
15926- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
15927- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
15928- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
15929- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
15930- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
15931- ],
15932- },
15933- {
15934- href: "/",
15935- eyebrow: "02 � Live sandbox isolation",
15936- title: "Every PR gets its own instant, disposable environment.",
15937- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
15938same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
15939- cta: "See a PR with its sandbox",
15940- mock: [
15941- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
15942- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
15943- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
15944- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
15945- ],
15946- },
15947- {
15948- href: "/",
15949- eyebrow: "03 � Multiplayer IDE workspaces",
15950- title: "You and the agent, side by side, in your editor.",
15951- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
15952agent into a silent reviewer in your gutter. The browser becomes optional.",
15953- cta: "See the editor session",
15954- mock: [
15955- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
15956- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
15957- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
15958- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
15959- ],
15960- },
15961-];
15962-
15963-const capabilities = [
15964- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
15965- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
15966- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
15967- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
15968- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
15969- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
15970- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
15971- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
15972-];
15973-
15974-const sovereignLayerNames = [
15975- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
15976- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
15977- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
15978- "Availability & recovery",
15979-];
15980-
15981-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
15982- return (
15983- <>
15984- <style dangerouslySetInnerHTML={{ __html: css }} />
15985-
15986- {/* Nav */}
15987- <header class="lv-nav">
15988- <div class="lv-nav-inner">
15989- <a href="/" class="lv-logo">
15990- <span class="lv-logo-mark"></span>gluecron
15991- </a>
15992- <nav class="lv-nav-links">
15993- <a href="#loop" class="lv-nav-link">The loop</a>
15994- <a href="#platform" class="lv-nav-link">Platform</a>
15995- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
15996- <a href="/trust" class="lv-nav-link">Trust</a>
15997- </nav>
15998- <div class="lv-nav-ctas">
15999- <a href="/login" class="lv-btn-secondary">Sign in</a>
16000- <a href="/register" class="lv-btn-primary">Start building</a>
16001- </div>
16002- </div>
16003- </header>
16004-
16005- {/* Hero */}
16006- <section class="lv-hero">
16007- <div class="lv-hero-glow"></div>
16008- <div class="lv-hero-inner">
16009- <div class="lv-hero-badge">
16010- <span class="lv-dot lv-dot-green lv-pulse"></span>
16011- Live: a repair loop converged on pr-218 while you read this
16012- </div>
16013- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
16014- <p class="lv-hero-sub">
16015- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
16016failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
16017- </p>
16018- <div class="lv-hero-actions">
16019- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
16020- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
16021- </div>
16022- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
16023-
16024- {/* Live product window */}
16025- <div class="lv-demo-window">
16026- <div class="lv-demo-bar">
16027- <span class="lv-demo-dot"></span>
16028- <span class="lv-demo-dot"></span>
16029- <span class="lv-demo-dot"></span>
16030- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
16031- <span class="lv-demo-live">
16032- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
16033- LIVE
16034- </span>
16035- </div>
16036- <div class="lv-demo-body" id="lv-demo-body">
16037- {/* Events rendered by JS */}
16038- {demoAllEvents.slice(0, 1).map((e, i) => (
16039- <div class="lv-demo-event" key={i}>
16040- <div class="lv-demo-event-track">
16041- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
16042- <span class="lv-demo-line" style="display:none"></span>
16043- </div>
16044- <div class="lv-demo-event-content">
16045- <div class="lv-demo-event-header">
16046- <span class="lv-demo-event-title">{e.title}</span>
16047- <span class="lv-demo-event-time">{e.time}</span>
16048- </div>
16049- <div class="lv-demo-event-body">{e.body}</div>
16050- </div>
16051- </div>
16052- ))}
16053- </div>
16054- </div>
16055- </div>
16056-
16057- {/* Activity ticker */}
16058- <div class="lv-ticker-wrap">
16059- <div class="lv-ticker-track">
16060- {tickerItems.map((t, i) => (
16061- <span class="lv-ticker-item" key={i}>
16062- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
16063- {t.text}
16064- </span>
16065- ))}
16066- </div>
16067- </div>
16068- </section>
16069-
16070- {/* Stat band */}
16071- <section class="lv-stats">
16072- <div class="lv-stats-inner">
16073- <div class="lv-stat">
16074- <div class="lv-stat-num">Sonnet 5</div>
16075- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
16076- </div>
16077- <div class="lv-stat">
16078- <div class="lv-stat-num">93.5%</div>
16079- <div class="lv-stat-label">of failures self-repair without a human</div>
16080- </div>
16081- <div class="lv-stat">
16082- <div class="lv-stat-num">1.9%</div>
16083- <div class="lv-stat-label">AI merges reverted  published live</div>
16084- </div>
16085- <div class="lv-stat">
16086- <div class="lv-stat-num">0</div>
16087- <div class="lv-stat-label">irreversible actions taken autonomously</div>
16088- </div>
16089- </div>
16090- </section>
16091-
16092- {/* The loop */}
16093- <section id="loop" class="lv-loop">
16094- <div class="lv-loop-inner">
16095- <div class="lv-section-header">
16096- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
16097- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
16098- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
16099- </div>
16100- <div class="lv-stages" id="lv-stages">
16101- {stageData.map((s, i) => (
16102- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
16103- <div class="lv-stage-header">
16104- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
16105- <span class="lv-stage-n">0{i + 1}</span>
16106- </div>
16107- <div class="lv-stage-name">{s.name}</div>
16108- <div class="lv-stage-desc">{s.desc}</div>
16109- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
16110- </div>
16111- ))}
16112- </div>
16113- </div>
16114- </section>
16115-
16116- {/* Three heroes */}
16117- <section class="lv-heroes">
16118- <div class="lv-heroes-inner">
16119- <div class="lv-heroes-header">
16120- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
16121- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
16122- </div>
16123- <div class="lv-heroes-list">
16124- {heroFeatures.map((h, i) => (
16125- <a href={h.href} class="lv-hero-card" key={i}>
16126- <div class="lv-hero-card-left">
16127- <div class="lv-eyebrow">{h.eyebrow}</div>
16128- <h3 class="lv-hero-card-title">{h.title}</h3>
16129- <p class="lv-hero-card-body">{h.body}</p>
16130- <span class="lv-hero-card-cta">{h.cta} �!</span>
16131- </div>
16132- <div class="lv-terminal">
16133- {h.mock.map((m, j) => (
16134- <div class="lv-terminal-line" key={j}>
16135- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
16136- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
16137- </div>
16138- ))}
16139- </div>
16140- </a>
16141- ))}
16142- </div>
16143- </div>
16144- </section>
16145-
16146- {/* Everything grid */}
16147- <section id="platform" class="lv-platform">
16148- <div class="lv-platform-inner">
16149- <div class="lv-section-header lv-section-header-center">
16150- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
16151- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
16152- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
16153- </div>
16154- <div class="lv-cap-grid">
16155- {capabilities.map((c, i) => (
16156- <div class="lv-cap-col" key={i}>
16157- <div class="lv-cap-group">{c.group}</div>
16158- <div class="lv-cap-items">
16159- {c.items.map((item, j) => (
16160- <div class="lv-cap-item" key={j}>{item}</div>
16161- ))}
16162- </div>
16163- </div>
16164- ))}
16165- </div>
16166- </div>
16167- </section>
16168-
16169- {/* Sovereignty band */}
16170- <section id="sovereign" class="lv-sovereign">
16171- <div class="lv-sovereign-grid-bg"></div>
16172- <div class="lv-sovereign-inner">
16173- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
16174- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
16175- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
16176- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
16177to private cloud, or run fully air-gapped on bare metal.</p>
16178- </div>
16179- <div class="lv-layers-grid">
16180- {sovereignLayerNames.map((name, i) => (
16181- <div class="lv-layer-chip" key={i}>
16182- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
16183- <div class="lv-layer-name">{name}</div>
16184- </div>
16185- ))}
16186- <a href="/" class="lv-layer-chip lv-layer-cta">
16187- <div class="lv-layer-cta-text">All self-owned �!</div>
16188- </a>
16189- </div>
16190- <div class="lv-sovereign-feats">
16191- <div class="lv-sovereign-feat">
16192- <div class="lv-sovereign-feat-title">Local inference first</div>
16193- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
16194- </div>
16195- <div class="lv-sovereign-feat">
16196- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
16197- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
16198- </div>
16199- <div class="lv-sovereign-feat">
16200- <div class="lv-sovereign-feat-title">Self-healing infra</div>
16201- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
16202- </div>
16203- </div>
16204- </div>
16205- </section>
16206-
16207- {/* Manual-first + reversibility */}
16208- <section class="lv-twin">
16209- <div class="lv-twin-inner">
16210- <div class="lv-twin-card">
16211- <div class="lv-eyebrow">Manual-first, always</div>
16212- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
16213- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
16214fallback. Developers who never touch AI get the best git host they've ever used.</p>
16215- </div>
16216- <div class="lv-twin-card">
16217- <div class="lv-eyebrow">The reversibility guarantee</div>
16218- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
16219- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
16220 policy, not promise. Our quality numbers are published live, unedited.</p>
16221- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
16222- </div>
16223- </div>
16224- </section>
16225-
16226- {/* Quote */}
16227- <section class="lv-quote">
16228- <div class="lv-quote-inner">
16229- <p class="lv-quote-text">
16230- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
16231- Gluecron is where code gets <em class="lv-em">finished</em>."
16232- </p>
16233- </div>
16234- </section>
16235-
16236- {/* CTA */}
16237- <section class="lv-cta-section">
16238- <div class="lv-cta-card">
16239- <div class="lv-cta-glow"></div>
16240- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
16241- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
16242- <div class="lv-cta-actions">
16243- <a href="/register" class="lv-cta-primary">Create your account �!</a>
16244- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
16245- </div>
16246- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
16247- </div>
16248- </section>
16249-
16250- {/* Footer */}
16251- <footer class="lv-footer">
16252- <div class="lv-footer-inner">
16253- <div class="lv-footer-brand">
16254- <a href="/" class="lv-logo">
16255- <span class="lv-logo-mark"></span>gluecron
16256- </a>
16257- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
16258- </div>
16259- <div class="lv-footer-cols">
16260- <div class="lv-footer-col">
16261- <h4 class="lv-footer-col-head">Product</h4>
16262- <a href="/" class="lv-footer-link">Agent workspace</a>
16263- <a href="/" class="lv-footer-link">Fleet refactors</a>
16264- <a href="/" class="lv-footer-link">Org memory</a>
16265- <a href="/" class="lv-footer-link">IDE extensions</a>
16266- </div>
16267- <div class="lv-footer-col">
16268- <h4 class="lv-footer-col-head">Platform</h4>
16269- <a href="/" class="lv-footer-link">Production layers</a>
16270- <a href="/trust" class="lv-footer-link">Trust report</a>
16271- <a href="/" class="lv-footer-link">Docs</a>
16272- <a href="/" class="lv-footer-link">Status</a>
16273- </div>
16274- <div class="lv-footer-col">
16275- <h4 class="lv-footer-col-head">Company</h4>
16276- <a href="/" class="lv-footer-link">About</a>
16277- <a href="/" class="lv-footer-link">Pricing</a>
16278- <a href="/" class="lv-footer-link">Enterprise</a>
16279- </div>
16280- </div>
16281- </div>
16282- <div class="lv-footer-bar">
16283- <span>� 2026 Gluecron</span>
16284- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
16285- </div>
16286- </footer>
16287-
16288- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
16289- </>
16290- );
16291-};
16292-
16293-export const LandingPage = LandingPageV2;
16294-export default LandingPageV2;
16295-
16296-const clientScript = `
16297-(function() {
16298- var demoAll = [
16299- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
16300- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
16301- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
16302- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
16303- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
16304- ];
16305-
16306- var demoStep = 0;
16307- var stage = 0;
16308-
16309- function renderDemo() {
16310- var container = document.getElementById('lv-demo-body');
16311- if (!container) return;
16312- var visible = demoAll.slice(0, demoStep + 1);
16313- container.innerHTML = visible.map(function(e, i) {
16314- var isLast = i === visible.length - 1;
16315- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
16316- return '<div class="lv-demo-event">' +
16317- '<div class="lv-demo-event-track">' +
16318- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
16319- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
16320- '</div>' +
16321- '<div class="lv-demo-event-content">' +
16322- '<div class="lv-demo-event-header">' +
16323- '<span class="lv-demo-event-title">' + e.title + '</span>' +
16324- '<span class="lv-demo-event-time">' + e.time + '</span>' +
16325- '</div>' +
16326- '<div class="lv-demo-event-body">' + e.body + '</div>' +
16327- '</div>' +
16328- '</div>';
16329- }).join('');
16330- }
16331-
16332- function renderStages() {
16333- var cards = document.querySelectorAll('.lv-stage-card');
16334- cards.forEach(function(card, i) {
16335- var dot = card.querySelector('.lv-dot');
16336- var meta = card.querySelector('.lv-stage-meta');
16337- if (i === stage) {
16338- card.classList.add('lv-stage-active');
16339- if (dot) {
16340- dot.classList.remove('lv-dot-idle');
16341- dot.classList.add('lv-dot-indigo', 'lv-pulse');
16342- }
16343- if (meta) meta.classList.add('lv-stage-meta-active');
16344- } else {
16345- card.classList.remove('lv-stage-active');
16346- if (dot) {
16347- dot.classList.add('lv-dot-idle');
16348- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
16349- }
16350- if (meta) meta.classList.remove('lv-stage-meta-active');
16351- }
16352- });
16353- }
16354-
16355- renderDemo();
16356-
16357- setInterval(function() {
16358- demoStep = (demoStep + 1) % 5;
16359- renderDemo();
16360- }, 3600);
16361-
16362- setInterval(function() {
16363- stage = (stage + 1) % 6;
16364- renderStages();
16365- }, 2200);
16366-})();
16367-`;
16368-
16369-const css = `
16370-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
16371-
16372-*, *::before, *::after { box-sizing: border-box; }
16373-
16374-body {
16375- margin: 0;
16376- background: #fcfcfd;
16377- -webkit-font-smoothing: antialiased;
16378- text-rendering: optimizeLegibility;
16379- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
16380- font-size: 15px;
16381- line-height: 1.6;
16382- letter-spacing: -0.008em;
16383- color: #16181d;
16384-}
16385-
16386-@keyframes gcPulse {
16387- 0%, 100% { opacity: 1; }
16388- 50% { opacity: 0.35; }
16389-}
16390-
16391-@keyframes gcTicker {
16392- 0% { transform: translateX(0); }
16393- 100% { transform: translateX(-50%); }
16394-}
16395-
16396-/* Shared utilities */
16397-.lv-dot {
16398- display: inline-block;
16399- border-radius: 50%;
16400-}
16401-.lv-dot-green { background: #1e7f5c; }
16402-.lv-dot-indigo { background: #4353c9; }
16403-.lv-dot-idle { background: #c4c6cf; }
16404-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
16405-
16406-.lv-strong { color: #16181d; font-weight: 600; }
16407-
16408-.lv-eyebrow {
16409- font-family: 'JetBrains Mono', monospace;
16410- font-size: 11px;
16411- letter-spacing: 0.12em;
16412- text-transform: uppercase;
16413- color: #8a8d99;
16414- font-weight: 500;
16415- margin-bottom: 12px;
16416-}
16417-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
16418-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
16419-
16420-.lv-h1 {
16421- font-family: 'Inter Tight', sans-serif;
16422- font-weight: 700;
16423- letter-spacing: -0.035em;
16424- font-size: clamp(44px, 7vw, 84px);
16425- line-height: 0.98;
16426- margin: 30px auto 0;
16427- max-width: 14ch;
16428- color: #111318;
16429-}
16430-
16431-.lv-h2 {
16432- font-family: 'Inter Tight', sans-serif;
16433- font-weight: 700;
16434- letter-spacing: -0.028em;
16435- font-size: clamp(30px, 4.4vw, 48px);
16436- line-height: 1.05;
16437- margin: 0;
16438- color: #111318;
16439-}
16440-
16441-.lv-h2-dark {
16442- font-family: 'Inter Tight', sans-serif;
16443- font-weight: 700;
16444- letter-spacing: -0.028em;
16445- font-size: clamp(30px, 4.6vw, 52px);
16446- line-height: 1.05;
16447- margin: 0;
16448- color: #fff;
16449-}
16450-
16451-.lv-section-header {
16452- max-width: 640px;
16453- margin: 0 auto 56px;
16454-}
16455-
16456-.lv-section-header-center {
16457- text-align: center;
16458-}
16459-
16460-.lv-section-sub {
16461- color: #6b7080;
16462- font-size: 17px;
16463- margin: 18px auto 0;
16464- max-width: 52ch;
16465-}
16466-
16467-.lv-section-sub-dark {
16468- color: rgba(255,255,255,0.72);
16469- font-size: 17px;
16470- margin: 18px auto 0;
16471- max-width: 56ch;
16472-}
16473-
16474-/* Nav */
16475-.lv-nav {
16476- position: sticky;
16477- top: 0;
16478- z-index: 60;
16479- backdrop-filter: saturate(180%) blur(14px);
16480- -webkit-backdrop-filter: saturate(180%) blur(14px);
16481- background: rgba(252,252,253,0.8);
16482- border-bottom: 1px solid rgba(22,24,29,0.07);
16483-}
16484-
16485-.lv-nav-inner {
16486- max-width: 1200px;
16487- margin: 0 auto;
16488- padding: 14px 28px;
16489- display: flex;
16490- align-items: center;
16491- gap: 28px;
16492-}
16493-
16494-.lv-logo {
16495- display: inline-flex;
16496- align-items: center;
16497- gap: 9px;
16498- font-family: 'Inter Tight', sans-serif;
16499- font-weight: 700;
16500- font-size: 17px;
16501- letter-spacing: -0.02em;
16502- color: #16181d;
16503- text-decoration: none;
16504-}
16505-
16506-.lv-logo-mark {
16507- width: 17px;
16508- height: 17px;
16509- border-radius: 5px;
16510- background: #4353c9;
16511- display: inline-block;
16512- flex-shrink: 0;
16513-}
16514-
16515-.lv-nav-links {
16516- display: flex;
16517- gap: 24px;
16518- font-size: 13.5px;
16519- font-weight: 500;
16520-}
16521-
16522-.lv-nav-link {
16523- color: #6b7080;
16524- text-decoration: none;
16525- transition: color 0.15s;
16526-}
16527-.lv-nav-link:hover { color: #16181d; }
16528-
16529-.lv-nav-ctas {
16530- margin-left: auto;
16531- display: flex;
16532- align-items: center;
16533- gap: 10px;
16534-}
16535-
16536-.lv-btn-secondary {
16537- padding: 8px 15px;
16538- border-radius: 8px;
16539- font-size: 13.5px;
16540- font-weight: 500;
16541- color: #16181d;
16542- border: 1px solid rgba(22,24,29,0.12);
16543- background: #ffffff;
16544- text-decoration: none;
16545- white-space: nowrap;
16546- transition: border-color 0.15s;
16547-}
16548-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
16549-
16550-.lv-btn-primary {
16551- padding: 8px 15px;
16552- border-radius: 8px;
16553- font-size: 13.5px;
16554- font-weight: 600;
16555- background: #16181d;
16556- color: #fff;
16557- text-decoration: none;
16558- white-space: nowrap;
16559- transition: box-shadow 0.15s;
16560-}
16561-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
16562-
16563-/* Hero */
16564-.lv-hero {
16565- position: relative;
16566- overflow: hidden;
16567- padding: 88px 0 0;
16568-}
16569-
16570-.lv-hero-glow {
16571- position: absolute;
16572- inset: -10% 0 auto 0;
16573- height: 640px;
16574- pointer-events: none;
16575- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
16576-}
16577-
16578-.lv-hero-inner {
16579- position: relative;
16580- max-width: 1200px;
16581- margin: 0 auto;
16582- padding: 0 28px;
16583- text-align: center;
16584-}
16585-
16586-.lv-hero-badge {
16587- display: inline-flex;
16588- align-items: center;
16589- gap: 9px;
16590- font-size: 12.5px;
16591- font-weight: 600;
16592- color: #3a3d45;
16593- background: #ffffff;
16594- border: 1px solid rgba(22,24,29,0.10);
16595- border-radius: 9999px;
16596- padding: 7px 16px;
16597- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
16598-}
16599-
16600-.lv-hero-sub {
16601- font-size: clamp(16px, 2vw, 19px);
16602- color: #6b7080;
16603- max-width: 60ch;
16604- margin: 24px auto 0;
16605- font-weight: 450;
16606- line-height: 1.65;
16607-}
16608-
16609-.lv-hero-actions {
16610- display: flex;
16611- gap: 12px;
16612- justify-content: center;
16613- flex-wrap: wrap;
16614- margin-top: 32px;
16615-}
16616-
16617-.lv-cta-primary {
16618- padding: 13px 24px;
16619- border-radius: 11px;
16620- font-size: 15.5px;
16621- font-weight: 600;
16622- background: #16181d;
16623- color: #fff;
16624- text-decoration: none;
16625- white-space: nowrap;
16626- transition: box-shadow 0.15s;
16627-}
16628-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
16629-
16630-.lv-cta-secondary {
16631- padding: 13px 24px;
16632- border-radius: 11px;
16633- font-size: 15.5px;
16634- font-weight: 600;
16635- color: #16181d;
16636- border: 1px solid rgba(22,24,29,0.14);
16637- background: #ffffff;
16638- text-decoration: none;
16639- white-space: nowrap;
16640- transition: border-color 0.15s;
16641-}
16642-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
16643-
16644-.lv-hero-tag {
16645- margin-top: 18px;
16646- font-family: 'JetBrains Mono', monospace;
16647- font-size: 11.5px;
16648- letter-spacing: 0.08em;
16649- text-transform: uppercase;
16650- color: #8a8d99;
16651-}
16652-
16653-/* Demo window */
16654-.lv-demo-window {
16655- margin: 56px auto 0;
16656- max-width: 860px;
16657- text-align: left;
16658- background: #ffffff;
16659- border: 1px solid rgba(22,24,29,0.09);
16660- border-radius: 18px;
16661- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
16662- overflow: hidden;
16663-}
16664-
16665-.lv-demo-bar {
16666- display: flex;
16667- align-items: center;
16668- gap: 7px;
16669- padding: 12px 18px;
16670- border-bottom: 1px solid rgba(22,24,29,0.07);
16671- background: #fcfcfd;
16672-}
16673-
16674-.lv-demo-dot {
16675- width: 10px;
16676- height: 10px;
16677- border-radius: 50%;
16678- background: #e4e5ea;
16679-}
16680-
16681-.lv-demo-url {
16682- margin-left: 10px;
16683- font-family: 'JetBrains Mono', monospace;
16684- font-size: 12px;
16685- color: #6b7080;
16686-}
16687-
16688-.lv-demo-live {
16689- margin-left: auto;
16690- display: inline-flex;
16691- align-items: center;
16692- gap: 6px;
16693- font-size: 11px;
16694- font-weight: 600;
16695- color: #1e7f5c;
16696-}
16697-
16698-.lv-demo-body {
16699- padding: 22px 24px;
16700-}
16701-
16702-.lv-demo-event {
16703- display: grid;
16704- grid-template-columns: 18px minmax(0, 1fr);
16705- gap: 14px;
16706- padding-bottom: 20px;
16707- position: relative;
16708-}
16709-.lv-demo-event:last-child { padding-bottom: 0; }
16710-
16711-.lv-demo-event-track {
16712- display: flex;
16713- flex-direction: column;
16714- align-items: center;
16715-}
16716-
16717-.lv-demo-line {
16718- width: 1px;
16719- flex: 1;
16720- background: rgba(22,24,29,0.08);
16721- margin-top: 5px;
16722- min-height: 20px;
16723-}
16724-
16725-.lv-demo-event-content {}
16726-
16727-.lv-demo-event-header {
16728- display: flex;
16729- align-items: baseline;
16730- gap: 10px;
16731-}
16732-
16733-.lv-demo-event-title {
16734- font-size: 13.5px;
16735- font-weight: 600;
16736- color: #16181d;
16737-}
16738-
16739-.lv-demo-event-time {
16740- font-family: 'JetBrains Mono', monospace;
16741- font-size: 11px;
16742- color: #8a8d99;
16743-}
16744-
16745-.lv-demo-event-body {
16746- font-size: 13px;
16747- color: #6b7080;
16748- margin-top: 2px;
16749-}
16750-
16751-/* Ticker */
16752-.lv-ticker-wrap {
16753- border-top: 1px solid rgba(22,24,29,0.07);
16754- border-bottom: 1px solid rgba(22,24,29,0.07);
16755- background: #ffffff;
16756- margin-top: 64px;
16757- overflow: hidden;
16758- white-space: nowrap;
16759- position: relative;
16760-}
16761-
16762-.lv-ticker-track {
16763- display: inline-flex;
16764- animation: gcTicker 40s linear infinite;
16765- padding: 11px 0;
16766-}
16767-
16768-.lv-ticker-item {
16769- display: inline-flex;
16770- align-items: center;
16771- gap: 8px;
16772- font-family: 'JetBrains Mono', monospace;
16773- font-size: 11.5px;
16774- color: #6b7080;
16775- padding: 0 28px;
16776- border-right: 1px solid rgba(22,24,29,0.06);
16777-}
16778-
16779-/* Stats */
16780-.lv-stats {
16781- background: #fcfcfd;
16782-}
16783-
16784-.lv-stats-inner {
16785- max-width: 1200px;
16786- margin: 0 auto;
16787- display: grid;
16788- grid-template-columns: repeat(4, 1fr);
16789- gap: 24px;
16790- padding: 52px 28px;
16791-}
16792-
16793-.lv-stat {
16794- text-align: center;
16795-}
16796-
16797-.lv-stat-num {
16798- font-family: 'Inter Tight', sans-serif;
16799- font-weight: 700;
16800- font-size: clamp(30px, 4vw, 44px);
16801- letter-spacing: -0.025em;
16802- color: #111318;
16803-}
16804-
16805-.lv-stat-label {
16806- font-size: 13px;
16807- color: #6b7080;
16808- margin-top: 4px;
16809-}
16810-
16811-/* Loop */
16812-.lv-loop {
16813- padding: 96px 0;
16814- background: #ffffff;
16815- border-top: 1px solid rgba(22,24,29,0.07);
16816- border-bottom: 1px solid rgba(22,24,29,0.07);
16817-}
16818-
16819-.lv-loop-inner {
16820- max-width: 1200px;
16821- margin: 0 auto;
16822- padding: 0 28px;
16823-}
16824-
16825-.lv-stages {
16826- display: grid;
16827- grid-template-columns: repeat(6, 1fr);
16828- gap: 12px;
16829-}
16830-
16831-.lv-stage-card {
16832- border: 1px solid rgba(22,24,29,0.08);
16833- border-radius: 14px;
16834- background: #ffffff;
16835- padding: 20px 18px;
16836- transition: border-color 0.3s, background 0.3s;
16837-}
16838-
16839-.lv-stage-card.lv-stage-active {
16840- border-color: rgba(67,83,201,0.45);
16841- background: rgba(67,83,201,0.03);
16842-}
16843-
16844-.lv-stage-header {
16845- display: flex;
16846- align-items: center;
16847- gap: 8px;
16848- margin-bottom: 10px;
16849-}
16850-
16851-.lv-stage-n {
16852- font-family: 'JetBrains Mono', monospace;
16853- font-size: 10.5px;
16854- letter-spacing: 0.1em;
16855- text-transform: uppercase;
16856- color: #8a8d99;
16857-}
16858-
16859-.lv-stage-name {
16860- font-family: 'Inter Tight', sans-serif;
16861- font-size: 16px;
16862- font-weight: 600;
16863- letter-spacing: -0.01em;
16864- color: #16181d;
16865- margin-bottom: 5px;
16866-}
16867-
16868-.lv-stage-desc {
16869- font-size: 12px;
16870- color: #6b7080;
16871- line-height: 1.55;
16872-}
16873-
16874-.lv-stage-meta {
16875- font-family: 'JetBrains Mono', monospace;
16876- font-size: 10.5px;
16877- color: #8a8d99;
16878- margin-top: 10px;
16879- transition: color 0.3s;
16880-}
16881-
16882-.lv-stage-meta.lv-stage-meta-active {
16883- color: #4353c9;
16884-}
16885-
16886-/* Heroes */
16887-.lv-heroes {
16888- padding: 96px 0;
16889- background: #fcfcfd;
16890-}
16891-
16892-.lv-heroes-inner {
16893- max-width: 1200px;
16894- margin: 0 auto;
16895- padding: 0 28px;
16896-}
16897-
16898-.lv-heroes-header {
16899- max-width: 640px;
16900- margin-bottom: 56px;
16901-}
16902-
16903-.lv-heroes-list {
16904- display: flex;
16905- flex-direction: column;
16906- gap: 20px;
16907-}
16908-
16909-.lv-hero-card {
16910- display: grid;
16911- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
16912- gap: 48px;
16913- align-items: center;
16914- border: 1px solid rgba(22,24,29,0.08);
16915- border-radius: 20px;
16916- background: #ffffff;
16917- padding: 44px 48px;
16918- text-decoration: none;
16919- transition: border-color 0.2s, box-shadow 0.2s;
16920-}
16921-.lv-hero-card:hover {
16922- border-color: rgba(22,24,29,0.22);
16923- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
16924-}
16925-
16926-.lv-hero-card-left {}
16927-
16928-.lv-hero-card-title {
16929- font-family: 'Inter Tight', sans-serif;
16930- font-size: 26px;
16931- font-weight: 600;
16932- letter-spacing: -0.022em;
16933- line-height: 1.15;
16934- color: #16181d;
16935- margin: 0 0 12px;
16936-}
16937-
16938-.lv-hero-card-body {
16939- font-size: 14.5px;
16940- color: #6b7080;
16941- margin: 0 0 18px;
16942- line-height: 1.65;
16943-}
16944-
16945-.lv-hero-card-cta {
16946- font-size: 13.5px;
16947- font-weight: 600;
16948- color: #4353c9;
16949-}
16950-
16951-.lv-terminal {
16952- border: 1px solid rgba(22,24,29,0.07);
16953- border-radius: 14px;
16954- background: #fcfcfd;
16955- padding: 20px 22px;
16956- font-family: 'JetBrains Mono', monospace;
16957- font-size: 12px;
16958- line-height: 1.9;
16959- overflow: hidden;
16960-}
16961-
16962-.lv-terminal-line {
16963- display: flex;
16964- align-items: center;
16965- gap: 10px;
16966- white-space: nowrap;
16967- overflow: hidden;
16968- text-overflow: ellipsis;
16969-}
16970-
16971-/* Platform */
16972-.lv-platform {
16973- padding: 96px 0;
16974- background: #ffffff;
16975- border-top: 1px solid rgba(22,24,29,0.07);
16976-}
16977-
16978-.lv-platform-inner {
16979- max-width: 1200px;
16980- margin: 0 auto;
16981- padding: 0 28px;
16982-}
16983-
16984-.lv-cap-grid {
16985- display: grid;
16986- grid-template-columns: repeat(4, 1fr);
16987- gap: 24px 32px;
16988-}
16989-
16990-.lv-cap-col {}
16991-
16992-.lv-cap-group {
16993- font-family: 'JetBrains Mono', monospace;
16994- font-size: 10.5px;
16995- letter-spacing: 0.12em;
16996- text-transform: uppercase;
16997- color: #8a8d99;
16998- font-weight: 500;
16999- margin-bottom: 12px;
17000- padding-bottom: 8px;
17001- border-bottom: 1px solid rgba(22,24,29,0.07);
17002-}
17003-
17004-.lv-cap-items {
17005- display: flex;
17006- flex-direction: column;
17007- gap: 7px;
17008-}
17009-
17010-.lv-cap-item {
17011- font-size: 12.5px;
17012- color: #3a3d45;
17013- line-height: 1.45;
17014-}
17015-
17016-/* Sovereignty */
17017-.lv-sovereign {
17018- position: relative;
17019- overflow: hidden;
17020- padding: 104px 0;
17021- color: #fff;
17022- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
17023-}
17024-
17025-.lv-sovereign-grid-bg {
17026- position: absolute;
17027- inset: 0;
17028- opacity: 0.4;
17029- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
17030- background-size: 56px 56px;
17031- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
17032- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
17033-}
17034-
17035-.lv-sovereign-inner {
17036- position: relative;
17037- max-width: 1200px;
17038- margin: 0 auto;
17039- padding: 0 28px;
17040-}
17041-
17042-.lv-section-header-dark {
17043- max-width: 680px;
17044- margin: 0 auto 48px;
17045- text-align: center;
17046-}
17047-
17048-.lv-layers-grid {
17049- display: grid;
17050- grid-template-columns: repeat(4, 1fr);
17051- gap: 10px;
17052- max-width: 980px;
17053- margin: 0 auto;
17054-}
17055-
17056-.lv-layer-chip {
17057- border: 1px solid rgba(255,255,255,0.10);
17058- border-radius: 10px;
17059- padding: 12px 16px;
17060- background: rgba(255,255,255,0.03);
17061-}
17062-
17063-.lv-layer-cta {
17064- border-color: rgba(169,180,238,0.30);
17065- background: rgba(169,180,238,0.06);
17066- display: flex;
17067- align-items: center;
17068- text-decoration: none;
17069- transition: background 0.15s;
17070-}
17071-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
17072-
17073-.lv-layer-cta-text {
17074- font-size: 13px;
17075- font-weight: 500;
17076- color: #a9b4ee;
17077-}
17078-
17079-.lv-layer-n {
17080- font-family: 'JetBrains Mono', monospace;
17081- font-size: 10px;
17082- color: rgba(255,255,255,0.4);
17083- margin-bottom: 3px;
17084-}
17085-
17086-.lv-layer-name {
17087- font-size: 13px;
17088- font-weight: 500;
17089- color: rgba(255,255,255,0.92);
17090-}
17091-
17092-.lv-sovereign-feats {
17093- display: flex;
17094- gap: 44px;
17095- justify-content: center;
17096- flex-wrap: wrap;
17097- margin-top: 52px;
17098- text-align: center;
17099-}
17100-
17101-.lv-sovereign-feat {}
17102-
17103-.lv-sovereign-feat-title {
17104- font-family: 'Inter Tight', sans-serif;
17105- font-size: 20px;
17106- font-weight: 700;
17107- color: #fff;
17108-}
17109-
17110-.lv-sovereign-feat-sub {
17111- color: rgba(255,255,255,0.55);
17112- font-size: 13px;
17113- margin-top: 2px;
17114-}
17115-
17116-/* Twin cards */
17117-.lv-twin {
17118- padding: 96px 0;
17119- background: #fcfcfd;
17120-}
17121-
17122-.lv-twin-inner {
17123- max-width: 1200px;
17124- margin: 0 auto;
17125- padding: 0 28px;
17126- display: grid;
17127- grid-template-columns: 1fr 1fr;
17128- gap: 24px;
17129-}
17130-
17131-.lv-twin-card {
17132- border: 1px solid rgba(22,24,29,0.08);
17133- border-radius: 20px;
17134- background: #ffffff;
17135- padding: 44px 48px;
17136-}
17137-
17138-.lv-twin-title {
17139- font-family: 'Inter Tight', sans-serif;
17140- font-size: 24px;
17141- font-weight: 600;
17142- letter-spacing: -0.02em;
17143- line-height: 1.2;
17144- margin: 0 0 12px;
17145- color: #16181d;
17146-}
17147-
17148-.lv-twin-body {
17149- font-size: 14.5px;
17150- color: #6b7080;
17151- margin: 0 0 16px;
17152- line-height: 1.7;
17153-}
17154-
17155-.lv-twin-link {
17156- font-size: 13.5px;
17157- font-weight: 600;
17158- color: #4353c9;
17159- text-decoration: none;
17160-}
17161-.lv-twin-link:hover { text-decoration: underline; }
17162-
17163-/* Quote */
17164-.lv-quote {
17165- padding: 40px 0 96px;
17166- background: #fcfcfd;
17167-}
17168-
17169-.lv-quote-inner {
17170- max-width: 980px;
17171- margin: 0 auto;
17172- padding: 0 28px;
17173- text-align: center;
17174-}
17175-
17176-.lv-quote-text {
17177- font-family: 'Inter Tight', sans-serif;
17178- font-weight: 600;
17179- font-size: clamp(26px, 3.8vw, 42px);
17180- line-height: 1.2;
17181- letter-spacing: -0.025em;
17182- margin: 0;
17183- color: #111318;
17184-}
17185-
17186-.lv-em {
17187- font-style: normal;
17188- color: #4353c9;
17189-}
17190-
17191-/* CTA */
17192-.lv-cta-section {
17193- padding: 0 0 104px;
17194- background: #fcfcfd;
17195-}
17196-
17197-.lv-cta-card {
17198- max-width: 820px;
17199- margin: 0 auto;
17200- padding: 64px 40px;
17201- text-align: center;
17202- background: #ffffff;
17203- border: 1px solid rgba(22,24,29,0.08);
17204- border-radius: 26px;
17205- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
17206- position: relative;
17207- overflow: hidden;
17208-}
17209-
17210-.lv-cta-glow {
17211- position: absolute;
17212- inset: -40% 0 auto 0;
17213- height: 280px;
17214- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
17215- pointer-events: none;
17216-}
17217-
17218-.lv-cta-h2 {
17219- font-family: 'Inter Tight', sans-serif;
17220- font-weight: 700;
17221- letter-spacing: -0.028em;
17222- font-size: clamp(30px, 4.6vw, 48px);
17223- margin: 0;
17224- position: relative;
17225- color: #111318;
17226-}
17227-
17228-.lv-cta-sub {
17229- color: #6b7080;
17230- font-size: 17px;
17231- margin: 16px 0 30px;
17232- position: relative;
17233-}
17234-
17235-.lv-cta-actions {
17236- display: flex;
17237- gap: 12px;
17238- justify-content: center;
17239- flex-wrap: wrap;
17240- position: relative;
17241-}
17242-
17243-.lv-cta-fine {
17244- margin-top: 20px;
17245- font-family: 'JetBrains Mono', monospace;
17246- font-size: 11px;
17247- color: #8a8d99;
17248- position: relative;
17249-}
17250-
17251-/* Footer */
17252-.lv-footer {
17253- border-top: 1px solid rgba(22,24,29,0.07);
17254- background: #ffffff;
17255- padding: 56px 0 30px;
17256-}
17257-
17258-.lv-footer-inner {
17259- max-width: 1200px;
17260- margin: 0 auto;
17261- padding: 0 28px;
17262- display: flex;
17263- gap: 48px;
17264- flex-wrap: wrap;
17265- justify-content: space-between;
17266-}
17267-
17268-.lv-footer-brand {}
17269-
17270-.lv-footer-tagline {
17271- color: #6b7080;
17272- font-size: 13.5px;
17273- margin: 12px 0 0;
17274- max-width: 32ch;
17275- line-height: 1.6;
17276-}
17277-
17278-.lv-footer-cols {
17279- display: flex;
17280- gap: 64px;
17281- flex-wrap: wrap;
17282-}
17283-
17284-.lv-footer-col {
17285- display: flex;
17286- flex-direction: column;
17287- gap: 9px;
17288-}
17289-
17290-.lv-footer-col-head {
17291- font-family: 'JetBrains Mono', monospace;
17292- font-size: 11px;
17293- text-transform: uppercase;
17294- letter-spacing: 0.1em;
17295- color: #8a8d99;
17296- margin: 0 0 4px;
17297- font-weight: 500;
17298-}
17299-
17300-.lv-footer-link {
17301- color: #3a3d45;
17302- font-size: 13.5px;
17303- text-decoration: none;
17304- transition: color 0.15s;
17305-}
17306-.lv-footer-link:hover { color: #16181d; }
17307-
17308-.lv-footer-bar {
17309- max-width: 1200px;
17310- margin: 44px auto 0;
17311- padding: 22px 28px 0;
17312- border-top: 1px solid rgba(22,24,29,0.06);
17313- display: flex;
17314- justify-content: space-between;
17315- flex-wrap: wrap;
17316- gap: 8px;
17317- color: #8a8d99;
17318- font-size: 12.5px;
17319-}
17320-
17321-.lv-footer-stack {
17322- font-family: 'JetBrains Mono', monospace;
17323- font-size: 11px;
17324-}
17325-`;
17326diff --git a/src/views/layout.tsx b/src/views/layout.tsx
17327index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
17328--- a/src/views/layout.tsx
17329+++ b/src/views/layout.tsx
17330@@ -3153,9 +3153,12 @@
17331 font-weight: 500;
17332 line-height: 1.4;
17333 }
17334- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
17335- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
17336- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
17337+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
17338+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
17339+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
17340+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
17341+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
17342+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
17343 .state-merged { color: var(--accent); }
17344 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
17345
17346diff --git a/src/views/ui.tsx b/src/views/ui.tsx
17347index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
17348--- a/src/views/ui.tsx
17349+++ b/src/views/ui.tsx
17350@@ -232,7 +232,7 @@
17351
17352 export const Badge: FC<
17353 PropsWithChildren<{
17354- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
17355+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
17356 style?: string;
17357 }>
17358 > = ({ children, variant = "default", style }) => {
17359@@ -241,9 +241,12 @@
17360 variant === "closed" ? "badge-closed" :
17361 variant === "merged" ? "badge-merged" :
17362 variant === "success" ? "badge-success" :
17363- variant === "danger" ? "badge-danger" :
17364- variant === "warning" ? "badge-warning" :
17365- "badge";
17366+ variant === "danger" ? "badge-danger" :
17367+ variant === "warning" ? "badge-warning" :
17368+ variant === "live" ? "badge-live" :
17369+ variant === "soon" ? "badge-soon" :
17370+ variant === "preview" ? "badge-preview" :
17371+ "badge";
17372 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
17373 };
17374
17375
17376diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
17377index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
17378--- a/src/views/landing-pro.tsx
17379+++ b/src/views/landing-pro.tsx
17380@@ -42,7 +42,7 @@
17381
17382 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17383
17384-function icon(paths: string, color = "#4353c9", size = 20) {
17385+function icon(paths: string, color = "#0891b2", size = 20) {
17386 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
17387 }
17388
17389@@ -947,7 +947,7 @@
17390 const css = `
17391 /* %% tokens %% */
17392 :root{
17393- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
17394+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
17395 --lp-bg:#ffffff;--lp-soft:#fafafb;
17396 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
17397 --lp-border:rgba(0,0,0,.08);
17398diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
17399deleted file mode 100644
17400index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
17401--- a/src/views/landing-v2.tsx
17402+++ /dev/null
17403@@ -1,1447 +0,0 @@
17404-import type { FC } from "hono/jsx";
17405-
17406-export interface LandingPageProps {
17407- stats?: {
17408- publicRepos?: number;
17409- users?: number;
17410- };
17411-}
17412-
17413-const demoAllEvents = [
17414- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
17415- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
17416- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
17417- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
17418- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
17419-];
17420-
17421-const tickerItems = [
17422- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
17423- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
17424- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
17425- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
17426- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
17427- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
17428- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
17429- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
17430- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
17431- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
17432- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
17433- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
17434- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
17435- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
17436- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
17437- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
17438-];
17439-
17440-const stageData = [
17441- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
17442- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
17443- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
17444- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
17445- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
17446- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
17447-];
17448-
17449-const heroFeatures = [
17450- {
17451- href: "/",
17452- eyebrow: "01 � The autonomous repair loop",
17453- title: "Failures fix themselves  and show their work.",
17454- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
17455failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
17456- cta: "Watch a live repair session",
17457- mock: [
17458- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
17459- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
17460- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
17461- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
17462- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
17463- ],
17464- },
17465- {
17466- href: "/",
17467- eyebrow: "02 � Live sandbox isolation",
17468- title: "Every PR gets its own instant, disposable environment.",
17469- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
17470same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
17471- cta: "See a PR with its sandbox",
17472- mock: [
17473- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
17474- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
17475- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
17476- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
17477- ],
17478- },
17479- {
17480- href: "/",
17481- eyebrow: "03 � Multiplayer IDE workspaces",
17482- title: "You and the agent, side by side, in your editor.",
17483- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
17484agent into a silent reviewer in your gutter. The browser becomes optional.",
17485- cta: "See the editor session",
17486- mock: [
17487- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
17488- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
17489- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
17490- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
17491- ],
17492- },
17493-];
17494-
17495-const capabilities = [
17496- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
17497- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
17498- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
17499- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
17500- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
17501- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
17502- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
17503- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
17504-];
17505-
17506-const sovereignLayerNames = [
17507- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
17508- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
17509- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
17510- "Availability & recovery",
17511-];
17512-
17513-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
17514- return (
17515- <>
17516- <style dangerouslySetInnerHTML={{ __html: css }} />
17517-
17518- {/* Nav */}
17519- <header class="lv-nav">
17520- <div class="lv-nav-inner">
17521- <a href="/" class="lv-logo">
17522- <span class="lv-logo-mark"></span>gluecron
17523- </a>
17524- <nav class="lv-nav-links">
17525- <a href="#loop" class="lv-nav-link">The loop</a>
17526- <a href="#platform" class="lv-nav-link">Platform</a>
17527- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
17528- <a href="/trust" class="lv-nav-link">Trust</a>
17529- </nav>
17530- <div class="lv-nav-ctas">
17531- <a href="/login" class="lv-btn-secondary">Sign in</a>
17532- <a href="/register" class="lv-btn-primary">Start building</a>
17533- </div>
17534- </div>
17535- </header>
17536-
17537- {/* Hero */}
17538- <section class="lv-hero">
17539- <div class="lv-hero-glow"></div>
17540- <div class="lv-hero-inner">
17541- <div class="lv-hero-badge">
17542- <span class="lv-dot lv-dot-green lv-pulse"></span>
17543- Live: a repair loop converged on pr-218 while you read this
17544- </div>
17545- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
17546- <p class="lv-hero-sub">
17547- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
17548failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
17549- </p>
17550- <div class="lv-hero-actions">
17551- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
17552- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
17553- </div>
17554- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
17555-
17556- {/* Live product window */}
17557- <div class="lv-demo-window">
17558- <div class="lv-demo-bar">
17559- <span class="lv-demo-dot"></span>
17560- <span class="lv-demo-dot"></span>
17561- <span class="lv-demo-dot"></span>
17562- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
17563- <span class="lv-demo-live">
17564- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
17565- LIVE
17566- </span>
17567- </div>
17568- <div class="lv-demo-body" id="lv-demo-body">
17569- {/* Events rendered by JS */}
17570- {demoAllEvents.slice(0, 1).map((e, i) => (
17571- <div class="lv-demo-event" key={i}>
17572- <div class="lv-demo-event-track">
17573- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
17574- <span class="lv-demo-line" style="display:none"></span>
17575- </div>
17576- <div class="lv-demo-event-content">
17577- <div class="lv-demo-event-header">
17578- <span class="lv-demo-event-title">{e.title}</span>
17579- <span class="lv-demo-event-time">{e.time}</span>
17580- </div>
17581- <div class="lv-demo-event-body">{e.body}</div>
17582- </div>
17583- </div>
17584- ))}
17585- </div>
17586- </div>
17587- </div>
17588-
17589- {/* Activity ticker */}
17590- <div class="lv-ticker-wrap">
17591- <div class="lv-ticker-track">
17592- {tickerItems.map((t, i) => (
17593- <span class="lv-ticker-item" key={i}>
17594- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
17595- {t.text}
17596- </span>
17597- ))}
17598- </div>
17599- </div>
17600- </section>
17601-
17602- {/* Stat band */}
17603- <section class="lv-stats">
17604- <div class="lv-stats-inner">
17605- <div class="lv-stat">
17606- <div class="lv-stat-num">Sonnet 5</div>
17607- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
17608- </div>
17609- <div class="lv-stat">
17610- <div class="lv-stat-num">93.5%</div>
17611- <div class="lv-stat-label">of failures self-repair without a human</div>
17612- </div>
17613- <div class="lv-stat">
17614- <div class="lv-stat-num">1.9%</div>
17615- <div class="lv-stat-label">AI merges reverted  published live</div>
17616- </div>
17617- <div class="lv-stat">
17618- <div class="lv-stat-num">0</div>
17619- <div class="lv-stat-label">irreversible actions taken autonomously</div>
17620- </div>
17621- </div>
17622- </section>
17623-
17624- {/* The loop */}
17625- <section id="loop" class="lv-loop">
17626- <div class="lv-loop-inner">
17627- <div class="lv-section-header">
17628- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
17629- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
17630- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
17631- </div>
17632- <div class="lv-stages" id="lv-stages">
17633- {stageData.map((s, i) => (
17634- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
17635- <div class="lv-stage-header">
17636- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
17637- <span class="lv-stage-n">0{i + 1}</span>
17638- </div>
17639- <div class="lv-stage-name">{s.name}</div>
17640- <div class="lv-stage-desc">{s.desc}</div>
17641- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
17642- </div>
17643- ))}
17644- </div>
17645- </div>
17646- </section>
17647-
17648- {/* Three heroes */}
17649- <section class="lv-heroes">
17650- <div class="lv-heroes-inner">
17651- <div class="lv-heroes-header">
17652- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
17653- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
17654- </div>
17655- <div class="lv-heroes-list">
17656- {heroFeatures.map((h, i) => (
17657- <a href={h.href} class="lv-hero-card" key={i}>
17658- <div class="lv-hero-card-left">
17659- <div class="lv-eyebrow">{h.eyebrow}</div>
17660- <h3 class="lv-hero-card-title">{h.title}</h3>
17661- <p class="lv-hero-card-body">{h.body}</p>
17662- <span class="lv-hero-card-cta">{h.cta} �!</span>
17663- </div>
17664- <div class="lv-terminal">
17665- {h.mock.map((m, j) => (
17666- <div class="lv-terminal-line" key={j}>
17667- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
17668- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
17669- </div>
17670- ))}
17671- </div>
17672- </a>
17673- ))}
17674- </div>
17675- </div>
17676- </section>
17677-
17678- {/* Everything grid */}
17679- <section id="platform" class="lv-platform">
17680- <div class="lv-platform-inner">
17681- <div class="lv-section-header lv-section-header-center">
17682- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
17683- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
17684- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
17685- </div>
17686- <div class="lv-cap-grid">
17687- {capabilities.map((c, i) => (
17688- <div class="lv-cap-col" key={i}>
17689- <div class="lv-cap-group">{c.group}</div>
17690- <div class="lv-cap-items">
17691- {c.items.map((item, j) => (
17692- <div class="lv-cap-item" key={j}>{item}</div>
17693- ))}
17694- </div>
17695- </div>
17696- ))}
17697- </div>
17698- </div>
17699- </section>
17700-
17701- {/* Sovereignty band */}
17702- <section id="sovereign" class="lv-sovereign">
17703- <div class="lv-sovereign-grid-bg"></div>
17704- <div class="lv-sovereign-inner">
17705- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
17706- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
17707- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
17708- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
17709to private cloud, or run fully air-gapped on bare metal.</p>
17710- </div>
17711- <div class="lv-layers-grid">
17712- {sovereignLayerNames.map((name, i) => (
17713- <div class="lv-layer-chip" key={i}>
17714- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
17715- <div class="lv-layer-name">{name}</div>
17716- </div>
17717- ))}
17718- <a href="/" class="lv-layer-chip lv-layer-cta">
17719- <div class="lv-layer-cta-text">All self-owned �!</div>
17720- </a>
17721- </div>
17722- <div class="lv-sovereign-feats">
17723- <div class="lv-sovereign-feat">
17724- <div class="lv-sovereign-feat-title">Local inference first</div>
17725- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
17726- </div>
17727- <div class="lv-sovereign-feat">
17728- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
17729- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
17730- </div>
17731- <div class="lv-sovereign-feat">
17732- <div class="lv-sovereign-feat-title">Self-healing infra</div>
17733- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
17734- </div>
17735- </div>
17736- </div>
17737- </section>
17738-
17739- {/* Manual-first + reversibility */}
17740- <section class="lv-twin">
17741- <div class="lv-twin-inner">
17742- <div class="lv-twin-card">
17743- <div class="lv-eyebrow">Manual-first, always</div>
17744- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
17745- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
17746fallback. Developers who never touch AI get the best git host they've ever used.</p>
17747- </div>
17748- <div class="lv-twin-card">
17749- <div class="lv-eyebrow">The reversibility guarantee</div>
17750- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
17751- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
17752 policy, not promise. Our quality numbers are published live, unedited.</p>
17753- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
17754- </div>
17755- </div>
17756- </section>
17757-
17758- {/* Quote */}
17759- <section class="lv-quote">
17760- <div class="lv-quote-inner">
17761- <p class="lv-quote-text">
17762- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
17763- Gluecron is where code gets <em class="lv-em">finished</em>."
17764- </p>
17765- </div>
17766- </section>
17767-
17768- {/* CTA */}
17769- <section class="lv-cta-section">
17770- <div class="lv-cta-card">
17771- <div class="lv-cta-glow"></div>
17772- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
17773- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
17774- <div class="lv-cta-actions">
17775- <a href="/register" class="lv-cta-primary">Create your account �!</a>
17776- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
17777- </div>
17778- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
17779- </div>
17780- </section>
17781-
17782- {/* Footer */}
17783- <footer class="lv-footer">
17784- <div class="lv-footer-inner">
17785- <div class="lv-footer-brand">
17786- <a href="/" class="lv-logo">
17787- <span class="lv-logo-mark"></span>gluecron
17788- </a>
17789- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
17790- </div>
17791- <div class="lv-footer-cols">
17792- <div class="lv-footer-col">
17793- <h4 class="lv-footer-col-head">Product</h4>
17794- <a href="/" class="lv-footer-link">Agent workspace</a>
17795- <a href="/" class="lv-footer-link">Fleet refactors</a>
17796- <a href="/" class="lv-footer-link">Org memory</a>
17797- <a href="/" class="lv-footer-link">IDE extensions</a>
17798- </div>
17799- <div class="lv-footer-col">
17800- <h4 class="lv-footer-col-head">Platform</h4>
17801- <a href="/" class="lv-footer-link">Production layers</a>
17802- <a href="/trust" class="lv-footer-link">Trust report</a>
17803- <a href="/" class="lv-footer-link">Docs</a>
17804- <a href="/" class="lv-footer-link">Status</a>
17805- </div>
17806- <div class="lv-footer-col">
17807- <h4 class="lv-footer-col-head">Company</h4>
17808- <a href="/" class="lv-footer-link">About</a>
17809- <a href="/" class="lv-footer-link">Pricing</a>
17810- <a href="/" class="lv-footer-link">Enterprise</a>
17811- </div>
17812- </div>
17813- </div>
17814- <div class="lv-footer-bar">
17815- <span>� 2026 Gluecron</span>
17816- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
17817- </div>
17818- </footer>
17819-
17820- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
17821- </>
17822- );
17823-};
17824-
17825-export const LandingPage = LandingPageV2;
17826-export default LandingPageV2;
17827-
17828-const clientScript = `
17829-(function() {
17830- var demoAll = [
17831- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
17832- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
17833- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
17834- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
17835- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
17836- ];
17837-
17838- var demoStep = 0;
17839- var stage = 0;
17840-
17841- function renderDemo() {
17842- var container = document.getElementById('lv-demo-body');
17843- if (!container) return;
17844- var visible = demoAll.slice(0, demoStep + 1);
17845- container.innerHTML = visible.map(function(e, i) {
17846- var isLast = i === visible.length - 1;
17847- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
17848- return '<div class="lv-demo-event">' +
17849- '<div class="lv-demo-event-track">' +
17850- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
17851- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
17852- '</div>' +
17853- '<div class="lv-demo-event-content">' +
17854- '<div class="lv-demo-event-header">' +
17855- '<span class="lv-demo-event-title">' + e.title + '</span>' +
17856- '<span class="lv-demo-event-time">' + e.time + '</span>' +
17857- '</div>' +
17858- '<div class="lv-demo-event-body">' + e.body + '</div>' +
17859- '</div>' +
17860- '</div>';
17861- }).join('');
17862- }
17863-
17864- function renderStages() {
17865- var cards = document.querySelectorAll('.lv-stage-card');
17866- cards.forEach(function(card, i) {
17867- var dot = card.querySelector('.lv-dot');
17868- var meta = card.querySelector('.lv-stage-meta');
17869- if (i === stage) {
17870- card.classList.add('lv-stage-active');
17871- if (dot) {
17872- dot.classList.remove('lv-dot-idle');
17873- dot.classList.add('lv-dot-indigo', 'lv-pulse');
17874- }
17875- if (meta) meta.classList.add('lv-stage-meta-active');
17876- } else {
17877- card.classList.remove('lv-stage-active');
17878- if (dot) {
17879- dot.classList.add('lv-dot-idle');
17880- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
17881- }
17882- if (meta) meta.classList.remove('lv-stage-meta-active');
17883- }
17884- });
17885- }
17886-
17887- renderDemo();
17888-
17889- setInterval(function() {
17890- demoStep = (demoStep + 1) % 5;
17891- renderDemo();
17892- }, 3600);
17893-
17894- setInterval(function() {
17895- stage = (stage + 1) % 6;
17896- renderStages();
17897- }, 2200);
17898-})();
17899-`;
17900-
17901-const css = `
17902-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
17903-
17904-*, *::before, *::after { box-sizing: border-box; }
17905-
17906-body {
17907- margin: 0;
17908- background: #fcfcfd;
17909- -webkit-font-smoothing: antialiased;
17910- text-rendering: optimizeLegibility;
17911- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
17912- font-size: 15px;
17913- line-height: 1.6;
17914- letter-spacing: -0.008em;
17915- color: #16181d;
17916-}
17917-
17918-@keyframes gcPulse {
17919- 0%, 100% { opacity: 1; }
17920- 50% { opacity: 0.35; }
17921-}
17922-
17923-@keyframes gcTicker {
17924- 0% { transform: translateX(0); }
17925- 100% { transform: translateX(-50%); }
17926-}
17927-
17928-/* Shared utilities */
17929-.lv-dot {
17930- display: inline-block;
17931- border-radius: 50%;
17932-}
17933-.lv-dot-green { background: #1e7f5c; }
17934-.lv-dot-indigo { background: #4353c9; }
17935-.lv-dot-idle { background: #c4c6cf; }
17936-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
17937-
17938-.lv-strong { color: #16181d; font-weight: 600; }
17939-
17940-.lv-eyebrow {
17941- font-family: 'JetBrains Mono', monospace;
17942- font-size: 11px;
17943- letter-spacing: 0.12em;
17944- text-transform: uppercase;
17945- color: #8a8d99;
17946- font-weight: 500;
17947- margin-bottom: 12px;
17948-}
17949-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
17950-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
17951-
17952-.lv-h1 {
17953- font-family: 'Inter Tight', sans-serif;
17954- font-weight: 700;
17955- letter-spacing: -0.035em;
17956- font-size: clamp(44px, 7vw, 84px);
17957- line-height: 0.98;
17958- margin: 30px auto 0;
17959- max-width: 14ch;
17960- color: #111318;
17961-}
17962-
17963-.lv-h2 {
17964- font-family: 'Inter Tight', sans-serif;
17965- font-weight: 700;
17966- letter-spacing: -0.028em;
17967- font-size: clamp(30px, 4.4vw, 48px);
17968- line-height: 1.05;
17969- margin: 0;
17970- color: #111318;
17971-}
17972-
17973-.lv-h2-dark {
17974- font-family: 'Inter Tight', sans-serif;
17975- font-weight: 700;
17976- letter-spacing: -0.028em;
17977- font-size: clamp(30px, 4.6vw, 52px);
17978- line-height: 1.05;
17979- margin: 0;
17980- color: #fff;
17981-}
17982-
17983-.lv-section-header {
17984- max-width: 640px;
17985- margin: 0 auto 56px;
17986-}
17987-
17988-.lv-section-header-center {
17989- text-align: center;
17990-}
17991-
17992-.lv-section-sub {
17993- color: #6b7080;
17994- font-size: 17px;
17995- margin: 18px auto 0;
17996- max-width: 52ch;
17997-}
17998-
17999-.lv-section-sub-dark {
18000- color: rgba(255,255,255,0.72);
18001- font-size: 17px;
18002- margin: 18px auto 0;
18003- max-width: 56ch;
18004-}
18005-
18006-/* Nav */
18007-.lv-nav {
18008- position: sticky;
18009- top: 0;
18010- z-index: 60;
18011- backdrop-filter: saturate(180%) blur(14px);
18012- -webkit-backdrop-filter: saturate(180%) blur(14px);
18013- background: rgba(252,252,253,0.8);
18014- border-bottom: 1px solid rgba(22,24,29,0.07);
18015-}
18016-
18017-.lv-nav-inner {
18018- max-width: 1200px;
18019- margin: 0 auto;
18020- padding: 14px 28px;
18021- display: flex;
18022- align-items: center;
18023- gap: 28px;
18024-}
18025-
18026-.lv-logo {
18027- display: inline-flex;
18028- align-items: center;
18029- gap: 9px;
18030- font-family: 'Inter Tight', sans-serif;
18031- font-weight: 700;
18032- font-size: 17px;
18033- letter-spacing: -0.02em;
18034- color: #16181d;
18035- text-decoration: none;
18036-}
18037-
18038-.lv-logo-mark {
18039- width: 17px;
18040- height: 17px;
18041- border-radius: 5px;
18042- background: #4353c9;
18043- display: inline-block;
18044- flex-shrink: 0;
18045-}
18046-
18047-.lv-nav-links {
18048- display: flex;
18049- gap: 24px;
18050- font-size: 13.5px;
18051- font-weight: 500;
18052-}
18053-
18054-.lv-nav-link {
18055- color: #6b7080;
18056- text-decoration: none;
18057- transition: color 0.15s;
18058-}
18059-.lv-nav-link:hover { color: #16181d; }
18060-
18061-.lv-nav-ctas {
18062- margin-left: auto;
18063- display: flex;
18064- align-items: center;
18065- gap: 10px;
18066-}
18067-
18068-.lv-btn-secondary {
18069- padding: 8px 15px;
18070- border-radius: 8px;
18071- font-size: 13.5px;
18072- font-weight: 500;
18073- color: #16181d;
18074- border: 1px solid rgba(22,24,29,0.12);
18075- background: #ffffff;
18076- text-decoration: none;
18077- white-space: nowrap;
18078- transition: border-color 0.15s;
18079-}
18080-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
18081-
18082-.lv-btn-primary {
18083- padding: 8px 15px;
18084- border-radius: 8px;
18085- font-size: 13.5px;
18086- font-weight: 600;
18087- background: #16181d;
18088- color: #fff;
18089- text-decoration: none;
18090- white-space: nowrap;
18091- transition: box-shadow 0.15s;
18092-}
18093-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
18094-
18095-/* Hero */
18096-.lv-hero {
18097- position: relative;
18098- overflow: hidden;
18099- padding: 88px 0 0;
18100-}
18101-
18102-.lv-hero-glow {
18103- position: absolute;
18104- inset: -10% 0 auto 0;
18105- height: 640px;
18106- pointer-events: none;
18107- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
18108-}
18109-
18110-.lv-hero-inner {
18111- position: relative;
18112- max-width: 1200px;
18113- margin: 0 auto;
18114- padding: 0 28px;
18115- text-align: center;
18116-}
18117-
18118-.lv-hero-badge {
18119- display: inline-flex;
18120- align-items: center;
18121- gap: 9px;
18122- font-size: 12.5px;
18123- font-weight: 600;
18124- color: #3a3d45;
18125- background: #ffffff;
18126- border: 1px solid rgba(22,24,29,0.10);
18127- border-radius: 9999px;
18128- padding: 7px 16px;
18129- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
18130-}
18131-
18132-.lv-hero-sub {
18133- font-size: clamp(16px, 2vw, 19px);
18134- color: #6b7080;
18135- max-width: 60ch;
18136- margin: 24px auto 0;
18137- font-weight: 450;
18138- line-height: 1.65;
18139-}
18140-
18141-.lv-hero-actions {
18142- display: flex;
18143- gap: 12px;
18144- justify-content: center;
18145- flex-wrap: wrap;
18146- margin-top: 32px;
18147-}
18148-
18149-.lv-cta-primary {
18150- padding: 13px 24px;
18151- border-radius: 11px;
18152- font-size: 15.5px;
18153- font-weight: 600;
18154- background: #16181d;
18155- color: #fff;
18156- text-decoration: none;
18157- white-space: nowrap;
18158- transition: box-shadow 0.15s;
18159-}
18160-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
18161-
18162-.lv-cta-secondary {
18163- padding: 13px 24px;
18164- border-radius: 11px;
18165- font-size: 15.5px;
18166- font-weight: 600;
18167- color: #16181d;
18168- border: 1px solid rgba(22,24,29,0.14);
18169- background: #ffffff;
18170- text-decoration: none;
18171- white-space: nowrap;
18172- transition: border-color 0.15s;
18173-}
18174-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
18175-
18176-.lv-hero-tag {
18177- margin-top: 18px;
18178- font-family: 'JetBrains Mono', monospace;
18179- font-size: 11.5px;
18180- letter-spacing: 0.08em;
18181- text-transform: uppercase;
18182- color: #8a8d99;
18183-}
18184-
18185-/* Demo window */
18186-.lv-demo-window {
18187- margin: 56px auto 0;
18188- max-width: 860px;
18189- text-align: left;
18190- background: #ffffff;
18191- border: 1px solid rgba(22,24,29,0.09);
18192- border-radius: 18px;
18193- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
18194- overflow: hidden;
18195-}
18196-
18197-.lv-demo-bar {
18198- display: flex;
18199- align-items: center;
18200- gap: 7px;
18201- padding: 12px 18px;
18202- border-bottom: 1px solid rgba(22,24,29,0.07);
18203- background: #fcfcfd;
18204-}
18205-
18206-.lv-demo-dot {
18207- width: 10px;
18208- height: 10px;
18209- border-radius: 50%;
18210- background: #e4e5ea;
18211-}
18212-
18213-.lv-demo-url {
18214- margin-left: 10px;
18215- font-family: 'JetBrains Mono', monospace;
18216- font-size: 12px;
18217- color: #6b7080;
18218-}
18219-
18220-.lv-demo-live {
18221- margin-left: auto;
18222- display: inline-flex;
18223- align-items: center;
18224- gap: 6px;
18225- font-size: 11px;
18226- font-weight: 600;
18227- color: #1e7f5c;
18228-}
18229-
18230-.lv-demo-body {
18231- padding: 22px 24px;
18232-}
18233-
18234-.lv-demo-event {
18235- display: grid;
18236- grid-template-columns: 18px minmax(0, 1fr);
18237- gap: 14px;
18238- padding-bottom: 20px;
18239- position: relative;
18240-}
18241-.lv-demo-event:last-child { padding-bottom: 0; }
18242-
18243-.lv-demo-event-track {
18244- display: flex;
18245- flex-direction: column;
18246- align-items: center;
18247-}
18248-
18249-.lv-demo-line {
18250- width: 1px;
18251- flex: 1;
18252- background: rgba(22,24,29,0.08);
18253- margin-top: 5px;
18254- min-height: 20px;
18255-}
18256-
18257-.lv-demo-event-content {}
18258-
18259-.lv-demo-event-header {
18260- display: flex;
18261- align-items: baseline;
18262- gap: 10px;
18263-}
18264-
18265-.lv-demo-event-title {
18266- font-size: 13.5px;
18267- font-weight: 600;
18268- color: #16181d;
18269-}
18270-
18271-.lv-demo-event-time {
18272- font-family: 'JetBrains Mono', monospace;
18273- font-size: 11px;
18274- color: #8a8d99;
18275-}
18276-
18277-.lv-demo-event-body {
18278- font-size: 13px;
18279- color: #6b7080;
18280- margin-top: 2px;
18281-}
18282-
18283-/* Ticker */
18284-.lv-ticker-wrap {
18285- border-top: 1px solid rgba(22,24,29,0.07);
18286- border-bottom: 1px solid rgba(22,24,29,0.07);
18287- background: #ffffff;
18288- margin-top: 64px;
18289- overflow: hidden;
18290- white-space: nowrap;
18291- position: relative;
18292-}
18293-
18294-.lv-ticker-track {
18295- display: inline-flex;
18296- animation: gcTicker 40s linear infinite;
18297- padding: 11px 0;
18298-}
18299-
18300-.lv-ticker-item {
18301- display: inline-flex;
18302- align-items: center;
18303- gap: 8px;
18304- font-family: 'JetBrains Mono', monospace;
18305- font-size: 11.5px;
18306- color: #6b7080;
18307- padding: 0 28px;
18308- border-right: 1px solid rgba(22,24,29,0.06);
18309-}
18310-
18311-/* Stats */
18312-.lv-stats {
18313- background: #fcfcfd;
18314-}
18315-
18316-.lv-stats-inner {
18317- max-width: 1200px;
18318- margin: 0 auto;
18319- display: grid;
18320- grid-template-columns: repeat(4, 1fr);
18321- gap: 24px;
18322- padding: 52px 28px;
18323-}
18324-
18325-.lv-stat {
18326- text-align: center;
18327-}
18328-
18329-.lv-stat-num {
18330- font-family: 'Inter Tight', sans-serif;
18331- font-weight: 700;
18332- font-size: clamp(30px, 4vw, 44px);
18333- letter-spacing: -0.025em;
18334- color: #111318;
18335-}
18336-
18337-.lv-stat-label {
18338- font-size: 13px;
18339- color: #6b7080;
18340- margin-top: 4px;
18341-}
18342-
18343-/* Loop */
18344-.lv-loop {
18345- padding: 96px 0;
18346- background: #ffffff;
18347- border-top: 1px solid rgba(22,24,29,0.07);
18348- border-bottom: 1px solid rgba(22,24,29,0.07);
18349-}
18350-
18351-.lv-loop-inner {
18352- max-width: 1200px;
18353- margin: 0 auto;
18354- padding: 0 28px;
18355-}
18356-
18357-.lv-stages {
18358- display: grid;
18359- grid-template-columns: repeat(6, 1fr);
18360- gap: 12px;
18361-}
18362-
18363-.lv-stage-card {
18364- border: 1px solid rgba(22,24,29,0.08);
18365- border-radius: 14px;
18366- background: #ffffff;
18367- padding: 20px 18px;
18368- transition: border-color 0.3s, background 0.3s;
18369-}
18370-
18371-.lv-stage-card.lv-stage-active {
18372- border-color: rgba(67,83,201,0.45);
18373- background: rgba(67,83,201,0.03);
18374-}
18375-
18376-.lv-stage-header {
18377- display: flex;
18378- align-items: center;
18379- gap: 8px;
18380- margin-bottom: 10px;
18381-}
18382-
18383-.lv-stage-n {
18384- font-family: 'JetBrains Mono', monospace;
18385- font-size: 10.5px;
18386- letter-spacing: 0.1em;
18387- text-transform: uppercase;
18388- color: #8a8d99;
18389-}
18390-
18391-.lv-stage-name {
18392- font-family: 'Inter Tight', sans-serif;
18393- font-size: 16px;
18394- font-weight: 600;
18395- letter-spacing: -0.01em;
18396- color: #16181d;
18397- margin-bottom: 5px;
18398-}
18399-
18400-.lv-stage-desc {
18401- font-size: 12px;
18402- color: #6b7080;
18403- line-height: 1.55;
18404-}
18405-
18406-.lv-stage-meta {
18407- font-family: 'JetBrains Mono', monospace;
18408- font-size: 10.5px;
18409- color: #8a8d99;
18410- margin-top: 10px;
18411- transition: color 0.3s;
18412-}
18413-
18414-.lv-stage-meta.lv-stage-meta-active {
18415- color: #4353c9;
18416-}
18417-
18418-/* Heroes */
18419-.lv-heroes {
18420- padding: 96px 0;
18421- background: #fcfcfd;
18422-}
18423-
18424-.lv-heroes-inner {
18425- max-width: 1200px;
18426- margin: 0 auto;
18427- padding: 0 28px;
18428-}
18429-
18430-.lv-heroes-header {
18431- max-width: 640px;
18432- margin-bottom: 56px;
18433-}
18434-
18435-.lv-heroes-list {
18436- display: flex;
18437- flex-direction: column;
18438- gap: 20px;
18439-}
18440-
18441-.lv-hero-card {
18442- display: grid;
18443- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
18444- gap: 48px;
18445- align-items: center;
18446- border: 1px solid rgba(22,24,29,0.08);
18447- border-radius: 20px;
18448- background: #ffffff;
18449- padding: 44px 48px;
18450- text-decoration: none;
18451- transition: border-color 0.2s, box-shadow 0.2s;
18452-}
18453-.lv-hero-card:hover {
18454- border-color: rgba(22,24,29,0.22);
18455- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
18456-}
18457-
18458-.lv-hero-card-left {}
18459-
18460-.lv-hero-card-title {
18461- font-family: 'Inter Tight', sans-serif;
18462- font-size: 26px;
18463- font-weight: 600;
18464- letter-spacing: -0.022em;
18465- line-height: 1.15;
18466- color: #16181d;
18467- margin: 0 0 12px;
18468-}
18469-
18470-.lv-hero-card-body {
18471- font-size: 14.5px;
18472- color: #6b7080;
18473- margin: 0 0 18px;
18474- line-height: 1.65;
18475-}
18476-
18477-.lv-hero-card-cta {
18478- font-size: 13.5px;
18479- font-weight: 600;
18480- color: #4353c9;
18481-}
18482-
18483-.lv-terminal {
18484- border: 1px solid rgba(22,24,29,0.07);
18485- border-radius: 14px;
18486- background: #fcfcfd;
18487- padding: 20px 22px;
18488- font-family: 'JetBrains Mono', monospace;
18489- font-size: 12px;
18490- line-height: 1.9;
18491- overflow: hidden;
18492-}
18493-
18494-.lv-terminal-line {
18495- display: flex;
18496- align-items: center;
18497- gap: 10px;
18498- white-space: nowrap;
18499- overflow: hidden;
18500- text-overflow: ellipsis;
18501-}
18502-
18503-/* Platform */
18504-.lv-platform {
18505- padding: 96px 0;
18506- background: #ffffff;
18507- border-top: 1px solid rgba(22,24,29,0.07);
18508-}
18509-
18510-.lv-platform-inner {
18511- max-width: 1200px;
18512- margin: 0 auto;
18513- padding: 0 28px;
18514-}
18515-
18516-.lv-cap-grid {
18517- display: grid;
18518- grid-template-columns: repeat(4, 1fr);
18519- gap: 24px 32px;
18520-}
18521-
18522-.lv-cap-col {}
18523-
18524-.lv-cap-group {
18525- font-family: 'JetBrains Mono', monospace;
18526- font-size: 10.5px;
18527- letter-spacing: 0.12em;
18528- text-transform: uppercase;
18529- color: #8a8d99;
18530- font-weight: 500;
18531- margin-bottom: 12px;
18532- padding-bottom: 8px;
18533- border-bottom: 1px solid rgba(22,24,29,0.07);
18534-}
18535-
18536-.lv-cap-items {
18537- display: flex;
18538- flex-direction: column;
18539- gap: 7px;
18540-}
18541-
18542-.lv-cap-item {
18543- font-size: 12.5px;
18544- color: #3a3d45;
18545- line-height: 1.45;
18546-}
18547-
18548-/* Sovereignty */
18549-.lv-sovereign {
18550- position: relative;
18551- overflow: hidden;
18552- padding: 104px 0;
18553- color: #fff;
18554- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
18555-}
18556-
18557-.lv-sovereign-grid-bg {
18558- position: absolute;
18559- inset: 0;
18560- opacity: 0.4;
18561- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
18562- background-size: 56px 56px;
18563- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
18564- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
18565-}
18566-
18567-.lv-sovereign-inner {
18568- position: relative;
18569- max-width: 1200px;
18570- margin: 0 auto;
18571- padding: 0 28px;
18572-}
18573-
18574-.lv-section-header-dark {
18575- max-width: 680px;
18576- margin: 0 auto 48px;
18577- text-align: center;
18578-}
18579-
18580-.lv-layers-grid {
18581- display: grid;
18582- grid-template-columns: repeat(4, 1fr);
18583- gap: 10px;
18584- max-width: 980px;
18585- margin: 0 auto;
18586-}
18587-
18588-.lv-layer-chip {
18589- border: 1px solid rgba(255,255,255,0.10);
18590- border-radius: 10px;
18591- padding: 12px 16px;
18592- background: rgba(255,255,255,0.03);
18593-}
18594-
18595-.lv-layer-cta {
18596- border-color: rgba(169,180,238,0.30);
18597- background: rgba(169,180,238,0.06);
18598- display: flex;
18599- align-items: center;
18600- text-decoration: none;
18601- transition: background 0.15s;
18602-}
18603-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
18604-
18605-.lv-layer-cta-text {
18606- font-size: 13px;
18607- font-weight: 500;
18608- color: #a9b4ee;
18609-}
18610-
18611-.lv-layer-n {
18612- font-family: 'JetBrains Mono', monospace;
18613- font-size: 10px;
18614- color: rgba(255,255,255,0.4);
18615- margin-bottom: 3px;
18616-}
18617-
18618-.lv-layer-name {
18619- font-size: 13px;
18620- font-weight: 500;
18621- color: rgba(255,255,255,0.92);
18622-}
18623-
18624-.lv-sovereign-feats {
18625- display: flex;
18626- gap: 44px;
18627- justify-content: center;
18628- flex-wrap: wrap;
18629- margin-top: 52px;
18630- text-align: center;
18631-}
18632-
18633-.lv-sovereign-feat {}
18634-
18635-.lv-sovereign-feat-title {
18636- font-family: 'Inter Tight', sans-serif;
18637- font-size: 20px;
18638- font-weight: 700;
18639- color: #fff;
18640-}
18641-
18642-.lv-sovereign-feat-sub {
18643- color: rgba(255,255,255,0.55);
18644- font-size: 13px;
18645- margin-top: 2px;
18646-}
18647-
18648-/* Twin cards */
18649-.lv-twin {
18650- padding: 96px 0;
18651- background: #fcfcfd;
18652-}
18653-
18654-.lv-twin-inner {
18655- max-width: 1200px;
18656- margin: 0 auto;
18657- padding: 0 28px;
18658- display: grid;
18659- grid-template-columns: 1fr 1fr;
18660- gap: 24px;
18661-}
18662-
18663-.lv-twin-card {
18664- border: 1px solid rgba(22,24,29,0.08);
18665- border-radius: 20px;
18666- background: #ffffff;
18667- padding: 44px 48px;
18668-}
18669-
18670-.lv-twin-title {
18671- font-family: 'Inter Tight', sans-serif;
18672- font-size: 24px;
18673- font-weight: 600;
18674- letter-spacing: -0.02em;
18675- line-height: 1.2;
18676- margin: 0 0 12px;
18677- color: #16181d;
18678-}
18679-
18680-.lv-twin-body {
18681- font-size: 14.5px;
18682- color: #6b7080;
18683- margin: 0 0 16px;
18684- line-height: 1.7;
18685-}
18686-
18687-.lv-twin-link {
18688- font-size: 13.5px;
18689- font-weight: 600;
18690- color: #4353c9;
18691- text-decoration: none;
18692-}
18693-.lv-twin-link:hover { text-decoration: underline; }
18694-
18695-/* Quote */
18696-.lv-quote {
18697- padding: 40px 0 96px;
18698- background: #fcfcfd;
18699-}
18700-
18701-.lv-quote-inner {
18702- max-width: 980px;
18703- margin: 0 auto;
18704- padding: 0 28px;
18705- text-align: center;
18706-}
18707-
18708-.lv-quote-text {
18709- font-family: 'Inter Tight', sans-serif;
18710- font-weight: 600;
18711- font-size: clamp(26px, 3.8vw, 42px);
18712- line-height: 1.2;
18713- letter-spacing: -0.025em;
18714- margin: 0;
18715- color: #111318;
18716-}
18717-
18718-.lv-em {
18719- font-style: normal;
18720- color: #4353c9;
18721-}
18722-
18723-/* CTA */
18724-.lv-cta-section {
18725- padding: 0 0 104px;
18726- background: #fcfcfd;
18727-}
18728-
18729-.lv-cta-card {
18730- max-width: 820px;
18731- margin: 0 auto;
18732- padding: 64px 40px;
18733- text-align: center;
18734- background: #ffffff;
18735- border: 1px solid rgba(22,24,29,0.08);
18736- border-radius: 26px;
18737- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
18738- position: relative;
18739- overflow: hidden;
18740-}
18741-
18742-.lv-cta-glow {
18743- position: absolute;
18744- inset: -40% 0 auto 0;
18745- height: 280px;
18746- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
18747- pointer-events: none;
18748-}
18749-
18750-.lv-cta-h2 {
18751- font-family: 'Inter Tight', sans-serif;
18752- font-weight: 700;
18753- letter-spacing: -0.028em;
18754- font-size: clamp(30px, 4.6vw, 48px);
18755- margin: 0;
18756- position: relative;
18757- color: #111318;
18758-}
18759-
18760-.lv-cta-sub {
18761- color: #6b7080;
18762- font-size: 17px;
18763- margin: 16px 0 30px;
18764- position: relative;
18765-}
18766-
18767-.lv-cta-actions {
18768- display: flex;
18769- gap: 12px;
18770- justify-content: center;
18771- flex-wrap: wrap;
18772- position: relative;
18773-}
18774-
18775-.lv-cta-fine {
18776- margin-top: 20px;
18777- font-family: 'JetBrains Mono', monospace;
18778- font-size: 11px;
18779- color: #8a8d99;
18780- position: relative;
18781-}
18782-
18783-/* Footer */
18784-.lv-footer {
18785- border-top: 1px solid rgba(22,24,29,0.07);
18786- background: #ffffff;
18787- padding: 56px 0 30px;
18788-}
18789-
18790-.lv-footer-inner {
18791- max-width: 1200px;
18792- margin: 0 auto;
18793- padding: 0 28px;
18794- display: flex;
18795- gap: 48px;
18796- flex-wrap: wrap;
18797- justify-content: space-between;
18798-}
18799-
18800-.lv-footer-brand {}
18801-
18802-.lv-footer-tagline {
18803- color: #6b7080;
18804- font-size: 13.5px;
18805- margin: 12px 0 0;
18806- max-width: 32ch;
18807- line-height: 1.6;
18808-}
18809-
18810-.lv-footer-cols {
18811- display: flex;
18812- gap: 64px;
18813- flex-wrap: wrap;
18814-}
18815-
18816-.lv-footer-col {
18817- display: flex;
18818- flex-direction: column;
18819- gap: 9px;
18820-}
18821-
18822-.lv-footer-col-head {
18823- font-family: 'JetBrains Mono', monospace;
18824- font-size: 11px;
18825- text-transform: uppercase;
18826- letter-spacing: 0.1em;
18827- color: #8a8d99;
18828- margin: 0 0 4px;
18829- font-weight: 500;
18830-}
18831-
18832-.lv-footer-link {
18833- color: #3a3d45;
18834- font-size: 13.5px;
18835- text-decoration: none;
18836- transition: color 0.15s;
18837-}
18838-.lv-footer-link:hover { color: #16181d; }
18839-
18840-.lv-footer-bar {
18841- max-width: 1200px;
18842- margin: 44px auto 0;
18843- padding: 22px 28px 0;
18844- border-top: 1px solid rgba(22,24,29,0.06);
18845- display: flex;
18846- justify-content: space-between;
18847- flex-wrap: wrap;
18848- gap: 8px;
18849- color: #8a8d99;
18850- font-size: 12.5px;
18851-}
18852-
18853-.lv-footer-stack {
18854- font-family: 'JetBrains Mono', monospace;
18855- font-size: 11px;
18856-}
18857-`;
18858diff --git a/src/views/layout.tsx b/src/views/layout.tsx
18859index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
18860--- a/src/views/layout.tsx
18861+++ b/src/views/layout.tsx
18862@@ -3153,9 +3153,12 @@
18863 font-weight: 500;
18864 line-height: 1.4;
18865 }
18866- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
18867- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
18868- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
18869+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
18870+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
18871+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
18872+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
18873+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
18874+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
18875 .state-merged { color: var(--accent); }
18876 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
18877
18878diff --git a/src/views/ui.tsx b/src/views/ui.tsx
18879index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
18880--- a/src/views/ui.tsx
18881+++ b/src/views/ui.tsx
18882@@ -232,7 +232,7 @@
18883
18884 export const Badge: FC<
18885 PropsWithChildren<{
18886- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
18887+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
18888 style?: string;
18889 }>
18890 > = ({ children, variant = "default", style }) => {
18891@@ -241,9 +241,12 @@
18892 variant === "closed" ? "badge-closed" :
18893 variant === "merged" ? "badge-merged" :
18894 variant === "success" ? "badge-success" :
18895- variant === "danger" ? "badge-danger" :
18896- variant === "warning" ? "badge-warning" :
18897- "badge";
18898+ variant === "danger" ? "badge-danger" :
18899+ variant === "warning" ? "badge-warning" :
18900+ variant === "live" ? "badge-live" :
18901+ variant === "soon" ? "badge-soon" :
18902+ variant === "preview" ? "badge-preview" :
18903+ "badge";
18904 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
18905 };
18906
18907
18908diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
18909index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
18910--- a/src/views/landing-pro.tsx
18911+++ b/src/views/landing-pro.tsx
18912@@ -42,7 +42,7 @@
18913
18914 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18915
18916-function icon(paths: string, color = "#4353c9", size = 20) {
18917+function icon(paths: string, color = "#0891b2", size = 20) {
18918 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
18919 }
18920
18921@@ -947,7 +947,7 @@
18922 const css = `
18923 /* %% tokens %% */
18924 :root{
18925- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
18926+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
18927 --lp-bg:#ffffff;--lp-soft:#fafafb;
18928 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
18929 --lp-border:rgba(0,0,0,.08);
18930diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
18931deleted file mode 100644
18932index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
18933--- a/src/views/landing-v2.tsx
18934+++ /dev/null
18935@@ -1,1447 +0,0 @@
18936-import type { FC } from "hono/jsx";
18937-
18938-export interface LandingPageProps {
18939- stats?: {
18940- publicRepos?: number;
18941- users?: number;
18942- };
18943-}
18944-
18945-const demoAllEvents = [
18946- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
18947- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
18948- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
18949- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
18950- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
18951-];
18952-
18953-const tickerItems = [
18954- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
18955- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
18956- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
18957- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
18958- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
18959- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
18960- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
18961- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
18962- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
18963- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
18964- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
18965- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
18966- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
18967- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
18968- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
18969- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
18970-];
18971-
18972-const stageData = [
18973- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
18974- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
18975- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
18976- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
18977- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
18978- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
18979-];
18980-
18981-const heroFeatures = [
18982- {
18983- href: "/",
18984- eyebrow: "01 � The autonomous repair loop",
18985- title: "Failures fix themselves  and show their work.",
18986- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
18987failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
18988- cta: "Watch a live repair session",
18989- mock: [
18990- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
18991- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
18992- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
18993- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
18994- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
18995- ],
18996- },
18997- {
18998- href: "/",
18999- eyebrow: "02 � Live sandbox isolation",
19000- title: "Every PR gets its own instant, disposable environment.",
19001- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
19002same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
19003- cta: "See a PR with its sandbox",
19004- mock: [
19005- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
19006- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
19007- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
19008- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
19009- ],
19010- },
19011- {
19012- href: "/",
19013- eyebrow: "03 � Multiplayer IDE workspaces",
19014- title: "You and the agent, side by side, in your editor.",
19015- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
19016agent into a silent reviewer in your gutter. The browser becomes optional.",
19017- cta: "See the editor session",
19018- mock: [
19019- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
19020- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
19021- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
19022- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
19023- ],
19024- },
19025-];
19026-
19027-const capabilities = [
19028- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
19029- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
19030- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
19031- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
19032- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
19033- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
19034- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
19035- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
19036-];
19037-
19038-const sovereignLayerNames = [
19039- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
19040- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
19041- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
19042- "Availability & recovery",
19043-];
19044-
19045-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
19046- return (
19047- <>
19048- <style dangerouslySetInnerHTML={{ __html: css }} />
19049-
19050- {/* Nav */}
19051- <header class="lv-nav">
19052- <div class="lv-nav-inner">
19053- <a href="/" class="lv-logo">
19054- <span class="lv-logo-mark"></span>gluecron
19055- </a>
19056- <nav class="lv-nav-links">
19057- <a href="#loop" class="lv-nav-link">The loop</a>
19058- <a href="#platform" class="lv-nav-link">Platform</a>
19059- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
19060- <a href="/trust" class="lv-nav-link">Trust</a>
19061- </nav>
19062- <div class="lv-nav-ctas">
19063- <a href="/login" class="lv-btn-secondary">Sign in</a>
19064- <a href="/register" class="lv-btn-primary">Start building</a>
19065- </div>
19066- </div>
19067- </header>
19068-
19069- {/* Hero */}
19070- <section class="lv-hero">
19071- <div class="lv-hero-glow"></div>
19072- <div class="lv-hero-inner">
19073- <div class="lv-hero-badge">
19074- <span class="lv-dot lv-dot-green lv-pulse"></span>
19075- Live: a repair loop converged on pr-218 while you read this
19076- </div>
19077- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
19078- <p class="lv-hero-sub">
19079- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
19080failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
19081- </p>
19082- <div class="lv-hero-actions">
19083- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
19084- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
19085- </div>
19086- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
19087-
19088- {/* Live product window */}
19089- <div class="lv-demo-window">
19090- <div class="lv-demo-bar">
19091- <span class="lv-demo-dot"></span>
19092- <span class="lv-demo-dot"></span>
19093- <span class="lv-demo-dot"></span>
19094- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
19095- <span class="lv-demo-live">
19096- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
19097- LIVE
19098- </span>
19099- </div>
19100- <div class="lv-demo-body" id="lv-demo-body">
19101- {/* Events rendered by JS */}
19102- {demoAllEvents.slice(0, 1).map((e, i) => (
19103- <div class="lv-demo-event" key={i}>
19104- <div class="lv-demo-event-track">
19105- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
19106- <span class="lv-demo-line" style="display:none"></span>
19107- </div>
19108- <div class="lv-demo-event-content">
19109- <div class="lv-demo-event-header">
19110- <span class="lv-demo-event-title">{e.title}</span>
19111- <span class="lv-demo-event-time">{e.time}</span>
19112- </div>
19113- <div class="lv-demo-event-body">{e.body}</div>
19114- </div>
19115- </div>
19116- ))}
19117- </div>
19118- </div>
19119- </div>
19120-
19121- {/* Activity ticker */}
19122- <div class="lv-ticker-wrap">
19123- <div class="lv-ticker-track">
19124- {tickerItems.map((t, i) => (
19125- <span class="lv-ticker-item" key={i}>
19126- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
19127- {t.text}
19128- </span>
19129- ))}
19130- </div>
19131- </div>
19132- </section>
19133-
19134- {/* Stat band */}
19135- <section class="lv-stats">
19136- <div class="lv-stats-inner">
19137- <div class="lv-stat">
19138- <div class="lv-stat-num">Sonnet 5</div>
19139- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
19140- </div>
19141- <div class="lv-stat">
19142- <div class="lv-stat-num">93.5%</div>
19143- <div class="lv-stat-label">of failures self-repair without a human</div>
19144- </div>
19145- <div class="lv-stat">
19146- <div class="lv-stat-num">1.9%</div>
19147- <div class="lv-stat-label">AI merges reverted  published live</div>
19148- </div>
19149- <div class="lv-stat">
19150- <div class="lv-stat-num">0</div>
19151- <div class="lv-stat-label">irreversible actions taken autonomously</div>
19152- </div>
19153- </div>
19154- </section>
19155-
19156- {/* The loop */}
19157- <section id="loop" class="lv-loop">
19158- <div class="lv-loop-inner">
19159- <div class="lv-section-header">
19160- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
19161- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
19162- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
19163- </div>
19164- <div class="lv-stages" id="lv-stages">
19165- {stageData.map((s, i) => (
19166- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
19167- <div class="lv-stage-header">
19168- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
19169- <span class="lv-stage-n">0{i + 1}</span>
19170- </div>
19171- <div class="lv-stage-name">{s.name}</div>
19172- <div class="lv-stage-desc">{s.desc}</div>
19173- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
19174- </div>
19175- ))}
19176- </div>
19177- </div>
19178- </section>
19179-
19180- {/* Three heroes */}
19181- <section class="lv-heroes">
19182- <div class="lv-heroes-inner">
19183- <div class="lv-heroes-header">
19184- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
19185- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
19186- </div>
19187- <div class="lv-heroes-list">
19188- {heroFeatures.map((h, i) => (
19189- <a href={h.href} class="lv-hero-card" key={i}>
19190- <div class="lv-hero-card-left">
19191- <div class="lv-eyebrow">{h.eyebrow}</div>
19192- <h3 class="lv-hero-card-title">{h.title}</h3>
19193- <p class="lv-hero-card-body">{h.body}</p>
19194- <span class="lv-hero-card-cta">{h.cta} �!</span>
19195- </div>
19196- <div class="lv-terminal">
19197- {h.mock.map((m, j) => (
19198- <div class="lv-terminal-line" key={j}>
19199- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
19200- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
19201- </div>
19202- ))}
19203- </div>
19204- </a>
19205- ))}
19206- </div>
19207- </div>
19208- </section>
19209-
19210- {/* Everything grid */}
19211- <section id="platform" class="lv-platform">
19212- <div class="lv-platform-inner">
19213- <div class="lv-section-header lv-section-header-center">
19214- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
19215- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
19216- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
19217- </div>
19218- <div class="lv-cap-grid">
19219- {capabilities.map((c, i) => (
19220- <div class="lv-cap-col" key={i}>
19221- <div class="lv-cap-group">{c.group}</div>
19222- <div class="lv-cap-items">
19223- {c.items.map((item, j) => (
19224- <div class="lv-cap-item" key={j}>{item}</div>
19225- ))}
19226- </div>
19227- </div>
19228- ))}
19229- </div>
19230- </div>
19231- </section>
19232-
19233- {/* Sovereignty band */}
19234- <section id="sovereign" class="lv-sovereign">
19235- <div class="lv-sovereign-grid-bg"></div>
19236- <div class="lv-sovereign-inner">
19237- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
19238- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
19239- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
19240- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
19241to private cloud, or run fully air-gapped on bare metal.</p>
19242- </div>
19243- <div class="lv-layers-grid">
19244- {sovereignLayerNames.map((name, i) => (
19245- <div class="lv-layer-chip" key={i}>
19246- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
19247- <div class="lv-layer-name">{name}</div>
19248- </div>
19249- ))}
19250- <a href="/" class="lv-layer-chip lv-layer-cta">
19251- <div class="lv-layer-cta-text">All self-owned �!</div>
19252- </a>
19253- </div>
19254- <div class="lv-sovereign-feats">
19255- <div class="lv-sovereign-feat">
19256- <div class="lv-sovereign-feat-title">Local inference first</div>
19257- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
19258- </div>
19259- <div class="lv-sovereign-feat">
19260- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
19261- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
19262- </div>
19263- <div class="lv-sovereign-feat">
19264- <div class="lv-sovereign-feat-title">Self-healing infra</div>
19265- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
19266- </div>
19267- </div>
19268- </div>
19269- </section>
19270-
19271- {/* Manual-first + reversibility */}
19272- <section class="lv-twin">
19273- <div class="lv-twin-inner">
19274- <div class="lv-twin-card">
19275- <div class="lv-eyebrow">Manual-first, always</div>
19276- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
19277- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
19278fallback. Developers who never touch AI get the best git host they've ever used.</p>
19279- </div>
19280- <div class="lv-twin-card">
19281- <div class="lv-eyebrow">The reversibility guarantee</div>
19282- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
19283- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
19284 policy, not promise. Our quality numbers are published live, unedited.</p>
19285- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
19286- </div>
19287- </div>
19288- </section>
19289-
19290- {/* Quote */}
19291- <section class="lv-quote">
19292- <div class="lv-quote-inner">
19293- <p class="lv-quote-text">
19294- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
19295- Gluecron is where code gets <em class="lv-em">finished</em>."
19296- </p>
19297- </div>
19298- </section>
19299-
19300- {/* CTA */}
19301- <section class="lv-cta-section">
19302- <div class="lv-cta-card">
19303- <div class="lv-cta-glow"></div>
19304- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
19305- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
19306- <div class="lv-cta-actions">
19307- <a href="/register" class="lv-cta-primary">Create your account �!</a>
19308- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
19309- </div>
19310- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
19311- </div>
19312- </section>
19313-
19314- {/* Footer */}
19315- <footer class="lv-footer">
19316- <div class="lv-footer-inner">
19317- <div class="lv-footer-brand">
19318- <a href="/" class="lv-logo">
19319- <span class="lv-logo-mark"></span>gluecron
19320- </a>
19321- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
19322- </div>
19323- <div class="lv-footer-cols">
19324- <div class="lv-footer-col">
19325- <h4 class="lv-footer-col-head">Product</h4>
19326- <a href="/" class="lv-footer-link">Agent workspace</a>
19327- <a href="/" class="lv-footer-link">Fleet refactors</a>
19328- <a href="/" class="lv-footer-link">Org memory</a>
19329- <a href="/" class="lv-footer-link">IDE extensions</a>
19330- </div>
19331- <div class="lv-footer-col">
19332- <h4 class="lv-footer-col-head">Platform</h4>
19333- <a href="/" class="lv-footer-link">Production layers</a>
19334- <a href="/trust" class="lv-footer-link">Trust report</a>
19335- <a href="/" class="lv-footer-link">Docs</a>
19336- <a href="/" class="lv-footer-link">Status</a>
19337- </div>
19338- <div class="lv-footer-col">
19339- <h4 class="lv-footer-col-head">Company</h4>
19340- <a href="/" class="lv-footer-link">About</a>
19341- <a href="/" class="lv-footer-link">Pricing</a>
19342- <a href="/" class="lv-footer-link">Enterprise</a>
19343- </div>
19344- </div>
19345- </div>
19346- <div class="lv-footer-bar">
19347- <span>� 2026 Gluecron</span>
19348- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
19349- </div>
19350- </footer>
19351-
19352- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
19353- </>
19354- );
19355-};
19356-
19357-export const LandingPage = LandingPageV2;
19358-export default LandingPageV2;
19359-
19360-const clientScript = `
19361-(function() {
19362- var demoAll = [
19363- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
19364- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
19365- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
19366- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
19367- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
19368- ];
19369-
19370- var demoStep = 0;
19371- var stage = 0;
19372-
19373- function renderDemo() {
19374- var container = document.getElementById('lv-demo-body');
19375- if (!container) return;
19376- var visible = demoAll.slice(0, demoStep + 1);
19377- container.innerHTML = visible.map(function(e, i) {
19378- var isLast = i === visible.length - 1;
19379- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
19380- return '<div class="lv-demo-event">' +
19381- '<div class="lv-demo-event-track">' +
19382- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
19383- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
19384- '</div>' +
19385- '<div class="lv-demo-event-content">' +
19386- '<div class="lv-demo-event-header">' +
19387- '<span class="lv-demo-event-title">' + e.title + '</span>' +
19388- '<span class="lv-demo-event-time">' + e.time + '</span>' +
19389- '</div>' +
19390- '<div class="lv-demo-event-body">' + e.body + '</div>' +
19391- '</div>' +
19392- '</div>';
19393- }).join('');
19394- }
19395-
19396- function renderStages() {
19397- var cards = document.querySelectorAll('.lv-stage-card');
19398- cards.forEach(function(card, i) {
19399- var dot = card.querySelector('.lv-dot');
19400- var meta = card.querySelector('.lv-stage-meta');
19401- if (i === stage) {
19402- card.classList.add('lv-stage-active');
19403- if (dot) {
19404- dot.classList.remove('lv-dot-idle');
19405- dot.classList.add('lv-dot-indigo', 'lv-pulse');
19406- }
19407- if (meta) meta.classList.add('lv-stage-meta-active');
19408- } else {
19409- card.classList.remove('lv-stage-active');
19410- if (dot) {
19411- dot.classList.add('lv-dot-idle');
19412- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
19413- }
19414- if (meta) meta.classList.remove('lv-stage-meta-active');
19415- }
19416- });
19417- }
19418-
19419- renderDemo();
19420-
19421- setInterval(function() {
19422- demoStep = (demoStep + 1) % 5;
19423- renderDemo();
19424- }, 3600);
19425-
19426- setInterval(function() {
19427- stage = (stage + 1) % 6;
19428- renderStages();
19429- }, 2200);
19430-})();
19431-`;
19432-
19433-const css = `
19434-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
19435-
19436-*, *::before, *::after { box-sizing: border-box; }
19437-
19438-body {
19439- margin: 0;
19440- background: #fcfcfd;
19441- -webkit-font-smoothing: antialiased;
19442- text-rendering: optimizeLegibility;
19443- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
19444- font-size: 15px;
19445- line-height: 1.6;
19446- letter-spacing: -0.008em;
19447- color: #16181d;
19448-}
19449-
19450-@keyframes gcPulse {
19451- 0%, 100% { opacity: 1; }
19452- 50% { opacity: 0.35; }
19453-}
19454-
19455-@keyframes gcTicker {
19456- 0% { transform: translateX(0); }
19457- 100% { transform: translateX(-50%); }
19458-}
19459-
19460-/* Shared utilities */
19461-.lv-dot {
19462- display: inline-block;
19463- border-radius: 50%;
19464-}
19465-.lv-dot-green { background: #1e7f5c; }
19466-.lv-dot-indigo { background: #4353c9; }
19467-.lv-dot-idle { background: #c4c6cf; }
19468-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
19469-
19470-.lv-strong { color: #16181d; font-weight: 600; }
19471-
19472-.lv-eyebrow {
19473- font-family: 'JetBrains Mono', monospace;
19474- font-size: 11px;
19475- letter-spacing: 0.12em;
19476- text-transform: uppercase;
19477- color: #8a8d99;
19478- font-weight: 500;
19479- margin-bottom: 12px;
19480-}
19481-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
19482-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
19483-
19484-.lv-h1 {
19485- font-family: 'Inter Tight', sans-serif;
19486- font-weight: 700;
19487- letter-spacing: -0.035em;
19488- font-size: clamp(44px, 7vw, 84px);
19489- line-height: 0.98;
19490- margin: 30px auto 0;
19491- max-width: 14ch;
19492- color: #111318;
19493-}
19494-
19495-.lv-h2 {
19496- font-family: 'Inter Tight', sans-serif;
19497- font-weight: 700;
19498- letter-spacing: -0.028em;
19499- font-size: clamp(30px, 4.4vw, 48px);
19500- line-height: 1.05;
19501- margin: 0;
19502- color: #111318;
19503-}
19504-
19505-.lv-h2-dark {
19506- font-family: 'Inter Tight', sans-serif;
19507- font-weight: 700;
19508- letter-spacing: -0.028em;
19509- font-size: clamp(30px, 4.6vw, 52px);
19510- line-height: 1.05;
19511- margin: 0;
19512- color: #fff;
19513-}
19514-
19515-.lv-section-header {
19516- max-width: 640px;
19517- margin: 0 auto 56px;
19518-}
19519-
19520-.lv-section-header-center {
19521- text-align: center;
19522-}
19523-
19524-.lv-section-sub {
19525- color: #6b7080;
19526- font-size: 17px;
19527- margin: 18px auto 0;
19528- max-width: 52ch;
19529-}
19530-
19531-.lv-section-sub-dark {
19532- color: rgba(255,255,255,0.72);
19533- font-size: 17px;
19534- margin: 18px auto 0;
19535- max-width: 56ch;
19536-}
19537-
19538-/* Nav */
19539-.lv-nav {
19540- position: sticky;
19541- top: 0;
19542- z-index: 60;
19543- backdrop-filter: saturate(180%) blur(14px);
19544- -webkit-backdrop-filter: saturate(180%) blur(14px);
19545- background: rgba(252,252,253,0.8);
19546- border-bottom: 1px solid rgba(22,24,29,0.07);
19547-}
19548-
19549-.lv-nav-inner {
19550- max-width: 1200px;
19551- margin: 0 auto;
19552- padding: 14px 28px;
19553- display: flex;
19554- align-items: center;
19555- gap: 28px;
19556-}
19557-
19558-.lv-logo {
19559- display: inline-flex;
19560- align-items: center;
19561- gap: 9px;
19562- font-family: 'Inter Tight', sans-serif;
19563- font-weight: 700;
19564- font-size: 17px;
19565- letter-spacing: -0.02em;
19566- color: #16181d;
19567- text-decoration: none;
19568-}
19569-
19570-.lv-logo-mark {
19571- width: 17px;
19572- height: 17px;
19573- border-radius: 5px;
19574- background: #4353c9;
19575- display: inline-block;
19576- flex-shrink: 0;
19577-}
19578-
19579-.lv-nav-links {
19580- display: flex;
19581- gap: 24px;
19582- font-size: 13.5px;
19583- font-weight: 500;
19584-}
19585-
19586-.lv-nav-link {
19587- color: #6b7080;
19588- text-decoration: none;
19589- transition: color 0.15s;
19590-}
19591-.lv-nav-link:hover { color: #16181d; }
19592-
19593-.lv-nav-ctas {
19594- margin-left: auto;
19595- display: flex;
19596- align-items: center;
19597- gap: 10px;
19598-}
19599-
19600-.lv-btn-secondary {
19601- padding: 8px 15px;
19602- border-radius: 8px;
19603- font-size: 13.5px;
19604- font-weight: 500;
19605- color: #16181d;
19606- border: 1px solid rgba(22,24,29,0.12);
19607- background: #ffffff;
19608- text-decoration: none;
19609- white-space: nowrap;
19610- transition: border-color 0.15s;
19611-}
19612-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
19613-
19614-.lv-btn-primary {
19615- padding: 8px 15px;
19616- border-radius: 8px;
19617- font-size: 13.5px;
19618- font-weight: 600;
19619- background: #16181d;
19620- color: #fff;
19621- text-decoration: none;
19622- white-space: nowrap;
19623- transition: box-shadow 0.15s;
19624-}
19625-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
19626-
19627-/* Hero */
19628-.lv-hero {
19629- position: relative;
19630- overflow: hidden;
19631- padding: 88px 0 0;
19632-}
19633-
19634-.lv-hero-glow {
19635- position: absolute;
19636- inset: -10% 0 auto 0;
19637- height: 640px;
19638- pointer-events: none;
19639- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
19640-}
19641-
19642-.lv-hero-inner {
19643- position: relative;
19644- max-width: 1200px;
19645- margin: 0 auto;
19646- padding: 0 28px;
19647- text-align: center;
19648-}
19649-
19650-.lv-hero-badge {
19651- display: inline-flex;
19652- align-items: center;
19653- gap: 9px;
19654- font-size: 12.5px;
19655- font-weight: 600;
19656- color: #3a3d45;
19657- background: #ffffff;
19658- border: 1px solid rgba(22,24,29,0.10);
19659- border-radius: 9999px;
19660- padding: 7px 16px;
19661- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
19662-}
19663-
19664-.lv-hero-sub {
19665- font-size: clamp(16px, 2vw, 19px);
19666- color: #6b7080;
19667- max-width: 60ch;
19668- margin: 24px auto 0;
19669- font-weight: 450;
19670- line-height: 1.65;
19671-}
19672-
19673-.lv-hero-actions {
19674- display: flex;
19675- gap: 12px;
19676- justify-content: center;
19677- flex-wrap: wrap;
19678- margin-top: 32px;
19679-}
19680-
19681-.lv-cta-primary {
19682- padding: 13px 24px;
19683- border-radius: 11px;
19684- font-size: 15.5px;
19685- font-weight: 600;
19686- background: #16181d;
19687- color: #fff;
19688- text-decoration: none;
19689- white-space: nowrap;
19690- transition: box-shadow 0.15s;
19691-}
19692-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
19693-
19694-.lv-cta-secondary {
19695- padding: 13px 24px;
19696- border-radius: 11px;
19697- font-size: 15.5px;
19698- font-weight: 600;
19699- color: #16181d;
19700- border: 1px solid rgba(22,24,29,0.14);
19701- background: #ffffff;
19702- text-decoration: none;
19703- white-space: nowrap;
19704- transition: border-color 0.15s;
19705-}
19706-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
19707-
19708-.lv-hero-tag {
19709- margin-top: 18px;
19710- font-family: 'JetBrains Mono', monospace;
19711- font-size: 11.5px;
19712- letter-spacing: 0.08em;
19713- text-transform: uppercase;
19714- color: #8a8d99;
19715-}
19716-
19717-/* Demo window */
19718-.lv-demo-window {
19719- margin: 56px auto 0;
19720- max-width: 860px;
19721- text-align: left;
19722- background: #ffffff;
19723- border: 1px solid rgba(22,24,29,0.09);
19724- border-radius: 18px;
19725- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
19726- overflow: hidden;
19727-}
19728-
19729-.lv-demo-bar {
19730- display: flex;
19731- align-items: center;
19732- gap: 7px;
19733- padding: 12px 18px;
19734- border-bottom: 1px solid rgba(22,24,29,0.07);
19735- background: #fcfcfd;
19736-}
19737-
19738-.lv-demo-dot {
19739- width: 10px;
19740- height: 10px;
19741- border-radius: 50%;
19742- background: #e4e5ea;
19743-}
19744-
19745-.lv-demo-url {
19746- margin-left: 10px;
19747- font-family: 'JetBrains Mono', monospace;
19748- font-size: 12px;
19749- color: #6b7080;
19750-}
19751-
19752-.lv-demo-live {
19753- margin-left: auto;
19754- display: inline-flex;
19755- align-items: center;
19756- gap: 6px;
19757- font-size: 11px;
19758- font-weight: 600;
19759- color: #1e7f5c;
19760-}
19761-
19762-.lv-demo-body {
19763- padding: 22px 24px;
19764-}
19765-
19766-.lv-demo-event {
19767- display: grid;
19768- grid-template-columns: 18px minmax(0, 1fr);
19769- gap: 14px;
19770- padding-bottom: 20px;
19771- position: relative;
19772-}
19773-.lv-demo-event:last-child { padding-bottom: 0; }
19774-
19775-.lv-demo-event-track {
19776- display: flex;
19777- flex-direction: column;
19778- align-items: center;
19779-}
19780-
19781-.lv-demo-line {
19782- width: 1px;
19783- flex: 1;
19784- background: rgba(22,24,29,0.08);
19785- margin-top: 5px;
19786- min-height: 20px;
19787-}
19788-
19789-.lv-demo-event-content {}
19790-
19791-.lv-demo-event-header {
19792- display: flex;
19793- align-items: baseline;
19794- gap: 10px;
19795-}
19796-
19797-.lv-demo-event-title {
19798- font-size: 13.5px;
19799- font-weight: 600;
19800- color: #16181d;
19801-}
19802-
19803-.lv-demo-event-time {
19804- font-family: 'JetBrains Mono', monospace;
19805- font-size: 11px;
19806- color: #8a8d99;
19807-}
19808-
19809-.lv-demo-event-body {
19810- font-size: 13px;
19811- color: #6b7080;
19812- margin-top: 2px;
19813-}
19814-
19815-/* Ticker */
19816-.lv-ticker-wrap {
19817- border-top: 1px solid rgba(22,24,29,0.07);
19818- border-bottom: 1px solid rgba(22,24,29,0.07);
19819- background: #ffffff;
19820- margin-top: 64px;
19821- overflow: hidden;
19822- white-space: nowrap;
19823- position: relative;
19824-}
19825-
19826-.lv-ticker-track {
19827- display: inline-flex;
19828- animation: gcTicker 40s linear infinite;
19829- padding: 11px 0;
19830-}
19831-
19832-.lv-ticker-item {
19833- display: inline-flex;
19834- align-items: center;
19835- gap: 8px;
19836- font-family: 'JetBrains Mono', monospace;
19837- font-size: 11.5px;
19838- color: #6b7080;
19839- padding: 0 28px;
19840- border-right: 1px solid rgba(22,24,29,0.06);
19841-}
19842-
19843-/* Stats */
19844-.lv-stats {
19845- background: #fcfcfd;
19846-}
19847-
19848-.lv-stats-inner {
19849- max-width: 1200px;
19850- margin: 0 auto;
19851- display: grid;
19852- grid-template-columns: repeat(4, 1fr);
19853- gap: 24px;
19854- padding: 52px 28px;
19855-}
19856-
19857-.lv-stat {
19858- text-align: center;
19859-}
19860-
19861-.lv-stat-num {
19862- font-family: 'Inter Tight', sans-serif;
19863- font-weight: 700;
19864- font-size: clamp(30px, 4vw, 44px);
19865- letter-spacing: -0.025em;
19866- color: #111318;
19867-}
19868-
19869-.lv-stat-label {
19870- font-size: 13px;
19871- color: #6b7080;
19872- margin-top: 4px;
19873-}
19874-
19875-/* Loop */
19876-.lv-loop {
19877- padding: 96px 0;
19878- background: #ffffff;
19879- border-top: 1px solid rgba(22,24,29,0.07);
19880- border-bottom: 1px solid rgba(22,24,29,0.07);
19881-}
19882-
19883-.lv-loop-inner {
19884- max-width: 1200px;
19885- margin: 0 auto;
19886- padding: 0 28px;
19887-}
19888-
19889-.lv-stages {
19890- display: grid;
19891- grid-template-columns: repeat(6, 1fr);
19892- gap: 12px;
19893-}
19894-
19895-.lv-stage-card {
19896- border: 1px solid rgba(22,24,29,0.08);
19897- border-radius: 14px;
19898- background: #ffffff;
19899- padding: 20px 18px;
19900- transition: border-color 0.3s, background 0.3s;
19901-}
19902-
19903-.lv-stage-card.lv-stage-active {
19904- border-color: rgba(67,83,201,0.45);
19905- background: rgba(67,83,201,0.03);
19906-}
19907-
19908-.lv-stage-header {
19909- display: flex;
19910- align-items: center;
19911- gap: 8px;
19912- margin-bottom: 10px;
19913-}
19914-
19915-.lv-stage-n {
19916- font-family: 'JetBrains Mono', monospace;
19917- font-size: 10.5px;
19918- letter-spacing: 0.1em;
19919- text-transform: uppercase;
19920- color: #8a8d99;
19921-}
19922-
19923-.lv-stage-name {
19924- font-family: 'Inter Tight', sans-serif;
19925- font-size: 16px;
19926- font-weight: 600;
19927- letter-spacing: -0.01em;
19928- color: #16181d;
19929- margin-bottom: 5px;
19930-}
19931-
19932-.lv-stage-desc {
19933- font-size: 12px;
19934- color: #6b7080;
19935- line-height: 1.55;
19936-}
19937-
19938-.lv-stage-meta {
19939- font-family: 'JetBrains Mono', monospace;
19940- font-size: 10.5px;
19941- color: #8a8d99;
19942- margin-top: 10px;
19943- transition: color 0.3s;
19944-}
19945-
19946-.lv-stage-meta.lv-stage-meta-active {
19947- color: #4353c9;
19948-}
19949-
19950-/* Heroes */
19951-.lv-heroes {
19952- padding: 96px 0;
19953- background: #fcfcfd;
19954-}
19955-
19956-.lv-heroes-inner {
19957- max-width: 1200px;
19958- margin: 0 auto;
19959- padding: 0 28px;
19960-}
19961-
19962-.lv-heroes-header {
19963- max-width: 640px;
19964- margin-bottom: 56px;
19965-}
19966-
19967-.lv-heroes-list {
19968- display: flex;
19969- flex-direction: column;
19970- gap: 20px;
19971-}
19972-
19973-.lv-hero-card {
19974- display: grid;
19975- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
19976- gap: 48px;
19977- align-items: center;
19978- border: 1px solid rgba(22,24,29,0.08);
19979- border-radius: 20px;
19980- background: #ffffff;
19981- padding: 44px 48px;
19982- text-decoration: none;
19983- transition: border-color 0.2s, box-shadow 0.2s;
19984-}
19985-.lv-hero-card:hover {
19986- border-color: rgba(22,24,29,0.22);
19987- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
19988-}
19989-
19990-.lv-hero-card-left {}
19991-
19992-.lv-hero-card-title {
19993- font-family: 'Inter Tight', sans-serif;
19994- font-size: 26px;
19995- font-weight: 600;
19996- letter-spacing: -0.022em;
19997- line-height: 1.15;
19998- color: #16181d;
19999- margin: 0 0 12px;
20000-}
20001-
20002-.lv-hero-card-body {
20003- font-size: 14.5px;
20004- color: #6b7080;
20005- margin: 0 0 18px;
20006- line-height: 1.65;
20007-}
20008-
20009-.lv-hero-card-cta {
20010- font-size: 13.5px;
20011- font-weight: 600;
20012- color: #4353c9;
20013-}
20014-
20015-.lv-terminal {
20016- border: 1px solid rgba(22,24,29,0.07);
20017- border-radius: 14px;
20018- background: #fcfcfd;
20019- padding: 20px 22px;
20020- font-family: 'JetBrains Mono', monospace;
20021- font-size: 12px;
20022- line-height: 1.9;
20023- overflow: hidden;
20024-}
20025-
20026-.lv-terminal-line {
20027- display: flex;
20028- align-items: center;
20029- gap: 10px;
20030- white-space: nowrap;
20031- overflow: hidden;
20032- text-overflow: ellipsis;
20033-}
20034-
20035-/* Platform */
20036-.lv-platform {
20037- padding: 96px 0;
20038- background: #ffffff;
20039- border-top: 1px solid rgba(22,24,29,0.07);
20040-}
20041-
20042-.lv-platform-inner {
20043- max-width: 1200px;
20044- margin: 0 auto;
20045- padding: 0 28px;
20046-}
20047-
20048-.lv-cap-grid {
20049- display: grid;
20050- grid-template-columns: repeat(4, 1fr);
20051- gap: 24px 32px;
20052-}
20053-
20054-.lv-cap-col {}
20055-
20056-.lv-cap-group {
20057- font-family: 'JetBrains Mono', monospace;
20058- font-size: 10.5px;
20059- letter-spacing: 0.12em;
20060- text-transform: uppercase;
20061- color: #8a8d99;
20062- font-weight: 500;
20063- margin-bottom: 12px;
20064- padding-bottom: 8px;
20065- border-bottom: 1px solid rgba(22,24,29,0.07);
20066-}
20067-
20068-.lv-cap-items {
20069- display: flex;
20070- flex-direction: column;
20071- gap: 7px;
20072-}
20073-
20074-.lv-cap-item {
20075- font-size: 12.5px;
20076- color: #3a3d45;
20077- line-height: 1.45;
20078-}
20079-
20080-/* Sovereignty */
20081-.lv-sovereign {
20082- position: relative;
20083- overflow: hidden;
20084- padding: 104px 0;
20085- color: #fff;
20086- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
20087-}
20088-
20089-.lv-sovereign-grid-bg {
20090- position: absolute;
20091- inset: 0;
20092- opacity: 0.4;
20093- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
20094- background-size: 56px 56px;
20095- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
20096- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
20097-}
20098-
20099-.lv-sovereign-inner {
20100- position: relative;
20101- max-width: 1200px;
20102- margin: 0 auto;
20103- padding: 0 28px;
20104-}
20105-
20106-.lv-section-header-dark {
20107- max-width: 680px;
20108- margin: 0 auto 48px;
20109- text-align: center;
20110-}
20111-
20112-.lv-layers-grid {
20113- display: grid;
20114- grid-template-columns: repeat(4, 1fr);
20115- gap: 10px;
20116- max-width: 980px;
20117- margin: 0 auto;
20118-}
20119-
20120-.lv-layer-chip {
20121- border: 1px solid rgba(255,255,255,0.10);
20122- border-radius: 10px;
20123- padding: 12px 16px;
20124- background: rgba(255,255,255,0.03);
20125-}
20126-
20127-.lv-layer-cta {
20128- border-color: rgba(169,180,238,0.30);
20129- background: rgba(169,180,238,0.06);
20130- display: flex;
20131- align-items: center;
20132- text-decoration: none;
20133- transition: background 0.15s;
20134-}
20135-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
20136-
20137-.lv-layer-cta-text {
20138- font-size: 13px;
20139- font-weight: 500;
20140- color: #a9b4ee;
20141-}
20142-
20143-.lv-layer-n {
20144- font-family: 'JetBrains Mono', monospace;
20145- font-size: 10px;
20146- color: rgba(255,255,255,0.4);
20147- margin-bottom: 3px;
20148-}
20149-
20150-.lv-layer-name {
20151- font-size: 13px;
20152- font-weight: 500;
20153- color: rgba(255,255,255,0.92);
20154-}
20155-
20156-.lv-sovereign-feats {
20157- display: flex;
20158- gap: 44px;
20159- justify-content: center;
20160- flex-wrap: wrap;
20161- margin-top: 52px;
20162- text-align: center;
20163-}
20164-
20165-.lv-sovereign-feat {}
20166-
20167-.lv-sovereign-feat-title {
20168- font-family: 'Inter Tight', sans-serif;
20169- font-size: 20px;
20170- font-weight: 700;
20171- color: #fff;
20172-}
20173-
20174-.lv-sovereign-feat-sub {
20175- color: rgba(255,255,255,0.55);
20176- font-size: 13px;
20177- margin-top: 2px;
20178-}
20179-
20180-/* Twin cards */
20181-.lv-twin {
20182- padding: 96px 0;
20183- background: #fcfcfd;
20184-}
20185-
20186-.lv-twin-inner {
20187- max-width: 1200px;
20188- margin: 0 auto;
20189- padding: 0 28px;
20190- display: grid;
20191- grid-template-columns: 1fr 1fr;
20192- gap: 24px;
20193-}
20194-
20195-.lv-twin-card {
20196- border: 1px solid rgba(22,24,29,0.08);
20197- border-radius: 20px;
20198- background: #ffffff;
20199- padding: 44px 48px;
20200-}
20201-
20202-.lv-twin-title {
20203- font-family: 'Inter Tight', sans-serif;
20204- font-size: 24px;
20205- font-weight: 600;
20206- letter-spacing: -0.02em;
20207- line-height: 1.2;
20208- margin: 0 0 12px;
20209- color: #16181d;
20210-}
20211-
20212-.lv-twin-body {
20213- font-size: 14.5px;
20214- color: #6b7080;
20215- margin: 0 0 16px;
20216- line-height: 1.7;
20217-}
20218-
20219-.lv-twin-link {
20220- font-size: 13.5px;
20221- font-weight: 600;
20222- color: #4353c9;
20223- text-decoration: none;
20224-}
20225-.lv-twin-link:hover { text-decoration: underline; }
20226-
20227-/* Quote */
20228-.lv-quote {
20229- padding: 40px 0 96px;
20230- background: #fcfcfd;
20231-}
20232-
20233-.lv-quote-inner {
20234- max-width: 980px;
20235- margin: 0 auto;
20236- padding: 0 28px;
20237- text-align: center;
20238-}
20239-
20240-.lv-quote-text {
20241- font-family: 'Inter Tight', sans-serif;
20242- font-weight: 600;
20243- font-size: clamp(26px, 3.8vw, 42px);
20244- line-height: 1.2;
20245- letter-spacing: -0.025em;
20246- margin: 0;
20247- color: #111318;
20248-}
20249-
20250-.lv-em {
20251- font-style: normal;
20252- color: #4353c9;
20253-}
20254-
20255-/* CTA */
20256-.lv-cta-section {
20257- padding: 0 0 104px;
20258- background: #fcfcfd;
20259-}
20260-
20261-.lv-cta-card {
20262- max-width: 820px;
20263- margin: 0 auto;
20264- padding: 64px 40px;
20265- text-align: center;
20266- background: #ffffff;
20267- border: 1px solid rgba(22,24,29,0.08);
20268- border-radius: 26px;
20269- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
20270- position: relative;
20271- overflow: hidden;
20272-}
20273-
20274-.lv-cta-glow {
20275- position: absolute;
20276- inset: -40% 0 auto 0;
20277- height: 280px;
20278- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
20279- pointer-events: none;
20280-}
20281-
20282-.lv-cta-h2 {
20283- font-family: 'Inter Tight', sans-serif;
20284- font-weight: 700;
20285- letter-spacing: -0.028em;
20286- font-size: clamp(30px, 4.6vw, 48px);
20287- margin: 0;
20288- position: relative;
20289- color: #111318;
20290-}
20291-
20292-.lv-cta-sub {
20293- color: #6b7080;
20294- font-size: 17px;
20295- margin: 16px 0 30px;
20296- position: relative;
20297-}
20298-
20299-.lv-cta-actions {
20300- display: flex;
20301- gap: 12px;
20302- justify-content: center;
20303- flex-wrap: wrap;
20304- position: relative;
20305-}
20306-
20307-.lv-cta-fine {
20308- margin-top: 20px;
20309- font-family: 'JetBrains Mono', monospace;
20310- font-size: 11px;
20311- color: #8a8d99;
20312- position: relative;
20313-}
20314-
20315-/* Footer */
20316-.lv-footer {
20317- border-top: 1px solid rgba(22,24,29,0.07);
20318- background: #ffffff;
20319- padding: 56px 0 30px;
20320-}
20321-
20322-.lv-footer-inner {
20323- max-width: 1200px;
20324- margin: 0 auto;
20325- padding: 0 28px;
20326- display: flex;
20327- gap: 48px;
20328- flex-wrap: wrap;
20329- justify-content: space-between;
20330-}
20331-
20332-.lv-footer-brand {}
20333-
20334-.lv-footer-tagline {
20335- color: #6b7080;
20336- font-size: 13.5px;
20337- margin: 12px 0 0;
20338- max-width: 32ch;
20339- line-height: 1.6;
20340-}
20341-
20342-.lv-footer-cols {
20343- display: flex;
20344- gap: 64px;
20345- flex-wrap: wrap;
20346-}
20347-
20348-.lv-footer-col {
20349- display: flex;
20350- flex-direction: column;
20351- gap: 9px;
20352-}
20353-
20354-.lv-footer-col-head {
20355- font-family: 'JetBrains Mono', monospace;
20356- font-size: 11px;
20357- text-transform: uppercase;
20358- letter-spacing: 0.1em;
20359- color: #8a8d99;
20360- margin: 0 0 4px;
20361- font-weight: 500;
20362-}
20363-
20364-.lv-footer-link {
20365- color: #3a3d45;
20366- font-size: 13.5px;
20367- text-decoration: none;
20368- transition: color 0.15s;
20369-}
20370-.lv-footer-link:hover { color: #16181d; }
20371-
20372-.lv-footer-bar {
20373- max-width: 1200px;
20374- margin: 44px auto 0;
20375- padding: 22px 28px 0;
20376- border-top: 1px solid rgba(22,24,29,0.06);
20377- display: flex;
20378- justify-content: space-between;
20379- flex-wrap: wrap;
20380- gap: 8px;
20381- color: #8a8d99;
20382- font-size: 12.5px;
20383-}
20384-
20385-.lv-footer-stack {
20386- font-family: 'JetBrains Mono', monospace;
20387- font-size: 11px;
20388-}
20389-`;
20390diff --git a/src/views/layout.tsx b/src/views/layout.tsx
20391index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
20392--- a/src/views/layout.tsx
20393+++ b/src/views/layout.tsx
20394@@ -3153,9 +3153,12 @@
20395 font-weight: 500;
20396 line-height: 1.4;
20397 }
20398- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
20399- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
20400- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
20401+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
20402+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
20403+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
20404+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
20405+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
20406+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
20407 .state-merged { color: var(--accent); }
20408 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
20409
20410diff --git a/src/views/ui.tsx b/src/views/ui.tsx
20411index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
20412--- a/src/views/ui.tsx
20413+++ b/src/views/ui.tsx
20414@@ -232,7 +232,7 @@
20415
20416 export const Badge: FC<
20417 PropsWithChildren<{
20418- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
20419+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
20420 style?: string;
20421 }>
20422 > = ({ children, variant = "default", style }) => {
20423@@ -241,9 +241,12 @@
20424 variant === "closed" ? "badge-closed" :
20425 variant === "merged" ? "badge-merged" :
20426 variant === "success" ? "badge-success" :
20427- variant === "danger" ? "badge-danger" :
20428- variant === "warning" ? "badge-warning" :
20429- "badge";
20430+ variant === "danger" ? "badge-danger" :
20431+ variant === "warning" ? "badge-warning" :
20432+ variant === "live" ? "badge-live" :
20433+ variant === "soon" ? "badge-soon" :
20434+ variant === "preview" ? "badge-preview" :
20435+ "badge";
20436 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
20437 };
20438
20439
20440codex
20441The first combined run hit the 120-second harness limit without returning results, so I split verification into individual commands with a longer allowance. Typecheck itself is unusually slow in this
20442repository and is still running; no diagnostics have appeared so far.
20443diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
20444index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
20445--- a/src/views/landing-pro.tsx
20446+++ b/src/views/landing-pro.tsx
20447@@ -42,7 +42,7 @@
20448
20449 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20450
20451-function icon(paths: string, color = "#4353c9", size = 20) {
20452+function icon(paths: string, color = "#0891b2", size = 20) {
20453 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
20454 }
20455
20456@@ -947,7 +947,7 @@
20457 const css = `
20458 /* %% tokens %% */
20459 :root{
20460- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
20461+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
20462 --lp-bg:#ffffff;--lp-soft:#fafafb;
20463 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
20464 --lp-border:rgba(0,0,0,.08);
20465diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
20466deleted file mode 100644
20467index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
20468--- a/src/views/landing-v2.tsx
20469+++ /dev/null
20470@@ -1,1447 +0,0 @@
20471-import type { FC } from "hono/jsx";
20472-
20473-export interface LandingPageProps {
20474- stats?: {
20475- publicRepos?: number;
20476- users?: number;
20477- };
20478-}
20479-
20480-const demoAllEvents = [
20481- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
20482- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
20483- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
20484- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
20485- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
20486-];
20487-
20488-const tickerItems = [
20489- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
20490- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
20491- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
20492- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
20493- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
20494- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
20495- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
20496- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
20497- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
20498- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
20499- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
20500- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
20501- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
20502- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
20503- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
20504- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
20505-];
20506-
20507-const stageData = [
20508- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
20509- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
20510- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
20511- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
20512- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
20513- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
20514-];
20515-
20516-const heroFeatures = [
20517- {
20518- href: "/",
20519- eyebrow: "01 � The autonomous repair loop",
20520- title: "Failures fix themselves  and show their work.",
20521- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
20522failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
20523- cta: "Watch a live repair session",
20524- mock: [
20525- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
20526- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
20527- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
20528- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
20529- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
20530- ],
20531- },
20532- {
20533- href: "/",
20534- eyebrow: "02 � Live sandbox isolation",
20535- title: "Every PR gets its own instant, disposable environment.",
20536- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
20537same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
20538- cta: "See a PR with its sandbox",
20539- mock: [
20540- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
20541- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
20542- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
20543- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
20544- ],
20545- },
20546- {
20547- href: "/",
20548- eyebrow: "03 � Multiplayer IDE workspaces",
20549- title: "You and the agent, side by side, in your editor.",
20550- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
20551agent into a silent reviewer in your gutter. The browser becomes optional.",
20552- cta: "See the editor session",
20553- mock: [
20554- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
20555- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
20556- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
20557- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
20558- ],
20559- },
20560-];
20561-
20562-const capabilities = [
20563- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
20564- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
20565- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
20566- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
20567- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
20568- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
20569- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
20570- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
20571-];
20572-
20573-const sovereignLayerNames = [
20574- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
20575- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
20576- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
20577- "Availability & recovery",
20578-];
20579-
20580-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
20581- return (
20582- <>
20583- <style dangerouslySetInnerHTML={{ __html: css }} />
20584-
20585- {/* Nav */}
20586- <header class="lv-nav">
20587- <div class="lv-nav-inner">
20588- <a href="/" class="lv-logo">
20589- <span class="lv-logo-mark"></span>gluecron
20590- </a>
20591- <nav class="lv-nav-links">
20592- <a href="#loop" class="lv-nav-link">The loop</a>
20593- <a href="#platform" class="lv-nav-link">Platform</a>
20594- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
20595- <a href="/trust" class="lv-nav-link">Trust</a>
20596- </nav>
20597- <div class="lv-nav-ctas">
20598- <a href="/login" class="lv-btn-secondary">Sign in</a>
20599- <a href="/register" class="lv-btn-primary">Start building</a>
20600- </div>
20601- </div>
20602- </header>
20603-
20604- {/* Hero */}
20605- <section class="lv-hero">
20606- <div class="lv-hero-glow"></div>
20607- <div class="lv-hero-inner">
20608- <div class="lv-hero-badge">
20609- <span class="lv-dot lv-dot-green lv-pulse"></span>
20610- Live: a repair loop converged on pr-218 while you read this
20611- </div>
20612- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
20613- <p class="lv-hero-sub">
20614- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
20615failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
20616- </p>
20617- <div class="lv-hero-actions">
20618- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
20619- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
20620- </div>
20621- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
20622-
20623- {/* Live product window */}
20624- <div class="lv-demo-window">
20625- <div class="lv-demo-bar">
20626- <span class="lv-demo-dot"></span>
20627- <span class="lv-demo-dot"></span>
20628- <span class="lv-demo-dot"></span>
20629- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
20630- <span class="lv-demo-live">
20631- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
20632- LIVE
20633- </span>
20634- </div>
20635- <div class="lv-demo-body" id="lv-demo-body">
20636- {/* Events rendered by JS */}
20637- {demoAllEvents.slice(0, 1).map((e, i) => (
20638- <div class="lv-demo-event" key={i}>
20639- <div class="lv-demo-event-track">
20640- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
20641- <span class="lv-demo-line" style="display:none"></span>
20642- </div>
20643- <div class="lv-demo-event-content">
20644- <div class="lv-demo-event-header">
20645- <span class="lv-demo-event-title">{e.title}</span>
20646- <span class="lv-demo-event-time">{e.time}</span>
20647- </div>
20648- <div class="lv-demo-event-body">{e.body}</div>
20649- </div>
20650- </div>
20651- ))}
20652- </div>
20653- </div>
20654- </div>
20655-
20656- {/* Activity ticker */}
20657- <div class="lv-ticker-wrap">
20658- <div class="lv-ticker-track">
20659- {tickerItems.map((t, i) => (
20660- <span class="lv-ticker-item" key={i}>
20661- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
20662- {t.text}
20663- </span>
20664- ))}
20665- </div>
20666- </div>
20667- </section>
20668-
20669- {/* Stat band */}
20670- <section class="lv-stats">
20671- <div class="lv-stats-inner">
20672- <div class="lv-stat">
20673- <div class="lv-stat-num">Sonnet 5</div>
20674- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
20675- </div>
20676- <div class="lv-stat">
20677- <div class="lv-stat-num">93.5%</div>
20678- <div class="lv-stat-label">of failures self-repair without a human</div>
20679- </div>
20680- <div class="lv-stat">
20681- <div class="lv-stat-num">1.9%</div>
20682- <div class="lv-stat-label">AI merges reverted  published live</div>
20683- </div>
20684- <div class="lv-stat">
20685- <div class="lv-stat-num">0</div>
20686- <div class="lv-stat-label">irreversible actions taken autonomously</div>
20687- </div>
20688- </div>
20689- </section>
20690-
20691- {/* The loop */}
20692- <section id="loop" class="lv-loop">
20693- <div class="lv-loop-inner">
20694- <div class="lv-section-header">
20695- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
20696- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
20697- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
20698- </div>
20699- <div class="lv-stages" id="lv-stages">
20700- {stageData.map((s, i) => (
20701- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
20702- <div class="lv-stage-header">
20703- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
20704- <span class="lv-stage-n">0{i + 1}</span>
20705- </div>
20706- <div class="lv-stage-name">{s.name}</div>
20707- <div class="lv-stage-desc">{s.desc}</div>
20708- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
20709- </div>
20710- ))}
20711- </div>
20712- </div>
20713- </section>
20714-
20715- {/* Three heroes */}
20716- <section class="lv-heroes">
20717- <div class="lv-heroes-inner">
20718- <div class="lv-heroes-header">
20719- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
20720- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
20721- </div>
20722- <div class="lv-heroes-list">
20723- {heroFeatures.map((h, i) => (
20724- <a href={h.href} class="lv-hero-card" key={i}>
20725- <div class="lv-hero-card-left">
20726- <div class="lv-eyebrow">{h.eyebrow}</div>
20727- <h3 class="lv-hero-card-title">{h.title}</h3>
20728- <p class="lv-hero-card-body">{h.body}</p>
20729- <span class="lv-hero-card-cta">{h.cta} �!</span>
20730- </div>
20731- <div class="lv-terminal">
20732- {h.mock.map((m, j) => (
20733- <div class="lv-terminal-line" key={j}>
20734- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
20735- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
20736- </div>
20737- ))}
20738- </div>
20739- </a>
20740- ))}
20741- </div>
20742- </div>
20743- </section>
20744-
20745- {/* Everything grid */}
20746- <section id="platform" class="lv-platform">
20747- <div class="lv-platform-inner">
20748- <div class="lv-section-header lv-section-header-center">
20749- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
20750- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
20751- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
20752- </div>
20753- <div class="lv-cap-grid">
20754- {capabilities.map((c, i) => (
20755- <div class="lv-cap-col" key={i}>
20756- <div class="lv-cap-group">{c.group}</div>
20757- <div class="lv-cap-items">
20758- {c.items.map((item, j) => (
20759- <div class="lv-cap-item" key={j}>{item}</div>
20760- ))}
20761- </div>
20762- </div>
20763- ))}
20764- </div>
20765- </div>
20766- </section>
20767-
20768- {/* Sovereignty band */}
20769- <section id="sovereign" class="lv-sovereign">
20770- <div class="lv-sovereign-grid-bg"></div>
20771- <div class="lv-sovereign-inner">
20772- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
20773- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
20774- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
20775- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
20776to private cloud, or run fully air-gapped on bare metal.</p>
20777- </div>
20778- <div class="lv-layers-grid">
20779- {sovereignLayerNames.map((name, i) => (
20780- <div class="lv-layer-chip" key={i}>
20781- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
20782- <div class="lv-layer-name">{name}</div>
20783- </div>
20784- ))}
20785- <a href="/" class="lv-layer-chip lv-layer-cta">
20786- <div class="lv-layer-cta-text">All self-owned �!</div>
20787- </a>
20788- </div>
20789- <div class="lv-sovereign-feats">
20790- <div class="lv-sovereign-feat">
20791- <div class="lv-sovereign-feat-title">Local inference first</div>
20792- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
20793- </div>
20794- <div class="lv-sovereign-feat">
20795- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
20796- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
20797- </div>
20798- <div class="lv-sovereign-feat">
20799- <div class="lv-sovereign-feat-title">Self-healing infra</div>
20800- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
20801- </div>
20802- </div>
20803- </div>
20804- </section>
20805-
20806- {/* Manual-first + reversibility */}
20807- <section class="lv-twin">
20808- <div class="lv-twin-inner">
20809- <div class="lv-twin-card">
20810- <div class="lv-eyebrow">Manual-first, always</div>
20811- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
20812- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
20813fallback. Developers who never touch AI get the best git host they've ever used.</p>
20814- </div>
20815- <div class="lv-twin-card">
20816- <div class="lv-eyebrow">The reversibility guarantee</div>
20817- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
20818- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
20819 policy, not promise. Our quality numbers are published live, unedited.</p>
20820- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
20821- </div>
20822- </div>
20823- </section>
20824-
20825- {/* Quote */}
20826- <section class="lv-quote">
20827- <div class="lv-quote-inner">
20828- <p class="lv-quote-text">
20829- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
20830- Gluecron is where code gets <em class="lv-em">finished</em>."
20831- </p>
20832- </div>
20833- </section>
20834-
20835- {/* CTA */}
20836- <section class="lv-cta-section">
20837- <div class="lv-cta-card">
20838- <div class="lv-cta-glow"></div>
20839- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
20840- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
20841- <div class="lv-cta-actions">
20842- <a href="/register" class="lv-cta-primary">Create your account �!</a>
20843- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
20844- </div>
20845- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
20846- </div>
20847- </section>
20848-
20849- {/* Footer */}
20850- <footer class="lv-footer">
20851- <div class="lv-footer-inner">
20852- <div class="lv-footer-brand">
20853- <a href="/" class="lv-logo">
20854- <span class="lv-logo-mark"></span>gluecron
20855- </a>
20856- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
20857- </div>
20858- <div class="lv-footer-cols">
20859- <div class="lv-footer-col">
20860- <h4 class="lv-footer-col-head">Product</h4>
20861- <a href="/" class="lv-footer-link">Agent workspace</a>
20862- <a href="/" class="lv-footer-link">Fleet refactors</a>
20863- <a href="/" class="lv-footer-link">Org memory</a>
20864- <a href="/" class="lv-footer-link">IDE extensions</a>
20865- </div>
20866- <div class="lv-footer-col">
20867- <h4 class="lv-footer-col-head">Platform</h4>
20868- <a href="/" class="lv-footer-link">Production layers</a>
20869- <a href="/trust" class="lv-footer-link">Trust report</a>
20870- <a href="/" class="lv-footer-link">Docs</a>
20871- <a href="/" class="lv-footer-link">Status</a>
20872- </div>
20873- <div class="lv-footer-col">
20874- <h4 class="lv-footer-col-head">Company</h4>
20875- <a href="/" class="lv-footer-link">About</a>
20876- <a href="/" class="lv-footer-link">Pricing</a>
20877- <a href="/" class="lv-footer-link">Enterprise</a>
20878- </div>
20879- </div>
20880- </div>
20881- <div class="lv-footer-bar">
20882- <span>� 2026 Gluecron</span>
20883- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
20884- </div>
20885- </footer>
20886-
20887- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
20888- </>
20889- );
20890-};
20891-
20892-export const LandingPage = LandingPageV2;
20893-export default LandingPageV2;
20894-
20895-const clientScript = `
20896-(function() {
20897- var demoAll = [
20898- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
20899- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
20900- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
20901- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
20902- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
20903- ];
20904-
20905- var demoStep = 0;
20906- var stage = 0;
20907-
20908- function renderDemo() {
20909- var container = document.getElementById('lv-demo-body');
20910- if (!container) return;
20911- var visible = demoAll.slice(0, demoStep + 1);
20912- container.innerHTML = visible.map(function(e, i) {
20913- var isLast = i === visible.length - 1;
20914- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
20915- return '<div class="lv-demo-event">' +
20916- '<div class="lv-demo-event-track">' +
20917- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
20918- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
20919- '</div>' +
20920- '<div class="lv-demo-event-content">' +
20921- '<div class="lv-demo-event-header">' +
20922- '<span class="lv-demo-event-title">' + e.title + '</span>' +
20923- '<span class="lv-demo-event-time">' + e.time + '</span>' +
20924- '</div>' +
20925- '<div class="lv-demo-event-body">' + e.body + '</div>' +
20926- '</div>' +
20927- '</div>';
20928- }).join('');
20929- }
20930-
20931- function renderStages() {
20932- var cards = document.querySelectorAll('.lv-stage-card');
20933- cards.forEach(function(card, i) {
20934- var dot = card.querySelector('.lv-dot');
20935- var meta = card.querySelector('.lv-stage-meta');
20936- if (i === stage) {
20937- card.classList.add('lv-stage-active');
20938- if (dot) {
20939- dot.classList.remove('lv-dot-idle');
20940- dot.classList.add('lv-dot-indigo', 'lv-pulse');
20941- }
20942- if (meta) meta.classList.add('lv-stage-meta-active');
20943- } else {
20944- card.classList.remove('lv-stage-active');
20945- if (dot) {
20946- dot.classList.add('lv-dot-idle');
20947- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
20948- }
20949- if (meta) meta.classList.remove('lv-stage-meta-active');
20950- }
20951- });
20952- }
20953-
20954- renderDemo();
20955-
20956- setInterval(function() {
20957- demoStep = (demoStep + 1) % 5;
20958- renderDemo();
20959- }, 3600);
20960-
20961- setInterval(function() {
20962- stage = (stage + 1) % 6;
20963- renderStages();
20964- }, 2200);
20965-})();
20966-`;
20967-
20968-const css = `
20969-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
20970-
20971-*, *::before, *::after { box-sizing: border-box; }
20972-
20973-body {
20974- margin: 0;
20975- background: #fcfcfd;
20976- -webkit-font-smoothing: antialiased;
20977- text-rendering: optimizeLegibility;
20978- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
20979- font-size: 15px;
20980- line-height: 1.6;
20981- letter-spacing: -0.008em;
20982- color: #16181d;
20983-}
20984-
20985-@keyframes gcPulse {
20986- 0%, 100% { opacity: 1; }
20987- 50% { opacity: 0.35; }
20988-}
20989-
20990-@keyframes gcTicker {
20991- 0% { transform: translateX(0); }
20992- 100% { transform: translateX(-50%); }
20993-}
20994-
20995-/* Shared utilities */
20996-.lv-dot {
20997- display: inline-block;
20998- border-radius: 50%;
20999-}
21000-.lv-dot-green { background: #1e7f5c; }
21001-.lv-dot-indigo { background: #4353c9; }
21002-.lv-dot-idle { background: #c4c6cf; }
21003-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
21004-
21005-.lv-strong { color: #16181d; font-weight: 600; }
21006-
21007-.lv-eyebrow {
21008- font-family: 'JetBrains Mono', monospace;
21009- font-size: 11px;
21010- letter-spacing: 0.12em;
21011- text-transform: uppercase;
21012- color: #8a8d99;
21013- font-weight: 500;
21014- margin-bottom: 12px;
21015-}
21016-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
21017-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
21018-
21019-.lv-h1 {
21020- font-family: 'Inter Tight', sans-serif;
21021- font-weight: 700;
21022- letter-spacing: -0.035em;
21023- font-size: clamp(44px, 7vw, 84px);
21024- line-height: 0.98;
21025- margin: 30px auto 0;
21026- max-width: 14ch;
21027- color: #111318;
21028-}
21029-
21030-.lv-h2 {
21031- font-family: 'Inter Tight', sans-serif;
21032- font-weight: 700;
21033- letter-spacing: -0.028em;
21034- font-size: clamp(30px, 4.4vw, 48px);
21035- line-height: 1.05;
21036- margin: 0;
21037- color: #111318;
21038-}
21039-
21040-.lv-h2-dark {
21041- font-family: 'Inter Tight', sans-serif;
21042- font-weight: 700;
21043- letter-spacing: -0.028em;
21044- font-size: clamp(30px, 4.6vw, 52px);
21045- line-height: 1.05;
21046- margin: 0;
21047- color: #fff;
21048-}
21049-
21050-.lv-section-header {
21051- max-width: 640px;
21052- margin: 0 auto 56px;
21053-}
21054-
21055-.lv-section-header-center {
21056- text-align: center;
21057-}
21058-
21059-.lv-section-sub {
21060- color: #6b7080;
21061- font-size: 17px;
21062- margin: 18px auto 0;
21063- max-width: 52ch;
21064-}
21065-
21066-.lv-section-sub-dark {
21067- color: rgba(255,255,255,0.72);
21068- font-size: 17px;
21069- margin: 18px auto 0;
21070- max-width: 56ch;
21071-}
21072-
21073-/* Nav */
21074-.lv-nav {
21075- position: sticky;
21076- top: 0;
21077- z-index: 60;
21078- backdrop-filter: saturate(180%) blur(14px);
21079- -webkit-backdrop-filter: saturate(180%) blur(14px);
21080- background: rgba(252,252,253,0.8);
21081- border-bottom: 1px solid rgba(22,24,29,0.07);
21082-}
21083-
21084-.lv-nav-inner {
21085- max-width: 1200px;
21086- margin: 0 auto;
21087- padding: 14px 28px;
21088- display: flex;
21089- align-items: center;
21090- gap: 28px;
21091-}
21092-
21093-.lv-logo {
21094- display: inline-flex;
21095- align-items: center;
21096- gap: 9px;
21097- font-family: 'Inter Tight', sans-serif;
21098- font-weight: 700;
21099- font-size: 17px;
21100- letter-spacing: -0.02em;
21101- color: #16181d;
21102- text-decoration: none;
21103-}
21104-
21105-.lv-logo-mark {
21106- width: 17px;
21107- height: 17px;
21108- border-radius: 5px;
21109- background: #4353c9;
21110- display: inline-block;
21111- flex-shrink: 0;
21112-}
21113-
21114-.lv-nav-links {
21115- display: flex;
21116- gap: 24px;
21117- font-size: 13.5px;
21118- font-weight: 500;
21119-}
21120-
21121-.lv-nav-link {
21122- color: #6b7080;
21123- text-decoration: none;
21124- transition: color 0.15s;
21125-}
21126-.lv-nav-link:hover { color: #16181d; }
21127-
21128-.lv-nav-ctas {
21129- margin-left: auto;
21130- display: flex;
21131- align-items: center;
21132- gap: 10px;
21133-}
21134-
21135-.lv-btn-secondary {
21136- padding: 8px 15px;
21137- border-radius: 8px;
21138- font-size: 13.5px;
21139- font-weight: 500;
21140- color: #16181d;
21141- border: 1px solid rgba(22,24,29,0.12);
21142- background: #ffffff;
21143- text-decoration: none;
21144- white-space: nowrap;
21145- transition: border-color 0.15s;
21146-}
21147-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
21148-
21149-.lv-btn-primary {
21150- padding: 8px 15px;
21151- border-radius: 8px;
21152- font-size: 13.5px;
21153- font-weight: 600;
21154- background: #16181d;
21155- color: #fff;
21156- text-decoration: none;
21157- white-space: nowrap;
21158- transition: box-shadow 0.15s;
21159-}
21160-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
21161-
21162-/* Hero */
21163-.lv-hero {
21164- position: relative;
21165- overflow: hidden;
21166- padding: 88px 0 0;
21167-}
21168-
21169-.lv-hero-glow {
21170- position: absolute;
21171- inset: -10% 0 auto 0;
21172- height: 640px;
21173- pointer-events: none;
21174- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
21175-}
21176-
21177-.lv-hero-inner {
21178- position: relative;
21179- max-width: 1200px;
21180- margin: 0 auto;
21181- padding: 0 28px;
21182- text-align: center;
21183-}
21184-
21185-.lv-hero-badge {
21186- display: inline-flex;
21187- align-items: center;
21188- gap: 9px;
21189- font-size: 12.5px;
21190- font-weight: 600;
21191- color: #3a3d45;
21192- background: #ffffff;
21193- border: 1px solid rgba(22,24,29,0.10);
21194- border-radius: 9999px;
21195- padding: 7px 16px;
21196- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
21197-}
21198-
21199-.lv-hero-sub {
21200- font-size: clamp(16px, 2vw, 19px);
21201- color: #6b7080;
21202- max-width: 60ch;
21203- margin: 24px auto 0;
21204- font-weight: 450;
21205- line-height: 1.65;
21206-}
21207-
21208-.lv-hero-actions {
21209- display: flex;
21210- gap: 12px;
21211- justify-content: center;
21212- flex-wrap: wrap;
21213- margin-top: 32px;
21214-}
21215-
21216-.lv-cta-primary {
21217- padding: 13px 24px;
21218- border-radius: 11px;
21219- font-size: 15.5px;
21220- font-weight: 600;
21221- background: #16181d;
21222- color: #fff;
21223- text-decoration: none;
21224- white-space: nowrap;
21225- transition: box-shadow 0.15s;
21226-}
21227-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
21228-
21229-.lv-cta-secondary {
21230- padding: 13px 24px;
21231- border-radius: 11px;
21232- font-size: 15.5px;
21233- font-weight: 600;
21234- color: #16181d;
21235- border: 1px solid rgba(22,24,29,0.14);
21236- background: #ffffff;
21237- text-decoration: none;
21238- white-space: nowrap;
21239- transition: border-color 0.15s;
21240-}
21241-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
21242-
21243-.lv-hero-tag {
21244- margin-top: 18px;
21245- font-family: 'JetBrains Mono', monospace;
21246- font-size: 11.5px;
21247- letter-spacing: 0.08em;
21248- text-transform: uppercase;
21249- color: #8a8d99;
21250-}
21251-
21252-/* Demo window */
21253-.lv-demo-window {
21254- margin: 56px auto 0;
21255- max-width: 860px;
21256- text-align: left;
21257- background: #ffffff;
21258- border: 1px solid rgba(22,24,29,0.09);
21259- border-radius: 18px;
21260- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
21261- overflow: hidden;
21262-}
21263-
21264-.lv-demo-bar {
21265- display: flex;
21266- align-items: center;
21267- gap: 7px;
21268- padding: 12px 18px;
21269- border-bottom: 1px solid rgba(22,24,29,0.07);
21270- background: #fcfcfd;
21271-}
21272-
21273-.lv-demo-dot {
21274- width: 10px;
21275- height: 10px;
21276- border-radius: 50%;
21277- background: #e4e5ea;
21278-}
21279-
21280-.lv-demo-url {
21281- margin-left: 10px;
21282- font-family: 'JetBrains Mono', monospace;
21283- font-size: 12px;
21284- color: #6b7080;
21285-}
21286-
21287-.lv-demo-live {
21288- margin-left: auto;
21289- display: inline-flex;
21290- align-items: center;
21291- gap: 6px;
21292- font-size: 11px;
21293- font-weight: 600;
21294- color: #1e7f5c;
21295-}
21296-
21297-.lv-demo-body {
21298- padding: 22px 24px;
21299-}
21300-
21301-.lv-demo-event {
21302- display: grid;
21303- grid-template-columns: 18px minmax(0, 1fr);
21304- gap: 14px;
21305- padding-bottom: 20px;
21306- position: relative;
21307-}
21308-.lv-demo-event:last-child { padding-bottom: 0; }
21309-
21310-.lv-demo-event-track {
21311- display: flex;
21312- flex-direction: column;
21313- align-items: center;
21314-}
21315-
21316-.lv-demo-line {
21317- width: 1px;
21318- flex: 1;
21319- background: rgba(22,24,29,0.08);
21320- margin-top: 5px;
21321- min-height: 20px;
21322-}
21323-
21324-.lv-demo-event-content {}
21325-
21326-.lv-demo-event-header {
21327- display: flex;
21328- align-items: baseline;
21329- gap: 10px;
21330-}
21331-
21332-.lv-demo-event-title {
21333- font-size: 13.5px;
21334- font-weight: 600;
21335- color: #16181d;
21336-}
21337-
21338-.lv-demo-event-time {
21339- font-family: 'JetBrains Mono', monospace;
21340- font-size: 11px;
21341- color: #8a8d99;
21342-}
21343-
21344-.lv-demo-event-body {
21345- font-size: 13px;
21346- color: #6b7080;
21347- margin-top: 2px;
21348-}
21349-
21350-/* Ticker */
21351-.lv-ticker-wrap {
21352- border-top: 1px solid rgba(22,24,29,0.07);
21353- border-bottom: 1px solid rgba(22,24,29,0.07);
21354- background: #ffffff;
21355- margin-top: 64px;
21356- overflow: hidden;
21357- white-space: nowrap;
21358- position: relative;
21359-}
21360-
21361-.lv-ticker-track {
21362- display: inline-flex;
21363- animation: gcTicker 40s linear infinite;
21364- padding: 11px 0;
21365-}
21366-
21367-.lv-ticker-item {
21368- display: inline-flex;
21369- align-items: center;
21370- gap: 8px;
21371- font-family: 'JetBrains Mono', monospace;
21372- font-size: 11.5px;
21373- color: #6b7080;
21374- padding: 0 28px;
21375- border-right: 1px solid rgba(22,24,29,0.06);
21376-}
21377-
21378-/* Stats */
21379-.lv-stats {
21380- background: #fcfcfd;
21381-}
21382-
21383-.lv-stats-inner {
21384- max-width: 1200px;
21385- margin: 0 auto;
21386- display: grid;
21387- grid-template-columns: repeat(4, 1fr);
21388- gap: 24px;
21389- padding: 52px 28px;
21390-}
21391-
21392-.lv-stat {
21393- text-align: center;
21394-}
21395-
21396-.lv-stat-num {
21397- font-family: 'Inter Tight', sans-serif;
21398- font-weight: 700;
21399- font-size: clamp(30px, 4vw, 44px);
21400- letter-spacing: -0.025em;
21401- color: #111318;
21402-}
21403-
21404-.lv-stat-label {
21405- font-size: 13px;
21406- color: #6b7080;
21407- margin-top: 4px;
21408-}
21409-
21410-/* Loop */
21411-.lv-loop {
21412- padding: 96px 0;
21413- background: #ffffff;
21414- border-top: 1px solid rgba(22,24,29,0.07);
21415- border-bottom: 1px solid rgba(22,24,29,0.07);
21416-}
21417-
21418-.lv-loop-inner {
21419- max-width: 1200px;
21420- margin: 0 auto;
21421- padding: 0 28px;
21422-}
21423-
21424-.lv-stages {
21425- display: grid;
21426- grid-template-columns: repeat(6, 1fr);
21427- gap: 12px;
21428-}
21429-
21430-.lv-stage-card {
21431- border: 1px solid rgba(22,24,29,0.08);
21432- border-radius: 14px;
21433- background: #ffffff;
21434- padding: 20px 18px;
21435- transition: border-color 0.3s, background 0.3s;
21436-}
21437-
21438-.lv-stage-card.lv-stage-active {
21439- border-color: rgba(67,83,201,0.45);
21440- background: rgba(67,83,201,0.03);
21441-}
21442-
21443-.lv-stage-header {
21444- display: flex;
21445- align-items: center;
21446- gap: 8px;
21447- margin-bottom: 10px;
21448-}
21449-
21450-.lv-stage-n {
21451- font-family: 'JetBrains Mono', monospace;
21452- font-size: 10.5px;
21453- letter-spacing: 0.1em;
21454- text-transform: uppercase;
21455- color: #8a8d99;
21456-}
21457-
21458-.lv-stage-name {
21459- font-family: 'Inter Tight', sans-serif;
21460- font-size: 16px;
21461- font-weight: 600;
21462- letter-spacing: -0.01em;
21463- color: #16181d;
21464- margin-bottom: 5px;
21465-}
21466-
21467-.lv-stage-desc {
21468- font-size: 12px;
21469- color: #6b7080;
21470- line-height: 1.55;
21471-}
21472-
21473-.lv-stage-meta {
21474- font-family: 'JetBrains Mono', monospace;
21475- font-size: 10.5px;
21476- color: #8a8d99;
21477- margin-top: 10px;
21478- transition: color 0.3s;
21479-}
21480-
21481-.lv-stage-meta.lv-stage-meta-active {
21482- color: #4353c9;
21483-}
21484-
21485-/* Heroes */
21486-.lv-heroes {
21487- padding: 96px 0;
21488- background: #fcfcfd;
21489-}
21490-
21491-.lv-heroes-inner {
21492- max-width: 1200px;
21493- margin: 0 auto;
21494- padding: 0 28px;
21495-}
21496-
21497-.lv-heroes-header {
21498- max-width: 640px;
21499- margin-bottom: 56px;
21500-}
21501-
21502-.lv-heroes-list {
21503- display: flex;
21504- flex-direction: column;
21505- gap: 20px;
21506-}
21507-
21508-.lv-hero-card {
21509- display: grid;
21510- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
21511- gap: 48px;
21512- align-items: center;
21513- border: 1px solid rgba(22,24,29,0.08);
21514- border-radius: 20px;
21515- background: #ffffff;
21516- padding: 44px 48px;
21517- text-decoration: none;
21518- transition: border-color 0.2s, box-shadow 0.2s;
21519-}
21520-.lv-hero-card:hover {
21521- border-color: rgba(22,24,29,0.22);
21522- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
21523-}
21524-
21525-.lv-hero-card-left {}
21526-
21527-.lv-hero-card-title {
21528- font-family: 'Inter Tight', sans-serif;
21529- font-size: 26px;
21530- font-weight: 600;
21531- letter-spacing: -0.022em;
21532- line-height: 1.15;
21533- color: #16181d;
21534- margin: 0 0 12px;
21535-}
21536-
21537-.lv-hero-card-body {
21538- font-size: 14.5px;
21539- color: #6b7080;
21540- margin: 0 0 18px;
21541- line-height: 1.65;
21542-}
21543-
21544-.lv-hero-card-cta {
21545- font-size: 13.5px;
21546- font-weight: 600;
21547- color: #4353c9;
21548-}
21549-
21550-.lv-terminal {
21551- border: 1px solid rgba(22,24,29,0.07);
21552- border-radius: 14px;
21553- background: #fcfcfd;
21554- padding: 20px 22px;
21555- font-family: 'JetBrains Mono', monospace;
21556- font-size: 12px;
21557- line-height: 1.9;
21558- overflow: hidden;
21559-}
21560-
21561-.lv-terminal-line {
21562- display: flex;
21563- align-items: center;
21564- gap: 10px;
21565- white-space: nowrap;
21566- overflow: hidden;
21567- text-overflow: ellipsis;
21568-}
21569-
21570-/* Platform */
21571-.lv-platform {
21572- padding: 96px 0;
21573- background: #ffffff;
21574- border-top: 1px solid rgba(22,24,29,0.07);
21575-}
21576-
21577-.lv-platform-inner {
21578- max-width: 1200px;
21579- margin: 0 auto;
21580- padding: 0 28px;
21581-}
21582-
21583-.lv-cap-grid {
21584- display: grid;
21585- grid-template-columns: repeat(4, 1fr);
21586- gap: 24px 32px;
21587-}
21588-
21589-.lv-cap-col {}
21590-
21591-.lv-cap-group {
21592- font-family: 'JetBrains Mono', monospace;
21593- font-size: 10.5px;
21594- letter-spacing: 0.12em;
21595- text-transform: uppercase;
21596- color: #8a8d99;
21597- font-weight: 500;
21598- margin-bottom: 12px;
21599- padding-bottom: 8px;
21600- border-bottom: 1px solid rgba(22,24,29,0.07);
21601-}
21602-
21603-.lv-cap-items {
21604- display: flex;
21605- flex-direction: column;
21606- gap: 7px;
21607-}
21608-
21609-.lv-cap-item {
21610- font-size: 12.5px;
21611- color: #3a3d45;
21612- line-height: 1.45;
21613-}
21614-
21615-/* Sovereignty */
21616-.lv-sovereign {
21617- position: relative;
21618- overflow: hidden;
21619- padding: 104px 0;
21620- color: #fff;
21621- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
21622-}
21623-
21624-.lv-sovereign-grid-bg {
21625- position: absolute;
21626- inset: 0;
21627- opacity: 0.4;
21628- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
21629- background-size: 56px 56px;
21630- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
21631- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
21632-}
21633-
21634-.lv-sovereign-inner {
21635- position: relative;
21636- max-width: 1200px;
21637- margin: 0 auto;
21638- padding: 0 28px;
21639-}
21640-
21641-.lv-section-header-dark {
21642- max-width: 680px;
21643- margin: 0 auto 48px;
21644- text-align: center;
21645-}
21646-
21647-.lv-layers-grid {
21648- display: grid;
21649- grid-template-columns: repeat(4, 1fr);
21650- gap: 10px;
21651- max-width: 980px;
21652- margin: 0 auto;
21653-}
21654-
21655-.lv-layer-chip {
21656- border: 1px solid rgba(255,255,255,0.10);
21657- border-radius: 10px;
21658- padding: 12px 16px;
21659- background: rgba(255,255,255,0.03);
21660-}
21661-
21662-.lv-layer-cta {
21663- border-color: rgba(169,180,238,0.30);
21664- background: rgba(169,180,238,0.06);
21665- display: flex;
21666- align-items: center;
21667- text-decoration: none;
21668- transition: background 0.15s;
21669-}
21670-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
21671-
21672-.lv-layer-cta-text {
21673- font-size: 13px;
21674- font-weight: 500;
21675- color: #a9b4ee;
21676-}
21677-
21678-.lv-layer-n {
21679- font-family: 'JetBrains Mono', monospace;
21680- font-size: 10px;
21681- color: rgba(255,255,255,0.4);
21682- margin-bottom: 3px;
21683-}
21684-
21685-.lv-layer-name {
21686- font-size: 13px;
21687- font-weight: 500;
21688- color: rgba(255,255,255,0.92);
21689-}
21690-
21691-.lv-sovereign-feats {
21692- display: flex;
21693- gap: 44px;
21694- justify-content: center;
21695- flex-wrap: wrap;
21696- margin-top: 52px;
21697- text-align: center;
21698-}
21699-
21700-.lv-sovereign-feat {}
21701-
21702-.lv-sovereign-feat-title {
21703- font-family: 'Inter Tight', sans-serif;
21704- font-size: 20px;
21705- font-weight: 700;
21706- color: #fff;
21707-}
21708-
21709-.lv-sovereign-feat-sub {
21710- color: rgba(255,255,255,0.55);
21711- font-size: 13px;
21712- margin-top: 2px;
21713-}
21714-
21715-/* Twin cards */
21716-.lv-twin {
21717- padding: 96px 0;
21718- background: #fcfcfd;
21719-}
21720-
21721-.lv-twin-inner {
21722- max-width: 1200px;
21723- margin: 0 auto;
21724- padding: 0 28px;
21725- display: grid;
21726- grid-template-columns: 1fr 1fr;
21727- gap: 24px;
21728-}
21729-
21730-.lv-twin-card {
21731- border: 1px solid rgba(22,24,29,0.08);
21732- border-radius: 20px;
21733- background: #ffffff;
21734- padding: 44px 48px;
21735-}
21736-
21737-.lv-twin-title {
21738- font-family: 'Inter Tight', sans-serif;
21739- font-size: 24px;
21740- font-weight: 600;
21741- letter-spacing: -0.02em;
21742- line-height: 1.2;
21743- margin: 0 0 12px;
21744- color: #16181d;
21745-}
21746-
21747-.lv-twin-body {
21748- font-size: 14.5px;
21749- color: #6b7080;
21750- margin: 0 0 16px;
21751- line-height: 1.7;
21752-}
21753-
21754-.lv-twin-link {
21755- font-size: 13.5px;
21756- font-weight: 600;
21757- color: #4353c9;
21758- text-decoration: none;
21759-}
21760-.lv-twin-link:hover { text-decoration: underline; }
21761-
21762-/* Quote */
21763-.lv-quote {
21764- padding: 40px 0 96px;
21765- background: #fcfcfd;
21766-}
21767-
21768-.lv-quote-inner {
21769- max-width: 980px;
21770- margin: 0 auto;
21771- padding: 0 28px;
21772- text-align: center;
21773-}
21774-
21775-.lv-quote-text {
21776- font-family: 'Inter Tight', sans-serif;
21777- font-weight: 600;
21778- font-size: clamp(26px, 3.8vw, 42px);
21779- line-height: 1.2;
21780- letter-spacing: -0.025em;
21781- margin: 0;
21782- color: #111318;
21783-}
21784-
21785-.lv-em {
21786- font-style: normal;
21787- color: #4353c9;
21788-}
21789-
21790-/* CTA */
21791-.lv-cta-section {
21792- padding: 0 0 104px;
21793- background: #fcfcfd;
21794-}
21795-
21796-.lv-cta-card {
21797- max-width: 820px;
21798- margin: 0 auto;
21799- padding: 64px 40px;
21800- text-align: center;
21801- background: #ffffff;
21802- border: 1px solid rgba(22,24,29,0.08);
21803- border-radius: 26px;
21804- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
21805- position: relative;
21806- overflow: hidden;
21807-}
21808-
21809-.lv-cta-glow {
21810- position: absolute;
21811- inset: -40% 0 auto 0;
21812- height: 280px;
21813- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
21814- pointer-events: none;
21815-}
21816-
21817-.lv-cta-h2 {
21818- font-family: 'Inter Tight', sans-serif;
21819- font-weight: 700;
21820- letter-spacing: -0.028em;
21821- font-size: clamp(30px, 4.6vw, 48px);
21822- margin: 0;
21823- position: relative;
21824- color: #111318;
21825-}
21826-
21827-.lv-cta-sub {
21828- color: #6b7080;
21829- font-size: 17px;
21830- margin: 16px 0 30px;
21831- position: relative;
21832-}
21833-
21834-.lv-cta-actions {
21835- display: flex;
21836- gap: 12px;
21837- justify-content: center;
21838- flex-wrap: wrap;
21839- position: relative;
21840-}
21841-
21842-.lv-cta-fine {
21843- margin-top: 20px;
21844- font-family: 'JetBrains Mono', monospace;
21845- font-size: 11px;
21846- color: #8a8d99;
21847- position: relative;
21848-}
21849-
21850-/* Footer */
21851-.lv-footer {
21852- border-top: 1px solid rgba(22,24,29,0.07);
21853- background: #ffffff;
21854- padding: 56px 0 30px;
21855-}
21856-
21857-.lv-footer-inner {
21858- max-width: 1200px;
21859- margin: 0 auto;
21860- padding: 0 28px;
21861- display: flex;
21862- gap: 48px;
21863- flex-wrap: wrap;
21864- justify-content: space-between;
21865-}
21866-
21867-.lv-footer-brand {}
21868-
21869-.lv-footer-tagline {
21870- color: #6b7080;
21871- font-size: 13.5px;
21872- margin: 12px 0 0;
21873- max-width: 32ch;
21874- line-height: 1.6;
21875-}
21876-
21877-.lv-footer-cols {
21878- display: flex;
21879- gap: 64px;
21880- flex-wrap: wrap;
21881-}
21882-
21883-.lv-footer-col {
21884- display: flex;
21885- flex-direction: column;
21886- gap: 9px;
21887-}
21888-
21889-.lv-footer-col-head {
21890- font-family: 'JetBrains Mono', monospace;
21891- font-size: 11px;
21892- text-transform: uppercase;
21893- letter-spacing: 0.1em;
21894- color: #8a8d99;
21895- margin: 0 0 4px;
21896- font-weight: 500;
21897-}
21898-
21899-.lv-footer-link {
21900- color: #3a3d45;
21901- font-size: 13.5px;
21902- text-decoration: none;
21903- transition: color 0.15s;
21904-}
21905-.lv-footer-link:hover { color: #16181d; }
21906-
21907-.lv-footer-bar {
21908- max-width: 1200px;
21909- margin: 44px auto 0;
21910- padding: 22px 28px 0;
21911- border-top: 1px solid rgba(22,24,29,0.06);
21912- display: flex;
21913- justify-content: space-between;
21914- flex-wrap: wrap;
21915- gap: 8px;
21916- color: #8a8d99;
21917- font-size: 12.5px;
21918-}
21919-
21920-.lv-footer-stack {
21921- font-family: 'JetBrains Mono', monospace;
21922- font-size: 11px;
21923-}
21924-`;
21925diff --git a/src/views/layout.tsx b/src/views/layout.tsx
21926index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
21927--- a/src/views/layout.tsx
21928+++ b/src/views/layout.tsx
21929@@ -3153,9 +3153,12 @@
21930 font-weight: 500;
21931 line-height: 1.4;
21932 }
21933- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
21934- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
21935- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
21936+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
21937+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
21938+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
21939+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
21940+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
21941+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
21942 .state-merged { color: var(--accent); }
21943 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
21944
21945diff --git a/src/views/ui.tsx b/src/views/ui.tsx
21946index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
21947--- a/src/views/ui.tsx
21948+++ b/src/views/ui.tsx
21949@@ -232,7 +232,7 @@
21950
21951 export const Badge: FC<
21952 PropsWithChildren<{
21953- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
21954+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
21955 style?: string;
21956 }>
21957 > = ({ children, variant = "default", style }) => {
21958@@ -241,9 +241,12 @@
21959 variant === "closed" ? "badge-closed" :
21960 variant === "merged" ? "badge-merged" :
21961 variant === "success" ? "badge-success" :
21962- variant === "danger" ? "badge-danger" :
21963- variant === "warning" ? "badge-warning" :
21964- "badge";
21965+ variant === "danger" ? "badge-danger" :
21966+ variant === "warning" ? "badge-warning" :
21967+ variant === "live" ? "badge-live" :
21968+ variant === "soon" ? "badge-soon" :
21969+ variant === "preview" ? "badge-preview" :
21970+ "badge";
21971 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
21972 };
21973
21974
21975diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
21976index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
21977--- a/src/views/landing-pro.tsx
21978+++ b/src/views/landing-pro.tsx
21979@@ -42,7 +42,7 @@
21980
21981 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21982
21983-function icon(paths: string, color = "#4353c9", size = 20) {
21984+function icon(paths: string, color = "#0891b2", size = 20) {
21985 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
21986 }
21987
21988@@ -947,7 +947,7 @@
21989 const css = `
21990 /* %% tokens %% */
21991 :root{
21992- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
21993+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
21994 --lp-bg:#ffffff;--lp-soft:#fafafb;
21995 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
21996 --lp-border:rgba(0,0,0,.08);
21997diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
21998deleted file mode 100644
21999index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
22000--- a/src/views/landing-v2.tsx
22001+++ /dev/null
22002@@ -1,1447 +0,0 @@
22003-import type { FC } from "hono/jsx";
22004-
22005-export interface LandingPageProps {
22006- stats?: {
22007- publicRepos?: number;
22008- users?: number;
22009- };
22010-}
22011-
22012-const demoAllEvents = [
22013- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
22014- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
22015- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
22016- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
22017- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
22018-];
22019-
22020-const tickerItems = [
22021- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
22022- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
22023- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
22024- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
22025- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
22026- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
22027- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
22028- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
22029- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
22030- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
22031- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
22032- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
22033- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
22034- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
22035- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
22036- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
22037-];
22038-
22039-const stageData = [
22040- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
22041- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
22042- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
22043- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
22044- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
22045- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
22046-];
22047-
22048-const heroFeatures = [
22049- {
22050- href: "/",
22051- eyebrow: "01 � The autonomous repair loop",
22052- title: "Failures fix themselves  and show their work.",
22053- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
22054failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
22055- cta: "Watch a live repair session",
22056- mock: [
22057- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
22058- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
22059- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
22060- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
22061- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
22062- ],
22063- },
22064- {
22065- href: "/",
22066- eyebrow: "02 � Live sandbox isolation",
22067- title: "Every PR gets its own instant, disposable environment.",
22068- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
22069same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
22070- cta: "See a PR with its sandbox",
22071- mock: [
22072- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
22073- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
22074- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
22075- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
22076- ],
22077- },
22078- {
22079- href: "/",
22080- eyebrow: "03 � Multiplayer IDE workspaces",
22081- title: "You and the agent, side by side, in your editor.",
22082- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
22083agent into a silent reviewer in your gutter. The browser becomes optional.",
22084- cta: "See the editor session",
22085- mock: [
22086- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
22087- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
22088- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
22089- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
22090- ],
22091- },
22092-];
22093-
22094-const capabilities = [
22095- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
22096- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
22097- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
22098- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
22099- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
22100- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
22101- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
22102- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
22103-];
22104-
22105-const sovereignLayerNames = [
22106- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
22107- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
22108- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
22109- "Availability & recovery",
22110-];
22111-
22112-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
22113- return (
22114- <>
22115- <style dangerouslySetInnerHTML={{ __html: css }} />
22116-
22117- {/* Nav */}
22118- <header class="lv-nav">
22119- <div class="lv-nav-inner">
22120- <a href="/" class="lv-logo">
22121- <span class="lv-logo-mark"></span>gluecron
22122- </a>
22123- <nav class="lv-nav-links">
22124- <a href="#loop" class="lv-nav-link">The loop</a>
22125- <a href="#platform" class="lv-nav-link">Platform</a>
22126- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
22127- <a href="/trust" class="lv-nav-link">Trust</a>
22128- </nav>
22129- <div class="lv-nav-ctas">
22130- <a href="/login" class="lv-btn-secondary">Sign in</a>
22131- <a href="/register" class="lv-btn-primary">Start building</a>
22132- </div>
22133- </div>
22134- </header>
22135-
22136- {/* Hero */}
22137- <section class="lv-hero">
22138- <div class="lv-hero-glow"></div>
22139- <div class="lv-hero-inner">
22140- <div class="lv-hero-badge">
22141- <span class="lv-dot lv-dot-green lv-pulse"></span>
22142- Live: a repair loop converged on pr-218 while you read this
22143- </div>
22144- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
22145- <p class="lv-hero-sub">
22146- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
22147failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
22148- </p>
22149- <div class="lv-hero-actions">
22150- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
22151- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
22152- </div>
22153- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
22154-
22155- {/* Live product window */}
22156- <div class="lv-demo-window">
22157- <div class="lv-demo-bar">
22158- <span class="lv-demo-dot"></span>
22159- <span class="lv-demo-dot"></span>
22160- <span class="lv-demo-dot"></span>
22161- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
22162- <span class="lv-demo-live">
22163- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
22164- LIVE
22165- </span>
22166- </div>
22167- <div class="lv-demo-body" id="lv-demo-body">
22168- {/* Events rendered by JS */}
22169- {demoAllEvents.slice(0, 1).map((e, i) => (
22170- <div class="lv-demo-event" key={i}>
22171- <div class="lv-demo-event-track">
22172- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
22173- <span class="lv-demo-line" style="display:none"></span>
22174- </div>
22175- <div class="lv-demo-event-content">
22176- <div class="lv-demo-event-header">
22177- <span class="lv-demo-event-title">{e.title}</span>
22178- <span class="lv-demo-event-time">{e.time}</span>
22179- </div>
22180- <div class="lv-demo-event-body">{e.body}</div>
22181- </div>
22182- </div>
22183- ))}
22184- </div>
22185- </div>
22186- </div>
22187-
22188- {/* Activity ticker */}
22189- <div class="lv-ticker-wrap">
22190- <div class="lv-ticker-track">
22191- {tickerItems.map((t, i) => (
22192- <span class="lv-ticker-item" key={i}>
22193- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
22194- {t.text}
22195- </span>
22196- ))}
22197- </div>
22198- </div>
22199- </section>
22200-
22201- {/* Stat band */}
22202- <section class="lv-stats">
22203- <div class="lv-stats-inner">
22204- <div class="lv-stat">
22205- <div class="lv-stat-num">Sonnet 5</div>
22206- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
22207- </div>
22208- <div class="lv-stat">
22209- <div class="lv-stat-num">93.5%</div>
22210- <div class="lv-stat-label">of failures self-repair without a human</div>
22211- </div>
22212- <div class="lv-stat">
22213- <div class="lv-stat-num">1.9%</div>
22214- <div class="lv-stat-label">AI merges reverted  published live</div>
22215- </div>
22216- <div class="lv-stat">
22217- <div class="lv-stat-num">0</div>
22218- <div class="lv-stat-label">irreversible actions taken autonomously</div>
22219- </div>
22220- </div>
22221- </section>
22222-
22223- {/* The loop */}
22224- <section id="loop" class="lv-loop">
22225- <div class="lv-loop-inner">
22226- <div class="lv-section-header">
22227- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
22228- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
22229- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
22230- </div>
22231- <div class="lv-stages" id="lv-stages">
22232- {stageData.map((s, i) => (
22233- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
22234- <div class="lv-stage-header">
22235- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
22236- <span class="lv-stage-n">0{i + 1}</span>
22237- </div>
22238- <div class="lv-stage-name">{s.name}</div>
22239- <div class="lv-stage-desc">{s.desc}</div>
22240- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
22241- </div>
22242- ))}
22243- </div>
22244- </div>
22245- </section>
22246-
22247- {/* Three heroes */}
22248- <section class="lv-heroes">
22249- <div class="lv-heroes-inner">
22250- <div class="lv-heroes-header">
22251- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
22252- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
22253- </div>
22254- <div class="lv-heroes-list">
22255- {heroFeatures.map((h, i) => (
22256- <a href={h.href} class="lv-hero-card" key={i}>
22257- <div class="lv-hero-card-left">
22258- <div class="lv-eyebrow">{h.eyebrow}</div>
22259- <h3 class="lv-hero-card-title">{h.title}</h3>
22260- <p class="lv-hero-card-body">{h.body}</p>
22261- <span class="lv-hero-card-cta">{h.cta} �!</span>
22262- </div>
22263- <div class="lv-terminal">
22264- {h.mock.map((m, j) => (
22265- <div class="lv-terminal-line" key={j}>
22266- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
22267- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
22268- </div>
22269- ))}
22270- </div>
22271- </a>
22272- ))}
22273- </div>
22274- </div>
22275- </section>
22276-
22277- {/* Everything grid */}
22278- <section id="platform" class="lv-platform">
22279- <div class="lv-platform-inner">
22280- <div class="lv-section-header lv-section-header-center">
22281- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
22282- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
22283- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
22284- </div>
22285- <div class="lv-cap-grid">
22286- {capabilities.map((c, i) => (
22287- <div class="lv-cap-col" key={i}>
22288- <div class="lv-cap-group">{c.group}</div>
22289- <div class="lv-cap-items">
22290- {c.items.map((item, j) => (
22291- <div class="lv-cap-item" key={j}>{item}</div>
22292- ))}
22293- </div>
22294- </div>
22295- ))}
22296- </div>
22297- </div>
22298- </section>
22299-
22300- {/* Sovereignty band */}
22301- <section id="sovereign" class="lv-sovereign">
22302- <div class="lv-sovereign-grid-bg"></div>
22303- <div class="lv-sovereign-inner">
22304- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
22305- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
22306- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
22307- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
22308to private cloud, or run fully air-gapped on bare metal.</p>
22309- </div>
22310- <div class="lv-layers-grid">
22311- {sovereignLayerNames.map((name, i) => (
22312- <div class="lv-layer-chip" key={i}>
22313- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
22314- <div class="lv-layer-name">{name}</div>
22315- </div>
22316- ))}
22317- <a href="/" class="lv-layer-chip lv-layer-cta">
22318- <div class="lv-layer-cta-text">All self-owned �!</div>
22319- </a>
22320- </div>
22321- <div class="lv-sovereign-feats">
22322- <div class="lv-sovereign-feat">
22323- <div class="lv-sovereign-feat-title">Local inference first</div>
22324- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
22325- </div>
22326- <div class="lv-sovereign-feat">
22327- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
22328- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
22329- </div>
22330- <div class="lv-sovereign-feat">
22331- <div class="lv-sovereign-feat-title">Self-healing infra</div>
22332- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
22333- </div>
22334- </div>
22335- </div>
22336- </section>
22337-
22338- {/* Manual-first + reversibility */}
22339- <section class="lv-twin">
22340- <div class="lv-twin-inner">
22341- <div class="lv-twin-card">
22342- <div class="lv-eyebrow">Manual-first, always</div>
22343- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
22344- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
22345fallback. Developers who never touch AI get the best git host they've ever used.</p>
22346- </div>
22347- <div class="lv-twin-card">
22348- <div class="lv-eyebrow">The reversibility guarantee</div>
22349- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
22350- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
22351 policy, not promise. Our quality numbers are published live, unedited.</p>
22352- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
22353- </div>
22354- </div>
22355- </section>
22356-
22357- {/* Quote */}
22358- <section class="lv-quote">
22359- <div class="lv-quote-inner">
22360- <p class="lv-quote-text">
22361- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
22362- Gluecron is where code gets <em class="lv-em">finished</em>."
22363- </p>
22364- </div>
22365- </section>
22366-
22367- {/* CTA */}
22368- <section class="lv-cta-section">
22369- <div class="lv-cta-card">
22370- <div class="lv-cta-glow"></div>
22371- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
22372- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
22373- <div class="lv-cta-actions">
22374- <a href="/register" class="lv-cta-primary">Create your account �!</a>
22375- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
22376- </div>
22377- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
22378- </div>
22379- </section>
22380-
22381- {/* Footer */}
22382- <footer class="lv-footer">
22383- <div class="lv-footer-inner">
22384- <div class="lv-footer-brand">
22385- <a href="/" class="lv-logo">
22386- <span class="lv-logo-mark"></span>gluecron
22387- </a>
22388- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
22389- </div>
22390- <div class="lv-footer-cols">
22391- <div class="lv-footer-col">
22392- <h4 class="lv-footer-col-head">Product</h4>
22393- <a href="/" class="lv-footer-link">Agent workspace</a>
22394- <a href="/" class="lv-footer-link">Fleet refactors</a>
22395- <a href="/" class="lv-footer-link">Org memory</a>
22396- <a href="/" class="lv-footer-link">IDE extensions</a>
22397- </div>
22398- <div class="lv-footer-col">
22399- <h4 class="lv-footer-col-head">Platform</h4>
22400- <a href="/" class="lv-footer-link">Production layers</a>
22401- <a href="/trust" class="lv-footer-link">Trust report</a>
22402- <a href="/" class="lv-footer-link">Docs</a>
22403- <a href="/" class="lv-footer-link">Status</a>
22404- </div>
22405- <div class="lv-footer-col">
22406- <h4 class="lv-footer-col-head">Company</h4>
22407- <a href="/" class="lv-footer-link">About</a>
22408- <a href="/" class="lv-footer-link">Pricing</a>
22409- <a href="/" class="lv-footer-link">Enterprise</a>
22410- </div>
22411- </div>
22412- </div>
22413- <div class="lv-footer-bar">
22414- <span>� 2026 Gluecron</span>
22415- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
22416- </div>
22417- </footer>
22418-
22419- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
22420- </>
22421- );
22422-};
22423-
22424-export const LandingPage = LandingPageV2;
22425-export default LandingPageV2;
22426-
22427-const clientScript = `
22428-(function() {
22429- var demoAll = [
22430- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
22431- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
22432- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
22433- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
22434- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
22435- ];
22436-
22437- var demoStep = 0;
22438- var stage = 0;
22439-
22440- function renderDemo() {
22441- var container = document.getElementById('lv-demo-body');
22442- if (!container) return;
22443- var visible = demoAll.slice(0, demoStep + 1);
22444- container.innerHTML = visible.map(function(e, i) {
22445- var isLast = i === visible.length - 1;
22446- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
22447- return '<div class="lv-demo-event">' +
22448- '<div class="lv-demo-event-track">' +
22449- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
22450- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
22451- '</div>' +
22452- '<div class="lv-demo-event-content">' +
22453- '<div class="lv-demo-event-header">' +
22454- '<span class="lv-demo-event-title">' + e.title + '</span>' +
22455- '<span class="lv-demo-event-time">' + e.time + '</span>' +
22456- '</div>' +
22457- '<div class="lv-demo-event-body">' + e.body + '</div>' +
22458- '</div>' +
22459- '</div>';
22460- }).join('');
22461- }
22462-
22463- function renderStages() {
22464- var cards = document.querySelectorAll('.lv-stage-card');
22465- cards.forEach(function(card, i) {
22466- var dot = card.querySelector('.lv-dot');
22467- var meta = card.querySelector('.lv-stage-meta');
22468- if (i === stage) {
22469- card.classList.add('lv-stage-active');
22470- if (dot) {
22471- dot.classList.remove('lv-dot-idle');
22472- dot.classList.add('lv-dot-indigo', 'lv-pulse');
22473- }
22474- if (meta) meta.classList.add('lv-stage-meta-active');
22475- } else {
22476- card.classList.remove('lv-stage-active');
22477- if (dot) {
22478- dot.classList.add('lv-dot-idle');
22479- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
22480- }
22481- if (meta) meta.classList.remove('lv-stage-meta-active');
22482- }
22483- });
22484- }
22485-
22486- renderDemo();
22487-
22488- setInterval(function() {
22489- demoStep = (demoStep + 1) % 5;
22490- renderDemo();
22491- }, 3600);
22492-
22493- setInterval(function() {
22494- stage = (stage + 1) % 6;
22495- renderStages();
22496- }, 2200);
22497-})();
22498-`;
22499-
22500-const css = `
22501-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
22502-
22503-*, *::before, *::after { box-sizing: border-box; }
22504-
22505-body {
22506- margin: 0;
22507- background: #fcfcfd;
22508- -webkit-font-smoothing: antialiased;
22509- text-rendering: optimizeLegibility;
22510- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
22511- font-size: 15px;
22512- line-height: 1.6;
22513- letter-spacing: -0.008em;
22514- color: #16181d;
22515-}
22516-
22517-@keyframes gcPulse {
22518- 0%, 100% { opacity: 1; }
22519- 50% { opacity: 0.35; }
22520-}
22521-
22522-@keyframes gcTicker {
22523- 0% { transform: translateX(0); }
22524- 100% { transform: translateX(-50%); }
22525-}
22526-
22527-/* Shared utilities */
22528-.lv-dot {
22529- display: inline-block;
22530- border-radius: 50%;
22531-}
22532-.lv-dot-green { background: #1e7f5c; }
22533-.lv-dot-indigo { background: #4353c9; }
22534-.lv-dot-idle { background: #c4c6cf; }
22535-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
22536-
22537-.lv-strong { color: #16181d; font-weight: 600; }
22538-
22539-.lv-eyebrow {
22540- font-family: 'JetBrains Mono', monospace;
22541- font-size: 11px;
22542- letter-spacing: 0.12em;
22543- text-transform: uppercase;
22544- color: #8a8d99;
22545- font-weight: 500;
22546- margin-bottom: 12px;
22547-}
22548-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
22549-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
22550-
22551-.lv-h1 {
22552- font-family: 'Inter Tight', sans-serif;
22553- font-weight: 700;
22554- letter-spacing: -0.035em;
22555- font-size: clamp(44px, 7vw, 84px);
22556- line-height: 0.98;
22557- margin: 30px auto 0;
22558- max-width: 14ch;
22559- color: #111318;
22560-}
22561-
22562-.lv-h2 {
22563- font-family: 'Inter Tight', sans-serif;
22564- font-weight: 700;
22565- letter-spacing: -0.028em;
22566- font-size: clamp(30px, 4.4vw, 48px);
22567- line-height: 1.05;
22568- margin: 0;
22569- color: #111318;
22570-}
22571-
22572-.lv-h2-dark {
22573- font-family: 'Inter Tight', sans-serif;
22574- font-weight: 700;
22575- letter-spacing: -0.028em;
22576- font-size: clamp(30px, 4.6vw, 52px);
22577- line-height: 1.05;
22578- margin: 0;
22579- color: #fff;
22580-}
22581-
22582-.lv-section-header {
22583- max-width: 640px;
22584- margin: 0 auto 56px;
22585-}
22586-
22587-.lv-section-header-center {
22588- text-align: center;
22589-}
22590-
22591-.lv-section-sub {
22592- color: #6b7080;
22593- font-size: 17px;
22594- margin: 18px auto 0;
22595- max-width: 52ch;
22596-}
22597-
22598-.lv-section-sub-dark {
22599- color: rgba(255,255,255,0.72);
22600- font-size: 17px;
22601- margin: 18px auto 0;
22602- max-width: 56ch;
22603-}
22604-
22605-/* Nav */
22606-.lv-nav {
22607- position: sticky;
22608- top: 0;
22609- z-index: 60;
22610- backdrop-filter: saturate(180%) blur(14px);
22611- -webkit-backdrop-filter: saturate(180%) blur(14px);
22612- background: rgba(252,252,253,0.8);
22613- border-bottom: 1px solid rgba(22,24,29,0.07);
22614-}
22615-
22616-.lv-nav-inner {
22617- max-width: 1200px;
22618- margin: 0 auto;
22619- padding: 14px 28px;
22620- display: flex;
22621- align-items: center;
22622- gap: 28px;
22623-}
22624-
22625-.lv-logo {
22626- display: inline-flex;
22627- align-items: center;
22628- gap: 9px;
22629- font-family: 'Inter Tight', sans-serif;
22630- font-weight: 700;
22631- font-size: 17px;
22632- letter-spacing: -0.02em;
22633- color: #16181d;
22634- text-decoration: none;
22635-}
22636-
22637-.lv-logo-mark {
22638- width: 17px;
22639- height: 17px;
22640- border-radius: 5px;
22641- background: #4353c9;
22642- display: inline-block;
22643- flex-shrink: 0;
22644-}
22645-
22646-.lv-nav-links {
22647- display: flex;
22648- gap: 24px;
22649- font-size: 13.5px;
22650- font-weight: 500;
22651-}
22652-
22653-.lv-nav-link {
22654- color: #6b7080;
22655- text-decoration: none;
22656- transition: color 0.15s;
22657-}
22658-.lv-nav-link:hover { color: #16181d; }
22659-
22660-.lv-nav-ctas {
22661- margin-left: auto;
22662- display: flex;
22663- align-items: center;
22664- gap: 10px;
22665-}
22666-
22667-.lv-btn-secondary {
22668- padding: 8px 15px;
22669- border-radius: 8px;
22670- font-size: 13.5px;
22671- font-weight: 500;
22672- color: #16181d;
22673- border: 1px solid rgba(22,24,29,0.12);
22674- background: #ffffff;
22675- text-decoration: none;
22676- white-space: nowrap;
22677- transition: border-color 0.15s;
22678-}
22679-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
22680-
22681-.lv-btn-primary {
22682- padding: 8px 15px;
22683- border-radius: 8px;
22684- font-size: 13.5px;
22685- font-weight: 600;
22686- background: #16181d;
22687- color: #fff;
22688- text-decoration: none;
22689- white-space: nowrap;
22690- transition: box-shadow 0.15s;
22691-}
22692-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
22693-
22694-/* Hero */
22695-.lv-hero {
22696- position: relative;
22697- overflow: hidden;
22698- padding: 88px 0 0;
22699-}
22700-
22701-.lv-hero-glow {
22702- position: absolute;
22703- inset: -10% 0 auto 0;
22704- height: 640px;
22705- pointer-events: none;
22706- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
22707-}
22708-
22709-.lv-hero-inner {
22710- position: relative;
22711- max-width: 1200px;
22712- margin: 0 auto;
22713- padding: 0 28px;
22714- text-align: center;
22715-}
22716-
22717-.lv-hero-badge {
22718- display: inline-flex;
22719- align-items: center;
22720- gap: 9px;
22721- font-size: 12.5px;
22722- font-weight: 600;
22723- color: #3a3d45;
22724- background: #ffffff;
22725- border: 1px solid rgba(22,24,29,0.10);
22726- border-radius: 9999px;
22727- padding: 7px 16px;
22728- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
22729-}
22730-
22731-.lv-hero-sub {
22732- font-size: clamp(16px, 2vw, 19px);
22733- color: #6b7080;
22734- max-width: 60ch;
22735- margin: 24px auto 0;
22736- font-weight: 450;
22737- line-height: 1.65;
22738-}
22739-
22740-.lv-hero-actions {
22741- display: flex;
22742- gap: 12px;
22743- justify-content: center;
22744- flex-wrap: wrap;
22745- margin-top: 32px;
22746-}
22747-
22748-.lv-cta-primary {
22749- padding: 13px 24px;
22750- border-radius: 11px;
22751- font-size: 15.5px;
22752- font-weight: 600;
22753- background: #16181d;
22754- color: #fff;
22755- text-decoration: none;
22756- white-space: nowrap;
22757- transition: box-shadow 0.15s;
22758-}
22759-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
22760-
22761-.lv-cta-secondary {
22762- padding: 13px 24px;
22763- border-radius: 11px;
22764- font-size: 15.5px;
22765- font-weight: 600;
22766- color: #16181d;
22767- border: 1px solid rgba(22,24,29,0.14);
22768- background: #ffffff;
22769- text-decoration: none;
22770- white-space: nowrap;
22771- transition: border-color 0.15s;
22772-}
22773-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
22774-
22775-.lv-hero-tag {
22776- margin-top: 18px;
22777- font-family: 'JetBrains Mono', monospace;
22778- font-size: 11.5px;
22779- letter-spacing: 0.08em;
22780- text-transform: uppercase;
22781- color: #8a8d99;
22782-}
22783-
22784-/* Demo window */
22785-.lv-demo-window {
22786- margin: 56px auto 0;
22787- max-width: 860px;
22788- text-align: left;
22789- background: #ffffff;
22790- border: 1px solid rgba(22,24,29,0.09);
22791- border-radius: 18px;
22792- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
22793- overflow: hidden;
22794-}
22795-
22796-.lv-demo-bar {
22797- display: flex;
22798- align-items: center;
22799- gap: 7px;
22800- padding: 12px 18px;
22801- border-bottom: 1px solid rgba(22,24,29,0.07);
22802- background: #fcfcfd;
22803-}
22804-
22805-.lv-demo-dot {
22806- width: 10px;
22807- height: 10px;
22808- border-radius: 50%;
22809- background: #e4e5ea;
22810-}
22811-
22812-.lv-demo-url {
22813- margin-left: 10px;
22814- font-family: 'JetBrains Mono', monospace;
22815- font-size: 12px;
22816- color: #6b7080;
22817-}
22818-
22819-.lv-demo-live {
22820- margin-left: auto;
22821- display: inline-flex;
22822- align-items: center;
22823- gap: 6px;
22824- font-size: 11px;
22825- font-weight: 600;
22826- color: #1e7f5c;
22827-}
22828-
22829-.lv-demo-body {
22830- padding: 22px 24px;
22831-}
22832-
22833-.lv-demo-event {
22834- display: grid;
22835- grid-template-columns: 18px minmax(0, 1fr);
22836- gap: 14px;
22837- padding-bottom: 20px;
22838- position: relative;
22839-}
22840-.lv-demo-event:last-child { padding-bottom: 0; }
22841-
22842-.lv-demo-event-track {
22843- display: flex;
22844- flex-direction: column;
22845- align-items: center;
22846-}
22847-
22848-.lv-demo-line {
22849- width: 1px;
22850- flex: 1;
22851- background: rgba(22,24,29,0.08);
22852- margin-top: 5px;
22853- min-height: 20px;
22854-}
22855-
22856-.lv-demo-event-content {}
22857-
22858-.lv-demo-event-header {
22859- display: flex;
22860- align-items: baseline;
22861- gap: 10px;
22862-}
22863-
22864-.lv-demo-event-title {
22865- font-size: 13.5px;
22866- font-weight: 600;
22867- color: #16181d;
22868-}
22869-
22870-.lv-demo-event-time {
22871- font-family: 'JetBrains Mono', monospace;
22872- font-size: 11px;
22873- color: #8a8d99;
22874-}
22875-
22876-.lv-demo-event-body {
22877- font-size: 13px;
22878- color: #6b7080;
22879- margin-top: 2px;
22880-}
22881-
22882-/* Ticker */
22883-.lv-ticker-wrap {
22884- border-top: 1px solid rgba(22,24,29,0.07);
22885- border-bottom: 1px solid rgba(22,24,29,0.07);
22886- background: #ffffff;
22887- margin-top: 64px;
22888- overflow: hidden;
22889- white-space: nowrap;
22890- position: relative;
22891-}
22892-
22893-.lv-ticker-track {
22894- display: inline-flex;
22895- animation: gcTicker 40s linear infinite;
22896- padding: 11px 0;
22897-}
22898-
22899-.lv-ticker-item {
22900- display: inline-flex;
22901- align-items: center;
22902- gap: 8px;
22903- font-family: 'JetBrains Mono', monospace;
22904- font-size: 11.5px;
22905- color: #6b7080;
22906- padding: 0 28px;
22907- border-right: 1px solid rgba(22,24,29,0.06);
22908-}
22909-
22910-/* Stats */
22911-.lv-stats {
22912- background: #fcfcfd;
22913-}
22914-
22915-.lv-stats-inner {
22916- max-width: 1200px;
22917- margin: 0 auto;
22918- display: grid;
22919- grid-template-columns: repeat(4, 1fr);
22920- gap: 24px;
22921- padding: 52px 28px;
22922-}
22923-
22924-.lv-stat {
22925- text-align: center;
22926-}
22927-
22928-.lv-stat-num {
22929- font-family: 'Inter Tight', sans-serif;
22930- font-weight: 700;
22931- font-size: clamp(30px, 4vw, 44px);
22932- letter-spacing: -0.025em;
22933- color: #111318;
22934-}
22935-
22936-.lv-stat-label {
22937- font-size: 13px;
22938- color: #6b7080;
22939- margin-top: 4px;
22940-}
22941-
22942-/* Loop */
22943-.lv-loop {
22944- padding: 96px 0;
22945- background: #ffffff;
22946- border-top: 1px solid rgba(22,24,29,0.07);
22947- border-bottom: 1px solid rgba(22,24,29,0.07);
22948-}
22949-
22950-.lv-loop-inner {
22951- max-width: 1200px;
22952- margin: 0 auto;
22953- padding: 0 28px;
22954-}
22955-
22956-.lv-stages {
22957- display: grid;
22958- grid-template-columns: repeat(6, 1fr);
22959- gap: 12px;
22960-}
22961-
22962-.lv-stage-card {
22963- border: 1px solid rgba(22,24,29,0.08);
22964- border-radius: 14px;
22965- background: #ffffff;
22966- padding: 20px 18px;
22967- transition: border-color 0.3s, background 0.3s;
22968-}
22969-
22970-.lv-stage-card.lv-stage-active {
22971- border-color: rgba(67,83,201,0.45);
22972- background: rgba(67,83,201,0.03);
22973-}
22974-
22975-.lv-stage-header {
22976- display: flex;
22977- align-items: center;
22978- gap: 8px;
22979- margin-bottom: 10px;
22980-}
22981-
22982-.lv-stage-n {
22983- font-family: 'JetBrains Mono', monospace;
22984- font-size: 10.5px;
22985- letter-spacing: 0.1em;
22986- text-transform: uppercase;
22987- color: #8a8d99;
22988-}
22989-
22990-.lv-stage-name {
22991- font-family: 'Inter Tight', sans-serif;
22992- font-size: 16px;
22993- font-weight: 600;
22994- letter-spacing: -0.01em;
22995- color: #16181d;
22996- margin-bottom: 5px;
22997-}
22998-
22999-.lv-stage-desc {
23000- font-size: 12px;
23001- color: #6b7080;
23002- line-height: 1.55;
23003-}
23004-
23005-.lv-stage-meta {
23006- font-family: 'JetBrains Mono', monospace;
23007- font-size: 10.5px;
23008- color: #8a8d99;
23009- margin-top: 10px;
23010- transition: color 0.3s;
23011-}
23012-
23013-.lv-stage-meta.lv-stage-meta-active {
23014- color: #4353c9;
23015-}
23016-
23017-/* Heroes */
23018-.lv-heroes {
23019- padding: 96px 0;
23020- background: #fcfcfd;
23021-}
23022-
23023-.lv-heroes-inner {
23024- max-width: 1200px;
23025- margin: 0 auto;
23026- padding: 0 28px;
23027-}
23028-
23029-.lv-heroes-header {
23030- max-width: 640px;
23031- margin-bottom: 56px;
23032-}
23033-
23034-.lv-heroes-list {
23035- display: flex;
23036- flex-direction: column;
23037- gap: 20px;
23038-}
23039-
23040-.lv-hero-card {
23041- display: grid;
23042- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
23043- gap: 48px;
23044- align-items: center;
23045- border: 1px solid rgba(22,24,29,0.08);
23046- border-radius: 20px;
23047- background: #ffffff;
23048- padding: 44px 48px;
23049- text-decoration: none;
23050- transition: border-color 0.2s, box-shadow 0.2s;
23051-}
23052-.lv-hero-card:hover {
23053- border-color: rgba(22,24,29,0.22);
23054- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
23055-}
23056-
23057-.lv-hero-card-left {}
23058-
23059-.lv-hero-card-title {
23060- font-family: 'Inter Tight', sans-serif;
23061- font-size: 26px;
23062- font-weight: 600;
23063- letter-spacing: -0.022em;
23064- line-height: 1.15;
23065- color: #16181d;
23066- margin: 0 0 12px;
23067-}
23068-
23069-.lv-hero-card-body {
23070- font-size: 14.5px;
23071- color: #6b7080;
23072- margin: 0 0 18px;
23073- line-height: 1.65;
23074-}
23075-
23076-.lv-hero-card-cta {
23077- font-size: 13.5px;
23078- font-weight: 600;
23079- color: #4353c9;
23080-}
23081-
23082-.lv-terminal {
23083- border: 1px solid rgba(22,24,29,0.07);
23084- border-radius: 14px;
23085- background: #fcfcfd;
23086- padding: 20px 22px;
23087- font-family: 'JetBrains Mono', monospace;
23088- font-size: 12px;
23089- line-height: 1.9;
23090- overflow: hidden;
23091-}
23092-
23093-.lv-terminal-line {
23094- display: flex;
23095- align-items: center;
23096- gap: 10px;
23097- white-space: nowrap;
23098- overflow: hidden;
23099- text-overflow: ellipsis;
23100-}
23101-
23102-/* Platform */
23103-.lv-platform {
23104- padding: 96px 0;
23105- background: #ffffff;
23106- border-top: 1px solid rgba(22,24,29,0.07);
23107-}
23108-
23109-.lv-platform-inner {
23110- max-width: 1200px;
23111- margin: 0 auto;
23112- padding: 0 28px;
23113-}
23114-
23115-.lv-cap-grid {
23116- display: grid;
23117- grid-template-columns: repeat(4, 1fr);
23118- gap: 24px 32px;
23119-}
23120-
23121-.lv-cap-col {}
23122-
23123-.lv-cap-group {
23124- font-family: 'JetBrains Mono', monospace;
23125- font-size: 10.5px;
23126- letter-spacing: 0.12em;
23127- text-transform: uppercase;
23128- color: #8a8d99;
23129- font-weight: 500;
23130- margin-bottom: 12px;
23131- padding-bottom: 8px;
23132- border-bottom: 1px solid rgba(22,24,29,0.07);
23133-}
23134-
23135-.lv-cap-items {
23136- display: flex;
23137- flex-direction: column;
23138- gap: 7px;
23139-}
23140-
23141-.lv-cap-item {
23142- font-size: 12.5px;
23143- color: #3a3d45;
23144- line-height: 1.45;
23145-}
23146-
23147-/* Sovereignty */
23148-.lv-sovereign {
23149- position: relative;
23150- overflow: hidden;
23151- padding: 104px 0;
23152- color: #fff;
23153- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
23154-}
23155-
23156-.lv-sovereign-grid-bg {
23157- position: absolute;
23158- inset: 0;
23159- opacity: 0.4;
23160- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
23161- background-size: 56px 56px;
23162- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
23163- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
23164-}
23165-
23166-.lv-sovereign-inner {
23167- position: relative;
23168- max-width: 1200px;
23169- margin: 0 auto;
23170- padding: 0 28px;
23171-}
23172-
23173-.lv-section-header-dark {
23174- max-width: 680px;
23175- margin: 0 auto 48px;
23176- text-align: center;
23177-}
23178-
23179-.lv-layers-grid {
23180- display: grid;
23181- grid-template-columns: repeat(4, 1fr);
23182- gap: 10px;
23183- max-width: 980px;
23184- margin: 0 auto;
23185-}
23186-
23187-.lv-layer-chip {
23188- border: 1px solid rgba(255,255,255,0.10);
23189- border-radius: 10px;
23190- padding: 12px 16px;
23191- background: rgba(255,255,255,0.03);
23192-}
23193-
23194-.lv-layer-cta {
23195- border-color: rgba(169,180,238,0.30);
23196- background: rgba(169,180,238,0.06);
23197- display: flex;
23198- align-items: center;
23199- text-decoration: none;
23200- transition: background 0.15s;
23201-}
23202-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
23203-
23204-.lv-layer-cta-text {
23205- font-size: 13px;
23206- font-weight: 500;
23207- color: #a9b4ee;
23208-}
23209-
23210-.lv-layer-n {
23211- font-family: 'JetBrains Mono', monospace;
23212- font-size: 10px;
23213- color: rgba(255,255,255,0.4);
23214- margin-bottom: 3px;
23215-}
23216-
23217-.lv-layer-name {
23218- font-size: 13px;
23219- font-weight: 500;
23220- color: rgba(255,255,255,0.92);
23221-}
23222-
23223-.lv-sovereign-feats {
23224- display: flex;
23225- gap: 44px;
23226- justify-content: center;
23227- flex-wrap: wrap;
23228- margin-top: 52px;
23229- text-align: center;
23230-}
23231-
23232-.lv-sovereign-feat {}
23233-
23234-.lv-sovereign-feat-title {
23235- font-family: 'Inter Tight', sans-serif;
23236- font-size: 20px;
23237- font-weight: 700;
23238- color: #fff;
23239-}
23240-
23241-.lv-sovereign-feat-sub {
23242- color: rgba(255,255,255,0.55);
23243- font-size: 13px;
23244- margin-top: 2px;
23245-}
23246-
23247-/* Twin cards */
23248-.lv-twin {
23249- padding: 96px 0;
23250- background: #fcfcfd;
23251-}
23252-
23253-.lv-twin-inner {
23254- max-width: 1200px;
23255- margin: 0 auto;
23256- padding: 0 28px;
23257- display: grid;
23258- grid-template-columns: 1fr 1fr;
23259- gap: 24px;
23260-}
23261-
23262-.lv-twin-card {
23263- border: 1px solid rgba(22,24,29,0.08);
23264- border-radius: 20px;
23265- background: #ffffff;
23266- padding: 44px 48px;
23267-}
23268-
23269-.lv-twin-title {
23270- font-family: 'Inter Tight', sans-serif;
23271- font-size: 24px;
23272- font-weight: 600;
23273- letter-spacing: -0.02em;
23274- line-height: 1.2;
23275- margin: 0 0 12px;
23276- color: #16181d;
23277-}
23278-
23279-.lv-twin-body {
23280- font-size: 14.5px;
23281- color: #6b7080;
23282- margin: 0 0 16px;
23283- line-height: 1.7;
23284-}
23285-
23286-.lv-twin-link {
23287- font-size: 13.5px;
23288- font-weight: 600;
23289- color: #4353c9;
23290- text-decoration: none;
23291-}
23292-.lv-twin-link:hover { text-decoration: underline; }
23293-
23294-/* Quote */
23295-.lv-quote {
23296- padding: 40px 0 96px;
23297- background: #fcfcfd;
23298-}
23299-
23300-.lv-quote-inner {
23301- max-width: 980px;
23302- margin: 0 auto;
23303- padding: 0 28px;
23304- text-align: center;
23305-}
23306-
23307-.lv-quote-text {
23308- font-family: 'Inter Tight', sans-serif;
23309- font-weight: 600;
23310- font-size: clamp(26px, 3.8vw, 42px);
23311- line-height: 1.2;
23312- letter-spacing: -0.025em;
23313- margin: 0;
23314- color: #111318;
23315-}
23316-
23317-.lv-em {
23318- font-style: normal;
23319- color: #4353c9;
23320-}
23321-
23322-/* CTA */
23323-.lv-cta-section {
23324- padding: 0 0 104px;
23325- background: #fcfcfd;
23326-}
23327-
23328-.lv-cta-card {
23329- max-width: 820px;
23330- margin: 0 auto;
23331- padding: 64px 40px;
23332- text-align: center;
23333- background: #ffffff;
23334- border: 1px solid rgba(22,24,29,0.08);
23335- border-radius: 26px;
23336- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
23337- position: relative;
23338- overflow: hidden;
23339-}
23340-
23341-.lv-cta-glow {
23342- position: absolute;
23343- inset: -40% 0 auto 0;
23344- height: 280px;
23345- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
23346- pointer-events: none;
23347-}
23348-
23349-.lv-cta-h2 {
23350- font-family: 'Inter Tight', sans-serif;
23351- font-weight: 700;
23352- letter-spacing: -0.028em;
23353- font-size: clamp(30px, 4.6vw, 48px);
23354- margin: 0;
23355- position: relative;
23356- color: #111318;
23357-}
23358-
23359-.lv-cta-sub {
23360- color: #6b7080;
23361- font-size: 17px;
23362- margin: 16px 0 30px;
23363- position: relative;
23364-}
23365-
23366-.lv-cta-actions {
23367- display: flex;
23368- gap: 12px;
23369- justify-content: center;
23370- flex-wrap: wrap;
23371- position: relative;
23372-}
23373-
23374-.lv-cta-fine {
23375- margin-top: 20px;
23376- font-family: 'JetBrains Mono', monospace;
23377- font-size: 11px;
23378- color: #8a8d99;
23379- position: relative;
23380-}
23381-
23382-/* Footer */
23383-.lv-footer {
23384- border-top: 1px solid rgba(22,24,29,0.07);
23385- background: #ffffff;
23386- padding: 56px 0 30px;
23387-}
23388-
23389-.lv-footer-inner {
23390- max-width: 1200px;
23391- margin: 0 auto;
23392- padding: 0 28px;
23393- display: flex;
23394- gap: 48px;
23395- flex-wrap: wrap;
23396- justify-content: space-between;
23397-}
23398-
23399-.lv-footer-brand {}
23400-
23401-.lv-footer-tagline {
23402- color: #6b7080;
23403- font-size: 13.5px;
23404- margin: 12px 0 0;
23405- max-width: 32ch;
23406- line-height: 1.6;
23407-}
23408-
23409-.lv-footer-cols {
23410- display: flex;
23411- gap: 64px;
23412- flex-wrap: wrap;
23413-}
23414-
23415-.lv-footer-col {
23416- display: flex;
23417- flex-direction: column;
23418- gap: 9px;
23419-}
23420-
23421-.lv-footer-col-head {
23422- font-family: 'JetBrains Mono', monospace;
23423- font-size: 11px;
23424- text-transform: uppercase;
23425- letter-spacing: 0.1em;
23426- color: #8a8d99;
23427- margin: 0 0 4px;
23428- font-weight: 500;
23429-}
23430-
23431-.lv-footer-link {
23432- color: #3a3d45;
23433- font-size: 13.5px;
23434- text-decoration: none;
23435- transition: color 0.15s;
23436-}
23437-.lv-footer-link:hover { color: #16181d; }
23438-
23439-.lv-footer-bar {
23440- max-width: 1200px;
23441- margin: 44px auto 0;
23442- padding: 22px 28px 0;
23443- border-top: 1px solid rgba(22,24,29,0.06);
23444- display: flex;
23445- justify-content: space-between;
23446- flex-wrap: wrap;
23447- gap: 8px;
23448- color: #8a8d99;
23449- font-size: 12.5px;
23450-}
23451-
23452-.lv-footer-stack {
23453- font-family: 'JetBrains Mono', monospace;
23454- font-size: 11px;
23455-}
23456-`;
23457diff --git a/src/views/layout.tsx b/src/views/layout.tsx
23458index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
23459--- a/src/views/layout.tsx
23460+++ b/src/views/layout.tsx
23461@@ -3153,9 +3153,12 @@
23462 font-weight: 500;
23463 line-height: 1.4;
23464 }
23465- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
23466- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
23467- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
23468+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
23469+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
23470+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
23471+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
23472+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
23473+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
23474 .state-merged { color: var(--accent); }
23475 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
23476
23477diff --git a/src/views/ui.tsx b/src/views/ui.tsx
23478index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
23479--- a/src/views/ui.tsx
23480+++ b/src/views/ui.tsx
23481@@ -232,7 +232,7 @@
23482
23483 export const Badge: FC<
23484 PropsWithChildren<{
23485- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
23486+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
23487 style?: string;
23488 }>
23489 > = ({ children, variant = "default", style }) => {
23490@@ -241,9 +241,12 @@
23491 variant === "closed" ? "badge-closed" :
23492 variant === "merged" ? "badge-merged" :
23493 variant === "success" ? "badge-success" :
23494- variant === "danger" ? "badge-danger" :
23495- variant === "warning" ? "badge-warning" :
23496- "badge";
23497+ variant === "danger" ? "badge-danger" :
23498+ variant === "warning" ? "badge-warning" :
23499+ variant === "live" ? "badge-live" :
23500+ variant === "soon" ? "badge-soon" :
23501+ variant === "preview" ? "badge-preview" :
23502+ "badge";
23503 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
23504 };
23505
23506
23507diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
23508index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
23509--- a/src/views/landing-pro.tsx
23510+++ b/src/views/landing-pro.tsx
23511@@ -42,7 +42,7 @@
23512
23513 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23514
23515-function icon(paths: string, color = "#4353c9", size = 20) {
23516+function icon(paths: string, color = "#0891b2", size = 20) {
23517 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
23518 }
23519
23520@@ -947,7 +947,7 @@
23521 const css = `
23522 /* %% tokens %% */
23523 :root{
23524- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
23525+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
23526 --lp-bg:#ffffff;--lp-soft:#fafafb;
23527 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
23528 --lp-border:rgba(0,0,0,.08);
23529diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
23530deleted file mode 100644
23531index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
23532--- a/src/views/landing-v2.tsx
23533+++ /dev/null
23534@@ -1,1447 +0,0 @@
23535-import type { FC } from "hono/jsx";
23536-
23537-export interface LandingPageProps {
23538- stats?: {
23539- publicRepos?: number;
23540- users?: number;
23541- };
23542-}
23543-
23544-const demoAllEvents = [
23545- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
23546- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
23547- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
23548- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
23549- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
23550-];
23551-
23552-const tickerItems = [
23553- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
23554- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
23555- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
23556- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
23557- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
23558- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
23559- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
23560- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
23561- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
23562- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
23563- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
23564- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
23565- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
23566- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
23567- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
23568- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
23569-];
23570-
23571-const stageData = [
23572- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
23573- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
23574- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
23575- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
23576- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
23577- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
23578-];
23579-
23580-const heroFeatures = [
23581- {
23582- href: "/",
23583- eyebrow: "01 � The autonomous repair loop",
23584- title: "Failures fix themselves  and show their work.",
23585- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
23586failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
23587- cta: "Watch a live repair session",
23588- mock: [
23589- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
23590- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
23591- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
23592- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
23593- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
23594- ],
23595- },
23596- {
23597- href: "/",
23598- eyebrow: "02 � Live sandbox isolation",
23599- title: "Every PR gets its own instant, disposable environment.",
23600- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
23601same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
23602- cta: "See a PR with its sandbox",
23603- mock: [
23604- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
23605- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
23606- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
23607- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
23608- ],
23609- },
23610- {
23611- href: "/",
23612- eyebrow: "03 � Multiplayer IDE workspaces",
23613- title: "You and the agent, side by side, in your editor.",
23614- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
23615agent into a silent reviewer in your gutter. The browser becomes optional.",
23616- cta: "See the editor session",
23617- mock: [
23618- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
23619- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
23620- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
23621- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
23622- ],
23623- },
23624-];
23625-
23626-const capabilities = [
23627- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
23628- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
23629- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
23630- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
23631- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
23632- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
23633- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
23634- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
23635-];
23636-
23637-const sovereignLayerNames = [
23638- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
23639- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
23640- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
23641- "Availability & recovery",
23642-];
23643-
23644-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
23645- return (
23646- <>
23647- <style dangerouslySetInnerHTML={{ __html: css }} />
23648-
23649- {/* Nav */}
23650- <header class="lv-nav">
23651- <div class="lv-nav-inner">
23652- <a href="/" class="lv-logo">
23653- <span class="lv-logo-mark"></span>gluecron
23654- </a>
23655- <nav class="lv-nav-links">
23656- <a href="#loop" class="lv-nav-link">The loop</a>
23657- <a href="#platform" class="lv-nav-link">Platform</a>
23658- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
23659- <a href="/trust" class="lv-nav-link">Trust</a>
23660- </nav>
23661- <div class="lv-nav-ctas">
23662- <a href="/login" class="lv-btn-secondary">Sign in</a>
23663- <a href="/register" class="lv-btn-primary">Start building</a>
23664- </div>
23665- </div>
23666- </header>
23667-
23668- {/* Hero */}
23669- <section class="lv-hero">
23670- <div class="lv-hero-glow"></div>
23671- <div class="lv-hero-inner">
23672- <div class="lv-hero-badge">
23673- <span class="lv-dot lv-dot-green lv-pulse"></span>
23674- Live: a repair loop converged on pr-218 while you read this
23675- </div>
23676- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
23677- <p class="lv-hero-sub">
23678- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
23679failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
23680- </p>
23681- <div class="lv-hero-actions">
23682- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
23683- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
23684- </div>
23685- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
23686-
23687- {/* Live product window */}
23688- <div class="lv-demo-window">
23689- <div class="lv-demo-bar">
23690- <span class="lv-demo-dot"></span>
23691- <span class="lv-demo-dot"></span>
23692- <span class="lv-demo-dot"></span>
23693- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
23694- <span class="lv-demo-live">
23695- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
23696- LIVE
23697- </span>
23698- </div>
23699- <div class="lv-demo-body" id="lv-demo-body">
23700- {/* Events rendered by JS */}
23701- {demoAllEvents.slice(0, 1).map((e, i) => (
23702- <div class="lv-demo-event" key={i}>
23703- <div class="lv-demo-event-track">
23704- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
23705- <span class="lv-demo-line" style="display:none"></span>
23706- </div>
23707- <div class="lv-demo-event-content">
23708- <div class="lv-demo-event-header">
23709- <span class="lv-demo-event-title">{e.title}</span>
23710- <span class="lv-demo-event-time">{e.time}</span>
23711- </div>
23712- <div class="lv-demo-event-body">{e.body}</div>
23713- </div>
23714- </div>
23715- ))}
23716- </div>
23717- </div>
23718- </div>
23719-
23720- {/* Activity ticker */}
23721- <div class="lv-ticker-wrap">
23722- <div class="lv-ticker-track">
23723- {tickerItems.map((t, i) => (
23724- <span class="lv-ticker-item" key={i}>
23725- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
23726- {t.text}
23727- </span>
23728- ))}
23729- </div>
23730- </div>
23731- </section>
23732-
23733- {/* Stat band */}
23734- <section class="lv-stats">
23735- <div class="lv-stats-inner">
23736- <div class="lv-stat">
23737- <div class="lv-stat-num">Sonnet 5</div>
23738- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
23739- </div>
23740- <div class="lv-stat">
23741- <div class="lv-stat-num">93.5%</div>
23742- <div class="lv-stat-label">of failures self-repair without a human</div>
23743- </div>
23744- <div class="lv-stat">
23745- <div class="lv-stat-num">1.9%</div>
23746- <div class="lv-stat-label">AI merges reverted  published live</div>
23747- </div>
23748- <div class="lv-stat">
23749- <div class="lv-stat-num">0</div>
23750- <div class="lv-stat-label">irreversible actions taken autonomously</div>
23751- </div>
23752- </div>
23753- </section>
23754-
23755- {/* The loop */}
23756- <section id="loop" class="lv-loop">
23757- <div class="lv-loop-inner">
23758- <div class="lv-section-header">
23759- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
23760- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
23761- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
23762- </div>
23763- <div class="lv-stages" id="lv-stages">
23764- {stageData.map((s, i) => (
23765- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
23766- <div class="lv-stage-header">
23767- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
23768- <span class="lv-stage-n">0{i + 1}</span>
23769- </div>
23770- <div class="lv-stage-name">{s.name}</div>
23771- <div class="lv-stage-desc">{s.desc}</div>
23772- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
23773- </div>
23774- ))}
23775- </div>
23776- </div>
23777- </section>
23778-
23779- {/* Three heroes */}
23780- <section class="lv-heroes">
23781- <div class="lv-heroes-inner">
23782- <div class="lv-heroes-header">
23783- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
23784- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
23785- </div>
23786- <div class="lv-heroes-list">
23787- {heroFeatures.map((h, i) => (
23788- <a href={h.href} class="lv-hero-card" key={i}>
23789- <div class="lv-hero-card-left">
23790- <div class="lv-eyebrow">{h.eyebrow}</div>
23791- <h3 class="lv-hero-card-title">{h.title}</h3>
23792- <p class="lv-hero-card-body">{h.body}</p>
23793- <span class="lv-hero-card-cta">{h.cta} �!</span>
23794- </div>
23795- <div class="lv-terminal">
23796- {h.mock.map((m, j) => (
23797- <div class="lv-terminal-line" key={j}>
23798- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
23799- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
23800- </div>
23801- ))}
23802- </div>
23803- </a>
23804- ))}
23805- </div>
23806- </div>
23807- </section>
23808-
23809- {/* Everything grid */}
23810- <section id="platform" class="lv-platform">
23811- <div class="lv-platform-inner">
23812- <div class="lv-section-header lv-section-header-center">
23813- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
23814- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
23815- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
23816- </div>
23817- <div class="lv-cap-grid">
23818- {capabilities.map((c, i) => (
23819- <div class="lv-cap-col" key={i}>
23820- <div class="lv-cap-group">{c.group}</div>
23821- <div class="lv-cap-items">
23822- {c.items.map((item, j) => (
23823- <div class="lv-cap-item" key={j}>{item}</div>
23824- ))}
23825- </div>
23826- </div>
23827- ))}
23828- </div>
23829- </div>
23830- </section>
23831-
23832- {/* Sovereignty band */}
23833- <section id="sovereign" class="lv-sovereign">
23834- <div class="lv-sovereign-grid-bg"></div>
23835- <div class="lv-sovereign-inner">
23836- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
23837- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
23838- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
23839- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
23840to private cloud, or run fully air-gapped on bare metal.</p>
23841- </div>
23842- <div class="lv-layers-grid">
23843- {sovereignLayerNames.map((name, i) => (
23844- <div class="lv-layer-chip" key={i}>
23845- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
23846- <div class="lv-layer-name">{name}</div>
23847- </div>
23848- ))}
23849- <a href="/" class="lv-layer-chip lv-layer-cta">
23850- <div class="lv-layer-cta-text">All self-owned �!</div>
23851- </a>
23852- </div>
23853- <div class="lv-sovereign-feats">
23854- <div class="lv-sovereign-feat">
23855- <div class="lv-sovereign-feat-title">Local inference first</div>
23856- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
23857- </div>
23858- <div class="lv-sovereign-feat">
23859- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
23860- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
23861- </div>
23862- <div class="lv-sovereign-feat">
23863- <div class="lv-sovereign-feat-title">Self-healing infra</div>
23864- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
23865- </div>
23866- </div>
23867- </div>
23868- </section>
23869-
23870- {/* Manual-first + reversibility */}
23871- <section class="lv-twin">
23872- <div class="lv-twin-inner">
23873- <div class="lv-twin-card">
23874- <div class="lv-eyebrow">Manual-first, always</div>
23875- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
23876- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
23877fallback. Developers who never touch AI get the best git host they've ever used.</p>
23878- </div>
23879- <div class="lv-twin-card">
23880- <div class="lv-eyebrow">The reversibility guarantee</div>
23881- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
23882- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
23883 policy, not promise. Our quality numbers are published live, unedited.</p>
23884- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
23885- </div>
23886- </div>
23887- </section>
23888-
23889- {/* Quote */}
23890- <section class="lv-quote">
23891- <div class="lv-quote-inner">
23892- <p class="lv-quote-text">
23893- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
23894- Gluecron is where code gets <em class="lv-em">finished</em>."
23895- </p>
23896- </div>
23897- </section>
23898-
23899- {/* CTA */}
23900- <section class="lv-cta-section">
23901- <div class="lv-cta-card">
23902- <div class="lv-cta-glow"></div>
23903- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
23904- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
23905- <div class="lv-cta-actions">
23906- <a href="/register" class="lv-cta-primary">Create your account �!</a>
23907- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
23908- </div>
23909- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
23910- </div>
23911- </section>
23912-
23913- {/* Footer */}
23914- <footer class="lv-footer">
23915- <div class="lv-footer-inner">
23916- <div class="lv-footer-brand">
23917- <a href="/" class="lv-logo">
23918- <span class="lv-logo-mark"></span>gluecron
23919- </a>
23920- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
23921- </div>
23922- <div class="lv-footer-cols">
23923- <div class="lv-footer-col">
23924- <h4 class="lv-footer-col-head">Product</h4>
23925- <a href="/" class="lv-footer-link">Agent workspace</a>
23926- <a href="/" class="lv-footer-link">Fleet refactors</a>
23927- <a href="/" class="lv-footer-link">Org memory</a>
23928- <a href="/" class="lv-footer-link">IDE extensions</a>
23929- </div>
23930- <div class="lv-footer-col">
23931- <h4 class="lv-footer-col-head">Platform</h4>
23932- <a href="/" class="lv-footer-link">Production layers</a>
23933- <a href="/trust" class="lv-footer-link">Trust report</a>
23934- <a href="/" class="lv-footer-link">Docs</a>
23935- <a href="/" class="lv-footer-link">Status</a>
23936- </div>
23937- <div class="lv-footer-col">
23938- <h4 class="lv-footer-col-head">Company</h4>
23939- <a href="/" class="lv-footer-link">About</a>
23940- <a href="/" class="lv-footer-link">Pricing</a>
23941- <a href="/" class="lv-footer-link">Enterprise</a>
23942- </div>
23943- </div>
23944- </div>
23945- <div class="lv-footer-bar">
23946- <span>� 2026 Gluecron</span>
23947- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
23948- </div>
23949- </footer>
23950-
23951- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
23952- </>
23953- );
23954-};
23955-
23956-export const LandingPage = LandingPageV2;
23957-export default LandingPageV2;
23958-
23959-const clientScript = `
23960-(function() {
23961- var demoAll = [
23962- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
23963- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
23964- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
23965- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
23966- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
23967- ];
23968-
23969- var demoStep = 0;
23970- var stage = 0;
23971-
23972- function renderDemo() {
23973- var container = document.getElementById('lv-demo-body');
23974- if (!container) return;
23975- var visible = demoAll.slice(0, demoStep + 1);
23976- container.innerHTML = visible.map(function(e, i) {
23977- var isLast = i === visible.length - 1;
23978- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
23979- return '<div class="lv-demo-event">' +
23980- '<div class="lv-demo-event-track">' +
23981- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
23982- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
23983- '</div>' +
23984- '<div class="lv-demo-event-content">' +
23985- '<div class="lv-demo-event-header">' +
23986- '<span class="lv-demo-event-title">' + e.title + '</span>' +
23987- '<span class="lv-demo-event-time">' + e.time + '</span>' +
23988- '</div>' +
23989- '<div class="lv-demo-event-body">' + e.body + '</div>' +
23990- '</div>' +
23991- '</div>';
23992- }).join('');
23993- }
23994-
23995- function renderStages() {
23996- var cards = document.querySelectorAll('.lv-stage-card');
23997- cards.forEach(function(card, i) {
23998- var dot = card.querySelector('.lv-dot');
23999- var meta = card.querySelector('.lv-stage-meta');
24000- if (i === stage) {
24001- card.classList.add('lv-stage-active');
24002- if (dot) {
24003- dot.classList.remove('lv-dot-idle');
24004- dot.classList.add('lv-dot-indigo', 'lv-pulse');
24005- }
24006- if (meta) meta.classList.add('lv-stage-meta-active');
24007- } else {
24008- card.classList.remove('lv-stage-active');
24009- if (dot) {
24010- dot.classList.add('lv-dot-idle');
24011- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
24012- }
24013- if (meta) meta.classList.remove('lv-stage-meta-active');
24014- }
24015- });
24016- }
24017-
24018- renderDemo();
24019-
24020- setInterval(function() {
24021- demoStep = (demoStep + 1) % 5;
24022- renderDemo();
24023- }, 3600);
24024-
24025- setInterval(function() {
24026- stage = (stage + 1) % 6;
24027- renderStages();
24028- }, 2200);
24029-})();
24030-`;
24031-
24032-const css = `
24033-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
24034-
24035-*, *::before, *::after { box-sizing: border-box; }
24036-
24037-body {
24038- margin: 0;
24039- background: #fcfcfd;
24040- -webkit-font-smoothing: antialiased;
24041- text-rendering: optimizeLegibility;
24042- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
24043- font-size: 15px;
24044- line-height: 1.6;
24045- letter-spacing: -0.008em;
24046- color: #16181d;
24047-}
24048-
24049-@keyframes gcPulse {
24050- 0%, 100% { opacity: 1; }
24051- 50% { opacity: 0.35; }
24052-}
24053-
24054-@keyframes gcTicker {
24055- 0% { transform: translateX(0); }
24056- 100% { transform: translateX(-50%); }
24057-}
24058-
24059-/* Shared utilities */
24060-.lv-dot {
24061- display: inline-block;
24062- border-radius: 50%;
24063-}
24064-.lv-dot-green { background: #1e7f5c; }
24065-.lv-dot-indigo { background: #4353c9; }
24066-.lv-dot-idle { background: #c4c6cf; }
24067-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
24068-
24069-.lv-strong { color: #16181d; font-weight: 600; }
24070-
24071-.lv-eyebrow {
24072- font-family: 'JetBrains Mono', monospace;
24073- font-size: 11px;
24074- letter-spacing: 0.12em;
24075- text-transform: uppercase;
24076- color: #8a8d99;
24077- font-weight: 500;
24078- margin-bottom: 12px;
24079-}
24080-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
24081-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
24082-
24083-.lv-h1 {
24084- font-family: 'Inter Tight', sans-serif;
24085- font-weight: 700;
24086- letter-spacing: -0.035em;
24087- font-size: clamp(44px, 7vw, 84px);
24088- line-height: 0.98;
24089- margin: 30px auto 0;
24090- max-width: 14ch;
24091- color: #111318;
24092-}
24093-
24094-.lv-h2 {
24095- font-family: 'Inter Tight', sans-serif;
24096- font-weight: 700;
24097- letter-spacing: -0.028em;
24098- font-size: clamp(30px, 4.4vw, 48px);
24099- line-height: 1.05;
24100- margin: 0;
24101- color: #111318;
24102-}
24103-
24104-.lv-h2-dark {
24105- font-family: 'Inter Tight', sans-serif;
24106- font-weight: 700;
24107- letter-spacing: -0.028em;
24108- font-size: clamp(30px, 4.6vw, 52px);
24109- line-height: 1.05;
24110- margin: 0;
24111- color: #fff;
24112-}
24113-
24114-.lv-section-header {
24115- max-width: 640px;
24116- margin: 0 auto 56px;
24117-}
24118-
24119-.lv-section-header-center {
24120- text-align: center;
24121-}
24122-
24123-.lv-section-sub {
24124- color: #6b7080;
24125- font-size: 17px;
24126- margin: 18px auto 0;
24127- max-width: 52ch;
24128-}
24129-
24130-.lv-section-sub-dark {
24131- color: rgba(255,255,255,0.72);
24132- font-size: 17px;
24133- margin: 18px auto 0;
24134- max-width: 56ch;
24135-}
24136-
24137-/* Nav */
24138-.lv-nav {
24139- position: sticky;
24140- top: 0;
24141- z-index: 60;
24142- backdrop-filter: saturate(180%) blur(14px);
24143- -webkit-backdrop-filter: saturate(180%) blur(14px);
24144- background: rgba(252,252,253,0.8);
24145- border-bottom: 1px solid rgba(22,24,29,0.07);
24146-}
24147-
24148-.lv-nav-inner {
24149- max-width: 1200px;
24150- margin: 0 auto;
24151- padding: 14px 28px;
24152- display: flex;
24153- align-items: center;
24154- gap: 28px;
24155-}
24156-
24157-.lv-logo {
24158- display: inline-flex;
24159- align-items: center;
24160- gap: 9px;
24161- font-family: 'Inter Tight', sans-serif;
24162- font-weight: 700;
24163- font-size: 17px;
24164- letter-spacing: -0.02em;
24165- color: #16181d;
24166- text-decoration: none;
24167-}
24168-
24169-.lv-logo-mark {
24170- width: 17px;
24171- height: 17px;
24172- border-radius: 5px;
24173- background: #4353c9;
24174- display: inline-block;
24175- flex-shrink: 0;
24176-}
24177-
24178-.lv-nav-links {
24179- display: flex;
24180- gap: 24px;
24181- font-size: 13.5px;
24182- font-weight: 500;
24183-}
24184-
24185-.lv-nav-link {
24186- color: #6b7080;
24187- text-decoration: none;
24188- transition: color 0.15s;
24189-}
24190-.lv-nav-link:hover { color: #16181d; }
24191-
24192-.lv-nav-ctas {
24193- margin-left: auto;
24194- display: flex;
24195- align-items: center;
24196- gap: 10px;
24197-}
24198-
24199-.lv-btn-secondary {
24200- padding: 8px 15px;
24201- border-radius: 8px;
24202- font-size: 13.5px;
24203- font-weight: 500;
24204- color: #16181d;
24205- border: 1px solid rgba(22,24,29,0.12);
24206- background: #ffffff;
24207- text-decoration: none;
24208- white-space: nowrap;
24209- transition: border-color 0.15s;
24210-}
24211-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
24212-
24213-.lv-btn-primary {
24214- padding: 8px 15px;
24215- border-radius: 8px;
24216- font-size: 13.5px;
24217- font-weight: 600;
24218- background: #16181d;
24219- color: #fff;
24220- text-decoration: none;
24221- white-space: nowrap;
24222- transition: box-shadow 0.15s;
24223-}
24224-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
24225-
24226-/* Hero */
24227-.lv-hero {
24228- position: relative;
24229- overflow: hidden;
24230- padding: 88px 0 0;
24231-}
24232-
24233-.lv-hero-glow {
24234- position: absolute;
24235- inset: -10% 0 auto 0;
24236- height: 640px;
24237- pointer-events: none;
24238- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
24239-}
24240-
24241-.lv-hero-inner {
24242- position: relative;
24243- max-width: 1200px;
24244- margin: 0 auto;
24245- padding: 0 28px;
24246- text-align: center;
24247-}
24248-
24249-.lv-hero-badge {
24250- display: inline-flex;
24251- align-items: center;
24252- gap: 9px;
24253- font-size: 12.5px;
24254- font-weight: 600;
24255- color: #3a3d45;
24256- background: #ffffff;
24257- border: 1px solid rgba(22,24,29,0.10);
24258- border-radius: 9999px;
24259- padding: 7px 16px;
24260- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
24261-}
24262-
24263-.lv-hero-sub {
24264- font-size: clamp(16px, 2vw, 19px);
24265- color: #6b7080;
24266- max-width: 60ch;
24267- margin: 24px auto 0;
24268- font-weight: 450;
24269- line-height: 1.65;
24270-}
24271-
24272-.lv-hero-actions {
24273- display: flex;
24274- gap: 12px;
24275- justify-content: center;
24276- flex-wrap: wrap;
24277- margin-top: 32px;
24278-}
24279-
24280-.lv-cta-primary {
24281- padding: 13px 24px;
24282- border-radius: 11px;
24283- font-size: 15.5px;
24284- font-weight: 600;
24285- background: #16181d;
24286- color: #fff;
24287- text-decoration: none;
24288- white-space: nowrap;
24289- transition: box-shadow 0.15s;
24290-}
24291-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
24292-
24293-.lv-cta-secondary {
24294- padding: 13px 24px;
24295- border-radius: 11px;
24296- font-size: 15.5px;
24297- font-weight: 600;
24298- color: #16181d;
24299- border: 1px solid rgba(22,24,29,0.14);
24300- background: #ffffff;
24301- text-decoration: none;
24302- white-space: nowrap;
24303- transition: border-color 0.15s;
24304-}
24305-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
24306-
24307-.lv-hero-tag {
24308- margin-top: 18px;
24309- font-family: 'JetBrains Mono', monospace;
24310- font-size: 11.5px;
24311- letter-spacing: 0.08em;
24312- text-transform: uppercase;
24313- color: #8a8d99;
24314-}
24315-
24316-/* Demo window */
24317-.lv-demo-window {
24318- margin: 56px auto 0;
24319- max-width: 860px;
24320- text-align: left;
24321- background: #ffffff;
24322- border: 1px solid rgba(22,24,29,0.09);
24323- border-radius: 18px;
24324- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
24325- overflow: hidden;
24326-}
24327-
24328-.lv-demo-bar {
24329- display: flex;
24330- align-items: center;
24331- gap: 7px;
24332- padding: 12px 18px;
24333- border-bottom: 1px solid rgba(22,24,29,0.07);
24334- background: #fcfcfd;
24335-}
24336-
24337-.lv-demo-dot {
24338- width: 10px;
24339- height: 10px;
24340- border-radius: 50%;
24341- background: #e4e5ea;
24342-}
24343-
24344-.lv-demo-url {
24345- margin-left: 10px;
24346- font-family: 'JetBrains Mono', monospace;
24347- font-size: 12px;
24348- color: #6b7080;
24349-}
24350-
24351-.lv-demo-live {
24352- margin-left: auto;
24353- display: inline-flex;
24354- align-items: center;
24355- gap: 6px;
24356- font-size: 11px;
24357- font-weight: 600;
24358- color: #1e7f5c;
24359-}
24360-
24361-.lv-demo-body {
24362- padding: 22px 24px;
24363-}
24364-
24365-.lv-demo-event {
24366- display: grid;
24367- grid-template-columns: 18px minmax(0, 1fr);
24368- gap: 14px;
24369- padding-bottom: 20px;
24370- position: relative;
24371-}
24372-.lv-demo-event:last-child { padding-bottom: 0; }
24373-
24374-.lv-demo-event-track {
24375- display: flex;
24376- flex-direction: column;
24377- align-items: center;
24378-}
24379-
24380-.lv-demo-line {
24381- width: 1px;
24382- flex: 1;
24383- background: rgba(22,24,29,0.08);
24384- margin-top: 5px;
24385- min-height: 20px;
24386-}
24387-
24388-.lv-demo-event-content {}
24389-
24390-.lv-demo-event-header {
24391- display: flex;
24392- align-items: baseline;
24393- gap: 10px;
24394-}
24395-
24396-.lv-demo-event-title {
24397- font-size: 13.5px;
24398- font-weight: 600;
24399- color: #16181d;
24400-}
24401-
24402-.lv-demo-event-time {
24403- font-family: 'JetBrains Mono', monospace;
24404- font-size: 11px;
24405- color: #8a8d99;
24406-}
24407-
24408-.lv-demo-event-body {
24409- font-size: 13px;
24410- color: #6b7080;
24411- margin-top: 2px;
24412-}
24413-
24414-/* Ticker */
24415-.lv-ticker-wrap {
24416- border-top: 1px solid rgba(22,24,29,0.07);
24417- border-bottom: 1px solid rgba(22,24,29,0.07);
24418- background: #ffffff;
24419- margin-top: 64px;
24420- overflow: hidden;
24421- white-space: nowrap;
24422- position: relative;
24423-}
24424-
24425-.lv-ticker-track {
24426- display: inline-flex;
24427- animation: gcTicker 40s linear infinite;
24428- padding: 11px 0;
24429-}
24430-
24431-.lv-ticker-item {
24432- display: inline-flex;
24433- align-items: center;
24434- gap: 8px;
24435- font-family: 'JetBrains Mono', monospace;
24436- font-size: 11.5px;
24437- color: #6b7080;
24438- padding: 0 28px;
24439- border-right: 1px solid rgba(22,24,29,0.06);
24440-}
24441-
24442-/* Stats */
24443-.lv-stats {
24444- background: #fcfcfd;
24445-}
24446-
24447-.lv-stats-inner {
24448- max-width: 1200px;
24449- margin: 0 auto;
24450- display: grid;
24451- grid-template-columns: repeat(4, 1fr);
24452- gap: 24px;
24453- padding: 52px 28px;
24454-}
24455-
24456-.lv-stat {
24457- text-align: center;
24458-}
24459-
24460-.lv-stat-num {
24461- font-family: 'Inter Tight', sans-serif;
24462- font-weight: 700;
24463- font-size: clamp(30px, 4vw, 44px);
24464- letter-spacing: -0.025em;
24465- color: #111318;
24466-}
24467-
24468-.lv-stat-label {
24469- font-size: 13px;
24470- color: #6b7080;
24471- margin-top: 4px;
24472-}
24473-
24474-/* Loop */
24475-.lv-loop {
24476- padding: 96px 0;
24477- background: #ffffff;
24478- border-top: 1px solid rgba(22,24,29,0.07);
24479- border-bottom: 1px solid rgba(22,24,29,0.07);
24480-}
24481-
24482-.lv-loop-inner {
24483- max-width: 1200px;
24484- margin: 0 auto;
24485- padding: 0 28px;
24486-}
24487-
24488-.lv-stages {
24489- display: grid;
24490- grid-template-columns: repeat(6, 1fr);
24491- gap: 12px;
24492-}
24493-
24494-.lv-stage-card {
24495- border: 1px solid rgba(22,24,29,0.08);
24496- border-radius: 14px;
24497- background: #ffffff;
24498- padding: 20px 18px;
24499- transition: border-color 0.3s, background 0.3s;
24500-}
24501-
24502-.lv-stage-card.lv-stage-active {
24503- border-color: rgba(67,83,201,0.45);
24504- background: rgba(67,83,201,0.03);
24505-}
24506-
24507-.lv-stage-header {
24508- display: flex;
24509- align-items: center;
24510- gap: 8px;
24511- margin-bottom: 10px;
24512-}
24513-
24514-.lv-stage-n {
24515- font-family: 'JetBrains Mono', monospace;
24516- font-size: 10.5px;
24517- letter-spacing: 0.1em;
24518- text-transform: uppercase;
24519- color: #8a8d99;
24520-}
24521-
24522-.lv-stage-name {
24523- font-family: 'Inter Tight', sans-serif;
24524- font-size: 16px;
24525- font-weight: 600;
24526- letter-spacing: -0.01em;
24527- color: #16181d;
24528- margin-bottom: 5px;
24529-}
24530-
24531-.lv-stage-desc {
24532- font-size: 12px;
24533- color: #6b7080;
24534- line-height: 1.55;
24535-}
24536-
24537-.lv-stage-meta {
24538- font-family: 'JetBrains Mono', monospace;
24539- font-size: 10.5px;
24540- color: #8a8d99;
24541- margin-top: 10px;
24542- transition: color 0.3s;
24543-}
24544-
24545-.lv-stage-meta.lv-stage-meta-active {
24546- color: #4353c9;
24547-}
24548-
24549-/* Heroes */
24550-.lv-heroes {
24551- padding: 96px 0;
24552- background: #fcfcfd;
24553-}
24554-
24555-.lv-heroes-inner {
24556- max-width: 1200px;
24557- margin: 0 auto;
24558- padding: 0 28px;
24559-}
24560-
24561-.lv-heroes-header {
24562- max-width: 640px;
24563- margin-bottom: 56px;
24564-}
24565-
24566-.lv-heroes-list {
24567- display: flex;
24568- flex-direction: column;
24569- gap: 20px;
24570-}
24571-
24572-.lv-hero-card {
24573- display: grid;
24574- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
24575- gap: 48px;
24576- align-items: center;
24577- border: 1px solid rgba(22,24,29,0.08);
24578- border-radius: 20px;
24579- background: #ffffff;
24580- padding: 44px 48px;
24581- text-decoration: none;
24582- transition: border-color 0.2s, box-shadow 0.2s;
24583-}
24584-.lv-hero-card:hover {
24585- border-color: rgba(22,24,29,0.22);
24586- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
24587-}
24588-
24589-.lv-hero-card-left {}
24590-
24591-.lv-hero-card-title {
24592- font-family: 'Inter Tight', sans-serif;
24593- font-size: 26px;
24594- font-weight: 600;
24595- letter-spacing: -0.022em;
24596- line-height: 1.15;
24597- color: #16181d;
24598- margin: 0 0 12px;
24599-}
24600-
24601-.lv-hero-card-body {
24602- font-size: 14.5px;
24603- color: #6b7080;
24604- margin: 0 0 18px;
24605- line-height: 1.65;
24606-}
24607-
24608-.lv-hero-card-cta {
24609- font-size: 13.5px;
24610- font-weight: 600;
24611- color: #4353c9;
24612-}
24613-
24614-.lv-terminal {
24615- border: 1px solid rgba(22,24,29,0.07);
24616- border-radius: 14px;
24617- background: #fcfcfd;
24618- padding: 20px 22px;
24619- font-family: 'JetBrains Mono', monospace;
24620- font-size: 12px;
24621- line-height: 1.9;
24622- overflow: hidden;
24623-}
24624-
24625-.lv-terminal-line {
24626- display: flex;
24627- align-items: center;
24628- gap: 10px;
24629- white-space: nowrap;
24630- overflow: hidden;
24631- text-overflow: ellipsis;
24632-}
24633-
24634-/* Platform */
24635-.lv-platform {
24636- padding: 96px 0;
24637- background: #ffffff;
24638- border-top: 1px solid rgba(22,24,29,0.07);
24639-}
24640-
24641-.lv-platform-inner {
24642- max-width: 1200px;
24643- margin: 0 auto;
24644- padding: 0 28px;
24645-}
24646-
24647-.lv-cap-grid {
24648- display: grid;
24649- grid-template-columns: repeat(4, 1fr);
24650- gap: 24px 32px;
24651-}
24652-
24653-.lv-cap-col {}
24654-
24655-.lv-cap-group {
24656- font-family: 'JetBrains Mono', monospace;
24657- font-size: 10.5px;
24658- letter-spacing: 0.12em;
24659- text-transform: uppercase;
24660- color: #8a8d99;
24661- font-weight: 500;
24662- margin-bottom: 12px;
24663- padding-bottom: 8px;
24664- border-bottom: 1px solid rgba(22,24,29,0.07);
24665-}
24666-
24667-.lv-cap-items {
24668- display: flex;
24669- flex-direction: column;
24670- gap: 7px;
24671-}
24672-
24673-.lv-cap-item {
24674- font-size: 12.5px;
24675- color: #3a3d45;
24676- line-height: 1.45;
24677-}
24678-
24679-/* Sovereignty */
24680-.lv-sovereign {
24681- position: relative;
24682- overflow: hidden;
24683- padding: 104px 0;
24684- color: #fff;
24685- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
24686-}
24687-
24688-.lv-sovereign-grid-bg {
24689- position: absolute;
24690- inset: 0;
24691- opacity: 0.4;
24692- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
24693- background-size: 56px 56px;
24694- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
24695- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
24696-}
24697-
24698-.lv-sovereign-inner {
24699- position: relative;
24700- max-width: 1200px;
24701- margin: 0 auto;
24702- padding: 0 28px;
24703-}
24704-
24705-.lv-section-header-dark {
24706- max-width: 680px;
24707- margin: 0 auto 48px;
24708- text-align: center;
24709-}
24710-
24711-.lv-layers-grid {
24712- display: grid;
24713- grid-template-columns: repeat(4, 1fr);
24714- gap: 10px;
24715- max-width: 980px;
24716- margin: 0 auto;
24717-}
24718-
24719-.lv-layer-chip {
24720- border: 1px solid rgba(255,255,255,0.10);
24721- border-radius: 10px;
24722- padding: 12px 16px;
24723- background: rgba(255,255,255,0.03);
24724-}
24725-
24726-.lv-layer-cta {
24727- border-color: rgba(169,180,238,0.30);
24728- background: rgba(169,180,238,0.06);
24729- display: flex;
24730- align-items: center;
24731- text-decoration: none;
24732- transition: background 0.15s;
24733-}
24734-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
24735-
24736-.lv-layer-cta-text {
24737- font-size: 13px;
24738- font-weight: 500;
24739- color: #a9b4ee;
24740-}
24741-
24742-.lv-layer-n {
24743- font-family: 'JetBrains Mono', monospace;
24744- font-size: 10px;
24745- color: rgba(255,255,255,0.4);
24746- margin-bottom: 3px;
24747-}
24748-
24749-.lv-layer-name {
24750- font-size: 13px;
24751- font-weight: 500;
24752- color: rgba(255,255,255,0.92);
24753-}
24754-
24755-.lv-sovereign-feats {
24756- display: flex;
24757- gap: 44px;
24758- justify-content: center;
24759- flex-wrap: wrap;
24760- margin-top: 52px;
24761- text-align: center;
24762-}
24763-
24764-.lv-sovereign-feat {}
24765-
24766-.lv-sovereign-feat-title {
24767- font-family: 'Inter Tight', sans-serif;
24768- font-size: 20px;
24769- font-weight: 700;
24770- color: #fff;
24771-}
24772-
24773-.lv-sovereign-feat-sub {
24774- color: rgba(255,255,255,0.55);
24775- font-size: 13px;
24776- margin-top: 2px;
24777-}
24778-
24779-/* Twin cards */
24780-.lv-twin {
24781- padding: 96px 0;
24782- background: #fcfcfd;
24783-}
24784-
24785-.lv-twin-inner {
24786- max-width: 1200px;
24787- margin: 0 auto;
24788- padding: 0 28px;
24789- display: grid;
24790- grid-template-columns: 1fr 1fr;
24791- gap: 24px;
24792-}
24793-
24794-.lv-twin-card {
24795- border: 1px solid rgba(22,24,29,0.08);
24796- border-radius: 20px;
24797- background: #ffffff;
24798- padding: 44px 48px;
24799-}
24800-
24801-.lv-twin-title {
24802- font-family: 'Inter Tight', sans-serif;
24803- font-size: 24px;
24804- font-weight: 600;
24805- letter-spacing: -0.02em;
24806- line-height: 1.2;
24807- margin: 0 0 12px;
24808- color: #16181d;
24809-}
24810-
24811-.lv-twin-body {
24812- font-size: 14.5px;
24813- color: #6b7080;
24814- margin: 0 0 16px;
24815- line-height: 1.7;
24816-}
24817-
24818-.lv-twin-link {
24819- font-size: 13.5px;
24820- font-weight: 600;
24821- color: #4353c9;
24822- text-decoration: none;
24823-}
24824-.lv-twin-link:hover { text-decoration: underline; }
24825-
24826-/* Quote */
24827-.lv-quote {
24828- padding: 40px 0 96px;
24829- background: #fcfcfd;
24830-}
24831-
24832-.lv-quote-inner {
24833- max-width: 980px;
24834- margin: 0 auto;
24835- padding: 0 28px;
24836- text-align: center;
24837-}
24838-
24839-.lv-quote-text {
24840- font-family: 'Inter Tight', sans-serif;
24841- font-weight: 600;
24842- font-size: clamp(26px, 3.8vw, 42px);
24843- line-height: 1.2;
24844- letter-spacing: -0.025em;
24845- margin: 0;
24846- color: #111318;
24847-}
24848-
24849-.lv-em {
24850- font-style: normal;
24851- color: #4353c9;
24852-}
24853-
24854-/* CTA */
24855-.lv-cta-section {
24856- padding: 0 0 104px;
24857- background: #fcfcfd;
24858-}
24859-
24860-.lv-cta-card {
24861- max-width: 820px;
24862- margin: 0 auto;
24863- padding: 64px 40px;
24864- text-align: center;
24865- background: #ffffff;
24866- border: 1px solid rgba(22,24,29,0.08);
24867- border-radius: 26px;
24868- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
24869- position: relative;
24870- overflow: hidden;
24871-}
24872-
24873-.lv-cta-glow {
24874- position: absolute;
24875- inset: -40% 0 auto 0;
24876- height: 280px;
24877- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
24878- pointer-events: none;
24879-}
24880-
24881-.lv-cta-h2 {
24882- font-family: 'Inter Tight', sans-serif;
24883- font-weight: 700;
24884- letter-spacing: -0.028em;
24885- font-size: clamp(30px, 4.6vw, 48px);
24886- margin: 0;
24887- position: relative;
24888- color: #111318;
24889-}
24890-
24891-.lv-cta-sub {
24892- color: #6b7080;
24893- font-size: 17px;
24894- margin: 16px 0 30px;
24895- position: relative;
24896-}
24897-
24898-.lv-cta-actions {
24899- display: flex;
24900- gap: 12px;
24901- justify-content: center;
24902- flex-wrap: wrap;
24903- position: relative;
24904-}
24905-
24906-.lv-cta-fine {
24907- margin-top: 20px;
24908- font-family: 'JetBrains Mono', monospace;
24909- font-size: 11px;
24910- color: #8a8d99;
24911- position: relative;
24912-}
24913-
24914-/* Footer */
24915-.lv-footer {
24916- border-top: 1px solid rgba(22,24,29,0.07);
24917- background: #ffffff;
24918- padding: 56px 0 30px;
24919-}
24920-
24921-.lv-footer-inner {
24922- max-width: 1200px;
24923- margin: 0 auto;
24924- padding: 0 28px;
24925- display: flex;
24926- gap: 48px;
24927- flex-wrap: wrap;
24928- justify-content: space-between;
24929-}
24930-
24931-.lv-footer-brand {}
24932-
24933-.lv-footer-tagline {
24934- color: #6b7080;
24935- font-size: 13.5px;
24936- margin: 12px 0 0;
24937- max-width: 32ch;
24938- line-height: 1.6;
24939-}
24940-
24941-.lv-footer-cols {
24942- display: flex;
24943- gap: 64px;
24944- flex-wrap: wrap;
24945-}
24946-
24947-.lv-footer-col {
24948- display: flex;
24949- flex-direction: column;
24950- gap: 9px;
24951-}
24952-
24953-.lv-footer-col-head {
24954- font-family: 'JetBrains Mono', monospace;
24955- font-size: 11px;
24956- text-transform: uppercase;
24957- letter-spacing: 0.1em;
24958- color: #8a8d99;
24959- margin: 0 0 4px;
24960- font-weight: 500;
24961-}
24962-
24963-.lv-footer-link {
24964- color: #3a3d45;
24965- font-size: 13.5px;
24966- text-decoration: none;
24967- transition: color 0.15s;
24968-}
24969-.lv-footer-link:hover { color: #16181d; }
24970-
24971-.lv-footer-bar {
24972- max-width: 1200px;
24973- margin: 44px auto 0;
24974- padding: 22px 28px 0;
24975- border-top: 1px solid rgba(22,24,29,0.06);
24976- display: flex;
24977- justify-content: space-between;
24978- flex-wrap: wrap;
24979- gap: 8px;
24980- color: #8a8d99;
24981- font-size: 12.5px;
24982-}
24983-
24984-.lv-footer-stack {
24985- font-family: 'JetBrains Mono', monospace;
24986- font-size: 11px;
24987-}
24988-`;
24989diff --git a/src/views/layout.tsx b/src/views/layout.tsx
24990index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
24991--- a/src/views/layout.tsx
24992+++ b/src/views/layout.tsx
24993@@ -3153,9 +3153,12 @@
24994 font-weight: 500;
24995 line-height: 1.4;
24996 }
24997- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
24998- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
24999- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
25000+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
25001+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
25002+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
25003+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
25004+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
25005+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
25006 .state-merged { color: var(--accent); }
25007 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
25008
25009diff --git a/src/views/ui.tsx b/src/views/ui.tsx
25010index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
25011--- a/src/views/ui.tsx
25012+++ b/src/views/ui.tsx
25013@@ -232,7 +232,7 @@
25014
25015 export const Badge: FC<
25016 PropsWithChildren<{
25017- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
25018+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
25019 style?: string;
25020 }>
25021 > = ({ children, variant = "default", style }) => {
25022@@ -241,9 +241,12 @@
25023 variant === "closed" ? "badge-closed" :
25024 variant === "merged" ? "badge-merged" :
25025 variant === "success" ? "badge-success" :
25026- variant === "danger" ? "badge-danger" :
25027- variant === "warning" ? "badge-warning" :
25028- "badge";
25029+ variant === "danger" ? "badge-danger" :
25030+ variant === "warning" ? "badge-warning" :
25031+ variant === "live" ? "badge-live" :
25032+ variant === "soon" ? "badge-soon" :
25033+ variant === "preview" ? "badge-preview" :
25034+ "badge";
25035 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
25036 };
25037
25038
250392026-07-17T06:23:11.788075Z ERROR codex_core::tools::router: error=Exit code: 1
25040Wall time: 227.9 seconds
25041Output:
25042src/__tests__/ai-review.test.ts(124,30): error TS2554: Expected 2 arguments, but got 1.
25043src/git/repository.ts(59,18): error TS2345: Argument of type 'number | ReadableStream<Uint8Array<ArrayBuffer>> | undefined' is not assignable to parameter of type 'BodyInit | null | undefined'.
25044 Type 'number' is not assignable to type 'BodyInit | null | undefined'.
25045src/git/repository.ts(60,18): error TS2345: Argument of type 'number | ReadableStream<Uint8Array<ArrayBuffer>> | undefined' is not assignable to parameter of type 'BodyInit | null | undefined'.
25046 Type 'number' is not assignable to type 'BodyInit | null | undefined'.
25047src/lib/markdown.ts(15,26): error TS7016: Could not find a declaration file for module 'sanitize-html'. 'C:/Users/ccant/gluecron.com/node_modules/sanitize-html/index.js' implicitly has an 'any' type.
25048 Try `npm i --save-dev @types/sanitize-html` if it exists or add a new declaration (.d.ts) file containing `declare module 'sanitize-html';`
25049src/routes/admin-command.tsx(54,4): error TS2503: Cannot find namespace 'JSX'.
25050src/routes/admin.tsx(2759,31): error TS2352: Conversion of type '{ n: number; } | { n: number; }' to type '{ n: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If
25051this was intentional, convert the expression to 'unknown' first.
25052 Type '{ n: number; }' is missing the following properties from type '{ n: number; }[]': length, pop, push, concat, and 29 more.
25053src/routes/admin.tsx(2760,34): error TS2352: Conversion of type '{ n: number; } | { n: number; }' to type '{ n: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If
25054this was intentional, convert the expression to 'unknown' first.
25055 Type '{ n: number; }' is missing the following properties from type '{ n: number; }[]': length, pop, push, concat, and 29 more.
25056src/routes/ai-archaeology.tsx(589,44): error TS2322: Type '"archaeology"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" |
25057"changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25058src/routes/ai-archaeology.tsx(670,42): error TS2322: Type '"archaeology"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" |
25059"changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25060src/routes/automation-settings.tsx(287,21): error TS2322: Type 'string' is not assignable to type '(event: Event) => void'.
25061src/routes/automation-settings.tsx(297,21): error TS2322: Type 'string' is not assignable to type '(event: Event) => void'.
25062src/routes/automation-settings.tsx(307,21): error TS2322: Type 'string' is not assignable to type '(event: Event) => void'.
25063src/routes/mcp.ts(52,17): error TS2344: Type 'undefined' does not satisfy the constraint '(...args: any) => any'.
25064src/routes/mcp.ts(52,45): error TS2493: Tuple type '[path: string]' of length '1' has no element at index '1'.
25065src/routes/mcp.ts(63,7): error TS2339: Property 'header' does not exist on type 'never'.
25066src/routes/mcp.ts(67,14): error TS2339: Property 'json' does not exist on type 'never'.
25067src/routes/mcp.ts(79,5): error TS2339: Property 'header' does not exist on type 'never'.
25068src/routes/mcp.ts(80,12): error TS2339: Property 'json' does not exist on type 'never'.
25069src/routes/mcp.ts(169,26): error TS2345: Argument of type 'Context<AuthEnv, "/mcp", BlankInput>' is not assignable to parameter of type 'never'.
25070src/routes/mcp.ts(176,26): error TS2345: Argument of type 'Context<AuthEnv, "/mcp", BlankInput>' is not assignable to parameter of type 'never'.
25071src/routes/oauth.tsx(697,14): error TS2769: No overload matches this call.
25072 Overload 1 of 3, '(left: PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true;
25073isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>, right: string | SQLWrapper): SQL<...>', gave the following error.
25074 Argument of type 'string | null' is not assignable to parameter of type 'string | SQLWrapper'.
25075 Type 'null' is not assignable to type 'string | SQLWrapper'.
25076 Overload 2 of 3, '(left: Aliased<string | null>, right: string | SQLWrapper | null): SQL<unknown>', gave the following error.
25077 Argument of type 'PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true;
25078isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>' is not assignable to parameter of type 'Aliased<string |
25079null>'.
25080 Type 'PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true; isAutoincrement:
25081false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>' is missing the following properties from type 'Aliased<string | null>': sql,
25082fieldAlias
25083 Overload 3 of 3, '(left: never, right: unknown): SQL<unknown>', gave the following error.
25084 Argument of type 'PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true;
25085isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>' is not assignable to parameter of type 'never'.
25086src/routes/oauth.tsx(1398,17): error TS2344: Type 'undefined' does not satisfy the constraint '(...args: any) => any'.
25087src/routes/oauth.tsx(1398,47): error TS2493: Tuple type '[path: string]' of length '1' has no element at index '1'.
25088src/routes/oauth.tsx(1403,12): error TS2339: Property 'json' does not exist on type 'never'.
25089src/routes/oauth.tsx(1411,21): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25090src/routes/oauth.tsx(1419,7): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25091src/routes/oauth.tsx(1426,7): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25092src/routes/oauth.tsx(1435,9): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25093src/routes/oauth.tsx(1456,7): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25094src/routes/pipeline.tsx(394,11): error TS2322: Type '{ owner: string; repo: string; description: string; isPrivate: boolean; isFork: boolean; stars: any; forks: any; }' is not assignable to type
25095'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined; currentUser?: string | ... 1 more ... | undefined; ... 4
25096more ...; healthScore?: number | undefined; }'.
25097 Property 'description' does not exist on type 'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined;
25098currentUser?: string | ... 1 more ... | undefined; ... 4 more ...; healthScore?: number | undefined; }'.
25099src/routes/pipeline.tsx(397,31): error TS2551: Property 'starsCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate: boolean;
25100isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'starCount'?
25101src/routes/pipeline.tsx(398,31): error TS2551: Property 'forksCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate: boolean;
25102isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'forkCount'?
25103src/routes/pipeline.tsx(400,44): error TS2322: Type '"pipeline"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" | "changelog"
25104| "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25105src/routes/web.tsx(1958,11): error TS2322: Type 'LandingLiveFeed | null' is not assignable to type 'LandingProLiveFeed | null | undefined'.
25106 Type 'LandingLiveFeed' is not assignable to type 'LandingProLiveFeed'.
25107 Types of property 'queued' are incompatible.
25108 Type 'LandingLiveFeedQueued[]' is not assignable to type 'QueuedAiBuildIssue[]'.
25109 Type 'LandingLiveFeedQueued' is not assignable to type 'QueuedAiBuildIssue'.
25110 Types of property 'createdAt' are incompatible.
25111 Type 'string | Date' is not assignable to type 'Date'.
25112 Type 'string' is not assignable to type 'Date'.
25113src/routes/web.tsx(2204,29): error TS2322: Type '{ id: string; username: string; email: string; displayName: string | null; passwordHash: string; avatarUrl: string | null; bio: string | null;
25114notifyEmailOnMention: boolean; notifyEmailOnAssign: boolean; ... 24 more ...; updatedAt: Date; } | null' is not assignable to type '{ name?: string | undefined; initials?: string | undefined; } | undefined'.
25115 Type 'null' is not assignable to type '{ name?: string | undefined; initials?: string | undefined; } | undefined'.
25116src/routes/webhooks.tsx(818,5): error TS2322: Type '(repositoryId: string) => Omit<PgSelectBase<"webhooks", { id: PgColumn<{ name: "id"; tableName: "webhooks"; dataType: "string"; columnType: "PgUUID"; data:
25117string; driverParam: string; notNull: true; hasDefault: true; ... 6 more ...; generated: undefined; }, {}, {}>; ... 7 more ...; createdAt: PgColumn<...>; }, ... ...' is not assignable to type '(repositoryId:
25118string) => Promise<{ id: string; secret: string; isActive: boolean; events: string; }[]>'.
25119 Call signature return types 'Omit<PgSelectBase<"webhooks", { id: PgColumn<{ name: "id"; tableName: "webhooks"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true;
25120hasDefault: true; isPrimaryKey: true; isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>; ... 7 more ...; createdAt: PgCo...' and 'Promise<{ id: string; secret: string; isActive:
25121boolean; events: string; }[]>' are incompatible.
25122 The types of 'then' are incompatible between these types.
25123 Type '<TResult1 = { id: string; repositoryId: string; url: string; secret: string | null; events: string; isActive: boolean; lastDeliveredAt: Date | null; lastStatus: number | null; createdAt: Date;
25124}[], TResult2 = never>(onFulfilled?: ((value: { ...; }[]) => TResult1 | PromiseLike<...>) | ... 1 more ... | undefined, onRe...' is not assignable to type '<TResult1 = { id: string; secret: string; isActive:
25125boolean; events: string; }[], TResult2 = never>(onfulfilled?: ((value: { id: string; secret: string; isActive: boolean; events: string; }[]) => TResult1 | PromiseLike<TResult1>) | null | undefined,
25126onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | ... 1...'.
25127 Types of parameters 'onFulfilled' and 'onfulfilled' are incompatible.
25128 Types of parameters 'value' and 'value' are incompatible.
25129 Type '{ id: string; repositoryId: string; url: string; secret: string | null; events: string; isActive: boolean; lastDeliveredAt: Date | null; lastStatus: number | null; createdAt: Date; }[]' is
25130not assignable to type '{ id: string; secret: string; isActive: boolean; events: string; }[]'.
25131 Type '{ id: string; repositoryId: string; url: string; secret: string | null; events: string; isActive: boolean; lastDeliveredAt: Date | null; lastStatus: number | null; createdAt: Date; }' is
25132not assignable to type '{ id: string; secret: string; isActive: boolean; events: string; }'.
25133 Types of property 'secret' are incompatible.
25134 Type 'string | null' is not assignable to type 'string'.
25135 Type 'null' is not assignable to type 'string'.
25136src/routes/well-known.ts(79,45): error TS2344: Type 'undefined' does not satisfy the constraint '(...args: any) => any'.
25137src/routes/well-known.ts(79,78): error TS2493: Tuple type '[path: string]' of length '1' has no element at index '1'.
25138src/routes/well-known.ts(81,12): error TS2339: Property 'json' does not exist on type 'never'.
25139src/routes/well-known.ts(94,56): error TS2769: No overload matches this call.
25140 The last overload gave the following error.
25141 Argument of type '(c: never) => any' is not assignable to parameter of type 'H<BlankEnv, "/.well-known/oauth-protected-resource", BlankInput, any>'.
25142 Type '(c: never) => any' is not assignable to type 'Handler<BlankEnv, "/.well-known/oauth-protected-resource", BlankInput, any>'.
25143 Types of parameters 'c' and 'c' are incompatible.
25144 Type 'Context<BlankEnv, "/.well-known/oauth-protected-resource", BlankInput>' is not assignable to type 'never'.
25145src/routes/well-known.ts(97,60): error TS2769: No overload matches this call.
25146 The last overload gave the following error.
25147 Argument of type '(c: never) => any' is not assignable to parameter of type 'H<BlankEnv, "/.well-known/oauth-protected-resource/mcp", BlankInput, any>'.
25148 Type '(c: never) => any' is not assignable to type 'Handler<BlankEnv, "/.well-known/oauth-protected-resource/mcp", BlankInput, any>'.
25149 Types of parameters 'c' and 'c' are incompatible.
25150 Type 'Context<BlankEnv, "/.well-known/oauth-protected-resource/mcp", BlankInput>' is not assignable to type 'never'.
25151src/routes/workspace-hub.tsx(230,11): error TS2322: Type '{ owner: string; repo: string; description: string; isPrivate: boolean; isFork: boolean; stars: any; forks: any; }' is not assignable to type
25152'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined; currentUser?: string | ... 1 more ... | undefined; ... 4
25153more ...; healthScore?: number | undefined; }'.
25154 Property 'description' does not exist on type 'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined;
25155currentUser?: string | ... 1 more ... | undefined; ... 4 more ...; healthScore?: number | undefined; }'.
25156src/routes/workspace-hub.tsx(233,31): error TS2551: Property 'starsCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate:
25157boolean; isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'starCount'?
25158src/routes/workspace-hub.tsx(234,31): error TS2551: Property 'forksCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate:
25159boolean; isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'forkCount'?
25160src/routes/workspace-hub.tsx(236,44): error TS2322: Type '"workspace"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" |
25161"changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25162src/views/components.tsx(284,14): error TS2367: This comparison appears to be unintentional because the types '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" |
25163"security" | "changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"' and '"pipeline"' have no overlap.
25164src/views/components.tsx(312,28): error TS2367: This comparison appears to be unintentional because the types '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" |
25165"security" | "changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"' and '"workspace"' have no overlap.
25166src/views/components.tsx(347,28): error TS2367: This comparison appears to be unintentional because the types '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" |
25167"security" | "changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"' and '"archaeology"' have no overlap.
25168src/views/pr-redesign.tsx(235,83): error TS2322: Type 'string' is not assignable to type 'number'.
25169$ tsc --noEmit
25170
25171 exited 1 in 227861ms:
25172src/__tests__/ai-review.test.ts(124,30): error TS2554: Expected 2 arguments, but got 1.
25173src/git/repository.ts(59,18): error TS2345: Argument of type 'number | ReadableStream<Uint8Array<ArrayBuffer>> | undefined' is not assignable to parameter of type 'BodyInit | null | undefined'.
25174 Type 'number' is not assignable to type 'BodyInit | null | undefined'.
25175src/git/repository.ts(60,18): error TS2345: Argument of type 'number | ReadableStream<Uint8Array<ArrayBuffer>> | undefined' is not assignable to parameter of type 'BodyInit | null | undefined'.
25176 Type 'number' is not assignable to type 'BodyInit | null | undefined'.
25177src/lib/markdown.ts(15,26): error TS7016: Could not find a declaration file for module 'sanitize-html'. 'C:/Users/ccant/gluecron.com/node_modules/sanitize-html/index.js' implicitly has an 'any' type.
25178 Try `npm i --save-dev @types/sanitize-html` if it exists or add a new declaration (.d.ts) file containing `declare module 'sanitize-html';`
25179src/routes/admin-command.tsx(54,4): error TS2503: Cannot find namespace 'JSX'.
25180src/routes/admin.tsx(2759,31): error TS2352: Conversion of type '{ n: number; } | { n: number; }' to type '{ n: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If
25181this was intentional, convert the expression to 'unknown' first.
25182 Type '{ n: number; }' is missing the following properties from type '{ n: number; }[]': length, pop, push, concat, and 29 more.
25183src/routes/admin.tsx(2760,34): error TS2352: Conversion of type '{ n: number; } | { n: number; }' to type '{ n: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If
25184this was intentional, convert the expression to 'unknown' first.
25185 Type '{ n: number; }' is missing the following properties from type '{ n: number; }[]': length, pop, push, concat, and 29 more.
25186src/routes/ai-archaeology.tsx(589,44): error TS2322: Type '"archaeology"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" |
25187"changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25188src/routes/ai-archaeology.tsx(670,42): error TS2322: Type '"archaeology"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" |
25189"changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25190src/routes/automation-settings.tsx(287,21): error TS2322: Type 'string' is not assignable to type '(event: Event) => void'.
25191src/routes/automation-settings.tsx(297,21): error TS2322: Type 'string' is not assignable to type '(event: Event) => void'.
25192src/routes/automation-settings.tsx(307,21): error TS2322: Type 'string' is not assignable to type '(event: Event) => void'.
25193src/routes/mcp.ts(52,17): error TS2344: Type 'undefined' does not satisfy the constraint '(...args: any) => any'.
25194src/routes/mcp.ts(52,45): error TS2493: Tuple type '[path: string]' of length '1' has no element at index '1'.
25195src/routes/mcp.ts(63,7): error TS2339: Property 'header' does not exist on type 'never'.
25196src/routes/mcp.ts(67,14): error TS2339: Property 'json' does not exist on type 'never'.
25197src/routes/mcp.ts(79,5): error TS2339: Property 'header' does not exist on type 'never'.
25198src/routes/mcp.ts(80,12): error TS2339: Property 'json' does not exist on type 'never'.
25199src/routes/mcp.ts(169,26): error TS2345: Argument of type 'Context<AuthEnv, "/mcp", BlankInput>' is not assignable to parameter of type 'never'.
25200src/routes/mcp.ts(176,26): error TS2345: Argument of type 'Context<AuthEnv, "/mcp", BlankInput>' is not assignable to parameter of type 'never'.
25201src/routes/oauth.tsx(697,14): error TS2769: No overload matches this call.
25202 Overload 1 of 3, '(left: PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true;
25203isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>, right: string | SQLWrapper): SQL<...>', gave the following error.
25204 Argument of type 'string | null' is not assignable to parameter of type 'string | SQLWrapper'.
25205 Type 'null' is not assignable to type 'string | SQLWrapper'.
25206 Overload 2 of 3, '(left: Aliased<string | null>, right: string | SQLWrapper | null): SQL<unknown>', gave the following error.
25207 Argument of type 'PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true;
25208isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>' is not assignable to parameter of type 'Aliased<string |
25209null>'.
25210 Type 'PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true; isAutoincrement:
25211false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>' is missing the following properties from type 'Aliased<string | null>': sql,
25212fieldAlias
25213 Overload 3 of 3, '(left: never, right: unknown): SQL<unknown>', gave the following error.
25214 Argument of type 'PgColumn<{ name: "id"; tableName: "users"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true;
25215isAutoincrement: false; hasRuntimeDefault: false; enumValues: undefined; baseColumn: never; identity: undefined; generated: undefined; }, {}, {}>' is not assignable to parameter of type 'never'.
25216src/routes/oauth.tsx(1398,17): error TS2344: Type 'undefined' does not satisfy the constraint '(...args: any) => any'.
25217src/routes/oauth.tsx(1398,47): error TS2493: Tuple type '[path: string]' of length '1' has no element at index '1'.
25218src/routes/oauth.tsx(1403,12): error TS2339: Property 'json' does not exist on type 'never'.
25219src/routes/oauth.tsx(1411,21): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25220src/routes/oauth.tsx(1419,7): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25221src/routes/oauth.tsx(1426,7): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25222src/routes/oauth.tsx(1435,9): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25223src/routes/oauth.tsx(1456,7): error TS2345: Argument of type 'Context<AuthEnv, "/oauth/register", BlankInput>' is not assignable to parameter of type 'never'.
25224src/routes/pipeline.tsx(394,11): error TS2322: Type '{ owner: string; repo: string; description: string; isPrivate: boolean; isFork: boolean; stars: any; forks: any; }' is not assignable to type
25225'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined; currentUser?: string | ... 1 more ... | undefined; ... 4
25226more ...; healthScore?: number | undefined; }'.
25227 Property 'description' does not exist on type 'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined;
25228currentUser?: string | ... 1 more ... | undefined; ... 4 more ...; healthScore?: number | undefined; }'.
25229src/routes/pipeline.tsx(397,31): error TS2551: Property 'starsCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate: boolean;
25230isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'starCount'?
25231src/routes/pipeline.tsx(398,31): error TS2551: Property 'forksCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate: boolean;
25232isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'forkCount'?
25233src/routes/pipeline.tsx(400,44): error TS2322: Type '"pipeline"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" | "changelog"
25234| "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25235src/routes/web.tsx(1958,11): error TS2322: Type 'LandingLiveFeed | null' is not assignable to type 'LandingProLiveFeed | null | undefined'.
25236 Type 'LandingLiveFeed' is not assignable to type 'LandingProLiveFeed'.
25237 Types of property 'queued' are incompatible.
25238 Type 'LandingLiveFeedQueued[]' is not assignable to type 'QueuedAiBuildIssue[]'.
25239 Type 'LandingLiveFeedQueued' is not assignable to type 'QueuedAiBuildIssue'.
25240 Types of property 'createdAt' are incompatible.
25241 Type 'string | Date' is not assignable to type 'Date'.
25242 Type 'string' is not assignable to type 'Date'.
25243src/routes/web.tsx(2204,29): error TS2322: Type '{ id: string; username: string; email: string; displayName: string | null; passwordHash: string; avatarUrl: string | null; bio: string | null;
25244notifyEmailOnMention: boolean; notifyEmailOnAssign: boolean; ... 24 more ...; updatedAt: Date; } | null' is not assignable to type '{ name?: string | undefined; initials?: string | undefined; } | undefined'.
25245 Type 'null' is not assignable to type '{ name?: string | undefined; initials?: string | undefined; } | undefined'.
25246src/routes/webhooks.tsx(818,5): error TS2322: Type '(repositoryId: string) => Omit<PgSelectBase<"webhooks", { id: PgColumn<{ name: "id"; tableName: "webhooks"; dataType: "string"; columnType: "PgUUID"; data:
25247string; driverParam: string; notNull: true; hasDefault: true; ... 6 more ...; generated: undefined; }, {}, {}>; ... 7 more ...; createdAt: PgColumn<...>; }, ... ...' is not assignable to type '(repositoryId:
25248string) => Promise<{ id: string; secret: string; isActive: boolean; events: string; }[]>'.
25249 Call signature return types 'Omit<PgSelectBase<"webhooks", { id: PgColumn<{ name: "id"; tableName: "webhooks"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true;
25250hasDefault: true; isPrimaryKey: true; isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>; ... 7 more ...; createdAt: PgCo...' and 'Promise<{ id: string; secret: string; isActive:
25251boolean; events: string; }[]>' are incompatible.
25252 The types of 'then' are incompatible between these types.
25253 Type '<TResult1 = { id: string; repositoryId: string; url: string; secret: string | null; events: string; isActive: boolean; lastDeliveredAt: Date | null; lastStatus: number | null; createdAt: Date;
25254}[], TResult2 = never>(onFulfilled?: ((value: { ...; }[]) => TResult1 | PromiseLike<...>) | ... 1 more ... | undefined, onRe...' is not assignable to type '<TResult1 = { id: string; secret: string; isActive:
25255boolean; events: string; }[], TResult2 = never>(onfulfilled?: ((value: { id: string; secret: string; isActive: boolean; events: string; }[]) => TResult1 | PromiseLike<TResult1>) | null | undefined,
25256onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | ... 1...'.
25257 Types of parameters 'onFulfilled' and 'onfulfilled' are incompatible.
25258 Types of parameters 'value' and 'value' are incompatible.
25259 Type '{ id: string; repositoryId: string; url: string; secret: string | null; events: string; isActive: boolean; lastDeliveredAt: Date | null; lastStatus: number | null; createdAt: Date; }[]' is
25260not assignable to type '{ id: string; secret: string; isActive: boolean; events: string; }[]'.
25261 Type '{ id: string; repositoryId: string; url: string; secret: string | null; events: string; isActive: boolean; lastDeliveredAt: Date | null; lastStatus: number | null; createdAt: Date; }' is
25262not assignable to type '{ id: string; secret: string; isActive: boolean; events: string; }'.
25263 Types of property 'secret' are incompatible.
25264 Type 'string | null' is not assignable to type 'string'.
25265 Type 'null' is not assignable to type 'string'.
25266src/routes/well-known.ts(79,45): error TS2344: Type 'undefined' does not satisfy the constraint '(...args: any) => any'.
25267src/routes/well-known.ts(79,78): error TS2493: Tuple type '[path: string]' of length '1' has no element at index '1'.
25268src/routes/well-known.ts(81,12): error TS2339: Property 'json' does not exist on type 'never'.
25269src/routes/well-known.ts(94,56): error TS2769: No overload matches this call.
25270 The last overload gave the following error.
25271 Argument of type '(c: never) => any' is not assignable to parameter of type 'H<BlankEnv, "/.well-known/oauth-protected-resource", BlankInput, any>'.
25272 Type '(c: never) => any' is not assignable to type 'Handler<BlankEnv, "/.well-known/oauth-protected-resource", BlankInput, any>'.
25273 Types of parameters 'c' and 'c' are incompatible.
25274 Type 'Context<BlankEnv, "/.well-known/oauth-protected-resource", BlankInput>' is not assignable to type 'never'.
25275src/routes/well-known.ts(97,60): error TS2769: No overload matches this call.
25276 The last overload gave the following error.
25277 Argument of type '(c: never) => any' is not assignable to parameter of type 'H<BlankEnv, "/.well-known/oauth-protected-resource/mcp", BlankInput, any>'.
25278 Type '(c: never) => any' is not assignable to type 'Handler<BlankEnv, "/.well-known/oauth-protected-resource/mcp", BlankInput, any>'.
25279 Types of parameters 'c' and 'c' are incompatible.
25280 Type 'Context<BlankEnv, "/.well-known/oauth-protected-resource/mcp", BlankInput>' is not assignable to type 'never'.
25281src/routes/workspace-hub.tsx(230,11): error TS2322: Type '{ owner: string; repo: string; description: string; isPrivate: boolean; isFork: boolean; stars: any; forks: any; }' is not assignable to type
25282'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined; currentUser?: string | ... 1 more ... | undefined; ... 4
25283more ...; healthScore?: number | undefined; }'.
25284 Property 'description' does not exist on type 'IntrinsicAttributes & { owner: string; repo: string; starCount?: number | undefined; starred?: boolean | undefined; forkCount?: number | undefined;
25285currentUser?: string | ... 1 more ... | undefined; ... 4 more ...; healthScore?: number | undefined; }'.
25286src/routes/workspace-hub.tsx(233,31): error TS2551: Property 'starsCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate:
25287boolean; isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'starCount'?
25288src/routes/workspace-hub.tsx(234,31): error TS2551: Property 'forksCount' does not exist on type '{ id: string; name: string; ownerId: string; orgId: string | null; description: string | null; isPrivate:
25289boolean; isArchived: boolean; isTemplate: boolean; defaultBranch: string; diskPath: string; ... 17 more ...; depUpdaterEnabled: boolean; }'. Did you mean 'forkCount'?
25290src/routes/workspace-hub.tsx(236,44): error TS2322: Type '"workspace"' is not assignable to type '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" | "security" |
25291"changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"'.
25292src/views/components.tsx(284,14): error TS2367: This comparison appears to be unintentional because the types '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" |
25293"security" | "changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"' and '"pipeline"' have no overlap.
25294src/views/components.tsx(312,28): error TS2367: This comparison appears to be unintentional because the types '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" |
25295"security" | "changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"' and '"workspace"' have no overlap.
25296src/views/components.tsx(347,28): error TS2367: This comparison appears to be unintentional because the types '"actions" | "releases" | "deployments" | "issues" | "discussions" | "projects" | "code" |
25297"security" | "changelog" | "insights" | "commits" | "pulls" | "gates" | "explain" | "semantic" | ... 8 more ... | "traffic"' and '"archaeology"' have no overlap.
25298src/views/pr-redesign.tsx(235,83): error TS2322: Type 'string' is not assignable to type 'number'.
25299$ tsc --noEmit
25300
25301diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
25302index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
25303--- a/src/views/landing-pro.tsx
25304+++ b/src/views/landing-pro.tsx
25305@@ -42,7 +42,7 @@
25306
25307 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25308
25309-function icon(paths: string, color = "#4353c9", size = 20) {
25310+function icon(paths: string, color = "#0891b2", size = 20) {
25311 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
25312 }
25313
25314@@ -947,7 +947,7 @@
25315 const css = `
25316 /* %% tokens %% */
25317 :root{
25318- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
25319+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
25320 --lp-bg:#ffffff;--lp-soft:#fafafb;
25321 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
25322 --lp-border:rgba(0,0,0,.08);
25323diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
25324deleted file mode 100644
25325index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
25326--- a/src/views/landing-v2.tsx
25327+++ /dev/null
25328@@ -1,1447 +0,0 @@
25329-import type { FC } from "hono/jsx";
25330-
25331-export interface LandingPageProps {
25332- stats?: {
25333- publicRepos?: number;
25334- users?: number;
25335- };
25336-}
25337-
25338-const demoAllEvents = [
25339- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
25340- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
25341- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
25342- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
25343- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
25344-];
25345-
25346-const tickerItems = [
25347- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
25348- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
25349- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
25350- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
25351- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
25352- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
25353- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
25354- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
25355- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
25356- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
25357- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
25358- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
25359- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
25360- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
25361- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
25362- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
25363-];
25364-
25365-const stageData = [
25366- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
25367- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
25368- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
25369- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
25370- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
25371- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
25372-];
25373-
25374-const heroFeatures = [
25375- {
25376- href: "/",
25377- eyebrow: "01 � The autonomous repair loop",
25378- title: "Failures fix themselves  and show their work.",
25379- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
25380failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
25381- cta: "Watch a live repair session",
25382- mock: [
25383- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
25384- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
25385- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
25386- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
25387- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
25388- ],
25389- },
25390- {
25391- href: "/",
25392- eyebrow: "02 � Live sandbox isolation",
25393- title: "Every PR gets its own instant, disposable environment.",
25394- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
25395same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
25396- cta: "See a PR with its sandbox",
25397- mock: [
25398- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
25399- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
25400- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
25401- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
25402- ],
25403- },
25404- {
25405- href: "/",
25406- eyebrow: "03 � Multiplayer IDE workspaces",
25407- title: "You and the agent, side by side, in your editor.",
25408- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
25409agent into a silent reviewer in your gutter. The browser becomes optional.",
25410- cta: "See the editor session",
25411- mock: [
25412- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
25413- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
25414- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
25415- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
25416- ],
25417- },
25418-];
25419-
25420-const capabilities = [
25421- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
25422- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
25423- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
25424- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
25425- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
25426- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
25427- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
25428- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
25429-];
25430-
25431-const sovereignLayerNames = [
25432- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
25433- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
25434- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
25435- "Availability & recovery",
25436-];
25437-
25438-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
25439- return (
25440- <>
25441- <style dangerouslySetInnerHTML={{ __html: css }} />
25442-
25443- {/* Nav */}
25444- <header class="lv-nav">
25445- <div class="lv-nav-inner">
25446- <a href="/" class="lv-logo">
25447- <span class="lv-logo-mark"></span>gluecron
25448- </a>
25449- <nav class="lv-nav-links">
25450- <a href="#loop" class="lv-nav-link">The loop</a>
25451- <a href="#platform" class="lv-nav-link">Platform</a>
25452- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
25453- <a href="/trust" class="lv-nav-link">Trust</a>
25454- </nav>
25455- <div class="lv-nav-ctas">
25456- <a href="/login" class="lv-btn-secondary">Sign in</a>
25457- <a href="/register" class="lv-btn-primary">Start building</a>
25458- </div>
25459- </div>
25460- </header>
25461-
25462- {/* Hero */}
25463- <section class="lv-hero">
25464- <div class="lv-hero-glow"></div>
25465- <div class="lv-hero-inner">
25466- <div class="lv-hero-badge">
25467- <span class="lv-dot lv-dot-green lv-pulse"></span>
25468- Live: a repair loop converged on pr-218 while you read this
25469- </div>
25470- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
25471- <p class="lv-hero-sub">
25472- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
25473failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
25474- </p>
25475- <div class="lv-hero-actions">
25476- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
25477- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
25478- </div>
25479- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
25480-
25481- {/* Live product window */}
25482- <div class="lv-demo-window">
25483- <div class="lv-demo-bar">
25484- <span class="lv-demo-dot"></span>
25485- <span class="lv-demo-dot"></span>
25486- <span class="lv-demo-dot"></span>
25487- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
25488- <span class="lv-demo-live">
25489- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
25490- LIVE
25491- </span>
25492- </div>
25493- <div class="lv-demo-body" id="lv-demo-body">
25494- {/* Events rendered by JS */}
25495- {demoAllEvents.slice(0, 1).map((e, i) => (
25496- <div class="lv-demo-event" key={i}>
25497- <div class="lv-demo-event-track">
25498- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
25499- <span class="lv-demo-line" style="display:none"></span>
25500- </div>
25501- <div class="lv-demo-event-content">
25502- <div class="lv-demo-event-header">
25503- <span class="lv-demo-event-title">{e.title}</span>
25504- <span class="lv-demo-event-time">{e.time}</span>
25505- </div>
25506- <div class="lv-demo-event-body">{e.body}</div>
25507- </div>
25508- </div>
25509- ))}
25510- </div>
25511- </div>
25512- </div>
25513-
25514- {/* Activity ticker */}
25515- <div class="lv-ticker-wrap">
25516- <div class="lv-ticker-track">
25517- {tickerItems.map((t, i) => (
25518- <span class="lv-ticker-item" key={i}>
25519- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
25520- {t.text}
25521- </span>
25522- ))}
25523- </div>
25524- </div>
25525- </section>
25526-
25527- {/* Stat band */}
25528- <section class="lv-stats">
25529- <div class="lv-stats-inner">
25530- <div class="lv-stat">
25531- <div class="lv-stat-num">Sonnet 5</div>
25532- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
25533- </div>
25534- <div class="lv-stat">
25535- <div class="lv-stat-num">93.5%</div>
25536- <div class="lv-stat-label">of failures self-repair without a human</div>
25537- </div>
25538- <div class="lv-stat">
25539- <div class="lv-stat-num">1.9%</div>
25540- <div class="lv-stat-label">AI merges reverted  published live</div>
25541- </div>
25542- <div class="lv-stat">
25543- <div class="lv-stat-num">0</div>
25544- <div class="lv-stat-label">irreversible actions taken autonomously</div>
25545- </div>
25546- </div>
25547- </section>
25548-
25549- {/* The loop */}
25550- <section id="loop" class="lv-loop">
25551- <div class="lv-loop-inner">
25552- <div class="lv-section-header">
25553- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
25554- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
25555- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
25556- </div>
25557- <div class="lv-stages" id="lv-stages">
25558- {stageData.map((s, i) => (
25559- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
25560- <div class="lv-stage-header">
25561- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
25562- <span class="lv-stage-n">0{i + 1}</span>
25563- </div>
25564- <div class="lv-stage-name">{s.name}</div>
25565- <div class="lv-stage-desc">{s.desc}</div>
25566- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
25567- </div>
25568- ))}
25569- </div>
25570- </div>
25571- </section>
25572-
25573- {/* Three heroes */}
25574- <section class="lv-heroes">
25575- <div class="lv-heroes-inner">
25576- <div class="lv-heroes-header">
25577- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
25578- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
25579- </div>
25580- <div class="lv-heroes-list">
25581- {heroFeatures.map((h, i) => (
25582- <a href={h.href} class="lv-hero-card" key={i}>
25583- <div class="lv-hero-card-left">
25584- <div class="lv-eyebrow">{h.eyebrow}</div>
25585- <h3 class="lv-hero-card-title">{h.title}</h3>
25586- <p class="lv-hero-card-body">{h.body}</p>
25587- <span class="lv-hero-card-cta">{h.cta} �!</span>
25588- </div>
25589- <div class="lv-terminal">
25590- {h.mock.map((m, j) => (
25591- <div class="lv-terminal-line" key={j}>
25592- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
25593- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
25594- </div>
25595- ))}
25596- </div>
25597- </a>
25598- ))}
25599- </div>
25600- </div>
25601- </section>
25602-
25603- {/* Everything grid */}
25604- <section id="platform" class="lv-platform">
25605- <div class="lv-platform-inner">
25606- <div class="lv-section-header lv-section-header-center">
25607- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
25608- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
25609- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
25610- </div>
25611- <div class="lv-cap-grid">
25612- {capabilities.map((c, i) => (
25613- <div class="lv-cap-col" key={i}>
25614- <div class="lv-cap-group">{c.group}</div>
25615- <div class="lv-cap-items">
25616- {c.items.map((item, j) => (
25617- <div class="lv-cap-item" key={j}>{item}</div>
25618- ))}
25619- </div>
25620- </div>
25621- ))}
25622- </div>
25623- </div>
25624- </section>
25625-
25626- {/* Sovereignty band */}
25627- <section id="sovereign" class="lv-sovereign">
25628- <div class="lv-sovereign-grid-bg"></div>
25629- <div class="lv-sovereign-inner">
25630- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
25631- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
25632- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
25633- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
25634to private cloud, or run fully air-gapped on bare metal.</p>
25635- </div>
25636- <div class="lv-layers-grid">
25637- {sovereignLayerNames.map((name, i) => (
25638- <div class="lv-layer-chip" key={i}>
25639- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
25640- <div class="lv-layer-name">{name}</div>
25641- </div>
25642- ))}
25643- <a href="/" class="lv-layer-chip lv-layer-cta">
25644- <div class="lv-layer-cta-text">All self-owned �!</div>
25645- </a>
25646- </div>
25647- <div class="lv-sovereign-feats">
25648- <div class="lv-sovereign-feat">
25649- <div class="lv-sovereign-feat-title">Local inference first</div>
25650- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
25651- </div>
25652- <div class="lv-sovereign-feat">
25653- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
25654- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
25655- </div>
25656- <div class="lv-sovereign-feat">
25657- <div class="lv-sovereign-feat-title">Self-healing infra</div>
25658- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
25659- </div>
25660- </div>
25661- </div>
25662- </section>
25663-
25664- {/* Manual-first + reversibility */}
25665- <section class="lv-twin">
25666- <div class="lv-twin-inner">
25667- <div class="lv-twin-card">
25668- <div class="lv-eyebrow">Manual-first, always</div>
25669- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
25670- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
25671fallback. Developers who never touch AI get the best git host they've ever used.</p>
25672- </div>
25673- <div class="lv-twin-card">
25674- <div class="lv-eyebrow">The reversibility guarantee</div>
25675- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
25676- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
25677 policy, not promise. Our quality numbers are published live, unedited.</p>
25678- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
25679- </div>
25680- </div>
25681- </section>
25682-
25683- {/* Quote */}
25684- <section class="lv-quote">
25685- <div class="lv-quote-inner">
25686- <p class="lv-quote-text">
25687- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
25688- Gluecron is where code gets <em class="lv-em">finished</em>."
25689- </p>
25690- </div>
25691- </section>
25692-
25693- {/* CTA */}
25694- <section class="lv-cta-section">
25695- <div class="lv-cta-card">
25696- <div class="lv-cta-glow"></div>
25697- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
25698- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
25699- <div class="lv-cta-actions">
25700- <a href="/register" class="lv-cta-primary">Create your account �!</a>
25701- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
25702- </div>
25703- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
25704- </div>
25705- </section>
25706-
25707- {/* Footer */}
25708- <footer class="lv-footer">
25709- <div class="lv-footer-inner">
25710- <div class="lv-footer-brand">
25711- <a href="/" class="lv-logo">
25712- <span class="lv-logo-mark"></span>gluecron
25713- </a>
25714- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
25715- </div>
25716- <div class="lv-footer-cols">
25717- <div class="lv-footer-col">
25718- <h4 class="lv-footer-col-head">Product</h4>
25719- <a href="/" class="lv-footer-link">Agent workspace</a>
25720- <a href="/" class="lv-footer-link">Fleet refactors</a>
25721- <a href="/" class="lv-footer-link">Org memory</a>
25722- <a href="/" class="lv-footer-link">IDE extensions</a>
25723- </div>
25724- <div class="lv-footer-col">
25725- <h4 class="lv-footer-col-head">Platform</h4>
25726- <a href="/" class="lv-footer-link">Production layers</a>
25727- <a href="/trust" class="lv-footer-link">Trust report</a>
25728- <a href="/" class="lv-footer-link">Docs</a>
25729- <a href="/" class="lv-footer-link">Status</a>
25730- </div>
25731- <div class="lv-footer-col">
25732- <h4 class="lv-footer-col-head">Company</h4>
25733- <a href="/" class="lv-footer-link">About</a>
25734- <a href="/" class="lv-footer-link">Pricing</a>
25735- <a href="/" class="lv-footer-link">Enterprise</a>
25736- </div>
25737- </div>
25738- </div>
25739- <div class="lv-footer-bar">
25740- <span>� 2026 Gluecron</span>
25741- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
25742- </div>
25743- </footer>
25744-
25745- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
25746- </>
25747- );
25748-};
25749-
25750-export const LandingPage = LandingPageV2;
25751-export default LandingPageV2;
25752-
25753-const clientScript = `
25754-(function() {
25755- var demoAll = [
25756- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
25757- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
25758- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
25759- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
25760- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
25761- ];
25762-
25763- var demoStep = 0;
25764- var stage = 0;
25765-
25766- function renderDemo() {
25767- var container = document.getElementById('lv-demo-body');
25768- if (!container) return;
25769- var visible = demoAll.slice(0, demoStep + 1);
25770- container.innerHTML = visible.map(function(e, i) {
25771- var isLast = i === visible.length - 1;
25772- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
25773- return '<div class="lv-demo-event">' +
25774- '<div class="lv-demo-event-track">' +
25775- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
25776- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
25777- '</div>' +
25778- '<div class="lv-demo-event-content">' +
25779- '<div class="lv-demo-event-header">' +
25780- '<span class="lv-demo-event-title">' + e.title + '</span>' +
25781- '<span class="lv-demo-event-time">' + e.time + '</span>' +
25782- '</div>' +
25783- '<div class="lv-demo-event-body">' + e.body + '</div>' +
25784- '</div>' +
25785- '</div>';
25786- }).join('');
25787- }
25788-
25789- function renderStages() {
25790- var cards = document.querySelectorAll('.lv-stage-card');
25791- cards.forEach(function(card, i) {
25792- var dot = card.querySelector('.lv-dot');
25793- var meta = card.querySelector('.lv-stage-meta');
25794- if (i === stage) {
25795- card.classList.add('lv-stage-active');
25796- if (dot) {
25797- dot.classList.remove('lv-dot-idle');
25798- dot.classList.add('lv-dot-indigo', 'lv-pulse');
25799- }
25800- if (meta) meta.classList.add('lv-stage-meta-active');
25801- } else {
25802- card.classList.remove('lv-stage-active');
25803- if (dot) {
25804- dot.classList.add('lv-dot-idle');
25805- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
25806- }
25807- if (meta) meta.classList.remove('lv-stage-meta-active');
25808- }
25809- });
25810- }
25811-
25812- renderDemo();
25813-
25814- setInterval(function() {
25815- demoStep = (demoStep + 1) % 5;
25816- renderDemo();
25817- }, 3600);
25818-
25819- setInterval(function() {
25820- stage = (stage + 1) % 6;
25821- renderStages();
25822- }, 2200);
25823-})();
25824-`;
25825-
25826-const css = `
25827-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
25828-
25829-*, *::before, *::after { box-sizing: border-box; }
25830-
25831-body {
25832- margin: 0;
25833- background: #fcfcfd;
25834- -webkit-font-smoothing: antialiased;
25835- text-rendering: optimizeLegibility;
25836- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
25837- font-size: 15px;
25838- line-height: 1.6;
25839- letter-spacing: -0.008em;
25840- color: #16181d;
25841-}
25842-
25843-@keyframes gcPulse {
25844- 0%, 100% { opacity: 1; }
25845- 50% { opacity: 0.35; }
25846-}
25847-
25848-@keyframes gcTicker {
25849- 0% { transform: translateX(0); }
25850- 100% { transform: translateX(-50%); }
25851-}
25852-
25853-/* Shared utilities */
25854-.lv-dot {
25855- display: inline-block;
25856- border-radius: 50%;
25857-}
25858-.lv-dot-green { background: #1e7f5c; }
25859-.lv-dot-indigo { background: #4353c9; }
25860-.lv-dot-idle { background: #c4c6cf; }
25861-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
25862-
25863-.lv-strong { color: #16181d; font-weight: 600; }
25864-
25865-.lv-eyebrow {
25866- font-family: 'JetBrains Mono', monospace;
25867- font-size: 11px;
25868- letter-spacing: 0.12em;
25869- text-transform: uppercase;
25870- color: #8a8d99;
25871- font-weight: 500;
25872- margin-bottom: 12px;
25873-}
25874-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
25875-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
25876-
25877-.lv-h1 {
25878- font-family: 'Inter Tight', sans-serif;
25879- font-weight: 700;
25880- letter-spacing: -0.035em;
25881- font-size: clamp(44px, 7vw, 84px);
25882- line-height: 0.98;
25883- margin: 30px auto 0;
25884- max-width: 14ch;
25885- color: #111318;
25886-}
25887-
25888-.lv-h2 {
25889- font-family: 'Inter Tight', sans-serif;
25890- font-weight: 700;
25891- letter-spacing: -0.028em;
25892- font-size: clamp(30px, 4.4vw, 48px);
25893- line-height: 1.05;
25894- margin: 0;
25895- color: #111318;
25896-}
25897-
25898-.lv-h2-dark {
25899- font-family: 'Inter Tight', sans-serif;
25900- font-weight: 700;
25901- letter-spacing: -0.028em;
25902- font-size: clamp(30px, 4.6vw, 52px);
25903- line-height: 1.05;
25904- margin: 0;
25905- color: #fff;
25906-}
25907-
25908-.lv-section-header {
25909- max-width: 640px;
25910- margin: 0 auto 56px;
25911-}
25912-
25913-.lv-section-header-center {
25914- text-align: center;
25915-}
25916-
25917-.lv-section-sub {
25918- color: #6b7080;
25919- font-size: 17px;
25920- margin: 18px auto 0;
25921- max-width: 52ch;
25922-}
25923-
25924-.lv-section-sub-dark {
25925- color: rgba(255,255,255,0.72);
25926- font-size: 17px;
25927- margin: 18px auto 0;
25928- max-width: 56ch;
25929-}
25930-
25931-/* Nav */
25932-.lv-nav {
25933- position: sticky;
25934- top: 0;
25935- z-index: 60;
25936- backdrop-filter: saturate(180%) blur(14px);
25937- -webkit-backdrop-filter: saturate(180%) blur(14px);
25938- background: rgba(252,252,253,0.8);
25939- border-bottom: 1px solid rgba(22,24,29,0.07);
25940-}
25941-
25942-.lv-nav-inner {
25943- max-width: 1200px;
25944- margin: 0 auto;
25945- padding: 14px 28px;
25946- display: flex;
25947- align-items: center;
25948- gap: 28px;
25949-}
25950-
25951-.lv-logo {
25952- display: inline-flex;
25953- align-items: center;
25954- gap: 9px;
25955- font-family: 'Inter Tight', sans-serif;
25956- font-weight: 700;
25957- font-size: 17px;
25958- letter-spacing: -0.02em;
25959- color: #16181d;
25960- text-decoration: none;
25961-}
25962-
25963-.lv-logo-mark {
25964- width: 17px;
25965- height: 17px;
25966- border-radius: 5px;
25967- background: #4353c9;
25968- display: inline-block;
25969- flex-shrink: 0;
25970-}
25971-
25972-.lv-nav-links {
25973- display: flex;
25974- gap: 24px;
25975- font-size: 13.5px;
25976- font-weight: 500;
25977-}
25978-
25979-.lv-nav-link {
25980- color: #6b7080;
25981- text-decoration: none;
25982- transition: color 0.15s;
25983-}
25984-.lv-nav-link:hover { color: #16181d; }
25985-
25986-.lv-nav-ctas {
25987- margin-left: auto;
25988- display: flex;
25989- align-items: center;
25990- gap: 10px;
25991-}
25992-
25993-.lv-btn-secondary {
25994- padding: 8px 15px;
25995- border-radius: 8px;
25996- font-size: 13.5px;
25997- font-weight: 500;
25998- color: #16181d;
25999- border: 1px solid rgba(22,24,29,0.12);
26000- background: #ffffff;
26001- text-decoration: none;
26002- white-space: nowrap;
26003- transition: border-color 0.15s;
26004-}
26005-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
26006-
26007-.lv-btn-primary {
26008- padding: 8px 15px;
26009- border-radius: 8px;
26010- font-size: 13.5px;
26011- font-weight: 600;
26012- background: #16181d;
26013- color: #fff;
26014- text-decoration: none;
26015- white-space: nowrap;
26016- transition: box-shadow 0.15s;
26017-}
26018-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
26019-
26020-/* Hero */
26021-.lv-hero {
26022- position: relative;
26023- overflow: hidden;
26024- padding: 88px 0 0;
26025-}
26026-
26027-.lv-hero-glow {
26028- position: absolute;
26029- inset: -10% 0 auto 0;
26030- height: 640px;
26031- pointer-events: none;
26032- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
26033-}
26034-
26035-.lv-hero-inner {
26036- position: relative;
26037- max-width: 1200px;
26038- margin: 0 auto;
26039- padding: 0 28px;
26040- text-align: center;
26041-}
26042-
26043-.lv-hero-badge {
26044- display: inline-flex;
26045- align-items: center;
26046- gap: 9px;
26047- font-size: 12.5px;
26048- font-weight: 600;
26049- color: #3a3d45;
26050- background: #ffffff;
26051- border: 1px solid rgba(22,24,29,0.10);
26052- border-radius: 9999px;
26053- padding: 7px 16px;
26054- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
26055-}
26056-
26057-.lv-hero-sub {
26058- font-size: clamp(16px, 2vw, 19px);
26059- color: #6b7080;
26060- max-width: 60ch;
26061- margin: 24px auto 0;
26062- font-weight: 450;
26063- line-height: 1.65;
26064-}
26065-
26066-.lv-hero-actions {
26067- display: flex;
26068- gap: 12px;
26069- justify-content: center;
26070- flex-wrap: wrap;
26071- margin-top: 32px;
26072-}
26073-
26074-.lv-cta-primary {
26075- padding: 13px 24px;
26076- border-radius: 11px;
26077- font-size: 15.5px;
26078- font-weight: 600;
26079- background: #16181d;
26080- color: #fff;
26081- text-decoration: none;
26082- white-space: nowrap;
26083- transition: box-shadow 0.15s;
26084-}
26085-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
26086-
26087-.lv-cta-secondary {
26088- padding: 13px 24px;
26089- border-radius: 11px;
26090- font-size: 15.5px;
26091- font-weight: 600;
26092- color: #16181d;
26093- border: 1px solid rgba(22,24,29,0.14);
26094- background: #ffffff;
26095- text-decoration: none;
26096- white-space: nowrap;
26097- transition: border-color 0.15s;
26098-}
26099-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
26100-
26101-.lv-hero-tag {
26102- margin-top: 18px;
26103- font-family: 'JetBrains Mono', monospace;
26104- font-size: 11.5px;
26105- letter-spacing: 0.08em;
26106- text-transform: uppercase;
26107- color: #8a8d99;
26108-}
26109-
26110-/* Demo window */
26111-.lv-demo-window {
26112- margin: 56px auto 0;
26113- max-width: 860px;
26114- text-align: left;
26115- background: #ffffff;
26116- border: 1px solid rgba(22,24,29,0.09);
26117- border-radius: 18px;
26118- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
26119- overflow: hidden;
26120-}
26121-
26122-.lv-demo-bar {
26123- display: flex;
26124- align-items: center;
26125- gap: 7px;
26126- padding: 12px 18px;
26127- border-bottom: 1px solid rgba(22,24,29,0.07);
26128- background: #fcfcfd;
26129-}
26130-
26131-.lv-demo-dot {
26132- width: 10px;
26133- height: 10px;
26134- border-radius: 50%;
26135- background: #e4e5ea;
26136-}
26137-
26138-.lv-demo-url {
26139- margin-left: 10px;
26140- font-family: 'JetBrains Mono', monospace;
26141- font-size: 12px;
26142- color: #6b7080;
26143-}
26144-
26145-.lv-demo-live {
26146- margin-left: auto;
26147- display: inline-flex;
26148- align-items: center;
26149- gap: 6px;
26150- font-size: 11px;
26151- font-weight: 600;
26152- color: #1e7f5c;
26153-}
26154-
26155-.lv-demo-body {
26156- padding: 22px 24px;
26157-}
26158-
26159-.lv-demo-event {
26160- display: grid;
26161- grid-template-columns: 18px minmax(0, 1fr);
26162- gap: 14px;
26163- padding-bottom: 20px;
26164- position: relative;
26165-}
26166-.lv-demo-event:last-child { padding-bottom: 0; }
26167-
26168-.lv-demo-event-track {
26169- display: flex;
26170- flex-direction: column;
26171- align-items: center;
26172-}
26173-
26174-.lv-demo-line {
26175- width: 1px;
26176- flex: 1;
26177- background: rgba(22,24,29,0.08);
26178- margin-top: 5px;
26179- min-height: 20px;
26180-}
26181-
26182-.lv-demo-event-content {}
26183-
26184-.lv-demo-event-header {
26185- display: flex;
26186- align-items: baseline;
26187- gap: 10px;
26188-}
26189-
26190-.lv-demo-event-title {
26191- font-size: 13.5px;
26192- font-weight: 600;
26193- color: #16181d;
26194-}
26195-
26196-.lv-demo-event-time {
26197- font-family: 'JetBrains Mono', monospace;
26198- font-size: 11px;
26199- color: #8a8d99;
26200-}
26201-
26202-.lv-demo-event-body {
26203- font-size: 13px;
26204- color: #6b7080;
26205- margin-top: 2px;
26206-}
26207-
26208-/* Ticker */
26209-.lv-ticker-wrap {
26210- border-top: 1px solid rgba(22,24,29,0.07);
26211- border-bottom: 1px solid rgba(22,24,29,0.07);
26212- background: #ffffff;
26213- margin-top: 64px;
26214- overflow: hidden;
26215- white-space: nowrap;
26216- position: relative;
26217-}
26218-
26219-.lv-ticker-track {
26220- display: inline-flex;
26221- animation: gcTicker 40s linear infinite;
26222- padding: 11px 0;
26223-}
26224-
26225-.lv-ticker-item {
26226- display: inline-flex;
26227- align-items: center;
26228- gap: 8px;
26229- font-family: 'JetBrains Mono', monospace;
26230- font-size: 11.5px;
26231- color: #6b7080;
26232- padding: 0 28px;
26233- border-right: 1px solid rgba(22,24,29,0.06);
26234-}
26235-
26236-/* Stats */
26237-.lv-stats {
26238- background: #fcfcfd;
26239-}
26240-
26241-.lv-stats-inner {
26242- max-width: 1200px;
26243- margin: 0 auto;
26244- display: grid;
26245- grid-template-columns: repeat(4, 1fr);
26246- gap: 24px;
26247- padding: 52px 28px;
26248-}
26249-
26250-.lv-stat {
26251- text-align: center;
26252-}
26253-
26254-.lv-stat-num {
26255- font-family: 'Inter Tight', sans-serif;
26256- font-weight: 700;
26257- font-size: clamp(30px, 4vw, 44px);
26258- letter-spacing: -0.025em;
26259- color: #111318;
26260-}
26261-
26262-.lv-stat-label {
26263- font-size: 13px;
26264- color: #6b7080;
26265- margin-top: 4px;
26266-}
26267-
26268-/* Loop */
26269-.lv-loop {
26270- padding: 96px 0;
26271- background: #ffffff;
26272- border-top: 1px solid rgba(22,24,29,0.07);
26273- border-bottom: 1px solid rgba(22,24,29,0.07);
26274-}
26275-
26276-.lv-loop-inner {
26277- max-width: 1200px;
26278- margin: 0 auto;
26279- padding: 0 28px;
26280-}
26281-
26282-.lv-stages {
26283- display: grid;
26284- grid-template-columns: repeat(6, 1fr);
26285- gap: 12px;
26286-}
26287-
26288-.lv-stage-card {
26289- border: 1px solid rgba(22,24,29,0.08);
26290- border-radius: 14px;
26291- background: #ffffff;
26292- padding: 20px 18px;
26293- transition: border-color 0.3s, background 0.3s;
26294-}
26295-
26296-.lv-stage-card.lv-stage-active {
26297- border-color: rgba(67,83,201,0.45);
26298- background: rgba(67,83,201,0.03);
26299-}
26300-
26301-.lv-stage-header {
26302- display: flex;
26303- align-items: center;
26304- gap: 8px;
26305- margin-bottom: 10px;
26306-}
26307-
26308-.lv-stage-n {
26309- font-family: 'JetBrains Mono', monospace;
26310- font-size: 10.5px;
26311- letter-spacing: 0.1em;
26312- text-transform: uppercase;
26313- color: #8a8d99;
26314-}
26315-
26316-.lv-stage-name {
26317- font-family: 'Inter Tight', sans-serif;
26318- font-size: 16px;
26319- font-weight: 600;
26320- letter-spacing: -0.01em;
26321- color: #16181d;
26322- margin-bottom: 5px;
26323-}
26324-
26325-.lv-stage-desc {
26326- font-size: 12px;
26327- color: #6b7080;
26328- line-height: 1.55;
26329-}
26330-
26331-.lv-stage-meta {
26332- font-family: 'JetBrains Mono', monospace;
26333- font-size: 10.5px;
26334- color: #8a8d99;
26335- margin-top: 10px;
26336- transition: color 0.3s;
26337-}
26338-
26339-.lv-stage-meta.lv-stage-meta-active {
26340- color: #4353c9;
26341-}
26342-
26343-/* Heroes */
26344-.lv-heroes {
26345- padding: 96px 0;
26346- background: #fcfcfd;
26347-}
26348-
26349-.lv-heroes-inner {
26350- max-width: 1200px;
26351- margin: 0 auto;
26352- padding: 0 28px;
26353-}
26354-
26355-.lv-heroes-header {
26356- max-width: 640px;
26357- margin-bottom: 56px;
26358-}
26359-
26360-.lv-heroes-list {
26361- display: flex;
26362- flex-direction: column;
26363- gap: 20px;
26364-}
26365-
26366-.lv-hero-card {
26367- display: grid;
26368- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
26369- gap: 48px;
26370- align-items: center;
26371- border: 1px solid rgba(22,24,29,0.08);
26372- border-radius: 20px;
26373- background: #ffffff;
26374- padding: 44px 48px;
26375- text-decoration: none;
26376- transition: border-color 0.2s, box-shadow 0.2s;
26377-}
26378-.lv-hero-card:hover {
26379- border-color: rgba(22,24,29,0.22);
26380- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
26381-}
26382-
26383-.lv-hero-card-left {}
26384-
26385-.lv-hero-card-title {
26386- font-family: 'Inter Tight', sans-serif;
26387- font-size: 26px;
26388- font-weight: 600;
26389- letter-spacing: -0.022em;
26390- line-height: 1.15;
26391- color: #16181d;
26392- margin: 0 0 12px;
26393-}
26394-
26395-.lv-hero-card-body {
26396- font-size: 14.5px;
26397- color: #6b7080;
26398- margin: 0 0 18px;
26399- line-height: 1.65;
26400-}
26401-
26402-.lv-hero-card-cta {
26403- font-size: 13.5px;
26404- font-weight: 600;
26405- color: #4353c9;
26406-}
26407-
26408-.lv-terminal {
26409- border: 1px solid rgba(22,24,29,0.07);
26410- border-radius: 14px;
26411- background: #fcfcfd;
26412- padding: 20px 22px;
26413- font-family: 'JetBrains Mono', monospace;
26414- font-size: 12px;
26415- line-height: 1.9;
26416- overflow: hidden;
26417-}
26418-
26419-.lv-terminal-line {
26420- display: flex;
26421- align-items: center;
26422- gap: 10px;
26423- white-space: nowrap;
26424- overflow: hidden;
26425- text-overflow: ellipsis;
26426-}
26427-
26428-/* Platform */
26429-.lv-platform {
26430- padding: 96px 0;
26431- background: #ffffff;
26432- border-top: 1px solid rgba(22,24,29,0.07);
26433-}
26434-
26435-.lv-platform-inner {
26436- max-width: 1200px;
26437- margin: 0 auto;
26438- padding: 0 28px;
26439-}
26440-
26441-.lv-cap-grid {
26442- display: grid;
26443- grid-template-columns: repeat(4, 1fr);
26444- gap: 24px 32px;
26445-}
26446-
26447-.lv-cap-col {}
26448-
26449-.lv-cap-group {
26450- font-family: 'JetBrains Mono', monospace;
26451- font-size: 10.5px;
26452- letter-spacing: 0.12em;
26453- text-transform: uppercase;
26454- color: #8a8d99;
26455- font-weight: 500;
26456- margin-bottom: 12px;
26457- padding-bottom: 8px;
26458- border-bottom: 1px solid rgba(22,24,29,0.07);
26459-}
26460-
26461-.lv-cap-items {
26462- display: flex;
26463- flex-direction: column;
26464- gap: 7px;
26465-}
26466-
26467-.lv-cap-item {
26468- font-size: 12.5px;
26469- color: #3a3d45;
26470- line-height: 1.45;
26471-}
26472-
26473-/* Sovereignty */
26474-.lv-sovereign {
26475- position: relative;
26476- overflow: hidden;
26477- padding: 104px 0;
26478- color: #fff;
26479- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
26480-}
26481-
26482-.lv-sovereign-grid-bg {
26483- position: absolute;
26484- inset: 0;
26485- opacity: 0.4;
26486- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
26487- background-size: 56px 56px;
26488- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
26489- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
26490-}
26491-
26492-.lv-sovereign-inner {
26493- position: relative;
26494- max-width: 1200px;
26495- margin: 0 auto;
26496- padding: 0 28px;
26497-}
26498-
26499-.lv-section-header-dark {
26500- max-width: 680px;
26501- margin: 0 auto 48px;
26502- text-align: center;
26503-}
26504-
26505-.lv-layers-grid {
26506- display: grid;
26507- grid-template-columns: repeat(4, 1fr);
26508- gap: 10px;
26509- max-width: 980px;
26510- margin: 0 auto;
26511-}
26512-
26513-.lv-layer-chip {
26514- border: 1px solid rgba(255,255,255,0.10);
26515- border-radius: 10px;
26516- padding: 12px 16px;
26517- background: rgba(255,255,255,0.03);
26518-}
26519-
26520-.lv-layer-cta {
26521- border-color: rgba(169,180,238,0.30);
26522- background: rgba(169,180,238,0.06);
26523- display: flex;
26524- align-items: center;
26525- text-decoration: none;
26526- transition: background 0.15s;
26527-}
26528-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
26529-
26530-.lv-layer-cta-text {
26531- font-size: 13px;
26532- font-weight: 500;
26533- color: #a9b4ee;
26534-}
26535-
26536-.lv-layer-n {
26537- font-family: 'JetBrains Mono', monospace;
26538- font-size: 10px;
26539- color: rgba(255,255,255,0.4);
26540- margin-bottom: 3px;
26541-}
26542-
26543-.lv-layer-name {
26544- font-size: 13px;
26545- font-weight: 500;
26546- color: rgba(255,255,255,0.92);
26547-}
26548-
26549-.lv-sovereign-feats {
26550- display: flex;
26551- gap: 44px;
26552- justify-content: center;
26553- flex-wrap: wrap;
26554- margin-top: 52px;
26555- text-align: center;
26556-}
26557-
26558-.lv-sovereign-feat {}
26559-
26560-.lv-sovereign-feat-title {
26561- font-family: 'Inter Tight', sans-serif;
26562- font-size: 20px;
26563- font-weight: 700;
26564- color: #fff;
26565-}
26566-
26567-.lv-sovereign-feat-sub {
26568- color: rgba(255,255,255,0.55);
26569- font-size: 13px;
26570- margin-top: 2px;
26571-}
26572-
26573-/* Twin cards */
26574-.lv-twin {
26575- padding: 96px 0;
26576- background: #fcfcfd;
26577-}
26578-
26579-.lv-twin-inner {
26580- max-width: 1200px;
26581- margin: 0 auto;
26582- padding: 0 28px;
26583- display: grid;
26584- grid-template-columns: 1fr 1fr;
26585- gap: 24px;
26586-}
26587-
26588-.lv-twin-card {
26589- border: 1px solid rgba(22,24,29,0.08);
26590- border-radius: 20px;
26591- background: #ffffff;
26592- padding: 44px 48px;
26593-}
26594-
26595-.lv-twin-title {
26596- font-family: 'Inter Tight', sans-serif;
26597- font-size: 24px;
26598- font-weight: 600;
26599- letter-spacing: -0.02em;
26600- line-height: 1.2;
26601- margin: 0 0 12px;
26602- color: #16181d;
26603-}
26604-
26605-.lv-twin-body {
26606- font-size: 14.5px;
26607- color: #6b7080;
26608- margin: 0 0 16px;
26609- line-height: 1.7;
26610-}
26611-
26612-.lv-twin-link {
26613- font-size: 13.5px;
26614- font-weight: 600;
26615- color: #4353c9;
26616- text-decoration: none;
26617-}
26618-.lv-twin-link:hover { text-decoration: underline; }
26619-
26620-/* Quote */
26621-.lv-quote {
26622- padding: 40px 0 96px;
26623- background: #fcfcfd;
26624-}
26625-
26626-.lv-quote-inner {
26627- max-width: 980px;
26628- margin: 0 auto;
26629- padding: 0 28px;
26630- text-align: center;
26631-}
26632-
26633-.lv-quote-text {
26634- font-family: 'Inter Tight', sans-serif;
26635- font-weight: 600;
26636- font-size: clamp(26px, 3.8vw, 42px);
26637- line-height: 1.2;
26638- letter-spacing: -0.025em;
26639- margin: 0;
26640- color: #111318;
26641-}
26642-
26643-.lv-em {
26644- font-style: normal;
26645- color: #4353c9;
26646-}
26647-
26648-/* CTA */
26649-.lv-cta-section {
26650- padding: 0 0 104px;
26651- background: #fcfcfd;
26652-}
26653-
26654-.lv-cta-card {
26655- max-width: 820px;
26656- margin: 0 auto;
26657- padding: 64px 40px;
26658- text-align: center;
26659- background: #ffffff;
26660- border: 1px solid rgba(22,24,29,0.08);
26661- border-radius: 26px;
26662- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
26663- position: relative;
26664- overflow: hidden;
26665-}
26666-
26667-.lv-cta-glow {
26668- position: absolute;
26669- inset: -40% 0 auto 0;
26670- height: 280px;
26671- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
26672- pointer-events: none;
26673-}
26674-
26675-.lv-cta-h2 {
26676- font-family: 'Inter Tight', sans-serif;
26677- font-weight: 700;
26678- letter-spacing: -0.028em;
26679- font-size: clamp(30px, 4.6vw, 48px);
26680- margin: 0;
26681- position: relative;
26682- color: #111318;
26683-}
26684-
26685-.lv-cta-sub {
26686- color: #6b7080;
26687- font-size: 17px;
26688- margin: 16px 0 30px;
26689- position: relative;
26690-}
26691-
26692-.lv-cta-actions {
26693- display: flex;
26694- gap: 12px;
26695- justify-content: center;
26696- flex-wrap: wrap;
26697- position: relative;
26698-}
26699-
26700-.lv-cta-fine {
26701- margin-top: 20px;
26702- font-family: 'JetBrains Mono', monospace;
26703- font-size: 11px;
26704- color: #8a8d99;
26705- position: relative;
26706-}
26707-
26708-/* Footer */
26709-.lv-footer {
26710- border-top: 1px solid rgba(22,24,29,0.07);
26711- background: #ffffff;
26712- padding: 56px 0 30px;
26713-}
26714-
26715-.lv-footer-inner {
26716- max-width: 1200px;
26717- margin: 0 auto;
26718- padding: 0 28px;
26719- display: flex;
26720- gap: 48px;
26721- flex-wrap: wrap;
26722- justify-content: space-between;
26723-}
26724-
26725-.lv-footer-brand {}
26726-
26727-.lv-footer-tagline {
26728- color: #6b7080;
26729- font-size: 13.5px;
26730- margin: 12px 0 0;
26731- max-width: 32ch;
26732- line-height: 1.6;
26733-}
26734-
26735-.lv-footer-cols {
26736- display: flex;
26737- gap: 64px;
26738- flex-wrap: wrap;
26739-}
26740-
26741-.lv-footer-col {
26742- display: flex;
26743- flex-direction: column;
26744- gap: 9px;
26745-}
26746-
26747-.lv-footer-col-head {
26748- font-family: 'JetBrains Mono', monospace;
26749- font-size: 11px;
26750- text-transform: uppercase;
26751- letter-spacing: 0.1em;
26752- color: #8a8d99;
26753- margin: 0 0 4px;
26754- font-weight: 500;
26755-}
26756-
26757-.lv-footer-link {
26758- color: #3a3d45;
26759- font-size: 13.5px;
26760- text-decoration: none;
26761- transition: color 0.15s;
26762-}
26763-.lv-footer-link:hover { color: #16181d; }
26764-
26765-.lv-footer-bar {
26766- max-width: 1200px;
26767- margin: 44px auto 0;
26768- padding: 22px 28px 0;
26769- border-top: 1px solid rgba(22,24,29,0.06);
26770- display: flex;
26771- justify-content: space-between;
26772- flex-wrap: wrap;
26773- gap: 8px;
26774- color: #8a8d99;
26775- font-size: 12.5px;
26776-}
26777-
26778-.lv-footer-stack {
26779- font-family: 'JetBrains Mono', monospace;
26780- font-size: 11px;
26781-}
26782-`;
26783diff --git a/src/views/layout.tsx b/src/views/layout.tsx
26784index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
26785--- a/src/views/layout.tsx
26786+++ b/src/views/layout.tsx
26787@@ -3153,9 +3153,12 @@
26788 font-weight: 500;
26789 line-height: 1.4;
26790 }
26791- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
26792- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
26793- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
26794+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
26795+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
26796+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
26797+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
26798+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
26799+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
26800 .state-merged { color: var(--accent); }
26801 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
26802
26803diff --git a/src/views/ui.tsx b/src/views/ui.tsx
26804index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
26805--- a/src/views/ui.tsx
26806+++ b/src/views/ui.tsx
26807@@ -232,7 +232,7 @@
26808
26809 export const Badge: FC<
26810 PropsWithChildren<{
26811- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
26812+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
26813 style?: string;
26814 }>
26815 > = ({ children, variant = "default", style }) => {
26816@@ -241,9 +241,12 @@
26817 variant === "closed" ? "badge-closed" :
26818 variant === "merged" ? "badge-merged" :
26819 variant === "success" ? "badge-success" :
26820- variant === "danger" ? "badge-danger" :
26821- variant === "warning" ? "badge-warning" :
26822- "badge";
26823+ variant === "danger" ? "badge-danger" :
26824+ variant === "warning" ? "badge-warning" :
26825+ variant === "live" ? "badge-live" :
26826+ variant === "soon" ? "badge-soon" :
26827+ variant === "preview" ? "badge-preview" :
26828+ "badge";
26829 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
26830 };
26831
26832
26833exec
26834"C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -Command 'bun test' in C:\Users\ccant\gluecron.com
26835diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
26836index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
26837--- a/src/views/landing-pro.tsx
26838+++ b/src/views/landing-pro.tsx
26839@@ -42,7 +42,7 @@
26840
26841 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26842
26843-function icon(paths: string, color = "#4353c9", size = 20) {
26844+function icon(paths: string, color = "#0891b2", size = 20) {
26845 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
26846 }
26847
26848@@ -947,7 +947,7 @@
26849 const css = `
26850 /* %% tokens %% */
26851 :root{
26852- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
26853+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
26854 --lp-bg:#ffffff;--lp-soft:#fafafb;
26855 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
26856 --lp-border:rgba(0,0,0,.08);
26857diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
26858deleted file mode 100644
26859index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
26860--- a/src/views/landing-v2.tsx
26861+++ /dev/null
26862@@ -1,1447 +0,0 @@
26863-import type { FC } from "hono/jsx";
26864-
26865-export interface LandingPageProps {
26866- stats?: {
26867- publicRepos?: number;
26868- users?: number;
26869- };
26870-}
26871-
26872-const demoAllEvents = [
26873- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
26874- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
26875- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
26876- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
26877- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
26878-];
26879-
26880-const tickerItems = [
26881- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
26882- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
26883- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
26884- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
26885- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
26886- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
26887- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
26888- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
26889- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
26890- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
26891- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
26892- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
26893- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
26894- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
26895- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
26896- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
26897-];
26898-
26899-const stageData = [
26900- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
26901- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
26902- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
26903- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
26904- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
26905- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
26906-];
26907-
26908-const heroFeatures = [
26909- {
26910- href: "/",
26911- eyebrow: "01 � The autonomous repair loop",
26912- title: "Failures fix themselves  and show their work.",
26913- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
26914failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
26915- cta: "Watch a live repair session",
26916- mock: [
26917- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
26918- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
26919- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
26920- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
26921- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
26922- ],
26923- },
26924- {
26925- href: "/",
26926- eyebrow: "02 � Live sandbox isolation",
26927- title: "Every PR gets its own instant, disposable environment.",
26928- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
26929same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
26930- cta: "See a PR with its sandbox",
26931- mock: [
26932- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
26933- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
26934- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
26935- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
26936- ],
26937- },
26938- {
26939- href: "/",
26940- eyebrow: "03 � Multiplayer IDE workspaces",
26941- title: "You and the agent, side by side, in your editor.",
26942- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
26943agent into a silent reviewer in your gutter. The browser becomes optional.",
26944- cta: "See the editor session",
26945- mock: [
26946- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
26947- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
26948- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
26949- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
26950- ],
26951- },
26952-];
26953-
26954-const capabilities = [
26955- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
26956- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
26957- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
26958- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
26959- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
26960- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
26961- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
26962- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
26963-];
26964-
26965-const sovereignLayerNames = [
26966- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
26967- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
26968- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
26969- "Availability & recovery",
26970-];
26971-
26972-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
26973- return (
26974- <>
26975- <style dangerouslySetInnerHTML={{ __html: css }} />
26976-
26977- {/* Nav */}
26978- <header class="lv-nav">
26979- <div class="lv-nav-inner">
26980- <a href="/" class="lv-logo">
26981- <span class="lv-logo-mark"></span>gluecron
26982- </a>
26983- <nav class="lv-nav-links">
26984- <a href="#loop" class="lv-nav-link">The loop</a>
26985- <a href="#platform" class="lv-nav-link">Platform</a>
26986- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
26987- <a href="/trust" class="lv-nav-link">Trust</a>
26988- </nav>
26989- <div class="lv-nav-ctas">
26990- <a href="/login" class="lv-btn-secondary">Sign in</a>
26991- <a href="/register" class="lv-btn-primary">Start building</a>
26992- </div>
26993- </div>
26994- </header>
26995-
26996- {/* Hero */}
26997- <section class="lv-hero">
26998- <div class="lv-hero-glow"></div>
26999- <div class="lv-hero-inner">
27000- <div class="lv-hero-badge">
27001- <span class="lv-dot lv-dot-green lv-pulse"></span>
27002- Live: a repair loop converged on pr-218 while you read this
27003- </div>
27004- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
27005- <p class="lv-hero-sub">
27006- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
27007failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
27008- </p>
27009- <div class="lv-hero-actions">
27010- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
27011- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
27012- </div>
27013- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
27014-
27015- {/* Live product window */}
27016- <div class="lv-demo-window">
27017- <div class="lv-demo-bar">
27018- <span class="lv-demo-dot"></span>
27019- <span class="lv-demo-dot"></span>
27020- <span class="lv-demo-dot"></span>
27021- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
27022- <span class="lv-demo-live">
27023- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
27024- LIVE
27025- </span>
27026- </div>
27027- <div class="lv-demo-body" id="lv-demo-body">
27028- {/* Events rendered by JS */}
27029- {demoAllEvents.slice(0, 1).map((e, i) => (
27030- <div class="lv-demo-event" key={i}>
27031- <div class="lv-demo-event-track">
27032- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
27033- <span class="lv-demo-line" style="display:none"></span>
27034- </div>
27035- <div class="lv-demo-event-content">
27036- <div class="lv-demo-event-header">
27037- <span class="lv-demo-event-title">{e.title}</span>
27038- <span class="lv-demo-event-time">{e.time}</span>
27039- </div>
27040- <div class="lv-demo-event-body">{e.body}</div>
27041- </div>
27042- </div>
27043- ))}
27044- </div>
27045- </div>
27046- </div>
27047-
27048- {/* Activity ticker */}
27049- <div class="lv-ticker-wrap">
27050- <div class="lv-ticker-track">
27051- {tickerItems.map((t, i) => (
27052- <span class="lv-ticker-item" key={i}>
27053- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
27054- {t.text}
27055- </span>
27056- ))}
27057- </div>
27058- </div>
27059- </section>
27060-
27061- {/* Stat band */}
27062- <section class="lv-stats">
27063- <div class="lv-stats-inner">
27064- <div class="lv-stat">
27065- <div class="lv-stat-num">Sonnet 5</div>
27066- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
27067- </div>
27068- <div class="lv-stat">
27069- <div class="lv-stat-num">93.5%</div>
27070- <div class="lv-stat-label">of failures self-repair without a human</div>
27071- </div>
27072- <div class="lv-stat">
27073- <div class="lv-stat-num">1.9%</div>
27074- <div class="lv-stat-label">AI merges reverted  published live</div>
27075- </div>
27076- <div class="lv-stat">
27077- <div class="lv-stat-num">0</div>
27078- <div class="lv-stat-label">irreversible actions taken autonomously</div>
27079- </div>
27080- </div>
27081- </section>
27082-
27083- {/* The loop */}
27084- <section id="loop" class="lv-loop">
27085- <div class="lv-loop-inner">
27086- <div class="lv-section-header">
27087- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
27088- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
27089- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
27090- </div>
27091- <div class="lv-stages" id="lv-stages">
27092- {stageData.map((s, i) => (
27093- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
27094- <div class="lv-stage-header">
27095- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
27096- <span class="lv-stage-n">0{i + 1}</span>
27097- </div>
27098- <div class="lv-stage-name">{s.name}</div>
27099- <div class="lv-stage-desc">{s.desc}</div>
27100- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
27101- </div>
27102- ))}
27103- </div>
27104- </div>
27105- </section>
27106-
27107- {/* Three heroes */}
27108- <section class="lv-heroes">
27109- <div class="lv-heroes-inner">
27110- <div class="lv-heroes-header">
27111- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
27112- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
27113- </div>
27114- <div class="lv-heroes-list">
27115- {heroFeatures.map((h, i) => (
27116- <a href={h.href} class="lv-hero-card" key={i}>
27117- <div class="lv-hero-card-left">
27118- <div class="lv-eyebrow">{h.eyebrow}</div>
27119- <h3 class="lv-hero-card-title">{h.title}</h3>
27120- <p class="lv-hero-card-body">{h.body}</p>
27121- <span class="lv-hero-card-cta">{h.cta} �!</span>
27122- </div>
27123- <div class="lv-terminal">
27124- {h.mock.map((m, j) => (
27125- <div class="lv-terminal-line" key={j}>
27126- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
27127- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
27128- </div>
27129- ))}
27130- </div>
27131- </a>
27132- ))}
27133- </div>
27134- </div>
27135- </section>
27136-
27137- {/* Everything grid */}
27138- <section id="platform" class="lv-platform">
27139- <div class="lv-platform-inner">
27140- <div class="lv-section-header lv-section-header-center">
27141- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
27142- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
27143- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
27144- </div>
27145- <div class="lv-cap-grid">
27146- {capabilities.map((c, i) => (
27147- <div class="lv-cap-col" key={i}>
27148- <div class="lv-cap-group">{c.group}</div>
27149- <div class="lv-cap-items">
27150- {c.items.map((item, j) => (
27151- <div class="lv-cap-item" key={j}>{item}</div>
27152- ))}
27153- </div>
27154- </div>
27155- ))}
27156- </div>
27157- </div>
27158- </section>
27159-
27160- {/* Sovereignty band */}
27161- <section id="sovereign" class="lv-sovereign">
27162- <div class="lv-sovereign-grid-bg"></div>
27163- <div class="lv-sovereign-inner">
27164- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
27165- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
27166- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
27167- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
27168to private cloud, or run fully air-gapped on bare metal.</p>
27169- </div>
27170- <div class="lv-layers-grid">
27171- {sovereignLayerNames.map((name, i) => (
27172- <div class="lv-layer-chip" key={i}>
27173- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
27174- <div class="lv-layer-name">{name}</div>
27175- </div>
27176- ))}
27177- <a href="/" class="lv-layer-chip lv-layer-cta">
27178- <div class="lv-layer-cta-text">All self-owned �!</div>
27179- </a>
27180- </div>
27181- <div class="lv-sovereign-feats">
27182- <div class="lv-sovereign-feat">
27183- <div class="lv-sovereign-feat-title">Local inference first</div>
27184- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
27185- </div>
27186- <div class="lv-sovereign-feat">
27187- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
27188- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
27189- </div>
27190- <div class="lv-sovereign-feat">
27191- <div class="lv-sovereign-feat-title">Self-healing infra</div>
27192- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
27193- </div>
27194- </div>
27195- </div>
27196- </section>
27197-
27198- {/* Manual-first + reversibility */}
27199- <section class="lv-twin">
27200- <div class="lv-twin-inner">
27201- <div class="lv-twin-card">
27202- <div class="lv-eyebrow">Manual-first, always</div>
27203- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
27204- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
27205fallback. Developers who never touch AI get the best git host they've ever used.</p>
27206- </div>
27207- <div class="lv-twin-card">
27208- <div class="lv-eyebrow">The reversibility guarantee</div>
27209- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
27210- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
27211 policy, not promise. Our quality numbers are published live, unedited.</p>
27212- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
27213- </div>
27214- </div>
27215- </section>
27216-
27217- {/* Quote */}
27218- <section class="lv-quote">
27219- <div class="lv-quote-inner">
27220- <p class="lv-quote-text">
27221- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
27222- Gluecron is where code gets <em class="lv-em">finished</em>."
27223- </p>
27224- </div>
27225- </section>
27226-
27227- {/* CTA */}
27228- <section class="lv-cta-section">
27229- <div class="lv-cta-card">
27230- <div class="lv-cta-glow"></div>
27231- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
27232- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
27233- <div class="lv-cta-actions">
27234- <a href="/register" class="lv-cta-primary">Create your account �!</a>
27235- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
27236- </div>
27237- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
27238- </div>
27239- </section>
27240-
27241- {/* Footer */}
27242- <footer class="lv-footer">
27243- <div class="lv-footer-inner">
27244- <div class="lv-footer-brand">
27245- <a href="/" class="lv-logo">
27246- <span class="lv-logo-mark"></span>gluecron
27247- </a>
27248- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
27249- </div>
27250- <div class="lv-footer-cols">
27251- <div class="lv-footer-col">
27252- <h4 class="lv-footer-col-head">Product</h4>
27253- <a href="/" class="lv-footer-link">Agent workspace</a>
27254- <a href="/" class="lv-footer-link">Fleet refactors</a>
27255- <a href="/" class="lv-footer-link">Org memory</a>
27256- <a href="/" class="lv-footer-link">IDE extensions</a>
27257- </div>
27258- <div class="lv-footer-col">
27259- <h4 class="lv-footer-col-head">Platform</h4>
27260- <a href="/" class="lv-footer-link">Production layers</a>
27261- <a href="/trust" class="lv-footer-link">Trust report</a>
27262- <a href="/" class="lv-footer-link">Docs</a>
27263- <a href="/" class="lv-footer-link">Status</a>
27264- </div>
27265- <div class="lv-footer-col">
27266- <h4 class="lv-footer-col-head">Company</h4>
27267- <a href="/" class="lv-footer-link">About</a>
27268- <a href="/" class="lv-footer-link">Pricing</a>
27269- <a href="/" class="lv-footer-link">Enterprise</a>
27270- </div>
27271- </div>
27272- </div>
27273- <div class="lv-footer-bar">
27274- <span>� 2026 Gluecron</span>
27275- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
27276- </div>
27277- </footer>
27278-
27279- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
27280- </>
27281- );
27282-};
27283-
27284-export const LandingPage = LandingPageV2;
27285-export default LandingPageV2;
27286-
27287-const clientScript = `
27288-(function() {
27289- var demoAll = [
27290- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
27291- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
27292- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
27293- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
27294- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
27295- ];
27296-
27297- var demoStep = 0;
27298- var stage = 0;
27299-
27300- function renderDemo() {
27301- var container = document.getElementById('lv-demo-body');
27302- if (!container) return;
27303- var visible = demoAll.slice(0, demoStep + 1);
27304- container.innerHTML = visible.map(function(e, i) {
27305- var isLast = i === visible.length - 1;
27306- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
27307- return '<div class="lv-demo-event">' +
27308- '<div class="lv-demo-event-track">' +
27309- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
27310- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
27311- '</div>' +
27312- '<div class="lv-demo-event-content">' +
27313- '<div class="lv-demo-event-header">' +
27314- '<span class="lv-demo-event-title">' + e.title + '</span>' +
27315- '<span class="lv-demo-event-time">' + e.time + '</span>' +
27316- '</div>' +
27317- '<div class="lv-demo-event-body">' + e.body + '</div>' +
27318- '</div>' +
27319- '</div>';
27320- }).join('');
27321- }
27322-
27323- function renderStages() {
27324- var cards = document.querySelectorAll('.lv-stage-card');
27325- cards.forEach(function(card, i) {
27326- var dot = card.querySelector('.lv-dot');
27327- var meta = card.querySelector('.lv-stage-meta');
27328- if (i === stage) {
27329- card.classList.add('lv-stage-active');
27330- if (dot) {
27331- dot.classList.remove('lv-dot-idle');
27332- dot.classList.add('lv-dot-indigo', 'lv-pulse');
27333- }
27334- if (meta) meta.classList.add('lv-stage-meta-active');
27335- } else {
27336- card.classList.remove('lv-stage-active');
27337- if (dot) {
27338- dot.classList.add('lv-dot-idle');
27339- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
27340- }
27341- if (meta) meta.classList.remove('lv-stage-meta-active');
27342- }
27343- });
27344- }
27345-
27346- renderDemo();
27347-
27348- setInterval(function() {
27349- demoStep = (demoStep + 1) % 5;
27350- renderDemo();
27351- }, 3600);
27352-
27353- setInterval(function() {
27354- stage = (stage + 1) % 6;
27355- renderStages();
27356- }, 2200);
27357-})();
27358-`;
27359-
27360-const css = `
27361-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
27362-
27363-*, *::before, *::after { box-sizing: border-box; }
27364-
27365-body {
27366- margin: 0;
27367- background: #fcfcfd;
27368- -webkit-font-smoothing: antialiased;
27369- text-rendering: optimizeLegibility;
27370- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
27371- font-size: 15px;
27372- line-height: 1.6;
27373- letter-spacing: -0.008em;
27374- color: #16181d;
27375-}
27376-
27377-@keyframes gcPulse {
27378- 0%, 100% { opacity: 1; }
27379- 50% { opacity: 0.35; }
27380-}
27381-
27382-@keyframes gcTicker {
27383- 0% { transform: translateX(0); }
27384- 100% { transform: translateX(-50%); }
27385-}
27386-
27387-/* Shared utilities */
27388-.lv-dot {
27389- display: inline-block;
27390- border-radius: 50%;
27391-}
27392-.lv-dot-green { background: #1e7f5c; }
27393-.lv-dot-indigo { background: #4353c9; }
27394-.lv-dot-idle { background: #c4c6cf; }
27395-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
27396-
27397-.lv-strong { color: #16181d; font-weight: 600; }
27398-
27399-.lv-eyebrow {
27400- font-family: 'JetBrains Mono', monospace;
27401- font-size: 11px;
27402- letter-spacing: 0.12em;
27403- text-transform: uppercase;
27404- color: #8a8d99;
27405- font-weight: 500;
27406- margin-bottom: 12px;
27407-}
27408-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
27409-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
27410-
27411-.lv-h1 {
27412- font-family: 'Inter Tight', sans-serif;
27413- font-weight: 700;
27414- letter-spacing: -0.035em;
27415- font-size: clamp(44px, 7vw, 84px);
27416- line-height: 0.98;
27417- margin: 30px auto 0;
27418- max-width: 14ch;
27419- color: #111318;
27420-}
27421-
27422-.lv-h2 {
27423- font-family: 'Inter Tight', sans-serif;
27424- font-weight: 700;
27425- letter-spacing: -0.028em;
27426- font-size: clamp(30px, 4.4vw, 48px);
27427- line-height: 1.05;
27428- margin: 0;
27429- color: #111318;
27430-}
27431-
27432-.lv-h2-dark {
27433- font-family: 'Inter Tight', sans-serif;
27434- font-weight: 700;
27435- letter-spacing: -0.028em;
27436- font-size: clamp(30px, 4.6vw, 52px);
27437- line-height: 1.05;
27438- margin: 0;
27439- color: #fff;
27440-}
27441-
27442-.lv-section-header {
27443- max-width: 640px;
27444- margin: 0 auto 56px;
27445-}
27446-
27447-.lv-section-header-center {
27448- text-align: center;
27449-}
27450-
27451-.lv-section-sub {
27452- color: #6b7080;
27453- font-size: 17px;
27454- margin: 18px auto 0;
27455- max-width: 52ch;
27456-}
27457-
27458-.lv-section-sub-dark {
27459- color: rgba(255,255,255,0.72);
27460- font-size: 17px;
27461- margin: 18px auto 0;
27462- max-width: 56ch;
27463-}
27464-
27465-/* Nav */
27466-.lv-nav {
27467- position: sticky;
27468- top: 0;
27469- z-index: 60;
27470- backdrop-filter: saturate(180%) blur(14px);
27471- -webkit-backdrop-filter: saturate(180%) blur(14px);
27472- background: rgba(252,252,253,0.8);
27473- border-bottom: 1px solid rgba(22,24,29,0.07);
27474-}
27475-
27476-.lv-nav-inner {
27477- max-width: 1200px;
27478- margin: 0 auto;
27479- padding: 14px 28px;
27480- display: flex;
27481- align-items: center;
27482- gap: 28px;
27483-}
27484-
27485-.lv-logo {
27486- display: inline-flex;
27487- align-items: center;
27488- gap: 9px;
27489- font-family: 'Inter Tight', sans-serif;
27490- font-weight: 700;
27491- font-size: 17px;
27492- letter-spacing: -0.02em;
27493- color: #16181d;
27494- text-decoration: none;
27495-}
27496-
27497-.lv-logo-mark {
27498- width: 17px;
27499- height: 17px;
27500- border-radius: 5px;
27501- background: #4353c9;
27502- display: inline-block;
27503- flex-shrink: 0;
27504-}
27505-
27506-.lv-nav-links {
27507- display: flex;
27508- gap: 24px;
27509- font-size: 13.5px;
27510- font-weight: 500;
27511-}
27512-
27513-.lv-nav-link {
27514- color: #6b7080;
27515- text-decoration: none;
27516- transition: color 0.15s;
27517-}
27518-.lv-nav-link:hover { color: #16181d; }
27519-
27520-.lv-nav-ctas {
27521- margin-left: auto;
27522- display: flex;
27523- align-items: center;
27524- gap: 10px;
27525-}
27526-
27527-.lv-btn-secondary {
27528- padding: 8px 15px;
27529- border-radius: 8px;
27530- font-size: 13.5px;
27531- font-weight: 500;
27532- color: #16181d;
27533- border: 1px solid rgba(22,24,29,0.12);
27534- background: #ffffff;
27535- text-decoration: none;
27536- white-space: nowrap;
27537- transition: border-color 0.15s;
27538-}
27539-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
27540-
27541-.lv-btn-primary {
27542- padding: 8px 15px;
27543- border-radius: 8px;
27544- font-size: 13.5px;
27545- font-weight: 600;
27546- background: #16181d;
27547- color: #fff;
27548- text-decoration: none;
27549- white-space: nowrap;
27550- transition: box-shadow 0.15s;
27551-}
27552-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
27553-
27554-/* Hero */
27555-.lv-hero {
27556- position: relative;
27557- overflow: hidden;
27558- padding: 88px 0 0;
27559-}
27560-
27561-.lv-hero-glow {
27562- position: absolute;
27563- inset: -10% 0 auto 0;
27564- height: 640px;
27565- pointer-events: none;
27566- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
27567-}
27568-
27569-.lv-hero-inner {
27570- position: relative;
27571- max-width: 1200px;
27572- margin: 0 auto;
27573- padding: 0 28px;
27574- text-align: center;
27575-}
27576-
27577-.lv-hero-badge {
27578- display: inline-flex;
27579- align-items: center;
27580- gap: 9px;
27581- font-size: 12.5px;
27582- font-weight: 600;
27583- color: #3a3d45;
27584- background: #ffffff;
27585- border: 1px solid rgba(22,24,29,0.10);
27586- border-radius: 9999px;
27587- padding: 7px 16px;
27588- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
27589-}
27590-
27591-.lv-hero-sub {
27592- font-size: clamp(16px, 2vw, 19px);
27593- color: #6b7080;
27594- max-width: 60ch;
27595- margin: 24px auto 0;
27596- font-weight: 450;
27597- line-height: 1.65;
27598-}
27599-
27600-.lv-hero-actions {
27601- display: flex;
27602- gap: 12px;
27603- justify-content: center;
27604- flex-wrap: wrap;
27605- margin-top: 32px;
27606-}
27607-
27608-.lv-cta-primary {
27609- padding: 13px 24px;
27610- border-radius: 11px;
27611- font-size: 15.5px;
27612- font-weight: 600;
27613- background: #16181d;
27614- color: #fff;
27615- text-decoration: none;
27616- white-space: nowrap;
27617- transition: box-shadow 0.15s;
27618-}
27619-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
27620-
27621-.lv-cta-secondary {
27622- padding: 13px 24px;
27623- border-radius: 11px;
27624- font-size: 15.5px;
27625- font-weight: 600;
27626- color: #16181d;
27627- border: 1px solid rgba(22,24,29,0.14);
27628- background: #ffffff;
27629- text-decoration: none;
27630- white-space: nowrap;
27631- transition: border-color 0.15s;
27632-}
27633-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
27634-
27635-.lv-hero-tag {
27636- margin-top: 18px;
27637- font-family: 'JetBrains Mono', monospace;
27638- font-size: 11.5px;
27639- letter-spacing: 0.08em;
27640- text-transform: uppercase;
27641- color: #8a8d99;
27642-}
27643-
27644-/* Demo window */
27645-.lv-demo-window {
27646- margin: 56px auto 0;
27647- max-width: 860px;
27648- text-align: left;
27649- background: #ffffff;
27650- border: 1px solid rgba(22,24,29,0.09);
27651- border-radius: 18px;
27652- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
27653- overflow: hidden;
27654-}
27655-
27656-.lv-demo-bar {
27657- display: flex;
27658- align-items: center;
27659- gap: 7px;
27660- padding: 12px 18px;
27661- border-bottom: 1px solid rgba(22,24,29,0.07);
27662- background: #fcfcfd;
27663-}
27664-
27665-.lv-demo-dot {
27666- width: 10px;
27667- height: 10px;
27668- border-radius: 50%;
27669- background: #e4e5ea;
27670-}
27671-
27672-.lv-demo-url {
27673- margin-left: 10px;
27674- font-family: 'JetBrains Mono', monospace;
27675- font-size: 12px;
27676- color: #6b7080;
27677-}
27678-
27679-.lv-demo-live {
27680- margin-left: auto;
27681- display: inline-flex;
27682- align-items: center;
27683- gap: 6px;
27684- font-size: 11px;
27685- font-weight: 600;
27686- color: #1e7f5c;
27687-}
27688-
27689-.lv-demo-body {
27690- padding: 22px 24px;
27691-}
27692-
27693-.lv-demo-event {
27694- display: grid;
27695- grid-template-columns: 18px minmax(0, 1fr);
27696- gap: 14px;
27697- padding-bottom: 20px;
27698- position: relative;
27699-}
27700-.lv-demo-event:last-child { padding-bottom: 0; }
27701-
27702-.lv-demo-event-track {
27703- display: flex;
27704- flex-direction: column;
27705- align-items: center;
27706-}
27707-
27708-.lv-demo-line {
27709- width: 1px;
27710- flex: 1;
27711- background: rgba(22,24,29,0.08);
27712- margin-top: 5px;
27713- min-height: 20px;
27714-}
27715-
27716-.lv-demo-event-content {}
27717-
27718-.lv-demo-event-header {
27719- display: flex;
27720- align-items: baseline;
27721- gap: 10px;
27722-}
27723-
27724-.lv-demo-event-title {
27725- font-size: 13.5px;
27726- font-weight: 600;
27727- color: #16181d;
27728-}
27729-
27730-.lv-demo-event-time {
27731- font-family: 'JetBrains Mono', monospace;
27732- font-size: 11px;
27733- color: #8a8d99;
27734-}
27735-
27736-.lv-demo-event-body {
27737- font-size: 13px;
27738- color: #6b7080;
27739- margin-top: 2px;
27740-}
27741-
27742-/* Ticker */
27743-.lv-ticker-wrap {
27744- border-top: 1px solid rgba(22,24,29,0.07);
27745- border-bottom: 1px solid rgba(22,24,29,0.07);
27746- background: #ffffff;
27747- margin-top: 64px;
27748- overflow: hidden;
27749- white-space: nowrap;
27750- position: relative;
27751-}
27752-
27753-.lv-ticker-track {
27754- display: inline-flex;
27755- animation: gcTicker 40s linear infinite;
27756- padding: 11px 0;
27757-}
27758-
27759-.lv-ticker-item {
27760- display: inline-flex;
27761- align-items: center;
27762- gap: 8px;
27763- font-family: 'JetBrains Mono', monospace;
27764- font-size: 11.5px;
27765- color: #6b7080;
27766- padding: 0 28px;
27767- border-right: 1px solid rgba(22,24,29,0.06);
27768-}
27769-
27770-/* Stats */
27771-.lv-stats {
27772- background: #fcfcfd;
27773-}
27774-
27775-.lv-stats-inner {
27776- max-width: 1200px;
27777- margin: 0 auto;
27778- display: grid;
27779- grid-template-columns: repeat(4, 1fr);
27780- gap: 24px;
27781- padding: 52px 28px;
27782-}
27783-
27784-.lv-stat {
27785- text-align: center;
27786-}
27787-
27788-.lv-stat-num {
27789- font-family: 'Inter Tight', sans-serif;
27790- font-weight: 700;
27791- font-size: clamp(30px, 4vw, 44px);
27792- letter-spacing: -0.025em;
27793- color: #111318;
27794-}
27795-
27796-.lv-stat-label {
27797- font-size: 13px;
27798- color: #6b7080;
27799- margin-top: 4px;
27800-}
27801-
27802-/* Loop */
27803-.lv-loop {
27804- padding: 96px 0;
27805- background: #ffffff;
27806- border-top: 1px solid rgba(22,24,29,0.07);
27807- border-bottom: 1px solid rgba(22,24,29,0.07);
27808-}
27809-
27810-.lv-loop-inner {
27811- max-width: 1200px;
27812- margin: 0 auto;
27813- padding: 0 28px;
27814-}
27815-
27816-.lv-stages {
27817- display: grid;
27818- grid-template-columns: repeat(6, 1fr);
27819- gap: 12px;
27820-}
27821-
27822-.lv-stage-card {
27823- border: 1px solid rgba(22,24,29,0.08);
27824- border-radius: 14px;
27825- background: #ffffff;
27826- padding: 20px 18px;
27827- transition: border-color 0.3s, background 0.3s;
27828-}
27829-
27830-.lv-stage-card.lv-stage-active {
27831- border-color: rgba(67,83,201,0.45);
27832- background: rgba(67,83,201,0.03);
27833-}
27834-
27835-.lv-stage-header {
27836- display: flex;
27837- align-items: center;
27838- gap: 8px;
27839- margin-bottom: 10px;
27840-}
27841-
27842-.lv-stage-n {
27843- font-family: 'JetBrains Mono', monospace;
27844- font-size: 10.5px;
27845- letter-spacing: 0.1em;
27846- text-transform: uppercase;
27847- color: #8a8d99;
27848-}
27849-
27850-.lv-stage-name {
27851- font-family: 'Inter Tight', sans-serif;
27852- font-size: 16px;
27853- font-weight: 600;
27854- letter-spacing: -0.01em;
27855- color: #16181d;
27856- margin-bottom: 5px;
27857-}
27858-
27859-.lv-stage-desc {
27860- font-size: 12px;
27861- color: #6b7080;
27862- line-height: 1.55;
27863-}
27864-
27865-.lv-stage-meta {
27866- font-family: 'JetBrains Mono', monospace;
27867- font-size: 10.5px;
27868- color: #8a8d99;
27869- margin-top: 10px;
27870- transition: color 0.3s;
27871-}
27872-
27873-.lv-stage-meta.lv-stage-meta-active {
27874- color: #4353c9;
27875-}
27876-
27877-/* Heroes */
27878-.lv-heroes {
27879- padding: 96px 0;
27880- background: #fcfcfd;
27881-}
27882-
27883-.lv-heroes-inner {
27884- max-width: 1200px;
27885- margin: 0 auto;
27886- padding: 0 28px;
27887-}
27888-
27889-.lv-heroes-header {
27890- max-width: 640px;
27891- margin-bottom: 56px;
27892-}
27893-
27894-.lv-heroes-list {
27895- display: flex;
27896- flex-direction: column;
27897- gap: 20px;
27898-}
27899-
27900-.lv-hero-card {
27901- display: grid;
27902- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
27903- gap: 48px;
27904- align-items: center;
27905- border: 1px solid rgba(22,24,29,0.08);
27906- border-radius: 20px;
27907- background: #ffffff;
27908- padding: 44px 48px;
27909- text-decoration: none;
27910- transition: border-color 0.2s, box-shadow 0.2s;
27911-}
27912-.lv-hero-card:hover {
27913- border-color: rgba(22,24,29,0.22);
27914- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
27915-}
27916-
27917-.lv-hero-card-left {}
27918-
27919-.lv-hero-card-title {
27920- font-family: 'Inter Tight', sans-serif;
27921- font-size: 26px;
27922- font-weight: 600;
27923- letter-spacing: -0.022em;
27924- line-height: 1.15;
27925- color: #16181d;
27926- margin: 0 0 12px;
27927-}
27928-
27929-.lv-hero-card-body {
27930- font-size: 14.5px;
27931- color: #6b7080;
27932- margin: 0 0 18px;
27933- line-height: 1.65;
27934-}
27935-
27936-.lv-hero-card-cta {
27937- font-size: 13.5px;
27938- font-weight: 600;
27939- color: #4353c9;
27940-}
27941-
27942-.lv-terminal {
27943- border: 1px solid rgba(22,24,29,0.07);
27944- border-radius: 14px;
27945- background: #fcfcfd;
27946- padding: 20px 22px;
27947- font-family: 'JetBrains Mono', monospace;
27948- font-size: 12px;
27949- line-height: 1.9;
27950- overflow: hidden;
27951-}
27952-
27953-.lv-terminal-line {
27954- display: flex;
27955- align-items: center;
27956- gap: 10px;
27957- white-space: nowrap;
27958- overflow: hidden;
27959- text-overflow: ellipsis;
27960-}
27961-
27962-/* Platform */
27963-.lv-platform {
27964- padding: 96px 0;
27965- background: #ffffff;
27966- border-top: 1px solid rgba(22,24,29,0.07);
27967-}
27968-
27969-.lv-platform-inner {
27970- max-width: 1200px;
27971- margin: 0 auto;
27972- padding: 0 28px;
27973-}
27974-
27975-.lv-cap-grid {
27976- display: grid;
27977- grid-template-columns: repeat(4, 1fr);
27978- gap: 24px 32px;
27979-}
27980-
27981-.lv-cap-col {}
27982-
27983-.lv-cap-group {
27984- font-family: 'JetBrains Mono', monospace;
27985- font-size: 10.5px;
27986- letter-spacing: 0.12em;
27987- text-transform: uppercase;
27988- color: #8a8d99;
27989- font-weight: 500;
27990- margin-bottom: 12px;
27991- padding-bottom: 8px;
27992- border-bottom: 1px solid rgba(22,24,29,0.07);
27993-}
27994-
27995-.lv-cap-items {
27996- display: flex;
27997- flex-direction: column;
27998- gap: 7px;
27999-}
28000-
28001-.lv-cap-item {
28002- font-size: 12.5px;
28003- color: #3a3d45;
28004- line-height: 1.45;
28005-}
28006-
28007-/* Sovereignty */
28008-.lv-sovereign {
28009- position: relative;
28010- overflow: hidden;
28011- padding: 104px 0;
28012- color: #fff;
28013- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
28014-}
28015-
28016-.lv-sovereign-grid-bg {
28017- position: absolute;
28018- inset: 0;
28019- opacity: 0.4;
28020- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
28021- background-size: 56px 56px;
28022- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
28023- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
28024-}
28025-
28026-.lv-sovereign-inner {
28027- position: relative;
28028- max-width: 1200px;
28029- margin: 0 auto;
28030- padding: 0 28px;
28031-}
28032-
28033-.lv-section-header-dark {
28034- max-width: 680px;
28035- margin: 0 auto 48px;
28036- text-align: center;
28037-}
28038-
28039-.lv-layers-grid {
28040- display: grid;
28041- grid-template-columns: repeat(4, 1fr);
28042- gap: 10px;
28043- max-width: 980px;
28044- margin: 0 auto;
28045-}
28046-
28047-.lv-layer-chip {
28048- border: 1px solid rgba(255,255,255,0.10);
28049- border-radius: 10px;
28050- padding: 12px 16px;
28051- background: rgba(255,255,255,0.03);
28052-}
28053-
28054-.lv-layer-cta {
28055- border-color: rgba(169,180,238,0.30);
28056- background: rgba(169,180,238,0.06);
28057- display: flex;
28058- align-items: center;
28059- text-decoration: none;
28060- transition: background 0.15s;
28061-}
28062-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
28063-
28064-.lv-layer-cta-text {
28065- font-size: 13px;
28066- font-weight: 500;
28067- color: #a9b4ee;
28068-}
28069-
28070-.lv-layer-n {
28071- font-family: 'JetBrains Mono', monospace;
28072- font-size: 10px;
28073- color: rgba(255,255,255,0.4);
28074- margin-bottom: 3px;
28075-}
28076-
28077-.lv-layer-name {
28078- font-size: 13px;
28079- font-weight: 500;
28080- color: rgba(255,255,255,0.92);
28081-}
28082-
28083-.lv-sovereign-feats {
28084- display: flex;
28085- gap: 44px;
28086- justify-content: center;
28087- flex-wrap: wrap;
28088- margin-top: 52px;
28089- text-align: center;
28090-}
28091-
28092-.lv-sovereign-feat {}
28093-
28094-.lv-sovereign-feat-title {
28095- font-family: 'Inter Tight', sans-serif;
28096- font-size: 20px;
28097- font-weight: 700;
28098- color: #fff;
28099-}
28100-
28101-.lv-sovereign-feat-sub {
28102- color: rgba(255,255,255,0.55);
28103- font-size: 13px;
28104- margin-top: 2px;
28105-}
28106-
28107-/* Twin cards */
28108-.lv-twin {
28109- padding: 96px 0;
28110- background: #fcfcfd;
28111-}
28112-
28113-.lv-twin-inner {
28114- max-width: 1200px;
28115- margin: 0 auto;
28116- padding: 0 28px;
28117- display: grid;
28118- grid-template-columns: 1fr 1fr;
28119- gap: 24px;
28120-}
28121-
28122-.lv-twin-card {
28123- border: 1px solid rgba(22,24,29,0.08);
28124- border-radius: 20px;
28125- background: #ffffff;
28126- padding: 44px 48px;
28127-}
28128-
28129-.lv-twin-title {
28130- font-family: 'Inter Tight', sans-serif;
28131- font-size: 24px;
28132- font-weight: 600;
28133- letter-spacing: -0.02em;
28134- line-height: 1.2;
28135- margin: 0 0 12px;
28136- color: #16181d;
28137-}
28138-
28139-.lv-twin-body {
28140- font-size: 14.5px;
28141- color: #6b7080;
28142- margin: 0 0 16px;
28143- line-height: 1.7;
28144-}
28145-
28146-.lv-twin-link {
28147- font-size: 13.5px;
28148- font-weight: 600;
28149- color: #4353c9;
28150- text-decoration: none;
28151-}
28152-.lv-twin-link:hover { text-decoration: underline; }
28153-
28154-/* Quote */
28155-.lv-quote {
28156- padding: 40px 0 96px;
28157- background: #fcfcfd;
28158-}
28159-
28160-.lv-quote-inner {
28161- max-width: 980px;
28162- margin: 0 auto;
28163- padding: 0 28px;
28164- text-align: center;
28165-}
28166-
28167-.lv-quote-text {
28168- font-family: 'Inter Tight', sans-serif;
28169- font-weight: 600;
28170- font-size: clamp(26px, 3.8vw, 42px);
28171- line-height: 1.2;
28172- letter-spacing: -0.025em;
28173- margin: 0;
28174- color: #111318;
28175-}
28176-
28177-.lv-em {
28178- font-style: normal;
28179- color: #4353c9;
28180-}
28181-
28182-/* CTA */
28183-.lv-cta-section {
28184- padding: 0 0 104px;
28185- background: #fcfcfd;
28186-}
28187-
28188-.lv-cta-card {
28189- max-width: 820px;
28190- margin: 0 auto;
28191- padding: 64px 40px;
28192- text-align: center;
28193- background: #ffffff;
28194- border: 1px solid rgba(22,24,29,0.08);
28195- border-radius: 26px;
28196- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
28197- position: relative;
28198- overflow: hidden;
28199-}
28200-
28201-.lv-cta-glow {
28202- position: absolute;
28203- inset: -40% 0 auto 0;
28204- height: 280px;
28205- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
28206- pointer-events: none;
28207-}
28208-
28209-.lv-cta-h2 {
28210- font-family: 'Inter Tight', sans-serif;
28211- font-weight: 700;
28212- letter-spacing: -0.028em;
28213- font-size: clamp(30px, 4.6vw, 48px);
28214- margin: 0;
28215- position: relative;
28216- color: #111318;
28217-}
28218-
28219-.lv-cta-sub {
28220- color: #6b7080;
28221- font-size: 17px;
28222- margin: 16px 0 30px;
28223- position: relative;
28224-}
28225-
28226-.lv-cta-actions {
28227- display: flex;
28228- gap: 12px;
28229- justify-content: center;
28230- flex-wrap: wrap;
28231- position: relative;
28232-}
28233-
28234-.lv-cta-fine {
28235- margin-top: 20px;
28236- font-family: 'JetBrains Mono', monospace;
28237- font-size: 11px;
28238- color: #8a8d99;
28239- position: relative;
28240-}
28241-
28242-/* Footer */
28243-.lv-footer {
28244- border-top: 1px solid rgba(22,24,29,0.07);
28245- background: #ffffff;
28246- padding: 56px 0 30px;
28247-}
28248-
28249-.lv-footer-inner {
28250- max-width: 1200px;
28251- margin: 0 auto;
28252- padding: 0 28px;
28253- display: flex;
28254- gap: 48px;
28255- flex-wrap: wrap;
28256- justify-content: space-between;
28257-}
28258-
28259-.lv-footer-brand {}
28260-
28261-.lv-footer-tagline {
28262- color: #6b7080;
28263- font-size: 13.5px;
28264- margin: 12px 0 0;
28265- max-width: 32ch;
28266- line-height: 1.6;
28267-}
28268-
28269-.lv-footer-cols {
28270- display: flex;
28271- gap: 64px;
28272- flex-wrap: wrap;
28273-}
28274-
28275-.lv-footer-col {
28276- display: flex;
28277- flex-direction: column;
28278- gap: 9px;
28279-}
28280-
28281-.lv-footer-col-head {
28282- font-family: 'JetBrains Mono', monospace;
28283- font-size: 11px;
28284- text-transform: uppercase;
28285- letter-spacing: 0.1em;
28286- color: #8a8d99;
28287- margin: 0 0 4px;
28288- font-weight: 500;
28289-}
28290-
28291-.lv-footer-link {
28292- color: #3a3d45;
28293- font-size: 13.5px;
28294- text-decoration: none;
28295- transition: color 0.15s;
28296-}
28297-.lv-footer-link:hover { color: #16181d; }
28298-
28299-.lv-footer-bar {
28300- max-width: 1200px;
28301- margin: 44px auto 0;
28302- padding: 22px 28px 0;
28303- border-top: 1px solid rgba(22,24,29,0.06);
28304- display: flex;
28305- justify-content: space-between;
28306- flex-wrap: wrap;
28307- gap: 8px;
28308- color: #8a8d99;
28309- font-size: 12.5px;
28310-}
28311-
28312-.lv-footer-stack {
28313- font-family: 'JetBrains Mono', monospace;
28314- font-size: 11px;
28315-}
28316-`;
28317diff --git a/src/views/layout.tsx b/src/views/layout.tsx
28318index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
28319--- a/src/views/layout.tsx
28320+++ b/src/views/layout.tsx
28321@@ -3153,9 +3153,12 @@
28322 font-weight: 500;
28323 line-height: 1.4;
28324 }
28325- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
28326- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
28327- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
28328+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
28329+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
28330+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
28331+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
28332+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
28333+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
28334 .state-merged { color: var(--accent); }
28335 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
28336
28337diff --git a/src/views/ui.tsx b/src/views/ui.tsx
28338index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
28339--- a/src/views/ui.tsx
28340+++ b/src/views/ui.tsx
28341@@ -232,7 +232,7 @@
28342
28343 export const Badge: FC<
28344 PropsWithChildren<{
28345- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
28346+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
28347 style?: string;
28348 }>
28349 > = ({ children, variant = "default", style }) => {
28350@@ -241,9 +241,12 @@
28351 variant === "closed" ? "badge-closed" :
28352 variant === "merged" ? "badge-merged" :
28353 variant === "success" ? "badge-success" :
28354- variant === "danger" ? "badge-danger" :
28355- variant === "warning" ? "badge-warning" :
28356- "badge";
28357+ variant === "danger" ? "badge-danger" :
28358+ variant === "warning" ? "badge-warning" :
28359+ variant === "live" ? "badge-live" :
28360+ variant === "soon" ? "badge-soon" :
28361+ variant === "preview" ? "badge-preview" :
28362+ "badge";
28363 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
28364 };
28365
28366
28367diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
28368index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
28369--- a/src/views/landing-pro.tsx
28370+++ b/src/views/landing-pro.tsx
28371@@ -42,7 +42,7 @@
28372
28373 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28374
28375-function icon(paths: string, color = "#4353c9", size = 20) {
28376+function icon(paths: string, color = "#0891b2", size = 20) {
28377 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
28378 }
28379
28380@@ -947,7 +947,7 @@
28381 const css = `
28382 /* %% tokens %% */
28383 :root{
28384- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
28385+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
28386 --lp-bg:#ffffff;--lp-soft:#fafafb;
28387 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
28388 --lp-border:rgba(0,0,0,.08);
28389diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
28390deleted file mode 100644
28391index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
28392--- a/src/views/landing-v2.tsx
28393+++ /dev/null
28394@@ -1,1447 +0,0 @@
28395-import type { FC } from "hono/jsx";
28396-
28397-export interface LandingPageProps {
28398- stats?: {
28399- publicRepos?: number;
28400- users?: number;
28401- };
28402-}
28403-
28404-const demoAllEvents = [
28405- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
28406- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
28407- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
28408- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
28409- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
28410-];
28411-
28412-const tickerItems = [
28413- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
28414- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
28415- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
28416- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
28417- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
28418- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
28419- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
28420- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
28421- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
28422- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
28423- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
28424- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
28425- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
28426- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
28427- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
28428- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
28429-];
28430-
28431-const stageData = [
28432- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
28433- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
28434- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
28435- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
28436- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
28437- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
28438-];
28439-
28440-const heroFeatures = [
28441- {
28442- href: "/",
28443- eyebrow: "01 � The autonomous repair loop",
28444- title: "Failures fix themselves  and show their work.",
28445- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
28446failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
28447- cta: "Watch a live repair session",
28448- mock: [
28449- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
28450- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
28451- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
28452- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
28453- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
28454- ],
28455- },
28456- {
28457- href: "/",
28458- eyebrow: "02 � Live sandbox isolation",
28459- title: "Every PR gets its own instant, disposable environment.",
28460- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
28461same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
28462- cta: "See a PR with its sandbox",
28463- mock: [
28464- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
28465- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
28466- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
28467- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
28468- ],
28469- },
28470- {
28471- href: "/",
28472- eyebrow: "03 � Multiplayer IDE workspaces",
28473- title: "You and the agent, side by side, in your editor.",
28474- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
28475agent into a silent reviewer in your gutter. The browser becomes optional.",
28476- cta: "See the editor session",
28477- mock: [
28478- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
28479- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
28480- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
28481- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
28482- ],
28483- },
28484-];
28485-
28486-const capabilities = [
28487- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
28488- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
28489- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
28490- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
28491- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
28492- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
28493- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
28494- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
28495-];
28496-
28497-const sovereignLayerNames = [
28498- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
28499- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
28500- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
28501- "Availability & recovery",
28502-];
28503-
28504-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
28505- return (
28506- <>
28507- <style dangerouslySetInnerHTML={{ __html: css }} />
28508-
28509- {/* Nav */}
28510- <header class="lv-nav">
28511- <div class="lv-nav-inner">
28512- <a href="/" class="lv-logo">
28513- <span class="lv-logo-mark"></span>gluecron
28514- </a>
28515- <nav class="lv-nav-links">
28516- <a href="#loop" class="lv-nav-link">The loop</a>
28517- <a href="#platform" class="lv-nav-link">Platform</a>
28518- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
28519- <a href="/trust" class="lv-nav-link">Trust</a>
28520- </nav>
28521- <div class="lv-nav-ctas">
28522- <a href="/login" class="lv-btn-secondary">Sign in</a>
28523- <a href="/register" class="lv-btn-primary">Start building</a>
28524- </div>
28525- </div>
28526- </header>
28527-
28528- {/* Hero */}
28529- <section class="lv-hero">
28530- <div class="lv-hero-glow"></div>
28531- <div class="lv-hero-inner">
28532- <div class="lv-hero-badge">
28533- <span class="lv-dot lv-dot-green lv-pulse"></span>
28534- Live: a repair loop converged on pr-218 while you read this
28535- </div>
28536- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
28537- <p class="lv-hero-sub">
28538- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
28539failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
28540- </p>
28541- <div class="lv-hero-actions">
28542- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
28543- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
28544- </div>
28545- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
28546-
28547- {/* Live product window */}
28548- <div class="lv-demo-window">
28549- <div class="lv-demo-bar">
28550- <span class="lv-demo-dot"></span>
28551- <span class="lv-demo-dot"></span>
28552- <span class="lv-demo-dot"></span>
28553- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
28554- <span class="lv-demo-live">
28555- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
28556- LIVE
28557- </span>
28558- </div>
28559- <div class="lv-demo-body" id="lv-demo-body">
28560- {/* Events rendered by JS */}
28561- {demoAllEvents.slice(0, 1).map((e, i) => (
28562- <div class="lv-demo-event" key={i}>
28563- <div class="lv-demo-event-track">
28564- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
28565- <span class="lv-demo-line" style="display:none"></span>
28566- </div>
28567- <div class="lv-demo-event-content">
28568- <div class="lv-demo-event-header">
28569- <span class="lv-demo-event-title">{e.title}</span>
28570- <span class="lv-demo-event-time">{e.time}</span>
28571- </div>
28572- <div class="lv-demo-event-body">{e.body}</div>
28573- </div>
28574- </div>
28575- ))}
28576- </div>
28577- </div>
28578- </div>
28579-
28580- {/* Activity ticker */}
28581- <div class="lv-ticker-wrap">
28582- <div class="lv-ticker-track">
28583- {tickerItems.map((t, i) => (
28584- <span class="lv-ticker-item" key={i}>
28585- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
28586- {t.text}
28587- </span>
28588- ))}
28589- </div>
28590- </div>
28591- </section>
28592-
28593- {/* Stat band */}
28594- <section class="lv-stats">
28595- <div class="lv-stats-inner">
28596- <div class="lv-stat">
28597- <div class="lv-stat-num">Sonnet 5</div>
28598- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
28599- </div>
28600- <div class="lv-stat">
28601- <div class="lv-stat-num">93.5%</div>
28602- <div class="lv-stat-label">of failures self-repair without a human</div>
28603- </div>
28604- <div class="lv-stat">
28605- <div class="lv-stat-num">1.9%</div>
28606- <div class="lv-stat-label">AI merges reverted  published live</div>
28607- </div>
28608- <div class="lv-stat">
28609- <div class="lv-stat-num">0</div>
28610- <div class="lv-stat-label">irreversible actions taken autonomously</div>
28611- </div>
28612- </div>
28613- </section>
28614-
28615- {/* The loop */}
28616- <section id="loop" class="lv-loop">
28617- <div class="lv-loop-inner">
28618- <div class="lv-section-header">
28619- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
28620- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
28621- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
28622- </div>
28623- <div class="lv-stages" id="lv-stages">
28624- {stageData.map((s, i) => (
28625- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
28626- <div class="lv-stage-header">
28627- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
28628- <span class="lv-stage-n">0{i + 1}</span>
28629- </div>
28630- <div class="lv-stage-name">{s.name}</div>
28631- <div class="lv-stage-desc">{s.desc}</div>
28632- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
28633- </div>
28634- ))}
28635- </div>
28636- </div>
28637- </section>
28638-
28639- {/* Three heroes */}
28640- <section class="lv-heroes">
28641- <div class="lv-heroes-inner">
28642- <div class="lv-heroes-header">
28643- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
28644- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
28645- </div>
28646- <div class="lv-heroes-list">
28647- {heroFeatures.map((h, i) => (
28648- <a href={h.href} class="lv-hero-card" key={i}>
28649- <div class="lv-hero-card-left">
28650- <div class="lv-eyebrow">{h.eyebrow}</div>
28651- <h3 class="lv-hero-card-title">{h.title}</h3>
28652- <p class="lv-hero-card-body">{h.body}</p>
28653- <span class="lv-hero-card-cta">{h.cta} �!</span>
28654- </div>
28655- <div class="lv-terminal">
28656- {h.mock.map((m, j) => (
28657- <div class="lv-terminal-line" key={j}>
28658- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
28659- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
28660- </div>
28661- ))}
28662- </div>
28663- </a>
28664- ))}
28665- </div>
28666- </div>
28667- </section>
28668-
28669- {/* Everything grid */}
28670- <section id="platform" class="lv-platform">
28671- <div class="lv-platform-inner">
28672- <div class="lv-section-header lv-section-header-center">
28673- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
28674- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
28675- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
28676- </div>
28677- <div class="lv-cap-grid">
28678- {capabilities.map((c, i) => (
28679- <div class="lv-cap-col" key={i}>
28680- <div class="lv-cap-group">{c.group}</div>
28681- <div class="lv-cap-items">
28682- {c.items.map((item, j) => (
28683- <div class="lv-cap-item" key={j}>{item}</div>
28684- ))}
28685- </div>
28686- </div>
28687- ))}
28688- </div>
28689- </div>
28690- </section>
28691-
28692- {/* Sovereignty band */}
28693- <section id="sovereign" class="lv-sovereign">
28694- <div class="lv-sovereign-grid-bg"></div>
28695- <div class="lv-sovereign-inner">
28696- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
28697- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
28698- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
28699- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
28700to private cloud, or run fully air-gapped on bare metal.</p>
28701- </div>
28702- <div class="lv-layers-grid">
28703- {sovereignLayerNames.map((name, i) => (
28704- <div class="lv-layer-chip" key={i}>
28705- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
28706- <div class="lv-layer-name">{name}</div>
28707- </div>
28708- ))}
28709- <a href="/" class="lv-layer-chip lv-layer-cta">
28710- <div class="lv-layer-cta-text">All self-owned �!</div>
28711- </a>
28712- </div>
28713- <div class="lv-sovereign-feats">
28714- <div class="lv-sovereign-feat">
28715- <div class="lv-sovereign-feat-title">Local inference first</div>
28716- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
28717- </div>
28718- <div class="lv-sovereign-feat">
28719- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
28720- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
28721- </div>
28722- <div class="lv-sovereign-feat">
28723- <div class="lv-sovereign-feat-title">Self-healing infra</div>
28724- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
28725- </div>
28726- </div>
28727- </div>
28728- </section>
28729-
28730- {/* Manual-first + reversibility */}
28731- <section class="lv-twin">
28732- <div class="lv-twin-inner">
28733- <div class="lv-twin-card">
28734- <div class="lv-eyebrow">Manual-first, always</div>
28735- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
28736- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
28737fallback. Developers who never touch AI get the best git host they've ever used.</p>
28738- </div>
28739- <div class="lv-twin-card">
28740- <div class="lv-eyebrow">The reversibility guarantee</div>
28741- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
28742- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
28743 policy, not promise. Our quality numbers are published live, unedited.</p>
28744- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
28745- </div>
28746- </div>
28747- </section>
28748-
28749- {/* Quote */}
28750- <section class="lv-quote">
28751- <div class="lv-quote-inner">
28752- <p class="lv-quote-text">
28753- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
28754- Gluecron is where code gets <em class="lv-em">finished</em>."
28755- </p>
28756- </div>
28757- </section>
28758-
28759- {/* CTA */}
28760- <section class="lv-cta-section">
28761- <div class="lv-cta-card">
28762- <div class="lv-cta-glow"></div>
28763- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
28764- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
28765- <div class="lv-cta-actions">
28766- <a href="/register" class="lv-cta-primary">Create your account �!</a>
28767- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
28768- </div>
28769- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
28770- </div>
28771- </section>
28772-
28773- {/* Footer */}
28774- <footer class="lv-footer">
28775- <div class="lv-footer-inner">
28776- <div class="lv-footer-brand">
28777- <a href="/" class="lv-logo">
28778- <span class="lv-logo-mark"></span>gluecron
28779- </a>
28780- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
28781- </div>
28782- <div class="lv-footer-cols">
28783- <div class="lv-footer-col">
28784- <h4 class="lv-footer-col-head">Product</h4>
28785- <a href="/" class="lv-footer-link">Agent workspace</a>
28786- <a href="/" class="lv-footer-link">Fleet refactors</a>
28787- <a href="/" class="lv-footer-link">Org memory</a>
28788- <a href="/" class="lv-footer-link">IDE extensions</a>
28789- </div>
28790- <div class="lv-footer-col">
28791- <h4 class="lv-footer-col-head">Platform</h4>
28792- <a href="/" class="lv-footer-link">Production layers</a>
28793- <a href="/trust" class="lv-footer-link">Trust report</a>
28794- <a href="/" class="lv-footer-link">Docs</a>
28795- <a href="/" class="lv-footer-link">Status</a>
28796- </div>
28797- <div class="lv-footer-col">
28798- <h4 class="lv-footer-col-head">Company</h4>
28799- <a href="/" class="lv-footer-link">About</a>
28800- <a href="/" class="lv-footer-link">Pricing</a>
28801- <a href="/" class="lv-footer-link">Enterprise</a>
28802- </div>
28803- </div>
28804- </div>
28805- <div class="lv-footer-bar">
28806- <span>� 2026 Gluecron</span>
28807- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
28808- </div>
28809- </footer>
28810-
28811- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
28812- </>
28813- );
28814-};
28815-
28816-export const LandingPage = LandingPageV2;
28817-export default LandingPageV2;
28818-
28819-const clientScript = `
28820-(function() {
28821- var demoAll = [
28822- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
28823- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
28824- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
28825- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
28826- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
28827- ];
28828-
28829- var demoStep = 0;
28830- var stage = 0;
28831-
28832- function renderDemo() {
28833- var container = document.getElementById('lv-demo-body');
28834- if (!container) return;
28835- var visible = demoAll.slice(0, demoStep + 1);
28836- container.innerHTML = visible.map(function(e, i) {
28837- var isLast = i === visible.length - 1;
28838- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
28839- return '<div class="lv-demo-event">' +
28840- '<div class="lv-demo-event-track">' +
28841- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
28842- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
28843- '</div>' +
28844- '<div class="lv-demo-event-content">' +
28845- '<div class="lv-demo-event-header">' +
28846- '<span class="lv-demo-event-title">' + e.title + '</span>' +
28847- '<span class="lv-demo-event-time">' + e.time + '</span>' +
28848- '</div>' +
28849- '<div class="lv-demo-event-body">' + e.body + '</div>' +
28850- '</div>' +
28851- '</div>';
28852- }).join('');
28853- }
28854-
28855- function renderStages() {
28856- var cards = document.querySelectorAll('.lv-stage-card');
28857- cards.forEach(function(card, i) {
28858- var dot = card.querySelector('.lv-dot');
28859- var meta = card.querySelector('.lv-stage-meta');
28860- if (i === stage) {
28861- card.classList.add('lv-stage-active');
28862- if (dot) {
28863- dot.classList.remove('lv-dot-idle');
28864- dot.classList.add('lv-dot-indigo', 'lv-pulse');
28865- }
28866- if (meta) meta.classList.add('lv-stage-meta-active');
28867- } else {
28868- card.classList.remove('lv-stage-active');
28869- if (dot) {
28870- dot.classList.add('lv-dot-idle');
28871- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
28872- }
28873- if (meta) meta.classList.remove('lv-stage-meta-active');
28874- }
28875- });
28876- }
28877-
28878- renderDemo();
28879-
28880- setInterval(function() {
28881- demoStep = (demoStep + 1) % 5;
28882- renderDemo();
28883- }, 3600);
28884-
28885- setInterval(function() {
28886- stage = (stage + 1) % 6;
28887- renderStages();
28888- }, 2200);
28889-})();
28890-`;
28891-
28892-const css = `
28893-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
28894-
28895-*, *::before, *::after { box-sizing: border-box; }
28896-
28897-body {
28898- margin: 0;
28899- background: #fcfcfd;
28900- -webkit-font-smoothing: antialiased;
28901- text-rendering: optimizeLegibility;
28902- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
28903- font-size: 15px;
28904- line-height: 1.6;
28905- letter-spacing: -0.008em;
28906- color: #16181d;
28907-}
28908-
28909-@keyframes gcPulse {
28910- 0%, 100% { opacity: 1; }
28911- 50% { opacity: 0.35; }
28912-}
28913-
28914-@keyframes gcTicker {
28915- 0% { transform: translateX(0); }
28916- 100% { transform: translateX(-50%); }
28917-}
28918-
28919-/* Shared utilities */
28920-.lv-dot {
28921- display: inline-block;
28922- border-radius: 50%;
28923-}
28924-.lv-dot-green { background: #1e7f5c; }
28925-.lv-dot-indigo { background: #4353c9; }
28926-.lv-dot-idle { background: #c4c6cf; }
28927-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
28928-
28929-.lv-strong { color: #16181d; font-weight: 600; }
28930-
28931-.lv-eyebrow {
28932- font-family: 'JetBrains Mono', monospace;
28933- font-size: 11px;
28934- letter-spacing: 0.12em;
28935- text-transform: uppercase;
28936- color: #8a8d99;
28937- font-weight: 500;
28938- margin-bottom: 12px;
28939-}
28940-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
28941-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
28942-
28943-.lv-h1 {
28944- font-family: 'Inter Tight', sans-serif;
28945- font-weight: 700;
28946- letter-spacing: -0.035em;
28947- font-size: clamp(44px, 7vw, 84px);
28948- line-height: 0.98;
28949- margin: 30px auto 0;
28950- max-width: 14ch;
28951- color: #111318;
28952-}
28953-
28954-.lv-h2 {
28955- font-family: 'Inter Tight', sans-serif;
28956- font-weight: 700;
28957- letter-spacing: -0.028em;
28958- font-size: clamp(30px, 4.4vw, 48px);
28959- line-height: 1.05;
28960- margin: 0;
28961- color: #111318;
28962-}
28963-
28964-.lv-h2-dark {
28965- font-family: 'Inter Tight', sans-serif;
28966- font-weight: 700;
28967- letter-spacing: -0.028em;
28968- font-size: clamp(30px, 4.6vw, 52px);
28969- line-height: 1.05;
28970- margin: 0;
28971- color: #fff;
28972-}
28973-
28974-.lv-section-header {
28975- max-width: 640px;
28976- margin: 0 auto 56px;
28977-}
28978-
28979-.lv-section-header-center {
28980- text-align: center;
28981-}
28982-
28983-.lv-section-sub {
28984- color: #6b7080;
28985- font-size: 17px;
28986- margin: 18px auto 0;
28987- max-width: 52ch;
28988-}
28989-
28990-.lv-section-sub-dark {
28991- color: rgba(255,255,255,0.72);
28992- font-size: 17px;
28993- margin: 18px auto 0;
28994- max-width: 56ch;
28995-}
28996-
28997-/* Nav */
28998-.lv-nav {
28999- position: sticky;
29000- top: 0;
29001- z-index: 60;
29002- backdrop-filter: saturate(180%) blur(14px);
29003- -webkit-backdrop-filter: saturate(180%) blur(14px);
29004- background: rgba(252,252,253,0.8);
29005- border-bottom: 1px solid rgba(22,24,29,0.07);
29006-}
29007-
29008-.lv-nav-inner {
29009- max-width: 1200px;
29010- margin: 0 auto;
29011- padding: 14px 28px;
29012- display: flex;
29013- align-items: center;
29014- gap: 28px;
29015-}
29016-
29017-.lv-logo {
29018- display: inline-flex;
29019- align-items: center;
29020- gap: 9px;
29021- font-family: 'Inter Tight', sans-serif;
29022- font-weight: 700;
29023- font-size: 17px;
29024- letter-spacing: -0.02em;
29025- color: #16181d;
29026- text-decoration: none;
29027-}
29028-
29029-.lv-logo-mark {
29030- width: 17px;
29031- height: 17px;
29032- border-radius: 5px;
29033- background: #4353c9;
29034- display: inline-block;
29035- flex-shrink: 0;
29036-}
29037-
29038-.lv-nav-links {
29039- display: flex;
29040- gap: 24px;
29041- font-size: 13.5px;
29042- font-weight: 500;
29043-}
29044-
29045-.lv-nav-link {
29046- color: #6b7080;
29047- text-decoration: none;
29048- transition: color 0.15s;
29049-}
29050-.lv-nav-link:hover { color: #16181d; }
29051-
29052-.lv-nav-ctas {
29053- margin-left: auto;
29054- display: flex;
29055- align-items: center;
29056- gap: 10px;
29057-}
29058-
29059-.lv-btn-secondary {
29060- padding: 8px 15px;
29061- border-radius: 8px;
29062- font-size: 13.5px;
29063- font-weight: 500;
29064- color: #16181d;
29065- border: 1px solid rgba(22,24,29,0.12);
29066- background: #ffffff;
29067- text-decoration: none;
29068- white-space: nowrap;
29069- transition: border-color 0.15s;
29070-}
29071-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
29072-
29073-.lv-btn-primary {
29074- padding: 8px 15px;
29075- border-radius: 8px;
29076- font-size: 13.5px;
29077- font-weight: 600;
29078- background: #16181d;
29079- color: #fff;
29080- text-decoration: none;
29081- white-space: nowrap;
29082- transition: box-shadow 0.15s;
29083-}
29084-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
29085-
29086-/* Hero */
29087-.lv-hero {
29088- position: relative;
29089- overflow: hidden;
29090- padding: 88px 0 0;
29091-}
29092-
29093-.lv-hero-glow {
29094- position: absolute;
29095- inset: -10% 0 auto 0;
29096- height: 640px;
29097- pointer-events: none;
29098- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
29099-}
29100-
29101-.lv-hero-inner {
29102- position: relative;
29103- max-width: 1200px;
29104- margin: 0 auto;
29105- padding: 0 28px;
29106- text-align: center;
29107-}
29108-
29109-.lv-hero-badge {
29110- display: inline-flex;
29111- align-items: center;
29112- gap: 9px;
29113- font-size: 12.5px;
29114- font-weight: 600;
29115- color: #3a3d45;
29116- background: #ffffff;
29117- border: 1px solid rgba(22,24,29,0.10);
29118- border-radius: 9999px;
29119- padding: 7px 16px;
29120- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
29121-}
29122-
29123-.lv-hero-sub {
29124- font-size: clamp(16px, 2vw, 19px);
29125- color: #6b7080;
29126- max-width: 60ch;
29127- margin: 24px auto 0;
29128- font-weight: 450;
29129- line-height: 1.65;
29130-}
29131-
29132-.lv-hero-actions {
29133- display: flex;
29134- gap: 12px;
29135- justify-content: center;
29136- flex-wrap: wrap;
29137- margin-top: 32px;
29138-}
29139-
29140-.lv-cta-primary {
29141- padding: 13px 24px;
29142- border-radius: 11px;
29143- font-size: 15.5px;
29144- font-weight: 600;
29145- background: #16181d;
29146- color: #fff;
29147- text-decoration: none;
29148- white-space: nowrap;
29149- transition: box-shadow 0.15s;
29150-}
29151-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
29152-
29153-.lv-cta-secondary {
29154- padding: 13px 24px;
29155- border-radius: 11px;
29156- font-size: 15.5px;
29157- font-weight: 600;
29158- color: #16181d;
29159- border: 1px solid rgba(22,24,29,0.14);
29160- background: #ffffff;
29161- text-decoration: none;
29162- white-space: nowrap;
29163- transition: border-color 0.15s;
29164-}
29165-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
29166-
29167-.lv-hero-tag {
29168- margin-top: 18px;
29169- font-family: 'JetBrains Mono', monospace;
29170- font-size: 11.5px;
29171- letter-spacing: 0.08em;
29172- text-transform: uppercase;
29173- color: #8a8d99;
29174-}
29175-
29176-/* Demo window */
29177-.lv-demo-window {
29178- margin: 56px auto 0;
29179- max-width: 860px;
29180- text-align: left;
29181- background: #ffffff;
29182- border: 1px solid rgba(22,24,29,0.09);
29183- border-radius: 18px;
29184- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
29185- overflow: hidden;
29186-}
29187-
29188-.lv-demo-bar {
29189- display: flex;
29190- align-items: center;
29191- gap: 7px;
29192- padding: 12px 18px;
29193- border-bottom: 1px solid rgba(22,24,29,0.07);
29194- background: #fcfcfd;
29195-}
29196-
29197-.lv-demo-dot {
29198- width: 10px;
29199- height: 10px;
29200- border-radius: 50%;
29201- background: #e4e5ea;
29202-}
29203-
29204-.lv-demo-url {
29205- margin-left: 10px;
29206- font-family: 'JetBrains Mono', monospace;
29207- font-size: 12px;
29208- color: #6b7080;
29209-}
29210-
29211-.lv-demo-live {
29212- margin-left: auto;
29213- display: inline-flex;
29214- align-items: center;
29215- gap: 6px;
29216- font-size: 11px;
29217- font-weight: 600;
29218- color: #1e7f5c;
29219-}
29220-
29221-.lv-demo-body {
29222- padding: 22px 24px;
29223-}
29224-
29225-.lv-demo-event {
29226- display: grid;
29227- grid-template-columns: 18px minmax(0, 1fr);
29228- gap: 14px;
29229- padding-bottom: 20px;
29230- position: relative;
29231-}
29232-.lv-demo-event:last-child { padding-bottom: 0; }
29233-
29234-.lv-demo-event-track {
29235- display: flex;
29236- flex-direction: column;
29237- align-items: center;
29238-}
29239-
29240-.lv-demo-line {
29241- width: 1px;
29242- flex: 1;
29243- background: rgba(22,24,29,0.08);
29244- margin-top: 5px;
29245- min-height: 20px;
29246-}
29247-
29248-.lv-demo-event-content {}
29249-
29250-.lv-demo-event-header {
29251- display: flex;
29252- align-items: baseline;
29253- gap: 10px;
29254-}
29255-
29256-.lv-demo-event-title {
29257- font-size: 13.5px;
29258- font-weight: 600;
29259- color: #16181d;
29260-}
29261-
29262-.lv-demo-event-time {
29263- font-family: 'JetBrains Mono', monospace;
29264- font-size: 11px;
29265- color: #8a8d99;
29266-}
29267-
29268-.lv-demo-event-body {
29269- font-size: 13px;
29270- color: #6b7080;
29271- margin-top: 2px;
29272-}
29273-
29274-/* Ticker */
29275-.lv-ticker-wrap {
29276- border-top: 1px solid rgba(22,24,29,0.07);
29277- border-bottom: 1px solid rgba(22,24,29,0.07);
29278- background: #ffffff;
29279- margin-top: 64px;
29280- overflow: hidden;
29281- white-space: nowrap;
29282- position: relative;
29283-}
29284-
29285-.lv-ticker-track {
29286- display: inline-flex;
29287- animation: gcTicker 40s linear infinite;
29288- padding: 11px 0;
29289-}
29290-
29291-.lv-ticker-item {
29292- display: inline-flex;
29293- align-items: center;
29294- gap: 8px;
29295- font-family: 'JetBrains Mono', monospace;
29296- font-size: 11.5px;
29297- color: #6b7080;
29298- padding: 0 28px;
29299- border-right: 1px solid rgba(22,24,29,0.06);
29300-}
29301-
29302-/* Stats */
29303-.lv-stats {
29304- background: #fcfcfd;
29305-}
29306-
29307-.lv-stats-inner {
29308- max-width: 1200px;
29309- margin: 0 auto;
29310- display: grid;
29311- grid-template-columns: repeat(4, 1fr);
29312- gap: 24px;
29313- padding: 52px 28px;
29314-}
29315-
29316-.lv-stat {
29317- text-align: center;
29318-}
29319-
29320-.lv-stat-num {
29321- font-family: 'Inter Tight', sans-serif;
29322- font-weight: 700;
29323- font-size: clamp(30px, 4vw, 44px);
29324- letter-spacing: -0.025em;
29325- color: #111318;
29326-}
29327-
29328-.lv-stat-label {
29329- font-size: 13px;
29330- color: #6b7080;
29331- margin-top: 4px;
29332-}
29333-
29334-/* Loop */
29335-.lv-loop {
29336- padding: 96px 0;
29337- background: #ffffff;
29338- border-top: 1px solid rgba(22,24,29,0.07);
29339- border-bottom: 1px solid rgba(22,24,29,0.07);
29340-}
29341-
29342-.lv-loop-inner {
29343- max-width: 1200px;
29344- margin: 0 auto;
29345- padding: 0 28px;
29346-}
29347-
29348-.lv-stages {
29349- display: grid;
29350- grid-template-columns: repeat(6, 1fr);
29351- gap: 12px;
29352-}
29353-
29354-.lv-stage-card {
29355- border: 1px solid rgba(22,24,29,0.08);
29356- border-radius: 14px;
29357- background: #ffffff;
29358- padding: 20px 18px;
29359- transition: border-color 0.3s, background 0.3s;
29360-}
29361-
29362-.lv-stage-card.lv-stage-active {
29363- border-color: rgba(67,83,201,0.45);
29364- background: rgba(67,83,201,0.03);
29365-}
29366-
29367-.lv-stage-header {
29368- display: flex;
29369- align-items: center;
29370- gap: 8px;
29371- margin-bottom: 10px;
29372-}
29373-
29374-.lv-stage-n {
29375- font-family: 'JetBrains Mono', monospace;
29376- font-size: 10.5px;
29377- letter-spacing: 0.1em;
29378- text-transform: uppercase;
29379- color: #8a8d99;
29380-}
29381-
29382-.lv-stage-name {
29383- font-family: 'Inter Tight', sans-serif;
29384- font-size: 16px;
29385- font-weight: 600;
29386- letter-spacing: -0.01em;
29387- color: #16181d;
29388- margin-bottom: 5px;
29389-}
29390-
29391-.lv-stage-desc {
29392- font-size: 12px;
29393- color: #6b7080;
29394- line-height: 1.55;
29395-}
29396-
29397-.lv-stage-meta {
29398- font-family: 'JetBrains Mono', monospace;
29399- font-size: 10.5px;
29400- color: #8a8d99;
29401- margin-top: 10px;
29402- transition: color 0.3s;
29403-}
29404-
29405-.lv-stage-meta.lv-stage-meta-active {
29406- color: #4353c9;
29407-}
29408-
29409-/* Heroes */
29410-.lv-heroes {
29411- padding: 96px 0;
29412- background: #fcfcfd;
29413-}
29414-
29415-.lv-heroes-inner {
29416- max-width: 1200px;
29417- margin: 0 auto;
29418- padding: 0 28px;
29419-}
29420-
29421-.lv-heroes-header {
29422- max-width: 640px;
29423- margin-bottom: 56px;
29424-}
29425-
29426-.lv-heroes-list {
29427- display: flex;
29428- flex-direction: column;
29429- gap: 20px;
29430-}
29431-
29432-.lv-hero-card {
29433- display: grid;
29434- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
29435- gap: 48px;
29436- align-items: center;
29437- border: 1px solid rgba(22,24,29,0.08);
29438- border-radius: 20px;
29439- background: #ffffff;
29440- padding: 44px 48px;
29441- text-decoration: none;
29442- transition: border-color 0.2s, box-shadow 0.2s;
29443-}
29444-.lv-hero-card:hover {
29445- border-color: rgba(22,24,29,0.22);
29446- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
29447-}
29448-
29449-.lv-hero-card-left {}
29450-
29451-.lv-hero-card-title {
29452- font-family: 'Inter Tight', sans-serif;
29453- font-size: 26px;
29454- font-weight: 600;
29455- letter-spacing: -0.022em;
29456- line-height: 1.15;
29457- color: #16181d;
29458- margin: 0 0 12px;
29459-}
29460-
29461-.lv-hero-card-body {
29462- font-size: 14.5px;
29463- color: #6b7080;
29464- margin: 0 0 18px;
29465- line-height: 1.65;
29466-}
29467-
29468-.lv-hero-card-cta {
29469- font-size: 13.5px;
29470- font-weight: 600;
29471- color: #4353c9;
29472-}
29473-
29474-.lv-terminal {
29475- border: 1px solid rgba(22,24,29,0.07);
29476- border-radius: 14px;
29477- background: #fcfcfd;
29478- padding: 20px 22px;
29479- font-family: 'JetBrains Mono', monospace;
29480- font-size: 12px;
29481- line-height: 1.9;
29482- overflow: hidden;
29483-}
29484-
29485-.lv-terminal-line {
29486- display: flex;
29487- align-items: center;
29488- gap: 10px;
29489- white-space: nowrap;
29490- overflow: hidden;
29491- text-overflow: ellipsis;
29492-}
29493-
29494-/* Platform */
29495-.lv-platform {
29496- padding: 96px 0;
29497- background: #ffffff;
29498- border-top: 1px solid rgba(22,24,29,0.07);
29499-}
29500-
29501-.lv-platform-inner {
29502- max-width: 1200px;
29503- margin: 0 auto;
29504- padding: 0 28px;
29505-}
29506-
29507-.lv-cap-grid {
29508- display: grid;
29509- grid-template-columns: repeat(4, 1fr);
29510- gap: 24px 32px;
29511-}
29512-
29513-.lv-cap-col {}
29514-
29515-.lv-cap-group {
29516- font-family: 'JetBrains Mono', monospace;
29517- font-size: 10.5px;
29518- letter-spacing: 0.12em;
29519- text-transform: uppercase;
29520- color: #8a8d99;
29521- font-weight: 500;
29522- margin-bottom: 12px;
29523- padding-bottom: 8px;
29524- border-bottom: 1px solid rgba(22,24,29,0.07);
29525-}
29526-
29527-.lv-cap-items {
29528- display: flex;
29529- flex-direction: column;
29530- gap: 7px;
29531-}
29532-
29533-.lv-cap-item {
29534- font-size: 12.5px;
29535- color: #3a3d45;
29536- line-height: 1.45;
29537-}
29538-
29539-/* Sovereignty */
29540-.lv-sovereign {
29541- position: relative;
29542- overflow: hidden;
29543- padding: 104px 0;
29544- color: #fff;
29545- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
29546-}
29547-
29548-.lv-sovereign-grid-bg {
29549- position: absolute;
29550- inset: 0;
29551- opacity: 0.4;
29552- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
29553- background-size: 56px 56px;
29554- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
29555- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
29556-}
29557-
29558-.lv-sovereign-inner {
29559- position: relative;
29560- max-width: 1200px;
29561- margin: 0 auto;
29562- padding: 0 28px;
29563-}
29564-
29565-.lv-section-header-dark {
29566- max-width: 680px;
29567- margin: 0 auto 48px;
29568- text-align: center;
29569-}
29570-
29571-.lv-layers-grid {
29572- display: grid;
29573- grid-template-columns: repeat(4, 1fr);
29574- gap: 10px;
29575- max-width: 980px;
29576- margin: 0 auto;
29577-}
29578-
29579-.lv-layer-chip {
29580- border: 1px solid rgba(255,255,255,0.10);
29581- border-radius: 10px;
29582- padding: 12px 16px;
29583- background: rgba(255,255,255,0.03);
29584-}
29585-
29586-.lv-layer-cta {
29587- border-color: rgba(169,180,238,0.30);
29588- background: rgba(169,180,238,0.06);
29589- display: flex;
29590- align-items: center;
29591- text-decoration: none;
29592- transition: background 0.15s;
29593-}
29594-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
29595-
29596-.lv-layer-cta-text {
29597- font-size: 13px;
29598- font-weight: 500;
29599- color: #a9b4ee;
29600-}
29601-
29602-.lv-layer-n {
29603- font-family: 'JetBrains Mono', monospace;
29604- font-size: 10px;
29605- color: rgba(255,255,255,0.4);
29606- margin-bottom: 3px;
29607-}
29608-
29609-.lv-layer-name {
29610- font-size: 13px;
29611- font-weight: 500;
29612- color: rgba(255,255,255,0.92);
29613-}
29614-
29615-.lv-sovereign-feats {
29616- display: flex;
29617- gap: 44px;
29618- justify-content: center;
29619- flex-wrap: wrap;
29620- margin-top: 52px;
29621- text-align: center;
29622-}
29623-
29624-.lv-sovereign-feat {}
29625-
29626-.lv-sovereign-feat-title {
29627- font-family: 'Inter Tight', sans-serif;
29628- font-size: 20px;
29629- font-weight: 700;
29630- color: #fff;
29631-}
29632-
29633-.lv-sovereign-feat-sub {
29634- color: rgba(255,255,255,0.55);
29635- font-size: 13px;
29636- margin-top: 2px;
29637-}
29638-
29639-/* Twin cards */
29640-.lv-twin {
29641- padding: 96px 0;
29642- background: #fcfcfd;
29643-}
29644-
29645-.lv-twin-inner {
29646- max-width: 1200px;
29647- margin: 0 auto;
29648- padding: 0 28px;
29649- display: grid;
29650- grid-template-columns: 1fr 1fr;
29651- gap: 24px;
29652-}
29653-
29654-.lv-twin-card {
29655- border: 1px solid rgba(22,24,29,0.08);
29656- border-radius: 20px;
29657- background: #ffffff;
29658- padding: 44px 48px;
29659-}
29660-
29661-.lv-twin-title {
29662- font-family: 'Inter Tight', sans-serif;
29663- font-size: 24px;
29664- font-weight: 600;
29665- letter-spacing: -0.02em;
29666- line-height: 1.2;
29667- margin: 0 0 12px;
29668- color: #16181d;
29669-}
29670-
29671-.lv-twin-body {
29672- font-size: 14.5px;
29673- color: #6b7080;
29674- margin: 0 0 16px;
29675- line-height: 1.7;
29676-}
29677-
29678-.lv-twin-link {
29679- font-size: 13.5px;
29680- font-weight: 600;
29681- color: #4353c9;
29682- text-decoration: none;
29683-}
29684-.lv-twin-link:hover { text-decoration: underline; }
29685-
29686-/* Quote */
29687-.lv-quote {
29688- padding: 40px 0 96px;
29689- background: #fcfcfd;
29690-}
29691-
29692-.lv-quote-inner {
29693- max-width: 980px;
29694- margin: 0 auto;
29695- padding: 0 28px;
29696- text-align: center;
29697-}
29698-
29699-.lv-quote-text {
29700- font-family: 'Inter Tight', sans-serif;
29701- font-weight: 600;
29702- font-size: clamp(26px, 3.8vw, 42px);
29703- line-height: 1.2;
29704- letter-spacing: -0.025em;
29705- margin: 0;
29706- color: #111318;
29707-}
29708-
29709-.lv-em {
29710- font-style: normal;
29711- color: #4353c9;
29712-}
29713-
29714-/* CTA */
29715-.lv-cta-section {
29716- padding: 0 0 104px;
29717- background: #fcfcfd;
29718-}
29719-
29720-.lv-cta-card {
29721- max-width: 820px;
29722- margin: 0 auto;
29723- padding: 64px 40px;
29724- text-align: center;
29725- background: #ffffff;
29726- border: 1px solid rgba(22,24,29,0.08);
29727- border-radius: 26px;
29728- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
29729- position: relative;
29730- overflow: hidden;
29731-}
29732-
29733-.lv-cta-glow {
29734- position: absolute;
29735- inset: -40% 0 auto 0;
29736- height: 280px;
29737- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
29738- pointer-events: none;
29739-}
29740-
29741-.lv-cta-h2 {
29742- font-family: 'Inter Tight', sans-serif;
29743- font-weight: 700;
29744- letter-spacing: -0.028em;
29745- font-size: clamp(30px, 4.6vw, 48px);
29746- margin: 0;
29747- position: relative;
29748- color: #111318;
29749-}
29750-
29751-.lv-cta-sub {
29752- color: #6b7080;
29753- font-size: 17px;
29754- margin: 16px 0 30px;
29755- position: relative;
29756-}
29757-
29758-.lv-cta-actions {
29759- display: flex;
29760- gap: 12px;
29761- justify-content: center;
29762- flex-wrap: wrap;
29763- position: relative;
29764-}
29765-
29766-.lv-cta-fine {
29767- margin-top: 20px;
29768- font-family: 'JetBrains Mono', monospace;
29769- font-size: 11px;
29770- color: #8a8d99;
29771- position: relative;
29772-}
29773-
29774-/* Footer */
29775-.lv-footer {
29776- border-top: 1px solid rgba(22,24,29,0.07);
29777- background: #ffffff;
29778- padding: 56px 0 30px;
29779-}
29780-
29781-.lv-footer-inner {
29782- max-width: 1200px;
29783- margin: 0 auto;
29784- padding: 0 28px;
29785- display: flex;
29786- gap: 48px;
29787- flex-wrap: wrap;
29788- justify-content: space-between;
29789-}
29790-
29791-.lv-footer-brand {}
29792-
29793-.lv-footer-tagline {
29794- color: #6b7080;
29795- font-size: 13.5px;
29796- margin: 12px 0 0;
29797- max-width: 32ch;
29798- line-height: 1.6;
29799-}
29800-
29801-.lv-footer-cols {
29802- display: flex;
29803- gap: 64px;
29804- flex-wrap: wrap;
29805-}
29806-
29807-.lv-footer-col {
29808- display: flex;
29809- flex-direction: column;
29810- gap: 9px;
29811-}
29812-
29813-.lv-footer-col-head {
29814- font-family: 'JetBrains Mono', monospace;
29815- font-size: 11px;
29816- text-transform: uppercase;
29817- letter-spacing: 0.1em;
29818- color: #8a8d99;
29819- margin: 0 0 4px;
29820- font-weight: 500;
29821-}
29822-
29823-.lv-footer-link {
29824- color: #3a3d45;
29825- font-size: 13.5px;
29826- text-decoration: none;
29827- transition: color 0.15s;
29828-}
29829-.lv-footer-link:hover { color: #16181d; }
29830-
29831-.lv-footer-bar {
29832- max-width: 1200px;
29833- margin: 44px auto 0;
29834- padding: 22px 28px 0;
29835- border-top: 1px solid rgba(22,24,29,0.06);
29836- display: flex;
29837- justify-content: space-between;
29838- flex-wrap: wrap;
29839- gap: 8px;
29840- color: #8a8d99;
29841- font-size: 12.5px;
29842-}
29843-
29844-.lv-footer-stack {
29845- font-family: 'JetBrains Mono', monospace;
29846- font-size: 11px;
29847-}
29848-`;
29849diff --git a/src/views/layout.tsx b/src/views/layout.tsx
29850index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
29851--- a/src/views/layout.tsx
29852+++ b/src/views/layout.tsx
29853@@ -3153,9 +3153,12 @@
29854 font-weight: 500;
29855 line-height: 1.4;
29856 }
29857- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
29858- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
29859- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
29860+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
29861+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
29862+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
29863+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
29864+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
29865+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
29866 .state-merged { color: var(--accent); }
29867 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
29868
29869diff --git a/src/views/ui.tsx b/src/views/ui.tsx
29870index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
29871--- a/src/views/ui.tsx
29872+++ b/src/views/ui.tsx
29873@@ -232,7 +232,7 @@
29874
29875 export const Badge: FC<
29876 PropsWithChildren<{
29877- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
29878+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
29879 style?: string;
29880 }>
29881 > = ({ children, variant = "default", style }) => {
29882@@ -241,9 +241,12 @@
29883 variant === "closed" ? "badge-closed" :
29884 variant === "merged" ? "badge-merged" :
29885 variant === "success" ? "badge-success" :
29886- variant === "danger" ? "badge-danger" :
29887- variant === "warning" ? "badge-warning" :
29888- "badge";
29889+ variant === "danger" ? "badge-danger" :
29890+ variant === "warning" ? "badge-warning" :
29891+ variant === "live" ? "badge-live" :
29892+ variant === "soon" ? "badge-soon" :
29893+ variant === "preview" ? "badge-preview" :
29894+ "badge";
29895 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
29896 };
29897
29898
29899diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
29900index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
29901--- a/src/views/landing-pro.tsx
29902+++ b/src/views/landing-pro.tsx
29903@@ -42,7 +42,7 @@
29904
29905 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29906
29907-function icon(paths: string, color = "#4353c9", size = 20) {
29908+function icon(paths: string, color = "#0891b2", size = 20) {
29909 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
29910 }
29911
29912@@ -947,7 +947,7 @@
29913 const css = `
29914 /* %% tokens %% */
29915 :root{
29916- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
29917+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
29918 --lp-bg:#ffffff;--lp-soft:#fafafb;
29919 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
29920 --lp-border:rgba(0,0,0,.08);
29921diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
29922deleted file mode 100644
29923index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
29924--- a/src/views/landing-v2.tsx
29925+++ /dev/null
29926@@ -1,1447 +0,0 @@
29927-import type { FC } from "hono/jsx";
29928-
29929-export interface LandingPageProps {
29930- stats?: {
29931- publicRepos?: number;
29932- users?: number;
29933- };
29934-}
29935-
29936-const demoAllEvents = [
29937- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
29938- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
29939- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
29940- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
29941- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
29942-];
29943-
29944-const tickerItems = [
29945- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
29946- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
29947- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
29948- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
29949- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
29950- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
29951- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
29952- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
29953- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
29954- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
29955- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
29956- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
29957- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
29958- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
29959- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
29960- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
29961-];
29962-
29963-const stageData = [
29964- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
29965- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
29966- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
29967- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
29968- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
29969- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
29970-];
29971-
29972-const heroFeatures = [
29973- {
29974- href: "/",
29975- eyebrow: "01 � The autonomous repair loop",
29976- title: "Failures fix themselves  and show their work.",
29977- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
29978failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
29979- cta: "Watch a live repair session",
29980- mock: [
29981- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
29982- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
29983- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
29984- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
29985- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
29986- ],
29987- },
29988- {
29989- href: "/",
29990- eyebrow: "02 � Live sandbox isolation",
29991- title: "Every PR gets its own instant, disposable environment.",
29992- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
29993same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
29994- cta: "See a PR with its sandbox",
29995- mock: [
29996- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
29997- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
29998- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
29999- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
30000- ],
30001- },
30002- {
30003- href: "/",
30004- eyebrow: "03 � Multiplayer IDE workspaces",
30005- title: "You and the agent, side by side, in your editor.",
30006- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
30007agent into a silent reviewer in your gutter. The browser becomes optional.",
30008- cta: "See the editor session",
30009- mock: [
30010- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
30011- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
30012- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
30013- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
30014- ],
30015- },
30016-];
30017-
30018-const capabilities = [
30019- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
30020- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
30021- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
30022- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
30023- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
30024- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
30025- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
30026- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
30027-];
30028-
30029-const sovereignLayerNames = [
30030- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
30031- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
30032- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
30033- "Availability & recovery",
30034-];
30035-
30036-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
30037- return (
30038- <>
30039- <style dangerouslySetInnerHTML={{ __html: css }} />
30040-
30041- {/* Nav */}
30042- <header class="lv-nav">
30043- <div class="lv-nav-inner">
30044- <a href="/" class="lv-logo">
30045- <span class="lv-logo-mark"></span>gluecron
30046- </a>
30047- <nav class="lv-nav-links">
30048- <a href="#loop" class="lv-nav-link">The loop</a>
30049- <a href="#platform" class="lv-nav-link">Platform</a>
30050- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
30051- <a href="/trust" class="lv-nav-link">Trust</a>
30052- </nav>
30053- <div class="lv-nav-ctas">
30054- <a href="/login" class="lv-btn-secondary">Sign in</a>
30055- <a href="/register" class="lv-btn-primary">Start building</a>
30056- </div>
30057- </div>
30058- </header>
30059-
30060- {/* Hero */}
30061- <section class="lv-hero">
30062- <div class="lv-hero-glow"></div>
30063- <div class="lv-hero-inner">
30064- <div class="lv-hero-badge">
30065- <span class="lv-dot lv-dot-green lv-pulse"></span>
30066- Live: a repair loop converged on pr-218 while you read this
30067- </div>
30068- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
30069- <p class="lv-hero-sub">
30070- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
30071failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
30072- </p>
30073- <div class="lv-hero-actions">
30074- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
30075- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
30076- </div>
30077- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
30078-
30079- {/* Live product window */}
30080- <div class="lv-demo-window">
30081- <div class="lv-demo-bar">
30082- <span class="lv-demo-dot"></span>
30083- <span class="lv-demo-dot"></span>
30084- <span class="lv-demo-dot"></span>
30085- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
30086- <span class="lv-demo-live">
30087- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
30088- LIVE
30089- </span>
30090- </div>
30091- <div class="lv-demo-body" id="lv-demo-body">
30092- {/* Events rendered by JS */}
30093- {demoAllEvents.slice(0, 1).map((e, i) => (
30094- <div class="lv-demo-event" key={i}>
30095- <div class="lv-demo-event-track">
30096- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
30097- <span class="lv-demo-line" style="display:none"></span>
30098- </div>
30099- <div class="lv-demo-event-content">
30100- <div class="lv-demo-event-header">
30101- <span class="lv-demo-event-title">{e.title}</span>
30102- <span class="lv-demo-event-time">{e.time}</span>
30103- </div>
30104- <div class="lv-demo-event-body">{e.body}</div>
30105- </div>
30106- </div>
30107- ))}
30108- </div>
30109- </div>
30110- </div>
30111-
30112- {/* Activity ticker */}
30113- <div class="lv-ticker-wrap">
30114- <div class="lv-ticker-track">
30115- {tickerItems.map((t, i) => (
30116- <span class="lv-ticker-item" key={i}>
30117- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
30118- {t.text}
30119- </span>
30120- ))}
30121- </div>
30122- </div>
30123- </section>
30124-
30125- {/* Stat band */}
30126- <section class="lv-stats">
30127- <div class="lv-stats-inner">
30128- <div class="lv-stat">
30129- <div class="lv-stat-num">Sonnet 5</div>
30130- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
30131- </div>
30132- <div class="lv-stat">
30133- <div class="lv-stat-num">93.5%</div>
30134- <div class="lv-stat-label">of failures self-repair without a human</div>
30135- </div>
30136- <div class="lv-stat">
30137- <div class="lv-stat-num">1.9%</div>
30138- <div class="lv-stat-label">AI merges reverted  published live</div>
30139- </div>
30140- <div class="lv-stat">
30141- <div class="lv-stat-num">0</div>
30142- <div class="lv-stat-label">irreversible actions taken autonomously</div>
30143- </div>
30144- </div>
30145- </section>
30146-
30147- {/* The loop */}
30148- <section id="loop" class="lv-loop">
30149- <div class="lv-loop-inner">
30150- <div class="lv-section-header">
30151- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
30152- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
30153- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
30154- </div>
30155- <div class="lv-stages" id="lv-stages">
30156- {stageData.map((s, i) => (
30157- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
30158- <div class="lv-stage-header">
30159- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
30160- <span class="lv-stage-n">0{i + 1}</span>
30161- </div>
30162- <div class="lv-stage-name">{s.name}</div>
30163- <div class="lv-stage-desc">{s.desc}</div>
30164- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
30165- </div>
30166- ))}
30167- </div>
30168- </div>
30169- </section>
30170-
30171- {/* Three heroes */}
30172- <section class="lv-heroes">
30173- <div class="lv-heroes-inner">
30174- <div class="lv-heroes-header">
30175- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
30176- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
30177- </div>
30178- <div class="lv-heroes-list">
30179- {heroFeatures.map((h, i) => (
30180- <a href={h.href} class="lv-hero-card" key={i}>
30181- <div class="lv-hero-card-left">
30182- <div class="lv-eyebrow">{h.eyebrow}</div>
30183- <h3 class="lv-hero-card-title">{h.title}</h3>
30184- <p class="lv-hero-card-body">{h.body}</p>
30185- <span class="lv-hero-card-cta">{h.cta} �!</span>
30186- </div>
30187- <div class="lv-terminal">
30188- {h.mock.map((m, j) => (
30189- <div class="lv-terminal-line" key={j}>
30190- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
30191- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
30192- </div>
30193- ))}
30194- </div>
30195- </a>
30196- ))}
30197- </div>
30198- </div>
30199- </section>
30200-
30201- {/* Everything grid */}
30202- <section id="platform" class="lv-platform">
30203- <div class="lv-platform-inner">
30204- <div class="lv-section-header lv-section-header-center">
30205- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
30206- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
30207- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
30208- </div>
30209- <div class="lv-cap-grid">
30210- {capabilities.map((c, i) => (
30211- <div class="lv-cap-col" key={i}>
30212- <div class="lv-cap-group">{c.group}</div>
30213- <div class="lv-cap-items">
30214- {c.items.map((item, j) => (
30215- <div class="lv-cap-item" key={j}>{item}</div>
30216- ))}
30217- </div>
30218- </div>
30219- ))}
30220- </div>
30221- </div>
30222- </section>
30223-
30224- {/* Sovereignty band */}
30225- <section id="sovereign" class="lv-sovereign">
30226- <div class="lv-sovereign-grid-bg"></div>
30227- <div class="lv-sovereign-inner">
30228- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
30229- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
30230- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
30231- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
30232to private cloud, or run fully air-gapped on bare metal.</p>
30233- </div>
30234- <div class="lv-layers-grid">
30235- {sovereignLayerNames.map((name, i) => (
30236- <div class="lv-layer-chip" key={i}>
30237- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
30238- <div class="lv-layer-name">{name}</div>
30239- </div>
30240- ))}
30241- <a href="/" class="lv-layer-chip lv-layer-cta">
30242- <div class="lv-layer-cta-text">All self-owned �!</div>
30243- </a>
30244- </div>
30245- <div class="lv-sovereign-feats">
30246- <div class="lv-sovereign-feat">
30247- <div class="lv-sovereign-feat-title">Local inference first</div>
30248- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
30249- </div>
30250- <div class="lv-sovereign-feat">
30251- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
30252- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
30253- </div>
30254- <div class="lv-sovereign-feat">
30255- <div class="lv-sovereign-feat-title">Self-healing infra</div>
30256- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
30257- </div>
30258- </div>
30259- </div>
30260- </section>
30261-
30262- {/* Manual-first + reversibility */}
30263- <section class="lv-twin">
30264- <div class="lv-twin-inner">
30265- <div class="lv-twin-card">
30266- <div class="lv-eyebrow">Manual-first, always</div>
30267- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
30268- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
30269fallback. Developers who never touch AI get the best git host they've ever used.</p>
30270- </div>
30271- <div class="lv-twin-card">
30272- <div class="lv-eyebrow">The reversibility guarantee</div>
30273- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
30274- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
30275 policy, not promise. Our quality numbers are published live, unedited.</p>
30276- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
30277- </div>
30278- </div>
30279- </section>
30280-
30281- {/* Quote */}
30282- <section class="lv-quote">
30283- <div class="lv-quote-inner">
30284- <p class="lv-quote-text">
30285- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
30286- Gluecron is where code gets <em class="lv-em">finished</em>."
30287- </p>
30288- </div>
30289- </section>
30290-
30291- {/* CTA */}
30292- <section class="lv-cta-section">
30293- <div class="lv-cta-card">
30294- <div class="lv-cta-glow"></div>
30295- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
30296- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
30297- <div class="lv-cta-actions">
30298- <a href="/register" class="lv-cta-primary">Create your account �!</a>
30299- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
30300- </div>
30301- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
30302- </div>
30303- </section>
30304-
30305- {/* Footer */}
30306- <footer class="lv-footer">
30307- <div class="lv-footer-inner">
30308- <div class="lv-footer-brand">
30309- <a href="/" class="lv-logo">
30310- <span class="lv-logo-mark"></span>gluecron
30311- </a>
30312- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
30313- </div>
30314- <div class="lv-footer-cols">
30315- <div class="lv-footer-col">
30316- <h4 class="lv-footer-col-head">Product</h4>
30317- <a href="/" class="lv-footer-link">Agent workspace</a>
30318- <a href="/" class="lv-footer-link">Fleet refactors</a>
30319- <a href="/" class="lv-footer-link">Org memory</a>
30320- <a href="/" class="lv-footer-link">IDE extensions</a>
30321- </div>
30322- <div class="lv-footer-col">
30323- <h4 class="lv-footer-col-head">Platform</h4>
30324- <a href="/" class="lv-footer-link">Production layers</a>
30325- <a href="/trust" class="lv-footer-link">Trust report</a>
30326- <a href="/" class="lv-footer-link">Docs</a>
30327- <a href="/" class="lv-footer-link">Status</a>
30328- </div>
30329- <div class="lv-footer-col">
30330- <h4 class="lv-footer-col-head">Company</h4>
30331- <a href="/" class="lv-footer-link">About</a>
30332- <a href="/" class="lv-footer-link">Pricing</a>
30333- <a href="/" class="lv-footer-link">Enterprise</a>
30334- </div>
30335- </div>
30336- </div>
30337- <div class="lv-footer-bar">
30338- <span>� 2026 Gluecron</span>
30339- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
30340- </div>
30341- </footer>
30342-
30343- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
30344- </>
30345- );
30346-};
30347-
30348-export const LandingPage = LandingPageV2;
30349-export default LandingPageV2;
30350-
30351-const clientScript = `
30352-(function() {
30353- var demoAll = [
30354- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
30355- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
30356- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
30357- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
30358- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
30359- ];
30360-
30361- var demoStep = 0;
30362- var stage = 0;
30363-
30364- function renderDemo() {
30365- var container = document.getElementById('lv-demo-body');
30366- if (!container) return;
30367- var visible = demoAll.slice(0, demoStep + 1);
30368- container.innerHTML = visible.map(function(e, i) {
30369- var isLast = i === visible.length - 1;
30370- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
30371- return '<div class="lv-demo-event">' +
30372- '<div class="lv-demo-event-track">' +
30373- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
30374- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
30375- '</div>' +
30376- '<div class="lv-demo-event-content">' +
30377- '<div class="lv-demo-event-header">' +
30378- '<span class="lv-demo-event-title">' + e.title + '</span>' +
30379- '<span class="lv-demo-event-time">' + e.time + '</span>' +
30380- '</div>' +
30381- '<div class="lv-demo-event-body">' + e.body + '</div>' +
30382- '</div>' +
30383- '</div>';
30384- }).join('');
30385- }
30386-
30387- function renderStages() {
30388- var cards = document.querySelectorAll('.lv-stage-card');
30389- cards.forEach(function(card, i) {
30390- var dot = card.querySelector('.lv-dot');
30391- var meta = card.querySelector('.lv-stage-meta');
30392- if (i === stage) {
30393- card.classList.add('lv-stage-active');
30394- if (dot) {
30395- dot.classList.remove('lv-dot-idle');
30396- dot.classList.add('lv-dot-indigo', 'lv-pulse');
30397- }
30398- if (meta) meta.classList.add('lv-stage-meta-active');
30399- } else {
30400- card.classList.remove('lv-stage-active');
30401- if (dot) {
30402- dot.classList.add('lv-dot-idle');
30403- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
30404- }
30405- if (meta) meta.classList.remove('lv-stage-meta-active');
30406- }
30407- });
30408- }
30409-
30410- renderDemo();
30411-
30412- setInterval(function() {
30413- demoStep = (demoStep + 1) % 5;
30414- renderDemo();
30415- }, 3600);
30416-
30417- setInterval(function() {
30418- stage = (stage + 1) % 6;
30419- renderStages();
30420- }, 2200);
30421-})();
30422-`;
30423-
30424-const css = `
30425-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
30426-
30427-*, *::before, *::after { box-sizing: border-box; }
30428-
30429-body {
30430- margin: 0;
30431- background: #fcfcfd;
30432- -webkit-font-smoothing: antialiased;
30433- text-rendering: optimizeLegibility;
30434- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
30435- font-size: 15px;
30436- line-height: 1.6;
30437- letter-spacing: -0.008em;
30438- color: #16181d;
30439-}
30440-
30441-@keyframes gcPulse {
30442- 0%, 100% { opacity: 1; }
30443- 50% { opacity: 0.35; }
30444-}
30445-
30446-@keyframes gcTicker {
30447- 0% { transform: translateX(0); }
30448- 100% { transform: translateX(-50%); }
30449-}
30450-
30451-/* Shared utilities */
30452-.lv-dot {
30453- display: inline-block;
30454- border-radius: 50%;
30455-}
30456-.lv-dot-green { background: #1e7f5c; }
30457-.lv-dot-indigo { background: #4353c9; }
30458-.lv-dot-idle { background: #c4c6cf; }
30459-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
30460-
30461-.lv-strong { color: #16181d; font-weight: 600; }
30462-
30463-.lv-eyebrow {
30464- font-family: 'JetBrains Mono', monospace;
30465- font-size: 11px;
30466- letter-spacing: 0.12em;
30467- text-transform: uppercase;
30468- color: #8a8d99;
30469- font-weight: 500;
30470- margin-bottom: 12px;
30471-}
30472-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
30473-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
30474-
30475-.lv-h1 {
30476- font-family: 'Inter Tight', sans-serif;
30477- font-weight: 700;
30478- letter-spacing: -0.035em;
30479- font-size: clamp(44px, 7vw, 84px);
30480- line-height: 0.98;
30481- margin: 30px auto 0;
30482- max-width: 14ch;
30483- color: #111318;
30484-}
30485-
30486-.lv-h2 {
30487- font-family: 'Inter Tight', sans-serif;
30488- font-weight: 700;
30489- letter-spacing: -0.028em;
30490- font-size: clamp(30px, 4.4vw, 48px);
30491- line-height: 1.05;
30492- margin: 0;
30493- color: #111318;
30494-}
30495-
30496-.lv-h2-dark {
30497- font-family: 'Inter Tight', sans-serif;
30498- font-weight: 700;
30499- letter-spacing: -0.028em;
30500- font-size: clamp(30px, 4.6vw, 52px);
30501- line-height: 1.05;
30502- margin: 0;
30503- color: #fff;
30504-}
30505-
30506-.lv-section-header {
30507- max-width: 640px;
30508- margin: 0 auto 56px;
30509-}
30510-
30511-.lv-section-header-center {
30512- text-align: center;
30513-}
30514-
30515-.lv-section-sub {
30516- color: #6b7080;
30517- font-size: 17px;
30518- margin: 18px auto 0;
30519- max-width: 52ch;
30520-}
30521-
30522-.lv-section-sub-dark {
30523- color: rgba(255,255,255,0.72);
30524- font-size: 17px;
30525- margin: 18px auto 0;
30526- max-width: 56ch;
30527-}
30528-
30529-/* Nav */
30530-.lv-nav {
30531- position: sticky;
30532- top: 0;
30533- z-index: 60;
30534- backdrop-filter: saturate(180%) blur(14px);
30535- -webkit-backdrop-filter: saturate(180%) blur(14px);
30536- background: rgba(252,252,253,0.8);
30537- border-bottom: 1px solid rgba(22,24,29,0.07);
30538-}
30539-
30540-.lv-nav-inner {
30541- max-width: 1200px;
30542- margin: 0 auto;
30543- padding: 14px 28px;
30544- display: flex;
30545- align-items: center;
30546- gap: 28px;
30547-}
30548-
30549-.lv-logo {
30550- display: inline-flex;
30551- align-items: center;
30552- gap: 9px;
30553- font-family: 'Inter Tight', sans-serif;
30554- font-weight: 700;
30555- font-size: 17px;
30556- letter-spacing: -0.02em;
30557- color: #16181d;
30558- text-decoration: none;
30559-}
30560-
30561-.lv-logo-mark {
30562- width: 17px;
30563- height: 17px;
30564- border-radius: 5px;
30565- background: #4353c9;
30566- display: inline-block;
30567- flex-shrink: 0;
30568-}
30569-
30570-.lv-nav-links {
30571- display: flex;
30572- gap: 24px;
30573- font-size: 13.5px;
30574- font-weight: 500;
30575-}
30576-
30577-.lv-nav-link {
30578- color: #6b7080;
30579- text-decoration: none;
30580- transition: color 0.15s;
30581-}
30582-.lv-nav-link:hover { color: #16181d; }
30583-
30584-.lv-nav-ctas {
30585- margin-left: auto;
30586- display: flex;
30587- align-items: center;
30588- gap: 10px;
30589-}
30590-
30591-.lv-btn-secondary {
30592- padding: 8px 15px;
30593- border-radius: 8px;
30594- font-size: 13.5px;
30595- font-weight: 500;
30596- color: #16181d;
30597- border: 1px solid rgba(22,24,29,0.12);
30598- background: #ffffff;
30599- text-decoration: none;
30600- white-space: nowrap;
30601- transition: border-color 0.15s;
30602-}
30603-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
30604-
30605-.lv-btn-primary {
30606- padding: 8px 15px;
30607- border-radius: 8px;
30608- font-size: 13.5px;
30609- font-weight: 600;
30610- background: #16181d;
30611- color: #fff;
30612- text-decoration: none;
30613- white-space: nowrap;
30614- transition: box-shadow 0.15s;
30615-}
30616-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
30617-
30618-/* Hero */
30619-.lv-hero {
30620- position: relative;
30621- overflow: hidden;
30622- padding: 88px 0 0;
30623-}
30624-
30625-.lv-hero-glow {
30626- position: absolute;
30627- inset: -10% 0 auto 0;
30628- height: 640px;
30629- pointer-events: none;
30630- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
30631-}
30632-
30633-.lv-hero-inner {
30634- position: relative;
30635- max-width: 1200px;
30636- margin: 0 auto;
30637- padding: 0 28px;
30638- text-align: center;
30639-}
30640-
30641-.lv-hero-badge {
30642- display: inline-flex;
30643- align-items: center;
30644- gap: 9px;
30645- font-size: 12.5px;
30646- font-weight: 600;
30647- color: #3a3d45;
30648- background: #ffffff;
30649- border: 1px solid rgba(22,24,29,0.10);
30650- border-radius: 9999px;
30651- padding: 7px 16px;
30652- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
30653-}
30654-
30655-.lv-hero-sub {
30656- font-size: clamp(16px, 2vw, 19px);
30657- color: #6b7080;
30658- max-width: 60ch;
30659- margin: 24px auto 0;
30660- font-weight: 450;
30661- line-height: 1.65;
30662-}
30663-
30664-.lv-hero-actions {
30665- display: flex;
30666- gap: 12px;
30667- justify-content: center;
30668- flex-wrap: wrap;
30669- margin-top: 32px;
30670-}
30671-
30672-.lv-cta-primary {
30673- padding: 13px 24px;
30674- border-radius: 11px;
30675- font-size: 15.5px;
30676- font-weight: 600;
30677- background: #16181d;
30678- color: #fff;
30679- text-decoration: none;
30680- white-space: nowrap;
30681- transition: box-shadow 0.15s;
30682-}
30683-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
30684-
30685-.lv-cta-secondary {
30686- padding: 13px 24px;
30687- border-radius: 11px;
30688- font-size: 15.5px;
30689- font-weight: 600;
30690- color: #16181d;
30691- border: 1px solid rgba(22,24,29,0.14);
30692- background: #ffffff;
30693- text-decoration: none;
30694- white-space: nowrap;
30695- transition: border-color 0.15s;
30696-}
30697-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
30698-
30699-.lv-hero-tag {
30700- margin-top: 18px;
30701- font-family: 'JetBrains Mono', monospace;
30702- font-size: 11.5px;
30703- letter-spacing: 0.08em;
30704- text-transform: uppercase;
30705- color: #8a8d99;
30706-}
30707-
30708-/* Demo window */
30709-.lv-demo-window {
30710- margin: 56px auto 0;
30711- max-width: 860px;
30712- text-align: left;
30713- background: #ffffff;
30714- border: 1px solid rgba(22,24,29,0.09);
30715- border-radius: 18px;
30716- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
30717- overflow: hidden;
30718-}
30719-
30720-.lv-demo-bar {
30721- display: flex;
30722- align-items: center;
30723- gap: 7px;
30724- padding: 12px 18px;
30725- border-bottom: 1px solid rgba(22,24,29,0.07);
30726- background: #fcfcfd;
30727-}
30728-
30729-.lv-demo-dot {
30730- width: 10px;
30731- height: 10px;
30732- border-radius: 50%;
30733- background: #e4e5ea;
30734-}
30735-
30736-.lv-demo-url {
30737- margin-left: 10px;
30738- font-family: 'JetBrains Mono', monospace;
30739- font-size: 12px;
30740- color: #6b7080;
30741-}
30742-
30743-.lv-demo-live {
30744- margin-left: auto;
30745- display: inline-flex;
30746- align-items: center;
30747- gap: 6px;
30748- font-size: 11px;
30749- font-weight: 600;
30750- color: #1e7f5c;
30751-}
30752-
30753-.lv-demo-body {
30754- padding: 22px 24px;
30755-}
30756-
30757-.lv-demo-event {
30758- display: grid;
30759- grid-template-columns: 18px minmax(0, 1fr);
30760- gap: 14px;
30761- padding-bottom: 20px;
30762- position: relative;
30763-}
30764-.lv-demo-event:last-child { padding-bottom: 0; }
30765-
30766-.lv-demo-event-track {
30767- display: flex;
30768- flex-direction: column;
30769- align-items: center;
30770-}
30771-
30772-.lv-demo-line {
30773- width: 1px;
30774- flex: 1;
30775- background: rgba(22,24,29,0.08);
30776- margin-top: 5px;
30777- min-height: 20px;
30778-}
30779-
30780-.lv-demo-event-content {}
30781-
30782-.lv-demo-event-header {
30783- display: flex;
30784- align-items: baseline;
30785- gap: 10px;
30786-}
30787-
30788-.lv-demo-event-title {
30789- font-size: 13.5px;
30790- font-weight: 600;
30791- color: #16181d;
30792-}
30793-
30794-.lv-demo-event-time {
30795- font-family: 'JetBrains Mono', monospace;
30796- font-size: 11px;
30797- color: #8a8d99;
30798-}
30799-
30800-.lv-demo-event-body {
30801- font-size: 13px;
30802- color: #6b7080;
30803- margin-top: 2px;
30804-}
30805-
30806-/* Ticker */
30807-.lv-ticker-wrap {
30808- border-top: 1px solid rgba(22,24,29,0.07);
30809- border-bottom: 1px solid rgba(22,24,29,0.07);
30810- background: #ffffff;
30811- margin-top: 64px;
30812- overflow: hidden;
30813- white-space: nowrap;
30814- position: relative;
30815-}
30816-
30817-.lv-ticker-track {
30818- display: inline-flex;
30819- animation: gcTicker 40s linear infinite;
30820- padding: 11px 0;
30821-}
30822-
30823-.lv-ticker-item {
30824- display: inline-flex;
30825- align-items: center;
30826- gap: 8px;
30827- font-family: 'JetBrains Mono', monospace;
30828- font-size: 11.5px;
30829- color: #6b7080;
30830- padding: 0 28px;
30831- border-right: 1px solid rgba(22,24,29,0.06);
30832-}
30833-
30834-/* Stats */
30835-.lv-stats {
30836- background: #fcfcfd;
30837-}
30838-
30839-.lv-stats-inner {
30840- max-width: 1200px;
30841- margin: 0 auto;
30842- display: grid;
30843- grid-template-columns: repeat(4, 1fr);
30844- gap: 24px;
30845- padding: 52px 28px;
30846-}
30847-
30848-.lv-stat {
30849- text-align: center;
30850-}
30851-
30852-.lv-stat-num {
30853- font-family: 'Inter Tight', sans-serif;
30854- font-weight: 700;
30855- font-size: clamp(30px, 4vw, 44px);
30856- letter-spacing: -0.025em;
30857- color: #111318;
30858-}
30859-
30860-.lv-stat-label {
30861- font-size: 13px;
30862- color: #6b7080;
30863- margin-top: 4px;
30864-}
30865-
30866-/* Loop */
30867-.lv-loop {
30868- padding: 96px 0;
30869- background: #ffffff;
30870- border-top: 1px solid rgba(22,24,29,0.07);
30871- border-bottom: 1px solid rgba(22,24,29,0.07);
30872-}
30873-
30874-.lv-loop-inner {
30875- max-width: 1200px;
30876- margin: 0 auto;
30877- padding: 0 28px;
30878-}
30879-
30880-.lv-stages {
30881- display: grid;
30882- grid-template-columns: repeat(6, 1fr);
30883- gap: 12px;
30884-}
30885-
30886-.lv-stage-card {
30887- border: 1px solid rgba(22,24,29,0.08);
30888- border-radius: 14px;
30889- background: #ffffff;
30890- padding: 20px 18px;
30891- transition: border-color 0.3s, background 0.3s;
30892-}
30893-
30894-.lv-stage-card.lv-stage-active {
30895- border-color: rgba(67,83,201,0.45);
30896- background: rgba(67,83,201,0.03);
30897-}
30898-
30899-.lv-stage-header {
30900- display: flex;
30901- align-items: center;
30902- gap: 8px;
30903- margin-bottom: 10px;
30904-}
30905-
30906-.lv-stage-n {
30907- font-family: 'JetBrains Mono', monospace;
30908- font-size: 10.5px;
30909- letter-spacing: 0.1em;
30910- text-transform: uppercase;
30911- color: #8a8d99;
30912-}
30913-
30914-.lv-stage-name {
30915- font-family: 'Inter Tight', sans-serif;
30916- font-size: 16px;
30917- font-weight: 600;
30918- letter-spacing: -0.01em;
30919- color: #16181d;
30920- margin-bottom: 5px;
30921-}
30922-
30923-.lv-stage-desc {
30924- font-size: 12px;
30925- color: #6b7080;
30926- line-height: 1.55;
30927-}
30928-
30929-.lv-stage-meta {
30930- font-family: 'JetBrains Mono', monospace;
30931- font-size: 10.5px;
30932- color: #8a8d99;
30933- margin-top: 10px;
30934- transition: color 0.3s;
30935-}
30936-
30937-.lv-stage-meta.lv-stage-meta-active {
30938- color: #4353c9;
30939-}
30940-
30941-/* Heroes */
30942-.lv-heroes {
30943- padding: 96px 0;
30944- background: #fcfcfd;
30945-}
30946-
30947-.lv-heroes-inner {
30948- max-width: 1200px;
30949- margin: 0 auto;
30950- padding: 0 28px;
30951-}
30952-
30953-.lv-heroes-header {
30954- max-width: 640px;
30955- margin-bottom: 56px;
30956-}
30957-
30958-.lv-heroes-list {
30959- display: flex;
30960- flex-direction: column;
30961- gap: 20px;
30962-}
30963-
30964-.lv-hero-card {
30965- display: grid;
30966- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
30967- gap: 48px;
30968- align-items: center;
30969- border: 1px solid rgba(22,24,29,0.08);
30970- border-radius: 20px;
30971- background: #ffffff;
30972- padding: 44px 48px;
30973- text-decoration: none;
30974- transition: border-color 0.2s, box-shadow 0.2s;
30975-}
30976-.lv-hero-card:hover {
30977- border-color: rgba(22,24,29,0.22);
30978- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
30979-}
30980-
30981-.lv-hero-card-left {}
30982-
30983-.lv-hero-card-title {
30984- font-family: 'Inter Tight', sans-serif;
30985- font-size: 26px;
30986- font-weight: 600;
30987- letter-spacing: -0.022em;
30988- line-height: 1.15;
30989- color: #16181d;
30990- margin: 0 0 12px;
30991-}
30992-
30993-.lv-hero-card-body {
30994- font-size: 14.5px;
30995- color: #6b7080;
30996- margin: 0 0 18px;
30997- line-height: 1.65;
30998-}
30999-
31000-.lv-hero-card-cta {
31001- font-size: 13.5px;
31002- font-weight: 600;
31003- color: #4353c9;
31004-}
31005-
31006-.lv-terminal {
31007- border: 1px solid rgba(22,24,29,0.07);
31008- border-radius: 14px;
31009- background: #fcfcfd;
31010- padding: 20px 22px;
31011- font-family: 'JetBrains Mono', monospace;
31012- font-size: 12px;
31013- line-height: 1.9;
31014- overflow: hidden;
31015-}
31016-
31017-.lv-terminal-line {
31018- display: flex;
31019- align-items: center;
31020- gap: 10px;
31021- white-space: nowrap;
31022- overflow: hidden;
31023- text-overflow: ellipsis;
31024-}
31025-
31026-/* Platform */
31027-.lv-platform {
31028- padding: 96px 0;
31029- background: #ffffff;
31030- border-top: 1px solid rgba(22,24,29,0.07);
31031-}
31032-
31033-.lv-platform-inner {
31034- max-width: 1200px;
31035- margin: 0 auto;
31036- padding: 0 28px;
31037-}
31038-
31039-.lv-cap-grid {
31040- display: grid;
31041- grid-template-columns: repeat(4, 1fr);
31042- gap: 24px 32px;
31043-}
31044-
31045-.lv-cap-col {}
31046-
31047-.lv-cap-group {
31048- font-family: 'JetBrains Mono', monospace;
31049- font-size: 10.5px;
31050- letter-spacing: 0.12em;
31051- text-transform: uppercase;
31052- color: #8a8d99;
31053- font-weight: 500;
31054- margin-bottom: 12px;
31055- padding-bottom: 8px;
31056- border-bottom: 1px solid rgba(22,24,29,0.07);
31057-}
31058-
31059-.lv-cap-items {
31060- display: flex;
31061- flex-direction: column;
31062- gap: 7px;
31063-}
31064-
31065-.lv-cap-item {
31066- font-size: 12.5px;
31067- color: #3a3d45;
31068- line-height: 1.45;
31069-}
31070-
31071-/* Sovereignty */
31072-.lv-sovereign {
31073- position: relative;
31074- overflow: hidden;
31075- padding: 104px 0;
31076- color: #fff;
31077- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
31078-}
31079-
31080-.lv-sovereign-grid-bg {
31081- position: absolute;
31082- inset: 0;
31083- opacity: 0.4;
31084- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
31085- background-size: 56px 56px;
31086- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
31087- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
31088-}
31089-
31090-.lv-sovereign-inner {
31091- position: relative;
31092- max-width: 1200px;
31093- margin: 0 auto;
31094- padding: 0 28px;
31095-}
31096-
31097-.lv-section-header-dark {
31098- max-width: 680px;
31099- margin: 0 auto 48px;
31100- text-align: center;
31101-}
31102-
31103-.lv-layers-grid {
31104- display: grid;
31105- grid-template-columns: repeat(4, 1fr);
31106- gap: 10px;
31107- max-width: 980px;
31108- margin: 0 auto;
31109-}
31110-
31111-.lv-layer-chip {
31112- border: 1px solid rgba(255,255,255,0.10);
31113- border-radius: 10px;
31114- padding: 12px 16px;
31115- background: rgba(255,255,255,0.03);
31116-}
31117-
31118-.lv-layer-cta {
31119- border-color: rgba(169,180,238,0.30);
31120- background: rgba(169,180,238,0.06);
31121- display: flex;
31122- align-items: center;
31123- text-decoration: none;
31124- transition: background 0.15s;
31125-}
31126-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
31127-
31128-.lv-layer-cta-text {
31129- font-size: 13px;
31130- font-weight: 500;
31131- color: #a9b4ee;
31132-}
31133-
31134-.lv-layer-n {
31135- font-family: 'JetBrains Mono', monospace;
31136- font-size: 10px;
31137- color: rgba(255,255,255,0.4);
31138- margin-bottom: 3px;
31139-}
31140-
31141-.lv-layer-name {
31142- font-size: 13px;
31143- font-weight: 500;
31144- color: rgba(255,255,255,0.92);
31145-}
31146-
31147-.lv-sovereign-feats {
31148- display: flex;
31149- gap: 44px;
31150- justify-content: center;
31151- flex-wrap: wrap;
31152- margin-top: 52px;
31153- text-align: center;
31154-}
31155-
31156-.lv-sovereign-feat {}
31157-
31158-.lv-sovereign-feat-title {
31159- font-family: 'Inter Tight', sans-serif;
31160- font-size: 20px;
31161- font-weight: 700;
31162- color: #fff;
31163-}
31164-
31165-.lv-sovereign-feat-sub {
31166- color: rgba(255,255,255,0.55);
31167- font-size: 13px;
31168- margin-top: 2px;
31169-}
31170-
31171-/* Twin cards */
31172-.lv-twin {
31173- padding: 96px 0;
31174- background: #fcfcfd;
31175-}
31176-
31177-.lv-twin-inner {
31178- max-width: 1200px;
31179- margin: 0 auto;
31180- padding: 0 28px;
31181- display: grid;
31182- grid-template-columns: 1fr 1fr;
31183- gap: 24px;
31184-}
31185-
31186-.lv-twin-card {
31187- border: 1px solid rgba(22,24,29,0.08);
31188- border-radius: 20px;
31189- background: #ffffff;
31190- padding: 44px 48px;
31191-}
31192-
31193-.lv-twin-title {
31194- font-family: 'Inter Tight', sans-serif;
31195- font-size: 24px;
31196- font-weight: 600;
31197- letter-spacing: -0.02em;
31198- line-height: 1.2;
31199- margin: 0 0 12px;
31200- color: #16181d;
31201-}
31202-
31203-.lv-twin-body {
31204- font-size: 14.5px;
31205- color: #6b7080;
31206- margin: 0 0 16px;
31207- line-height: 1.7;
31208-}
31209-
31210-.lv-twin-link {
31211- font-size: 13.5px;
31212- font-weight: 600;
31213- color: #4353c9;
31214- text-decoration: none;
31215-}
31216-.lv-twin-link:hover { text-decoration: underline; }
31217-
31218-/* Quote */
31219-.lv-quote {
31220- padding: 40px 0 96px;
31221- background: #fcfcfd;
31222-}
31223-
31224-.lv-quote-inner {
31225- max-width: 980px;
31226- margin: 0 auto;
31227- padding: 0 28px;
31228- text-align: center;
31229-}
31230-
31231-.lv-quote-text {
31232- font-family: 'Inter Tight', sans-serif;
31233- font-weight: 600;
31234- font-size: clamp(26px, 3.8vw, 42px);
31235- line-height: 1.2;
31236- letter-spacing: -0.025em;
31237- margin: 0;
31238- color: #111318;
31239-}
31240-
31241-.lv-em {
31242- font-style: normal;
31243- color: #4353c9;
31244-}
31245-
31246-/* CTA */
31247-.lv-cta-section {
31248- padding: 0 0 104px;
31249- background: #fcfcfd;
31250-}
31251-
31252-.lv-cta-card {
31253- max-width: 820px;
31254- margin: 0 auto;
31255- padding: 64px 40px;
31256- text-align: center;
31257- background: #ffffff;
31258- border: 1px solid rgba(22,24,29,0.08);
31259- border-radius: 26px;
31260- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
31261- position: relative;
31262- overflow: hidden;
31263-}
31264-
31265-.lv-cta-glow {
31266- position: absolute;
31267- inset: -40% 0 auto 0;
31268- height: 280px;
31269- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
31270- pointer-events: none;
31271-}
31272-
31273-.lv-cta-h2 {
31274- font-family: 'Inter Tight', sans-serif;
31275- font-weight: 700;
31276- letter-spacing: -0.028em;
31277- font-size: clamp(30px, 4.6vw, 48px);
31278- margin: 0;
31279- position: relative;
31280- color: #111318;
31281-}
31282-
31283-.lv-cta-sub {
31284- color: #6b7080;
31285- font-size: 17px;
31286- margin: 16px 0 30px;
31287- position: relative;
31288-}
31289-
31290-.lv-cta-actions {
31291- display: flex;
31292- gap: 12px;
31293- justify-content: center;
31294- flex-wrap: wrap;
31295- position: relative;
31296-}
31297-
31298-.lv-cta-fine {
31299- margin-top: 20px;
31300- font-family: 'JetBrains Mono', monospace;
31301- font-size: 11px;
31302- color: #8a8d99;
31303- position: relative;
31304-}
31305-
31306-/* Footer */
31307-.lv-footer {
31308- border-top: 1px solid rgba(22,24,29,0.07);
31309- background: #ffffff;
31310- padding: 56px 0 30px;
31311-}
31312-
31313-.lv-footer-inner {
31314- max-width: 1200px;
31315- margin: 0 auto;
31316- padding: 0 28px;
31317- display: flex;
31318- gap: 48px;
31319- flex-wrap: wrap;
31320- justify-content: space-between;
31321-}
31322-
31323-.lv-footer-brand {}
31324-
31325-.lv-footer-tagline {
31326- color: #6b7080;
31327- font-size: 13.5px;
31328- margin: 12px 0 0;
31329- max-width: 32ch;
31330- line-height: 1.6;
31331-}
31332-
31333-.lv-footer-cols {
31334- display: flex;
31335- gap: 64px;
31336- flex-wrap: wrap;
31337-}
31338-
31339-.lv-footer-col {
31340- display: flex;
31341- flex-direction: column;
31342- gap: 9px;
31343-}
31344-
31345-.lv-footer-col-head {
31346- font-family: 'JetBrains Mono', monospace;
31347- font-size: 11px;
31348- text-transform: uppercase;
31349- letter-spacing: 0.1em;
31350- color: #8a8d99;
31351- margin: 0 0 4px;
31352- font-weight: 500;
31353-}
31354-
31355-.lv-footer-link {
31356- color: #3a3d45;
31357- font-size: 13.5px;
31358- text-decoration: none;
31359- transition: color 0.15s;
31360-}
31361-.lv-footer-link:hover { color: #16181d; }
31362-
31363-.lv-footer-bar {
31364- max-width: 1200px;
31365- margin: 44px auto 0;
31366- padding: 22px 28px 0;
31367- border-top: 1px solid rgba(22,24,29,0.06);
31368- display: flex;
31369- justify-content: space-between;
31370- flex-wrap: wrap;
31371- gap: 8px;
31372- color: #8a8d99;
31373- font-size: 12.5px;
31374-}
31375-
31376-.lv-footer-stack {
31377- font-family: 'JetBrains Mono', monospace;
31378- font-size: 11px;
31379-}
31380-`;
31381diff --git a/src/views/layout.tsx b/src/views/layout.tsx
31382index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
31383--- a/src/views/layout.tsx
31384+++ b/src/views/layout.tsx
31385@@ -3153,9 +3153,12 @@
31386 font-weight: 500;
31387 line-height: 1.4;
31388 }
31389- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
31390- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
31391- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
31392+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
31393+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
31394+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
31395+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
31396+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
31397+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
31398 .state-merged { color: var(--accent); }
31399 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
31400
31401diff --git a/src/views/ui.tsx b/src/views/ui.tsx
31402index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
31403--- a/src/views/ui.tsx
31404+++ b/src/views/ui.tsx
31405@@ -232,7 +232,7 @@
31406
31407 export const Badge: FC<
31408 PropsWithChildren<{
31409- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
31410+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
31411 style?: string;
31412 }>
31413 > = ({ children, variant = "default", style }) => {
31414@@ -241,9 +241,12 @@
31415 variant === "closed" ? "badge-closed" :
31416 variant === "merged" ? "badge-merged" :
31417 variant === "success" ? "badge-success" :
31418- variant === "danger" ? "badge-danger" :
31419- variant === "warning" ? "badge-warning" :
31420- "badge";
31421+ variant === "danger" ? "badge-danger" :
31422+ variant === "warning" ? "badge-warning" :
31423+ variant === "live" ? "badge-live" :
31424+ variant === "soon" ? "badge-soon" :
31425+ variant === "preview" ? "badge-preview" :
31426+ "badge";
31427 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
31428 };
31429
31430
31431codex
31432Typecheck completed with pre-existing repository-wide errors in unrelated areas (plus the existing `web.tsx` live-feed type mismatch); none point to the changed badge/accent files or deleted module. The full
31433test suite is now running separately.
31434diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
31435index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
31436--- a/src/views/landing-pro.tsx
31437+++ b/src/views/landing-pro.tsx
31438@@ -42,7 +42,7 @@
31439
31440 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31441
31442-function icon(paths: string, color = "#4353c9", size = 20) {
31443+function icon(paths: string, color = "#0891b2", size = 20) {
31444 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
31445 }
31446
31447@@ -947,7 +947,7 @@
31448 const css = `
31449 /* %% tokens %% */
31450 :root{
31451- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
31452+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
31453 --lp-bg:#ffffff;--lp-soft:#fafafb;
31454 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
31455 --lp-border:rgba(0,0,0,.08);
31456diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
31457deleted file mode 100644
31458index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
31459--- a/src/views/landing-v2.tsx
31460+++ /dev/null
31461@@ -1,1447 +0,0 @@
31462-import type { FC } from "hono/jsx";
31463-
31464-export interface LandingPageProps {
31465- stats?: {
31466- publicRepos?: number;
31467- users?: number;
31468- };
31469-}
31470-
31471-const demoAllEvents = [
31472- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
31473- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
31474- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
31475- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
31476- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
31477-];
31478-
31479-const tickerItems = [
31480- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
31481- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
31482- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
31483- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
31484- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
31485- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
31486- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
31487- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
31488- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
31489- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
31490- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
31491- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
31492- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
31493- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
31494- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
31495- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
31496-];
31497-
31498-const stageData = [
31499- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
31500- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
31501- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
31502- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
31503- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
31504- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
31505-];
31506-
31507-const heroFeatures = [
31508- {
31509- href: "/",
31510- eyebrow: "01 � The autonomous repair loop",
31511- title: "Failures fix themselves  and show their work.",
31512- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
31513failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
31514- cta: "Watch a live repair session",
31515- mock: [
31516- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
31517- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
31518- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
31519- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
31520- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
31521- ],
31522- },
31523- {
31524- href: "/",
31525- eyebrow: "02 � Live sandbox isolation",
31526- title: "Every PR gets its own instant, disposable environment.",
31527- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
31528same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
31529- cta: "See a PR with its sandbox",
31530- mock: [
31531- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
31532- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
31533- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
31534- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
31535- ],
31536- },
31537- {
31538- href: "/",
31539- eyebrow: "03 � Multiplayer IDE workspaces",
31540- title: "You and the agent, side by side, in your editor.",
31541- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
31542agent into a silent reviewer in your gutter. The browser becomes optional.",
31543- cta: "See the editor session",
31544- mock: [
31545- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
31546- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
31547- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
31548- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
31549- ],
31550- },
31551-];
31552-
31553-const capabilities = [
31554- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
31555- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
31556- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
31557- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
31558- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
31559- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
31560- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
31561- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
31562-];
31563-
31564-const sovereignLayerNames = [
31565- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
31566- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
31567- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
31568- "Availability & recovery",
31569-];
31570-
31571-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
31572- return (
31573- <>
31574- <style dangerouslySetInnerHTML={{ __html: css }} />
31575-
31576- {/* Nav */}
31577- <header class="lv-nav">
31578- <div class="lv-nav-inner">
31579- <a href="/" class="lv-logo">
31580- <span class="lv-logo-mark"></span>gluecron
31581- </a>
31582- <nav class="lv-nav-links">
31583- <a href="#loop" class="lv-nav-link">The loop</a>
31584- <a href="#platform" class="lv-nav-link">Platform</a>
31585- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
31586- <a href="/trust" class="lv-nav-link">Trust</a>
31587- </nav>
31588- <div class="lv-nav-ctas">
31589- <a href="/login" class="lv-btn-secondary">Sign in</a>
31590- <a href="/register" class="lv-btn-primary">Start building</a>
31591- </div>
31592- </div>
31593- </header>
31594-
31595- {/* Hero */}
31596- <section class="lv-hero">
31597- <div class="lv-hero-glow"></div>
31598- <div class="lv-hero-inner">
31599- <div class="lv-hero-badge">
31600- <span class="lv-dot lv-dot-green lv-pulse"></span>
31601- Live: a repair loop converged on pr-218 while you read this
31602- </div>
31603- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
31604- <p class="lv-hero-sub">
31605- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
31606failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
31607- </p>
31608- <div class="lv-hero-actions">
31609- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
31610- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
31611- </div>
31612- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
31613-
31614- {/* Live product window */}
31615- <div class="lv-demo-window">
31616- <div class="lv-demo-bar">
31617- <span class="lv-demo-dot"></span>
31618- <span class="lv-demo-dot"></span>
31619- <span class="lv-demo-dot"></span>
31620- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
31621- <span class="lv-demo-live">
31622- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
31623- LIVE
31624- </span>
31625- </div>
31626- <div class="lv-demo-body" id="lv-demo-body">
31627- {/* Events rendered by JS */}
31628- {demoAllEvents.slice(0, 1).map((e, i) => (
31629- <div class="lv-demo-event" key={i}>
31630- <div class="lv-demo-event-track">
31631- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
31632- <span class="lv-demo-line" style="display:none"></span>
31633- </div>
31634- <div class="lv-demo-event-content">
31635- <div class="lv-demo-event-header">
31636- <span class="lv-demo-event-title">{e.title}</span>
31637- <span class="lv-demo-event-time">{e.time}</span>
31638- </div>
31639- <div class="lv-demo-event-body">{e.body}</div>
31640- </div>
31641- </div>
31642- ))}
31643- </div>
31644- </div>
31645- </div>
31646-
31647- {/* Activity ticker */}
31648- <div class="lv-ticker-wrap">
31649- <div class="lv-ticker-track">
31650- {tickerItems.map((t, i) => (
31651- <span class="lv-ticker-item" key={i}>
31652- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
31653- {t.text}
31654- </span>
31655- ))}
31656- </div>
31657- </div>
31658- </section>
31659-
31660- {/* Stat band */}
31661- <section class="lv-stats">
31662- <div class="lv-stats-inner">
31663- <div class="lv-stat">
31664- <div class="lv-stat-num">Sonnet 5</div>
31665- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
31666- </div>
31667- <div class="lv-stat">
31668- <div class="lv-stat-num">93.5%</div>
31669- <div class="lv-stat-label">of failures self-repair without a human</div>
31670- </div>
31671- <div class="lv-stat">
31672- <div class="lv-stat-num">1.9%</div>
31673- <div class="lv-stat-label">AI merges reverted  published live</div>
31674- </div>
31675- <div class="lv-stat">
31676- <div class="lv-stat-num">0</div>
31677- <div class="lv-stat-label">irreversible actions taken autonomously</div>
31678- </div>
31679- </div>
31680- </section>
31681-
31682- {/* The loop */}
31683- <section id="loop" class="lv-loop">
31684- <div class="lv-loop-inner">
31685- <div class="lv-section-header">
31686- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
31687- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
31688- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
31689- </div>
31690- <div class="lv-stages" id="lv-stages">
31691- {stageData.map((s, i) => (
31692- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
31693- <div class="lv-stage-header">
31694- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
31695- <span class="lv-stage-n">0{i + 1}</span>
31696- </div>
31697- <div class="lv-stage-name">{s.name}</div>
31698- <div class="lv-stage-desc">{s.desc}</div>
31699- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
31700- </div>
31701- ))}
31702- </div>
31703- </div>
31704- </section>
31705-
31706- {/* Three heroes */}
31707- <section class="lv-heroes">
31708- <div class="lv-heroes-inner">
31709- <div class="lv-heroes-header">
31710- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
31711- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
31712- </div>
31713- <div class="lv-heroes-list">
31714- {heroFeatures.map((h, i) => (
31715- <a href={h.href} class="lv-hero-card" key={i}>
31716- <div class="lv-hero-card-left">
31717- <div class="lv-eyebrow">{h.eyebrow}</div>
31718- <h3 class="lv-hero-card-title">{h.title}</h3>
31719- <p class="lv-hero-card-body">{h.body}</p>
31720- <span class="lv-hero-card-cta">{h.cta} �!</span>
31721- </div>
31722- <div class="lv-terminal">
31723- {h.mock.map((m, j) => (
31724- <div class="lv-terminal-line" key={j}>
31725- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
31726- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
31727- </div>
31728- ))}
31729- </div>
31730- </a>
31731- ))}
31732- </div>
31733- </div>
31734- </section>
31735-
31736- {/* Everything grid */}
31737- <section id="platform" class="lv-platform">
31738- <div class="lv-platform-inner">
31739- <div class="lv-section-header lv-section-header-center">
31740- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
31741- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
31742- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
31743- </div>
31744- <div class="lv-cap-grid">
31745- {capabilities.map((c, i) => (
31746- <div class="lv-cap-col" key={i}>
31747- <div class="lv-cap-group">{c.group}</div>
31748- <div class="lv-cap-items">
31749- {c.items.map((item, j) => (
31750- <div class="lv-cap-item" key={j}>{item}</div>
31751- ))}
31752- </div>
31753- </div>
31754- ))}
31755- </div>
31756- </div>
31757- </section>
31758-
31759- {/* Sovereignty band */}
31760- <section id="sovereign" class="lv-sovereign">
31761- <div class="lv-sovereign-grid-bg"></div>
31762- <div class="lv-sovereign-inner">
31763- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
31764- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
31765- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
31766- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
31767to private cloud, or run fully air-gapped on bare metal.</p>
31768- </div>
31769- <div class="lv-layers-grid">
31770- {sovereignLayerNames.map((name, i) => (
31771- <div class="lv-layer-chip" key={i}>
31772- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
31773- <div class="lv-layer-name">{name}</div>
31774- </div>
31775- ))}
31776- <a href="/" class="lv-layer-chip lv-layer-cta">
31777- <div class="lv-layer-cta-text">All self-owned �!</div>
31778- </a>
31779- </div>
31780- <div class="lv-sovereign-feats">
31781- <div class="lv-sovereign-feat">
31782- <div class="lv-sovereign-feat-title">Local inference first</div>
31783- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
31784- </div>
31785- <div class="lv-sovereign-feat">
31786- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
31787- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
31788- </div>
31789- <div class="lv-sovereign-feat">
31790- <div class="lv-sovereign-feat-title">Self-healing infra</div>
31791- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
31792- </div>
31793- </div>
31794- </div>
31795- </section>
31796-
31797- {/* Manual-first + reversibility */}
31798- <section class="lv-twin">
31799- <div class="lv-twin-inner">
31800- <div class="lv-twin-card">
31801- <div class="lv-eyebrow">Manual-first, always</div>
31802- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
31803- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
31804fallback. Developers who never touch AI get the best git host they've ever used.</p>
31805- </div>
31806- <div class="lv-twin-card">
31807- <div class="lv-eyebrow">The reversibility guarantee</div>
31808- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
31809- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
31810 policy, not promise. Our quality numbers are published live, unedited.</p>
31811- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
31812- </div>
31813- </div>
31814- </section>
31815-
31816- {/* Quote */}
31817- <section class="lv-quote">
31818- <div class="lv-quote-inner">
31819- <p class="lv-quote-text">
31820- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
31821- Gluecron is where code gets <em class="lv-em">finished</em>."
31822- </p>
31823- </div>
31824- </section>
31825-
31826- {/* CTA */}
31827- <section class="lv-cta-section">
31828- <div class="lv-cta-card">
31829- <div class="lv-cta-glow"></div>
31830- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
31831- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
31832- <div class="lv-cta-actions">
31833- <a href="/register" class="lv-cta-primary">Create your account �!</a>
31834- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
31835- </div>
31836- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
31837- </div>
31838- </section>
31839-
31840- {/* Footer */}
31841- <footer class="lv-footer">
31842- <div class="lv-footer-inner">
31843- <div class="lv-footer-brand">
31844- <a href="/" class="lv-logo">
31845- <span class="lv-logo-mark"></span>gluecron
31846- </a>
31847- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
31848- </div>
31849- <div class="lv-footer-cols">
31850- <div class="lv-footer-col">
31851- <h4 class="lv-footer-col-head">Product</h4>
31852- <a href="/" class="lv-footer-link">Agent workspace</a>
31853- <a href="/" class="lv-footer-link">Fleet refactors</a>
31854- <a href="/" class="lv-footer-link">Org memory</a>
31855- <a href="/" class="lv-footer-link">IDE extensions</a>
31856- </div>
31857- <div class="lv-footer-col">
31858- <h4 class="lv-footer-col-head">Platform</h4>
31859- <a href="/" class="lv-footer-link">Production layers</a>
31860- <a href="/trust" class="lv-footer-link">Trust report</a>
31861- <a href="/" class="lv-footer-link">Docs</a>
31862- <a href="/" class="lv-footer-link">Status</a>
31863- </div>
31864- <div class="lv-footer-col">
31865- <h4 class="lv-footer-col-head">Company</h4>
31866- <a href="/" class="lv-footer-link">About</a>
31867- <a href="/" class="lv-footer-link">Pricing</a>
31868- <a href="/" class="lv-footer-link">Enterprise</a>
31869- </div>
31870- </div>
31871- </div>
31872- <div class="lv-footer-bar">
31873- <span>� 2026 Gluecron</span>
31874- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
31875- </div>
31876- </footer>
31877-
31878- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
31879- </>
31880- );
31881-};
31882-
31883-export const LandingPage = LandingPageV2;
31884-export default LandingPageV2;
31885-
31886-const clientScript = `
31887-(function() {
31888- var demoAll = [
31889- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
31890- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
31891- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
31892- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
31893- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
31894- ];
31895-
31896- var demoStep = 0;
31897- var stage = 0;
31898-
31899- function renderDemo() {
31900- var container = document.getElementById('lv-demo-body');
31901- if (!container) return;
31902- var visible = demoAll.slice(0, demoStep + 1);
31903- container.innerHTML = visible.map(function(e, i) {
31904- var isLast = i === visible.length - 1;
31905- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
31906- return '<div class="lv-demo-event">' +
31907- '<div class="lv-demo-event-track">' +
31908- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
31909- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
31910- '</div>' +
31911- '<div class="lv-demo-event-content">' +
31912- '<div class="lv-demo-event-header">' +
31913- '<span class="lv-demo-event-title">' + e.title + '</span>' +
31914- '<span class="lv-demo-event-time">' + e.time + '</span>' +
31915- '</div>' +
31916- '<div class="lv-demo-event-body">' + e.body + '</div>' +
31917- '</div>' +
31918- '</div>';
31919- }).join('');
31920- }
31921-
31922- function renderStages() {
31923- var cards = document.querySelectorAll('.lv-stage-card');
31924- cards.forEach(function(card, i) {
31925- var dot = card.querySelector('.lv-dot');
31926- var meta = card.querySelector('.lv-stage-meta');
31927- if (i === stage) {
31928- card.classList.add('lv-stage-active');
31929- if (dot) {
31930- dot.classList.remove('lv-dot-idle');
31931- dot.classList.add('lv-dot-indigo', 'lv-pulse');
31932- }
31933- if (meta) meta.classList.add('lv-stage-meta-active');
31934- } else {
31935- card.classList.remove('lv-stage-active');
31936- if (dot) {
31937- dot.classList.add('lv-dot-idle');
31938- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
31939- }
31940- if (meta) meta.classList.remove('lv-stage-meta-active');
31941- }
31942- });
31943- }
31944-
31945- renderDemo();
31946-
31947- setInterval(function() {
31948- demoStep = (demoStep + 1) % 5;
31949- renderDemo();
31950- }, 3600);
31951-
31952- setInterval(function() {
31953- stage = (stage + 1) % 6;
31954- renderStages();
31955- }, 2200);
31956-})();
31957-`;
31958-
31959-const css = `
31960-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
31961-
31962-*, *::before, *::after { box-sizing: border-box; }
31963-
31964-body {
31965- margin: 0;
31966- background: #fcfcfd;
31967- -webkit-font-smoothing: antialiased;
31968- text-rendering: optimizeLegibility;
31969- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
31970- font-size: 15px;
31971- line-height: 1.6;
31972- letter-spacing: -0.008em;
31973- color: #16181d;
31974-}
31975-
31976-@keyframes gcPulse {
31977- 0%, 100% { opacity: 1; }
31978- 50% { opacity: 0.35; }
31979-}
31980-
31981-@keyframes gcTicker {
31982- 0% { transform: translateX(0); }
31983- 100% { transform: translateX(-50%); }
31984-}
31985-
31986-/* Shared utilities */
31987-.lv-dot {
31988- display: inline-block;
31989- border-radius: 50%;
31990-}
31991-.lv-dot-green { background: #1e7f5c; }
31992-.lv-dot-indigo { background: #4353c9; }
31993-.lv-dot-idle { background: #c4c6cf; }
31994-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
31995-
31996-.lv-strong { color: #16181d; font-weight: 600; }
31997-
31998-.lv-eyebrow {
31999- font-family: 'JetBrains Mono', monospace;
32000- font-size: 11px;
32001- letter-spacing: 0.12em;
32002- text-transform: uppercase;
32003- color: #8a8d99;
32004- font-weight: 500;
32005- margin-bottom: 12px;
32006-}
32007-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
32008-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
32009-
32010-.lv-h1 {
32011- font-family: 'Inter Tight', sans-serif;
32012- font-weight: 700;
32013- letter-spacing: -0.035em;
32014- font-size: clamp(44px, 7vw, 84px);
32015- line-height: 0.98;
32016- margin: 30px auto 0;
32017- max-width: 14ch;
32018- color: #111318;
32019-}
32020-
32021-.lv-h2 {
32022- font-family: 'Inter Tight', sans-serif;
32023- font-weight: 700;
32024- letter-spacing: -0.028em;
32025- font-size: clamp(30px, 4.4vw, 48px);
32026- line-height: 1.05;
32027- margin: 0;
32028- color: #111318;
32029-}
32030-
32031-.lv-h2-dark {
32032- font-family: 'Inter Tight', sans-serif;
32033- font-weight: 700;
32034- letter-spacing: -0.028em;
32035- font-size: clamp(30px, 4.6vw, 52px);
32036- line-height: 1.05;
32037- margin: 0;
32038- color: #fff;
32039-}
32040-
32041-.lv-section-header {
32042- max-width: 640px;
32043- margin: 0 auto 56px;
32044-}
32045-
32046-.lv-section-header-center {
32047- text-align: center;
32048-}
32049-
32050-.lv-section-sub {
32051- color: #6b7080;
32052- font-size: 17px;
32053- margin: 18px auto 0;
32054- max-width: 52ch;
32055-}
32056-
32057-.lv-section-sub-dark {
32058- color: rgba(255,255,255,0.72);
32059- font-size: 17px;
32060- margin: 18px auto 0;
32061- max-width: 56ch;
32062-}
32063-
32064-/* Nav */
32065-.lv-nav {
32066- position: sticky;
32067- top: 0;
32068- z-index: 60;
32069- backdrop-filter: saturate(180%) blur(14px);
32070- -webkit-backdrop-filter: saturate(180%) blur(14px);
32071- background: rgba(252,252,253,0.8);
32072- border-bottom: 1px solid rgba(22,24,29,0.07);
32073-}
32074-
32075-.lv-nav-inner {
32076- max-width: 1200px;
32077- margin: 0 auto;
32078- padding: 14px 28px;
32079- display: flex;
32080- align-items: center;
32081- gap: 28px;
32082-}
32083-
32084-.lv-logo {
32085- display: inline-flex;
32086- align-items: center;
32087- gap: 9px;
32088- font-family: 'Inter Tight', sans-serif;
32089- font-weight: 700;
32090- font-size: 17px;
32091- letter-spacing: -0.02em;
32092- color: #16181d;
32093- text-decoration: none;
32094-}
32095-
32096-.lv-logo-mark {
32097- width: 17px;
32098- height: 17px;
32099- border-radius: 5px;
32100- background: #4353c9;
32101- display: inline-block;
32102- flex-shrink: 0;
32103-}
32104-
32105-.lv-nav-links {
32106- display: flex;
32107- gap: 24px;
32108- font-size: 13.5px;
32109- font-weight: 500;
32110-}
32111-
32112-.lv-nav-link {
32113- color: #6b7080;
32114- text-decoration: none;
32115- transition: color 0.15s;
32116-}
32117-.lv-nav-link:hover { color: #16181d; }
32118-
32119-.lv-nav-ctas {
32120- margin-left: auto;
32121- display: flex;
32122- align-items: center;
32123- gap: 10px;
32124-}
32125-
32126-.lv-btn-secondary {
32127- padding: 8px 15px;
32128- border-radius: 8px;
32129- font-size: 13.5px;
32130- font-weight: 500;
32131- color: #16181d;
32132- border: 1px solid rgba(22,24,29,0.12);
32133- background: #ffffff;
32134- text-decoration: none;
32135- white-space: nowrap;
32136- transition: border-color 0.15s;
32137-}
32138-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
32139-
32140-.lv-btn-primary {
32141- padding: 8px 15px;
32142- border-radius: 8px;
32143- font-size: 13.5px;
32144- font-weight: 600;
32145- background: #16181d;
32146- color: #fff;
32147- text-decoration: none;
32148- white-space: nowrap;
32149- transition: box-shadow 0.15s;
32150-}
32151-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
32152-
32153-/* Hero */
32154-.lv-hero {
32155- position: relative;
32156- overflow: hidden;
32157- padding: 88px 0 0;
32158-}
32159-
32160-.lv-hero-glow {
32161- position: absolute;
32162- inset: -10% 0 auto 0;
32163- height: 640px;
32164- pointer-events: none;
32165- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
32166-}
32167-
32168-.lv-hero-inner {
32169- position: relative;
32170- max-width: 1200px;
32171- margin: 0 auto;
32172- padding: 0 28px;
32173- text-align: center;
32174-}
32175-
32176-.lv-hero-badge {
32177- display: inline-flex;
32178- align-items: center;
32179- gap: 9px;
32180- font-size: 12.5px;
32181- font-weight: 600;
32182- color: #3a3d45;
32183- background: #ffffff;
32184- border: 1px solid rgba(22,24,29,0.10);
32185- border-radius: 9999px;
32186- padding: 7px 16px;
32187- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
32188-}
32189-
32190-.lv-hero-sub {
32191- font-size: clamp(16px, 2vw, 19px);
32192- color: #6b7080;
32193- max-width: 60ch;
32194- margin: 24px auto 0;
32195- font-weight: 450;
32196- line-height: 1.65;
32197-}
32198-
32199-.lv-hero-actions {
32200- display: flex;
32201- gap: 12px;
32202- justify-content: center;
32203- flex-wrap: wrap;
32204- margin-top: 32px;
32205-}
32206-
32207-.lv-cta-primary {
32208- padding: 13px 24px;
32209- border-radius: 11px;
32210- font-size: 15.5px;
32211- font-weight: 600;
32212- background: #16181d;
32213- color: #fff;
32214- text-decoration: none;
32215- white-space: nowrap;
32216- transition: box-shadow 0.15s;
32217-}
32218-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
32219-
32220-.lv-cta-secondary {
32221- padding: 13px 24px;
32222- border-radius: 11px;
32223- font-size: 15.5px;
32224- font-weight: 600;
32225- color: #16181d;
32226- border: 1px solid rgba(22,24,29,0.14);
32227- background: #ffffff;
32228- text-decoration: none;
32229- white-space: nowrap;
32230- transition: border-color 0.15s;
32231-}
32232-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
32233-
32234-.lv-hero-tag {
32235- margin-top: 18px;
32236- font-family: 'JetBrains Mono', monospace;
32237- font-size: 11.5px;
32238- letter-spacing: 0.08em;
32239- text-transform: uppercase;
32240- color: #8a8d99;
32241-}
32242-
32243-/* Demo window */
32244-.lv-demo-window {
32245- margin: 56px auto 0;
32246- max-width: 860px;
32247- text-align: left;
32248- background: #ffffff;
32249- border: 1px solid rgba(22,24,29,0.09);
32250- border-radius: 18px;
32251- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
32252- overflow: hidden;
32253-}
32254-
32255-.lv-demo-bar {
32256- display: flex;
32257- align-items: center;
32258- gap: 7px;
32259- padding: 12px 18px;
32260- border-bottom: 1px solid rgba(22,24,29,0.07);
32261- background: #fcfcfd;
32262-}
32263-
32264-.lv-demo-dot {
32265- width: 10px;
32266- height: 10px;
32267- border-radius: 50%;
32268- background: #e4e5ea;
32269-}
32270-
32271-.lv-demo-url {
32272- margin-left: 10px;
32273- font-family: 'JetBrains Mono', monospace;
32274- font-size: 12px;
32275- color: #6b7080;
32276-}
32277-
32278-.lv-demo-live {
32279- margin-left: auto;
32280- display: inline-flex;
32281- align-items: center;
32282- gap: 6px;
32283- font-size: 11px;
32284- font-weight: 600;
32285- color: #1e7f5c;
32286-}
32287-
32288-.lv-demo-body {
32289- padding: 22px 24px;
32290-}
32291-
32292-.lv-demo-event {
32293- display: grid;
32294- grid-template-columns: 18px minmax(0, 1fr);
32295- gap: 14px;
32296- padding-bottom: 20px;
32297- position: relative;
32298-}
32299-.lv-demo-event:last-child { padding-bottom: 0; }
32300-
32301-.lv-demo-event-track {
32302- display: flex;
32303- flex-direction: column;
32304- align-items: center;
32305-}
32306-
32307-.lv-demo-line {
32308- width: 1px;
32309- flex: 1;
32310- background: rgba(22,24,29,0.08);
32311- margin-top: 5px;
32312- min-height: 20px;
32313-}
32314-
32315-.lv-demo-event-content {}
32316-
32317-.lv-demo-event-header {
32318- display: flex;
32319- align-items: baseline;
32320- gap: 10px;
32321-}
32322-
32323-.lv-demo-event-title {
32324- font-size: 13.5px;
32325- font-weight: 600;
32326- color: #16181d;
32327-}
32328-
32329-.lv-demo-event-time {
32330- font-family: 'JetBrains Mono', monospace;
32331- font-size: 11px;
32332- color: #8a8d99;
32333-}
32334-
32335-.lv-demo-event-body {
32336- font-size: 13px;
32337- color: #6b7080;
32338- margin-top: 2px;
32339-}
32340-
32341-/* Ticker */
32342-.lv-ticker-wrap {
32343- border-top: 1px solid rgba(22,24,29,0.07);
32344- border-bottom: 1px solid rgba(22,24,29,0.07);
32345- background: #ffffff;
32346- margin-top: 64px;
32347- overflow: hidden;
32348- white-space: nowrap;
32349- position: relative;
32350-}
32351-
32352-.lv-ticker-track {
32353- display: inline-flex;
32354- animation: gcTicker 40s linear infinite;
32355- padding: 11px 0;
32356-}
32357-
32358-.lv-ticker-item {
32359- display: inline-flex;
32360- align-items: center;
32361- gap: 8px;
32362- font-family: 'JetBrains Mono', monospace;
32363- font-size: 11.5px;
32364- color: #6b7080;
32365- padding: 0 28px;
32366- border-right: 1px solid rgba(22,24,29,0.06);
32367-}
32368-
32369-/* Stats */
32370-.lv-stats {
32371- background: #fcfcfd;
32372-}
32373-
32374-.lv-stats-inner {
32375- max-width: 1200px;
32376- margin: 0 auto;
32377- display: grid;
32378- grid-template-columns: repeat(4, 1fr);
32379- gap: 24px;
32380- padding: 52px 28px;
32381-}
32382-
32383-.lv-stat {
32384- text-align: center;
32385-}
32386-
32387-.lv-stat-num {
32388- font-family: 'Inter Tight', sans-serif;
32389- font-weight: 700;
32390- font-size: clamp(30px, 4vw, 44px);
32391- letter-spacing: -0.025em;
32392- color: #111318;
32393-}
32394-
32395-.lv-stat-label {
32396- font-size: 13px;
32397- color: #6b7080;
32398- margin-top: 4px;
32399-}
32400-
32401-/* Loop */
32402-.lv-loop {
32403- padding: 96px 0;
32404- background: #ffffff;
32405- border-top: 1px solid rgba(22,24,29,0.07);
32406- border-bottom: 1px solid rgba(22,24,29,0.07);
32407-}
32408-
32409-.lv-loop-inner {
32410- max-width: 1200px;
32411- margin: 0 auto;
32412- padding: 0 28px;
32413-}
32414-
32415-.lv-stages {
32416- display: grid;
32417- grid-template-columns: repeat(6, 1fr);
32418- gap: 12px;
32419-}
32420-
32421-.lv-stage-card {
32422- border: 1px solid rgba(22,24,29,0.08);
32423- border-radius: 14px;
32424- background: #ffffff;
32425- padding: 20px 18px;
32426- transition: border-color 0.3s, background 0.3s;
32427-}
32428-
32429-.lv-stage-card.lv-stage-active {
32430- border-color: rgba(67,83,201,0.45);
32431- background: rgba(67,83,201,0.03);
32432-}
32433-
32434-.lv-stage-header {
32435- display: flex;
32436- align-items: center;
32437- gap: 8px;
32438- margin-bottom: 10px;
32439-}
32440-
32441-.lv-stage-n {
32442- font-family: 'JetBrains Mono', monospace;
32443- font-size: 10.5px;
32444- letter-spacing: 0.1em;
32445- text-transform: uppercase;
32446- color: #8a8d99;
32447-}
32448-
32449-.lv-stage-name {
32450- font-family: 'Inter Tight', sans-serif;
32451- font-size: 16px;
32452- font-weight: 600;
32453- letter-spacing: -0.01em;
32454- color: #16181d;
32455- margin-bottom: 5px;
32456-}
32457-
32458-.lv-stage-desc {
32459- font-size: 12px;
32460- color: #6b7080;
32461- line-height: 1.55;
32462-}
32463-
32464-.lv-stage-meta {
32465- font-family: 'JetBrains Mono', monospace;
32466- font-size: 10.5px;
32467- color: #8a8d99;
32468- margin-top: 10px;
32469- transition: color 0.3s;
32470-}
32471-
32472-.lv-stage-meta.lv-stage-meta-active {
32473- color: #4353c9;
32474-}
32475-
32476-/* Heroes */
32477-.lv-heroes {
32478- padding: 96px 0;
32479- background: #fcfcfd;
32480-}
32481-
32482-.lv-heroes-inner {
32483- max-width: 1200px;
32484- margin: 0 auto;
32485- padding: 0 28px;
32486-}
32487-
32488-.lv-heroes-header {
32489- max-width: 640px;
32490- margin-bottom: 56px;
32491-}
32492-
32493-.lv-heroes-list {
32494- display: flex;
32495- flex-direction: column;
32496- gap: 20px;
32497-}
32498-
32499-.lv-hero-card {
32500- display: grid;
32501- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
32502- gap: 48px;
32503- align-items: center;
32504- border: 1px solid rgba(22,24,29,0.08);
32505- border-radius: 20px;
32506- background: #ffffff;
32507- padding: 44px 48px;
32508- text-decoration: none;
32509- transition: border-color 0.2s, box-shadow 0.2s;
32510-}
32511-.lv-hero-card:hover {
32512- border-color: rgba(22,24,29,0.22);
32513- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
32514-}
32515-
32516-.lv-hero-card-left {}
32517-
32518-.lv-hero-card-title {
32519- font-family: 'Inter Tight', sans-serif;
32520- font-size: 26px;
32521- font-weight: 600;
32522- letter-spacing: -0.022em;
32523- line-height: 1.15;
32524- color: #16181d;
32525- margin: 0 0 12px;
32526-}
32527-
32528-.lv-hero-card-body {
32529- font-size: 14.5px;
32530- color: #6b7080;
32531- margin: 0 0 18px;
32532- line-height: 1.65;
32533-}
32534-
32535-.lv-hero-card-cta {
32536- font-size: 13.5px;
32537- font-weight: 600;
32538- color: #4353c9;
32539-}
32540-
32541-.lv-terminal {
32542- border: 1px solid rgba(22,24,29,0.07);
32543- border-radius: 14px;
32544- background: #fcfcfd;
32545- padding: 20px 22px;
32546- font-family: 'JetBrains Mono', monospace;
32547- font-size: 12px;
32548- line-height: 1.9;
32549- overflow: hidden;
32550-}
32551-
32552-.lv-terminal-line {
32553- display: flex;
32554- align-items: center;
32555- gap: 10px;
32556- white-space: nowrap;
32557- overflow: hidden;
32558- text-overflow: ellipsis;
32559-}
32560-
32561-/* Platform */
32562-.lv-platform {
32563- padding: 96px 0;
32564- background: #ffffff;
32565- border-top: 1px solid rgba(22,24,29,0.07);
32566-}
32567-
32568-.lv-platform-inner {
32569- max-width: 1200px;
32570- margin: 0 auto;
32571- padding: 0 28px;
32572-}
32573-
32574-.lv-cap-grid {
32575- display: grid;
32576- grid-template-columns: repeat(4, 1fr);
32577- gap: 24px 32px;
32578-}
32579-
32580-.lv-cap-col {}
32581-
32582-.lv-cap-group {
32583- font-family: 'JetBrains Mono', monospace;
32584- font-size: 10.5px;
32585- letter-spacing: 0.12em;
32586- text-transform: uppercase;
32587- color: #8a8d99;
32588- font-weight: 500;
32589- margin-bottom: 12px;
32590- padding-bottom: 8px;
32591- border-bottom: 1px solid rgba(22,24,29,0.07);
32592-}
32593-
32594-.lv-cap-items {
32595- display: flex;
32596- flex-direction: column;
32597- gap: 7px;
32598-}
32599-
32600-.lv-cap-item {
32601- font-size: 12.5px;
32602- color: #3a3d45;
32603- line-height: 1.45;
32604-}
32605-
32606-/* Sovereignty */
32607-.lv-sovereign {
32608- position: relative;
32609- overflow: hidden;
32610- padding: 104px 0;
32611- color: #fff;
32612- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
32613-}
32614-
32615-.lv-sovereign-grid-bg {
32616- position: absolute;
32617- inset: 0;
32618- opacity: 0.4;
32619- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
32620- background-size: 56px 56px;
32621- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
32622- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
32623-}
32624-
32625-.lv-sovereign-inner {
32626- position: relative;
32627- max-width: 1200px;
32628- margin: 0 auto;
32629- padding: 0 28px;
32630-}
32631-
32632-.lv-section-header-dark {
32633- max-width: 680px;
32634- margin: 0 auto 48px;
32635- text-align: center;
32636-}
32637-
32638-.lv-layers-grid {
32639- display: grid;
32640- grid-template-columns: repeat(4, 1fr);
32641- gap: 10px;
32642- max-width: 980px;
32643- margin: 0 auto;
32644-}
32645-
32646-.lv-layer-chip {
32647- border: 1px solid rgba(255,255,255,0.10);
32648- border-radius: 10px;
32649- padding: 12px 16px;
32650- background: rgba(255,255,255,0.03);
32651-}
32652-
32653-.lv-layer-cta {
32654- border-color: rgba(169,180,238,0.30);
32655- background: rgba(169,180,238,0.06);
32656- display: flex;
32657- align-items: center;
32658- text-decoration: none;
32659- transition: background 0.15s;
32660-}
32661-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
32662-
32663-.lv-layer-cta-text {
32664- font-size: 13px;
32665- font-weight: 500;
32666- color: #a9b4ee;
32667-}
32668-
32669-.lv-layer-n {
32670- font-family: 'JetBrains Mono', monospace;
32671- font-size: 10px;
32672- color: rgba(255,255,255,0.4);
32673- margin-bottom: 3px;
32674-}
32675-
32676-.lv-layer-name {
32677- font-size: 13px;
32678- font-weight: 500;
32679- color: rgba(255,255,255,0.92);
32680-}
32681-
32682-.lv-sovereign-feats {
32683- display: flex;
32684- gap: 44px;
32685- justify-content: center;
32686- flex-wrap: wrap;
32687- margin-top: 52px;
32688- text-align: center;
32689-}
32690-
32691-.lv-sovereign-feat {}
32692-
32693-.lv-sovereign-feat-title {
32694- font-family: 'Inter Tight', sans-serif;
32695- font-size: 20px;
32696- font-weight: 700;
32697- color: #fff;
32698-}
32699-
32700-.lv-sovereign-feat-sub {
32701- color: rgba(255,255,255,0.55);
32702- font-size: 13px;
32703- margin-top: 2px;
32704-}
32705-
32706-/* Twin cards */
32707-.lv-twin {
32708- padding: 96px 0;
32709- background: #fcfcfd;
32710-}
32711-
32712-.lv-twin-inner {
32713- max-width: 1200px;
32714- margin: 0 auto;
32715- padding: 0 28px;
32716- display: grid;
32717- grid-template-columns: 1fr 1fr;
32718- gap: 24px;
32719-}
32720-
32721-.lv-twin-card {
32722- border: 1px solid rgba(22,24,29,0.08);
32723- border-radius: 20px;
32724- background: #ffffff;
32725- padding: 44px 48px;
32726-}
32727-
32728-.lv-twin-title {
32729- font-family: 'Inter Tight', sans-serif;
32730- font-size: 24px;
32731- font-weight: 600;
32732- letter-spacing: -0.02em;
32733- line-height: 1.2;
32734- margin: 0 0 12px;
32735- color: #16181d;
32736-}
32737-
32738-.lv-twin-body {
32739- font-size: 14.5px;
32740- color: #6b7080;
32741- margin: 0 0 16px;
32742- line-height: 1.7;
32743-}
32744-
32745-.lv-twin-link {
32746- font-size: 13.5px;
32747- font-weight: 600;
32748- color: #4353c9;
32749- text-decoration: none;
32750-}
32751-.lv-twin-link:hover { text-decoration: underline; }
32752-
32753-/* Quote */
32754-.lv-quote {
32755- padding: 40px 0 96px;
32756- background: #fcfcfd;
32757-}
32758-
32759-.lv-quote-inner {
32760- max-width: 980px;
32761- margin: 0 auto;
32762- padding: 0 28px;
32763- text-align: center;
32764-}
32765-
32766-.lv-quote-text {
32767- font-family: 'Inter Tight', sans-serif;
32768- font-weight: 600;
32769- font-size: clamp(26px, 3.8vw, 42px);
32770- line-height: 1.2;
32771- letter-spacing: -0.025em;
32772- margin: 0;
32773- color: #111318;
32774-}
32775-
32776-.lv-em {
32777- font-style: normal;
32778- color: #4353c9;
32779-}
32780-
32781-/* CTA */
32782-.lv-cta-section {
32783- padding: 0 0 104px;
32784- background: #fcfcfd;
32785-}
32786-
32787-.lv-cta-card {
32788- max-width: 820px;
32789- margin: 0 auto;
32790- padding: 64px 40px;
32791- text-align: center;
32792- background: #ffffff;
32793- border: 1px solid rgba(22,24,29,0.08);
32794- border-radius: 26px;
32795- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
32796- position: relative;
32797- overflow: hidden;
32798-}
32799-
32800-.lv-cta-glow {
32801- position: absolute;
32802- inset: -40% 0 auto 0;
32803- height: 280px;
32804- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
32805- pointer-events: none;
32806-}
32807-
32808-.lv-cta-h2 {
32809- font-family: 'Inter Tight', sans-serif;
32810- font-weight: 700;
32811- letter-spacing: -0.028em;
32812- font-size: clamp(30px, 4.6vw, 48px);
32813- margin: 0;
32814- position: relative;
32815- color: #111318;
32816-}
32817-
32818-.lv-cta-sub {
32819- color: #6b7080;
32820- font-size: 17px;
32821- margin: 16px 0 30px;
32822- position: relative;
32823-}
32824-
32825-.lv-cta-actions {
32826- display: flex;
32827- gap: 12px;
32828- justify-content: center;
32829- flex-wrap: wrap;
32830- position: relative;
32831-}
32832-
32833-.lv-cta-fine {
32834- margin-top: 20px;
32835- font-family: 'JetBrains Mono', monospace;
32836- font-size: 11px;
32837- color: #8a8d99;
32838- position: relative;
32839-}
32840-
32841-/* Footer */
32842-.lv-footer {
32843- border-top: 1px solid rgba(22,24,29,0.07);
32844- background: #ffffff;
32845- padding: 56px 0 30px;
32846-}
32847-
32848-.lv-footer-inner {
32849- max-width: 1200px;
32850- margin: 0 auto;
32851- padding: 0 28px;
32852- display: flex;
32853- gap: 48px;
32854- flex-wrap: wrap;
32855- justify-content: space-between;
32856-}
32857-
32858-.lv-footer-brand {}
32859-
32860-.lv-footer-tagline {
32861- color: #6b7080;
32862- font-size: 13.5px;
32863- margin: 12px 0 0;
32864- max-width: 32ch;
32865- line-height: 1.6;
32866-}
32867-
32868-.lv-footer-cols {
32869- display: flex;
32870- gap: 64px;
32871- flex-wrap: wrap;
32872-}
32873-
32874-.lv-footer-col {
32875- display: flex;
32876- flex-direction: column;
32877- gap: 9px;
32878-}
32879-
32880-.lv-footer-col-head {
32881- font-family: 'JetBrains Mono', monospace;
32882- font-size: 11px;
32883- text-transform: uppercase;
32884- letter-spacing: 0.1em;
32885- color: #8a8d99;
32886- margin: 0 0 4px;
32887- font-weight: 500;
32888-}
32889-
32890-.lv-footer-link {
32891- color: #3a3d45;
32892- font-size: 13.5px;
32893- text-decoration: none;
32894- transition: color 0.15s;
32895-}
32896-.lv-footer-link:hover { color: #16181d; }
32897-
32898-.lv-footer-bar {
32899- max-width: 1200px;
32900- margin: 44px auto 0;
32901- padding: 22px 28px 0;
32902- border-top: 1px solid rgba(22,24,29,0.06);
32903- display: flex;
32904- justify-content: space-between;
32905- flex-wrap: wrap;
32906- gap: 8px;
32907- color: #8a8d99;
32908- font-size: 12.5px;
32909-}
32910-
32911-.lv-footer-stack {
32912- font-family: 'JetBrains Mono', monospace;
32913- font-size: 11px;
32914-}
32915-`;
32916diff --git a/src/views/layout.tsx b/src/views/layout.tsx
32917index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
32918--- a/src/views/layout.tsx
32919+++ b/src/views/layout.tsx
32920@@ -3153,9 +3153,12 @@
32921 font-weight: 500;
32922 line-height: 1.4;
32923 }
32924- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
32925- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
32926- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
32927+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
32928+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
32929+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
32930+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
32931+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
32932+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
32933 .state-merged { color: var(--accent); }
32934 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
32935
32936diff --git a/src/views/ui.tsx b/src/views/ui.tsx
32937index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
32938--- a/src/views/ui.tsx
32939+++ b/src/views/ui.tsx
32940@@ -232,7 +232,7 @@
32941
32942 export const Badge: FC<
32943 PropsWithChildren<{
32944- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
32945+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
32946 style?: string;
32947 }>
32948 > = ({ children, variant = "default", style }) => {
32949@@ -241,9 +241,12 @@
32950 variant === "closed" ? "badge-closed" :
32951 variant === "merged" ? "badge-merged" :
32952 variant === "success" ? "badge-success" :
32953- variant === "danger" ? "badge-danger" :
32954- variant === "warning" ? "badge-warning" :
32955- "badge";
32956+ variant === "danger" ? "badge-danger" :
32957+ variant === "warning" ? "badge-warning" :
32958+ variant === "live" ? "badge-live" :
32959+ variant === "soon" ? "badge-soon" :
32960+ variant === "preview" ? "badge-preview" :
32961+ "badge";
32962 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
32963 };
32964
32965
32966diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
32967index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
32968--- a/src/views/landing-pro.tsx
32969+++ b/src/views/landing-pro.tsx
32970@@ -42,7 +42,7 @@
32971
32972 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32973
32974-function icon(paths: string, color = "#4353c9", size = 20) {
32975+function icon(paths: string, color = "#0891b2", size = 20) {
32976 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
32977 }
32978
32979@@ -947,7 +947,7 @@
32980 const css = `
32981 /* %% tokens %% */
32982 :root{
32983- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
32984+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
32985 --lp-bg:#ffffff;--lp-soft:#fafafb;
32986 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
32987 --lp-border:rgba(0,0,0,.08);
32988diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
32989deleted file mode 100644
32990index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
32991--- a/src/views/landing-v2.tsx
32992+++ /dev/null
32993@@ -1,1447 +0,0 @@
32994-import type { FC } from "hono/jsx";
32995-
32996-export interface LandingPageProps {
32997- stats?: {
32998- publicRepos?: number;
32999- users?: number;
33000- };
33001-}
33002-
33003-const demoAllEvents = [
33004- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
33005- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
33006- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
33007- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
33008- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
33009-];
33010-
33011-const tickerItems = [
33012- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
33013- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
33014- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
33015- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
33016- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
33017- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
33018- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
33019- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
33020- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
33021- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
33022- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
33023- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
33024- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
33025- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
33026- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
33027- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
33028-];
33029-
33030-const stageData = [
33031- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
33032- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
33033- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
33034- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
33035- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
33036- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
33037-];
33038-
33039-const heroFeatures = [
33040- {
33041- href: "/",
33042- eyebrow: "01 � The autonomous repair loop",
33043- title: "Failures fix themselves  and show their work.",
33044- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
33045failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
33046- cta: "Watch a live repair session",
33047- mock: [
33048- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
33049- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
33050- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
33051- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
33052- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
33053- ],
33054- },
33055- {
33056- href: "/",
33057- eyebrow: "02 � Live sandbox isolation",
33058- title: "Every PR gets its own instant, disposable environment.",
33059- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
33060same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
33061- cta: "See a PR with its sandbox",
33062- mock: [
33063- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
33064- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
33065- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
33066- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
33067- ],
33068- },
33069- {
33070- href: "/",
33071- eyebrow: "03 � Multiplayer IDE workspaces",
33072- title: "You and the agent, side by side, in your editor.",
33073- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
33074agent into a silent reviewer in your gutter. The browser becomes optional.",
33075- cta: "See the editor session",
33076- mock: [
33077- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
33078- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
33079- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
33080- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
33081- ],
33082- },
33083-];
33084-
33085-const capabilities = [
33086- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
33087- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
33088- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
33089- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
33090- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
33091- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
33092- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
33093- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
33094-];
33095-
33096-const sovereignLayerNames = [
33097- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
33098- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
33099- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
33100- "Availability & recovery",
33101-];
33102-
33103-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
33104- return (
33105- <>
33106- <style dangerouslySetInnerHTML={{ __html: css }} />
33107-
33108- {/* Nav */}
33109- <header class="lv-nav">
33110- <div class="lv-nav-inner">
33111- <a href="/" class="lv-logo">
33112- <span class="lv-logo-mark"></span>gluecron
33113- </a>
33114- <nav class="lv-nav-links">
33115- <a href="#loop" class="lv-nav-link">The loop</a>
33116- <a href="#platform" class="lv-nav-link">Platform</a>
33117- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
33118- <a href="/trust" class="lv-nav-link">Trust</a>
33119- </nav>
33120- <div class="lv-nav-ctas">
33121- <a href="/login" class="lv-btn-secondary">Sign in</a>
33122- <a href="/register" class="lv-btn-primary">Start building</a>
33123- </div>
33124- </div>
33125- </header>
33126-
33127- {/* Hero */}
33128- <section class="lv-hero">
33129- <div class="lv-hero-glow"></div>
33130- <div class="lv-hero-inner">
33131- <div class="lv-hero-badge">
33132- <span class="lv-dot lv-dot-green lv-pulse"></span>
33133- Live: a repair loop converged on pr-218 while you read this
33134- </div>
33135- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
33136- <p class="lv-hero-sub">
33137- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
33138failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
33139- </p>
33140- <div class="lv-hero-actions">
33141- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
33142- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
33143- </div>
33144- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
33145-
33146- {/* Live product window */}
33147- <div class="lv-demo-window">
33148- <div class="lv-demo-bar">
33149- <span class="lv-demo-dot"></span>
33150- <span class="lv-demo-dot"></span>
33151- <span class="lv-demo-dot"></span>
33152- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
33153- <span class="lv-demo-live">
33154- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
33155- LIVE
33156- </span>
33157- </div>
33158- <div class="lv-demo-body" id="lv-demo-body">
33159- {/* Events rendered by JS */}
33160- {demoAllEvents.slice(0, 1).map((e, i) => (
33161- <div class="lv-demo-event" key={i}>
33162- <div class="lv-demo-event-track">
33163- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
33164- <span class="lv-demo-line" style="display:none"></span>
33165- </div>
33166- <div class="lv-demo-event-content">
33167- <div class="lv-demo-event-header">
33168- <span class="lv-demo-event-title">{e.title}</span>
33169- <span class="lv-demo-event-time">{e.time}</span>
33170- </div>
33171- <div class="lv-demo-event-body">{e.body}</div>
33172- </div>
33173- </div>
33174- ))}
33175- </div>
33176- </div>
33177- </div>
33178-
33179- {/* Activity ticker */}
33180- <div class="lv-ticker-wrap">
33181- <div class="lv-ticker-track">
33182- {tickerItems.map((t, i) => (
33183- <span class="lv-ticker-item" key={i}>
33184- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
33185- {t.text}
33186- </span>
33187- ))}
33188- </div>
33189- </div>
33190- </section>
33191-
33192- {/* Stat band */}
33193- <section class="lv-stats">
33194- <div class="lv-stats-inner">
33195- <div class="lv-stat">
33196- <div class="lv-stat-num">Sonnet 5</div>
33197- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
33198- </div>
33199- <div class="lv-stat">
33200- <div class="lv-stat-num">93.5%</div>
33201- <div class="lv-stat-label">of failures self-repair without a human</div>
33202- </div>
33203- <div class="lv-stat">
33204- <div class="lv-stat-num">1.9%</div>
33205- <div class="lv-stat-label">AI merges reverted  published live</div>
33206- </div>
33207- <div class="lv-stat">
33208- <div class="lv-stat-num">0</div>
33209- <div class="lv-stat-label">irreversible actions taken autonomously</div>
33210- </div>
33211- </div>
33212- </section>
33213-
33214- {/* The loop */}
33215- <section id="loop" class="lv-loop">
33216- <div class="lv-loop-inner">
33217- <div class="lv-section-header">
33218- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
33219- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
33220- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
33221- </div>
33222- <div class="lv-stages" id="lv-stages">
33223- {stageData.map((s, i) => (
33224- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
33225- <div class="lv-stage-header">
33226- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
33227- <span class="lv-stage-n">0{i + 1}</span>
33228- </div>
33229- <div class="lv-stage-name">{s.name}</div>
33230- <div class="lv-stage-desc">{s.desc}</div>
33231- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
33232- </div>
33233- ))}
33234- </div>
33235- </div>
33236- </section>
33237-
33238- {/* Three heroes */}
33239- <section class="lv-heroes">
33240- <div class="lv-heroes-inner">
33241- <div class="lv-heroes-header">
33242- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
33243- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
33244- </div>
33245- <div class="lv-heroes-list">
33246- {heroFeatures.map((h, i) => (
33247- <a href={h.href} class="lv-hero-card" key={i}>
33248- <div class="lv-hero-card-left">
33249- <div class="lv-eyebrow">{h.eyebrow}</div>
33250- <h3 class="lv-hero-card-title">{h.title}</h3>
33251- <p class="lv-hero-card-body">{h.body}</p>
33252- <span class="lv-hero-card-cta">{h.cta} �!</span>
33253- </div>
33254- <div class="lv-terminal">
33255- {h.mock.map((m, j) => (
33256- <div class="lv-terminal-line" key={j}>
33257- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
33258- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
33259- </div>
33260- ))}
33261- </div>
33262- </a>
33263- ))}
33264- </div>
33265- </div>
33266- </section>
33267-
33268- {/* Everything grid */}
33269- <section id="platform" class="lv-platform">
33270- <div class="lv-platform-inner">
33271- <div class="lv-section-header lv-section-header-center">
33272- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
33273- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
33274- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
33275- </div>
33276- <div class="lv-cap-grid">
33277- {capabilities.map((c, i) => (
33278- <div class="lv-cap-col" key={i}>
33279- <div class="lv-cap-group">{c.group}</div>
33280- <div class="lv-cap-items">
33281- {c.items.map((item, j) => (
33282- <div class="lv-cap-item" key={j}>{item}</div>
33283- ))}
33284- </div>
33285- </div>
33286- ))}
33287- </div>
33288- </div>
33289- </section>
33290-
33291- {/* Sovereignty band */}
33292- <section id="sovereign" class="lv-sovereign">
33293- <div class="lv-sovereign-grid-bg"></div>
33294- <div class="lv-sovereign-inner">
33295- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
33296- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
33297- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
33298- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
33299to private cloud, or run fully air-gapped on bare metal.</p>
33300- </div>
33301- <div class="lv-layers-grid">
33302- {sovereignLayerNames.map((name, i) => (
33303- <div class="lv-layer-chip" key={i}>
33304- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
33305- <div class="lv-layer-name">{name}</div>
33306- </div>
33307- ))}
33308- <a href="/" class="lv-layer-chip lv-layer-cta">
33309- <div class="lv-layer-cta-text">All self-owned �!</div>
33310- </a>
33311- </div>
33312- <div class="lv-sovereign-feats">
33313- <div class="lv-sovereign-feat">
33314- <div class="lv-sovereign-feat-title">Local inference first</div>
33315- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
33316- </div>
33317- <div class="lv-sovereign-feat">
33318- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
33319- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
33320- </div>
33321- <div class="lv-sovereign-feat">
33322- <div class="lv-sovereign-feat-title">Self-healing infra</div>
33323- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
33324- </div>
33325- </div>
33326- </div>
33327- </section>
33328-
33329- {/* Manual-first + reversibility */}
33330- <section class="lv-twin">
33331- <div class="lv-twin-inner">
33332- <div class="lv-twin-card">
33333- <div class="lv-eyebrow">Manual-first, always</div>
33334- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
33335- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
33336fallback. Developers who never touch AI get the best git host they've ever used.</p>
33337- </div>
33338- <div class="lv-twin-card">
33339- <div class="lv-eyebrow">The reversibility guarantee</div>
33340- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
33341- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
33342 policy, not promise. Our quality numbers are published live, unedited.</p>
33343- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
33344- </div>
33345- </div>
33346- </section>
33347-
33348- {/* Quote */}
33349- <section class="lv-quote">
33350- <div class="lv-quote-inner">
33351- <p class="lv-quote-text">
33352- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
33353- Gluecron is where code gets <em class="lv-em">finished</em>."
33354- </p>
33355- </div>
33356- </section>
33357-
33358- {/* CTA */}
33359- <section class="lv-cta-section">
33360- <div class="lv-cta-card">
33361- <div class="lv-cta-glow"></div>
33362- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
33363- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
33364- <div class="lv-cta-actions">
33365- <a href="/register" class="lv-cta-primary">Create your account �!</a>
33366- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
33367- </div>
33368- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
33369- </div>
33370- </section>
33371-
33372- {/* Footer */}
33373- <footer class="lv-footer">
33374- <div class="lv-footer-inner">
33375- <div class="lv-footer-brand">
33376- <a href="/" class="lv-logo">
33377- <span class="lv-logo-mark"></span>gluecron
33378- </a>
33379- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
33380- </div>
33381- <div class="lv-footer-cols">
33382- <div class="lv-footer-col">
33383- <h4 class="lv-footer-col-head">Product</h4>
33384- <a href="/" class="lv-footer-link">Agent workspace</a>
33385- <a href="/" class="lv-footer-link">Fleet refactors</a>
33386- <a href="/" class="lv-footer-link">Org memory</a>
33387- <a href="/" class="lv-footer-link">IDE extensions</a>
33388- </div>
33389- <div class="lv-footer-col">
33390- <h4 class="lv-footer-col-head">Platform</h4>
33391- <a href="/" class="lv-footer-link">Production layers</a>
33392- <a href="/trust" class="lv-footer-link">Trust report</a>
33393- <a href="/" class="lv-footer-link">Docs</a>
33394- <a href="/" class="lv-footer-link">Status</a>
33395- </div>
33396- <div class="lv-footer-col">
33397- <h4 class="lv-footer-col-head">Company</h4>
33398- <a href="/" class="lv-footer-link">About</a>
33399- <a href="/" class="lv-footer-link">Pricing</a>
33400- <a href="/" class="lv-footer-link">Enterprise</a>
33401- </div>
33402- </div>
33403- </div>
33404- <div class="lv-footer-bar">
33405- <span>� 2026 Gluecron</span>
33406- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
33407- </div>
33408- </footer>
33409-
33410- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
33411- </>
33412- );
33413-};
33414-
33415-export const LandingPage = LandingPageV2;
33416-export default LandingPageV2;
33417-
33418-const clientScript = `
33419-(function() {
33420- var demoAll = [
33421- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
33422- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
33423- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
33424- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
33425- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
33426- ];
33427-
33428- var demoStep = 0;
33429- var stage = 0;
33430-
33431- function renderDemo() {
33432- var container = document.getElementById('lv-demo-body');
33433- if (!container) return;
33434- var visible = demoAll.slice(0, demoStep + 1);
33435- container.innerHTML = visible.map(function(e, i) {
33436- var isLast = i === visible.length - 1;
33437- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
33438- return '<div class="lv-demo-event">' +
33439- '<div class="lv-demo-event-track">' +
33440- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
33441- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
33442- '</div>' +
33443- '<div class="lv-demo-event-content">' +
33444- '<div class="lv-demo-event-header">' +
33445- '<span class="lv-demo-event-title">' + e.title + '</span>' +
33446- '<span class="lv-demo-event-time">' + e.time + '</span>' +
33447- '</div>' +
33448- '<div class="lv-demo-event-body">' + e.body + '</div>' +
33449- '</div>' +
33450- '</div>';
33451- }).join('');
33452- }
33453-
33454- function renderStages() {
33455- var cards = document.querySelectorAll('.lv-stage-card');
33456- cards.forEach(function(card, i) {
33457- var dot = card.querySelector('.lv-dot');
33458- var meta = card.querySelector('.lv-stage-meta');
33459- if (i === stage) {
33460- card.classList.add('lv-stage-active');
33461- if (dot) {
33462- dot.classList.remove('lv-dot-idle');
33463- dot.classList.add('lv-dot-indigo', 'lv-pulse');
33464- }
33465- if (meta) meta.classList.add('lv-stage-meta-active');
33466- } else {
33467- card.classList.remove('lv-stage-active');
33468- if (dot) {
33469- dot.classList.add('lv-dot-idle');
33470- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
33471- }
33472- if (meta) meta.classList.remove('lv-stage-meta-active');
33473- }
33474- });
33475- }
33476-
33477- renderDemo();
33478-
33479- setInterval(function() {
33480- demoStep = (demoStep + 1) % 5;
33481- renderDemo();
33482- }, 3600);
33483-
33484- setInterval(function() {
33485- stage = (stage + 1) % 6;
33486- renderStages();
33487- }, 2200);
33488-})();
33489-`;
33490-
33491-const css = `
33492-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
33493-
33494-*, *::before, *::after { box-sizing: border-box; }
33495-
33496-body {
33497- margin: 0;
33498- background: #fcfcfd;
33499- -webkit-font-smoothing: antialiased;
33500- text-rendering: optimizeLegibility;
33501- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
33502- font-size: 15px;
33503- line-height: 1.6;
33504- letter-spacing: -0.008em;
33505- color: #16181d;
33506-}
33507-
33508-@keyframes gcPulse {
33509- 0%, 100% { opacity: 1; }
33510- 50% { opacity: 0.35; }
33511-}
33512-
33513-@keyframes gcTicker {
33514- 0% { transform: translateX(0); }
33515- 100% { transform: translateX(-50%); }
33516-}
33517-
33518-/* Shared utilities */
33519-.lv-dot {
33520- display: inline-block;
33521- border-radius: 50%;
33522-}
33523-.lv-dot-green { background: #1e7f5c; }
33524-.lv-dot-indigo { background: #4353c9; }
33525-.lv-dot-idle { background: #c4c6cf; }
33526-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
33527-
33528-.lv-strong { color: #16181d; font-weight: 600; }
33529-
33530-.lv-eyebrow {
33531- font-family: 'JetBrains Mono', monospace;
33532- font-size: 11px;
33533- letter-spacing: 0.12em;
33534- text-transform: uppercase;
33535- color: #8a8d99;
33536- font-weight: 500;
33537- margin-bottom: 12px;
33538-}
33539-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
33540-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
33541-
33542-.lv-h1 {
33543- font-family: 'Inter Tight', sans-serif;
33544- font-weight: 700;
33545- letter-spacing: -0.035em;
33546- font-size: clamp(44px, 7vw, 84px);
33547- line-height: 0.98;
33548- margin: 30px auto 0;
33549- max-width: 14ch;
33550- color: #111318;
33551-}
33552-
33553-.lv-h2 {
33554- font-family: 'Inter Tight', sans-serif;
33555- font-weight: 700;
33556- letter-spacing: -0.028em;
33557- font-size: clamp(30px, 4.4vw, 48px);
33558- line-height: 1.05;
33559- margin: 0;
33560- color: #111318;
33561-}
33562-
33563-.lv-h2-dark {
33564- font-family: 'Inter Tight', sans-serif;
33565- font-weight: 700;
33566- letter-spacing: -0.028em;
33567- font-size: clamp(30px, 4.6vw, 52px);
33568- line-height: 1.05;
33569- margin: 0;
33570- color: #fff;
33571-}
33572-
33573-.lv-section-header {
33574- max-width: 640px;
33575- margin: 0 auto 56px;
33576-}
33577-
33578-.lv-section-header-center {
33579- text-align: center;
33580-}
33581-
33582-.lv-section-sub {
33583- color: #6b7080;
33584- font-size: 17px;
33585- margin: 18px auto 0;
33586- max-width: 52ch;
33587-}
33588-
33589-.lv-section-sub-dark {
33590- color: rgba(255,255,255,0.72);
33591- font-size: 17px;
33592- margin: 18px auto 0;
33593- max-width: 56ch;
33594-}
33595-
33596-/* Nav */
33597-.lv-nav {
33598- position: sticky;
33599- top: 0;
33600- z-index: 60;
33601- backdrop-filter: saturate(180%) blur(14px);
33602- -webkit-backdrop-filter: saturate(180%) blur(14px);
33603- background: rgba(252,252,253,0.8);
33604- border-bottom: 1px solid rgba(22,24,29,0.07);
33605-}
33606-
33607-.lv-nav-inner {
33608- max-width: 1200px;
33609- margin: 0 auto;
33610- padding: 14px 28px;
33611- display: flex;
33612- align-items: center;
33613- gap: 28px;
33614-}
33615-
33616-.lv-logo {
33617- display: inline-flex;
33618- align-items: center;
33619- gap: 9px;
33620- font-family: 'Inter Tight', sans-serif;
33621- font-weight: 700;
33622- font-size: 17px;
33623- letter-spacing: -0.02em;
33624- color: #16181d;
33625- text-decoration: none;
33626-}
33627-
33628-.lv-logo-mark {
33629- width: 17px;
33630- height: 17px;
33631- border-radius: 5px;
33632- background: #4353c9;
33633- display: inline-block;
33634- flex-shrink: 0;
33635-}
33636-
33637-.lv-nav-links {
33638- display: flex;
33639- gap: 24px;
33640- font-size: 13.5px;
33641- font-weight: 500;
33642-}
33643-
33644-.lv-nav-link {
33645- color: #6b7080;
33646- text-decoration: none;
33647- transition: color 0.15s;
33648-}
33649-.lv-nav-link:hover { color: #16181d; }
33650-
33651-.lv-nav-ctas {
33652- margin-left: auto;
33653- display: flex;
33654- align-items: center;
33655- gap: 10px;
33656-}
33657-
33658-.lv-btn-secondary {
33659- padding: 8px 15px;
33660- border-radius: 8px;
33661- font-size: 13.5px;
33662- font-weight: 500;
33663- color: #16181d;
33664- border: 1px solid rgba(22,24,29,0.12);
33665- background: #ffffff;
33666- text-decoration: none;
33667- white-space: nowrap;
33668- transition: border-color 0.15s;
33669-}
33670-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
33671-
33672-.lv-btn-primary {
33673- padding: 8px 15px;
33674- border-radius: 8px;
33675- font-size: 13.5px;
33676- font-weight: 600;
33677- background: #16181d;
33678- color: #fff;
33679- text-decoration: none;
33680- white-space: nowrap;
33681- transition: box-shadow 0.15s;
33682-}
33683-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
33684-
33685-/* Hero */
33686-.lv-hero {
33687- position: relative;
33688- overflow: hidden;
33689- padding: 88px 0 0;
33690-}
33691-
33692-.lv-hero-glow {
33693- position: absolute;
33694- inset: -10% 0 auto 0;
33695- height: 640px;
33696- pointer-events: none;
33697- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
33698-}
33699-
33700-.lv-hero-inner {
33701- position: relative;
33702- max-width: 1200px;
33703- margin: 0 auto;
33704- padding: 0 28px;
33705- text-align: center;
33706-}
33707-
33708-.lv-hero-badge {
33709- display: inline-flex;
33710- align-items: center;
33711- gap: 9px;
33712- font-size: 12.5px;
33713- font-weight: 600;
33714- color: #3a3d45;
33715- background: #ffffff;
33716- border: 1px solid rgba(22,24,29,0.10);
33717- border-radius: 9999px;
33718- padding: 7px 16px;
33719- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
33720-}
33721-
33722-.lv-hero-sub {
33723- font-size: clamp(16px, 2vw, 19px);
33724- color: #6b7080;
33725- max-width: 60ch;
33726- margin: 24px auto 0;
33727- font-weight: 450;
33728- line-height: 1.65;
33729-}
33730-
33731-.lv-hero-actions {
33732- display: flex;
33733- gap: 12px;
33734- justify-content: center;
33735- flex-wrap: wrap;
33736- margin-top: 32px;
33737-}
33738-
33739-.lv-cta-primary {
33740- padding: 13px 24px;
33741- border-radius: 11px;
33742- font-size: 15.5px;
33743- font-weight: 600;
33744- background: #16181d;
33745- color: #fff;
33746- text-decoration: none;
33747- white-space: nowrap;
33748- transition: box-shadow 0.15s;
33749-}
33750-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
33751-
33752-.lv-cta-secondary {
33753- padding: 13px 24px;
33754- border-radius: 11px;
33755- font-size: 15.5px;
33756- font-weight: 600;
33757- color: #16181d;
33758- border: 1px solid rgba(22,24,29,0.14);
33759- background: #ffffff;
33760- text-decoration: none;
33761- white-space: nowrap;
33762- transition: border-color 0.15s;
33763-}
33764-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
33765-
33766-.lv-hero-tag {
33767- margin-top: 18px;
33768- font-family: 'JetBrains Mono', monospace;
33769- font-size: 11.5px;
33770- letter-spacing: 0.08em;
33771- text-transform: uppercase;
33772- color: #8a8d99;
33773-}
33774-
33775-/* Demo window */
33776-.lv-demo-window {
33777- margin: 56px auto 0;
33778- max-width: 860px;
33779- text-align: left;
33780- background: #ffffff;
33781- border: 1px solid rgba(22,24,29,0.09);
33782- border-radius: 18px;
33783- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
33784- overflow: hidden;
33785-}
33786-
33787-.lv-demo-bar {
33788- display: flex;
33789- align-items: center;
33790- gap: 7px;
33791- padding: 12px 18px;
33792- border-bottom: 1px solid rgba(22,24,29,0.07);
33793- background: #fcfcfd;
33794-}
33795-
33796-.lv-demo-dot {
33797- width: 10px;
33798- height: 10px;
33799- border-radius: 50%;
33800- background: #e4e5ea;
33801-}
33802-
33803-.lv-demo-url {
33804- margin-left: 10px;
33805- font-family: 'JetBrains Mono', monospace;
33806- font-size: 12px;
33807- color: #6b7080;
33808-}
33809-
33810-.lv-demo-live {
33811- margin-left: auto;
33812- display: inline-flex;
33813- align-items: center;
33814- gap: 6px;
33815- font-size: 11px;
33816- font-weight: 600;
33817- color: #1e7f5c;
33818-}
33819-
33820-.lv-demo-body {
33821- padding: 22px 24px;
33822-}
33823-
33824-.lv-demo-event {
33825- display: grid;
33826- grid-template-columns: 18px minmax(0, 1fr);
33827- gap: 14px;
33828- padding-bottom: 20px;
33829- position: relative;
33830-}
33831-.lv-demo-event:last-child { padding-bottom: 0; }
33832-
33833-.lv-demo-event-track {
33834- display: flex;
33835- flex-direction: column;
33836- align-items: center;
33837-}
33838-
33839-.lv-demo-line {
33840- width: 1px;
33841- flex: 1;
33842- background: rgba(22,24,29,0.08);
33843- margin-top: 5px;
33844- min-height: 20px;
33845-}
33846-
33847-.lv-demo-event-content {}
33848-
33849-.lv-demo-event-header {
33850- display: flex;
33851- align-items: baseline;
33852- gap: 10px;
33853-}
33854-
33855-.lv-demo-event-title {
33856- font-size: 13.5px;
33857- font-weight: 600;
33858- color: #16181d;
33859-}
33860-
33861-.lv-demo-event-time {
33862- font-family: 'JetBrains Mono', monospace;
33863- font-size: 11px;
33864- color: #8a8d99;
33865-}
33866-
33867-.lv-demo-event-body {
33868- font-size: 13px;
33869- color: #6b7080;
33870- margin-top: 2px;
33871-}
33872-
33873-/* Ticker */
33874-.lv-ticker-wrap {
33875- border-top: 1px solid rgba(22,24,29,0.07);
33876- border-bottom: 1px solid rgba(22,24,29,0.07);
33877- background: #ffffff;
33878- margin-top: 64px;
33879- overflow: hidden;
33880- white-space: nowrap;
33881- position: relative;
33882-}
33883-
33884-.lv-ticker-track {
33885- display: inline-flex;
33886- animation: gcTicker 40s linear infinite;
33887- padding: 11px 0;
33888-}
33889-
33890-.lv-ticker-item {
33891- display: inline-flex;
33892- align-items: center;
33893- gap: 8px;
33894- font-family: 'JetBrains Mono', monospace;
33895- font-size: 11.5px;
33896- color: #6b7080;
33897- padding: 0 28px;
33898- border-right: 1px solid rgba(22,24,29,0.06);
33899-}
33900-
33901-/* Stats */
33902-.lv-stats {
33903- background: #fcfcfd;
33904-}
33905-
33906-.lv-stats-inner {
33907- max-width: 1200px;
33908- margin: 0 auto;
33909- display: grid;
33910- grid-template-columns: repeat(4, 1fr);
33911- gap: 24px;
33912- padding: 52px 28px;
33913-}
33914-
33915-.lv-stat {
33916- text-align: center;
33917-}
33918-
33919-.lv-stat-num {
33920- font-family: 'Inter Tight', sans-serif;
33921- font-weight: 700;
33922- font-size: clamp(30px, 4vw, 44px);
33923- letter-spacing: -0.025em;
33924- color: #111318;
33925-}
33926-
33927-.lv-stat-label {
33928- font-size: 13px;
33929- color: #6b7080;
33930- margin-top: 4px;
33931-}
33932-
33933-/* Loop */
33934-.lv-loop {
33935- padding: 96px 0;
33936- background: #ffffff;
33937- border-top: 1px solid rgba(22,24,29,0.07);
33938- border-bottom: 1px solid rgba(22,24,29,0.07);
33939-}
33940-
33941-.lv-loop-inner {
33942- max-width: 1200px;
33943- margin: 0 auto;
33944- padding: 0 28px;
33945-}
33946-
33947-.lv-stages {
33948- display: grid;
33949- grid-template-columns: repeat(6, 1fr);
33950- gap: 12px;
33951-}
33952-
33953-.lv-stage-card {
33954- border: 1px solid rgba(22,24,29,0.08);
33955- border-radius: 14px;
33956- background: #ffffff;
33957- padding: 20px 18px;
33958- transition: border-color 0.3s, background 0.3s;
33959-}
33960-
33961-.lv-stage-card.lv-stage-active {
33962- border-color: rgba(67,83,201,0.45);
33963- background: rgba(67,83,201,0.03);
33964-}
33965-
33966-.lv-stage-header {
33967- display: flex;
33968- align-items: center;
33969- gap: 8px;
33970- margin-bottom: 10px;
33971-}
33972-
33973-.lv-stage-n {
33974- font-family: 'JetBrains Mono', monospace;
33975- font-size: 10.5px;
33976- letter-spacing: 0.1em;
33977- text-transform: uppercase;
33978- color: #8a8d99;
33979-}
33980-
33981-.lv-stage-name {
33982- font-family: 'Inter Tight', sans-serif;
33983- font-size: 16px;
33984- font-weight: 600;
33985- letter-spacing: -0.01em;
33986- color: #16181d;
33987- margin-bottom: 5px;
33988-}
33989-
33990-.lv-stage-desc {
33991- font-size: 12px;
33992- color: #6b7080;
33993- line-height: 1.55;
33994-}
33995-
33996-.lv-stage-meta {
33997- font-family: 'JetBrains Mono', monospace;
33998- font-size: 10.5px;
33999- color: #8a8d99;
34000- margin-top: 10px;
34001- transition: color 0.3s;
34002-}
34003-
34004-.lv-stage-meta.lv-stage-meta-active {
34005- color: #4353c9;
34006-}
34007-
34008-/* Heroes */
34009-.lv-heroes {
34010- padding: 96px 0;
34011- background: #fcfcfd;
34012-}
34013-
34014-.lv-heroes-inner {
34015- max-width: 1200px;
34016- margin: 0 auto;
34017- padding: 0 28px;
34018-}
34019-
34020-.lv-heroes-header {
34021- max-width: 640px;
34022- margin-bottom: 56px;
34023-}
34024-
34025-.lv-heroes-list {
34026- display: flex;
34027- flex-direction: column;
34028- gap: 20px;
34029-}
34030-
34031-.lv-hero-card {
34032- display: grid;
34033- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
34034- gap: 48px;
34035- align-items: center;
34036- border: 1px solid rgba(22,24,29,0.08);
34037- border-radius: 20px;
34038- background: #ffffff;
34039- padding: 44px 48px;
34040- text-decoration: none;
34041- transition: border-color 0.2s, box-shadow 0.2s;
34042-}
34043-.lv-hero-card:hover {
34044- border-color: rgba(22,24,29,0.22);
34045- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
34046-}
34047-
34048-.lv-hero-card-left {}
34049-
34050-.lv-hero-card-title {
34051- font-family: 'Inter Tight', sans-serif;
34052- font-size: 26px;
34053- font-weight: 600;
34054- letter-spacing: -0.022em;
34055- line-height: 1.15;
34056- color: #16181d;
34057- margin: 0 0 12px;
34058-}
34059-
34060-.lv-hero-card-body {
34061- font-size: 14.5px;
34062- color: #6b7080;
34063- margin: 0 0 18px;
34064- line-height: 1.65;
34065-}
34066-
34067-.lv-hero-card-cta {
34068- font-size: 13.5px;
34069- font-weight: 600;
34070- color: #4353c9;
34071-}
34072-
34073-.lv-terminal {
34074- border: 1px solid rgba(22,24,29,0.07);
34075- border-radius: 14px;
34076- background: #fcfcfd;
34077- padding: 20px 22px;
34078- font-family: 'JetBrains Mono', monospace;
34079- font-size: 12px;
34080- line-height: 1.9;
34081- overflow: hidden;
34082-}
34083-
34084-.lv-terminal-line {
34085- display: flex;
34086- align-items: center;
34087- gap: 10px;
34088- white-space: nowrap;
34089- overflow: hidden;
34090- text-overflow: ellipsis;
34091-}
34092-
34093-/* Platform */
34094-.lv-platform {
34095- padding: 96px 0;
34096- background: #ffffff;
34097- border-top: 1px solid rgba(22,24,29,0.07);
34098-}
34099-
34100-.lv-platform-inner {
34101- max-width: 1200px;
34102- margin: 0 auto;
34103- padding: 0 28px;
34104-}
34105-
34106-.lv-cap-grid {
34107- display: grid;
34108- grid-template-columns: repeat(4, 1fr);
34109- gap: 24px 32px;
34110-}
34111-
34112-.lv-cap-col {}
34113-
34114-.lv-cap-group {
34115- font-family: 'JetBrains Mono', monospace;
34116- font-size: 10.5px;
34117- letter-spacing: 0.12em;
34118- text-transform: uppercase;
34119- color: #8a8d99;
34120- font-weight: 500;
34121- margin-bottom: 12px;
34122- padding-bottom: 8px;
34123- border-bottom: 1px solid rgba(22,24,29,0.07);
34124-}
34125-
34126-.lv-cap-items {
34127- display: flex;
34128- flex-direction: column;
34129- gap: 7px;
34130-}
34131-
34132-.lv-cap-item {
34133- font-size: 12.5px;
34134- color: #3a3d45;
34135- line-height: 1.45;
34136-}
34137-
34138-/* Sovereignty */
34139-.lv-sovereign {
34140- position: relative;
34141- overflow: hidden;
34142- padding: 104px 0;
34143- color: #fff;
34144- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
34145-}
34146-
34147-.lv-sovereign-grid-bg {
34148- position: absolute;
34149- inset: 0;
34150- opacity: 0.4;
34151- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
34152- background-size: 56px 56px;
34153- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
34154- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
34155-}
34156-
34157-.lv-sovereign-inner {
34158- position: relative;
34159- max-width: 1200px;
34160- margin: 0 auto;
34161- padding: 0 28px;
34162-}
34163-
34164-.lv-section-header-dark {
34165- max-width: 680px;
34166- margin: 0 auto 48px;
34167- text-align: center;
34168-}
34169-
34170-.lv-layers-grid {
34171- display: grid;
34172- grid-template-columns: repeat(4, 1fr);
34173- gap: 10px;
34174- max-width: 980px;
34175- margin: 0 auto;
34176-}
34177-
34178-.lv-layer-chip {
34179- border: 1px solid rgba(255,255,255,0.10);
34180- border-radius: 10px;
34181- padding: 12px 16px;
34182- background: rgba(255,255,255,0.03);
34183-}
34184-
34185-.lv-layer-cta {
34186- border-color: rgba(169,180,238,0.30);
34187- background: rgba(169,180,238,0.06);
34188- display: flex;
34189- align-items: center;
34190- text-decoration: none;
34191- transition: background 0.15s;
34192-}
34193-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
34194-
34195-.lv-layer-cta-text {
34196- font-size: 13px;
34197- font-weight: 500;
34198- color: #a9b4ee;
34199-}
34200-
34201-.lv-layer-n {
34202- font-family: 'JetBrains Mono', monospace;
34203- font-size: 10px;
34204- color: rgba(255,255,255,0.4);
34205- margin-bottom: 3px;
34206-}
34207-
34208-.lv-layer-name {
34209- font-size: 13px;
34210- font-weight: 500;
34211- color: rgba(255,255,255,0.92);
34212-}
34213-
34214-.lv-sovereign-feats {
34215- display: flex;
34216- gap: 44px;
34217- justify-content: center;
34218- flex-wrap: wrap;
34219- margin-top: 52px;
34220- text-align: center;
34221-}
34222-
34223-.lv-sovereign-feat {}
34224-
34225-.lv-sovereign-feat-title {
34226- font-family: 'Inter Tight', sans-serif;
34227- font-size: 20px;
34228- font-weight: 700;
34229- color: #fff;
34230-}
34231-
34232-.lv-sovereign-feat-sub {
34233- color: rgba(255,255,255,0.55);
34234- font-size: 13px;
34235- margin-top: 2px;
34236-}
34237-
34238-/* Twin cards */
34239-.lv-twin {
34240- padding: 96px 0;
34241- background: #fcfcfd;
34242-}
34243-
34244-.lv-twin-inner {
34245- max-width: 1200px;
34246- margin: 0 auto;
34247- padding: 0 28px;
34248- display: grid;
34249- grid-template-columns: 1fr 1fr;
34250- gap: 24px;
34251-}
34252-
34253-.lv-twin-card {
34254- border: 1px solid rgba(22,24,29,0.08);
34255- border-radius: 20px;
34256- background: #ffffff;
34257- padding: 44px 48px;
34258-}
34259-
34260-.lv-twin-title {
34261- font-family: 'Inter Tight', sans-serif;
34262- font-size: 24px;
34263- font-weight: 600;
34264- letter-spacing: -0.02em;
34265- line-height: 1.2;
34266- margin: 0 0 12px;
34267- color: #16181d;
34268-}
34269-
34270-.lv-twin-body {
34271- font-size: 14.5px;
34272- color: #6b7080;
34273- margin: 0 0 16px;
34274- line-height: 1.7;
34275-}
34276-
34277-.lv-twin-link {
34278- font-size: 13.5px;
34279- font-weight: 600;
34280- color: #4353c9;
34281- text-decoration: none;
34282-}
34283-.lv-twin-link:hover { text-decoration: underline; }
34284-
34285-/* Quote */
34286-.lv-quote {
34287- padding: 40px 0 96px;
34288- background: #fcfcfd;
34289-}
34290-
34291-.lv-quote-inner {
34292- max-width: 980px;
34293- margin: 0 auto;
34294- padding: 0 28px;
34295- text-align: center;
34296-}
34297-
34298-.lv-quote-text {
34299- font-family: 'Inter Tight', sans-serif;
34300- font-weight: 600;
34301- font-size: clamp(26px, 3.8vw, 42px);
34302- line-height: 1.2;
34303- letter-spacing: -0.025em;
34304- margin: 0;
34305- color: #111318;
34306-}
34307-
34308-.lv-em {
34309- font-style: normal;
34310- color: #4353c9;
34311-}
34312-
34313-/* CTA */
34314-.lv-cta-section {
34315- padding: 0 0 104px;
34316- background: #fcfcfd;
34317-}
34318-
34319-.lv-cta-card {
34320- max-width: 820px;
34321- margin: 0 auto;
34322- padding: 64px 40px;
34323- text-align: center;
34324- background: #ffffff;
34325- border: 1px solid rgba(22,24,29,0.08);
34326- border-radius: 26px;
34327- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
34328- position: relative;
34329- overflow: hidden;
34330-}
34331-
34332-.lv-cta-glow {
34333- position: absolute;
34334- inset: -40% 0 auto 0;
34335- height: 280px;
34336- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
34337- pointer-events: none;
34338-}
34339-
34340-.lv-cta-h2 {
34341- font-family: 'Inter Tight', sans-serif;
34342- font-weight: 700;
34343- letter-spacing: -0.028em;
34344- font-size: clamp(30px, 4.6vw, 48px);
34345- margin: 0;
34346- position: relative;
34347- color: #111318;
34348-}
34349-
34350-.lv-cta-sub {
34351- color: #6b7080;
34352- font-size: 17px;
34353- margin: 16px 0 30px;
34354- position: relative;
34355-}
34356-
34357-.lv-cta-actions {
34358- display: flex;
34359- gap: 12px;
34360- justify-content: center;
34361- flex-wrap: wrap;
34362- position: relative;
34363-}
34364-
34365-.lv-cta-fine {
34366- margin-top: 20px;
34367- font-family: 'JetBrains Mono', monospace;
34368- font-size: 11px;
34369- color: #8a8d99;
34370- position: relative;
34371-}
34372-
34373-/* Footer */
34374-.lv-footer {
34375- border-top: 1px solid rgba(22,24,29,0.07);
34376- background: #ffffff;
34377- padding: 56px 0 30px;
34378-}
34379-
34380-.lv-footer-inner {
34381- max-width: 1200px;
34382- margin: 0 auto;
34383- padding: 0 28px;
34384- display: flex;
34385- gap: 48px;
34386- flex-wrap: wrap;
34387- justify-content: space-between;
34388-}
34389-
34390-.lv-footer-brand {}
34391-
34392-.lv-footer-tagline {
34393- color: #6b7080;
34394- font-size: 13.5px;
34395- margin: 12px 0 0;
34396- max-width: 32ch;
34397- line-height: 1.6;
34398-}
34399-
34400-.lv-footer-cols {
34401- display: flex;
34402- gap: 64px;
34403- flex-wrap: wrap;
34404-}
34405-
34406-.lv-footer-col {
34407- display: flex;
34408- flex-direction: column;
34409- gap: 9px;
34410-}
34411-
34412-.lv-footer-col-head {
34413- font-family: 'JetBrains Mono', monospace;
34414- font-size: 11px;
34415- text-transform: uppercase;
34416- letter-spacing: 0.1em;
34417- color: #8a8d99;
34418- margin: 0 0 4px;
34419- font-weight: 500;
34420-}
34421-
34422-.lv-footer-link {
34423- color: #3a3d45;
34424- font-size: 13.5px;
34425- text-decoration: none;
34426- transition: color 0.15s;
34427-}
34428-.lv-footer-link:hover { color: #16181d; }
34429-
34430-.lv-footer-bar {
34431- max-width: 1200px;
34432- margin: 44px auto 0;
34433- padding: 22px 28px 0;
34434- border-top: 1px solid rgba(22,24,29,0.06);
34435- display: flex;
34436- justify-content: space-between;
34437- flex-wrap: wrap;
34438- gap: 8px;
34439- color: #8a8d99;
34440- font-size: 12.5px;
34441-}
34442-
34443-.lv-footer-stack {
34444- font-family: 'JetBrains Mono', monospace;
34445- font-size: 11px;
34446-}
34447-`;
34448diff --git a/src/views/layout.tsx b/src/views/layout.tsx
34449index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
34450--- a/src/views/layout.tsx
34451+++ b/src/views/layout.tsx
34452@@ -3153,9 +3153,12 @@
34453 font-weight: 500;
34454 line-height: 1.4;
34455 }
34456- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
34457- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
34458- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
34459+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
34460+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
34461+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
34462+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
34463+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
34464+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
34465 .state-merged { color: var(--accent); }
34466 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
34467
34468diff --git a/src/views/ui.tsx b/src/views/ui.tsx
34469index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
34470--- a/src/views/ui.tsx
34471+++ b/src/views/ui.tsx
34472@@ -232,7 +232,7 @@
34473
34474 export const Badge: FC<
34475 PropsWithChildren<{
34476- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
34477+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
34478 style?: string;
34479 }>
34480 > = ({ children, variant = "default", style }) => {
34481@@ -241,9 +241,12 @@
34482 variant === "closed" ? "badge-closed" :
34483 variant === "merged" ? "badge-merged" :
34484 variant === "success" ? "badge-success" :
34485- variant === "danger" ? "badge-danger" :
34486- variant === "warning" ? "badge-warning" :
34487- "badge";
34488+ variant === "danger" ? "badge-danger" :
34489+ variant === "warning" ? "badge-warning" :
34490+ variant === "live" ? "badge-live" :
34491+ variant === "soon" ? "badge-soon" :
34492+ variant === "preview" ? "badge-preview" :
34493+ "badge";
34494 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
34495 };
34496
34497
34498diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
34499index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
34500--- a/src/views/landing-pro.tsx
34501+++ b/src/views/landing-pro.tsx
34502@@ -42,7 +42,7 @@
34503
34504 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34505
34506-function icon(paths: string, color = "#4353c9", size = 20) {
34507+function icon(paths: string, color = "#0891b2", size = 20) {
34508 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
34509 }
34510
34511@@ -947,7 +947,7 @@
34512 const css = `
34513 /* %% tokens %% */
34514 :root{
34515- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
34516+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
34517 --lp-bg:#ffffff;--lp-soft:#fafafb;
34518 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
34519 --lp-border:rgba(0,0,0,.08);
34520diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
34521deleted file mode 100644
34522index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
34523--- a/src/views/landing-v2.tsx
34524+++ /dev/null
34525@@ -1,1447 +0,0 @@
34526-import type { FC } from "hono/jsx";
34527-
34528-export interface LandingPageProps {
34529- stats?: {
34530- publicRepos?: number;
34531- users?: number;
34532- };
34533-}
34534-
34535-const demoAllEvents = [
34536- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
34537- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
34538- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
34539- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
34540- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
34541-];
34542-
34543-const tickerItems = [
34544- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
34545- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
34546- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
34547- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
34548- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
34549- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
34550- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
34551- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
34552- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
34553- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
34554- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
34555- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
34556- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
34557- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
34558- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
34559- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
34560-];
34561-
34562-const stageData = [
34563- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
34564- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
34565- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
34566- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
34567- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
34568- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
34569-];
34570-
34571-const heroFeatures = [
34572- {
34573- href: "/",
34574- eyebrow: "01 � The autonomous repair loop",
34575- title: "Failures fix themselves  and show their work.",
34576- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
34577failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
34578- cta: "Watch a live repair session",
34579- mock: [
34580- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
34581- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
34582- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
34583- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
34584- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
34585- ],
34586- },
34587- {
34588- href: "/",
34589- eyebrow: "02 � Live sandbox isolation",
34590- title: "Every PR gets its own instant, disposable environment.",
34591- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
34592same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
34593- cta: "See a PR with its sandbox",
34594- mock: [
34595- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
34596- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
34597- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
34598- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
34599- ],
34600- },
34601- {
34602- href: "/",
34603- eyebrow: "03 � Multiplayer IDE workspaces",
34604- title: "You and the agent, side by side, in your editor.",
34605- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
34606agent into a silent reviewer in your gutter. The browser becomes optional.",
34607- cta: "See the editor session",
34608- mock: [
34609- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
34610- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
34611- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
34612- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
34613- ],
34614- },
34615-];
34616-
34617-const capabilities = [
34618- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
34619- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
34620- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
34621- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
34622- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
34623- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
34624- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
34625- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
34626-];
34627-
34628-const sovereignLayerNames = [
34629- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
34630- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
34631- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
34632- "Availability & recovery",
34633-];
34634-
34635-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
34636- return (
34637- <>
34638- <style dangerouslySetInnerHTML={{ __html: css }} />
34639-
34640- {/* Nav */}
34641- <header class="lv-nav">
34642- <div class="lv-nav-inner">
34643- <a href="/" class="lv-logo">
34644- <span class="lv-logo-mark"></span>gluecron
34645- </a>
34646- <nav class="lv-nav-links">
34647- <a href="#loop" class="lv-nav-link">The loop</a>
34648- <a href="#platform" class="lv-nav-link">Platform</a>
34649- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
34650- <a href="/trust" class="lv-nav-link">Trust</a>
34651- </nav>
34652- <div class="lv-nav-ctas">
34653- <a href="/login" class="lv-btn-secondary">Sign in</a>
34654- <a href="/register" class="lv-btn-primary">Start building</a>
34655- </div>
34656- </div>
34657- </header>
34658-
34659- {/* Hero */}
34660- <section class="lv-hero">
34661- <div class="lv-hero-glow"></div>
34662- <div class="lv-hero-inner">
34663- <div class="lv-hero-badge">
34664- <span class="lv-dot lv-dot-green lv-pulse"></span>
34665- Live: a repair loop converged on pr-218 while you read this
34666- </div>
34667- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
34668- <p class="lv-hero-sub">
34669- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
34670failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
34671- </p>
34672- <div class="lv-hero-actions">
34673- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
34674- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
34675- </div>
34676- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
34677-
34678- {/* Live product window */}
34679- <div class="lv-demo-window">
34680- <div class="lv-demo-bar">
34681- <span class="lv-demo-dot"></span>
34682- <span class="lv-demo-dot"></span>
34683- <span class="lv-demo-dot"></span>
34684- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
34685- <span class="lv-demo-live">
34686- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
34687- LIVE
34688- </span>
34689- </div>
34690- <div class="lv-demo-body" id="lv-demo-body">
34691- {/* Events rendered by JS */}
34692- {demoAllEvents.slice(0, 1).map((e, i) => (
34693- <div class="lv-demo-event" key={i}>
34694- <div class="lv-demo-event-track">
34695- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
34696- <span class="lv-demo-line" style="display:none"></span>
34697- </div>
34698- <div class="lv-demo-event-content">
34699- <div class="lv-demo-event-header">
34700- <span class="lv-demo-event-title">{e.title}</span>
34701- <span class="lv-demo-event-time">{e.time}</span>
34702- </div>
34703- <div class="lv-demo-event-body">{e.body}</div>
34704- </div>
34705- </div>
34706- ))}
34707- </div>
34708- </div>
34709- </div>
34710-
34711- {/* Activity ticker */}
34712- <div class="lv-ticker-wrap">
34713- <div class="lv-ticker-track">
34714- {tickerItems.map((t, i) => (
34715- <span class="lv-ticker-item" key={i}>
34716- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
34717- {t.text}
34718- </span>
34719- ))}
34720- </div>
34721- </div>
34722- </section>
34723-
34724- {/* Stat band */}
34725- <section class="lv-stats">
34726- <div class="lv-stats-inner">
34727- <div class="lv-stat">
34728- <div class="lv-stat-num">Sonnet 5</div>
34729- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
34730- </div>
34731- <div class="lv-stat">
34732- <div class="lv-stat-num">93.5%</div>
34733- <div class="lv-stat-label">of failures self-repair without a human</div>
34734- </div>
34735- <div class="lv-stat">
34736- <div class="lv-stat-num">1.9%</div>
34737- <div class="lv-stat-label">AI merges reverted  published live</div>
34738- </div>
34739- <div class="lv-stat">
34740- <div class="lv-stat-num">0</div>
34741- <div class="lv-stat-label">irreversible actions taken autonomously</div>
34742- </div>
34743- </div>
34744- </section>
34745-
34746- {/* The loop */}
34747- <section id="loop" class="lv-loop">
34748- <div class="lv-loop-inner">
34749- <div class="lv-section-header">
34750- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
34751- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
34752- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
34753- </div>
34754- <div class="lv-stages" id="lv-stages">
34755- {stageData.map((s, i) => (
34756- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
34757- <div class="lv-stage-header">
34758- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
34759- <span class="lv-stage-n">0{i + 1}</span>
34760- </div>
34761- <div class="lv-stage-name">{s.name}</div>
34762- <div class="lv-stage-desc">{s.desc}</div>
34763- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
34764- </div>
34765- ))}
34766- </div>
34767- </div>
34768- </section>
34769-
34770- {/* Three heroes */}
34771- <section class="lv-heroes">
34772- <div class="lv-heroes-inner">
34773- <div class="lv-heroes-header">
34774- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
34775- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
34776- </div>
34777- <div class="lv-heroes-list">
34778- {heroFeatures.map((h, i) => (
34779- <a href={h.href} class="lv-hero-card" key={i}>
34780- <div class="lv-hero-card-left">
34781- <div class="lv-eyebrow">{h.eyebrow}</div>
34782- <h3 class="lv-hero-card-title">{h.title}</h3>
34783- <p class="lv-hero-card-body">{h.body}</p>
34784- <span class="lv-hero-card-cta">{h.cta} �!</span>
34785- </div>
34786- <div class="lv-terminal">
34787- {h.mock.map((m, j) => (
34788- <div class="lv-terminal-line" key={j}>
34789- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
34790- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
34791- </div>
34792- ))}
34793- </div>
34794- </a>
34795- ))}
34796- </div>
34797- </div>
34798- </section>
34799-
34800- {/* Everything grid */}
34801- <section id="platform" class="lv-platform">
34802- <div class="lv-platform-inner">
34803- <div class="lv-section-header lv-section-header-center">
34804- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
34805- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
34806- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
34807- </div>
34808- <div class="lv-cap-grid">
34809- {capabilities.map((c, i) => (
34810- <div class="lv-cap-col" key={i}>
34811- <div class="lv-cap-group">{c.group}</div>
34812- <div class="lv-cap-items">
34813- {c.items.map((item, j) => (
34814- <div class="lv-cap-item" key={j}>{item}</div>
34815- ))}
34816- </div>
34817- </div>
34818- ))}
34819- </div>
34820- </div>
34821- </section>
34822-
34823- {/* Sovereignty band */}
34824- <section id="sovereign" class="lv-sovereign">
34825- <div class="lv-sovereign-grid-bg"></div>
34826- <div class="lv-sovereign-inner">
34827- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
34828- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
34829- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
34830- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
34831to private cloud, or run fully air-gapped on bare metal.</p>
34832- </div>
34833- <div class="lv-layers-grid">
34834- {sovereignLayerNames.map((name, i) => (
34835- <div class="lv-layer-chip" key={i}>
34836- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
34837- <div class="lv-layer-name">{name}</div>
34838- </div>
34839- ))}
34840- <a href="/" class="lv-layer-chip lv-layer-cta">
34841- <div class="lv-layer-cta-text">All self-owned �!</div>
34842- </a>
34843- </div>
34844- <div class="lv-sovereign-feats">
34845- <div class="lv-sovereign-feat">
34846- <div class="lv-sovereign-feat-title">Local inference first</div>
34847- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
34848- </div>
34849- <div class="lv-sovereign-feat">
34850- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
34851- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
34852- </div>
34853- <div class="lv-sovereign-feat">
34854- <div class="lv-sovereign-feat-title">Self-healing infra</div>
34855- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
34856- </div>
34857- </div>
34858- </div>
34859- </section>
34860-
34861- {/* Manual-first + reversibility */}
34862- <section class="lv-twin">
34863- <div class="lv-twin-inner">
34864- <div class="lv-twin-card">
34865- <div class="lv-eyebrow">Manual-first, always</div>
34866- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
34867- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
34868fallback. Developers who never touch AI get the best git host they've ever used.</p>
34869- </div>
34870- <div class="lv-twin-card">
34871- <div class="lv-eyebrow">The reversibility guarantee</div>
34872- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
34873- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
34874 policy, not promise. Our quality numbers are published live, unedited.</p>
34875- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
34876- </div>
34877- </div>
34878- </section>
34879-
34880- {/* Quote */}
34881- <section class="lv-quote">
34882- <div class="lv-quote-inner">
34883- <p class="lv-quote-text">
34884- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
34885- Gluecron is where code gets <em class="lv-em">finished</em>."
34886- </p>
34887- </div>
34888- </section>
34889-
34890- {/* CTA */}
34891- <section class="lv-cta-section">
34892- <div class="lv-cta-card">
34893- <div class="lv-cta-glow"></div>
34894- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
34895- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
34896- <div class="lv-cta-actions">
34897- <a href="/register" class="lv-cta-primary">Create your account �!</a>
34898- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
34899- </div>
34900- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
34901- </div>
34902- </section>
34903-
34904- {/* Footer */}
34905- <footer class="lv-footer">
34906- <div class="lv-footer-inner">
34907- <div class="lv-footer-brand">
34908- <a href="/" class="lv-logo">
34909- <span class="lv-logo-mark"></span>gluecron
34910- </a>
34911- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
34912- </div>
34913- <div class="lv-footer-cols">
34914- <div class="lv-footer-col">
34915- <h4 class="lv-footer-col-head">Product</h4>
34916- <a href="/" class="lv-footer-link">Agent workspace</a>
34917- <a href="/" class="lv-footer-link">Fleet refactors</a>
34918- <a href="/" class="lv-footer-link">Org memory</a>
34919- <a href="/" class="lv-footer-link">IDE extensions</a>
34920- </div>
34921- <div class="lv-footer-col">
34922- <h4 class="lv-footer-col-head">Platform</h4>
34923- <a href="/" class="lv-footer-link">Production layers</a>
34924- <a href="/trust" class="lv-footer-link">Trust report</a>
34925- <a href="/" class="lv-footer-link">Docs</a>
34926- <a href="/" class="lv-footer-link">Status</a>
34927- </div>
34928- <div class="lv-footer-col">
34929- <h4 class="lv-footer-col-head">Company</h4>
34930- <a href="/" class="lv-footer-link">About</a>
34931- <a href="/" class="lv-footer-link">Pricing</a>
34932- <a href="/" class="lv-footer-link">Enterprise</a>
34933- </div>
34934- </div>
34935- </div>
34936- <div class="lv-footer-bar">
34937- <span>� 2026 Gluecron</span>
34938- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
34939- </div>
34940- </footer>
34941-
34942- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
34943- </>
34944- );
34945-};
34946-
34947-export const LandingPage = LandingPageV2;
34948-export default LandingPageV2;
34949-
34950-const clientScript = `
34951-(function() {
34952- var demoAll = [
34953- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
34954- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
34955- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
34956- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
34957- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
34958- ];
34959-
34960- var demoStep = 0;
34961- var stage = 0;
34962-
34963- function renderDemo() {
34964- var container = document.getElementById('lv-demo-body');
34965- if (!container) return;
34966- var visible = demoAll.slice(0, demoStep + 1);
34967- container.innerHTML = visible.map(function(e, i) {
34968- var isLast = i === visible.length - 1;
34969- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
34970- return '<div class="lv-demo-event">' +
34971- '<div class="lv-demo-event-track">' +
34972- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
34973- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
34974- '</div>' +
34975- '<div class="lv-demo-event-content">' +
34976- '<div class="lv-demo-event-header">' +
34977- '<span class="lv-demo-event-title">' + e.title + '</span>' +
34978- '<span class="lv-demo-event-time">' + e.time + '</span>' +
34979- '</div>' +
34980- '<div class="lv-demo-event-body">' + e.body + '</div>' +
34981- '</div>' +
34982- '</div>';
34983- }).join('');
34984- }
34985-
34986- function renderStages() {
34987- var cards = document.querySelectorAll('.lv-stage-card');
34988- cards.forEach(function(card, i) {
34989- var dot = card.querySelector('.lv-dot');
34990- var meta = card.querySelector('.lv-stage-meta');
34991- if (i === stage) {
34992- card.classList.add('lv-stage-active');
34993- if (dot) {
34994- dot.classList.remove('lv-dot-idle');
34995- dot.classList.add('lv-dot-indigo', 'lv-pulse');
34996- }
34997- if (meta) meta.classList.add('lv-stage-meta-active');
34998- } else {
34999- card.classList.remove('lv-stage-active');
35000- if (dot) {
35001- dot.classList.add('lv-dot-idle');
35002- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
35003- }
35004- if (meta) meta.classList.remove('lv-stage-meta-active');
35005- }
35006- });
35007- }
35008-
35009- renderDemo();
35010-
35011- setInterval(function() {
35012- demoStep = (demoStep + 1) % 5;
35013- renderDemo();
35014- }, 3600);
35015-
35016- setInterval(function() {
35017- stage = (stage + 1) % 6;
35018- renderStages();
35019- }, 2200);
35020-})();
35021-`;
35022-
35023-const css = `
35024-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
35025-
35026-*, *::before, *::after { box-sizing: border-box; }
35027-
35028-body {
35029- margin: 0;
35030- background: #fcfcfd;
35031- -webkit-font-smoothing: antialiased;
35032- text-rendering: optimizeLegibility;
35033- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
35034- font-size: 15px;
35035- line-height: 1.6;
35036- letter-spacing: -0.008em;
35037- color: #16181d;
35038-}
35039-
35040-@keyframes gcPulse {
35041- 0%, 100% { opacity: 1; }
35042- 50% { opacity: 0.35; }
35043-}
35044-
35045-@keyframes gcTicker {
35046- 0% { transform: translateX(0); }
35047- 100% { transform: translateX(-50%); }
35048-}
35049-
35050-/* Shared utilities */
35051-.lv-dot {
35052- display: inline-block;
35053- border-radius: 50%;
35054-}
35055-.lv-dot-green { background: #1e7f5c; }
35056-.lv-dot-indigo { background: #4353c9; }
35057-.lv-dot-idle { background: #c4c6cf; }
35058-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
35059-
35060-.lv-strong { color: #16181d; font-weight: 600; }
35061-
35062-.lv-eyebrow {
35063- font-family: 'JetBrains Mono', monospace;
35064- font-size: 11px;
35065- letter-spacing: 0.12em;
35066- text-transform: uppercase;
35067- color: #8a8d99;
35068- font-weight: 500;
35069- margin-bottom: 12px;
35070-}
35071-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
35072-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
35073-
35074-.lv-h1 {
35075- font-family: 'Inter Tight', sans-serif;
35076- font-weight: 700;
35077- letter-spacing: -0.035em;
35078- font-size: clamp(44px, 7vw, 84px);
35079- line-height: 0.98;
35080- margin: 30px auto 0;
35081- max-width: 14ch;
35082- color: #111318;
35083-}
35084-
35085-.lv-h2 {
35086- font-family: 'Inter Tight', sans-serif;
35087- font-weight: 700;
35088- letter-spacing: -0.028em;
35089- font-size: clamp(30px, 4.4vw, 48px);
35090- line-height: 1.05;
35091- margin: 0;
35092- color: #111318;
35093-}
35094-
35095-.lv-h2-dark {
35096- font-family: 'Inter Tight', sans-serif;
35097- font-weight: 700;
35098- letter-spacing: -0.028em;
35099- font-size: clamp(30px, 4.6vw, 52px);
35100- line-height: 1.05;
35101- margin: 0;
35102- color: #fff;
35103-}
35104-
35105-.lv-section-header {
35106- max-width: 640px;
35107- margin: 0 auto 56px;
35108-}
35109-
35110-.lv-section-header-center {
35111- text-align: center;
35112-}
35113-
35114-.lv-section-sub {
35115- color: #6b7080;
35116- font-size: 17px;
35117- margin: 18px auto 0;
35118- max-width: 52ch;
35119-}
35120-
35121-.lv-section-sub-dark {
35122- color: rgba(255,255,255,0.72);
35123- font-size: 17px;
35124- margin: 18px auto 0;
35125- max-width: 56ch;
35126-}
35127-
35128-/* Nav */
35129-.lv-nav {
35130- position: sticky;
35131- top: 0;
35132- z-index: 60;
35133- backdrop-filter: saturate(180%) blur(14px);
35134- -webkit-backdrop-filter: saturate(180%) blur(14px);
35135- background: rgba(252,252,253,0.8);
35136- border-bottom: 1px solid rgba(22,24,29,0.07);
35137-}
35138-
35139-.lv-nav-inner {
35140- max-width: 1200px;
35141- margin: 0 auto;
35142- padding: 14px 28px;
35143- display: flex;
35144- align-items: center;
35145- gap: 28px;
35146-}
35147-
35148-.lv-logo {
35149- display: inline-flex;
35150- align-items: center;
35151- gap: 9px;
35152- font-family: 'Inter Tight', sans-serif;
35153- font-weight: 700;
35154- font-size: 17px;
35155- letter-spacing: -0.02em;
35156- color: #16181d;
35157- text-decoration: none;
35158-}
35159-
35160-.lv-logo-mark {
35161- width: 17px;
35162- height: 17px;
35163- border-radius: 5px;
35164- background: #4353c9;
35165- display: inline-block;
35166- flex-shrink: 0;
35167-}
35168-
35169-.lv-nav-links {
35170- display: flex;
35171- gap: 24px;
35172- font-size: 13.5px;
35173- font-weight: 500;
35174-}
35175-
35176-.lv-nav-link {
35177- color: #6b7080;
35178- text-decoration: none;
35179- transition: color 0.15s;
35180-}
35181-.lv-nav-link:hover { color: #16181d; }
35182-
35183-.lv-nav-ctas {
35184- margin-left: auto;
35185- display: flex;
35186- align-items: center;
35187- gap: 10px;
35188-}
35189-
35190-.lv-btn-secondary {
35191- padding: 8px 15px;
35192- border-radius: 8px;
35193- font-size: 13.5px;
35194- font-weight: 500;
35195- color: #16181d;
35196- border: 1px solid rgba(22,24,29,0.12);
35197- background: #ffffff;
35198- text-decoration: none;
35199- white-space: nowrap;
35200- transition: border-color 0.15s;
35201-}
35202-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
35203-
35204-.lv-btn-primary {
35205- padding: 8px 15px;
35206- border-radius: 8px;
35207- font-size: 13.5px;
35208- font-weight: 600;
35209- background: #16181d;
35210- color: #fff;
35211- text-decoration: none;
35212- white-space: nowrap;
35213- transition: box-shadow 0.15s;
35214-}
35215-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
35216-
35217-/* Hero */
35218-.lv-hero {
35219- position: relative;
35220- overflow: hidden;
35221- padding: 88px 0 0;
35222-}
35223-
35224-.lv-hero-glow {
35225- position: absolute;
35226- inset: -10% 0 auto 0;
35227- height: 640px;
35228- pointer-events: none;
35229- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
35230-}
35231-
35232-.lv-hero-inner {
35233- position: relative;
35234- max-width: 1200px;
35235- margin: 0 auto;
35236- padding: 0 28px;
35237- text-align: center;
35238-}
35239-
35240-.lv-hero-badge {
35241- display: inline-flex;
35242- align-items: center;
35243- gap: 9px;
35244- font-size: 12.5px;
35245- font-weight: 600;
35246- color: #3a3d45;
35247- background: #ffffff;
35248- border: 1px solid rgba(22,24,29,0.10);
35249- border-radius: 9999px;
35250- padding: 7px 16px;
35251- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
35252-}
35253-
35254-.lv-hero-sub {
35255- font-size: clamp(16px, 2vw, 19px);
35256- color: #6b7080;
35257- max-width: 60ch;
35258- margin: 24px auto 0;
35259- font-weight: 450;
35260- line-height: 1.65;
35261-}
35262-
35263-.lv-hero-actions {
35264- display: flex;
35265- gap: 12px;
35266- justify-content: center;
35267- flex-wrap: wrap;
35268- margin-top: 32px;
35269-}
35270-
35271-.lv-cta-primary {
35272- padding: 13px 24px;
35273- border-radius: 11px;
35274- font-size: 15.5px;
35275- font-weight: 600;
35276- background: #16181d;
35277- color: #fff;
35278- text-decoration: none;
35279- white-space: nowrap;
35280- transition: box-shadow 0.15s;
35281-}
35282-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
35283-
35284-.lv-cta-secondary {
35285- padding: 13px 24px;
35286- border-radius: 11px;
35287- font-size: 15.5px;
35288- font-weight: 600;
35289- color: #16181d;
35290- border: 1px solid rgba(22,24,29,0.14);
35291- background: #ffffff;
35292- text-decoration: none;
35293- white-space: nowrap;
35294- transition: border-color 0.15s;
35295-}
35296-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
35297-
35298-.lv-hero-tag {
35299- margin-top: 18px;
35300- font-family: 'JetBrains Mono', monospace;
35301- font-size: 11.5px;
35302- letter-spacing: 0.08em;
35303- text-transform: uppercase;
35304- color: #8a8d99;
35305-}
35306-
35307-/* Demo window */
35308-.lv-demo-window {
35309- margin: 56px auto 0;
35310- max-width: 860px;
35311- text-align: left;
35312- background: #ffffff;
35313- border: 1px solid rgba(22,24,29,0.09);
35314- border-radius: 18px;
35315- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
35316- overflow: hidden;
35317-}
35318-
35319-.lv-demo-bar {
35320- display: flex;
35321- align-items: center;
35322- gap: 7px;
35323- padding: 12px 18px;
35324- border-bottom: 1px solid rgba(22,24,29,0.07);
35325- background: #fcfcfd;
35326-}
35327-
35328-.lv-demo-dot {
35329- width: 10px;
35330- height: 10px;
35331- border-radius: 50%;
35332- background: #e4e5ea;
35333-}
35334-
35335-.lv-demo-url {
35336- margin-left: 10px;
35337- font-family: 'JetBrains Mono', monospace;
35338- font-size: 12px;
35339- color: #6b7080;
35340-}
35341-
35342-.lv-demo-live {
35343- margin-left: auto;
35344- display: inline-flex;
35345- align-items: center;
35346- gap: 6px;
35347- font-size: 11px;
35348- font-weight: 600;
35349- color: #1e7f5c;
35350-}
35351-
35352-.lv-demo-body {
35353- padding: 22px 24px;
35354-}
35355-
35356-.lv-demo-event {
35357- display: grid;
35358- grid-template-columns: 18px minmax(0, 1fr);
35359- gap: 14px;
35360- padding-bottom: 20px;
35361- position: relative;
35362-}
35363-.lv-demo-event:last-child { padding-bottom: 0; }
35364-
35365-.lv-demo-event-track {
35366- display: flex;
35367- flex-direction: column;
35368- align-items: center;
35369-}
35370-
35371-.lv-demo-line {
35372- width: 1px;
35373- flex: 1;
35374- background: rgba(22,24,29,0.08);
35375- margin-top: 5px;
35376- min-height: 20px;
35377-}
35378-
35379-.lv-demo-event-content {}
35380-
35381-.lv-demo-event-header {
35382- display: flex;
35383- align-items: baseline;
35384- gap: 10px;
35385-}
35386-
35387-.lv-demo-event-title {
35388- font-size: 13.5px;
35389- font-weight: 600;
35390- color: #16181d;
35391-}
35392-
35393-.lv-demo-event-time {
35394- font-family: 'JetBrains Mono', monospace;
35395- font-size: 11px;
35396- color: #8a8d99;
35397-}
35398-
35399-.lv-demo-event-body {
35400- font-size: 13px;
35401- color: #6b7080;
35402- margin-top: 2px;
35403-}
35404-
35405-/* Ticker */
35406-.lv-ticker-wrap {
35407- border-top: 1px solid rgba(22,24,29,0.07);
35408- border-bottom: 1px solid rgba(22,24,29,0.07);
35409- background: #ffffff;
35410- margin-top: 64px;
35411- overflow: hidden;
35412- white-space: nowrap;
35413- position: relative;
35414-}
35415-
35416-.lv-ticker-track {
35417- display: inline-flex;
35418- animation: gcTicker 40s linear infinite;
35419- padding: 11px 0;
35420-}
35421-
35422-.lv-ticker-item {
35423- display: inline-flex;
35424- align-items: center;
35425- gap: 8px;
35426- font-family: 'JetBrains Mono', monospace;
35427- font-size: 11.5px;
35428- color: #6b7080;
35429- padding: 0 28px;
35430- border-right: 1px solid rgba(22,24,29,0.06);
35431-}
35432-
35433-/* Stats */
35434-.lv-stats {
35435- background: #fcfcfd;
35436-}
35437-
35438-.lv-stats-inner {
35439- max-width: 1200px;
35440- margin: 0 auto;
35441- display: grid;
35442- grid-template-columns: repeat(4, 1fr);
35443- gap: 24px;
35444- padding: 52px 28px;
35445-}
35446-
35447-.lv-stat {
35448- text-align: center;
35449-}
35450-
35451-.lv-stat-num {
35452- font-family: 'Inter Tight', sans-serif;
35453- font-weight: 700;
35454- font-size: clamp(30px, 4vw, 44px);
35455- letter-spacing: -0.025em;
35456- color: #111318;
35457-}
35458-
35459-.lv-stat-label {
35460- font-size: 13px;
35461- color: #6b7080;
35462- margin-top: 4px;
35463-}
35464-
35465-/* Loop */
35466-.lv-loop {
35467- padding: 96px 0;
35468- background: #ffffff;
35469- border-top: 1px solid rgba(22,24,29,0.07);
35470- border-bottom: 1px solid rgba(22,24,29,0.07);
35471-}
35472-
35473-.lv-loop-inner {
35474- max-width: 1200px;
35475- margin: 0 auto;
35476- padding: 0 28px;
35477-}
35478-
35479-.lv-stages {
35480- display: grid;
35481- grid-template-columns: repeat(6, 1fr);
35482- gap: 12px;
35483-}
35484-
35485-.lv-stage-card {
35486- border: 1px solid rgba(22,24,29,0.08);
35487- border-radius: 14px;
35488- background: #ffffff;
35489- padding: 20px 18px;
35490- transition: border-color 0.3s, background 0.3s;
35491-}
35492-
35493-.lv-stage-card.lv-stage-active {
35494- border-color: rgba(67,83,201,0.45);
35495- background: rgba(67,83,201,0.03);
35496-}
35497-
35498-.lv-stage-header {
35499- display: flex;
35500- align-items: center;
35501- gap: 8px;
35502- margin-bottom: 10px;
35503-}
35504-
35505-.lv-stage-n {
35506- font-family: 'JetBrains Mono', monospace;
35507- font-size: 10.5px;
35508- letter-spacing: 0.1em;
35509- text-transform: uppercase;
35510- color: #8a8d99;
35511-}
35512-
35513-.lv-stage-name {
35514- font-family: 'Inter Tight', sans-serif;
35515- font-size: 16px;
35516- font-weight: 600;
35517- letter-spacing: -0.01em;
35518- color: #16181d;
35519- margin-bottom: 5px;
35520-}
35521-
35522-.lv-stage-desc {
35523- font-size: 12px;
35524- color: #6b7080;
35525- line-height: 1.55;
35526-}
35527-
35528-.lv-stage-meta {
35529- font-family: 'JetBrains Mono', monospace;
35530- font-size: 10.5px;
35531- color: #8a8d99;
35532- margin-top: 10px;
35533- transition: color 0.3s;
35534-}
35535-
35536-.lv-stage-meta.lv-stage-meta-active {
35537- color: #4353c9;
35538-}
35539-
35540-/* Heroes */
35541-.lv-heroes {
35542- padding: 96px 0;
35543- background: #fcfcfd;
35544-}
35545-
35546-.lv-heroes-inner {
35547- max-width: 1200px;
35548- margin: 0 auto;
35549- padding: 0 28px;
35550-}
35551-
35552-.lv-heroes-header {
35553- max-width: 640px;
35554- margin-bottom: 56px;
35555-}
35556-
35557-.lv-heroes-list {
35558- display: flex;
35559- flex-direction: column;
35560- gap: 20px;
35561-}
35562-
35563-.lv-hero-card {
35564- display: grid;
35565- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
35566- gap: 48px;
35567- align-items: center;
35568- border: 1px solid rgba(22,24,29,0.08);
35569- border-radius: 20px;
35570- background: #ffffff;
35571- padding: 44px 48px;
35572- text-decoration: none;
35573- transition: border-color 0.2s, box-shadow 0.2s;
35574-}
35575-.lv-hero-card:hover {
35576- border-color: rgba(22,24,29,0.22);
35577- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
35578-}
35579-
35580-.lv-hero-card-left {}
35581-
35582-.lv-hero-card-title {
35583- font-family: 'Inter Tight', sans-serif;
35584- font-size: 26px;
35585- font-weight: 600;
35586- letter-spacing: -0.022em;
35587- line-height: 1.15;
35588- color: #16181d;
35589- margin: 0 0 12px;
35590-}
35591-
35592-.lv-hero-card-body {
35593- font-size: 14.5px;
35594- color: #6b7080;
35595- margin: 0 0 18px;
35596- line-height: 1.65;
35597-}
35598-
35599-.lv-hero-card-cta {
35600- font-size: 13.5px;
35601- font-weight: 600;
35602- color: #4353c9;
35603-}
35604-
35605-.lv-terminal {
35606- border: 1px solid rgba(22,24,29,0.07);
35607- border-radius: 14px;
35608- background: #fcfcfd;
35609- padding: 20px 22px;
35610- font-family: 'JetBrains Mono', monospace;
35611- font-size: 12px;
35612- line-height: 1.9;
35613- overflow: hidden;
35614-}
35615-
35616-.lv-terminal-line {
35617- display: flex;
35618- align-items: center;
35619- gap: 10px;
35620- white-space: nowrap;
35621- overflow: hidden;
35622- text-overflow: ellipsis;
35623-}
35624-
35625-/* Platform */
35626-.lv-platform {
35627- padding: 96px 0;
35628- background: #ffffff;
35629- border-top: 1px solid rgba(22,24,29,0.07);
35630-}
35631-
35632-.lv-platform-inner {
35633- max-width: 1200px;
35634- margin: 0 auto;
35635- padding: 0 28px;
35636-}
35637-
35638-.lv-cap-grid {
35639- display: grid;
35640- grid-template-columns: repeat(4, 1fr);
35641- gap: 24px 32px;
35642-}
35643-
35644-.lv-cap-col {}
35645-
35646-.lv-cap-group {
35647- font-family: 'JetBrains Mono', monospace;
35648- font-size: 10.5px;
35649- letter-spacing: 0.12em;
35650- text-transform: uppercase;
35651- color: #8a8d99;
35652- font-weight: 500;
35653- margin-bottom: 12px;
35654- padding-bottom: 8px;
35655- border-bottom: 1px solid rgba(22,24,29,0.07);
35656-}
35657-
35658-.lv-cap-items {
35659- display: flex;
35660- flex-direction: column;
35661- gap: 7px;
35662-}
35663-
35664-.lv-cap-item {
35665- font-size: 12.5px;
35666- color: #3a3d45;
35667- line-height: 1.45;
35668-}
35669-
35670-/* Sovereignty */
35671-.lv-sovereign {
35672- position: relative;
35673- overflow: hidden;
35674- padding: 104px 0;
35675- color: #fff;
35676- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
35677-}
35678-
35679-.lv-sovereign-grid-bg {
35680- position: absolute;
35681- inset: 0;
35682- opacity: 0.4;
35683- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
35684- background-size: 56px 56px;
35685- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
35686- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
35687-}
35688-
35689-.lv-sovereign-inner {
35690- position: relative;
35691- max-width: 1200px;
35692- margin: 0 auto;
35693- padding: 0 28px;
35694-}
35695-
35696-.lv-section-header-dark {
35697- max-width: 680px;
35698- margin: 0 auto 48px;
35699- text-align: center;
35700-}
35701-
35702-.lv-layers-grid {
35703- display: grid;
35704- grid-template-columns: repeat(4, 1fr);
35705- gap: 10px;
35706- max-width: 980px;
35707- margin: 0 auto;
35708-}
35709-
35710-.lv-layer-chip {
35711- border: 1px solid rgba(255,255,255,0.10);
35712- border-radius: 10px;
35713- padding: 12px 16px;
35714- background: rgba(255,255,255,0.03);
35715-}
35716-
35717-.lv-layer-cta {
35718- border-color: rgba(169,180,238,0.30);
35719- background: rgba(169,180,238,0.06);
35720- display: flex;
35721- align-items: center;
35722- text-decoration: none;
35723- transition: background 0.15s;
35724-}
35725-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
35726-
35727-.lv-layer-cta-text {
35728- font-size: 13px;
35729- font-weight: 500;
35730- color: #a9b4ee;
35731-}
35732-
35733-.lv-layer-n {
35734- font-family: 'JetBrains Mono', monospace;
35735- font-size: 10px;
35736- color: rgba(255,255,255,0.4);
35737- margin-bottom: 3px;
35738-}
35739-
35740-.lv-layer-name {
35741- font-size: 13px;
35742- font-weight: 500;
35743- color: rgba(255,255,255,0.92);
35744-}
35745-
35746-.lv-sovereign-feats {
35747- display: flex;
35748- gap: 44px;
35749- justify-content: center;
35750- flex-wrap: wrap;
35751- margin-top: 52px;
35752- text-align: center;
35753-}
35754-
35755-.lv-sovereign-feat {}
35756-
35757-.lv-sovereign-feat-title {
35758- font-family: 'Inter Tight', sans-serif;
35759- font-size: 20px;
35760- font-weight: 700;
35761- color: #fff;
35762-}
35763-
35764-.lv-sovereign-feat-sub {
35765- color: rgba(255,255,255,0.55);
35766- font-size: 13px;
35767- margin-top: 2px;
35768-}
35769-
35770-/* Twin cards */
35771-.lv-twin {
35772- padding: 96px 0;
35773- background: #fcfcfd;
35774-}
35775-
35776-.lv-twin-inner {
35777- max-width: 1200px;
35778- margin: 0 auto;
35779- padding: 0 28px;
35780- display: grid;
35781- grid-template-columns: 1fr 1fr;
35782- gap: 24px;
35783-}
35784-
35785-.lv-twin-card {
35786- border: 1px solid rgba(22,24,29,0.08);
35787- border-radius: 20px;
35788- background: #ffffff;
35789- padding: 44px 48px;
35790-}
35791-
35792-.lv-twin-title {
35793- font-family: 'Inter Tight', sans-serif;
35794- font-size: 24px;
35795- font-weight: 600;
35796- letter-spacing: -0.02em;
35797- line-height: 1.2;
35798- margin: 0 0 12px;
35799- color: #16181d;
35800-}
35801-
35802-.lv-twin-body {
35803- font-size: 14.5px;
35804- color: #6b7080;
35805- margin: 0 0 16px;
35806- line-height: 1.7;
35807-}
35808-
35809-.lv-twin-link {
35810- font-size: 13.5px;
35811- font-weight: 600;
35812- color: #4353c9;
35813- text-decoration: none;
35814-}
35815-.lv-twin-link:hover { text-decoration: underline; }
35816-
35817-/* Quote */
35818-.lv-quote {
35819- padding: 40px 0 96px;
35820- background: #fcfcfd;
35821-}
35822-
35823-.lv-quote-inner {
35824- max-width: 980px;
35825- margin: 0 auto;
35826- padding: 0 28px;
35827- text-align: center;
35828-}
35829-
35830-.lv-quote-text {
35831- font-family: 'Inter Tight', sans-serif;
35832- font-weight: 600;
35833- font-size: clamp(26px, 3.8vw, 42px);
35834- line-height: 1.2;
35835- letter-spacing: -0.025em;
35836- margin: 0;
35837- color: #111318;
35838-}
35839-
35840-.lv-em {
35841- font-style: normal;
35842- color: #4353c9;
35843-}
35844-
35845-/* CTA */
35846-.lv-cta-section {
35847- padding: 0 0 104px;
35848- background: #fcfcfd;
35849-}
35850-
35851-.lv-cta-card {
35852- max-width: 820px;
35853- margin: 0 auto;
35854- padding: 64px 40px;
35855- text-align: center;
35856- background: #ffffff;
35857- border: 1px solid rgba(22,24,29,0.08);
35858- border-radius: 26px;
35859- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
35860- position: relative;
35861- overflow: hidden;
35862-}
35863-
35864-.lv-cta-glow {
35865- position: absolute;
35866- inset: -40% 0 auto 0;
35867- height: 280px;
35868- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
35869- pointer-events: none;
35870-}
35871-
35872-.lv-cta-h2 {
35873- font-family: 'Inter Tight', sans-serif;
35874- font-weight: 700;
35875- letter-spacing: -0.028em;
35876- font-size: clamp(30px, 4.6vw, 48px);
35877- margin: 0;
35878- position: relative;
35879- color: #111318;
35880-}
35881-
35882-.lv-cta-sub {
35883- color: #6b7080;
35884- font-size: 17px;
35885- margin: 16px 0 30px;
35886- position: relative;
35887-}
35888-
35889-.lv-cta-actions {
35890- display: flex;
35891- gap: 12px;
35892- justify-content: center;
35893- flex-wrap: wrap;
35894- position: relative;
35895-}
35896-
35897-.lv-cta-fine {
35898- margin-top: 20px;
35899- font-family: 'JetBrains Mono', monospace;
35900- font-size: 11px;
35901- color: #8a8d99;
35902- position: relative;
35903-}
35904-
35905-/* Footer */
35906-.lv-footer {
35907- border-top: 1px solid rgba(22,24,29,0.07);
35908- background: #ffffff;
35909- padding: 56px 0 30px;
35910-}
35911-
35912-.lv-footer-inner {
35913- max-width: 1200px;
35914- margin: 0 auto;
35915- padding: 0 28px;
35916- display: flex;
35917- gap: 48px;
35918- flex-wrap: wrap;
35919- justify-content: space-between;
35920-}
35921-
35922-.lv-footer-brand {}
35923-
35924-.lv-footer-tagline {
35925- color: #6b7080;
35926- font-size: 13.5px;
35927- margin: 12px 0 0;
35928- max-width: 32ch;
35929- line-height: 1.6;
35930-}
35931-
35932-.lv-footer-cols {
35933- display: flex;
35934- gap: 64px;
35935- flex-wrap: wrap;
35936-}
35937-
35938-.lv-footer-col {
35939- display: flex;
35940- flex-direction: column;
35941- gap: 9px;
35942-}
35943-
35944-.lv-footer-col-head {
35945- font-family: 'JetBrains Mono', monospace;
35946- font-size: 11px;
35947- text-transform: uppercase;
35948- letter-spacing: 0.1em;
35949- color: #8a8d99;
35950- margin: 0 0 4px;
35951- font-weight: 500;
35952-}
35953-
35954-.lv-footer-link {
35955- color: #3a3d45;
35956- font-size: 13.5px;
35957- text-decoration: none;
35958- transition: color 0.15s;
35959-}
35960-.lv-footer-link:hover { color: #16181d; }
35961-
35962-.lv-footer-bar {
35963- max-width: 1200px;
35964- margin: 44px auto 0;
35965- padding: 22px 28px 0;
35966- border-top: 1px solid rgba(22,24,29,0.06);
35967- display: flex;
35968- justify-content: space-between;
35969- flex-wrap: wrap;
35970- gap: 8px;
35971- color: #8a8d99;
35972- font-size: 12.5px;
35973-}
35974-
35975-.lv-footer-stack {
35976- font-family: 'JetBrains Mono', monospace;
35977- font-size: 11px;
35978-}
35979-`;
35980diff --git a/src/views/layout.tsx b/src/views/layout.tsx
35981index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
35982--- a/src/views/layout.tsx
35983+++ b/src/views/layout.tsx
35984@@ -3153,9 +3153,12 @@
35985 font-weight: 500;
35986 line-height: 1.4;
35987 }
35988- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
35989- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
35990- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
35991+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
35992+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
35993+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
35994+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
35995+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
35996+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
35997 .state-merged { color: var(--accent); }
35998 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
35999
36000diff --git a/src/views/ui.tsx b/src/views/ui.tsx
36001index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
36002--- a/src/views/ui.tsx
36003+++ b/src/views/ui.tsx
36004@@ -232,7 +232,7 @@
36005
36006 export const Badge: FC<
36007 PropsWithChildren<{
36008- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
36009+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
36010 style?: string;
36011 }>
36012 > = ({ children, variant = "default", style }) => {
36013@@ -241,9 +241,12 @@
36014 variant === "closed" ? "badge-closed" :
36015 variant === "merged" ? "badge-merged" :
36016 variant === "success" ? "badge-success" :
36017- variant === "danger" ? "badge-danger" :
36018- variant === "warning" ? "badge-warning" :
36019- "badge";
36020+ variant === "danger" ? "badge-danger" :
36021+ variant === "warning" ? "badge-warning" :
36022+ variant === "live" ? "badge-live" :
36023+ variant === "soon" ? "badge-soon" :
36024+ variant === "preview" ? "badge-preview" :
36025+ "badge";
36026 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
36027 };
36028
36029
36030codex
36031The full suite has passed the two-minute mark without emitting results. I m continuing to the five-minute command limit; if the runner itself does not terminate, I ll distinguish that from an actual test
36032failure and run focused tests for the affected import graph.
36033diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
36034index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
36035--- a/src/views/landing-pro.tsx
36036+++ b/src/views/landing-pro.tsx
36037@@ -42,7 +42,7 @@
36038
36039 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36040
36041-function icon(paths: string, color = "#4353c9", size = 20) {
36042+function icon(paths: string, color = "#0891b2", size = 20) {
36043 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
36044 }
36045
36046@@ -947,7 +947,7 @@
36047 const css = `
36048 /* %% tokens %% */
36049 :root{
36050- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
36051+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
36052 --lp-bg:#ffffff;--lp-soft:#fafafb;
36053 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
36054 --lp-border:rgba(0,0,0,.08);
36055diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
36056deleted file mode 100644
36057index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
36058--- a/src/views/landing-v2.tsx
36059+++ /dev/null
36060@@ -1,1447 +0,0 @@
36061-import type { FC } from "hono/jsx";
36062-
36063-export interface LandingPageProps {
36064- stats?: {
36065- publicRepos?: number;
36066- users?: number;
36067- };
36068-}
36069-
36070-const demoAllEvents = [
36071- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
36072- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
36073- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
36074- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
36075- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
36076-];
36077-
36078-const tickerItems = [
36079- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
36080- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
36081- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
36082- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
36083- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
36084- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
36085- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
36086- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
36087- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
36088- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
36089- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
36090- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
36091- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
36092- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
36093- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
36094- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
36095-];
36096-
36097-const stageData = [
36098- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
36099- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
36100- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
36101- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
36102- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
36103- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
36104-];
36105-
36106-const heroFeatures = [
36107- {
36108- href: "/",
36109- eyebrow: "01 � The autonomous repair loop",
36110- title: "Failures fix themselves  and show their work.",
36111- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
36112failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
36113- cta: "Watch a live repair session",
36114- mock: [
36115- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
36116- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
36117- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
36118- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
36119- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
36120- ],
36121- },
36122- {
36123- href: "/",
36124- eyebrow: "02 � Live sandbox isolation",
36125- title: "Every PR gets its own instant, disposable environment.",
36126- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
36127same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
36128- cta: "See a PR with its sandbox",
36129- mock: [
36130- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
36131- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
36132- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
36133- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
36134- ],
36135- },
36136- {
36137- href: "/",
36138- eyebrow: "03 � Multiplayer IDE workspaces",
36139- title: "You and the agent, side by side, in your editor.",
36140- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
36141agent into a silent reviewer in your gutter. The browser becomes optional.",
36142- cta: "See the editor session",
36143- mock: [
36144- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
36145- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
36146- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
36147- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
36148- ],
36149- },
36150-];
36151-
36152-const capabilities = [
36153- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
36154- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
36155- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
36156- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
36157- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
36158- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
36159- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
36160- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
36161-];
36162-
36163-const sovereignLayerNames = [
36164- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
36165- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
36166- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
36167- "Availability & recovery",
36168-];
36169-
36170-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
36171- return (
36172- <>
36173- <style dangerouslySetInnerHTML={{ __html: css }} />
36174-
36175- {/* Nav */}
36176- <header class="lv-nav">
36177- <div class="lv-nav-inner">
36178- <a href="/" class="lv-logo">
36179- <span class="lv-logo-mark"></span>gluecron
36180- </a>
36181- <nav class="lv-nav-links">
36182- <a href="#loop" class="lv-nav-link">The loop</a>
36183- <a href="#platform" class="lv-nav-link">Platform</a>
36184- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
36185- <a href="/trust" class="lv-nav-link">Trust</a>
36186- </nav>
36187- <div class="lv-nav-ctas">
36188- <a href="/login" class="lv-btn-secondary">Sign in</a>
36189- <a href="/register" class="lv-btn-primary">Start building</a>
36190- </div>
36191- </div>
36192- </header>
36193-
36194- {/* Hero */}
36195- <section class="lv-hero">
36196- <div class="lv-hero-glow"></div>
36197- <div class="lv-hero-inner">
36198- <div class="lv-hero-badge">
36199- <span class="lv-dot lv-dot-green lv-pulse"></span>
36200- Live: a repair loop converged on pr-218 while you read this
36201- </div>
36202- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
36203- <p class="lv-hero-sub">
36204- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
36205failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
36206- </p>
36207- <div class="lv-hero-actions">
36208- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
36209- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
36210- </div>
36211- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
36212-
36213- {/* Live product window */}
36214- <div class="lv-demo-window">
36215- <div class="lv-demo-bar">
36216- <span class="lv-demo-dot"></span>
36217- <span class="lv-demo-dot"></span>
36218- <span class="lv-demo-dot"></span>
36219- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
36220- <span class="lv-demo-live">
36221- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
36222- LIVE
36223- </span>
36224- </div>
36225- <div class="lv-demo-body" id="lv-demo-body">
36226- {/* Events rendered by JS */}
36227- {demoAllEvents.slice(0, 1).map((e, i) => (
36228- <div class="lv-demo-event" key={i}>
36229- <div class="lv-demo-event-track">
36230- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
36231- <span class="lv-demo-line" style="display:none"></span>
36232- </div>
36233- <div class="lv-demo-event-content">
36234- <div class="lv-demo-event-header">
36235- <span class="lv-demo-event-title">{e.title}</span>
36236- <span class="lv-demo-event-time">{e.time}</span>
36237- </div>
36238- <div class="lv-demo-event-body">{e.body}</div>
36239- </div>
36240- </div>
36241- ))}
36242- </div>
36243- </div>
36244- </div>
36245-
36246- {/* Activity ticker */}
36247- <div class="lv-ticker-wrap">
36248- <div class="lv-ticker-track">
36249- {tickerItems.map((t, i) => (
36250- <span class="lv-ticker-item" key={i}>
36251- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
36252- {t.text}
36253- </span>
36254- ))}
36255- </div>
36256- </div>
36257- </section>
36258-
36259- {/* Stat band */}
36260- <section class="lv-stats">
36261- <div class="lv-stats-inner">
36262- <div class="lv-stat">
36263- <div class="lv-stat-num">Sonnet 5</div>
36264- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
36265- </div>
36266- <div class="lv-stat">
36267- <div class="lv-stat-num">93.5%</div>
36268- <div class="lv-stat-label">of failures self-repair without a human</div>
36269- </div>
36270- <div class="lv-stat">
36271- <div class="lv-stat-num">1.9%</div>
36272- <div class="lv-stat-label">AI merges reverted  published live</div>
36273- </div>
36274- <div class="lv-stat">
36275- <div class="lv-stat-num">0</div>
36276- <div class="lv-stat-label">irreversible actions taken autonomously</div>
36277- </div>
36278- </div>
36279- </section>
36280-
36281- {/* The loop */}
36282- <section id="loop" class="lv-loop">
36283- <div class="lv-loop-inner">
36284- <div class="lv-section-header">
36285- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
36286- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
36287- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
36288- </div>
36289- <div class="lv-stages" id="lv-stages">
36290- {stageData.map((s, i) => (
36291- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
36292- <div class="lv-stage-header">
36293- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
36294- <span class="lv-stage-n">0{i + 1}</span>
36295- </div>
36296- <div class="lv-stage-name">{s.name}</div>
36297- <div class="lv-stage-desc">{s.desc}</div>
36298- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
36299- </div>
36300- ))}
36301- </div>
36302- </div>
36303- </section>
36304-
36305- {/* Three heroes */}
36306- <section class="lv-heroes">
36307- <div class="lv-heroes-inner">
36308- <div class="lv-heroes-header">
36309- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
36310- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
36311- </div>
36312- <div class="lv-heroes-list">
36313- {heroFeatures.map((h, i) => (
36314- <a href={h.href} class="lv-hero-card" key={i}>
36315- <div class="lv-hero-card-left">
36316- <div class="lv-eyebrow">{h.eyebrow}</div>
36317- <h3 class="lv-hero-card-title">{h.title}</h3>
36318- <p class="lv-hero-card-body">{h.body}</p>
36319- <span class="lv-hero-card-cta">{h.cta} �!</span>
36320- </div>
36321- <div class="lv-terminal">
36322- {h.mock.map((m, j) => (
36323- <div class="lv-terminal-line" key={j}>
36324- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
36325- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
36326- </div>
36327- ))}
36328- </div>
36329- </a>
36330- ))}
36331- </div>
36332- </div>
36333- </section>
36334-
36335- {/* Everything grid */}
36336- <section id="platform" class="lv-platform">
36337- <div class="lv-platform-inner">
36338- <div class="lv-section-header lv-section-header-center">
36339- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
36340- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
36341- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
36342- </div>
36343- <div class="lv-cap-grid">
36344- {capabilities.map((c, i) => (
36345- <div class="lv-cap-col" key={i}>
36346- <div class="lv-cap-group">{c.group}</div>
36347- <div class="lv-cap-items">
36348- {c.items.map((item, j) => (
36349- <div class="lv-cap-item" key={j}>{item}</div>
36350- ))}
36351- </div>
36352- </div>
36353- ))}
36354- </div>
36355- </div>
36356- </section>
36357-
36358- {/* Sovereignty band */}
36359- <section id="sovereign" class="lv-sovereign">
36360- <div class="lv-sovereign-grid-bg"></div>
36361- <div class="lv-sovereign-inner">
36362- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
36363- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
36364- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
36365- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
36366to private cloud, or run fully air-gapped on bare metal.</p>
36367- </div>
36368- <div class="lv-layers-grid">
36369- {sovereignLayerNames.map((name, i) => (
36370- <div class="lv-layer-chip" key={i}>
36371- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
36372- <div class="lv-layer-name">{name}</div>
36373- </div>
36374- ))}
36375- <a href="/" class="lv-layer-chip lv-layer-cta">
36376- <div class="lv-layer-cta-text">All self-owned �!</div>
36377- </a>
36378- </div>
36379- <div class="lv-sovereign-feats">
36380- <div class="lv-sovereign-feat">
36381- <div class="lv-sovereign-feat-title">Local inference first</div>
36382- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
36383- </div>
36384- <div class="lv-sovereign-feat">
36385- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
36386- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
36387- </div>
36388- <div class="lv-sovereign-feat">
36389- <div class="lv-sovereign-feat-title">Self-healing infra</div>
36390- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
36391- </div>
36392- </div>
36393- </div>
36394- </section>
36395-
36396- {/* Manual-first + reversibility */}
36397- <section class="lv-twin">
36398- <div class="lv-twin-inner">
36399- <div class="lv-twin-card">
36400- <div class="lv-eyebrow">Manual-first, always</div>
36401- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
36402- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
36403fallback. Developers who never touch AI get the best git host they've ever used.</p>
36404- </div>
36405- <div class="lv-twin-card">
36406- <div class="lv-eyebrow">The reversibility guarantee</div>
36407- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
36408- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
36409 policy, not promise. Our quality numbers are published live, unedited.</p>
36410- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
36411- </div>
36412- </div>
36413- </section>
36414-
36415- {/* Quote */}
36416- <section class="lv-quote">
36417- <div class="lv-quote-inner">
36418- <p class="lv-quote-text">
36419- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
36420- Gluecron is where code gets <em class="lv-em">finished</em>."
36421- </p>
36422- </div>
36423- </section>
36424-
36425- {/* CTA */}
36426- <section class="lv-cta-section">
36427- <div class="lv-cta-card">
36428- <div class="lv-cta-glow"></div>
36429- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
36430- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
36431- <div class="lv-cta-actions">
36432- <a href="/register" class="lv-cta-primary">Create your account �!</a>
36433- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
36434- </div>
36435- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
36436- </div>
36437- </section>
36438-
36439- {/* Footer */}
36440- <footer class="lv-footer">
36441- <div class="lv-footer-inner">
36442- <div class="lv-footer-brand">
36443- <a href="/" class="lv-logo">
36444- <span class="lv-logo-mark"></span>gluecron
36445- </a>
36446- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
36447- </div>
36448- <div class="lv-footer-cols">
36449- <div class="lv-footer-col">
36450- <h4 class="lv-footer-col-head">Product</h4>
36451- <a href="/" class="lv-footer-link">Agent workspace</a>
36452- <a href="/" class="lv-footer-link">Fleet refactors</a>
36453- <a href="/" class="lv-footer-link">Org memory</a>
36454- <a href="/" class="lv-footer-link">IDE extensions</a>
36455- </div>
36456- <div class="lv-footer-col">
36457- <h4 class="lv-footer-col-head">Platform</h4>
36458- <a href="/" class="lv-footer-link">Production layers</a>
36459- <a href="/trust" class="lv-footer-link">Trust report</a>
36460- <a href="/" class="lv-footer-link">Docs</a>
36461- <a href="/" class="lv-footer-link">Status</a>
36462- </div>
36463- <div class="lv-footer-col">
36464- <h4 class="lv-footer-col-head">Company</h4>
36465- <a href="/" class="lv-footer-link">About</a>
36466- <a href="/" class="lv-footer-link">Pricing</a>
36467- <a href="/" class="lv-footer-link">Enterprise</a>
36468- </div>
36469- </div>
36470- </div>
36471- <div class="lv-footer-bar">
36472- <span>� 2026 Gluecron</span>
36473- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
36474- </div>
36475- </footer>
36476-
36477- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
36478- </>
36479- );
36480-};
36481-
36482-export const LandingPage = LandingPageV2;
36483-export default LandingPageV2;
36484-
36485-const clientScript = `
36486-(function() {
36487- var demoAll = [
36488- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
36489- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
36490- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
36491- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
36492- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
36493- ];
36494-
36495- var demoStep = 0;
36496- var stage = 0;
36497-
36498- function renderDemo() {
36499- var container = document.getElementById('lv-demo-body');
36500- if (!container) return;
36501- var visible = demoAll.slice(0, demoStep + 1);
36502- container.innerHTML = visible.map(function(e, i) {
36503- var isLast = i === visible.length - 1;
36504- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
36505- return '<div class="lv-demo-event">' +
36506- '<div class="lv-demo-event-track">' +
36507- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
36508- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
36509- '</div>' +
36510- '<div class="lv-demo-event-content">' +
36511- '<div class="lv-demo-event-header">' +
36512- '<span class="lv-demo-event-title">' + e.title + '</span>' +
36513- '<span class="lv-demo-event-time">' + e.time + '</span>' +
36514- '</div>' +
36515- '<div class="lv-demo-event-body">' + e.body + '</div>' +
36516- '</div>' +
36517- '</div>';
36518- }).join('');
36519- }
36520-
36521- function renderStages() {
36522- var cards = document.querySelectorAll('.lv-stage-card');
36523- cards.forEach(function(card, i) {
36524- var dot = card.querySelector('.lv-dot');
36525- var meta = card.querySelector('.lv-stage-meta');
36526- if (i === stage) {
36527- card.classList.add('lv-stage-active');
36528- if (dot) {
36529- dot.classList.remove('lv-dot-idle');
36530- dot.classList.add('lv-dot-indigo', 'lv-pulse');
36531- }
36532- if (meta) meta.classList.add('lv-stage-meta-active');
36533- } else {
36534- card.classList.remove('lv-stage-active');
36535- if (dot) {
36536- dot.classList.add('lv-dot-idle');
36537- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
36538- }
36539- if (meta) meta.classList.remove('lv-stage-meta-active');
36540- }
36541- });
36542- }
36543-
36544- renderDemo();
36545-
36546- setInterval(function() {
36547- demoStep = (demoStep + 1) % 5;
36548- renderDemo();
36549- }, 3600);
36550-
36551- setInterval(function() {
36552- stage = (stage + 1) % 6;
36553- renderStages();
36554- }, 2200);
36555-})();
36556-`;
36557-
36558-const css = `
36559-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
36560-
36561-*, *::before, *::after { box-sizing: border-box; }
36562-
36563-body {
36564- margin: 0;
36565- background: #fcfcfd;
36566- -webkit-font-smoothing: antialiased;
36567- text-rendering: optimizeLegibility;
36568- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
36569- font-size: 15px;
36570- line-height: 1.6;
36571- letter-spacing: -0.008em;
36572- color: #16181d;
36573-}
36574-
36575-@keyframes gcPulse {
36576- 0%, 100% { opacity: 1; }
36577- 50% { opacity: 0.35; }
36578-}
36579-
36580-@keyframes gcTicker {
36581- 0% { transform: translateX(0); }
36582- 100% { transform: translateX(-50%); }
36583-}
36584-
36585-/* Shared utilities */
36586-.lv-dot {
36587- display: inline-block;
36588- border-radius: 50%;
36589-}
36590-.lv-dot-green { background: #1e7f5c; }
36591-.lv-dot-indigo { background: #4353c9; }
36592-.lv-dot-idle { background: #c4c6cf; }
36593-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
36594-
36595-.lv-strong { color: #16181d; font-weight: 600; }
36596-
36597-.lv-eyebrow {
36598- font-family: 'JetBrains Mono', monospace;
36599- font-size: 11px;
36600- letter-spacing: 0.12em;
36601- text-transform: uppercase;
36602- color: #8a8d99;
36603- font-weight: 500;
36604- margin-bottom: 12px;
36605-}
36606-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
36607-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
36608-
36609-.lv-h1 {
36610- font-family: 'Inter Tight', sans-serif;
36611- font-weight: 700;
36612- letter-spacing: -0.035em;
36613- font-size: clamp(44px, 7vw, 84px);
36614- line-height: 0.98;
36615- margin: 30px auto 0;
36616- max-width: 14ch;
36617- color: #111318;
36618-}
36619-
36620-.lv-h2 {
36621- font-family: 'Inter Tight', sans-serif;
36622- font-weight: 700;
36623- letter-spacing: -0.028em;
36624- font-size: clamp(30px, 4.4vw, 48px);
36625- line-height: 1.05;
36626- margin: 0;
36627- color: #111318;
36628-}
36629-
36630-.lv-h2-dark {
36631- font-family: 'Inter Tight', sans-serif;
36632- font-weight: 700;
36633- letter-spacing: -0.028em;
36634- font-size: clamp(30px, 4.6vw, 52px);
36635- line-height: 1.05;
36636- margin: 0;
36637- color: #fff;
36638-}
36639-
36640-.lv-section-header {
36641- max-width: 640px;
36642- margin: 0 auto 56px;
36643-}
36644-
36645-.lv-section-header-center {
36646- text-align: center;
36647-}
36648-
36649-.lv-section-sub {
36650- color: #6b7080;
36651- font-size: 17px;
36652- margin: 18px auto 0;
36653- max-width: 52ch;
36654-}
36655-
36656-.lv-section-sub-dark {
36657- color: rgba(255,255,255,0.72);
36658- font-size: 17px;
36659- margin: 18px auto 0;
36660- max-width: 56ch;
36661-}
36662-
36663-/* Nav */
36664-.lv-nav {
36665- position: sticky;
36666- top: 0;
36667- z-index: 60;
36668- backdrop-filter: saturate(180%) blur(14px);
36669- -webkit-backdrop-filter: saturate(180%) blur(14px);
36670- background: rgba(252,252,253,0.8);
36671- border-bottom: 1px solid rgba(22,24,29,0.07);
36672-}
36673-
36674-.lv-nav-inner {
36675- max-width: 1200px;
36676- margin: 0 auto;
36677- padding: 14px 28px;
36678- display: flex;
36679- align-items: center;
36680- gap: 28px;
36681-}
36682-
36683-.lv-logo {
36684- display: inline-flex;
36685- align-items: center;
36686- gap: 9px;
36687- font-family: 'Inter Tight', sans-serif;
36688- font-weight: 700;
36689- font-size: 17px;
36690- letter-spacing: -0.02em;
36691- color: #16181d;
36692- text-decoration: none;
36693-}
36694-
36695-.lv-logo-mark {
36696- width: 17px;
36697- height: 17px;
36698- border-radius: 5px;
36699- background: #4353c9;
36700- display: inline-block;
36701- flex-shrink: 0;
36702-}
36703-
36704-.lv-nav-links {
36705- display: flex;
36706- gap: 24px;
36707- font-size: 13.5px;
36708- font-weight: 500;
36709-}
36710-
36711-.lv-nav-link {
36712- color: #6b7080;
36713- text-decoration: none;
36714- transition: color 0.15s;
36715-}
36716-.lv-nav-link:hover { color: #16181d; }
36717-
36718-.lv-nav-ctas {
36719- margin-left: auto;
36720- display: flex;
36721- align-items: center;
36722- gap: 10px;
36723-}
36724-
36725-.lv-btn-secondary {
36726- padding: 8px 15px;
36727- border-radius: 8px;
36728- font-size: 13.5px;
36729- font-weight: 500;
36730- color: #16181d;
36731- border: 1px solid rgba(22,24,29,0.12);
36732- background: #ffffff;
36733- text-decoration: none;
36734- white-space: nowrap;
36735- transition: border-color 0.15s;
36736-}
36737-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
36738-
36739-.lv-btn-primary {
36740- padding: 8px 15px;
36741- border-radius: 8px;
36742- font-size: 13.5px;
36743- font-weight: 600;
36744- background: #16181d;
36745- color: #fff;
36746- text-decoration: none;
36747- white-space: nowrap;
36748- transition: box-shadow 0.15s;
36749-}
36750-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
36751-
36752-/* Hero */
36753-.lv-hero {
36754- position: relative;
36755- overflow: hidden;
36756- padding: 88px 0 0;
36757-}
36758-
36759-.lv-hero-glow {
36760- position: absolute;
36761- inset: -10% 0 auto 0;
36762- height: 640px;
36763- pointer-events: none;
36764- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
36765-}
36766-
36767-.lv-hero-inner {
36768- position: relative;
36769- max-width: 1200px;
36770- margin: 0 auto;
36771- padding: 0 28px;
36772- text-align: center;
36773-}
36774-
36775-.lv-hero-badge {
36776- display: inline-flex;
36777- align-items: center;
36778- gap: 9px;
36779- font-size: 12.5px;
36780- font-weight: 600;
36781- color: #3a3d45;
36782- background: #ffffff;
36783- border: 1px solid rgba(22,24,29,0.10);
36784- border-radius: 9999px;
36785- padding: 7px 16px;
36786- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
36787-}
36788-
36789-.lv-hero-sub {
36790- font-size: clamp(16px, 2vw, 19px);
36791- color: #6b7080;
36792- max-width: 60ch;
36793- margin: 24px auto 0;
36794- font-weight: 450;
36795- line-height: 1.65;
36796-}
36797-
36798-.lv-hero-actions {
36799- display: flex;
36800- gap: 12px;
36801- justify-content: center;
36802- flex-wrap: wrap;
36803- margin-top: 32px;
36804-}
36805-
36806-.lv-cta-primary {
36807- padding: 13px 24px;
36808- border-radius: 11px;
36809- font-size: 15.5px;
36810- font-weight: 600;
36811- background: #16181d;
36812- color: #fff;
36813- text-decoration: none;
36814- white-space: nowrap;
36815- transition: box-shadow 0.15s;
36816-}
36817-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
36818-
36819-.lv-cta-secondary {
36820- padding: 13px 24px;
36821- border-radius: 11px;
36822- font-size: 15.5px;
36823- font-weight: 600;
36824- color: #16181d;
36825- border: 1px solid rgba(22,24,29,0.14);
36826- background: #ffffff;
36827- text-decoration: none;
36828- white-space: nowrap;
36829- transition: border-color 0.15s;
36830-}
36831-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
36832-
36833-.lv-hero-tag {
36834- margin-top: 18px;
36835- font-family: 'JetBrains Mono', monospace;
36836- font-size: 11.5px;
36837- letter-spacing: 0.08em;
36838- text-transform: uppercase;
36839- color: #8a8d99;
36840-}
36841-
36842-/* Demo window */
36843-.lv-demo-window {
36844- margin: 56px auto 0;
36845- max-width: 860px;
36846- text-align: left;
36847- background: #ffffff;
36848- border: 1px solid rgba(22,24,29,0.09);
36849- border-radius: 18px;
36850- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
36851- overflow: hidden;
36852-}
36853-
36854-.lv-demo-bar {
36855- display: flex;
36856- align-items: center;
36857- gap: 7px;
36858- padding: 12px 18px;
36859- border-bottom: 1px solid rgba(22,24,29,0.07);
36860- background: #fcfcfd;
36861-}
36862-
36863-.lv-demo-dot {
36864- width: 10px;
36865- height: 10px;
36866- border-radius: 50%;
36867- background: #e4e5ea;
36868-}
36869-
36870-.lv-demo-url {
36871- margin-left: 10px;
36872- font-family: 'JetBrains Mono', monospace;
36873- font-size: 12px;
36874- color: #6b7080;
36875-}
36876-
36877-.lv-demo-live {
36878- margin-left: auto;
36879- display: inline-flex;
36880- align-items: center;
36881- gap: 6px;
36882- font-size: 11px;
36883- font-weight: 600;
36884- color: #1e7f5c;
36885-}
36886-
36887-.lv-demo-body {
36888- padding: 22px 24px;
36889-}
36890-
36891-.lv-demo-event {
36892- display: grid;
36893- grid-template-columns: 18px minmax(0, 1fr);
36894- gap: 14px;
36895- padding-bottom: 20px;
36896- position: relative;
36897-}
36898-.lv-demo-event:last-child { padding-bottom: 0; }
36899-
36900-.lv-demo-event-track {
36901- display: flex;
36902- flex-direction: column;
36903- align-items: center;
36904-}
36905-
36906-.lv-demo-line {
36907- width: 1px;
36908- flex: 1;
36909- background: rgba(22,24,29,0.08);
36910- margin-top: 5px;
36911- min-height: 20px;
36912-}
36913-
36914-.lv-demo-event-content {}
36915-
36916-.lv-demo-event-header {
36917- display: flex;
36918- align-items: baseline;
36919- gap: 10px;
36920-}
36921-
36922-.lv-demo-event-title {
36923- font-size: 13.5px;
36924- font-weight: 600;
36925- color: #16181d;
36926-}
36927-
36928-.lv-demo-event-time {
36929- font-family: 'JetBrains Mono', monospace;
36930- font-size: 11px;
36931- color: #8a8d99;
36932-}
36933-
36934-.lv-demo-event-body {
36935- font-size: 13px;
36936- color: #6b7080;
36937- margin-top: 2px;
36938-}
36939-
36940-/* Ticker */
36941-.lv-ticker-wrap {
36942- border-top: 1px solid rgba(22,24,29,0.07);
36943- border-bottom: 1px solid rgba(22,24,29,0.07);
36944- background: #ffffff;
36945- margin-top: 64px;
36946- overflow: hidden;
36947- white-space: nowrap;
36948- position: relative;
36949-}
36950-
36951-.lv-ticker-track {
36952- display: inline-flex;
36953- animation: gcTicker 40s linear infinite;
36954- padding: 11px 0;
36955-}
36956-
36957-.lv-ticker-item {
36958- display: inline-flex;
36959- align-items: center;
36960- gap: 8px;
36961- font-family: 'JetBrains Mono', monospace;
36962- font-size: 11.5px;
36963- color: #6b7080;
36964- padding: 0 28px;
36965- border-right: 1px solid rgba(22,24,29,0.06);
36966-}
36967-
36968-/* Stats */
36969-.lv-stats {
36970- background: #fcfcfd;
36971-}
36972-
36973-.lv-stats-inner {
36974- max-width: 1200px;
36975- margin: 0 auto;
36976- display: grid;
36977- grid-template-columns: repeat(4, 1fr);
36978- gap: 24px;
36979- padding: 52px 28px;
36980-}
36981-
36982-.lv-stat {
36983- text-align: center;
36984-}
36985-
36986-.lv-stat-num {
36987- font-family: 'Inter Tight', sans-serif;
36988- font-weight: 700;
36989- font-size: clamp(30px, 4vw, 44px);
36990- letter-spacing: -0.025em;
36991- color: #111318;
36992-}
36993-
36994-.lv-stat-label {
36995- font-size: 13px;
36996- color: #6b7080;
36997- margin-top: 4px;
36998-}
36999-
37000-/* Loop */
37001-.lv-loop {
37002- padding: 96px 0;
37003- background: #ffffff;
37004- border-top: 1px solid rgba(22,24,29,0.07);
37005- border-bottom: 1px solid rgba(22,24,29,0.07);
37006-}
37007-
37008-.lv-loop-inner {
37009- max-width: 1200px;
37010- margin: 0 auto;
37011- padding: 0 28px;
37012-}
37013-
37014-.lv-stages {
37015- display: grid;
37016- grid-template-columns: repeat(6, 1fr);
37017- gap: 12px;
37018-}
37019-
37020-.lv-stage-card {
37021- border: 1px solid rgba(22,24,29,0.08);
37022- border-radius: 14px;
37023- background: #ffffff;
37024- padding: 20px 18px;
37025- transition: border-color 0.3s, background 0.3s;
37026-}
37027-
37028-.lv-stage-card.lv-stage-active {
37029- border-color: rgba(67,83,201,0.45);
37030- background: rgba(67,83,201,0.03);
37031-}
37032-
37033-.lv-stage-header {
37034- display: flex;
37035- align-items: center;
37036- gap: 8px;
37037- margin-bottom: 10px;
37038-}
37039-
37040-.lv-stage-n {
37041- font-family: 'JetBrains Mono', monospace;
37042- font-size: 10.5px;
37043- letter-spacing: 0.1em;
37044- text-transform: uppercase;
37045- color: #8a8d99;
37046-}
37047-
37048-.lv-stage-name {
37049- font-family: 'Inter Tight', sans-serif;
37050- font-size: 16px;
37051- font-weight: 600;
37052- letter-spacing: -0.01em;
37053- color: #16181d;
37054- margin-bottom: 5px;
37055-}
37056-
37057-.lv-stage-desc {
37058- font-size: 12px;
37059- color: #6b7080;
37060- line-height: 1.55;
37061-}
37062-
37063-.lv-stage-meta {
37064- font-family: 'JetBrains Mono', monospace;
37065- font-size: 10.5px;
37066- color: #8a8d99;
37067- margin-top: 10px;
37068- transition: color 0.3s;
37069-}
37070-
37071-.lv-stage-meta.lv-stage-meta-active {
37072- color: #4353c9;
37073-}
37074-
37075-/* Heroes */
37076-.lv-heroes {
37077- padding: 96px 0;
37078- background: #fcfcfd;
37079-}
37080-
37081-.lv-heroes-inner {
37082- max-width: 1200px;
37083- margin: 0 auto;
37084- padding: 0 28px;
37085-}
37086-
37087-.lv-heroes-header {
37088- max-width: 640px;
37089- margin-bottom: 56px;
37090-}
37091-
37092-.lv-heroes-list {
37093- display: flex;
37094- flex-direction: column;
37095- gap: 20px;
37096-}
37097-
37098-.lv-hero-card {
37099- display: grid;
37100- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
37101- gap: 48px;
37102- align-items: center;
37103- border: 1px solid rgba(22,24,29,0.08);
37104- border-radius: 20px;
37105- background: #ffffff;
37106- padding: 44px 48px;
37107- text-decoration: none;
37108- transition: border-color 0.2s, box-shadow 0.2s;
37109-}
37110-.lv-hero-card:hover {
37111- border-color: rgba(22,24,29,0.22);
37112- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
37113-}
37114-
37115-.lv-hero-card-left {}
37116-
37117-.lv-hero-card-title {
37118- font-family: 'Inter Tight', sans-serif;
37119- font-size: 26px;
37120- font-weight: 600;
37121- letter-spacing: -0.022em;
37122- line-height: 1.15;
37123- color: #16181d;
37124- margin: 0 0 12px;
37125-}
37126-
37127-.lv-hero-card-body {
37128- font-size: 14.5px;
37129- color: #6b7080;
37130- margin: 0 0 18px;
37131- line-height: 1.65;
37132-}
37133-
37134-.lv-hero-card-cta {
37135- font-size: 13.5px;
37136- font-weight: 600;
37137- color: #4353c9;
37138-}
37139-
37140-.lv-terminal {
37141- border: 1px solid rgba(22,24,29,0.07);
37142- border-radius: 14px;
37143- background: #fcfcfd;
37144- padding: 20px 22px;
37145- font-family: 'JetBrains Mono', monospace;
37146- font-size: 12px;
37147- line-height: 1.9;
37148- overflow: hidden;
37149-}
37150-
37151-.lv-terminal-line {
37152- display: flex;
37153- align-items: center;
37154- gap: 10px;
37155- white-space: nowrap;
37156- overflow: hidden;
37157- text-overflow: ellipsis;
37158-}
37159-
37160-/* Platform */
37161-.lv-platform {
37162- padding: 96px 0;
37163- background: #ffffff;
37164- border-top: 1px solid rgba(22,24,29,0.07);
37165-}
37166-
37167-.lv-platform-inner {
37168- max-width: 1200px;
37169- margin: 0 auto;
37170- padding: 0 28px;
37171-}
37172-
37173-.lv-cap-grid {
37174- display: grid;
37175- grid-template-columns: repeat(4, 1fr);
37176- gap: 24px 32px;
37177-}
37178-
37179-.lv-cap-col {}
37180-
37181-.lv-cap-group {
37182- font-family: 'JetBrains Mono', monospace;
37183- font-size: 10.5px;
37184- letter-spacing: 0.12em;
37185- text-transform: uppercase;
37186- color: #8a8d99;
37187- font-weight: 500;
37188- margin-bottom: 12px;
37189- padding-bottom: 8px;
37190- border-bottom: 1px solid rgba(22,24,29,0.07);
37191-}
37192-
37193-.lv-cap-items {
37194- display: flex;
37195- flex-direction: column;
37196- gap: 7px;
37197-}
37198-
37199-.lv-cap-item {
37200- font-size: 12.5px;
37201- color: #3a3d45;
37202- line-height: 1.45;
37203-}
37204-
37205-/* Sovereignty */
37206-.lv-sovereign {
37207- position: relative;
37208- overflow: hidden;
37209- padding: 104px 0;
37210- color: #fff;
37211- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
37212-}
37213-
37214-.lv-sovereign-grid-bg {
37215- position: absolute;
37216- inset: 0;
37217- opacity: 0.4;
37218- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
37219- background-size: 56px 56px;
37220- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
37221- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
37222-}
37223-
37224-.lv-sovereign-inner {
37225- position: relative;
37226- max-width: 1200px;
37227- margin: 0 auto;
37228- padding: 0 28px;
37229-}
37230-
37231-.lv-section-header-dark {
37232- max-width: 680px;
37233- margin: 0 auto 48px;
37234- text-align: center;
37235-}
37236-
37237-.lv-layers-grid {
37238- display: grid;
37239- grid-template-columns: repeat(4, 1fr);
37240- gap: 10px;
37241- max-width: 980px;
37242- margin: 0 auto;
37243-}
37244-
37245-.lv-layer-chip {
37246- border: 1px solid rgba(255,255,255,0.10);
37247- border-radius: 10px;
37248- padding: 12px 16px;
37249- background: rgba(255,255,255,0.03);
37250-}
37251-
37252-.lv-layer-cta {
37253- border-color: rgba(169,180,238,0.30);
37254- background: rgba(169,180,238,0.06);
37255- display: flex;
37256- align-items: center;
37257- text-decoration: none;
37258- transition: background 0.15s;
37259-}
37260-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
37261-
37262-.lv-layer-cta-text {
37263- font-size: 13px;
37264- font-weight: 500;
37265- color: #a9b4ee;
37266-}
37267-
37268-.lv-layer-n {
37269- font-family: 'JetBrains Mono', monospace;
37270- font-size: 10px;
37271- color: rgba(255,255,255,0.4);
37272- margin-bottom: 3px;
37273-}
37274-
37275-.lv-layer-name {
37276- font-size: 13px;
37277- font-weight: 500;
37278- color: rgba(255,255,255,0.92);
37279-}
37280-
37281-.lv-sovereign-feats {
37282- display: flex;
37283- gap: 44px;
37284- justify-content: center;
37285- flex-wrap: wrap;
37286- margin-top: 52px;
37287- text-align: center;
37288-}
37289-
37290-.lv-sovereign-feat {}
37291-
37292-.lv-sovereign-feat-title {
37293- font-family: 'Inter Tight', sans-serif;
37294- font-size: 20px;
37295- font-weight: 700;
37296- color: #fff;
37297-}
37298-
37299-.lv-sovereign-feat-sub {
37300- color: rgba(255,255,255,0.55);
37301- font-size: 13px;
37302- margin-top: 2px;
37303-}
37304-
37305-/* Twin cards */
37306-.lv-twin {
37307- padding: 96px 0;
37308- background: #fcfcfd;
37309-}
37310-
37311-.lv-twin-inner {
37312- max-width: 1200px;
37313- margin: 0 auto;
37314- padding: 0 28px;
37315- display: grid;
37316- grid-template-columns: 1fr 1fr;
37317- gap: 24px;
37318-}
37319-
37320-.lv-twin-card {
37321- border: 1px solid rgba(22,24,29,0.08);
37322- border-radius: 20px;
37323- background: #ffffff;
37324- padding: 44px 48px;
37325-}
37326-
37327-.lv-twin-title {
37328- font-family: 'Inter Tight', sans-serif;
37329- font-size: 24px;
37330- font-weight: 600;
37331- letter-spacing: -0.02em;
37332- line-height: 1.2;
37333- margin: 0 0 12px;
37334- color: #16181d;
37335-}
37336-
37337-.lv-twin-body {
37338- font-size: 14.5px;
37339- color: #6b7080;
37340- margin: 0 0 16px;
37341- line-height: 1.7;
37342-}
37343-
37344-.lv-twin-link {
37345- font-size: 13.5px;
37346- font-weight: 600;
37347- color: #4353c9;
37348- text-decoration: none;
37349-}
37350-.lv-twin-link:hover { text-decoration: underline; }
37351-
37352-/* Quote */
37353-.lv-quote {
37354- padding: 40px 0 96px;
37355- background: #fcfcfd;
37356-}
37357-
37358-.lv-quote-inner {
37359- max-width: 980px;
37360- margin: 0 auto;
37361- padding: 0 28px;
37362- text-align: center;
37363-}
37364-
37365-.lv-quote-text {
37366- font-family: 'Inter Tight', sans-serif;
37367- font-weight: 600;
37368- font-size: clamp(26px, 3.8vw, 42px);
37369- line-height: 1.2;
37370- letter-spacing: -0.025em;
37371- margin: 0;
37372- color: #111318;
37373-}
37374-
37375-.lv-em {
37376- font-style: normal;
37377- color: #4353c9;
37378-}
37379-
37380-/* CTA */
37381-.lv-cta-section {
37382- padding: 0 0 104px;
37383- background: #fcfcfd;
37384-}
37385-
37386-.lv-cta-card {
37387- max-width: 820px;
37388- margin: 0 auto;
37389- padding: 64px 40px;
37390- text-align: center;
37391- background: #ffffff;
37392- border: 1px solid rgba(22,24,29,0.08);
37393- border-radius: 26px;
37394- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
37395- position: relative;
37396- overflow: hidden;
37397-}
37398-
37399-.lv-cta-glow {
37400- position: absolute;
37401- inset: -40% 0 auto 0;
37402- height: 280px;
37403- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
37404- pointer-events: none;
37405-}
37406-
37407-.lv-cta-h2 {
37408- font-family: 'Inter Tight', sans-serif;
37409- font-weight: 700;
37410- letter-spacing: -0.028em;
37411- font-size: clamp(30px, 4.6vw, 48px);
37412- margin: 0;
37413- position: relative;
37414- color: #111318;
37415-}
37416-
37417-.lv-cta-sub {
37418- color: #6b7080;
37419- font-size: 17px;
37420- margin: 16px 0 30px;
37421- position: relative;
37422-}
37423-
37424-.lv-cta-actions {
37425- display: flex;
37426- gap: 12px;
37427- justify-content: center;
37428- flex-wrap: wrap;
37429- position: relative;
37430-}
37431-
37432-.lv-cta-fine {
37433- margin-top: 20px;
37434- font-family: 'JetBrains Mono', monospace;
37435- font-size: 11px;
37436- color: #8a8d99;
37437- position: relative;
37438-}
37439-
37440-/* Footer */
37441-.lv-footer {
37442- border-top: 1px solid rgba(22,24,29,0.07);
37443- background: #ffffff;
37444- padding: 56px 0 30px;
37445-}
37446-
37447-.lv-footer-inner {
37448- max-width: 1200px;
37449- margin: 0 auto;
37450- padding: 0 28px;
37451- display: flex;
37452- gap: 48px;
37453- flex-wrap: wrap;
37454- justify-content: space-between;
37455-}
37456-
37457-.lv-footer-brand {}
37458-
37459-.lv-footer-tagline {
37460- color: #6b7080;
37461- font-size: 13.5px;
37462- margin: 12px 0 0;
37463- max-width: 32ch;
37464- line-height: 1.6;
37465-}
37466-
37467-.lv-footer-cols {
37468- display: flex;
37469- gap: 64px;
37470- flex-wrap: wrap;
37471-}
37472-
37473-.lv-footer-col {
37474- display: flex;
37475- flex-direction: column;
37476- gap: 9px;
37477-}
37478-
37479-.lv-footer-col-head {
37480- font-family: 'JetBrains Mono', monospace;
37481- font-size: 11px;
37482- text-transform: uppercase;
37483- letter-spacing: 0.1em;
37484- color: #8a8d99;
37485- margin: 0 0 4px;
37486- font-weight: 500;
37487-}
37488-
37489-.lv-footer-link {
37490- color: #3a3d45;
37491- font-size: 13.5px;
37492- text-decoration: none;
37493- transition: color 0.15s;
37494-}
37495-.lv-footer-link:hover { color: #16181d; }
37496-
37497-.lv-footer-bar {
37498- max-width: 1200px;
37499- margin: 44px auto 0;
37500- padding: 22px 28px 0;
37501- border-top: 1px solid rgba(22,24,29,0.06);
37502- display: flex;
37503- justify-content: space-between;
37504- flex-wrap: wrap;
37505- gap: 8px;
37506- color: #8a8d99;
37507- font-size: 12.5px;
37508-}
37509-
37510-.lv-footer-stack {
37511- font-family: 'JetBrains Mono', monospace;
37512- font-size: 11px;
37513-}
37514-`;
37515diff --git a/src/views/layout.tsx b/src/views/layout.tsx
37516index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
37517--- a/src/views/layout.tsx
37518+++ b/src/views/layout.tsx
37519@@ -3153,9 +3153,12 @@
37520 font-weight: 500;
37521 line-height: 1.4;
37522 }
37523- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
37524- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
37525- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
37526+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
37527+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
37528+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
37529+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
37530+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
37531+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
37532 .state-merged { color: var(--accent); }
37533 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
37534
37535diff --git a/src/views/ui.tsx b/src/views/ui.tsx
37536index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
37537--- a/src/views/ui.tsx
37538+++ b/src/views/ui.tsx
37539@@ -232,7 +232,7 @@
37540
37541 export const Badge: FC<
37542 PropsWithChildren<{
37543- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
37544+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
37545 style?: string;
37546 }>
37547 > = ({ children, variant = "default", style }) => {
37548@@ -241,9 +241,12 @@
37549 variant === "closed" ? "badge-closed" :
37550 variant === "merged" ? "badge-merged" :
37551 variant === "success" ? "badge-success" :
37552- variant === "danger" ? "badge-danger" :
37553- variant === "warning" ? "badge-warning" :
37554- "badge";
37555+ variant === "danger" ? "badge-danger" :
37556+ variant === "warning" ? "badge-warning" :
37557+ variant === "live" ? "badge-live" :
37558+ variant === "soon" ? "badge-soon" :
37559+ variant === "preview" ? "badge-preview" :
37560+ "badge";
37561 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
37562 };
37563
37564
37565diff --git a/src/views/landing-pro.tsx b/src/views/landing-pro.tsx
37566index 7af3994da2028d1f8b90f11714cc713d70e4dfae..e311df20b024a1898d30a0cc91679638e4c2ce27
37567--- a/src/views/landing-pro.tsx
37568+++ b/src/views/landing-pro.tsx
37569@@ -42,7 +42,7 @@
37570
37571 // %%% inline SVG icon helper %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37572
37573-function icon(paths: string, color = "#4353c9", size = 20) {
37574+function icon(paths: string, color = "#0891b2", size = 20) {
37575 return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${paths}</svg>`;
37576 }
37577
37578@@ -947,7 +947,7 @@
37579 const css = `
37580 /* %% tokens %% */
37581 :root{
37582- --lp-brand:#4353c9;--lp-brand-h:#3848b6;
37583+ --lp-brand:#0891b2;--lp-brand-h:#0a7288;
37584 --lp-bg:#ffffff;--lp-soft:#fafafb;
37585 --lp-ink:#0a0b0d;--lp-ink-2:#3a3d45;--lp-muted:#6b7280;
37586 --lp-border:rgba(0,0,0,.08);
37587diff --git a/src/views/landing-v2.tsx b/src/views/landing-v2.tsx
37588deleted file mode 100644
37589index e71fe33d82576cfad7e79165da8cf94295cb2309..0000000000000000000000000000000000000000
37590--- a/src/views/landing-v2.tsx
37591+++ /dev/null
37592@@ -1,1447 +0,0 @@
37593-import type { FC } from "hono/jsx";
37594-
37595-export interface LandingPageProps {
37596- stats?: {
37597- publicRepos?: number;
37598- users?: number;
37599- };
37600-}
37601-
37602-const demoAllEvents = [
37603- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
37604- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
37605- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
37606- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
37607- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
37608-];
37609-
37610-const tickerItems = [
37611- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
37612- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
37613- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
37614- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
37615- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
37616- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
37617- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
37618- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
37619- { dot: "#1e7f5c", text: "auto-merge � northwind-labs/api !341  gates green" },
37620- { dot: "#b45309", text: "repair � acme-tools/web !88  attempt 2 of 5" },
37621- { dot: "#4353c9", text: "review � Sonnet 5 posted 6 comments on helvetia/core !129" },
37622- { dot: "#1e7f5c", text: "deploy � gluecron 82321e8 �! production, 41s" },
37623- { dot: "#1e7f5c", text: "fleet � auth-header rename merged atomically across 4 repos" },
37624- { dot: "#4353c9", text: "sandbox � pr-220.preview booted" },
37625- { dot: "#1e7f5c", text: "flaky test assassinated � sandbox-boot.test.ts fixed after bisect" },
37626- { dot: "#b45309", text: "advisory � transitive CVE patched, exposure 19 min" },
37627-];
37628-
37629-const stageData = [
37630- { name: "Push", desc: "Git-native Smart HTTP. Your existing workflow, unchanged.", meta: "no queue, ever" },
37631- { name: "Gate", desc: "Security, tests, types  enforced at the moment of push.", meta: "before the branch moves" },
37632- { name: "Review", desc: "Sonnet 5 reviews the instant the PR opens. Line-level, auditable.", meta: "the model devs trust" },
37633- { name: "Repair", desc: "Red gate? The agent fixes it inside an isolated sandbox.", meta: "93.5% self-heal" },
37634- { name: "Merge", desc: "Green across the board merges immediately  with your approval policy.", meta: "you set the policy" },
37635- { name: "Deploy", desc: "Streams live to the dashboard. One-click rollback, always.", meta: "reversible by design" },
37636-];
37637-
37638-const heroFeatures = [
37639- {
37640- href: "/",
37641- eyebrow: "01 � The autonomous repair loop",
37642- title: "Failures fix themselves  and show their work.",
37643- body: "When a gate goes red, the repair engine attaches to the PR's own sandbox, reproduces the failure, drafts a bounded patch, and re-runs the gates. Every attempt is recorded to the flywheel with the
37644failing gate, the diff, and the outcome. You watch it happen live, interrupt any time, or take the keyboard yourself.",
37645- cta: "Watch a live repair session",
37646- mock: [
37647- { dot: "#b42318", color: "#b42318", text: "' gate: tests  2 failing" },
37648- { dot: "#b45309", color: "#b45309", text: "agent attached � sandbox pr-218" },
37649- { dot: "#b45309", color: "#b45309", text: "patch drafted � +9 "3 � bounded loop" },
37650- { dot: "#1e7f5c", color: "#1e7f5c", text: "' gates re-run  412 passing" },
37651- { dot: "#1e7f5c", color: "#8a8d99", text: "waiting on your approval" },
37652- ],
37653- },
37654- {
37655- href: "/",
37656- eyebrow: "02 � Live sandbox isolation",
37657- title: "Every PR gets its own instant, disposable environment.",
37658- body: "The moment a PR opens, an isolated environment boots on your hardware: preview URL, shared terminal, real data shape. Reviewers click a link instead of pulling a branch. Agents repair inside the
37659same box they broke nothing in. It expires on merge and leaves an audit trail behind.",
37660- cta: "See a PR with its sandbox",
37661- mock: [
37662- { dot: "#1e7f5c", color: "#1e7f5c", text: "pr-218.preview.gluecron.com � live" },
37663- { dot: "#c4c6cf", color: "#8a8d99", text: "isolated � branch-scoped � your metal" },
37664- { dot: "#4353c9", color: "#4353c9", text: "reviewer joined the shared terminal" },
37665- { dot: "#c4c6cf", color: "#8a8d99", text: "expires on merge � audit retained" },
37666- ],
37667- },
37668- {
37669- href: "/",
37670- eyebrow: "03 � Multiplayer IDE workspaces",
37671- title: "You and the agent, side by side, in your editor.",
37672- body: "The VS Code and JetBrains extensions join the same live session: you see the agent's cursor, it sees your edits, and either of you can take over. Prefer to fly solo? Observe-only mode turns the
37673agent into a silent reviewer in your gutter. The browser becomes optional.",
37674- cta: "See the editor session",
37675- mock: [
37676- { dot: "#4353c9", color: "#4353c9", text: "you: the loop needs an upper bound" },
37677- { dot: "#1e7f5c", color: "#1e7f5c", text: "claude: agreed  typing lines 151 154" },
37678- { dot: "#1e7f5c", color: "#d6d8e0", text: "+ for (let i = 0; i < MAX_ATTEMPTS; i++)" },
37679- { dot: "#c4c6cf", color: "#8a8d99", text: "mode: suggest �! you accept � or observe-only" },
37680- ],
37681- },
37682-];
37683-
37684-const capabilities = [
37685- { group: "Code hosting", items: ["Git Smart HTTP", "SSH, PATs, OAuth2 provider", "Forks, stars, templates, mirrors", "Releases & protected tags", "Push policy rulesets"] },
37686- { group: "Collaboration", items: ["Issues, labels, milestones", "Inline review & draft PRs", "Merge queues", "Discussions, wikis, projects", "Gists & reactions"] },
37687- { group: "AI-native", items: ["Sonnet 5 code review", "Security review + secret scanner", "Auto-repair engine", "Spec-to-PR with plan approval", "Merge-conflict resolver", "Org memory & archaeology"] },
37688- { group: "Automation", items: ["Push-time gates", "Workflow runner, zero YAML", "HMAC webhooks", "Dependency updater", "CODEOWNERS auto-sync"] },
37689- { group: "Platform", items: ["Orgs, teams, roles", "2FA, passkeys, OIDC SSO", "npm package registry", "Static pages hosting", "REST + GraphQL + MCP"] },
37690- { group: "Sovereignty", items: ["Self-host anywhere Bun runs", "Local LLM routing", "Air-gapped region sync", "Own-edge Caddy ingress", "Data-region residency"] },
37691- { group: "Observability", items: ["Request-ID tracing", "Audit log, 100% coverage", "Traffic analytics", "Org insights & green rate", "Health scores"] },
37692- { group: "Trust", items: ["Live public quality metrics", "Blast radius before approval", "One-click reversal", "Zero irreversible auto-actions", "Manual twin for every surface"] },
37693-];
37694-
37695-const sovereignLayerNames = [
37696- "Frontend foundation", "APIs & backend logic", "Database & storage", "Auth & permissions",
37697- "Hosting & deployment", "Cloud & compute", "CI/CD & version control", "Security & RLS",
37698- "Rate limiting", "Caching & CDN", "Load balancing & scaling", "Error tracking & logs",
37699- "Availability & recovery",
37700-];
37701-
37702-export const LandingPageV2: FC<LandingPageProps> = (_props) => {
37703- return (
37704- <>
37705- <style dangerouslySetInnerHTML={{ __html: css }} />
37706-
37707- {/* Nav */}
37708- <header class="lv-nav">
37709- <div class="lv-nav-inner">
37710- <a href="/" class="lv-logo">
37711- <span class="lv-logo-mark"></span>gluecron
37712- </a>
37713- <nav class="lv-nav-links">
37714- <a href="#loop" class="lv-nav-link">The loop</a>
37715- <a href="#platform" class="lv-nav-link">Platform</a>
37716- <a href="#sovereign" class="lv-nav-link">Sovereignty</a>
37717- <a href="/trust" class="lv-nav-link">Trust</a>
37718- </nav>
37719- <div class="lv-nav-ctas">
37720- <a href="/login" class="lv-btn-secondary">Sign in</a>
37721- <a href="/register" class="lv-btn-primary">Start building</a>
37722- </div>
37723- </div>
37724- </header>
37725-
37726- {/* Hero */}
37727- <section class="lv-hero">
37728- <div class="lv-hero-glow"></div>
37729- <div class="lv-hero-inner">
37730- <div class="lv-hero-badge">
37731- <span class="lv-dot lv-dot-green lv-pulse"></span>
37732- Live: a repair loop converged on pr-218 while you read this
37733- </div>
37734- <h1 class="lv-h1">Your PR is done before the dinosaurs finish booting.</h1>
37735- <p class="lv-hero-sub">
37736- No CI queue. No pipeline warm-up. Gates fire <strong class="lv-strong">at the moment of push</strong>, <strong class="lv-strong">Claude Sonnet 5</strong> reviews the instant your PR opens,
37737failures repair themselves in isolated sandboxes, and clean work merges immediately. You stay in flow  and the manual path is always one click away.
37738- </p>
37739- <div class="lv-hero-actions">
37740- <a href="/register" class="lv-cta-primary">Start building  free �!</a>
37741- <a href="/" class="lv-cta-secondary">Watch a live repair</a>
37742- </div>
37743- <div class="lv-hero-tag">Self-hosted � Git-native � Sonnet 5 reviews � Manual-always-possible</div>
37744-
37745- {/* Live product window */}
37746- <div class="lv-demo-window">
37747- <div class="lv-demo-bar">
37748- <span class="lv-demo-dot"></span>
37749- <span class="lv-demo-dot"></span>
37750- <span class="lv-demo-dot"></span>
37751- <span class="lv-demo-url">gluecron.com / ccantynz-alt / gluecron � PR !218 � live</span>
37752- <span class="lv-demo-live">
37753- <span class="lv-dot lv-dot-green lv-pulse" style="width:6px;height:6px"></span>
37754- LIVE
37755- </span>
37756- </div>
37757- <div class="lv-demo-body" id="lv-demo-body">
37758- {/* Events rendered by JS */}
37759- {demoAllEvents.slice(0, 1).map((e, i) => (
37760- <div class="lv-demo-event" key={i}>
37761- <div class="lv-demo-event-track">
37762- <span class="lv-dot lv-pulse" style={`width:8px;height:8px;background:${e.dot}`}></span>
37763- <span class="lv-demo-line" style="display:none"></span>
37764- </div>
37765- <div class="lv-demo-event-content">
37766- <div class="lv-demo-event-header">
37767- <span class="lv-demo-event-title">{e.title}</span>
37768- <span class="lv-demo-event-time">{e.time}</span>
37769- </div>
37770- <div class="lv-demo-event-body">{e.body}</div>
37771- </div>
37772- </div>
37773- ))}
37774- </div>
37775- </div>
37776- </div>
37777-
37778- {/* Activity ticker */}
37779- <div class="lv-ticker-wrap">
37780- <div class="lv-ticker-track">
37781- {tickerItems.map((t, i) => (
37782- <span class="lv-ticker-item" key={i}>
37783- <span class="lv-dot" style={`width:6px;height:6px;background:${t.dot}`}></span>
37784- {t.text}
37785- </span>
37786- ))}
37787- </div>
37788- </div>
37789- </section>
37790-
37791- {/* Stat band */}
37792- <section class="lv-stats">
37793- <div class="lv-stats-inner">
37794- <div class="lv-stat">
37795- <div class="lv-stat-num">Sonnet 5</div>
37796- <div class="lv-stat-label">reviews every pull request  the model developers trust</div>
37797- </div>
37798- <div class="lv-stat">
37799- <div class="lv-stat-num">93.5%</div>
37800- <div class="lv-stat-label">of failures self-repair without a human</div>
37801- </div>
37802- <div class="lv-stat">
37803- <div class="lv-stat-num">1.9%</div>
37804- <div class="lv-stat-label">AI merges reverted  published live</div>
37805- </div>
37806- <div class="lv-stat">
37807- <div class="lv-stat-num">0</div>
37808- <div class="lv-stat-label">irreversible actions taken autonomously</div>
37809- </div>
37810- </div>
37811- </section>
37812-
37813- {/* The loop */}
37814- <section id="loop" class="lv-loop">
37815- <div class="lv-loop-inner">
37816- <div class="lv-section-header">
37817- <div class="lv-eyebrow lv-eyebrow-indigo">The closed loop  running now</div>
37818- <h2 class="lv-h2">Push. Gate. Review. Repair. Merge. Deploy.</h2>
37819- <p class="lv-section-sub">Six stages, zero YAML, full audit trail. The highlighted stage is cycling live  this is the pipeline, not a diagram of one.</p>
37820- </div>
37821- <div class="lv-stages" id="lv-stages">
37822- {stageData.map((s, i) => (
37823- <div class={`lv-stage-card${i === 0 ? " lv-stage-active" : ""}`} key={i} data-stage={i}>
37824- <div class="lv-stage-header">
37825- <span class={`lv-dot${i === 0 ? " lv-dot-indigo lv-pulse" : " lv-dot-idle"}`} style="width:7px;height:7px"></span>
37826- <span class="lv-stage-n">0{i + 1}</span>
37827- </div>
37828- <div class="lv-stage-name">{s.name}</div>
37829- <div class="lv-stage-desc">{s.desc}</div>
37830- <div class={`lv-stage-meta${i === 0 ? " lv-stage-meta-active" : ""}`}>{s.meta}</div>
37831- </div>
37832- ))}
37833- </div>
37834- </div>
37835- </section>
37836-
37837- {/* Three heroes */}
37838- <section class="lv-heroes">
37839- <div class="lv-heroes-inner">
37840- <div class="lv-heroes-header">
37841- <div class="lv-eyebrow lv-eyebrow-indigo">Three things nobody else has</div>
37842- <h2 class="lv-h2">Legacy hosts store code.<br />Gluecron finishes it.</h2>
37843- </div>
37844- <div class="lv-heroes-list">
37845- {heroFeatures.map((h, i) => (
37846- <a href={h.href} class="lv-hero-card" key={i}>
37847- <div class="lv-hero-card-left">
37848- <div class="lv-eyebrow">{h.eyebrow}</div>
37849- <h3 class="lv-hero-card-title">{h.title}</h3>
37850- <p class="lv-hero-card-body">{h.body}</p>
37851- <span class="lv-hero-card-cta">{h.cta} �!</span>
37852- </div>
37853- <div class="lv-terminal">
37854- {h.mock.map((m, j) => (
37855- <div class="lv-terminal-line" key={j}>
37856- <span class="lv-dot" style={`width:6px;height:6px;background:${m.dot};flex-shrink:0`}></span>
37857- <span style={`color:${m.color};overflow:hidden;text-overflow:ellipsis`}>{m.text}</span>
37858- </div>
37859- ))}
37860- </div>
37861- </a>
37862- ))}
37863- </div>
37864- </div>
37865- </section>
37866-
37867- {/* Everything grid */}
37868- <section id="platform" class="lv-platform">
37869- <div class="lv-platform-inner">
37870- <div class="lv-section-header lv-section-header-center">
37871- <div class="lv-eyebrow lv-eyebrow-indigo">The whole platform, day one</div>
37872- <h2 class="lv-h2">Everything you'd assemble from five vendors. Built in.</h2>
37873- <p class="lv-section-sub">No marketplace scavenger hunt. Every capability below ships with your first push  on by default, opt out per feature.</p>
37874- </div>
37875- <div class="lv-cap-grid">
37876- {capabilities.map((c, i) => (
37877- <div class="lv-cap-col" key={i}>
37878- <div class="lv-cap-group">{c.group}</div>
37879- <div class="lv-cap-items">
37880- {c.items.map((item, j) => (
37881- <div class="lv-cap-item" key={j}>{item}</div>
37882- ))}
37883- </div>
37884- </div>
37885- ))}
37886- </div>
37887- </div>
37888- </section>
37889-
37890- {/* Sovereignty band */}
37891- <section id="sovereign" class="lv-sovereign">
37892- <div class="lv-sovereign-grid-bg"></div>
37893- <div class="lv-sovereign-inner">
37894- <div class="lv-section-header lv-section-header-center lv-section-header-dark">
37895- <div class="lv-eyebrow lv-eyebrow-light">Infrastructure sovereignty</div>
37896- <h2 class="lv-h2-dark">Your code. Your servers. Your models. Your keys.</h2>
37897- <p class="lv-section-sub-dark">Thirteen production layers with zero external runtime dependencies  no magic edge proxies, no third-party CDN in the serving path. Route AI to local models, burst
37898to private cloud, or run fully air-gapped on bare metal.</p>
37899- </div>
37900- <div class="lv-layers-grid">
37901- {sovereignLayerNames.map((name, i) => (
37902- <div class="lv-layer-chip" key={i}>
37903- <div class="lv-layer-n">{String(i + 1).padStart(2, "0")}</div>
37904- <div class="lv-layer-name">{name}</div>
37905- </div>
37906- ))}
37907- <a href="/" class="lv-layer-chip lv-layer-cta">
37908- <div class="lv-layer-cta-text">All self-owned �!</div>
37909- </a>
37910- </div>
37911- <div class="lv-sovereign-feats">
37912- <div class="lv-sovereign-feat">
37913- <div class="lv-sovereign-feat-title">Local inference first</div>
37914- <div class="lv-sovereign-feat-sub">your hardware, private cloud only on burst</div>
37915- </div>
37916- <div class="lv-sovereign-feat">
37917- <div class="lv-sovereign-feat-title">Air-gapped sync</div>
37918- <div class="lv-sovereign-feat-sub">repos, indices, and registries to bare metal</div>
37919- </div>
37920- <div class="lv-sovereign-feat">
37921- <div class="lv-sovereign-feat-title">Self-healing infra</div>
37922- <div class="lv-sovereign-feat-sub">the platform repairs itself with the same engine</div>
37923- </div>
37924- </div>
37925- </div>
37926- </section>
37927-
37928- {/* Manual-first + reversibility */}
37929- <section class="lv-twin">
37930- <div class="lv-twin-inner">
37931- <div class="lv-twin-card">
37932- <div class="lv-eyebrow">Manual-first, always</div>
37933- <h3 class="lv-twin-title">Every AI surface has a manual twin.</h3>
37934- <p class="lv-twin-body">Pull up the raw diff. Work the merge by hand. Set agents to observe-only, per repo or per developer. The manual path is the same first-class UI  never a degraded
37935fallback. Developers who never touch AI get the best git host they've ever used.</p>
37936- </div>
37937- <div class="lv-twin-card">
37938- <div class="lv-eyebrow">The reversibility guarantee</div>
37939- <h3 class="lv-twin-title">One click undoes anything the AI did.</h3>
37940- <p class="lv-twin-body">Every autonomous merge, repair, and deploy shows its blast radius before you approve and reverses in one click after. If it can't be reversed, it isn't done autonomously
37941 policy, not promise. Our quality numbers are published live, unedited.</p>
37942- <a href="/trust" class="lv-twin-link">See the live trust report �!</a>
37943- </div>
37944- </div>
37945- </section>
37946-
37947- {/* Quote */}
37948- <section class="lv-quote">
37949- <div class="lv-quote-inner">
37950- <p class="lv-quote-text">
37951- "GitHub gives you a place to <em class="lv-em">store</em> code.<br />
37952- Gluecron is where code gets <em class="lv-em">finished</em>."
37953- </p>
37954- </div>
37955- </section>
37956-
37957- {/* CTA */}
37958- <section class="lv-cta-section">
37959- <div class="lv-cta-card">
37960- <div class="lv-cta-glow"></div>
37961- <h2 class="lv-cta-h2">The next decade of shipping starts with one push.</h2>
37962- <p class="lv-cta-sub">Migrate from GitHub in one click  continuous two-way mirror, zero cutover risk, leave whenever you want.</p>
37963- <div class="lv-cta-actions">
37964- <a href="/register" class="lv-cta-primary">Create your account �!</a>
37965- <a href="/" class="lv-cta-secondary">Migrate from GitHub</a>
37966- </div>
37967- <div class="lv-cta-fine">free for individuals � internal orgs never billed � try without signing up at /play</div>
37968- </div>
37969- </section>
37970-
37971- {/* Footer */}
37972- <footer class="lv-footer">
37973- <div class="lv-footer-inner">
37974- <div class="lv-footer-brand">
37975- <a href="/" class="lv-logo">
37976- <span class="lv-logo-mark"></span>gluecron
37977- </a>
37978- <p class="lv-footer-tagline">The AI-native git host. Self-hosted, auditable, reversible  and fully manual whenever you want it.</p>
37979- </div>
37980- <div class="lv-footer-cols">
37981- <div class="lv-footer-col">
37982- <h4 class="lv-footer-col-head">Product</h4>
37983- <a href="/" class="lv-footer-link">Agent workspace</a>
37984- <a href="/" class="lv-footer-link">Fleet refactors</a>
37985- <a href="/" class="lv-footer-link">Org memory</a>
37986- <a href="/" class="lv-footer-link">IDE extensions</a>
37987- </div>
37988- <div class="lv-footer-col">
37989- <h4 class="lv-footer-col-head">Platform</h4>
37990- <a href="/" class="lv-footer-link">Production layers</a>
37991- <a href="/trust" class="lv-footer-link">Trust report</a>
37992- <a href="/" class="lv-footer-link">Docs</a>
37993- <a href="/" class="lv-footer-link">Status</a>
37994- </div>
37995- <div class="lv-footer-col">
37996- <h4 class="lv-footer-col-head">Company</h4>
37997- <a href="/" class="lv-footer-link">About</a>
37998- <a href="/" class="lv-footer-link">Pricing</a>
37999- <a href="/" class="lv-footer-link">Enterprise</a>
38000- </div>
38001- </div>
38002- </div>
38003- <div class="lv-footer-bar">
38004- <span>� 2026 Gluecron</span>
38005- <span class="lv-footer-stack">Self-hosted � Git-native � Sonnet 5 � Reversible</span>
38006- </div>
38007- </footer>
38008-
38009- <script dangerouslySetInnerHTML={{ __html: clientScript }} />
38010- </>
38011- );
38012-};
38013-
38014-export const LandingPage = LandingPageV2;
38015-export default LandingPageV2;
38016-
38017-const clientScript = `
38018-(function() {
38019- var demoAll = [
38020- { title: "Push received", time: "now", dot: "#16181d", body: "feat/repair-sandbox-loop  gates fire at the wire, not in a queue." },
38021- { title: "Sonnet 5 review posted", time: "now", dot: "#4353c9", body: "Line-level comments, one risk flag, verdict: approve pending gates." },
38022- { title: "Gate failed  repair engaged", time: "now", dot: "#b45309", body: "2 tests red. The agent attached to the PR sandbox and reproduced both in isolation." },
38023- { title: "Patch drafted, gates re-run", time: "now", dot: "#b45309", body: "Bounded the repair loop, threaded the sandbox session. All 412 tests green." },
38024- { title: "Merged & deployed", time: "now", dot: "#1e7f5c", body: "One human approval, then auto-merge and deploy. Fully reversible in one click." },
38025- ];
38026-
38027- var demoStep = 0;
38028- var stage = 0;
38029-
38030- function renderDemo() {
38031- var container = document.getElementById('lv-demo-body');
38032- if (!container) return;
38033- var visible = demoAll.slice(0, demoStep + 1);
38034- container.innerHTML = visible.map(function(e, i) {
38035- var isLast = i === visible.length - 1;
38036- var pulse = isLast && demoStep < 4 ? 'lv-pulse' : '';
38037- return '<div class="lv-demo-event">' +
38038- '<div class="lv-demo-event-track">' +
38039- '<span class="lv-dot ' + pulse + '" style="width:8px;height:8px;background:' + e.dot + '"></span>' +
38040- '<span class="lv-demo-line" style="display:' + (isLast ? 'none' : 'block') + '"></span>' +
38041- '</div>' +
38042- '<div class="lv-demo-event-content">' +
38043- '<div class="lv-demo-event-header">' +
38044- '<span class="lv-demo-event-title">' + e.title + '</span>' +
38045- '<span class="lv-demo-event-time">' + e.time + '</span>' +
38046- '</div>' +
38047- '<div class="lv-demo-event-body">' + e.body + '</div>' +
38048- '</div>' +
38049- '</div>';
38050- }).join('');
38051- }
38052-
38053- function renderStages() {
38054- var cards = document.querySelectorAll('.lv-stage-card');
38055- cards.forEach(function(card, i) {
38056- var dot = card.querySelector('.lv-dot');
38057- var meta = card.querySelector('.lv-stage-meta');
38058- if (i === stage) {
38059- card.classList.add('lv-stage-active');
38060- if (dot) {
38061- dot.classList.remove('lv-dot-idle');
38062- dot.classList.add('lv-dot-indigo', 'lv-pulse');
38063- }
38064- if (meta) meta.classList.add('lv-stage-meta-active');
38065- } else {
38066- card.classList.remove('lv-stage-active');
38067- if (dot) {
38068- dot.classList.add('lv-dot-idle');
38069- dot.classList.remove('lv-dot-indigo', 'lv-pulse');
38070- }
38071- if (meta) meta.classList.remove('lv-stage-meta-active');
38072- }
38073- });
38074- }
38075-
38076- renderDemo();
38077-
38078- setInterval(function() {
38079- demoStep = (demoStep + 1) % 5;
38080- renderDemo();
38081- }, 3600);
38082-
38083- setInterval(function() {
38084- stage = (stage + 1) % 6;
38085- renderStages();
38086- }, 2200);
38087-})();
38088-`;
38089-
38090-const css = `
38091-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
38092-
38093-*, *::before, *::after { box-sizing: border-box; }
38094-
38095-body {
38096- margin: 0;
38097- background: #fcfcfd;
38098- -webkit-font-smoothing: antialiased;
38099- text-rendering: optimizeLegibility;
38100- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
38101- font-size: 15px;
38102- line-height: 1.6;
38103- letter-spacing: -0.008em;
38104- color: #16181d;
38105-}
38106-
38107-@keyframes gcPulse {
38108- 0%, 100% { opacity: 1; }
38109- 50% { opacity: 0.35; }
38110-}
38111-
38112-@keyframes gcTicker {
38113- 0% { transform: translateX(0); }
38114- 100% { transform: translateX(-50%); }
38115-}
38116-
38117-/* Shared utilities */
38118-.lv-dot {
38119- display: inline-block;
38120- border-radius: 50%;
38121-}
38122-.lv-dot-green { background: #1e7f5c; }
38123-.lv-dot-indigo { background: #4353c9; }
38124-.lv-dot-idle { background: #c4c6cf; }
38125-.lv-pulse { animation: gcPulse 1.4s ease-in-out infinite; }
38126-
38127-.lv-strong { color: #16181d; font-weight: 600; }
38128-
38129-.lv-eyebrow {
38130- font-family: 'JetBrains Mono', monospace;
38131- font-size: 11px;
38132- letter-spacing: 0.12em;
38133- text-transform: uppercase;
38134- color: #8a8d99;
38135- font-weight: 500;
38136- margin-bottom: 12px;
38137-}
38138-.lv-eyebrow-indigo { color: #4353c9; font-size: 11.5px; margin-bottom: 16px; }
38139-.lv-eyebrow-light { color: #a9b4ee; font-size: 11.5px; margin-bottom: 16px; }
38140-
38141-.lv-h1 {
38142- font-family: 'Inter Tight', sans-serif;
38143- font-weight: 700;
38144- letter-spacing: -0.035em;
38145- font-size: clamp(44px, 7vw, 84px);
38146- line-height: 0.98;
38147- margin: 30px auto 0;
38148- max-width: 14ch;
38149- color: #111318;
38150-}
38151-
38152-.lv-h2 {
38153- font-family: 'Inter Tight', sans-serif;
38154- font-weight: 700;
38155- letter-spacing: -0.028em;
38156- font-size: clamp(30px, 4.4vw, 48px);
38157- line-height: 1.05;
38158- margin: 0;
38159- color: #111318;
38160-}
38161-
38162-.lv-h2-dark {
38163- font-family: 'Inter Tight', sans-serif;
38164- font-weight: 700;
38165- letter-spacing: -0.028em;
38166- font-size: clamp(30px, 4.6vw, 52px);
38167- line-height: 1.05;
38168- margin: 0;
38169- color: #fff;
38170-}
38171-
38172-.lv-section-header {
38173- max-width: 640px;
38174- margin: 0 auto 56px;
38175-}
38176-
38177-.lv-section-header-center {
38178- text-align: center;
38179-}
38180-
38181-.lv-section-sub {
38182- color: #6b7080;
38183- font-size: 17px;
38184- margin: 18px auto 0;
38185- max-width: 52ch;
38186-}
38187-
38188-.lv-section-sub-dark {
38189- color: rgba(255,255,255,0.72);
38190- font-size: 17px;
38191- margin: 18px auto 0;
38192- max-width: 56ch;
38193-}
38194-
38195-/* Nav */
38196-.lv-nav {
38197- position: sticky;
38198- top: 0;
38199- z-index: 60;
38200- backdrop-filter: saturate(180%) blur(14px);
38201- -webkit-backdrop-filter: saturate(180%) blur(14px);
38202- background: rgba(252,252,253,0.8);
38203- border-bottom: 1px solid rgba(22,24,29,0.07);
38204-}
38205-
38206-.lv-nav-inner {
38207- max-width: 1200px;
38208- margin: 0 auto;
38209- padding: 14px 28px;
38210- display: flex;
38211- align-items: center;
38212- gap: 28px;
38213-}
38214-
38215-.lv-logo {
38216- display: inline-flex;
38217- align-items: center;
38218- gap: 9px;
38219- font-family: 'Inter Tight', sans-serif;
38220- font-weight: 700;
38221- font-size: 17px;
38222- letter-spacing: -0.02em;
38223- color: #16181d;
38224- text-decoration: none;
38225-}
38226-
38227-.lv-logo-mark {
38228- width: 17px;
38229- height: 17px;
38230- border-radius: 5px;
38231- background: #4353c9;
38232- display: inline-block;
38233- flex-shrink: 0;
38234-}
38235-
38236-.lv-nav-links {
38237- display: flex;
38238- gap: 24px;
38239- font-size: 13.5px;
38240- font-weight: 500;
38241-}
38242-
38243-.lv-nav-link {
38244- color: #6b7080;
38245- text-decoration: none;
38246- transition: color 0.15s;
38247-}
38248-.lv-nav-link:hover { color: #16181d; }
38249-
38250-.lv-nav-ctas {
38251- margin-left: auto;
38252- display: flex;
38253- align-items: center;
38254- gap: 10px;
38255-}
38256-
38257-.lv-btn-secondary {
38258- padding: 8px 15px;
38259- border-radius: 8px;
38260- font-size: 13.5px;
38261- font-weight: 500;
38262- color: #16181d;
38263- border: 1px solid rgba(22,24,29,0.12);
38264- background: #ffffff;
38265- text-decoration: none;
38266- white-space: nowrap;
38267- transition: border-color 0.15s;
38268-}
38269-.lv-btn-secondary:hover { border-color: rgba(22,24,29,0.28); }
38270-
38271-.lv-btn-primary {
38272- padding: 8px 15px;
38273- border-radius: 8px;
38274- font-size: 13.5px;
38275- font-weight: 600;
38276- background: #16181d;
38277- color: #fff;
38278- text-decoration: none;
38279- white-space: nowrap;
38280- transition: box-shadow 0.15s;
38281-}
38282-.lv-btn-primary:hover { box-shadow: 0 8px 22px rgba(22,24,29,0.18); }
38283-
38284-/* Hero */
38285-.lv-hero {
38286- position: relative;
38287- overflow: hidden;
38288- padding: 88px 0 0;
38289-}
38290-
38291-.lv-hero-glow {
38292- position: absolute;
38293- inset: -10% 0 auto 0;
38294- height: 640px;
38295- pointer-events: none;
38296- background: radial-gradient(55% 55% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
38297-}
38298-
38299-.lv-hero-inner {
38300- position: relative;
38301- max-width: 1200px;
38302- margin: 0 auto;
38303- padding: 0 28px;
38304- text-align: center;
38305-}
38306-
38307-.lv-hero-badge {
38308- display: inline-flex;
38309- align-items: center;
38310- gap: 9px;
38311- font-size: 12.5px;
38312- font-weight: 600;
38313- color: #3a3d45;
38314- background: #ffffff;
38315- border: 1px solid rgba(22,24,29,0.10);
38316- border-radius: 9999px;
38317- padding: 7px 16px;
38318- box-shadow: 0 1px 2px rgba(22,24,29,0.04);
38319-}
38320-
38321-.lv-hero-sub {
38322- font-size: clamp(16px, 2vw, 19px);
38323- color: #6b7080;
38324- max-width: 60ch;
38325- margin: 24px auto 0;
38326- font-weight: 450;
38327- line-height: 1.65;
38328-}
38329-
38330-.lv-hero-actions {
38331- display: flex;
38332- gap: 12px;
38333- justify-content: center;
38334- flex-wrap: wrap;
38335- margin-top: 32px;
38336-}
38337-
38338-.lv-cta-primary {
38339- padding: 13px 24px;
38340- border-radius: 11px;
38341- font-size: 15.5px;
38342- font-weight: 600;
38343- background: #16181d;
38344- color: #fff;
38345- text-decoration: none;
38346- white-space: nowrap;
38347- transition: box-shadow 0.15s;
38348-}
38349-.lv-cta-primary:hover { box-shadow: 0 10px 26px rgba(22,24,29,0.22); }
38350-
38351-.lv-cta-secondary {
38352- padding: 13px 24px;
38353- border-radius: 11px;
38354- font-size: 15.5px;
38355- font-weight: 600;
38356- color: #16181d;
38357- border: 1px solid rgba(22,24,29,0.14);
38358- background: #ffffff;
38359- text-decoration: none;
38360- white-space: nowrap;
38361- transition: border-color 0.15s;
38362-}
38363-.lv-cta-secondary:hover { border-color: rgba(22,24,29,0.30); }
38364-
38365-.lv-hero-tag {
38366- margin-top: 18px;
38367- font-family: 'JetBrains Mono', monospace;
38368- font-size: 11.5px;
38369- letter-spacing: 0.08em;
38370- text-transform: uppercase;
38371- color: #8a8d99;
38372-}
38373-
38374-/* Demo window */
38375-.lv-demo-window {
38376- margin: 56px auto 0;
38377- max-width: 860px;
38378- text-align: left;
38379- background: #ffffff;
38380- border: 1px solid rgba(22,24,29,0.09);
38381- border-radius: 18px;
38382- box-shadow: 0 40px 90px -40px rgba(22,24,29,0.30), 0 1px 2px rgba(22,24,29,0.04);
38383- overflow: hidden;
38384-}
38385-
38386-.lv-demo-bar {
38387- display: flex;
38388- align-items: center;
38389- gap: 7px;
38390- padding: 12px 18px;
38391- border-bottom: 1px solid rgba(22,24,29,0.07);
38392- background: #fcfcfd;
38393-}
38394-
38395-.lv-demo-dot {
38396- width: 10px;
38397- height: 10px;
38398- border-radius: 50%;
38399- background: #e4e5ea;
38400-}
38401-
38402-.lv-demo-url {
38403- margin-left: 10px;
38404- font-family: 'JetBrains Mono', monospace;
38405- font-size: 12px;
38406- color: #6b7080;
38407-}
38408-
38409-.lv-demo-live {
38410- margin-left: auto;
38411- display: inline-flex;
38412- align-items: center;
38413- gap: 6px;
38414- font-size: 11px;
38415- font-weight: 600;
38416- color: #1e7f5c;
38417-}
38418-
38419-.lv-demo-body {
38420- padding: 22px 24px;
38421-}
38422-
38423-.lv-demo-event {
38424- display: grid;
38425- grid-template-columns: 18px minmax(0, 1fr);
38426- gap: 14px;
38427- padding-bottom: 20px;
38428- position: relative;
38429-}
38430-.lv-demo-event:last-child { padding-bottom: 0; }
38431-
38432-.lv-demo-event-track {
38433- display: flex;
38434- flex-direction: column;
38435- align-items: center;
38436-}
38437-
38438-.lv-demo-line {
38439- width: 1px;
38440- flex: 1;
38441- background: rgba(22,24,29,0.08);
38442- margin-top: 5px;
38443- min-height: 20px;
38444-}
38445-
38446-.lv-demo-event-content {}
38447-
38448-.lv-demo-event-header {
38449- display: flex;
38450- align-items: baseline;
38451- gap: 10px;
38452-}
38453-
38454-.lv-demo-event-title {
38455- font-size: 13.5px;
38456- font-weight: 600;
38457- color: #16181d;
38458-}
38459-
38460-.lv-demo-event-time {
38461- font-family: 'JetBrains Mono', monospace;
38462- font-size: 11px;
38463- color: #8a8d99;
38464-}
38465-
38466-.lv-demo-event-body {
38467- font-size: 13px;
38468- color: #6b7080;
38469- margin-top: 2px;
38470-}
38471-
38472-/* Ticker */
38473-.lv-ticker-wrap {
38474- border-top: 1px solid rgba(22,24,29,0.07);
38475- border-bottom: 1px solid rgba(22,24,29,0.07);
38476- background: #ffffff;
38477- margin-top: 64px;
38478- overflow: hidden;
38479- white-space: nowrap;
38480- position: relative;
38481-}
38482-
38483-.lv-ticker-track {
38484- display: inline-flex;
38485- animation: gcTicker 40s linear infinite;
38486- padding: 11px 0;
38487-}
38488-
38489-.lv-ticker-item {
38490- display: inline-flex;
38491- align-items: center;
38492- gap: 8px;
38493- font-family: 'JetBrains Mono', monospace;
38494- font-size: 11.5px;
38495- color: #6b7080;
38496- padding: 0 28px;
38497- border-right: 1px solid rgba(22,24,29,0.06);
38498-}
38499-
38500-/* Stats */
38501-.lv-stats {
38502- background: #fcfcfd;
38503-}
38504-
38505-.lv-stats-inner {
38506- max-width: 1200px;
38507- margin: 0 auto;
38508- display: grid;
38509- grid-template-columns: repeat(4, 1fr);
38510- gap: 24px;
38511- padding: 52px 28px;
38512-}
38513-
38514-.lv-stat {
38515- text-align: center;
38516-}
38517-
38518-.lv-stat-num {
38519- font-family: 'Inter Tight', sans-serif;
38520- font-weight: 700;
38521- font-size: clamp(30px, 4vw, 44px);
38522- letter-spacing: -0.025em;
38523- color: #111318;
38524-}
38525-
38526-.lv-stat-label {
38527- font-size: 13px;
38528- color: #6b7080;
38529- margin-top: 4px;
38530-}
38531-
38532-/* Loop */
38533-.lv-loop {
38534- padding: 96px 0;
38535- background: #ffffff;
38536- border-top: 1px solid rgba(22,24,29,0.07);
38537- border-bottom: 1px solid rgba(22,24,29,0.07);
38538-}
38539-
38540-.lv-loop-inner {
38541- max-width: 1200px;
38542- margin: 0 auto;
38543- padding: 0 28px;
38544-}
38545-
38546-.lv-stages {
38547- display: grid;
38548- grid-template-columns: repeat(6, 1fr);
38549- gap: 12px;
38550-}
38551-
38552-.lv-stage-card {
38553- border: 1px solid rgba(22,24,29,0.08);
38554- border-radius: 14px;
38555- background: #ffffff;
38556- padding: 20px 18px;
38557- transition: border-color 0.3s, background 0.3s;
38558-}
38559-
38560-.lv-stage-card.lv-stage-active {
38561- border-color: rgba(67,83,201,0.45);
38562- background: rgba(67,83,201,0.03);
38563-}
38564-
38565-.lv-stage-header {
38566- display: flex;
38567- align-items: center;
38568- gap: 8px;
38569- margin-bottom: 10px;
38570-}
38571-
38572-.lv-stage-n {
38573- font-family: 'JetBrains Mono', monospace;
38574- font-size: 10.5px;
38575- letter-spacing: 0.1em;
38576- text-transform: uppercase;
38577- color: #8a8d99;
38578-}
38579-
38580-.lv-stage-name {
38581- font-family: 'Inter Tight', sans-serif;
38582- font-size: 16px;
38583- font-weight: 600;
38584- letter-spacing: -0.01em;
38585- color: #16181d;
38586- margin-bottom: 5px;
38587-}
38588-
38589-.lv-stage-desc {
38590- font-size: 12px;
38591- color: #6b7080;
38592- line-height: 1.55;
38593-}
38594-
38595-.lv-stage-meta {
38596- font-family: 'JetBrains Mono', monospace;
38597- font-size: 10.5px;
38598- color: #8a8d99;
38599- margin-top: 10px;
38600- transition: color 0.3s;
38601-}
38602-
38603-.lv-stage-meta.lv-stage-meta-active {
38604- color: #4353c9;
38605-}
38606-
38607-/* Heroes */
38608-.lv-heroes {
38609- padding: 96px 0;
38610- background: #fcfcfd;
38611-}
38612-
38613-.lv-heroes-inner {
38614- max-width: 1200px;
38615- margin: 0 auto;
38616- padding: 0 28px;
38617-}
38618-
38619-.lv-heroes-header {
38620- max-width: 640px;
38621- margin-bottom: 56px;
38622-}
38623-
38624-.lv-heroes-list {
38625- display: flex;
38626- flex-direction: column;
38627- gap: 20px;
38628-}
38629-
38630-.lv-hero-card {
38631- display: grid;
38632- grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
38633- gap: 48px;
38634- align-items: center;
38635- border: 1px solid rgba(22,24,29,0.08);
38636- border-radius: 20px;
38637- background: #ffffff;
38638- padding: 44px 48px;
38639- text-decoration: none;
38640- transition: border-color 0.2s, box-shadow 0.2s;
38641-}
38642-.lv-hero-card:hover {
38643- border-color: rgba(22,24,29,0.22);
38644- box-shadow: 0 24px 60px -36px rgba(22,24,29,0.24);
38645-}
38646-
38647-.lv-hero-card-left {}
38648-
38649-.lv-hero-card-title {
38650- font-family: 'Inter Tight', sans-serif;
38651- font-size: 26px;
38652- font-weight: 600;
38653- letter-spacing: -0.022em;
38654- line-height: 1.15;
38655- color: #16181d;
38656- margin: 0 0 12px;
38657-}
38658-
38659-.lv-hero-card-body {
38660- font-size: 14.5px;
38661- color: #6b7080;
38662- margin: 0 0 18px;
38663- line-height: 1.65;
38664-}
38665-
38666-.lv-hero-card-cta {
38667- font-size: 13.5px;
38668- font-weight: 600;
38669- color: #4353c9;
38670-}
38671-
38672-.lv-terminal {
38673- border: 1px solid rgba(22,24,29,0.07);
38674- border-radius: 14px;
38675- background: #fcfcfd;
38676- padding: 20px 22px;
38677- font-family: 'JetBrains Mono', monospace;
38678- font-size: 12px;
38679- line-height: 1.9;
38680- overflow: hidden;
38681-}
38682-
38683-.lv-terminal-line {
38684- display: flex;
38685- align-items: center;
38686- gap: 10px;
38687- white-space: nowrap;
38688- overflow: hidden;
38689- text-overflow: ellipsis;
38690-}
38691-
38692-/* Platform */
38693-.lv-platform {
38694- padding: 96px 0;
38695- background: #ffffff;
38696- border-top: 1px solid rgba(22,24,29,0.07);
38697-}
38698-
38699-.lv-platform-inner {
38700- max-width: 1200px;
38701- margin: 0 auto;
38702- padding: 0 28px;
38703-}
38704-
38705-.lv-cap-grid {
38706- display: grid;
38707- grid-template-columns: repeat(4, 1fr);
38708- gap: 24px 32px;
38709-}
38710-
38711-.lv-cap-col {}
38712-
38713-.lv-cap-group {
38714- font-family: 'JetBrains Mono', monospace;
38715- font-size: 10.5px;
38716- letter-spacing: 0.12em;
38717- text-transform: uppercase;
38718- color: #8a8d99;
38719- font-weight: 500;
38720- margin-bottom: 12px;
38721- padding-bottom: 8px;
38722- border-bottom: 1px solid rgba(22,24,29,0.07);
38723-}
38724-
38725-.lv-cap-items {
38726- display: flex;
38727- flex-direction: column;
38728- gap: 7px;
38729-}
38730-
38731-.lv-cap-item {
38732- font-size: 12.5px;
38733- color: #3a3d45;
38734- line-height: 1.45;
38735-}
38736-
38737-/* Sovereignty */
38738-.lv-sovereign {
38739- position: relative;
38740- overflow: hidden;
38741- padding: 104px 0;
38742- color: #fff;
38743- background: radial-gradient(130% 130% at 50% -10%, #1b2030 0%, #12151f 45%, #0b0d13 100%);
38744-}
38745-
38746-.lv-sovereign-grid-bg {
38747- position: absolute;
38748- inset: 0;
38749- opacity: 0.4;
38750- background-image: linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
38751- background-size: 56px 56px;
38752- -webkit-mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
38753- mask-image: radial-gradient(80% 80% at 50% 0%, #000, transparent 78%);
38754-}
38755-
38756-.lv-sovereign-inner {
38757- position: relative;
38758- max-width: 1200px;
38759- margin: 0 auto;
38760- padding: 0 28px;
38761-}
38762-
38763-.lv-section-header-dark {
38764- max-width: 680px;
38765- margin: 0 auto 48px;
38766- text-align: center;
38767-}
38768-
38769-.lv-layers-grid {
38770- display: grid;
38771- grid-template-columns: repeat(4, 1fr);
38772- gap: 10px;
38773- max-width: 980px;
38774- margin: 0 auto;
38775-}
38776-
38777-.lv-layer-chip {
38778- border: 1px solid rgba(255,255,255,0.10);
38779- border-radius: 10px;
38780- padding: 12px 16px;
38781- background: rgba(255,255,255,0.03);
38782-}
38783-
38784-.lv-layer-cta {
38785- border-color: rgba(169,180,238,0.30);
38786- background: rgba(169,180,238,0.06);
38787- display: flex;
38788- align-items: center;
38789- text-decoration: none;
38790- transition: background 0.15s;
38791-}
38792-.lv-layer-cta:hover { background: rgba(169,180,238,0.10); }
38793-
38794-.lv-layer-cta-text {
38795- font-size: 13px;
38796- font-weight: 500;
38797- color: #a9b4ee;
38798-}
38799-
38800-.lv-layer-n {
38801- font-family: 'JetBrains Mono', monospace;
38802- font-size: 10px;
38803- color: rgba(255,255,255,0.4);
38804- margin-bottom: 3px;
38805-}
38806-
38807-.lv-layer-name {
38808- font-size: 13px;
38809- font-weight: 500;
38810- color: rgba(255,255,255,0.92);
38811-}
38812-
38813-.lv-sovereign-feats {
38814- display: flex;
38815- gap: 44px;
38816- justify-content: center;
38817- flex-wrap: wrap;
38818- margin-top: 52px;
38819- text-align: center;
38820-}
38821-
38822-.lv-sovereign-feat {}
38823-
38824-.lv-sovereign-feat-title {
38825- font-family: 'Inter Tight', sans-serif;
38826- font-size: 20px;
38827- font-weight: 700;
38828- color: #fff;
38829-}
38830-
38831-.lv-sovereign-feat-sub {
38832- color: rgba(255,255,255,0.55);
38833- font-size: 13px;
38834- margin-top: 2px;
38835-}
38836-
38837-/* Twin cards */
38838-.lv-twin {
38839- padding: 96px 0;
38840- background: #fcfcfd;
38841-}
38842-
38843-.lv-twin-inner {
38844- max-width: 1200px;
38845- margin: 0 auto;
38846- padding: 0 28px;
38847- display: grid;
38848- grid-template-columns: 1fr 1fr;
38849- gap: 24px;
38850-}
38851-
38852-.lv-twin-card {
38853- border: 1px solid rgba(22,24,29,0.08);
38854- border-radius: 20px;
38855- background: #ffffff;
38856- padding: 44px 48px;
38857-}
38858-
38859-.lv-twin-title {
38860- font-family: 'Inter Tight', sans-serif;
38861- font-size: 24px;
38862- font-weight: 600;
38863- letter-spacing: -0.02em;
38864- line-height: 1.2;
38865- margin: 0 0 12px;
38866- color: #16181d;
38867-}
38868-
38869-.lv-twin-body {
38870- font-size: 14.5px;
38871- color: #6b7080;
38872- margin: 0 0 16px;
38873- line-height: 1.7;
38874-}
38875-
38876-.lv-twin-link {
38877- font-size: 13.5px;
38878- font-weight: 600;
38879- color: #4353c9;
38880- text-decoration: none;
38881-}
38882-.lv-twin-link:hover { text-decoration: underline; }
38883-
38884-/* Quote */
38885-.lv-quote {
38886- padding: 40px 0 96px;
38887- background: #fcfcfd;
38888-}
38889-
38890-.lv-quote-inner {
38891- max-width: 980px;
38892- margin: 0 auto;
38893- padding: 0 28px;
38894- text-align: center;
38895-}
38896-
38897-.lv-quote-text {
38898- font-family: 'Inter Tight', sans-serif;
38899- font-weight: 600;
38900- font-size: clamp(26px, 3.8vw, 42px);
38901- line-height: 1.2;
38902- letter-spacing: -0.025em;
38903- margin: 0;
38904- color: #111318;
38905-}
38906-
38907-.lv-em {
38908- font-style: normal;
38909- color: #4353c9;
38910-}
38911-
38912-/* CTA */
38913-.lv-cta-section {
38914- padding: 0 0 104px;
38915- background: #fcfcfd;
38916-}
38917-
38918-.lv-cta-card {
38919- max-width: 820px;
38920- margin: 0 auto;
38921- padding: 64px 40px;
38922- text-align: center;
38923- background: #ffffff;
38924- border: 1px solid rgba(22,24,29,0.08);
38925- border-radius: 26px;
38926- box-shadow: 0 30px 80px -50px rgba(22,24,29,0.28);
38927- position: relative;
38928- overflow: hidden;
38929-}
38930-
38931-.lv-cta-glow {
38932- position: absolute;
38933- inset: -40% 0 auto 0;
38934- height: 280px;
38935- background: radial-gradient(50% 60% at 50% 0%, rgba(67,83,201,0.06), transparent 70%);
38936- pointer-events: none;
38937-}
38938-
38939-.lv-cta-h2 {
38940- font-family: 'Inter Tight', sans-serif;
38941- font-weight: 700;
38942- letter-spacing: -0.028em;
38943- font-size: clamp(30px, 4.6vw, 48px);
38944- margin: 0;
38945- position: relative;
38946- color: #111318;
38947-}
38948-
38949-.lv-cta-sub {
38950- color: #6b7080;
38951- font-size: 17px;
38952- margin: 16px 0 30px;
38953- position: relative;
38954-}
38955-
38956-.lv-cta-actions {
38957- display: flex;
38958- gap: 12px;
38959- justify-content: center;
38960- flex-wrap: wrap;
38961- position: relative;
38962-}
38963-
38964-.lv-cta-fine {
38965- margin-top: 20px;
38966- font-family: 'JetBrains Mono', monospace;
38967- font-size: 11px;
38968- color: #8a8d99;
38969- position: relative;
38970-}
38971-
38972-/* Footer */
38973-.lv-footer {
38974- border-top: 1px solid rgba(22,24,29,0.07);
38975- background: #ffffff;
38976- padding: 56px 0 30px;
38977-}
38978-
38979-.lv-footer-inner {
38980- max-width: 1200px;
38981- margin: 0 auto;
38982- padding: 0 28px;
38983- display: flex;
38984- gap: 48px;
38985- flex-wrap: wrap;
38986- justify-content: space-between;
38987-}
38988-
38989-.lv-footer-brand {}
38990-
38991-.lv-footer-tagline {
38992- color: #6b7080;
38993- font-size: 13.5px;
38994- margin: 12px 0 0;
38995- max-width: 32ch;
38996- line-height: 1.6;
38997-}
38998-
38999-.lv-footer-cols {
39000- display: flex;
39001- gap: 64px;
39002- flex-wrap: wrap;
39003-}
39004-
39005-.lv-footer-col {
39006- display: flex;
39007- flex-direction: column;
39008- gap: 9px;
39009-}
39010-
39011-.lv-footer-col-head {
39012- font-family: 'JetBrains Mono', monospace;
39013- font-size: 11px;
39014- text-transform: uppercase;
39015- letter-spacing: 0.1em;
39016- color: #8a8d99;
39017- margin: 0 0 4px;
39018- font-weight: 500;
39019-}
39020-
39021-.lv-footer-link {
39022- color: #3a3d45;
39023- font-size: 13.5px;
39024- text-decoration: none;
39025- transition: color 0.15s;
39026-}
39027-.lv-footer-link:hover { color: #16181d; }
39028-
39029-.lv-footer-bar {
39030- max-width: 1200px;
39031- margin: 44px auto 0;
39032- padding: 22px 28px 0;
39033- border-top: 1px solid rgba(22,24,29,0.06);
39034- display: flex;
39035- justify-content: space-between;
39036- flex-wrap: wrap;
39037- gap: 8px;
39038- color: #8a8d99;
39039- font-size: 12.5px;
39040-}
39041-
39042-.lv-footer-stack {
39043- font-family: 'JetBrains Mono', monospace;
39044- font-size: 11px;
39045-}
39046-`;
39047diff --git a/src/views/layout.tsx b/src/views/layout.tsx
39048index 63ddf0656a07a4051d5a2b834de8e7a776395fe0..8a3d88323fcf1ecc9a4f78121846c9f0338ff983
39049--- a/src/views/layout.tsx
39050+++ b/src/views/layout.tsx
39051@@ -3153,9 +3153,12 @@
39052 font-weight: 500;
39053 line-height: 1.4;
39054 }
39055- .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
39056- .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
39057- .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
39058+ .badge-open { background: rgba(52,211,153,0.10); color: var(--green); border: 1px solid rgba(52,211,153,0.35); }
39059+ .badge-closed { background: rgba(154,168,239,0.10); color: var(--text-link); border: 1px solid rgba(154,168,239,0.35); }
39060+ .badge-merged { background: rgba(91,110,232,0.10); color: var(--accent); border: 1px solid rgba(91,110,232,0.35); }
39061+ .badge-live { background: #0891b2; color: #fff; border: 1px solid #0891b2; }
39062+ .badge-soon { background: transparent; color: #6b7280; border: 1px solid #d1d5db; }
39063+ .badge-preview { background: transparent; color: #0891b2; border: 1px dashed rgba(8,145,178,0.45); }
39064 .state-merged { color: var(--accent); }
39065 .ai-review { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(91,110,232,0.3); }
39066
39067diff --git a/src/views/ui.tsx b/src/views/ui.tsx
39068index 1bdaa070caf5e8852683941c589f5f49e59e5cf8..b06481d851a3727c739c9254921f0304df587f95
39069--- a/src/views/ui.tsx
39070+++ b/src/views/ui.tsx
39071@@ -232,7 +232,7 @@
39072
39073 export const Badge: FC<
39074 PropsWithChildren<{
39075- variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning";
39076+ variant?: "default" | "open" | "closed" | "merged" | "success" | "danger" | "warning" | "live" | "soon" | "preview";
39077 style?: string;
39078 }>
39079 > = ({ children, variant = "default", style }) => {
39080@@ -241,9 +241,12 @@
39081 variant === "closed" ? "badge-closed" :
39082 variant === "merged" ? "badge-merged" :
39083 variant === "success" ? "badge-success" :
39084- variant === "danger" ? "badge-danger" :
39085- variant === "warning" ? "badge-warning" :
39086- "badge";
39087+ variant === "danger" ? "badge-danger" :
39088+ variant === "warning" ? "badge-warning" :
39089+ variant === "live" ? "badge-live" :
39090+ variant === "soon" ? "badge-soon" :
39091+ variant === "preview" ? "badge-preview" :
39092+ "badge";
39093 return <span class={`issue-badge ${cls}`} style={style}>{children}</span>;
39094 };
39095
39096
4fc7860Test User39097