feat(site): rewrite landing page — Claude Code Command Center
Reposition cladm from "monitor & launcher" to "command center" with embedded PTY grid, tabbed workspaces, and pane controls. New hero animation shows picker → grid transition. JSX workspace mockup with 4 active panes, traffic-light buttons, and live terminal content. Updated features, two-mode controls, and metadata throughout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
const projects = [
|
||||
{ name: "acme-api", branch: "main", time: "25m ago", status: "busy" as const },
|
||||
@@ -10,13 +9,13 @@ const projects = [
|
||||
];
|
||||
|
||||
type Phase =
|
||||
| "typing" // cladm console visible, cursor selecting projects
|
||||
| "selecting" // checkboxes toggling on one by one
|
||||
| "enter" // "Enter" flash, cladm fades
|
||||
| "cascade" // terminals fly in
|
||||
| "hold" // terminals visible
|
||||
| "fadeout" // everything fades, restart
|
||||
| "pause"; // brief gap before loop
|
||||
| "typing"
|
||||
| "selecting"
|
||||
| "enter"
|
||||
| "grid"
|
||||
| "hold"
|
||||
| "fadeout"
|
||||
| "pause";
|
||||
|
||||
export function TerminalCascade() {
|
||||
const [phase, setPhase] = useState<Phase>("typing");
|
||||
@@ -27,31 +26,18 @@ export function TerminalCascade() {
|
||||
setSelectedCount(0);
|
||||
setPhase("typing");
|
||||
|
||||
// Typing/appear cladm console
|
||||
const t1 = setTimeout(() => setPhase("selecting"), 800);
|
||||
|
||||
// Toggle checkboxes one by one
|
||||
const t2 = setTimeout(() => setSelectedCount(1), 1200);
|
||||
const t3 = setTimeout(() => setSelectedCount(2), 1600);
|
||||
const t4 = setTimeout(() => setSelectedCount(3), 2000);
|
||||
|
||||
// Enter pressed
|
||||
const t5 = setTimeout(() => setPhase("enter"), 2600);
|
||||
|
||||
// Cascade terminals in
|
||||
const t6 = setTimeout(() => setPhase("cascade"), 3200);
|
||||
|
||||
// Hold
|
||||
const t7 = setTimeout(() => setPhase("hold"), 3800);
|
||||
|
||||
// Fade out
|
||||
const t8 = setTimeout(() => setPhase("fadeout"), 6200);
|
||||
|
||||
// Pause then restart
|
||||
const t6 = setTimeout(() => setPhase("grid"), 3400);
|
||||
const t7 = setTimeout(() => setPhase("hold"), 4000);
|
||||
const t8 = setTimeout(() => setPhase("fadeout"), 7000);
|
||||
const t9 = setTimeout(() => {
|
||||
setPhase("pause");
|
||||
setCycle((c) => c + 1);
|
||||
}, 7000);
|
||||
}, 7800);
|
||||
|
||||
return [t1, t2, t3, t4, t5, t6, t7, t8, t9];
|
||||
}, []);
|
||||
@@ -65,19 +51,18 @@ export function TerminalCascade() {
|
||||
return () => clearTimeout(start);
|
||||
}, [cycle, runCycle]);
|
||||
|
||||
const showCladm = phase === "typing" || phase === "selecting" || phase === "enter";
|
||||
const showCascade = phase === "cascade" || phase === "hold" || phase === "fadeout";
|
||||
const showPicker = phase === "typing" || phase === "selecting" || phase === "enter";
|
||||
const showGrid = phase === "grid" || phase === "hold" || phase === "fadeout";
|
||||
|
||||
return (
|
||||
<div className="relative w-full min-h-[340px]">
|
||||
{/* ── CLADM console (cause) ── */}
|
||||
<div className="relative w-full min-h-[360px]">
|
||||
{/* ── Picker (select projects) ── */}
|
||||
<div
|
||||
className={`transition-all duration-500 ${
|
||||
showCladm ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none absolute inset-0"
|
||||
showPicker ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none absolute inset-0"
|
||||
}`}
|
||||
>
|
||||
<div className="pixel-border bg-surface overflow-hidden">
|
||||
{/* Title bar */}
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-2 border-b-2 border-border">
|
||||
<div className="w-3 h-3 bg-[#ff5f56]" />
|
||||
<div className="w-3 h-3 bg-[#ffbd2e]" />
|
||||
@@ -86,7 +71,6 @@ export function TerminalCascade() {
|
||||
cladm — {selectedCount} selected
|
||||
</span>
|
||||
</div>
|
||||
{/* Project rows */}
|
||||
<div className="p-3 font-[family-name:var(--font-mono)] text-[11px] leading-relaxed">
|
||||
<div className="text-dim mb-1 text-[10px]">
|
||||
{" PROJECT BRANCH LAST USE"}
|
||||
@@ -121,15 +105,14 @@ export function TerminalCascade() {
|
||||
<span>○</span><span> </span>[ ] pixel-engine{" "}develop{" "}3h ago
|
||||
</div>
|
||||
|
||||
{/* Enter hint */}
|
||||
<div className="mt-3 pt-2 border-t border-border text-[10px]">
|
||||
{phase === "enter" ? (
|
||||
<span className="text-accent font-bold cascade-flash">
|
||||
⏎ Launching 3 projects...
|
||||
⏎ Launching 3 sessions into grid...
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-dim">
|
||||
↑↓ navigate · space toggle · enter launch
|
||||
↑↓ navigate · space toggle · enter launch grid
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -137,45 +120,92 @@ export function TerminalCascade() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Terminal cascade (effect) ── */}
|
||||
{/* ── Grid workspace (result) ── */}
|
||||
<div
|
||||
className={`transition-opacity duration-500 ${
|
||||
showCascade ? "opacity-100" : "opacity-0 pointer-events-none absolute inset-0"
|
||||
className={`transition-opacity duration-600 ${
|
||||
showGrid ? "opacity-100" : "opacity-0 pointer-events-none absolute inset-0"
|
||||
}`}
|
||||
>
|
||||
<div className="relative h-[320px]">
|
||||
{projects.map((proj, i) => (
|
||||
<div
|
||||
key={`term-${proj.name}-${cycle}`}
|
||||
className={`absolute left-0 right-0 border-2 bg-surface overflow-hidden
|
||||
${phase === "cascade" || phase === "hold" ? "cascade-in" : ""}
|
||||
${phase === "hold" && i === projects.length - 1 ? "cascade-glow" : ""}`}
|
||||
style={{
|
||||
animationDelay: `${i * 0.2}s`,
|
||||
top: `${i * 80}px`,
|
||||
marginLeft: `${i * 16}px`,
|
||||
marginRight: `${(projects.length - 1 - i) * 16}px`,
|
||||
zIndex: i + 1,
|
||||
borderColor: "var(--color-border)",
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-1.5 px-3 py-1 bg-surface-2 border-b border-border">
|
||||
<div className="w-[7px] h-[7px] bg-[#ff5f56]" />
|
||||
<div className="w-[7px] h-[7px] bg-[#ffbd2e]" />
|
||||
<div className="w-[7px] h-[7px] bg-[#27c93f]" />
|
||||
<span className="ml-2 font-[family-name:var(--font-mono)] text-dim text-[9px] truncate">
|
||||
claude — {proj.name}
|
||||
</span>
|
||||
</div>
|
||||
<Image
|
||||
src="/claude-welcome.png"
|
||||
alt="Claude Code welcome screen"
|
||||
width={570}
|
||||
height={260}
|
||||
className="w-full h-auto"
|
||||
/>
|
||||
<div className={`pixel-border bg-surface overflow-hidden ${phase === "hold" ? "cascade-glow" : phase === "grid" ? "cascade-in" : ""}`}>
|
||||
{/* Tab bar */}
|
||||
<div className="flex items-center bg-surface-2 border-b-2 border-border">
|
||||
<div className="px-3 py-1.5 border-b-2 border-accent font-[family-name:var(--font-mono)] text-[9px]">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-text"> acme-api</span>
|
||||
<span className="text-dim"> · </span>
|
||||
<span className="text-yellow">◉</span>
|
||||
<span className="text-text"> quantum-dash</span>
|
||||
</div>
|
||||
))}
|
||||
<div className="px-3 py-1.5 font-[family-name:var(--font-mono)] text-[9px] text-dim border-b-2 border-transparent">
|
||||
<span className="text-green">●</span>
|
||||
<span> ml-pipeline</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pane grid */}
|
||||
<div className="grid grid-cols-2 gap-px bg-border">
|
||||
{/* Pane 1: acme-api (busy) */}
|
||||
<div className="bg-surface">
|
||||
<div className="flex items-center justify-between px-2 py-[3px] border-b border-border">
|
||||
<div className="font-[family-name:var(--font-mono)] text-[8px]">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-text"> acme-api</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<span className="text-cyan text-[6px]">●</span>
|
||||
<span className="text-[#27c93f] text-[6px]">●</span>
|
||||
<span className="text-[#ff5f56] text-[6px]">●</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-2 font-[family-name:var(--font-mono)] text-[8px] text-dim leading-[1.6] h-[85px]">
|
||||
<div className="text-green">> I'll fix the token refresh bug</div>
|
||||
<div>Reading src/auth/token.ts...</div>
|
||||
<div>Reading src/auth/middleware.ts...</div>
|
||||
<div>Grep: refreshToken pattern<span className="cursor-blink text-accent">_</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pane 2: quantum-dash (idle) */}
|
||||
<div className="bg-surface">
|
||||
<div className="flex items-center justify-between px-2 py-[3px] border-b border-border">
|
||||
<div className="font-[family-name:var(--font-mono)] text-[8px]">
|
||||
<span className="text-yellow">◉</span>
|
||||
<span className="text-dim"> 4m </span>
|
||||
<span className="text-text">quantum-dash</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<span className="text-cyan text-[6px]">●</span>
|
||||
<span className="text-[#27c93f] text-[6px]">●</span>
|
||||
<span className="text-[#ff5f56] text-[6px]">●</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-2 font-[family-name:var(--font-mono)] text-[8px] text-dim leading-[1.6] h-[85px]">
|
||||
<div className="text-text">Updated chart component</div>
|
||||
<div className="text-text">New hook: useChartData.ts</div>
|
||||
<div className="text-yellow mt-1">Waiting for input...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pane 3: ml-pipeline (busy, full width) */}
|
||||
<div className="bg-surface col-span-2">
|
||||
<div className="flex items-center justify-between px-2 py-[3px] border-b border-border">
|
||||
<div className="font-[family-name:var(--font-mono)] text-[8px]">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-text"> ml-pipeline</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<span className="text-cyan text-[6px]">●</span>
|
||||
<span className="text-[#27c93f] text-[6px]">●</span>
|
||||
<span className="text-[#ff5f56] text-[6px]">●</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-2 font-[family-name:var(--font-mono)] text-[8px] text-dim leading-[1.6] h-[65px]">
|
||||
<div className="text-green">> Building BERT fine-tuning pipeline</div>
|
||||
<div>Processing dataset: train.jsonl</div>
|
||||
<div>Epoch 3/10 <span className="text-accent">████████</span><span className="text-border">░░░░░░░░░░░░</span> 30%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user