ccvideo — 클로드 스타일 제품 프로모션 비디오은(는) 무엇을 하나요?
당신은 Anthropic의 Claude 런치 비디오 시각 언어를 사용하여 짧은 프로모션 비디오(20–45초, 1920×1080 @ 30fps)를 제작합니다: 따뜻한 테라코타 캔버스, Claude Code 세션을 실행하는 단일 macOS 터미널 창, 텍스트가 타이핑되어 스트리밍 방식으로 나타나며, 고정된 프레이밍 사이의 짧은 카메라 푸시, 세리프 타이틀 카드.
전제 조건
- Remotion 프로젝트가 존재해야 합니다. 존재하지 않으면 새로 생성하세요:
npx create-video@latest --yes --blank --no-tailwind .그런 다음npm i. - 패키지 (버전 일치를 위해
npx remotion add <pkg>로 설치):@remotion/google-fonts,@remotion/transitions,zod(zod를 명시적으로 선언하세요 — 라이브러리가 직접 임포트합니다; transitive 의존성에 의존하지 마세요). - 컴포넌트 라이브러리가
src/ccvideo/에 있어야 합니다. 없으면 이 스킬의templates/디렉토리에서 모든 파일을src/ccvideo/로 복사하세요. 처음부터 컴포넌트를 다시 작성하지 마세요. - 캡처/검증 툴링이 프로젝트 루트의
scripts/에 있어야 합니다. 없으면 이 스킬의scripts/디렉토리(scripts/lib/포함)를 복사하세요. 모든 스크립트는captures/를 실행하는 디렉토리 기준으로 확인하므로, 항상 프로젝트 루트에서 실행하세요.
Ground truth (불가침 콘텐츠 규칙)
비디오 콘텐츠는 절대 장면 컴포넌트에 수동으로 작성되지 않습니다. 표시되는 모든 사실(숫자, 경로, 엔드포인트, 명령 출력, 줄 수)은 실제로 실행된 것의 캡처에서 비롯되어야 합니다:
- 각 비디오에는 원시 아티팩트(API 응답, 추출된 세션 이벤트)와 이로부터 결정론적으로 구축된
props.json을 보관하는captures/<name>/디렉토리가 있습니다.props.json은 컴포지션이 렌더링하는 단일 진실 공급원입니다. - 먼저 캡처하세요. 비디오를 만들기 전에 실제 작업을 실행하세요:
node scripts/capture-xapi-cli.mjs— xapi CLI를 통한 실시간 X 데이터 (npx xapi-to, 키는~/.xapi/config.json에 있음;.agents/skills/xapi/에 있는xapi스킬이 모든 기능을 설명합니다).node scripts/capture-x-user.mjs— 공식 X API 변형 (X_BEARER_TOKEN필요;--sample은sample: true로 표시된raw-meta.json과 함께 플레이스홀더 데이터를 작성합니다 — 샘플 캡처를 절대 게시하지 마세요).node scripts/transcript-to-props.mjs <session.jsonl> --prompt-match <str> --out captures/<name>— 실제 Claude Code 세션 턴을 재생합니다 (트랜스크립트는~/.claude/projects/<project-slug>/*.jsonl에 있습니다).- 새로운 데이터 소스? 동일한 패턴을 따르는 새 캡처 스크립트를 작성하세요: 실제를 가져오기 → 원시 저장 →
scripts/lib/의 공유 결정론적 빌더를 통해 props 구축.
- 게시 전에 검증하세요:
node scripts/verify-props.mjs captures/<name>는 원시 아티팩트에서 props를 재구축하고 수동 편집이 있으면 실패합니다.props.json을 편집하지 말고 다시 캡처하여 수정하세요. - 정직한 재생 경계: 페이싱은 퍼포먼스(타이핑 속도, 스피너 시간)이지만, 기능은 실제여야 합니다 — 비디오는 캡처된 실행이 실제로 수행한 것만 보여줄 수 있습니다. 이는 크롬에도 적용됩니다: 세션 헤더 정보(Claude Code 버전, cwd)는 캡처(
claude --version, 실제 cwd)에서 가져오거나 헤더를 생략합니다; 스피너의 토큰 카운터는 캡처가 실제thinkingTokens값을 제공하는 경우에만 렌더링합니다 (그렇지 않으면 초만 표시). 샘플 캡처는verify-props에서 완전히 실패합니다 (--allow-sample은 파이프라인 테스트 전용). - 캡처는 커밋 안전을 목표로 하며 심층 방어를 제공하지만 완벽을 보장하지는 않습니다:
transcript-to-props는 비디오가 실제로 사용하는 입력(선택된 이벤트의 표시된 줄 + 카운트, 하나의 잘린 명령 출력, 요약 글머리 기호 줄)만 유지하고, 비밀처럼 보이는 문자열(API 키, Bearer 토큰, URL 자격 증명, env/JSON 암호 필드, 개인 키)을 정리하며, 일반 및 slug-평탄화된 홈 경로를 모두~로 다시 작성합니다 — 이 모든 작업은 props가 구축되기 전에 이루어지므로 props, 비디오, 보관된 원시 데이터가 동일한 수정된 콘텐츠를 봅니다. 패턴 목록은 완전할 수 없습니다: 항상 커밋하기 전에 캡처를 검토하고, 수정 경고를 중지 신호로 간주하세요.
워크플로우
- 먼저 캡처 (Ground truth 참조): 실제 실행에서
captures/<name>/props.json을 생성합니다. - 캡처에서 비트 시트 작성. 프레젠테이션 텍스트(카드 제목, 생각 단어)는 캡처 스크립트의 상수/플래그에 있습니다 — 하나의 프롬프트, 코드 비트, 실행 출력, 요약 글머리 기호를 선택하세요. 고전적인 아크를 목표로 하세요: 코드 → 생성 → 실행+출력 → 요약.
- 구성:
src/ccvideo의GroundedVideo를 사용하여src/Root.tsx에<Composition>을 등록하고,schema={groundedVideoSchema}, 캡처의props.json에서 가져온defaultProps, 그리고groundedVideoDuration을 통해 지속 시간을 도출하는calculateMetadata를 사용하세요 — 지속 시간은 자동으로 콘텐츠를 따릅니다. 표준 아크를 넘어서는 사용자 정의 장면 작업: 라이브러리 프리미티브로 구축하고, 동일한 규칙을 따르세요. - 스틸로 검증하기 전에 완료했다고 선언하지 마세요. 비트당 하나의 스틸을 렌더링하세요:
npx remotion still <CompId> --frame=<n> --scale=0.5 out.png그리고 살펴보세요. 확인: 터미널 창에 의해 잘린 것이 없는지 ([ccvideo]오버플로우 경고가 렌더 출력에 표시되면 비트를 다듬으세요), 타이밍이 서두르지 않은지, 색상이 팔레트와 일치하는지. node scripts/verify-props.mjs captures/<name>를 실행하고,npx remotion studio --no-open으로 미리보기;npx remotion render <CompId> out/<CompId>.mp4로 최종 렌더링합니다 (--props=captures/<name>/props.json을 추가하면 코드를 건드리지 않고 다른 캡처를 렌더링할 수 있습니다; 공식 데모처럼 4K 마스터를 위해--scale=2를 추가하세요 — 코드에서는 컴포지션이 1920×1080 @ 30fps로 유지됩니다).
두 가지 테마
제품별로 선택하며, 둘 다 브랜드 테라코타 #D97656/#D97757를 공유합니다:
- Terracotta (기본값) — 따뜻한 캔버스, Claude Code REPL 세션. 에이전트/AI 워크플로우 스토리용. 컴포넌트:
GroundedVideo/DataSession. - Dark (
antCLI 데모 문법) — 거의 검은색 캔버스#0B0B0B, 따뜻한 검은색 터미널#181716(미묘한 테두리로만 분리), 셸 프롬프트▶ ~/디렉토리 >(화살표#8B92C9, chevron#5FA97B), 크림 세리프#D6D4CF. 구조는 챕터 방식: 픽셀 로고 워드마크 카드 → [챕터당 인터스티셜 카드 (모노 킥커 + 얇은 구분선 + 세리프 클레임) → 새로운 셸 비트 (실제 명령어 입력, 실제 출력이 페이드 인, 유휴 프롬프트로 복귀)] → 워드마크 아웃트로. CLI/개발자 도구 제품용. 컴포넌트:DarkVideo/ShellBeat/InterstitialCard/WordmarkCard,theme.ts의dark팔레트,darkVideoSchema스키마 (라이트 테마와 마찬가지로 캡처에서 구축 — 예:capture-xapi-cli.mjs가 작성하고verify-props.mjs가 검증하는props-dark.json).
비주얼 (불가침 스타일 규칙)
- 캔버스
#CC7D5D, 터미널#2B2C36, 타이틀바#3A3634. 본문 텍스트#E3E4EB, 흐릿한 텍스트#9899A1, 주석#6C6E6A, 줄 번호#83848C. 강조 색상: 연보라#B8B9F2(경로, 인라인 코드, 문자열), 청록#85BEC5(키워드), 금색#F2C43D(상태 화살표). 이 모든 것은src/ccvideo/theme.ts에 정의되어 있습니다 — 임포트하고, 하드코딩하지 마세요. - 글꼴: 터미널 관련 항목에는 JetBrains Mono, 타이틀 카드에는 Source Serif 4.
theme.ts에서@remotion/google-fonts를 통해 로드되며, 두 스택에 CJK 폴백으로 Noto Sans SC가 이미 추가되어 있습니다 — 중국어 프롬프트가 즉시 렌더링됩니다. - 터미널 창 1560×950 중앙 정렬 (세션
header가 표시되면 985; 다크 테마는 1860×1010), 14px 반경, 깊은 부드러운 그림자, 세 개의 트래픽 라이트, 작업을 반영하는 모노 타이틀바 텍스트 (예:dev — · Implement X — claude — 106×31). - Claude Code 세션은 실제처럼 보여야 합니다: 금색
⏵⏵ auto mode on (shift+tab to cycle) · esc to interrupt상태 표시줄 위의>입력 행 (둘 다 항상 표시되고 하단에 고정됨); 입력 행 바로 위 고정 높이 슬롯의✻ Cogitating…스피너;●도구-결과 글머리 기호;… +N lines (ctrl+o to expand)로 끝나는 번호가 매겨진 코드 블록;-글머리 기호가 있는 굵은What it does요약. - 카메라: 터미널 장면에서 지속적인 줌 또는 팬 금지 — 느린 분수 스케일링은 작은 모노 텍스트를 눈에 띄게 표류시키고 떠다니게 합니다. 허용되는 유일한 카메라 움직임은
<CutZoom>: 그렇지 않으면 고정된 프레이밍 사이의 짧고 강력하게 이징된 움직임(~0.6초) — 밀도 높은 콘텐츠로 밀어 넣고, 유지한 다음, 페이오프를 위해 뒤로 당깁니다. 텍스트는 의도적인 빠른 움직임 중에만 중간 스케일일 수 있으며, 몇 초 동안 지속되지 않습니다. 풀아웃 시 push-in과 동일한origin을 유지하여 측면 슬라이드로 읽히지 않도록 합니다.DataSession은run비트 주위에 이를 자동으로 적용합니다.<SlowZoom>은 타이틀 카드 전용입니다. - 세션 인증 크롬 (모두 스키마 기반, 모두 선택 사항):
header(픽셀 로고 +Claude Code vX+ 모델/cwd 행, 항상 표시됨), 프롬프트 제출 시windowTitleIdle→windowTitle전환, 강조 표시된 블록으로서의 프롬프트 에코, 라이브(Ns · ↓ N tokens)카운터와 선택적⎿ Tip:행이 있는 스피너, 작업 중에만esc to interrupt를 얻는 상태 표시줄. 추가 비트 종류:answer(풍부한 산문 블록),alert(빨간색 강조 행),tool비트는⎿자식 행을 가질 수 있습니다. - 자막 표류 금지. 터미널 텍스트는 제자리에서만 페이드 인할 수 있습니다: 창 내부에 위치 시작 애니메이션 없음, 아래 줄을 리플로우하는 요소를 절대 마운트/언마운트하지 않음 — 일시적인 행(스피너, 진행률)은 고정 높이 슬롯에 있어 사라져도 아무것도 이동하지 않습니다.
- 타이틀 카드: 테라코타 위에 거의 검은색
#1F1508의 세리프 헤드라인, 68% 불투명도의 모노 서브타이틀, 페이드 업 입장. 1920 너비에서 헤드라인 ≥ 132px, 서브타이틀 ≥ 52px.
컴포넌트 API (src/ccvideo)
데이터 기반 레이어 (전체 비디오에 권장):
<GroundedVideo {...props}>— 소개 카드 → 세션 → 아웃트로 카드, 전적으로groundedVideoSchema값(캡처의props.json)에서 가져옴.<DataSession {...props.session}>— 모든sessionSchema값을 렌더링: 선택적 헤더, 프롬프트 타이핑, 스피너, 그 다음beats(discriminated union:code,tool,run,summary,answer,alert). 실행 비트 컷-줌을 자동으로 적용; 렌더링 시 콘텐츠가 오버플로우되면 경고.sessionTiming(props, fps)/groundedVideoDuration(props, fps)— 순수 타이밍 도출;calculateMetadata에서 사용.<Rich segments>— JSON 세그먼트{t: 'plain'|'kw'|'code'|'comment'|'dim'|'bold', s}를 렌더링; props.json에서 스타일이 지정된 텍스트로의 브리지.
프레젠테이션 프리미티브:
<TerminalWindow title width? height? variant?>— 캔버스 위의 창 (variant="dark"는 다크 테마용). 자식은 flex column입니다; transcript에flex: 1을 주어<InputBox>+<StatusBar>가 하단에 고정되도록 합니다.<TypeText text from cps? cursor?>/<Cursor>— 타자기, 35–45 cps.<InputBox typedText? from? cps?>—>행;typedText없음 = 깜빡이는 커서.<StatusBar mode? hint?>.<Thinking from? until? word? stats? tokens? tip?>— 스피너;stats는 라이브(Ns)를 표시 —tokens가 실제 캡처된 값을 가질 때만↓ N tokens를 추가;tip은⎿ Tip:행을 추가합니다. transcript와 입력 사이의 고정 높이 슬롯에 배치;until은 제자리에서 페이드 아웃됩니다.<Line from?>— 하나의 출력 행, 8프레임 페이드 인 (불투명도만).<ToolLine from>—●글머리 기호 행.<CodeBlock from lines stagger? startLineNo? expandNote?>— 번호가 매겨진 줄.- 토큰 스팬:
<K>키워드,<C>코드/경로,<Cm>주석,<Dim>,<B>. <SessionHeader version modelLine>,<PromptEcho>,<AlertLine from?>,<ToolChild from?>— 세션 크롬 (스타일 규칙 참조).<CutZoom cuts={[{from, scale?, origin?, ease?}]}>— 고정된 프레이밍 사이의 짧은 이징된 움직임; 터미널 장면에서 허용되는 유일한 카메라 움직임.<SlowZoom from? to?>— 타이틀 카드 전용, 터미널 주변에서는 절대 사용하지 않음.<TitleCard title subtitle? titleSize?>.
모든 애니메이션은 프레임 기반입니다 (useCurrentFrame + interpolate, 클램프됨, style에 인라인). 절대 CSS transition/animation을 사용하지 마세요.