$npx -y skills add kwakseongjae/oh-my-design --skill omd-asset-fetch사용자 product UI 생성 시 placeholder 자리를 generic SVG가 아닌 실제 free-license CDN 자산으로 채운다. 로고·일러스트·아이콘·사진·폰트·패턴 카탈로그를 verified URL만으로 운영. '에셋 가져와줘', '플레이스홀더 진짜 이미지로', '로고 자리 채워줘', 'unsplash에서 사진 가져와' 류 요청에 트리거. omd:apply / omd:harness 안에서 자동 호출됨.
| 1 | <!-- omd:installed-skill — managed by `omd install-skills`. Do not edit; rerun the command to refresh. --> |
| 2 | |
| 3 | |
| 4 | # omd:asset-fetch — Free-license Asset Catalog |
| 5 | |
| 6 | ## 왜 이 스킬 |
| 7 | |
| 8 | "초안 같음" 결과물의 90%는 **placeholder가 너무 generic**이라서 — `[YOUR LOGO]` 점선 박스, organic blob SVG, "image placeholder" 회색 사각형. 사용자가 "와우" 못 느낌. |
| 9 | |
| 10 | 이 스킬은 **모든 placeholder 자리에 verified free-license CDN 자산**을 박는 catalog. URL은 전부 200 OK 검증됨 (2026-05-14 기준). |
| 11 | |
| 12 | ## 핵심 원칙 |
| 13 | |
| 14 | 1. **검증된 URL만**. 이 catalog에 없으면 generator가 임의로 만들지 말 것. |
| 15 | 2. **모든 자산은 commercial-use 허용** — 사용자 product에 ship 가능. |
| 16 | 3. **출처는 `assets/attribution.md`에 의무 기록** — URL + license + 사용 위치 + fetch 일자. |
| 17 | 4. **deterministic seeding 권장** — `seed` 또는 `lock` 파라미터로 결과 재현 가능. 매번 다른 이미지 나오는 random URL은 피할 것. |
| 18 | 5. **금지**: handcraft inline SVG로 placeholder를 "그려서" 채우기. catalog 자산 fetch 실패 시 → brand-color CSS gradient placeholder (이전 v1.3.4 fallback 정책과 동일). |
| 19 | |
| 20 | ## Catalog (verified 2026-05-14) |
| 21 | |
| 22 | ### 1. LOGO — product name **워드마크만** (v1.3.7부터) |
| 23 | |
| 24 | 별도 icon / shapes mark / DiceBear logo 합성 **금지**. 헤더 logo = product name 텍스트 + 디스플레이 폰트, 그게 전부. |
| 25 | |
| 26 | **왜**: AI가 합성한 icon mark는 "generic"하게 보임 (사용자 frustration source). product 이름을 **꽤 괜찮은 폰트로** 그대로 박는 게 진짜 brand wordmark처럼 보이고 사용자가 1초만에 자기 product name으로 swap 가능. |
| 27 | |
| 28 | **패턴**: |
| 29 | ```html |
| 30 | <a class="logo" href="/" style="display:inline-flex;align-items:center;text-decoration:none;"> |
| 31 | <span class="logo-wordmark">{{PRODUCT_NAME}}</span> |
| 32 | </a> |
| 33 | <style> |
| 34 | .logo-wordmark{ |
| 35 | font-family:"Bricolage Grotesque","Space Grotesk","DM Serif Display","Fraunces",-apple-system,sans-serif; |
| 36 | font-size:22px;font-weight:700;letter-spacing:-0.04em; |
| 37 | color:var(--color-text-heading); |
| 38 | } |
| 39 | </style> |
| 40 | ``` |
| 41 | |
| 42 | `<head>`에 디스플레이 폰트 `<link>` 의무 (§6 참고). |
| 43 | |
| 44 | **brand vibe별 폰트 매칭**: |
| 45 | - cool / minimal / fintech serious → **Space Grotesk** 700 (geometric) |
| 46 | - warm / playful / community → **Bricolage Grotesque** 700 (friendly variable) |
| 47 | - editorial / luxury → **DM Serif Display** 또는 **Fraunces** (display serif) |
| 48 | - bold / display → **Bricolage Grotesque** 800 |
| 49 | |
| 50 | **`{{PRODUCT_NAME}}` 결정**: |
| 51 | 1. 사용자 prompt에 명시 product name 있으면 그대로 사용 |
| 52 | 2. 없으면 brand vibe 맞는 generic placeholder 1개 선택 (omd-harness rule 5 §placeholder 표 참고: `Folio`, `Mint`, `Pop`, `Spark`, `Townie`, `Lane`, `Compass`, ...) |
| 53 | 3. 선택된 이름은 `<title>`, hero copy, footer brand 자리 전부 **일관 적용** (사용자 grep replace 1번이면 swap 끝) |
| 54 | |
| 55 | **금지 패턴 (v1.3.6 회귀 방지)**: |
| 56 | - ❌ DiceBear `shapes` mark + wordmark 페어 — generic "AI 로고" 느낌 |
| 57 | - ❌ DiceBear `initials` 이니셜 chip — 이메일 아바타 같이 보임 |
| 58 | - ❌ 직접 그린 inline `<svg>` logo icon — 손그림 anatomy 회귀 |
| 59 | - ❌ `[YOUR LOGO]` / `[YOUR PRODUCT NAME]` 텍스트가 점선 박스 안에 그대로 — placeholder 티 폭발 |
| 60 | |
| 61 | ### 2. HERO 일러스트레이션 / 캐릭터 |
| 62 | |
| 63 | **DiceBear avatars** (CC0) — v1.3.4부터 이미 사용 중. 5 스타일: |
| 64 | |
| 65 | | style | use case | URL pattern | |
| 66 | |---|---|---| |
| 67 | | `notionists` | financial advisor, business persona | `https://api.dicebear.com/9.x/notionists/svg?seed=<seed>&size=520` | |
| 68 | | `lorelei` | warm, approachable | `https://api.dicebear.com/9.x/lorelei/svg?seed=<seed>&size=520` | |
| 69 | | `personas` | diverse persona | `https://api.dicebear.com/9.x/personas/svg?seed=<seed>&size=520` | |
| 70 | | `adventurer` | active, mobility | `https://api.dicebear.com/9.x/adventurer/svg?seed=<seed>&size=520` | |
| 71 | | `fun-emoji` | warm, casual commerce | `https://api.dicebear.com/9.x/fun-emoji/svg?seed=<seed>&size=520` | |
| 72 | |
| 73 | 생성기는 brand의 voice register 또는 surface signal에 맞춰 style 선택 — 예: 핀테크 advisor → `notionists`, 커뮤니티 커머스 → `lorelei` 또는 `fun-emoji`. |
| 74 | |
| 75 | **금지** (v1.3.4부터 누적, 자주 어겨지므로 재명시): |
| 76 | - handcraft inline SVG 캐릭터 — 손그림 stick figure 합성 절대 금지 |
| 77 | - 캐릭터 일러스트를 우리 generator가 직접 inline `<path>`로 그리지 말 것 |
| 78 | - CDN fetch 후 다운로드한 파일 첫 부분에 `<!-- dicebear-fetched: <full URL> | <ISO> -->` 코멘트 박을 것 — 후속 audit gate가 검증 |
| 79 | |
| 80 | ### 3. ICONS — feature 카드, nav, product 카테고리 |
| 81 | |
| 82 | **Lucide** (ISC) — 한 줄 1500+ 아이콘 |
| 83 | - URL: `https://cdn.jsdelivr.net/npm/lucide-static@latest/icons/<name>.svg` |
| 84 | - 예시: `credit-card`, `home`, `landmark`, `shield-check`, `trending-up`, `book-open`, `map-pin`, `bell`, `heart`, `search`, `user`, `chevron-right`, `arrow-right`, `external-link`, `play`, `bar-chart-3` |
| 85 | |
| 86 | **Heroicons** (MIT) |
| 87 | - URL: `https://cdn.jsdelivr.net/npm/heroicons@2/24/outline/<name>.svg` |
| 88 | - outline + solid family |
| 89 | |
| 90 | **Tabler Icons** (MIT) |
| 91 | - URL: `https://cdn.jsdelivr.net/npm/@tabler/icons@latest/icons/<name>.svg` |
| 92 | |
| 93 | 색상 적용: SVG inline 후 `currentColor` / `stroke="..."` 변경, 또는 CSS filter |
| 94 | |
| 95 | ### 4. PHOTOS — product 카드, hero 배경, testimonial 아바타 |
| 96 | |
| 97 | **Lorem Picsum** (CC0 — Unsplash-derived rehosting) |
| 98 | - random photo: `https://picsum.photos/<w>/<h>` (매 호출 다름) |
| 99 | - **deterministic** (권장): `https://picsum.photos/seed/<seed>/<w>/<h>` |
| 100 | - seed는 `<brand>-product-01`, `<brand>-hero-01` 식으로 의미 부여 |
| 101 | - grayscale: `?grayscale` |
| 102 | - blur: `?blur=2` |
| 103 | - 예: `https://picsum.photos/seed/musinsa-card-1/400/500` → musinsa product 카드 자리에 들어갈 결정적 이미지 |
| 104 | |
| 105 | **Loremflickr** (Flickr CC) — 키워드 매칭 + |