Skip to content
1,035 linesCodeBlameRaw
1import {
2 ArrowRight,
3 BookOpen,
4 Bot,
5 Check,
6 CircleDashed,
7 Code2,
8 Eye,
9 Handshake,
10 Bell,
11 KeyRound,
12 Lock,
13 MessagesSquare,
14 PackageCheck,
15 ScanSearch,
16 ScrollText,
17 ShieldCheck,
18 Wallet,
19} from "lucide-react";
20import type { CSSProperties, ReactNode } from "react";
21import { Link } from "react-router";
22
23import { DeployArt, Live, QueueArt, WhyArt } from "./art";
24import { ProductTour } from "./product-tour";
25import { ButtonLink, CopyLine } from "./ui";
26
27const DOCS = "https://docs.g1t.sh";
28
29/** A small label above a heading, in the mono face. */
30function Eyebrow({ children }: { children: ReactNode }) {
31 return (
32 <p className="font-mono text-xs tracking-[0.2em] text-accent uppercase">
33 {children}
34 </p>
35 );
36}
37
38/** Marks something planned and not built yet, wherever it is mentioned. */
39function Soon({ className = "" }: { className?: string }) {
40 return (
41 <span
42 className={`inline-flex shrink-0 items-center rounded-full bg-raised px-2 py-0.5 align-middle font-mono text-[0.625rem] font-medium tracking-wide whitespace-nowrap text-muted uppercase ring-1 ring-line-strong ${className}`}
43 >
44 Coming soon
45 </span>
46 );
47}
48
49function Tags({ items }: { items: string[] }) {
50 return (
51 <ul className="mt-6 flex flex-wrap gap-1.5">
52 {items.map((item) => (
53 <li
54 key={item}
55 className="rounded-full bg-bg/80 px-2.5 py-1 font-mono text-[0.6875rem] tracking-wide text-muted uppercase ring-1 ring-line"
56 >
57 {item}
58 </li>
59 ))}
60 </ul>
61 );
62}
63
64/** A link in running copy that leads to the docs or another page. */
65function More({ to, children }: { to: string; children: ReactNode }) {
66 return (
67 <Link
68 to={to}
69 className="group mt-7 inline-flex items-center gap-1.5 text-sm font-medium text-fg hover:text-accent"
70 >
71 {children}
72 <ArrowRight
73 size={14}
74 className="transition-transform group-hover:translate-x-0.5"
75 />
76 </Link>
77 );
78}
79
80/**
81 * A point in a list: a check, a check whose words link somewhere, or a
82 * "Coming soon" tag for what is not built yet.
83 */
84type Point =
85 | string
86 | { text: string; link: { to: string; label: string } }
87 | { text: string; soon: true };
88
89function Points({
90 points,
91 columns = true,
92}: {
93 points: Point[];
94 columns?: boolean;
95}) {
96 const now = points.filter((point) => typeof point === "string" || !("soon" in point));
97 const later = points
98 .filter((point) => typeof point !== "string" && "soon" in point)
99 .map((point) => (point as { text: string }).text);
100 return (
101 <>
102 <ul
103 className={`mt-6 grid gap-2.5 text-sm ${columns ? "sm:grid-cols-2" : ""}`}
104 >
105 {now.map((point) =>
106 typeof point === "string" ? (
107 <li key={point} className="flex gap-2.5 text-fg-soft">
108 <Check size={15} className="mt-0.5 shrink-0 text-accent" />
109 <span>{point}</span>
110 </li>
111 ) : (
112 "link" in point && (
113 <li key={point.text} className="flex gap-2.5 text-fg-soft">
114 <Check size={15} className="mt-0.5 shrink-0 text-accent" />
115 <span>
116 {point.text}{" "}
117 <Link
118 to={point.link.to}
119 className="text-fg underline underline-offset-4 hover:text-accent"
120 >
121 {point.link.label}
122 </Link>
123 </span>
124 </li>
125 )
126 ),
127 )}
128 </ul>
129 {later.length > 0 && (
130 <div className="mt-5 rounded-xl border border-dashed border-line-strong px-4 py-3.5">
131 <Soon />
132 <ul
133 className={`mt-3 grid gap-2 text-sm ${columns ? "sm:grid-cols-2" : ""}`}
134 >
135 {later.map((text) => (
136 <li key={text} className="flex gap-2.5 text-muted">
137 <CircleDashed
138 size={14}
139 className="mt-0.5 shrink-0 text-faint"
140 />
141 <span>{text}</span>
142 </li>
143 ))}
144 </ul>
145 </div>
146 )}
147 </>
148 );
149}
150
151/** A drawing in its own card, on the page's dark gray. */
152function ArtFrame({ children }: { children: ReactNode }) {
153 return (
154 <Live className="relative overflow-hidden rounded-3xl bg-surface/60 px-4 py-6 ring-1 ring-line sm:px-8">
155 <div
156 aria-hidden="true"
157 className="pointer-events-none absolute inset-x-0 -bottom-24 h-48 bg-[radial-gradient(50%_60%_at_50%_100%,rgb(182_168_255/0.08),transparent)]"
158 />
159 <div className="relative mx-auto max-w-lg">{children}</div>
160 </Live>
161 );
162}
163
164/**
165 * One part of Code: what it does, the features that prove it, and a
166 * drawing of the idea, on alternating sides.
167 */
168function Pillar({
169 eyebrow,
170 title,
171 art,
172 points,
173 more,
174 flip,
175 children,
176}: {
177 eyebrow: string;
178 title: string;
179 art: ReactNode;
180 points: string[];
181 more: [string, string];
182 flip?: boolean;
183 children: ReactNode;
184}) {
185 return (
186 <article className="grid items-center gap-10 py-14 lg:grid-cols-2 lg:gap-16">
187 <div className={flip ? "lg:order-2" : undefined}>
188 <Eyebrow>{eyebrow}</Eyebrow>
189 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance sm:text-3xl">
190 {title}
191 </h3>
192 <p className="mt-4 max-w-xl leading-7 text-muted">{children}</p>
193 <Points points={points} />
194 <More to={more[1]}>{more[0]}</More>
195 </div>
196 <div className={flip ? "lg:order-1" : undefined}>
197 <ArtFrame>{art}</ArtFrame>
198 </div>
199 </article>
200 );
201}
202
203/** Facts under the opening, each one true today. */
204const FACTS: [string, string][] = [
205 [
206 "$0",
207 "for people to chat. Every plan, the free one too, with no history cutoff.",
208 ],
209 [
210 "0 seats",
211 "Everyone in the company joins at one workspace price, never per person.",
212 ],
213 [
214 "+20%",
215 "on what compute costs g1t: checks, workflows and deployments. Your own runners are free.",
216 ],
217 [
218 "MIT",
219 "licensed. g1t's own source lives on g1t and lands through its own queue.",
220 ],
221];
222
223/** What a workspace holds, and the coding agents it works with. */
224const MODES: {
225 icon: ReactNode;
226 name: string;
227 about: string;
228 soon?: boolean;
229 to: string;
230}[] = [
231 {
232 icon: <Code2 size={18} />,
233 name: "Code",
234 about:
235 "Repositories, issues, pull requests, checks, a merge queue and deployments. For the people who build.",
236 to: `${DOCS}/concepts/overview/`,
237 },
238 {
239 icon: <MessagesSquare size={18} />,
240 name: "Chat",
241 about:
242 "Channels, direct messages and threads, live, for everyone in the company.",
243 to: `${DOCS}/guides/chat/`,
244 },
245 {
246 icon: <BookOpen size={18} />,
247 name: "Artifacts",
248 about:
249 "Docs now, and slides, designs and dashboards next, made together live.",
250 to: `${DOCS}/guides/artifacts/`,
251 },
252 {
253 icon: <Bot size={18} />,
254 name: "Your coding agents",
255 about:
256 "Claude Code, Codex, Cursor or any MCP client, working as you through MCP, the g1t CLI or the API, with only the access you give them.",
257 to: `${DOCS}/guides/bring-your-own-agent/`,
258 },
259];
260
261const RAILS: { icon: ReactNode; title: string; about: string; to: string }[] = [
262 {
263 icon: <KeyRound size={18} />,
264 title: "Scopes",
265 about:
266 "A token or an OAuth app gets only the scopes you grant it, and never does more than you could do yourself.",
267 to: `${DOCS}/guides/authentication/#access-tokens`,
268 },
269 {
270 icon: <Handshake size={18} />,
271 title: "Rules",
272 about:
273 "Protected branches, required checks and required approvals apply to every push and every merge, whoever made it.",
274 to: `${DOCS}/guides/rules/`,
275 },
276 {
277 icon: <Eye size={18} />,
278 title: "Guardrails",
279 about:
280 "Which hosts a project's jobs, checks and deploy builds may reach, and how long they may run, enforced in g1t's sandboxes.",
281 to: `${DOCS}/guides/guardrails/`,
282 },
283 {
284 icon: <ScrollText size={18} />,
285 title: "Audit",
286 about:
287 "Every action by people and tokens: who did it, through what, whether it was allowed and the rule that decided.",
288 to: `${DOCS}/guides/audit-log/`,
289 },
290];
291
292const FLOW: [string, string][] = [
293 [
294 "Ask",
295 "Open an issue, or raise it in a channel: what should change, and what done looks like.",
296 ],
297 [
298 "Change",
299 "You or your coding agent push a branch and open a pull request. The agent's session is recorded onto it.",
300 ],
301 [
302 "Check",
303 "Required checks run on g1t's runners or your own, and the pull request gets a live preview.",
304 ],
305 [
306 "Review",
307 "A person reviews and approves. Rules and protected branches apply to everyone.",
308 ],
309 [
310 "Main",
311 "The queue tests each change with what lands before it. Production follows main.",
312 ],
313];
314
315/** The forge itself, for the people who build. */
316const FORGE = [
317 "Git over HTTPS",
318 "Public and private repositories",
319 "Issues and labels",
320 "Pull requests and forks",
321 "Line comments and reviews",
322 "Protected branches",
323 "Required approvals",
324 "Workspaces and roles",
325 "Teams",
326 "Search and Explore",
327 "Webhooks",
328 "Import from any git host",
329 "REST API and OpenAPI",
330 "MCP server",
331 "The g1t CLI",
332];
333
334const SECURE: { icon: ReactNode; title: string; about: string; to: string }[] =
335 [
336 {
337 icon: <ShieldCheck size={18} />,
338 title: "Push protection",
339 about:
340 "A push that adds a key or a token is refused before it lands, and the history is scanned for ones already there.",
341 to: `${DOCS}/guides/security/secret-protection/`,
342 },
343 {
344 icon: <PackageCheck size={18} />,
345 title: "Dependency upkeep",
346 about:
347 "Each vulnerable dependency that has a fixed version becomes an upgrade, landed through the same checks as any change.",
348 to: `${DOCS}/guides/security/#security-updates`,
349 },
350 {
351 icon: <ScanSearch size={18} />,
352 title: "Code scanning",
353 about:
354 "Static analysis results become alerts, comments on the pull request that caused them, and a check that can block the merge.",
355 to: `${DOCS}/guides/security/code-scanning/`,
356 },
357 {
358 icon: <Lock size={18} />,
359 title: "Supply chain",
360 about:
361 "The dependency graph, an SBOM of it, and dependency review on every pull request that changes what you depend on.",
362 to: `${DOCS}/guides/security/supply-chain/`,
363 },
364 ];
365
366const PRICES: { name: string; price: string; unit?: string; about: string }[] =
367 [
368 {
369 name: "People",
370 price: "$0",
371 unit: "to chat",
372 about:
373 "Channels, DMs, threads and the forge are included on every plan, free too. No seats and no history cutoff.",
374 },
375 {
376 name: "The g1t plan",
377 price: "$20",
378 unit: "a month per workspace",
379 about:
380 "$10 of usage included. Unlimited members. Checks, workflows, the merge queue and deployments.",
381 },
382 {
383 name: "Usage",
384 price: "Cost + 20%",
385 about:
386 "Checks, workflows, deployments and storage at what they cost g1t, plus 20%. Time on your own runners costs nothing.",
387 },
388 ];
389
390/**
391 * The signed-out home page: what g1t is, what it does, and how to start.
392 * It lists no one's repositories; those are a click away under Explore.
393 */
394export function Landing() {
395 return (
396 <main className="overflow-x-clip">
397 {/* The opening. */}
398 <section className="dusk relative">
399 <div
400 aria-hidden="true"
401 className="dusk-planet pointer-events-none absolute -top-120 left-1/2 size-240 translate-x-[-10%] rounded-full"
402 />
403 <div className="relative mx-auto max-w-6xl px-4 pt-20 text-center sm:pt-24">
404 <Link
405 to={`${DOCS}/guides/bring-your-own-agent/`}
406 className="inline-flex animate-fade-up items-center gap-2 rounded-full bg-bg/50 px-3 py-1 text-xs text-fg-soft ring-1 ring-line backdrop-blur transition-colors hover:bg-bg/70"
407 >
408 <span className="size-1.5 shrink-0 rounded-full bg-accent" />
409 Works with Claude Code, Codex, Cursor and any MCP client
410 <ArrowRight size={12} className="shrink-0" />
411 </Link>
412 <h1 className="mx-auto mt-7 max-w-4xl animate-fade-up text-[2.75rem] leading-[1.04] font-semibold tracking-tight text-balance sm:text-7xl">
413 Where your team&apos;s code{" "}
414 <span className="bg-linear-to-r from-fg via-accent-high to-accent bg-clip-text text-transparent">
415 lands, whoever wrote it.
416 </span>
417 </h1>
418 <p className="mx-auto mt-7 max-w-2xl animate-fade-up text-lg leading-8 text-fg-soft/80 text-balance">
419 Repositories, pull requests, required checks, a merge queue and
420 deployments, with chat and docs for your team. Connect the coding
421 agents you already use, and their work lands through the same
422 checks as everyone&apos;s.
423 </p>
424 <div className="mt-9 flex animate-fade-up flex-wrap items-center justify-center gap-3">
425 <ButtonLink to="/register" size="lg" className="rounded-full">
426 Get started
427 <ArrowRight size={15} />
428 </ButtonLink>
429 <ButtonLink
430 to="#how"
431 variant="outline"
432 size="lg"
433 className="rounded-full"
434 >
435 See how it works
436 </ButtonLink>
437 </div>
438 <p className="mx-auto mt-5 max-w-xl animate-fade-up text-sm text-fg-soft/60 text-balance">
439 Chat and the forge are free, with no card. No seats, ever.
440 </p>
441 </div>
442 <div className="relative mx-auto max-w-5xl px-4 pt-14 pb-2">
443 <div
444 aria-hidden="true"
445 className="pointer-events-none absolute inset-x-10 top-10 bottom-0 rounded-[3rem] bg-[radial-gradient(60%_60%_at_50%_40%,rgb(182_168_255/0.14),transparent)] blur-2xl"
446 />
447 <ProductTour className="relative" />
448 </div>
449 <div
450 aria-hidden="true"
451 className="h-16 bg-linear-to-b from-transparent to-bg"
452 />
453 </section>
454
455 {/* Facts, each one true today. */}
456 <section className="relative z-10 mx-auto max-w-6xl px-4">
457 <dl className="grid gap-px overflow-hidden rounded-2xl border border-line bg-line sm:grid-cols-2 lg:grid-cols-4">
458 {FACTS.map(([figure, about]) => (
459 <div key={figure} className="bg-bg px-6 py-6">
460 <dt className="font-mono text-2xl font-medium tracking-tight text-fg">
461 {figure}
462 </dt>
463 <dd className="mt-2 text-sm leading-6 text-muted">{about}</dd>
464 </div>
465 ))}
466 </dl>
467 </section>
468
469 {/* What a workspace holds. */}
470 <section className="mx-auto max-w-6xl px-4 pt-24">
471 <div className="max-w-3xl">
472 <Eyebrow>One workspace</Eyebrow>
473 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
474 Talk, write it down, ship.
475 </h2>
476 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
477 Code, Chat and Artifacts share one set of members, one sign-in and
478 one bill. The coding agents you connect work as you, through MCP,
479 the g1t CLI and the API.
480 </p>
481 </div>
482 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
483 {MODES.map((mode) => (
484 <Link
485 key={mode.name}
486 to={mode.to}
487 className="group flex flex-col rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
488 >
489 <span className="flex items-center justify-between gap-2">
490 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
491 {mode.icon}
492 </span>
493 {mode.soon && <Soon />}
494 </span>
495 <h3 className="mt-5 text-lg font-semibold">{mode.name}</h3>
496 <p className="mt-2 text-sm leading-6 text-muted">{mode.about}</p>
497 </Link>
498 ))}
499 </div>
500 </section>
501
502 {/* Code. */}
503 <section className="mx-auto max-w-6xl px-4 pt-24">
504 <div className="max-w-3xl">
505 <Eyebrow>Code</Eyebrow>
506 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
507 A forge built for many changes at once.
508 </h2>
509 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
510 Underneath is plain git. Every change, whether you wrote it or
511 your coding agent did, is a pull request: checked, reviewed, and
512 landed through a queue that keeps main passing.
513 </p>
514 </div>
515
516 <div className="mt-6 divide-y divide-line">
517 <Pillar
518 eyebrow="Ship safely"
519 title="Main only moves to what passed"
520 art={<QueueArt className="w-full" />}
521 points={[
522 "Checks in a clean sandbox, or on your own runners",
523 "Workflows from .g1t/workflows",
524 "A merge queue that tests changes together",
525 "Conflicts found on every push, before a merge",
526 "Catch up with main in seconds",
527 "Required reviews, with code owners",
528 ]}
529 more={["The merge queue", `${DOCS}/guides/merge-queue/`]}
530 >
531 Required checks run on g1t&apos;s runners or your own. The queue
532 tests each change together with what lands ahead of it; one that
533 breaks goes back to its author with what failed, and main never sees
534 it.
535 </Pillar>
536
537 <Pillar
538 flip
539 eyebrow="Context"
540 title="Every line knows why it is there"
541 art={<WhyArt className="w-full" />}
542 points={[
543 "Sessions recorded onto pull requests",
544 "Why-blame on any line",
545 "Project memory your coding agents read and add to",
546 "Search across code, issues and people",
547 ]}
548 more={["Sessions and why-blame", `${DOCS}/guides/why-blame/`]}
549 >
550 Pick any line. g1t shows the commit that changed it, the pull
551 request and issue it came from, and the session your coding agent
552 recorded as it worked: what it read, ran and decided. The reasoning
553 stays with the code, for people and for the next agent.
554 </Pillar>
555
556 <Pillar
557 eyebrow="Run it"
558 title="Every change, live on the edge"
559 art={<DeployArt className="w-full" />}
560 points={[
561 "A live preview for every pull request",
562 "Production on every merge to main",
563 "Custom domains, with certificates",
564 "Projects that depend on each other",
565 ]}
566 more={["Deployments", `${DOCS}/guides/deployments/`]}
567 >
568 Turn on deployments and every pull request gets its own address on
569 g1t.page; merging ships production. Reviewers click through a
570 change instead of reading a diff. An app nobody visits runs nothing
571 and costs nothing.
572 </Pillar>
573 </div>
574 </section>
575
576 {/* The forge, for people. */}
577 <section className="mx-auto max-w-6xl px-4 py-24">
578 <div className="grid gap-10 lg:grid-cols-[1fr_1.2fr] lg:gap-16">
579 <div>
580 <Eyebrow>Collaborate</Eyebrow>
581 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
582 A complete forge for the people who build
583 </h2>
584 <p className="mt-4 max-w-md leading-7 text-muted">
585 Issues, branches, pull requests and reviews, the way your team
586 already works. Write a change by hand, have your coding agent
587 write it, or both on the same branch.
588 </p>
589 <More to={`${DOCS}/concepts/overview/`}>How g1t works</More>
590 </div>
591 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line">
592 <p className="text-sm font-medium">Included in every workspace</p>
593 <Tags items={FORGE} />
594 </div>
595 </div>
596 </section>
597
598 {/* Chat, where people talk about the work. */}
599 <section className="mx-auto grid max-w-6xl items-start gap-12 px-4 lg:grid-cols-[1.1fr_1fr] lg:gap-16">
600 <div>
601 <Eyebrow>Chat</Eyebrow>
602 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
603 Just talk to your team.
604 </h2>
605 <p className="mt-4 max-w-xl leading-7 text-muted">
606 Chat is where your team talks about the work, next to the code it
607 is about. Ask a question in a channel, DM a colleague, or reply in
608 a thread. Messages arrive the moment they are sent, and everyone in
609 the company can join for free.
610 </p>
611 <Points
612 points={[
613 "Public and private channels",
614 "Direct messages",
615 "Threads on any message",
616 "@mentions",
617 "Live delivery, typing and read state",
618 "A desktop app for Windows, macOS and Linux",
619 {
620 text: "Pull requests, checks and deploys as cards in the channel",
621 soon: true,
622 },
623 { text: "Chat mentions in Notifications", soon: true },
624 {
625 text: "An Android app with notifications: scan the QR code on",
626 link: { to: "/download", label: "Download" },
627 },
628 { text: "The phone app on iPhone", soon: true },
629 ]}
630 />
631 <More to={`${DOCS}/guides/chat/`}>How Chat works</More>
632 </div>
633 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line">
634 <Eyebrow>Issues</Eyebrow>
635 <h3 className="mt-3 text-xl font-semibold tracking-tight">
636 Point your coding agent at an issue
637 </h3>
638 <p className="mt-3 text-sm leading-6 text-muted">
639 Your coding agent connects to g1t through MCP and works as you. It
640 reads the issue, pushes a branch, opens the pull request and
641 records its session onto it, and the pull request goes through the
642 same checks and reviews as anyone&apos;s.
643 </p>
644 <ol className="mt-6 space-y-3 text-sm">
645 {[
646 "Open an issue: what should change, and what done looks like",
647 "Work it yourself, or hand it to your coding agent",
648 "The pull request runs your checks and lands through the queue",
649 ].map((step, index) => (
650 <li key={step} className="flex items-start gap-3 text-fg-soft">
651 <span className="flex size-6 shrink-0 items-center justify-center rounded-full bg-bg font-mono text-xs text-faint ring-1 ring-line">
652 {index + 1}
653 </span>
654 {step}
655 </li>
656 ))}
657 </ol>
658 <More to={`${DOCS}/guides/bring-your-own-agent/`}>
659 Connect a coding agent
660 </More>
661 </div>
662 </section>
663
664 {/* The rails. */}
665 <section className="mx-auto max-w-6xl px-4 py-24">
666 <Eyebrow>The rails</Eyebrow>
667 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
668 Rules decide what lands, not whoever wrote it
669 </h2>
670 <p className="mt-4 max-w-2xl leading-7 text-muted">
671 Scopes, rules, guardrails and audit are set by the workspace and
672 enforced by g1t. They hold the same for a person at a keyboard and
673 for the coding agent working as them.
674 </p>
675 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
676 {RAILS.map((item) => (
677 <Link
678 key={item.title}
679 to={item.to}
680 className="group rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
681 >
682 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
683 {item.icon}
684 </span>
685 <h3 className="mt-5 font-semibold">{item.title}</h3>
686 <p className="mt-2 text-sm leading-6 text-muted">{item.about}</p>
687 </Link>
688 ))}
689 </div>
690 </section>
691
692 {/* Switching: what moving in costs, and what holds if g1t goes away. */}
693 <section
694 id="switching"
695 className="mx-auto max-w-6xl scroll-mt-20 px-4 pb-24"
696 >
697 <div className="grid gap-10 rounded-3xl bg-surface p-8 ring-1 ring-line sm:p-10 lg:grid-cols-[1fr_1.1fr] lg:gap-16">
698 <div>
699 <Eyebrow>Switching</Eyebrow>
700 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
701 Moving in is an import. Leaving is a git clone.
702 </h2>
703 <p className="mt-4 max-w-xl leading-7 text-muted">
704 Bring repositories across from GitHub in a few clicks: every
705 branch and tag with full history, and their issues if you want
706 them. The copy on g1t is then your own.
707 </p>
708 <p className="mt-4 max-w-xl leading-7 text-muted">
709 If g1t went away tomorrow, your code is plain git, the source is
710 MIT licensed, and the core forge runs on your own machine with
711 Docker Compose.
712 </p>
713 <More
714 to={`${DOCS}/guides/github/#import-a-repository`}
715 >
716 Import from GitHub
717 </More>
718 </div>
719 <div className="space-y-6">
720 <div>
721 <p className="text-sm font-medium">What keeps working</p>
722 <Points
723 columns={false}
724 points={[
725 "git over HTTPS, with your history as it is",
726 "GitHub Actions workflows: rename .github to .g1t and push",
727 "The coding agents you use today, through MCP",
728 "Leaving: git clone, and the REST API for the rest",
729 ]}
730 />
731 </div>
732 <div className="rounded-xl border border-dashed border-line-strong px-4 py-3.5 text-sm leading-6 text-muted">
733 <p className="font-medium text-fg-soft">
734 Not a fit yet if you need
735 </p>
736 <p className="mt-1.5">
737 Single sign-on, git over SSH, or chat and deployments on your
738 own machines: those run only on g1t.sh today. Open pull
739 requests, issue comments, releases and wikis stay behind on
740 import.{" "}
741 <Link
742 to={`${DOCS}/about/limitations/`}
743 className="text-fg-soft underline-offset-4 hover:text-accent hover:underline"
744 >
745 What g1t can&apos;t do yet
746 </Link>
747 </p>
748 </div>
749 </div>
750 </div>
751 </section>
752
753 {/* Coordination, as it works today; and Docs, coming next. */}
754 <section className="mx-auto grid max-w-6xl gap-4 px-4 pb-24 lg:grid-cols-2">
755 <div className="rounded-3xl bg-surface p-8 ring-1 ring-line">
756 <Eyebrow>Coordination</Eyebrow>
757 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance">
758 Many agents, no collisions
759 </h3>
760 <p className="mt-3 text-sm leading-6 text-muted">
761 Run as many coding agents as you like. Each change is a pull
762 request, pull requests that touch the same files are flagged to
763 each other, conflicts are found on every push, and the merge queue
764 tests changes together with what lands ahead of them. Five agents
765 can open pull requests the same afternoon and main still only
766 moves to what passed.
767 </p>
768 <More to={`${DOCS}/guides/merge-queue/`}>The merge queue</More>
769 </div>
770 <div className="rounded-3xl bg-surface p-8 ring-1 ring-line">
771 <Eyebrow>Artifacts</Eyebrow>
772 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance">
773 A knowledge base that keeps itself true
774 </h3>
775 <p className="mt-3 text-sm leading-6 text-muted">
776 Docs, private until you share them or kept in spaces, edited
777 together live, with history, comments and backlinks. When a merged
778 change touches something a doc cites, the doc is flagged for its
779 owner to update.
780 </p>
781 <More to={`${DOCS}/guides/artifacts/`}>How Artifacts work</More>
782 </div>
783 </section>
784
785 {/* How it flows */}
786 <section
787 id="how"
788 className="scroll-mt-20 border-y border-line bg-surface/40"
789 >
790 <div className="mx-auto max-w-6xl px-4 py-24">
791 <Eyebrow>How it flows</Eyebrow>
792 <h2 className="mt-3 text-3xl font-semibold tracking-tight">
793 From an issue to main
794 </h2>
795 <Live>
796 <ol className="relative mt-12 grid gap-6 md:grid-cols-5">
797 {/* From the first step's dot to the last one's, and no further: five
798 columns with 1.5rem gaps put the last dot 1rem into the last
799 column, so the line stops one column, less that, from the end. */}
800 <span
801 aria-hidden="true"
802 className="absolute top-4 right-[calc((100%-6rem)/5-1rem)] left-4 hidden h-px bg-linear-to-r from-accent/50 via-warn/50 to-success/70 md:block"
803 >
804 <span className="flow-runner absolute inset-0">
805 <span className="absolute -top-0.75 left-[-3.5px] size-1.75 rounded-full bg-accent shadow-[0_0_12px_2px_rgb(182_168_255/0.6)]" />
806 </span>
807 </span>
808 {FLOW.map(([step, about], index) => (
809 <li key={step} className="relative">
810 <span
811 className={`flow-step relative flex size-8 items-center justify-center rounded-full font-mono text-xs ring-1 ${
812 index === FLOW.length - 1
813 ? "bg-success text-bg ring-success"
814 : "bg-bg text-fg-soft ring-line-strong"
815 }`}
816 style={{ "--delay": `${index * 2}s` } as CSSProperties}
817 >
818 {index + 1}
819 </span>
820 <h3 className="mt-4 font-semibold">{step}</h3>
821 <p className="mt-1.5 text-sm leading-6 text-muted">{about}</p>
822 </li>
823 ))}
824 </ol>
825 </Live>
826 </div>
827 </section>
828
829 {/* Secure by default */}
830 <section className="mx-auto max-w-6xl px-4 py-24">
831 <Eyebrow>Secure by default</Eyebrow>
832 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
833 Safe to hand the work to, and healthy without anyone watching
834 </h2>
835 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
836 {SECURE.map((item) => (
837 <Link
838 key={item.title}
839 to={item.to}
840 className="group rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
841 >
842 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-accent ring-1 ring-line">
843 {item.icon}
844 </span>
845 <h3 className="mt-5 font-semibold">{item.title}</h3>
846 <p className="mt-2 text-sm leading-6 text-muted">{item.about}</p>
847 </Link>
848 ))}
849 </div>
850 </section>
851
852 {/* Connect */}
853 <section className="border-y border-line bg-surface/40">
854 <div className="mx-auto grid max-w-6xl items-center gap-12 px-4 py-24 lg:grid-cols-2">
855 <div>
856 <Eyebrow>Bring your own agent</Eyebrow>
857 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
858 Any agent that speaks MCP works on g1t
859 </h2>
860 <p className="mt-4 max-w-md leading-7 text-muted">
861 Connect Claude Code, Codex, Cursor or any other MCP client and
862 sign in once. It works as you: it reads issues, pushes branches,
863 opens pull requests, records its session onto them, and reads
864 and adds to the project&apos;s memory.
865 </p>
866 <p className="mt-4 max-w-md leading-7 text-muted">
867 Every action is a REST route and an MCP tool, with an OpenAPI
868 document, OAuth apps, access tokens and signed webhooks for every
869 event. The g1t CLI does the same from a terminal or a script:
870 open a pull request, wait on its checks, read a failed run&apos;s
871 logs.
872 </p>
873 <div className="mt-6 flex flex-wrap gap-3">
874 <ButtonLink
875 to={`${DOCS}/guides/bring-your-own-agent/`}
876 variant="outline"
877 >
878 Connect an agent
879 <ArrowRight size={14} />
880 </ButtonLink>
881 <ButtonLink to={`${DOCS}/guides/cli/`} variant="outline">
882 The g1t CLI
883 </ButtonLink>
884 <ButtonLink to={`${DOCS}/reference/api/`} variant="outline">
885 API reference
886 </ButtonLink>
887 </div>
888 </div>
889 <div className="min-w-0 space-y-3">
890 <p className="text-sm text-muted">
891 Add g1t as a remote MCP server, then sign in through your browser:
892 </p>
893 <CopyLine text="https://mcp.g1t.sh" />
894 <p className="pt-3 text-sm text-muted">
895 Install the CLI, then sign in with{" "}
896 <code className="font-mono text-fg-soft">g1t auth login</code>:
897 </p>
898 <CopyLine prompt text="curl -fsSL https://g1t.sh/install | sh" />
899 <p className="pt-3 text-sm text-muted">
900 Underneath, it is plain git and HTTP:
901 </p>
902 <CopyLine
903 prompt
904 breakAtSlashes
905 text="git clone https://g1t.sh/flagon-io/g1t.git"
906 />
907 <CopyLine
908 prompt
909 breakAtSlashes
910 text="curl https://api.g1t.sh/repos/flagon-io/g1t/queue"
911 />
912 </div>
913 </div>
914 </section>
915
916 {/* Pricing, in one band. */}
917 <section className="mx-auto max-w-6xl px-4 py-24">
918 <div className="flex flex-wrap items-end justify-between gap-6">
919 <div>
920 <Eyebrow>Pricing</Eyebrow>
921 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
922 People chat free. Pay for what runs. Never per seat.
923 </h2>
924 </div>
925 <More to="/pricing">See every price</More>
926 </div>
927 <div className="mt-10 grid gap-px overflow-hidden rounded-3xl bg-line ring-1 ring-line md:grid-cols-3">
928 {PRICES.map((item) => (
929 <div key={item.name} className="bg-surface p-7">
930 <p className="text-sm text-muted">{item.name}</p>
931 <p className="mt-3 flex flex-wrap items-baseline gap-x-2">
932 <span className="text-3xl font-semibold tracking-tight">
933 {item.price}
934 </span>
935 {item.unit && (
936 <span className="text-sm text-muted">{item.unit}</span>
937 )}
938 </p>
939 <p className="mt-3 text-sm leading-6 text-muted">{item.about}</p>
940 </div>
941 ))}
942 </div>
943 </section>
944
945 {/* Open source */}
946 <section className="mx-auto max-w-6xl px-4 pb-24">
947 <div className="grid gap-10 rounded-3xl bg-surface p-8 ring-1 ring-line sm:p-10 lg:grid-cols-[1.3fr_1fr]">
948 <div>
949 <Eyebrow>Open source</Eyebrow>
950 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
951 Open, and built on itself
952 </h2>
953 <p className="mt-4 max-w-xl leading-7 text-muted">
954 g1t is MIT licensed. Its own source lives on g1t, and its changes
955 land through its own merge queue. Your code is plain git: leaving
956 is a <code className="font-mono text-fg-soft">git clone</code>.
957 </p>
958 <p className="mt-4 max-w-xl leading-7 text-muted">
959 You can run the core forge yourself with Docker Compose today:
960 accounts, repositories, issues, pull requests and search. It is an
961 early version, and chat and deployments still run only on g1t.sh.
962 </p>
963 <div className="mt-7 flex flex-wrap gap-3">
964 <ButtonLink to="/flagon-io/g1t" variant="outline">
965 Browse the source
966 </ButtonLink>
967 <ButtonLink to={`${DOCS}/guides/self-hosting/`} variant="outline">
968 Run g1t yourself
969 </ButtonLink>
970 </div>
971 </div>
972 <div className="flex flex-col justify-between gap-6">
973 <ul className="space-y-3 text-sm">
974 {[
975 {
976 icon: <Bell size={15} />,
977 text: "One place for mentions, reviews and approvals",
978 },
979 {
980 icon: <ScrollText size={15} />,
981 text: "One audit log for people and tokens",
982 },
983 {
984 icon: <Wallet size={15} />,
985 text: "One bill, at cost plus 20%",
986 },
987 ].map((item) => (
988 <li
989 key={item.text}
990 className="flex items-center gap-3 text-fg-soft"
991 >
992 <span className="flex size-7 items-center justify-center rounded-md bg-bg text-accent ring-1 ring-line">
993 {item.icon}
994 </span>
995 {item.text}
996 </li>
997 ))}
998 </ul>
999 <p className="text-sm leading-6 text-muted">
1000 g1t is made by Flagon, Inc., a small, independent software company
1001 founded by Chase Pierce.
1002 </p>
1003 </div>
1004 </div>
1005 </section>
1006
1007 {/* The close. */}
1008 <section className="mx-auto max-w-6xl px-4 pb-8">
1009 <div className="dusk relative overflow-hidden rounded-3xl px-6 py-16 text-center ring-1 ring-line">
1010 <h2 className="mx-auto max-w-2xl text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
1011 Bring your team. Bring your agents.
1012 </h2>
1013 <p className="mx-auto mt-4 max-w-xl text-fg-soft/80 text-balance">
1014 Make a workspace, push a repository and connect the coding agent
1015 you already use. Chat and the forge are free.
1016 </p>
1017 <div className="mt-8 flex flex-wrap justify-center gap-3">
1018 <ButtonLink to="/register" size="lg" className="rounded-full">
1019 Get started
1020 <ArrowRight size={15} />
1021 </ButtonLink>
1022 <ButtonLink
1023 to={`${DOCS}/quickstart/`}
1024 variant="outline"
1025 size="lg"
1026 className="rounded-full"
1027 >
1028 Read the quickstart
1029 </ButtonLink>
1030 </div>
1031 </div>
1032 </section>
1033 </main>
1034 );
1035}