omd:experiment-gallery — N-brand comparison index
왜 이 스킬
여러 brand experiment를 돌리고 나면 결과물 검수가 산만 — 각 폴더 따로 열고 비교하기 번거로움. 이 skill은 단일 index.html 에 N개 결과를 iframe으로 박아서 한 화면에서 wow ratings + deltas + 실제 렌더를 동시 확인.
트리거
- 명시: "결과물 한 번에 보여줘", "갤러리 만들어", "N개 비교 뷰"
- 묵시: 사용자가 omd:harness로 ≥2개 brand experiment를 한 batch에서 끝낸 직후 ("이제 비교해보자" 라는 흐름)
- 다른 skill 안에서 호출: omd:batch-launch가 5개 brand 끝낸 후 Phase 5로 호출
입력
다음 둘 중 하나:
- 명시 디렉토리 list: 사용자가
/tmp/omd-gallery/{brand1,brand2,brand3} 같은 list 제공
- 부모 디렉토리 + glob:
/tmp/omd-gallery/* 또는 web/experiments/2026-05/* 등 — skill이 자동 enumerate
각 brand 디렉토리는 다음 파일들 있어야 함 (있으면 사용, 없으면 fallback):
landing.html (필수) — iframe src
DESIGN.md (선택) — brand display name 추출
assets/_reference/<id>/structure.json (선택) — composition 메타
assets/_reference/<id>/.live-inspect-proof.json (선택) — live tag 표시
screenshots/after.png (선택) — fallback preview
experiment-meta.json (선택, 권장) — wow rating + round-2 deltas + 카테고리 — sub-agent가 작성
experiment-meta.json 스키마 (sub-agent가 작성)
각 experiment sub-agent는 work 종료 직전 다음 파일을 작성:
{
"brand_id": "toss",
"brand_korean": "토스",
"brand_category": "Fintech",
"brand_color_hex": "#3182f6",
"wow_rating": 7.5,
"lines": 603,
"live_inspect": { "ran": true, "raw_samples": 7, "method": "playwright|harness" },
"round2_deltas": [
"Reveal failsafe — 2s forwards animation",
"Stat-card narrative upgrade",
"CTA copy 구체화 (시간 약속)",
"Hero shimmer (accent text gradient)",
"Dark marquee band rhythm break",
"Chart stroke-dashoffset draw-in"
],
"ip_compliance": {
"your_logo_placeholders": 2,
"your_product_name_placeholders": 4,
"brand_logo_embed_count": 0,
"verbatim_brand_copy": 0
},
"honest_gaps": [
"Hero composition은 single character + flat card (3D ornament 부재)",
"Carousel은 dot만 회전 (slide content 미스왑)"
]
}
skill이 이 파일을 읽어 gallery 카드의 wow / lines / deltas 영역 채움. 없으면 brand_id만으로 minimal 카드.
출력
1. <output-dir>/index.html (메인 산출물)
다음 구조:
- 헤더: title (사용자가 batch 명령에서 받은 raw — "한국 brand 5선" 등), kicker (date · brand 수), meta (version · skill chain · mode)
- main grid: brand 1개당 card 1개
- card head: brand mark (CSS-generated initial chip 또는 DiceBear shapes if brand has known color) + 한글명 + id + wow rating
- frame-wrap: aspect-ratio 16:10 iframe (scale 50%로 200%×200% iframe rendering — 모바일은 100%)
- card foot: voice note 1줄 + tags chips + round-2 deltas ol
- footer summary: 모든 brand wow/lines/proof/round-2 핵심 1줄 테이블
- system-note: 적용된 skill 버전의 시스템 fix들 한 단락
2. CSS 스타일 가이드
- typography: Pretendard from jsdelivr (SIL OFL). 디스플레이는 본문 헤더에만 (
clamp(36px,4.4vw,56px) / weight 800 / letter-spacing -0.04em)
- 다크 surface (
#0b0d10) — gallery는 dark mode가 정석 (검토 환경 자체가 광원이 되도록)
- accent: gradient
linear-gradient(135deg, #7c5cfc 0%, #fa2e5f 50%, #04c584 100%) — Stripe-like
- card:
bg #13161b, border #252b35, hover border #7c5cfc + translateY -2px
- 반응형: ≥1100px 2-col grid, <1100px 1-col
3. iframe scaling
.frame-wrap { aspect-ratio: 16/10; background: #fff; overflow: hidden; position: relative; }
.frame-wrap iframe {
position: absolute; top: 0; left: 0;
width: 200%; height: 200%;
transform: scale(.5); transform-origin: top left;
border: 0;
}
.open-link {
position: absolute; top: 12px; right: 12px;
background: rgba(11,13,16,.7); color: #fff;
padding: 6px 12px; border-radius: 999px;
font-size: 11px; backdrop-filter: blur(8px);
}
200% × scale(.5)는 모바일 viewport에서도 데스크탑 layout 그대로 렌더하기 위함 (iframe 본인은 1280-1920px 가정).
4. 정적 vs 서버 모드
실행 절차
입력 검증: 디렉토리 list parsed, 각 디렉토리에 landing.html 존재 확인. 없으면 그 brand는 skip + 사용자에게 알림.
meta 수집: 각 brand 디렉토리에서:
experiment-meta.json 있으면 그대로 사용
- 없으면
DESIGN.md frontmatter에서 brand 추출, landing.html에서 <title> 추출 → minimal card
structure.json이 있으면 hero.type / cta.dominant_shape 정도를 tag로 추가
.live-inspect-proof.json 존재 → "live ✓" tag, raw_samples 수 표시
brand mark 생성: brand_color_hex가 있으면 색칩 div에 첫 글자. 없으면 회색 fallback.
gallery HTML 작성: 위 CSS + 카드 구조로 출력. <output-dir>/index.html에 write.
사용자 요약:
✓ Gallery 생성: <output-dir>/index.html
- 카드 N개 · wow 평균 X.X · live-inspect 통과 Y/N
- 서버 띄우는 법: cd <output-dir> && python3 -m http.server 8770
- 열기: http://localhost:8770/index.html
멀티턴 self-feedback 옵션 (v1.3.6 신설)
browser-harness 또는 mcp__playwright__* 가용 시, gallery 생성 후 gallery 자체에 self-critique 라운드:
- gallery index.html을 browser-harness로 열어 screenshot
- 각 brand 카드의 iframe rendering이 정상인지 (빈 화면 / 깨진 layout / 누락 자산) 시각 grading
- 발견된 문제 brand에 대해 issue.md 작성 (
<output-dir>/issues.md):# Gallery issues — auto-detected via browser-harness
- toss: hero section reveals empty (IntersectionObserver fired but skill rule 10 safety net missing) — re-run with v1.3.6
- karrot: product card photo 3 fails to load (Loremflickr 503) — fallback to Picsum needed
- 사용자에게 issues.md 안내 + 자동 fix 진행 여부 묻기
안티패턴 (절대 금지)
- ❌ Brand 디렉토리 안의 자산을 gallery에 직접 복사 (iframe으로만 reference)
- ❌ Brand creative work 재구성 (각 brand의 own landing.html이 self-contained — gallery는 그 wrapper일 뿐)
- ❌ wow rating 임의 부여 (sub-agent의 honest assessment가 출처)
한 줄 요약
N개 brand experiment → 1개 index.html. iframe scaled, wow rating, round-2 deltas, system-fix summary. 재사용 무한.
1---2name: omd-experiment-gallery-23description: N개 brand experiment를 한 화면에서 비교하는 gallery index.html을 생성. 각 카드는 brand name, wow rating, multi-turn refinement deltas, iframe scaled preview, standalone link 포함. '결과물 한 번에 보여줘', '갤러리 만들어', '5개 비교 뷰', 'experiment 결과 정리' 류 트리거. omd:harness가 N개 brand batch 작업 끝낸 직후 자동 호출되거나 사용자가 명시적으로 호출.4---5<!-- omd:installed-skill — managed by `omd install-skills`. Do not edit; rerun the command to refresh. -->678# omd:experiment-gallery — N-brand comparison index910## 왜 이 스킬1112여러 brand experiment를 돌리고 나면 결과물 검수가 산만 — 각 폴더 따로 열고 비교하기 번거로움. 이 skill은 **단일 `index.html`** 에 N개 결과를 iframe으로 박아서 한 화면에서 wow ratings + deltas + 실제 렌더를 동시 확인.1314## 트리거1516- 명시: "결과물 한 번에 보여줘", "갤러리 만들어", "N개 비교 뷰"17- 묵시: 사용자가 omd:harness로 ≥2개 brand experiment를 한 batch에서 끝낸 직후 ("이제 비교해보자" 라는 흐름)18- 다른 skill 안에서 호출: omd:batch-launch가 5개 brand 끝낸 후 Phase 5로 호출1920## 입력2122다음 둘 중 하나:23241. **명시 디렉토리 list**: 사용자가 `/tmp/omd-gallery/{brand1,brand2,brand3}` 같은 list 제공252. **부모 디렉토리 + glob**: `/tmp/omd-gallery/*` 또는 `web/experiments/2026-05/*` 등 — skill이 자동 enumerate2627각 brand 디렉토리는 다음 파일들 있어야 함 (있으면 사용, 없으면 fallback):28- `landing.html` (필수) — iframe src29- `DESIGN.md` (선택) — brand display name 추출30- `assets/_reference/<id>/structure.json` (선택) — composition 메타31- `assets/_reference/<id>/.live-inspect-proof.json` (선택) — live tag 표시32- `screenshots/after.png` (선택) — fallback preview33- `experiment-meta.json` (선택, 권장) — wow rating + round-2 deltas + 카테고리 — sub-agent가 작성3435## experiment-meta.json 스키마 (sub-agent가 작성)3637각 experiment sub-agent는 work 종료 직전 다음 파일을 작성:3839```json40{41 "brand_id": "toss",42 "brand_korean": "토스",43 "brand_category": "Fintech",44 "brand_color_hex": "#3182f6",45 "wow_rating": 7.5,46 "lines": 603,47 "live_inspect": { "ran": true, "raw_samples": 7, "method": "playwright|harness" },48 "round2_deltas": [49 "Reveal failsafe — 2s forwards animation",50 "Stat-card narrative upgrade",51 "CTA copy 구체화 (시간 약속)",52 "Hero shimmer (accent text gradient)",53 "Dark marquee band rhythm break",54 "Chart stroke-dashoffset draw-in"55 ],56 "ip_compliance": {57 "your_logo_placeholders": 2,58 "your_product_name_placeholders": 4,59 "brand_logo_embed_count": 0,60 "verbatim_brand_copy": 061 },62 "honest_gaps": [63 "Hero composition은 single character + flat card (3D ornament 부재)",64 "Carousel은 dot만 회전 (slide content 미스왑)"65 ]66}67```6869skill이 이 파일을 읽어 gallery 카드의 wow / lines / deltas 영역 채움. 없으면 brand_id만으로 minimal 카드.7071## 출력7273### 1. `<output-dir>/index.html` (메인 산출물)7475다음 구조:7677- 헤더: title (사용자가 batch 명령에서 받은 raw — "한국 brand 5선" 등), kicker (date · brand 수), meta (version · skill chain · mode)78- main grid: brand 1개당 card 1개79 - card head: brand mark (CSS-generated initial chip 또는 DiceBear shapes if brand has known color) + 한글명 + id + wow rating80 - frame-wrap: aspect-ratio 16:10 iframe (scale 50%로 200%×200% iframe rendering — 모바일은 100%)81 - card foot: voice note 1줄 + tags chips + round-2 deltas ol82- footer summary: 모든 brand wow/lines/proof/round-2 핵심 1줄 테이블83- system-note: 적용된 skill 버전의 시스템 fix들 한 단락8485### 2. CSS 스타일 가이드8687- typography: Pretendard from jsdelivr (SIL OFL). 디스플레이는 본문 헤더에만 (`clamp(36px,4.4vw,56px) / weight 800 / letter-spacing -0.04em`)88- 다크 surface (`#0b0d10`) — gallery는 dark mode가 정석 (검토 환경 자체가 광원이 되도록)89- accent: gradient `linear-gradient(135deg, #7c5cfc 0%, #fa2e5f 50%, #04c584 100%)` — Stripe-like90- card: `bg #13161b`, border `#252b35`, hover `border #7c5cfc` + `translateY -2px`91- 반응형: ≥1100px 2-col grid, <1100px 1-col9293### 3. iframe scaling9495```css96.frame-wrap { aspect-ratio: 16/10; background: #fff; overflow: hidden; position: relative; }97.frame-wrap iframe {98 position: absolute; top: 0; left: 0;99 width: 200%; height: 200%;100 transform: scale(.5); transform-origin: top left;101 border: 0;102}103.open-link {104 position: absolute; top: 12px; right: 12px;105 background: rgba(11,13,16,.7); color: #fff;106 padding: 6px 12px; border-radius: 999px;107 font-size: 11px; backdrop-filter: blur(8px);108}109```110111200% × scale(.5)는 모바일 viewport에서도 데스크탑 layout 그대로 렌더하기 위함 (iframe 본인은 1280-1920px 가정).112113### 4. 정적 vs 서버 모드114115- iframe src는 **상대 경로** (`./toss/landing.html`) — 정적 file:// open 안 됨 (CORS), `python3 -m http.server <port>` 추천116- skill 끝에 사용자에게 "서버 띄우는 명령" 출력:117 ```118 cd <output-dir> && python3 -m http.server 8770119 open http://localhost:8770/index.html120 ```121122## 실행 절차1231241. **입력 검증**: 디렉토리 list parsed, 각 디렉토리에 `landing.html` 존재 확인. 없으면 그 brand는 skip + 사용자에게 알림.1251262. **meta 수집**: 각 brand 디렉토리에서:127 - `experiment-meta.json` 있으면 그대로 사용128 - 없으면 `DESIGN.md` frontmatter에서 `brand` 추출, `landing.html`에서 `<title>` 추출 → minimal card129 - `structure.json`이 있으면 hero.type / cta.dominant_shape 정도를 tag로 추가130 - `.live-inspect-proof.json` 존재 → "live ✓" tag, raw_samples 수 표시1311323. **brand mark 생성**: brand_color_hex가 있으면 색칩 div에 첫 글자. 없으면 회색 fallback.1331344. **gallery HTML 작성**: 위 CSS + 카드 구조로 출력. `<output-dir>/index.html`에 write.1351365. **사용자 요약**:137 ```138 ✓ Gallery 생성: <output-dir>/index.html139 - 카드 N개 · wow 평균 X.X · live-inspect 통과 Y/N140 - 서버 띄우는 법: cd <output-dir> && python3 -m http.server 8770141 - 열기: http://localhost:8770/index.html142 ```143144## 멀티턴 self-feedback 옵션 (v1.3.6 신설)145146`browser-harness` 또는 `mcp__playwright__*` 가용 시, gallery 생성 후 **gallery 자체에 self-critique 라운드**:1471481. gallery index.html을 browser-harness로 열어 screenshot1492. 각 brand 카드의 iframe rendering이 정상인지 (빈 화면 / 깨진 layout / 누락 자산) 시각 grading1503. 발견된 문제 brand에 대해 **issue.md** 작성 (`<output-dir>/issues.md`):151 ```markdown152 # Gallery issues — auto-detected via browser-harness153 - toss: hero section reveals empty (IntersectionObserver fired but skill rule 10 safety net missing) — re-run with v1.3.6154 - karrot: product card photo 3 fails to load (Loremflickr 503) — fallback to Picsum needed155 ```1564. 사용자에게 issues.md 안내 + 자동 fix 진행 여부 묻기157158## 안티패턴 (절대 금지)159160- ❌ Brand 디렉토리 안의 자산을 gallery에 직접 복사 (iframe으로만 reference)161- ❌ Brand creative work 재구성 (각 brand의 own landing.html이 self-contained — gallery는 그 wrapper일 뿐)162- ❌ wow rating 임의 부여 (sub-agent의 honest assessment가 출처)163164## 한 줄 요약165166**N개 brand experiment → 1개 index.html. iframe scaled, wow rating, round-2 deltas, system-fix summary. 재사용 무한.**