Checker contrast error on the first check: the thumbnail's faint 'NEXT VIDEO' texture word (#3d3d3d on #1c1c1c, 1.57:1) failed WCAG — raised to #676767 (the checker's suggested value) before rendering.
Checker type-floor warnings: fine print raised 15px→19px and the subscribe card's sub-line shortened to 'WEEKLY BUILDS' at 19px so nothing sits under the 19px floor.
film_silent warning left as-is: end screens are silent by design (YouTube plays the video's own audio under them). First render (52.4s) was the final render.
Original promptTested
YouTube end screen — HyperFrames prompt (subscribe + next video cards)
Banned list —Beat grid —Build method —Self-review —
<direction>
Build a 20-second YouTube end screen as a single HyperFrames composition, 1280x720, 30fps. This film sits UNDER YouTube's own clickable end-screen elements, so it is a calm backdrop with three clear zones — it must never fight for attention with fast motion.
House style: background #0a0a0a, white type, ONE orange accent #ff5c1a, Arial/Helvetica bold only. NO webfonts, no gradients, no glows, no 3D.
HARD LAYOUT RULE: every element stays inside YouTube's end-screen safe zones — at least 40px from every edge of the frame.
Channel name: FRAME BY FRAME. Next video title: I BUILT A DESK SETUP FOR $200.
Banned: any animation faster than a gentle pulse after 1.5s, flashing, spinning, elements entering from off-frame edges, text smaller than 19px.
</direction>
<structure>
0.0-1.5s — All three cards animate in once, staggered: LEFT next-video card slides in from x-36 (starts 0.1s), RIGHT-TOP playlist card slides in from x+36 (starts 0.45s), CENTRE-BOTTOM subscribe card rises 26px (starts 0.8s), fine print fades in at 1.0s.
LEFT card (x60, y120, 480 wide): orange kicker "WATCH NEXT", a 480x270 thumbnail block (dark fill, thin border, faint "NEXT VIDEO" texture word, orange circle play button with a white triangle at its centre), and I BUILT A DESK SETUP FOR $200 in 27px bold white under the block.
RIGHT-TOP card (x740, y120, 480 wide): orange kicker "PLAYLIST", a stacked-cards graphic (three offset bordered rectangles), the front card reading "FULL SERIES →".
CENTRE-BOTTOM subscribe card (x340, y528, 600 wide): avatar circle with the channel initials, FRAME BY FRAME in 25px, a small grey weekly-uploads line, an orange "SUBSCRIBE" pill, and a white bell glyph.
1.5-20.0s — Long gentle hold: the play button pulses softly every ~5s, the bell glyph wiggles every ~5s (at ~5s, ~10s, ~15s) with a small subscribe-pill pulse after each wiggle. Nothing else moves.
Bottom edge fine print, centred: "END SCREEN — ELEMENTS SIT INSIDE YOUTUBE SAFE ZONES".
</structure>
<build>
One root div, data-composition-id "main", data-duration 20, 1280x720. Group each card's pieces inside one .clip container div per card (with data-start/data-duration/data-track-index) and animate the containers, not the pieces. Draw the play triangle with CSS borders and the bell as a small inline SVG — no icon fonts, no images. Build ONE paused GSAP timeline, register it as window.__timelines["main"], and end with tl.seek(0). Load GSAP from a local gsap.min.js file only — never a CDN. Schedule the hold pulses at absolute times on the same timeline so the render is deterministic.
</build>
<gotchas>
- YouTube overlays its own clickable elements on the end screen: if your cards sit outside the safe zones or keep moving, the real buttons look broken. Gentle is a requirement, not a taste.
- The subscribe card is centre-BOTTOM: keep its bottom edge at least 60px above the fine print line or the two collide visually.
- The stacked-cards graphic reads as one card unless the offsets are at least 24px and each card keeps a visible border.
- A 20s render punishes re-dos: snapshot at 6s, 14s and 19.9s before the full render and confirm the hold still looks identical at all three.
</gotchas>
Before you finish: step through the timeline at five points and fix anything that overlaps, clips the frame, or drifts off the beat grid.
Rendered as prompted on the first pass: all three cards sit inside the 40px safe zones, the bell wiggles at ~5s/10s/15s and the 6s/14s/19.9s stills are identical holds as an end screen should be. Pre-render fixes were checker-driven only (see whatBroke).