# insane-design 스킬 심층 분석 + 시스템 통합 설계

> 분석일: 2026-04-12 | 분석자: 비슈누(dev4팀장) | task: task-1722.1
> 레포: https://github.com/fivetaku/insane-design | 라이선스: MIT

---

## 1. 레포 전체 구조 분석

### 1.1 디렉토리 구조

```
insane-design/
├── .claude-plugin/
│   └── plugin.json           # Claude Code Plugin 메타데이터 (v0.1.0)
├── commands/
│   └── insane-design.md      # /insane-design [URL] 슬래시 커맨드 정의
├── skills/insane-design/
│   ├── SKILL.md              # 7-Step 실행 지시서 (310줄)
│   ├── references/           # 7개 레퍼런스 문서
│   │   ├── architecture.md   # SSoT — 6-Phase 파이프라인 설계
│   │   ├── data-collection.md # 5-tier fallback HTML/CSS 수집 전략
│   │   ├── methodology.md    # 수작업 분석 방법론 (Stripe 케이스)
│   │   ├── workflow.md       # 서비스당 절차 (최신, 34개 서비스 검증)
│   │   ├── template.md       # design.md 16섹션 v2.0 템플릿
│   │   ├── report-prompt.md  # HTML 리포트 생성 규칙 v2.1
│   │   └── pitfalls.md       # 35개 서비스 분석 14가지 함정
│   ├── scripts/              # Python 추출 스크립트 (총 846줄)
│   │   ├── brand_candidates.py    # 222줄 — 브랜드 색상 후보 추출
│   │   ├── var_resolver.py        # 193줄 — CSS var() 체인 재귀 해결
│   │   ├── typo_extractor.py      # 175줄 — 타이포그래피 스케일 추출
│   │   ├── alias_layer.py         # 99줄 — 시맨틱 alias tier 분류
│   │   └── capture_jina_screenshots.py # 157줄 — Jina API 스크린샷
│   └── examples/             # 25+ 서비스 완성 산출물
│       ├── stripe/           # 골드 스탠다드 (design.md 25KB + report 88KB)
│       ├── linear/           # dark 테마 예시
│       ├── toss/             # 한국 서비스 예시
│       ├── vercel/           # 개발 도구 예시
│       └── ... (총 25+ 서비스)
├── README.md                 # 레포 설명 (177줄)
└── .gitignore
```

### 1.2 plugin.json

```json
{
  "name": "insane-design",
  "version": "0.1.0",
  "description": "URL one-shot design system extractor",
  "author": { "name": "fivetaku" },
  "license": "MIT"
}
```

### 1.3 commands/insane-design.md

- `/insane-design [URL]` 슬래시 커맨드 정의
- 허용 도구: Bash, Read, Write, Glob, Grep, AskUserQuestion
- URL 미제공 시 AskUserQuestion으로 사용자에게 질문
- 실행 시 SKILL.md를 Read하여 7-Step 파이프라인 수행

### 1.4 설정 파일

- `.gitignore`: `insane-design/` 출력 디렉토리 제외
- 환경 변수: `CLAUDE_PLUGIN_ROOT` (Claude Code Plugin 시스템 제공)
- 별도 config 파일 없음 — 모든 설정이 SKILL.md 내 하드코딩

---

## 2. 코드 단위 분석

### 2.1 brand_candidates.py (222줄) — 브랜드 색상 후보 추출기

**핵심 로직**: CSS에서 브랜드 색상 후보를 3가지 전략으로 추출

| 전략 | 함수 | 방식 |
|------|------|------|
| Semantic | `extract_semantic_brand_vars()` | CSS 변수명에 brand/primary/accent/action/cta 키워드 탐색 |
| Selector-role | `extract_selector_role_hex()` | button/btn/cta/nav 셀렉터의 color/background 값 추출 |
| Frequency | `extract_frequency_candidates()` | CSS+HTML 전체 hex 빈도 상위 30개, 종류 분류 (chromatic/neutral/svg_pattern/logo_wall) |

**주요 함수 12개**: `_normalize_hex`, `_pick_role`, `_count_hexes`, `_hex_saturation`, `_extract_svg_counts`, `_extract_logo_wall_counts`, `_empty_result`, `_build_summary`, `extract_semantic_brand_vars`, `extract_selector_role_hex`, `extract_frequency_candidates`, `extract_all`

