add: figma_to_html_agent/blocks/ + 변환 도구 docs 갱신

전체 401 files (397 추가 + 4 수정), 14304 insertions.

추가:
- figma_to_html_agent/blocks/ — Figma 변환 결과 (32 frame, ~79MB).
  각 frame folder = {analysis.md, flat.md, texts.md, index.html, assets/,
  _renders/, _render.py, RELATIONSHIPS.md / STATUS.md / classification.md
  (일부 frame)}.
  Phase Z 의 *figma source layer* — runtime 에서 직접 사용 X, contract /
  partial / builder adapter (미래 axis A) 의 source.
- figma_to_html_agent/DISCUSSION-SUMMARY-20260411.md — 변환 설계 회의 기록.
- figma_to_html_agent/HARNESS.md — 변환 검증 harness.
- figma_to_html_agent/scripts/fetch_figma_screenshots.py — Figma 스크린샷 자동 수집.

수정:
- figma_to_html_agent/PROCESS-CONTROL.md / PROCESS.md / RULES.md —
  변환 프로세스 / 룰 갱신 (R8/R9 lock 강화 등).
- figma_to_html_agent/blocks_index.md — 32 frame 인덱스 갱신.

Phase Z 영향 0 (figma_to_html_agent/blocks/ 가 V4 catalog +
templates/phase_z2/families adapter 의 source — runtime 에서 직접 import X).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 09:41:05 +09:00
parent cc2f434000
commit 9fbe3ac90c
401 changed files with 14304 additions and 2 deletions

View File

@@ -0,0 +1,42 @@
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from PIL import Image
import os, time
here = os.path.dirname(os.path.abspath(__file__))
renders = os.path.join(here, '_renders')
os.makedirs(renders, exist_ok=True)
opts = Options()
opts.add_argument('--headless=new')
opts.add_argument('--hide-scrollbars')
opts.add_argument('--force-device-scale-factor=1')
opts.add_argument('--window-size=1600,900')
d = webdriver.Chrome(options=opts)
p = os.path.join(here, 'index.html').replace(os.sep, '/')
d.get('file:///' + p)
time.sleep(2.0)
full_png = os.path.join(renders, '_full.png')
d.save_screenshot(full_png)
r = d.execute_script(
'const r=document.querySelector(".slide").getBoundingClientRect();'
'return [r.x,r.y,r.width,r.height];'
)
print('slide bounds:', r)
Image.open(full_png).crop(
(int(r[0]), int(r[1]), int(r[0]+r[2]), int(r[1]+r[3]))
).save(os.path.join(renders, 'slide.png'))
b = d.execute_script(
'const r=document.querySelector(".block").getBoundingClientRect();'
'return [r.x,r.y,r.width,r.height];'
)
print('block bounds:', b)
Image.open(full_png).crop(
(int(b[0]), int(b[1]), int(b[0]+b[2]), int(b[1]+b[3]))
).save(os.path.join(renders, 'block.png'))
d.quit()
print('OK')

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

View File

@@ -0,0 +1,62 @@
# Frame 1171281174 — 국외 BIM 수행 현황
## 내용 설명
국외 BIM 및 설계 업무 수행의 4가지 주요 특징을 번호별 리스트로
제시하는 디자인. 항목: Claim 최소화 오류예방, 설계 업무 Data 정리
필수, 기술업무 Manual 작성, 데이터 통합 및 관리. 국외 선진 사례
특성 나열·자체 기술력 기반 수행 특징 정리·번호별 항목 4개 병렬
제시에 적합. 3개 이하·5개 이상 항목·주체별 나열·2개 비교·시간
순서 단계(step1→step2)·필수요건 나열에는 부적합.
## 후보 키워드
국외, BIM수행, Claim최소화, 오류예방, 설계Data, Manual, 기술업무, 데이터통합, 관리
## 정제 Anchor Sets
- **overseas_bim**: 국외, BIM수행
- **bim_practices**: Claim최소화, 오류예방, 설계Data, Manual, 기술업무, 데이터통합
- **management**: 관리, 기술업무
## 구조 매칭 정보
- **family**: list
- **layout**: list-numbered-4
- **axis**: vertical
- **relation_type**: parallel
- **cardinality**: ideal 4 / min 4 / max 4
- **slots** (5개, required 5개): title, item_1, item_2, item_3, item_4
- **source title**: 국외 BIM 수행 현황
- **original layout**: list-numbered
## 적합/부적합 기준
### suits
- 국외 선진 사례 특성 4항목
- 자체 기술력 기반 수행 특징
- 번호별 4 병렬 리스트
### not_suits
- 3개 이하 항목
- 5개 이상 항목
- 주체별 나열 (발주자/시공자/설계자)
- 2개 비교
- 시간 순서 단계
- 필수요건 나열 (기술/사람/자연)
## 재구성 허용
- **split**: False
- **merge**: False
- **infer_missing_slot**: False
- **rewrite_label**: True
- **rewrite_body**: True
## 메타
- schema_version: template-fit-v1 mirror
- source_of_truth: structure_ontology.yaml + keyword_base.yaml
- structure_content_original_tagged_by: claude-opus-4-7 (2026-04-21)
- keyword_base_sync_at: 2026-04-22
- anchor_sets_cleaned_at: 2026-04-22

