g1t/apps/web/app/components/landing.tsx

648 lines28,198 bytesCodeBlame
1import { ArrowRight, Check, KeyRound, PackageCheck, ScrollText, ShieldCheck } from "lucide-react";
2import type { CSSProperties, ReactNode } from "react";
3import { Link } from "react-router";
4
5import { type Provider, PROVIDERS } from "@g1t/contracts";
6
7import { AgentSetup } from "./agent-setup";
8import { DeployArt, HeroArt, Live, PlanArt, QueueArt, TeamArt, WhyArt } from "./art";
9import { ProviderMark } from "./model-providers";
10import { ButtonLink, CopyLine } from "./ui";
11import { HAVE_AN_INVITE } from "../lib/invites";
12import { useInviteOnly } from "../lib/registration";
13
14const DOCS = "https://docs.g1t.sh";
15
16/** A small label above a heading, in the mono face. */
17function Eyebrow({ children }: { children: ReactNode }) {
18 return <p className="font-mono text-xs tracking-[0.2em] text-merged uppercase">{children}</p>;
19}
20
21function Tags({ items }: { items: string[] }) {
22 return (
23 <ul className="mt-6 flex flex-wrap gap-1.5">
24 {items.map((item) => (
25 <li
26 key={item}
27 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"
28 >
29 {item}
30 </li>
31 ))}
32 </ul>
33 );
34}
35
36/** A link in running copy that leads to the docs or another page. */
37function More({ to, children }: { to: string; children: ReactNode }) {
38 return (
39 <Link to={to} className="group mt-7 inline-flex items-center gap-1.5 text-sm font-medium text-fg hover:text-merged">
40 {children}
41 <ArrowRight size={14} className="transition-transform group-hover:translate-x-0.5" />
42 </Link>
43 );
44}
45
46/** A drawing in its own card, on the page's dark gray. */
47function ArtFrame({ children }: { children: ReactNode }) {
48 return (
49 <Live className="relative overflow-hidden rounded-3xl bg-surface/60 px-4 py-6 ring-1 ring-line sm:px-8">
50 <div
51 aria-hidden="true"
52 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)]"
53 />
54 <div className="relative mx-auto max-w-lg">{children}</div>
55 </Live>
56 );
57}
58
59/**
60 * One of the product's pillars: what it does, the features that prove it,
61 * and a drawing of the idea, on alternating sides.
62 */
63function Pillar({
64 eyebrow,
65 title,
66 art,
67 points,
68 more,
69 flip,
70 children,
71}: {
72 eyebrow: string;
73 title: string;
74 art: ReactNode;
75 points: string[];
76 more: [string, string];
77 flip?: boolean;
78 children: ReactNode;
79}) {
80 return (
81 <article className="grid items-center gap-10 py-14 lg:grid-cols-2 lg:gap-16">
82 <div className={flip ? "lg:order-2" : undefined}>
83 <Eyebrow>{eyebrow}</Eyebrow>
84 <h3 className="mt-3 text-2xl font-semibold tracking-tight text-balance sm:text-3xl">{title}</h3>
85 <p className="mt-4 max-w-xl leading-7 text-muted">{children}</p>
86 <ul className="mt-6 grid gap-2.5 text-sm sm:grid-cols-2">
87 {points.map((point) => (
88 <li key={point} className="flex gap-2.5 text-fg-soft">
89 <Check size={15} className="mt-0.5 shrink-0 text-merged" />
90 <span>{point}</span>
91 </li>
92 ))}
93 </ul>
94 <More to={more[1]}>{more[0]}</More>
95 </div>
96 <div className={flip ? "lg:order-1" : undefined}>
97 <ArtFrame>{art}</ArtFrame>
98 </div>
99 </article>
100 );
101}
102
103/** Facts under the opening, each one true today. */
104const FACTS: [string, string][] = [
105 ["$0", "for the forge: repositories, issues, pull requests and review. No card."],
106 ["+20%", "on what compute costs g1t. That is the whole markup, and there is no seat price."],
107 ["1 command", "connects Claude Code, Codex, OpenCode or Cursor to your workspace."],
108 ["MIT", "licensed. g1t's own source lives on g1t and lands through its own queue."],
109];
110
111const FLOW: [string, string][] = [
112 ["Brief", "Write the outcome you want, in plain words, or open an issue as you always would."],
113 ["Plan", "A planner agent splits it into issues, each saying what done looks like, and the order they depend on."],
114 ["Agents", "Each issue gets an agent as it unblocks. They know what the others are changing, and tell each other."],
115 ["Review", "Checks run in clean sandboxes; a second agent reviews; you ask for changes and the agent makes them."],
116 ["Main", "The queue tests every change with what lands before it. Main moves only to what passed, and production follows."],
117];
118
119/** The forge itself, for the people on the team. */
120const FORGE = [
121 "Git over HTTPS",
122 "Public and private repositories",
123 "Issues and labels",
124 "Pull requests and forks",
125 "Line comments and reviews",
126 "Protected branches",
127 "Required approvals",
128 "Workspaces and roles",
129 "Profiles",
130 "Search and Explore",
131 "Webhooks",
132 "Import from any git host",
133 "REST API and OpenAPI",
134 "MCP server",
135 "OAuth sign-in",
136];
137
138const SECURE: { icon: ReactNode; title: string; about: string; to: string }[] = [
139 {
140 icon: <ShieldCheck size={18} />,
141 title: "Push protection",
142 about: "A push that adds a key or a token is refused before it lands, and the history is scanned for ones already there.",
143 to: `${DOCS}/guides/security/`,
144 },
145 {
146 icon: <PackageCheck size={18} />,
147 title: "Dependency upkeep",
148 about: "Each vulnerable dependency becomes an upgrade issue, and an agent lands the fix through the same checks as any change.",
149 to: `${DOCS}/guides/security/#dependency-upkeep`,
150 },
151 {
152 icon: <KeyRound size={18} />,
153 title: "Guardrails and credentials",
154 about: "What an agent may reach, run and spend is enforced outside its sandbox. Each run gets its own credential; your model keys never reach it.",
155 to: `${DOCS}/guides/guardrails/`,
156 },
157 {
158 icon: <ScrollText size={18} />,
159 title: "Audit log on every workspace",
160 about: "Every action by people, tokens and agents, with whether it was allowed and the rule that decided. Kept 90 days, with export.",
161 to: `${DOCS}/guides/audit-log/`,
162 },
163];
164
165/** The systems g1t connects to, shown on the landing page. */
166const STACK: Provider[] = [
167 "anthropic",
168 "openai",
169 "gemini",
170 "xai",
171 "mistral",
172 "deepseek",
173 "azure_openai",
174 "openrouter",
175 "groq",
176 "sentry",
177 "jira",
178 "linear",
179];
180
181/** What happens to a production error once Sentry is connected. */
182const LOOP = [
183 "Sentry: TypeError in checkout",
184 "g1t opens an issue, with the stack trace",
185 "An agent fixes it; another reviews it",
186 "The merge queue lands it on main",
187 "Sentry marks the error resolved",
188];
189
190const PRICES: { name: string; price: string; unit?: string; about: string }[] = [
191 {
192 name: "The forge",
193 price: "$0",
194 about: "Public and private repositories, git, issues, pull requests, reviews, search and the audit log. No card.",
195 },
196 {
197 name: "The g1t plan",
198 price: "$20",
199 unit: "a month per workspace",
200 about: "$10 of usage included. Unlimited members. Agents, checks, the merge queue and deployments.",
201 },
202 {
203 name: "Usage",
204 price: "Cost + 20%",
205 about: "Past what is included, everything is priced at what it costs g1t plus 20%, under a spend limit you set.",
206 },
207];
208
209const PLATFORM = ["Workers", "Artifacts", "Containers", "D1", "Queues", "Durable Objects", "AI Gateway", "Rust"];
210
211/**
212 * The signed-out home page: what g1t is, what it does, and how to start.
213 * It lists no one's repositories; those are a click away under Explore.
214 */
215export function Landing() {
216 const inviteOnly = useInviteOnly();
217 return (
218 <main className="overflow-x-clip">
219 {/* The opening. */}
220 <section className="dusk relative">
221 <div
222 aria-hidden="true"
223 className="dusk-planet pointer-events-none absolute -top-[30rem] left-1/2 size-[60rem] -translate-x-[10%] rounded-full"
224 />
225 <div className="relative mx-auto max-w-6xl px-4 pt-20 text-center sm:pt-24">
226 <Link
227 to={`${DOCS}/concepts/overview/`}
228 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-white/10 backdrop-blur transition-colors hover:bg-bg/70"
229 >
230 <span className="size-1.5 rounded-full bg-merged" />
231 Open source · built on Cloudflare
232 <ArrowRight size={12} />
233 </Link>
234 <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">
235 Where people and agents{" "}
236 <span className="bg-gradient-to-r from-fg via-[#d9d1ff] to-merged bg-clip-text text-transparent">
237 ship software together.
238 </span>
239 </h1>
240 <p className="mx-auto mt-7 max-w-2xl animate-fade-up text-lg leading-8 text-fg-soft/80 text-balance">
241 g1t is the git platform for the whole job. Plan in issues, assign work to agents like
242 teammates, land it through checks that hold, and deploy every change to the edge. Open
243 source, and priced at what it costs.
244 </p>
245 <div className="mt-9 flex animate-fade-up flex-wrap items-center justify-center gap-3">
246 <ButtonLink to="/register" variant="primary" large>
247 {inviteOnly ? "Request access" : "Start for free"}
248 <ArrowRight size={15} />
249 </ButtonLink>
250 {inviteOnly ? (
251 <ButtonLink to={HAVE_AN_INVITE} variant="quiet" large>
252 Have an invite?
253 </ButtonLink>
254 ) : (
255 <ButtonLink to="#how" variant="quiet" large>
256 See how it works
257 </ButtonLink>
258 )}
259 </div>
260 <p className="mx-auto mt-5 max-w-xl animate-fade-up text-sm text-fg-soft/60 text-balance">
261 {inviteOnly
262 ? "g1t is invite-only while we open it up. The forge is free, with no card; agents, checks and deployments run on the g1t plan."
263 : "The forge is free, with no card. Agents, checks and deployments run on the g1t plan."}
264 </p>
265 </div>
266 <Live className="relative mx-auto max-w-6xl px-2 pt-6 pb-2 sm:px-4">
267 <HeroArt className="w-full" />
268 </Live>
269 <div aria-hidden="true" className="h-16 bg-gradient-to-b from-transparent to-bg" />
270 </section>
271
272 {/* Facts, each one true today. */}
273 <section className="mx-auto max-w-6xl px-4">
274 <dl className="grid gap-px overflow-hidden rounded-2xl bg-line ring-1 ring-line sm:grid-cols-2 lg:grid-cols-4">
275 {FACTS.map(([figure, about]) => (
276 <div key={figure} className="bg-bg px-6 py-6">
277 <dt className="font-mono text-2xl font-medium tracking-tight text-fg">{figure}</dt>
278 <dd className="mt-2 text-sm leading-6 text-muted">{about}</dd>
279 </div>
280 ))}
281 </dl>
282 </section>
283
284 {/* The pillars. */}
285 <section className="mx-auto max-w-6xl px-4 pt-24">
286 <div className="max-w-3xl">
287 <Eyebrow>One place, idea to production</Eyebrow>
288 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
289 Everything between an idea and the people using it.
290 </h2>
291 <p className="mt-5 max-w-2xl text-lg leading-8 text-muted">
292 Agents are members of the forge, not a tool beside it. They take issues, review, answer
293 each other and fix what fails, under the same rules, records and review as everyone
294 else.
295 </p>
296 </div>
297
298 <div className="mt-6 divide-y divide-line">
299 <Pillar
300 eyebrow="Agents as teammates"
301 title="Assign an agent like anyone on the team"
302 art={<TeamArt className="w-full" />}
303 points={[
304 "Assign an issue, or @mention g1t-agent anywhere",
305 "Told what the others are changing while they work",
306 "Agents ask each other, and ask you, through the forge",
307 "Steer a run while it works, or stop it",
308 "Memory per project and per workspace",
309 "Your own agent over MCP, its session on the pull request",
310 ]}
311 more={["How g1t agents work", `${DOCS}/guides/g1t-agents/`]}
312 >
313 Every agent works in its own sandbox and its own fork. It sees what is in flight, files
314 what it finds instead of widening its change, comments on the work of others, and
315 defers to people.
316 </Pillar>
317
318 <Pillar
319 flip
320 eyebrow="Outcomes"
321 title="Hand off an outcome, not just a task"
322 art={<PlanArt className="w-full" />}
323 points={[
324 "A brief planned into issues with dependencies",
325 "Your workflows' required checks on every change",
326 "Work starts as each dependency lands",
327 "The plan as a live graph, with its cost",
328 ]}
329 more={["Hand off an outcome", `${DOCS}/guides/outcomes/`]}
330 >
331 Write what should be true. A planner turns it into issues, each saying what done looks
332 like, and the order they depend on. Agents take each issue as it unblocks, and you
333 watch the whole outcome converge.
334 </Pillar>
335
336 <Pillar
337 eyebrow="Ship safely"
338 title="Main only moves to what passed"
339 art={<QueueArt className="w-full" />}
340 points={[
341 "Checks run by g1t in a clean sandbox",
342 "GitHub Actions workflows run as they are",
343 "A merge queue that tests changes together",
344 "Conflicts found on every push, before a merge",
345 "Catch up with main in seconds",
346 "Reviews by people and by agents",
347 ]}
348 more={["The merge queue", `${DOCS}/guides/merge-queue/`]}
349 >
350 Checks are run by g1t, never by the agent being checked. The queue tests each change
351 together with what lands ahead of it; one that breaks goes back to its author with what
352 failed, and main never sees it.
353 </Pillar>
354
355 <Pillar
356 flip
357 eyebrow="Context"
358 title="Every line knows why it is there"
359 art={<WhyArt className="w-full" />}
360 points={[
361 "Sessions recorded onto pull requests",
362 "Why-blame on any line",
363 "A context hub agents search before they start",
364 "Search across code, issues and people",
365 ]}
366 more={["Sessions and why-blame", `${DOCS}/guides/why-blame/`]}
367 >
368 Pick any line. g1t shows the commit that changed it, the pull request and issue it came
369 from, and the agent&apos;s own session: what it read, ran and decided. The reasoning stays
370 with the code, for people and for the next agent.
371 </Pillar>
372
373 <Pillar
374 eyebrow="Run it"
375 title="Every change, live on the edge"
376 art={<DeployArt className="w-full" />}
377 points={[
378 "A live preview for every pull request",
379 "Production on every merge to main",
380 "Custom domains, with certificates",
381 "Projects that depend on each other",
382 ]}
383 more={["Deployments", `${DOCS}/guides/deployments/`]}
384 >
385 Turn on deployments and every pull request gets its own address on g1t.page; merging
386 ships production. Reviewers, and the agents reviewing for you, click through a change
387 instead of reading a diff. An app nobody visits runs nothing and costs nothing.
388 </Pillar>
389 </div>
390 </section>
391
392 {/* How it flows */}
393 <section id="how" className="scroll-mt-20 border-y border-line bg-surface/40">
394 <div className="mx-auto max-w-6xl px-4 py-24">
395 <Eyebrow>How it flows</Eyebrow>
396 <h2 className="mt-3 text-3xl font-semibold tracking-tight">From a sentence to main</h2>
397 <Live>
398 <ol className="relative mt-12 grid gap-6 md:grid-cols-5">
399 {/* From the first step's dot to the last one's, and no further: five
400 columns with 1.5rem gaps put the last dot 1rem into the last
401 column, so the line stops one column, less that, from the end. */}
402 <span
403 aria-hidden="true"
404 className="absolute top-4 right-[calc((100%-6rem)/5-1rem)] left-4 hidden h-px bg-gradient-to-r from-merged/50 via-warn/50 to-accent/70 md:block"
405 >
406 <span className="flow-runner absolute inset-0">
407 <span className="absolute -top-[3px] -left-[3.5px] size-[7px] rounded-full bg-merged shadow-[0_0_12px_2px_rgb(182_168_255/0.6)]" />
408 </span>
409 </span>
410 {FLOW.map(([step, about], index) => (
411 <li key={step} className="relative">
412 <span
413 className={`flow-step relative flex size-8 items-center justify-center rounded-full font-mono text-xs ring-1 ${
414 index === FLOW.length - 1 ? "bg-accent text-bg ring-accent" : "bg-bg text-fg-soft ring-line-strong"
415 }`}
416 style={{ "--delay": `${index * 2}s` } as CSSProperties}
417 >
418 {index + 1}
419 </span>
420 <h3 className="mt-4 font-semibold">{step}</h3>
421 <p className="mt-1.5 text-sm leading-6 text-muted">{about}</p>
422 </li>
423 ))}
424 </ol>
425 </Live>
426 </div>
427 </section>
428
429 {/* The forge, for people. */}
430 <section className="mx-auto max-w-6xl px-4 py-24">
431 <div className="grid gap-10 lg:grid-cols-[1fr_1.2fr] lg:gap-16">
432 <div>
433 <Eyebrow>Collaborate</Eyebrow>
434 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
435 A complete forge for the people on your team
436 </h2>
437 <p className="mt-4 max-w-md leading-7 text-muted">
438 Issues, branches, pull requests and reviews, the way your team already works, with
439 agents as members alongside you. Work by hand, hand work off, or both on the same
440 issue.
441 </p>
442 <More to={`${DOCS}/concepts/overview/`}>How g1t works</More>
443 </div>
444 <div className="rounded-3xl bg-surface p-7 ring-1 ring-line">
445 <p className="text-sm font-medium">Included in every workspace</p>
446 <Tags items={FORGE} />
447 </div>
448 </div>
449 </section>
450
451 {/* Secure by default */}
452 <section className="mx-auto max-w-6xl px-4 pb-24">
453 <Eyebrow>Secure by default</Eyebrow>
454 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
455 Safe to hand the work to, and healthy without anyone watching
456 </h2>
457 <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
458 {SECURE.map((item) => (
459 <Link
460 key={item.title}
461 to={item.to}
462 className="group rounded-2xl bg-surface p-6 ring-1 ring-line transition-colors hover:ring-line-strong"
463 >
464 <span className="flex size-9 items-center justify-center rounded-lg bg-bg text-merged ring-1 ring-line">{item.icon}</span>
465 <h3 className="mt-5 font-semibold">{item.title}</h3>
466 <p className="mt-2 text-sm leading-6 text-muted">{item.about}</p>
467 </Link>
468 ))}
469 </div>
470 </section>
471
472 {/* Connect */}
473 <section className="border-y border-line bg-surface/40">
474 <div className="mx-auto grid max-w-6xl items-center gap-12 px-4 py-24 lg:grid-cols-2">
475 <div>
476 <Eyebrow>Bring your own agent</Eyebrow>
477 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
478 Any agent joins the team with one command
479 </h2>
480 <p className="mt-4 max-w-md leading-7 text-muted">
481 Add g1t to Claude Code, Codex, OpenCode or Cursor and it can read the plan, take an
482 issue, open a pull request with a fork to push to, and see what the others are doing.
483 Install the hook in Claude Code and its session is recorded onto the pull request as
484 it works. g1t&apos;s own agents use the same tools.
485 </p>
486 <p className="mt-4 max-w-md leading-7 text-muted">
487 Every action is a REST route and an MCP tool, with an OpenAPI document and signed
488 webhooks for every event.
489 </p>
490 <div className="mt-6 flex flex-wrap gap-3">
491 <ButtonLink to={`${DOCS}/guides/bring-your-own-agent/`} variant="quiet">
492 Connect an agent
493 <ArrowRight size={14} />
494 </ButtonLink>
495 <ButtonLink to={`${DOCS}/reference/api/`} variant="quiet">
496 API reference
497 </ButtonLink>
498 </div>
499 </div>
500 <div className="space-y-3">
501 <AgentSetup />
502 <CopyLine prompt text="curl -fsSL https://g1t.sh/install/claude.sh | sh" />
503 <CopyLine prompt text="git clone https://g1t.sh/flagon-io/g1t.git" />
504 <CopyLine prompt text="curl https://api.g1t.sh/repos/flagon-io/g1t/queue" />
505 </div>
506 </div>
507 </section>
508
509 {/* Your stack */}
510 <section className="mx-auto grid max-w-6xl items-center gap-12 px-4 py-24 lg:grid-cols-2">
511 <div className="lg:order-2">
512 <Eyebrow>Your stack</Eyebrow>
513 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">
514 Your models. Your alerts. Your tickets.
515 </h2>
516 <p className="mt-4 max-w-md leading-7 text-muted">
517 Run g1t&apos;s agents on g1t&apos;s models, or on your own accounts with any of the labs and
518 platforms, and choose which model does which work. Keys stay with g1t: an agent&apos;s
519 sandbox only ever holds a token for its own run.
520 </p>
521 <p className="mt-4 max-w-md leading-7 text-muted">
522 Connect Sentry and a new error becomes an issue, an agent fixes it, and Sentry hears it
523 was resolved. Mention TECH-1234 and the agent reads the Jira ticket.
524 </p>
525 <More to={`${DOCS}/guides/integrations/`}>See the integrations</More>
526 </div>
527 <div className="space-y-6 lg:order-1">
528 <div className="grid grid-cols-3 gap-2 sm:grid-cols-4">
529 {STACK.map((provider) => (
530 <div
531 key={provider}
532 className="flex flex-col items-center gap-2 rounded-xl bg-surface px-2 py-3 ring-1 ring-line"
533 title={PROVIDERS[provider].label}
534 >
535 <ProviderMark provider={provider} size={30} />
536 <span className="w-full text-center text-xs leading-tight text-muted">{PROVIDERS[provider].label}</span>
537 </div>
538 ))}
539 </div>
540 <ol className="space-y-2 font-mono text-[0.8125rem]">
541 {LOOP.map((step, index) => (
542 <li key={step} className="flex items-center gap-3 text-fg-soft">
543 <span className="flex size-6 shrink-0 items-center justify-center rounded-full bg-surface text-xs text-faint ring-1 ring-line">
544 {index + 1}
545 </span>
546 {step}
547 </li>
548 ))}
549 </ol>
550 </div>
551 </section>
552
553 {/* Pricing, in one band. */}
554 <section className="mx-auto max-w-6xl px-4 pb-24">
555 <div className="flex flex-wrap items-end justify-between gap-6">
556 <div>
557 <Eyebrow>Pricing</Eyebrow>
558 <h2 className="mt-3 max-w-2xl text-3xl font-semibold tracking-tight text-balance">
559 What it costs to run, plus 20%. Never per seat.
560 </h2>
561 </div>
562 <More to="/pricing">See every price</More>
563 </div>
564 <div className="mt-10 grid gap-px overflow-hidden rounded-3xl bg-line ring-1 ring-line md:grid-cols-3">
565 {PRICES.map((item) => (
566 <div key={item.name} className="bg-surface p-7">
567 <p className="text-sm text-muted">{item.name}</p>
568 <p className="mt-3 flex flex-wrap items-baseline gap-x-2">
569 <span className="text-3xl font-semibold tracking-tight">{item.price}</span>
570 {item.unit && <span className="text-sm text-muted">{item.unit}</span>}
571 </p>
572 <p className="mt-3 text-sm leading-6 text-muted">{item.about}</p>
573 </div>
574 ))}
575 </div>
576 </section>
577
578 {/* Open source */}
579 <section className="mx-auto max-w-6xl px-4 pb-24">
580 <div className="grid gap-10 rounded-3xl bg-surface p-8 ring-1 ring-line sm:p-10 lg:grid-cols-[1.3fr_1fr]">
581 <div>
582 <Eyebrow>Open source</Eyebrow>
583 <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance">Open, and built on itself</h2>
584 <p className="mt-4 max-w-xl leading-7 text-muted">
585 g1t is MIT licensed. Its own source lives on g1t, and its changes land through its own
586 merge queue. Your code is plain git: leaving is a <code className="font-mono text-fg-soft">git clone</code>.
587 </p>
588 <p className="mt-4 max-w-xl leading-7 text-muted">
589 You can run the core forge yourself with Docker Compose today: accounts, repositories,
590 issues, pull requests and search. It is an early version, and agents, deployments and
591 context search still run only on g1t.sh.
592 </p>
593 <div className="mt-7 flex flex-wrap gap-3">
594 <ButtonLink to="/flagon-io/g1t" variant="quiet">
595 Browse the source
596 </ButtonLink>
597 <ButtonLink to={`${DOCS}/guides/self-hosting/`} variant="quiet">
598 Run g1t yourself
599 </ButtonLink>
600 </div>
601 </div>
602 <div className="flex flex-col justify-between gap-6">
603 <div>
604 <p className="text-sm font-medium">Built on Cloudflare</p>
605 <ul className="mt-4 flex flex-wrap gap-2">
606 {PLATFORM.map((name) => (
607 <li key={name} className="rounded-full bg-bg/60 px-3 py-1 font-mono text-xs text-fg-soft ring-1 ring-line">
608 {name}
609 </li>
610 ))}
611 </ul>
612 </div>
613 <p className="text-sm leading-6 text-muted">
614 g1t is made by Flagon, Inc., a small, independent software company.
615 </p>
616 </div>
617 </div>
618 </section>
619
620 {/* The close. */}
621 <section className="mx-auto max-w-6xl px-4 pb-8">
622 <div className="dusk relative overflow-hidden rounded-3xl px-6 py-16 text-center ring-1 ring-line">
623 <h2 className="mx-auto max-w-2xl text-3xl font-semibold tracking-tight text-balance sm:text-4xl">
624 Bring your team. Bring your agents.
625 </h2>
626 <p className="mx-auto mt-4 max-w-xl text-fg-soft/80 text-balance">
627 Create a workspace in a minute and push your first repository. The forge is free; start
628 the plan when you want agents and deployments.
629 </p>
630 <div className="mt-8 flex flex-wrap justify-center gap-3">
631 <ButtonLink to="/register" variant="primary" large>
632 {inviteOnly ? "Request access" : "Create your workspace"}
633 <ArrowRight size={15} />
634 </ButtonLink>
635 {inviteOnly && (
636 <ButtonLink to={HAVE_AN_INVITE} variant="quiet" large>
637 Have an invite?
638 </ButtonLink>
639 )}
640 <ButtonLink to={`${DOCS}/quickstart/`} variant="quiet" large>
641 Read the quickstart
642 </ButtonLink>
643 </div>
644 </div>
645 </section>
646 </main>
647 );
648}