Skip to content

Instantly share code, notes, and snippets.

@miguel-heygen
Last active August 14, 2026 08:38
Show Gist options
  • Select an option

  • Save miguel-heygen/3f7f28c41b9fd9a76972af4ad0b32f8f to your computer and use it in GitHub Desktop.

Select an option

Save miguel-heygen/3f7f28c41b9fd9a76972af4ad0b32f8f to your computer and use it in GitHub Desktop.
Anthropic Agentic Loop — HyperFrames composition (pixel-perfect recreation)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=720, height=720" />
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { width: 720px; height: 720px; overflow: hidden; background: #faf9f5; }
/* ── Colors (Anthropic brand kit) ── */
:root {
--cream: #faf9f5;
--beige: #e3dacc;
--dark: #141413;
--medium: #5e5d59;
--light: #b0aea5;
--sage: #bcd1ca;
--sage-text: #3d3d3a;
--blue-pill: #cbcadb;
--blue-text: #3d3d3a;
--coral: #d97757;
--terminal-dark: #141413;
--card-white: #faf9f5;
--divider: #1414131a;
}
/* ── Typography ── */
.serif { font-family: 'EB Garamond', serif; }
.sans { font-family: 'Inter', sans-serif; }
.mono { font-family: 'JetBrains Mono', monospace; }
/* ── Main container ── */
#main {
position: relative;
width: 720px;
height: 720px;
overflow: hidden;
}
/* ── Subtle grain overlay ── */
.grain {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
opacity: 0.03;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E");
background-size: 256px 256px;
}
/* ── Scene base ── */
.scene {
position: absolute;
inset: 0;
width: 720px;
height: 720px;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
}
/* ── Scene 1: Flow Diagram (simple) ── */
.scene-flow { background: var(--cream); }
.flow-chain {
display: flex;
align-items: center;
gap: 0;
}
.flow-node {
display: flex;
align-items: center;
justify-content: center;
padding: 14px 28px;
border-radius: 8px;
font-size: 22px;
font-weight: 500;
white-space: nowrap;
}
.flow-node.active {
background: var(--sage);
color: var(--sage-text);
}
.flow-node.ghost {
background: #e8e5dd;
color: var(--medium);
}
.flow-node.prompt {
background: #EDE8E1;
color: var(--dark);
}
.flow-arrow {
display: flex;
align-items: center;
padding: 0 10px;
color: var(--medium);
font-size: 20px;
}
.flow-arrow svg {
width: 40px;
height: 16px;
}
.flow-arrow line, .flow-arrow polyline {
stroke: var(--medium);
stroke-width: 1.5;
fill: none;
}
/* ── Scene 2: Terminal ── */
.scene-terminal { background: var(--coral); }
.terminal-bg-lines {
position: absolute;
inset: 0;
overflow: hidden;
}
.terminal-bg-lines svg {
width: 100%;
height: 100%;
}
.terminal-bg-lines path {
fill: none;
stroke: rgba(255, 255, 255, 0.12);
stroke-width: 1.5;
}
.terminal-window {
position: relative;
width: 560px;
height: 480px;
background: var(--terminal-dark);
border-radius: 16px;
overflow: hidden;
transform-origin: center center;
}
.pong-canvas {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
/* ── Scene 3: Title "The agentic loop" ── */
.scene-title-agentic { background: var(--cream); padding-top: 40px; }
.title-text {
font-size: 78px;
font-weight: 500;
color: var(--dark);
letter-spacing: -0.02em;
line-height: 1.1;
}
.title-text .word {
display: inline-block;
color: var(--light);
}
/* ── Scene 4: Extended Flow with Verify ── */
.scene-flow-ext { background: var(--cream); }
.flow-ext-wrap {
position: relative;
width: 720px;
height: 400px;
}
.s4-node {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
padding: 14px 24px;
border-radius: 8px;
font-size: 19px;
font-weight: 500;
white-space: nowrap;
}
.s4-action { background: var(--sage); color: var(--sage-text); top: 130px; left: 30px; }
.s4-verify { background: var(--blue-pill); color: var(--blue-text); top: 130px; left: 250px; opacity: 0; }
.s4-response { background: #e8e5dd; color: var(--medium); top: 130px; left: 460px; }
.s4-arrow {
position: absolute;
top: 142px;
color: var(--medium);
}
.s4-arrow svg { width: 36px; height: 14px; }
.s4-arrow line, .s4-arrow polyline { stroke: var(--medium); stroke-width: 1.5; fill: none; }
.s4-a1 { left: 170px; }
.s4-a2 { left: 400px; opacity: 0; }
.s4-feedback-outer {
position: absolute;
top: 175px;
left: 30px;
width: 580px;
height: 110px;
opacity: 0;
}
.s4-feedback-outer svg { width: 100%; height: 100%; }
.s4-feedback-outer path { fill: none; stroke: var(--medium); stroke-width: 1.5; }
.s4-feedback-inner {
position: absolute;
top: 175px;
left: 130px;
width: 360px;
height: 80px;
opacity: 0;
}
.s4-feedback-inner svg { width: 100%; height: 100%; }
.s4-feedback-inner path { fill: none; stroke: var(--medium); stroke-width: 1.5; stroke-dasharray: 6 4; }
.s4-vert-dash {
position: absolute;
top: 60px;
left: 340px;
height: 200px;
border-left: 1.5px dashed var(--light);
opacity: 0;
}
.s4-label {
position: absolute;
top: 55px;
left: 240px;
font-size: 16px;
font-style: italic;
color: var(--medium);
opacity: 0;
}
.s4-label-dash-l {
position: absolute;
top: 65px;
left: 30px;
width: 200px;
border-top: 1.5px dashed var(--light);
opacity: 0;
}
.s4-label-dash-r {
position: absolute;
top: 65px;
left: 390px;
width: 220px;
border-top: 1.5px dashed var(--light);
opacity: 0;
}
/* ── Scene 5: Title "Verification loops" ── */
.scene-title-verify { background: var(--beige); padding-top: 40px; }
/* ── Scene 6: Domain Table ── */
.scene-table { background: var(--cream); align-items: flex-start; padding-top: 120px; }
.domain-table {
width: 560px;
}
.table-header {
display: flex;
padding: 0 0 16px 0;
border-bottom: 1px solid var(--divider);
margin-bottom: 8px;
}
.table-header span {
font-size: 13px;
font-weight: 500;
letter-spacing: 0.08em;
color: var(--medium);
}
.th-domain { width: 140px; }
.th-behavior { flex: 1; }
.table-row {
display: flex;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid rgba(224, 216, 206, 0.5);
opacity: 0;
}
.table-row:last-child { border-bottom: none; }
.row-domain {
width: 140px;
}
.domain-pill {
display: inline-flex;
align-items: center;
padding: 6px 16px;
border-radius: 20px;
background: var(--sage);
color: var(--sage-text);
font-size: 15px;
font-weight: 500;
}
.row-behavior {
flex: 1;
font-size: 18px;
color: var(--dark);
font-weight: 400;
}
/* ── Scene 7: Task Cards ── */
.scene-cards { background: var(--beige); align-items: flex-start; padding-top: 70px; }
.card-stack {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
width: 480px;
}
.task-card {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
padding: 18px 40px;
background: var(--card-white);
border-radius: 12px;
font-size: 26px;
font-weight: 400;
color: var(--dark);
opacity: 0;
}
/* ── Scene 8: Code Editor ── */
.scene-code { background: #DDD8CE; }
.code-editor {
width: 580px;
background: var(--card-white);
border-radius: 16px;
overflow: hidden;
box-shadow: 0 2px 20px rgba(0,0,0,0.06);
}
.code-titlebar {
padding: 14px 20px;
font-size: 14px;
font-weight: 500;
color: var(--medium);
border-bottom: 1px solid var(--divider);
}
.code-body {
padding: 20px;
font-size: 14px;
line-height: 2;
color: var(--dark);
}
.code-line {
display: flex;
opacity: 0;
}
.line-num {
width: 36px;
text-align: right;
padding-right: 16px;
color: var(--light);
user-select: none;
}
.line-content { flex: 1; }
.code-keyword { color: #6B8E5A; }
.code-string { color: #B07040; }
.code-comment { color: var(--medium); }
.code-punct { color: var(--light); }
.code-cursor {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
opacity: 0;
z-index: 10;
}
.code-cursor svg {
width: 20px;
height: 28px;
filter: drop-shadow(0 1px 2px rgba(0,0,0,0.15));
}
</style>
</head>
<body>
<div id="main" data-composition-id="main" data-start="0" data-duration="13.3" data-width="720" data-height="720">
<div class="grain"></div>
<!-- ═══ Scene 1: Simple Flow Diagram ═══ -->
<div id="s1" class="scene scene-flow clip" data-start="0" data-duration="3.5" data-track-index="0">
<div class="flow-chain sans">
<div id="s1-prompt" class="flow-node prompt">Prompt</div>
<div id="s1-a1" class="flow-arrow"><svg viewBox="0 0 40 16"><line x1="0" y1="8" x2="32" y2="8"/><polyline points="28,4 34,8 28,12"/></svg></div>
<div id="s1-gather" class="flow-node active">Gather context</div>
<div id="s1-a2" class="flow-arrow"><svg viewBox="0 0 40 16"><line x1="0" y1="8" x2="32" y2="8"/><polyline points="28,4 34,8 28,12"/></svg></div>
<div id="s1-action" class="flow-node active">Take action</div>
<div id="s1-a3" class="flow-arrow"><svg viewBox="0 0 40 16"><line x1="0" y1="8" x2="32" y2="8"/><polyline points="28,4 34,8 28,12"/></svg></div>
<div id="s1-response" class="flow-node ghost">Response</div>
</div>
</div>
<!-- ═══ Scene 2: Terminal Animation ═══ -->
<div id="s2" class="scene scene-terminal clip" data-start="1.5" data-duration="2.0" data-track-index="1">
<div class="terminal-bg-lines">
<svg viewBox="0 0 720 720">
<path d="M-20,200 Q180,150 360,220 T740,180" />
<path d="M-20,350 Q200,300 400,380 T740,320" />
<path d="M-20,500 Q150,450 350,520 T740,480" />
<path d="M-20,600 Q200,560 420,620 T740,580" />
<path d="M100,-20 Q80,200 120,400 T90,740" />
<path d="M300,-20 Q280,180 320,380 T290,740" />
<path d="M550,-20 Q530,200 570,420 T540,740" />
</svg>
</div>
<div id="s2-terminal" class="terminal-window">
<canvas id="pong-canvas" class="pong-canvas" width="560" height="480"></canvas>
</div>
</div>
<!-- ═══ Scene 3: "The agentic loop" Title ═══ -->
<div id="s3" class="scene scene-title-agentic clip" data-start="3.25" data-duration="2.0" data-track-index="2">
<div class="title-text serif">
<span id="s3-w1" class="word">The</span>
<span id="s3-w2" class="word">agentic</span>
<span id="s3-w3" class="word">loop</span>
</div>
</div>
<!-- ═══ Scene 4: Extended Flow with Verify ═══ -->
<div id="s4" class="scene scene-flow-ext clip" data-start="4.75" data-duration="2.0" data-track-index="3">
<div class="flow-ext-wrap sans">
<div id="s4-action" class="s4-node s4-action">Take action</div>
<div id="s4-a1" class="s4-arrow s4-a1"><svg viewBox="0 0 36 14"><line x1="0" y1="7" x2="28" y2="7"/><polyline points="24,3 30,7 24,11"/></svg></div>
<div id="s4-verify" class="s4-node s4-verify">Verify results</div>
<div id="s4-a2" class="s4-arrow s4-a2"><svg viewBox="0 0 36 14"><line x1="0" y1="7" x2="28" y2="7"/><polyline points="24,3 30,7 24,11"/></svg></div>
<div id="s4-resp" class="s4-node s4-response">Response</div>
<div id="s4-fb-outer" class="s4-feedback-outer">
<svg viewBox="0 0 580 110"><path d="M560,0 L560,75 Q560,95 540,95 L40,95 Q20,95 20,75 L20,0"/></svg>
</div>
<div id="s4-fb-inner" class="s4-feedback-inner">
<svg viewBox="0 0 360 80"><path d="M340,0 L340,50 Q340,65 320,65 L40,65 Q20,65 20,50 L20,0"/></svg>
</div>
<div id="s4-vdash" class="s4-vert-dash"></div>
<div id="s4-label" class="s4-label">Agentic loop</div>
<div id="s4-dl" class="s4-label-dash-l"></div>
<div id="s4-dr" class="s4-label-dash-r"></div>
</div>
</div>
<!-- ═══ Scene 5: "Verification loops" Title ═══ -->
<div id="s5" class="scene scene-title-verify clip" data-start="6.5" data-duration="2.0" data-track-index="4">
<div class="title-text serif">
<span id="s5-w1" class="word">Verification</span>
<span id="s5-w2" class="word">loops</span>
</div>
</div>
<!-- ═══ Scene 6: Domain Validation Table ═══ -->
<div id="s6" class="scene scene-table clip" data-start="8.0" data-duration="2.25" data-track-index="5">
<div class="domain-table sans">
<div id="s6-header" class="table-header" style="opacity:0">
<span class="th-domain">DOMAIN</span>
<span class="th-behavior">VALIDATE BEHAVIOR</span>
</div>
<div id="s6-r1" class="table-row">
<div class="row-domain"><span class="domain-pill">Frontend</span></div>
<div class="row-behavior serif">Run dev server, click around, read console</div>
</div>
<div id="s6-r2" class="table-row">
<div class="row-domain"><span class="domain-pill">Backend</span></div>
<div class="row-behavior serif">Hit endpoint, send payload, check response</div>
</div>
<div id="s6-r3" class="table-row">
<div class="row-domain"><span class="domain-pill">Data</span></div>
<div class="row-behavior serif">Run migration on staging, check row counts</div>
</div>
<div id="s6-r4" class="table-row">
<div class="row-domain"><span class="domain-pill">Mobile</span></div>
<div class="row-behavior serif">Launch simulator, click around, watch logs</div>
</div>
<div id="s6-r5" class="table-row">
<div class="row-domain"><span class="domain-pill">Desktop</span></div>
<div class="row-behavior serif">Launch app, click around, watch logs</div>
</div>
</div>
</div>
<!-- ═══ Scene 7: Task Cards ═══ -->
<div id="s7" class="scene scene-cards clip" data-start="9.75" data-duration="1.75" data-track-index="6">
<div class="card-stack serif">
<div id="s7-c1" class="task-card">Make a change</div>
<div id="s7-c2" class="task-card">Clean it up</div>
<div id="s7-c3" class="task-card">Verify it works</div>
<div id="s7-c4" class="task-card">Commit</div>
<div id="s7-c5" class="task-card">Open a PR</div>
<div id="s7-c6" class="task-card">Get it reviewed</div>
<div id="s7-c7" class="task-card">Monitor CI</div>
</div>
</div>
<!-- ═══ Scene 8: SKILL.md Code Editor ═══ -->
<div id="s8" class="scene scene-code clip" data-start="11.0" data-duration="2.3" data-track-index="7">
<div class="code-editor" id="s8-editor">
<div class="code-titlebar mono">SKILL.md</div>
<div class="code-body mono">
<div id="s8-l1" class="code-line"><span class="line-num">1</span><span class="line-content"><span class="code-punct">---</span></span></div>
<div id="s8-l2" class="code-line"><span class="line-num">2</span><span class="line-content"><span class="code-keyword">name:</span> ship</span></div>
<div id="s8-l3" class="code-line"><span class="line-num">3</span><span class="line-content"><span class="code-keyword">description:</span> <span class="code-string">Take a finished change f...</span></span></div>
<div id="s8-l4" class="code-line"><span class="line-num">4</span><span class="line-content"><span class="code-punct">---</span></span></div>
<div id="s8-l5" class="code-line"><span class="line-num">5</span><span class="line-content">&nbsp;</span></div>
<div id="s8-l6" class="code-line"><span class="line-num">6</span><span class="line-content">1. Run <span class="code-string">`/simplify`</span> <span class="code-comment">— Code quality pas...</span></span></div>
<div id="s8-l7" class="code-line"><span class="line-num">7</span><span class="line-content">2. Run <span class="code-string">`/verify`</span> <span class="code-comment">— Edge-case sweep, r...</span></span></div>
<div id="s8-l8" class="code-line"><span class="line-num">8</span><span class="line-content"><span class="code-comment"> change end-to-end. Tests passing #...</span></span></div>
<div id="s8-l9" class="code-line"><span class="line-num">9</span><span class="line-content">3. Run <span class="code-string">`/design`</span> <span class="code-comment">— Design check if th...</span></span></div>
<div id="s8-l10" class="code-line"><span class="line-num">10</span><span class="line-content">4. Run <span class="code-string">`/pr`</span> <span class="code-comment">— Commit, push, open a P...</span></span></div>
<div id="s8-l11" class="code-line"><span class="line-num">11</span><span class="line-content">5. Run <span class="code-string">`/babysit`</span> <span class="code-comment">— Watch PR, fix fai...</span></span></div>
</div>
</div>
<div id="s8-cursor" class="code-cursor"><svg viewBox="0 0 24 34" fill="none"><path d="M5.5 2L5.5 24.5L10.5 19.5L15.5 28L19 26L14 17.5L21 17.5L5.5 2Z" fill="white" stroke="#141413" stroke-width="1.5" stroke-linejoin="round"/></svg></div>
</div>
</div>
<script>
window.__timelines = window.__timelines || {};
const tl = gsap.timeline({ paused: true });
// ═══ Scene 1: Flow Diagram Build (0 – 1.5s) ═══
// Each pill+arrow pair fades from 0→1 over ~0.4s. No pre-existing ghosts.
tl.to("#s1", { opacity: 1, duration: 0.01 }, 0);
tl.set(".flow-chain", { x: 250 }, 0);
// Hide everything initially
tl.set(["#s1-prompt","#s1-a1","#s1-gather","#s1-a2","#s1-action","#s1-a3","#s1-response"], { opacity: 0 }, 0);
// Prompt fades in alone (0→1 over 0.4s)
tl.to("#s1-prompt", { opacity: 1, duration: 0.4, ease: "power1.out" }, 0.05);
// Arrow 1 + Gather context fade in together
tl.to("#s1-a1", { opacity: 1, duration: 0.4, ease: "power1.out" }, 0.35);
tl.to("#s1-gather", { opacity: 1, duration: 0.4, ease: "power1.out" }, 0.35);
// Pan left as chain grows
tl.to(".flow-chain", { x: 120, duration: 0.5, ease: "power2.inOut" }, 0.5);
// Arrow 2 + Take action fade in together
tl.to("#s1-a2", { opacity: 1, duration: 0.4, ease: "power1.out" }, 0.7);
tl.to("#s1-action", { opacity: 1, duration: 0.4, ease: "power1.out" }, 0.7);
// Pan left more
tl.to(".flow-chain", { x: -10, duration: 0.5, ease: "power2.inOut" }, 0.85);
// Arrow 3 + Response fade in together
tl.to("#s1-a3", { opacity: 1, duration: 0.4, ease: "power1.out" }, 1.05);
tl.to("#s1-response", { opacity: 1, duration: 0.4, ease: "power1.out" }, 1.05);
// Final pan left
tl.to(".flow-chain", { x: -100, duration: 0.5, ease: "power2.inOut" }, 1.15);
// ═══ Transition 1→2: Fast dissolve ═══
tl.to("#s1", { opacity: 0, duration: 0.08 }, 1.6);
// ═══ Scene 2: Terminal (1.5 – 3.25s) ═══
tl.to("#s2", { opacity: 1, duration: 0.08 }, 1.6);
tl.from("#s2-terminal", { scale: 1.3, rotation: -3, opacity: 0, duration: 0.4, ease: "power3.out" }, 1.6);
// Terminal rotates during game
tl.to("#s2-terminal", { rotation: 12, scale: 1.3, x: -50, y: -30, duration: 1.5, ease: "power1.inOut" }, 1.7);
// Deterministic Canvas Pong simulation
const canvas = document.getElementById("pong-canvas");
const ctx = canvas.getContext("2d");
const W = 560, H = 480;
const PADDLE_W = 5, PADDLE_H = 44, BALL_S = 10;
const PADDLE_MARGIN = 35;
function simulatePong(t) {
const speed = 320;
let bx = W - 80, by = H * 0.7;
let vx = -speed, vy = -speed * 0.3;
let lpY = H * 0.7, rpY = H * 0.3;
const dt = 1 / 120;
const steps = Math.floor(t / dt);
for (let i = 0; i < steps; i++) {
bx += vx * dt;
by += vy * dt;
// Top/bottom wall bounce
if (by <= BALL_S / 2) { by = BALL_S / 2; vy = Math.abs(vy); }
if (by >= H - BALL_S / 2) { by = H - BALL_S / 2; vy = -Math.abs(vy); }
// Left paddle hit
if (bx <= PADDLE_MARGIN + PADDLE_W + BALL_S / 2 && vx < 0) {
if (by >= lpY - PADDLE_H / 2 - 8 && by <= lpY + PADDLE_H / 2 + 8) {
bx = PADDLE_MARGIN + PADDLE_W + BALL_S / 2;
vx = Math.abs(vx);
vy = (by - lpY) * 3.5;
}
}
// Right paddle hit
if (bx >= W - PADDLE_MARGIN - PADDLE_W - BALL_S / 2 && vx > 0) {
if (by >= rpY - PADDLE_H / 2 - 8 && by <= rpY + PADDLE_H / 2 + 8) {
bx = W - PADDLE_MARGIN - PADDLE_W - BALL_S / 2;
vx = -Math.abs(vx);
vy = (by - rpY) * 3.5;
}
}
// Reset if off-screen
if (bx < -20 || bx > W + 20) { bx = W / 2; by = H / 2; vx = speed * (bx > W / 2 ? -1 : 1); vy = speed * 0.4; }
// AI paddles track ball
const trackSpeed = 280 * dt;
if (vx < 0) { lpY += Math.sign(by - lpY) * Math.min(Math.abs(by - lpY), trackSpeed); }
else { rpY += Math.sign(by - rpY) * Math.min(Math.abs(by - rpY), trackSpeed); }
lpY = Math.max(PADDLE_H / 2, Math.min(H - PADDLE_H / 2, lpY));
rpY = Math.max(PADDLE_H / 2, Math.min(H - PADDLE_H / 2, rpY));
}
return { bx, by, lpY, rpY };
}
function drawPong(t) {
ctx.clearRect(0, 0, W, H);
const { bx, by, lpY, rpY } = simulatePong(t);
const col = "#E8E0D6";
// Center dashed line
ctx.strokeStyle = "rgba(255,255,255,0.15)";
ctx.lineWidth = 2;
ctx.setLineDash([6, 6]);
ctx.beginPath(); ctx.moveTo(W / 2, 0); ctx.lineTo(W / 2, H); ctx.stroke();
ctx.setLineDash([]);
// Left paddle
ctx.fillStyle = col;
ctx.fillRect(PADDLE_MARGIN, lpY - PADDLE_H / 2, PADDLE_W, PADDLE_H);
// Right paddle (fade in after 0.5s)
if (t > 0.5) {
const a = Math.min(1, (t - 0.5) / 0.3);
ctx.globalAlpha = a;
ctx.fillRect(W - PADDLE_MARGIN - PADDLE_W, rpY - PADDLE_H / 2, PADDLE_W, PADDLE_H);
ctx.globalAlpha = 1;
}
// Ball
ctx.fillStyle = col;
ctx.fillRect(bx - BALL_S / 2, by - BALL_S / 2, BALL_S, BALL_S);
}
// Drive Pong via GSAP progress tween (1.6s duration of pong scene)
const pongObj = { t: 0 };
tl.to(pongObj, {
t: 1.6,
duration: 1.6,
ease: "none",
onUpdate: function() { drawPong(pongObj.t); }
}, 1.6);
// ═══ Transition 2→3: Fast dissolve ═══
tl.to("#s2", { opacity: 0, duration: 0.1 }, 3.2);
tl.set("#s2", { opacity: 0 }, 3.25);
// ═══ Scene 3: "The agentic loop" (3.25 – 4.75s) ═══
tl.to("#s3", { opacity: 1, duration: 0.1 }, 3.2);
// Words fade from light gray → dark (color transition, not opacity)
tl.to("#s3-w1", { color: "#141413", duration: 0.35, ease: "power2.out" }, 3.3);
tl.to("#s3-w2", { color: "#141413", duration: 0.4, ease: "power2.out" }, 3.5);
tl.to("#s3-w3", { color: "#141413", duration: 0.45, ease: "power2.out" }, 3.7);
// ═══ Transition 3→4: Fast dissolve ═══
tl.to("#s3", { opacity: 0, duration: 0.1 }, 4.7);
tl.set("#s3", { opacity: 0 }, 4.75);
// ═══ Scene 4: Extended Flow with Verify (4.75 – 6.5s) ═══
tl.to("#s4", { opacity: 1, duration: 0.1 }, 4.7);
// Start: Take action + Response close together, no Verify
tl.set("#s4-resp", { left: 240 }, 4.75);
tl.set("#s4-a1", { left: 170 }, 4.75);
// Show outer feedback loop immediately
tl.to("#s4-fb-outer", { opacity: 1, duration: 0.3, ease: "power2.out" }, 4.85);
// Pan: spread Take action and Response apart to make room
tl.to("#s4-resp", { left: 460, duration: 0.6, ease: "power2.inOut" }, 5.2);
tl.to("#s4-fb-outer", { width: 580, duration: 0.6, ease: "power2.inOut" }, 5.2);
// Insert Verify results in the gap
tl.to("#s4-verify", { opacity: 1, duration: 0.35, ease: "power2.out" }, 5.5);
tl.to("#s4-a1", { opacity: 1, duration: 0.2 }, 5.5);
tl.to("#s4-a2", { opacity: 1, left: 400, duration: 0.3, ease: "power2.out" }, 5.6);
// Inner dashed feedback loop
tl.to("#s4-fb-inner", { opacity: 1, duration: 0.35, ease: "power2.out" }, 5.7);
// Vertical dashed line
tl.to("#s4-vdash", { opacity: 1, duration: 0.3, ease: "power2.out" }, 5.8);
// "Agentic loop" label + horizontal dashes
tl.to("#s4-label", { opacity: 1, duration: 0.3, ease: "power2.out" }, 5.9);
tl.to("#s4-dl", { opacity: 1, duration: 0.25, ease: "power2.out" }, 5.95);
tl.to("#s4-dr", { opacity: 1, duration: 0.25, ease: "power2.out" }, 5.95);
// ═══ Transition 4→5: Fast dissolve ═══
tl.to("#s4", { opacity: 0, duration: 0.1 }, 6.4);
tl.set("#s4", { opacity: 0 }, 6.5);
// ═══ Scene 5: "Verification loops" (6.5 – 8.0s) ═══
tl.to("#s5", { opacity: 1, duration: 0.1 }, 6.4);
tl.to("#s5-w1", { color: "#141413", duration: 0.35, ease: "power2.out" }, 6.55);
tl.to("#s5-w2", { color: "#141413", duration: 0.4, ease: "power2.out" }, 6.8);
// ═══ Transition 5→6 ═══
tl.to("#s5", { opacity: 0, duration: 0.1 }, 7.9);
tl.set("#s5", { opacity: 0 }, 8.0);
// ═══ Scene 6: Domain Table (8.0 – 9.75s) ═══
tl.to("#s6", { opacity: 1, duration: 0.1 }, 7.9);
tl.to("#s6-header", { opacity: 1, duration: 0.3, ease: "power2.out" }, 8.1);
tl.to("#s6-r1", { opacity: 1, y: 0, duration: 0.35, ease: "power2.out" }, 8.3);
tl.from("#s6-r1", { y: 15 }, 8.3);
tl.to("#s6-r2", { opacity: 1, y: 0, duration: 0.35, ease: "power2.out" }, 8.55);
tl.from("#s6-r2", { y: 15 }, 8.55);
tl.to("#s6-r3", { opacity: 1, y: 0, duration: 0.35, ease: "power2.out" }, 8.8);
tl.from("#s6-r3", { y: 15 }, 8.8);
tl.to("#s6-r4", { opacity: 1, y: 0, duration: 0.35, ease: "power2.out" }, 9.05);
tl.from("#s6-r4", { y: 15 }, 9.05);
tl.to("#s6-r5", { opacity: 1, y: 0, duration: 0.35, ease: "power2.out" }, 9.3);
tl.from("#s6-r5", { y: 15 }, 9.3);
// ═══ Transition 6→7 ═══
tl.to("#s6", { opacity: 0, duration: 0.1 }, 9.65);
tl.set("#s6", { opacity: 0 }, 9.75);
// ═══ Scene 7: Task Cards (9.75 – 11.0s) ═══
tl.to("#s7", { opacity: 1, duration: 0.1 }, 9.65);
const cards = ["#s7-c1", "#s7-c2", "#s7-c3", "#s7-c4", "#s7-c5", "#s7-c6", "#s7-c7"];
cards.forEach((c, i) => {
tl.to(c, { opacity: 1, duration: 0.25, ease: "power2.out" }, 9.85 + i * 0.12);
tl.from(c, { y: 20, duration: 0.3, ease: "power2.out" }, 9.85 + i * 0.12);
});
// ═══ Transition 7→8 ═══
tl.to("#s7", { opacity: 0, duration: 0.1 }, 10.9);
tl.set("#s7", { opacity: 0 }, 11.0);
// ═══ Scene 8: Code Editor (11.0 – 13.3s) ═══
tl.to("#s8", { opacity: 1, duration: 0.1 }, 10.9);
tl.from("#s8-editor", { y: 30, scale: 0.95, duration: 0.5, ease: "power3.out" }, 11.0);
// Lines appear
const lines = ["#s8-l1","#s8-l2","#s8-l3","#s8-l4","#s8-l5","#s8-l6","#s8-l7","#s8-l8","#s8-l9","#s8-l10","#s8-l11"];
lines.forEach((l, i) => {
tl.to(l, { opacity: 1, duration: 0.15, ease: "power1.out" }, 11.2 + i * 0.08);
});
// Cursor appears from bottom-right, moves to /verify on line 7
tl.set("#s8-cursor", { x: 550, y: 550 }, 11.6);
tl.to("#s8-cursor", { opacity: 1, duration: 0.2 }, 11.8);
tl.to("#s8-cursor", { x: 240, y: 395, duration: 0.6, ease: "power2.out" }, 11.9);
// Settle on /verify, small drift
tl.to("#s8-cursor", { x: 235, y: 390, duration: 0.5, ease: "power1.inOut" }, 12.5);
// Slight movement as if reading down
tl.to("#s8-cursor", { x: 245, y: 400, duration: 0.5, ease: "power1.inOut" }, 13.0);
// Zoom into editor as cursor settles
tl.to("#s8-editor", { scale: 1.05, duration: 1.2, ease: "power1.inOut" }, 12.0);
window.__timelines["main"] = tl;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment