Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ lint-fix.sh

draft/
.venv/

# Vercel (local project link from CLI preview deploys)
.vercel

# Local raw-asset drop folder (copied into docs/public to serve)
/assets/
100 changes: 100 additions & 0 deletions docs/app/(home)/agent-interface/AgentSteps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"use client";

import { useRef } from "react";
import {
StepsAccordion,
type StepsAccordionItem,
} from "../components/StepsAccordion/StepsAccordion";
function createVideoIllustration(src: string) {
return function VideoIllustration() {
const videoRef = useRef<HTMLVideoElement>(null);

const handleLoadedMetadata = () => {
const video = videoRef.current;
if (!video) return;
const parent = video.parentElement;
if (!parent) return;
const ratio = video.videoWidth / video.videoHeight;
if (Number.isFinite(ratio) && ratio > 0) {
parent.style.aspectRatio = String(ratio);
parent.style.height = "auto";
// On mobile the scale wrapper sits inside a fixed-aspect frame; match the
// frame to the video's ratio so it hugs the video with no empty space.
if (parent.className.includes("mobileIllustrationScale")) {
const frame = parent.parentElement;
if (frame) frame.style.aspectRatio = String(ratio);
}
}
};

return (
<video
ref={videoRef}
src={src}
autoPlay
muted
loop
playsInline
preload="metadata"
onLoadedMetadata={handleLoadedMetadata}
style={{
width: "100%",
height: "100%",
objectFit: "cover",
borderRadius: "inherit",
display: "block",
}}
/>
);
};
}

const AGENT_STEPS: StepsAccordionItem[] = [
{
number: 1,
title: "Analytics",
description:
"Help users move from raw data to dashboards, insights, and decision-ready reports.",
details: [],
Illustration: createVideoIllustration("/agent-interface/hostpog.mp4"),
},
{
number: 2,
title: "CRM / Sales",
description:
"Help teams turn account context into QBRs, follow-ups, and revenue actions.",
details: [],
Illustration: createVideoIllustration("/agent-interface/Play.mp4"),
},
{
number: 3,
title: "Customer support",
description:
"Help support teams resolve issues faster with guided answers, actions, and workflows.",
details: [],
Illustration: createVideoIllustration("/agent-interface/tendesk.mp4"),
},
{
number: 4,
title: "DevTools",
description:
"Help developers move from logs and errors to explanations, fixes, and workflows.",
details: [],
Illustration: createVideoIllustration("/agent-interface/Fixpanel.mp4"),
},
{
number: 5,
title: "Project management",
description:
"Help teams turn scattered work into plans, summaries, blockers, and next steps.",
details: [],
Illustration: createVideoIllustration("/agent-interface/Linea.mp4"),
},
];

export function AgentSteps({
autoAdvance = false,
variant,
}: { autoAdvance?: boolean; variant?: "useCases" } = {}) {
return <StepsAccordion steps={AGENT_STEPS} autoAdvance={autoAdvance} variant={variant} />;
}
4 changes: 3 additions & 1 deletion docs/app/(home)/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface AccordionItemProps {
zIndexClosed?: number;
transition?: Transition;
onActivate?: () => void;
activateOnHover?: boolean;
children: ReactNode;
}

