IMPROVEMENT Phase A~D + Phase 2 전체 반영

## IMPROVEMENT (Phase A~D)
- A-1: 4단계 Sonnet 디자인 조정 (_adjust_design) — CSS 변수 cascade
- A-2: 5단계 HTML 전문 프롬프트 전달
- A-3: shrink/expand 하드코딩 제거 → Sonnet target_ratio 기반
- A-4: rewrite action 구현
- A-5: overflow: visible (area 레벨 텍스트 잘림 방지)
- A-6: object-fit cover → contain (이미지 crop 방지)
- A-7: table-layout: fixed
- A-8: container query 폰트 스케일링
- B-1: details-block 템플릿 신규 (CSS 변수만 사용)
- B-2: 인쇄 시 details 자동 펼침 JS
- B-3: catalog에 details-block 등록
- B-4/B-5: images[]/tables[] 상세 판단 + fallback 3곳 동기화
- B-8: fallback card-grid → topic-header + char_guide 제거
- C-1: CLAUDE.md gradient 원칙 완화
- C-3: border-radius 9개 파일 var(--radius) 통일
- C-4: box-shadow 2레벨 → 1레벨
- D-0: 이미지 경로 입력 UI + API base_path
- D-1: Pillow 의존성 + image_utils.py
- D-2~D-4: 이미지 비율/축소방지 프롬프트 전달
- D-5: HTML에 이미지 base64 삽입

## Phase 2 (다른 Claude 작업)
- P2-A: FAISS 블록 검색 (bge-m3, 46개 블록)
- P2-B: SVG N개 자동 배치 (svg_calculator.py)
- P2-C: Opus 블록 추천 (Kei API 경유)
- P2-D: 5단계 재검토 루프 강화 (MAX_REVIEW_ROUNDS=2)
- P2-E: details-block fallback 연동

## 버그 수정 (BF-8~10)
- BF-8: 컨테이너 예산 기반 블록 배치
- BF-9: grid와 Sonnet 역할 분리
- BF-10: catalog mtime 캐시 자동 갱신

## 블록 라이브러리
- 46개 블록 (6 카테고리), catalog/BLOCK_SLOTS/INDEX 동기화
- 구 블록 제거 (quote-block, card-grid, comparison)
- 13개 _legacy 블록 보존

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 18:40:20 +09:00
parent 91d5779a16
commit 9bd9dad9ac
220 changed files with 19115 additions and 667 deletions

105
docs/BLOCK_SLOTS_45.py Normal file
View 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": ""},
}

245
docs/PHASE2-PLAN.md Normal file
View 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
docs/PHASE2-PROCESS.md Normal file
View 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
docs/PHASE2-TECH-REVIEW.md Normal file
View 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개 프리셋 × 테스트 콘텐츠 조합 |

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View 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>

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View 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>

View 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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View 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. 복합 시각 효과 (글로우, 보케, 입체)

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Some files were not shown because too many files have changed in this diff Show More