Skip to content

Commit aebe1cf

Browse files
authored
feat: typewriter animation for hero headline (#20)
## Summary - Hero headline now reads "Debug mode for [agent name]" with a typewriter effect - Cycles through: Claude Code, Cursor, Codex, Copilot, Goose, Amp, any agent - Agent name shown in green with a blinking cursor - Removes the static "For Claude Code, Cursor, Copilot, and any agent" label ## Test plan - [ ] `pnpm docs:dev` and check homepage hero - [ ] Typewriter types out each name, pauses, deletes, moves to next - [ ] "any agent" pauses longer (4s vs 2s) - [ ] Loops back to Claude Code after completing the cycle
2 parents 10675aa + 684ed5e commit aebe1cf

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

docs/src/app/home.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
.hp-hero { padding: 80px 0 48px; text-align: center; }
4343
.hp-hero-label { font-family: var(--hp-mono); font-size: 12px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--hp-accent); margin-bottom: 16px; }
4444
.hp-hero h1 { font-family: var(--hp-title); font-size: clamp(32px, 5vw, 56px); font-weight: 700; line-height: 1.1; letter-spacing: -0.03em; margin-bottom: 20px; }
45+
.hp-typewriter { color: var(--hp-accent); }
46+
.hp-cursor { display: inline-block; width: 3px; height: 0.9em; background: var(--hp-accent); margin-left: 2px; vertical-align: baseline; animation: blink 0.6s step-end infinite; }
47+
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
4548
.hp-hero p { font-size: 18px; color: var(--hp-text-dim); max-width: 640px; margin: 0 auto; line-height: 1.6; font-weight: 300; }
4649

4750
/* CODE BLOCK */

docs/src/app/page.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import './home.css';
4-
import { useState } from 'react';
4+
import { useState, useEffect, useCallback } from 'react';
55

66
function copyCmd(id: string, btn: HTMLButtonElement) {
77
const el = document.getElementById(id);
@@ -12,6 +12,36 @@ function copyCmd(id: string, btn: HTMLButtonElement) {
1212
});
1313
}
1414

15+
const AGENTS = ['Claude Code', 'Cursor', 'Codex', 'Copilot', 'Goose', 'Amp', 'any agent'];
16+
17+
function TypewriterAgent() {
18+
const [index, setIndex] = useState(0);
19+
const [text, setText] = useState('');
20+
const [deleting, setDeleting] = useState(false);
21+
22+
const word = AGENTS[index];
23+
24+
useEffect(() => {
25+
if (!deleting && text === word) {
26+
const pause = index === AGENTS.length - 1 ? 4000 : 2000;
27+
const timer = setTimeout(() => setDeleting(true), pause);
28+
return () => clearTimeout(timer);
29+
}
30+
if (deleting && text === '') {
31+
setDeleting(false);
32+
setIndex((i) => (i + 1) % AGENTS.length);
33+
return;
34+
}
35+
const speed = deleting ? 40 : 80;
36+
const timer = setTimeout(() => {
37+
setText(deleting ? word.slice(0, text.length - 1) : word.slice(0, text.length + 1));
38+
}, speed);
39+
return () => clearTimeout(timer);
40+
}, [text, deleting, word, index]);
41+
42+
return <span className="hp-typewriter">{text}<span className="hp-cursor" /></span>;
43+
}
44+
1545
function CodeTabs() {
1646
const [active, setActive] = useState('api-gateway');
1747

@@ -102,8 +132,7 @@ export default function HomePage() {
102132
{/* HERO */}
103133
<section className="hp-hero">
104134
<div className="hp-container">
105-
<div className="hp-hero-label">For Claude Code, Cursor, Copilot, and any agent</div>
106-
<h1>Debug mode for<br />any agent</h1>
135+
<h1>Debug mode for<br /><TypewriterAgent /></h1>
107136
<p>Agents can read your code but they can&apos;t see what happened at runtime. agentcrumbs lets them drop structured traces inline while writing code, then query those traces when something breaks. Stripped before merge, zero cost when off.</p>
108137
</div>
109138
</section>

0 commit comments

Comments
 (0)