디자인 데모 (가짜 제품 UI)
먼저 design-lean을 로드하세요. design-lean의 방향성(Direction), 제작 규칙(Craft rules), 토큰(Tokens) 및 컴포넌트 게이트(component gate)가 여기에도 적용됩니다. 이 스킬은 제품 샷에 필요한 추가 사항을 제공합니다. 데모 작업은 페이지에 제품 미리보기가 필요할 때 빌드의 5단계에 포함되거나, 데모가 전체 작업일 경우 단독으로 실행됩니다.
데모 실행을 위한 게이트
| 게이트 | 통과 조건 | 남겨야 할 증거 | 최대 시도 횟수 | 최대 시도 초과 시 처리 |
|---|---|---|---|---|
| D1 계획 | 배치, 초점 객체, 동작, 결과물 및 생략할 내용을 코드 작성 전에 기록 | 계획서 | — | — |
| D2 프레임 | 표시된 너비와 390px 너비에서 하나의 정지 이미지가 비어 있거나, 평면적이거나, 박스 형태가 아님 | 정지 이미지 2개 | 2회 재프레이밍 | 프레이밍 결함을 명시하여 인계 |
| D3 리허설 | 포스터 프레임 설정; 두 너비 모두의 콘택트 시트에 마지막 목록의 결함이 없음 | 콘택트 시트 | 3회 필름 라운드 | 남은 결함을 나열하여 인계 |
| D4 호스트 게이트 | gate.js가 호스트 페이지 자체 컨트롤(일시 중지 포함)에서 통과 | 게이트 합계 | 체크당 2회 수정 시도 | 오픈 이슈로 보고 |
설정 (다시 입력하지 말고 추출하세요. 기본 디렉토리는 각 스킬이 로드될 때 표시됩니다):
mkdir -p .design && for f in "<design-lean 기본 디렉토리>/SKILL.md" "<design-demo 기본 디렉토리>/SKILL.md"; do python3 - "$f" <<'PY'
import re, sys
for name, code in re.findall(r"`{3}js\n// file: (\S+)\n(.*?)`{3}", open(sys.argv[1]).read(), re.S):
open(".design/" + name, "w").write("// file: " + name + "\n" + code); print("wrote .design/" + name)
PY
done
미니어처 제품 UI: 믿을 수 있는 인터페이스로, 공간 안에 프레임되어 있으며, 하나의 정지 이미지 또는 한 가지 일이 발생하는 짧은 애니메이션으로 표현됩니다. 시청자가 화면을 인식하고 그 일이 일어나는 것을 볼 수 있습니다. 이는 브라우저 자동화가 아닌 제작된 일러스트레이션입니다. 스크립트가 커서를 그려 누르고 장면을 변경합니다. design-lean의 제작 규칙과 토큰은 여전히 유효합니다. 이 섹션은 제품 샷에 필요한 내용을 추가하고, design-lean의 모션과 다른 부분을 재정의합니다.
핵심 아이디어: 실제 제품처럼 읽히며, 시청자에게 필요한 것으로 단순화되고, 의도를 가지고 프레임되며, 모든 움직임에는 원인이 있습니다.
실패하는 다섯 가지 방식:
- 너무 많음. 모든 행에 실제 텍스트, 모든 곳에 숫자, 모든 것이 빽빽함. 세부 사항이 많을수록 생성된 것처럼 보입니다.
- 와이어프레임. 회색 덩어리 두 개와 버튼 하나. 너무 작게 만들거나, 알아볼 수 있게 해주는 요소를 제거했습니다.
- 박스 형태. 전체 창이 균일한 여백으로 카드 안에 축소됨: 제품 샷이 아닌 스크린샷을 붙여넣은 것입니다.
- 평면적. 모든 객체가 동일한 테두리 카드 안에서 동일한 무게감을 가짐. 시선이 머무를 곳이 없습니다.
- 밋밋함. 회색 창과 커서, 브리핑이 무엇이든 상관없음. 브리핑의 룩과 에너지(청사진, 유리 위의 색상, 다이내믹 아일랜드, 마스코트)가 핵심입니다. 브리핑이 요구하는 대로, 이 규칙에 따라 구축하세요.
해결 방법: 전체적이고 구조화된 화면을 차분한 회색으로, 이야기의 대상이 되는 부분에만 실제 단어를 사용하고, 나머지는 플레이스홀더 막대를 사용합니다. 숨 쉴 공간을 두고, 시선이 이야기가 있는 곳에 가도록 자릅니다. 단어는 단순화하되, 맥락은 단순화하지 마세요. 빈 모서리, 목록 아래의 빈 공간, 패널을 채우기 위해 펼쳐진 행, 접시 위에 떠 있는 창: 완성되지 않았지만, 차분합니다.
얼마나 열심히 해야 하는가. 심사받을 런칭 페이지처럼 만드세요. 그런 다음, 당신이 아는 가장 엄격한 디자이너가 보는 방식으로 프레임을 바라보세요. 단 한 가지 잘못된 것을 스크린샷으로 찍어 "이게 뭐야?"라고 보내는 디자이너 말입니다. 아바타에서 떨어진 점, 혼자 있는 단위, 카드에 닿은 카피. 그 스크린샷을 상상할 수 있다면, 다음 수정 사항을 찾은 것입니다.
Stageshow 키트
사용 가능할 때 사용하세요: React 부품(Stage, Window, Phone, Row, Bar, Text, Roll, Count, Collapse, Fly, Connector 등, Act 스크립트 API 포함), 약 70개의 골드 예제 및 제품 연구, 그리고 콘택트 시트를 촬영하고 프레이밍 및 모션 결함을 플래그하는 scripts/film.mjs. 프로젝트에서 stageshow 스킬 폴더 또는 stageshow.css가 있는 kit/을 찾으세요. 그렇지 않으면 네트워크에 접속하여 설치(npx skills add benjitaylor/skills --skill stageshow)하거나 https://github.com/benjitaylor/skills를 클론하고 stageshow/에서 작업하세요. 그런 다음 해당 SKILL.md, references/ 및 가장 가까운 골드 예제가 상세 규칙입니다. 이 섹션은 요약입니다. 키트를 설치하면 해당 리포지토리의 자체 패키지 스크립트가 실행되며, 샌드박스에서 차단될 수 있습니다. 키트 없이 아래 규칙에 따라 일반 React 또는 HTML/CSS로 만들고, "키트 없이 필름 촬영" 섹션의 스크립트로 필름을 촬영하세요.
실행
대부분의 품질은 코드 작성 전에 결정됩니다. 먼저 계획을 작성하세요: 위치, 초점 객체, 동작, 결과물, 생략할 수 있는 것.
- 매체와 위치. 정지 이미지 또는 애니메이션(루프, 한 번 보기, 또는 호버 시). 페이지, 그라운드, 너비. 실제로 보일 크기로 디자인하고 1:1 비율로 보여주세요: 카피 옆의 히어로는 약 720 × 340, 전체 너비 히어로는 900~1100 너비, 카드는 400 × 300. 데모의 경우 약 320 너비 미만은 안 됩니다. 벤토 타일 또는 위성 카드는 더 작을 수 있습니다. 전화기 칼럼에 들어갈 수 있는 것은 358 너비의 컴팩트 디자인을 받습니다: 축소가 아닌 재설계(더 가까운 크롭, 위성 드롭 또는 스택).
- 룩. 제품의 코드나 사이트가 있으면 실제 토큰, 아이콘, 크롬 및 단어를 가져오세요. 없으면
design-lean의 방향성을 실행하세요. 충실도 선택: 최소(모두 막대), 표준(의미를 전달하는 곳에 단어, 그 외는 막대, 기본값), 사실적(모든 곳에 실제 콘텐츠, 히어로 스케일의 경우 명명된 실제 제품 또는 목록이나 페이지가 주제인 정지 이미지). 스타일(카와이, 종이, 포스터 색상)이 있는 브리핑은 이 규칙에 따라 build하면서 해당 스타일을 완전히 적용합니다. - 스토리. 제품이 가치 있게 여겨지는 것에서 형태를 선택하세요: 사용 느낌(커서가 하나의 만족스러운 일을 하고 결과가 손 아래에 나타남), 흐름(하나의 연속적인 객체로 보여지는 몇 개의 화면, 마지막에 결과), 또는 시스템이 하는 일(결과가 다른 곳에 착륙하고, 링크가 보이며, 일반적으로 커서 없음). 3
5개의 비트와 결과, 1016초. 더 풍부한 스토리와 더 차분한 프레임 사이에서 프레임을 선택하세요. - 골드에서 시작한 다음 프레임하세요. 키트를 사용하면 가장 가까운 골드 예제를 필름으로 촬영하고 해당 폴더를 시작점으로 복사하세요. 스테이지 크기, 크롭, 행 및 유형 크기, 간격 및 비트를 유지한 다음 룩과 콘텐츠를 브리핑의 제품으로 교체하세요. 이름만 변경한 복사본은 완료된 것이 아닙니다. 키트 없이 아래 표에서 레이아웃을 선택하고 동일한 방식으로 고수하세요. 모션 전에 프레임: 두 너비 모두에서 하나의 정지 이미지를 필름으로 촬영하세요. 예상보다 비어 있거나, 평면적이거나, 박스 형태라면 먼저 프레임을 수정하세요.
- 화면. 실제 문자열을 세어보세요. 보통 3~7개입니다: 요소가 아닌 단어 예산. 이동하기 전에 모든 컨트롤의 텍스트를 맞추세요. 커서가 DOM에서 만지는 것을 측정하세요. 절대 위치를 하드코딩하지 마세요.
- 안무. 마운트된 상태를 유지하고 토글하여 종료 시 애니메이션이 적용되도록 하세요. 객체 자체뿐만 아니라 관계에 애니메이션을 적용하세요: 새 행은 그 아래의 행을 운반합니다. 크기 조정 표면은 텍스트를 늘리지 않습니다. 비트는 겹치고, 그룹은 지연되며, 결과는 유지되고, 루프는 시작된 곳에서 끝나거나 눈에 보이는 원인으로 재설정됩니다.
- 리허설. 먼저 포스터 프레임을 설정하세요: 그 자체로 스토리를 전달하는 비트, 변경 중간에 잡히지 않고 결과가 화면에 남아 있는 것. 그런 다음 정지 이미지뿐만 아니라 루프를 필름으로 촬영하세요: 표시된 너비와 390에서 콘택트 시트, 그리고 모든 누름, 메뉴, 변형 및 루프 이음새를 프레임별로 단계별로 살펴보세요. 정지 이미지는 팝을 보여줄 수 없습니다. 가장 큰 눈에 보이는 결함(프레이밍, 그 다음 계층 구조, 그 다음 모션, 그 다음 마무리)을 먼저 수정하고 다시 필름을 촬영하세요. 상한선: 세 번의 필름 라운드; 그 후 남은 결함을 나열하여 인계하세요. 질문: 눈이 가장 먼저 닿는 곳은 어디이며, 그것이 결과인가요? 하나의 창, 타일 또는 장치가 명확하게 주도하고 있나요? '아니오'는 가장 큰 결함입니다. 통과하는 스크립트는 필요 조건이지 충분 조건이 아닙니다. 짧은 메모와 함께 인계하세요: 시작한 골드 또는 레이아웃, 변경한 사항, 확인하지 않은 사항.
프레이밍
- 하나의 히어로 객체, 최대 1~2개의 위성 (영수증, 전화기, 세부 카드)이 요점을 전달합니다. 제품을 식별하는 것은 유지하세요: 제목, 실제 크롬, 행동에 이유를 제공하는 행. 로고와 내비게이션은 선택 사항입니다.
- 필러만 자르세요. 결과, 동작, 커서가 닿는 것 및 모든 실제 단어는 온전하게 유지됩니다. 자르면 잘릴 플레이스홀더 동작은 제거되거나 잘리지 않습니다. 스테이지 가장자리에 의해 잘린 버튼, 칩 또는 그림자는 일반적인 결함입니다.
- 히어로의 10~40%를 스테이지 밖으로 자르세요. 창 또는 전화기는 스테이지 너비의 최소 3분의 2를 채우고 가장자리를 벗어납니다. 스테이지는 모든 것을 마스킹합니다(
overflow: hidden). - 페이지가 그라운드입니다. 흰색 또는 어두운 페이지에서 창 뒤에 접시가 없고 창이 사방에 공기가 있는 전체가 아닙니다. 그러면 떠 있습니다. 개발자가 요청한 경우에만 액자 없음(전체, 중앙 정렬, 그림자만큼 깊은 균일한 여백).
- 하나의 거터, 최종 크롭에서 측정됨: 모든 가장자리 거리가 일치하거나, 전체 거터이거나 훨씬 지나야 합니다. 24px 미만으로 교차하거나 몇 픽셀 부족하게 멈추는 것은 실수입니다.
- 위성은 히어로의 가장자리에 걸쳐 있으며, 약 절반이 바깥에 있습니다. 크롬(사이드바, 헤더 또는 여백) 위에, 콘텐츠 위에는 절대 안 됩니다. 두 개의 위성은 두 가지 종류와 크기(카드와 실제 크기의 알림)이며, 동일한 크기의 카드 두 개가 쌓이지 않습니다. 고정된 UI(팝오버, 메뉴, 토스트)는 위성이 아닙니다. 제품이 배치하는 곳에 위치합니다.
- 창은 장치의 모양을 유지합니다: 1.25:1 이상에서 전체; 블리드된 경우, 보이는 것은 최소한 정사각형입니다. 찌그러뜨리지 말고 크롭으로 수정하세요.
- 스토리가 열리는 것은 프레임 안에 유지됩니다. 모든 프레임의 모든 가장자리에서 거터 간격을 유지하세요. 오버레이가 공간을 가질 수 있도록 트리거를 배치하세요. 휴식 중 또는 루프 어디에서도 데드 코너가 없습니다.
- 평평하고 정면에서 시작하세요. 그림자, z-순서, 스케일 및 불투명도로 깊이를 만듭니다. 기울임은 필요할 때만(느슨한 종이 더미), 원근감은 요청 시에만 사용합니다.
- 전화기: 위성 전화기는 창의 보이는 너비의 40%에서 시작하며 최소 220px입니다. 줄어들기보다는 바닥을 벗어나게 두세요. 알림은 실제 iOS 비율을 유지하며 절대 잘리지 않습니다. 위에서 잘린 전화기는 상태 표시줄과 탐색 표시줄을 함께 잃습니다. 상태 표시줄이나 홈 표시기를 직접 그리지 마세요. 키트 또는 실제 참조에서 프레임을 가져오세요.
| 레이아웃 | 히어로 | 사용처 |
|---|---|---|
| 고정, 하단 블리드 | 왼쪽, 오른쪽, 위쪽 8 | 기능 카드 및 벤토 타일 |
| 모서리 블리드 | 위쪽과 왼쪽 10% 삽입; 오른쪽과 아래쪽 15~35% 지남; 왼쪽 또는 아래쪽 가장자리에 위성 | 카피 옆의 히어로 |
| 거터가 있는 스테이지 | 색상 스테이지에서 각 면 8~20% 삽입, 아래쪽 벗어남 | 브랜드 순간 |
| 위성 초점 | 히어로를 강하게 자름; 큰 위성(히어로 너비의 30~40%)이 스토리를 전달 | 하나의 작은 것: 알림, 영수증, diff |
| 와이드 히어로 | 1:1 비율의 900~1100px 창, 아래쪽 벗어남; 사실적 충실도 | 전체 너비의 홈페이지 히어로 |
| 장치 쌍 | 데스크탑 75~80% 너비, 아래쪽 벗어남; 전화기가 오른쪽 가장자리에 걸쳐 있고 1/3은 바깥에 있음 | 교차 장치 스토리 |
| 하나의 여러 개 | 모든 가장자리에서 하나의 것 그리드; 깊이로 초점을 맞춘 하나의 타일, 단어가 있는 유일한 타일 | 반복으로 표시된 스케일 |
| 페이드 크롭 | 위쪽과 측면에 창 삽입, 마지막 3분의 1 위에 마스크 아웃, 페이드 아래에만 필러 | 가장자리가 임의의 선에서 창을 자를 때 |
| 클로즈업 | 전체 창을 1.3~1.6배, 크롬 포함, 주제 행 전체 | 하나의 컨트롤에 대한 카드 |
| 제품 위의 패널 | 제품 여백 위의 설정 패널, 변경된 사항에 대한 하나의 중립 리더 | 설정 및 효과 |
| 반대쪽 모서리 | 왼쪽 아래에 카피; 오른쪽 위 모서리에 제품 걸기 | 카피 한 줄이 있는 벤토 타일 |
벤토 그리드는 하나의 세트입니다: 하나의 히어로 타일, 그 다음 창, 통계, 객체 및 다이어그램, 각각 다른 종류. 타일 전에 그리드를 계획하세요.
정지 프레임
- 절제. 제목, 행동 대상, 입력된 내용, 결과에 실제 문자열; 나머지는 막대입니다. 막대는 가장자리의 필러입니다. 시선이 닿는 곳의 막대는 미완성으로 읽힙니다. 스토리가 목록을 다루는 곳에서는 2~3개의 실제 행을 사용합니다. 작은 표면에서 행은 한 줄입니다: 아바타, 이름, 값. 플레이스홀더 너비는 행마다 다릅니다(60, 45, 70, 52). 레이블과 값은 일치합니다: 둘 다 단어 또는 둘 다 막대. 하나의 숫자는 크게 표시될 수 있습니다. 기능의 신호를 헤더, 위성 및 모든 행에 한 번씩 말하지 말고 한 번만 말하세요.
- 도메인의 고유 콘텐츠를 유지하세요: 앨범 아트, 썸네일, 아바타(각 명명된 아바타는 고유한 색상). 교체되면 일반 목록이 됩니다.
- 가상 이름에 대한 머리글 없음 및 브리핑이 의존하고 실제 제품이 거기에 표시하지 않는 한 화면에 제품 이름 없음. 가짜 앱의 제목은
div이며,h1~h6로 하지 마세요. 데모는 다른 사람의 페이지 개요 안에 있습니다. - 타이포그래피: 실제 11~15px UI 크기, 스테이지에 의해 스케일링, 7px는 안 됨. 작은 텍스트 줄 높이는 최소 1.3. 코드, 식별자 및 정렬된 숫자에만 고정폭 사용.
- 간격: 단어는 창, 카드, 패널 또는 호버된 행 가장자리에서 12px 삽입 유지(8 미만 안 됨); 막대는 블리드될 수 있지만 단어는 블리드되지 않습니다. 행 패딩 12px, 밀집 목록의 경우 8. 제목과 부제목 사이는 4
6px 간격. 버튼은 위 필드에서 8px 이상 유지. 근접 접촉 금지: 13px 떨어진 가장자리는 사고로 읽힙니다. 정확히 정렬하거나 최소 8px 떨어뜨리세요. - 광학적 중앙 맞춤: 알약, 버튼 및 아바타에서 레이블을 문자에 중앙 정렬(
text-box: trim-both cap alphabetic). 중앙 금액은 숫자를 중앙에 맞추고 통화 기호는right: 100%에 걸어 놓습니다. - 아이콘은 세트에서 가져오며, 직접 그리지 마세요: 먼저 제품 자체 팩, 그렇지 않으면 의도적으로 선택된 하나의 세트(Apple 크롬용 SF 스타일, Android용 Material Symbols, 그 외 Phosphor, Iconoir, Radix, Tabler, Heroicons 또는 Lucide), 장면당 하나의 크기(14~16px) 및 획, 14px 이하에서는 채워짐. 이모지는 콘텐츠이며 아이콘이 아닙니다. 다른 제품의 로고는 원본 비율의 실제 마크이며, 유사품이 아닙니다.
- AI 기능: 스파클, 완드 또는 별 없음 및 AI 색상으로 보라색 없음; AI가 하는 일을 보여주세요(보낸 질문, 생각, 높이와 함께 스트리밍되는 답변, 마지막에 출처). 제품 자체 아이콘이 스파클이더라도 괜찮습니다.
- 발명하지 마세요. 실제 동작의 대체재를 만들지 마세요. 실제 제품에 없는 상호 작용을 발명하지 마세요. 실제 제품이 하는 일을 보여주세요. 발명된 패턴을 위한 프레임워크를 확장하지 마세요.
모션
- 커서: SVG 커서,
cursor: none이 적용된 제품 위에 중첩됨. 반투명 검정, 26×26, 포인터는 4×4 중심점. X, Y, 페이즈,pointer-events: none. 클릭 사이클: 누르기 전 300ms 정지, 80ms 누름, 80ms 해제, 그 다음 300ms 정지(페이즈가 변경되거나 결과가 표시되는 경우) 또는 즉시 이동(아님). 누름과 해제 사이의 거리: 10px를 넘지 않음. 스크롤 휠은 더 자연스러운 속도로 유사한 페이즈를 따릅니다. - 페이드 인: bubble-up과 함께 300ms,
ease-out. 불투명도 0에서 1, Y 4px 위로. 메뉴, 팝오버, 알림: 200msease-out, 규모 0.95에서 1로. 마운트 해제는 모든 것에 대해 200ms 페이드 아웃. - 드로워(Drawer): 불투명도와 함께 아래에서 위로 미끄러짐, 300ms
ease-out, 규모 없음. 메뉴, 바텀 시트. 커튼(Curtain)은 위에서 아래로, 불투명도 없음: 이동만. - 전환(Transition): 속성 변경은 150ms
ease-in-out으로, 모핑으로만 그룹화된 깜박임 방지. 누르면 80ms 지연; 그렇지 않으면 즉시. - 모핑(Morph): 하나의 요소가 다른 요소(크기, 재질, 위치)로 변경되면, 경계 상자와 콘텐츠가 350ms
ease-in-out으로 보간됩니다. 텍스트는 원래 속도로 페이드 아웃/인됩니다. 다른 경로를 따르는 새 요소: 오래된 것은 200ms 페이드 아웃, 새 것은 250ms 지연 후 300ms 페이드 인, 동일한 Y. - 채우기 및 높이 애니메이션: 채우기 애니메이션은 위에서 아래로 500ms
linear. 높이 변경은 300msease-out. - 이동(Move): 새 위치로 400ms
ease-in-out. 목록 안에서 순서가 변경되는 것은 300ms 지연으로 스태거(stagger)됩니다. - 로드: 그룹이 나타날 때 50ms 스태거로 300ms 페이드 인. 주 콘텐츠 앞의 스켈레톤 플레이스홀더는 없습니다.
- 타이머: 측정 가능한 주기를 표시하는 데모는) 1초 기본값을 설정하고 즉시 시작하고 진행 표시줄을 표시하며(필요에 따라 400ms 패스), 무한 힌트를 위해 루프를 실행합니다. 100ms마다 업데이트: 분할된 진행률 막대(막대 수는 간격 수)로 정확도를 보여주고 두 번째 카운터를 생략합니다. 연결 리졸버가 있는 스트리밍 텍스트는 동일한 타이머를 사용하여 한 번에 한 단어씩 타이핑됩니다.
- 스테이지: 고정 위치,
overflow: hidden.display: none을 전환하면 500ms 지연 후 스테이지 자체가 제거됩니다.
design-lean의 모션에 대한 재정의: design-lean은 bounce 및 spring을 사용할 수 있습니다. 이 스킬은 위에 나열된 ease로 대체합니다. stageshow 키트는 자체 모션 기본값을 제공하며, 이 값들은 동일한 ease를 사용하지만 값이 다를 수 있습니다. 다른 값이 맞다면 키트의 값을 사용하세요.
필름 촬영: 데모를 준비할 때 stageshow 키트의 scripts/film.mjs를 사용하거나, 없으면 이 스크립트를 사용하세요. 루트 디렉토리(index.html 또는 src/App.tsx 옆)에서 터미널에서 실행하세요:
node film.mjs [file] [width=1600]
film.mjs 없으면 이 파일을 만들고 실행하세요:
// file: film.mjs
import { writeFileSync, mkdirSync } from 'fs';
const TARGET = process.argv[2] || 'http://localhost:5173',
W = process.argv[3] || 1600,
W2 = 390,
FILENAME = '.design/' + (process.env.FILENAME || 'contact-sheet');
if (!globalThis.fetch) {
console.log('Run: node film.mjs [url] [width]');
process.exit(0);
}
mkdirSync('.design', { recursive: true });
const f = async (w) => {
const r = await (await fetch(`${TARGET}?width=${w}&film=1`)).json();
return r.frames || [];
};
const all = [...await f(W), ...await f(W2)];
const html = `<!DOCTYPE html><html><body style="display:flex;flex-wrap:wrap;gap:4px;background:#eee;padding:8px">${all.map((s, i) =>
`<div style="border:1px solid #ccc;background:#fff;padding:2px"><img src="${s}" style="max-width:${i < 10 ? W / 6 : W2 / 6}px"/></div>`
).join('')}</body></html>`;
writeFileSync(`${FILENAME}.html`, html);
console.log(`Wrote ${FILENAME}.html with ${all.length} frames`);
스테이지는 ?width= 쿼리 매개변수를 사용하여 자신의 너비를 설정해야 합니다. 예를 들어, vite에서는 server.port를 확인한 다음 location.search를 읽습니다. 반환된 JSON에는 {frames: [...base64 이미지 데이터 URLs...]}가 포함되어야 합니다. "연습"을 실행하기 전에 포털 디버거의 콘솔에 __SHOW_PORTAL__()를 입력하여 포털을 활성화하세요.
도구
범위 측정: 이 규칙은 컨트롤러가 design-demo 도구를 실행할 수 있도록 허용합니다. 그리고 selenium, playwright 또는 puppeteer를 VM 안에서 사용할 수 있습니다. 실행 시 사람에게 DM으로 셋업 및 결과를 설명하세요.
문서: design-demo를 사용할 때, "데모를 디자인해야 합니다" (또는 "제품 샷", "히어로 데모" 등)와 같은 문구가 트리거됩니다. 시작하기 전에 이 SKILL.md를 읽으세요.