Replace homepage hero code selector with GSAP agent-loop animation - #21134
Conversation
The homepage hero's right slot becomes a single GSAP-driven inline SVG narrating the agentic loop from design's 7-frame storyboard (Figma Storyboards R2, 752:19223): a prompt goes to an agent, the agent writes the Pulumi VPC program, CI checks pass and roll up into a summary pill, a platform agent runs pulumi up under policy, and the AWS VPC diagram grows in. Plays once (~20s), holds on the finished diagram, loops. - The scene is one morphing surface (tile -> code panel -> CI pill) plus a second shell (terminal -> policy pill); geometry is lifted verbatim from the storyboard exports, and code/terminal text is re-authored as per-line <text> elements at exact Figma metrics (Monaspace Neon 7.44141px advance), revealed by clip rects — no JS text measurement. - Authored in the finished frame-7 state, so prefers-reduced-motion and no-JS readers get the static finished frame with no layout shift; the script pauses offscreen and on hidden tabs. - template-hero gains hero_animation as the highest-precedence right-slot option (split layout); the code-snippets composite stays for the four other pages that use it. The homepage's removed code_snippets block is preserved in the workspace .context for reference. - Monaspace preload no longer skips the homepage — the hero now types monospace above the fold. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ixes Round of design feedback on the agent-loop hero: - The program and pulumi up stream now live in data/hero_agent_loop.yaml as colored text runs; a single _code-lines.html partial derives every tspan x position from monospace column math (verified within 0.001px of the Figma export), so editing the examples means editing plain YAML strings. The seven scene partials collapse into agent-loop.html plus that renderer. - Subnet cubes now extrude isometrically: the top face drops onto the bottom face and rises while the vertical edges scale up in lockstep, instead of the whole cube zooming in from a point. - The viewBox crops the 744x550 canvas to the artwork bounds (98 22 553 506), so the scene fills its frame — noticeably larger on mobile. - Strokes get vector-effect: non-scaling-stroke, except the three dash-drawn rects (tile working stroke, badge borders): Chrome measures their pathLength-normalized dashes in screen units under that effect, which blanked the code panel border and leaked pill-border slivers. Dashes are also cleared after each draw-on completes, and the hidden dash state carries margin so no boundary sliver parks visible. - Fixed the pending spinner arcs orbiting off-center (wrong sweep flag put the arc's center a radius away from the solid dot). - Fixed the block cursor left floating on the next loop's opening frame: zero-duration caret sets rewound to stale values when the playhead wrapped, so caret visibility now runs through callbacks that reset() alone can override; the prompt caret also appears with the first typed character rather than ahead of it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two artwork corrections from the storyboard exports: the GitPullRequest icon sits 10px left of its exported position (the slide-in lands on the same offset), and us-east-2a now paints in front of us-east-2b — the cubes' DOM order is the isometric depth order, with data-order carrying the original left-to-right extrusion stagger. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each pass (page load and every loop) now picks the agent that answers the prompt: Claude Code 66%, Codex 15%, Cursor 8%, opencode 4%, GitHub Copilot 3.5%, Pulumi Neo 3.5%. - All six tiles are now uniform (rect + data-tile-logo group, including a Claude Code tile authored at tile coordinates); shell A starts at the chosen tile's cell, derived from its rect at pick time. - The handover is a single callback right before the morph: the chosen tile's logo moves into the glyph wrapper at unchanged user-space coordinates while shell A's fill replaces the tile rect — invisible swap, and every tween keeps fixed targets. reset() sends the logo home and re-picks on each loop. - Logos anchor by bbox bottom-center to the shared perch point (the storyboard's stations are all "bottom edge ~12.6px above the surface below"), so no per-logo tuning; the viewBox gains 8px of headroom for the tallest marks at the plate station. The robot stays baked in as the static finished frame for no-JS and reduced motion. - The timeline uses repeatRefresh with function-based glyph/halo values so per-pass geometry re-records on every loop; proxy objects the typing and roll-up tweens mutate are rewound by reset(). - Fixes the missing CI checks, tests badge, and policy badge from the second loop on: the closing collapse fades those groups and reset() never restored their visibility. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The four pending spinners rotate at uneven phase offsets so they no longer read as one synchronized ring, and the pulumi up stream gains the Policy Packs run table (cis-aws, nist-aws, pci-dss-aws, iso-27001-aws — matching the four policy stacks below) between the Resources summary and Duration. The scroll end extends to land on the longer tail. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comments removed from hero-animation.ts, the hero SCSS, and the scene partial's section banners (the partial and data-file headers stay — they document the calling/editing interface). Where a comment was doing naming work the code now does it: agent weights are keyed by data-agent instead of positional order, the hidden dash state is a named constant, and the PR icon's resting offset is named rather than baked into tween endpoints. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The homepage's code_snippets composite config returns to content/_index.md
instead of living only outside the repo, and template-hero gains an
explicit hero_visual key ("animation", "code", "video", "image") so
alternate visuals can stay fully configured while one is active — on the
homepage, hero_visual: code restores the classic language selector in a
one-word change. Pages without hero_visual keep the existing precedence
(hero_animation > code_snippets > video_youtube_id > image).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The editor and terminal examples are now plain-text sources at the top of data/hero_agent_loop.yaml; `yarn --cwd theme gen:hero-text` re-highlights them with shiki (min-light theme, ts + bash — the same scheme the storyboards used; the editor output matches the Figma export character for character) and rewrites the generated run sections the partial renders. shiki is a devDependency used only by the script, so the page bundle is unchanged (~30KB gz). Regenerating normalizes a few terminal colors to canonical min-light-bash: multi-word phrases like "Loading policy packs..." keep only the command word purple, the Policy Packs table gets purple pack names and blue versions, and "1m47s" drops its blue digit. Text and geometry are byte-identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Your site preview for commit 288fe06 is ready! 🎉 http://www-testing-pulumi-docs-origin-pr-21134-288fe067.s3-website.us-west-2.amazonaws.com Changed pages: |
Lighthouse Performance ReportCommit: 288fe06 | Metric definitions
|
Each pass now also picks a uniform-random language alongside the weighted-random agent, per the updated storyboards (frames 1-2): - A row of seven language tiles (TypeScript, Python, Go, C#, Java, HCL, YAML) enters with the agent grid; after the agent takes the double outline, the chosen language gets the same selection chrome and the unselected agent and language logos recede to violet-400. - The chosen language's icon travels to the code panel's upper-right corner during the morph (same adoption mechanic as the protagonist glyph, anchored by bbox center) and fades with the panel at roll-up. - data/hero_agent_loop.yaml carries one example per language, adapted from the classic code-selector hero to fit the panel's 13 rows; the shiki generator highlights each with its own grammar (all seven land within min-light's existing 7-color palette) and fails the run if an example outgrows the panel. - The typing beat is one fixed-duration progress tween mapped onto the active language's line structure at pick time (blank source lines become pauses), so the timeline stays static while line counts and lengths vary per pass; long lines clip at the panel edge. - reset() kills any in-flight recolor tweens before restoring logo fills, so a stale dim can never carry into the next pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ted picks The language row becomes the storyboard's label pill (same geometry as the prompt pill): TS PY GO C# JAVA HCL YAML, centered flow layout with a constant gap derived from the monospace metrics. On selection the chosen label gains its 18px icon and a rounded ring, expands to its full name where one exists (TYPESCRIPT, PYTHON), and the row reflows around it while the other labels recede to violet-400; the icon then travels to the code panel's corner, scaling from 18px to its 23.4px panel size via one manual translate+scale transform. Layout positions are computed per pass, so both storyboard states reproduce exactly (TS-selected verified against frame 1's coordinates). Language picks are now weighted by real usage share with brand-new HCL boosted above YAML: TypeScript 51, Python 29, Go 7.5, C# 5, HCL 3.5, YAML 3, Java 1. The agent picker shares the same weighted-pick helper. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The language selection now settles for ~0.8s — ring, icon, and expanded name all on screen — before the grid collapses and the tile morphs into the code panel; the write beat and everything after shift accordingly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
15px instead of the storyboard's 23.4, centered at 615.5,172.5 — clear of the second code line even at full width. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…bels The selection reflow stopped moving the other language labels from the second loop on: the slide used per-target function-based x values, which did not re-evaluate under repeatRefresh. It now runs through a proxy tween whose onUpdate reads the current pass's layout, the same pattern the roll-up and icon travel already use; verified across three loops with different picks. The rest-state labels are also justified across the full pill instead of grouping in the middle, which makes the selection's gather-and-reflow much more visible. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Craft fixes from a review against the piece's motion contract, all in the anticipation / never-opacity-only family: - The language selection ring pops from inset geometry instead of fading in place (the same treatment the agent halo gets), and the language icon scale-settles in with back.out rather than fading. - The chosen agent tile dips to 0.965 as its working stroke starts drawing — the press that causes the outline. - The PR icon slides out the way it slid in at the merge swap. - The closing collapse adds a slight scale drift on the diagram so the exit has depth. Ring geometry verified across loops with different picks in both orders. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reset guard for the spawned icon pop used gsap.killTweensOf(iconT), which also killed the timeline's travel tween on the same proxy — alive on loop 1 only because reset first runs before the timeline exists. The pop is now tracked and killed individually. Icon transform verified identical at the panel corner across three loops with mixed picks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Preview and production builds run hugo --minify, whose HTML minifier strips xml:space and collapses whitespace inside the SVG tspans — the leading-pad spaces that carried code indentation and terminal column alignment vanished on deploys while local dev (no minify) looked fine. Generated runs are now [color, startColumn, text] segments: the renderer positions every tspan from its column offset, and segment text never begins with a space or contains consecutive spaces (single interior spaces survive minification). Verified by rebuilding with --minify and reconstructing all seven editor examples character for character from the minified output. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conflicts were confined to theme/package.json (both sides appended a script — kept gen:hero-text and test-support-form) and theme/yarn.lock (regenerated via yarn install's automatic lockfile merge). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
data/hero_agent_loop.yaml is now purely the human-editable plain-text sources; the generator writes the colored run segments to data/hero_agent_loop_generated.yaml (with a GENERATED — DO NOT EDIT header), and the hero partial renders from the generated file. No more mixed file where hand edits below a marker would be silently overwritten. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pre-merge Review — Last updated 2026-08-26T20:03:41ZTip Summary: This PR replaces the homepage hero's language-selector code composite with a GSAP-driven inline SVG that plays the agentic loop (prompt → agent writes a VPC program → CI passes → Review confidence:
Investigation log
🔍 Verification trail128 claims extracted · 23 verified · 1 unverifiable · 0 contradicted
Important Please don't hide, resolve, or delete this comment! It breaks things! 📖 How pre-merge review works — the full lifecycle, short-circuits, and escape hatches. |
🚨 Outstanding in this PRNo outstanding findings in this PR.
|
- Prompt reads "Give me a VPC with a subnet in every AZ." at 13.5px;
sync promptChars/CW_PROMPT so the trailing period reveals cleanly.
- Badge labels tightened to "TESTS PASSED" / "POLICY CHECKS PASSED",
with pills re-measured to keep matched insets and right alignment.
- Role label is singular ("PLATFORM AGENT").
- Terminal output reworked to mirror a real pulumi up run.
- Extend TERM_SCROLL_END to -862 so the longer terminal scrolls the
full tail (Outputs -> Policy Packs -> Duration) into view.
- Homepage hero copy: "infrastructure as software"; refresh language mix.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cnunciato
left a comment
There was a problem hiding this comment.
This looks great! Made a few tweaks to some copy and adjusted the measurements to make everything fit.
The only thing I noticed (which we can definitely address as a follow-up) is that at narrower widths, the animation is slightly off center, and vertical whitespace feels like it could be tightened. So we may want to make a few tweaks to address that:
resizing.mp4
Otherwise, this is good to go. I'll merge and we can come back to it once I verify all's well in a few other browsers.
- Play the agent-loop scene a single time and rest on the completed diagram instead of looping (repeat 0; drop the exit fade). - Terminal copy: "Running Pulumi..." / "pulumi up" and "Policies applied:"; regenerate the highlighted runs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Change the terminal's opening status line to "Tests passed. Deploying." Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Trim the platform description to end on "— safely." Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Proposed changes
Replaces the homepage hero's code selector composite with a GSAP-driven inline SVG that plays the agentic loop from design's storyboards (Figma "Storyboards R2", node 752:19223): a prompt goes to an agent, the agent writes the VPC program in a chosen language, CI checks pass, a platform agent runs
pulumi upunder policy, and the AWS VPC diagram grows in. One ~23s pass, then it loops with a fresh agent and language.hero-animation.ts(AGENT_WEIGHTS/LANG_WEIGHTS). The static no-JS/reduced-motion frame always shows Claude Code with no language chrome.prefers-reduced-motionrender the final frame statically with no layout shift; the animation pauses offscreen and on hidden tabs.data/hero_agent_loop.yaml— editing the content means editing those and runningyarn --cwd theme gen:hero-text, which re-highlights them with shiki (min-light, each language's own grammar plus bash) and rewrites the generated sections underneath. shiki is a devDependency used only by that script; nothing highlight-related runs at build or page-load time. The generator fails if an example outgrows the panel's 13 rows - note: adding or removing terminal rows means shiftingTERM_SCROLL_ENDby 18px per row.hugo --minify(preview/production only) collapses whitespace inside the tspans.template-hero.htmlgainshero_animation, plus an explicithero_visualkey ("animation", "code", "video", "image") so alternate visuals can stay fully configured while one is active; pages without it keep the existing precedence. The homepage keeps its fullcode_snippetsblock configured, sohero_visual: coderestores the classic selector in a one-word change. The composite itself is untouched and still used by/product/infrastructure-as-code,/gcp,/azure, and/kubernetes.hero-animationwebpack entry loaded only by the homepage, ~31KB gzipped including the newgsapdependency (core only).vector-effect: non-scaling-strokeexcept the dash-drawn rects, since Chrome measures their dashes in screen units under that effect.🤖 Generated with Claude Code