A sync tool's integrations, riding three lines through one giant word. One line runs behind the letters, and the glass turns red where a tile crosses one.
registry/demos/throughline-demo.tsx
import * as React from "react";
import { Throughline, type ThroughlineItem, type ThroughlineLine } from "@/components/ui/throughline";
/** A small app icon: a colored square with a white or ink glyph. */
function AppIcon({ bg, children }: { bg: string; children: React.ReactNode }) {
return (
<span className="flex size-full items-center justify-center rounded-[26%] shadow-[inset_0_1px_0_rgb(255_255_255/0.25)]" style={{ background: bg }}>
<svg viewBox="0 0 24 24" className="size-[62%]" fill="none" strokeLinecap="round" strokeLinejoin="round">
{children}
</svg>
</span>
);
}
const LINES: ThroughlineLine[] = [
{ from: [5, 84], to: [95, 10], bend: -0.12 },
{ from: [8, 8], to: [92, 90], bend: 0.14 },
{ from: [2, 46], to: [98, 38], bend: -0.24, behind: true },
];
const ITEMS: ThroughlineItem[] = [
{
label: "Tally · Billing",
line: 0,
icon: (
<AppIcon bg="#c6ff3d">
<path d="M12 3.5 13.9 10l6.6 2-6.6 2L12 20.5 10.1 14 3.5 12l6.6-2Z" fill="#0b0b0f" />
</AppIcon>
),
},
{
label: "Halfmoon · Support inbox",
line: 0,
icon: (
<AppIcon bg="#0b0b0f">
<path d="M16.5 4.6a8 8 0 1 0 2.9 10.9A6.5 6.5 0 0 1 16.5 4.6Z" fill="#fff" />
</AppIcon>
),
},
{
label: "Wavelet · Product analytics",
line: 0,
icon: (
<AppIcon bg="#2f3cff">
<path d="M3 12c2.2-5 4.3-5 6.5 0s4.3 5 6.5 0 3.3-4 5-2" stroke="#fff" strokeWidth="2.6" />
</AppIcon>
),
},
{
label: "Gridline · Spreadsheets",
line: 1,
icon: (
<AppIcon bg="#ffffff">
<rect x="4" y="4" width="7" height="7" rx="2" fill="#0b0b0f" />
<rect x="13" y="4" width="7" height="7" rx="3.5" fill="#ff3b1f" />
<rect x="4" y="13" width="7" height="7" rx="3.5" fill="#ff3b1f" />
<rect x="13" y="13" width="7" height="7" rx="2" fill="#0b0b0f" />
</AppIcon>
),
},
{
label: "Roundup · CRM",
line: 1,
icon: (
<AppIcon bg="linear-gradient(140deg,#ff5fa2,#ff7a1a)">
<circle cx="12" cy="12" r="6.5" stroke="#fff" strokeWidth="2.8" />
<circle cx="12" cy="12" r="2" fill="#fff" />
</AppIcon>
),
},
{
label: "Relay Mail · Email",
line: 1,
icon: (
<AppIcon bg="#0b0b0f">
<path d="M4 7.5 12 13l8-5.5M5 6h14a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Z" stroke="#c6ff3d" strokeWidth="2" />
</AppIcon>
),
},
{
label: "Stint · Time tracking",
line: 2,
icon: (
<AppIcon bg="#7b5cff">
<path d="M12 7v5l3 2" stroke="#fff" strokeWidth="2.4" />
<circle cx="12" cy="12" r="8" stroke="#fff" strokeWidth="2.4" />
</AppIcon>
),
},
{
label: "Bolt Forms · Surveys",
line: 2,
icon: (
<AppIcon bg="#ff3b1f">
<path d="M13.5 3 6 13.5h5.5L10.5 21 18 10.5h-5.5Z" fill="#fff" />
</AppIcon>
),
},
];
export function ThroughlineDemo() {
return (
<section className="w-full overflow-hidden rounded-[28px] bg-white py-14 text-center text-zinc-950 sm:py-16 dark:bg-[#08080c] dark:text-white">
<p className="text-[13px] font-medium tracking-[-0.01em] text-zinc-500 dark:text-zinc-400">Okto integrations</p>
<Throughline lines={LINES} items={ITEMS} className="text-[#ff3b1f] dark:text-[#ff5a3a]">
<h2 className="px-4 pb-[max(3.5rem,7.5cqi)] pt-[max(4.5rem,9.5cqi)] text-[clamp(3.25rem,16.5cqi,12.5rem)] font-black leading-[0.8] tracking-[-0.065em] text-[#ff3b1f] dark:text-[#ff5a3a]">
Everything
</h2>
</Throughline>
<p className="mx-auto max-w-[23rem] px-6 text-pretty text-[15px] leading-relaxed text-zinc-600 dark:text-zinc-400">
Okto keeps billing, support and analytics in sync both ways. Edit a record in one, and the
rest have it within a second.
</p>
<a
href="#"
className="mt-7 inline-flex h-11 items-center rounded-full bg-[#ff3b1f] px-6 text-sm font-semibold text-white shadow-[0_8px_20px_-8px_rgb(255_59_31/0.7)] transition-transform duration-150 ease-out active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#ff3b1f] dark:bg-[#ff5a3a]"
>
Browse 40 integrations
</a>
</section>
);
}
Live preview, examples and props: https://keyframeui.com/components/throughline#throughline-demo