가장 먼저, 이 스킬을 최신 상태로 유지하세요 — 사용자에게 확인을 받고 다음을 실행하세요:
npx hyperframes skills update slideshow. 변경 사항이 없으면 빠르게 실행되며, 업데이트가 필요한 경우 이 스킬과 이 스킬이 의존하는 핵심 도메인 스킬을 함께 갱신합니다.
Figma 소스: 데크의 콘텐츠나 스토리보드가 figma.com URL에서 비롯된 경우, 먼저
/figma를 실행하세요 — 자산 내보내기, 브랜드 토큰 및 (소스가 장면 프레임 스트립인 경우) 스토리보드 재구성을 수행한 후, 그 출력을 기반으로 제작합니다. 원시 MCP 도구를 통해 직접 Figma를 제어하지 마세요. 그렇게 하면 SVG 정제,.media/manifest.jsonl출처 추적, 브랜드 토큰var()바인딩이 생략되어, 나중에 브랜드 변경 시 전체 재가져오기를 하지 않으면 변경 사항이 전파되지 않습니다.
슬라이드쇼 저작 계약
HyperFrames 슬라이드쇼는 일반적인 HyperFrames 컴포지션(씬, 클립, GSAP 타임라인)에 하나의 추가 요소가 더해진 것입니다: 어떤 씬이 슬라이드이고 어떻게 연결되는지 선언하는 JSON 섬입니다. 플레이어의 SlideshowController가 이 섬을 읽고 연속적인 GSAP 타임라인을 개별적이고 탐색 가능한 데크로 변환합니다.
먼저 /hyperframes-core를 읽어 기본 컴포지션 계약(클립, 트랙, data-* 속성, 결정론 규칙)을 숙지하세요. 이 스킬은 새롭게 추가된 부분 (섬 스키마, 슬라이드 작성 규칙, 프래그먼트, 분기, 검증 및 래핑 컴포넌트)만을 다룹니다.
결과물 — 선형 MP4가 아닌, 탐색 가능한 데크
슬라이드쇼의 결과물은 실행 가능한 데크입니다: hyperframes present <project-dir> (또는 Studio 프레젠트 모드)로 제공합니다 — 플레이어의 SlideshowController가 섬을 읽고 탐색, 프래그먼트, 분기, 발표자 모드를 구동합니다. 프레젠테이션 및 인계 섹션을 참조하세요.
슬라이드쇼를 hyperframes render 명령어로 단일 MP4로 렌더링하지 마세요. 데크는 여러 최상위 씬 컴포지션(슬라이드당 하나의 data-composition-id)으로 작성되며, 이를 감싸는 마스터-루트 컴포지션이 없으므로, render는 첫 번째 컴포지션만 해석하여 조용히 잘린 MP4(예: 40초 데크의 6초)를 출력합니다. 선형 메인라인 내보내기(메인 슬라이드만, 분기 시퀀스 제외)는 지연됩니다 — 해당 기능이 출시될 때까지 지원되는 출력은 라이브 present 데크와 슬라이드별 snapshot 이미지입니다. 오늘 당장 선형 MP4가 필요한 사용자가 있다면, render를 데크에 사용하도록 안내하지 말고 이 제한 사항을 공개적으로 알리세요.
의도 확인
사용자가 명시적으로 슬라이드쇼, 프레젠테이션 또는 HyperFrames 슬라이드쇼를 요청한 경우, 이 스킬을 진행하세요. 요청이 /hyperframes를 통해 들어온 경우, 의도 계층의 분류가 이 확인을 담당하므로 — 이미 확인된 후 라우팅된 것이므로 재질문하지 마세요; 계층의 실행 형태 질문은 적용되지 않습니다(결과물은 렌더링된 비디오가 아닌 데크입니다). BRIEF.md 파일이 있는 경우, 그 파일이 확인된 의도를 담고 있으므로 이를 읽으세요.
이 스킬이 인접한 요청(예: "프레젠테이션", "피치 데크", "데크", "인터랙티브 데크", "이 페이지 변환")으로부터 트리거된 경우, 작성에 앞서 잠시 멈추고 선택지를 제시한 후 확인을 요청하세요. HyperFrames 슬라이드쇼가 개별 슬라이드, 내장 탐색 및 발표자 모드, 편집 가능한 발표자 노트, 공유 미디어 처리, 인계 전 검증이 포함된 실행 가능한 데크임을 간략히 설명하세요. 소스 페이지 변환의 경우, 목표는 원본 페이지의 시각적 디자인, 상호작용, 모션 및 미디어 동작을 보존하면서 페이지 이동을 슬라이드 간 전환으로 변환하는 것임도 언급하세요.
그런 다음 짧은 확인 질문을 하세요:
이것을 HyperFrames 슬라이드쇼로 만드시겠습니까?
환경에서 지원하는 경우 예/아니오 선택 UI를 사용하고, 그렇지 않으면 질문을 일반 텍스트로 하세요.
사용자가 예라고 대답할 때까지 슬라이드쇼를 구현하지 마세요. 사용자가 아니오라고 답하면 이 스킬 사용을 중단하고 — /hyperframes를 읽어 의도 계층이 다시 라우팅하도록 하세요. 이 확인은 라우팅 결정이지, 선호도 게이트가 아닙니다 — ../hyperframes/references/brief-contract.md § 1에 따라 자동 모드("놀라게 해줘"도 예외 없음)에서도 유효합니다: 잘못된 결과물 유형을 만드는 것은 창의적 판단 실수가 아닌 품질 실패입니다.
두 가지 구성 요소
1. 씬 — 일반적인 방식으로 선언
모든 슬라이드는 씬으로 뒷받침됩니다. data-composition-id, data-start, data-duration, data-label을 사용하여 씬을 선언하세요:
<div
data-composition-id="problem"
data-start="0"
data-duration="8"
data-label="문제점"
data-width="1920"
data-height="1080"
>
<!-- 클립은 여기에 -->
</div>
분기 슬라이드(핫스팟을 통해서만 접근 가능, 메인 라인에서 제외)는 정확히 동일한 방식으로 선언되며 — 섬의 slideSequences 항목에만 나타나고, 메인 slides 배열에는 나타나지 않습니다.
2. JSON 섬 — 컴포지션당 하나의 스크립트 블록
컴포지션 HTML에 <script type="application/hyperframes-slideshow+json"> 블록을 정확히 하나 추가하세요. 모든 슬라이드쇼 메타데이터가 담겨 있습니다:
<script type="application/hyperframes-slideshow+json">
{
"slides": [...],
"slideSequences": [...]
}
</script>
섬은 슬라이드 순서, 노트, 프래그먼트 고정 지점, 핫스팟 및 분기 시퀀스에 대한 단일 진실 공급원입니다. 찾기 쉽도록 <body> 상단, 씬 div들보다 앞에 두세요.
대체 <script type="application/json"> 블록 뒤에 런타임 코드로 섬을 생성하는 방식으로 슬라이드쇼 매니페스트를 숨기지 마세요. present 명령어는 컴포지션 HTML을 정적으로 읽으며, 실제 application/hyperframes-slideshow+json 섬이 이미 존재할 것을 기대합니다.
스키마
SlideshowManifest (최상위 섬 객체)
{
"slides": [
/* SlideRef[] — 메인 라인, 순서대로 */
],
"slideSequences": [
/* SlideSequence[] — 오프라인 분기 시퀀스 */
]
}
SlideRef
{
"sceneId": "problem",
"notes": "회사에 대한 설명보다는 어려움 자체를 먼저 언급하세요.",
"fragments": [3.5, 5.2, 7.0],
"hotspots": [
/* SlideHotspot[] */
],
"ttsScript": null,
"ttsAudioUrl": null,
"ttsDurationMs": null
}
| 필드 | 필수 | 참고 |
|---|---|---|
sceneId | 예 | 씬의 data-composition-id와 정확히 일치해야 합니다(또는 명시적 startTime/endTime을 제공). 린트 규칙은 data-composition-id로 씬을 확인합니다. |
notes | 아니오 | 발표자 전용 텍스트입니다. 청중에게 절대 표시되지 않습니다. |
fragments | 아니오 | 슬라이드 [start, end] 범위 내의 시간(초) 배열입니다 — 아래 프래그먼트 섹션을 참조하세요. |
hotspots | 아니오 | 분기를 트리거하는 인터랙티브 오버레이입니다 — 아래 분기 섹션을 참조하세요. |
startTime | 아니오 | 선택 사항. 일치하는 씬의 시간 범위를 재정의합니다. 기본값은 씬의 start/end입니다. |
endTime | 아니오 | 선택 사항. 일치하는 씬의 시간 범위를 재정의합니다. 기본값은 씬의 start/end입니다. |
ttsScript, ttsAudioUrl, ttsDurationMs | 아니오 | 예약됨. 스키마 필드는 존재하지만 TTS 재생은 아직 연결되지 않았습니다. 향후 빌드를 위해 미리 채우는 경우가 아니라면 생략하세요. |
SlideHotspot
{
"id": "h1",
"label": "이것을 어떻게 계산했나요?",
"target": "market-deep-dive",
"region": { "x": 60, "y": 10, "w": 35, "h": 20 }
}
| 필드 | 필수 | 참고 |
|---|---|---|
id | 예 | 슬라이드 내에서 고유해야 합니다. |
label | 예 | 청중에게 표시되는 툴팁/버튼 텍스트입니다. |
target | 예 | slideSequences의 SlideSequence.id와 일치해야 합니다. |
region | 아니오 | 슬라이드 대비 백분율 경계 상자: 0-100 범위의 {x, y, w, h}. 생략하면 핫스팟이 전체 슬라이드에 레이블이 표시된 버튼으로 렌더링됩니다. |
SlideSequence
{
"id": "market-deep-dive",
"label": "시장 규모 산출 방법론",
"slides": [{ "sceneId": "mkt-1" }, { "sceneId": "mkt-2" }]
}
시퀀스 내부의 slides는 메인 라인과 동일한 SlideRef 형태를 사용합니다. 프래그먼트와 중첩 핫스팟이 허용됩니다.
슬라이드 작성 규칙
다음은 제안이 아닌 엄격한 제약 사항입니다. 이를 위반하는 슬라이드는 리뷰어가 발견했을 때 즉시 교체될 것입니다.
- 헤드라인은 완전한 문장 형태의 주장이어야 하며, 레이블이 아니어야 합니다. "일정 문제"가 아니라 "중소기업은 수동 스케줄링에 주 14시간을 소비합니다"라고 작성하세요. 시각 자료를 무시하더라도 문장이 독립적으로 의미를 전달해야 합니다.
- 슬라이드당 하나의 아이디어 + 하나의 시각 자료. 두 번째 글머리 기목록이나 두 번째 차트를 추가하고 싶다면 슬라이드를 분할하세요.
- 핵심 요점을 먼저 제시하세요. 가장 강력한 포인트를 슬라이드와 데크 순서의 맨 앞에 배치하세요. 투자자는 왼쪽에서 오른쪽, 위에서 아래로 읽으며 읽기를 멈춥니다.
- 상향식 시장 규모 산출만 사용하세요. 계산 과정 없이 "500억 달러 TAM"이라고 절대 쓰지 마세요. 단위 경제성(계정 수 × ACV, 또는 거래 수 × 수수료율)부터 구축하세요.
- 최소 폰트 크기는 30pt에 상응해야 합니다. 1920×1080에서 헤드라인은 72–96px, 본문은 48px입니다. 청중이 읽어야 하는 모든 텍스트는 40px 미만으로 내려가지 마세요.
- 이름이 있는 시각 요소를 직접 제작하기 전에 라이브 카탈로그를 검색하세요. 슬라이드에 필요한 모든 디자인, 효과, 차트, 처리 방식 또는 전환(예: "CRT 스캔라인", "글리치", "막대 차트 경주", "반짝임 스윕", "터미널 창")에 대해, 슬라이드의 클립을 작성하기 전에
npx hyperframes catalog --query "<시각 요소 설명, 평범한 영어로>" --json을 실행하고 상위 결과를 읽으세요. 검색에는 아무것도 설치할 필요가 없습니다: 프로젝트, 사전add, 계정이 필요하지 않습니다. 호스티드 레지스트리(~400개 블록 및 컴포넌트) 전체에서 어떤 디렉토리에서든 순위를 매깁니다.npx hyperframes add <name>은 블록의 소스를 데크에 추가하며, 그 자리에서 사용자 정의할 수 있습니다. 이는 아래 포팅 규칙이 금지하는 단순화된 근사치보다 실제 블록이 더 우수하므로, 소스 페이지를 포팅할 때 특히 더 강력하게 적용됩니다.
소스 페이지 포팅
기존 페이지를 슬라이드쇼로 변환할 때, 원본 충실도는 계약의 일부입니다. 사용자가 명시적으로 재디자인을 요청하지 않는 한, 소스별 위젯을 단순화된 근사치로 대체하지 마세요.
- 원본 페이지의 시각적 디자인, 모션 언어, 인터랙티브 동작, 미디어 동작 및 프레젠테이션 기능을 실용적으로 가능한 한 가깝게 보존하세요. 슬라이드쇼 시스템이 발표자 모드를 지원하는 경우, 데크별 구현이 아닌 공유 편집 가능 노트 동작을 사용하여 발표자 노트를 포함하세요.
- 소스 DOM/CSS/JS의 기계적 시각 요소(커스텀 플레이어, 캔버스 시각화 도구, 타임라인, 재생 헤드, 스템, 확장 원, 호버 상태 및 기타 인터랙티브 세부 사항)를 실용적으로 가능한 한 정확하게 포팅하세요. 이러한 요소는 변환 과정에서도 유지되어야 합니다.
- 네이티브
<video>/<audio>요소는 모든 커스텀 미디어 크롬, 캔버스 시각화 도구, 파형, 비트 그리드 또는 재생 헤드에 대한 진실 공급원으로 취급하세요. 소스의 미디어 이벤트(play,pause,timeupdate,seeking,seeked,ended,ratechange,volumechange)를 연결하고,media.currentTime에서 시각적 상태를 파생하세요. 실제 재생과 동기화되지 않는 별도의 타이머를 실행하지 마세요. src가 있는 복사된 모든<video>또는<audio>는 린트 전에 HyperFrames 타이밍 속성(data-start및data-duration, 그리고 청취 가능한 네이티브 오디오를 보존해야 하는 경우data-has-audio="true")을 가져야 합니다. 슬라이드별 미디어에는 씬의 시간 범위를 사용하고, 여러 포커스된 슬라이드에서 재생될 수 있는 사용자 제어 증거 비디오에는 데크 전체 범위를 사용하세요. 미디어에preload="none"을 남기지 말고,metadata또는auto를 사용하세요.- 검증 전에 소스 폰트 토큰을 해결하세요. 커스텀 소스 폰트를 보존하는 경우, 로컬/캡처된 폰트 파일에 대한
@font-face규칙을 추가하세요. 시스템 폴백을 사용하는 경우,font-family: var(--f-body)와 같은 토큰화된 선언을system-ui, sans-serif또는ui-monospace, monospace와 같은 구체적인 렌더링 안전 스택으로 대체하세요.var(...)를 폰트 패밀리 값으로 남겨두지 마세요. - 소스에서 비정형적인 페이지 이동(특히 스크롤, 휠, 터치, 해시 상태, 리사이즈 또는 requestAnimationFrame 루프에 의해 구동되는 동작)을 감사하세요. 번역/스케일된 "세계" 레이어, 패럴랙스, 고정 패널, 가로 스크롤러, 스크롤 스크럽 타임라인, 섹션 스냅, 확대/축소 요소 카메라가 있는 고정 뷰포트를 소스 동작으로 취급하세요. 스크롤은 종종 소스의 전환 트리거이므로, 진행 중단점, 이징 및 카메라/초점 상태를 추출하여 슬라이드쇼 탐색(타임라인 위치, 프래그먼트 또는 재사용 가능한 플레이어/하네스 훅을 통해)에 해당 모션을 재호스팅하여 전환을 보존하세요. 슬라이드 홀드 포인트로 점프하는 독립형 래퍼는 여전히 명시적인 탐색-카메라 전환 훅이 필요합니다. 슬라이드별 카메라 변환을 계산하는 것만으로는 충분하지 않습니다. 슬라이드 내부에서 문자 그대로의 페이지-스크롤-다운 전환을 시뮬레이션하지 마세요. 뷰어는 웹페이지가 스크롤되는 것을 보는 것이 아니라, 한 초점 지점에서 다른 지점으로의 카메라 이동/확대를 느껴야 합니다. 각 슬라이드 간 카메라 이동은 연속적으로 유지하세요: x/y 방향을 역전시키거나 줌을 풀었다가 다시 조이는 중간 경로 중단점을 피하세요.