View File

@@ -0,0 +1,17 @@
# Frame 1171281174 — 국외 BIM 수행 현황
## 구조
- **layout**: list-numbered
- **detail**: 타이틀("국외") + 번호별 4개 항목 리스트(01~04)
## 내용
국외 BIM/설계 업무 수행 특징 — Claim 최소화, 설계 업무 Data 정리 필수, 기술업무 Manual 작성, 데이터 통합 및 관리.
## 후보 키워드
국외, BIM수행, Claim최소화, 오류예방, 설계Data, Manual, 기술업무, 데이터통합, 관리, 자체기술력
## 메타
- source: texts.md + flat.md
- schema_version: analysis-v1
- tagged_by: claude-opus-4-7
- tagged_at: 2026-04-21

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,80 @@
# Frame 1171281174 — 실측 기록 (flat)
> 원본: 1728 × 657 px (node 182:2810, file 9S6LsQyO6zlRxtiqZccOUM, page 29:373)
> 패턴: scene-with-numbered-list-4 (좌:장면 이미지+글로브, 우:번호 4개 + brown pill 텍스트 버블)
> Scale: 1280 / 1728 = **0.74074** → 슬라이드 안 1280 × 486.7 px 차지
## 구조 (bottom-up)
```
Frame 182:2810 "Frame 1171281174" (1728 × 657)
├─ rounded-rect 182:2811 "image 3939" (0, 0) 447×133 ← header_pill.png (브라운 pill 배경)
├─ TEXT 182:2812 "국외" center=(223.5, 68), top-left=(46, 23) 355×90 — 60px Bold 흰색, tracking -1.8, line-height 90
├─ rounded-rect 182:2813 "image 3940" (0, 19) 75×88 ← pin_icon.png (pin/marker 아이콘)
├─ rounded-rect 182:2825 "image 3949" (53, 139) 815×465 ← scene.png (건설 현장 합성 이미지, opacity 0.7, radius 27)
├─ rounded-rect 182:2826 "image 3951" (718, 159) 127×126 ← globe.png (구 모양 아이콘, border 3 white, radius 132.5, opacity 0.8)
├─ rounded-rect 182:2828 "image 3957" (825, 86) 115×571 ← arrow_chain.png (수직 화살표 체인, 4개 노드를 연결)
├─ rounded-rect 182:2814 "image 3953" (954, 136) 760×97 ← text_bubble.png (브라운 둥근 막대)
├─ rounded-rect 182:2815 "image 3954" (954, 266) 760×97 ← text_bubble.png (재사용)
├─ rounded-rect 182:2816 "image 3955" (954, 407) 760×97 ← text_bubble.png (재사용)
├─ rounded-rect 182:2817 "image 3956" (954, 543) 760×97 ← text_bubble.png (재사용)
├─ TEXT 182:2818 "오류에 의한 Claim 최소화" (1033, 149) 695×60 — 45px Medium #11231D, leading 60, text-shadow
├─ TEXT 182:2819 "설계 업무 시 사업 Data 정리 필수" (1033, 285) 695×60
├─ TEXT 182:2820 "자체적인 기술업무 Manual 작성" (1033, 421) 695×60
├─ TEXT 182:2821 "데이터 통합 및 관리" (1033, 562) 695×60
├─ rounded-rect 182:2822 "01 2" (906, 117) 89×93 ← badge_01.png (번호 1 + 우측 화살표)
├─ rounded-rect 182:2823 "02 2" (906, 238) 89×93 ← badge_02.png
├─ rounded-rect 182:2824 "03 2" (906, 376) 89×93 ← badge_03.png
└─ rounded-rect 182:2827 "04 1" (906, 509) 89×93 ← badge_04.png (이름 suffix만 다름)
```
## 에셋 (10개)
| 파일 | 의미 | 크기 | 사용 횟수 |
|------|------|------|---------|
| `assets/header_pill.png` | 좌상단 브라운 pill 헤더 배경 | 447×133 | 1 |
| `assets/pin_icon.png` | pin/marker 아이콘 (헤더 위 겹침) | 75×88 | 1 |
| `assets/scene.png` | 건설 현장 합성 메인 이미지 (4.5MB) | 815×465 | 1 (opacity 0.7) |
| `assets/globe.png` | 구 모양 원형 아이콘 (장면 위) | 127×126 | 1 (opacity 0.8, white border) |
| `assets/arrow_chain.png` | 수직 화살표 체인 (장면→번호 연결) | 115×571 | 1 |
| `assets/text_bubble.png` | 브라운 둥근 막대 배경 | 760×97 | **4** (재사용) |
| `assets/badge_01.png` | 번호 1 (chevron 우측 화살표 포함) | 89×93 | 1 |
| `assets/badge_02.png` | 번호 2 | 89×93 | 1 |
| `assets/badge_03.png` | 번호 3 | 89×93 | 1 |
| `assets/badge_04.png` | 번호 4 (Figma 이름 suffix `_1` 다름, 비주얼 동일) | 89×93 | 1 |
## 이상 탐지 결과
| 검사 | 결과 |
|------|------|
| 회전 단일문자 | 없음 |
| 좁은 박스 세로 텍스트 | 없음 |
| 중복 노드 (동일 좌표 + 동일 내용) | 없음. text_bubble은 동일 src 4× 재사용 — 정상 |
| Vector 좌표 metadata vs design_context 불일치 | 일치 |
| 회전 적용 (bbox vs render 차이) | 없음 (모두 정사각형 또는 가로 배치) |
| z-order 비정상 | scene(이미지 3949)가 badges 01-03 다음 순서로 그려짐 → 시각 영향 없음 (위치 비겹침) |
## 변형 가능 축
- **list_items[N=4] (required)** — 번호 4개 항목, cardinality=4 고정 (analysis.md)
- `text` (required, 한 줄, 45px 분량)
- `header_pill` (required) — 좌상단 카테고리 헤더 ("국외" 외 다른 텍스트 가능)
- `header_pin` (optional) — pin 아이콘
- `scene_image` (optional) — 메인 합성 이미지. 없으면 박스 자리만 차지하거나 단색 fill
- `globe_overlay` (optional) — 원형 오버레이 아이콘
- `arrow_chain` (required) — 장면과 리스트 연결하는 수직 체인
- `numbered_badges[N=list_items.length]` (required) — 번호별 PNG 배지
## Sub-patterns
- `scene-photo-with-circle-overlay` — 큰 합성 이미지 + 원형 아이콘 오버레이 (R16 비슷한 프레임 배치 패턴)
- `numbered-pill-list` — 번호 배지 + 옆 pill 텍스트 막대 N개 (1171281180 stacked-arrow-list와 다름: 여기는 평행 배열, 1171281180은 계단)
## 임시 보정 (1:1, 템플릿화 시 재고려)
- 번호 배지를 PNG로 유지 (CSS 변환 시 1171281174의 chevron 모양 + 번호 폰트 동시 재현 필요 → 향후 svg/ 폴더로 정리)
- text_bubble을 PNG로 유지 (CSS gradient/border-radius로 변환 가능 → 프로모션 시 CSS화 후보)

