duo
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDuo
Duo
One fixed 1448×1086 @ 30fps composition: a photo of two hands holding an open
foldable, with both screens blanked. You fill the two screen slots with HTML
(live video, a mock chat, a scrolling feed, anything HyperFrames renders) and
the rig masks it to the phone's true rounded-corner geometry.

The phone and hands are a photograph, not something you build.
IS the device. Never recreate, redraw, or CSS-model the
foldable, its bezel, the hinge, or the hands, and never substitute a different
image. copies the plate into every project; if it is missing, stop
and reinstall the skill rather than improvising a phone.
assets/plate.pngbuild.mjsDo not edit the rig. The two rects, their corner radii and the
hinge divider were measured from that photo pixel by pixel. Every visual change
you make happens inside and ,
plus the one shared GSAP timeline.
.screen#screen-left .content#screen-right .content固定的 1448×1086 @ 30fps 构图:一张双手手持打开的折叠手机的照片,
两个屏幕均为空白。你用 HTML
(实时视频、模拟聊天、滚动信息流,以及 HyperFrames 能渲染的任何内容)填充两个屏幕插槽,
rig 会通过遮罩将其适配到手机真实的圆角几何结构中。

手机和双手来自照片,不是由你构建出来的。
就是设备本身。绝不要重新创建、重绘,
或使用 CSS 对折叠手机、边框、铰链或双手建模,
也绝不要替换成其他图片。 会将底板复制到每个项目中;
如果它缺失,请停止操作并重新安装 skill,而不是临时拼凑一部手机。
assets/plate.pngbuild.mjs不要编辑 rig。 两个 矩形、它们的圆角半径以及
铰链分隔线都是根据那张照片逐像素测量得出的。你所做的每一项视觉改动,
都只能发生在 和 内,
此外只能使用那一条共享的 GSAP timeline。
.screen#screen-left .content#screen-right .contentWhen to use / when not to
何时使用 / 何时不要使用
- Use for any "two things side by side on a phone" beat: app vs app, feed vs feed, two chats answering the same prompt, two versions of a product.
- Do not use when the user wants a single phone, a laptop, or a real device
bezel they supply — this skill is one specific photo. For a different device
plate you would re-measure geometry the same way (see
) rather than stretch this one.
references/screen-geometry.md
- 用于任何“在一部手机上并排展示两个内容”的场景:应用 vs 应用、信息流 vs 信息流、两个聊天窗口回答同一个提示词、同一产品的两个版本。
- 当用户想要单台手机、笔记本电脑,或自己提供的真实设备边框时,不要使用——
这个 skill 对应的是一张特定的照片。如果要使用其他设备底板,应以相同方式
重新测量几何结构(见 ),而不是拉伸当前底板。
references/screen-geometry.md
Requirements
要求
- Node 18+ and the HyperFrames CLI via (
npx hyperframes@latestis mutable; pin a version for byte-identical re-renders).@latest - Load your motion doctrine first if your workspace has one. The rig's only built-in motion is one slow camera push; everything inside the screens must perform (scrolls, swipes, typing, taps), never idle-wobble.
- 需要 Node 18+,并通过 使用 HyperFrames CLI (
npx hyperframes@latest是可变的;如需逐字节一致的重新渲染,请固定版本)。@latest - 如果工作区中有 motion doctrine,请先加载它。rig 唯一内置的动效 是一次缓慢的镜头推进;屏幕内的所有内容都必须执行动作 (滚动、滑动、输入、点击),绝不能只是闲置晃动。
Network and side effects (complete list)
网络与副作用(完整清单)
- — the HyperFrames CLI itself, via
registry.npmjs.org.npx - — the composition loads GSAP (pinned
cdn.jsdelivr.net) at preview/render time. Rendering is not fully offline.3.14.2 - Anything YOU add to the screens (video clips, avatars, fonts) is your side
effect: fetching a site, downloading media, or scraping UI happens only if the
user's request calls for real content, and only from sources they are entitled
to use. documents how, and the rights caveat.
references/sourcing-real-ui.md
No credentials, no paid operations, no telemetry. writes only
inside and refuses to write through symlinks.
build.mjs--out- — 通过
registry.npmjs.org获取 HyperFrames CLI 本身。npx - — 合成内容会在预览/渲染时加载 GSAP(固定为
cdn.jsdelivr.net)。 渲染并非完全离线。3.14.2 - 任何由 YOU 添加到屏幕中的内容(视频片段、头像、字体)都属于你的副作用:
只有当用户请求真实内容时,才会访问站点、下载媒体或抓取 UI,而且只能使用
用户有权使用的来源。记录了具体方法以及版权注意事项。
references/sourcing-real-ui.md
不需要凭据、不执行付费操作,也不进行遥测。 只会写入
目录内,并拒绝通过符号链接写入。
build.mjs--outFlow
流程
<SKILL_DIR>~/.claude/skills/duo- Scaffold a project:
bash
node <SKILL_DIR>/scripts/build.mjs --out ./foldable-meme --duration 10 --icons tiktok,instagram--iconsassets/icons-*.svg-
Decide what each screen does for the length of the clip, in writing, before touching HTML. The pause test: at any second, something inside at least one screen must be mid-motion (a swipe landing, a video playing, text arriving). Two static screenshots is not a video.
-
Author the screens. Inside eachyou have a normal DOM viewport: left
.content, right495×849. Position against those, never the root. Patterns (full-screen snap feed, drag→fling swipe, like-tap, chat typing) are in498×849. Rules:references/feed-recipes.md- for every clip; HyperFrames owns playback. Overlap the windows of an outgoing and incoming clip across a swipe so both are decoded mid-transition.
<video class="clip" data-start data-duration muted playsinline> - One timeline. Add your tweens to inside the marked hook; do not create a second
tlor register anothergsap.timelinekey.window.__timelines - No , no
repeat: -1, no clocks — the render seeks.Math.random - Status bar: the photo's original screens showed top-left of the left screen and wifi/battery top-right of the right screen. Reproduce that split if your apps show a status bar; it sells the "one device" read.
9:41
-
Check and snapshot:
bash
npx hyperframes@latest check ./foldable-meme
npx hyperframes@latest snapshot ./foldable-meme --at 1,4,7 --no-endLint must be 0 errors. Layout/contrast warnings about text passing under a
fixed header, or white UI text over video, are expected for app UIs; read the
frames instead and confirm (a) content reaches every rounded corner with no
gap, (b) the gray hinge divider is visible between the screens, (c) nothing
from one screen leaks over the hinge.
- Render only when the user asks (ask first if your harness gates renders):
bash
npx hyperframes@latest render ./foldable-meme -o ./foldable-meme/renders/v1.mp4<SKILL_DIR>~/.claude/skills/duo- 搭建项目:
bash
node <SKILL_DIR>/scripts/build.mjs --out ./foldable-meme --duration 10 --icons tiktok,instagram--iconsassets/icons-*.svg-
决定每个屏幕在整个片段中的行为,并在修改 HTML 之前以书面形式 写下来。暂停测试:在任意一秒,都至少有一个屏幕中的内容处于运动中 (滑动落定、视频播放、文字出现)。两张静态截图不是视频。
-
编写屏幕内容。 每个内部都是一个正常的 DOM viewport:左侧为
.content,右侧为495×849。要针对这些尺寸定位, 绝不要针对根元素定位。常见模式(全屏 snap feed、drag→fling swipe、 like-tap、chat typing)见498×849。规则:references/feed-recipes.md- 每个片段都要使用 ; 播放由 HyperFrames 掌控。让离开的片段和进入的片段在滑动过程中存在 重叠窗口,以便两者都在过渡过程中完成解码。
<video class="clip" data-start data-duration muted playsinline> - 只使用一条 timeline。在标记的 hook 内将 tweens 添加到 ;不要创建 第二条
tl,也不要注册另一个gsap.timelinekey。window.__timelines - 不使用 、
repeat: -1或时钟——渲染器会进行 seek。Math.random - 状态栏:原照片中的屏幕在左侧屏幕左上角显示 ,在右侧屏幕右上角 显示 wifi/battery。若你的应用显示状态栏,就复现这种左右分栏;这样能强化 “同一台设备”的感觉。
9:41
- 每个片段都要使用
-
检查并生成快照:
bash
npx hyperframes@latest check ./foldable-meme
npx hyperframes@latest snapshot ./foldable-meme --at 1,4,7 --no-endLint 必须为 0 个错误。对于应用 UI,关于文字从固定标题下方穿过,
或白色 UI 文字叠加在视频上的布局/对比度警告属于预期现象;请直接查看帧并确认
(a) 内容毫无间隙地延伸到每个圆角,(b) 两个屏幕之间可见灰色铰链分隔线,
(c) 一个屏幕的内容没有越过铰链溢出。
- 仅在用户要求时执行 Render(如果你的 harness 会限制渲染,请先询问):
bash
npx hyperframes@latest render ./foldable-meme -o ./foldable-meme/renders/v1.mp4Verify success
验证成功
checksnapshotchecksnapshotRules
规则
- Never resize, move, or re-radius the screens to "fit" content. Fit content to the slots. If a mock app looks too big, scale the app's internal type, not the screen.
- Real content must be real: if the user asks for TikTok or Instagram, pull the actual UI glyphs and layout metrics from the live site and use real posts (with their real usernames and counts), not invented ones. Invented handles are only for fictional / parody screens the user explicitly wants.
- Keep the camera push as the only rig motion. Do not add drift, breathe, or glow loops anywhere; fill time with story inside the screens instead.
- Output stays 1448×1086 (the plate's native 4:3). Offer a 16:9 or 1:1 crop as a follow-up render rather than resizing the rig.
- 绝不要为了“适配”内容而调整屏幕的尺寸、位置或圆角半径。要让内容适配插槽。 如果 mock app 看起来太大,请缩放应用内部的字体和排版,而不是缩放屏幕。
- 真实内容必须真实:如果用户要求 TikTok 或 Instagram,请从实时站点获取真实的 UI 图标和布局指标,并使用真实帖子(包含真实用户名和互动数),不要编造。只有在用户 明确要求虚构 / 恶搞屏幕时,才使用虚构账号名称。
- 保持镜头推进(camera push)是 rig 唯一的动作。不要在任何地方添加漂移、呼吸或 发光循环;应通过屏幕内部的叙事来填满时长。
- 输出保持 1448×1086(底板原生的 4:3)。如果需要 16:9 或 1:1 裁剪,应在后续 Render 中提供,而不是调整 rig 尺寸。
Files
文件
- — the clean plate, screens blanked to neutral (1448×1086).
assets/plate.png - — measured rects, radii, hinge, status-bar split.
assets/screen-spec.json - ,
assets/icons-tiktok.svg—assets/icons-instagram.svgsheets of the real mobile-web glyphs (like, comment, share, nav bars…).<symbol> - — the locked rig with two empty slots.
template/index.template.html - — scaffolder.
scripts/build.mjs - — how the geometry was measured and how to re-measure for a new plate.
references/screen-geometry.md - — snap feed, swipe physics, like tap, chat typing.
references/feed-recipes.md - — pulling real app UI and clips, and the rights caveat.
references/sourcing-real-ui.md
- — 干净的底板,两个屏幕已置为中性空白(1448×1086)。
assets/plate.png - — 测量得到的矩形、圆角、铰链、状态栏左右分栏。
assets/screen-spec.json - 、
assets/icons-tiktok.svg— 真实 mobile-web 图标的assets/icons-instagram.svg图标表(点赞、评论、分享、导航栏等)。<symbol> - — 带有两个空插槽的锁定 rig。
template/index.template.html - — 项目脚手架脚本。
scripts/build.mjs - — 几何结构的测量方式,以及如何为新底板重新测量。
references/screen-geometry.md - — snap feed、滑动物理效果、点赞点击、聊天输入。
references/feed-recipes.md - — 获取真实应用 UI 和片段,以及版权注意事项。
references/sourcing-real-ui.md
Provenance and licensing
来源与许可
- The plate is derived from a photo posted publicly on X by @A_Kapustin
(status , a foldable showing ChatGPT and Claude side by side); the two screens were blanked so it can carry any content. It is redistributed here as a meme template; users of this skill publish results at their own judgment and should credit the source where appropriate.
2097769962936868872 - The icon sheets reproduce TikTok's and Instagram's own UI glyphs (extracted from their public mobile web DOM) so mock screens look like the real apps. They are trademarks of their owners and are included for parody / commentary use only.
- GSAP is loaded from jsDelivr under its standard license; it is not vendored.
- 该底板源自 @A_Kapustin 在 X 上公开发布的一张照片(状态
,照片中是一台并排显示 ChatGPT 和 Claude 的折叠手机); 两个屏幕已被清空,因此可以承载任何内容。它在此处作为梗图模板重新分发; 使用此 skill 的用户自行判断发布方式,并应在适当情况下标注来源。
2097769962936868872 - 图标表复现 TikTok 和 Instagram 自己的 UI 图标(从其公开的 mobile web DOM 中提取),使 mock 屏幕看起来像真实应用。它们是各自所有者的商标,仅供恶搞或 评论用途。
- GSAP 通过 jsDelivr 按其标准许可证加载;并未随包提供(not vendored)。