Expand All @@ -31,6 +32,7 @@ export function AccordionItem({
zIndexClosed = 1,
transition,
onActivate,
activateOnHover = true,
children,
}: AccordionItemProps) {
return (
Expand All @@ -43,7 +45,7 @@ export function AccordionItem({
}}
transition={transition}
onClick={onActivate}
onMouseEnter={onActivate}
onMouseEnter={activateOnHover ? onActivate : undefined}
>
{children}
</motion.div>
Expand Down
94 changes: 94 additions & 0 deletions docs/app/(home)/components/Button/BevelButton.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* Beveled pill CTA with a circular badge. Light variant on white sections,
dark on the black cloud band. Values mirror the original per-section styles
so the desktop rendering is unchanged. */
.button {
display: inline-flex;
align-items: center;
gap: 0.625rem;
height: 3rem;
padding-left: 1.25rem;
padding-right: 0.5rem;
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 9999px;
background: var(--home-surface-raised);
box-shadow: var(--home-bevel);
color: #0a0a0a;
font-family: "Inter Display", sans-serif;
font-size: 1rem;
font-weight: 500;
text-decoration: none;
transition:
transform 0.2s ease,
box-shadow 0.2s ease;
}

.button:hover {
transform: scale(0.99);
}

.label {
line-height: 1.5rem;
}

.badge {
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 2rem;
height: 2rem;
border-radius: 9999px;
background: var(--bevel-badge-bg, #0a0a0a);
color: var(--bevel-badge-fg, #fff);
}

/* Dark variant for the black cloud band. */
.dark {
background: #0a0a0a;
border-color: rgba(255, 255, 255, 0.2);
box-shadow: var(--home-bevel-on-dark);
color: #fff;
--bevel-badge-bg: #fff;
--bevel-badge-fg: #0a0a0a;
}

/* Primary (theme-adaptive, high contrast): black-on-white in light, white-on-black
in dark — the inverse of the page surface. */
.primary {
background: #0a0a0a;
border-color: rgba(255, 255, 255, 0.12);
box-shadow: var(--home-bevel-on-dark);
color: #fff;
--bevel-badge-bg: #fff;
--bevel-badge-fg: #0a0a0a;
}

[data-theme="dark"] .primary {
background: var(--home-surface-raised);
border-color: rgba(0, 0, 0, 0.08);
box-shadow: var(--home-bevel);
color: #0a0a0a;
--bevel-badge-bg: #0a0a0a;
--bevel-badge-fg: #fff;
}

/* Secondary (theme-adaptive, low contrast): matches the surface — light bevel on
light pages (inherits the base .button), dark bevel on dark pages. */
[data-theme="dark"] .secondary {
/* matches the homepage dark npx button (and the openclaw install button) */
background: var(--home-surface-ink);
border-color: rgba(255, 255, 255, 0.1);
box-shadow: var(--home-bevel-on-dark);
color: var(--openui-text-neutral-primary);
--bevel-badge-bg: var(--openui-inverted-background);
--bevel-badge-fg: var(--openui-background);
}

/* Mobile: full-width pill so every CTA shares one footprint with the hero. */
@media (max-width: 767px) {
.button {
width: 100%;
max-width: 320px;
justify-content: space-between;
}
}
50 changes: 50 additions & 0 deletions docs/app/(home)/components/Button/BevelButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { ReactNode } from "react";
import styles from "./BevelButton.module.css";

/**
* Beveled pill CTA with a circular badge. Shared by the home content sections
* (View benchmarks, View Documentation, Talk to our team) so the button lives
* in one place.
*
* Theme-independent variants: `light` (always white) sits on white sections,
* `dark` (always black) on the black cloud band.
* Theme-adaptive variants: `primary` is high-contrast/inverted (black on light
* pages, white on dark pages); `secondary` matches the surface (light bevel on
* light pages, dark bevel on dark pages).
* On phones it becomes a full-width pill to match the hero CTAs.
*/
export function BevelButton({
href,
label,
badge,
variant = "light",
external = false,
className = "",
}: {
href: string;
label: string;
badge: ReactNode;
variant?: "light" | "dark" | "primary" | "secondary";
external?: boolean;
className?: string;
}) {
const variantClass = {
light: "",
dark: styles.dark,
primary: styles.primary,
secondary: styles.secondary,
}[variant];
const classes = [styles.button, variantClass, className].filter(Boolean).join(" ");
const externalProps = external
? { target: "_blank", rel: "noopener noreferrer" }
: {};

return (
<a href={href} className={classes} {...externalProps}>
<span className={styles.label}>{label}</span>
<span className={styles.badge} aria-hidden="true">
{badge}
</span>
</a>
);
}
68 changes: 68 additions & 0 deletions docs/app/(home)/components/Button/Button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,71 @@
opacity: 0;
transform: scale(0.5);
}

/* ── PillLink variants ── */

.pillBase {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
height: 3rem;
padding-inline: 1.25rem;
border: 1px solid transparent;
border-radius: var(--openui-radius-full, 999px);
font-family: "Inter Display", sans-serif;
font-weight: 600;
font-size: 0.9375rem;
line-height: 1;
text-decoration: none;
white-space: nowrap;
transition:
transform 0.2s ease,
background-color 0.2s ease,
border-color 0.2s ease,
box-shadow 0.2s ease;
}

.pillPrimary {
background: var(--openui-text-neutral-primary);
color: var(--openui-foreground);
box-shadow: var(--openui-shadow-l);
}

.pillPrimary:hover {
transform: scale(0.99);
box-shadow: none;
}

.pillSecondary {
background: var(--openui-foreground);
color: var(--openui-text-neutral-primary);
border-color: var(--openui-border-default);
box-shadow: var(--openui-shadow-l);
}

.pillSecondary:hover {
transform: scale(0.99);
box-shadow: none;
}

.pillGhost {
background: transparent;
color: var(--openui-text-neutral-primary);
font-weight: 500;
font-size: 1.125rem;
}

.pillGhost:hover {
background: var(--openui-highlight);
}

.pillFullWidthMobile {
width: 100%;
}

@media (min-width: 900px) {
.pillFullWidthMobile {
width: auto;
}
}
Loading
Loading