Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
9 changes: 6 additions & 3 deletions src/components/CTA.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { Link } from "@tanstack/react-router";
import { useProduct } from "@/context/ProductContext";

export const CTA = () => {
const { ctaHeadline, ctaButtonText, docsBasePath } = useProduct();

return (
<section className="py-32 lg:py-48 border-b border-border relative overflow-hidden">
<div className="absolute inset-0 grid-bg" aria-hidden />
<div className="container mx-auto px-6 relative text-center">
<h2 className="font-mono font-light tracking-tight leading-[1.05] text-foreground text-[14vw] md:text-[10vw] lg:text-[140px] mb-12">
Ship.
{ctaHeadline}
</h2>
<p className="text-base text-foreground/70 max-w-xl mx-auto mb-10">
Join thousands of engineers who replaced six dashboards with one CLI.
Install in 30 seconds. Cancel anytime.
</p>
<div className="flex flex-wrap justify-center gap-3">
<a href="#" className="btn-mono px-6 py-3 bg-foreground text-background hover:bg-foreground/90 transition-colors">
Start Now
{ctaButtonText}
</a>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
<Link to="/docs" className="btn-mono px-6 py-3 border border-[rgba(255,255,255,0.2)] text-foreground hover:bg-[rgba(255,255,255,0.05)] transition-colors">
<Link to={docsBasePath} className="btn-mono px-6 py-3 border border-[rgba(255,255,255,0.2)] text-foreground hover:bg-[rgba(255,255,255,0.05)] transition-colors">
Read the docs
</Link>
</div>
Expand Down
107 changes: 34 additions & 73 deletions src/components/Commands.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,13 @@
import { useState } from "react";
import { CommandExample } from "@/config/products/types";

const commands = [
{
name: "show",
sig: "kdm show <target>",
desc: "List running runners, pods, containers, or minikube clusters.",
output: `> kdm show pods
NAMESPACE NAME READY STATUS AGE
default api-server-7d4f8b 1/1 Running 3d
default worker-queue-2c9a1 1/1 Running 3d
ingress traefik-controller-x9 1/1 Running 14d
monitoring prometheus-0 2/2 Running 21d`,
},
{
name: "health",
sig: "kdm health <target>",
desc: "Detailed health, liveness, and resource pressure diagnostics.",
output: `> kdm health pods
[ok] api-server-7d4f8b healthy cpu 12% mem 248Mi
[ok] worker-queue-2c9a1 healthy cpu 34% mem 512Mi
[warn] log-shipper-abc12 degraded restarts: 3 (last 1h)
[fail] batch-runner-99fa1 failing OOMKilled · 2x in 5m`,
},
{
name: "watch",
sig: "kdm watch",
desc: "Live monitoring dashboard right inside your terminal.",
output: `> kdm watch
+- Live - 14:02:31 ----------------------------+
| pods: 24 running · 1 pending · 0 failed |
| cpu: ######======== 62% |
| mem: ####========== 41% |
| net: in 124 MB/s out 38 MB/s |
+----------------------------------------------+`,
},
{
name: "logs",
sig: "kdm logs <name>",
desc: "Tail logs with structured parsing and instant search.",
output: `> kdm logs api-server-7d4f8b -f
14:02:30 INFO request GET /api/users 200 12ms
14:02:30 INFO request POST /api/auth 201 48ms
14:02:31 WARN cache miss key=user:8821
14:02:31 INFO request GET /api/orders 200 18ms`,
},
];
export interface CommandsProps {
commands: CommandExample[];
}

export const Commands = () => {
export const Commands = ({ commands }: CommandsProps) => {
const [active, setActive] = useState(0);
const cmd = commands[active];
const cmd = commands[active] || { sig: "", output: "" };

return (
<section id="commands" className="py-24 lg:py-32 border-b border-border">
Expand All @@ -62,35 +21,37 @@ export const Commands = () => {
</h2>
</div>

<div className="grid lg:grid-cols-[320px_1fr] gap-6">
<div className="flex lg:flex-col gap-px bg-border overflow-x-auto">
{commands.map((c, i) => (
<button
key={c.name}
onClick={() => setActive(i)}
className={`text-left p-5 transition-colors whitespace-nowrap lg:whitespace-normal flex-1 min-h-[44px] ${
active === i
? "bg-[rgba(255,255,255,0.05)] border-l-2 border-l-foreground"
: "bg-background hover:bg-[rgba(255,255,255,0.03)]"
}`}
>
<div className="font-mono text-sm mb-1">{c.sig}</div>
<div className="text-xs text-foreground/70 hidden lg:block">{c.desc}</div>
</button>
))}
</div>

<div className="border border-border bg-[rgba(255,255,255,0.03)] overflow-hidden">
<div className="flex items-center gap-2 px-4 py-3 border-b border-border">
<span className="font-mono text-xs uppercase tracking-[1px] text-foreground/50">
{cmd.sig}
</span>
{commands.length > 0 && (
<div className="grid lg:grid-cols-[320px_1fr] gap-6">
<div className="flex lg:flex-col gap-px bg-border overflow-x-auto">
{commands.map((c, i) => (
<button
key={c.name}
onClick={() => setActive(i)}
className={`text-left p-5 transition-colors whitespace-nowrap lg:whitespace-normal flex-1 min-h-[44px] ${
active === i
? "bg-[rgba(255,255,255,0.05)] border-l-2 border-l-foreground"
: "bg-background hover:bg-[rgba(255,255,255,0.03)]"
}`}
>
<div className="font-mono text-sm mb-1">{c.sig}</div>
<div className="text-xs text-foreground/70 hidden lg:block">{c.desc}</div>
</button>
))}
</div>
<pre className="p-6 font-mono text-sm leading-relaxed text-foreground/90 overflow-x-auto whitespace-pre">

<div className="border border-border bg-[rgba(255,255,255,0.03)] overflow-hidden">
<div className="flex items-center gap-2 px-4 py-3 border-b border-border">
<span className="font-mono text-xs uppercase tracking-[1px] text-foreground/50">
{cmd.sig}
</span>
</div>
<pre className="p-6 font-mono text-sm leading-relaxed text-foreground/90 overflow-x-auto whitespace-pre">
{cmd.output}
</pre>
</pre>
</div>
</div>
</div>
)}
</div>
</section>
);
Expand Down
48 changes: 7 additions & 41 deletions src/components/Features.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,11 @@
import { Eye, HeartPulse, Radio, ScrollText, Cloud, Shield } from "lucide-react";
import { Feature } from "@/config/products/types";

const features = [
{
icon: Eye,
title: "Unified visibility",
desc: "Show running pods, containers, runners, and Minikube nodes — across clouds — in a single command.",
cmd: "kdm show <target>",
},
{
icon: HeartPulse,
title: "Health diagnostics",
desc: "Probe liveness, readiness, restarts, and resource pressure with intelligent severity scoring.",
cmd: "kdm health <target>",
},
{
icon: Radio,
title: "Live watch mode",
desc: "Stream metrics in real time with millisecond updates. Pin services, filter noise, alert on drift.",
cmd: "kdm watch",
},
{
icon: ScrollText,
title: "Smart log tailing",
desc: "Tail container or pod logs with structured parsing, multi-line stitching, and instant search.",
cmd: "kdm logs <name>",
},
{
icon: Cloud,
title: "Cloud-synced state",
desc: "Securely sync cluster state across your team. Share dashboards, runbooks, and incident timelines.",
cmd: "cloud · auto",
},
{
icon: Shield,
title: "Zero-trust by default",
desc: "Read-only kubeconfig context, scoped tokens, and end-to-end encrypted streams. SOC 2 ready.",
cmd: "built-in",
},
];
export interface FeaturesProps {
features: Feature[];
productName: string;
}

export const Features = () => {
export const Features = ({ features, productName }: FeaturesProps) => {
return (
<section id="features" className="py-24 lg:py-32 border-b border-border">
<div className="container mx-auto px-6">
Expand All @@ -51,7 +17,7 @@ export const Features = () => {
One CLI for the entire stack.
</h2>
<p className="text-base text-foreground/70">
From local Minikube clusters to multi-region production, KDM gives you the same crisp
From local Minikube clusters to multi-region production, {productName.toUpperCase()} gives you the same crisp
experience whether you're debugging on a laptop or paging at 3 AM.
</p>
</div>
Expand Down
15 changes: 11 additions & 4 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { useOptionalProduct } from "@/context/ProductContext";
import { Link } from "@tanstack/react-router";

export const Footer = () => {
const product = useOptionalProduct();

return (
<footer className="py-12">
<footer className="py-12 border-t border-border mt-auto">
<div className="container mx-auto px-6">
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
<div className="flex items-center gap-4">
<span className="font-mono text-sm uppercase tracking-[1.4px]">kdm</span>
<span className="text-xs text-foreground/50">© 2026 KDM Labs</span>
<span className="font-mono text-sm uppercase tracking-[1.4px]">
{product ? product.displayName : "Antigravity Labs"}
</span>
<span className="text-xs text-foreground/50">
© 2026 {product ? `${product.displayName} Labs` : "Antigravity Labs"}
</span>
</div>
<div className="flex gap-6 font-mono text-xs uppercase tracking-[1px] text-foreground/70">
<Link to="/privacy" className="hover:text-foreground/40 transition-colors">
Expand All @@ -25,7 +32,7 @@ export const Footer = () => {
Status
</a>
<a
href="https://github.com/KDM-cli/kdm-cli"
href={product ? product.githubUrl : "https://github.com/KDM-cli/kdm-cli"}
target="_blank"
rel="noreferrer"
className="hover:text-foreground/40 transition-colors"
Expand Down
37 changes: 16 additions & 21 deletions src/components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Copy, Check } from "lucide-react";
import { useState } from "react";
import { Terminal } from "./Terminal";
import { useProduct } from "@/context/ProductContext";

export const Hero = () => {
const { displayName, tagline, description, installCommand, githubUrl, stats, terminalLines } = useProduct();
const [copied, setCopied] = useState(false);
const copy = () => {
navigator.clipboard.writeText("npm install -g kdm-cli");
navigator.clipboard.writeText(installCommand);
setCopied(true);
setTimeout(() => setCopied(false), 1500);
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Expand All @@ -21,55 +23,48 @@ export const Hero = () => {
</div>

<h1 className="font-mono font-light tracking-tight leading-[1.05] text-foreground text-[14vw] md:text-[12vw] lg:text-[180px] xl:text-[220px] mb-12">
kdm.
{displayName.toLowerCase()}.
</h1>

<div className="grid lg:grid-cols-2 gap-16 items-start">
<div className="space-y-8">
<h2 className="text-2xl lg:text-3xl font-normal leading-tight max-w-xl">
Monitor every pod and container from your terminal.
{tagline}
</h2>
<p className="text-base text-foreground/70 max-w-xl leading-relaxed">
KDM is a cloud-native CLI that streams real-time health, logs, and metrics
for Kubernetes clusters, Docker hosts, and Minikube — all from one unified command.
{description}
</p>

<button
onClick={copy}
className="group flex items-center justify-between gap-3 px-4 py-3 w-full max-w-md border border-[rgba(255,255,255,0.2)] font-mono text-sm hover:border-foreground/50 transition-colors"
>
<span className="text-foreground/50">$</span>
<span className="flex-1 text-left">npm install -g kdm-cli</span>
<span className="flex-1 text-left">{installCommand}</span>
{copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4 text-foreground/50 group-hover:text-foreground transition-colors" />}
</button>

<div className="flex flex-wrap gap-3">
<a href="#" className="btn-mono px-6 py-3 bg-foreground text-background hover:bg-foreground/90 transition-colors">
Try KDM
Try {displayName.toUpperCase()}
</a>
<a href="https://github.com/KDM-cli/kdm-cli" className="btn-mono px-6 py-3 border border-[rgba(255,255,255,0.2)] text-foreground hover:bg-[rgba(255,255,255,0.05)] transition-colors">
<a href={githubUrl} target="_blank" rel="noreferrer" className="btn-mono px-6 py-3 border border-[rgba(255,255,255,0.2)] text-foreground hover:bg-[rgba(255,255,255,0.05)] transition-colors">
View on GitHub
</a>
</div>

<div className="grid grid-cols-1 sm:grid-cols-3 gap-6 pt-8 border-t border-border">
<div>
<div className="font-mono text-2xl sm:text-3xl font-light">12k+</div>
<div className="text-xs text-foreground/50 mt-1">Active clusters</div>
</div>
<div>
<div className="font-mono text-2xl sm:text-3xl font-light">99.99%</div>
<div className="text-xs text-foreground/50 mt-1">Uptime SLA</div>
</div>
<div>
<div className="font-mono text-2xl sm:text-3xl font-light">&lt;50ms</div>
<div className="text-xs text-foreground/50 mt-1">Stream latency</div>
</div>
{stats.map((stat, i) => (
<div key={i}>
<div className="font-mono text-2xl sm:text-3xl font-light">{stat.value}</div>
<div className="text-xs text-foreground/50 mt-1">{stat.label}</div>
</div>
))}
</div>
</div>

<div className="relative">
<Terminal />
<Terminal lines={terminalLines} productName={displayName} />
</div>
</div>
</div>
Expand Down
Loading
Loading