fixed features section,footer and some minor changes

This commit is contained in:
codebanditssss 2026-06-29 06:29:22 +05:30
parent eb6b5cdb3a
commit f6c1869ab9
8 changed files with 1321 additions and 243 deletions

View File

@ -3,9 +3,6 @@ import { LandingHero } from "../../components/LandingHero";
import { LandingAgentsBar } from "../../components/LandingAgentsBar";
import { LandingVideo } from "../../components/LandingVideo";
import { LandingFeatures } from "../../components/LandingFeatures";
import { LandingHowItWorks } from "../../components/LandingHowItWorks";
import { LandingArchitecture } from "../../components/LandingArchitecture";
import { LandingLiveDemo } from "../../components/LandingLiveDemo";
import { LandingSocialProof } from "../../components/LandingSocialProof";
import { LandingFooter } from "../../components/LandingFooter";
import { ScrollRevealProvider } from "../../components/ScrollRevealProvider";
@ -19,9 +16,6 @@ export default function LandingPage() {
<LandingAgentsBar />
<LandingVideo />
<LandingFeatures />
<LandingHowItWorks />
<LandingArchitecture />
<LandingLiveDemo />
<LandingSocialProof />
<LandingFooter />
</div>

View File

@ -36,9 +36,9 @@ export function LandingAgentsBar() {
<div className="container-page py-7">
<div className="mx-auto flex max-w-[1280px] flex-wrap items-baseline justify-between gap-5">
<div className="flex flex-wrap items-baseline gap-x-4 gap-y-2">
<span className="serial-num font-mono text-xs">01 - coverage</span>
<span className="serial-num font-mono text-xs">Coverage</span>
<h2 className="font-display text-2xl font-bold leading-none tracking-tight text-[color:var(--fg)] sm:text-3xl">
One daemon. <span className="text-[color:var(--fg-muted)]">23 agent harnesses.</span>
One Daemon. <span className="text-[color:var(--fg-muted)]">23 agent harnesses.</span>
</h2>
</div>
<p className="max-w-md font-mono text-xs leading-relaxed text-[color:var(--fg-dim)]">

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,34 @@
const LOGO_URL = "/ao-logo.svg";
const LOGO_URL = "/ao-logo-transparent.png";
const columns = [
{
title: "Product",
links: [
{ label: "Features", href: "#features" },
{ label: "Agents", href: "#agents" },
{ label: "Install", href: "/docs/installation" },
{ label: "CLI", href: "/docs/cli" },
],
},
{
title: "Docs",
links: [
{ label: "Overview", href: "/docs" },
{ label: "Architecture", href: "/docs/architecture" },
{ label: "Plugins", href: "/docs/plugins" },
{ label: "Changelog", href: "/docs/changelog" },
],
},
{
title: "Community",
links: [
{ label: "GitHub", href: "https://github.com/AgentWrapper/agent-orchestrator" },
{ label: "Issues", href: "https://github.com/AgentWrapper/agent-orchestrator/issues" },
{ label: "Pull requests", href: "https://github.com/AgentWrapper/agent-orchestrator/pulls" },
{ label: "Releases", href: "https://github.com/AgentWrapper/agent-orchestrator/releases" },
],
},
];
function GithubIcon({ className = "" }: { className?: string }) {
return (
@ -8,86 +38,69 @@ function GithubIcon({ className = "" }: { className?: string }) {
);
}
const productLinks = [
{ label: "Features", href: "#features" },
{ label: "How it works", href: "#how" },
{ label: "Architecture", href: "#architecture" },
{ label: "Quickstart", href: "#quickstart" },
];
const resourceLinks = [
{ label: "GitHub", href: "https://github.com/AgentWrapper/agent-orchestrator" },
{ label: "Architecture docs", href: "/docs/architecture" },
{ label: "CLI reference", href: "/docs/cli" },
{ label: "Releases", href: "https://github.com/AgentWrapper/agent-orchestrator/releases" },
];
const communityLinks = [
{ label: "Contributors", href: "https://github.com/AgentWrapper/agent-orchestrator/graphs/contributors" },
{ label: "Issues", href: "https://github.com/AgentWrapper/agent-orchestrator/issues" },
{ label: "Pull requests", href: "https://github.com/AgentWrapper/agent-orchestrator/pulls" },
{ label: "ao-agents.com", href: "https://ao-agents.com" },
];
export function LandingFooter() {
return (
<footer data-testid="footer" className="border-t border-[color:var(--border)] bg-[color:var(--bg-deep)]">
<div className="container-page py-16">
<div className="grid gap-10 md:grid-cols-12">
<div className="md:col-span-5">
<div className="mb-4 inline-flex h-10 items-center gap-2.5">
<img src={LOGO_URL} alt="Agent Orchestrator" className="block h-10 w-10 shrink-0 object-contain" />
<span className="font-display text-lg font-bold leading-none tracking-tight text-[color:var(--fg)]">
Agent Orchestrator
<footer data-testid="footer" className="border-t border-[color:var(--border)] bg-black">
<div className="container-page py-14 sm:py-16">
<div className="grid gap-10 lg:grid-cols-[0.95fr_1.05fr]">
<div className="max-w-md">
<a href="/" className="inline-flex items-center gap-3">
<img src={LOGO_URL} alt="Agent Orchestrator" className="h-10 w-10 object-contain" />
<span className="text-[16px] font-semibold text-[color:var(--fg)]">Agent Orchestrator</span>
</a>
<p className="mt-4 max-w-md text-[14px] leading-relaxed text-[color:var(--fg-muted)]">
Open-source orchestration for terminal-native coding agents. Local daemon, isolated worktrees, live
sessions, and PR feedback routed to the right worker.
</p>
<div className="mt-5 flex flex-wrap gap-2">
<a
href="https://github.com/AgentWrapper/agent-orchestrator"
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-2 rounded-md border border-[color:var(--border)] bg-white/[0.025] px-3 py-2 text-[13px] font-medium text-[color:var(--fg-muted)] transition hover:bg-white/[0.05] hover:text-[color:var(--fg)]"
>
<GithubIcon className="h-4 w-4" />
GitHub
</a>
<span className="inline-flex items-center rounded-md border border-[color:var(--border)] bg-white/[0.015] px-3 py-2 font-mono text-[12px] text-[color:var(--fg-dim)]">
Apache 2.0
</span>
<span className="inline-flex items-center rounded-md border border-[color:var(--border)] bg-white/[0.015] px-3 py-2 font-mono text-[12px] text-[color:var(--fg-dim)]">
127.0.0.1
</span>
</div>
<p className="max-w-sm text-[14px] leading-relaxed text-[color:var(--fg-muted)]">
The open-source orchestration layer for parallel AI coding agents. Loopback-only, Apache 2.0 licensed,
runs on your laptop.
</p>
</div>
<FooterCol title="Product" links={productLinks} />
<FooterCol title="Resources" links={resourceLinks} />
<FooterCol title="Community" links={communityLinks} />
<div className="grid gap-8 sm:grid-cols-3 lg:justify-items-end">
{columns.map((column) => (
<div key={column.title} className="w-full max-w-[160px]">
<h4 className="mb-4 font-mono text-[10px] uppercase tracking-[0.22em] text-[color:var(--fg-dim)]">
{column.title}
</h4>
<ul className="space-y-2.5">
{column.links.map((link) => (
<li key={link.label}>
<a
href={link.href}
target={link.href.startsWith("#") || link.href.startsWith("/") ? undefined : "_blank"}
rel={link.href.startsWith("#") || link.href.startsWith("/") ? undefined : "noreferrer"}
className="text-[13px] text-[color:var(--fg-muted)] transition-colors hover:text-[color:var(--fg)]"
>
{link.label}
</a>
</li>
))}
</ul>
</div>
))}
</div>
</div>
<div className="mt-14 flex flex-col items-start justify-between gap-3 border-t border-[color:var(--border)] pt-6 font-mono text-[10px] uppercase tracking-[0.22em] text-[color:var(--fg-dim)] sm:flex-row sm:items-center">
<div>Built by the open-source community.</div>
<a
href="https://github.com/AgentWrapper/agent-orchestrator"
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1.5 transition-colors hover:text-[color:var(--accent)]"
data-testid="footer-github-link"
>
<GithubIcon className="h-3 w-3" />
AgentWrapper/agent-orchestrator
</a>
<div className="mt-12 flex flex-col justify-between gap-3 border-t border-[color:var(--border)] pt-5 font-mono text-[10px] uppercase tracking-[0.2em] text-[color:var(--fg-dim)] sm:flex-row">
<span>AgentWrapper/agent-orchestrator</span>
<span>Runs locally on your laptop.</span>
</div>
</div>
</footer>
);
}
function FooterCol({ title, links }: { title: string; links: Array<{ label: string; href: string }> }) {
return (
<div className="md:col-span-2 lg:col-span-2">
<h4 className="mb-4 font-mono text-[10px] uppercase tracking-[0.22em] text-[color:var(--fg-dim)]">{title}</h4>
<ul className="space-y-2.5">
{links.map((link) => (
<li key={link.label}>
<a
href={link.href}
target={link.href.startsWith("#") || link.href.startsWith("/") ? undefined : "_blank"}
rel={link.href.startsWith("#") || link.href.startsWith("/") ? undefined : "noreferrer"}
className="text-[13.5px] text-[color:var(--fg-muted)] transition-colors hover:text-[color:var(--fg)]"
>
{link.label}
</a>
</li>
))}
</ul>
</div>
);
}

View File

@ -558,15 +558,16 @@ export function LandingHero() {
<div className="mx-auto max-w-[1500px] text-center">
<h1
data-testid="hero-headline"
className="mx-auto max-w-[1280px] font-display font-[650] leading-[1.01] text-[#f2f3f5]"
className="mx-auto max-w-[1120px] font-sans font-[600] leading-[1.08] text-[#f2f3f5]"
style={{
fontSize: "clamp(38px, 4.2vw, 76px)",
letterSpacing: "-0.035em",
fontFamily: '"Instrument Sans", "Inter", "Helvetica Neue", Arial, sans-serif',
fontSize: "clamp(34px, 3.55vw, 62px)",
letterSpacing: "-0.026em",
}}
>
<span className="block">Stop babysitting coding agents.</span>
<span className="mt-2 block">
Start merging <span className="text-[#93b4f8]">real work.</span>
<span className="mt-2 block italic">
Start merging <span className="font-[620] text-[#93b4f8]">real work.</span>
</span>
</h1>
<p className="mx-auto mt-7 max-w-[680px] text-[15px] font-medium leading-[1.75] text-[color:var(--fg-muted)] sm:text-[17px]">

View File

@ -71,7 +71,7 @@ const socials = [
const navLinks = [
{ label: "Demo", href: "#see-it" },
{ label: "Agents", href: "#agents" },
{ label: "Features", href: "#features" },
{ label: "Docs", href: "/docs" },
];

View File

@ -1,12 +1,18 @@
"use client";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
declare global {
interface Window {
twttr?: {
ready?: (callback: () => void) => void;
widgets?: {
load?: () => void;
load?: (element?: HTMLElement) => void;
createTweet?: (
tweetId: string,
element: HTMLElement,
options?: { theme?: "dark" | "light"; dnt?: boolean; conversation?: "none"; width?: number },
) => Promise<HTMLElement>;
};
};
}
@ -19,6 +25,8 @@ const posts = [
label: "Signal",
author: "Teknium",
note: "Most important outside validation.",
text: "Outside validation that AO is landing with serious agent builders.",
meta: "builder signal",
},
{
handle: "facito0",
@ -26,6 +34,8 @@ const posts = [
label: "Mood",
author: "FacitoO",
note: "A lightweight social proof hit from daily AO usage.",
text: "A small but useful signal from someone actually using the workflow.",
meta: "daily AO usage",
},
{
handle: "buchireddy",
@ -33,6 +43,8 @@ const posts = [
label: "Builder",
author: "Buchi Reddy B",
note: "Went all-in early on the AO building blocks.",
text: "I really loved the building blocks present in @aoagents, hence we went all-in on that pretty early. Happy to share more details if it helps others.",
meta: "3:41 AM - Jun 9, 2026",
},
{
handle: "oxwizzdom",
@ -40,6 +52,8 @@ const posts = [
label: "Code read",
author: "oxwizzdom",
note: "Weekend codebase teardown and minimal rebuild.",
text: "1/ @agent_wrapper & @composio shipped @aoagents a while back. runs 50 coding agents in parallel on the same repo. i spent a weekend reading the codebase. found 5 techniques that make it work.",
meta: "repo teardown",
},
{
handle: "addddiiie",
@ -47,6 +61,8 @@ const posts = [
label: "Use case",
author: "Adi",
note: "Parallel dev agents framed in one clean line.",
text: "The core use case explained simply: parallel agents without babysitting.",
meta: "parallel workflow",
},
{
handle: "aoagents",
@ -54,6 +70,8 @@ const posts = [
label: "Official",
author: "Agent Orchestrator",
note: "A short official signal from the AO account.",
text: "Best as it gets",
meta: "official AO",
},
];
@ -61,6 +79,10 @@ function postUrl(post: (typeof posts)[number]) {
return `https://twitter.com/${post.handle}/status/${post.statusIdParts.join("")}`;
}
function postId(post: (typeof posts)[number]) {
return post.statusIdParts.join("");
}
function ArrowUpRightIcon({ className = "" }: { className?: string }) {
return (
<svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
@ -78,15 +100,21 @@ function MessageCircleIcon({ className = "" }: { className?: string }) {
);
}
function loadTwitterWidgets() {
function loadTwitterWidgets(target?: HTMLElement | null, onReady?: () => void) {
const load = () => {
window.twttr?.widgets?.load?.(target ?? undefined);
window.twttr?.ready?.(() => onReady?.());
onReady?.();
};
if (window.twttr?.widgets) {
window.twttr.widgets.load?.();
load();
return;
}
const existing = document.getElementById("twitter-wjs");
if (existing) {
existing.addEventListener("load", () => window.twttr?.widgets?.load?.(), { once: true });
existing.addEventListener("load", load, { once: true });
return;
}
@ -95,7 +123,7 @@ function loadTwitterWidgets() {
script.src = "https://platform.twitter.com/widgets.js";
script.async = true;
script.charset = "utf-8";
script.onload = () => window.twttr?.widgets?.load?.();
script.onload = load;
document.body.appendChild(script);
}
@ -119,9 +147,43 @@ function usePageTheme() {
export function LandingSocialProof() {
const theme = usePageTheme();
const tweetRefs = useRef<Record<string, HTMLDivElement | null>>({});
useEffect(() => {
loadTwitterWidgets();
const target = document.getElementById("testimonials");
const renderTweets = () => {
for (const post of posts) {
const id = postId(post);
const node = tweetRefs.current[id];
if (!node || node.dataset.tweetRendered === `${id}-${theme}`) continue;
if (!window.twttr?.widgets?.createTweet) continue;
node.dataset.tweetRendered = `${id}-${theme}`;
node.innerHTML = "";
void window.twttr.widgets
.createTweet(id, node, {
theme: theme === "light" ? "light" : "dark",
dnt: true,
conversation: "none",
width: 420,
})
.catch(() => {
delete node.dataset.tweetRendered;
});
}
};
loadTwitterWidgets(target, renderTweets);
window.twttr?.ready?.(renderTweets);
const timers = [350, 1000, 2200, 4200, 7000].map((delay) =>
window.setTimeout(() => {
window.twttr?.ready?.(renderTweets);
renderTweets();
}, delay),
);
return () => timers.forEach((timer) => window.clearTimeout(timer));
}, [theme]);
return (
@ -134,7 +196,7 @@ export function LandingSocialProof() {
<div className="mx-auto max-w-[1320px]">
<div className="mb-12 grid items-end gap-8 lg:grid-cols-12">
<div className="lg:col-span-7">
<div className="serial-num mb-3 font-mono text-xs">06 - in the wild</div>
<div className="serial-num mb-3 font-mono text-xs">In the wild</div>
<h2
className="font-display font-bold leading-[1.02] tracking-tight text-[color:var(--fg)]"
style={{ fontSize: "clamp(32px, 4.8vw, 60px)" }}
@ -154,7 +216,14 @@ export function LandingSocialProof() {
<div className="tweet-masonry">
{posts.map((post, index) => (
<TweetCard key={`${theme}-${post.handle}-${index}`} post={post} index={index} theme={theme} />
<TweetCard
key={`${theme}-${post.handle}-${index}`}
post={post}
index={index}
setTweetRef={(node) => {
tweetRefs.current[postId(post)] = node;
}}
/>
))}
</div>
</div>
@ -163,7 +232,47 @@ export function LandingSocialProof() {
);
}
function TweetCard({ post, index, theme }: { post: (typeof posts)[number]; index: number; theme: string }) {
function TweetFallback({ post, url }: { post: (typeof posts)[number]; url: string }) {
return (
<div className="tweet-fallback">
<div className="flex items-start justify-between gap-3">
<div className="flex min-w-0 items-center gap-3">
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-[color:var(--accent-soft)] text-sm font-bold text-[color:var(--accent)]">
{post.author.slice(0, 1)}
</div>
<div className="min-w-0">
<div className="truncate text-[15px] font-semibold text-[color:var(--fg)]">{post.author}</div>
<div className="truncate text-[13px] text-[color:var(--fg-dim)]">@{post.handle}</div>
</div>
</div>
<span className="text-lg font-semibold text-[color:var(--fg-muted)]">X</span>
</div>
<p className="mt-4 whitespace-pre-line text-[17px] leading-relaxed text-[color:var(--fg)]">{post.text}</p>
<div className="mt-5 border-t border-[color:var(--border-strong)] pt-3 text-[13px] text-[color:var(--fg-dim)]">
{post.meta}
</div>
<div className="mt-4 flex items-center gap-5 text-[13px] text-[color:var(--fg-muted)]">
<span>Like</span>
<span>Reply</span>
<a href={url} target="_blank" rel="noreferrer" className="hover:text-[color:var(--accent)]">
Read more on X
</a>
</div>
</div>
);
}
function TweetCard({
post,
index,
setTweetRef,
}: {
post: (typeof posts)[number];
index: number;
setTweetRef: (node: HTMLDivElement | null) => void;
}) {
const url = postUrl(post);
return (
@ -195,15 +304,12 @@ function TweetCard({ post, index, theme }: { post: (typeof posts)[number]; index
<div className="px-3 pb-4 pt-3">
<p className="mb-3 px-1 text-[13px] leading-relaxed text-[color:var(--fg-muted)]">{post.note}</p>
<div className="tweet-shell [&_.twitter-tweet]:mx-auto [&_.twitter-tweet]:max-w-full">
<blockquote
className="twitter-tweet"
data-theme={theme === "light" ? "light" : "dark"}
data-dnt="true"
data-conversation="none"
data-width="420"
<div
ref={setTweetRef}
className="min-h-[240px]"
>
<a href={url}>View post on X</a>
</blockquote>
<TweetFallback post={post} url={url} />
</div>
</div>
</div>
</article>

View File

@ -239,6 +239,17 @@ body::-webkit-scrollbar,
background: var(--bg-deep);
}
.tweet-fallback {
min-height: 240px;
border-radius: 14px;
border: 1px solid var(--border);
background:
linear-gradient(180deg, rgba(130, 170, 255, 0.035), transparent 36%),
#050607;
padding: 18px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
.tweet-shell .twitter-tweet,
.tweet-shell iframe {
width: 100% !important;
@ -558,6 +569,54 @@ body::-webkit-scrollbar,
animation: landing-sse-pulse 1.6s ease-in-out infinite;
}
@keyframes landing-adapter-pulse {
0% {
transform: translateX(-24px);
opacity: 0;
}
18%,
72% {
opacity: 1;
}
100% {
transform: translateX(24px);
opacity: 0;
}
}
.landing-adapter-pulse {
animation: landing-adapter-pulse 1.7s cubic-bezier(0.4, 0.8, 0.6, 1) infinite;
}
.landing-feature-stack-card {
will-change: transform;
}
.landing-feature-stack-cover {
isolation: isolate;
}
.landing-feature-stack-cover::before {
content: "";
position: absolute;
inset: -28px -2px -28px -2px;
z-index: -1;
border-radius: 24px;
background: var(--bg);
box-shadow: 0 -80px 0 80px var(--bg);
}
@media (max-width: 1023px) {
.landing-feature-stack-card {
position: relative;
top: auto;
}
.landing-feature-stack-cover::before {
display: none;
}
}
/* Switcher progress bar */
@keyframes landing-switcher-progress {
from {