diff --git a/website-next/src/components/home/BuildYourWay.tsx b/website-next/src/components/home/BuildYourWay.tsx
new file mode 100644
index 00000000000..2e5aa0b2de2
--- /dev/null
+++ b/website-next/src/components/home/BuildYourWay.tsx
@@ -0,0 +1,40 @@
+import { CoffeeTray } from "@/src/icons/CoffeeTray";
+
+/** Brand spectrum (cyan -> violet -> coral), reused from the hero accent. */
+const CARD_GRADIENT =
+ "linear-gradient(100deg,#16b9e4 0%,#7c92c6 36%,#b681a9 64%,#f0786a 100%)";
+
+/**
+ * Full-bleed gradient feature card introducing the "stack your way" idea: the
+ * coffee-tray illustration on one side, the headline and supporting copy on the
+ * other. The card sits on the brand spectrum, so the text switches to the dark
+ * page ink for contrast. Stacks to a single column on small screens.
+ */
+export function BuildYourWay() {
+ return (
+
+
+
+
+
+
+ Build your way.
+
+ Ship faster.
+
+ Stay in control.
+
+
+ Pick what you need for your stack. Whether you’re building a
+ monolithic or federated GraphQL API, a message-intensive service,
+ or an application, we’ve got the right tools for you.
+
+
+
+
+
+ );
+}
diff --git a/website-next/src/components/home/FusionFlow.tsx b/website-next/src/components/home/FusionFlow.tsx
new file mode 100644
index 00000000000..e55e04e9bad
--- /dev/null
+++ b/website-next/src/components/home/FusionFlow.tsx
@@ -0,0 +1,199 @@
+interface Source {
+ readonly label: string;
+ readonly color: string;
+ /** Center x as a percentage of the band width. */
+ readonly x: number;
+ /** Top offset as a percentage of the band height (the stagger). */
+ readonly top: number;
+}
+
+const SOURCES: readonly Source[] = [
+ { label: "Catalog", color: "#f27765", x: 11, top: 6 },
+ { label: "Billing", color: "#eabd21", x: 30.5, top: 14 },
+ { label: "Ordering", color: "#66be77", x: 50, top: 22 },
+ { label: "Shipping", color: "#36c6e0", x: 69.5, top: 14 },
+ { label: "User", color: "#b07fd0", x: 89, top: 6 },
+];
+
+/**
+ * Long vertical drops that sweep inward to the convergence point (500,770) in
+ * the 1000x820 band, mirroring the design's tall "river" of subgraph streams.
+ */
+const CONVERGENCE: readonly { color: string; d: string }[] = [
+ { color: "#f27765", d: "M110 70 L110 300 C110 520 500 560 500 770" },
+ { color: "#eabd21", d: "M305 135 L305 360 C305 560 500 600 500 770" },
+ { color: "#66be77", d: "M500 195 L500 770" },
+ { color: "#36c6e0", d: "M695 135 L695 360 C695 560 500 600 500 770" },
+ { color: "#b07fd0", d: "M890 70 L890 300 C890 520 500 560 500 770" },
+];
+
+const CHIPS = ["gRPC", "GraphQL", "OpenAPI", "MCP"] as const;
+
+/** Fan-out from the chip box down to the four protocol columns below. */
+const FANOUT: readonly string[] = [
+ "M500 0 C500 90 125 70 125 180",
+ "M500 0 C500 110 375 70 375 180",
+ "M500 0 C500 110 625 70 625 180",
+ "M500 0 C500 90 875 70 875 180",
+];
+
+/** Brand spectrum used for the headline accent and the chip-box border. */
+const SPECTRUM =
+ "linear-gradient(100deg,#16b9e4 0%,#7c92c6 33%,#b681a9 63%,#f0786a 100%)";
+
+function GlowBeam({ className }: { readonly className?: string }) {
+ return (
+
+ );
+}
+
+/**
+ * The Fusion narrative, rendered as a tall top-to-bottom "river": independent
+ * subgraphs (Catalog, Billing, ...) flow down and converge into a single
+ * glowing composition node, which then speaks every protocol (gRPC, GraphQL,
+ * OpenAPI, MCP) and fans back out to every consumer.
+ *
+ * The line art is SVG (scaled by `viewBox`), while every label and heading is
+ * real HTML positioned by the same percentage columns the SVG uses, so the
+ * graphic stays aligned and legible at any width. The decorative fan-out lines
+ * drop away on small screens where the layout reflows.
+ */
+export function FusionFlow() {
+ return (
+
+ {/* Built apart / queried together */}
+
+
+ Built apart.
+
+ Queried together.
+
+
+ Unify all your APIs into a comprehensive company graph, streamlining
+ data accessibility and enhancing integration. Transform the way you
+ manage and interact with your data.
+
+
+
+ {/* Sources converge into the composition node */}
+
+ {/* Source labels (HTML), aligned to the SVG columns. */}
+ {SOURCES.map((s) => (
+
+
+
+ {s.label}
+
+
+ ))}
+
+ {/* Converging line art. */}
+
+
+ {/* "No matter the format" sits in the clear center band. */}
+
+
+ No Matter the Format. Fusion transforms.
+
+
+
+ {/* Composition glow + label at the convergence point. */}
+
+
+
+
+
+
+
+
+ Fusion Composition
+
+
+
+
+
+ {/* The API that speaks any language */}
+
+
+
+ The API that speaks any Language.
+
+
+ Unify all your APIs into a comprehensive company graph, streamlining
+ data accessibility and enhancing integration. Transform the way you
+ manage and interact with your data.
+
+
+
+
+ {/* Protocol chip box with the brand-spectrum border. */}
+
+
+ {CHIPS.map((chip) => (
+
+ {chip}
+
+ ))}
+
+
+
+ {/* Fan-out toward the protocol cards below. */}
+
+
+ );
+}
diff --git a/website-next/src/components/home/GrabADrink.tsx b/website-next/src/components/home/GrabADrink.tsx
new file mode 100644
index 00000000000..7c7ef82268c
--- /dev/null
+++ b/website-next/src/components/home/GrabADrink.tsx
@@ -0,0 +1,27 @@
+import { OutlineButton, SolidButton } from "@/src/design-system/Button";
+
+/**
+ * Closing call-to-action. The oversized display headline echoes the coffee
+ * theme that runs through the page; the buttons give the otherwise open canvas
+ * a clear next step.
+ */
+export function GrabADrink() {
+ return (
+
+
+ Want to grab a Drink?
+
+
+ Unify all your APIs into a comprehensive company graph, streamlining
+ data accessibility and enhancing integration. Transform the way you
+ manage and interact with your data.
+
+
+ Start for Free
+
+ Talk to Us
+
+
+
+ );
+}
diff --git a/website-next/src/components/home/LogoCloud.tsx b/website-next/src/components/home/LogoCloud.tsx
new file mode 100644
index 00000000000..57df7baf31e
--- /dev/null
+++ b/website-next/src/components/home/LogoCloud.tsx
@@ -0,0 +1,24 @@
+import { GalaxusLogo } from "@/src/icons/GalaxusLogo";
+import { MicrosoftLogo } from "@/src/icons/MicrosoftLogo";
+import { SwissLifeLogo } from "@/src/icons/SwissLifeLogo";
+
+/**
+ * Social-proof logo cloud beneath the hero: a small uppercase label over a row
+ * of customer wordmarks. The logos are inlined single-path SVGs that inherit
+ * the (dimmed) ink color via `currentColor`, so they read as a calm,
+ * monochrome band rather than competing brand colors.
+ */
+export function LogoCloud() {
+ return (
+
+
+ );
+}
+
+/**
+ * Nitro pricing: three plans framed as coffee brews (French Press, Pour-Over,
+ * Chemex). The middle plan is highlighted as the popular pick. Cards stack on
+ * small screens and sit side by side from large up.
+ */
+export function NitroPricing() {
+ return (
+
+
+ Brew it your Way
+
+
+ Nitro is the Control Plane and CLI that keeps you in control, whether
+ you’re deploying a new schema, rolling out a new client, or
+ gaining insights into your API environments.
+
+
+
+ {PLANS.map((plan) => (
+
+ ))}
+
+
+ );
+}
diff --git a/website-next/src/components/home/ProtocolCards.tsx b/website-next/src/components/home/ProtocolCards.tsx
new file mode 100644
index 00000000000..e23644ba006
--- /dev/null
+++ b/website-next/src/components/home/ProtocolCards.tsx
@@ -0,0 +1,93 @@
+import type { ComponentType } from "react";
+
+import { BrowserIcon } from "@/src/icons/BrowserIcon";
+import { HandshakeIcon } from "@/src/icons/HandshakeIcon";
+import { PhoneIcon } from "@/src/icons/PhoneIcon";
+import { RobotIcon } from "@/src/icons/RobotIcon";
+
+interface IconProps {
+ readonly className?: string;
+}
+
+interface Protocol {
+ readonly Icon: ComponentType;
+ readonly title: string;
+ readonly subtitle: string;
+ readonly tags: readonly string[];
+}
+
+const PROTOCOLS: readonly Protocol[] = [
+ {
+ Icon: BrowserIcon,
+ title: "Web",
+ subtitle: "Browser SPA",
+ tags: ["GraphQL"],
+ },
+ {
+ Icon: PhoneIcon,
+ title: "Mobile",
+ subtitle: "Android / iOS",
+ tags: ["GraphQL"],
+ },
+ {
+ Icon: RobotIcon,
+ title: "AI Agents",
+ subtitle: "MCP Tools",
+ tags: ["GraphQL", "gRPC"],
+ },
+ {
+ Icon: HandshakeIcon,
+ title: "Partners",
+ subtitle: "Federated API",
+ tags: ["OpenAPI", "gRPC"],
+ },
+];
+
+function ProtocolTag({ label }: { readonly label: string }) {
+ return (
+
+ {label}
+
+ );
+}
+
+/**
+ * "Choose your Protocol" grid: four consumer archetypes (Web, Mobile, AI
+ * Agents, Partners), each in an icon tile with the protocols it speaks. The
+ * Fusion flow above feeds a connector line into the top of each tile.
+ */
+export function ProtocolCards() {
+ return (
+
+
+ Choose your Protocol.
+
+ One Source of Truth.
+
+
+ Unify all your APIs into a comprehensive company graph, streamlining
+ data accessibility and enhancing integration. Transform the way you
+ manage and interact with your data.
+
+
+ );
+}
diff --git a/website-next/src/components/home/StackDiagrams.tsx b/website-next/src/components/home/StackDiagrams.tsx
new file mode 100644
index 00000000000..96fdf797b1d
--- /dev/null
+++ b/website-next/src/components/home/StackDiagrams.tsx
@@ -0,0 +1,127 @@
+import type { ReactNode } from "react";
+
+const EDGE = "rgba(236,232,245,0.55)";
+
+interface NodeBox {
+ readonly x: number;
+ readonly y: number;
+ readonly w: number;
+ readonly h: number;
+}
+
+function Node({ x, y, w, h }: NodeBox) {
+ return (
+
+ );
+}
+
+/**
+ * Hub-and-spoke graph used by both feature rows: one larger node in the center,
+ * three satellites above and three below, joined by S-curves that gather into
+ * the center node's top and bottom edges. Matches the source design's node art.
+ */
+function Hub({ className }: { readonly className?: string }) {
+ const cx = 180;
+ const cy = 185;
+ const topY = 58;
+ const botY = 312;
+ const cols = [80, 180, 280];
+
+ return (
+
+ );
+}
+
+interface StackRowProps {
+ readonly title: string;
+ readonly diagram: ReactNode;
+ /** When true, the diagram sits on the left and the copy on the right. */
+ readonly reverse?: boolean;
+}
+
+function StackRow({ title, diagram, reverse }: StackRowProps) {
+ return (
+
+
+
+ {title}
+
+
+ Pick what you need for your stack. Whether you’re building a
+ monolithic or federated GraphQL API, a message-intensive service, or
+ an application, we’ve got the right tools for you.
+
+
+
{diagram}
+
+ );
+}
+
+/**
+ * Two alternating feature rows that introduce the platform's shape: one graph
+ * for the "Platform" story and a mirrored one for the "Agentic Era".
+ */
+export function StackDiagrams() {
+ return (
+
+ } />
+ }
+ reverse
+ />
+
+ );
+}
diff --git a/website-next/src/icons/BrowserIcon.tsx b/website-next/src/icons/BrowserIcon.tsx
new file mode 100644
index 00000000000..3f82a0cb22e
--- /dev/null
+++ b/website-next/src/icons/BrowserIcon.tsx
@@ -0,0 +1,23 @@
+import type { CSSProperties } from "react";
+
+interface BrowserIconProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function BrowserIcon({ className, style }: BrowserIconProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/Chemex.tsx b/website-next/src/icons/Chemex.tsx
new file mode 100644
index 00000000000..4ef6583e972
--- /dev/null
+++ b/website-next/src/icons/Chemex.tsx
@@ -0,0 +1,46 @@
+import type { CSSProperties } from "react";
+
+interface ChemexProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+/**
+ * Chemex carafe with its collar, drawn as monoline art so it inherits
+ * `currentColor` and scales crisply. Decorative by default.
+ */
+export function Chemex({ className, style }: ChemexProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/CoffeeTray.tsx b/website-next/src/icons/CoffeeTray.tsx
new file mode 100644
index 00000000000..42dc414629a
--- /dev/null
+++ b/website-next/src/icons/CoffeeTray.tsx
@@ -0,0 +1,215 @@
+import type { CSSProperties } from "react";
+
+interface CoffeeTrayProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function CoffeeTray({ className, style }: CoffeeTrayProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/FrenchPress.tsx b/website-next/src/icons/FrenchPress.tsx
new file mode 100644
index 00000000000..eaa02f2cb5b
--- /dev/null
+++ b/website-next/src/icons/FrenchPress.tsx
@@ -0,0 +1,48 @@
+import type { CSSProperties } from "react";
+
+interface FrenchPressProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+/**
+ * French press brewer, drawn as monoline art so it inherits `currentColor` and
+ * scales crisply. Decorative by default.
+ */
+export function FrenchPress({ className, style }: FrenchPressProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/GalaxusLogo.tsx b/website-next/src/icons/GalaxusLogo.tsx
new file mode 100644
index 00000000000..e3f665bc31b
--- /dev/null
+++ b/website-next/src/icons/GalaxusLogo.tsx
@@ -0,0 +1,24 @@
+import type { CSSProperties } from "react";
+
+interface GalaxusLogoProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function GalaxusLogo({ className, style }: GalaxusLogoProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/HandshakeIcon.tsx b/website-next/src/icons/HandshakeIcon.tsx
new file mode 100644
index 00000000000..4c5cd458b45
--- /dev/null
+++ b/website-next/src/icons/HandshakeIcon.tsx
@@ -0,0 +1,23 @@
+import type { CSSProperties } from "react";
+
+interface HandshakeIconProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function HandshakeIcon({ className, style }: HandshakeIconProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/MicrosoftLogo.tsx b/website-next/src/icons/MicrosoftLogo.tsx
new file mode 100644
index 00000000000..edb3dc60a44
--- /dev/null
+++ b/website-next/src/icons/MicrosoftLogo.tsx
@@ -0,0 +1,24 @@
+import type { CSSProperties } from "react";
+
+interface MicrosoftLogoProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function MicrosoftLogo({ className, style }: MicrosoftLogoProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/PhoneIcon.tsx b/website-next/src/icons/PhoneIcon.tsx
new file mode 100644
index 00000000000..2e071ff8007
--- /dev/null
+++ b/website-next/src/icons/PhoneIcon.tsx
@@ -0,0 +1,23 @@
+import type { CSSProperties } from "react";
+
+interface PhoneIconProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function PhoneIcon({ className, style }: PhoneIconProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/PourOver.tsx b/website-next/src/icons/PourOver.tsx
new file mode 100644
index 00000000000..1c1648eb87d
--- /dev/null
+++ b/website-next/src/icons/PourOver.tsx
@@ -0,0 +1,48 @@
+import type { CSSProperties } from "react";
+
+interface PourOverProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+/**
+ * Pour-over dripper and mug, drawn as monoline art so it inherits
+ * `currentColor` and scales crisply. Decorative by default.
+ */
+export function PourOver({ className, style }: PourOverProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/RobotIcon.tsx b/website-next/src/icons/RobotIcon.tsx
new file mode 100644
index 00000000000..2c8a4e47d51
--- /dev/null
+++ b/website-next/src/icons/RobotIcon.tsx
@@ -0,0 +1,23 @@
+import type { CSSProperties } from "react";
+
+interface RobotIconProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function RobotIcon({ className, style }: RobotIconProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/SwissLifeLogo.tsx b/website-next/src/icons/SwissLifeLogo.tsx
new file mode 100644
index 00000000000..267bde30250
--- /dev/null
+++ b/website-next/src/icons/SwissLifeLogo.tsx
@@ -0,0 +1,27 @@
+import type { CSSProperties } from "react";
+
+interface SwissLifeLogoProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+export function SwissLifeLogo({ className, style }: SwissLifeLogoProps) {
+ return (
+
+ );
+}
From ea674065a3adbc695642fd7d2911a5713d4c2281 Mon Sep 17 00:00:00 2001
From: tobias-tengler <45513122+tobias-tengler@users.noreply.github.com>
Date: Wed, 17 Jun 2026 16:21:13 +0200
Subject: [PATCH 02/10] some changes
---
.../src/components/home/NitroPricing.tsx | 26 ++----
.../src/components/home/StackDiagrams.tsx | 89 ++++++++++++++-----
website-next/src/icons/Chemex.tsx | 46 ----------
website-next/src/icons/DripBrewer.tsx | 33 +++++++
website-next/src/icons/FrenchPress.tsx | 33 +++----
website-next/src/icons/GalaxusLogo.tsx | 10 +--
website-next/src/icons/HandshakeIcon.tsx | 9 +-
website-next/src/icons/MicrosoftLogo.tsx | 14 +--
website-next/src/icons/PourOver.tsx | 35 +++-----
website-next/src/icons/SwissLifeLogo.tsx | 19 ++--
10 files changed, 147 insertions(+), 167 deletions(-)
delete mode 100644 website-next/src/icons/Chemex.tsx
create mode 100644 website-next/src/icons/DripBrewer.tsx
diff --git a/website-next/src/components/home/NitroPricing.tsx b/website-next/src/components/home/NitroPricing.tsx
index f11ea8c2238..1288041e5fd 100644
--- a/website-next/src/components/home/NitroPricing.tsx
+++ b/website-next/src/components/home/NitroPricing.tsx
@@ -1,12 +1,11 @@
import type { ComponentType } from "react";
import { CheckIcon } from "@/src/components/CheckIcon";
-import { Chemex } from "@/src/icons/Chemex";
+import { DripBrewer } from "@/src/icons/DripBrewer";
import { FrenchPress } from "@/src/icons/FrenchPress";
import { PourOver } from "@/src/icons/PourOver";
interface Plan {
- readonly brew: string;
readonly Icon: ComponentType<{ readonly className?: string }>;
readonly name: string;
readonly tagline: string;
@@ -20,7 +19,6 @@ interface Plan {
const PLANS: readonly Plan[] = [
{
- brew: "French Press",
Icon: FrenchPress,
name: "Shared Instance",
tagline: "Shared resources, fully managed",
@@ -37,8 +35,7 @@ const PLANS: readonly Plan[] = [
ctaHref: "/get-started",
},
{
- brew: "Pour-Over",
- Icon: PourOver,
+ Icon: DripBrewer,
name: "Dedicated Instance",
tagline: "Dedicated resources, fully managed",
price: "$400",
@@ -55,8 +52,7 @@ const PLANS: readonly Plan[] = [
popular: true,
},
{
- brew: "Chemex",
- Icon: Chemex,
+ Icon: PourOver,
name: "Self-Hosted",
tagline: "Self managed",
price: "Custom",
@@ -98,15 +94,7 @@ function PlanCard({ plan }: { readonly plan: Plan }) {
)}
-
-
-
-
- {plan.brew}
-
+
@@ -153,9 +141,9 @@ function PlanCard({ plan }: { readonly plan: Plan }) {
}
/**
- * Nitro pricing: three plans framed as coffee brews (French Press, Pour-Over,
- * Chemex). The middle plan is highlighted as the popular pick. Cards stack on
- * small screens and sit side by side from large up.
+ * Nitro pricing: three plans framed as coffee brews (French Press, Drip
+ * Brewer, Pour-Over). The middle plan is highlighted as the popular pick. Cards
+ * stack on small screens and sit side by side from large up.
*/
export function NitroPricing() {
return (
diff --git a/website-next/src/components/home/StackDiagrams.tsx b/website-next/src/components/home/StackDiagrams.tsx
index 96fdf797b1d..34d3367ed3e 100644
--- a/website-next/src/components/home/StackDiagrams.tsx
+++ b/website-next/src/components/home/StackDiagrams.tsx
@@ -23,21 +23,69 @@ function Node({ x, y, w, h }: NodeBox) {
);
}
+interface Leg {
+ /** Satellite (node) center. */
+ readonly x: number;
+ readonly y: number;
+ /** Where the spoke attaches to the hub perimeter. */
+ readonly ax: number;
+ readonly ay: number;
+}
+
/**
- * Hub-and-spoke graph used by both feature rows: one larger node in the center,
- * three satellites above and three below, joined by S-curves that gather into
- * the center node's top and bottom edges. Matches the source design's node art.
+ * Hub-and-spoke graph used by both feature rows: one larger node in the center
+ * with three satellites above and three below. The six spokes radiate from
+ * points spread around the hub's perimeter (left side, top, right side, ...)
+ * like an asterisk, each leaving the hub along its own diagonal and arriving at
+ * its satellite as a short vertical stub.
*/
function Hub({ className }: { readonly className?: string }) {
- const cx = 180;
- const cy = 185;
- const topY = 58;
- const botY = 312;
- const cols = [80, 180, 280];
+ const cx = 210;
+ const cy = 190;
+ const hubW = 56;
+ const hubH = 42;
+ const satW = 34;
+ const satH = 26;
+ const topY = 40;
+ const botY = 340;
+ const cols = [56, 210, 364];
+
+ const hubTop = cy - hubH / 2;
+ const hubBot = cy + hubH / 2;
+ const hubLeft = cx - hubW / 2;
+ const hubRight = cx + hubW / 2;
+ // Upper/lower attach points on the hub's side edges for the diagonal legs.
+ const sideUp = cy - hubH / 4;
+ const sideDown = cy + hubH / 4;
+
+ const topRow = topY + satH / 2;
+ const botRow = botY - satH / 2;
+
+ // Attach the centre legs to the top/bottom edge and the diagonal legs to the
+ // side edges, so the spokes splay around the box instead of pinching to a
+ // single point.
+ const legs: readonly Leg[] = [
+ { x: cols[0], y: topRow, ax: hubLeft, ay: sideUp },
+ { x: cols[1], y: topRow, ax: cx, ay: hubTop },
+ { x: cols[2], y: topRow, ax: hubRight, ay: sideUp },
+ { x: cols[0], y: botRow, ax: hubLeft, ay: sideDown },
+ { x: cols[1], y: botRow, ax: cx, ay: hubBot },
+ { x: cols[2], y: botRow, ax: hubRight, ay: sideDown },
+ ];
+
+ // Cubic from the hub anchor to the satellite: the first control point pushes
+ // out along the anchor->node diagonal (radial departure); the second sits
+ // directly above/below the node so the line lands as a short vertical stub.
+ const spoke = ({ x, y, ax, ay }: Leg) => {
+ const stub = y < cy ? 40 : -40;
+ const c1x = ax + (x - ax) * 0.55;
+ const c1y = ay + (y - ay) * 0.2;
+ return `M ${ax} ${ay} C ${c1x} ${c1y} ${x} ${y + stub} ${x} ${y}`;
+ };
return (
);
@@ -104,7 +143,9 @@ function StackRow({ title, diagram, reverse }: StackRowProps) {
an application, we’ve got the right tools for you.
-
{diagram}
+
+
{diagram}
+
);
}
diff --git a/website-next/src/icons/Chemex.tsx b/website-next/src/icons/Chemex.tsx
deleted file mode 100644
index 4ef6583e972..00000000000
--- a/website-next/src/icons/Chemex.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import type { CSSProperties } from "react";
-
-interface ChemexProps {
- readonly className?: string;
- readonly style?: CSSProperties;
-}
-
-/**
- * Chemex carafe with its collar, drawn as monoline art so it inherits
- * `currentColor` and scales crisply. Decorative by default.
- */
-export function Chemex({ className, style }: ChemexProps) {
- return (
-
- );
-}
diff --git a/website-next/src/icons/DripBrewer.tsx b/website-next/src/icons/DripBrewer.tsx
new file mode 100644
index 00000000000..5dc46fabcd1
--- /dev/null
+++ b/website-next/src/icons/DripBrewer.tsx
@@ -0,0 +1,33 @@
+import type { CSSProperties } from "react";
+
+interface DripBrewerProps {
+ readonly className?: string;
+ readonly style?: CSSProperties;
+}
+
+/**
+ * Drip coffee brewer, drawn as monoline art so it inherits `currentColor` and
+ * scales crisply. Decorative by default.
+ */
+export function DripBrewer({ className, style }: DripBrewerProps) {
+ return (
+
+ );
+}
diff --git a/website-next/src/icons/FrenchPress.tsx b/website-next/src/icons/FrenchPress.tsx
index eaa02f2cb5b..9fd3d257043 100644
--- a/website-next/src/icons/FrenchPress.tsx
+++ b/website-next/src/icons/FrenchPress.tsx
@@ -12,37 +12,24 @@ interface FrenchPressProps {
export function FrenchPress({ className, style }: FrenchPressProps) {
return (
);
}
diff --git a/website-next/src/icons/GalaxusLogo.tsx b/website-next/src/icons/GalaxusLogo.tsx
index e3f665bc31b..caf040beeab 100644
--- a/website-next/src/icons/GalaxusLogo.tsx
+++ b/website-next/src/icons/GalaxusLogo.tsx
@@ -8,17 +8,13 @@ interface GalaxusLogoProps {
export function GalaxusLogo({ className, style }: GalaxusLogoProps) {
return (
);
}
diff --git a/website-next/src/icons/HandshakeIcon.tsx b/website-next/src/icons/HandshakeIcon.tsx
index 4c5cd458b45..c0a35a997f1 100644
--- a/website-next/src/icons/HandshakeIcon.tsx
+++ b/website-next/src/icons/HandshakeIcon.tsx
@@ -8,16 +8,13 @@ interface HandshakeIconProps {
export function HandshakeIcon({ className, style }: HandshakeIconProps) {
return (
);
}
diff --git a/website-next/src/icons/MicrosoftLogo.tsx b/website-next/src/icons/MicrosoftLogo.tsx
index edb3dc60a44..1f6f3f81922 100644
--- a/website-next/src/icons/MicrosoftLogo.tsx
+++ b/website-next/src/icons/MicrosoftLogo.tsx
@@ -8,17 +8,17 @@ interface MicrosoftLogoProps {
export function MicrosoftLogo({ className, style }: MicrosoftLogoProps) {
return (
);
}
diff --git a/website-next/src/icons/PourOver.tsx b/website-next/src/icons/PourOver.tsx
index 1c1648eb87d..2e4dde5984e 100644
--- a/website-next/src/icons/PourOver.tsx
+++ b/website-next/src/icons/PourOver.tsx
@@ -6,43 +6,28 @@ interface PourOverProps {
}
/**
- * Pour-over dripper and mug, drawn as monoline art so it inherits
- * `currentColor` and scales crisply. Decorative by default.
+ * Pour-over brewer, drawn as monoline art so it inherits `currentColor` and
+ * scales crisply. Decorative by default.
*/
export function PourOver({ className, style }: PourOverProps) {
return (
);
}
diff --git a/website-next/src/icons/SwissLifeLogo.tsx b/website-next/src/icons/SwissLifeLogo.tsx
index 267bde30250..a2060d7799e 100644
--- a/website-next/src/icons/SwissLifeLogo.tsx
+++ b/website-next/src/icons/SwissLifeLogo.tsx
@@ -8,20 +8,19 @@ interface SwissLifeLogoProps {
export function SwissLifeLogo({ className, style }: SwissLifeLogoProps) {
return (
);
}
From b8ae2ea1924eda449113122af30b2277feb1b73e Mon Sep 17 00:00:00 2001
From: tobias-tengler <45513122+tobias-tengler@users.noreply.github.com>
Date: Wed, 17 Jun 2026 17:45:13 +0200
Subject: [PATCH 03/10] fix lines
---
.../src/components/home/FusionFlow.tsx | 50 -------
.../src/components/home/ProtocolCards.tsx | 135 ++++++++++++++----
2 files changed, 106 insertions(+), 79 deletions(-)
diff --git a/website-next/src/components/home/FusionFlow.tsx b/website-next/src/components/home/FusionFlow.tsx
index e55e04e9bad..aefce683003 100644
--- a/website-next/src/components/home/FusionFlow.tsx
+++ b/website-next/src/components/home/FusionFlow.tsx
@@ -27,20 +27,6 @@ const CONVERGENCE: readonly { color: string; d: string }[] = [
{ color: "#b07fd0", d: "M890 70 L890 300 C890 520 500 560 500 770" },
];
-const CHIPS = ["gRPC", "GraphQL", "OpenAPI", "MCP"] as const;
-
-/** Fan-out from the chip box down to the four protocol columns below. */
-const FANOUT: readonly string[] = [
- "M500 0 C500 90 125 70 125 180",
- "M500 0 C500 110 375 70 375 180",
- "M500 0 C500 110 625 70 625 180",
- "M500 0 C500 90 875 70 875 180",
-];
-
-/** Brand spectrum used for the headline accent and the chip-box border. */
-const SPECTRUM =
- "linear-gradient(100deg,#16b9e4 0%,#7c92c6 33%,#b681a9 63%,#f0786a 100%)";
-
function GlowBeam({ className }: { readonly className?: string }) {
return (
-
- {/* Protocol chip box with the brand-spectrum border. */}
-
-
- {CHIPS.map((chip) => (
-
- {chip}
-
- ))}
-
-
-
- {/* Fan-out toward the protocol cards below. */}
-
);
}
diff --git a/website-next/src/components/home/ProtocolCards.tsx b/website-next/src/components/home/ProtocolCards.tsx
index e23644ba006..638201dce91 100644
--- a/website-next/src/components/home/ProtocolCards.tsx
+++ b/website-next/src/components/home/ProtocolCards.tsx
@@ -16,6 +16,12 @@ interface Protocol {
readonly tags: readonly string[];
}
+const CHIPS = ["gRPC", "GraphQL", "OpenAPI", "MCP"] as const;
+
+/** Brand spectrum used for the chip-box border. */
+const SPECTRUM =
+ "linear-gradient(100deg,#16b9e4 0%,#7c92c6 33%,#b681a9 63%,#f0786a 100%)";
+
const PROTOCOLS: readonly Protocol[] = [
{
Icon: BrowserIcon,
@@ -43,6 +49,36 @@ const PROTOCOLS: readonly Protocol[] = [
},
];
+// Connector geometry in the 1000-wide layer. The chip box is narrower than the
+// card grid, so the chip anchors sit inboard of the card columns; every line
+// therefore runs on a diagonal and the bundle weaves on its way down.
+const CHIP_X = [250, 417, 583, 750];
+const CARD_X = [125, 375, 625, 875];
+// The connector layer is stretched over the whole region (chip box bottom to
+// the card row). LINK_Y is the y, in the 0..1000 viewBox, where the spokes meet
+// the icon tiles; tuned against the icon row on desktop.
+const LINK_Y = 720;
+
+/**
+ * One spoke per (card, protocol) pairing, derived from each card's tags. The
+ * line drops vertically out of the chip, crosses through the middle, and rises
+ * vertically into the destination icon tile.
+ */
+const LINKS = PROTOCOLS.flatMap((card, to) =>
+ card.tags
+ .map((tag) => CHIPS.indexOf(tag as (typeof CHIPS)[number]))
+ .filter((from) => from >= 0)
+ .map((from) => {
+ const x0 = CHIP_X[from];
+ const x1 = CARD_X[to];
+ const mid = LINK_Y / 2;
+ return {
+ key: `${from}-${to}`,
+ d: `M ${x0} 0 C ${x0} ${mid} ${x1} ${mid} ${x1} ${LINK_Y}`,
+ };
+ }),
+);
+
function ProtocolTag({ label }: { readonly label: string }) {
return (
@@ -52,41 +88,82 @@ function ProtocolTag({ label }: { readonly label: string }) {
}
/**
- * "Choose your Protocol" grid: four consumer archetypes (Web, Mobile, AI
- * Agents, Partners), each in an icon tile with the protocols it speaks. The
- * Fusion flow above feeds a connector line into the top of each tile.
+ * "Choose your Protocol" section: the protocol chip box feeds connector lines
+ * down through the headline and into four consumer archetypes (Web, Mobile, AI
+ * Agents, Partners), each tile showing the protocols it speaks.
*/
export function ProtocolCards() {
return (
-
- Choose your Protocol.
-
- One Source of Truth.
-
-
- Unify all your APIs into a comprehensive company graph, streamlining
- data accessibility and enhancing integration. Transform the way you
- manage and interact with your data.
-
-
+ {/* Protocol chip box with the brand-spectrum border. */}
+
+
+ {CHIPS.map((chip) => (
+
+ {chip}
-
- {title}
-
-
{subtitle}
-
- {tags.map((tag) => (
-
- ))}
+ ))}
+
+
+
+ {/* Connector layer + headline + consumer tiles share one positioning
+ context so the spokes can run from the chip box into each tile. */}
+
+
+
+
+
+ Choose your Protocol.
+
+ One Source of Truth.
+
+
+ Unify all your APIs into a comprehensive company graph, streamlining
+ data accessibility and enhancing integration. Transform the way you
+ manage and interact with your data.
+
diff --git a/website-next/src/components/home/FusionFlow.tsx b/website-next/src/components/home/FusionFlow.tsx
index aefce683003..79738808c53 100644
--- a/website-next/src/components/home/FusionFlow.tsx
+++ b/website-next/src/components/home/FusionFlow.tsx
@@ -1,31 +1,62 @@
interface Source {
readonly label: string;
readonly color: string;
- /** Center x as a percentage of the band width. */
+ /** Source-square anchor, in the design's 1360x8000 coordinate space. */
readonly x: number;
- /** Top offset as a percentage of the band height (the stagger). */
- readonly top: number;
+ readonly y: number;
+ /** Exact stream path lifted from the design SVG (design coordinates). */
+ readonly d: string;
}
+// Streams lifted verbatim from the design SVG: each path is the rounded source
+// square plus the curving ribbon that flows down to the convergence point
+// (680, 4461.9). Staggered exactly as designed (Catalog highest, then Shipping,
+// Billing, Ordering, User lowest).
const SOURCES: readonly Source[] = [
- { label: "Catalog", color: "#f27765", x: 11, top: 6 },
- { label: "Billing", color: "#eabd21", x: 30.5, top: 14 },
- { label: "Ordering", color: "#66be77", x: 50, top: 22 },
- { label: "Shipping", color: "#36c6e0", x: 69.5, top: 14 },
- { label: "User", color: "#b07fd0", x: 89, top: 6 },
+ {
+ label: "Catalog",
+ color: "#f27765",
+ x: 248.3,
+ y: 3342.2,
+ d: "M248.32,3342.2c2.21,0,4,1.79,4,4v11.61c0,2.21-1.79,4-4,4h-3.92v364.52c0,48.51,7.63,96.04,22.68,141.27,13.52,40.62,34.17,81.3,61.39,120.91,30.42,44.26,68.46,86.2,113.05,124.63,66.77,57.55,111.02,100.15,143.47,138.11,28.75,33.63,49.27,64.91,68.6,104.58,16.07,32.97,25.52,69.86,27.38,106.8h-2.78c-1.85-36.52-11.21-72.99-27.09-105.58-19.23-39.45-39.63-70.54-68.22-103.99-32.36-37.85-76.52-80.36-143.18-137.81-44.77-38.59-82.97-80.7-113.52-125.16-27.37-39.82-48.14-80.73-61.74-121.6-15.15-45.51-22.82-93.33-22.82-142.15v-364.52h-3.92c-2.21,0-4-1.79-4-4v-11.61c0-2.21,1.79-4,4-4h10.61Z",
+ },
+ {
+ label: "Billing",
+ color: "#eabd21",
+ x: 446.0,
+ y: 3456.6,
+ d: "M445.98,3456.63c2.21,0,4,1.79,4,4v11.61c0,2.21-1.79,4-4,4h-3.84s-.08.03-.08.08v249.33c0,53.74,2.96,102.73,8.81,145.6,5.12,37.57,11.42,64.55,21.73,93.11,11.22,31.07,27.7,64.79,53.43,109.34,13.21,22.86,26.95,42.96,40.24,62.4,27.23,39.83,55.39,81.01,82.47,149.96,18.83,47.95,30.09,131.33,32.22,176.48,0,.04-.03.08-.08.08h-2.62s-.08-.03-.08-.07c-2.12-44.85-13.32-127.81-32.03-175.47-26.96-68.66-55.03-109.71-82.17-149.41-13.32-19.48-27.09-39.63-40.35-62.58-25.82-44.7-42.37-78.55-53.64-109.78-10.38-28.76-16.72-55.9-21.87-93.68-5.86-43-8.84-92.11-8.84-145.98v-249.33s-.03-.08-.08-.08h-3.84c-2.21,0-4-1.79-4-4v-11.61c0-2.21,1.79-4,4-4h10.61Z",
+ },
+ {
+ label: "Ordering",
+ color: "#66be77",
+ x: 591.6,
+ y: 3612.7,
+ d: "M591.62,3612.67c2.21,0,4,1.79,4,4v11.61c0,2.21-1.79,4-4,4h-3.92v93.36c0,67.59,2.81,197.14,21.65,305.45,8.51,48.94,24.17,103.9,37.99,152.4,13.75,48.25,25.62,89.93,29.19,119.24,5.58,45.91,4.97,103.54,4.53,145.62v.29c-.05,4.82-.1,9.5-.14,13.96h-2.78c.04-4.56.09-9.35.14-14.28.44-42,1.05-99.52-4.51-145.25-3.54-29.1-15.95-72.68-29.1-118.83-13.83-48.55-29.51-103.58-38.05-152.67-8.8-50.58-15.04-110.85-18.54-179.12-2.09-40.78-3.15-83.45-3.15-126.81v-93.36h-3.92c-2.21,0-4-1.79-4-4v-11.61c0-2.21,1.79-4,4-4h10.61Z",
+ },
+ {
+ label: "Shipping",
+ color: "#00bce5",
+ x: 893.3,
+ y: 3428.6,
+ d: "M893.31,3428.64c2.21,0,4,1.79,4,4v11.61c0,2.21-1.79,4-4,4h-3.92v277.39c0,49.37-4.49,95.84-13.72,142.06-21.14,105.85-46.06,198.34-98.98,305.7l-.02.05c-21.71,39.79-44.59,82.66-64.86,126.46-9.73,21.02-16.67,43.06-20.63,65.52-5.83,33.04-9.01,64.85-9.7,97.19h-2.78c.69-32.5,3.88-64.47,9.74-97.67,4.01-22.69,11.02-44.97,20.85-66.2,20.3-43.86,43.19-86.75,64.91-126.57v-.03s.03-.03.03-.03c52.77-107.06,77.63-199.34,98.72-304.96,9.19-46.04,13.66-92.33,13.66-141.52v-277.39h-3.92c-2.21,0-4-1.79-4-4v-11.61c0-2.21,1.79-4,4-4h10.61Z",
+ },
+ {
+ label: "User",
+ color: "#a983ba",
+ x: 1122.2,
+ y: 3654.3,
+ d: "M1122.17,3654.28c2.21,0,4,1.79,4,4v11.61c0,2.21-1.79,4-4,4h-3.92v52.43c0,48.81-7.68,96.64-22.82,142.15-13.6,40.87-34.37,81.78-61.74,121.6-30.56,44.46-68.75,86.57-113.52,125.16-66.66,57.46-110.82,99.96-143.18,137.81-28.59,33.44-48.99,64.54-68.22,103.99-15.88,32.59-25.24,69.06-27.09,105.58h-2.78c1.85-36.94,11.31-73.83,27.38-106.8,19.34-39.67,39.85-70.94,68.6-104.58,32.45-37.96,76.7-80.56,143.47-138.11,44.59-38.43,82.63-80.37,113.05-124.63,27.22-39.6,47.88-80.28,61.39-120.91,15.05-45.23,22.68-92.75,22.68-141.27v-52.43h-3.92c-2.21,0-4-1.79-4-4v-11.61c0-2.21,1.79-4,4-4h10.61Z",
+ },
];
-/**
- * Long vertical drops that sweep inward to the convergence point (500,770) in
- * the 1000x820 band, mirroring the design's tall "river" of subgraph streams.
- */
-const CONVERGENCE: readonly { color: string; d: string }[] = [
- { color: "#f27765", d: "M110 70 L110 300 C110 520 500 560 500 770" },
- { color: "#eabd21", d: "M305 135 L305 360 C305 560 500 600 500 770" },
- { color: "#66be77", d: "M500 195 L500 770" },
- { color: "#36c6e0", d: "M695 135 L695 360 C695 560 500 600 500 770" },
- { color: "#b07fd0", d: "M890 70 L890 300 C890 520 500 560 500 770" },
-];
+// Design coordinate window cropped to the streams band, and the convergence
+// point (the glowing composition node) within it.
+const VIEW = { x: 0, y: 3320, w: 1360, h: 1340 };
+const GLOW = { x: 680, y: 4461.9 };
+
+const pctX = (x: number) => `${((x - VIEW.x) / VIEW.w) * 100}%`;
+const pctY = (y: number) => `${((y - VIEW.y) / VIEW.h) * 100}%`;
function GlowBeam({ className }: { readonly className?: string }) {
return (
@@ -42,102 +73,150 @@ function GlowBeam({ className }: { readonly className?: string }) {
* glowing composition node, which then speaks every protocol (gRPC, GraphQL,
* OpenAPI, MCP) and fans back out to every consumer.
*
- * The line art is SVG (scaled by `viewBox`), while every label and heading is
- * real HTML positioned by the same percentage columns the SVG uses, so the
- * graphic stays aligned and legible at any width. The decorative fan-out lines
- * drop away on small screens where the layout reflows.
+ * The stream/glow artwork is lifted verbatim from the design SVG (its 1360x8000
+ * coordinate space, cropped via `VIEW`), while the headings and source labels
+ * are real HTML positioned by the same coordinates so they stay crisp.
*/
export function FusionFlow() {
return (
{/* Built apart / queried together */}
-
+
Built apart.
Queried together.
-
+
Unify all your APIs into a comprehensive company graph, streamlining
data accessibility and enhancing integration. Transform the way you
manage and interact with your data.
- {/* Sources converge into the composition node */}
-
- {/* Source labels (HTML), aligned to the SVG columns. */}
- {SOURCES.map((s) => (
-
-
-
- {s.label}
-
-
- ))}
-
- {/* Converging line art. */}
+ {/* Sources converge into the composition node. */}
+
+
+ {/* Soft dark scrim that ONLY dims the streams behind the copy. It sits
+ above the lines but below the squares, labels and headline, so those
+ stay at full strength. Broad and feathered, as in the design. */}
+
+
+ {/* Larger square markers, redrawn on top of the scrim so they stay
+ bright (and bigger than the design's hairline path squares). */}
+
- {/* "No matter the format" sits in the clear center band. */}
-
-
+ {/* Source labels (HTML for crisp text), on top of the scrim. Sized to
+ sit flush with the top and bottom of the square. */}
+ {SOURCES.map((s) => (
+
+ {s.label}
+
+ ))}
+
+ {/* "No matter the format" sits over the stream region. It breaks out of
+ the section's max width so the line stays single, as in the design. */}
+
+
No Matter the Format. Fusion transforms.
+
+ Unify all your APIs into a comprehensive company graph, streamlining
+ data accessibility and enhancing integration. Transform the way you
+ manage and interact with your data.
+
- {/* Composition glow + label at the convergence point. */}
-
-
-
-
-
-
-
-
+ {/* "Fusion Composition" caption with a dashed line running to the glow. */}
+
+
Fusion Composition
-
+
{/* The API that speaks any language */}
-
+
The API that speaks any Language.
-
+
Unify all your APIs into a comprehensive company graph, streamlining
data accessibility and enhancing integration. Transform the way you
manage and interact with your data.
diff --git a/website-next/src/components/home/GrabADrink.tsx b/website-next/src/components/home/GrabADrink.tsx
index 7c7ef82268c..125f9f5d496 100644
--- a/website-next/src/components/home/GrabADrink.tsx
+++ b/website-next/src/components/home/GrabADrink.tsx
@@ -7,11 +7,11 @@ import { OutlineButton, SolidButton } from "@/src/design-system/Button";
*/
export function GrabADrink() {
return (
-
-
+
+
Want to grab a Drink?
-
+
Unify all your APIs into a comprehensive company graph, streamlining
data accessibility and enhancing integration. Transform the way you
manage and interact with your data.
diff --git a/website-next/src/components/home/LogoCloud.tsx b/website-next/src/components/home/LogoCloud.tsx
index 57df7baf31e..dc007d8ee86 100644
--- a/website-next/src/components/home/LogoCloud.tsx
+++ b/website-next/src/components/home/LogoCloud.tsx
@@ -14,7 +14,7 @@ export function LogoCloud() {
Unify all your APIs into a comprehensive company graph, streamlining
data accessibility and enhancing integration. Transform the way you
manage and interact with your data.