View File

@@ -0,0 +1,205 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>국외 BIM 수행 현황 (Frame 1171281174)</title>
<!--
Frame: 182:2810, 1728 × 657 px (Frame 1171281174)
Source: file 9S6LsQyO6zlRxtiqZccOUM, page 29:373
Scale: 1280 / 1728 = 0.74074 (zoom on .inner per R19)
패턴: scene-with-numbered-list-4
구조: 좌(헤더 pill + scene + 글로브) / 우(수직 화살표 체인 + 번호 배지 4개 + 텍스트 버블)
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
word-break: keep-all;
}
.slide {
width: 1280px; height: 720px;
background: #fff;
position: relative; overflow: hidden;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
display: flex; align-items: center; justify-content: center;
}
.block {
width: 1280px;
position: relative;
overflow: hidden;
}
.inner {
width: 1728px; height: 657px;
position: relative;
zoom: 0.74074;
}
/* ① 메인 장면 이미지 (배경) */
.scene {
position: absolute;
left: 53px; top: 139px;
width: 815px; height: 465px;
border-radius: 27px;
overflow: hidden;
}
.scene img {
width: 100%; height: 100%;
object-fit: cover;
opacity: 0.7;
display: block;
}
/* ② 글로브 오버레이 (원형, 흰 테두리) */
.globe {
position: absolute;
left: 718px; top: 159px;
width: 127px; height: 126px;
border: 3px solid white;
border-radius: 132.5px;
overflow: hidden;
}
.globe img {
width: 100%; height: 100%;
object-fit: cover;
opacity: 0.8;
display: block;
}
/* ③ 좌상단 헤더 pill */
.header-pill {
position: absolute;
left: 0; top: 0;
width: 447px; height: 133.005px;
}
.header-pill img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ④ pin 아이콘 (헤더 위에 겹침) */
.pin {
position: absolute;
left: 0; top: 19px;
width: 75px; height: 87.662px;
}
.pin img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ⑤ "국외" 타이틀 텍스트 */
.title-text {
position: absolute;
left: 46px; top: 23px;
width: 355px; height: 90px;
font-family: 'Noto Sans KR', sans-serif;
font-weight: 700;
font-size: 60px;
color: white;
text-align: center;
letter-spacing: -1.8px;
line-height: 90px;
text-shadow: 0 0 4px rgba(0,0,0,0.5);
}
/* ⑥ 수직 화살표 체인 (장면 → 리스트) */
.arrow-chain {
position: absolute;
left: 825px; top: 86px;
width: 115px; height: 571px;
}
.arrow-chain img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ⑦ 텍스트 버블 4개 (브라운 pill 배경) */
.bubble {
position: absolute;
left: 954px;
width: 760px; height: 97px;
}
.bubble img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bubble--1 { top: 136px; }
.bubble--2 { top: 266px; }
.bubble--3 { top: 407px; }
.bubble--4 { top: 543px; }
/* ⑧ 텍스트 라벨 4개 */
.label {
position: absolute;
left: 1033px;
width: 695px; height: 60px;
font-family: 'Noto Sans KR', sans-serif;
font-weight: 500;
font-size: 45px;
color: #11231D;
text-shadow: 0 0 4px rgba(0,0,0,0.5);
display: flex;
align-items: center;
}
.label > p { margin: 0; line-height: 60px; }
.label--1 { top: 149px; } /* center_y=179, h=60 → top=149 */
.label--2 { top: 285px; }
.label--3 { top: 421px; }
.label--4 { top: 562px; }
/* ⑨ 번호 배지 4개 */
.badge {
position: absolute;
left: 906px;
width: 89px; height: 93px;
}
.badge img { width: 100%; height: 100%; object-fit: cover; display: block; }
.badge--1 { top: 117px; }
.badge--2 { top: 238px; }
.badge--3 { top: 376px; }
.badge--4 { top: 509px; }
</style>
</head>
<body>
<div class="slide">
<div class="block">
<div class="inner">
<!-- ① 장면 이미지 (배경, opacity 0.7) -->
<div class="scene"><img src="assets/scene.png" alt=""></div>
<!-- ② 글로브 오버레이 -->
<div class="globe"><img src="assets/globe.png" alt=""></div>
<!-- ③ 좌상단 헤더 pill -->
<div class="header-pill"><img src="assets/header_pill.png" alt=""></div>
<!-- ④ pin 아이콘 -->
<div class="pin"><img src="assets/pin_icon.png" alt=""></div>
<!-- ⑤ "국외" 타이틀 -->
<div class="title-text">국외</div>
<!-- ⑥ 수직 화살표 체인 -->
<div class="arrow-chain"><img src="assets/arrow_chain.png" alt=""></div>
<!-- ⑦ 텍스트 버블 4개 -->
<div class="bubble bubble--1"><img src="assets/text_bubble.png" alt=""></div>
<div class="bubble bubble--2"><img src="assets/text_bubble.png" alt=""></div>
<div class="bubble bubble--3"><img src="assets/text_bubble.png" alt=""></div>
<div class="bubble bubble--4"><img src="assets/text_bubble.png" alt=""></div>
<!-- ⑧ 텍스트 라벨 4개 -->
<div class="label label--1"><p>오류에 의한 Claim 최소화</p></div>
<div class="label label--2"><p>설계 업무 시 사업 Data 정리 필수</p></div>
<div class="label label--3"><p>자체적인 기술업무 Manual 작성</p></div>
<div class="label label--4"><p>데이터 통합 및 관리</p></div>
<!-- ⑨ 번호 배지 4개 -->
<div class="badge badge--1"><img src="assets/badge_01.png" alt="1"></div>
<div class="badge badge--2"><img src="assets/badge_02.png" alt="2"></div>
<div class="badge badge--3"><img src="assets/badge_03.png" alt="3"></div>
<div class="badge badge--4"><img src="assets/badge_04.png" alt="4"></div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,25 @@
# Frame 1171281174 — 텍스트 (TF-IDF 매칭용)
> 프레임 안의 모든 텍스트를 빠짐없이 추출. nodeId: 182:2810
## 타이틀
국외
## 본문 (번호별 항목)
### 01
오류에 의한 Claim 최소화
### 02
설계 업무 시 사업 Data 정리 필수
### 03
자체적인 기술업무 Manual 작성
### 04
데이터 통합 및 관리