Communitygithub.com

remotion-design-system

口播 MG 设计系统硬约束:token 语义、组件规格、铁律。做任何包装元素/视觉决策前必读。触发词:设计系统、组件、token、字体、配色。

remotion-design-system란 무엇인가요?

이 스킬은 `remotion-design-system`으로, Remotion 기반의 구술형 MG(Motion Graphics) 패키징 디자인 시스템을 정의한 하드 컨스트레인트 허브입니다. 개발자는 이 스킬을 통해 디자인 시스템의 핵심 철칙(6대 불문율), 디자인 토큰(색상, 폰트, 크기, 간격)의 의미론적 사용 규칙, 그리고 SideLabel, HeroText, Chip 등 주요 컴포넌트의 상세 스펙을 참조할 수 있습니다. 또한, references/ 디렉토리 내 세부 문서(레이아웃, 타이포그래피, 텍스처, 모션 등)로의 라우팅 테이블을 제공하여, 특정 시각적 결정을 내리기 전에 해당 파일을 먼저 확인하도록 유도합니다. 이 스킬은 특히 '밝은 배경에 텍스트를 직접 사용하지 않는다', '한 문장에 하나의 강조어만 사용한다' 등 구체적이고 엄격한 규칙을 통해 일관된 브랜드 경험을 보장하며, 이전 프로젝트에서 발생한 77개의 차이점을 분석하여 체계화된 지식 베이스를 제공합니다. 최종적으로 `src/design/tokens.ts`를 유일한 진리값 소스로 삼아 코드와 디자인 명세 간의 불일치를 방지합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jincheng2026/jc-remotion-skills/tree/main/skills/remotion-design-system

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Remotion 구술 패키징 디자인 시스템 (v1 hub)

스타일 목표: 기준 영상의 구술 HUD 패키징 재현 (참고 이미지 프로젝트 refs/). 이 파일은 하드 컨스트레인트 허브입니다: 불문율 + 토큰 의미론 + 컴포넌트 요약 + 오답 노트; 세부 규칙은 references/에 있습니다 (2026-07-16 77개 차이점 심층 비교 결과 정착). 이 체계에 없는 시각적 결정은, 해당 섹션 파일에 먼저 보충한 후 코드를 작성하세요.

섹션 라우팅 테이블 (무엇을 할지 해당 파일을 읽으세요)

섹션파일담당 내용
스펙 테이블 (먼저 확인 후 코드 작성)references/specs.md기준 영상 측정 진리값: 카드 너비/폰트 크기/위치/모션 프레임 수 조립 전 필수 확인, 테이블에 없으면 직접 측정하여 추가, 육안 추정 금지
레이아웃 구성references/layout.md3구역, 테이크오버 메커니즘 (A급은 PiP 없음, 어둡게 슬로우모션은 이미 기각), 한 화면 한 중심, 그룹핑 템플릿, 끼워맞춤 위치
타이포그래피references/typography.md유일한 최대 폰트, h1 의무, hero 샌드위치, SideLabel title 변형
색상 & 질감references/texture.md젤리 블록/글로우, SURFACE 밝음/어두움 변형, 스탬프 사양 유일선, 동일 화면 색상 계열 ≤2, 밝은 배경 텍스트 직접 사용 금지 세부 규칙
모션references/motion.mduseEnter/useExit 사용, 비트 분할, 빌드업, 서비스 구간, Breathe, 빈 화면
정보 디자인references/infographic.md차트 옵션, 비유적 그래픽, 와플, 큰 숫자 3단 구조, 마이크로 그래픽 어휘
내러티브/리듬/자막/소스/오디오remotion-assembly의 references/narrative / rhythm / subtitle / broll / audio
오답 노트 (증상 → 수정법 인덱스)독립 스킬 remotion-gotchas-index전체 문서에서 '오답 #NN'의 수정 위치를 여기서 조회; 렌더링 이상/화면 불일치 시 먼저 확인

엔지니어링 베이스 목록 (substrate — 콜드 스타트 / 새 영상 시작 전에 먼저 확인)

