$npx -y skills add heygen-com/hyperframes --skill oversized-cursorHouse-style oversized macOS cursor technique for HyperFrames launch videos. Load whenever a scene involves cursors or a pointer-led action, when kicking off a UI scene, when igniting a morph/transition/typing run with a click, or when a scene reads as static, dead, or stale and n
| 1 | # Oversized Cursor — the eye-carrier |
| 2 | |
| 3 | A deliberately oversized macOS-style pointer that travels the frame as a _visible |
| 4 | protagonist_: it enters from off-screen, walks the viewer's eye to the next point of |
| 5 | interest, clicks to cause the next thing that happens, and leaves. Production-proven |
| 6 | across multiple launch films. |
| 7 | |
| 8 | **Why it exists.** Big cursor movement is one of the cheapest high-yield motion sources |
| 9 | in a launch video: one element, transform-only tweens, and it (1) brings the eye across |
| 10 | the screen on scenes that would otherwise read as dead, (2) gives causal ignition to |
| 11 | morphs/transitions ("the click did that"), and (3) segments the eye out of a stale |
| 12 | state when kicking off a new scene or a complex animation sequence. Bigger is better — |
| 13 | an actual-size cursor disappears at video scale. |
| 14 | |
| 15 | ## Size & look (house convention) |
| 16 | |
| 17 | - **Full-frame scenes: `7cqw`** (≈134px at 1920). In-mock / small-frame variants: |
| 18 | `4.6–5.5cqw`. Never smaller. |
| 19 | - One SVG arrow geometry everywhere. Two proven fills — white body + black stroke, or |
| 20 | black body (`#1c1c1c`) + white stroke (1.4px). Pick per scene contrast, keep it |
| 21 | constant per film. |
| 22 | - **Brand-motif cursors (the power play).** The macOS arrow is the DEFAULT, not a |
| 23 | mandate. When the subject brand has a recognizable cursor identity — a collaborative |
| 24 | design tool's colored multiplayer arrow with a name tag (Figma-style), a creative |
| 25 | suite's precision crosshair, a distinctive product pointer — use THAT cursor instead: |
| 26 | instantly legible brand language for anyone who knows the product. Same laws apply |
| 27 | unchanged (oversized scale, physical entry/exit, tip-targeting, click-ignition), and |
| 28 | a name-tag variant travels as one rigid unit (tag trailing the arrow). Reach for it |
| 29 | only when the motif is genuinely referenceable; a cursor nobody recognizes is just a |
| 30 | weird arrow — default back to macOS. |
| 31 | - `filter: drop-shadow(0 4px 6px rgba(0,0,0,.3))`, `pointer-events: none`, |
| 32 | `z-index` above all scene content, `will-change: transform`. |
| 33 | |
| 34 | ```css |
| 35 | #root .cursor { |
| 36 | position: absolute; |
| 37 | left: 48%; |
| 38 | top: 115%; /* off-screen below — the resting pose IS off-screen */ |
| 39 | width: 7cqw; |
| 40 | height: 7cqw; |
| 41 | z-index: 20; |
| 42 | filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.3)); |
| 43 | pointer-events: none; |
| 44 | will-change: transform; |
| 45 | } |
| 46 | ``` |
| 47 | |
| 48 | ## Entry law — physical, never revealed |
| 49 | |
| 50 | The cursor **always enters from off-screen** (canonical: from below, `top:115–120%`) |
| 51 | and travels to its first target in one decelerating glide. It must _feel like it |
| 52 | entered the room_. Never opacity-fade it in at a resting position, never mask-reveal |
| 53 | it — that reads as a glitch (a real, repeatedly observed failure mode). |
| 54 | |
| 55 | - Default path: **straight up the y-axis** to the target — no fragmented diagonals. |
| 56 | A diagonal is fine when it IS the story (entering toward an off-axis target), but it |
| 57 | is one continuous vector either way. |
| 58 | - `duration: 0.4–0.92s`, `ease: power3.out`, `immediateRender: false` on the fromTo. |
| 59 | |
| 60 | ```js |
| 61 | tl.fromTo( |
| 62 | cursor, |
| 63 | { left: "48.6%", top: "115%" }, |
| 64 | { left: "48.6%", top: "55%", duration: 0.85, ease: "power3.out", immediateRender: false }, |
| 65 | 0.25, |
| 66 | ); |
| 67 | ``` |
| 68 | |
| 69 | ## Tip-targeting & the click tap |
| 70 | |
| 71 | The hot-spot is the arrow TIP, not the box center. Land the **tip** on the target's |
| 72 | center, and pivot all press scaling on the tip: `transformOrigin: '21% 14%'` (for the |
| 73 | house arrow path in a 24-unit viewBox). |
| 74 | |
| 75 | Click = asymmetric compress/expand (1:2 ratio reads as a real tap): |
| 76 | |
| 77 | ```js |
| 78 | tl.to(cursor, { scale: 0.84, duration: 0.1, ease: "power2.in", transformOrigin: "21% 14%" }, t); |
| 79 | tl.to( |
| 80 | cursor, |
| 81 | { scale: 1, duration: 0.22, ease: "power2.out", transformOrigin: "21% 14%" }, |
| 82 | t + 0.1, |
| 83 | ); |
| 84 | ``` |
| 85 | |
| 86 | **The target's reaction is a separate, parallel tween** (button: `scale: 0.94` + press |
| 87 | color/shadow, starting at the same `t`). Cursor-only taps (e.g. focusing a text input) |
| 88 | get NO target reaction. Pair with `cursor-click-ripple` / `press-release-spring` for |
| 89 | the target side. |
| 90 | |
| 91 | ## The click IGNITES the next beat |
| 92 | |
| 93 | Never let a morph, typing run, window transform, or scene-defining animation simply |
| 94 | _start_. Park the cursor on the trigger and let the click cause it, same-frame: |
| 95 | |
| 96 | - click ▸ menu/submenu cascade, toggle flip |
| 97 | - click ▸ typing kickoff into an input |
| 98 | - click ▸ composer morph-down / window shrink |
| 99 | - click ▸ logo ignition / flight launch |
| 100 | - click ▸ play-state flip + UI-life wake in a product mock |
| 101 | |
| 102 | During long beats it doesn't own (typ |