byheygen-com· 46 skills
House-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 needs a cheap high-yield source of motion to carry the viewer's eye and segment them out of the stale state. Covers cursor size/look (incl. brand-motif cursors), the off-screen entry law, tip-targeting and the click tap, click-ignites-the-next-beat, and exit / cross-scene handoff.
$npx -y skills add heygen-com/hyperframes --skill oversized-cursorInstalls into the current project.
Run `npx skills use "https://github.com/heygen-com/hyperframes" --skill "heygen-com/hyperframes/oversized-cursor"` and follow the generated skill instructions now. Read its complete output, redirecting it to a temporary file first if necessary. Resolve relative paths from the supporting-files directory it provides.
Use the skills in "https://github.com/heygen-com/hyperframes" that are relevant to the current task. Run `npx skills add "https://github.com/heygen-com/hyperframes"` and select the relevant skills, then follow their instructions.
| 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 (typing, narration), the cursor **drifts aside** |
| 103 | (0.5–0.9s, `power2.out`) — never sits frozen on top of the action, never wobbles idly. |
| 104 | |
| 105 | ## Exit law & cross-scene handoff |
| 106 | |
| 107 | Two sanctioned exits — both physical, **never an opacity fade in place**: |
| 108 | |
| 109 | 1. **Leave the frame**: accelerate off the nearest edge with `power2.in` |
| 110 | (`left:'118%'`, `left:'-12%'`, or `top:'116%'`), 0.5–0.7s. |
| 111 | 2. **Cut-the-curve handoff**: in the final ~0.3s before a hard cut, the cursor starts |
| 112 | accelerating (`power2.in`) toward the NEXT scene's first click point, covering the |
| 113 | first ~1/3 of that path; the next composition `gsap.set`s the cursor at the |
| 114 | handoff pose and continues with `power2.out` at matched velocity. The cursor itself |
| 115 | becomes the carrier element that stitches the seam: |
| 116 | |
| 117 | ```js |
| 118 | // scene A, last 0.3s — start the journey: |
| 119 | tl.to(cursor, { left: "40.7%", top: "63.7%", duration: 0.3, ease: "power2.in" }, CUT - 0.3); |
| 120 | // scene B, t=0 — finish it at matched velocity: |
| 121 | gsap.set(cursorB, { left: "40.7%", top: "63.7%" }); |
| 122 | tl.to(cursorB, { left: "22%", top: "45%", duration: 0.6, ease: "power2.out" }, 0); |
| 123 | ``` |
| 124 | |
| 125 | ## Checklist |
| 126 | |
| 127 | - [ ] ≥ 7cqw full-frame (4.6–5.5cqw inside a mock) — when unsure, bigger |
| 128 | - [ ] enters from off-screen on one continuous vector (no fade/mask reveal) |
| 129 | - [ ] tip lands on the target center; press pivots on `transformOrigin: '21% 14%'` |
| 130 | - [ ] every click causes something, same-frame |
| 131 | - [ ] drifts aside during beats it doesn't own; zero idle wobble |
| 132 | - [ ] exits physically (off-frame or cut-the-curve handoff) — no fade-in-place |