04. design_agent 추가 — 콘텐츠 시각 구조화 슬라이드 생성기
5단계 AI 파이프라인: 1. Kei 실장(Opus via Kei API) — 꼭지 추출 + 정보 구조 파악 2. 디자인 팀장 — FAISS 블록 검색 + Opus 추천 + Sonnet 블록 매핑 3. Kei 편집자(Kei API) — 도메인 전문 텍스트 정리 4. 디자인 실무자(Sonnet + Jinja2) — CSS 변수 조정 + HTML 조립 5. 디자인 팀장(Sonnet) — 균형 재검토 (최대 2회 루프) 블록 라이브러리 46개 (6 카테고리) + _legacy 13개 FAISS 블록 검색 (bge-m3, 1024차원) SVG N개 동적 배치 (cos/sin 좌표 계산) Pillow 이미지 크기 측정 + base64 인라인 컨테이너 예산 기반 블록 배치 (zone별 높이 px) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
105
04. design_agent/docs/BLOCK_SLOTS_45.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# 45개 블록 BLOCK_SLOTS — design_director.py에 반영 필요
|
||||
# 다른 쪽 작업 완료 후 교체
|
||||
|
||||
BLOCK_SLOTS = {
|
||||
# headers/
|
||||
"section-title-with-bg": {"required": ["title_ko"], "optional": ["title_en", "breadcrumb", "bg_image"]},
|
||||
"section-header-bar": {"required": ["title"], "optional": ["subtitle"]},
|
||||
"topic-left-right": {"required": ["title", "description"], "optional": []},
|
||||
"topic-center": {"required": ["title"], "optional": ["subtitle", "description"]},
|
||||
"topic-numbered": {"required": ["number", "title"], "optional": ["description", "color"]},
|
||||
# cards/
|
||||
"card-image-3col": {"required": ["cards"], "optional": []},
|
||||
"card-text-grid": {"required": ["cards"], "optional": []},
|
||||
"card-dark-overlay": {"required": ["cards"], "optional": []},
|
||||
"card-tag-image": {"required": ["cards"], "optional": []},
|
||||
"card-icon-desc": {"required": ["cards"], "optional": []},
|
||||
"card-compare-3col": {"required": ["cards"], "optional": []},
|
||||
"card-step-vertical": {"required": ["steps"], "optional": []},
|
||||
"card-image-round": {"required": ["cards"], "optional": []},
|
||||
"card-stat-number": {"required": ["stats"], "optional": []},
|
||||
"card-numbered": {"required": ["items"], "optional": []},
|
||||
# tables/
|
||||
"compare-3col-badge": {"required": ["headers", "rows"], "optional": []},
|
||||
"compare-2col-split": {"required": ["left_title", "right_title", "rows"], "optional": []},
|
||||
"table-simple-striped": {"required": ["headers", "rows"], "optional": []},
|
||||
# visuals/
|
||||
"venn-diagram": {"required": ["center_label", "items"], "optional": ["center_sub", "description"]},
|
||||
"circle-gradient": {"required": ["label"], "optional": ["sub_label"]},
|
||||
"compare-pill-pair": {"required": ["left_label", "right_label"], "optional": ["left_sub", "right_sub"]},
|
||||
"process-horizontal": {"required": ["steps"], "optional": []},
|
||||
"flow-arrow-horizontal": {"required": ["steps"], "optional": []},
|
||||
"keyword-circle-row": {"required": ["keywords"], "optional": []},
|
||||
"layer-diagram": {"required": ["layers"], "optional": ["title"]},
|
||||
"timeline-vertical": {"required": ["events"], "optional": []},
|
||||
"timeline-horizontal": {"required": ["events"], "optional": []},
|
||||
"pyramid-hierarchy": {"required": ["levels"], "optional": []},
|
||||
# emphasis/
|
||||
"quote-left-border": {"required": ["quote_text"], "optional": ["source"]},
|
||||
"quote-big-mark": {"required": ["quote_text"], "optional": ["source"]},
|
||||
"quote-question": {"required": ["question"], "optional": ["description"]},
|
||||
"conclusion-accent-bar": {"required": ["conclusion_text"], "optional": ["label"]},
|
||||
"comparison-2col": {"required": ["left_title", "left_content", "right_title", "right_content"], "optional": ["left_subtitle", "right_subtitle"]},
|
||||
"banner-gradient": {"required": ["text"], "optional": ["sub_text"]},
|
||||
"dark-bullet-list": {"required": ["bullets"], "optional": ["title"]},
|
||||
"highlight-strip": {"required": ["segments"], "optional": []},
|
||||
"callout-solution": {"required": ["title", "description"], "optional": ["icon", "source"]},
|
||||
"callout-warning": {"required": ["title", "description"], "optional": ["icon"]},
|
||||
"tab-label-row": {"required": ["tabs"], "optional": []},
|
||||
"divider-text": {"required": ["text"], "optional": []},
|
||||
# media/
|
||||
"image-row-2col": {"required": ["images"], "optional": []},
|
||||
"image-grid-2x2": {"required": ["images"], "optional": []},
|
||||
"image-side-text": {"required": ["image_src"], "optional": ["image_alt", "title", "description", "bullets"]},
|
||||
"image-full-caption": {"required": ["src"], "optional": ["alt", "caption"]},
|
||||
"image-before-after": {"required": ["before_src", "after_src"], "optional": ["before_label", "after_label", "caption"]},
|
||||
}
|
||||
|
||||
# _apply_defaults 용
|
||||
BLOCK_DEFAULTS = {
|
||||
"section-title-with-bg": {"title_ko": "(제목)"},
|
||||
"section-header-bar": {"title": "(섹션)"},
|
||||
"topic-left-right": {"title": "(소제목)", "description": ""},
|
||||
"topic-center": {"title": "(제목)"},
|
||||
"topic-numbered": {"number": "1", "title": "(단계)"},
|
||||
"card-image-3col": {"cards": []},
|
||||
"card-text-grid": {"cards": []},
|
||||
"card-dark-overlay": {"cards": []},
|
||||
"card-tag-image": {"cards": []},
|
||||
"card-icon-desc": {"cards": []},
|
||||
"card-compare-3col": {"cards": []},
|
||||
"card-step-vertical": {"steps": []},
|
||||
"card-image-round": {"cards": []},
|
||||
"card-stat-number": {"stats": []},
|
||||
"card-numbered": {"items": []},
|
||||
"compare-3col-badge": {"headers": [], "rows": []},
|
||||
"compare-2col-split": {"left_title": "A", "right_title": "B", "rows": []},
|
||||
"table-simple-striped": {"headers": [], "rows": []},
|
||||
"venn-diagram": {"center_label": "관계도", "items": [], "center_sub": "", "description": ""},
|
||||
"circle-gradient": {"label": "(라벨)"},
|
||||
"compare-pill-pair": {"left_label": "A", "right_label": "B"},
|
||||
"process-horizontal": {"steps": []},
|
||||
"flow-arrow-horizontal": {"steps": []},
|
||||
"keyword-circle-row": {"keywords": []},
|
||||
"layer-diagram": {"layers": []},
|
||||
"timeline-vertical": {"events": []},
|
||||
"timeline-horizontal": {"events": []},
|
||||
"pyramid-hierarchy": {"levels": []},
|
||||
"quote-left-border": {"quote_text": "(인용)"},
|
||||
"quote-big-mark": {"quote_text": "(인용)"},
|
||||
"quote-question": {"question": "(질문)"},
|
||||
"conclusion-accent-bar": {"conclusion_text": "(결론)"},
|
||||
"comparison-2col": {"left_title": "A", "left_content": "-", "right_title": "B", "right_content": "-"},
|
||||
"banner-gradient": {"text": "(배너)"},
|
||||
"dark-bullet-list": {"bullets": []},
|
||||
"highlight-strip": {"segments": []},
|
||||
"callout-solution": {"title": "(솔루션)", "description": ""},
|
||||
"callout-warning": {"title": "(경고)", "description": ""},
|
||||
"tab-label-row": {"tabs": []},
|
||||
"divider-text": {"text": "구분"},
|
||||
"image-row-2col": {"images": []},
|
||||
"image-grid-2x2": {"images": []},
|
||||
"image-side-text": {"image_src": ""},
|
||||
"image-full-caption": {"src": ""},
|
||||
"image-before-after": {"before_src": "", "after_src": ""},
|
||||
}
|
||||
582
04. design_agent/docs/FIGMA-COMPONENT-EXTRACTION-PLAN.md
Normal file
@@ -0,0 +1,582 @@
|
||||
# Figma → 컴포넌트 추출 + 카탈로그 구축 계획
|
||||
|
||||
## 목적
|
||||
|
||||
Figma 디자인(바론컨설턴트 홈페이지 기획팀 공유)에서 재사용 가능한 **콘텐츠 블록**을 추출하고, 디자인 팀장(Sonnet)이 선택할 수 있는 카탈로그로 체계화한다.
|
||||
|
||||
**핵심 원칙: 블록은 모드 독립적이다.**
|
||||
- 블록 자체는 "슬라이드 전용"이 아니라 **HTML/CSS 콘텐츠 블록**
|
||||
- 슬라이드 모드(100vh, overflow:hidden)와 웹/스크롤 모드(auto, overflow:visible)는 **컨테이너(base 템플릿)**가 결정
|
||||
- 블록은 높이를 고정하지 않음 → 어떤 컨테이너에도 들어갈 수 있음
|
||||
- 현재는 `slide-base.html`(슬라이드)에 집중하되, 향후 `page-base.html`(웹) 추가 가능
|
||||
|
||||
```
|
||||
블록 (카드, 표, 인용 등) — 모드와 무관, 재사용 가능
|
||||
↓
|
||||
slide-base.html → height:100vh, overflow:hidden (슬라이드 모드)
|
||||
page-base.html → height:auto, overflow:visible (웹/스크롤 모드, 향후)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 현재 상태
|
||||
|
||||
### 보유 자산
|
||||
|
||||
| 항목 | 상태 | 위치 |
|
||||
|------|------|------|
|
||||
| Figma API 접근 | ✅ 가능 | Token: `.env` |
|
||||
| 기존 블록 템플릿 7종 | ✅ 완성 | `templates/blocks/` |
|
||||
| 디자인 토큰 | ✅ 완성 | `static/tokens.css` |
|
||||
| 슬라이드 렌더러 | ✅ 완성 | `src/renderer.py` |
|
||||
| 디자인 팀장 (DA-13) | ❌ todo | `src/design_director.py` |
|
||||
| 블록 카탈로그 | ❌ 없음 | - |
|
||||
|
||||
### Figma 파일 구조
|
||||
|
||||
```
|
||||
바론 공유 2025.05.13 (node: 1574-6254)
|
||||
├── 1장 바론컨설턴트
|
||||
├── 2장 디지털전환
|
||||
│ ├── 2-1 건설산업에서의 디지털전환 (1920x8538, 스크롤형)
|
||||
│ ├── 2-2 디지털전환과 소프트웨어 (1920x9123, 스크롤형)
|
||||
│ └── 건설산업에서의 디지털전환 (1920x8536, 스크롤형)
|
||||
│ [자세히보기]
|
||||
│ ├── 2-1장 자세히보기 (4프레임: 건설산업/BIM/GIS/디지털트윈)
|
||||
│ ├── 2-2장 자세히보기
|
||||
│ └── 2-3장 자세히보기
|
||||
├── 3장 제공서비스
|
||||
│ ├── 3-1장 솔루션프로그램 자세히보기
|
||||
│ └── 3-3장 빅룸 자세히보기
|
||||
└── 모션작업
|
||||
```
|
||||
|
||||
### 기존 블록 vs Figma에서 발견된 패턴
|
||||
|
||||
| 패턴 | 기존 블록 | Figma에서 발견 | 갭 |
|
||||
|------|----------|--------------|-----|
|
||||
| 2단 비교 | ✅ comparison | ✅ | - |
|
||||
| 카드 그리드 | ✅ card-grid | ✅ (변형 다수) | 변형 추가 필요 |
|
||||
| 벤 다이어그램 | ✅ relationship | ✅ | - |
|
||||
| 단계 흐름 | ✅ process | ✅ | - |
|
||||
| 강조 인용 | ✅ quote-block | ✅ (큰따옴표 장식) | 변형 추가 필요 |
|
||||
| 결론 바 | ✅ conclusion-bar | ✅ | - |
|
||||
| 비교 테이블 | ✅ comparison-table | ✅ | - |
|
||||
| **이미지 갤러리** | ❌ | ✅ (2열, 3열, 2x2) | **신규** |
|
||||
| **타임라인** | ❌ | ✅ (세로 원형 4단계) | **신규** |
|
||||
| **섹션 타이틀** | ❌ | ✅ (영문+한글 공통 헤더) | **신규** |
|
||||
| **사례 카드** | ❌ | ✅ (출처+불릿 카드) | **신규** |
|
||||
| **핵심 지표** | ❌ (정의만) | ✅ (큰 숫자+보조) | **신규** |
|
||||
| **아이콘 리스트** | ❌ | ✅ (아이콘+제목+설명) | **신규** |
|
||||
| **Hero 섹션** | ❌ | ✅ (배경+원형이미지+텍스트) | **신규** |
|
||||
| **CTA 버튼 바** | ❌ | ✅ (자세히보기 버튼) | **필요 시** |
|
||||
| **이미지 블록** | ❌ | ✅ (도표, 참고자료) | **신규** (3변형: full/side/thumb) |
|
||||
| **자세히보기 블록** | ❌ | ✅ (상세 콘텐츠 접기/펼치기) | **신규** (`<details>/<summary>`) |
|
||||
|
||||
---
|
||||
|
||||
## 작업 계획
|
||||
|
||||
### Phase A: Figma 분석 + 패턴 추출
|
||||
|
||||
#### A-1: Figma 전체 섹션 이미지 렌더링
|
||||
- **작업:** 각 섹션/프레임을 이미지로 렌더링하여 시각적으로 패턴 식별
|
||||
- **방법:**
|
||||
- **1차:** Framelink MCP `get_figma_data` — CSS-ready 데이터로 노드 구조 + 스타일 동시 추출
|
||||
- **2차:** Figma 공식 MCP `get_screenshot` — 시각 참고용 스크린샷
|
||||
- **fallback:** Figma REST API `/v1/images/{file_key}?ids={node_ids}` (MCP 미설치 시)
|
||||
- **산출물:** `docs/figma-screenshots/` 폴더에 PNG 저장
|
||||
- **완료 기준:** 모든 자세히보기 프레임(8개)의 스크린샷 확보
|
||||
|
||||
#### A-2: Figma 노드 구조 심층 분석
|
||||
- **작업:** 각 프레임의 상세 스타일 + 레이아웃 정보 추출
|
||||
- **방법:**
|
||||
- **1차:** Framelink MCP `get_figma_data` (nodeId 지정, depth 조절)
|
||||
- 자동 CSS 변환: 색상→hex/rgba, 레이아웃→flex 용어, 그림자→box-shadow, 그라데이션→linear-gradient()
|
||||
- 스타일 중복 제거 (글로벌 변수로 추출)
|
||||
- 토큰 효율적 (raw API 대비 1/5 크기)
|
||||
- **2차:** Figma 공식 MCP `get_variable_defs` — 디자인 토큰/변수 추출
|
||||
- **fallback:** Figma REST API `/v1/files/{key}/nodes?ids={ids}&depth=5` (MCP 미설치 시)
|
||||
- **추출 정보:**
|
||||
- TEXT 노드: fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, color, 텍스트 내용
|
||||
- FRAME/GROUP: auto-layout (direction, gap, padding, alignItems, justifyContent), constraints
|
||||
- RECTANGLE: fills (solid/gradient/image), strokes, cornerRadius, effects
|
||||
- INSTANCE: componentId (재사용 컴포넌트 식별)
|
||||
- **Figma → CSS 매핑 (Framelink MCP가 자동 처리, REST API 시 수동):**
|
||||
- `layoutMode: "VERTICAL"` → `flex-direction: column`
|
||||
- `primaryAxisAlignItems: "CENTER"` → `justify-content: center`
|
||||
- `itemSpacing: 20` → `gap: 20px`
|
||||
- `paddingLeft/Right/Top/Bottom` → `padding`
|
||||
- `fills[].color {r,g,b,a}` → `rgba()` 또는 `#hex`
|
||||
- `fills[].type: "GRADIENT_LINEAR"` → `linear-gradient(...)`
|
||||
- `cornerRadius` → `border-radius`
|
||||
- `strokes + strokeWeight` → `border`
|
||||
- `effects[].type: "DROP_SHADOW"` → `box-shadow`
|
||||
- `fontSize` → `font-size` (px 단위)
|
||||
- `lineHeightPercentFontSize: 170` → `line-height: 1.7`
|
||||
- **산출물:** `docs/figma-analysis/` 폴더에 구조 문서
|
||||
- **주의:** Figma API rate limit 심함 — depth 깊은 요청은 30분 차단 가능. 얕게 요청 후 필요한 노드만 상세 조회
|
||||
|
||||
#### A-3: 디자인 패턴 분류 + 명명
|
||||
- **작업:** 추출된 시각 요소를 재사용 가능한 블록 단위로 분류
|
||||
- **기준:**
|
||||
- 2회 이상 반복되는 패턴 → 블록 후보
|
||||
- 슬롯(교체 가능한 위치)이 명확한 것 → 우선 순위 높음
|
||||
- 콘텐츠 유형과 매칭되는 것 → 우선 순위 높음
|
||||
- **산출물:** 패턴 목록 + 각 패턴의 Figma 원본 노드 ID
|
||||
|
||||
### Phase B: HTML/CSS 컴포넌트 제작
|
||||
|
||||
#### B-1: 신규 블록 템플릿 제작 (8~10종)
|
||||
- **파일:** `templates/blocks/{name}/` 폴더별 정리 (변형별 파일 + preview.png)
|
||||
- **제작 순서 (우선순위):**
|
||||
1. `section-title/default.html` — 공통 헤더 (모든 슬라이드에서 사용)
|
||||
2. `example-card/2col.html` — 사례 카드 (출처+불릿, 정책 문서 인용)
|
||||
3. `image-block/full.html`, `side.html`, `thumb.html` — 이미지 블록 3변형
|
||||
- full: 전체 너비 (핵심 도표, 가로형)
|
||||
- side: 텍스트 옆 (보조 이미지, 세로형)
|
||||
- thumb: 썸네일 (참고 문서 표지)
|
||||
- CSS: `object-fit: contain` (비율 유지, 잘리지 않음)
|
||||
- 원본 이미지 그대로 사용, 크기만 조절 (crop 안 함)
|
||||
4. `image-gallery/2col.html`, `3col.html`, `2x2.html` — 이미지 갤러리
|
||||
5. `timeline/vertical.html`, `horizontal.html` — 타임라인 (연혁/로드맵)
|
||||
6. `big-number/3col.html`, `4col.html` — 핵심 지표 (큰 숫자 + 보조 텍스트)
|
||||
7. `icon-list/vertical.html`, `grid.html` — 아이콘 리스트 (기능 나열)
|
||||
8. `details-block/default.html` — 자세히보기 (`<details>/<summary>`)
|
||||
- 슬라이드 표면: 요약만 표시
|
||||
- 펼치면: 전체 상세 내용
|
||||
- 인쇄 시: `beforeprint` 이벤트로 자동 펼침
|
||||
- **규칙:**
|
||||
- 디자인 토큰(`var(--color-*)`) 사용 (하드코딩 색상 금지)
|
||||
- Jinja2 슬롯 (`{{ variable }}`) 형식
|
||||
- `<style>` 태그를 블록 HTML 안에 포함 (자체 완결)
|
||||
- Figma 원본과 시각적으로 유사하되 1:1 복제 아님 (디자인 토큰 기준)
|
||||
- **높이를 고정하지 않음** (auto 또는 비율 사용) — 모드 독립적
|
||||
- 각 블록에 사람용 주석 포함 (용도, 적합/부적합, Figma 원본 위치)
|
||||
|
||||
#### B-1a: Figma 웹 → 블록 변환 규칙
|
||||
Figma는 웹사이트 디자인(920px 너비, 세로 스크롤)이므로, 블록으로 변환할 때 아래 규칙을 적용한다:
|
||||
|
||||
| Figma 원본 | 블록 변환 | 이유 |
|
||||
|------------|----------|------|
|
||||
| 높이: 고정 px (예: 200px) | `height: auto` 또는 비율(%) | 720px 안에 들어가야 하고, 웹 모드에서도 동작해야 함 |
|
||||
| 너비: 고정 px (예: 920px) | `fr` 또는 `%` (grid 컬럼에 맞춤) | 컨테이너 너비에 적응해야 함 |
|
||||
| 색상: Figma 값 (예: #1565c0) | `var(--color-accent)` 등 디자인 토큰 | 토큰 체계 통일. 필요 시 `tokens.css`에 토큰 추가 |
|
||||
| 폰트: Figma 값 (예: Noto Sans CJK KR 24px) | `var(--font-subtitle)` 등 디자인 토큰 | Pretendard 기준. 크기 비율만 참고 |
|
||||
| 간격: Figma 값 (예: padding 20px, gap 80px) | `var(--spacing-inner)`, `var(--spacing-block)` 등 | 토큰 체계. 비율 참고 |
|
||||
| 그라데이션 배경 | **제거** | CLAUDE.md 디자인 규칙: 그라데이션 금지 |
|
||||
| 호버/클릭 효과 | **제거** | CLAUDE.md 디자인 규칙: 호버 금지 |
|
||||
| 애니메이션/트랜지션 | **제거** | CLAUDE.md 디자인 규칙: 애니메이션 금지 |
|
||||
| 원형 이미지 마스크 | **제거** (필요 시 별도 변형으로) | 장식 요소는 기본에서 제외 |
|
||||
| 텍스트 위치 | `{{ variable }}` Jinja2 슬롯으로 표시 | 교체 가능한 부분 |
|
||||
|
||||
**원칙:** Figma에서 가져오는 것은 **정보 구조(카드 배치, 타임라인 흐름, 비교 레이아웃)**이지, 장식 요소가 아니다.
|
||||
|
||||
#### B-2: 기존 블록 변형 추가
|
||||
- **대상:**
|
||||
- `quote-block.html` → `quote-block-decorated.html` (큰따옴표 ::before/::after 장식)
|
||||
- `card-grid.html` → `card-grid-icon.html` (아이콘 강조 변형)
|
||||
- `comparison.html` → `comparison-visual.html` (이미지 포함 비교)
|
||||
- **규칙:** 기존 슬롯 구조 유지, CSS만 변형
|
||||
|
||||
#### B-3: slide-base.html 업데이트
|
||||
- **내용:** 신규 블록의 grid-area 지원, 디자인 토큰 추가 (필요 시)
|
||||
- **주의:** 기존 7개 블록의 렌더링이 깨지지 않는지 반드시 검증
|
||||
|
||||
### Phase C: 카탈로그 구축
|
||||
|
||||
#### C-1: catalog.yaml 생성
|
||||
- **파일:** `templates/catalog.yaml`
|
||||
- **구조:**
|
||||
|
||||
```yaml
|
||||
version: "1.0"
|
||||
blocks:
|
||||
# --- 기존 블록 ---
|
||||
- id: quote-block
|
||||
name: 강조 인용
|
||||
visual: "좌측 컬러 라인 + 배경색 + 인용 텍스트"
|
||||
when: "문제 제기, 핵심 주장, 정의 강조할 때"
|
||||
not_for: "일반 설명문, 사례 나열"
|
||||
slots:
|
||||
required: [quote_text]
|
||||
optional: [source]
|
||||
character_limits:
|
||||
quote_text: 150
|
||||
source: 50
|
||||
variations: [default, decorated]
|
||||
figma_ref: null # 기존 블록은 Figma 이전에 제작됨
|
||||
|
||||
# --- 신규 블록 ---
|
||||
- id: example-card
|
||||
name: 사례 카드
|
||||
visual: "제목 + 출처(기관/연도) + 불릿 목록, 테두리 박스. 2~3장 나란히."
|
||||
when: "정책 문서 인용, 법령/지침 사례, 출처가 명확한 근거 제시"
|
||||
not_for: "용어 정의, 일반 설명, 비교"
|
||||
slots:
|
||||
required: [items[].title, items[].bullets[]]
|
||||
optional: [items[].source_org, items[].source_year]
|
||||
character_limits:
|
||||
title: 30
|
||||
bullet: 60
|
||||
variations: [single, 2col, 3col]
|
||||
figma_ref: "1574:54586 > 2-1_01 > examples-row"
|
||||
|
||||
- id: image-gallery
|
||||
name: 이미지 갤러리
|
||||
visual: "이미지 2~4장 나란히 + 캡션, 중앙 정렬"
|
||||
when: "근거 자료 사진, 문서 표지, 현장 사진, 참고 이미지"
|
||||
not_for: "텍스트 콘텐츠, 다이어그램 (다이어그램은 relationship 사용)"
|
||||
slots:
|
||||
required: [images[].src, images[].alt]
|
||||
optional: [images[].caption]
|
||||
variations: [2col, 3col, 2x2]
|
||||
figma_ref: "1574:54586 > 2-1_03 > image grid"
|
||||
|
||||
- id: timeline
|
||||
name: 타임라인
|
||||
visual: "세로/가로 축 위에 원형 마커 + 연도/제목/설명"
|
||||
when: "연혁, 로드맵, 정책 시행 일정, 단계별 계획"
|
||||
not_for: "프로세스 흐름 (순서는 있지만 시간이 아닌 것은 process 사용)"
|
||||
slots:
|
||||
required: [events[].year, events[].title]
|
||||
optional: [events[].description]
|
||||
character_limits:
|
||||
title: 25
|
||||
description: 60
|
||||
variations: [vertical, horizontal]
|
||||
figma_ref: "1574:54586 > 2-1_01 > timeline"
|
||||
|
||||
- id: big-number
|
||||
name: 핵심 지표
|
||||
visual: "큰 숫자(2rem+) + 단위 + 보조 설명. 2~4개 나란히."
|
||||
when: "KPI, 통계, 목표 수치, 성과 지표"
|
||||
not_for: "텍스트 설명, 정의"
|
||||
slots:
|
||||
required: [metrics[].number, metrics[].label]
|
||||
optional: [metrics[].unit, metrics[].description]
|
||||
variations: [2col, 3col, 4col]
|
||||
figma_ref: null
|
||||
|
||||
- id: section-title
|
||||
name: 섹션 타이틀
|
||||
visual: "영문 소제목(작은 글씨) + 한글 대제목(큰 글씨), 하단 구분선"
|
||||
when: "모든 슬라이드 상단, 섹션 시작"
|
||||
not_for: "본문 콘텐츠 영역"
|
||||
slots:
|
||||
required: [title_ko]
|
||||
optional: [title_en, subtitle]
|
||||
figma_ref: "공통 > section_title 컴포넌트"
|
||||
|
||||
- id: icon-list
|
||||
name: 아이콘 리스트
|
||||
visual: "아이콘 + 제목 + 설명이 세로로 나열, 좌측 아이콘 정렬"
|
||||
when: "기능 나열, 특성 목록, 장점 리스트"
|
||||
not_for: "비교 (comparison 사용), 순서 (process 사용)"
|
||||
slots:
|
||||
required: [items[].icon, items[].title, items[].description]
|
||||
character_limits:
|
||||
title: 20
|
||||
description: 80
|
||||
variations: [vertical, horizontal, grid]
|
||||
figma_ref: null
|
||||
|
||||
layouts:
|
||||
- id: "65-35"
|
||||
name: "6.5:3.5 좌우 분할"
|
||||
grid_columns: "6.5fr 3.5fr"
|
||||
when: "좌측 메인 콘텐츠 + 우측 보조/정의"
|
||||
|
||||
- id: "50-50"
|
||||
name: "5:5 균등 분할"
|
||||
grid_columns: "1fr 1fr"
|
||||
when: "대등한 비교, 병렬 콘텐츠"
|
||||
|
||||
- id: "single"
|
||||
name: "단일 컬럼"
|
||||
grid_columns: "1fr"
|
||||
when: "프로세스 흐름, 타임라인, 단순 구조"
|
||||
|
||||
- id: "35-65"
|
||||
name: "3.5:6.5 좌우 분할"
|
||||
grid_columns: "3.5fr 6.5fr"
|
||||
when: "좌측 요약/네비게이션 + 우측 메인 콘텐츠"
|
||||
```
|
||||
|
||||
#### C-2: 카탈로그 → 디자인 팀장 프롬프트 연결
|
||||
- **파일:** `src/design_director.py` 수정
|
||||
- **방법:** `catalog.yaml` 로드 → 블록 목록을 시스템 프롬프트에 삽입
|
||||
- **프롬프트 구조:**
|
||||
```
|
||||
사용 가능한 블록:
|
||||
- quote-block: 좌측 컬러 라인 + 인용 텍스트. 문제 제기할 때 사용. 일반 설명문에는 부적합.
|
||||
- example-card: 제목+출처+불릿. 정책 사례 인용할 때 사용. 2~3장 나란히.
|
||||
- card-grid: 2~4열 카드. 용어 정의 여러 개 나열할 때 사용.
|
||||
...
|
||||
|
||||
사용 가능한 레이아웃:
|
||||
- 65-35: 좌측 메인 + 우측 보조. 메인 콘텐츠가 많을 때.
|
||||
- 50-50: 균등 비교. 대등한 내용일 때.
|
||||
...
|
||||
|
||||
위 블록과 레이아웃만 사용하여 배치해라. 목록에 없는 블록은 만들지 마라.
|
||||
```
|
||||
|
||||
#### C-3: renderer.py 업데이트
|
||||
- **내용:** 신규 블록 템플릿 로드 지원
|
||||
- **주의:** 기존 `BLOCK_SLOTS` dict에 신규 블록 추가
|
||||
|
||||
---
|
||||
|
||||
## 충돌 지점 + 리스크 검토
|
||||
|
||||
### 1. Figma 디자인 ≠ 디자인 토큰
|
||||
|
||||
| 리스크 | 설명 | 대응 |
|
||||
|--------|------|------|
|
||||
| **색상 불일치** | Figma는 파란 그라데이션 배경 사용, 디자인 토큰은 `#2563eb` 단색 | Figma 색상을 참고하되 토큰 체계 우선. 필요 시 토큰 추가 (`--color-accent-light` 등) |
|
||||
| **폰트 불일치** | Figma는 Noto Sans CJK KR 사용, 토큰은 Pretendard Variable | Pretendard 유지. Figma 폰트 크기 비율만 참고 |
|
||||
| **여백 불일치** | Figma 920px 프레임 vs 슬라이드 1280px | 비율 기반으로 변환. 고정 px 대신 토큰 사용 |
|
||||
| **웹 vs 슬라이드** | Figma는 웹사이트(세로 스크롤, 920x1231~2208px), 슬라이드는 고정(1280x720px) | 높이 고정하지 않음(auto). 컨테이너가 모드를 결정 |
|
||||
|
||||
**원칙:** Figma 디자인을 1:1 복제하지 않는다. 패턴(정보 구조)만 추출하고, 스타일은 디자인 토큰으로 통일한다.
|
||||
|
||||
**디자인 토큰 매핑 테이블 (Figma 추출 시 작성):**
|
||||
Figma에서 추출한 색상/폰트/간격을 기존 `tokens.css`와 매핑하고, 누락된 토큰이 있으면 추가한다.
|
||||
|
||||
| Figma 속성 | 추출값 (예시) | 기존 토큰 매핑 | 신규 토큰 필요? |
|
||||
|------------|-------------|--------------|--------------|
|
||||
| 배경색 (SOLID fill) | `#f8fafc` | `--color-bg-subtle` | - |
|
||||
| 포인트 색상 | `#1565c0` | `--color-accent` (현재 `#2563eb`) | 검토 필요 |
|
||||
| 텍스트 색상 | `#1e293b` | `--color-primary` | - |
|
||||
| 보조 텍스트 | `#64748b` | `--color-neutral` | - |
|
||||
| 경고/강조 | `#dc2626` | `--color-danger` | - |
|
||||
| 본문 폰트 크기 | `16px` | `--font-body` (현재 `0.95rem ≈ 15.2px`) | 비율 확인 |
|
||||
| 제목 폰트 크기 | `24px` | `--font-subtitle` (현재 `1.25rem = 20px`) | 비율 확인 |
|
||||
| 블록 간 간격 | `20px` | `--spacing-block` | - |
|
||||
| 내부 패딩 | `16px` | `--spacing-inner` | - |
|
||||
| 카드 상단 액센트 | `3px solid` | `--accent-border` | - |
|
||||
|
||||
이 매핑 테이블은 Phase A-2에서 실제 Figma 값을 추출한 후 정확한 값으로 채운다. 기존 토큰과 차이가 크면 토큰을 추가하되, 기존 토큰의 값을 변경하지 않는다 (기존 7개 블록이 깨질 수 있음).
|
||||
|
||||
### 2. 블록 개수 증가 → 디자인 팀장 혼란
|
||||
|
||||
| 리스크 | 설명 | 대응 |
|
||||
|--------|------|------|
|
||||
| **선택지 과다** | 7개 → 13~15개로 증가 시 Sonnet이 부적절한 블록 선택 가능 | `when` + `not_for` 필드로 선택 기준 명확화. 프롬프트에 "이런 콘텐츠에는 이 블록을 쓰지 마라" 명시 |
|
||||
| **유사 블록 혼동** | card-grid vs example-card vs icon-list 구분 | 카탈로그에 각 블록의 차이점 명시. 예: "card-grid는 정의, example-card는 출처 있는 사례, icon-list는 기능 나열" |
|
||||
|
||||
**대응:** catalog.yaml의 `not_for` 필드가 핵심. "이 블록은 이것에 쓰지 마라"를 명시해야 혼동 감소.
|
||||
|
||||
### 3. 기존 파이프라인 깨짐
|
||||
|
||||
| 리스크 | 설명 | 대응 |
|
||||
|--------|------|------|
|
||||
| **renderer.py 호환성** | 신규 블록 추가 시 기존 렌더링 깨짐 | 기존 7개 블록 테스트 먼저 통과 확인 후 신규 추가 |
|
||||
| **BLOCK_SLOTS 누락** | design_director.py의 BLOCK_SLOTS에 신규 블록 미등록 | catalog.yaml에서 자동 로드하는 방식으로 전환 |
|
||||
| **slide-base.html** | grid-template-areas에 신규 area명 미지원 | 동적 생성이므로 문제 없음 (Sonnet이 area명을 직접 지정) |
|
||||
|
||||
**대응:** Phase B 완료 후 기존 테스트 케이스(DA-16) 반드시 재실행.
|
||||
|
||||
### 4. Figma API 제약
|
||||
|
||||
| 리스크 | 설명 | 대응 |
|
||||
|--------|------|------|
|
||||
| **CSS 미제공** | Figma REST API는 CSS를 직접 제공하지 않음. 스타일 속성만 제공 | **Framelink MCP 사용 시 자동 CSS 변환.** REST API만 사용 시 수동 변환 필요 |
|
||||
| **이미지 에셋** | 벡터(VECTOR, ELLIPSE)는 PNG로 렌더링 가능하나 CSS 재현 필요 | **Framelink MCP `download_figma_images`로 일괄 export.** 단순 도형은 CSS, 복잡한 것은 PNG |
|
||||
| **INSTANCE 참조** | Figma 컴포넌트(Instance)의 master 확인 필요 | `GET /v1/files/{key}/components`로 마스터 컴포넌트 조회 |
|
||||
| **Rate Limit** | REST API depth 깊은 요청 시 30분 차단 가능 | **Framelink MCP가 토큰 효율적 (raw API 대비 1/5).** 얕게 요청 후 필요한 노드만 상세 조회. 결과 캐싱 |
|
||||
| **디자인 토큰 접근** | REST API로는 Figma 변수/토큰 추출 불가 (별도 scope 필요) | **Figma 공식 MCP `get_variable_defs` 사용.** 또는 노드 속성에서 수동 추출 |
|
||||
| **의미적 HTML 추론 불가** | "버튼"은 FRAME+TEXT, "카드"는 FRAME+FRAME — 태그 구분 없음 | 노드 이름(naming convention)으로 추론. 예: `section_title`, `example-card` |
|
||||
|
||||
#### MCP 도구 설정
|
||||
|
||||
**Framelink MCP (권장, CSS-ready 추출):**
|
||||
```json
|
||||
// Claude Code MCP 설정
|
||||
{
|
||||
"mcpServers": {
|
||||
"Framelink MCP for Figma": {
|
||||
"command": "cmd",
|
||||
"args": ["/c", "npx", "-y", "figma-developer-mcp", "--figma-api-key=YOUR-KEY", "--stdio"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- `get_figma_data`: 노드 스타일을 CSS-ready YAML로 변환 (색상→hex, 레이아웃→flex, 그림자→box-shadow)
|
||||
- `download_figma_images`: 이미지 일괄 다운로드 (크롭, 중복 제거 자동)
|
||||
|
||||
**Figma 공식 MCP (디자인 토큰 + 스크린샷):**
|
||||
```
|
||||
claude mcp add --transport http figma https://mcp.figma.com/mcp
|
||||
```
|
||||
- `get_variable_defs`: 디자인 토큰(색상, 간격, 타이포) 추출
|
||||
- `get_screenshot`: 시각 참고용 스크린샷
|
||||
- 주의: Free/Starter 플랜 = 월 6회 호출 제한
|
||||
|
||||
### 5. Starlight(.astro) 연결 시 충돌
|
||||
|
||||
| 리스크 | 설명 | 대응 |
|
||||
|--------|------|------|
|
||||
| **CSS 변수 충돌** | Starlight 자체 CSS 변수(`--sl-*`)와 디자인 토큰(`--color-*`) 충돌 | 네임스페이스 분리: `--da-color-*` 접두사 사용 검토 |
|
||||
| **폰트 로딩** | .astro에서 Pretendard CDN 로드 필요 | `<style is:global>`에 @import 포함 |
|
||||
| **`<style>` 인라인** | 현재 렌더러가 CSS를 인라인하는데, .astro에서 Starlight CSS와 섞임 | `.astro` 출력 시 scoped style 또는 `is:global` + 높은 specificity |
|
||||
|
||||
**대응:** .astro 출력은 Phase C 이후 별도 태스크로. 현재는 독립 HTML 출력에 집중.
|
||||
|
||||
### 6. 유사 프로젝트 사례에서 발견된 문제
|
||||
|
||||
| 사례 | 문제 | 교훈 |
|
||||
|------|------|------|
|
||||
| **SlideSpeak** | 16개 레이아웃으로 시작했으나 실제 콘텐츠 다양성 커버 못함 | 블록을 조합하는 방식이 고정 레이아웃보다 유연 (현재 방식 유지) |
|
||||
| **PPTAgent (EMNLP 2025)** | 레퍼런스 슬라이드 클러스터링 시 과소/과다 분류 문제 | 블록 수를 10~15개로 제한. 너무 세분화하면 AI 선택이 어려워짐 |
|
||||
| **Beautiful.ai** | 300개 템플릿 중 실제 사용은 20개 | 처음부터 많이 만들지 않기. 실제 사용 빈도 보고 추가 |
|
||||
| **InfoDesignLM** | 텍스트만으로 레이아웃 생성 시 콘텐츠 양 ↔ 공간 불일치 | character_limits를 카탈로그에 명시, 텍스트 편집자가 강제 준수 |
|
||||
|
||||
---
|
||||
|
||||
## 작업 순서 (의존 관계)
|
||||
|
||||
```
|
||||
A-1 (Figma 스크린샷) ──┐
|
||||
├→ A-3 (패턴 분류) → B-1 (신규 블록 제작) → B-3 (base 업데이트)
|
||||
A-2 (노드 구조 분석) ──┘ ↓
|
||||
C-1 (catalog.yaml)
|
||||
↓
|
||||
B-2 (변형 추가) → C-2 (팀장 프롬프트 연결)
|
||||
↓
|
||||
C-3 (renderer 업데이트)
|
||||
↓
|
||||
기존 테스트 재실행 (DA-16)
|
||||
```
|
||||
|
||||
### 예상 소요
|
||||
|
||||
| Phase | 작업 | 규모 |
|
||||
|-------|------|------|
|
||||
| A (분석) | Figma 스크린샷 + 노드 분석 + 패턴 분류 | 탐색/조사 |
|
||||
| B (제작) | 신규 블록 6~8종 + 변형 3종 + base 업데이트 | 구현 (핵심) |
|
||||
| C (카탈로그) | catalog.yaml + 팀장 프롬프트 + renderer 업데이트 | 연결/통합 |
|
||||
|
||||
**핵심 원칙:** Phase A에서 패턴을 정확히 분류하지 않으면 Phase B에서 쓸모없는 블록을 만들게 된다. 분석 먼저, 제작은 그 다음.
|
||||
|
||||
---
|
||||
|
||||
## 산출물 목록
|
||||
|
||||
```
|
||||
docs/
|
||||
├── figma-screenshots/ # A-1: 각 프레임 PNG
|
||||
├── figma-analysis/ # A-2: 노드 구조 문서 + 디자인 토큰 매핑 테이블
|
||||
└── FIGMA-COMPONENT-EXTRACTION-PLAN.md # 이 파일
|
||||
|
||||
templates/
|
||||
├── catalog.yaml # C-1: 블록 카탈로그 (AI용 메뉴판 + 사람용 참고)
|
||||
├── blocks/
|
||||
│ ├── comparison/ # 기존 (폴더 구조로 재편)
|
||||
│ │ ├── default.html
|
||||
│ │ └── preview.png
|
||||
│ ├── card-grid/ # 기존
|
||||
│ │ ├── default.html
|
||||
│ │ ├── icon.html # B-2: 변형
|
||||
│ │ └── preview.png
|
||||
│ ├── relationship/ # 기존
|
||||
│ ├── process/ # 기존
|
||||
│ ├── quote-block/ # 기존
|
||||
│ │ ├── default.html
|
||||
│ │ ├── decorated.html # B-2: 변형
|
||||
│ │ └── preview.png
|
||||
│ ├── conclusion-bar/ # 기존
|
||||
│ ├── comparison-table/ # 기존
|
||||
│ ├── section-title/ # B-1: 신규
|
||||
│ │ ├── default.html
|
||||
│ │ └── preview.png
|
||||
│ ├── example-card/ # B-1: 신규
|
||||
│ │ ├── single.html
|
||||
│ │ ├── 2col.html
|
||||
│ │ ├── 3col.html
|
||||
│ │ └── preview.png
|
||||
│ ├── image-block/ # B-1: 신규 (3변형)
|
||||
│ │ ├── full.html # 전체 너비 (핵심 도표)
|
||||
│ │ ├── side.html # 텍스트 옆 (보조 이미지)
|
||||
│ │ ├── thumb.html # 썸네일 (참고 문서)
|
||||
│ │ └── preview.png
|
||||
│ ├── image-gallery/ # B-1: 신규
|
||||
│ │ ├── 2col.html
|
||||
│ │ ├── 3col.html
|
||||
│ │ ├── 2x2.html
|
||||
│ │ └── preview.png
|
||||
│ ├── timeline/ # B-1: 신규
|
||||
│ │ ├── vertical.html
|
||||
│ │ ├── horizontal.html
|
||||
│ │ └── preview.png
|
||||
│ ├── big-number/ # B-1: 신규
|
||||
│ │ ├── 3col.html
|
||||
│ │ ├── 4col.html
|
||||
│ │ └── preview.png
|
||||
│ ├── icon-list/ # B-1: 신규
|
||||
│ │ ├── vertical.html
|
||||
│ │ ├── grid.html
|
||||
│ │ └── preview.png
|
||||
│ └── details-block/ # B-1: 신규
|
||||
│ ├── default.html
|
||||
│ └── preview.png
|
||||
├── slide-base.html # B-3: 업데이트 (슬라이드 모드)
|
||||
└── page-base.html # 향후: 웹/스크롤 모드
|
||||
|
||||
samples/ # 완성 슬라이드 레시피
|
||||
├── dx-bim-comparison/
|
||||
│ ├── slide.html # 완성 HTML
|
||||
│ ├── preview.png # 스크린샷
|
||||
│ └── meta.yaml # 사용된 블록 조합 + Figma 원본 참조
|
||||
└── ...
|
||||
|
||||
src/
|
||||
├── design_director.py # C-2: catalog.yaml 연동
|
||||
└── renderer.py # C-3: 신규 블록 지원
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PROGRESS.md 연동
|
||||
|
||||
이 계획의 태스크들은 PROGRESS.md에 아래와 같이 등록한다:
|
||||
|
||||
### Phase F (Figma 컴포넌트 추출) — PROGRESS.md 등록 항목
|
||||
|
||||
| 태스크 | 상태 | 의존성 | 메모 |
|
||||
|--------|------|--------|------|
|
||||
| F-A1: Figma 스크린샷 확보 | todo | MCP 설치 후 | Framelink MCP 또는 REST API |
|
||||
| F-A2: 노드 구조 심층 분석 | todo | F-A1 | CSS-ready 데이터 + 토큰 매핑 테이블 |
|
||||
| F-A3: 패턴 분류 + 명명 | todo | F-A1, F-A2 | 블록 후보 목록 확정 |
|
||||
| F-B1: 신규 블록 템플릿 제작 (8~10종) | todo | F-A3 | 폴더 구조, 변환 규칙 적용 |
|
||||
| F-B1a: Figma 웹→블록 변환 규칙 검증 | todo | F-B1 | 토큰 매핑, 높이 auto 확인 |
|
||||
| F-B2: 기존 블록 변형 추가 | todo | F-B1 | CSS만 변형, 슬롯 유지 |
|
||||
| F-B3: slide-base.html 업데이트 | todo | F-B1 | 기존 7개 블록 깨지지 않는지 검증 |
|
||||
| F-C1: catalog.yaml 생성 | todo | F-B1 | when/not_for/slots/char_limits |
|
||||
| F-C2: 팀장 프롬프트 연결 | todo | F-C1 | catalog.yaml → 시스템 프롬프트 |
|
||||
| F-C3: renderer.py 업데이트 | todo | F-C1 | 신규 블록 로드 + BLOCK_SLOTS 동기화 |
|
||||
| F-T1: 기존 테스트 재실행 | todo | F-B3, F-C3 | DA-16 기존 케이스 전체 통과 확인 |
|
||||
|
||||
**사전 세팅 (Figma 작업 시작 전 필요):**
|
||||
|
||||
| 세팅 | 상태 | 설명 |
|
||||
|------|------|------|
|
||||
| Framelink MCP 설치 | todo | `npx figma-developer-mcp --figma-api-key=...` |
|
||||
| Figma 공식 MCP 설치 | todo | `claude mcp add --transport http figma https://mcp.figma.com/mcp` |
|
||||
| 기존 블록 폴더 구조 재편 | todo | 플랫 파일 → 블록별 폴더 (`templates/blocks/{name}/`) |
|
||||
| preview.png 생성 방법 확보 | todo | HTML을 브라우저로 열어 스크린샷 (수동 또는 Playwright) |
|
||||
|
||||
---
|
||||
|
||||
## 금지 사항
|
||||
|
||||
1. Figma 디자인을 1:1 복제하지 않는다 (정보 구조만 추출, 장식은 제거, 스타일은 토큰 기준)
|
||||
2. 기존 7개 블록 템플릿을 수정하지 않는다 (신규/변형은 별도 파일)
|
||||
3. 한 번에 모든 블록을 만들지 않는다 (A-3 분류 결과를 보고 우선순위 재조정)
|
||||
4. catalog.yaml 없이 블록을 추가하지 않는다 (카탈로그 미등록 = 디자인 팀장이 모름)
|
||||
5. Kei Persona Agent 코드를 수정하지 않는다
|
||||
6. 블록의 높이를 고정 px로 하드코딩하지 않는다 (모드 독립적이어야 함)
|
||||
7. 기존 `tokens.css`의 값을 변경하지 않는다 (신규 토큰 추가는 가능, 기존 값 변경은 7개 블록 깨짐 위험)
|
||||
8. 이미지를 crop하지 않는다 (원본 그대로, 크기만 조절)
|
||||
9. 그라데이션, 호버, 애니메이션 등 Figma 장식 요소를 가져오지 않는다
|
||||
245
04. design_agent/docs/PHASE2-PLAN.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# Phase 2 계획 — 파이프라인 고도화 + 검색 + 시각화 자동화
|
||||
|
||||
## Phase 1 완료 현황 (2026-03-25)
|
||||
|
||||
| 항목 | 상태 | 수량 |
|
||||
|------|------|------|
|
||||
| 블록 라이브러리 | ✅ | 46개 (6 카테고리) |
|
||||
| catalog.yaml | ✅ | 46개 등록, when/not_for/slots/height_cost |
|
||||
| BLOCK_SLOTS | ✅ | 46개 동기화 |
|
||||
| _apply_defaults | ✅ | 46개 동기화 |
|
||||
| SVG premium | ✅ | venn-diagram 검증 (3개 고정) |
|
||||
| Figma 에셋 | ✅ | 스크린샷 16장, 에셋 15개+ |
|
||||
| 5단계 파이프라인 | ✅ | 코드 동작 (BF-4~10 수정 완료/진행중) |
|
||||
| Kei API 연동 | ✅ | 1단계(실장) + 3단계(편집자) |
|
||||
| catalog→renderer 매핑 | ✅ | mtime 캐시 (BF-10) |
|
||||
| grid 역할 분리 | ✅ | BF-9 (코드가 grid, Sonnet은 blocks만) |
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 목표
|
||||
|
||||
**파이프라인을 실제 사용 가능한 수준으로 고도화한다.**
|
||||
|
||||
Phase 1은 "기반 구축 + 블록 라이브러리"였고,
|
||||
Phase 2는 "AI가 블록을 정확히 선택 + 고품질 결과물 생성"이다.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-A: FAISS 블록 검색 인덱스
|
||||
|
||||
### 목적
|
||||
디자인 팀장(Step B)이 콘텐츠를 보고 46개 블록 중 적합한 것을 **검색**으로 찾는다.
|
||||
현재는 catalog.yaml 전문이 프롬프트에 들어가는데, 46개가 넘으면 토큰 낭비 + 선택 정확도 저하.
|
||||
|
||||
### 구현
|
||||
```
|
||||
1. 각 블록의 (id + visual + when + not_for)를 임베딩
|
||||
2. FAISS 인덱스 구축 (46개 벡터)
|
||||
3. 콘텐츠 꼭지 분석 결과를 쿼리 → 상위 5~8개 후보 반환
|
||||
4. 팀장 프롬프트에 후보 블록만 포함 (전체 46개 대신)
|
||||
```
|
||||
|
||||
### 효과
|
||||
- 프롬프트 토큰 절약 (46개 전문 → 5~8개만)
|
||||
- 선택 정확도 향상 (관련 블록만 보여주니까)
|
||||
- 블록 100개+까지 확장 가능
|
||||
|
||||
### 파일
|
||||
- `src/block_search.py` (신규)
|
||||
- `data/block_index.faiss` (생성)
|
||||
- `src/design_director.py` (catalog 전문 → 검색 결과로 교체)
|
||||
|
||||
### 의존성
|
||||
- sentence-transformers 또는 Anthropic embeddings
|
||||
- FAISS (faiss-cpu)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-B: SVG N개 자동 배치
|
||||
|
||||
### 목적
|
||||
현재 venn-diagram은 3개 원 고정. 콘텐츠에 따라 2~7개 원이 필요할 수 있음.
|
||||
수학적 계산(cos/sin)으로 N개를 자동 배치한다.
|
||||
|
||||
### 구현
|
||||
```
|
||||
1. renderer.py에 SVG 좌표 계산 함수 추가
|
||||
- calc_circle_positions(n, center, radius) → [(cx, cy), ...]
|
||||
- 360/N 간격, 12시 방향부터 시계방향
|
||||
|
||||
2. venn-diagram.html 템플릿을 동적으로 변경
|
||||
- items[]에 사전 계산된 cx, cy가 포함
|
||||
- 원 크기도 N에 따라 자동 조정 (N=3: r=120, N=5: r=80, N=7: r=60)
|
||||
|
||||
3. Gemini 참고 디자인 흐름 (선택적)
|
||||
- SVG 초안 → Gemini에게 "이 구조로 고급 디자인" 요청
|
||||
- 생성 이미지의 색감/그라데이션을 참고하여 SVG tokens 업데이트
|
||||
- 최종은 항상 SVG (AI 이미지는 참고만)
|
||||
```
|
||||
|
||||
### 파일
|
||||
- `src/svg_calculator.py` (신규)
|
||||
- `templates/blocks/visuals/venn-diagram.html` (동적 좌표 지원)
|
||||
- `src/renderer.py` (SVG 계산 호출 추가)
|
||||
|
||||
### 검증 완료 사항
|
||||
- 3/4/5개 수학적 계산: ✅ (Phase 1에서 테스트)
|
||||
- SVG premium 디자인 (radialGradient+filter): ✅
|
||||
- AI 이미지 방식 폐기: ✅ (텍스트 위치 불일치로 사용 불가)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-C: 2단계 Step A 고도화 (Opus + FAISS)
|
||||
|
||||
### 목적
|
||||
현재 Step A는 규칙 4줄(프리셋 4개 중 선택)인데,
|
||||
원래 의도는 **Opus가 FAISS로 적합한 구조/블록을 검색해서 배치와 크기까지 정하는 것**.
|
||||
|
||||
### 구현
|
||||
```
|
||||
현재 (Phase 1):
|
||||
Step A: 규칙 기반 프리셋 선택 (코드)
|
||||
Step B: Sonnet이 블록 매핑
|
||||
|
||||
Phase 2:
|
||||
Step A: Opus + FAISS로 구조/블록 검색 + 배치/크기 결정
|
||||
Step B: Sonnet이 Step A 결과를 grid에 매칭 + 글자수 가이드
|
||||
```
|
||||
|
||||
### 세부
|
||||
1. Opus가 콘텐츠를 보고 "이 콘텐츠에는 비교형+정의형+관계도가 적합" 판단
|
||||
2. FAISS에서 각 유형에 맞는 블록 후보 검색
|
||||
3. 후보 중 배치/크기를 결정 (좌 65% 비교표, 우 35% 정의 카드, 하단 관계도)
|
||||
4. Step B(Sonnet)에게 이 배치 구조 + 후보 블록을 전달
|
||||
|
||||
### 의존성
|
||||
- Phase 2-A (FAISS 인덱스) 완료 필요
|
||||
- Kei API (Opus) 안정 동작
|
||||
|
||||
### 파일
|
||||
- `src/design_director.py` (Step A 전면 재작성)
|
||||
- `src/block_search.py` (Phase 2-A에서 생성)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-D: 5단계 재검토 강화
|
||||
|
||||
### 현재 문제
|
||||
```
|
||||
IMPROVEMENT 분석에서 발견된 문제:
|
||||
- HTML을 프롬프트에 실제 전달하지 않음 (블록 데이터 양만 전달)
|
||||
- shrink action이 no-op
|
||||
- rewrite action이 no-op
|
||||
- 조정 후 재편집이 정확하지 않음
|
||||
```
|
||||
|
||||
### 구현
|
||||
```
|
||||
1. HTML 코드 요약을 프롬프트에 전달
|
||||
- 전체 HTML은 너무 크니까, 블록별 텍스트 길이 + 구조 요약
|
||||
|
||||
2. shrink action 구현
|
||||
- char_guide를 줄여서 재편집 유도
|
||||
|
||||
3. rewrite action 구현
|
||||
- 특정 블록의 텍스트를 완전히 재작성
|
||||
|
||||
4. 조정 횟수 제한
|
||||
- 무한 루프 방지: 최대 2회 재조정
|
||||
```
|
||||
|
||||
### 파일
|
||||
- `src/pipeline.py` (_review_balance, _apply_adjustments 개선)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-E: 누락 기능 구현
|
||||
|
||||
### E-1: Pillow 이미지 크기 읽기
|
||||
```
|
||||
콘텐츠에 이미지가 포함될 때:
|
||||
- Pillow로 원본 크기 확인
|
||||
- 가로/세로 비율에 따라 블록 선택 (image-full vs image-side-text)
|
||||
- 팀장에게 이미지 크기 정보 전달
|
||||
```
|
||||
- 파일: `src/design_director.py` (Step B에 이미지 정보 추가)
|
||||
|
||||
### E-2: `<details>/<summary>` 완성
|
||||
```
|
||||
현재 details-block.html은 있지만 파이프라인에서 활용 안 됨:
|
||||
- 실장이 detail_target으로 판단한 꼭지를 details-block으로 연결
|
||||
- 편집자가 summary + detail 두 버전 작성
|
||||
- 인쇄 시 자동 펼침 JavaScript
|
||||
```
|
||||
- 파일: `src/pipeline.py`, `templates/blocks/emphasis/details-block.html`
|
||||
|
||||
### E-3: 디자인 실무자 AI 조정
|
||||
```
|
||||
현재 4단계는 순수 코드(Jinja2)만.
|
||||
CLAUDE.md에는 "텍스트에 맞게 폰트/여백/박스 조정"이라고 되어있음.
|
||||
- Sonnet이 렌더링된 HTML을 보고 CSS 미세 조정 제안
|
||||
- 또는 CSS 변수를 동적으로 조정하는 코드
|
||||
```
|
||||
- 파일: `src/renderer.py` 또는 `src/pipeline.py`
|
||||
- 우선순위: 낮음 (다른 것이 더 급함)
|
||||
|
||||
---
|
||||
|
||||
## ~~Phase 2-F: 출력 확장~~ (design_agent 범위 밖)
|
||||
|
||||
**글벗에서 처리:**
|
||||
- design_agent는 HTML 생성까지만 담당
|
||||
- .astro 변환 → 글벗이 design_agent API 호출 후 HTML → .astro 래핑
|
||||
- 글벗 연동 → 글벗 쪽에서 design_agent의 `/api/generate` 호출
|
||||
|
||||
---
|
||||
|
||||
## 작업 순서 (의존 관계)
|
||||
|
||||
```
|
||||
Phase 2-A (FAISS) ─────────────────────┐
|
||||
├→ Phase 2-C (Step A: Opus+FAISS)
|
||||
Phase 2-B (SVG N개) ── 독립, 병렬 가능 │
|
||||
│
|
||||
Phase 2-D (5단계 강화) ── 독립, 병렬 가능 │
|
||||
│
|
||||
Phase 2-E (누락 기능) ── 독립, 병렬 가능 │
|
||||
│
|
||||
Phase 2-F (출력 확장) ─── 글벗에서 처리 (design_agent 범위 밖)
|
||||
```
|
||||
|
||||
### 추천 실행 순서
|
||||
```
|
||||
1순위: Phase 2-A (FAISS) — 블록 선택 정확도의 핵심
|
||||
2순위: Phase 2-B (SVG N개) — 시각화 자동화
|
||||
3순위: Phase 2-D (5단계 강화) — 결과물 품질
|
||||
4순위: Phase 2-E (누락 기능) — 완성도
|
||||
5순위: Phase 2-C (Step A: Opus) — Phase 2-A 완료 필요
|
||||
※ Phase 2-F (출력 확장) — 글벗에서 처리, design_agent 범위 밖
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 기술 스택 추가
|
||||
|
||||
| 역할 | 도구 | Phase |
|
||||
|------|------|-------|
|
||||
| 블록 검색 | FAISS + sentence-transformers | 2-A |
|
||||
| SVG 계산 | Python math (cos/sin) | 2-B |
|
||||
| Step A | Opus via Kei API + FAISS | 2-C |
|
||||
| 이미지 크기 | Pillow | 2-E |
|
||||
| .astro 출력 | Jinja2 + StarlightPage 템플릿 | 2-F |
|
||||
|
||||
---
|
||||
|
||||
## 성공 기준
|
||||
|
||||
```
|
||||
Phase 2 완료 시:
|
||||
✅ 텍스트 원고 입력 → 85점 슬라이드 HTML 자동 생성
|
||||
✅ 블록 선택이 콘텐츠에 정확히 매칭 (FAISS 검색)
|
||||
✅ 관계도/다이어그램 N개 자동 배치 (SVG)
|
||||
✅ 재검토 루프가 실질적으로 동작
|
||||
✅ Starlight에서 바로 볼 수 있는 .astro 출력
|
||||
```
|
||||
321
04. design_agent/docs/PHASE2-PROCESS.md
Normal file
@@ -0,0 +1,321 @@
|
||||
# Phase 2 실행 프로세스
|
||||
|
||||
## 절대 규칙 (모든 작업에 적용)
|
||||
|
||||
```
|
||||
🔴 단발성/하드코딩 금지 — 모든 구현은 N개, M종류에 범용 동작
|
||||
🔴 회귀 금지 — Phase 1 확정 구조(catalog 매핑, grid 분리, Kei API 우선) 되돌리지 않음
|
||||
🔴 Opus→Sonnet 대체 금지 — Kei API가 기본, Sonnet은 fallback만
|
||||
🔴 "일단 돌아가게" 금지 — 설계대로 구현하거나 설계를 먼저 변경
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 완료 자산
|
||||
|
||||
| 항목 | 수량/상태 |
|
||||
|------|----------|
|
||||
| 블록 라이브러리 | 46개 (6 카테고리) |
|
||||
| catalog.yaml | 46개 (when/not_for/slots/height_cost) |
|
||||
| BLOCK_SLOTS + _apply_defaults | 46개 동기화 |
|
||||
| SVG premium | venn-diagram 3개 고정 검증 |
|
||||
| 5단계 파이프라인 | 동작 (BF-4~10 수정) |
|
||||
| Kei API 연동 | 1단계(실장) + 3단계(편집자) |
|
||||
| grid 역할 분리 | BF-9 (코드가 grid, Sonnet은 blocks만) |
|
||||
| catalog→renderer 매핑 | mtime 캐시 (BF-10) |
|
||||
|
||||
---
|
||||
|
||||
## 실행 순서
|
||||
|
||||
```
|
||||
Phase 2-A (FAISS 블록 검색)
|
||||
↓
|
||||
Phase 2-B (SVG N개 자동 배치) ← 2-A와 병렬 가능
|
||||
↓
|
||||
Phase 2-D (5단계 재검토 강화) ← 2-A/2-B와 병렬 가능
|
||||
↓
|
||||
Phase 2-E (누락 기능: Pillow, details-block)
|
||||
↓
|
||||
Phase 2-C (Step A: Opus + FAISS) ← 2-A 완료 필수
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-A: FAISS 블록 검색 인덱스
|
||||
|
||||
### 목적
|
||||
팀장(Step B) 프롬프트에 46개 catalog 전문 대신, FAISS 검색으로 **관련 블록 5~8개만** 전달.
|
||||
|
||||
### 수정 파일
|
||||
| 파일 | 변경 | 신규/수정 |
|
||||
|------|------|---------|
|
||||
| `src/block_search.py` | FAISS 인덱스 구축 + 검색 함수 | **신규** |
|
||||
| `src/design_director.py` | `_load_catalog()` → 검색 결과로 교체 | 수정 (line 294) |
|
||||
| `data/block_index.faiss` | 인덱스 파일 | **신규** |
|
||||
| `data/block_metadata.json` | id→블록 매핑 | **신규** |
|
||||
| `pyproject.toml` | faiss-cpu, sentence-transformers 의존성 | 수정 |
|
||||
|
||||
### 기술 상세
|
||||
```
|
||||
임베딩 모델: BAAI/bge-m3 (1024차원)
|
||||
→ Kei persona에서 검증됨 (retriever.py line 49)
|
||||
→ 한국어 최적화
|
||||
|
||||
인덱스 방식: faiss.IndexFlatIP (Inner Product = 코사인 유사도)
|
||||
→ Kei와 동일 패턴 (retriever.py line 88)
|
||||
|
||||
검색 입력: 꼭지별 title + summary + layer + role
|
||||
검색 출력: 상위 8개 블록 (id + visual + when + not_for + slots)
|
||||
|
||||
fallback: FAISS 인덱스 없거나 검색 실패 시 → catalog.yaml 전문 (기존 방식)
|
||||
```
|
||||
|
||||
### 프로세스
|
||||
```
|
||||
1. scripts/build_block_index.py 실행 (1회성)
|
||||
→ catalog.yaml 읽기
|
||||
→ 각 블록의 (name + visual + when) 임베딩
|
||||
→ data/block_index.faiss + data/block_metadata.json 생성
|
||||
|
||||
2. src/block_search.py
|
||||
→ 서버 시작 시 인덱스 로드
|
||||
→ search_blocks(query, top_k=8) → 관련 블록 목록 반환
|
||||
|
||||
3. src/design_director.py 수정
|
||||
→ _load_catalog() 대신 search_blocks() 호출
|
||||
→ 꼭지별 검색 → 카테고리별 최소 1개 보장 → 프롬프트에 삽입
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
```
|
||||
design_director.py _load_catalog(): 문자열 반환 → 문자열 반환 (인터페이스 동일) ✅
|
||||
renderer.py _load_catalog_map(): 별도 함수, 영향 없음 ✅
|
||||
content_editor.py: BLOCK_SLOTS만 참조, 영향 없음 ✅
|
||||
pipeline.py: create_layout_concept() 인터페이스 동일 ✅
|
||||
```
|
||||
|
||||
### 점검
|
||||
- [ ] FAISS 실패 시 catalog 전문 fallback 동작하는가?
|
||||
- [ ] 검색 결과에 카테고리별 최소 1개 보장되는가?
|
||||
- [ ] 블록 60개로 늘어나도 인덱스 재구축만으로 동작하는가?
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-B: SVG N개 자동 배치
|
||||
|
||||
### 목적
|
||||
venn-diagram의 원 3개 고정 → N개(2~7) 자동 배치. cos/sin 수학적 계산.
|
||||
|
||||
### 수정 파일
|
||||
| 파일 | 변경 | 신규/수정 |
|
||||
|------|------|---------|
|
||||
| `src/svg_calculator.py` | 좌표 계산 함수 | **신규** |
|
||||
| `src/renderer.py` | venn-diagram 렌더링 전 좌표 전처리 | 수정 (render_multi_page 내) |
|
||||
| `templates/blocks/visuals/venn-diagram.html` | 하드코딩 좌표 → 동적 `{{ item.cx }}` | 수정 |
|
||||
|
||||
### 기술 상세
|
||||
```
|
||||
src/svg_calculator.py:
|
||||
calc_circle_positions(n, center_x, center_y, radius) → [{cx, cy}, ...]
|
||||
→ angle = (2π × i / n) - π/2 (12시부터 시계방향)
|
||||
→ 의존성: Python math (내장)
|
||||
|
||||
calc_circle_radius(n) → int
|
||||
→ n≤3: 120, n≤5: 80, n≤7: 60
|
||||
→ 하드코딩 아님: base_radius / (1 + (n-3)*0.15) 공식
|
||||
|
||||
calc_outer_circle(n) → int
|
||||
→ 큰 원 반지름도 N에 따라 조정
|
||||
|
||||
renderer.py 수정:
|
||||
render_multi_page() 안에서 block_type == "venn-diagram" 일 때:
|
||||
1. items = block_data.get("items", [])
|
||||
2. positions = calc_circle_positions(len(items))
|
||||
3. for i, item in enumerate(items): item["cx"] = positions[i]["cx"]
|
||||
4. 나머지는 Jinja2가 처리
|
||||
|
||||
venn-diagram.html 수정:
|
||||
현재: cx="265" (하드코딩)
|
||||
변경: cx="{{ item.cx }}" (동적)
|
||||
fallback: items에 cx가 없으면 기존 3개 고정 좌표 사용
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
```
|
||||
renderer.py: render_multi_page()에 if 분기 추가 — 기존 흐름에 영향 없음 ✅
|
||||
(venn-diagram 아닌 블록은 그대로 통과)
|
||||
venn-diagram.html: Phase 1 고정 SVG → 동적으로 변경
|
||||
→ fallback(cx 없으면 기존 좌표) 필수 ✅
|
||||
pipeline.py: 변경 없음 ✅
|
||||
content_editor.py: items[].cx는 renderer에서 추가, 편집자는 모름 ✅
|
||||
```
|
||||
|
||||
### 점검
|
||||
- [ ] N=2, 3, 4, 5, 6, 7 각각 렌더링 테스트
|
||||
- [ ] items에 cx/cy가 없을 때 Phase 1 고정 SVG로 fallback
|
||||
- [ ] 원끼리 겹침 없이 배치되는가? (N=7 특히)
|
||||
- [ ] 큰 원 안에 모든 작은 원이 들어가는가?
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-D: 5단계 재검토 강화
|
||||
|
||||
### 목적
|
||||
_review_balance가 실질적으로 동작하도록 강화. shrink/rewrite 구현.
|
||||
|
||||
### 수정 파일
|
||||
| 파일 | 변경 | 신규/수정 |
|
||||
|------|------|---------|
|
||||
| `src/pipeline.py` | _review_balance 프롬프트 + _apply_adjustments 3개 action | 수정 |
|
||||
|
||||
### 기술 상세
|
||||
```
|
||||
_review_balance 개선:
|
||||
현재: 블록별 데이터 양(글자수)만 전달
|
||||
변경: 블록별 (area + type + 데이터 양 + height_cost) 전달
|
||||
+ 전체 zone 예산 대비 사용량
|
||||
|
||||
_apply_adjustments 개선:
|
||||
현재: expand만 동작 (char_guide * 1.5)
|
||||
변경:
|
||||
expand: char_guide * 1.5 (현재와 동일)
|
||||
shrink: char_guide * 0.7 (신규)
|
||||
rewrite: block["data"] 제거 → fill_content 재호출 시 재작성 (신규)
|
||||
|
||||
재조정 루프:
|
||||
MAX_ADJUSTMENTS = 2 (상수, 하드코딩 아닌 설정값)
|
||||
for attempt in range(MAX_ADJUSTMENTS): ...
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
```
|
||||
pipeline.py 내부 함수만 수정 ✅
|
||||
fill_content 재호출: Kei API 우선 (Phase 1에서 수정됨) ✅
|
||||
renderer.py: 변경 없음 ✅
|
||||
```
|
||||
|
||||
### 점검
|
||||
- [ ] expand/shrink/rewrite 3개 action 모두 동작하는가?
|
||||
- [ ] MAX_ADJUSTMENTS 초과 시 루프 종료되는가?
|
||||
- [ ] fill_content 재호출이 Kei API를 거치는가? (Sonnet 직접 아닌지)
|
||||
- [ ] rewrite 후 _apply_defaults로 빈 데이터가 처리되는가?
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-E: 누락 기능
|
||||
|
||||
### E-1: Pillow 이미지 크기
|
||||
| 파일 | 변경 |
|
||||
|------|------|
|
||||
| `src/design_director.py` | create_layout_concept() 내 이미지 크기 확인 |
|
||||
|
||||
```
|
||||
수정 위치: topics 순회할 때 content_type=="image" 확인
|
||||
→ Pillow Image.open().size로 width, height 읽기
|
||||
→ topic에 image_width, image_height, image_ratio 추가
|
||||
→ Step B 프롬프트에 이미지 크기 정보 포함
|
||||
→ 팀장이 가로형→image-full, 세로형→image-side-text 판단 가능
|
||||
|
||||
fallback: 이미지 파일 없으면 → 기본 비율 1.5 (가로형 가정)
|
||||
⚠️ 이것은 하드코딩이 아닌 "정보 부재 시 안전한 기본값"
|
||||
```
|
||||
|
||||
### E-2: details-block 연결
|
||||
| 파일 | 변경 |
|
||||
|------|------|
|
||||
| `src/design_director.py` | detail_target 꼭지를 "생략" → "details-block 배치"로 |
|
||||
| `src/content_editor.py` | detail_target 꼭지에 summary + detail 두 버전 작성 |
|
||||
|
||||
```
|
||||
현재: design_director.py에서 detail_target 꼭지를 "생략 (미구현)"으로 처리
|
||||
변경: detail_target 꼭지를 details-block으로 body/sidebar에 배치
|
||||
→ 편집자가 summary(3줄) + detail(전체) 작성
|
||||
→ renderer가 <details>/<summary>로 조립
|
||||
```
|
||||
|
||||
### 점검
|
||||
- [ ] 이미지 없는 콘텐츠에서 Pillow 에러 안 나는가?
|
||||
- [ ] detail_target 꼭지가 details-block으로 렌더링되는가?
|
||||
- [ ] <details> 접기/펼치기가 브라우저에서 동작하는가?
|
||||
- [ ] 인쇄 시 자동 펼침 JavaScript가 동작하는가?
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-C: Step A Opus+FAISS
|
||||
|
||||
### 목적
|
||||
규칙 4줄 → Opus가 FAISS 검색으로 구조/블록 선정 + 배치/크기 결정.
|
||||
|
||||
### 수정 파일
|
||||
| 파일 | 변경 | 신규/수정 |
|
||||
|------|------|---------|
|
||||
| `src/design_director.py` | select_preset() 유지 + _opus_block_selection() 추가 | 수정 |
|
||||
|
||||
### 기술 상세
|
||||
```
|
||||
현재 흐름:
|
||||
Step A: select_preset() → 규칙 기반 (코드)
|
||||
Step B: Sonnet → 블록 매핑
|
||||
|
||||
Phase 2 흐름:
|
||||
Step A-1: select_preset() → 프리셋 선택 (유지, 안정적)
|
||||
Step A-2: _opus_block_selection() → Kei API(Opus)로 블록 후보 선정
|
||||
입력: 꼭지 분석 + FAISS 검색 결과
|
||||
출력: 각 꼭지에 추천 블록 + 배치 방향 + 크기 가이드
|
||||
Step B: Sonnet → Opus 추천 기반으로 최종 매핑 + 글자수 가이드
|
||||
|
||||
핵심: Opus 호출은 반드시 Kei API 경유
|
||||
→ kei_client.py의 _call_kei_api() 패턴 재사용
|
||||
→ anthropic.AsyncAnthropic 직접 호출 절대 금지
|
||||
```
|
||||
|
||||
### 의존성
|
||||
```
|
||||
Phase 2-A 완료 필수 (FAISS 인덱스 + search_blocks 함수)
|
||||
Kei API(localhost:8000) 안정 동작 필요
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
```
|
||||
select_preset(): 유지 (삭제하지 않음) ✅
|
||||
create_layout_concept(): Step A-2 결과를 Step B에 전달하는 구조 추가
|
||||
→ 기존 인터페이스(return {"title": ..., "pages": [...]}) 동일 ✅
|
||||
pipeline.py: create_layout_concept() 호출 방식 동일 ✅
|
||||
```
|
||||
|
||||
### 점검
|
||||
- [ ] Opus 호출이 Kei API를 거치는가? (`grep "AsyncAnthropic" → fallback만`)
|
||||
- [ ] Kei API 실패 시 현재 방식(규칙+Sonnet)으로 fallback
|
||||
- [ ] FAISS 검색 결과가 Opus에게 전달되는가?
|
||||
- [ ] select_preset()이 삭제되지 않았는가? (안정적 규칙은 유지)
|
||||
|
||||
---
|
||||
|
||||
## 산출물 체크리스트
|
||||
|
||||
### 코드 파일
|
||||
```
|
||||
신규:
|
||||
src/block_search.py ← 2-A
|
||||
src/svg_calculator.py ← 2-B
|
||||
scripts/build_block_index.py ← 2-A
|
||||
data/block_index.faiss ← 2-A
|
||||
data/block_metadata.json ← 2-A
|
||||
|
||||
수정:
|
||||
src/design_director.py ← 2-A, 2-C, 2-E
|
||||
src/renderer.py ← 2-B
|
||||
src/pipeline.py ← 2-D, 2-E
|
||||
templates/blocks/visuals/venn-diagram.html ← 2-B
|
||||
pyproject.toml ← 2-A (의존성)
|
||||
```
|
||||
|
||||
### 문서
|
||||
```
|
||||
docs/PHASE2-PLAN.md ← 완료
|
||||
docs/PHASE2-PROCESS.md ← 이 파일
|
||||
docs/PHASE2-TECH-REVIEW.md ← 완료
|
||||
PLAN.md ← Phase 2 태스크 추가 필요
|
||||
PROGRESS.md ← Phase 2 진행 상황 추적
|
||||
```
|
||||
396
04. design_agent/docs/PHASE2-TECH-REVIEW.md
Normal file
@@ -0,0 +1,396 @@
|
||||
# Phase 2 기술 검토 보고서
|
||||
|
||||
각 항목별로 **정확한 구현 방법, 기존 코드 충돌 여부, 회귀 위험, 대충 처리 위험**을 검토한다.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-A: FAISS 블록 검색
|
||||
|
||||
### 현재 코드 상태
|
||||
```
|
||||
design_director.py line 184~188: _load_catalog()
|
||||
→ catalog.yaml 전문을 문자열로 읽어서 프롬프트에 통째로 넣음
|
||||
→ 46개 블록 전체 설명 = 약 8,000~10,000 토큰
|
||||
|
||||
design_director.py line 294: catalog_text = _load_catalog()
|
||||
design_director.py line 322: catalog=catalog_text # 프롬프트에 삽입
|
||||
```
|
||||
|
||||
### 정확한 구현 방법
|
||||
|
||||
**1. 임베딩 모델 선택**
|
||||
```
|
||||
Kei persona가 사용하는 모델: BAAI/bge-m3 (1024차원)
|
||||
위치: D:\ad-hoc\kei\persona_agent\backend\llm\retriever.py line 49
|
||||
|
||||
design_agent에서도 동일 모델 사용:
|
||||
→ 한국어 지원 ✅
|
||||
→ Kei에서 검증됨 ✅
|
||||
→ 1024차원으로 46개 벡터 = 약 184KB (가벼움)
|
||||
```
|
||||
|
||||
**2. 인덱스 구축 (1회성, 오프라인)**
|
||||
```python
|
||||
# src/block_search.py (신규 파일)
|
||||
import faiss
|
||||
import yaml
|
||||
from sentence_transformers import SentenceTransformer
|
||||
|
||||
def build_block_index():
|
||||
# 1. catalog.yaml 로드
|
||||
with open("templates/catalog.yaml") as f:
|
||||
catalog = yaml.safe_load(f)
|
||||
|
||||
# 2. 각 블록의 검색용 텍스트 생성
|
||||
texts = []
|
||||
ids = []
|
||||
for block in catalog["blocks"]:
|
||||
text = f"{block['name']}. {block['visual']}. {block['when']}"
|
||||
texts.append(text)
|
||||
ids.append(block["id"])
|
||||
|
||||
# 3. 임베딩
|
||||
model = SentenceTransformer("BAAI/bge-m3")
|
||||
embeddings = model.encode(texts, normalize_embeddings=True)
|
||||
|
||||
# 4. FAISS 인덱스 생성
|
||||
dim = embeddings.shape[1]
|
||||
index = faiss.IndexFlatIP(dim) # Inner Product (코사인 유사도)
|
||||
index.add(embeddings)
|
||||
|
||||
# 5. 저장
|
||||
faiss.write_index(index, "data/block_index.faiss")
|
||||
# ids 매핑도 저장
|
||||
```
|
||||
|
||||
**3. 검색 (런타임, 매 요청)**
|
||||
```python
|
||||
def search_blocks(query: str, top_k: int = 8) -> list[dict]:
|
||||
"""콘텐츠 꼭지 설명으로 적합한 블록 검색"""
|
||||
embedding = model.encode([query], normalize_embeddings=True)
|
||||
scores, indices = index.search(embedding, top_k)
|
||||
return [catalog_blocks[i] for i in indices[0]]
|
||||
```
|
||||
|
||||
**4. design_director.py 수정 지점**
|
||||
```
|
||||
현재 line 294: catalog_text = _load_catalog() # 전문
|
||||
변경: catalog_text = search_blocks(topics_summary, top_k=8) # 관련 8개만
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
|
||||
| 파일 | 영향 | 충돌? |
|
||||
|------|------|-------|
|
||||
| design_director.py | _load_catalog() 반환값이 문자열 → 문자열(검색결과) | ❌ (인터페이스 동일) |
|
||||
| pipeline.py | 호출하지 않음 | ❌ |
|
||||
| renderer.py | _load_catalog_map()은 별도 함수 (경로 매핑용) | ❌ (다른 함수) |
|
||||
| content_editor.py | BLOCK_SLOTS만 참조 | ❌ |
|
||||
|
||||
### 회귀 위험
|
||||
- _load_catalog()를 교체하므로, 검색이 실패하면 catalog 전문을 fallback으로 넘겨야 함
|
||||
- FAISS 인덱스 파일이 없으면 기존 방식(전문)으로 동작해야 함
|
||||
|
||||
### 대충 처리 위험
|
||||
- ⚠️ "검색 결과 8개만 넣으면 되지" → 검색 품질이 낮으면 적합한 블록이 빠질 수 있음
|
||||
- 대응: 검색 결과 + 카테고리별 최소 1개 보장 (8개 중 카테고리 커버 확인)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-B: SVG N개 자동 배치
|
||||
|
||||
### 현재 코드 상태
|
||||
```
|
||||
templates/blocks/visuals/venn-diagram.html:
|
||||
→ 3개 원 좌표가 하드코딩 (cx="265" cy="300", cx="370" cy="230", cx="365" cy="355")
|
||||
→ items[0], items[1], items[2]로 직접 인덱싱
|
||||
|
||||
renderer.py:
|
||||
→ render_standalone_block()에서 block_data를 Jinja2에 **kwargs로 전달
|
||||
→ 별도 전처리 없음
|
||||
```
|
||||
|
||||
### 정확한 구현 방법
|
||||
|
||||
**1. 좌표 계산 함수 (신규)**
|
||||
```python
|
||||
# src/svg_calculator.py (신규 파일)
|
||||
import math
|
||||
|
||||
def calc_circle_positions(
|
||||
n: int,
|
||||
center_x: float = 300,
|
||||
center_y: float = 300,
|
||||
radius: float = 120,
|
||||
) -> list[dict]:
|
||||
"""N개 원소를 원형으로 배치. 12시부터 시계방향."""
|
||||
positions = []
|
||||
for i in range(n):
|
||||
angle = (2 * math.pi * i / n) - math.pi / 2
|
||||
positions.append({
|
||||
"cx": round(center_x + radius * math.cos(angle), 1),
|
||||
"cy": round(center_y + radius * math.sin(angle), 1),
|
||||
})
|
||||
return positions
|
||||
|
||||
def calc_circle_radius(n: int, base_radius: int = 120) -> int:
|
||||
"""N에 따라 작은 원 크기 자동 조정."""
|
||||
if n <= 3: return base_radius
|
||||
if n <= 5: return int(base_radius * 0.7)
|
||||
return int(base_radius * 0.5)
|
||||
```
|
||||
|
||||
**2. renderer.py 수정 지점**
|
||||
```python
|
||||
# render_multi_page() 또는 render_slide() 안에서:
|
||||
if block_type in ("venn-diagram", "relationship"):
|
||||
items = block_data.get("items", [])
|
||||
if items:
|
||||
from src.svg_calculator import calc_circle_positions, calc_circle_radius
|
||||
positions = calc_circle_positions(len(items))
|
||||
small_r = calc_circle_radius(len(items))
|
||||
for i, item in enumerate(items):
|
||||
item["cx"] = positions[i]["cx"]
|
||||
item["cy"] = positions[i]["cy"]
|
||||
item["r"] = small_r
|
||||
```
|
||||
|
||||
**3. venn-diagram.html 수정**
|
||||
```
|
||||
현재: cx="265" (하드코딩)
|
||||
변경: cx="{{ items[0].cx }}" (동적)
|
||||
+ items 개수에 따라 for 루프로 생성
|
||||
+ 큰 원 크기도 N에 따라 조정
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
|
||||
| 파일 | 영향 | 충돌? |
|
||||
|------|------|-------|
|
||||
| renderer.py | block_data 전처리 추가 | ⚠️ 주의: 기존 render 흐름에 if 분기 추가 |
|
||||
| venn-diagram.html | 하드코딩 → 동적 좌표 | ⚠️ Phase 1 고정 SVG가 깨짐 → fallback 필요 |
|
||||
| pipeline.py | 변경 없음 | ❌ |
|
||||
| content_editor.py | items[].cx/cy는 편집자가 생성하지 않음 | ❌ (renderer에서 추가) |
|
||||
|
||||
### 회귀 위험
|
||||
- **venn-diagram.html 변경 시 Phase 1 고정 SVG가 깨질 수 있음**
|
||||
- 대응: items에 cx/cy가 없으면 기존 하드코딩 좌표 사용 (fallback)
|
||||
|
||||
### 대충 처리 위험
|
||||
- ⚠️ 원 크기 자동 조정을 대충 하면 7개 원이 겹침
|
||||
- 대응: N별 최적 반지름/큰원 크기 테이블 사전 정의
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-C: Step A Opus+FAISS
|
||||
|
||||
### 현재 코드 상태
|
||||
```
|
||||
design_director.py line 145~178: select_preset()
|
||||
→ 규칙 4줄: reference→sidebar, 대등비교→two-column, 고강조→hero, 나머지→single
|
||||
→ LLM 호출 없음, 코드만
|
||||
|
||||
의도: Opus가 FAISS로 적합한 구조/블록 검색 + 배치/크기 결정
|
||||
```
|
||||
|
||||
### 정확한 구현 방법
|
||||
|
||||
**1단계: select_preset()은 유지 (규칙 기반 프리셋은 안정적)**
|
||||
**2단계: Opus가 블록 후보를 검색+선정하는 함수 추가**
|
||||
|
||||
```python
|
||||
# design_director.py에 추가
|
||||
async def _opus_block_selection(
|
||||
content: str,
|
||||
analysis: dict,
|
||||
block_candidates: list[dict], # FAISS 검색 결과
|
||||
) -> list[dict]:
|
||||
"""Opus가 FAISS 후보에서 최종 블록을 선정하고 배치를 결정."""
|
||||
# Kei API를 통해 Opus 호출
|
||||
kei_url = settings.kei_api_url
|
||||
prompt = f"""
|
||||
콘텐츠 분석 결과와 블록 후보를 보고,
|
||||
각 꼭지에 가장 적합한 블록을 선택하고 배치를 결정해줘.
|
||||
후보 블록: {block_candidates}
|
||||
꼭지: {analysis['topics']}
|
||||
"""
|
||||
# Kei API 호출 (실장과 동일 패턴)
|
||||
...
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
|
||||
| 파일 | 영향 | 충돌? |
|
||||
|------|------|-------|
|
||||
| design_director.py | select_preset() 유지 + _opus_block_selection() 추가 | ❌ (추가만) |
|
||||
| kei_client.py | Kei API 호출 패턴 재사용 | ❌ (참조만) |
|
||||
| pipeline.py | create_layout_concept() 인터페이스 동일 | ❌ |
|
||||
|
||||
### 회귀 위험
|
||||
- ⚠️ Opus가 Kei API를 통해 호출되어야 하는데, **Sonnet을 직접 호출하면 안 됨**
|
||||
- 대응: _call_kei_api() 패턴 그대로 복제. Anthropic 직접 호출 금지.
|
||||
- ⚠️ Kei API 실패 시 fallback = 현재 규칙 기반 방식 (select_preset + Sonnet Step B)
|
||||
|
||||
### 대충 처리 위험
|
||||
- ⚠️ "Opus 대신 Sonnet 직접 호출" → **절대 금지**. 3단계에서 이미 이 실수 했음.
|
||||
- ⚠️ FAISS 없이 catalog 전문 넣기 → Phase 2-A가 선행 안 되면 의미 없음
|
||||
- 대응: Phase 2-A 완료 후에만 시작
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-D: 5단계 재검토 강화
|
||||
|
||||
### 현재 코드 상태
|
||||
```
|
||||
pipeline.py line 102~161: _review_balance()
|
||||
→ Sonnet에게 블록별 데이터 양(글자수)만 전달
|
||||
→ HTML 자체는 전달하지 않음
|
||||
→ shrink/rewrite action이 실질적으로 no-op
|
||||
|
||||
pipeline.py line 164~193: _apply_adjustments()
|
||||
→ expand만 동작 (char_guide * 1.5)
|
||||
→ shrink: 조건 매칭 안 됨 (expand만 if 처리)
|
||||
→ rewrite: 아예 동작 없음
|
||||
```
|
||||
|
||||
### 정확한 구현 방법
|
||||
|
||||
**1. _review_balance 프롬프트 개선**
|
||||
```python
|
||||
# 현재: 블록별 데이터 양만
|
||||
# 변경: 블록별 텍스트 길이 + 블록 타입 + zone + height_cost
|
||||
block_summary = []
|
||||
for block in blocks:
|
||||
data_len = len(json.dumps(block.get("data", {}), ensure_ascii=False))
|
||||
block_summary.append(
|
||||
f" {block['area']}/{block['type']}: "
|
||||
f"데이터 {data_len}자, height_cost={block.get('height_cost', '?')}"
|
||||
)
|
||||
```
|
||||
|
||||
**2. shrink/rewrite 구현**
|
||||
```python
|
||||
# _apply_adjustments 수정
|
||||
for adj in adjustments:
|
||||
action = adj.get("action", "")
|
||||
if action == "expand":
|
||||
# 현재 동작: char_guide * 1.5
|
||||
...
|
||||
elif action == "shrink":
|
||||
# 신규: char_guide * 0.7
|
||||
for key in block.get("char_guide", {}):
|
||||
block["char_guide"][key] = int(block["char_guide"][key] * 0.7)
|
||||
elif action == "rewrite":
|
||||
# 신규: data를 비우고 재편집 유도
|
||||
block.pop("data", None)
|
||||
```
|
||||
|
||||
**3. 재조정 횟수 제한**
|
||||
```python
|
||||
MAX_ADJUSTMENTS = 2
|
||||
for attempt in range(MAX_ADJUSTMENTS):
|
||||
review = await _review_balance(...)
|
||||
if not review or not review.get("needs_adjustment"):
|
||||
break
|
||||
layout_concept = await _apply_adjustments(...)
|
||||
html = render_slide(layout_concept)
|
||||
```
|
||||
|
||||
### 충돌 검토
|
||||
|
||||
| 파일 | 영향 | 충돌? |
|
||||
|------|------|-------|
|
||||
| pipeline.py | _review_balance, _apply_adjustments 수정 | ❌ (내부 함수만) |
|
||||
| content_editor.py | fill_content() 재호출됨 | ⚠️ data가 비워진 블록 → _apply_defaults로 fallback |
|
||||
| renderer.py | 변경 없음 | ❌ |
|
||||
|
||||
### 회귀 위험
|
||||
- ⚠️ 재조정 루프가 무한 반복되면 API 비용 폭증
|
||||
- 대응: MAX_ADJUSTMENTS = 2로 하드 제한
|
||||
- ⚠️ fill_content 재호출 시 Kei API가 아닌 Sonnet으로 빠질 수 있음
|
||||
- 대응: fill_content는 이미 Kei API 1순위로 수정됨 ✅
|
||||
|
||||
---
|
||||
|
||||
## Phase 2-E: 누락 기능
|
||||
|
||||
### E-1: Pillow 이미지 크기
|
||||
|
||||
**수정 지점:** design_director.py create_layout_concept() 내부
|
||||
```python
|
||||
# 콘텐츠에 이미지 경로가 있으면 크기 확인
|
||||
from PIL import Image
|
||||
for topic in analysis.get("topics", []):
|
||||
if topic.get("content_type") == "image":
|
||||
img_path = topic.get("image_path")
|
||||
if img_path and Path(img_path).exists():
|
||||
w, h = Image.open(img_path).size
|
||||
topic["image_width"] = w
|
||||
topic["image_height"] = h
|
||||
topic["image_ratio"] = w / h # >1.2 가로, <0.8 세로
|
||||
```
|
||||
|
||||
**충돌:** 없음 (analysis dict에 필드 추가만)
|
||||
**회귀:** 없음 (이미지가 없으면 기존 흐름 그대로)
|
||||
|
||||
### E-2: details-block 연결
|
||||
|
||||
**수정 지점:** pipeline.py generate_slide() 내부
|
||||
```python
|
||||
# 실장이 detail_target=True로 판단한 꼭지를 details-block으로 변환
|
||||
# 현재 "생략"으로 처리 → details-block으로 연결
|
||||
```
|
||||
|
||||
**충돌:** design_director.py에서 detail_target 꼭지를 "생략"으로 처리 중 → 이것을 "details-block으로 배치"로 변경 필요
|
||||
**회귀:** detail_target 로직이 변경되므로 기존 테스트 영향
|
||||
|
||||
---
|
||||
|
||||
## 전체 충돌 매트릭스
|
||||
|
||||
```
|
||||
director editor renderer pipeline kei_client config
|
||||
2-A FAISS 수정 - - - - -
|
||||
2-B SVG - - 수정 - - -
|
||||
2-C Opus 수정 - - - 참조 -
|
||||
2-D 재검토 - 호출 - 수정 - -
|
||||
2-E Pillow 수정 - - 수정 - -
|
||||
```
|
||||
|
||||
**동시 수정 파일이 겹치는 경우:**
|
||||
- design_director.py: 2-A + 2-C + 2-E → **순서대로 진행 (2-A 먼저)**
|
||||
- pipeline.py: 2-D + 2-E → **독립적 함수라 병렬 가능**
|
||||
|
||||
---
|
||||
|
||||
## 절대 규칙 (모든 Phase 2 작업에 적용)
|
||||
|
||||
### 🔴 절대 금지
|
||||
1. **단발성/하드코딩 금지** — 특정 상황만 해결하는 if문, 매직넘버, 고정값 절대 금지. 모든 구현은 N개, M종류에 범용으로 동작해야 한다.
|
||||
2. **회귀 금지** — Phase 1에서 확정한 구조(catalog 매핑, 카테고리 경로, BF-9 grid 분리, Kei API 우선)를 절대 되돌리지 않는다.
|
||||
3. **Opus 대신 Sonnet 직접 호출 금지** — Kei API가 필요한 곳에 anthropic.AsyncAnthropic 직접 호출로 대체하지 않는다. fallback은 fallback이지 기본 경로가 아니다.
|
||||
4. **"일단 돌아가게" 금지** — 동작하지만 원래 설계와 다른 구현은 기술 부채다. 설계대로 구현하거나 설계를 먼저 변경한다.
|
||||
|
||||
### 자가 점검 질문 (구현 전 반드시 확인)
|
||||
- [ ] 이 코드가 블록 100개가 되어도 동작하는가?
|
||||
- [ ] 이 코드가 원소 7개가 되어도 동작하는가?
|
||||
- [ ] 이 코드에 하드코딩된 값이 있는가? 있다면 설정/계산으로 대체 가능한가?
|
||||
- [ ] Phase 1에서 확정한 인터페이스(catalog 매핑, grid 프리셋 분리)를 변경하는가?
|
||||
- [ ] Kei API가 아닌 Sonnet을 직접 호출하는 코드가 있는가? (fallback 제외)
|
||||
- [ ] 이 수정이 다른 모듈의 기존 동작을 깨뜨리는가?
|
||||
|
||||
---
|
||||
|
||||
## "대충 처리" 방지 체크리스트
|
||||
|
||||
| # | 위험 | 방지책 | 점검 방법 |
|
||||
|---|------|-------|----------|
|
||||
| 1 | Opus 대신 Sonnet 직접 호출 | Kei API 패턴만 사용 | `grep "AsyncAnthropic" src/*.py` → fallback 위치만 허용 |
|
||||
| 2 | FAISS 없이 catalog 전문 유지 | _load_catalog() 교체 | FAISS 실패 시에만 fallback, 기본은 검색 |
|
||||
| 3 | SVG 좌표를 하드코딩 | calc_circle_positions() 계산 | `grep "cx=\"[0-9]" templates/blocks/visuals/` → 0건이어야 함 |
|
||||
| 4 | 재검토 루프 무한 반복 | MAX_ADJUSTMENTS = 2 | 코드에 상수 존재 확인 |
|
||||
| 5 | shrink/rewrite 미구현 | 3개 action 모두 if 분기 | _apply_adjustments에서 action별 동작 확인 |
|
||||
| 6 | 이미지 크기 하드코딩 | Pillow로 실측 | 고정 비율(예: 1.5) 사용 금지 |
|
||||
| 7 | details-block "생략" 유지 | detail_target → details-block 배치 | design_director에서 "생략" 문자열 제거 확인 |
|
||||
| 8 | 특정 블록 수에만 동작 | N개 범용 루프 | `for i in range(n)` 패턴 확인, `items[0]` 직접 인덱싱 금지 |
|
||||
| 9 | 특정 프리셋에만 동작 | 모든 프리셋에서 테스트 | 4개 프리셋 × 테스트 콘텐츠 조합 |
|
||||
686
04. design_agent/docs/RESEARCH.md
Normal file
@@ -0,0 +1,686 @@
|
||||
# Design Agent - Technology Research Report
|
||||
|
||||
Date: 2026-03-24
|
||||
|
||||
---
|
||||
|
||||
## 1. CSS Grid for Slide Layouts
|
||||
|
||||
### 1.1 Fixed-Viewport Approach (16:9, 1280x720)
|
||||
|
||||
**Recommended technique: Fixed container + CSS transform scaling.**
|
||||
|
||||
The slide container should be authored at a fixed "normal" size (1280x720), then scaled to fit any viewport using `transform: scale()`. This is the same approach used by reveal.js, the dominant HTML presentation framework.
|
||||
|
||||
```css
|
||||
.slide {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
aspect-ratio: 16 / 9;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
```
|
||||
|
||||
For preview/embedding, wrap in a container that calculates a scale factor:
|
||||
```css
|
||||
.slide-wrapper {
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
aspect-ratio: 16 / 9;
|
||||
overflow: hidden;
|
||||
}
|
||||
.slide-wrapper > .slide {
|
||||
transform-origin: top left;
|
||||
transform: scale(var(--slide-scale, 1));
|
||||
}
|
||||
```
|
||||
|
||||
The scale factor can be computed with minimal JS: `containerWidth / 1280`.
|
||||
|
||||
**Key insight from reveal.js:** All presentations have a "normal" size at which they are authored. The framework automatically scales uniformly to fit different resolutions without changing aspect ratio or layout. Default is 960x700; for our use case, 1280x720 is the standard 16:9 HD dimension.
|
||||
|
||||
**Why this works for Design Agent:** The renderer produces HTML at exactly 1280x720. It never needs to be "responsive" -- it's a fixed-format document like a PDF page. Scaling is only for preview purposes.
|
||||
|
||||
### 1.2 Grid-Template-Areas for Block Combinations
|
||||
|
||||
`grid-template-areas` provides named regions that map directly to the block composition concept in the CLAUDE.md:
|
||||
|
||||
```css
|
||||
.layout-quote-compare-cards-conclusion {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"quote quote"
|
||||
"compare cards"
|
||||
"diagram diagram"
|
||||
"conclusion conclusion";
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: auto 1fr auto auto;
|
||||
gap: var(--spacing-block);
|
||||
padding: var(--spacing-page);
|
||||
}
|
||||
```
|
||||
|
||||
**Best practice:** Define each layout as a separate CSS class with its own `grid-template-areas`. The Sonnet agent selects which layout class to apply based on the block combination it decides. This keeps the renderer deterministic -- it just applies the class.
|
||||
|
||||
**Reusability:** CSS variables allow the same grid template to adapt:
|
||||
- Column count: `grid-template-columns: repeat(var(--cols, 3), 1fr)`
|
||||
- Gap: `gap: var(--spacing-block)`
|
||||
- Row sizing: `grid-template-rows` can mix `auto` (content-sized) and `1fr` (fill remaining)
|
||||
|
||||
### 1.3 Design Tokens
|
||||
|
||||
**Naming convention:** `--{category}-{property}-{variant}`
|
||||
|
||||
The CLAUDE.md already defines a good token set. The industry standard approach (from EightShapes, Nord Design System) uses kebab-case with semantic naming:
|
||||
|
||||
```
|
||||
--color-primary, --color-accent, --color-neutral
|
||||
--font-title, --font-subtitle, --font-body, --font-caption
|
||||
--spacing-page, --spacing-block, --spacing-inner
|
||||
--radius, --border-width, --accent-border
|
||||
```
|
||||
|
||||
This matches what's already in the project's CLAUDE.md. No changes needed.
|
||||
|
||||
**For slide-specific tokens, add:**
|
||||
```css
|
||||
--slide-width: 1280px;
|
||||
--slide-height: 720px;
|
||||
--slide-aspect: 16 / 9;
|
||||
```
|
||||
|
||||
### 1.4 Overflow Handling in Fixed Pages
|
||||
|
||||
Three techniques for ensuring content fits within fixed dimensions:
|
||||
|
||||
1. **Single-line truncation:**
|
||||
```css
|
||||
.truncate {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
```
|
||||
|
||||
2. **Multi-line truncation (line clamping):**
|
||||
```css
|
||||
.line-clamp-3 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
```
|
||||
|
||||
3. **Container overflow hidden (safety net):**
|
||||
```css
|
||||
.block { overflow: hidden; }
|
||||
.slide { overflow: hidden; }
|
||||
```
|
||||
|
||||
**Korean-specific consideration:** `word-break: keep-all` affects how text wraps, which impacts line count. Content fitting calculations must account for this. The Sonnet agent should be instructed with character limits per slot, not word limits.
|
||||
|
||||
---
|
||||
|
||||
## 2. Content-to-Layout Classification
|
||||
|
||||
### 2.1 How to Prompt an LLM for Reliable Classification
|
||||
|
||||
**Claude Structured Output (recommended):**
|
||||
|
||||
Anthropic launched Structured Outputs in November 2025, supporting Claude Sonnet 4.5 and Opus 4.1. This guarantees JSON schema conformance at the token generation level -- the model literally cannot produce tokens that violate the schema.
|
||||
|
||||
Implementation:
|
||||
```python
|
||||
from pydantic import BaseModel, Field
|
||||
from anthropic import Anthropic
|
||||
|
||||
class ContentBlock(BaseModel):
|
||||
content_type: str = Field(description="One of: comparison, process, relationship, big-number, definition, list, timeline, emphasis, problem")
|
||||
evidence: str = Field(description="Which text patterns led to this classification")
|
||||
suggested_block: str = Field(description="Block type from the template library")
|
||||
|
||||
class ContentAnalysis(BaseModel):
|
||||
blocks: list[ContentBlock]
|
||||
layout_direction: str = Field(description="How blocks should be arranged on the page")
|
||||
primary_message: str = Field(description="The single key takeaway for this slide")
|
||||
```
|
||||
|
||||
**Reliability strategies:**
|
||||
- Set temperature to 0.0-0.1 for classification tasks (reduces format drift)
|
||||
- Use the `output_format` parameter with JSON schema (not just prompting)
|
||||
- Include one perfect example in the system prompt
|
||||
- Add explicit validation instructions
|
||||
|
||||
### 2.2 Information Type Taxonomy for Presentations
|
||||
|
||||
Based on research from SlideSpeak (16 layout types), PPTAgent (EMNLP 2025), Beautiful.ai (300 templates), and Dr. Andrew Abela's Chart Chooser:
|
||||
|
||||
**The CLAUDE.md already defines 9 excellent content types.** Here is how they map to industry precedent:
|
||||
|
||||
| CLAUDE.md Type | SlideSpeak Equivalent | PPTAgent Category | Common Slide Type |
|
||||
|---|---|---|---|
|
||||
| comparison | SS_ITEMS_*_A/B | Content slide (multi-column) | Comparison slide |
|
||||
| process | SS_STEPS_3/4/5 | Content slide (sequential) | Process/workflow slide |
|
||||
| relationship | (custom) | Content slide (diagram) | Venn/tree diagram slide |
|
||||
| big-number | SS_BIGNUMBER_1/3 | Content slide (metric) | KPI/statistics slide |
|
||||
| definition (card-grid) | SS_ITEMS_3/4/5/6 | Content slide (grid) | Definition/feature slide |
|
||||
| list | SS_CONTENT | Content slide (list) | Bullet point slide |
|
||||
| timeline | (custom) | Content slide (sequential) | Timeline slide |
|
||||
| emphasis (quote-block) | (custom) | Structural slide | Quote/callout slide |
|
||||
| problem | (custom) | Structural slide | Problem statement slide |
|
||||
|
||||
**Additional types to consider (from industry):**
|
||||
- **SWOT** (SlideSpeak has SS_SWOT) -- 4-quadrant grid
|
||||
- **Matrix/Table** (already covered by comparison-table)
|
||||
- **Cover/Title** -- for when the content is just a single title/subtitle
|
||||
|
||||
### 2.3 Structured Output Schema for Layout Decisions
|
||||
|
||||
The PPTAgent paper (EMNLP 2025) uses a two-stage approach that aligns perfectly with the Design Agent architecture:
|
||||
|
||||
- **Stage 1 (Opus):** Analyze content, classify into functional types, extract content schemas
|
||||
- **Stage 2 (Sonnet):** Select reference layouts, fill content into slots, apply editing actions
|
||||
|
||||
PPTAgent represents all parsed outputs in JSON format for LLM compatibility. The Design Agent should do the same.
|
||||
|
||||
---
|
||||
|
||||
## 3. Slot-Based Template Systems
|
||||
|
||||
### 3.1 SlideSpeak's Named Slot System
|
||||
|
||||
SlideSpeak uses a comprehensive naming convention for template placeholders:
|
||||
|
||||
**Layout names:** SS_COVER, SS_CONTENT, SS_TABLE_OF_CONTENT, SS_BIGNUMBER_1_A, SS_BIGNUMBER_3_A, SS_ITEMS_3_A through SS_ITEMS_6_B, SS_STEPS_3 through SS_STEPS_5_ICONS, SS_SWOT
|
||||
|
||||
**Universal slot names:**
|
||||
- `SS_TITLE` -- slide title
|
||||
- `SS_SUBTITLE` -- subtitle
|
||||
- `SS_LOGO` -- logo placeholder
|
||||
- `SS_IMAGE` -- general image
|
||||
- `SS_PAGE` -- page number
|
||||
- `SS_PRESENTATION_TITLE` -- footer title
|
||||
|
||||
**Multi-item slot naming pattern:**
|
||||
- `SS_ITEM_{N}_TITLE` -- title for item N
|
||||
- `SS_ITEM_{N}_CONTENT` -- content for item N
|
||||
- `SS_ITEM_{N}_NUMBER` -- number for item N (big-number layouts)
|
||||
- `SS_ICON_{N}` -- icon for item N
|
||||
|
||||
**Key insight for Design Agent:** The `{{SLOT_NAME}}` convention in CLAUDE.md maps well. Adopt a similar systematic naming: `{{BLOCK_TITLE}}`, `{{ITEM_1_TITLE}}`, `{{ITEM_1_CONTENT}}`, etc.
|
||||
|
||||
### 3.2 Jinja2 for Template Rendering
|
||||
|
||||
Jinja2 is the recommended engine. It integrates natively with FastAPI and Python.
|
||||
|
||||
**Block inheritance for base layout:**
|
||||
```jinja2
|
||||
{# base_slide.html #}
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<link rel="stylesheet" href="design-tokens.css">
|
||||
<style>{% block extra_style %}{% endblock %}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="slide">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
**Block-level templates:**
|
||||
```jinja2
|
||||
{# blocks/comparison.html #}
|
||||
<div class="block-comparison">
|
||||
<div class="col-left">
|
||||
<h3>{{ left_title }}</h3>
|
||||
<p>{{ left_content }}</p>
|
||||
</div>
|
||||
<div class="col-right">
|
||||
<h3>{{ right_title }}</h3>
|
||||
<p>{{ right_content }}</p>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Composition via includes:**
|
||||
```jinja2
|
||||
{# Generated by renderer based on Sonnet's layout decision #}
|
||||
{% extends "base_slide.html" %}
|
||||
{% block content %}
|
||||
{% include "blocks/quote-block.html" %}
|
||||
<div class="grid-row-2">
|
||||
{% include "blocks/comparison.html" %}
|
||||
{% include "blocks/card-grid.html" %}
|
||||
</div>
|
||||
{% include "blocks/conclusion-bar.html" %}
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
### 3.3 Slot Constraints
|
||||
|
||||
Each slot should have defined constraints that Sonnet respects:
|
||||
|
||||
| Slot Type | Max Characters (Korean) | Required | Notes |
|
||||
|---|---|---|---|
|
||||
| slide_title | 30 | Yes | Single line |
|
||||
| block_title | 20 | Yes | Single line |
|
||||
| item_title | 15 | Yes | Single line |
|
||||
| item_content | 80 | No | 2-3 lines |
|
||||
| quote_text | 120 | Yes | 3-4 lines |
|
||||
| big_number | 8 | Yes | Number + unit |
|
||||
| conclusion | 60 | Yes | Single line |
|
||||
| caption | 40 | No | Single line |
|
||||
|
||||
**Korean consideration:** Korean characters are roughly 2x the width of Latin characters at the same font size. Character limits should be specified in characters, not words, since Korean doesn't use spaces the same way as English.
|
||||
|
||||
---
|
||||
|
||||
## 4. HTML to PDF Conversion
|
||||
|
||||
### 4.1 Playwright (Recommended)
|
||||
|
||||
**Why Playwright over Puppeteer:**
|
||||
- Native Python SDK (no Node.js dependency for a Python project)
|
||||
- Multiple browser support (Chromium, Firefox, WebKit), though PDF only works in Chromium
|
||||
- Growing community, active maintenance, better CI/CD integration
|
||||
- Full CSS Grid support via real Chromium rendering engine
|
||||
|
||||
**Python implementation:**
|
||||
```python
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
async def html_to_pdf(html_content: str, output_path: str) -> None:
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch()
|
||||
page = await browser.new_page()
|
||||
await page.set_content(html_content, wait_until="networkidle")
|
||||
await page.pdf(
|
||||
path=output_path,
|
||||
width="1280px",
|
||||
height="720px",
|
||||
print_background=True,
|
||||
prefer_css_page_size=True,
|
||||
)
|
||||
await browser.close()
|
||||
```
|
||||
|
||||
**Key options:**
|
||||
- `print_background=True` -- required for background colors/images
|
||||
- `prefer_css_page_size=True` -- lets CSS `@page` rules control dimensions
|
||||
- `width`/`height` -- custom page dimensions (accepts px, in, mm, cm units)
|
||||
|
||||
### 4.2 Print CSS for Slide Format
|
||||
|
||||
```css
|
||||
@media print {
|
||||
@page {
|
||||
size: 1280px 720px;
|
||||
margin: 0;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
.slide {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
page-break-after: always;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**`-webkit-print-color-adjust: exact`** is critical -- without it, background colors and images may be stripped in PDF output.
|
||||
|
||||
### 4.3 Quality Comparison
|
||||
|
||||
Both Puppeteer and Playwright use Chromium's print-to-PDF engine, so output quality is identical. The choice comes down to:
|
||||
|
||||
| Factor | Playwright | Puppeteer |
|
||||
|---|---|---|
|
||||
| Language | Python, JS, C#, Java | JS/Node.js only |
|
||||
| PDF engine | Chromium only | Chromium only |
|
||||
| CSS Grid quality | Excellent (Chromium) | Excellent (Chromium) |
|
||||
| Korean font rendering | Excellent | Excellent |
|
||||
| Install size | ~400MB (browser binary) | ~300MB |
|
||||
| API ergonomics | Better async patterns | More established |
|
||||
|
||||
**Recommendation:** Playwright, because the Design Agent backend is Python. No need to bridge to Node.js.
|
||||
|
||||
### 4.4 Korean-Specific Considerations
|
||||
|
||||
- Fonts must be available on the server. Self-host Pretendard/Noto Sans KR WOFF2 files or use CDN.
|
||||
- Set `lang="ko"` on the HTML element for proper line-breaking algorithms.
|
||||
- Ensure `@font-face` declarations are loaded before PDF generation (`wait_until="networkidle"`).
|
||||
|
||||
---
|
||||
|
||||
## 5. Pure CSS Diagrams
|
||||
|
||||
### 5.1 Venn Diagrams (Pure CSS)
|
||||
|
||||
**Technique:** Overlapping circles with opacity and negative margins.
|
||||
|
||||
```css
|
||||
.venn-container { display: flex; align-items: center; justify-content: center; }
|
||||
.venn-circle {
|
||||
width: 200px; height: 200px;
|
||||
border-radius: 50%;
|
||||
opacity: 0.7;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.venn-a { background: var(--color-accent); }
|
||||
.venn-b { background: var(--color-neutral); margin-left: -60px; }
|
||||
```
|
||||
|
||||
**Advanced approach (Adrian Roselli):** CSS Grid + `shape-outside` for text wrapping within overlapping regions. More complex but better for text-heavy Venn diagrams.
|
||||
|
||||
**Limitation:** Pure CSS Venn diagrams work well for 2-3 circles. Beyond that, SVG is more practical.
|
||||
|
||||
### 5.2 Flowcharts / Process Arrows (Pure CSS)
|
||||
|
||||
**Technique:** Flexbox/Grid layout + pseudo-elements for arrows.
|
||||
|
||||
```css
|
||||
.process-steps { display: flex; align-items: center; gap: 0; }
|
||||
.process-step {
|
||||
background: var(--color-bg-subtle);
|
||||
padding: var(--spacing-inner);
|
||||
position: relative;
|
||||
flex: 1;
|
||||
}
|
||||
.process-step + .process-step::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -12px; top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border: 8px solid transparent;
|
||||
border-left-color: var(--color-accent);
|
||||
}
|
||||
```
|
||||
|
||||
**CSS Anchor Positioning (2025-2026):** A new CSS feature for connecting elements with lines. Supported in Chrome 125+, Safari 26+, not yet in Firefox. Since we target Chromium (for PDF generation), this is usable but adds complexity. For the Design Agent, pseudo-element arrows are simpler and more reliable.
|
||||
|
||||
### 5.3 Tree/Hierarchy Diagrams (Pure CSS)
|
||||
|
||||
**Technique:** Nested `<ul>/<li>` + pseudo-elements for connector lines.
|
||||
|
||||
Libraries:
|
||||
- **Treeflex** (https://dumptyd.github.io/treeflex/) -- CSS-only library for hierarchy trees, no JS
|
||||
- Custom implementation using `border-left` on `<li>` for vertical lines, `::before` for horizontal connectors, `::after` for node circles
|
||||
|
||||
### 5.4 When to Use SVG Instead
|
||||
|
||||
| Use Case | CSS | SVG | Recommendation |
|
||||
|---|---|---|---|
|
||||
| Venn (2-3 circles) | Good | Better | CSS for simplicity |
|
||||
| Process arrows (linear) | Excellent | Overkill | CSS |
|
||||
| Tree (2-3 levels) | Good | Better | CSS (Treeflex) |
|
||||
| Complex flowchart (branches) | Difficult | Much better | SVG |
|
||||
| Curved connectors | Impossible | Easy | SVG |
|
||||
| Data-driven charts | Impossible | Required | SVG |
|
||||
| Accessible diagrams | Poor | Excellent | SVG |
|
||||
|
||||
**Recommendation for Design Agent:** Use pure CSS for simple diagrams (process arrows, 2-circle Venn, basic tree). Generate inline SVG for anything more complex. Since the renderer produces static HTML for PDF export, there's no JS concern.
|
||||
|
||||
**Accessibility note:** SVG has built-in accessibility elements (`<title>`, `<desc>`, `aria-*`). For the Design Agent's output (primarily visual slides for PDF), this is less critical but good practice.
|
||||
|
||||
---
|
||||
|
||||
## 6. Korean Typography in CSS
|
||||
|
||||
### 6.1 Font Selection
|
||||
|
||||
**Primary recommendation: Pretendard**
|
||||
|
||||
- Modern system-ui replacement font designed for cross-platform use
|
||||
- Built on Inter (Latin) + Source Han Sans (CJK) + M PLUS 1p
|
||||
- 9 weights + variable font support
|
||||
- Dynamic subset via CDN (Google Fonts-style loading for Korean)
|
||||
- Most popular Korean web font according to HTTP Archive 2024
|
||||
|
||||
**CDN options:**
|
||||
```css
|
||||
/* Dynamic subset (recommended for web) */
|
||||
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');
|
||||
|
||||
/* Or from cdnjs */
|
||||
@import url('https://cdnjs.cloudflare.com/ajax/libs/pretendard/1.3.9/variable/pretendardvariable-dynamic-subset.min.css');
|
||||
```
|
||||
|
||||
**For PDF generation (self-hosted):**
|
||||
Download WOFF2 files and serve locally to avoid CDN dependency during headless browser PDF generation.
|
||||
|
||||
**Fallback stack:**
|
||||
```css
|
||||
font-family: 'Pretendard Variable', 'Pretendard', -apple-system, 'Noto Sans KR',
|
||||
'Malgun Gothic', sans-serif;
|
||||
```
|
||||
|
||||
**Alternative: Noto Sans KR**
|
||||
- Google Fonts native, widest browser support
|
||||
- Available via Google Fonts CDN with automatic Korean subsetting
|
||||
- Good for when Pretendard is not available
|
||||
|
||||
### 6.2 Line-Height and Letter-Spacing
|
||||
|
||||
**W3C KLREQ (Korean Layout Requirements) recommendations:**
|
||||
|
||||
| Property | Value | Rationale |
|
||||
|---|---|---|
|
||||
| `line-height` | 1.6-1.8 | CJK text needs ~1.7 (vs 1.2-1.5 for Latin) due to higher information density per character |
|
||||
| `letter-spacing` | 0 to -0.02em | Korean text looks best with tight or default spacing. Avoid positive letter-spacing. |
|
||||
| `word-spacing` | normal | Korean uses spaces between words (unlike Japanese/Chinese) |
|
||||
|
||||
**For slides specifically:**
|
||||
```css
|
||||
body {
|
||||
line-height: 1.7;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
line-height: 1.3;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 Word-Break Rules
|
||||
|
||||
```css
|
||||
/* Korean text: keep syllable blocks together */
|
||||
body {
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
```
|
||||
|
||||
**`word-break: keep-all`** prevents line breaks within Korean syllable blocks (e.g., "한글" won't break as "한" / "글" mid-word). This is essential for readable Korean typography.
|
||||
|
||||
**`overflow-wrap: break-word`** is the safety net for extremely long strings (URLs, technical terms) that might overflow.
|
||||
|
||||
**Browser support:** All modern browsers support `keep-all` since 2016. There is ongoing W3C discussion about a potential `keep-all-hangul` value that would apply `keep-all` only to Hangul characters and `normal` to everything else.
|
||||
|
||||
### 6.4 Mixing Korean + English
|
||||
|
||||
**Key challenge:** At the same point size, Latin letters appear smaller than Korean characters.
|
||||
|
||||
**Solutions:**
|
||||
1. Use a font designed for mixed text (Pretendard handles this well, being built on Inter + Source Han Sans)
|
||||
2. Set the Latin font first in `font-family` stack, CJK font second (most CJK fonts include Latin glyphs, but their Latin is often inferior)
|
||||
3. No need for `font-size-adjust` if using Pretendard (it's designed for optical balance between scripts)
|
||||
|
||||
**Punctuation:** Korean uses proportional-width punctuation (like Latin), unlike Japanese/Chinese which use full-width. Pretendard handles this correctly.
|
||||
|
||||
### 6.5 Language Attribute
|
||||
|
||||
Always set `lang="ko"` on the HTML element:
|
||||
```html
|
||||
<html lang="ko">
|
||||
```
|
||||
This enables the browser's Korean-specific line-breaking algorithms and font selection.
|
||||
|
||||
---
|
||||
|
||||
## 7. FastAPI Integration
|
||||
|
||||
### 7.1 Serving the Design Agent
|
||||
|
||||
The Design Agent should be a FastAPI application with these endpoints:
|
||||
|
||||
| Endpoint | Method | Purpose |
|
||||
|---|---|---|
|
||||
| `/api/analyze` | POST | Step 1: Send content to Opus for classification |
|
||||
| `/api/generate` | POST | Steps 2-3: Sonnet selects + renderer produces HTML |
|
||||
| `/api/generate/stream` | GET (SSE) | Steps 1-3 with real-time progress |
|
||||
| `/api/preview/{job_id}` | GET | Return generated HTML for iframe preview |
|
||||
| `/api/download/{job_id}/pdf` | GET | Generate and return PDF |
|
||||
| `/api/download/{job_id}/html` | GET | Return HTML file |
|
||||
| `/api/templates` | GET | List available block templates |
|
||||
|
||||
### 7.2 SSE Streaming
|
||||
|
||||
FastAPI has native SSE support (added to official docs). Two library options:
|
||||
|
||||
**Option A: sse-starlette (recommended)**
|
||||
- Production-ready, W3C SSE spec compliant
|
||||
- Already used in the HWPX project
|
||||
- `pip install sse-starlette`
|
||||
|
||||
**Option B: fastapi-sse**
|
||||
- Lighter weight, built specifically for FastAPI
|
||||
- Supports sending Pydantic models as SSE events
|
||||
- `pip install fastapi-sse`
|
||||
|
||||
**Implementation:**
|
||||
```python
|
||||
from sse_starlette.sse import EventSourceResponse
|
||||
|
||||
@router.get("/api/generate/stream")
|
||||
async def stream_generation(content: str):
|
||||
async def event_generator():
|
||||
yield {"event": "step_start", "data": "analyzing"}
|
||||
# ... Opus classification
|
||||
yield {"event": "step_complete", "data": json.dumps(analysis)}
|
||||
|
||||
yield {"event": "step_start", "data": "selecting"}
|
||||
# ... Sonnet selection
|
||||
yield {"event": "step_complete", "data": json.dumps(slots)}
|
||||
|
||||
yield {"event": "step_start", "data": "rendering"}
|
||||
# ... CSS Grid rendering
|
||||
yield {"event": "complete", "data": job_id}
|
||||
|
||||
return EventSourceResponse(event_generator())
|
||||
```
|
||||
|
||||
### 7.3 File Upload
|
||||
|
||||
```python
|
||||
from fastapi import UploadFile, File
|
||||
|
||||
@router.post("/api/upload")
|
||||
async def upload_content(file: UploadFile = File(...)):
|
||||
# Read and extract text from uploaded file
|
||||
text = await extract_text(file)
|
||||
return {"text": text, "filename": file.filename}
|
||||
```
|
||||
|
||||
### 7.4 Static File Serving for Preview
|
||||
|
||||
**For development:** FastAPI's `StaticFiles` mount for serving generated HTML:
|
||||
```python
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
app.mount("/static", StaticFiles(directory="output"), name="static")
|
||||
```
|
||||
|
||||
**For production:** Serve HTML via API response body (like the HWPX project does with `<iframe srcDoc>`). This is more secure -- no direct file path exposure.
|
||||
|
||||
**Font serving:** Self-hosted Pretendard WOFF2 files should be served as static files for reliable PDF generation.
|
||||
|
||||
---
|
||||
|
||||
## Summary: Technology Stack Recommendation
|
||||
|
||||
| Component | Technology | Version | Rationale |
|
||||
|---|---|---|---|
|
||||
| LLM (Analysis) | Claude Opus via Anthropic API | Structured Outputs beta | Content classification, layout direction |
|
||||
| LLM (Selection) | Claude Sonnet via Anthropic API | Structured Outputs beta | Slot filling, content editing |
|
||||
| Template Engine | Jinja2 | >=3.1 | Native Python, FastAPI integration, block inheritance |
|
||||
| CSS Layout | CSS Grid + grid-template-areas | Native CSS | Named regions map to block composition |
|
||||
| Design Tokens | CSS Custom Properties | Native CSS | Already defined in CLAUDE.md |
|
||||
| Typography | Pretendard Variable | 1.3.9 | Best Korean web font, dynamic subset |
|
||||
| Fallback Font | Noto Sans KR | Latest | Google Fonts CDN backup |
|
||||
| PDF Generation | Playwright (Python) | >=1.40 | Native Python SDK, full CSS Grid support |
|
||||
| Web Framework | FastAPI | >=0.115 | SSE support, file upload, same as HWPX project |
|
||||
| SSE | sse-starlette | >=2.0 | Production-ready, W3C compliant |
|
||||
| CSS Diagrams | Pure CSS + inline SVG fallback | N/A | Pseudo-elements for simple, SVG for complex |
|
||||
| Slide Scaling | CSS transform: scale() | Native CSS | reveal.js-proven approach |
|
||||
| Korean Line Breaking | word-break: keep-all | Native CSS | W3C KLREQ recommendation |
|
||||
|
||||
---
|
||||
|
||||
## Key References
|
||||
|
||||
### CSS Grid & Layout
|
||||
- [CSS-Tricks Complete Guide to CSS Grid](https://css-tricks.com/complete-guide-css-grid-layout/)
|
||||
- [Smashing Magazine: Understanding CSS Grid Template Areas](https://www.smashingmagazine.com/2020/02/understanding-css-grid-template-areas/)
|
||||
- [MDN: aspect-ratio](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio)
|
||||
- [Grid by Example](https://gridbyexample.com/examples/)
|
||||
- [reveal.js Presentation Size](https://revealjs.com/presentation-size/)
|
||||
|
||||
### Design Tokens
|
||||
- [CSS-Tricks: What Are Design Tokens?](https://css-tricks.com/what-are-design-tokens/)
|
||||
- [EightShapes: Naming Tokens in Design Systems](https://medium.com/eightshapes-llc/naming-tokens-in-design-systems-9e86c7444676)
|
||||
- [FrontendTools: CSS Variables Guide](https://www.frontendtools.tech/blog/css-variables-guide-design-tokens-theming-2025)
|
||||
- [Nord Design System: Naming](https://nordhealth.design/naming/)
|
||||
|
||||
### Content Classification & Presentation AI
|
||||
- [PPTAgent (EMNLP 2025)](https://arxiv.org/abs/2501.03936)
|
||||
- [SlideSpeak Layouts & Placeholders](https://docs.slidespeak.co/basics/custom-templates/layouts-and-placeholders)
|
||||
- [SlideSpeak Template Preparation](https://docs.slidespeak.co/basics/custom-templates/preparing)
|
||||
- [SlideModel: 12 Types of Slides](https://slidemodel.com/types-of-slides/)
|
||||
- [SlideUpLift: Types of Slides](https://slideuplift.com/blog/types-of-slides/)
|
||||
- [LLM-Powered Slide Decks Comparison](https://nbrosse.github.io/posts/llm-slides/llm-slides.html)
|
||||
|
||||
### Structured Output
|
||||
- [Anthropic Structured Outputs Docs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs)
|
||||
- [PromptLayer: How JSON Schema Works for Structured Outputs](https://blog.promptlayer.com/how-json-schema-works-for-structured-outputs-and-tool-integration/)
|
||||
|
||||
### PDF Generation
|
||||
- [Playwright Python page.pdf() API](https://playwright.dev/python/docs/api/class-page)
|
||||
- [PDF Generation from HTML Comparison (2026)](https://medium.com/@coders.stop/pdf-generation-from-html-i-tested-puppeteer-playwright-and-wkhtmltopdf-so-you-dont-have-to-d14228d28c4c)
|
||||
- [Checkly: Generating PDFs with Playwright](https://www.checklyhq.com/docs/learn/playwright/generating-pdfs/)
|
||||
- [Print CSS Cheatsheet](https://www.customjs.space/blog/print-css-cheatsheet/)
|
||||
|
||||
### Pure CSS Diagrams
|
||||
- [Adrian Roselli: A CSS Venn Diagram](https://adrianroselli.com/2018/12/a-css-venn-diagram.html)
|
||||
- [CSS-Tricks: A CSS Venn Diagram](https://css-tricks.com/a-css-venn-diagram/)
|
||||
- [FreeFrontend: 17 Pure CSS Flowcharts](https://freefrontend.com/css-flowcharts/)
|
||||
- [Cory Rylan: Flow Charts with CSS Anchor Positioning](https://coryrylan.com/blog/flow-charts-with-css-anchor-positioning)
|
||||
- [Treeflex: CSS Tree Library](https://dumptyd.github.io/treeflex/)
|
||||
- [MDN: CSS Anchor Positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Anchor_positioning)
|
||||
|
||||
### Korean Typography
|
||||
- [W3C KLREQ: Requirements for Hangul Text Layout](https://www.w3.org/TR/klreq/)
|
||||
- [Pretendard GitHub](https://github.com/orioncactus/pretendard)
|
||||
- [Noto Sans KR on Google Fonts](https://fonts.google.com/noto/specimen/Noto+Sans+KR)
|
||||
- [CJK Typesetting in 2025](https://asianabsolute.co.uk/blog/cjk-typesetting-challenges-workflows-and-best-practices/)
|
||||
- [Typotheque: CJK Typesetting Principles](https://www.typotheque.com/articles/typesetting-cjk-text)
|
||||
- [CSS WG: word-break for Korean (Issue #4285)](https://github.com/w3c/csswg-drafts/issues/4285)
|
||||
|
||||
### FastAPI & SSE
|
||||
- [FastAPI SSE Tutorial](https://fastapi.tiangolo.com/tutorial/server-sent-events/)
|
||||
- [sse-starlette on PyPI](https://pypi.org/project/sse-starlette/)
|
||||
- [Real Python: FastAPI with Jinja2](https://realpython.com/fastapi-jinja2-template/)
|
||||
|
||||
### SVG vs CSS
|
||||
- [Adobe Blog: CSS vs SVG](https://blog.adobe.com/en/publish/2015/09/16/css-vs-svg-the-final-roundup)
|
||||
- [Sara Soueidan: Accessible Data Charts](https://www.sarasoueidan.com/blog/accessible-data-charts-for-khan-academy-2018-annual-report/)
|
||||
BIN
04. design_agent/docs/bg-texture-only.png
Normal file
|
After Width: | Height: | Size: 936 KiB |
219
04. design_agent/docs/block-tests/card-image.html
Normal file
@@ -0,0 +1,219 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>블록 테스트: card-image</title>
|
||||
<style>
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Pretendard Variable", "Noto Sans KR", sans-serif;
|
||||
background: #e8ecf0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
.block-container {
|
||||
width: 920px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
.block-container .block-section-title {
|
||||
margin: -20px -20px 0;
|
||||
border-radius: 8px 8px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
<!-- 이미지 카드: 상단 이미지 + 하단 텍스트 (2~4열) -->
|
||||
<!--
|
||||
📋 card-image
|
||||
─────────────────
|
||||
용도: 단계별 설명, 카테고리별 설명 (이미지가 핵심인 카드)
|
||||
슬롯: cards[] 배열 (각 카드에 image, title, title_en, items[])
|
||||
Figma 원본: 2-1_02 > Group 1171281594 (카드 3열)
|
||||
-->
|
||||
<div class="block-card-image" style="--ci-count: 3">
|
||||
|
||||
<div class="ci-card">
|
||||
|
||||
<img class="ci-img" src="figma-assets/card_img_design.png" alt="설계단계">
|
||||
|
||||
<div class="ci-body">
|
||||
<div class="ci-title" style="color: #00aaff">설계단계</div>
|
||||
<div class="ci-title-en">Design Stage</div>
|
||||
<div class="ci-divider"></div>
|
||||
<ul class="ci-list">
|
||||
|
||||
<li>고도화된 BIM 구현</li>
|
||||
|
||||
<li>최첨단 디지털트윈</li>
|
||||
|
||||
<li>시뮬레이션 분석 & 성능평가</li>
|
||||
|
||||
<li>지속가능한 인프라개발</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ci-card">
|
||||
|
||||
<img class="ci-img" src="figma-assets/card_img_construction.png" alt="시공 단계">
|
||||
|
||||
<div class="ci-body">
|
||||
<div class="ci-title" style="color: #006aff">시공 단계</div>
|
||||
<div class="ci-title-en">Construction Stage</div>
|
||||
<div class="ci-divider"></div>
|
||||
<ul class="ci-list">
|
||||
|
||||
<li>향상된 건설 계획과 공정 순서 관리</li>
|
||||
|
||||
<li>Big Room 등 환경을 통한 협업 및 조정</li>
|
||||
|
||||
<li>정확한 수량산출서와 비용 산정</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ci-card">
|
||||
|
||||
<img class="ci-img" src="figma-assets/card_img_maintenance.png" alt="유지관리 단계">
|
||||
|
||||
<div class="ci-body">
|
||||
<div class="ci-title" style="color: #004cbe">유지관리 단계</div>
|
||||
<div class="ci-title-en">Maintenance Stage</div>
|
||||
<div class="ci-divider"></div>
|
||||
<ul class="ci-list">
|
||||
|
||||
<li>자산 정보 및 데이터 관리</li>
|
||||
|
||||
<li>예측 기반 유지보수 및 생애주기 분석</li>
|
||||
|
||||
<li>효율적인 시설 운영 및 지속가능한 관리</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-image {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--ci-count, 3), 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.ci-card {
|
||||
background: var(--color-bg, #ffffff);
|
||||
border-radius: var(--radius, 8px);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.ci-img {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
object-fit: contain;
|
||||
background: #f8f9fb;
|
||||
padding: 10px;
|
||||
}
|
||||
.ci-body {
|
||||
padding: 16px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.ci-title {
|
||||
font-size: 14px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.ci-title-en {
|
||||
font-size: 12px;
|
||||
font-weight: var(--weight-normal, 400);
|
||||
color: var(--color-text-secondary, #666);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ci-divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #000;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ci-list {
|
||||
list-style: disc;
|
||||
padding-left: 18px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: var(--color-text, #000);
|
||||
flex: 1;
|
||||
}
|
||||
.ci-list li {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.ci-source {
|
||||
font-size: 11px;
|
||||
color: var(--color-text-light, #94a3b8);
|
||||
font-style: italic;
|
||||
margin-top: 8px;
|
||||
border-top: 1px solid var(--color-border, #e2e8f0);
|
||||
padding-top: 6px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
162
04. design_agent/docs/block-tests/cards_card-compare-3col.html
Normal file
@@ -0,0 +1,162 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>cards/card-compare-3col</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 3단 비교 카드: 각각 다른 색상 헤더 + 아이콘/이미지 + 불릿 -->
|
||||
<!--
|
||||
📋 card-compare-3col
|
||||
─────────────────
|
||||
용도: 3개 카테고리 비교 (예: 상용SW / 3rd Party / 전문SW)
|
||||
슬롯: cards[] (각 카드에 title, subtitle, color, image, bullets[])
|
||||
Figma 원본: 2-2_03 "상용 / 3rd Party(범용) / 전문·전용 S/W"
|
||||
-->
|
||||
<div class="block-compare-3" style="--cc-count: 3">
|
||||
|
||||
<div class="cc-card">
|
||||
<div class="cc-header" style="background: #6b7280">
|
||||
<div class="cc-title">상용 S/W</div>
|
||||
<div class="cc-sub">Commercial</div>
|
||||
</div>
|
||||
|
||||
|
||||
<ul class="cc-list">
|
||||
|
||||
<li>Autodesk, Bentley 등</li>
|
||||
|
||||
<li>범용 기능 제공</li>
|
||||
|
||||
<li>라이선스 비용 높음</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="cc-card">
|
||||
<div class="cc-header" style="background: #2563eb">
|
||||
<div class="cc-title">3rd Party 범용</div>
|
||||
<div class="cc-sub">General Purpose</div>
|
||||
</div>
|
||||
|
||||
|
||||
<ul class="cc-list">
|
||||
|
||||
<li>Rhino, Sketchup 등</li>
|
||||
|
||||
<li>특정 분야 특화</li>
|
||||
|
||||
<li>상대적 저비용</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="cc-card">
|
||||
<div class="cc-header" style="background: #dc2626">
|
||||
<div class="cc-title">전문·전용 S/W</div>
|
||||
<div class="cc-sub">Specialized</div>
|
||||
</div>
|
||||
|
||||
|
||||
<ul class="cc-list">
|
||||
|
||||
<li>자체 개발 솔루션</li>
|
||||
|
||||
<li>업무 프로세스 최적화</li>
|
||||
|
||||
<li>지속적 업그레이드 가능</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-compare-3 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--cc-count, 3), 1fr);
|
||||
gap: 14px;
|
||||
}
|
||||
.cc-card {
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: #ffffff;
|
||||
}
|
||||
.cc-header {
|
||||
padding: 12px 16px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
}
|
||||
.cc-title {
|
||||
font-size: 15px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.cc-sub {
|
||||
font-size: 11px;
|
||||
opacity: 0.85;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.cc-img {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
object-fit: contain;
|
||||
background: #f8fafc;
|
||||
padding: 8px;
|
||||
}
|
||||
.cc-list {
|
||||
list-style: disc;
|
||||
padding: 12px 16px 14px 30px;
|
||||
font-size: 13px;
|
||||
color: #334155;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.cc-list li {
|
||||
margin-bottom: 3px;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
174
04. design_agent/docs/block-tests/cards_card-dark-overlay.html
Normal file
@@ -0,0 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>cards/card-dark-overlay</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 다크 오버레이 카드: 배경 이미지 + 흰 텍스트 오버레이 -->
|
||||
<!--
|
||||
📋 card-dark-overlay
|
||||
─────────────────
|
||||
용도: 키워드+짧은 설명을 시각적으로 강조. 이미지 위에 다크 오버레이 + 흰 텍스트.
|
||||
슬롯: cards[] (각 카드에 image, title, description)
|
||||
Figma 원본: 2-2_01 > 아이콘 카드 5열 (협업지원, 오류감소, 생산성향상 등)
|
||||
-->
|
||||
<div class="block-card-dark" style="--cd-count: 5">
|
||||
|
||||
<div class="cd-card">
|
||||
|
||||
<img class="cd-bg" src="../figma-assets/2-2_icon_card_1.png" alt="">
|
||||
|
||||
<div class="cd-overlay">
|
||||
<div class="cd-title">협업지원</div>
|
||||
<div class="cd-desc">팀원간 협업 원활히하여
|
||||
프로젝트 관리 개선</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cd-card">
|
||||
|
||||
<img class="cd-bg" src="../figma-assets/2-2_icon_card_2.png" alt="">
|
||||
|
||||
<div class="cd-overlay">
|
||||
<div class="cd-title">오류감소</div>
|
||||
<div class="cd-desc">설계 오류 최소화
|
||||
품질 향상</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cd-card">
|
||||
|
||||
<img class="cd-bg" src="../figma-assets/2-2_icon_card_3.png" alt="">
|
||||
|
||||
<div class="cd-overlay">
|
||||
<div class="cd-title">생산성 향상</div>
|
||||
<div class="cd-desc">반복적 작업의 자동화
|
||||
시간과 노력 절약</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cd-card">
|
||||
|
||||
<img class="cd-bg" src="../figma-assets/2-2_icon_card_4.png" alt="">
|
||||
|
||||
<div class="cd-overlay">
|
||||
<div class="cd-title">비용절감</div>
|
||||
<div class="cd-desc">설계 변경 최소화
|
||||
공사비 절감</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cd-card">
|
||||
|
||||
<img class="cd-bg" src="../figma-assets/2-2_icon_card_5.png" alt="">
|
||||
|
||||
<div class="cd-overlay">
|
||||
<div class="cd-title">데이터 관리</div>
|
||||
<div class="cd-desc">체계적 정보 관리
|
||||
생애주기 활용</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-dark {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--cd-count, 3), 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.cd-card {
|
||||
position: relative;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
height: 200px;
|
||||
}
|
||||
.cd-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
z-index: 1;
|
||||
}
|
||||
.cd-bg-default {
|
||||
background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%);
|
||||
}
|
||||
.cd-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 2;
|
||||
background: linear-gradient(180deg, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.55) 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
}
|
||||
.cd-title {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
line-height: 1.3;
|
||||
margin-bottom: 6px;
|
||||
text-shadow: 0 1px 4px rgba(0,0,0,0.3);
|
||||
}
|
||||
.cd-desc {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
opacity: 0.9;
|
||||
text-shadow: 0 1px 3px rgba(0,0,0,0.3);
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
114
04. design_agent/docs/block-tests/cards_card-icon-desc.html
Normal file
@@ -0,0 +1,114 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head><meta charset="UTF-8"><title>cards/card-icon-desc</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head>
|
||||
<body><div class="block-container"><!-- 아이콘 설명 카드: 아이콘 + 제목 + 설명 (2~4열) -->
|
||||
<!--
|
||||
📋 card-icon-desc
|
||||
─────────────────
|
||||
용도: 기능/특성/장점을 아이콘과 함께 나열. 시각적으로 분류.
|
||||
슬롯: cards[] (각 카드에 icon, title, description)
|
||||
Figma 원본: 2-3_01 아이콘 3열 설명
|
||||
-->
|
||||
<div class="block-card-icon" style="--ci-count: 3">
|
||||
|
||||
<div class="cid-card">
|
||||
<div class="cid-icon">🔧</div>
|
||||
<div class="cid-title">기술 기반</div>
|
||||
<div class="cid-desc">건설 분야별
|
||||
전문지식과 경험</div>
|
||||
</div>
|
||||
|
||||
<div class="cid-card">
|
||||
<div class="cid-icon">💻</div>
|
||||
<div class="cid-title">S/W 역량</div>
|
||||
<div class="cid-desc">디지털 도구와
|
||||
Process 통합</div>
|
||||
</div>
|
||||
|
||||
<div class="cid-card">
|
||||
<div class="cid-icon">🌏</div>
|
||||
<div class="cid-title">여건 조성</div>
|
||||
<div class="cid-desc">사회·기업·제도
|
||||
수용 환경 구축</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-icon {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--ci-count, 3), 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.cid-card {
|
||||
text-align: center;
|
||||
padding: 20px 16px;
|
||||
background: #f8fafc;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
.cid-icon {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.cid-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.cid-desc {
|
||||
font-size: 13px;
|
||||
color: #475569;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
199
04. design_agent/docs/block-tests/cards_card-image-3col.html
Normal file
@@ -0,0 +1,199 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>cards/card-image-3col</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 이미지 카드: 상단 이미지 + 하단 텍스트 (2~4열) -->
|
||||
<!--
|
||||
📋 card-image
|
||||
─────────────────
|
||||
용도: 단계별 설명, 카테고리별 설명 (이미지가 핵심인 카드)
|
||||
슬롯: cards[] 배열 (각 카드에 image, title, title_en, items[])
|
||||
Figma 원본: 2-1_02 > Group 1171281594 (카드 3열)
|
||||
-->
|
||||
<div class="block-card-image" style="--ci-count: 3">
|
||||
|
||||
<div class="ci-card">
|
||||
|
||||
<img class="ci-img" src="../figma-assets/card_img_design.png" alt="설계단계">
|
||||
|
||||
<div class="ci-body">
|
||||
<div class="ci-title" style="color: #00aaff">설계단계</div>
|
||||
<div class="ci-title-en">Design Stage</div>
|
||||
<div class="ci-divider"></div>
|
||||
<ul class="ci-list">
|
||||
|
||||
<li>고도화된 BIM 구현</li>
|
||||
|
||||
<li>최첨단 디지털트윈</li>
|
||||
|
||||
<li>시뮬레이션 분석 & 성능평가</li>
|
||||
|
||||
<li>지속가능한 인프라개발</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ci-card">
|
||||
|
||||
<img class="ci-img" src="../figma-assets/card_img_construction.png" alt="시공 단계">
|
||||
|
||||
<div class="ci-body">
|
||||
<div class="ci-title" style="color: #006aff">시공 단계</div>
|
||||
<div class="ci-title-en">Construction Stage</div>
|
||||
<div class="ci-divider"></div>
|
||||
<ul class="ci-list">
|
||||
|
||||
<li>향상된 건설 계획과 공정 순서 관리</li>
|
||||
|
||||
<li>Big Room 등 환경을 통한 협업 및 조정</li>
|
||||
|
||||
<li>정확한 수량산출서와 비용 산정</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ci-card">
|
||||
|
||||
<img class="ci-img" src="../figma-assets/card_img_maintenance.png" alt="유지관리 단계">
|
||||
|
||||
<div class="ci-body">
|
||||
<div class="ci-title" style="color: #004cbe">유지관리 단계</div>
|
||||
<div class="ci-title-en">Maintenance Stage</div>
|
||||
<div class="ci-divider"></div>
|
||||
<ul class="ci-list">
|
||||
|
||||
<li>자산 정보 및 데이터 관리</li>
|
||||
|
||||
<li>예측 기반 유지보수 및 생애주기 분석</li>
|
||||
|
||||
<li>효율적인 시설 운영 및 지속가능한 관리</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-image {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--ci-count, 3), 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.ci-card {
|
||||
background: var(--color-bg, #ffffff);
|
||||
border-radius: var(--radius, 8px);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.ci-img {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
object-fit: contain;
|
||||
background: #f8f9fb;
|
||||
padding: 10px;
|
||||
}
|
||||
.ci-body {
|
||||
padding: 16px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.ci-title {
|
||||
font-size: 14px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.ci-title-en {
|
||||
font-size: 12px;
|
||||
font-weight: var(--weight-normal, 400);
|
||||
color: var(--color-text-secondary, #666);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ci-divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #000;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ci-list {
|
||||
list-style: disc;
|
||||
padding-left: 18px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: var(--color-text, #000);
|
||||
flex: 1;
|
||||
}
|
||||
.ci-list li {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.ci-source {
|
||||
font-size: 11px;
|
||||
color: var(--color-text-light, #94a3b8);
|
||||
font-style: italic;
|
||||
margin-top: 8px;
|
||||
border-top: 1px solid var(--color-border, #e2e8f0);
|
||||
padding-top: 6px;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
133
04. design_agent/docs/block-tests/cards_card-image-round.html
Normal file
@@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>cards/card-image-round</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 원형 이미지 카드: 원형 이미지 + 하단 제목/설명 -->
|
||||
<!--
|
||||
📋 card-image-round
|
||||
─────────────────
|
||||
용도: 포트폴리오형, 팀 소개, 가치/비전 표현 (원형 이미지가 핵심)
|
||||
슬롯: cards[] (각 카드에 image, title, description)
|
||||
Figma 원본: 1장_가치 하단 3열 원형 이미지 + 설명
|
||||
-->
|
||||
<div class="block-card-round" style="--cr-count: 3">
|
||||
|
||||
<div class="cr-card">
|
||||
|
||||
<div class="cr-img-wrap">
|
||||
<img src="../figma-assets/card_img_design.png" alt="설계 혁신">
|
||||
</div>
|
||||
|
||||
<div class="cr-title">설계 혁신</div>
|
||||
<div class="cr-desc">3D 모델 기반
|
||||
통합 설계</div>
|
||||
</div>
|
||||
|
||||
<div class="cr-card">
|
||||
|
||||
<div class="cr-img-wrap">
|
||||
<img src="../figma-assets/card_img_construction.png" alt="시공 효율">
|
||||
</div>
|
||||
|
||||
<div class="cr-title">시공 효율</div>
|
||||
<div class="cr-desc">디지털 관리
|
||||
품질 향상</div>
|
||||
</div>
|
||||
|
||||
<div class="cr-card">
|
||||
|
||||
<div class="cr-img-wrap">
|
||||
<img src="../figma-assets/card_img_maintenance.png" alt="유지관리">
|
||||
</div>
|
||||
|
||||
<div class="cr-title">유지관리</div>
|
||||
<div class="cr-desc">생애주기
|
||||
자산 관리</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-round {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--cr-count, 3), 1fr);
|
||||
gap: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.cr-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.cr-img-wrap {
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
border: 3px solid #e2e8f0;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.cr-img-wrap img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.cr-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.cr-desc {
|
||||
font-size: 13px;
|
||||
color: #475569;
|
||||
line-height: 1.6;
|
||||
white-space: pre-line;
|
||||
max-width: 200px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
136
04. design_agent/docs/block-tests/cards_card-numbered.html
Normal file
@@ -0,0 +1,136 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>cards/card-numbered</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 번호 카드: 순서 번호 + 제목 + 설명 (세로 나열) -->
|
||||
<!--
|
||||
📋 card-numbered
|
||||
─────────────────
|
||||
용도: 순서가 있는 항목 나열 (1. 2. 3.), 실행 조건, 요구사항
|
||||
슬롯: items[] (각 항목에 title, description)
|
||||
card-icon-desc와 다른 점: 아이콘 대신 순서 번호, 세로 나열
|
||||
-->
|
||||
<div class="block-card-num">
|
||||
|
||||
<div class="cn-item">
|
||||
<div class="cn-number" style="background: #2563eb">1</div>
|
||||
<div class="cn-body">
|
||||
<div class="cn-title">요구사항 분석</div>
|
||||
<div class="cn-desc">디지털 전환 목표 수립
|
||||
사용자 요구사항 수집</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cn-item">
|
||||
<div class="cn-number" style="background: #059669">2</div>
|
||||
<div class="cn-body">
|
||||
<div class="cn-title">S/W 개발</div>
|
||||
<div class="cn-desc">건설산업 디지털화를 위한
|
||||
솔루션 개발 및 업그레이드</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cn-item">
|
||||
<div class="cn-number" style="background: #7c3aed">3</div>
|
||||
<div class="cn-body">
|
||||
<div class="cn-title">System 통합</div>
|
||||
<div class="cn-desc">기존 시스템 호환성 분석
|
||||
API 데이터 통합</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cn-item">
|
||||
<div class="cn-number" style="background: #dc2626">4</div>
|
||||
<div class="cn-body">
|
||||
<div class="cn-title">교육/피드백</div>
|
||||
<div class="cn-desc">사용자 교육 프로그램
|
||||
지속적 모니터링 & 개선</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-num {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.cn-item {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
align-items: flex-start;
|
||||
padding: 12px 16px;
|
||||
background: #f8fafc;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
.cn-number {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.cn-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.cn-desc {
|
||||
font-size: 13px;
|
||||
color: #475569;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
129
04. design_agent/docs/block-tests/cards_card-stat-number.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>cards/card-stat-number</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 통계 숫자 카드: 큰 숫자 + 라벨 + 설명 -->
|
||||
<!--
|
||||
📋 card-stat-number
|
||||
─────────────────
|
||||
용도: KPI, 성과 수치, 목표 달성률, 비용 절감율 등 핵심 지표 강조
|
||||
슬롯: stats[] (각 항목에 number, unit, label, description, color)
|
||||
Figma 참고: 건설 정책 수치 (30% 절감, 40% 감소 등)
|
||||
-->
|
||||
<div class="block-stat" style="--st-count: 4">
|
||||
|
||||
<div class="st-card">
|
||||
<div class="st-number" style="color: #2563eb">
|
||||
30<span class="st-unit">%</span>
|
||||
</div>
|
||||
<div class="st-label">공기/공사비 절감</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="st-card">
|
||||
<div class="st-number" style="color: #059669">
|
||||
40<span class="st-unit">%</span>
|
||||
</div>
|
||||
<div class="st-label">안전사고 감소</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="st-card">
|
||||
<div class="st-number" style="color: #7c3aed">
|
||||
220<span class="st-unit">명+</span>
|
||||
</div>
|
||||
<div class="st-label">IT+CIVIL ENG 인력</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="st-card">
|
||||
<div class="st-number" style="color: #dc2626">
|
||||
80<span class="st-unit">개+</span>
|
||||
</div>
|
||||
<div class="st-label">전용 S/W 개발</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-stat {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--st-count, 3), 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.st-card {
|
||||
text-align: center;
|
||||
padding: 20px 12px;
|
||||
background: #f8fafc;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
.st-number {
|
||||
font-size: 36px;
|
||||
font-weight: 900;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.st-unit {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.st-label {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.st-desc {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
margin-top: 4px;
|
||||
line-height: 1.5;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
170
04. design_agent/docs/block-tests/cards_card-step-vertical.html
Normal file
@@ -0,0 +1,170 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>cards/card-step-vertical</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 세로 단계 카드: 좌측 단계 마커 + 우측 이미지/텍스트 -->
|
||||
<!--
|
||||
📋 card-step-vertical
|
||||
─────────────────
|
||||
용도: 생애주기 단계별 설명, 시간순 프로세스 (설계→시공→운영→유지관리)
|
||||
슬롯: steps[] (각 단계에 phase, title, description, image, color)
|
||||
Figma 원본: 2-3_04 "건설 생애주기와 정보모델 연계" (설계단계/시공단계/운영관리/유지관리)
|
||||
-->
|
||||
<div class="block-step-v">
|
||||
|
||||
<div class="sv-step">
|
||||
<div class="sv-marker" style="background: #00aaff">
|
||||
<div class="sv-phase">설계단계</div>
|
||||
</div>
|
||||
<div class="sv-content">
|
||||
<div class="sv-title">BIM 기반 3D 설계</div>
|
||||
|
||||
<div class="sv-desc">• 고도화된 BIM 구현
|
||||
• 시뮬레이션 분석 & 성능평가</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sv-connector">
|
||||
<div class="sv-line" style="background: #00aaff"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sv-step">
|
||||
<div class="sv-marker" style="background: #006aff">
|
||||
<div class="sv-phase">시공단계</div>
|
||||
</div>
|
||||
<div class="sv-content">
|
||||
<div class="sv-title">현장 디지털 관리</div>
|
||||
|
||||
<div class="sv-desc">• 공정 순서 관리
|
||||
• Big Room 협업 환경</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sv-connector">
|
||||
<div class="sv-line" style="background: #006aff"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sv-step">
|
||||
<div class="sv-marker" style="background: #004cbe">
|
||||
<div class="sv-phase">운영단계</div>
|
||||
</div>
|
||||
<div class="sv-content">
|
||||
<div class="sv-title">디지털 트윈 운영</div>
|
||||
|
||||
<div class="sv-desc">• 실시간 모니터링
|
||||
• 예측 기반 유지보수</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-step-v {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
.sv-step {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.sv-marker {
|
||||
width: 100px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
}
|
||||
.sv-phase {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.sv-content {
|
||||
flex: 1;
|
||||
background: #f8fafc;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
.sv-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.sv-img {
|
||||
width: 100%;
|
||||
max-height: 150px;
|
||||
object-fit: cover;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.sv-desc {
|
||||
font-size: 13px;
|
||||
color: #475569;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.sv-connector {
|
||||
display: flex;
|
||||
justify-content: 50px;
|
||||
padding-left: 48px;
|
||||
height: 20px;
|
||||
}
|
||||
.sv-line {
|
||||
width: 3px;
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
opacity: 0.4;
|
||||
}
|
||||
</style></div></body></html>
|
||||
132
04. design_agent/docs/block-tests/cards_card-tag-image.html
Normal file
@@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head><meta charset="UTF-8"><title>cards/card-tag-image</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head>
|
||||
<body><div class="block-container"><!-- 태그 카드: 상단 태그 라벨 + 이미지 + 설명 -->
|
||||
<!--
|
||||
📋 card-tag-image
|
||||
─────────────────
|
||||
용도: 카테고리별 분류 (제조/건축/토목 등), 태그로 구분되는 항목
|
||||
슬롯: cards[] (각 카드에 tag, tag_color, image, title, description)
|
||||
Figma 원본: 2-3_01 "산업별 특성과 현장의 모습" (제조, 건축, 인프라/토목)
|
||||
-->
|
||||
<div class="block-card-tag" style="--ct-count: 3">
|
||||
|
||||
<div class="ct-card">
|
||||
<div class="ct-tag" style="background: #2563eb">제조</div>
|
||||
|
||||
<div class="ct-title">제조업 현장</div>
|
||||
<div class="ct-desc">반복적 공정
|
||||
표준화된 부품
|
||||
자동화 라인</div>
|
||||
</div>
|
||||
|
||||
<div class="ct-card">
|
||||
<div class="ct-tag" style="background: #059669">건축</div>
|
||||
|
||||
<div class="ct-title">건축 현장</div>
|
||||
<div class="ct-desc">수직적 작업공간
|
||||
Library 기반 설계
|
||||
반복 요소 활용</div>
|
||||
</div>
|
||||
|
||||
<div class="ct-card">
|
||||
<div class="ct-tag" style="background: #dc2626">인프라/토목</div>
|
||||
|
||||
<div class="ct-title">인프라 현장</div>
|
||||
<div class="ct-desc">수평적 작업공간
|
||||
비반복적 공정
|
||||
GIS 기반 위치정보 필수</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-tag {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--ct-count, 3), 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.ct-card {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.ct-tag {
|
||||
display: inline-block;
|
||||
padding: 4px 14px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
border-radius: 0 0 8px 0;
|
||||
align-self: flex-start;
|
||||
}
|
||||
.ct-img {
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
object-fit: cover;
|
||||
}
|
||||
.ct-title {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
padding: 10px 14px 4px;
|
||||
}
|
||||
.ct-desc {
|
||||
font-size: 13px;
|
||||
color: #475569;
|
||||
line-height: 1.7;
|
||||
padding: 0 14px 14px;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
137
04. design_agent/docs/block-tests/cards_card-text-grid.html
Normal file
@@ -0,0 +1,137 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>cards/card-text-grid</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 카드 그리드 블록: 2~4열 카드 배열 -->
|
||||
<div class="block-card-grid" style="--card-count: 3">
|
||||
|
||||
<div class="card" style="border-top-color: None">
|
||||
|
||||
<div class="card-title">건설산업</div>
|
||||
<span class="card-category">종합산업</span>
|
||||
<div class="card-description">다양한 시설물을 광범위한 기술을 통합·융합하여 만들어내는 종합산업</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card" style="border-top-color: None">
|
||||
|
||||
<div class="card-title">BIM</div>
|
||||
<span class="card-category">핵심 인프라 기술</span>
|
||||
<div class="card-description">시설물 생애주기 정보를 3D 모델 기반으로 통합·관리하는 도구</div>
|
||||
<div class="card-source">국토교통부, 2020</div>
|
||||
</div>
|
||||
|
||||
<div class="card" style="border-top-color: None">
|
||||
|
||||
<div class="card-title">DX</div>
|
||||
<span class="card-category">패러다임 변화</span>
|
||||
<div class="card-description">디지털 기술 기반으로 업무방식과 가치 창출 구조를 전환하는 과정</div>
|
||||
<div class="card-source">IBM, 2011</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--card-count, 3), 1fr);
|
||||
gap: var(--spacing-inner);
|
||||
height: 100%;
|
||||
}
|
||||
.card {
|
||||
background: var(--color-bg);
|
||||
border: var(--border-width) solid var(--color-border);
|
||||
border-top: var(--accent-border) solid var(--color-accent);
|
||||
border-radius: var(--radius);
|
||||
padding: var(--spacing-inner);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.card-icon {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: var(--spacing-small);
|
||||
}
|
||||
.card-title {
|
||||
font-size: var(--font-subtitle);
|
||||
font-weight: var(--weight-bold);
|
||||
color: var(--color-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.card-category {
|
||||
font-size: var(--font-small);
|
||||
font-weight: var(--weight-medium);
|
||||
color: var(--color-accent);
|
||||
background: #dbeafe;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
display: inline-block;
|
||||
margin-bottom: var(--spacing-small);
|
||||
width: fit-content;
|
||||
}
|
||||
.card-description {
|
||||
font-size: var(--font-body);
|
||||
color: var(--color-text);
|
||||
line-height: var(--line-height-ko);
|
||||
flex: 1;
|
||||
}
|
||||
.card-source {
|
||||
font-size: var(--font-small);
|
||||
color: var(--color-text-light);
|
||||
font-style: italic;
|
||||
margin-top: var(--spacing-small);
|
||||
border-top: var(--border-width) solid var(--color-border);
|
||||
padding-top: var(--spacing-small);
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
133
04. design_agent/docs/block-tests/circle-label.html
Normal file
@@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>블록 테스트: circle-label</title>
|
||||
<style>
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Pretendard Variable", "Noto Sans KR", sans-serif;
|
||||
background: #e8ecf0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
.block-container {
|
||||
width: 920px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
.block-container .block-section-title {
|
||||
margin: -20px -20px 0;
|
||||
border-radius: 8px 8px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
<!-- 원형 라벨: CSS 그라데이션 원 + 중앙 텍스트 -->
|
||||
<!--
|
||||
📋 circle-label
|
||||
─────────────────
|
||||
용도: 섹션 전환점, 핵심 키워드 강조, 시각적 구분자
|
||||
슬롯: label (필수), sub_label (선택)
|
||||
Figma 원본: 2-1_02 > Group 1171281590 (190x190)
|
||||
-->
|
||||
<div class="block-circle-label">
|
||||
<div class="cl-outer">
|
||||
<div class="cl-inner">
|
||||
<div class="cl-text">단계별
|
||||
BIM의 활용</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-circle-label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.cl-outer {
|
||||
width: 190px;
|
||||
height: 190px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, #3db8ff 0%, #006aff 100%);
|
||||
box-shadow: 0 0 30px rgba(0, 106, 255, 0.25), 0 0 60px rgba(0, 106, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.cl-inner {
|
||||
width: 170px;
|
||||
height: 170px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, #4dc4ff 0%, #0080ff 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
}
|
||||
.cl-text {
|
||||
font-size: 20px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
line-height: 1.4;
|
||||
}
|
||||
.cl-sub {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
124
04. design_agent/docs/block-tests/compare-box.html
Normal file
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>compare-box</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 비교 박스: 둥근 테두리 박스 2개 + VS 라벨 -->
|
||||
<!--
|
||||
📋 compare-box
|
||||
─────────────────
|
||||
용도: 2개 개념을 시각적으로 대비 (비교 테이블 위 헤더로 사용)
|
||||
슬롯: left_label, left_sub, right_label, right_sub
|
||||
Figma 원본: 2-1_02 > 하늘색 둥근 박스 2개 + 시안 텍스트
|
||||
-->
|
||||
<div class="block-compare-box">
|
||||
<div class="cb-item">
|
||||
<div class="cb-text">
|
||||
<div class="cb-label">디지털 기술을 활용한
|
||||
협업 프로세스</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="cb-vs">VS</div>
|
||||
<div class="cb-item">
|
||||
<div class="cb-text">
|
||||
<div class="cb-label">시설물의 전 생애주기 동안
|
||||
정보의 생성 및 관리</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-compare-box {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 15px 0;
|
||||
}
|
||||
.cb-item {
|
||||
width: 340px;
|
||||
height: 110px;
|
||||
border-radius: 55px;
|
||||
border: 3px solid #7ec8f0;
|
||||
background: linear-gradient(135deg, #e8f4fd 0%, #d4ecfa 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 10px rgba(0, 140, 220, 0.1);
|
||||
}
|
||||
.cb-text {
|
||||
text-align: center;
|
||||
}
|
||||
.cb-label {
|
||||
font-size: 19px;
|
||||
font-weight: 800;
|
||||
color: #0090d0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.cb-sub {
|
||||
font-size: 13px;
|
||||
color: #0090d0;
|
||||
margin-top: 3px;
|
||||
line-height: 1.5;
|
||||
white-space: pre-line;
|
||||
font-weight: 500;
|
||||
}
|
||||
.cb-vs {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
278
04. design_agent/docs/block-tests/comparison-table.html
Normal file
@@ -0,0 +1,278 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>comparison-table</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 비교 테이블: BIM vs DX 스타일 3단 테이블 -->
|
||||
<!--
|
||||
📋 comparison-table
|
||||
─────────────────
|
||||
용도: 다항목 비교 (좌측 A | 중앙 기준 | 우측 B)
|
||||
슬롯: headers[] (3개), rows[][] (각 행 3칸)
|
||||
Figma 원본: 2-1_02 > BIM VS D/X 테이블
|
||||
특징: 중앙 칼럼에 파란 그라데이션 배지, 좌우 불릿 대비
|
||||
-->
|
||||
<div class="block-table-figma">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th class="th-left">
|
||||
BIM
|
||||
</th>
|
||||
|
||||
<th class="th-center">
|
||||
<span class="th-badge">VS</span>
|
||||
</th>
|
||||
|
||||
<th class="th-right">
|
||||
D/X
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• Only 3D</td>
|
||||
|
||||
<td class="td-center">BIM · D/X</td>
|
||||
|
||||
<td class="td-right">• BIM ≪ D/X (ENG. + Management 포함)</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 모델 제작용 상용 S/W
|
||||
(Civil 3D, Revit, Navisworks, Autocad)</td>
|
||||
|
||||
<td class="td-center">S/W</td>
|
||||
|
||||
<td class="td-right">• 제작 및 운영(상용 + 전용 40~80개)
|
||||
[Rhino, Sketchup, Blender...] + [EG-BIM 등]</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 기존 2D 설계방식 유지</td>
|
||||
|
||||
<td class="td-center">프로세스</td>
|
||||
|
||||
<td class="td-right">• 근본적 문제의식을 통한 개선</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 3D 모델 중심
|
||||
• 기존 성과품 유지</td>
|
||||
|
||||
<td class="td-center">성과물</td>
|
||||
|
||||
<td class="td-right">• 공학 정보 및 콘텐츠 연계에 집중
|
||||
• 도면, 수량, 시공계획 등 일식</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 3D 모델에 의한 일반적 이해 향상</td>
|
||||
|
||||
<td class="td-center">활용</td>
|
||||
|
||||
<td class="td-right">• 설계/시공의 혁신(개념의 재정립)</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• (설계/시공/운영) 분야별 단절</td>
|
||||
|
||||
<td class="td-center">확장성</td>
|
||||
|
||||
<td class="td-right">• 전 생애주기 활용 시스템</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 단순화(오류) - 수동적/집단적 동질화</td>
|
||||
|
||||
<td class="td-center">수행개념</td>
|
||||
|
||||
<td class="td-right">• 구체화(복잡) - 적극/구체적 실현 방안</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 소극적, 상용 기술에 의존</td>
|
||||
|
||||
<td class="td-center">CIVIL + IT</td>
|
||||
|
||||
<td class="td-right">• 적극적, 주체적인 기술 접목/융합</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• S/W 제작사 판매 정책에 의존</td>
|
||||
|
||||
<td class="td-center">주체</td>
|
||||
|
||||
<td class="td-right">• 자체 수행능력 - 지속가능성 확보</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 평준화, 국내 중심</td>
|
||||
|
||||
<td class="td-center">발주처</td>
|
||||
|
||||
<td class="td-right">• 차별화 및 경쟁력 확보, 해외 진출</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 소규모 BIM팀 운영 + 단순교육에 집중</td>
|
||||
|
||||
<td class="td-center">설계사</td>
|
||||
|
||||
<td class="td-right">• IT + CIVIL ENG 220명 운영 + 기술 개발</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 국내 토목 소극적/ 해외 토목증가</td>
|
||||
|
||||
<td class="td-center">시공사</td>
|
||||
|
||||
<td class="td-right">• 분야 확장 모델 및 시스템</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-table-figma {
|
||||
overflow: auto;
|
||||
}
|
||||
.block-table-figma table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* 헤더 */
|
||||
.block-table-figma thead th {
|
||||
padding: 14px 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
border-bottom: 2px solid #e8edf2;
|
||||
}
|
||||
.th-left {
|
||||
text-align: center;
|
||||
color: #6bcdff;
|
||||
}
|
||||
.th-center {
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
}
|
||||
.th-badge {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, #006eff 0%, #00aaff 100%);
|
||||
color: #ffffff;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
padding: 8px 28px;
|
||||
border-radius: 25px;
|
||||
}
|
||||
.th-right {
|
||||
text-align: center;
|
||||
color: #006eff;
|
||||
}
|
||||
|
||||
/* 본문 */
|
||||
.block-table-figma tbody td {
|
||||
padding: 10px 14px;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.td-left {
|
||||
text-align: center;
|
||||
color: #444;
|
||||
}
|
||||
.td-center {
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
background: #f6f8fb;
|
||||
font-size: 13px;
|
||||
}
|
||||
.td-right {
|
||||
text-align: center;
|
||||
color: #444;
|
||||
}
|
||||
.block-table-figma tbody tr:hover {
|
||||
background: #fafbfd;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
93
04. design_agent/docs/block-tests/conclusion-bar.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>conclusion-bar</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 결론 바: Figma 톤에 맞춘 하단 핵심 메시지 -->
|
||||
<!--
|
||||
📋 conclusion-bar
|
||||
─────────────────
|
||||
용도: 슬라이드/페이지 하단 핵심 한 줄 요약
|
||||
슬롯: conclusion_text (필수), label (선택)
|
||||
Figma 톤: 밝은 회색 배경 + 좌측 파란 액센트 라인 + 진한 텍스트
|
||||
-->
|
||||
<div class="block-conclusion-figma">
|
||||
<div class="cf-label">핵심 요약</div>
|
||||
<div class="cf-text">BIM은 건설산업의 디지털전환(DX)을 수행하는 과정에서 가장 기초가 되는 일부분이다</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-conclusion-figma {
|
||||
background: #f4f6f9;
|
||||
border-left: 4px solid #006aff;
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 18px 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.cf-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #006aff;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.cf-text {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
line-height: 1.6;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>emphasis/banner-gradient</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 그라데이션 배너 바: 전체 너비 파란 그라데이션 + 중앙 텍스트 -->
|
||||
<!--
|
||||
📋 banner-gradient
|
||||
─────────────────
|
||||
용도: 섹션 구분, 핵심 선언, 강조 문구를 전체 너비 배너로
|
||||
슬롯: text (필수), sub_text (선택)
|
||||
Figma 원본: 2-2_01 하단, 2-2_03 분류 바
|
||||
-->
|
||||
<div class="block-banner-grad">
|
||||
<div class="bg-text">Engineering Software는 건설산업 DX를 실현하기 위한 핵심 도구입니다</div>
|
||||
<div class="bg-sub">단순 도구가 아닌, 엔지니어의 전문지식과 프로세스를 디지털화하는 기반 기술</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-banner-grad {
|
||||
background: linear-gradient(135deg, #006aff 0%, #00aaff 100%);
|
||||
border-radius: 8px;
|
||||
padding: 16px 30px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
}
|
||||
.bg-text {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.bg-sub {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
opacity: 0.85;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
104
04. design_agent/docs/block-tests/emphasis_callout-solution.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>emphasis/callout-solution</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 솔루션 콜아웃: 강조 배경 + 아이콘 + 제목 + 설명 -->
|
||||
<!--
|
||||
📋 callout-solution
|
||||
─────────────────
|
||||
용도: 핵심 해결책/솔루션/방향성 강조. 눈에 띄는 콜아웃 박스.
|
||||
슬롯: icon (선택), title (필수), description (필수), source (선택)
|
||||
Figma 원본: 2-3_05 "Solution 제시 포인트"
|
||||
-->
|
||||
<div class="block-callout-sol">
|
||||
<div class="cs-icon">💡</div>
|
||||
<div class="cs-body">
|
||||
<div class="cs-title">Solution 제시 포인트</div>
|
||||
<div class="cs-desc">지금의 방식 속에서도 앞으로도 지속적으로 가능할까?
|
||||
건설산업의 디지털 전환을 위해 근본적인 변화가 필요한 시점입니다.</div>
|
||||
<div class="cs-source">건설산업 DX 전략 보고서</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-callout-sol {
|
||||
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
||||
border: 2px solid #93c5fd;
|
||||
border-radius: 12px;
|
||||
padding: 20px 24px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.cs-icon {
|
||||
font-size: 2rem;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.cs-body {
|
||||
flex: 1;
|
||||
}
|
||||
.cs-title {
|
||||
font-size: 17px;
|
||||
font-weight: 800;
|
||||
color: #1e40af;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.cs-desc {
|
||||
font-size: 14px;
|
||||
color: #334155;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.cs-source {
|
||||
font-size: 11px;
|
||||
color: #64748b;
|
||||
font-style: italic;
|
||||
margin-top: 8px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>emphasis/callout-warning</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 경고 콜아웃: 주의/경고/문제점 강조 -->
|
||||
<!--
|
||||
📋 callout-warning
|
||||
─────────────────
|
||||
용도: 문제점 지적, 주의사항, 잘못된 접근 경고
|
||||
슬롯: title (필수), description (필수), icon (선택)
|
||||
callout-solution과 다른 점: 경고 톤 (빨간/주황), 문제 지적용
|
||||
-->
|
||||
<div class="block-callout-warn">
|
||||
<div class="cw-icon">⚠️</div>
|
||||
<div class="cw-body">
|
||||
<div class="cw-title">현재 접근 방식의 한계</div>
|
||||
<div class="cw-desc">단순 BIM S/W 도입만으로는 DX를 달성할 수 없습니다.
|
||||
기존 2D 설계방식 위에 3D를 덧씌우는 접근은
|
||||
비용 증가와 효율 저하를 초래합니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-callout-warn {
|
||||
background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
|
||||
border: 2px solid #fca5a5;
|
||||
border-radius: 12px;
|
||||
padding: 20px 24px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.cw-icon {
|
||||
font-size: 2rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.cw-body { flex: 1; }
|
||||
.cw-title {
|
||||
font-size: 17px;
|
||||
font-weight: 800;
|
||||
color: #991b1b;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.cw-desc {
|
||||
font-size: 14px;
|
||||
color: #7f1d1d;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body></html>
|
||||
111
04. design_agent/docs/block-tests/emphasis_comparison-2col.html
Normal file
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>emphasis/comparison-2col</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 비교 블록: 2단 병렬 레이아웃 -->
|
||||
<div class="block-comparison">
|
||||
<div class="comparison-left">
|
||||
<div class="comparison-header comparison-header--left">잘못된 인식</div>
|
||||
|
||||
<div class="comparison-content">• BIM 기술 도입 = DX 완성
|
||||
• DX를 단순 기술 도입으로 한정
|
||||
• 개별 기술 중심의 접근</div>
|
||||
</div>
|
||||
<div class="comparison-divider"></div>
|
||||
<div class="comparison-right">
|
||||
<div class="comparison-header comparison-header--right">올바른 이해</div>
|
||||
|
||||
<div class="comparison-content">• DX는 BIM을 포함한 상위 개념
|
||||
• 산업 패러다임의 근본적 변화
|
||||
• GIS-BIM-디지털트윈 기술 융합 필수</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-comparison {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
gap: var(--spacing-inner);
|
||||
height: 100%;
|
||||
}
|
||||
.comparison-divider {
|
||||
width: 1px;
|
||||
background: var(--color-border);
|
||||
}
|
||||
.comparison-header {
|
||||
font-size: var(--font-subtitle);
|
||||
font-weight: var(--weight-bold);
|
||||
padding-bottom: var(--spacing-small);
|
||||
margin-bottom: var(--spacing-small);
|
||||
border-bottom: var(--accent-border) solid;
|
||||
}
|
||||
.comparison-header--left {
|
||||
border-color: var(--color-accent);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
.comparison-header--right {
|
||||
border-color: var(--color-danger);
|
||||
color: var(--color-danger);
|
||||
}
|
||||
.comparison-subtitle {
|
||||
font-size: var(--font-caption);
|
||||
color: var(--color-text-secondary);
|
||||
margin-bottom: var(--spacing-small);
|
||||
}
|
||||
.comparison-content {
|
||||
font-size: var(--font-body);
|
||||
line-height: var(--line-height-ko);
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>emphasis/conclusion-accent-bar</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 결론 바: Figma 톤에 맞춘 하단 핵심 메시지 -->
|
||||
<!--
|
||||
📋 conclusion-bar
|
||||
─────────────────
|
||||
용도: 슬라이드/페이지 하단 핵심 한 줄 요약
|
||||
슬롯: conclusion_text (필수), label (선택)
|
||||
Figma 톤: 밝은 회색 배경 + 좌측 파란 액센트 라인 + 진한 텍스트
|
||||
-->
|
||||
<div class="block-conclusion-figma">
|
||||
<div class="cf-label">핵심 요약</div>
|
||||
<div class="cf-text">BIM은 건설산업의 디지털전환(DX)을 수행하는 과정에서 가장 기초가 되는 일부분이다</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-conclusion-figma {
|
||||
background: #f4f6f9;
|
||||
border-left: 4px solid #006aff;
|
||||
border-radius: 0 8px 8px 0;
|
||||
padding: 18px 28px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.cf-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #006aff;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.cf-text {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
line-height: 1.6;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
105
04. design_agent/docs/block-tests/emphasis_dark-bullet-list.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head><meta charset="UTF-8"><title>emphasis/dark-bullet-list</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head>
|
||||
<body><div class="block-container"><!-- 다크 배경 불릿 리스트: 짙은 배경 + 흰 텍스트 불릿 목록 -->
|
||||
<!--
|
||||
📋 dark-bullet-list
|
||||
─────────────────
|
||||
용도: 핵심 포인트를 짙은 배경 위에 강조. 시각적 무게감.
|
||||
슬롯: title (선택), bullets[] (필수)
|
||||
Figma 원본: 2-2_01 하단, 2-3_01 하단 다크 섹션
|
||||
-->
|
||||
<div class="block-dark-bullets">
|
||||
<div class="db-title">건설산업 DX의 핵심 과제</div>
|
||||
<ul class="db-list">
|
||||
|
||||
<li>기존 2D 설계방식의 근본적 한계 인식</li>
|
||||
|
||||
<li>3D 모델 기반의 정보 통합·관리 체계 구축</li>
|
||||
|
||||
<li>전 생애주기 데이터 연계 및 활용 시스템 도입</li>
|
||||
|
||||
<li>디지털 트윈 기반 시뮬레이션 및 의사결정 지원</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-dark-bullets {
|
||||
background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
|
||||
border-radius: 8px;
|
||||
padding: 20px 28px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.db-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
color: #93c5fd;
|
||||
}
|
||||
.db-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
.db-list li {
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.db-list li::before {
|
||||
content: '•';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: #60a5fa;
|
||||
}
|
||||
</style></div></body></html>
|
||||
80
04. design_agent/docs/block-tests/emphasis_divider-text.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>emphasis/divider-text</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 텍스트 구분선: 좌우 선 + 중앙 텍스트 -->
|
||||
<!--
|
||||
📋 divider-text
|
||||
─────────────────
|
||||
용도: 섹션 구분, 주제 전환, 시각적 휴식점
|
||||
슬롯: text (필수)
|
||||
-->
|
||||
<div class="block-divider-text">
|
||||
<div class="dt-line"></div>
|
||||
<div class="dt-text">핵심 요약</div>
|
||||
<div class="dt-line"></div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-divider-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
.dt-line {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: #cbd5e1;
|
||||
}
|
||||
.dt-text {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #64748b;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>emphasis/highlight-strip</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 강조 스트립: 3구간 색상 분류 바 -->
|
||||
<!--
|
||||
📋 highlight-strip
|
||||
─────────────────
|
||||
용도: 카테고리별 색상 분류 (예: 상용/범용/전문), 비교 카드 상단 헤더
|
||||
슬롯: segments[] (각 구간에 label, color)
|
||||
Figma 원본: 2-2_03 "상용 | 3rd Party(범용) | 전문·전용 S/W" 색상 바
|
||||
-->
|
||||
<div class="block-strip">
|
||||
|
||||
<div class="strip-seg" style="background: #6b7280; flex: 1">
|
||||
상용
|
||||
</div>
|
||||
|
||||
<div class="strip-seg" style="background: #2563eb; flex: 1.5">
|
||||
3rd Party(범용)
|
||||
</div>
|
||||
|
||||
<div class="strip-seg" style="background: #dc2626; flex: 1.5">
|
||||
전문·전용 S/W
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-strip {
|
||||
display: flex;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.strip-seg {
|
||||
padding: 10px 16px;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style></div></body></html>
|
||||
107
04. design_agent/docs/block-tests/emphasis_quote-big-mark.html
Normal file
@@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>emphasis/quote-big-mark</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 큰따옴표 장식 인용: ❝❞ 큰따옴표 + 인용 텍스트 -->
|
||||
<!--
|
||||
📋 quote-big-mark
|
||||
─────────────────
|
||||
용도: 문제 제기, 핵심 발언, 임팩트 있는 인용
|
||||
슬롯: quote_text (필수), source (선택)
|
||||
Figma 원본: DX와 BIM 슬라이드 상단 인용 박스 (큰따옴표 장식)
|
||||
-->
|
||||
<div class="block-quote-big">
|
||||
<div class="qb-mark qb-open">❝</div>
|
||||
<div class="qb-content">
|
||||
<div class="qb-text">건설산업의 디지털 전환 논의에서 DX와 BIM이 개념적으로 명확히 정립되지 않은 채 혼용되어 사용되고 있으며, 이로 인해 BIM 기술의 도입을 DX의 완성으로 오인하는 인식이 확산되고 있다</div>
|
||||
<div class="qb-source">— 건설산업 DX 분석 보고서</div>
|
||||
</div>
|
||||
<div class="qb-mark qb-close">❞</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-quote-big {
|
||||
background: #f8fafc;
|
||||
border-radius: 10px;
|
||||
padding: 24px 28px;
|
||||
position: relative;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
.qb-mark {
|
||||
font-size: 3rem;
|
||||
color: #cbd5e1;
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
position: absolute;
|
||||
}
|
||||
.qb-open {
|
||||
top: 8px;
|
||||
left: 12px;
|
||||
}
|
||||
.qb-close {
|
||||
bottom: -8px;
|
||||
right: 16px;
|
||||
}
|
||||
.qb-content {
|
||||
padding: 10px 30px 0;
|
||||
}
|
||||
.qb-text {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #1e293b;
|
||||
line-height: 1.8;
|
||||
word-break: keep-all;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.qb-source {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
font-style: italic;
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>emphasis/quote-left-border</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 강조 인용 블록: 문제 제기, 핵심 메시지 -->
|
||||
<div class="block-quote">
|
||||
<div class="quote-text">BIM은 건설산업의 디지털전환을 수행하는 과정에서 가장 기초가 되는 일부분이다</div>
|
||||
<div class="quote-source">건설산업 BIM 기본지침, 국토교통부, 2020</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-quote {
|
||||
background: var(--color-bg-subtle);
|
||||
border-left: var(--accent-border) solid var(--color-danger);
|
||||
padding: var(--spacing-inner) var(--spacing-block);
|
||||
border-radius: 0 var(--radius) var(--radius) 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.quote-text {
|
||||
font-size: var(--font-body);
|
||||
color: var(--color-text);
|
||||
line-height: var(--line-height-ko);
|
||||
font-weight: var(--weight-medium);
|
||||
}
|
||||
.quote-source {
|
||||
font-size: var(--font-caption);
|
||||
color: var(--color-text-light);
|
||||
font-style: italic;
|
||||
margin-top: var(--spacing-small);
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
@@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>emphasis/quote-question</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 질문형 강조 박스: 큰 질문 텍스트 + 부연 설명 -->
|
||||
<!--
|
||||
📋 quote-question
|
||||
─────────────────
|
||||
용도: 독자에게 질문 던지기, 문제 인식 유도, 전환점 강조
|
||||
슬롯: question (필수), description (선택)
|
||||
Figma 원본: 2-3_05 "지금의 방식으로도 가능할까?"
|
||||
-->
|
||||
<div class="block-quote-q">
|
||||
<div class="qq-question">지금의 상황 속에서도 앞으로도,
|
||||
지속적으로 가능할까?</div>
|
||||
<div class="qq-desc">지금의 방식으로 복잡해지는 건설 환경에 대응할 수 있을지, 근본적인 변화가 필요한 시점입니다.</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-quote-q {
|
||||
background: linear-gradient(135deg, #f0f7ff 0%, #e8f1fb 100%);
|
||||
border: 2px solid #b8d4f0;
|
||||
border-radius: 12px;
|
||||
padding: 28px 36px;
|
||||
text-align: center;
|
||||
}
|
||||
.qq-question {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #1e3a5f;
|
||||
line-height: 1.5;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.qq-desc {
|
||||
font-size: 14px;
|
||||
color: #4a6b8a;
|
||||
margin-top: 10px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
@@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>emphasis/tab-label-row</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 탭 라벨 행: 가로로 나열된 탭 버튼 형태 -->
|
||||
<!--
|
||||
📋 tab-label-row
|
||||
─────────────────
|
||||
용도: 카테고리 전환, 분류 표시, 선택된 항목 강조
|
||||
슬롯: tabs[] (각 탭에 label, active, color)
|
||||
Figma 원본: 2-3_02 상단 "건축과 인프라의 건설프로세스 특성" 탭, 2-2_01 탭
|
||||
-->
|
||||
<div class="block-tab-row">
|
||||
|
||||
<div class="tr-tab " style="">
|
||||
제조
|
||||
</div>
|
||||
|
||||
<div class="tr-tab " style="">
|
||||
건축
|
||||
</div>
|
||||
|
||||
<div class="tr-tab tr-active" style="background: #2563eb">
|
||||
인프라/토목
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-tab-row {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
background: #f1f5f9;
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
}
|
||||
.tr-tab {
|
||||
flex: 1;
|
||||
padding: 10px 16px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #64748b;
|
||||
border-radius: 6px;
|
||||
cursor: default;
|
||||
}
|
||||
.tr-active {
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head><meta charset="UTF-8"><title>headers/section-header-bar</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head>
|
||||
<body><div class="block-container"><!-- 섹션 헤더 바: 파란 배경 + 흰 텍스트 제목 -->
|
||||
<!--
|
||||
📋 section-header-bar
|
||||
─────────────────
|
||||
용도: 섹션 시작부 강조 헤더. 전체 너비 파란 바 + 흰 대제목.
|
||||
슬롯: title (필수), subtitle (선택)
|
||||
Figma 원본: 2-2_01 "Eng. S/W의 구성", "Eng. S/W의 특성"
|
||||
-->
|
||||
<div class="block-section-bar">
|
||||
<div class="sb-title">Eng. S/W의 구성</div>
|
||||
<div class="sb-sub">Engineering Software Components</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-section-bar {
|
||||
background: linear-gradient(135deg, #0d47a1 0%, #1565c0 100%);
|
||||
border-radius: 6px;
|
||||
padding: 14px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.sb-title {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.sb-sub {
|
||||
font-size: 12px;
|
||||
color: rgba(255,255,255,0.8);
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>headers/section-title-with-bg</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 섹션 타이틀: 배경 헤더 위 영문+한글 타이틀 오버레이 -->
|
||||
<!--
|
||||
📋 section-title
|
||||
─────────────────
|
||||
용도: 자세히보기 페이지 상단, 배경 이미지 위에 타이틀 표시
|
||||
슬롯: title_ko (필수), title_en (선택), breadcrumb (선택), bg_image (선택)
|
||||
Figma 원본: 공통 > section_title + bg 컴포넌트
|
||||
-->
|
||||
<div class="block-section-title">
|
||||
|
||||
<img class="st-bg" src="../figma-assets/bg_header.png" alt="">
|
||||
|
||||
|
||||
<div class="st-breadcrumb">건설산업에서의 디지털전환 › BIM</div>
|
||||
|
||||
<div class="st-text">
|
||||
<div class="st-en">Building Information Modeling</div>
|
||||
<div class="st-ko">건설정보모델링(BIM)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-section-title {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.st-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
z-index: 1;
|
||||
}
|
||||
.st-bg-default {
|
||||
background: linear-gradient(135deg, #1e3a5f 0%, #2563eb 50%, #4dc4ff 100%);
|
||||
}
|
||||
.st-breadcrumb {
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
left: 89px;
|
||||
z-index: 5;
|
||||
font-size: 13px;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
.st-text {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
left: 89px;
|
||||
z-index: 5;
|
||||
}
|
||||
.st-en {
|
||||
font-size: 15px;
|
||||
font-weight: var(--weight-normal, 400);
|
||||
color: #ffffff;
|
||||
opacity: 0.85;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.st-ko {
|
||||
font-size: 35px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
color: #ffffff;
|
||||
line-height: 1.3;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
91
04. design_agent/docs/block-tests/headers_topic-center.html
Normal file
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>headers/topic-center</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 중앙 정렬 꼭지 헤더: 대제목 + 하단 설명 -->
|
||||
<!--
|
||||
📋 topic-center
|
||||
─────────────────
|
||||
용도: 단독 강조 꼭지, 페이지 중심 주제 선언
|
||||
슬롯: title (필수), subtitle (선택), description (선택)
|
||||
Figma 원본: 2-2_02 "디지털전환을 위한 S/W 필요성"
|
||||
-->
|
||||
<div class="block-topic-center">
|
||||
<div class="tc-title">디지털전환을 위한
|
||||
S/W 필요성</div>
|
||||
<div class="tc-sub">Software Requirements for DX</div>
|
||||
<div class="tc-desc">건설산업의 DX를 실현하기 위해서는 기존 상용 S/W의 한계를 넘어
|
||||
전문·전용 소프트웨어의 개발과 도입이 필수적입니다.</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-topic-center {
|
||||
text-align: center;
|
||||
padding: 20px 40px;
|
||||
}
|
||||
.tc-title {
|
||||
font-size: 26px;
|
||||
font-weight: 900;
|
||||
color: #1e293b;
|
||||
line-height: 1.4;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.tc-sub {
|
||||
font-size: 14px;
|
||||
color: #2563eb;
|
||||
font-weight: 600;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.tc-desc {
|
||||
font-size: 15px;
|
||||
color: #475569;
|
||||
line-height: 1.7;
|
||||
margin-top: 12px;
|
||||
word-break: keep-all;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>headers/topic-left-right</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 꼭지 제목+설명: 좌측 질문/소제목 + 우측 설명 -->
|
||||
<!--
|
||||
📋 topic-header
|
||||
─────────────────
|
||||
용도: 각 꼭지의 시작부, 좌측에 파란 굵은 제목 + 우측에 본문 설명
|
||||
슬롯: title (필수), description (필수)
|
||||
비율: 좌 240px : 우 나머지
|
||||
Figma 원본: sub_제목,내용 (742x68~78)
|
||||
-->
|
||||
<div class="block-topic-header">
|
||||
<div class="th-title">단순 BIM의 적용이
|
||||
D/X가 아닙니다</div>
|
||||
<div class="th-desc">BIM은 건설산업의 디지털전환을 수행하는 과정에서 가장 기초가 되는 일부분임을 인지하는 것이 매우 중요합니다.</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-topic-header {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
padding: 12px 0;
|
||||
}
|
||||
.th-title {
|
||||
width: 240px;
|
||||
flex-shrink: 0;
|
||||
font-size: 24px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
color: var(--color-accent-deep, #004cbe);
|
||||
line-height: 1.4;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.th-desc {
|
||||
flex: 1;
|
||||
font-size: 16px;
|
||||
font-weight: var(--weight-normal, 400);
|
||||
color: var(--color-text, #000000);
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
105
04. design_agent/docs/block-tests/headers_topic-numbered.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>headers/topic-numbered</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 번호 꼭지 헤더: 번호 원형 + 제목 + 구분선 + 설명 -->
|
||||
<!--
|
||||
📋 topic-numbered
|
||||
─────────────────
|
||||
용도: 순서가 있는 꼭지 시작, 단계별 섹션 헤더
|
||||
슬롯: number, title, description (선택), color (선택)
|
||||
topic-left-right와 다른 점: 좌우 배치가 아닌 번호+세로 배치
|
||||
-->
|
||||
<div class="block-topic-num">
|
||||
<div class="tn-header">
|
||||
<div class="tn-number" style="background: #2563eb">1</div>
|
||||
<div class="tn-title">건설산업의 디지털전환(DX)</div>
|
||||
</div>
|
||||
<div class="tn-divider" style="background: #2563eb"></div>
|
||||
<div class="tn-desc">건설산업은 디지털 기술의 발전에 따라 빠르게 변화하고 있으며, 생산성 향상과 안전성 강화를 목표로 디지털전환이 가속화되고 있습니다.</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-topic-num {
|
||||
padding: 8px 0;
|
||||
}
|
||||
.tn-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.tn-number {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.tn-title {
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
color: #1e293b;
|
||||
}
|
||||
.tn-divider {
|
||||
height: 2px;
|
||||
margin: 8px 0 10px;
|
||||
border-radius: 1px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.tn-desc {
|
||||
font-size: 15px;
|
||||
color: #475569;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body></html>
|
||||
120
04. design_agent/docs/block-tests/image-row.html
Normal file
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>블록 테스트: image-row</title>
|
||||
<style>
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Pretendard Variable", "Noto Sans KR", sans-serif;
|
||||
background: #e8ecf0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
.block-container {
|
||||
width: 920px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
.block-container .block-section-title {
|
||||
margin: -20px -20px 0;
|
||||
border-radius: 8px 8px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
<!-- 이미지 행: 2~4장 이미지 나란히 -->
|
||||
<!--
|
||||
📋 image-row
|
||||
─────────────────
|
||||
용도: 시공 사진, 근거 자료, 현장 이미지 나란히 배치
|
||||
슬롯: images[] 배열 (각 이미지에 src, alt, caption)
|
||||
Figma 원본: 2-1_02 > image grid (460x354 x 2)
|
||||
-->
|
||||
<div class="block-image-row" style="--ir-count: 2">
|
||||
|
||||
<div class="ir-item">
|
||||
<img src="figma-assets/image_grid_left.png" alt="현장1">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="ir-item">
|
||||
<img src="figma-assets/image_grid_right.png" alt="현장2">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-image-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--ir-count, 2), 1fr);
|
||||
gap: 0;
|
||||
}
|
||||
.ir-item {
|
||||
overflow: hidden;
|
||||
}
|
||||
.ir-item img {
|
||||
width: 100%;
|
||||
height: 354px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.ir-caption {
|
||||
font-size: 11px;
|
||||
color: var(--color-text-light, #94a3b8);
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
108
04. design_agent/docs/block-tests/media_image-before-after.html
Normal file
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>media/image-before-after</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- Before/After 이미지: 좌측 Before + 우측 After + 화살표 -->
|
||||
<!--
|
||||
📋 image-before-after
|
||||
─────────────────
|
||||
용도: 변화 전후 비교, 공정 전후, 디지털 전환 전후
|
||||
슬롯: before_src, before_label, after_src, after_label, caption (선택)
|
||||
-->
|
||||
<div class="block-ba">
|
||||
<div class="ba-item">
|
||||
<div class="ba-label ba-before">기존 방식</div>
|
||||
<img src="../figma-assets/card_img_construction.png" alt="before">
|
||||
</div>
|
||||
<div class="ba-arrow">→</div>
|
||||
<div class="ba-item">
|
||||
<div class="ba-label ba-after">DX 적용 후</div>
|
||||
<img src="../figma-assets/card_img_design.png" alt="after">
|
||||
</div>
|
||||
</div>
|
||||
<div class="ba-caption">건설 현장의 디지털 전환 전후 비교</div>
|
||||
|
||||
<style>
|
||||
.block-ba {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
.ba-item {
|
||||
flex: 1;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
.ba-label {
|
||||
padding: 6px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
}
|
||||
.ba-before { background: #6b7280; }
|
||||
.ba-after { background: #2563eb; }
|
||||
.ba-item img {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.ba-arrow {
|
||||
font-size: 2rem;
|
||||
color: #2563eb;
|
||||
font-weight: 900;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ba-caption {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
text-align: center;
|
||||
margin-top: 8px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>media/image-full-caption</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 전체 너비 이미지 + 캡션 -->
|
||||
<!--
|
||||
📋 image-full-caption
|
||||
─────────────────
|
||||
용도: 핵심 도표, 대형 다이어그램, 전경 사진을 전체 너비로 표시
|
||||
슬롯: src (필수), alt (선택), caption (선택)
|
||||
Figma 원본: 2-3_05 하단 전경 사진, 2-3_03 하단 항공 사진
|
||||
-->
|
||||
<div class="block-img-full">
|
||||
<img src="../figma-assets/image_grid_left.png" alt="건설 현장 전경">
|
||||
<div class="if-caption">[사진] 인프라 건설 현장 전경 — 디지털 전환의 현장 적용</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-img-full {
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.block-img-full img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
.if-caption {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
text-align: center;
|
||||
padding: 6px;
|
||||
background: #f8fafc;
|
||||
}
|
||||
</style></div></body></html>
|
||||
111
04. design_agent/docs/block-tests/media_image-grid-2x2.html
Normal file
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>media/image-grid-2x2</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 이미지 2x2 그리드: 4장 이미지 격자 배치 -->
|
||||
<!--
|
||||
📋 image-grid-2x2
|
||||
─────────────────
|
||||
용도: 현장 사진 4장, 참고 이미지 4장, 사례 이미지 갤러리
|
||||
슬롯: images[] (4개, 각각 src, alt, caption)
|
||||
Figma 원본: 2-1_03 GIS 항공/위성/현장 사진
|
||||
-->
|
||||
<div class="block-img-2x2">
|
||||
|
||||
<div class="ig-item">
|
||||
<img src="../figma-assets/image_grid_left.png" alt="현장1">
|
||||
<div class="ig-caption">항공측량 데이터</div>
|
||||
</div>
|
||||
|
||||
<div class="ig-item">
|
||||
<img src="../figma-assets/image_grid_right.png" alt="현장2">
|
||||
<div class="ig-caption">시공 현장</div>
|
||||
</div>
|
||||
|
||||
<div class="ig-item">
|
||||
<img src="../figma-assets/card_img_design.png" alt="설계">
|
||||
<div class="ig-caption">3D 지형 모델</div>
|
||||
</div>
|
||||
|
||||
<div class="ig-item">
|
||||
<img src="../figma-assets/card_img_construction.png" alt="시공">
|
||||
<div class="ig-caption">시공 BIM 모델</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-img-2x2 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
.ig-item {
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.ig-item img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.ig-caption {
|
||||
font-size: 11px;
|
||||
color: #64748b;
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
background: #f8f9fb;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
100
04. design_agent/docs/block-tests/media_image-row-2col.html
Normal file
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>media/image-row-2col</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 이미지 행: 2~4장 이미지 나란히 -->
|
||||
<!--
|
||||
📋 image-row
|
||||
─────────────────
|
||||
용도: 시공 사진, 근거 자료, 현장 이미지 나란히 배치
|
||||
슬롯: images[] 배열 (각 이미지에 src, alt, caption)
|
||||
Figma 원본: 2-1_02 > image grid (460x354 x 2)
|
||||
-->
|
||||
<div class="block-image-row" style="--ir-count: 2">
|
||||
|
||||
<div class="ir-item">
|
||||
<img src="../figma-assets/image_grid_left.png" alt="시공 현장 1">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="ir-item">
|
||||
<img src="../figma-assets/image_grid_right.png" alt="시공 현장 2">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-image-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--ir-count, 2), 1fr);
|
||||
gap: 0;
|
||||
}
|
||||
.ir-item {
|
||||
overflow: hidden;
|
||||
}
|
||||
.ir-item img {
|
||||
width: 100%;
|
||||
height: 354px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.ir-caption {
|
||||
font-size: 11px;
|
||||
color: var(--color-text-light, #94a3b8);
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
130
04. design_agent/docs/block-tests/media_image-side-text.html
Normal file
@@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>media/image-side-text</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 이미지+텍스트 가로 배치: 좌측 이미지 + 우측 텍스트 -->
|
||||
<!--
|
||||
📋 image-side-text
|
||||
─────────────────
|
||||
용도: 이미지에 대한 설명, 제품/시스템 소개, 참고 자료 설명
|
||||
슬롯: image_src, image_alt, title, description, bullets[]
|
||||
Figma 원본: 2-2_01 하단 이미지+텍스트 영역
|
||||
-->
|
||||
<div class="block-img-side">
|
||||
<div class="is-image">
|
||||
<img src="../figma-assets/card_img_design.png" alt="3D 지형 모델">
|
||||
</div>
|
||||
<div class="is-text">
|
||||
<div class="is-title">고도화된 BIM 설계</div>
|
||||
<div class="is-desc">최첨단 디지털트윈 기술을 활용하여 시뮬레이션 분석 및 성능평가를 수행합니다.</div>
|
||||
|
||||
<ul class="is-bullets">
|
||||
|
||||
<li>3D 지형 모델 기반 설계</li>
|
||||
|
||||
<li>시뮬레이션 분석 & 성능평가</li>
|
||||
|
||||
<li>지속가능한 인프라 개발</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-img-side {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.is-image {
|
||||
flex-shrink: 0;
|
||||
width: 320px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.is-image img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
.is-text {
|
||||
flex: 1;
|
||||
padding-top: 4px;
|
||||
}
|
||||
.is-title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.is-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.is-bullets {
|
||||
list-style: disc;
|
||||
padding-left: 18px;
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.is-bullets li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
105
04. design_agent/docs/block-tests/quote-block.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>블록 테스트: quote-block</title>
|
||||
<style>
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Pretendard Variable", "Noto Sans KR", sans-serif;
|
||||
background: #e8ecf0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
.block-container {
|
||||
width: 920px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
.block-container .block-section-title {
|
||||
margin: -20px -20px 0;
|
||||
border-radius: 8px 8px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
<!-- 강조 인용 블록: 문제 제기, 핵심 메시지 -->
|
||||
<div class="block-quote">
|
||||
<div class="quote-text">BIM은 건설산업의 디지털전환을 수행하는 과정에서 가장 기초가 되는 일부분이다</div>
|
||||
<div class="quote-source">건설산업 BIM 기본지침, 국토교통부, 2020</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-quote {
|
||||
background: var(--color-bg-subtle);
|
||||
border-left: var(--accent-border) solid var(--color-danger);
|
||||
padding: var(--spacing-inner) var(--spacing-block);
|
||||
border-radius: 0 var(--radius) var(--radius) 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.quote-text {
|
||||
font-size: var(--font-body);
|
||||
color: var(--color-text);
|
||||
line-height: var(--line-height-ko);
|
||||
font-weight: var(--weight-medium);
|
||||
}
|
||||
.quote-source {
|
||||
font-size: var(--font-caption);
|
||||
color: var(--color-text-light);
|
||||
font-style: italic;
|
||||
margin-top: var(--spacing-small);
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
143
04. design_agent/docs/block-tests/section-title.html
Normal file
@@ -0,0 +1,143 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>블록 테스트: section-title</title>
|
||||
<style>
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Pretendard Variable", "Noto Sans KR", sans-serif;
|
||||
background: #e8ecf0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
.block-container {
|
||||
width: 920px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
.block-container .block-section-title {
|
||||
margin: -20px -20px 0;
|
||||
border-radius: 8px 8px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
<!-- 섹션 타이틀: 배경 헤더 위 영문+한글 타이틀 오버레이 -->
|
||||
<!--
|
||||
📋 section-title
|
||||
─────────────────
|
||||
용도: 자세히보기 페이지 상단, 배경 이미지 위에 타이틀 표시
|
||||
슬롯: title_ko (필수), title_en (선택), breadcrumb (선택), bg_image (선택)
|
||||
Figma 원본: 공통 > section_title + bg 컴포넌트
|
||||
-->
|
||||
<div class="block-section-title">
|
||||
|
||||
<img class="st-bg" src="figma-assets/bg_header.png" alt="">
|
||||
|
||||
|
||||
<div class="st-breadcrumb">건설산업에서의 디지털전환 › BIM</div>
|
||||
|
||||
<div class="st-text">
|
||||
<div class="st-en">Building Information Modeling</div>
|
||||
<div class="st-ko">건설정보모델링(BIM)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-section-title {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.st-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
z-index: 1;
|
||||
}
|
||||
.st-bg-default {
|
||||
background: linear-gradient(135deg, #1e3a5f 0%, #2563eb 50%, #4dc4ff 100%);
|
||||
}
|
||||
.st-breadcrumb {
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
left: 89px;
|
||||
z-index: 5;
|
||||
font-size: 13px;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
.st-text {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
left: 89px;
|
||||
z-index: 5;
|
||||
}
|
||||
.st-en {
|
||||
font-size: 15px;
|
||||
font-weight: var(--weight-normal, 400);
|
||||
color: #ffffff;
|
||||
opacity: 0.85;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.st-ko {
|
||||
font-size: 35px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
color: #ffffff;
|
||||
line-height: 1.3;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
141
04. design_agent/docs/block-tests/tables_compare-2col-split.html
Normal file
@@ -0,0 +1,141 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>tables/compare-2col-split</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 2단 분할 비교: 좌측 GIS / 우측 BIM 같은 상세 비교 -->
|
||||
<!--
|
||||
📋 compare-2col-split
|
||||
─────────────────
|
||||
용도: 두 개념/기술의 상세 항목별 비교 (좌우 나란히, 중앙 기준 라벨)
|
||||
슬롯: left_title, right_title, rows[] (각 행에 criteria, left, right)
|
||||
Figma 원본: 2-3_03 GIS vs BIM 비교 (개념/분석/도면/발전 등)
|
||||
-->
|
||||
<div class="block-split-compare">
|
||||
<div class="sc-header">
|
||||
<div class="sc-h-left">GIS</div>
|
||||
<div class="sc-h-center">구분</div>
|
||||
<div class="sc-h-right">BIM</div>
|
||||
</div>
|
||||
|
||||
<div class="sc-row sc-row-odd">
|
||||
<div class="sc-left">지리적 데이터를
|
||||
공간 분석하여 시각적 표현</div>
|
||||
<div class="sc-center">개념</div>
|
||||
<div class="sc-right">3D 모델 기반
|
||||
건설 정보 통합 관리</div>
|
||||
</div>
|
||||
|
||||
<div class="sc-row ">
|
||||
<div class="sc-left">Surface Shape 분석
|
||||
지형/지질 해석</div>
|
||||
<div class="sc-center">분석</div>
|
||||
<div class="sc-right">Object Shape 분석
|
||||
구조/설비 해석</div>
|
||||
</div>
|
||||
|
||||
<div class="sc-row sc-row-odd">
|
||||
<div class="sc-left">GIS, 지도, 배치도</div>
|
||||
<div class="sc-center">도면</div>
|
||||
<div class="sc-right">CAD, BIM 모델</div>
|
||||
</div>
|
||||
|
||||
<div class="sc-row ">
|
||||
<div class="sc-left">GIS ↔ SPCC</div>
|
||||
<div class="sc-center">발전</div>
|
||||
<div class="sc-right">CAD → BIM</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-split-compare {
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sc-header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 100px 1fr;
|
||||
background: linear-gradient(135deg, #0d47a1, #1565c0);
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
.sc-h-left, .sc-h-right, .sc-h-center {
|
||||
padding: 12px;
|
||||
}
|
||||
.sc-h-center {
|
||||
background: rgba(0,0,0,0.15);
|
||||
font-size: 13px;
|
||||
}
|
||||
.sc-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 100px 1fr;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
}
|
||||
.sc-row-odd {
|
||||
background: #f8fafc;
|
||||
}
|
||||
.sc-left, .sc-right {
|
||||
padding: 10px 14px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: #334155;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.sc-center {
|
||||
padding: 10px 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #1565c0;
|
||||
text-align: center;
|
||||
background: #f0f7ff;
|
||||
border-left: 1px solid #e2e8f0;
|
||||
border-right: 1px solid #e2e8f0;
|
||||
}
|
||||
</style></div></body></html>
|
||||
219
04. design_agent/docs/block-tests/tables_compare-3col-badge.html
Normal file
@@ -0,0 +1,219 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>tables/compare-3col-badge</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 비교 테이블: BIM vs DX 스타일 3단 테이블 -->
|
||||
<!--
|
||||
📋 comparison-table
|
||||
─────────────────
|
||||
용도: 다항목 비교 (좌측 A | 중앙 기준 | 우측 B)
|
||||
슬롯: headers[] (3개), rows[][] (각 행 3칸)
|
||||
Figma 원본: 2-1_02 > BIM VS D/X 테이블
|
||||
특징: 중앙 칼럼에 파란 그라데이션 배지, 좌우 불릿 대비
|
||||
-->
|
||||
<div class="block-table-figma">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th class="th-left">
|
||||
BIM
|
||||
</th>
|
||||
|
||||
<th class="th-center">
|
||||
<span class="th-badge">VS</span>
|
||||
</th>
|
||||
|
||||
<th class="th-right">
|
||||
D/X
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• Only 3D</td>
|
||||
|
||||
<td class="td-center">BIM · D/X</td>
|
||||
|
||||
<td class="td-right">• BIM ≪ D/X (ENG. + Management 포함)</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 모델 제작용 상용 S/W
|
||||
(Civil 3D, Revit, Navisworks)</td>
|
||||
|
||||
<td class="td-center">S/W</td>
|
||||
|
||||
<td class="td-right">• 제작 및 운영(상용 + 전용 40~80개)
|
||||
[Rhino, Sketchup, Blender...]</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 기존 2D 설계방식 유지</td>
|
||||
|
||||
<td class="td-center">프로세스</td>
|
||||
|
||||
<td class="td-right">• 근본적 문제의식을 통한 개선</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 3D 모델 중심
|
||||
• 기존 성과품 유지</td>
|
||||
|
||||
<td class="td-center">성과물</td>
|
||||
|
||||
<td class="td-right">• 공학 정보 및 콘텐츠 연계에 집중
|
||||
• 도면, 수량, 시공계획 등 일식</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• 3D 모델에 의한 일반적 이해 향상</td>
|
||||
|
||||
<td class="td-center">활용</td>
|
||||
|
||||
<td class="td-right">• 설계/시공의 혁신(개념의 재정립)</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="td-left">• (설계/시공/운영) 분야별 단절</td>
|
||||
|
||||
<td class="td-center">확장성</td>
|
||||
|
||||
<td class="td-right">• 전 생애주기 활용 시스템</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-table-figma {
|
||||
overflow: auto;
|
||||
}
|
||||
.block-table-figma table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* 헤더 */
|
||||
.block-table-figma thead th {
|
||||
padding: 14px 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
border-bottom: 2px solid #e8edf2;
|
||||
}
|
||||
.th-left {
|
||||
text-align: center;
|
||||
color: #6bcdff;
|
||||
}
|
||||
.th-center {
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
}
|
||||
.th-badge {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, #006eff 0%, #00aaff 100%);
|
||||
color: #ffffff;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
padding: 8px 28px;
|
||||
border-radius: 25px;
|
||||
}
|
||||
.th-right {
|
||||
text-align: center;
|
||||
color: #006eff;
|
||||
}
|
||||
|
||||
/* 본문 */
|
||||
.block-table-figma tbody td {
|
||||
padding: 10px 14px;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.td-left {
|
||||
text-align: center;
|
||||
color: #444;
|
||||
}
|
||||
.td-center {
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
background: #f6f8fb;
|
||||
font-size: 13px;
|
||||
}
|
||||
.td-right {
|
||||
text-align: center;
|
||||
color: #444;
|
||||
}
|
||||
.block-table-figma tbody tr:hover {
|
||||
background: #fafbfd;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
@@ -0,0 +1,154 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>tables/table-simple-striped</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 심플 줄무늬 테이블: 범용 데이터 테이블 -->
|
||||
<!--
|
||||
📋 table-simple-striped
|
||||
─────────────────
|
||||
용도: 스펙, 수치, 일정, 항목별 데이터 나열
|
||||
슬롯: headers[], rows[][]
|
||||
compare-3col-badge와 다른 점: VS 배지 없음, 범용 데이터용
|
||||
-->
|
||||
<div class="block-table-striped">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>구분</th>
|
||||
|
||||
<th>현재</th>
|
||||
|
||||
<th>목표</th>
|
||||
|
||||
<th>비고</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>BIM 적용률</td>
|
||||
|
||||
<td>30%</td>
|
||||
|
||||
<td>100%</td>
|
||||
|
||||
<td>2025 목표</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>디지털 전환 수준</td>
|
||||
|
||||
<td>초기</td>
|
||||
|
||||
<td>고도화</td>
|
||||
|
||||
<td>단계적 추진</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>전문 인력</td>
|
||||
|
||||
<td>50명</td>
|
||||
|
||||
<td>220명+</td>
|
||||
|
||||
<td>IT+CIVIL</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td>자체 S/W</td>
|
||||
|
||||
<td>5개</td>
|
||||
|
||||
<td>80개+</td>
|
||||
|
||||
<td>지속 개발</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-table-striped table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.block-table-striped thead th {
|
||||
background: #1e293b;
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
}
|
||||
.block-table-striped tbody td {
|
||||
padding: 9px 14px;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
white-space: pre-line;
|
||||
color: #334155;
|
||||
}
|
||||
.block-table-striped tbody tr:nth-child(even) {
|
||||
background: #f8fafc;
|
||||
}
|
||||
.block-table-striped tbody td:first-child {
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
}
|
||||
</style></div></body></html>
|
||||
115
04. design_agent/docs/block-tests/topic-header.html
Normal file
@@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>블록 테스트: topic-header</title>
|
||||
<style>
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Pretendard Variable", "Noto Sans KR", sans-serif;
|
||||
background: #e8ecf0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
.block-container {
|
||||
width: 920px;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
.block-container .block-section-title {
|
||||
margin: -20px -20px 0;
|
||||
border-radius: 8px 8px 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
<!-- 꼭지 제목+설명: 좌측 질문/소제목 + 우측 설명 -->
|
||||
<!--
|
||||
📋 topic-header
|
||||
─────────────────
|
||||
용도: 각 꼭지의 시작부, 좌측에 파란 굵은 제목 + 우측에 본문 설명
|
||||
슬롯: title (필수), description (필수)
|
||||
비율: 좌 240px : 우 나머지
|
||||
Figma 원본: sub_제목,내용 (742x68~78)
|
||||
-->
|
||||
<div class="block-topic-header">
|
||||
<div class="th-title">단순 BIM의 적용이
|
||||
D/X가 아닙니다</div>
|
||||
<div class="th-desc">BIM은 건설산업의 디지털전환을 수행하는 과정에서 가장 기초가 되는 일부분임을 인지하는 것이 매우 중요합니다.</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-topic-header {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
padding: 12px 0;
|
||||
}
|
||||
.th-title {
|
||||
width: 240px;
|
||||
flex-shrink: 0;
|
||||
font-size: 24px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
color: var(--color-accent-deep, #004cbe);
|
||||
line-height: 1.4;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.th-desc {
|
||||
flex: 1;
|
||||
font-size: 16px;
|
||||
font-weight: var(--weight-normal, 400);
|
||||
color: var(--color-text, #000000);
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
04. design_agent/docs/block-tests/venn_premium_bg.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
113
04. design_agent/docs/block-tests/visuals_circle-gradient.html
Normal file
@@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>visuals/circle-gradient</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 원형 라벨: CSS 그라데이션 원 + 중앙 텍스트 -->
|
||||
<!--
|
||||
📋 circle-label
|
||||
─────────────────
|
||||
용도: 섹션 전환점, 핵심 키워드 강조, 시각적 구분자
|
||||
슬롯: label (필수), sub_label (선택)
|
||||
Figma 원본: 2-1_02 > Group 1171281590 (190x190)
|
||||
-->
|
||||
<div class="block-circle-label">
|
||||
<div class="cl-outer">
|
||||
<div class="cl-inner">
|
||||
<div class="cl-text">단계별
|
||||
BIM의 활용</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-circle-label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.cl-outer {
|
||||
width: 190px;
|
||||
height: 190px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, #3db8ff 0%, #006aff 100%);
|
||||
box-shadow: 0 0 30px rgba(0, 106, 255, 0.25), 0 0 60px rgba(0, 106, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.cl-inner {
|
||||
width: 170px;
|
||||
height: 170px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, #4dc4ff 0%, #0080ff 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
}
|
||||
.cl-text {
|
||||
font-size: 20px;
|
||||
font-weight: var(--weight-bold, 700);
|
||||
line-height: 1.4;
|
||||
}
|
||||
.cl-sub {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
131
04. design_agent/docs/block-tests/visuals_compare-pill-pair.html
Normal file
@@ -0,0 +1,131 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>visuals/compare-pill-pair</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 비교 박스: 이중 테두리 둥근 박스 2개 + VS -->
|
||||
<!--
|
||||
📋 compare-pill-pair
|
||||
─────────────────
|
||||
용도: 2개 개념 시각적 대비 (비교 테이블 위 헤더)
|
||||
슬롯: left_label, left_sub, right_label, right_sub
|
||||
Figma 원본: 이중 테두리 (바깥 얇은 선 + 안쪽 둥근 박스)
|
||||
-->
|
||||
<div class="block-compare-pill">
|
||||
<div class="cp-item">
|
||||
<div class="cp-outer">
|
||||
<div class="cp-inner">
|
||||
<div class="cp-label">디지털 기술을 활용한
|
||||
협업 프로세스</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cp-vs">VS</div>
|
||||
<div class="cp-item">
|
||||
<div class="cp-outer">
|
||||
<div class="cp-inner">
|
||||
<div class="cp-label">시설물의 전 생애주기 동안
|
||||
정보의 생성 및 관리</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-compare-pill {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.cp-item {
|
||||
width: 350px;
|
||||
}
|
||||
.cp-outer {
|
||||
border: 2px solid #a8d8f0;
|
||||
border-radius: 60px;
|
||||
padding: 6px;
|
||||
background: transparent;
|
||||
}
|
||||
.cp-inner {
|
||||
border: 2px solid #7ec8f0;
|
||||
border-radius: 55px;
|
||||
background: linear-gradient(135deg, #e8f4fd 0%, #d6edfa 100%);
|
||||
padding: 18px 30px;
|
||||
text-align: center;
|
||||
}
|
||||
.cp-label {
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
color: #0088cc;
|
||||
line-height: 1.4;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.cp-sub {
|
||||
font-size: 12px;
|
||||
color: #0088cc;
|
||||
margin-top: 4px;
|
||||
line-height: 1.5;
|
||||
white-space: pre-line;
|
||||
font-weight: 500;
|
||||
}
|
||||
.cp-vs {
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>visuals/flow-arrow-horizontal</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 가로 흐름도: 좌→우 화살표로 연결된 단계 (SVG) -->
|
||||
<!--
|
||||
📋 flow-arrow-horizontal
|
||||
─────────────────
|
||||
용도: 발전 과정, 기술 진화, 전환 흐름 (A → B → C)
|
||||
슬롯: steps[] (각 단계에 label, sub)
|
||||
Figma 원본: 2-3_03 "GIS ↔ SPCC → 토공 → ..." / 2-2_04 개발 패러다임
|
||||
-->
|
||||
<div class="block-flow-h">
|
||||
<svg viewBox="0 0 720 80" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
|
||||
|
||||
<rect x="10" y="10" width="120" height="50" rx="25" fill="#059669" opacity="0.9" />
|
||||
<text x="70" y="32" text-anchor="middle" fill="white" font-size="13" font-weight="700">GIS</text>
|
||||
|
||||
|
||||
<polygon points="135,35 150,35 145,28" fill="#94a3b8" />
|
||||
<polygon points="135,35 150,35 145,42" fill="#94a3b8" />
|
||||
|
||||
|
||||
|
||||
<rect x="190" y="10" width="120" height="50" rx="25" fill="#2563eb" opacity="0.9" />
|
||||
<text x="250" y="32" text-anchor="middle" fill="white" font-size="13" font-weight="700">SPCC</text>
|
||||
|
||||
|
||||
<polygon points="315,35 330,35 325,28" fill="#94a3b8" />
|
||||
<polygon points="315,35 330,35 325,42" fill="#94a3b8" />
|
||||
|
||||
|
||||
|
||||
<rect x="370" y="10" width="120" height="50" rx="25" fill="#7c3aed" opacity="0.9" />
|
||||
<text x="430" y="32" text-anchor="middle" fill="white" font-size="13" font-weight="700">토공</text>
|
||||
|
||||
|
||||
<polygon points="495,35 510,35 505,28" fill="#94a3b8" />
|
||||
<polygon points="495,35 510,35 505,42" fill="#94a3b8" />
|
||||
|
||||
|
||||
|
||||
<rect x="550" y="10" width="120" height="50" rx="25" fill="#dc2626" opacity="0.9" />
|
||||
<text x="610" y="32" text-anchor="middle" fill="white" font-size="13" font-weight="700">BIM</text>
|
||||
|
||||
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-flow-h {
|
||||
padding: 10px 0;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.block-flow-h svg {
|
||||
min-width: 400px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,153 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>visuals/keyword-circle-row</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 키워드 원형 행: 원 안에 키워드 + 하단 설명 (SVG) -->
|
||||
<!--
|
||||
📋 keyword-circle-row
|
||||
─────────────────
|
||||
용도: 핵심 키워드를 원형으로 나열하며 각각 설명. 약어 풀이.
|
||||
슬롯: keywords[] (각 항목에 letter, label, description, color)
|
||||
Figma 원본: 2-3_03 G-S-I-M 약어 설명, 2-2_04 개발 조건 키워드
|
||||
-->
|
||||
<div class="block-kw-circles">
|
||||
|
||||
<div class="kw-item">
|
||||
<svg viewBox="0 0 80 80" width="70" height="70" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<radialGradient id="kwGrad1" cx="40%" cy="35%" r="60%">
|
||||
<stop offset="0%" stop-color="#6ee7b7" />
|
||||
<stop offset="100%" stop-color="#059669" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<circle cx="40" cy="40" r="38" fill="url(#kwGrad1)" />
|
||||
<text x="40" y="44" text-anchor="middle" dominant-baseline="central" fill="white" font-size="28" font-weight="900" font-family="Pretendard Variable, sans-serif">G</text>
|
||||
</svg>
|
||||
<div class="kw-label">Geographic</div>
|
||||
<div class="kw-desc">지리적 위치
|
||||
공간 정보</div>
|
||||
</div>
|
||||
|
||||
<div class="kw-item">
|
||||
<svg viewBox="0 0 80 80" width="70" height="70" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<radialGradient id="kwGrad2" cx="40%" cy="35%" r="60%">
|
||||
<stop offset="0%" stop-color="#93c5fd" />
|
||||
<stop offset="100%" stop-color="#2563eb" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<circle cx="40" cy="40" r="38" fill="url(#kwGrad2)" />
|
||||
<text x="40" y="44" text-anchor="middle" dominant-baseline="central" fill="white" font-size="28" font-weight="900" font-family="Pretendard Variable, sans-serif">S</text>
|
||||
</svg>
|
||||
<div class="kw-label">Structure</div>
|
||||
<div class="kw-desc">구조물
|
||||
형상 정보</div>
|
||||
</div>
|
||||
|
||||
<div class="kw-item">
|
||||
<svg viewBox="0 0 80 80" width="70" height="70" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<radialGradient id="kwGrad3" cx="40%" cy="35%" r="60%">
|
||||
<stop offset="0%" stop-color="#c4b5fd" />
|
||||
<stop offset="100%" stop-color="#7c3aed" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<circle cx="40" cy="40" r="38" fill="url(#kwGrad3)" />
|
||||
<text x="40" y="44" text-anchor="middle" dominant-baseline="central" fill="white" font-size="28" font-weight="900" font-family="Pretendard Variable, sans-serif">I</text>
|
||||
</svg>
|
||||
<div class="kw-label">Information</div>
|
||||
<div class="kw-desc">건설 정보
|
||||
속성 데이터</div>
|
||||
</div>
|
||||
|
||||
<div class="kw-item">
|
||||
<svg viewBox="0 0 80 80" width="70" height="70" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<radialGradient id="kwGrad4" cx="40%" cy="35%" r="60%">
|
||||
<stop offset="0%" stop-color="#fca5a5" />
|
||||
<stop offset="100%" stop-color="#dc2626" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<circle cx="40" cy="40" r="38" fill="url(#kwGrad4)" />
|
||||
<text x="40" y="44" text-anchor="middle" dominant-baseline="central" fill="white" font-size="28" font-weight="900" font-family="Pretendard Variable, sans-serif">M</text>
|
||||
</svg>
|
||||
<div class="kw-label">Model</div>
|
||||
<div class="kw-desc">3D 모델
|
||||
통합 관리</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-kw-circles {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.kw-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
width: 140px;
|
||||
}
|
||||
.kw-label {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.kw-desc {
|
||||
font-size: 12px;
|
||||
color: #475569;
|
||||
line-height: 1.5;
|
||||
margin-top: 4px;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
134
04. design_agent/docs/block-tests/visuals_layer-diagram.html
Normal file
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>visuals/layer-diagram</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 레이어 다이어그램: 겹쳐진 레이어 표현 (SVG) -->
|
||||
<!--
|
||||
📋 layer-diagram
|
||||
─────────────────
|
||||
용도: GIS/BIM/DT 레이어 구조, 기술 스택, 계층 구조 시각화
|
||||
슬롯: layers[] (각 레이어에 label, color), title (선택)
|
||||
Figma 원본: 1장_1-1_미래 "GIS+BIM+DT 레이어 시각화"
|
||||
-->
|
||||
<div class="block-layer-diag">
|
||||
<div class="ld-title">건설산업 DX 기술 레이어</div>
|
||||
<svg viewBox="0 0 400 280" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
|
||||
<linearGradient id="layerGrad1" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#7c3aed" stop-opacity="0.85" />
|
||||
<stop offset="100%" stop-color="#7c3aed" stop-opacity="0.6" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="layerGrad2" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#2563eb" stop-opacity="0.85" />
|
||||
<stop offset="100%" stop-color="#2563eb" stop-opacity="0.6" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="layerGrad3" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#059669" stop-opacity="0.85" />
|
||||
<stop offset="100%" stop-color="#059669" stop-opacity="0.6" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="layerGrad4" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#475569" stop-opacity="0.85" />
|
||||
<stop offset="100%" stop-color="#475569" stop-opacity="0.6" />
|
||||
</linearGradient>
|
||||
|
||||
<filter id="layerShadow">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-opacity="0.15" />
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
|
||||
|
||||
<!-- 3D 효과: 사다리꼴 레이어 -->
|
||||
<path d="M 40,185 L 360,185 L 340,225 L 60,225 Z"
|
||||
fill="url(#layerGrad1)" filter="url(#layerShadow)" />
|
||||
<text x="200" y="210" text-anchor="middle" fill="white" font-size="14" font-weight="700">Digital Twin (가상환경)</text>
|
||||
|
||||
|
||||
|
||||
<!-- 3D 효과: 사다리꼴 레이어 -->
|
||||
<path d="M 55,130 L 345,130 L 325,170 L 75,170 Z"
|
||||
fill="url(#layerGrad2)" filter="url(#layerShadow)" />
|
||||
<text x="200" y="155" text-anchor="middle" fill="white" font-size="14" font-weight="700">BIM (건설정보모델링)</text>
|
||||
|
||||
|
||||
|
||||
<!-- 3D 효과: 사다리꼴 레이어 -->
|
||||
<path d="M 70,75 L 330,75 L 310,115 L 90,115 Z"
|
||||
fill="url(#layerGrad3)" filter="url(#layerShadow)" />
|
||||
<text x="200" y="100" text-anchor="middle" fill="white" font-size="14" font-weight="700">GIS (공간정보시스템)</text>
|
||||
|
||||
|
||||
|
||||
<!-- 3D 효과: 사다리꼴 레이어 -->
|
||||
<path d="M 85,20 L 315,20 L 295,60 L 105,60 Z"
|
||||
fill="url(#layerGrad4)" filter="url(#layerShadow)" />
|
||||
<text x="200" y="45" text-anchor="middle" fill="white" font-size="14" font-weight="700">실세계 인프라</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-layer-diag {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.ld-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
}
|
||||
.block-layer-diag svg {
|
||||
max-width: 400px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,142 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>visuals/process-horizontal</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
.block-container .block-section-title { margin: -20px -20px 0; border-radius: 8px 8px 0 0; overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 프로세스 블록: 가로 단계 흐름 -->
|
||||
<div class="block-process">
|
||||
|
||||
<div class="process-step">
|
||||
<div class="process-number">1</div>
|
||||
<div class="process-title">요구사항 분석</div>
|
||||
<div class="process-desc">목표 수립</div>
|
||||
</div>
|
||||
|
||||
<div class="process-arrow">→</div>
|
||||
|
||||
|
||||
<div class="process-step">
|
||||
<div class="process-number">2</div>
|
||||
<div class="process-title">S/W 개발</div>
|
||||
<div class="process-desc">솔루션 개발</div>
|
||||
</div>
|
||||
|
||||
<div class="process-arrow">→</div>
|
||||
|
||||
|
||||
<div class="process-step">
|
||||
<div class="process-number">3</div>
|
||||
<div class="process-title">System 통합</div>
|
||||
<div class="process-desc">데이터 통합</div>
|
||||
</div>
|
||||
|
||||
<div class="process-arrow">→</div>
|
||||
|
||||
|
||||
<div class="process-step">
|
||||
<div class="process-number">4</div>
|
||||
<div class="process-title">교육/피드백</div>
|
||||
<div class="process-desc">지속 개선</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-process {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--spacing-small);
|
||||
height: 100%;
|
||||
}
|
||||
.process-step {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: var(--spacing-inner);
|
||||
background: var(--color-bg-subtle);
|
||||
border: var(--border-width) solid var(--color-border);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
.process-number {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-accent);
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: var(--weight-bold);
|
||||
font-size: var(--font-body);
|
||||
margin: 0 auto var(--spacing-small);
|
||||
}
|
||||
.process-title {
|
||||
font-size: var(--font-body);
|
||||
font-weight: var(--weight-bold);
|
||||
color: var(--color-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.process-desc {
|
||||
font-size: var(--font-caption);
|
||||
color: var(--color-text-secondary);
|
||||
line-height: var(--line-height-ko);
|
||||
}
|
||||
.process-arrow {
|
||||
font-size: 1.5rem;
|
||||
color: var(--color-accent);
|
||||
font-weight: var(--weight-bold);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
121
04. design_agent/docs/block-tests/visuals_pyramid-hierarchy.html
Normal file
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>visuals/pyramid-hierarchy</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 피라미드 계층: 위에서 아래로 넓어지는 계층 구조 (SVG) -->
|
||||
<!--
|
||||
📋 pyramid-hierarchy
|
||||
─────────────────
|
||||
용도: 위계, 우선순위, 상위→하위 개념 (좁은→넓은)
|
||||
슬롯: levels[] (상단부터, 각 레벨에 label, color)
|
||||
-->
|
||||
<div class="block-pyramid">
|
||||
<svg viewBox="0 0 500 300" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
|
||||
<linearGradient id="pyrGrad1" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#0d47a1" />
|
||||
<stop offset="100%" stop-color="#0d47a1" stop-opacity="0.7" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="pyrGrad2" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1565c0" />
|
||||
<stop offset="100%" stop-color="#1565c0" stop-opacity="0.7" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="pyrGrad3" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#1976d2" />
|
||||
<stop offset="100%" stop-color="#1976d2" stop-opacity="0.7" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="pyrGrad4" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stop-color="#2196f3" />
|
||||
<stop offset="100%" stop-color="#2196f3" stop-opacity="0.7" />
|
||||
</linearGradient>
|
||||
|
||||
<filter id="pyrShadow">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-opacity="0.12" />
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
|
||||
|
||||
|
||||
<rect x="190" y="10" width="120" height="50" rx="6" fill="url(#pyrGrad1)" filter="url(#pyrShadow)" />
|
||||
<text x="250" y="40" text-anchor="middle" fill="white" font-size="14" font-weight="700">DX (디지털 전환)</text>
|
||||
|
||||
|
||||
|
||||
|
||||
<rect x="135" y="75" width="230" height="50" rx="6" fill="url(#pyrGrad2)" filter="url(#pyrShadow)" />
|
||||
<text x="250" y="105" text-anchor="middle" fill="white" font-size="14" font-weight="700">BIM + GIS + Digital Twin</text>
|
||||
|
||||
|
||||
|
||||
|
||||
<rect x="80" y="140" width="340" height="50" rx="6" fill="url(#pyrGrad3)" filter="url(#pyrShadow)" />
|
||||
<text x="250" y="170" text-anchor="middle" fill="white" font-size="14" font-weight="700">프로세스 혁신 + S/W 개발</text>
|
||||
|
||||
|
||||
|
||||
|
||||
<rect x="25" y="205" width="450" height="50" rx="6" fill="url(#pyrGrad4)" filter="url(#pyrShadow)" />
|
||||
<text x="250" y="235" text-anchor="middle" fill="white" font-size="14" font-weight="700">기반 인프라 + 인력 양성</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-pyramid {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.block-pyramid svg {
|
||||
max-width: 450px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
@@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>visuals/timeline-horizontal</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 가로 타임라인: 좌→우 시간축 + 마커 + 라벨 (SVG) -->
|
||||
<!--
|
||||
📋 timeline-horizontal
|
||||
─────────────────
|
||||
용도: 연도별 로드맵, 짧은 일정, 마일스톤 (가로 배치)
|
||||
슬롯: events[] (각 이벤트에 year, title, color)
|
||||
timeline-vertical과 다른 점: 가로 방향, 공간 효율적
|
||||
-->
|
||||
<div class="block-timeline-h">
|
||||
<svg viewBox="0 0 680 100" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<!-- 가로 선 -->
|
||||
<line x1="30" y1="40" x2="630" y2="40" stroke="#cbd5e1" stroke-width="2" />
|
||||
|
||||
|
||||
<!-- 마커 -->
|
||||
<circle cx="60" cy="40" r="12" fill="#059669" />
|
||||
<circle cx="60" cy="40" r="5" fill="white" />
|
||||
<!-- 연도 -->
|
||||
<text x="60" y="22" text-anchor="middle" fill="#059669" font-size="12" font-weight="800">2020</text>
|
||||
<!-- 제목 -->
|
||||
<text x="60" y="65" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="600">BIM 기본지침</text>
|
||||
|
||||
|
||||
|
||||
<!-- 마커 -->
|
||||
<circle cx="220" cy="40" r="12" fill="#2563eb" />
|
||||
<circle cx="220" cy="40" r="5" fill="white" />
|
||||
<!-- 연도 -->
|
||||
<text x="220" y="22" text-anchor="middle" fill="#2563eb" font-size="12" font-weight="800">2022</text>
|
||||
<!-- 제목 -->
|
||||
<text x="220" y="65" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="600">스마트건설 방안</text>
|
||||
|
||||
|
||||
|
||||
<!-- 마커 -->
|
||||
<circle cx="380" cy="40" r="12" fill="#7c3aed" />
|
||||
<circle cx="380" cy="40" r="5" fill="white" />
|
||||
<!-- 연도 -->
|
||||
<text x="380" y="22" text-anchor="middle" fill="#7c3aed" font-size="12" font-weight="800">2023</text>
|
||||
<!-- 제목 -->
|
||||
<text x="380" y="65" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="600">7차 기본계획</text>
|
||||
|
||||
|
||||
|
||||
<!-- 마커 -->
|
||||
<circle cx="540" cy="40" r="12" fill="#dc2626" />
|
||||
<circle cx="540" cy="40" r="5" fill="white" />
|
||||
<!-- 연도 -->
|
||||
<text x="540" y="22" text-anchor="middle" fill="#dc2626" font-size="12" font-weight="800">2025</text>
|
||||
<!-- 제목 -->
|
||||
<text x="540" y="65" text-anchor="middle" fill="#1e293b" font-size="12" font-weight="600">전면 BIM</text>
|
||||
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-timeline-h {
|
||||
padding: 10px 0;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.block-timeline-h svg {
|
||||
min-width: 500px;
|
||||
}
|
||||
</style></div></body></html>
|
||||
167
04. design_agent/docs/block-tests/visuals_timeline-vertical.html
Normal file
@@ -0,0 +1,167 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>visuals/timeline-vertical</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 세로 타임라인: 좌측 선 + 원형 마커 + 우측 내용 (SVG 마커) -->
|
||||
<!--
|
||||
📋 timeline-vertical
|
||||
─────────────────
|
||||
용도: 연혁, 정책 시행 일정, 로드맵, 연도별 사건
|
||||
슬롯: events[] (각 이벤트에 year, title, description, color)
|
||||
Figma 참고: 정책 로드맵, 건설 정책 추진현황
|
||||
-->
|
||||
<div class="block-timeline-v">
|
||||
|
||||
<div class="tv-event">
|
||||
<div class="tv-marker-col">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="#059669" />
|
||||
<circle cx="12" cy="12" r="5" fill="white" />
|
||||
</svg>
|
||||
<div class="tv-line" style="background: #059669"></div>
|
||||
</div>
|
||||
<div class="tv-content">
|
||||
<div class="tv-year" style="color: #059669">2020</div>
|
||||
<div class="tv-title">건설산업 BIM 기본지침</div>
|
||||
<div class="tv-desc">BIM 도입의 법적 근거 마련</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tv-event">
|
||||
<div class="tv-marker-col">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="#2563eb" />
|
||||
<circle cx="12" cy="12" r="5" fill="white" />
|
||||
</svg>
|
||||
<div class="tv-line" style="background: #2563eb"></div>
|
||||
</div>
|
||||
<div class="tv-content">
|
||||
<div class="tv-year" style="color: #2563eb">2022.07</div>
|
||||
<div class="tv-title">스마트 건설 활성화 방안</div>
|
||||
<div class="tv-desc">BIM 전면 도입 + 전문인력 양성</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tv-event">
|
||||
<div class="tv-marker-col">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="#7c3aed" />
|
||||
<circle cx="12" cy="12" r="5" fill="white" />
|
||||
</svg>
|
||||
<div class="tv-line" style="background: #7c3aed"></div>
|
||||
</div>
|
||||
<div class="tv-content">
|
||||
<div class="tv-year" style="color: #7c3aed">2023.12</div>
|
||||
<div class="tv-title">제7차 건설기술진흥 기본계획</div>
|
||||
<div class="tv-desc">디지털 전환을 통한 스마트 건설 확산</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tv-event">
|
||||
<div class="tv-marker-col">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="10" fill="#dc2626" />
|
||||
<circle cx="12" cy="12" r="5" fill="white" />
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<div class="tv-content">
|
||||
<div class="tv-year" style="color: #dc2626">2025</div>
|
||||
<div class="tv-title">전면 BIM 적용</div>
|
||||
<div class="tv-desc">공공 건설사업 BIM 의무화 목표</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-timeline-v {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.tv-event {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
}
|
||||
.tv-marker-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
width: 24px;
|
||||
}
|
||||
.tv-line {
|
||||
width: 2px;
|
||||
flex: 1;
|
||||
min-height: 20px;
|
||||
opacity: 0.3;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.tv-content {
|
||||
padding-bottom: 20px;
|
||||
flex: 1;
|
||||
}
|
||||
.tv-year {
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.tv-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.tv-desc {
|
||||
font-size: 13px;
|
||||
color: #475569;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
}
|
||||
</style></div></body></html>
|
||||
151
04. design_agent/docs/block-tests/visuals_venn-2items-p2.html
Normal file
@@ -0,0 +1,151 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>venn-2items</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 벤 다이어그램: SVG premium (N개 자동 배치) -->
|
||||
<!--
|
||||
📋 venn-diagram (P2-B: 동적 좌표 계산)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: renderer가 svg_calculator.prepare_venn_data()로 좌표 사전 계산
|
||||
→ items[].cx, cy, r + outer_r, center_x, center_y 전달
|
||||
Phase 1 fallback: outer_r이 없으면 3개 고정 좌표 사용
|
||||
-->
|
||||
<div class="block-venn-svg">
|
||||
|
||||
|
||||
<svg viewBox="0 0 600.0 550.0" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#dce3ea" />
|
||||
<stop offset="100%" stop-color="#f0f2f5" />
|
||||
</linearGradient>
|
||||
<radialGradient id="blueOuter" cx="45%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#2979ff" />
|
||||
<stop offset="40%" stop-color="#1565c0" />
|
||||
<stop offset="100%" stop-color="#0d47a1" />
|
||||
</radialGradient>
|
||||
<radialGradient id="hlGrad" cx="35%" cy="25%" r="40%">
|
||||
<stop offset="0%" stop-color="rgba(255,255,255,0.5)" />
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)" />
|
||||
</radialGradient>
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="8" result="blur" />
|
||||
<feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="rgba(0,0,0,0.3)" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#10b98180" />
|
||||
<stop offset="100%" stop-color="#10b981" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#3b82f680" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<rect width="600.0" height="550.0" fill="url(#bgGrad)" />
|
||||
|
||||
<circle cx="300.0" cy="295.0" r="235.0" fill="url(#blueOuter)" filter="url(#shadow)" />
|
||||
<circle cx="300.0" cy="295.0" r="225.0" fill="none" stroke="#4a90d9" stroke-width="1.5" opacity="0.4" />
|
||||
<circle cx="300.0" cy="295.0" r="210.0" fill="none" stroke="#5a9de0" stroke-width="1" opacity="0.3" />
|
||||
<circle cx="300.0" cy="295.0" r="195.0" fill="none" stroke="#6aabe6" stroke-width="0.8" opacity="0.25" />
|
||||
|
||||
|
||||
<circle cx="300.0" cy="175.0" r="75.0" fill="url(#itemGrad1)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="300.0" cy="175.0" r="75.0" fill="url(#hlGrad)" />
|
||||
<text x="300.0" y="175.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">BIM</text>
|
||||
|
||||
|
||||
<circle cx="300.0" cy="415.0" r="75.0" fill="url(#itemGrad2)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="300.0" cy="415.0" r="75.0" fill="url(#hlGrad)" />
|
||||
<text x="300.0" y="415.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">GIS</text>
|
||||
|
||||
|
||||
|
||||
<text x="300.0" y="95.0" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="400" opacity="0.85">Digital Transformation</text>
|
||||
<text x="300.0" y="120.0" text-anchor="middle" fill="#ffffff" font-size="24" font-weight="900">DX (2개)</text>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="venn-desc">2개 요소의 기술 융합 구조</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-svg {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
flex-shrink: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.block-venn-svg svg {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.venn-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body></html>
|
||||
161
04. design_agent/docs/block-tests/visuals_venn-3items-p2.html
Normal file
@@ -0,0 +1,161 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>venn-3items</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 벤 다이어그램: SVG premium (N개 자동 배치) -->
|
||||
<!--
|
||||
📋 venn-diagram (P2-B: 동적 좌표 계산)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: renderer가 svg_calculator.prepare_venn_data()로 좌표 사전 계산
|
||||
→ items[].cx, cy, r + outer_r, center_x, center_y 전달
|
||||
Phase 1 fallback: outer_r이 없으면 3개 고정 좌표 사용
|
||||
-->
|
||||
<div class="block-venn-svg">
|
||||
|
||||
|
||||
<svg viewBox="0 0 600.0 550.0" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#dce3ea" />
|
||||
<stop offset="100%" stop-color="#f0f2f5" />
|
||||
</linearGradient>
|
||||
<radialGradient id="blueOuter" cx="45%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#2979ff" />
|
||||
<stop offset="40%" stop-color="#1565c0" />
|
||||
<stop offset="100%" stop-color="#0d47a1" />
|
||||
</radialGradient>
|
||||
<radialGradient id="hlGrad" cx="35%" cy="25%" r="40%">
|
||||
<stop offset="0%" stop-color="rgba(255,255,255,0.5)" />
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)" />
|
||||
</radialGradient>
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="8" result="blur" />
|
||||
<feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="rgba(0,0,0,0.3)" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#6ee7b7" />
|
||||
<stop offset="100%" stop-color="#10b981" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#93c5fd" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad3" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#c4b5fd" />
|
||||
<stop offset="100%" stop-color="#8b5cf6" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<rect width="600.0" height="550.0" fill="url(#bgGrad)" />
|
||||
|
||||
<circle cx="300.0" cy="295.0" r="235.0" fill="url(#blueOuter)" filter="url(#shadow)" />
|
||||
<circle cx="300.0" cy="295.0" r="225.0" fill="none" stroke="#4a90d9" stroke-width="1.5" opacity="0.4" />
|
||||
<circle cx="300.0" cy="295.0" r="210.0" fill="none" stroke="#5a9de0" stroke-width="1" opacity="0.3" />
|
||||
<circle cx="300.0" cy="295.0" r="195.0" fill="none" stroke="#6aabe6" stroke-width="0.8" opacity="0.25" />
|
||||
|
||||
|
||||
<circle cx="300.0" cy="175.0" r="75.0" fill="url(#itemGrad1)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="300.0" cy="175.0" r="75.0" fill="url(#hlGrad)" />
|
||||
<text x="300.0" y="175.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">GIS</text>
|
||||
|
||||
|
||||
<circle cx="403.9" cy="355.0" r="75.0" fill="url(#itemGrad2)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="403.9" cy="355.0" r="75.0" fill="url(#hlGrad)" />
|
||||
<text x="403.9" y="355.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">BIM</text>
|
||||
|
||||
|
||||
<circle cx="196.1" cy="355.0" r="75.0" fill="url(#itemGrad3)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="196.1" cy="355.0" r="75.0" fill="url(#hlGrad)" />
|
||||
<text x="196.1" y="355.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">DT</text>
|
||||
|
||||
|
||||
|
||||
<text x="300.0" y="95.0" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="400" opacity="0.85">Digital Transformation</text>
|
||||
<text x="300.0" y="120.0" text-anchor="middle" fill="#ffffff" font-size="24" font-weight="900">DX (3개)</text>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="venn-desc">3개 요소의 기술 융합 구조</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-svg {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
flex-shrink: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.block-venn-svg svg {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.venn-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body></html>
|
||||
165
04. design_agent/docs/block-tests/visuals_venn-3items.html
Normal file
@@ -0,0 +1,165 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>venn-3items</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 벤 다이어그램: 수학적 계산 기반 원형 배치 + SVG -->
|
||||
<!--
|
||||
📋 venn-diagram (계산 기반)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: 중앙 큰 원 + 작은 원 N개를 360/N 간격으로 배치 (수학적 계산)
|
||||
슬롯: center_label, center_sub, items[] (개수 자유), description
|
||||
계산: items 개수에 따라 자동으로 360도 분할 → cos/sin으로 좌표 결정
|
||||
|
||||
렌더링 전 Python에서 계산 필요:
|
||||
for i, item in enumerate(items):
|
||||
angle = (2 * pi * i / n) - pi/2 # 12시부터 시작
|
||||
item['cx'] = 200 + 110 * cos(angle)
|
||||
item['cy'] = 200 + 110 * sin(angle)
|
||||
-->
|
||||
<div class="block-venn-calc">
|
||||
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" class="vc-svg">
|
||||
<defs>
|
||||
<radialGradient id="outerGrad" cx="50%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#e8f4fd" />
|
||||
<stop offset="100%" stop-color="#d0e8f8" />
|
||||
</radialGradient>
|
||||
<filter id="glow">
|
||||
<feGaussianBlur stdDeviation="6" result="blur" />
|
||||
<feMerge>
|
||||
<feMergeNode in="blur" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-opacity="0.15" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#6ee7b7" />
|
||||
<stop offset="100%" stop-color="#10b981" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#93c5fd" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad3" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#c4b5fd" />
|
||||
<stop offset="100%" stop-color="#8b5cf6" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<!-- 바깥 링 -->
|
||||
<circle cx="200" cy="200" r="185" fill="none" stroke="#b8d4f0" stroke-width="1" opacity="0.5" />
|
||||
|
||||
<!-- 큰 원 (상위 개념) -->
|
||||
<circle cx="200" cy="200" r="170" fill="url(#outerGrad)" stroke="#7eb8e0" stroke-width="2.5" />
|
||||
|
||||
<!-- 연결선 (각 작은 원 → 중심) -->
|
||||
|
||||
<line x1="200" y1="200" x2="200.0" y2="110.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="295.3" y2="275.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="104.7" y2="275.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
|
||||
<!-- 작은 원들 (하위 요소) -->
|
||||
|
||||
<circle cx="200.0" cy="110.0" r="42" fill="url(#itemGrad1)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="200.0" y="110.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">GIS</text>
|
||||
|
||||
<circle cx="295.3" cy="275.0" r="42" fill="url(#itemGrad2)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="295.3" y="275.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">BIM</text>
|
||||
|
||||
<circle cx="104.7" cy="275.0" r="42" fill="url(#itemGrad3)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="104.7" y="275.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">DT</text>
|
||||
|
||||
|
||||
<!-- 중앙 텍스트 -->
|
||||
<text x="200" y="85" text-anchor="middle" dominant-baseline="central" fill="#1e3a6e" font-size="20" font-weight="900" font-family="Pretendard Variable, sans-serif">건설산업의 DX</text>
|
||||
|
||||
<text x="200" y="108" text-anchor="middle" dominant-baseline="central" fill="#6b7280" font-size="11" font-family="Pretendard Variable, sans-serif">Digital Transformation</text>
|
||||
|
||||
</svg>
|
||||
|
||||
|
||||
<div class="vc-desc">건설산업의 DX는 GIS, BIM, 디지털 트윈의 기술 융합을 통해서만 실현 가능</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-calc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.vc-svg {
|
||||
width: 380px;
|
||||
height: 380px;
|
||||
}
|
||||
.vc-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
171
04. design_agent/docs/block-tests/visuals_venn-4items-p2.html
Normal file
@@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>venn-4items</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 벤 다이어그램: SVG premium (N개 자동 배치) -->
|
||||
<!--
|
||||
📋 venn-diagram (P2-B: 동적 좌표 계산)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: renderer가 svg_calculator.prepare_venn_data()로 좌표 사전 계산
|
||||
→ items[].cx, cy, r + outer_r, center_x, center_y 전달
|
||||
Phase 1 fallback: outer_r이 없으면 3개 고정 좌표 사용
|
||||
-->
|
||||
<div class="block-venn-svg">
|
||||
|
||||
|
||||
<svg viewBox="0 0 600.0 550.0" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#dce3ea" />
|
||||
<stop offset="100%" stop-color="#f0f2f5" />
|
||||
</linearGradient>
|
||||
<radialGradient id="blueOuter" cx="45%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#2979ff" />
|
||||
<stop offset="40%" stop-color="#1565c0" />
|
||||
<stop offset="100%" stop-color="#0d47a1" />
|
||||
</radialGradient>
|
||||
<radialGradient id="hlGrad" cx="35%" cy="25%" r="40%">
|
||||
<stop offset="0%" stop-color="rgba(255,255,255,0.5)" />
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)" />
|
||||
</radialGradient>
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="8" result="blur" />
|
||||
<feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="rgba(0,0,0,0.3)" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#10b98180" />
|
||||
<stop offset="100%" stop-color="#10b981" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#3b82f680" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad3" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#8b5cf680" />
|
||||
<stop offset="100%" stop-color="#8b5cf6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad4" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#f59e0b80" />
|
||||
<stop offset="100%" stop-color="#f59e0b" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<rect width="600.0" height="550.0" fill="url(#bgGrad)" />
|
||||
|
||||
<circle cx="300.0" cy="295.0" r="232.1" fill="url(#blueOuter)" filter="url(#shadow)" />
|
||||
<circle cx="300.0" cy="295.0" r="222.1" fill="none" stroke="#4a90d9" stroke-width="1.5" opacity="0.4" />
|
||||
<circle cx="300.0" cy="295.0" r="207.1" fill="none" stroke="#5a9de0" stroke-width="1" opacity="0.3" />
|
||||
<circle cx="300.0" cy="295.0" r="192.1" fill="none" stroke="#6aabe6" stroke-width="0.8" opacity="0.25" />
|
||||
|
||||
|
||||
<circle cx="300.0" cy="165.4" r="62.5" fill="url(#itemGrad1)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="300.0" cy="165.4" r="62.5" fill="url(#hlGrad)" />
|
||||
<text x="300.0" y="165.4" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">설계</text>
|
||||
|
||||
|
||||
<circle cx="429.6" cy="295.0" r="62.5" fill="url(#itemGrad2)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="429.6" cy="295.0" r="62.5" fill="url(#hlGrad)" />
|
||||
<text x="429.6" y="295.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">시공</text>
|
||||
|
||||
|
||||
<circle cx="300.0" cy="424.6" r="62.5" fill="url(#itemGrad3)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="300.0" cy="424.6" r="62.5" fill="url(#hlGrad)" />
|
||||
<text x="300.0" y="424.6" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">유지관리</text>
|
||||
|
||||
|
||||
<circle cx="170.4" cy="295.0" r="62.5" fill="url(#itemGrad4)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="170.4" cy="295.0" r="62.5" fill="url(#hlGrad)" />
|
||||
<text x="170.4" y="295.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="18" font-weight="700">운영</text>
|
||||
|
||||
|
||||
|
||||
<text x="300.0" y="97.9" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="400" opacity="0.85">Digital Transformation</text>
|
||||
<text x="300.0" y="122.9" text-anchor="middle" fill="#ffffff" font-size="24" font-weight="900">DX (4개)</text>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="venn-desc">4개 요소의 기술 융합 구조</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-svg {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
flex-shrink: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.block-venn-svg svg {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.venn-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body></html>
|
||||
175
04. design_agent/docs/block-tests/visuals_venn-4items.html
Normal file
@@ -0,0 +1,175 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>venn-4items</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 벤 다이어그램: 수학적 계산 기반 원형 배치 + SVG -->
|
||||
<!--
|
||||
📋 venn-diagram (계산 기반)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: 중앙 큰 원 + 작은 원 N개를 360/N 간격으로 배치 (수학적 계산)
|
||||
슬롯: center_label, center_sub, items[] (개수 자유), description
|
||||
계산: items 개수에 따라 자동으로 360도 분할 → cos/sin으로 좌표 결정
|
||||
|
||||
렌더링 전 Python에서 계산 필요:
|
||||
for i, item in enumerate(items):
|
||||
angle = (2 * pi * i / n) - pi/2 # 12시부터 시작
|
||||
item['cx'] = 200 + 110 * cos(angle)
|
||||
item['cy'] = 200 + 110 * sin(angle)
|
||||
-->
|
||||
<div class="block-venn-calc">
|
||||
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" class="vc-svg">
|
||||
<defs>
|
||||
<radialGradient id="outerGrad" cx="50%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#e8f4fd" />
|
||||
<stop offset="100%" stop-color="#d0e8f8" />
|
||||
</radialGradient>
|
||||
<filter id="glow">
|
||||
<feGaussianBlur stdDeviation="6" result="blur" />
|
||||
<feMerge>
|
||||
<feMergeNode in="blur" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-opacity="0.15" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#7dd3fc" />
|
||||
<stop offset="100%" stop-color="#00aaff" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#93c5fd" />
|
||||
<stop offset="100%" stop-color="#006aff" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad3" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#6b9fff" />
|
||||
<stop offset="100%" stop-color="#004cbe" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad4" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#c4b5fd" />
|
||||
<stop offset="100%" stop-color="#7c3aed" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<!-- 바깥 링 -->
|
||||
<circle cx="200" cy="200" r="185" fill="none" stroke="#b8d4f0" stroke-width="1" opacity="0.5" />
|
||||
|
||||
<!-- 큰 원 (상위 개념) -->
|
||||
<circle cx="200" cy="200" r="170" fill="url(#outerGrad)" stroke="#7eb8e0" stroke-width="2.5" />
|
||||
|
||||
<!-- 연결선 (각 작은 원 → 중심) -->
|
||||
|
||||
<line x1="200" y1="200" x2="200.0" y2="110.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="310.0" y2="220.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="200.0" y2="330.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="90.0" y2="220.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
|
||||
<!-- 작은 원들 (하위 요소) -->
|
||||
|
||||
<circle cx="200.0" cy="110.0" r="42" fill="url(#itemGrad1)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="200.0" y="110.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">설계</text>
|
||||
|
||||
<circle cx="310.0" cy="220.0" r="42" fill="url(#itemGrad2)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="310.0" y="220.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">시공</text>
|
||||
|
||||
<circle cx="200.0" cy="330.0" r="42" fill="url(#itemGrad3)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="200.0" y="330.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">유지관리</text>
|
||||
|
||||
<circle cx="90.0" cy="220.0" r="42" fill="url(#itemGrad4)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="90.0" y="220.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">운영</text>
|
||||
|
||||
|
||||
<!-- 중앙 텍스트 -->
|
||||
<text x="200" y="85" text-anchor="middle" dominant-baseline="central" fill="#1e3a6e" font-size="20" font-weight="900" font-family="Pretendard Variable, sans-serif">생애주기</text>
|
||||
|
||||
<text x="200" y="108" text-anchor="middle" dominant-baseline="central" fill="#6b7280" font-size="11" font-family="Pretendard Variable, sans-serif">Life Cycle</text>
|
||||
|
||||
</svg>
|
||||
|
||||
|
||||
<div class="vc-desc">설계 → 시공 → 유지관리 → 운영의 전 생애주기 관리</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-calc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.vc-svg {
|
||||
width: 380px;
|
||||
height: 380px;
|
||||
}
|
||||
.vc-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
181
04. design_agent/docs/block-tests/visuals_venn-5items-p2.html
Normal file
@@ -0,0 +1,181 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>venn-5items</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 벤 다이어그램: SVG premium (N개 자동 배치) -->
|
||||
<!--
|
||||
📋 venn-diagram (P2-B: 동적 좌표 계산)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: renderer가 svg_calculator.prepare_venn_data()로 좌표 사전 계산
|
||||
→ items[].cx, cy, r + outer_r, center_x, center_y 전달
|
||||
Phase 1 fallback: outer_r이 없으면 3개 고정 좌표 사용
|
||||
-->
|
||||
<div class="block-venn-svg">
|
||||
|
||||
|
||||
<svg viewBox="0 0 600.0 550.0" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#dce3ea" />
|
||||
<stop offset="100%" stop-color="#f0f2f5" />
|
||||
</linearGradient>
|
||||
<radialGradient id="blueOuter" cx="45%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#2979ff" />
|
||||
<stop offset="40%" stop-color="#1565c0" />
|
||||
<stop offset="100%" stop-color="#0d47a1" />
|
||||
</radialGradient>
|
||||
<radialGradient id="hlGrad" cx="35%" cy="25%" r="40%">
|
||||
<stop offset="0%" stop-color="rgba(255,255,255,0.5)" />
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)" />
|
||||
</radialGradient>
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="8" result="blur" />
|
||||
<feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="rgba(0,0,0,0.3)" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#10b98180" />
|
||||
<stop offset="100%" stop-color="#10b981" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#3b82f680" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad3" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#8b5cf680" />
|
||||
<stop offset="100%" stop-color="#8b5cf6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad4" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#f59e0b80" />
|
||||
<stop offset="100%" stop-color="#f59e0b" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad5" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#ef444480" />
|
||||
<stop offset="100%" stop-color="#ef4444" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<rect width="600.0" height="550.0" fill="url(#bgGrad)" />
|
||||
|
||||
<circle cx="300.0" cy="295.0" r="232.8" fill="url(#blueOuter)" filter="url(#shadow)" />
|
||||
<circle cx="300.0" cy="295.0" r="222.8" fill="none" stroke="#4a90d9" stroke-width="1.5" opacity="0.4" />
|
||||
<circle cx="300.0" cy="295.0" r="207.8" fill="none" stroke="#5a9de0" stroke-width="1" opacity="0.3" />
|
||||
<circle cx="300.0" cy="295.0" r="192.8" fill="none" stroke="#6aabe6" stroke-width="0.8" opacity="0.25" />
|
||||
|
||||
|
||||
<circle cx="300.0" cy="155.8" r="53.6" fill="url(#itemGrad1)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="300.0" cy="155.8" r="53.6" fill="url(#hlGrad)" />
|
||||
<text x="300.0" y="155.8" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">기술</text>
|
||||
|
||||
|
||||
<circle cx="432.4" cy="252.0" r="53.6" fill="url(#itemGrad2)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="432.4" cy="252.0" r="53.6" fill="url(#hlGrad)" />
|
||||
<text x="432.4" y="252.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">S/W</text>
|
||||
|
||||
|
||||
<circle cx="381.8" cy="407.6" r="53.6" fill="url(#itemGrad3)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="381.8" cy="407.6" r="53.6" fill="url(#hlGrad)" />
|
||||
<text x="381.8" y="407.6" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">인력</text>
|
||||
|
||||
|
||||
<circle cx="218.2" cy="407.6" r="53.6" fill="url(#itemGrad4)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="218.2" cy="407.6" r="53.6" fill="url(#hlGrad)" />
|
||||
<text x="218.2" y="407.6" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">여건</text>
|
||||
|
||||
|
||||
<circle cx="167.6" cy="252.0" r="53.6" fill="url(#itemGrad5)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="167.6" cy="252.0" r="53.6" fill="url(#hlGrad)" />
|
||||
<text x="167.6" y="252.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">투자</text>
|
||||
|
||||
|
||||
|
||||
<text x="300.0" y="97.19999999999999" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="400" opacity="0.85">Digital Transformation</text>
|
||||
<text x="300.0" y="122.19999999999999" text-anchor="middle" fill="#ffffff" font-size="24" font-weight="900">DX (5개)</text>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="venn-desc">5개 요소의 기술 융합 구조</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-svg {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
flex-shrink: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.block-venn-svg svg {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.venn-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body></html>
|
||||
185
04. design_agent/docs/block-tests/visuals_venn-5items.html
Normal file
@@ -0,0 +1,185 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>venn-5items</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 벤 다이어그램: 수학적 계산 기반 원형 배치 + SVG -->
|
||||
<!--
|
||||
📋 venn-diagram (계산 기반)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: 중앙 큰 원 + 작은 원 N개를 360/N 간격으로 배치 (수학적 계산)
|
||||
슬롯: center_label, center_sub, items[] (개수 자유), description
|
||||
계산: items 개수에 따라 자동으로 360도 분할 → cos/sin으로 좌표 결정
|
||||
|
||||
렌더링 전 Python에서 계산 필요:
|
||||
for i, item in enumerate(items):
|
||||
angle = (2 * pi * i / n) - pi/2 # 12시부터 시작
|
||||
item['cx'] = 200 + 110 * cos(angle)
|
||||
item['cy'] = 200 + 110 * sin(angle)
|
||||
-->
|
||||
<div class="block-venn-calc">
|
||||
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" class="vc-svg">
|
||||
<defs>
|
||||
<radialGradient id="outerGrad" cx="50%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#e8f4fd" />
|
||||
<stop offset="100%" stop-color="#d0e8f8" />
|
||||
</radialGradient>
|
||||
<filter id="glow">
|
||||
<feGaussianBlur stdDeviation="6" result="blur" />
|
||||
<feMerge>
|
||||
<feMergeNode in="blur" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-opacity="0.15" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#67e8f9" />
|
||||
<stop offset="100%" stop-color="#0891b2" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#93c5fd" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad3" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#c4b5fd" />
|
||||
<stop offset="100%" stop-color="#8b5cf6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad4" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#f9a8d4" />
|
||||
<stop offset="100%" stop-color="#ec4899" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad5" cx="40%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#fcd34d" />
|
||||
<stop offset="100%" stop-color="#f59e0b" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<!-- 바깥 링 -->
|
||||
<circle cx="200" cy="200" r="185" fill="none" stroke="#b8d4f0" stroke-width="1" opacity="0.5" />
|
||||
|
||||
<!-- 큰 원 (상위 개념) -->
|
||||
<circle cx="200" cy="200" r="170" fill="url(#outerGrad)" stroke="#7eb8e0" stroke-width="2.5" />
|
||||
|
||||
<!-- 연결선 (각 작은 원 → 중심) -->
|
||||
|
||||
<line x1="200" y1="200" x2="200.0" y2="110.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="304.6" y2="186.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="264.7" y2="309.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="135.3" y2="309.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
<line x1="200" y1="200" x2="95.4" y2="186.0" stroke="#a0c4e0" stroke-width="1" stroke-dasharray="4,4" opacity="0.4" />
|
||||
|
||||
|
||||
<!-- 작은 원들 (하위 요소) -->
|
||||
|
||||
<circle cx="200.0" cy="110.0" r="42" fill="url(#itemGrad1)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="200.0" y="110.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">기술기반</text>
|
||||
|
||||
<circle cx="304.6" cy="186.0" r="42" fill="url(#itemGrad2)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="304.6" y="186.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">S/W</text>
|
||||
|
||||
<circle cx="264.7" cy="309.0" r="42" fill="url(#itemGrad3)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="264.7" y="309.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">인력</text>
|
||||
|
||||
<circle cx="135.3" cy="309.0" r="42" fill="url(#itemGrad4)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="135.3" y="309.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">여건</text>
|
||||
|
||||
<circle cx="95.4" cy="186.0" r="42" fill="url(#itemGrad5)" filter="url(#shadow)" opacity="0.9" />
|
||||
<text x="95.4" y="186.0" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700" font-family="Pretendard Variable, sans-serif">투자</text>
|
||||
|
||||
|
||||
<!-- 중앙 텍스트 -->
|
||||
<text x="200" y="85" text-anchor="middle" dominant-baseline="central" fill="#1e3a6e" font-size="20" font-weight="900" font-family="Pretendard Variable, sans-serif">DX 성공 요건</text>
|
||||
|
||||
<text x="200" y="108" text-anchor="middle" dominant-baseline="central" fill="#6b7280" font-size="11" font-family="Pretendard Variable, sans-serif">5대 필수 요건</text>
|
||||
|
||||
</svg>
|
||||
|
||||
|
||||
<div class="vc-desc">디지털 전환 성공을 위해 기술, S/W, 인력, 여건, 투자 5가지 요건이 필요</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-calc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.vc-svg {
|
||||
width: 380px;
|
||||
height: 380px;
|
||||
}
|
||||
.vc-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
201
04. design_agent/docs/block-tests/visuals_venn-7items-p2.html
Normal file
@@ -0,0 +1,201 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko"><head><meta charset="UTF-8"><title>venn-7items</title>
|
||||
<style>@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style></head><body><div class="block-container"><!-- 벤 다이어그램: SVG premium (N개 자동 배치) -->
|
||||
<!--
|
||||
📋 venn-diagram (P2-B: 동적 좌표 계산)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: renderer가 svg_calculator.prepare_venn_data()로 좌표 사전 계산
|
||||
→ items[].cx, cy, r + outer_r, center_x, center_y 전달
|
||||
Phase 1 fallback: outer_r이 없으면 3개 고정 좌표 사용
|
||||
-->
|
||||
<div class="block-venn-svg">
|
||||
|
||||
|
||||
<svg viewBox="0 0 600.0 550.0" width="100%" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#dce3ea" />
|
||||
<stop offset="100%" stop-color="#f0f2f5" />
|
||||
</linearGradient>
|
||||
<radialGradient id="blueOuter" cx="45%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#2979ff" />
|
||||
<stop offset="40%" stop-color="#1565c0" />
|
||||
<stop offset="100%" stop-color="#0d47a1" />
|
||||
</radialGradient>
|
||||
<radialGradient id="hlGrad" cx="35%" cy="25%" r="40%">
|
||||
<stop offset="0%" stop-color="rgba(255,255,255,0.5)" />
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)" />
|
||||
</radialGradient>
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="8" result="blur" />
|
||||
<feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
|
||||
</filter>
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="rgba(0,0,0,0.3)" />
|
||||
</filter>
|
||||
|
||||
<radialGradient id="itemGrad1" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#10b98180" />
|
||||
<stop offset="100%" stop-color="#10b981" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad2" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#3b82f680" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad3" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#8b5cf680" />
|
||||
<stop offset="100%" stop-color="#8b5cf6" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad4" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#f59e0b80" />
|
||||
<stop offset="100%" stop-color="#f59e0b" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad5" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#ef444480" />
|
||||
<stop offset="100%" stop-color="#ef4444" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad6" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#06b6d480" />
|
||||
<stop offset="100%" stop-color="#06b6d4" />
|
||||
</radialGradient>
|
||||
|
||||
<radialGradient id="itemGrad7" cx="35%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#ec489980" />
|
||||
<stop offset="100%" stop-color="#ec4899" />
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<rect width="600.0" height="550.0" fill="url(#bgGrad)" />
|
||||
|
||||
<circle cx="300.0" cy="295.0" r="240.1" fill="url(#blueOuter)" filter="url(#shadow)" />
|
||||
<circle cx="300.0" cy="295.0" r="230.1" fill="none" stroke="#4a90d9" stroke-width="1.5" opacity="0.4" />
|
||||
<circle cx="300.0" cy="295.0" r="215.1" fill="none" stroke="#5a9de0" stroke-width="1" opacity="0.3" />
|
||||
<circle cx="300.0" cy="295.0" r="200.1" fill="none" stroke="#6aabe6" stroke-width="0.8" opacity="0.25" />
|
||||
|
||||
|
||||
<circle cx="300.0" cy="136.6" r="41.7" fill="url(#itemGrad1)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="300.0" cy="136.6" r="41.7" fill="url(#hlGrad)" />
|
||||
<text x="300.0" y="136.6" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">GIS</text>
|
||||
|
||||
|
||||
<circle cx="423.8" cy="196.2" r="41.7" fill="url(#itemGrad2)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="423.8" cy="196.2" r="41.7" fill="url(#hlGrad)" />
|
||||
<text x="423.8" y="196.2" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">BIM</text>
|
||||
|
||||
|
||||
<circle cx="454.4" cy="330.2" r="41.7" fill="url(#itemGrad3)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="454.4" cy="330.2" r="41.7" fill="url(#hlGrad)" />
|
||||
<text x="454.4" y="330.2" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">DT</text>
|
||||
|
||||
|
||||
<circle cx="368.7" cy="437.7" r="41.7" fill="url(#itemGrad4)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="368.7" cy="437.7" r="41.7" fill="url(#hlGrad)" />
|
||||
<text x="368.7" y="437.7" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">IoT</text>
|
||||
|
||||
|
||||
<circle cx="231.3" cy="437.7" r="41.7" fill="url(#itemGrad5)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="231.3" cy="437.7" r="41.7" fill="url(#hlGrad)" />
|
||||
<text x="231.3" y="437.7" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">AI</text>
|
||||
|
||||
|
||||
<circle cx="145.6" cy="330.2" r="41.7" fill="url(#itemGrad6)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="145.6" cy="330.2" r="41.7" fill="url(#hlGrad)" />
|
||||
<text x="145.6" y="330.2" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">Cloud</text>
|
||||
|
||||
|
||||
<circle cx="176.2" cy="196.2" r="41.7" fill="url(#itemGrad7)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="176.2" cy="196.2" r="41.7" fill="url(#hlGrad)" />
|
||||
<text x="176.2" y="196.2" text-anchor="middle" dominant-baseline="central" fill="white" font-size="15" font-weight="700">Robot</text>
|
||||
|
||||
|
||||
|
||||
<text x="300.0" y="89.9" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="400" opacity="0.85">Digital Transformation</text>
|
||||
<text x="300.0" y="114.9" text-anchor="middle" fill="#ffffff" font-size="24" font-weight="900">DX (7개)</text>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="venn-desc">7개 요소의 기술 융합 구조</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-svg {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
flex-shrink: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.block-venn-svg svg {
|
||||
max-width: 450px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.venn-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body></html>
|
||||
172
04. design_agent/docs/block-tests/visuals_venn-diagram.html
Normal file
@@ -0,0 +1,172 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>venn-diagram</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="block-container"><!-- 벤 다이어그램: AI 생성 배경 이미지 + HTML 텍스트 오버레이 -->
|
||||
<!--
|
||||
📋 venn-diagram (레이어 방식)
|
||||
─────────────────
|
||||
용도: 상위-하위 포함 관계, 기술 융합 구조
|
||||
방식: 배경 이미지(원형 다이어그램) + HTML 텍스트 오버레이
|
||||
슬롯: bg_image (선택), center_label, center_sub, items[], description
|
||||
참고: bg_image가 없으면 기본 CSS 원으로 fallback
|
||||
-->
|
||||
<div class="block-venn-layer">
|
||||
<div class="vl-diagram">
|
||||
|
||||
<img class="vl-bg" src="../figma-assets/venn_bg.png" alt="">
|
||||
|
||||
|
||||
<div class="vl-center-text">
|
||||
<div class="vl-main">건설산업의 DX</div>
|
||||
<div class="vl-sub">Digital Transformation</div>
|
||||
</div>
|
||||
|
||||
<div class="vl-items">
|
||||
|
||||
<div class="vl-item vl-item-1">GIS</div>
|
||||
|
||||
<div class="vl-item vl-item-2">BIM</div>
|
||||
|
||||
<div class="vl-item vl-item-3">DT</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="vl-desc">건설산업의 DX는 GIS, BIM, 디지털 트윈의 기술 융합을 통해서만 실현 가능</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.block-venn-layer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.vl-diagram {
|
||||
position: relative;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
}
|
||||
.vl-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
z-index: 1;
|
||||
}
|
||||
.vl-bg-fallback {
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(37,99,235,0.04), rgba(37,99,235,0.08));
|
||||
border: 3px solid rgba(37,99,235,0.2);
|
||||
}
|
||||
.vl-center-text {
|
||||
position: absolute;
|
||||
top: 15%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 5;
|
||||
text-align: center;
|
||||
}
|
||||
.vl-main {
|
||||
font-size: 20px;
|
||||
font-weight: 900;
|
||||
color: #1e3a6e;
|
||||
line-height: 1.3;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.vl-sub {
|
||||
font-size: 11px;
|
||||
color: #6b7280;
|
||||
margin-top: 3px;
|
||||
}
|
||||
.vl-items {
|
||||
position: absolute;
|
||||
bottom: 8%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 0;
|
||||
z-index: 5;
|
||||
}
|
||||
.vl-item {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
text-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
||||
/* 배경은 투명 — 이미지의 원이 보이도록 */
|
||||
background: transparent;
|
||||
}
|
||||
.vl-item-1 { margin-right: -8px; }
|
||||
.vl-item-2 { z-index: 3; }
|
||||
.vl-item-3 { margin-left: -8px; }
|
||||
.vl-desc {
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
text-align: center;
|
||||
max-width: 450px;
|
||||
line-height: 1.7;
|
||||
word-break: keep-all;
|
||||
}
|
||||
</style></div></body>
|
||||
</html>
|
||||
104
04. design_agent/docs/block-tests/visuals_venn-premium.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>venn-premium v6</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
/* Design Agent — 디자인 토큰 */
|
||||
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
|
||||
|
||||
:root {
|
||||
/* 색상 */
|
||||
--color-primary: #1e293b;
|
||||
--color-accent: #2563eb;
|
||||
--color-neutral: #64748b;
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-subtle: #f8fafc;
|
||||
--color-border: #e2e8f0;
|
||||
--color-danger: #dc2626;
|
||||
--color-success: #16a34a;
|
||||
--color-text: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-light: #94a3b8;
|
||||
|
||||
/* 폰트 크기 */
|
||||
--font-title: 2rem;
|
||||
--font-subtitle: 1.25rem;
|
||||
--font-body: 0.95rem;
|
||||
--font-caption: 0.8rem;
|
||||
--font-small: 0.7rem;
|
||||
|
||||
/* 폰트 두께 */
|
||||
--weight-normal: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-bold: 700;
|
||||
--weight-black: 900;
|
||||
|
||||
/* 여백 */
|
||||
--spacing-page: 40px;
|
||||
--spacing-block: 20px;
|
||||
--spacing-inner: 16px;
|
||||
--spacing-small: 8px;
|
||||
|
||||
/* 기타 */
|
||||
--radius: 6px;
|
||||
--border-width: 1px;
|
||||
--accent-border: 3px;
|
||||
--line-height-ko: 1.7;
|
||||
}
|
||||
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e8ecf0; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
|
||||
|
||||
.venn-premium { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 10px 0; }
|
||||
.vp-diagram { position: relative; width: 480px; height: 480px; }
|
||||
.vp-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; z-index: 1; }
|
||||
.vp-label {
|
||||
position: absolute; z-index: 5; color: #fff;
|
||||
text-align: center; font-weight: 700;
|
||||
text-shadow: 0 2px 6px rgba(0,0,0,0.35);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.vp-center { top: 22%; left: 50%; }
|
||||
.vp-center .en { font-size: 13px; font-weight: 400; opacity: 0.9; }
|
||||
.vp-center .ko { font-size: 24px; font-weight: 900; margin-top: 2px; }
|
||||
|
||||
.vp-dt { top: 51.8%; left: 40.2%; }
|
||||
.vp-dt .name { font-size: 20px; font-weight: 800; }
|
||||
.vp-dt .sub { font-size: 13px; font-weight: 400; opacity: 0.85; margin-top: 2px; }
|
||||
|
||||
.vp-bim { top: 41%; left: 60.6%; }
|
||||
.vp-bim .name { font-size: 20px; font-weight: 800; }
|
||||
|
||||
.vp-gis { top: 62.9%; left: 60.3%; }
|
||||
.vp-gis .name { font-size: 20px; font-weight: 800; }
|
||||
|
||||
.vp-desc { font-size: 14px; color: #444; text-align: center; max-width: 500px; line-height: 1.7; word-break: keep-all; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
<div class="venn-premium">
|
||||
<div class="vp-diagram">
|
||||
<img class="vp-bg" src="venn_premium_bg.png" alt="">
|
||||
<div class="vp-label vp-center">
|
||||
<div class="en">Digital Transformation</div>
|
||||
<div class="ko">디지털 전환(D/X)</div>
|
||||
</div>
|
||||
<div class="vp-label vp-dt">
|
||||
<div class="name">Digital Twin</div>
|
||||
<div class="sub">(Metaverse)</div>
|
||||
</div>
|
||||
<div class="vp-label vp-bim">
|
||||
<div class="name">BIM</div>
|
||||
</div>
|
||||
<div class="vp-label vp-gis">
|
||||
<div class="name">GIS</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vp-desc">건설산업의 DX는 GIS, BIM, 디지털 트윈의 기술 융합을 통해서만 실현 가능</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
121
04. design_agent/docs/block-tests/visuals_venn-svg-premium.html
Normal file
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>venn SVG premium test</title>
|
||||
<style>
|
||||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
body { font-family: "Pretendard Variable", sans-serif; background: #e0e5ea; display: flex; justify-content: center; padding: 30px; margin: 0; }
|
||||
.block-container { width: 920px; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); display: flex; flex-direction: column; align-items: center; gap: 16px; }
|
||||
.desc { font-size: 14px; color: #444; text-align: center; line-height: 1.7; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="block-container">
|
||||
|
||||
<svg viewBox="0 0 600 550" width="500" height="460" xmlns="http://www.w3.org/2000/svg" font-family="Pretendard Variable, sans-serif">
|
||||
<defs>
|
||||
<!-- 배경 그라데이션 (연한 회색→흰) -->
|
||||
<linearGradient id="bgGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#dce3ea" />
|
||||
<stop offset="100%" stop-color="#f0f2f5" />
|
||||
</linearGradient>
|
||||
|
||||
<!-- 큰 파란 원 그라데이션 -->
|
||||
<radialGradient id="blueOuter" cx="45%" cy="40%" r="55%">
|
||||
<stop offset="0%" stop-color="#2979ff" />
|
||||
<stop offset="40%" stop-color="#1565c0" />
|
||||
<stop offset="100%" stop-color="#0d47a1" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- 주황→마젠타 원 -->
|
||||
<radialGradient id="orangeGrad" cx="35%" cy="35%" r="65%">
|
||||
<stop offset="0%" stop-color="#ffab40" />
|
||||
<stop offset="40%" stop-color="#ff6d00" />
|
||||
<stop offset="100%" stop-color="#c2185b" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- 민트/틸 원 -->
|
||||
<radialGradient id="mintGrad" cx="40%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#80deea" />
|
||||
<stop offset="40%" stop-color="#26c6da" />
|
||||
<stop offset="100%" stop-color="#00897b" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- 골드 원 -->
|
||||
<radialGradient id="goldGrad" cx="40%" cy="30%" r="65%">
|
||||
<stop offset="0%" stop-color="#ffd54f" />
|
||||
<stop offset="40%" stop-color="#ffb300" />
|
||||
<stop offset="100%" stop-color="#e65100" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- 하이라이트 (구체 광택) -->
|
||||
<radialGradient id="highlight" cx="35%" cy="25%" r="40%">
|
||||
<stop offset="0%" stop-color="rgba(255,255,255,0.5)" />
|
||||
<stop offset="100%" stop-color="rgba(255,255,255,0)" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- 글로우 필터 -->
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="8" result="blur" />
|
||||
<feMerge>
|
||||
<feMergeNode in="blur" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- 그림자 -->
|
||||
<filter id="shadow">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="rgba(0,0,0,0.3)" />
|
||||
</filter>
|
||||
|
||||
<!-- 큰 원 안쪽 그림자 (깊이감) -->
|
||||
<filter id="innerDepth" x="-10%" y="-10%" width="120%" height="120%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="15" result="blur" />
|
||||
<feOffset dx="0" dy="5" result="offsetBlur" />
|
||||
<feComposite in="SourceGraphic" in2="offsetBlur" operator="over" />
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- 배경 -->
|
||||
<rect width="600" height="550" fill="url(#bgGrad)" rx="0" />
|
||||
|
||||
<!-- 큰 파란 원 + 동심원 링 (바깥→안쪽) -->
|
||||
<circle cx="300" cy="270" r="230" fill="url(#blueOuter)" filter="url(#shadow)" />
|
||||
<circle cx="300" cy="270" r="220" fill="none" stroke="#4a90d9" stroke-width="1.5" opacity="0.4" />
|
||||
<circle cx="300" cy="270" r="205" fill="none" stroke="#5a9de0" stroke-width="1" opacity="0.3" />
|
||||
<circle cx="300" cy="270" r="190" fill="none" stroke="#6aabe6" stroke-width="0.8" opacity="0.25" />
|
||||
<circle cx="300" cy="270" r="175" fill="none" stroke="#7ab8ec" stroke-width="0.6" opacity="0.2" />
|
||||
|
||||
<!-- 주황→마젠타 원 (가장 큼, 좌측) -->
|
||||
<circle cx="265" cy="300" r="120" fill="url(#orangeGrad)" opacity="0.92" filter="url(#glow)" />
|
||||
<circle cx="265" cy="300" r="120" fill="url(#highlight)" />
|
||||
|
||||
<!-- 민트 원 (우상) -->
|
||||
<circle cx="370" cy="230" r="75" fill="url(#mintGrad)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="370" cy="230" r="75" fill="url(#highlight)" />
|
||||
|
||||
<!-- 골드 원 (우하) -->
|
||||
<circle cx="365" cy="355" r="75" fill="url(#goldGrad)" opacity="0.9" filter="url(#glow)" />
|
||||
<circle cx="365" cy="355" r="75" fill="url(#highlight)" />
|
||||
|
||||
<!-- 텍스트: 디지털 전환 (큰 원 상단) -->
|
||||
<text x="300" y="95" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="400" opacity="0.85">Digital Transformation</text>
|
||||
<text x="300" y="125" text-anchor="middle" fill="#ffffff" font-size="26" font-weight="900">디지털 전환(D/X)</text>
|
||||
|
||||
<!-- 텍스트: Digital Twin (주황 원 중앙) -->
|
||||
<text x="250" y="295" text-anchor="middle" fill="#ffffff" font-size="20" font-weight="800">Digital Twin</text>
|
||||
<text x="250" y="318" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="400" opacity="0.85">(Metaverse)</text>
|
||||
|
||||
<!-- 텍스트: BIM (민트 원 중앙) -->
|
||||
<text x="370" y="237" text-anchor="middle" fill="#ffffff" font-size="20" font-weight="800">BIM</text>
|
||||
|
||||
<!-- 텍스트: GIS (골드 원 중앙) -->
|
||||
<text x="365" y="362" text-anchor="middle" fill="#ffffff" font-size="20" font-weight="800">GIS</text>
|
||||
</svg>
|
||||
|
||||
<div class="desc">건설산업의 DX는 GIS, BIM, 디지털 트윈의 기술 융합을 통해서만 실현 가능</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1
04. design_agent/docs/figma-analysis/1-1_d1.json
Normal file
@@ -0,0 +1 @@
|
||||
{"status":429,"err":"Rate limit exceeded"}
|
||||
1
04. design_agent/docs/figma-analysis/1-1_raw.json
Normal file
@@ -0,0 +1 @@
|
||||
{"status":429,"err":"Rate limit exceeded"}
|
||||
1
04. design_agent/docs/figma-analysis/1-1_미래_raw.json
Normal file
@@ -0,0 +1 @@
|
||||
{"status":429,"err":"Rate limit exceeded"}
|
||||
1
04. design_agent/docs/figma-analysis/2-1_01_detail.json
Normal file
1
04. design_agent/docs/figma-analysis/2-1_02_detail.json
Normal file
254
04. design_agent/docs/figma-analysis/DESIGN-ANALYSIS.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# Figma 디자인 분석 보고서
|
||||
|
||||
## 파일 정보
|
||||
- **파일명:** 바론컨설턴트 홈페이지_기획팀공유
|
||||
- **페이지:** 바론 공유 2025.05.13 (node: 1574-6254)
|
||||
- **분석일:** 2026-03-25
|
||||
|
||||
---
|
||||
|
||||
## 1. 전체 구조
|
||||
|
||||
### 메인 페이지 (3장)
|
||||
| 섹션 | 프레임 | 크기 | 스크린샷 |
|
||||
|------|--------|------|---------|
|
||||
| 1장 바론컨설턴트 | 1-1 미래 | 1920x5990 | `1장_1-1_미래.png` |
|
||||
| | 기술 | 1920x5677 | `1장_기술.png` |
|
||||
| | 가치 | 1920x4157 | `1장_가치.png` |
|
||||
|
||||
### 자세히보기 페이지 (13개 서브 프레임)
|
||||
| 섹션 | 프레임 | 크기 | 스크린샷 |
|
||||
|------|--------|------|---------|
|
||||
| 2-1장 건설산업 DX | 2-1_01 건설산업 | 920x1231 | `2-1_01_건설산업.png` |
|
||||
| | 2-1_02 BIM | 920x2179 | `2-1_02_BIM.png` |
|
||||
| | 2-1_03 GIS | 920x2208 | `2-1_03_GIS.png` |
|
||||
| | 2-1_04 디지털트윈 | 920x1651 | `2-1_04_디지털트윈.png` |
|
||||
| 2-2장 DX와 SW | 2-2_01 | 920x3013 | `2-2_01.png` |
|
||||
| | 2-2_02 | 920x1742 | `2-2_02.png` |
|
||||
| | 2-2_03 | 920x2129 | `2-2_03.png` |
|
||||
| | 2-2_04 | 920x1814 | `2-2_04.png` |
|
||||
| 2-3장 DX 활용 | 2-3_01 ~ 2-3_05 | 920x2300~3016 | `2-3_01~05.png` |
|
||||
|
||||
---
|
||||
|
||||
## 2. 추출된 디자인 토큰
|
||||
|
||||
### 색상 팔레트
|
||||
|
||||
| 용도 | Figma 값 | 현재 tokens.css | 비고 |
|
||||
|------|----------|---------------|------|
|
||||
| **메인 텍스트** | `#000000` | `--color-primary: #1e293b` | Figma가 더 진함 |
|
||||
| **포인트 (파란)** | `#004cbe` | `--color-accent: #2563eb` | Figma가 더 진한 남색 |
|
||||
| **포인트 밝은** | `#006aff` | 없음 | **추가 필요:** `--color-accent-bright` |
|
||||
| **포인트 하늘** | `#6bcdff` | 없음 | **추가 필요:** `--color-accent-light` |
|
||||
| **포인트 하늘2** | `#00aaff` | 없음 | 참고 |
|
||||
| **포인트 파랑** | `#008fff`, `#007cff` | 없음 | 원형 마커 색상 |
|
||||
| **배경 밝은** | `#f6f7f9` | `--color-bg-subtle: #f8fafc` | 거의 동일 |
|
||||
| **배경 흰** | `#ffffff` | `--color-bg: #ffffff` | 동일 |
|
||||
| **섹션 타이틀** | `#ffffff` (배경 위) | - | 다크 배경 위 흰 텍스트 |
|
||||
|
||||
### 폰트 체계
|
||||
|
||||
| 용도 | Figma | 현재 tokens.css | 비고 |
|
||||
|------|-------|---------------|------|
|
||||
| **페이지 타이틀** | Noto Sans CJK KR, 35px, w700 | `--font-title: 2rem (32px)` | Figma가 약간 큼 |
|
||||
| **영문 서브타이틀** | 15px, w400 | 없음 | section_title 영문 |
|
||||
| **꼭지 제목** | 24px, w700 | `--font-subtitle: 1.25rem (20px)` | Figma가 큼 |
|
||||
| **본문** | 16px, w400 | `--font-body: 0.95rem (15.2px)` | 거의 동일 |
|
||||
| **카드 내 제목** | 14px, w700 | `--font-caption: 0.8rem (12.8px)` | Figma가 큼 |
|
||||
| **카드 내 본문** | 14px, w400 | `--font-caption` | 동일 |
|
||||
| **태그/라벨** | 20px, w700 | 없음 | DX/BIM/VS 라벨 |
|
||||
| **소제목** | 13px, w400 | `--font-small: 0.7rem (11.2px)` | Figma가 약간 큼 |
|
||||
|
||||
### 간격/크기
|
||||
|
||||
| 요소 | Figma 값 | 비고 |
|
||||
|------|----------|------|
|
||||
| 프레임 폭 | 920px | 자세히보기 프레임 |
|
||||
| 섹션 타이틀 영역 | 249x73px | 영문+한글 2줄 |
|
||||
| 꼭지 제목+설명 영역 | 742x68~78px | 좌: 제목 240px, 우: 설명 422px |
|
||||
| 카드 (3열) | 240x365px 각각 | 이미지+제목+설명 |
|
||||
| 이미지 그리드 | 460x354px (2열) | 그라데이션 오버레이 포함 |
|
||||
| 비교 박스 | 327x116px, 325x116px | 나란히 2개 |
|
||||
| 원형 마커 | 10x10px, 151x151px | 작은 점, 큰 원 |
|
||||
| 배경 헤더 영역 | 963x515px | 그라데이션+웨이브 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 발견된 재사용 컴포넌트
|
||||
|
||||
### 공통 컴포넌트 (모든 자세히보기에 반복)
|
||||
|
||||
#### A. section_title (섹션 타이틀)
|
||||
```
|
||||
구조: FRAME 249x73
|
||||
├── TEXT 15px/w400 #ffffff — 영문 (예: "Building Information Modeling")
|
||||
└── TEXT 35px/w700 #ffffff — 한글 (예: "건설정보모델링(BIM)")
|
||||
배경: 파란 그라데이션 헤더 위에 위치
|
||||
```
|
||||
- **모든 자세히보기 프레임의 상단**에 동일 구조로 반복
|
||||
- 영문 서브타이틀 + 한글 메인 타이틀
|
||||
- 흰색 텍스트 + 다크 배경
|
||||
|
||||
#### B. bg (배경 헤더)
|
||||
```
|
||||
구조: GROUP 1319x671
|
||||
├── Mask group (그라데이션 + 웨이브 이미지)
|
||||
├── RECTANGLE 그라데이션 (파란→투명)
|
||||
├── RECTANGLE 흰색 배경
|
||||
└── shape (벡터 웨이브 라인 7줄)
|
||||
```
|
||||
- 상단 파란 그라데이션 + 웨이브 패턴
|
||||
- **이미지로 export해서 사용해야 하는 영역** (CSS 재현 불가)
|
||||
|
||||
#### C. sub_제목,내용 (꼭지 제목+설명)
|
||||
```
|
||||
구조: FRAME 742x68~78
|
||||
├── TEXT 24px/w700 #004cbe — 질문/소제목 (좌측 240px)
|
||||
└── TEXT 16px/w400 #000000 — 설명 (우측 422px)
|
||||
```
|
||||
- 좌: 파란 굵은 제목 (질문형)
|
||||
- 우: 검정 본문 설명
|
||||
- 2단 가로 배치 (240:422 비율)
|
||||
|
||||
#### D. close 버튼
|
||||
```
|
||||
구조: FRAME 40x40
|
||||
└── VECTOR 23x23 #ffffff — X 아이콘
|
||||
```
|
||||
|
||||
### 콘텐츠 컴포넌트
|
||||
|
||||
#### E. 카드 3열 (2-1_02 BIM 페이지)
|
||||
```
|
||||
구조: GROUP 751x377
|
||||
├── FRAME 744x365 (카드 3장 컨테이너)
|
||||
│ ├── RECTANGLE 240x365 #ffffff (카드1)
|
||||
│ ├── RECTANGLE 240x365 #ffffff (카드2)
|
||||
│ └── RECTANGLE 240x365 #ffffff (카드3)
|
||||
├── 이미지 3장 (각 카드 상단)
|
||||
└── FRAME 240x180~188 (각 카드 텍스트)
|
||||
├── TEXT 14px/w700 — 단계명 (영문 포함)
|
||||
├── RECTANGLE 구분선
|
||||
└── TEXT 14px/w400 — 설명 불릿
|
||||
```
|
||||
- 카드 크기: 240x365px
|
||||
- 상단: 이미지 (시공/설계/유지관리)
|
||||
- 중간: 14px 굵은 제목 (색상으로 구분: `#00aaff`, `#006aff`, `#004cbe`)
|
||||
- 하단: 14px 일반 설명
|
||||
|
||||
#### F. 비교 박스 2열 (2-1_02 BIM 페이지)
|
||||
```
|
||||
구조: 2개 GROUP 나란히
|
||||
├── GROUP 327x116
|
||||
│ ├── RECTANGLE #006aff (배경)
|
||||
│ └── FRAME (그라데이션 내부)
|
||||
└── GROUP 325x116
|
||||
├── RECTANGLE #006aff (배경)
|
||||
└── FRAME (그라데이션 내부)
|
||||
+ DX/BIM/VS 라벨 (20px/w700, #ffffff)
|
||||
```
|
||||
- 파란 배경 박스 2개 나란히
|
||||
- 내부에 방사형 그라데이션
|
||||
- 가운데 "VS" 라벨
|
||||
|
||||
#### G. 이미지 그리드 2열 (2-1_02 BIM 페이지)
|
||||
```
|
||||
구조: 2개 GROUP 나란히
|
||||
├── GROUP 460x354
|
||||
│ ├── RECTANGLE 그라데이션 오버레이
|
||||
│ └── RECTANGLE IMG (실제 이미지)
|
||||
└── GROUP 460x354
|
||||
├── RECTANGLE 그라데이션 오버레이
|
||||
└── RECTANGLE IMG (실제 이미지)
|
||||
```
|
||||
- 2열 이미지 나란히 (460x354 각)
|
||||
- 이미지 위에 그라데이션 오버레이 (어두워지는 효과)
|
||||
|
||||
#### H. 산맥 시각화 (2-1_02 BIM 페이지)
|
||||
```
|
||||
구조: GROUP 920x183
|
||||
├── RECTANGLE 그라데이션 배경
|
||||
├── GROUP 벡터 산맥 라인 (20+ VECTOR)
|
||||
└── GROUP 수직 라인 마커
|
||||
```
|
||||
- **이미지로 export** (벡터 라인이 너무 복잡)
|
||||
|
||||
#### I. 원형 라벨 (2-1_02 BIM 페이지)
|
||||
```
|
||||
구조: GROUP 190x190
|
||||
├── GROUP (원형 테두리 그룹)
|
||||
├── ELLIPSE 151x151 그라데이션
|
||||
├── ELLIPSE 145x145 그라데이션
|
||||
└── TEXT 20px/w700 #ffffff — "단계별 BIM의 활용"
|
||||
```
|
||||
- 중앙 큰 원 + 텍스트
|
||||
- 이중 원 테두리 (그라데이션)
|
||||
|
||||
---
|
||||
|
||||
## 4. 블록 매핑 (Figma 패턴 → design_agent 블록)
|
||||
|
||||
| Figma 패턴 | design_agent 블록 | 구현 방식 | 상태 |
|
||||
|------------|-----------------|---------|------|
|
||||
| section_title | `section-title` | HTML/CSS | **신규 필요** |
|
||||
| sub_제목,내용 | 기존 없음 → `topic-header` | HTML/CSS (좌:제목 우:설명) | **신규 필요** |
|
||||
| 카드 3열 (이미지+제목+설명) | `card-grid` 변형 | HTML/CSS (이미지 추가) | **변형 필요** |
|
||||
| 비교 박스 2열 | `comparison` | HTML/CSS | ✅ 기존 |
|
||||
| 이미지 그리드 2열 | `image-gallery` | HTML + 이미지 | **신규 필요** |
|
||||
| 원형 라벨 | `circle-label` | CSS 원 + 텍스트 | **신규 필요** |
|
||||
| 배경 헤더 (bg) | - | **이미지 export** | Figma export |
|
||||
| 산맥 시각화 | - | **이미지 export** | Figma export |
|
||||
| 벡터 웨이브 | - | **이미지 export** | Figma export |
|
||||
| DX/BIM/VS 비교 라벨 | `comparison` 내부 | HTML/CSS | ✅ 기존 활용 |
|
||||
|
||||
### 이미지로 export해야 하는 요소
|
||||
|
||||
| 요소 | 이유 | export 형식 |
|
||||
|------|------|-----------|
|
||||
| bg (배경 헤더) | 그라데이션+웨이브+마스크 | PNG (배경용) |
|
||||
| 산맥 시각화 | 20+ 벡터 라인 | PNG 또는 SVG |
|
||||
| 이미지 오버레이 그라데이션 | CSS로 가능하지만 Figma 원본이 더 정확 | CSS gradient (재현 가능) |
|
||||
| 3D 렌더링 이미지 | Figma 내 이미지 에셋 | PNG |
|
||||
|
||||
---
|
||||
|
||||
## 5. 디자인 토큰 업데이트 제안
|
||||
|
||||
기존 `tokens.css`에 추가가 필요한 토큰:
|
||||
|
||||
```css
|
||||
/* Figma 기반 추가 토큰 */
|
||||
--color-accent-deep: #004cbe; /* Figma 진한 파란 (꼭지 제목) */
|
||||
--color-accent-bright: #006aff; /* Figma 밝은 파란 (카드 헤더, 박스) */
|
||||
--color-accent-sky: #6bcdff; /* Figma 하늘색 (BIM 라벨) */
|
||||
--color-accent-cyan: #00aaff; /* Figma 시안 (설계단계) */
|
||||
|
||||
--font-page-title: 35px; /* Figma 페이지 타이틀 */
|
||||
--font-topic-title: 24px; /* Figma 꼭지 제목 */
|
||||
--font-card-title: 14px; /* Figma 카드 내 제목 */
|
||||
--font-en-subtitle: 15px; /* Figma 영문 서브타이틀 */
|
||||
--font-tag: 20px; /* Figma 태그/라벨 (DX, BIM, VS) */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 다음 단계
|
||||
|
||||
### 즉시 가능 (HTML/CSS로 구현)
|
||||
1. `section-title` 블록 — 영문+한글 2줄 타이틀
|
||||
2. `topic-header` 블록 — 좌:질문 우:설명 (742px, 240:422 비율)
|
||||
3. `card-grid` 이미지 변형 — 상단 이미지 + 하단 텍스트
|
||||
4. `image-gallery` 블록 — 2열 이미지 + 오버레이
|
||||
5. `circle-label` 블록 — CSS 원형 + 중앙 텍스트
|
||||
|
||||
### Figma에서 이미지 export 필요
|
||||
1. 배경 헤더 (bg) — 각 프레임의 상단 파란 영역
|
||||
2. 산맥/웨이브 시각화
|
||||
3. 3D 렌더링 이미지 (시공, 설계, 유지관리 등)
|
||||
4. 아이콘 에셋
|
||||
|
||||
### AI 이미지 생성 영역 (레이어 방식)
|
||||
1. 순환도/관계도 배경
|
||||
2. 3D 효과가 필요한 다이어그램
|
||||
3. 복합 시각 효과 (글로우, 보케, 입체)
|
||||
BIN
04. design_agent/docs/figma-assets/2-1_02_full_frame.png
Normal file
|
After Width: | Height: | Size: 784 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_01_full_hd.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
04. design_agent/docs/figma-assets/2-2_01_icon_card_1.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_01_icon_card_2.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_01_icon_card_3.png
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
04. design_agent/docs/figma-assets/2-2_01_icon_card_4.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_01_icon_card_5.png
Normal file
|
After Width: | Height: | Size: 852 B |
BIN
04. design_agent/docs/figma-assets/2-2_02_full_hd.png
Normal file
|
After Width: | Height: | Size: 746 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_03_full_hd.png
Normal file
|
After Width: | Height: | Size: 717 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_04_full_hd.png
Normal file
|
After Width: | Height: | Size: 964 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_icon_card_1.png
Normal file
|
After Width: | Height: | Size: 273 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_icon_card_2.png
Normal file
|
After Width: | Height: | Size: 334 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_icon_card_3.png
Normal file
|
After Width: | Height: | Size: 336 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_icon_card_4.png
Normal file
|
After Width: | Height: | Size: 457 KiB |
BIN
04. design_agent/docs/figma-assets/2-2_icon_card_5.png
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
04. design_agent/docs/figma-assets/bg_header.png
Normal file
|
After Width: | Height: | Size: 522 KiB |
BIN
04. design_agent/docs/figma-assets/bim_card_3col.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
04. design_agent/docs/figma-assets/bim_circle_label.png
Normal file
|
After Width: | Height: | Size: 170 B |
BIN
04. design_agent/docs/figma-assets/bim_comparison_table.png
Normal file
|
After Width: | Height: | Size: 162 B |
BIN
04. design_agent/docs/figma-assets/bim_mountain_viz.png
Normal file
|
After Width: | Height: | Size: 162 B |
BIN
04. design_agent/docs/figma-assets/breadcrumb_area.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
04. design_agent/docs/figma-assets/card_3col.png
Normal file
|
After Width: | Height: | Size: 388 KiB |