이 디자인 시스템은 전체 저장소 공유 베이스이며, 각 영상마다 재구축하지 않습니다. 다음 파일들은 전체 프로세스(assembly '입력 검수→프레임 출력→3중 게이트' + motion §12 게이트) 실행의 전제 조건입니다; 새 영상은 기본적으로 이를 재사용하며, 자신의 composition + 자막 + Scene만 추가하고 베이스를 다시 만들지 않습니다. 콜드 스타트 독자(src/ 읽기 금지)는 종종 여기서 실패합니다 — 이 테이블을 따라 파일이 있는지 확인하고, 구체적인 값을 원하면 해당 파일을 열어 읽으십시오. 스킬이 값을 전달해 주기를 기대하지 마세요.

베이스 파일내용물콜드 스타트 사용법
src/design/tokens.ts수치 유일 진리값: COLOR (4가지 의미론적 색상 + 기본색 hex), SURFACE, FONT, GRADIENT, SIZE 계단 (kicker…mega), GRID, RADIUS, SAFE, MOTION 프레임 수SIZE.mega, 의미론적 색상 hex 등 구체적인 픽셀/색상은 이 파일에서 직접 가져오세요 — 스킬은 일부러 복사하지 않습니다 (스냅샷과 코드 불일치 방지, §1 참조); 파일이 없음 = 베이스 누락, 먼저 생성
src/design/*.tsx컴포넌트 라이브러리 (§3 전체 표: SideLabel/HeroText/Chip…) + FontGuard.tsx (폰트 문지기, 오답 #01) + qc.tsx (QC 프로브 QcProbe: 프레임별 [data-qc] 박스 판독하여 겹침 검사, 오답 #29)패키징 요소 작성 전 §3 컴포넌트 표에서 파일 위치 확인
src/design/motion.tsuseEnter/useExit/usePop 하위 훅 + MOTION 상수motion.md 규칙이 참조하는 훅은 모두 여기에 있음
src/design/fonts.ts@fontsource 로컬 폰트 등록 (오답 #01: 웹폰트는 네트워크를 통해 가져올 경우 자동으로 명조체로 폴백)package.json sideEffects에 반드시 포함
src/koubo/scenes/shared.tsx조립 레이어 게이트 4종 세트 Enter/DimAfter/Exit/ClearOut (motion §12) + Place 위치 박스 + qcAllow QC 끼워맞춤 화이트리스트 (assembly §2.5 게이트 ①)어셈블리 Scene 작성 시 이러한 래퍼를 직접 사용, opacity를 수동 조작하지 않음
src/Root.tsxcomposition 등록 위치 (기존 <Composition id="Koubo-0715-01" fps={30} …/>)새 영상은 여기에 <Composition> 하나를 추가, id는 자유롭게 지정; 단편 렌더링 스크립트는 이 id와 일치해야 함 (assembly §6 render-service id 변경 참조)
src/koubo/각 영상 전용: subtitles-<영상명>.ts / SubtitleTrack.tsx / <영상명 메인 컴포넌트>.tsx / scenes/SceneNN.tsx새 영상은 이 레이어에만 파일을 추가 (구조는 assembly §4 참조)

진정한 처음부터 부트스트랩 (src/가 완전히 비어 있음): 베이스가 준비되기 전에는 assembly 프로세스를 시작할 수 없습니다 (토큰 획득 불가, 첫 프레임 출력 불가, 3중 게이트 진행 불가). 순서 = 베이스 먼저 구축 후 어셈블리: ① tokens.ts 수치 진리값 설정 → ② fonts.ts + FontGuard.tsx (오답 #01) → ③ motion.ts 3개 훅 → ④ §3 컴포넌트 라이브러리 → ⑤ src/koubo/scenes/shared.tsx 게이트 4종 세트 + Place/qcAllow → ⑥ src/design/qc.tsx QC 프로브 → ⑦ src/Root.tsx composition 등록. 이 저장소의 src/design을 참조 구현으로 이식; 이식 후에도 수치는 여전히 tokens.ts에서 읽어오며, 스킬에 다시 채우지 않습니다.

0. 6대 불문율

  1. 정보 영역은 기본적으로 왼쪽, 인물은 오른쪽: 정보 영역은 기본적으로 왼쪽 (사용자 결정 작성자 기본값), HUD는 왼쪽 세로 방향으로 고정, 인물 영역은 진입 불가; 하지만 각 영상의 구성은 먼저 사용자에게 물어보고 임의로 결정하지 마세요, 3구역 좌표와 테이크오버 예외 메커니즘은 references/layout.md 규칙 1 참조.
  2. 모든 텍스트는 이중 구조: 대문자 넓은 자간 kicker (작게) + 중문 굵은 검정 (크게). 한 층의 텍스트만 있는 컴포넌트는 미완성으로 간주.
  3. 한 문장에서 하나의 단어만 강조: 중문 제목에서 색상 변경/강조 단어는 최대 한 곳, 색상은 반드시 4색 의미론 시스템에서 가져와야 함.
  4. 실제 소재가 주체, Remotion은 합성기이지 드로잉 보드가 아님 (2026-07-16 seg01 결정 업그레이드): '제품 경험'류 화면 (타이핑/생성/인터페이스/데모)은 모두 실제 소재 편집 — 직접 화면 녹화 > 공식 동영상 > 웹페이지 스크린샷 > UI 시뮬레이션 카드; 손 그림은 HUD 레이어(사이드 레이블/자막/차트/스탬프/비유적 그래픽)만 담당. CSS로 수제 모션 그래픽 전문가 팀의 작품을 따라 하면 반드시 실패하며, '아무리 조정해도 비슷하지 않음/차이가 크다'는 근본 원인은 드로잉 보드로 합성기의 싸움을 하는 것입니다. 수집 및 편집 파이프라인은 assembly references/broll.md 참조.
  5. 밝은 배경에 텍스트 직접 사용 금지 (2026-07-16 심층 비교 판결, 6개 섹션에 걸친 최상위 크로스 규칙): 밝은 배경 (흰 보드/흰 벽/밝은 색상 테이크오버 바닥) 위에 배경 없는 텍스트 금지 — 모든 텍스트는 반드시 어두운 색상 바닥판 (SURFACE.darkPlate), 카드 본체 또는 밝은 표면 변형 위에 위치해야 하며, textShadow는 해결책이 아님. 세부 규칙은 references/texture.md 참조.
  6. 한 화면에 하나의 지배 레이어: 각 정보 화면은 단 하나의 '최대 글자/최대 요소'만 있으며, 주 영역 외에 최대 2개의 칩 수준의 작은 요소만 허용. 세부 규칙은 references/typography.md와 layout.md 참조.

1. Design Tokens

유일한 진리값 = src/design/tokens.ts, 모든 컴포넌트는 거기서만 값을 가져와야 합니다. 이 섹션은 의미론과 사용 규칙만 작성하며, 수치는 복사하지 않습니다 — 이전에 스냅샷과 코드가 한 번 불일치했으며 (2026-07-16 kicker/h1 등 여러 곳 불일치 발견), 코드를 기준으로 합니다.

  • 4색 의미론 (유일하게 허용되는 강조 색상): blue=정의/방법/중립적 진행; green=긍정/낮은 진입 장벽/이미 적용됨; yellow=기회/경고/논쟁/전환; red=부정/함정/위기. 기본 색상에는 white/grey/greyDim/cardBg/cardStroke가 별도로 있음.
  • 폰트 (두 층으로 구분, 혼용 금지): MG 패키징 레이어 — FONT.zh=Noto Sans SC (패키징 레이어 중문 유일 폰트, 제목은 일률적으로 FONT.zhHeavy); FONT.en=Inter (kicker/본문/숫자); FONT.enTitle=Archivo Black (영문 제목과 큰 글자 결론, 좁은 사각형 초흑체, weight는 일률적으로 400 — Inter는 큰 글자 기세를 지탱하지 못함, 2026-07 자형 비교 결론). 하단 자막 레이어 — FONT.subZh=PingFang SC 400 / FONT.subEn=Inter 300 (2026-07-26 5단계 실사 비교 후 사용자 판결): 자막은 따라 읽기 레이어이지 패키징 레이어가 아니며, 가는 체만이 애플 자막의 질감을 가지며, MG 굵은 검정 제목과 계층을 나누고 주의를 빼앗지 않음; 구버전은 전체를 Noto 700으로 사용하여 스티커처럼 보였음. PingFang SC는 macOS 시스템 폰트이며, @fontsource 번들링을 사용하지 않음 — 로컬 렌더링은 문제없지만, Windows/Linux 환경에서는 번들링된 Noto Sans SC 400 가는 파일로 폴백됨 (fonts.ts에 이미 포함되어 있어 느낌은 비슷하지만 동일 폰트는 아님), 교차 머신 렌더링 전에 먼저 한 프레임을 렌더링하여 자막 느낌 확인. 자막 영문 줄은 반드시 비례 서양 폰트를 사용해야 하며, 오답 #42 참조.
  • 큰 글자 결론은 일률적으로 순수 의미론적 색상 + textShadow를 사용하며, backgroundClip:text 그라데이션 폰트 금지 (오답 #06); GRADIENT는 색상 블록/테두리류 용도에만 사용.
  • 글자 크기는 SIZE 계단 (kicker / subSmall / chip / subZh / subEn / card / h2 / h1 / mega)만 허용하며, 계단 외 글자 크기 금지; 1080p 기준, 4K 출력은 등비 ×2.
  • 간격은 일률적으로 GRID (8px)의 배수; 둥근 모서리는 RADIUS 사용; 안전 영역은 SAFE 사용 (사이드 레이블 앵커, 스택 왼쪽 가장자리, 자막 바닥 거리; 상주 카드는 x55%를 넘지 않음, 인물 진입 금지 구역/오른쪽 구역 좌표는 layout.md 참조; 자막 금지 구역 y>82%, 왼쪽 영역 요소 하단 가장자리 ≤y840은 y82%보다 더 엄격한 왼쪽 영역 하드라인).

2. 챕터 사이드 레이블 SideLabel (전편 상주, 최우선 순위 컴포넌트)

  • 구조: │ (4px 세로선, 의미론적 색상) + ENGLISH KICKER · 중문 구문 (첫 번째 줄, 영문은 kicker 사양 + 의미론적 색상, 중문 흰색 34px) + 두 번째 줄 회색 24px 보충 설명.
  • 위치: 고정 SAFE.sideLabel, 전환 시 기존 레이블 페이드 아웃 12프레임, 새 레이블 왼쪽 슬라이드 인 15프레임.
  • 명명 규칙은 번호 체계: SCENE 01, PATH 1/2/3, 대칭/반대 (DISSOLVED·01.. vs IMMUNE·01..).
  • 색상 = 이 단락의 감정적 의미론, tokens 주석 참조. 참고: refs/01-版式与侧标/.

3. 컴포넌트 사양 요약 (상세 사양은 구현과 함께 보충, 먼저 참고 이미지 확인 후 코드 작성)

컴포넌트핵심 사양참고
BilingualSub중문 52 흰색+검은 그림자 / 영문 28 순수 흰색, 하단 중앙, 항상 최상위 레이어임의 refs
HeroTextkicker + 중문 h1/h2, 강조 단어는 의미론적 색상 교체; 변형: 빨간색 취소선 교정, 노란색 브러시 밑줄, 기울어진 스탬프refs/02
Chip검정 카드 RADIUS.chip + 컬러 아이콘 + 34px 텍스트, 한 곳 색상 변경 단어 가능refs/03
ChecklistChip 세로 쌓기, 하나씩 탄성 입력; 비활성화 항목 opacity 0.35refs/03
InfoCard아이콘 + kicker + 44px 제목 + 파란색 강조 단어refs/01
StepList①②③ 원형 번호 + 중문 + 영문 작은 kicker, 단계별 점등refs/04
FlowChain검정 카드 + → 화살표 직렬 연결, 노드별 나타남refs/04
CompareCard로고 + 이름 + 빨간색 ✕ 약점 chip + 초록색 ✓ 강점 chip, 세로 쌓기refs/04
Formula큰 글자 A 기호 B (>, », ⇄, =), 기호는 의미론적 색상 사용refs/05
BigNumberInter 큰 숫자 + 단위 작은 글자 + kicker; 카운터는 spring 스크롤 사용refs/05
BarChart데이터 막대 8px 둥근 모서리; 강조 막대는 노란색 + 상단 왕관 chip; 나머지 회색refs/05
CurveOverlay2–3px 노란색 곡선을 B-roll에 직접 오버레이, 오른쪽 끝점 레이블refs/05
Timeline양 끝점 구간형 / 이벤트에 빨간색/초록색 결과 chip 부착형refs/05
ScoreBoard초록색:빨간색 큰 숫자 점수판refs/05
PhoneMockupiPhone 외곽선 + 그라데이션 테두리 발광 + 내장 스크린샷 긴 이미지 스크롤refs/06
WindowCardmac 신호등 + 앱 아이콘 + 기능 chip, 내용 동적refs/04
QuoteDoc흰색 배경 스크린샷 카드 + 노란색 형광펜 강조 + 검정 배경 중문 번역 바 오버레이refs/07
TweetCard프로필 사진 + 신원 kicker + 빨간색 큰 글자 결론 + views chiprefs/07
PersonCard원형 프로필 사진 + 이름 + 신원 작은 글자 + 기관 chiprefs/07
Stamp기울기 -8°~-6° 테두리 스탬프 글자 (빨간색/초록색), 도장 애니메이션 = scale 1.3→1 + 가벼운 진동refs/08
MatrixIcon사각형 매트릭스 아이콘: 빨간색 = 용해될 진영 / 초록색 = 면역 진영refs/08
CardWall흰색 작은 카드 3→20장 차례로 화면 채우기, 수요 폭발 시뮬레이션refs/06
BeforeAfter두 개의 아이콘 카드 + 파란색 화살표 + 하단 결론 chiprefs/04
Breatheidle 미세 모션 래퍼: 호흡 scale ±0.6% + 부동 ±3px, phase로 위상 분산하여 동기화 방지; 주인공 요소 외부 감싸기src/design/Breathe.tsx
BrickWall맞물린 금색 벽돌 가로 벽을 하나씩 쌓아 올림 + 중앙 레이블, '벽 쌓기/하드 장벽' 비유src/design/BrickWall.tsx
UnitMatrixN개 그룹의 사각형 매트릭스를 셀별로 점등; fillRatio 와플 모드 (73% 데이터 필드)src/design/UnitMatrix.tsx
CloneCascade소스 아이콘 카드 + 모조품이 차례로 페이드 인 + 경고 chip, '복제/증류' 비유src/design/CloneCascade.tsx

일괄 생산 라인 Scene 인라인 요소 (2026-07-17 일괄 생산 추가, 아직 공유 요소로 승격되지 않음)

다음 요소는 현재 단일 Scene에만 존재하며, 'Scene 인라인, 두 번째 재사용 시 src/design 공유 요소로 승격하고 specs 사양 줄 추가' 로 표시 — 새 영상에서 유사한 요구사항 충돌 시 여기를 먼저 확인하고, 다시 만들지 마세요:

인라인 요소위치기능승격 조건
DissolveGridscenes/Scene08.tsx용해 그리드: 용해될 진영 블록이 셀별로 용해 분산, 중앙 ⚡ 바닥판 페이드 아웃 후 흰색 윤곽선 떠 있음두 번째 '진영 용해' 비유 재사용 시
VerdictBox (결산 프레임)scenes/Scene17.tsx빨간색/초록색 미러 결산 프레임: ≈400×170 테두리 빈 프레임 먼저 세움 + 프레임 내 header + 가로 배열 3 chip 분할 입장 (빨간색 먼저 채워지고 초록색 나중에 채워져 '어느 쪽에 설래' 서스펜스 생성)두 번째 'VS 결산' 승격 시
NamePlate + CtaBadge (CTA 배지 열)scenes/Scene19.tsx엔딩 CTA 하단 가로 배열 한 줄: 명판 먼저 착지하여 앵커 역할 → 4개 액션 배지 차례로 탄성 입력 (댓글 배지 마지막이 가장 넓음 = 강조)두 번째 엔딩 CTA 마무리 시

아이콘 규칙

  • 아이콘은 일률적으로 lucide-react 선형 SVG 아이콘 사용, 색상은 의미론적 색상 (COLOR[accent]), strokeWidth 2.5 정도; 이모지 금지 (컬러 둥근 모서리 블록은 기준 영상의 단색 선형 스타일과 충돌, 2026-07 세 번째 배치 검수 교훈).
  • Chip / Checklist / SideLabel의 icon prop은 모두 ReactNode를 허용: icon={<Lock size={26} strokeWidth={2.5} />}.

질감 규칙 → references/texture.md

젤리 블록 그라데이션, 동일 색상 glow, 비네트, 진짜 로고, SURFACE 밝음/어두움 변형, 스탬프 사양 유일선은 모두 texture.md에 있음 (2026-07-16부터 질감 유일 진리값, 이 섹션의 기존 내용은 이동됨).

4. 모션 규칙 → references/motion.md

useEnter/useExit, 비트 분할 입장, 서비스 구간, Breathe, 챕터 간 빈 화면, 금지 항목은 모두 motion.md에 있음 (2026-07-16부터 모션 유일 진리값, 이 섹션의 기존 내용은 이동됨; '이전 정보 투명도 감소 상주'는 '서비스 구간 + 퇴장 규율'로 대체되었음에 주의).

5. 내보내기 전 자체 점검 (매 렌더링 전에 실행)

  1. grep 검사로 tokens 외부의 색상 값/글자 크기/폰트를 컴포넌트에 인라인으로 사용했는지 확인.
  2. 모든 상주 카드가 faceZone / subtitleZone을 침범하는지 확인.
  3. 각 제목 강조 단어가 ≤ 1곳인지 확인; 영문 kicker가 모두 대문자 + 자간인지 확인.
  4. 3–5개의 키 프레임을 캡처하여 refs/의 해당 참고 이미지와 나란히 비교, 다르면 어떤 token 규칙을 위반했는지 파악하고 token을 수정, 컴포넌트 인라인을 수정하지 않음.

6. 오답 노트

#01 중문이 자동으로 명조체로 폴백 (2026-07-15 · 디자인 시스템 첫날)

  • 증상: 렌더링/스크린샷에서 중문이 명조체로 바뀌고, 영문은 정상; 동일 컴포넌트가 때때로 정상이고 때로는 비정상 (운에 따라 다름).
  • 원인: 세 가지 층, 마지막 층이 진짜 원인. ① @remotion/google-fonts 런타임에 gstatic에서 폰트를 가져오고, 국내 네트워크에서 가져올 수 없어 자동 폴백; ② 중문 웹폰트는 unicode-range로 분할되어, 로딩과 스크린샷 사이에 경쟁 상태 발생; ③ 트리 쉐이킹: package.json의 sideEffects: ["*.css"]로 인해 사이드 이펙트로만 가져온 fonts.ts가 프로덕션 번들링 시 전체 제거되어 폰트 CSS가 렌더링 번들에 없음 (document.fonts.size === 0) — Studio 개발 모드는 트리 쉐이킹하지 않으므로 'Studio 정상, 렌더링 실패'.
  • 수정법: ① 폰트는 @fontsource 로컬 패키지 사용 (src/design/fonts.ts); ② package.json의 sideEffects에 반드시 "src/design/fonts.ts" 포함; ③ 텍스트가 포함된 모든 합성에는 <FontGuard/>를 적용: load→check 루프 검증, 동시에 document.fonts.size > 0 확인 (fonts.check()는 폰트 등록이 0일 때 빈 값으로 true 반환 가능), 타임아웃 시 즉시 cancelRender로 오류 보고, 절대 명조체 프레임을 묵인하지 않음.
  • 교훈: 'Studio 정상, 내보내기 실패'는 우선 프로덕션 번들링 차이(트리 쉐이킹/압축)를 의심, 미스터리한 경쟁 상태가 아님; 폰트 검수는 FontGuard 하드 게이트에 의존해야 하며, 사람 눈으로 썸네일을 믿을 수 없음.

#02 remotion still 출력 '○' = 이전 이미지 재사용

  • 증상: 코드를 변경하고 다시 렌더링했지만 출력 파일이 전혀 변하지 않음; 명령줄에 + 대신 ○ 표시.
  • 수정법: 렌더링 검수 전에 이전 출력 삭제 (또는 새 파일 이름으로 렌더링); 필요시 --bundle-cache=false 추가. + = 실제 렌더링, ○ = 의심스러움.
  • 교훈: 비교 검수는 반드시 실제로 신선한 렌더링 결과물을 기반으로 해야 하며, 그렇지 않으면 '수정 무효'로 오진하게 됨 (이번에 이로 인해 두 바퀴를 더 돌았음).

#03 썸네일 비교 이미지는 속일 수 있음

  • 증상: 나란히 비교한 작은 이미지에서 중문이 명조체처럼 보이지만, 원본은 실제로 정상.
  • 수정법: 폰트/테두리 세부 사항을 판단할 때는 반드시 원본 해상도로 잘라서局部 확대하여 보며, 전체 프레임 썸네일로 결론 내리지 않음.

#04 JSX 속성 문자열이 \uXXXX 이스케이프를 해석하지 않음

  • 증상: <Chip icon="\u2705" /> 화면에 실제 ✅ 대신 문자 그대로 \u2705 표시.
  • 원인: JSX 속성의 문자열 리터럴은 HTML 방식 텍스트이며, JS 이스케이프 해석을 거치지 않음; JS 표현식 내의 문자열 (icon={'\u2705'})만 이스케이프를 해석. 스크립트로 대량 TSX를 작성할 때 가장 쉽게 밟음.
  • 수정법: JSX 속성에서 이모지/특수 문자는 직접 실제 문자를 사용 (icon="✅"); 이스케이프가 반드시 필요하면 icon={'\u2705'}로 작성.

#06 backgroundClip: text 그라데이션 폰트 렌더링 어두움

  • 증상: 큰 글자 제목에 backgroundImage 그라데이션 + WebkitBackgroundClip:'text' + WebkitTextFillColor:'transparent' 사용, Studio에서는 괜찮지만 렌더링 출력물에서 색상이 어둡고 탁해짐 (밝은 빨간색이 벽돌색으로 변함), 사용자가 단번에 거절.
  • 수정법: 큰 글자 결론은 일률적으로 순수 의미론적 색상 COLOR[semantic] + textShadow; 계층감을 원하면 그림자와 글자 두께로 구현, 그라데이션 채우기로 하지 않음. tokens.GRADIENT는 색상 블록/테두리류 용도에만 사용.

#08 완성 영상 MG 텍스트 가장자리 후광 효과, 칠한 듯한 느낌 ('MG 추가 시 화질 저하')(2026-07-16 · 0715-01 v3)

  • 증상: 사용자가 완성 영상을 보고 화질이 나쁘다고 함; 확대하여 MG 텍스트 가장자리에 JPEG 모기 잡음/후광 효과가 있으며, 선명한 요소일수록 더 두드러짐. 소스 자체는 15 Mbps HEVC로 매우 깨끗함.
  • 원인: Remotion 기본 파이프라인의 이중 압축 — 매 프레임을 품질 80의 JPEG 스크린샷으로 캡처한 후, CRF 18로 H264 압축. MG 큰 글자/가는 선은 고주파 신호로, 압축 아티팩트가 가장 먼저 나타남. MG 추가 전에는 아티팩트가 실제 촬영 텍스처에 숨어 눈에 띄지 않아 'MG가 화질을 나쁘게 한다'로 오진.
  • 수정법: remotion.config.ts에 Config.setJpegQuality(100) + Config.setCrf(15) 고정 (본 프로젝트 이미 설정됨, 되돌리지 마십시오). 용량 약 +20%, 렌더링 약간 느림, 그만한 가치가 있음.
  • 진단법: 동일 프레임을 소스/이전 완성 영상/새 파라미터 테스트 구간에서 각각 캡처하여 동일 MG 텍스트 영역을 잘라 확대하여 나란히 비교; 먼저 5초 테스트 구간을 렌더링하여 파라미터를 검증한 후 전체 영상 렌더링.

#09 긴 렌더링 도중 사라짐, mp4가 조각 파일로 남음 (2026-07-16 · 0715-01 v3)

  • 증상: 렌더링이 오래 실행된 후 '프로세스는 살아 있지만' 결과물 파일이 오랫동안 크기가 증가하지 않음; 또는 렌더링이 소리 없이 사라져서 열 수 없는 mp4가 남음.
  • 원인: ① 렌더링이 AI 세션의 하위 프로세스에 걸려 있어, 세션 재시작/종료 시 렌더링도 함께 종료됨 (이번에는 90%에서 종료됨); ② 프로세스 감지를 위해 pgrep -f "remotion render" 사용 시 감지 스크립트 자체도 일치할 수 있음 (명령줄에 동일한 문자열이 포함되어 있어), '프로세스가 살아 있다'는 착각을 일으킴.
  • 수정법: ① 수 분 이상의 렌더링은 일률적으로 nohup npx remotion render … > /tmp/xx.log 2>&1 & disown으로 세션에서 분리; ② 완료 판단 기준은 로그 내 + 출력 파일 이름 행 (+ = 실제 렌더링 성공)으로 인지하며, 프로세스 존재 여부로 판단하지 않음; ③ 프로세스 감지는 자기 자신과의 일치를 배제 (CPU 점유율 확인 또는 정확한 PID 사용); ④ 다시 렌더링하기 전에 조각 파일 삭제.
  • 교훈: 조각 mp4 (재생 시간/용량이 일치하지 않음)는 절대 전달하지 않고, 먼저 ffprobe로 재생 시간과 오디오 트랙을 확인한 후 사용자에게 보여줌.

Individual skills in this repo

This repo contains 5 individual skills — each has its own dedicated page.

관련 스킬