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