Skip to content

Commit 127cf69

Browse files
Update website landing page (#402)
Signed-off-by: B-Step62 <[email protected]> Co-authored-by: Daniel Lok <[email protected]>
1 parent ba0b736 commit 127cf69

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1947
-332
lines changed

website/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@tailwindcss/postcss": "^4.1.4",
3535
"class-variance-authority": "^0.7.1",
3636
"clsx": "^2.1.1",
37+
"lucide-react": "^0.563.0",
3738
"motion": "^12.16.0",
3839
"postcss-import": "^16.1.0",
3940
"prism-react-renderer": "^2.3.0",
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { type ReactNode } from "react";
2+
import { motion } from "motion/react";
3+
import { Section } from "../Section/Section";
4+
import { LockOpen, Link, Zap, BarChart3, Users, Puzzle } from "lucide-react";
5+
6+
const benefits: {
7+
icon: ReactNode;
8+
title: string;
9+
description: string;
10+
color: string;
11+
iconBg: string;
12+
iconColor: string;
13+
}[] = [
14+
{
15+
icon: <LockOpen className="w-6 h-6" />,
16+
title: "Open Source",
17+
description:
18+
"100% open source under Apache 2.0 license. Forever free, no strings attached.",
19+
color: "from-blue-500/20 to-blue-600/20",
20+
iconBg: "bg-blue-500/20",
21+
iconColor: "text-blue-400",
22+
},
23+
{
24+
icon: <Link className="w-6 h-6" />,
25+
title: "No Vendor Lock-in",
26+
description:
27+
"Works with any cloud, framework, or tool you use. Switch vendors anytime.",
28+
color: "from-purple-500/20 to-purple-600/20",
29+
iconBg: "bg-purple-500/20",
30+
iconColor: "text-purple-400",
31+
},
32+
{
33+
icon: <Zap className="w-6 h-6" />,
34+
title: "Production Ready",
35+
description:
36+
"Battle-tested at scale by Fortune 500 companies and thousands of teams.",
37+
color: "from-amber-500/20 to-amber-600/20",
38+
iconBg: "bg-amber-500/20",
39+
iconColor: "text-amber-400",
40+
},
41+
{
42+
icon: <BarChart3 className="w-6 h-6" />,
43+
title: "Full Visibility",
44+
description:
45+
"Complete tracking and observability for all your AI applications and agents.",
46+
color: "from-cyan-500/20 to-cyan-600/20",
47+
iconBg: "bg-cyan-500/20",
48+
iconColor: "text-cyan-400",
49+
},
50+
{
51+
icon: <Users className="w-6 h-6" />,
52+
title: "Community",
53+
description:
54+
"20K+ GitHub stars, 900+ contributors. Join the fastest-growing MLOps community.",
55+
color: "from-green-500/20 to-green-600/20",
56+
iconBg: "bg-green-500/20",
57+
iconColor: "text-green-400",
58+
},
59+
{
60+
icon: <Puzzle className="w-6 h-6" />,
61+
title: "Integrations",
62+
description:
63+
"Works out of the box with LangChain, OpenAI, PyTorch, and 100+ AI frameworks.",
64+
color: "from-rose-500/20 to-rose-600/20",
65+
iconBg: "bg-rose-500/20",
66+
iconColor: "text-rose-400",
67+
},
68+
];
69+
70+
export function BenefitsSection() {
71+
return (
72+
<Section
73+
title="Why Teams Choose MLflow"
74+
body="Focus on building great AI, not managing infrastructure. MLflow handles the complexity so you can ship faster."
75+
align="center"
76+
>
77+
<motion.div
78+
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-px max-w-6xl mx-auto bg-white/10"
79+
initial={{ opacity: 0 }}
80+
whileInView={{ opacity: 1 }}
81+
viewport={{ once: true }}
82+
transition={{ duration: 0.6 }}
83+
>
84+
{benefits.map((benefit, index) => (
85+
<motion.div
86+
key={benefit.title}
87+
className="relative p-6 bg-[#0E1416]"
88+
initial={{ opacity: 0, y: 20 }}
89+
whileInView={{ opacity: 1, y: 0 }}
90+
viewport={{ once: true }}
91+
transition={{ duration: 0.5, delay: index * 0.1 }}
92+
>
93+
{/* Icon */}
94+
<div
95+
className={`w-12 h-12 ${benefit.iconBg} ${benefit.iconColor} flex items-center justify-center mb-4`}
96+
>
97+
{benefit.icon}
98+
</div>
99+
100+
{/* Title */}
101+
<h3 className="text-lg font-semibold text-white mb-2">
102+
{benefit.title}
103+
</h3>
104+
105+
{/* Description */}
106+
<p className="text-sm text-white/60 leading-relaxed">
107+
{benefit.description}
108+
</p>
109+
</motion.div>
110+
))}
111+
</motion.div>
112+
</Section>
113+
);
114+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { useState, useCallback } from "react";
2+
import { motion, AnimatePresence } from "motion/react";
3+
4+
export const CopyButton = ({
5+
code,
6+
className = "",
7+
}: {
8+
code: string;
9+
className?: string;
10+
}) => {
11+
const [copied, setCopied] = useState(false);
12+
13+
const handleCopy = useCallback(async () => {
14+
try {
15+
await navigator.clipboard.writeText(code);
16+
setCopied(true);
17+
setTimeout(() => setCopied(false), 2000);
18+
} catch {
19+
// Silently fail - clipboard may not be available
20+
}
21+
}, [code]);
22+
23+
return (
24+
<button
25+
onClick={handleCopy}
26+
className={`p-1.5 rounded bg-white/10 hover:bg-white/20 transition-colors ${className}`}
27+
aria-label={copied ? "Copied!" : "Copy code"}
28+
>
29+
<AnimatePresence mode="wait" initial={false}>
30+
{copied ? (
31+
<motion.svg
32+
key="check"
33+
initial={{ scale: 0 }}
34+
animate={{ scale: 1 }}
35+
exit={{ scale: 0 }}
36+
className="w-4 h-4 text-green-400"
37+
fill="none"
38+
viewBox="0 0 24 24"
39+
stroke="currentColor"
40+
>
41+
<path
42+
strokeLinecap="round"
43+
strokeLinejoin="round"
44+
strokeWidth={2}
45+
d="M5 13l4 4L19 7"
46+
/>
47+
</motion.svg>
48+
) : (
49+
<motion.svg
50+
key="copy"
51+
initial={{ scale: 0 }}
52+
animate={{ scale: 1 }}
53+
exit={{ scale: 0 }}
54+
className="w-4 h-4 text-white/50 hover:text-white/80"
55+
fill="none"
56+
viewBox="0 0 24 24"
57+
stroke="currentColor"
58+
>
59+
<path
60+
strokeLinecap="round"
61+
strokeLinejoin="round"
62+
strokeWidth={2}
63+
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
64+
/>
65+
</motion.svg>
66+
)}
67+
</AnimatePresence>
68+
</button>
69+
);
70+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { themes } from "prism-react-renderer";
2+
3+
export const customNightOwl = {
4+
...themes.nightOwl,
5+
styles: themes.nightOwl.styles.map((style) => {
6+
if (style.types.includes("string")) {
7+
return { ...style, style: { ...style.style, color: "#58a6ff" } };
8+
}
9+
return style;
10+
}),
11+
};
12+
13+
export const CODE_BG = "#0d1117";

website/src/components/Customers/Customers.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { LogosCarousel, Section } from "..";
22

33
export const Customers = () => {
44
return (
5-
<Section title="Trusted by thousands of organizations and research teams">
5+
<Section
6+
title="Trusted by thousands of organizations and research teams"
7+
headingLevel={3}
8+
>
69
<LogosCarousel />
710
</Section>
811
);

0 commit comments

Comments
 (0)