Skip to content

Commit f6ac7ff

Browse files
nearestnaborsclaudegithub-actions[bot]
authored
Redesign landing page with improved layout and messaging (#662)
* Redesign landing page with improved layout and messaging - Update hero section with new tagline emphasizing auth for AI agents - Restructure "Choose Your Path" into two columns: "Get Tools" and "Use Arcade" - Add responsive breakpoints at 1062px for tile layouts - Fix framework logos for dark mode with invertInDark support - Add local SVG icons for LangChain, Mastra, CrewAI, Jira, Confluence - Make section headers responsive (centered on mobile) - Add cursor-pointer to clickable cards - Fix image distortion with object-contain - Remove video section (not ready for launch) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update How Arcade Works section with better links and descriptions - Rename "Runtime" tile to "Authorized Tool Calling" with working link - Update tile descriptions for clarity - All links verified to exist Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add image support to SampleAppCard component Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add agentic development callout and move overview image - Add LLMs.txt callout section to landing page for IDE integration - Move overview architecture image to about page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Invert Cursor and Claude icons in light mode on MCP clients page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Make SampleAppCard image optional and remove images from landing page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix Tailwind gradient class name Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update framework icons to use local SVGs with dark mode support - Add invertInDark prop to PlatformCard component - Update LangChain, Mastra, and Vercel AI icons to use local SVGs - Apply dark:invert for proper visibility in dark mode Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add redirect from CrewAI index to use-arcade-tools Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * 🤖 Regenerate LLMs.txt * Add redirects for all agent framework index pages - LangChain -> use-arcade-tools - Google ADK -> overview - Mastra -> overview - OpenAI Agents -> overview Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * 🤖 Regenerate LLMs.txt * 🤖 Regenerate LLMs.txt * Update sample app cards and fix framework links - Remove placeholder images from examples page - Remove "Try it out" / "View project" buttons from SampleAppCard - Keep images on landing page sample apps - Update framework links to point to correct subpages - Remove redirect pages (links updated instead) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * 🤖 Regenerate LLMs.txt * Add IDE logos to Connect to Your IDE card Added logos prop to QuickStartCard component to display small icons. Shows Cursor, VS Code, and Claude Desktop icons on the IDE tile. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Style IDE logos: bigger, centered with padding, offset Use Arcade column - Increased logo size from h-5/w-5 to h-7/w-7 - Centered logos with justify-center and gap-4 - Added horizontal padding to logo container - Added mt-12 to Use Arcade column on desktop to offset below Get Tools Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Increase Use Arcade column offset to 100px Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Align Learn more links to the right in QuickStartCard tiles Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update app/en/resources/examples/page.mdx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update app/en/resources/examples/page.mdx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update app/en/resources/examples/page.mdx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --------- Co-authored-by: Rachel Lee Nabors <nearestnabors@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 2488206 commit f6ac7ff

15 files changed

Lines changed: 763 additions & 401 deletions

File tree

app/_components/platform-card.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ type PlatformCardProps = {
99
icon: string;
1010
link: string;
1111
type: "Agent Framework" | "MCP Client";
12+
invertInDark?: boolean;
1213
};
1314

1415
export const PlatformCard: React.FC<PlatformCardProps> = ({
1516
name,
1617
icon,
1718
link,
1819
type,
20+
invertInDark,
1921
}) => {
2022
const cardContent = (
2123
<Card
@@ -28,7 +30,7 @@ export const PlatformCard: React.FC<PlatformCardProps> = ({
2830
<div className="relative flex h-10 w-10 items-center justify-center overflow-hidden rounded-lg">
2931
<img
3032
alt={`${name} logo`}
31-
className="size-9"
33+
className={cn("size-9", invertInDark && "dark:invert")}
3234
height={36}
3335
src={icon}
3436
width={36}

app/_components/quick-start-card.tsx

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@ import {
55
CardHeader,
66
CardTitle,
77
} from "@arcadeai/design-system";
8+
import { ArrowRight } from "lucide-react";
89
import { motion } from "motion/react";
910
import Link from "next/link";
1011
import posthog from "posthog-js";
1112

13+
type LogoItem = {
14+
src: string;
15+
alt: string;
16+
invertInLight?: boolean;
17+
invertInDark?: boolean;
18+
};
19+
1220
type QuickStartCardProps = {
1321
icon: React.ElementType;
1422
title: string;
1523
description: string;
1624
href?: string;
1725
onClick?: () => void;
1826
code?: string;
27+
logos?: LogoItem[];
1928
};
2029

2130
export function QuickStartCard({
@@ -25,6 +34,7 @@ export function QuickStartCard({
2534
href,
2635
onClick,
2736
code,
37+
logos,
2838
}: QuickStartCardProps) {
2939
const handleCardClick = () => {
3040
posthog.capture("Quickstart card clicked", {
@@ -34,25 +44,58 @@ export function QuickStartCard({
3444
});
3545
};
3646

47+
const isClickable = href || onClick;
48+
3749
const content = (
3850
<>
39-
<CardHeader className="flex flex-row items-center gap-3 p-6">
51+
<CardHeader className="flex flex-row items-center gap-3 p-4 min-[1062px]:p-6">
4052
<div className="rounded-full bg-[#ee175e]/10 p-2">
4153
<Icon className="h-5 w-5 text-[#ee175e]" />
4254
</div>
4355
<CardTitle className="text-gray-900 text-xl tracking-tight dark:text-white">
4456
{title}
4557
</CardTitle>
4658
</CardHeader>
47-
<CardContent className="p-6 pt-0">
59+
<CardContent className="p-4 pt-0 min-[1062px]:p-6 min-[1062px]:pt-0">
4860
<p className="text-gray-600 text-sm leading-relaxed dark:text-gray-300">
4961
{description}
5062
</p>
63+
{logos && logos.length > 0 && (
64+
<div className="mt-4 flex items-center justify-center gap-4 px-2">
65+
{logos.map((logo) => {
66+
const getInvertClass = () => {
67+
if (logo.invertInLight) {
68+
return "invert dark:invert-0";
69+
}
70+
if (logo.invertInDark) {
71+
return "dark:invert";
72+
}
73+
return "";
74+
};
75+
return (
76+
<img
77+
alt={logo.alt}
78+
className={`h-7 w-7 object-contain ${getInvertClass()}`}
79+
height={28}
80+
key={logo.src}
81+
src={logo.src}
82+
width={28}
83+
/>
84+
);
85+
})}
86+
</div>
87+
)}
5188
{code && (
5289
<pre className="mt-1 rounded-md bg-gray-100 p-1 text-gray-800 text-sm dark:bg-gray-900 dark:text-gray-300">
5390
<code>{code}</code>
5491
</pre>
5592
)}
93+
{isClickable && (
94+
<div className="mt-4 flex items-center justify-end font-medium text-[#ee175e] text-sm">
95+
Learn more
96+
<ArrowRight className="ml-1 h-4 w-4 transition-transform group-hover:translate-x-1" />
97+
</div>
98+
)}
5699
</CardContent>
57100
</>
58101
);
@@ -66,7 +109,7 @@ export function QuickStartCard({
66109
if (onClick) {
67110
wrapper = (
68111
<button
69-
className="block h-full w-full text-left"
112+
className="group block h-full w-full cursor-pointer text-left"
70113
onClick={handleClick}
71114
type="button"
72115
>
@@ -75,7 +118,11 @@ export function QuickStartCard({
75118
);
76119
} else if (href) {
77120
wrapper = (
78-
<Link className="block h-full" href={href} onClick={handleCardClick}>
121+
<Link
122+
className="group block h-full cursor-pointer"
123+
href={href}
124+
onClick={handleCardClick}
125+
>
79126
{content}
80127
</Link>
81128
);
@@ -91,7 +138,7 @@ export function QuickStartCard({
91138
}}
92139
whileTap={{ scale: 0.98 }}
93140
>
94-
<Card className="h-full border-gray-800 bg-white/80 backdrop-blur-xs transition-all hover:border-[#ee175e]/30 dark:border-gray-800 dark:bg-[rgba(17,17,17,0.8)]">
141+
<Card className="h-full border-gray-200 bg-white/80 backdrop-blur-xs transition-all hover:border-[#ee175e]/30 dark:border-gray-700 dark:bg-[rgba(17,17,17,0.8)]">
95142
{wrapper}
96143
</Card>
97144
</motion.div>
Lines changed: 102 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"use client";
22
import { Card, CardContent } from "@arcadeai/design-system";
3+
import { motion } from "motion/react";
34
import Link from "next/link";
45
import posthog from "posthog-js";
56

67
type SampleAppCardProps = {
78
title: string;
89
description: string;
9-
image: string;
10+
image?: string;
1011
href: string;
1112
blank?: boolean;
1213
tags?: string[];
@@ -16,6 +17,7 @@ type SampleAppCardProps = {
1617
export function SampleAppCard({
1718
title,
1819
description,
20+
image,
1921
href,
2022
blank = false,
2123
tags = [],
@@ -31,87 +33,107 @@ export function SampleAppCard({
3133
};
3234

3335
return (
34-
<Link
35-
href={href}
36-
onClick={handleClick}
37-
target={blank ? "_blank" : undefined}
36+
<motion.div
37+
whileHover={{
38+
scale: 1.02,
39+
boxShadow: "0 0 20px 0 rgba(238, 23, 94, 0.1)",
40+
}}
41+
whileTap={{ scale: 0.98 }}
3842
>
39-
<Card className="flex h-full flex-col gap-1.5 border border-gray-600/20 bg-white/90 py-3 backdrop-blur-sm transition-all duration-300 hover:border-primary hover:bg-gray-600/[0.03] hover:shadow-lg dark:bg-gray-900/80">
40-
<CardContent className="p-0">
41-
<div className="space-y-2 p-6">
42-
<div className="flex items-start justify-between gap-2">
43-
<h3 className="font-semibold text-gray-900 text-xl tracking-tight dark:text-white">
44-
{title}
45-
</h3>
46-
{date && (
47-
<span className="whitespace-nowrap font-medium text-gray-500 text-xs dark:text-gray-400">
48-
{date}
49-
</span>
50-
)}
51-
</div>
52-
<p className="text-gray-600 text-sm leading-relaxed dark:text-gray-300">
53-
{description}
54-
</p>
55-
{tags.length > 0 && (
56-
<div className="flex flex-wrap gap-2 pt-2">
57-
{tags.map((tag) => {
58-
const getTagColor = (tagName: string) => {
59-
const languages = [
60-
"JavaScript",
61-
"Python",
62-
"TypeScript",
63-
"Java",
64-
"Go",
65-
"Rust",
66-
];
67-
const frameworks = [
68-
"Langchain",
69-
"mastra",
70-
"CrewAI",
71-
"LangGraph",
72-
"OpenAI",
73-
"Anthropic",
74-
"Next.js",
75-
];
76-
const integrations = [
77-
"Slack",
78-
"GitHub",
79-
"Gmail",
80-
"Discord",
81-
"Notion",
82-
"Linear",
83-
"Jira",
84-
"Weaviate",
85-
"Email",
86-
"Stytch",
87-
];
88-
89-
if (languages.includes(tagName)) {
90-
return "bg-gradient-to-br from-emerald-600 to-emerald-800";
91-
}
92-
if (frameworks.includes(tagName)) {
93-
return "bg-gradient-to-br from-blue-600 to-blue-800";
94-
}
95-
if (integrations.includes(tagName)) {
96-
return "bg-gradient-to-br from-yellow-600 to-yellow-800";
97-
}
98-
return "bg-gradient-to-br from-gray-600 to-gray-800";
99-
};
100-
101-
return (
102-
<span
103-
className={`inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap rounded-md border-0 border-transparent px-2 py-1 font-semibold text-[0.725rem] text-white uppercase leading-4 tracking-wide shadow-md ${getTagColor(tag)}`}
104-
key={tag}
105-
>
106-
{tag}
107-
</span>
108-
);
109-
})}
43+
<Link
44+
className="group block h-full cursor-pointer"
45+
href={href}
46+
onClick={handleClick}
47+
target={blank ? "_blank" : undefined}
48+
>
49+
<Card className="h-full border-gray-200 bg-white/80 backdrop-blur-xs transition-all hover:border-[#ee175e]/30 dark:border-gray-700 dark:bg-[rgba(17,17,17,0.8)]">
50+
<CardContent className="p-0">
51+
{image && (
52+
<div className="relative aspect-video w-full overflow-hidden rounded-t-lg bg-gray-100 dark:bg-gray-800">
53+
<img
54+
alt={title}
55+
className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
56+
height={360}
57+
src={image}
58+
width={640}
59+
/>
11060
</div>
11161
)}
112-
</div>
113-
</CardContent>
114-
</Card>
115-
</Link>
62+
<div className="space-y-2 p-4 min-[1062px]:p-6">
63+
<div className="flex items-start justify-between gap-2">
64+
<h3 className="font-semibold text-gray-900 text-xl tracking-tight dark:text-white">
65+
{title}
66+
</h3>
67+
{date && (
68+
<span className="whitespace-nowrap font-medium text-gray-500 text-xs dark:text-gray-400">
69+
{date}
70+
</span>
71+
)}
72+
</div>
73+
<p className="text-gray-600 text-sm leading-relaxed dark:text-gray-300">
74+
{description}
75+
</p>
76+
{tags.length > 0 && (
77+
<div className="flex flex-wrap gap-2 pt-2">
78+
{tags.map((tag) => {
79+
const getTagColor = (tagName: string) => {
80+
const languages = [
81+
"JavaScript",
82+
"Python",
83+
"TypeScript",
84+
"Java",
85+
"Go",
86+
"Rust",
87+
];
88+
const frameworks = [
89+
"Langchain",
90+
"mastra",
91+
"CrewAI",
92+
"LangGraph",
93+
"OpenAI",
94+
"Anthropic",
95+
"Next.js",
96+
];
97+
const integrations = [
98+
"Slack",
99+
"GitHub",
100+
"Gmail",
101+
"Discord",
102+
"Notion",
103+
"Linear",
104+
"Jira",
105+
"Weaviate",
106+
"Email",
107+
"Stytch",
108+
];
109+
110+
if (languages.includes(tagName)) {
111+
return "bg-gradient-to-br from-emerald-600 to-emerald-800";
112+
}
113+
if (frameworks.includes(tagName)) {
114+
return "bg-gradient-to-br from-blue-600 to-blue-800";
115+
}
116+
if (integrations.includes(tagName)) {
117+
return "bg-gradient-to-br from-yellow-600 to-yellow-800";
118+
}
119+
return "bg-gradient-to-br from-gray-600 to-gray-800";
120+
};
121+
122+
return (
123+
<span
124+
className={`inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap rounded-md border-0 border-transparent px-2 py-1 font-semibold text-[0.725rem] text-white uppercase leading-4 tracking-wide shadow-md ${getTagColor(tag)}`}
125+
key={tag}
126+
>
127+
{tag}
128+
</span>
129+
);
130+
})}
131+
</div>
132+
)}
133+
</div>
134+
</CardContent>
135+
</Card>
136+
</Link>
137+
</motion.div>
116138
);
117139
}

app/en/get-started/about-arcade/page.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ Without auth, AI agents are severely limited in what they can do.
1919

2020
Arcade provides an authorization system that handles OAuth 2.0, API keys, and user tokens needed by AI agents to access external services through tools. This means your AI agents can now act on behalf of users securely and privately.
2121

22+
<picture>
23+
<source srcSet="/images/overview-dark.png" media="(prefers-color-scheme: dark)" />
24+
<img src="/images/overview-light.png" alt="Arcade architecture overview" />
25+
</picture>
26+
2227
With Arcade, developers can now create agents that can _act as the end users of their application_ to perform tasks like:
2328

2429
- Creating a new Zoom meeting

0 commit comments

Comments
 (0)