**입출력**:
- 입력: `insane-design/{slug}/css/*.css` + `index.html`
- 출력: `insane-design/{slug}/phase1/brand_candidates.json`

**특이 사항**: logo wall hex 필터링 — `section/div/aside`에서 `logo|customer|trusted` 클래스를 가진 블록 내 hex를 별도 집계하여 브랜드 색상 오염 방지 (pitfall #12 대응)

### 2.2 var_resolver.py (193줄) — CSS var() 체인 재귀 해결기

**핵심 로직**: CSS 커스텀 프로퍼티의 `var()` 참조 체인을 재귀적으로 해결

```
--color-brand-500: var(--color-primary)
--color-primary: var(--core-brand-600)
--core-brand-600: #533AFD
→ chain: [--color-brand-500, --color-primary, --core-brand-600, #533AFD]
→ resolved: #533AFD
```

**주요 함수 11개**: `parse_all_custom_properties`, `_normalize_name`, `_unwrap_var_call`, `_split_var_arguments`, `_is_terminal_value`, `_prepend_chain`, `_resolve_value`, `_resolve_var_with_chain`, `resolve_var`, `resolve_all`, `resolve_slug`

**순환 참조 감지**: `seen: set[str]`로 방문 변수 추적, 순환 시 None 반환
**중첩 var() 처리**: depth 카운터로 `var(var(...))` 안전 언래핑

**입출력**:
- 입력: `insane-design/{slug}/css/*.css`
- 출력: `insane-design/{slug}/phase1/resolved_tokens.json` (최대 50개 samples)

### 2.3 typo_extractor.py (175줄) — 타이포그래피 스케일 추출기

**핵심 로직**: CSS 커스텀 프로퍼티에서 타이포그래피 관련 토큰을 구조화된 스케일로 그룹핑

**정규식 패턴**: `--(.*)font-(heading|text|display|title|label|caption|input|quote|body)-?([a-z0-9]*)-(size|weight|lineHeight|line-height|letterSpacing|letter-spacing)$`

**추출 항목**: size, weight, lineHeight, letterSpacing를 category-variant 키로 그룹핑

**주요 함수 5개**: `group_typography_tokens`, `extract_font_families`, `extract_font_weights_used`, `extract_slug`, `main`

**입출력**:
- 입력: `insane-design/{slug}/css/*.css`
- 출력: `insane-design/{slug}/phase1/typography.json`

### 2.4 alias_layer.py (99줄) — 시맨틱 Alias 계층 분류기

**핵심 로직**: CSS 커스텀 프로퍼티를 5개 tier로 분류

| Tier | 키워드 |
|------|--------|
| util | `-util-` |
| semantic | `-semantic-` |
| action | `-action-`, `-btn-`, `-button-` |
| component | `-input-`, `-card-`, `-nav-`, `-dialog-`, `-popover-` |
| core | `-core-`, hex 리터럴, rgb/rgba/hsl/hsla |

**주의**: Mutually exclusive 아님 — 하나의 alias가 여러 tier에 동시 포함 가능

**입출력**:
- 입력: `insane-design/{slug}/css/*.css`
- 출력: `insane-design/{slug}/phase1/alias_layer.json`

### 2.5 capture_jina_screenshots.py (157줄) — 스크린샷 캡처기

**핵심 로직**: Jina Reader API를 사용하여 웹사이트 스크린샷을 캡처

- `curl -sL -H "X-Respond-With: screenshot" https://r.jina.ai/{url}` 실행
- 35개 서비스 URL 하드코딩 (`SLUG_URL_MAP`)
- ThreadPoolExecutor(max_workers=5)로 병렬 캡처
- PIL로 1280×1280 → 1280×800 crop

**외부 의존성**: Pillow (선택적 — 없으면 crop 생략), curl (시스템)

### 2.6 의존성 종합

| 패키지 | 종류 | 사용 스크립트 |
|--------|------|-------------|
| json, re, sys, pathlib | 표준 라이브러리 | 전체 |
| collections.Counter | 표준 라이브러리 | brand_candidates, typo_extractor |
| subprocess | 표준 라이브러리 | capture_jina |
| concurrent.futures | 표준 라이브러리 | capture_jina |
| Pillow (PIL) | **외부** (선택) | capture_jina |
| curl | **시스템 CLI** | capture_jina, SKILL.md Step 2 |

**핵심**: 분석 스크립트 4개는 순수 표준 라이브러리만 사용. 외부 의존성은 Pillow뿐이고 선택적.

### 2.7 코드 품질 이슈 (우선순위 순)

| 우선순위 | 이슈 | 스크립트 | 영향 |
|---------|------|---------|------|
| 높음 | `parse_all_custom_properties` 3중 구현 — probe 유무/comment 제거/중복키 처리 불일치 | var_resolver, typo_extractor, alias_layer | 동일 CSS에서 다른 결과 가능 |
| 높음 | `alias_layer.py` errors= 미지정 — UnicodeDecodeError crash 가능 | alias_layer | 비-UTF8 CSS 파일 crash |
| 중간 | 지정 slug가 SLUG_URL_MAP에 없으면 KeyError | capture_jina | CLI 입력 검증 부재 |
| 중간 | CSS nested {} (at-rule) 파싱 오류 가능 | brand_candidates | 정확성 |
| 낮음 | 미사용 import (json, time) | capture_jina | 가독성 |
| 낮음 | main() SystemExit 패턴 불일치 | typo_extractor | 일관성 |

---

## 3. 워크플로우 분석

### 3.1 7-Step 파이프라인

```
사용자: /insane-design https://stripe.com
        ↓
Step 1: INIT (script)
  URL 파싱 → slug 추출 → 디렉토리 생성
        ↓
Step 2: FETCH (script, 병렬)
  ┌─ 2A: HTML 수집 (5-tier fallback: curl Chrome UA → Mobile UA → Jina HTML → curl_cffi → Playwright)
  │     + CSS 링크 추출 + 병렬 다운로드
  └─ 2B: 스크린샷 (Jina Reader API → PIL crop 1280×800)
        ↓
Step 3: EXTRACT (script, 순차)
  brand_candidates.py → brand_candidates.json
  var_resolver.py     → resolved_tokens.json
  typo_extractor.py   → typography.json
  alias_layer.py      → alias_layer.json
        ↓
Step 4: INTERPRET (AI 멀티모달 판정)
  스크린샷 + 4개 JSON + pitfalls.md 읽기
  → 7가지 판정: Brand color / Light-Dark / Custom font / Framework / Hero anatomy / Quick Start 금지 / DO/DON'T
        ↓
Step 5: WRITE-MD (AI 생성)
  template.md + stripe/design.md 참조
  → insane-design/{slug}/design.md (16섹션, ≥8KB)
        ↓
Step 6: RENDER-HTML (AI 생성)
  report-prompt.md + stripe/report.ko.html 참조
  → insane-design/{slug}/report.ko.html (한국어, ≥20KB)
        ↓
Step 7: VALIDATE (script + review)
  YAML frontmatter 검증 + 필수 섹션 11개 존재 + 파일 크기 + hex 실존 확인
  실패 시 최대 2회 재생성
```

### 3.2 입력/출력

**입력**: URL 하나 (HTTP/HTTPS만 허용, localhost/file:// 차단)

**출력**:
```
insane-design/{slug}/
├── design.md              # AI 에이전트용 디자인 시스템 (≥8KB, 16섹션)
├── report.ko.html         # 인터랙티브 HTML 리포트 (≥20KB, 한국어)
├── screenshots/
│   ├── jina-hero.png      # 원본 스크린샷 (1280×1280)
│   └── hero-cropped.png   # crop 결과 (1280×800)
├── index.html             # 수집된 HTML
├── css/*.css              # 수집된 CSS 파일들
└── phase1/                # 추출 결과 JSON
    ├── brand_candidates.json
    ├── resolved_tokens.json
    ├── typography.json
    └── alias_layer.json
```

### 3.3 에러 핸들링

| 상황 | 처리 |
|------|------|
| HTML 5-tier 전부 실패 | 사용자에게 "접근 불가" 메시지 + 중단 |
| CSS 0개 | 인라인 `<style>` 블록 추출 시도 |
| CSS custom properties 0개 | hex frequency 기반 분석으로 전환 + 경고 |
| 스크린샷 실패 | 경고 후 계속 진행 (design.md 생성 가능) |
| design.md 검증 실패 | 최대 2회 재생성 |

### 3.4 3대 원칙 (절대 위반 금지)

1. **AI는 hex 값을 만들지 않는다** — CSS에 없는 hex 생성 = 환각
2. **AI는 토큰명을 만들지 않는다** — `color-brand` 같은 가상 이름 금지
3. **AI는 팩트 위에 해석만 얹는다** — 값 변경 NO, 분류/설명 OK

---

## 4. 우리 시스템과 비교

### 4.1 기능 대조 매트릭스

| 기능 | frontend-design | canvas-design | satori-cardnews | brainstorming | insane-design |
|------|:---:|:---:|:---:|:---:|:---:|
| 코드 기반 UI 생성 | **핵심** | - | - | - (설계만) | - (분석만) |
| 정적 이미지 생성 | - | **핵심** | **핵심** | - | - |
| 실제 CSS 추출/분석 | - | - | - | - | **핵심** |
| URL 디자인 벤치마킹 | - | - | - | - | **핵심** |
| 디자인 시스템 생성 | 자체 DB 기반 | - | - | - | CSS 파싱 기반 |
| UX 사전 설계 | - | - | - | **핵심** | - |
| 접근성 가이드 | 99개 규칙 | - | - | 부분적 | - |
| 한국어 특화 | Supanova | 부분적 | Supanova | 보험/금융 | - |
| 대량 이미지 생산 | - | - | 0.32초/장 | - | - |
| Tailwind Config 생성 | 부분적 | - | - | - | **자동** |
| Drop-in CSS 생성 | - | - | - | - | **자동** |
| 멀티모달 분석 | - | - | - | - | 스크린샷+JSON |

### 4.2 insane-design에 있고 우리에게 없는 것

1. **URL → 실제 CSS 파싱 파이프라인**: 우리는 "Stripe처럼 해줘"에 내부 DB 추천으로 대응. insane-design은 실제 stripe.com CSS를 다운로드하여 hex 직접 추출
2. **var() 체인 재귀 해결**: CSS 변수의 참조 체인을 terminal hex까지 추적
3. **16섹션 design.md**: AI 에이전트에 바로 첨부 가능한 구조화 디자인 레퍼런스
4. **인터랙티브 HTML 리포트**: 컬러 스와치 hover, 타이포 live preview, Copy 버튼 등
5. **35개 서비스 골드 스탠다드**: Stripe/Linear/Vercel/Toss 등 분석 결과
6. **14가지 함정 방지**: 가상 토큰명, logo wall 오염, Light/Dark 역전 등

### 4.3 우리가 insane-design보다 나은 것

1. **완성 UI 코드 생성**: insane-design은 design.md까지만. frontend-design은 동작하는 코드 생성
2. **99개 UX 가이드라인**: 접근성, 터치, 퍼포먼스, 폼/피드백, 네비게이션
3. **한국어 Supanova 패턴**: Pretendard 필수, word-break:keep-all, AI 클리셰 금지
4. **보험/금융 도메인 특화**: 규제 준수, 점진적 노출, 신뢰 우선 설계
5. **UX 하드 게이트**: brainstorming 스킬의 승인 없이 코드 생성 방지
6. **대량 이미지 생산**: satori-cardnews 0.32초/장
7. **디자인 철학/무드**: 50+ 스타일, 161개 팔레트, 57개 폰트 페어링 DB

### 4.4 중복 영역

| 기능 | 우리 방식 | insane-design 방식 |
|------|----------|-------------------|
| 디자인 시스템 생성 | 내부 DB BM25 검색 → 스타일 추천 | 실제 URL CSS 파싱 → 토큰 추출 |
| 타이포그래피 가이드 | 57개 폰트 페어링 DB | 실제 사이트 폰트 스케일 추출 |
| 색상 팔레트 | 161개 팔레트 DB 검색 | 실제 CSS hex 빈도 분석 |

**결론**: 기능적 충돌 없음. 접근 방식이 근본적으로 다름 (DB 기반 vs CSS 파싱 기반).

---

## 5. 시스템 통합 설계

### 5.1 제이회장님 사용 시나리오

> "URL을 주면서 디자인 벤치마킹 해서 프론트엔드 구현해달라"

### 5.2 통합 워크플로우 설계

```
[사용자: "이 사이트처럼 만들어줘" + URL]
         ↓
  ① insane-design (URL → design.md + report.ko.html)
    - CSS 파싱 기반 실제 토큰 추출
    - AI 판정: 브랜드 컬러, 테마, 폰트 등
    - 산출물: design.md (AI 첨부용), report.ko.html (리뷰용)
         ↓
  ② brainstorming (선택) — UX 방향 확정
    - design.md를 참고 자료로 첨부
    - 하드 게이트: 방향 승인 없이 코드 생성 금지
         ↓
  ③ frontend-design (design.md 첨부 → 코드 생성)
    - design.md의 Drop-in CSS / Tailwind Config를 직접 사용
    - 실제 hex, font-family, spacing, radius 값 적용
    - Supanova 한국어 규칙 + 99개 UX 가이드라인 동시 적용
         ↓
  [산출물: 동작하는 프론트엔드 코드]
```

### 5.3 트리거 설계

**명시적 트리거**:
- `/insane-design [URL]`
- "디자인 벤치마킹 해줘" + URL
- "이 사이트 디자인 분석해줘" + URL
- "이 사이트처럼 만들어줘" + URL

**description CSO 최적화 키워드**:
```
디자인 벤치마킹, URL 디자인 분석, 사이트 클론, 디자인 참고,
CSS 분석, 디자인 토큰 추출, 디자인 시스템 추출,
design benchmarking, CSS analysis, design tokens, site clone,
"이 사이트처럼", "이런 느낌으로"
```

### 5.4 SKILL.md 작성 방안

우리 스킬 포맷으로 변환 시 고려사항:

1. **frontmatter**: 기존 SKILL.md frontmatter 그대로 사용 가능 (name, description 형식 동일)
2. **scripts 경로**: `${CLAUDE_PLUGIN_ROOT}` → 우리 시스템의 스킬 경로로 변경
3. **레퍼런스 문서 7개**: 그대로 포함 — 분석 품질의 핵심
4. **examples**: Stripe 골드 스탠다드 최소 포함, 나머지는 선택
5. **14가지 pitfalls**: 그대로 포함 — AI 환각 방지의 핵심

### 5.5 기존 스킬 연동 방안

**frontend-design 연동**:
- insane-design 산출물 `design.md`를 frontend-design의 `--design-system` 입력으로 활용
- Drop-in CSS 섹션 → frontend-design의 CSS 변수 초기화
- Tailwind Config → frontend-design의 tailwind.config.js 자동 적용
- DO/DON'T 섹션 → frontend-design의 디자인 규칙으로 주입

**webapp-testing (Playwright) 연동**:
- insane-design의 Playwright fallback → 이미 설치된 Playwright MCP 활용
- Step 2B 스크린샷 품질 향상
- Step 7 VALIDATE 시 생성된 UI의 시각적 비교 검증 가능

**brainstorming 연동**:
- design.md를 브레인스토밍의 참고 자료로 첨부
- "이 사이트의 레이아웃 패턴(§11)을 참고하되, 우리 도메인에 맞게 변형" 식 활용

---

## 6. 도입 판정

### 6.1 판정: **전체 도입 권장**

**근거**:
1. **고유 역할**: URL → CSS 토큰 추출은 우리 시스템에 완전히 부재한 기능
2. **기능 충돌 없음**: frontend-design과 보완적 관계 (분석 → 코드 생성 파이프라인)
3. **낮은 의존성**: Python 3.11+ (이미 보유) + Pillow (pip install 1건) + curl (시스템 기본)
4. **MIT 라이선스**: 상업적 사용 제한 없음
5. **검증된 품질**: 35개 서비스 분석 결과 예시 보유
6. **한국어 지원**: report.ko.html 한국어 기본
7. **3대 원칙**: AI 환각 방지 체계가 견고 (hex 생성 금지, 토큰명 생성 금지)

### 6.2 도입 시 예상 공수

| 작업 | 예상 공수 | 난이도 |
|------|----------|-------|
| 스킬 파일 복사 + 경로 조정 | 0.5일 | 낮음 |
| 우리 스킬 포맷으로 SKILL.md 변환 | 0.5일 | 낮음 |
| frontend-design 연동 코드 작성 | 1일 | 중간 |
| description CSO 최적화 + 트리거 테스트 | 0.5일 | 낮음 |
| 3개 이상 URL 테스트 + 검증 | 0.5일 | 낮음 |
| **합계** | **3일** | — |

### 6.3 우선순위

**P2 (중요, 긴급하지 않음)**

사유:
- 현재 프로덕트 개발에 즉시 필요하지는 않으나
- "이 사이트처럼 만들어줘" 요청 시 정확도를 크게 개선
- frontend-design 스킬의 품질을 근본적으로 향상시키는 인프라 투자

### 6.4 도입 시 개선 권장사항

1. **코드 이슈 수정**: `parse_all_custom_properties` 3중 구현 → 공통 모듈로 통합
2. **alias_layer.py**: `errors="replace"` 추가 (UnicodeDecodeError 방지)
3. **capture_jina**: slug 유효성 검사 추가
4. **한국어 강화**: design.md 주석/설명을 한국어로 확장 (현재 토큰명/CSS값만 영어)
5. **Playwright 우선 전환**: 우리 시스템에 Playwright MCP가 이미 있으므로, Jina Reader 대신 Playwright를 1순위로 전환 검토

---

## 부록: design.md 16섹션 구조

| # | 섹션 | SOURCE | 필수 |
|---|------|--------|------|
| 01 | Quick Start (3가지 CSS + 금지 1개) | manual | 필수 |
| 02 | Provenance (수집 메타데이터) | auto | 필수 |
| 03 | Tech Stack (프레임워크, CSS 아키텍처) | auto+manual | 필수 |
| 04 | Font Stack (폰트 패밀리, 라이선스) | auto+manual | 필수 |
| 05 | Typography Scale (heading/text 스케일) | auto | 필수 |
| 06 | Colors (Brand/Neutral/Accent/Semantic) | auto | 필수 |
| 07 | Spacing (토큰 시스템) | auto | 필수 |
| 08 | Radius (border-radius 체계) | auto | 필수 |
| 09 | Shadows (box-shadow 레이어) | auto | 선택 |
| 10 | Motion (애니메이션 토큰) | auto+manual | 선택 |
| 11 | Layout Patterns (Hero, 브레이크포인트) | manual | 선택 |
| 12 | Components (BEM 클래스, 데모) | auto+manual | 필수 |
| 13 | Content/Copy Voice (톤, CTA 패턴) | manual | 선택 |
| 14 | Drop-in CSS (:root 블록) | auto+manual | 필수 |
| 15 | Tailwind Config (module.exports) | auto+manual | 선택 |
| 16 | DO/DON'T (각 4-10개) | manual | 필수 |

## 부록: 14가지 함정 요약

| # | 함정 | 대표 사례 |
|---|------|----------|
| 1 | 가상 토큰명 | `color-brand` → 실제 `--hds-color-core-brand-600` |
| 2 | 브랜드 키트 ≠ UI 색 | Figma/Slack 로고 5색은 일러스트 전용 |
| 3 | 리브랜딩 지체 | Atlassian #0052CC → #1868DB |
| 4 | Light/Dark 역전 | Warp 마케팅=light, 앱=dark |
| 5 | 앱 UI vs 마케팅 혼동 | Linear, Framer, GitHub |
| 6 | Hero 구체 수치 필수 | "spacious feel" 금지 |
| 7 | DS 네임스페이스 보존 | --hds-*, --ds-* 실제 prefix |
| 8 | Tailwind v4 @theme | --tw-*, --color-*-NNN |
| 9 | next/font metric fallback | "Inter Fallback" |
| 10 | Warm vs Cool neutral | Notion #37352F warm ink |
| 11 | Multi-layer shadow | Stripe 2-layer, Linear 5-layer |
| 12 | Customer logo wall 오염 | "trusted by" SVG hex |
| 13 | Letter-spacing optical | 큰 heading negative tracking |
| 14 | Variable font 비표준 weight | Saans 300/380/570 |
