Figma-to-HTML 에이전트 초기 커밋

- 10단계 변환 프로세스 (PROCESS.md)
- 수학 공식 레퍼런스 (MATH.md, gradient_math.py)
- CSS 보정 규칙 R1~R16 (RULES.md)
- 작업 규율 7개 규칙 (PROCESS-CONTROL.md)
- 8개 Figma 프레임 1:1 HTML 변환물 (block-tests/)
- 8개 Jinja2 템플릿 staging (templates_staging/)
- 변환 완료 도서관 + 디자인 인사이트 (blocks_index.md)
- 사용법 가이드 (README.md)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 11:16:33 +09:00
commit beb5fd0c61
205 changed files with 19164 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
# templates_staging/
**Stage 2 — Jinja2 추상화 staging 영역**
블록이 2번째로 등장한 순간 여기에 Jinja2 템플릿으로 추출된다. 사용자가 직접 검수한 뒤 design_agent 본체로 프로모션한다.
## 파일 구조
```
templates_staging/
├── README.md ← 이 파일
├── {pattern_id}.html.j2 ← Jinja2 템플릿 본체
└── {pattern_id}.meta.yaml ← when/slots/min_size_px 초안
```
## meta.yaml 형식 (초안)
```yaml
pattern_id: cycle-3way-intersect
category: visuals
when:
relation_type: [hierarchy, cycle]
min_circles: 2
max_circles: 5
not_for:
- linear_process
- simple_list
slots:
- name: circles
type: list
min: 2
max: 5
item:
label: string
gradient_from: color
gradient_to: color
accents: list
- name: side_labels
type: list
min: 0
max: 20
min_size_px:
width: 1024
height: 480
provenance:
source_frames:
- 66:310 (Frame 1171281211)
- {2번째 등장 frame ID}
reference_html: block-tests/bim-goals-3circles.html
```
## 흐름
```
1. block-tests/{slug_a}.html ← 1번째 등장
2. block-tests/{slug_b}.html ← 2번째 등장 (같은 패턴 발견)
3. templates_staging/{pattern_id}.html.j2 ← Jinja2 추출 (NOW)
templates_staging/{pattern_id}.meta.yaml
4. 🚧 사용자 검수 게이트 🚧
- 다양한 파라미터로 렌더 테스트
- 시각 충실도 확인
- meta.yaml 정밀화
5. design_agent/templates/blocks/{category}/{pattern_id}.html.j2 (사용자 직접)
design_agent/templates/catalog.yaml 등록 (사용자 직접)
6. blocks_index.md 상태 → "promoted"
```
## 금지
- 에이전트가 4단계 이후를 자동 수행하는 것
- meta.yaml 없이 .html.j2 만 작성하는 것
- 1개 등장만 보고 미리 templates_staging 작성 (반드시 2번째 등장 후)

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

View File

@@ -0,0 +1,418 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>BIM 3역할 목표 (사진 없는 mdx, 검증용)</title>
<!--
============================================================
Pattern: cards-3col-persona
Source: figma_to_html_agent/block-tests/bim-3roles-cards.html (1:1 reference)
Origin frame: 45:16 / Frame 1171281191
STRUCTURE: N개의 평행한 stakeholder 카드 (N=2~4)
각 카드 = bg image + color overlay + 상단 원형 badge + bullet list (custom marker) + optional bottom photo
PRINCIPLES (RULES.md, blocks_index.md 디자인 인사이트):
- I-1: 마커+텍스트는 시맨틱 list (R13)
- I-2: 평행 컬럼은 동일 top/bottom + 내부 spacing 자동 분배
- I-3: 모든 슬롯은 기본 optional (bottom_photo 등)
============================================================
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
/* 디자인 토큰 — 외부에서 override 가능 */
--block-w: 1280px;
--block-h: 720px;
--font-family: 'Noto Sans KR', sans-serif;
--font-body-size: 1.05rem;
--font-body-lh: 2.125; /* 85/40 */
--font-body-lh-compact: 1.25; /* 50/40 */
--col-gap: 4px;
--col-padding-x: 21px; /* block 좌우 padding */
--badge-width-ratio: 48%; /* col 너비 대비 */
--bullet-list-padding-x: 10%;
--bullet-list-padding-y: 13%;
--photo-height-ratio: 38%;
--photo-margin-x: 8%;
--photo-margin-bottom: 4%;
--photo-radius: 6%;
--marker-w: 1.4rem;
--marker-h: 1.4rem;
--marker-gap: 0.55rem;
}
body {
font-family: var(--font-family);
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.block {
width: var(--block-w);
height: var(--block-h);
background: #ffffff;
position: relative;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, .15);
/* Layout: flex row of N columns */
display: flex;
flex-direction: row;
gap: var(--col-gap);
padding: 0 var(--col-padding-x);
}
/* ─────────────────────────────────────────────────────────
role-card: 한 stakeholder 컬럼. flex column.
───────────────────────────────────────────────────────── */
.role-card {
flex: 1 1 0; /* 모든 컬럼 동일 width */
position: relative;
display: flex;
flex-direction: column;
}
/* ─────────────────────────────────────────────────────────
badge: 카드 상단 원형 뱃지 (역할 라벨)
───────────────────────────────────────────────────────── */
.badge {
position: relative;
width: var(--badge-width-ratio);
aspect-ratio: 1; /* 정사각형 영역 */
margin: 0 auto;
z-index: 3;
flex: none;
}
.badge img.outer {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.badge img.inner {
position: absolute;
width: 76%;
height: 76%;
inset: 12%;
object-fit: contain;
}
.badge .label {
position: absolute;
/* Figma: label center at ~64% of badge height (figure가 상단부 차지)
→ label area를 badge 하단 ~52%에 배치 */
left: 0; right: 0;
top: 38%;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: 700;
text-align: center;
letter-spacing: -0.02em;
z-index: 10;
pointer-events: none;
}
.badge .label .ln1 { font-size: 1.7rem; line-height: 1; }
.badge .label .ln2 { font-size: 1.3rem; line-height: 1.2; margin-top: 0.1em; }
/* ─────────────────────────────────────────────────────────
card-body: bg + overlay + bullet list + optional photo
───────────────────────────────────────────────────────── */
.card-body {
position: relative;
flex: 1;
margin-top: -10%; /* badge와 약간 겹침 */
z-index: 1;
display: flex;
flex-direction: column;
}
.card-body .bg,
.card-body .overlay {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
pointer-events: none;
}
.card-body .overlay {
opacity: 0.80;
}
/* ─────────────────────────────────────────────────────────
bullet-list: R13 Custom-Marker Bullet List 패턴
각 컬럼이 동일 height + justify-content space-between
───────────────────────────────────────────────────────── */
.bullet-list {
position: relative;
z-index: 2;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: var(--bullet-list-padding-y) var(--bullet-list-padding-x);
list-style: none;
}
.bullet-row {
display: flex;
align-items: flex-start;
--lh: var(--font-body-lh);
}
.bullet-row.compact {
--lh: var(--font-body-lh-compact);
}
.bullet-icon {
flex: none;
width: var(--marker-w);
height: var(--marker-h);
margin-right: var(--marker-gap);
/* 핵심: icon center align with text first line center */
margin-top: calc((1em * var(--lh) - var(--marker-h)) / 2);
}
.bullet-icon img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
}
.bullet-text {
flex: 1;
font-size: var(--font-body-size);
line-height: var(--lh);
color: #000;
white-space: normal;
word-break: keep-all;
}
/* ─────────────────────────────────────────────────────────
bottom-photo: optional. 카드 하단 사진 카드
───────────────────────────────────────────────────────── */
.bottom-photo {
position: relative;
z-index: 2;
flex: none;
height: var(--photo-height-ratio);
margin: 0 var(--photo-margin-x) var(--photo-margin-bottom) var(--photo-margin-x);
border-radius: var(--photo-radius);
overflow: hidden;
opacity: 0.70;
}
.bottom-photo img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
/* photo가 없는 컬럼은 bullet-list가 더 많은 공간 차지 */
.role-card.no-photo .bullet-list {
padding-bottom: 6%;
}
</style>
</head>
<body>
<div class="block">
<article class="role-card no-photo">
<!-- Badge: 상단 원형 -->
<div class="badge">
<img class="outer" src="../../block-tests/assets/shared/77f319979c880da34ff3d423fcd97827f636c01e.png" alt="">
<img class="inner" src="../../block-tests/assets/shared/e64c967dd00302bfbef6cfbcbb4f7a4db5d9d96c.png" alt="">
<span class="label" style="color: #285b4a;">
<span class="ln1">발주자</span>
<span class="ln2">목표</span>
</span>
</div>
<!-- Card body: bg + overlay + bullets + optional photo -->
<div class="card-body">
<img class="bg" src="../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png" alt="">
<img class="overlay" src="../../block-tests/assets/shared/e837f8707efeffc9e357d084ad72b752a5fba0f9.png" alt="">
<!-- bullet-list: R13 sub-pattern -->
<ul class="bullet-list">
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">민원, 재 작업 등의 예방 및 최소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">직관화로 품질 향상 및 안정성 제고</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">수행공정의 쉬운이해로 관리 편의성 증진</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">실무자와 발주자간의 소통 오류 최소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">행정 자동화와 최소화로 생산성 향상</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">건설정보의 통합관리로 활용성 강화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">전 생애주기에 걸친 효율적 디지털 자산관리</span>
</li>
</ul>
<!-- Optional bottom photo -->
</div>
</article>
<article class="role-card no-photo">
<!-- Badge: 상단 원형 -->
<div class="badge">
<img class="outer" src="../../block-tests/assets/shared/1550ec755fa7922dcfc1c90135a570d6b9df82cc.png" alt="">
<img class="inner" src="../../block-tests/assets/shared/85beaf9dfc17b7ed4620729a086ba22143606517.png" alt="">
<span class="label" style="color: #445a2f;">
<span class="ln1">시공자</span>
<span class="ln2">목표</span>
</span>
</div>
<!-- Card body: bg + overlay + bullets + optional photo -->
<div class="card-body">
<img class="bg" src="../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png" alt="">
<img class="overlay" src="../../block-tests/assets/shared/755384bd81ba10f62628933f16595eb054064846.png" alt="">
<!-- bullet-list: R13 sub-pattern -->
<ul class="bullet-list">
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">시공 오류예방 및 공사 Risk 최소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">시각화로 안전성 제고 및 품질 향상</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">중간태, 완성태 측량을 통한 시‧공간적 관리 편리성 향상</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">건설 관계자들 간의 의사소통 강화</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">Model을 활용한 시공상세도 등의 관련도서 작성 용이</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">System 구축을 통한 행정 간소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">기술개발을 통한 생산성 향상</span>
</li>
</ul>
<!-- Optional bottom photo -->
</div>
</article>
<article class="role-card no-photo">
<!-- Badge: 상단 원형 -->
<div class="badge">
<img class="outer" src="../../block-tests/assets/shared/9ac089fa9c5106b6b26d47727003641bb56ba4b0.png" alt="">
<img class="inner" src="../../block-tests/assets/shared/4b534ccf4e945fbe7436a0d8d96a6deffcfe5cef.png" alt="">
<span class="label" style="color: #743002;">
<span class="ln1">설계자</span>
<span class="ln2">목표</span>
</span>
</div>
<!-- Card body: bg + overlay + bullets + optional photo -->
<div class="card-body">
<img class="bg" src="../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png" alt="">
<img class="overlay" src="../../block-tests/assets/shared/5577732e17bedec9eb1de4f77583cf67c8137f92.png" alt="">
<!-- bullet-list: R13 sub-pattern -->
<ul class="bullet-list">
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">직관적 시각화로 원활한 소통</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">3D 모델 활용으로 오류 최소화 및 Claim 예방</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">발주자와의 상호 신뢰 증진</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">정보물 생산으로 부가가치 창출</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">고부가가치 창출산업으로 전환</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">프로젝트 정보의 일관성 유지 및 관리를 통한 오류 최소화</span>
</li>
</ul>
<!-- Optional bottom photo -->
</div>
</article>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -0,0 +1,430 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>BIM 3역할 목표 카드 (Frame 1171281191) — 템플릿 렌더 검증</title>
<!--
============================================================
Pattern: cards-3col-persona
Source: figma_to_html_agent/block-tests/bim-3roles-cards.html (1:1 reference)
Origin frame: 45:16 / Frame 1171281191
STRUCTURE: N개의 평행한 stakeholder 카드 (N=2~4)
각 카드 = bg image + color overlay + 상단 원형 badge + bullet list (custom marker) + optional bottom photo
PRINCIPLES (RULES.md, blocks_index.md 디자인 인사이트):
- I-1: 마커+텍스트는 시맨틱 list (R13)
- I-2: 평행 컬럼은 동일 top/bottom + 내부 spacing 자동 분배
- I-3: 모든 슬롯은 기본 optional (bottom_photo 등)
============================================================
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
/* 디자인 토큰 — 외부에서 override 가능 */
--block-w: 1280px;
--block-h: 948px;
--font-family: 'Noto Sans KR', sans-serif;
--font-body-size: 1.05rem;
--font-body-lh: 2.125; /* 85/40 */
--font-body-lh-compact: 1.25; /* 50/40 */
--col-gap: 4px;
--col-padding-x: 21px; /* block 좌우 padding */
--badge-width-ratio: 48%; /* col 너비 대비 */
--bullet-list-padding-x: 10%;
--bullet-list-padding-y: 13%;
--photo-height-ratio: 38%;
--photo-margin-x: 8%;
--photo-margin-bottom: 4%;
--photo-radius: 6%;
--marker-w: 1.4rem;
--marker-h: 1.4rem;
--marker-gap: 0.55rem;
}
body {
font-family: var(--font-family);
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.block {
width: var(--block-w);
height: var(--block-h);
background: #ffffff;
position: relative;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, .15);
/* Layout: flex row of N columns */
display: flex;
flex-direction: row;
gap: var(--col-gap);
padding: 0 var(--col-padding-x);
}
/* ─────────────────────────────────────────────────────────
role-card: 한 stakeholder 컬럼. flex column.
───────────────────────────────────────────────────────── */
.role-card {
flex: 1 1 0; /* 모든 컬럼 동일 width */
position: relative;
display: flex;
flex-direction: column;
}
/* ─────────────────────────────────────────────────────────
badge: 카드 상단 원형 뱃지 (역할 라벨)
───────────────────────────────────────────────────────── */
.badge {
position: relative;
width: var(--badge-width-ratio);
aspect-ratio: 1; /* 정사각형 영역 */
margin: 0 auto;
z-index: 3;
flex: none;
}
.badge img.outer {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.badge img.inner {
position: absolute;
width: 76%;
height: 76%;
inset: 12%;
object-fit: contain;
}
.badge .label {
position: absolute;
/* Figma: label center at ~64% of badge height (figure가 상단부 차지)
→ label area를 badge 하단 ~52%에 배치 */
left: 0; right: 0;
top: 38%;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: 700;
text-align: center;
letter-spacing: -0.02em;
z-index: 10;
pointer-events: none;
}
.badge .label .ln1 { font-size: 1.7rem; line-height: 1; }
.badge .label .ln2 { font-size: 1.3rem; line-height: 1.2; margin-top: 0.1em; }
/* ─────────────────────────────────────────────────────────
card-body: bg + overlay + bullet list + optional photo
───────────────────────────────────────────────────────── */
.card-body {
position: relative;
flex: 1;
margin-top: -10%; /* badge와 약간 겹침 */
z-index: 1;
display: flex;
flex-direction: column;
}
.card-body .bg,
.card-body .overlay {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
pointer-events: none;
}
.card-body .overlay {
opacity: 0.80;
}
/* ─────────────────────────────────────────────────────────
bullet-list: R13 Custom-Marker Bullet List 패턴
각 컬럼이 동일 height + justify-content space-between
───────────────────────────────────────────────────────── */
.bullet-list {
position: relative;
z-index: 2;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: var(--bullet-list-padding-y) var(--bullet-list-padding-x);
list-style: none;
}
.bullet-row {
display: flex;
align-items: flex-start;
--lh: var(--font-body-lh);
}
.bullet-row.compact {
--lh: var(--font-body-lh-compact);
}
.bullet-icon {
flex: none;
width: var(--marker-w);
height: var(--marker-h);
margin-right: var(--marker-gap);
/* 핵심: icon center align with text first line center */
margin-top: calc((1em * var(--lh) - var(--marker-h)) / 2);
}
.bullet-icon img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
}
.bullet-text {
flex: 1;
font-size: var(--font-body-size);
line-height: var(--lh);
color: #000;
white-space: normal;
word-break: keep-all;
}
/* ─────────────────────────────────────────────────────────
bottom-photo: optional. 카드 하단 사진 카드
───────────────────────────────────────────────────────── */
.bottom-photo {
position: relative;
z-index: 2;
flex: none;
height: var(--photo-height-ratio);
margin: 0 var(--photo-margin-x) var(--photo-margin-bottom) var(--photo-margin-x);
border-radius: var(--photo-radius);
overflow: hidden;
opacity: 0.70;
}
.bottom-photo img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
/* photo가 없는 컬럼은 bullet-list가 더 많은 공간 차지 */
.role-card.no-photo .bullet-list {
padding-bottom: 6%;
}
</style>
</head>
<body>
<div class="block">
<article class="role-card">
<!-- Badge: 상단 원형 -->
<div class="badge">
<img class="outer" src="../../block-tests/assets/shared/77f319979c880da34ff3d423fcd97827f636c01e.png" alt="">
<img class="inner" src="../../block-tests/assets/shared/e64c967dd00302bfbef6cfbcbb4f7a4db5d9d96c.png" alt="">
<span class="label" style="color: #285b4a;">
<span class="ln1">발주자</span>
<span class="ln2">목표</span>
</span>
</div>
<!-- Card body: bg + overlay + bullets + optional photo -->
<div class="card-body">
<img class="bg" src="../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png" alt="">
<img class="overlay" src="../../block-tests/assets/shared/e837f8707efeffc9e357d084ad72b752a5fba0f9.png" alt="">
<!-- bullet-list: R13 sub-pattern -->
<ul class="bullet-list">
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">민원, 재 작업 등의 예방 및 최소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">직관화로 품질 향상 및 안정성 제고</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">수행공정의 쉬운이해로 관리 편의성 증진</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">실무자와 발주자간의 소통 오류 최소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">행정 자동화와 최소화로 생산성 향상</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">건설정보의 통합관리로 활용성 강화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">전 생애주기에 걸친 효율적 디지털 자산관리</span>
</li>
</ul>
<!-- Optional bottom photo -->
<div class="bottom-photo">
<img src="../../block-tests/assets/shared/d2c070f200af83f563976b6b0f309d38321d204d.png" alt="">
</div>
</div>
</article>
<article class="role-card">
<!-- Badge: 상단 원형 -->
<div class="badge">
<img class="outer" src="../../block-tests/assets/shared/1550ec755fa7922dcfc1c90135a570d6b9df82cc.png" alt="">
<img class="inner" src="../../block-tests/assets/shared/85beaf9dfc17b7ed4620729a086ba22143606517.png" alt="">
<span class="label" style="color: #445a2f;">
<span class="ln1">시공자</span>
<span class="ln2">목표</span>
</span>
</div>
<!-- Card body: bg + overlay + bullets + optional photo -->
<div class="card-body">
<img class="bg" src="../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png" alt="">
<img class="overlay" src="../../block-tests/assets/shared/755384bd81ba10f62628933f16595eb054064846.png" alt="">
<!-- bullet-list: R13 sub-pattern -->
<ul class="bullet-list">
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">시공 오류예방 및 공사 Risk 최소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">시각화로 안전성 제고 및 품질 향상</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">중간태, 완성태 측량을 통한 시‧공간적 관리 편리성 향상</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">건설 관계자들 간의 의사소통 강화</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">Model을 활용한 시공상세도 등의 관련도서 작성 용이</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">System 구축을 통한 행정 간소화</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">기술개발을 통한 생산성 향상</span>
</li>
</ul>
<!-- Optional bottom photo -->
<div class="bottom-photo">
<img src="../../block-tests/assets/shared/2a6a58e7bf7a645b5ede65115feb2890ccc414d1.png" alt="">
</div>
</div>
</article>
<article class="role-card">
<!-- Badge: 상단 원형 -->
<div class="badge">
<img class="outer" src="../../block-tests/assets/shared/9ac089fa9c5106b6b26d47727003641bb56ba4b0.png" alt="">
<img class="inner" src="../../block-tests/assets/shared/4b534ccf4e945fbe7436a0d8d96a6deffcfe5cef.png" alt="">
<span class="label" style="color: #743002;">
<span class="ln1">설계자</span>
<span class="ln2">목표</span>
</span>
</div>
<!-- Card body: bg + overlay + bullets + optional photo -->
<div class="card-body">
<img class="bg" src="../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png" alt="">
<img class="overlay" src="../../block-tests/assets/shared/5577732e17bedec9eb1de4f77583cf67c8137f92.png" alt="">
<!-- bullet-list: R13 sub-pattern -->
<ul class="bullet-list">
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">직관적 시각화로 원활한 소통</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">3D 모델 활용으로 오류 최소화 및 Claim 예방</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">발주자와의 상호 신뢰 증진</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">정보물 생산으로 부가가치 창출</span>
</li>
<li class="bullet-row">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">고부가가치 창출산업으로 전환</span>
</li>
<li class="bullet-row compact">
<span class="bullet-icon"><img src="../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png" alt=""></span>
<span class="bullet-text">프로젝트 정보의 일관성 유지 및 관리를 통한 오류 최소화</span>
</li>
</ul>
<!-- Optional bottom photo -->
<div class="bottom-photo">
<img src="../../block-tests/assets/shared/39113493f6e3ae76d766e86e293b0f0dcbf55d91.png" alt="">
</div>
</div>
</article>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 KiB

View File

@@ -0,0 +1,273 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>BIM vs DX 비교 표 (Frame 1171281195)</title>
<!--
Pattern: compare-vs-rows
Origin: 45:20 / Frame 1171281195
N개의 카테고리별 비교 행. 각 행 = 좌(A 진영) | 중앙(카테고리 라벨 pill) | 우(B 진영)
+ 헤더(타이틀 + icon) + 메인 pill ("A vs. B") + 결론 박스
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: 1280px;
--left-color: #5c3714; /* 좌 진영 색 */
--right-color: #285b4a; /* 우 진영 색 */
--header-from: #cc5200;
--header-to: #883700;
--pill-bg-from: rgb(40,91,74);
--pill-bg-to: rgb(74,64,38);
--conclusion-color: #000;
--conclusion-highlight: #ae3607;
--row-font-size: 1.4rem;
--row-sub-font-size: 1.2rem;
--cat-pill-w: 16%;
--cat-font-size: 1.4rem;
--row-gap: 0.8rem;
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.block {
width: var(--block-w);
background: #ffffff;
position: relative;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
padding: 1.5rem 1.8rem 1.5rem 1.8rem;
}
/* ─── 헤더 ─── */
.header {
display: flex; align-items: center; gap: 0.6rem;
margin-bottom: 0.8rem;
}
.header-icon {
width: 1.8rem; height: 1.8rem;
flex: none;
}
.header-icon img { width: 100%; height: 100%; object-fit: contain; }
.header-title {
font-weight: 700;
font-size: 1.6rem;
background-image: linear-gradient(180deg, var(--header-from) 0%, var(--header-to) 100%);
-webkit-background-clip: text; background-clip: text;
color: transparent;
text-shadow: 0 0 4px rgba(50,44,30,0.4);
}
/* ─── 메인 pill (A vs B) ─── */
.main-pill {
position: relative;
height: 2.2rem;
border-radius: 1.1rem;
background-image: linear-gradient(270deg,
var(--pill-bg-from) 0%, color-mix(in srgb, var(--pill-bg-from) 80%, transparent) 30%,
color-mix(in srgb, var(--pill-bg-to) 80%, transparent) 70%, var(--pill-bg-to) 100%);
display: grid;
grid-template-columns: 1fr var(--cat-pill-w) 1fr;
align-items: center;
font-weight: 700;
font-size: 1.5rem;
color: #fff;
margin-bottom: 0.6rem;
}
.main-pill .l { text-align: center; }
.main-pill .v { text-align: center; }
.main-pill .r { text-align: center; }
/* ─── 비교 표 ─── */
.cmp-table {
display: flex;
flex-direction: column;
gap: var(--row-gap);
}
.cmp-row {
display: grid;
grid-template-columns: 1fr var(--cat-pill-w) 1fr;
align-items: center;
gap: 0.5rem;
min-height: 2.4rem;
}
/* 좌 텍스트 (text-right) */
.cmp-row .left {
text-align: right;
font-weight: 700;
font-size: var(--row-font-size);
color: var(--left-color);
line-height: 1.3;
padding-right: 0.4rem;
}
.cmp-row .left .sub { font-size: var(--row-sub-font-size); }
/* 우 텍스트 (text-left) */
.cmp-row .right {
text-align: left;
font-weight: 700;
font-size: var(--row-font-size);
color: var(--right-color);
line-height: 1.3;
padding-left: 0.4rem;
}
.cmp-row .right .sub { font-size: var(--row-sub-font-size); }
/* 가운데 카테고리 pill */
.cmp-row .cat {
height: 100%;
min-height: 2rem;
border-radius: 0.4rem;
background-image: linear-gradient(270deg,
color-mix(in srgb, var(--pill-bg-from) 80%, transparent) 0%,
color-mix(in srgb, var(--pill-bg-from) 64%, transparent) 30%,
color-mix(in srgb, var(--pill-bg-to) 64%, transparent) 70%,
color-mix(in srgb, var(--pill-bg-to) 80%, transparent) 100%);
display: flex; align-items: center; justify-content: center;
font-weight: 700;
font-size: var(--cat-font-size);
color: #fff;
text-align: center;
padding: 0.4rem 0.6rem;
}
/* ─── 결론 박스 ─── */
.conclusion {
margin-top: 1rem;
position: relative;
border: 2px solid #4a4028;
background: #fff;
padding: 1rem 1.5rem 1rem 4rem;
border-radius: 0.4rem;
}
.conclusion .arrow {
position: absolute;
left: -0.5rem;
top: 50%;
transform: translateY(-50%);
width: 2.5rem;
height: 2.5rem;
}
.conclusion .arrow img { width: 100%; height: 100%; object-fit: contain; }
.conclusion .text {
font-weight: 700;
font-size: 1.3rem;
line-height: 1.5;
color: var(--conclusion-color);
}
.conclusion .text .hl {
color: var(--conclusion-highlight);
font-size: 1.45rem;
}
</style>
</head>
<body>
<div class="block">
<div class="header">
<div class="header-icon"><img src="../../block-tests/assets/shared/b0e9fad5b03f4d9e368524976c20c9886392e17b.png" alt=""></div>
<div class="header-title">BIM과 DX의 이해</div>
</div>
<div class="main-pill">
<div class="l">BIM</div>
<div class="v">vs.</div>
<div class="r">DX</div>
</div>
<div class="cmp-table">
<div class="cmp-row">
<div class="left">Only 3D</div>
<div class="cat">BIM/DX</div>
<div class="right">BIM &lt;&lt; DX <span class="sub">(ENG. + Management 포함)</span></div>
</div>
<div class="cmp-row">
<div class="left">모델 제작용 상용 S/W<br><span class="sub">[Civil 3D, Revit, Navisworks, Autocad]</span></div>
<div class="cat">S/W</div>
<div class="right">제작 및 운영 (상용 + 전용 40~80개)<br><span class="sub">[Rhino, Sketchup, Blender ..] + [EG-BIM 등]</span></div>
</div>
<div class="cmp-row">
<div class="left">기존 2D 설계방식 유지</div>
<div class="cat">프로세스</div>
<div class="right">근본적 문제의식을 통한 개선</div>
</div>
<div class="cmp-row">
<div class="left">3D 모델 중심<br>기존 성과품 유지</div>
<div class="cat">성과물</div>
<div class="right">공학 정보 및 콘텐츠 연계에 집중<br>도면, 수량, 시공계획 등 일식</div>
</div>
<div class="cmp-row">
<div class="left">3D 모델에 의한 일반적 이해 향상</div>
<div class="cat">활 용</div>
<div class="right">설계/시공의 혁신(개념의 재정립)</div>
</div>
<div class="cmp-row">
<div class="left">(설계/시공/운영) 분야별 단절</div>
<div class="cat">확장성</div>
<div class="right">전 생애주기 활용 시스템</div>
</div>
<div class="cmp-row">
<div class="left">단순화(오류) - 수동적/집단적 동질화</div>
<div class="cat">수행개념</div>
<div class="right">구체화(복잡) - 적극/구체적 실현 방안</div>
</div>
<div class="cmp-row">
<div class="left">소극적, 상용 기술에 의존</div>
<div class="cat">CIVIL + IT</div>
<div class="right">적극적, 주체적인 기술 접목/융합</div>
</div>
<div class="cmp-row">
<div class="left">S/W 제작사 판매 정책에 의존</div>
<div class="cat">주 체</div>
<div class="right">자체 수행능력 - 지속가능성 확보</div>
</div>
<div class="cmp-row">
<div class="left">평준화, 국내 중심</div>
<div class="cat">발주처</div>
<div class="right">차별화 및 경쟁력 확보, 해외 진출</div>
</div>
<div class="cmp-row">
<div class="left">소규모 BIM팀 운영 + 단순교육에 집중</div>
<div class="cat">설계사</div>
<div class="right">IT + CIVIL ENG 220명 운영 + 기술 개발</div>
</div>
<div class="cmp-row">
<div class="left">국내 토목 소극적/해외 토목증가</div>
<div class="cat">시공사</div>
<div class="right">분야 확장 모델 및 시스템</div>
</div>
</div>
<div class="conclusion">
<div class="arrow"><img src="../../block-tests/assets/shared/bf1755273910e17f7a012ce2d269a93cca9483ac.svg" alt=""></div>
<div class="text">
<span>BIM은 건설산업의 DX(디지털전환)을 수행하는 과정에서 </span><span class="hl">가장 기초가 되는 일부분</span><span>임을 인지하는 것이 매우 중요</span>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

View File

@@ -0,0 +1,470 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>BIM 3원 교차 다이어그램 (Frame 1171281211) — 템플릿 렌더 검증</title>
<!--
============================================================
Pattern: cycle-3way-intersect
Source: figma_to_html_agent/block-tests/bim-goals-3circles.html (1:1 reference)
Origin frame: 66:310 / Frame 1171281211
STRUCTURE: 3개의 큰 원이 교차 (Venn-like)
- 3 main circles at FIXED positions (top, bot-left, bot-right)
- 6 accent circles at corners (top-left, top-right, left-top, left-bot, right-top, right-bot)
- 12 side labels at 6 positions (4 per circle context)
- 3 connecting arcs (PNG, optional)
- Background texture (optional)
- Decoration gradient (optional)
POSITION 고정 이유: 3-way intersect는 기하학적으로 결정되는 패턴.
2-way나 4-way는 별도 패턴 (cycle-2way-intersect, cycle-4way-intersect)으로 분리.
이 템플릿은 콘텐츠만 변수화 (라벨, 색상, 한자, 설명 등).
PRINCIPLES:
- I-3: 모든 슬롯은 기본 optional (bg, deco, arcs, side_labels 등)
- 1:1 reference의 transform: scale 전략 유지
============================================================
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin:0; padding:0; box-sizing:border-box; }
:root {
--block-w: 1280px;
--block-h: 594px; /* 957 × 0.620694 */
--inner-w: 2062.205px;
--inner-h: 956.998px;
--scale: 0.620694;
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
}
.slide {
width: var(--block-w);
height: 720px;
background: #ffffff;
position: relative;
display: flex; justify-content: center; align-items: center;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
}
.block {
width: var(--block-w);
height: var(--block-h);
background: #ffffff;
position: relative;
overflow: hidden;
}
.inner {
position: absolute;
left: 0; top: 0;
width: var(--inner-w);
height: var(--inner-h);
transform: scale(var(--scale));
transform-origin: top left;
}
/* ─── 배경 텍스처 (optional) ─── */
.bg-texture {
position: absolute;
left: 139px; top: 683px;
width: 1768px; height: 274px;
mix-blend-mode: multiply;
pointer-events: none;
z-index: 0;
}
.bg-texture img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ─── 회전 그라데이션 데코 (optional) ─── */
.deco-wrap {
position: absolute;
left: 71px; top: 38px;
width: 685.475px; height: 836.277px;
display: flex; align-items: center; justify-content: center;
pointer-events: none;
z-index: 1;
}
.deco-rot { flex: none; transform: rotate(-120deg); }
.deco-flip { transform: scaleY(-1); }
.deco-rect {
width: 763px; height: 351px;
border-radius: 175.5px 0 0 175.5px;
background: linear-gradient(235.162deg,
rgba(115,115,115,0) 14.18%,
rgba(213,170,137,0.33) 66.964%);
}
/* ─── 연결 아크 (optional) ─── */
.arc { position: absolute; z-index: 2; display: flex; align-items: center; justify-content: center; }
.arc img { display: block; flex: none; }
.arc--top { left: 926px; top: 134px; width: 209px; height: 99px; }
.arc--top img { width: 209px; height: 99px; transform: rotate(180deg); }
.arc--left { left: 627px; top: 549px; width: 99px; height: 209px; }
.arc--left img { width: 209px; height: 99px; transform: rotate(90deg); }
.arc--right { left: 1329px; top: 549px; width: 99px; height: 209px; }
.arc--right img { width: 209px; height: 99px; transform: rotate(-90deg); }
/* ─── 메인 3원 outer (350×350) ─── */
.big-outer {
position: absolute;
width: 350px; height: 350px;
border-radius: 50%;
mix-blend-mode: multiply;
z-index: 3;
}
.big-outer.top { left: 853px; top: 206px; }
.big-outer.bot-left { left: 694px; top: 480px; }
.big-outer.bot-right{ left: 1009px; top: 480px; }
/* ─── 메인 3원 ring (280 또는 290 with stroke) ─── */
.big-ring {
position: absolute;
border-radius: 50%;
box-shadow: 0 0 10px 0 rgba(0,0,0,1);
z-index: 4;
}
.big-ring.top {
left: 882.06px; top: 235.06px;
width: 290px; height: 290px;
border: 5px solid #FFFFFF;
}
.big-ring.bot-left {
left: 728.06px; top: 514.06px;
width: 280px; height: 280px;
border: 5px solid #FFFFFF;
background-origin: border-box;
background-clip: border-box;
}
.big-ring.bot-right {
left: 1043.06px; top: 514.06px;
width: 280px; height: 280px;
border: 5px solid #FFFFFF;
background-origin: border-box;
background-clip: border-box;
}
/* ─── 메인 원 라벨 (50px Bold) ─── */
.big-title {
position: absolute;
width: 262.923px; height: 114.078px;
font-weight: 700;
font-size: 50px;
line-height: 50px;
color: #ffffff;
text-align: center;
letter-spacing: -2.5px;
display: flex; flex-direction: column; justify-content: center;
z-index: 5;
}
.big-title p { line-height: 50px; }
.big-title.top { left: 896.46px; top: 330.49px; }
.big-title.bot-left { left: 737.46px; top: 604.49px; }
.big-title.bot-right{ left: 1053.63px; top: 597.45px; }
/* ─── 액센트 6원 (130.9 outer + 82.965 inner with border) ─── */
.acc-outer {
position: absolute;
width: 130.901px; height: 130.901px;
border-radius: 50%;
opacity: 0.3;
mix-blend-mode: multiply;
z-index: 6;
}
.acc-outer.top-left { left: 859px; top: 22px; }
.acc-outer.top-right { left: 1071px; top: 22px; }
.acc-outer.left-top { left: 555px; top: 483px; }
.acc-outer.left-bot { left: 555px; top: 689px; }
.acc-outer.right-top { left: 1372px; top: 483px; }
.acc-outer.right-bot { left: 1372px; top: 689px; }
.acc-inner {
position: absolute;
width: 82.965px; height: 82.965px;
border: 2px solid #FFFFFF;
border-radius: 50%;
box-shadow: 0 0 10px 0 rgba(0,0,0,1);
z-index: 7;
}
.acc-inner.top-left { left: 882.47px; top: 45.47px; }
.acc-inner.top-right { left: 1094.47px; top: 45.47px; }
.acc-inner.left-top { left: 578.47px; top: 506.47px; }
.acc-inner.left-bot { left: 578.47px; top: 712.47px; }
.acc-inner.right-top { left: 1395.47px; top: 506.47px; }
.acc-inner.right-bot { left: 1395.47px; top: 712.47px; }
.acc-text {
position: absolute;
width: 98.334px; height: 42.666px;
font-weight: 700;
font-size: 45px;
line-height: 50px;
color: #ffffff;
text-align: center;
letter-spacing: -2.25px;
text-shadow: 0 0 5px #cc5200;
display: flex; align-items: center; justify-content: center;
z-index: 8;
}
.acc-text.top-left { left: 875.25px; top: 63.60px; }
.acc-text.top-right { left: 1087.25px; top: 63.60px; }
.acc-text.left-top { left: 571.25px; top: 524.60px; }
.acc-text.left-bot { left: 571.25px; top: 730.60px; }
.acc-text.right-top { left: 1388.25px; top: 524.60px; }
.acc-text.right-bot { left: 1388.25px; top: 730.60px; }
/* ─── 사이드 텍스트 라벨 (12개, 6 위치 × 2 (title+desc)) ─── */
.side-title {
position: absolute;
font-weight: 700;
font-size: 40px;
line-height: 95px;
white-space: nowrap;
z-index: 5;
}
.side-desc {
position: absolute;
font-weight: 500;
font-size: 30px;
color: #525151;
z-index: 5;
}
.side-desc p { line-height: 35px; padding-bottom: 5px; }
/* 상단 (top) — 안전성 제고 / 품질 향상 */
.side-title.top-left { left: 645px; top: 0; width: 194px; text-align: right; }
.side-title.top-right { left: 1233px; top: 0; width: 157px; text-align: right; }
.side-desc.top-left { left: 331px; top: 78px; width: 508.478px; text-align: right; }
.side-desc.top-right { left: 1233px; top: 78px; width: 508.478px; }
/* 좌측 (mid-left) — 신속·정확성 / 비용저감 */
.side-title.mid-left { left: 0; top: 456px; width: 531.393px; height: 95.345px; text-align: right; white-space: nowrap; }
.side-title.bot-left {
left: 84.67px; top: 661.79px; width: 446.049px; height: 96.418px;
display: flex; flex-direction: column; justify-content: center;
text-align: right;
}
.side-desc.mid-left { left: 52.01px; top: 546px; width: 478.731px; height: 70.561px; text-align: right; }
.side-desc.bot-left {
left: 102.02px; top: 734px; width: 428.315px; height: 91.343px;
display: flex; flex-direction: column; justify-content: center;
text-align: right;
}
/* 우측 (mid-right) — 소통·이해 / 신뢰·투명성 */
.side-title.mid-right { left: 1518px; top: 456px; width: 267.016px; }
.side-title.bot-right { left: 1518px; top: 664px; width: 304.016px; }
.side-desc.mid-right { left: 1518px; top: 541px; width: 429.012px; white-space: nowrap; }
.side-desc.bot-right {
left: 1518px; top: 754.21px; width: 544.198px; height: 70.561px;
display: flex; flex-direction: column; justify-content: center;
}
</style>
</head>
<body>
<div class="slide">
<div class="block">
<div class="inner">
<div class="bg-texture"><img src="../../block-tests/assets/frame_1171281211/bg_texture.png" alt=""></div>
<div class="deco-wrap">
<div class="deco-rot"><div class="deco-flip"><div class="deco-rect"></div></div></div>
</div>
<div class="arc arc--top"><img src="../../block-tests/assets/frame_1171281211/arc_top.png" alt=""></div>
<div class="arc arc--left"><img src="../../block-tests/assets/frame_1171281211/arc_side.png" alt=""></div>
<div class="arc arc--right"><img src="../../block-tests/assets/frame_1171281211/arc_side.png" alt=""></div>
<div class="big-outer top"
style="background: linear-gradient(145.28deg, #FDC69E 16.04%, #E0782C 55.20%);">
</div>
<div class="big-ring top"
style="background: linear-gradient(145.28deg, #BC652B 16.04%, #A24200 55.20%);">
</div>
<div class="big-title top"
style="text-shadow: 0 0 5px #cc5200;">
<p>안전과</p><p>품질</p>
</div>
<div class="big-outer bot-left"
style="background: linear-gradient(218.84deg, #D5AA89 14.08%, #737373 92.67%);">
</div>
<div class="big-ring bot-left"
style="background: linear-gradient(153.95deg, #897445 15.27%, #3E3523 61.74%);">
</div>
<div class="big-title bot-left"
>
<p>생산성</p><p>향상</p>
</div>
<div class="big-outer bot-right"
style="background: linear-gradient(145.90deg, #FFFFFF 8.47%, #253E1F 87.56%);">
</div>
<div class="big-ring bot-right"
style="background: linear-gradient(153.95deg, #296B55 15.27%, #123328 61.74%);">
</div>
<div class="big-title bot-right"
>
<p>소통과</p><p>신뢰</p>
</div>
<div class="acc-outer top-left"
style="background: linear-gradient(145.90deg, #D9C868 8.47%, #DC670E 87.56%);">
</div>
<div class="acc-inner top-left"
style="background: linear-gradient(145.28deg, #BC652B 16.04%, #A24200 55.20%);">
</div>
<div class="acc-text top-left"></div>
<div class="acc-outer top-right"
style="background: linear-gradient(145.90deg, #D9C868 8.47%, #DC670E 87.56%);">
</div>
<div class="acc-inner top-right"
style="background: linear-gradient(145.28deg, #BC652B 16.04%, #A24200 55.20%);">
</div>
<div class="acc-text top-right"></div>
<div class="acc-outer left-top"
style="background: linear-gradient(218.84deg, #D5AA89 14.08%, #737373 92.67%);">
</div>
<div class="acc-inner left-top"
style="background: linear-gradient(153.95deg, #897445 15.27%, #3E3523 61.73%);">
</div>
<div class="acc-text left-top"></div>
<div class="acc-outer left-bot"
style="background: linear-gradient(218.84deg, #D5AA89 14.08%, #737373 92.67%);">
</div>
<div class="acc-inner left-bot"
style="background: linear-gradient(153.95deg, #897445 15.27%, #3E3523 61.73%);">
</div>
<div class="acc-text left-bot"></div>
<div class="acc-outer right-top"
style="background: linear-gradient(145.90deg, #60A451 8.47%, #253E1F 87.56%);">
</div>
<div class="acc-inner right-top"
style="background: linear-gradient(153.95deg, #296B55 15.27%, #123328 61.73%);">
</div>
<div class="acc-text right-top"></div>
<div class="acc-outer right-bot"
style="background: linear-gradient(145.90deg, #60A451 8.47%, #253E1F 87.56%);">
</div>
<div class="acc-inner right-bot"
style="background: linear-gradient(153.95deg, #296B55 15.27%, #123328 61.73%);">
</div>
<div class="acc-text right-bot"></div>
<div class="side-title top-left" style="color: #cc5200;">안전성 제고</div>
<div class="side-desc top-left">
<p>시설물의 요구성능의 만족,</p><p>건설중 및 운영중 안전확보</p>
</div>
<div class="side-title top-right" style="color: #cc5200;">품질 향상</div>
<div class="side-desc top-right">
<p>Copy & Paste로 하향 평준화된</p><p>기존 성과물의 품질 향상</p>
</div>
<div class="side-title mid-left" style="color: #604f32;">신속ㆍ정확성 증진</div>
<div class="side-desc mid-left">
<p>Analogue 기반 업무를</p><p>Digital화 하는 Process 혁신</p>
</div>
<div class="side-title mid-right" style="color: #124133;">소통ㆍ이해 원할</div>
<div class="side-desc mid-right">
<p>성과품, Solution을 통한</p><p>사용 편리성, 협업 및 의사소통 강화</p>
</div>
<div class="side-title bot-left" style="color: #604f32;">비용저감ㆍ부가가치 창출</div>
<div class="side-desc bot-left">
<p>건설비용 및 유지관리비 감소,</p><p>인력투입 최소화 등 생산성 향상</p>
</div>
<div class="side-title bot-right" style="color: #124133;">신뢰ㆍ투명성 강화</div>
<div class="side-desc bot-right">
<p>3D 모델을 통한 오류</p><p>최소화 및 Claim 예방</p>
</div>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

View File

@@ -0,0 +1,245 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>현황 및 문제점 (Frame 1171281194)</title>
<!--
Pattern: issues-paired-rows
Origin: 45:19 / Frame 1171281194
구조: flex column (텍스트 양에 따라 박스 유동 조절)
pill: 고정 크기 (25.5% of row width), 박스 border에 걸침 (negative margin)
pill 이미지: R16 (overflow:hidden으로 한쪽 곡선만 보임)
bottom pill: rotate(180) + 이미지 배치 반전
텍스트: pill과 분리된 flex item → 절대 가려지지 않음
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: 1280px;
--border-color: #60a451;
--box-bg: rgba(250,237,203,0.15);
--text-color: #0c271e;
--pill-text-color: #ffffff;
--pill-width: 25.5%;
--pill-height: 4.1rem;
--pill-overlap: 0.8rem;
--row-gap: 0.4rem;
--font-body: 1.05rem;
--font-pill: 1.2rem;
--divider-color: rgba(96,164,81,0.4);
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh; padding: 20px;
word-break: keep-all;
}
.block {
width: var(--block-w);
background: #fff;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
padding: 1.2rem 1.8rem;
}
.header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.8rem; }
.header-icon { width: 1.8rem; height: 1.8rem; flex: none; }
.header-icon img { width: 100%; height: 100%; object-fit: contain; }
.header-title {
font-weight: 700; font-size: 1.6rem;
background-image: linear-gradient(180deg, #cc5200 0%, #883700 100%);
-webkit-background-clip: text; background-clip: text; color: transparent;
text-shadow: 0 0 4px rgba(50,44,30,0.4);
}
.rows { display: flex; flex-direction: column; gap: var(--row-gap); }
/* issue-row: 하나의 행 (border 박스) */
.issue-row {
border: 2px solid var(--border-color);
border-radius: 1rem;
background: var(--box-bg);
display: flex;
flex-direction: column;
}
/* pill-row: 좌/우 pill 2개 배치 */
.pill-row {
display: flex;
justify-content: space-between;
}
/* pill이 박스 border 위/아래로 걸침 */
.pill-row.top { margin-top: calc(-1 * var(--pill-overlap)); }
.pill-row.bottom { margin-bottom: calc(-1 * var(--pill-overlap)); }
/* 개별 pill */
.pill-cell {
position: relative;
width: var(--pill-width);
height: var(--pill-height);
overflow: hidden;
flex: none;
}
/* R16: 이미지 프레임 배치 — 한쪽 곡선만 보임 */
.pill-cell.left img {
position: absolute;
top: 0; height: 100%;
left: -45.3%;
width: 145.3%;
}
.pill-cell.right img {
position: absolute;
top: 0; height: 100%;
left: 0;
width: 151.25%;
}
/* bottom pill: rotate(180) + 이미지 배치 반전 */
.pill-row.bottom .pill-cell { transform: rotate(180deg); }
.pill-row.bottom .pill-cell.left img {
left: 0;
width: 151.25%;
}
.pill-row.bottom .pill-cell.right img {
left: -45.3%;
width: 145.3%;
}
.pill-cell .label {
position: absolute; inset: 0;
display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: var(--font-pill); color: var(--pill-text-color);
white-space: nowrap; z-index: 2;
}
.pill-row.bottom .pill-cell .label { transform: rotate(180deg); }
/* 텍스트 영역: 좌/우 나란히 + 가운데 점선 */
.text-row {
display: grid;
grid-template-columns: 1fr 1px 1fr;
padding: 0.5rem 0.8rem;
}
.text-row .divider {
border-left: 1px dashed var(--divider-color);
margin: 0.2rem 0;
}
.text-row .text-cell {
font-weight: 500;
font-size: var(--font-body);
line-height: 1.8;
color: var(--text-color);
padding: 0.3rem 0.6rem;
}
.text-row .text-cell.right { text-align: right; }
</style>
</head>
<body>
<div class="block">
<div class="header">
<div class="header-icon"><img src="../../block-tests/assets/shared/b0e9fad5b03f4d9e368524976c20c9886392e17b.png" alt=""></div>
<div class="header-title">현황 및 문제점</div>
</div>
<div class="rows">
<div class="issue-row">
<!-- pills top -->
<div class="pill-row top">
<div class="pill-cell left">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">개념 부재</span>
</div>
<div class="pill-cell right">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">잘못된 접근방식</span>
</div>
</div>
<div class="text-row">
<div class="text-cell">BIM을 Digital 전환의 개념이 아닌, CAD의 확장판으로 해석하여 3D를 그리는 수단 정도로만 인식</div>
<div class="divider"></div>
<div class="text-cell right">단순 업무효율 증진을 위한 도구로만 인식하여, 기술자들이 도구로서 사용만 할 수 있도록 교육시키면 된다고 판단</div>
</div>
</div>
<div class="issue-row">
<div class="text-row">
<div class="text-cell">대형 S/W 개발 및 판매회사에서 제시된 내용과 방향대로 따라하므로써, 국내는 자체적 목표설정 기능을 상실</div>
<div class="divider"></div>
<div class="text-cell right">건축과 토목이 유사하다는 전제하에 Library를 활용하는 건축에서 수행하고 있는 방식을 토목에도 동일하게 적용</div>
</div>
<!-- pills bottom -->
<div class="pill-row bottom">
<div class="pill-cell left">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">방향성 상실</span>
</div>
<div class="pill-cell right">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">전제조건 오류</span>
</div>
</div>
</div>
<div class="issue-row">
<!-- pills top -->
<div class="pill-row top">
<div class="pill-cell left">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">수행주체 혼란</span>
</div>
<div class="pill-cell right">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">수행방식 무지</span>
</div>
</div>
<div class="text-row">
<div class="text-cell">학자, 발주처 중심으로 S/W 판매회사에서 제시한 기술 수행 방식의 변화를 주도, 실행주체인 기업과 기술자들은 기존의 방식을 고수하면서 눈치만 보는 실정</div>
<div class="divider"></div>
<div class="text-cell right">기존 2D 설계의 결과가 옳다는 전제와 3D 설계를 수행/검토해본 경험이 없어, 전환설계의 개념으로 수행하므로써 비용과 시간이 추가로 소요, 높은 수준의 품질확보 불가</div>
</div>
</div>
<div class="issue-row">
<div class="text-row">
<div class="text-cell">단순 외산 범용S/W만 사용하면 BIM이 될 수 있을 것이라는 안일한 생각으로 접근하므로 외국 대형S/W 회사에 기술예속 가속</div>
<div class="divider"></div>
<div class="text-cell right">도면작성 중심의 기존 설계방식과 동일한 개념으로 생각하여, 탁상용 개인 PC, Monitor 사용기반 정도에 머물러 있어 실무적용에 필요한 높은 수준의 모델 등의 표출은 한계</div>
</div>
<!-- pills bottom -->
<div class="pill-row bottom">
<div class="pill-cell left">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">외산S/W 기술예속</span>
</div>
<div class="pill-cell right">
<img src="../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png" alt="">
<span class="label">H/W 미비</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

View File

@@ -0,0 +1,255 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>BIM 수행실정 — 2x2 진단 (Frame 1171281193)</title>
<!--
Pattern: quadrant-2x2-issues
Origin: 45:18 / Frame 1171281193
2×2 카테고리 그리드 (issue/diagnosis 진단). 각 카테고리에 N개의 issue + bullet body.
중앙에 optional 인용구 원.
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: 1280px;
--headline-color: #ff0000;
--body-color: #000000;
--header-bg: linear-gradient(90deg, #4a4028 0%, #285b4a 100%);
--header-text-color: #ffffff;
--card-bg-image: ../../block-tests/assets/shared/fdcafc1b6ab639b9a4c75ce36014f3b16ea0fbc1.png;
--row-gap: 0.6rem;
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.block {
width: var(--block-w);
background: #ffffff;
position: relative;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.4rem;
padding: 0;
}
.quadrant {
position: relative;
display: flex;
flex-direction: column;
background-color: #2a2a1a;
background-image: url('../../block-tests/assets/shared/fdcafc1b6ab639b9a4c75ce36014f3b16ea0fbc1.png');
background-size: cover;
border-radius: 1.5rem;
overflow: hidden;
}
.quadrant.tl, .quadrant.tr { border-radius: 1.5rem 1.5rem 0 0; }
.quadrant.bl, .quadrant.br { border-radius: 0 0 1.5rem 1.5rem; }
/* Header ribbon */
.q-header {
flex: none;
height: 3.4rem;
background: var(--header-bg);
display: flex; align-items: center; justify-content: center;
font-weight: 900;
font-size: 1.7rem;
color: var(--header-text-color);
text-shadow: 0 0 4px #322c1e;
}
/* 카테고리 본문 */
.q-body {
flex: 1;
padding: 1.2rem 1.4rem;
display: flex;
flex-direction: column;
gap: var(--row-gap);
color: #fff;
}
/* Each issue */
.issue {
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.issue .headline {
font-weight: 700;
font-size: 1.55rem;
line-height: 1.2;
color: var(--headline-color);
}
.issue .bullets {
list-style: disc;
padding-left: 1.6rem;
font-weight: 400;
font-size: 1.15rem;
line-height: 1.55;
color: #ffffff;
}
.issue .bullets li {
word-break: keep-all;
}
/* TR/BR alignment: text-right */
.quadrant.tr .issue .headline,
.quadrant.br .issue .headline {
text-align: right;
}
.quadrant.tr .issue .bullets,
.quadrant.br .issue .bullets {
list-style-position: inside;
padding-left: 0;
text-align: right;
}
/* 가운데 인용구 (optional, absolute over the grid) */
.center-quote {
position: absolute;
left: 50%; top: 50%;
transform: translate(-50%, -50%);
width: 28%;
aspect-ratio: 1.1;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 5;
text-align: center;
font-weight: 700;
font-size: 1.8rem;
color: #ffffff;
background-color: rgba(40, 91, 74, 0.95);
box-shadow: 0 0 30px rgba(0,0,0,0.5);
pointer-events: none;
overflow: hidden;
}
.center-quote img {
position: absolute;
inset: 0;
width: 100%; height: 100%;
object-fit: cover;
border-radius: 50%;
}
.center-quote .text {
position: relative;
z-index: 2;
padding: 0 1rem;
line-height: 1.15;
white-space: pre-line;
}
</style>
</head>
<body>
<div class="block">
<div class="quadrant tl">
<div class="q-header">정책 집행</div>
<div class="q-body">
<div class="issue">
<div class="headline">인정주의 정책 집행</div>
<ul class="bullets">
<li>수행능력이 없는 업체 선정 후 품질을 낮추어 시행하고 낮은 수준의 성과품을 실적으로 수용</li><li>모든 설계사가 할 수 있다는 전제하에 정책 시행</li><li>발주처의 책임회피를 위한 제도 운영</li>
</ul>
</div>
<div class="issue">
<div class="headline">적용효과도 사례도 없는 방침부터 남발</div>
<ul class="bullets">
<li>효과 검증도 없는 지침부터 만들고보는 현실</li><li>BIM/DX 적용효과를 판단할 사례 부재</li><li>대부분 홍보목적으로 포장되어 투자 대비 효과 없음</li>
</ul>
</div>
</div>
</div>
<div class="quadrant tr">
<div class="q-header">수행 개념</div>
<div class="q-body">
<div class="issue">
<div class="headline">공학적 개념 정립 부재</div>
<ul class="bullets">
<li>DX 개념과 BIM 기술의 차이점의 이해부족으로 전략적 접근방식과 기술적 도구 사이의 혼란만 가중</li><li>인프라시설의 DX의 기본은 단순 모델이 아닌 위치기반 3D 모델(BIM)을 활용한 과정(Process)의 혁신</li><li>기술적 도구인 3D 모델 제작S/W에 과도하게 의존</li>
</ul>
</div>
<div class="issue">
<div class="headline">'본업 기술력 확보' 우선의 개념 부재</div>
<ul class="bullets">
<li>깊은 기반지식 바탕의 기술이 축적된 메뉴얼에 대한 중요성 및 필요성에 대한 이해 부족</li><li>자체 기술개발 없이 국내 발주처의 지침과 방침에만 의존한 낮은 기술력</li>
</ul>
</div>
</div>
</div>
<div class="quadrant bl">
<div class="q-header">근본 취지의 이해부족</div>
<div class="q-body">
<div class="issue">
<div class="headline">기술투자 없는 성과 창출 기대</div>
<ul class="bullets">
<li>이전의 CAD 도입·확장 시기처럼 상용화된 BIM S/W만 구입·구독하면 될거라는 안일한 생각</li><li>기술개발 노력없이 과거처럼 하면 된다는 착각</li>
</ul>
</div>
<div class="issue">
<div class="headline">엔지니어링 S/W에 대한 개념 부재</div>
<ul class="bullets">
<li>다양한 엔지니어링 S/W의 특성에 대한 깊은 이해없이 단기 비용절감에 치우쳐 범용 S/W 선택</li><li>대형 Global S/W 회사에 과도한 의존과 이에 예속되는 방침 남발로 전용S/W 소멸</li>
</ul>
</div>
</div>
</div>
<div class="quadrant br">
<div class="q-header">지속적 투자 의지 부재</div>
<div class="q-body">
<div class="issue">
<div class="headline">근본적인 역할은 회피</div>
<ul class="bullets">
<li>엔지니어의 근본적인 역할인 과정의 혁신과 결과물의 변화에 대한 고민 부재</li><li>기술자가 직접 3D 모델을 만들고 수정하며 설계를 수행해야하는데 정작 모델제작은 외주처리</li>
</ul>
</div>
<div class="issue">
<div class="headline">과거의 타성에 머무르고 있는 업계</div>
<ul class="bullets">
<li>설계/감리/시공 임직원들의 디지털무지와 전략적 무지</li><li>S/W 판매업체의 기능적 사용법을 BIM 교육으로 착각</li><li>교육을 통한 인재양성보다는 당장 실무활용이 가능한 타사의 인력을 빼오기에 집중</li>
</ul>
</div>
</div>
</div>
<div class="center-quote">
<img src="../../block-tests/assets/shared/922ee6f4bea1434652ffc08f962086052286b6c5.png" alt="">
<div class="text">Rome wasn't
Built in a day!</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>BIM 미래 선언 메시지 (Frame 1171281207) — 템플릿 검증</title>
<!--
Pattern: statement-pill-highlight
Origin: 51:170 / Frame 1171281207
Single-line statement banner with optional inline highlighted segments.
pill 모양 (border-radius = height/2) + 배경 이미지(또는 단색) + 텍스트 + highlight 색
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: 1280px;
--block-h: 60px;
--slide-h: 720px;
--font-size: 1.7rem;
--font-weight: 700;
--text-color: #ffffff;
--highlight-color: #fe3;
--bg-color: #3a4a2f;
--text-shadow-color: rgba(0,0,0,0.5);
--text-shadow-blur: 4px;
--inner-padding-x: 3.5%;
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.slide {
width: var(--block-w);
height: var(--slide-h);
background: #ffffff;
position: relative;
display: flex; justify-content: center; align-items: center;
box-shadow: 0 4px 20px rgba(0, 0, 0, .15);
}
.banner-pill {
width: var(--block-w);
height: var(--block-h);
border-radius: calc(var(--block-h) / 2); /* 완전 캡슐 */
background: var(--bg-color);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
padding: 0 var(--inner-padding-x);
}
.banner-pill .bg {
position: absolute;
inset: 0;
width: 100%; height: 100%;
object-fit: cover;
}
.banner-pill .text {
position: relative;
z-index: 2;
font-weight: var(--font-weight);
font-size: var(--font-size);
color: var(--text-color);
letter-spacing: -0.01em;
text-shadow: 0 0 var(--text-shadow-blur) var(--text-shadow-color);
white-space: nowrap;
text-align: center;
}
.banner-pill .highlight {
color: var(--highlight-color);
}
</style>
</head>
<body>
<div class="slide">
<div class="banner-pill">
<img class="bg" src="../../block-tests/assets/shared/527bd7809f4b2e5f3cd42f2e713ccbfb37537d82.png" alt="">
<div class="text"><span>수행과정 연속화와 관리체계 일원화된 형태의 </span><span class="highlight">전용ㆍ전문 S/W 개발</span><span> 없이는 미래가 없다.</span></div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -0,0 +1,59 @@
# Example 2: 사진 없는 mdx 케이스
# 같은 블록이 사진 없는 콘텐츠도 매칭/렌더 가능한지 검증.
# bottom_photo 필드 생략 → no-photo 모드로 자동 렌더.
title: "BIM 3역할 목표 (사진 없는 mdx, 검증용)"
marker_icon: "../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png"
columns:
- role_label: ["발주자", "목표"]
role_color: "#285b4a"
bg_image: "../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png"
overlay_image: "../../block-tests/assets/shared/e837f8707efeffc9e357d084ad72b752a5fba0f9.png"
badge:
outer_image: "../../block-tests/assets/shared/77f319979c880da34ff3d423fcd97827f636c01e.png"
inner_image: "../../block-tests/assets/shared/e64c967dd00302bfbef6cfbcbb4f7a4db5d9d96c.png"
bullet_items:
- { text: "민원, 재 작업 등의 예방 및 최소화" }
- { text: "직관화로 품질 향상 및 안정성 제고" }
- { text: "수행공정의 쉬운이해로 관리 편의성 증진" }
- { text: "실무자와 발주자간의 소통 오류 최소화" }
- { text: "행정 자동화와 최소화로 생산성 향상" }
- { text: "건설정보의 통합관리로 활용성 강화" }
- { text: "전 생애주기에 걸친 효율적 디지털 자산관리" }
# bottom_photo 생략 ★
- role_label: ["시공자", "목표"]
role_color: "#445a2f"
bg_image: "../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png"
overlay_image: "../../block-tests/assets/shared/755384bd81ba10f62628933f16595eb054064846.png"
badge:
outer_image: "../../block-tests/assets/shared/1550ec755fa7922dcfc1c90135a570d6b9df82cc.png"
inner_image: "../../block-tests/assets/shared/85beaf9dfc17b7ed4620729a086ba22143606517.png"
bullet_items:
- { text: "시공 오류예방 및 공사 Risk 최소화" }
- { text: "시각화로 안전성 제고 및 품질 향상" }
- { text: "중간태, 완성태 측량을 통한 시‧공간적 관리 편리성 향상", compact: true }
- { text: "건설 관계자들 간의 의사소통 강화" }
- { text: "Model을 활용한 시공상세도 등의 관련도서 작성 용이", compact: true }
- { text: "System 구축을 통한 행정 간소화" }
- { text: "기술개발을 통한 생산성 향상" }
- role_label: ["설계자", "목표"]
role_color: "#743002"
bg_image: "../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png"
overlay_image: "../../block-tests/assets/shared/5577732e17bedec9eb1de4f77583cf67c8137f92.png"
badge:
outer_image: "../../block-tests/assets/shared/9ac089fa9c5106b6b26d47727003641bb56ba4b0.png"
inner_image: "../../block-tests/assets/shared/4b534ccf4e945fbe7436a0d8d96a6deffcfe5cef.png"
bullet_items:
- { text: "직관적 시각화로 원활한 소통" }
- { text: "3D 모델 활용으로 오류 최소화 및 Claim 예방", compact: true }
- { text: "발주자와의 상호 신뢰 증진" }
- { text: "정보물 생산으로 부가가치 창출" }
- { text: "고부가가치 창출산업으로 전환" }
- { text: "프로젝트 정보의 일관성 유지 및 관리를 통한 오류 최소화", compact: true }
# 슬라이드 height를 짧게 (사진 없으므로)
block_h: 720

View File

@@ -0,0 +1,63 @@
# Example data for cards-3col-persona template
# Reproduces frame 1171281191 (BIM 발주자/시공자/설계자 목표) content as template input.
#
# Use with: python templates_staging/render.py cards-3col-persona example
title: "BIM 3역할 목표 카드 (Frame 1171281191) — 템플릿 렌더 검증"
# 마커 (모든 컬럼 공통). 1:1 ref와 동일 자산 재사용.
marker_icon: "../../block-tests/assets/shared/6896d5c231e51de7cb844b99905e40b846863cd5.png"
columns:
# ─── 발주자 컬럼 ───
- role_label: ["발주자", "목표"]
role_color: "#285b4a"
bg_image: "../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png"
overlay_image: "../../block-tests/assets/shared/e837f8707efeffc9e357d084ad72b752a5fba0f9.png"
badge:
outer_image: "../../block-tests/assets/shared/77f319979c880da34ff3d423fcd97827f636c01e.png"
inner_image: "../../block-tests/assets/shared/e64c967dd00302bfbef6cfbcbb4f7a4db5d9d96c.png"
bullet_items:
- { text: "민원, 재 작업 등의 예방 및 최소화" }
- { text: "직관화로 품질 향상 및 안정성 제고" }
- { text: "수행공정의 쉬운이해로 관리 편의성 증진" }
- { text: "실무자와 발주자간의 소통 오류 최소화" }
- { text: "행정 자동화와 최소화로 생산성 향상" }
- { text: "건설정보의 통합관리로 활용성 강화" }
- { text: "전 생애주기에 걸친 효율적 디지털 자산관리" }
bottom_photo: "../../block-tests/assets/shared/d2c070f200af83f563976b6b0f309d38321d204d.png"
# ─── 시공자 컬럼 ───
- role_label: ["시공자", "목표"]
role_color: "#445a2f"
bg_image: "../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png"
overlay_image: "../../block-tests/assets/shared/755384bd81ba10f62628933f16595eb054064846.png"
badge:
outer_image: "../../block-tests/assets/shared/1550ec755fa7922dcfc1c90135a570d6b9df82cc.png"
inner_image: "../../block-tests/assets/shared/85beaf9dfc17b7ed4620729a086ba22143606517.png"
bullet_items:
- { text: "시공 오류예방 및 공사 Risk 최소화" }
- { text: "시각화로 안전성 제고 및 품질 향상" }
- { text: "중간태, 완성태 측량을 통한 시‧공간적 관리 편리성 향상", compact: true }
- { text: "건설 관계자들 간의 의사소통 강화" }
- { text: "Model을 활용한 시공상세도 등의 관련도서 작성 용이", compact: true }
- { text: "System 구축을 통한 행정 간소화" }
- { text: "기술개발을 통한 생산성 향상" }
bottom_photo: "../../block-tests/assets/shared/2a6a58e7bf7a645b5ede65115feb2890ccc414d1.png"
# ─── 설계자 컬럼 ───
- role_label: ["설계자", "목표"]
role_color: "#743002"
bg_image: "../../block-tests/assets/shared/4a17cd1dddaba8a220b706df3ec052d2bfde4f47.png"
overlay_image: "../../block-tests/assets/shared/5577732e17bedec9eb1de4f77583cf67c8137f92.png"
badge:
outer_image: "../../block-tests/assets/shared/9ac089fa9c5106b6b26d47727003641bb56ba4b0.png"
inner_image: "../../block-tests/assets/shared/4b534ccf4e945fbe7436a0d8d96a6deffcfe5cef.png"
bullet_items:
- { text: "직관적 시각화로 원활한 소통" }
- { text: "3D 모델 활용으로 오류 최소화 및 Claim 예방", compact: true }
- { text: "발주자와의 상호 신뢰 증진" }
- { text: "정보물 생산으로 부가가치 창출" }
- { text: "고부가가치 창출산업으로 전환" }
- { text: "프로젝트 정보의 일관성 유지 및 관리를 통한 오류 최소화", compact: true }
bottom_photo: "../../block-tests/assets/shared/39113493f6e3ae76d766e86e293b0f0dcbf55d91.png"

View File

@@ -0,0 +1,269 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>{{ title|default("cards-3col-persona") }}</title>
<!--
============================================================
Pattern: cards-3col-persona
Source: figma_to_html_agent/block-tests/bim-3roles-cards.html (1:1 reference)
Origin frame: 45:16 / Frame 1171281191
STRUCTURE: N개의 평행한 stakeholder 카드 (N=2~4)
각 카드 = bg image + color overlay + 상단 원형 badge + bullet list (custom marker) + optional bottom photo
PRINCIPLES (RULES.md, blocks_index.md 디자인 인사이트):
- I-1: 마커+텍스트는 시맨틱 list (R13)
- I-2: 평행 컬럼은 동일 top/bottom + 내부 spacing 자동 분배
- I-3: 모든 슬롯은 기본 optional (bottom_photo 등)
============================================================
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
/* 디자인 토큰 — 외부에서 override 가능 */
--block-w: {{ block_w|default(1280) }}px;
--block-h: {{ block_h|default(948) }}px;
--font-family: 'Noto Sans KR', sans-serif;
--font-body-size: {{ font_body_size|default("1.05rem") }};
--font-body-lh: {{ font_body_lh|default(2.125) }}; /* 85/40 */
--font-body-lh-compact: {{ font_body_lh_compact|default(1.25) }}; /* 50/40 */
--col-gap: {{ col_gap|default("4px") }};
--col-padding-x: {{ col_padding_x|default("21px") }}; /* block 좌우 padding */
--badge-width-ratio: {{ badge_width_ratio|default("48%") }}; /* col 너비 대비 */
--bullet-list-padding-x: {{ bullet_list_padding_x|default("10%") }};
--bullet-list-padding-y: {{ bullet_list_padding_y|default("13%") }};
--photo-height-ratio: {{ photo_height_ratio|default("38%") }};
--photo-margin-x: {{ photo_margin_x|default("8%") }};
--photo-margin-bottom: {{ photo_margin_bottom|default("4%") }};
--photo-radius: {{ photo_radius|default("6%") }};
--marker-w: {{ marker_w|default("1.4rem") }};
--marker-h: {{ marker_h|default("1.4rem") }};
--marker-gap: {{ marker_gap|default("0.55rem") }};
}
body {
font-family: var(--font-family);
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.block {
width: var(--block-w);
height: var(--block-h);
background: #ffffff;
position: relative;
overflow: hidden;
box-shadow: 0 4px 20px rgba(0, 0, 0, .15);
/* Layout: flex row of N columns */
display: flex;
flex-direction: row;
gap: var(--col-gap);
padding: 0 var(--col-padding-x);
}
/* ─────────────────────────────────────────────────────────
role-card: 한 stakeholder 컬럼. flex column.
───────────────────────────────────────────────────────── */
.role-card {
flex: 1 1 0; /* 모든 컬럼 동일 width */
position: relative;
display: flex;
flex-direction: column;
}
/* ─────────────────────────────────────────────────────────
badge: 카드 상단 원형 뱃지 (역할 라벨)
───────────────────────────────────────────────────────── */
.badge {
position: relative;
width: var(--badge-width-ratio);
aspect-ratio: 1; /* 정사각형 영역 */
margin: 0 auto;
z-index: 3;
flex: none;
}
.badge img.outer {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.badge img.inner {
position: absolute;
width: 76%;
height: 76%;
inset: 12%;
object-fit: contain;
}
.badge .label {
position: absolute;
/* Figma: label center at ~64% of badge height (figure가 상단부 차지)
→ label area를 badge 하단 ~52%에 배치 */
left: 0; right: 0;
top: 38%;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: 700;
text-align: center;
letter-spacing: -0.02em;
z-index: 10;
pointer-events: none;
}
.badge .label .ln1 { font-size: 1.7rem; line-height: 1; }
.badge .label .ln2 { font-size: 1.3rem; line-height: 1.2; margin-top: 0.1em; }
/* ─────────────────────────────────────────────────────────
card-body: bg + overlay + bullet list + optional photo
───────────────────────────────────────────────────────── */
.card-body {
position: relative;
flex: 1;
margin-top: -10%; /* badge와 약간 겹침 */
z-index: 1;
display: flex;
flex-direction: column;
}
.card-body .bg,
.card-body .overlay {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
pointer-events: none;
}
.card-body .overlay {
opacity: 0.80;
}
/* ─────────────────────────────────────────────────────────
bullet-list: R13 Custom-Marker Bullet List 패턴
각 컬럼이 동일 height + justify-content space-between
───────────────────────────────────────────────────────── */
.bullet-list {
position: relative;
z-index: 2;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: var(--bullet-list-padding-y) var(--bullet-list-padding-x);
list-style: none;
}
.bullet-row {
display: flex;
align-items: flex-start;
--lh: var(--font-body-lh);
}
.bullet-row.compact {
--lh: var(--font-body-lh-compact);
}
.bullet-icon {
flex: none;
width: var(--marker-w);
height: var(--marker-h);
margin-right: var(--marker-gap);
/* 핵심: icon center align with text first line center */
margin-top: calc((1em * var(--lh) - var(--marker-h)) / 2);
}
.bullet-icon img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
}
.bullet-text {
flex: 1;
font-size: var(--font-body-size);
line-height: var(--lh);
color: #000;
white-space: normal;
word-break: keep-all;
}
/* ─────────────────────────────────────────────────────────
bottom-photo: optional. 카드 하단 사진 카드
───────────────────────────────────────────────────────── */
.bottom-photo {
position: relative;
z-index: 2;
flex: none;
height: var(--photo-height-ratio);
margin: 0 var(--photo-margin-x) var(--photo-margin-bottom) var(--photo-margin-x);
border-radius: var(--photo-radius);
overflow: hidden;
opacity: 0.70;
}
.bottom-photo img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
/* photo가 없는 컬럼은 bullet-list가 더 많은 공간 차지 */
.role-card.no-photo .bullet-list {
padding-bottom: 6%;
}
</style>
</head>
<body>
<div class="block">
{% for col in columns %}
<article class="role-card{% if not col.bottom_photo %} no-photo{% endif %}">
<!-- Badge: 상단 원형 -->
<div class="badge">
<img class="outer" src="{{ col.badge.outer_image }}" alt="">
<img class="inner" src="{{ col.badge.inner_image }}" alt="">
<span class="label" style="color: {{ col.role_color }};">
<span class="ln1">{{ col.role_label[0] }}</span>
<span class="ln2">{{ col.role_label[1] }}</span>
</span>
</div>
<!-- Card body: bg + overlay + bullets + optional photo -->
<div class="card-body">
<img class="bg" src="{{ col.bg_image }}" alt="">
{% if col.overlay_image %}
<img class="overlay" src="{{ col.overlay_image }}" alt="">
{% endif %}
<!-- bullet-list: R13 sub-pattern -->
<ul class="bullet-list">
{% for item in col.bullet_items %}
<li class="bullet-row{% if item.compact %} compact{% endif %}">
<span class="bullet-icon"><img src="{{ marker_icon }}" alt=""></span>
<span class="bullet-text">{{ item.text|safe }}</span>
</li>
{% endfor %}
</ul>
<!-- Optional bottom photo -->
{% if col.bottom_photo %}
<div class="bottom-photo">
<img src="{{ col.bottom_photo }}" alt="">
</div>
{% endif %}
</div>
</article>
{% endfor %}
</div>
</body>
</html>

View File

@@ -0,0 +1,127 @@
pattern_id: cards-3col-persona
category: cards
version: 0.1.0 # staging draft
provenance:
source_frame: "45:16 / Frame 1171281191"
reference_html: ../block-tests/bim-3roles-cards.html
reference_render: ../block-tests/_renders/bim-3roles-cards_v8.png
description: |
N개의 평행한 stakeholder/관점/카테고리 카드. 각 카드는 상단 원형 뱃지(역할 라벨),
배경 이미지+컬러 오버레이, 본문 bullet 리스트(custom marker), 그리고 optional 하단 사진을 포함.
R13 (Custom-Marker Bullet List) sub-pattern을 카드 본문에 사용.
# AI 블록 선택기가 매칭에 사용하는 조건
when:
relation_type:
- parallel-stakeholders # 발주자/시공자/설계자 같이 여러 주체의 관점
- multi-perspective # 같은 주제를 여러 시각으로
- role-comparison # 역할별 책임/목표/특징 나열
- parallel-categories # N개 카테고리의 병렬 항목 나열
content_shape:
columns_count: { min: 2, max: 4 }
items_per_column: { min: 1, max: 12 }
not_for:
- linear_process # 순차적 단계
- single_main_message # 단일 핵심 메시지
- hierarchical_tree # 트리/계층
# 슬롯 정의
slots:
marker_icon:
type: image
required: true
description: bullet 마커 (체크박스/점/화살표/PNG 등). 모든 컬럼 공통.
columns:
type: list
required: true
min: 2
max: 4
item:
role_label:
type: tuple
items: [string, string] # ["발주자", "목표"] — 2 line label
required: true
role_color:
type: color # CSS color (hex, rgb, hsl)
required: true
description: 뱃지 라벨 색 + (옵션) overlay tint
bg_image:
type: image
required: true
description: 카드 배경 사진/일러스트
overlay_image:
type: image
required: false # 없으면 단색 BG만
description: 배경 위 컬러 오버레이 (보통 80% opacity)
badge:
type: object
required: true
properties:
outer_image: { type: image, required: true }
inner_image: { type: image, required: true }
bullet_items:
type: list
required: true
min: 1
max: 12
item:
text:
type: string
required: true
max_chars: 25 # zone width 기준 가이드
compact:
type: boolean
default: false
description: 2줄 들어가는 긴 항목인 경우 true. 텍스트 길이로 자동 결정 가능.
bottom_photo:
type: image
required: false # ★ 사진 없는 mdx도 매칭 가능
description: 카드 하단 보조 사진. 없으면 bullet-list가 더 많은 공간 사용.
# 디자인 토큰 (외부 override 가능)
tokens:
block_w: { default: 1280, unit: px }
block_h: { default: 948, unit: px }
font_body_size: { default: "0.95rem" }
font_body_lh: { default: 2.125 } # 단일 line item line-height ratio
font_body_lh_compact: { default: 1.25 } # 2-line item line-height ratio
col_gap: { default: "0.3%" }
card_padding_top: { default: "4.3%" }
marker_w: { default: "1.25rem" }
marker_h: { default: "1.25rem" }
marker_gap: { default: "0.45rem" }
# zone 적합성
min_size_px:
width: 720
height: 540
max_size_px:
width: 2600
height: 2000
# 적용 sub-pattern
sub_patterns:
- id: bullet-list-with-marker
rule: R13
location: card-body > .bullet-list
# 우선순위 (다른 블록과 경합 시)
priority: 50
# 1:1 reference 와의 차이 (intentional)
diff_from_reference:
- "Figma 절대 좌표 → flex layout (반응형)"
- "Figma 픽셀 fixed values → CSS 변수 + % 비율"
- "letter-spacing 보정 제거 → 자연 wrap"
- "explicit <br> 제거 → 자연 wrap (텍스트 길이로 결정)"
- "compact class 수동 → 텍스트 길이로 자동 (또는 외부 입력)"
- "사진 absolute → flex item, optional"

View File

@@ -0,0 +1,56 @@
# Example: Frame 1171281195 (BIM vs DX 비교 표)
title: "BIM vs DX 비교 표 (Frame 1171281195)"
header:
title: "BIM과 DX의 이해"
icon: "../../block-tests/assets/shared/b0e9fad5b03f4d9e368524976c20c9886392e17b.png"
left_label: "BIM"
right_label: "DX"
vs_label: "vs."
rows:
- category: "BIM/DX"
left: "Only 3D"
right: 'BIM &lt;&lt; DX <span class="sub">(ENG. + Management 포함)</span>'
- category: "S/W"
left: '모델 제작용 상용 S/W<br><span class="sub">[Civil 3D, Revit, Navisworks, Autocad]</span>'
right: '제작 및 운영 (상용 + 전용 40~80개)<br><span class="sub">[Rhino, Sketchup, Blender ..] + [EG-BIM 등]</span>'
- category: "프로세스"
left: "기존 2D 설계방식 유지"
right: "근본적 문제의식을 통한 개선"
- category: "성과물"
left: "3D 모델 중심<br>기존 성과품 유지"
right: "공학 정보 및 콘텐츠 연계에 집중<br>도면, 수량, 시공계획 등 일식"
- category: "활 용"
left: "3D 모델에 의한 일반적 이해 향상"
right: "설계/시공의 혁신(개념의 재정립)"
- category: "확장성"
left: "(설계/시공/운영) 분야별 단절"
right: "전 생애주기 활용 시스템"
- category: "수행개념"
left: "단순화(오류) - 수동적/집단적 동질화"
right: "구체화(복잡) - 적극/구체적 실현 방안"
- category: "CIVIL + IT"
left: "소극적, 상용 기술에 의존"
right: "적극적, 주체적인 기술 접목/융합"
- category: "주 체"
left: "S/W 제작사 판매 정책에 의존"
right: "자체 수행능력 - 지속가능성 확보"
- category: "발주처"
left: "평준화, 국내 중심"
right: "차별화 및 경쟁력 확보, 해외 진출"
- category: "설계사"
left: "소규모 BIM팀 운영 + 단순교육에 집중"
right: "IT + CIVIL ENG 220명 운영 + 기술 개발"
- category: "시공사"
left: "국내 토목 소극적/해외 토목증가"
right: "분야 확장 모델 및 시스템"
conclusion:
arrow: "../../block-tests/assets/shared/bf1755273910e17f7a012ce2d269a93cca9483ac.svg"
segments:
- text: "BIM은 건설산업의 DX(디지털전환)을 수행하는 과정에서 "
- text: "가장 기초가 되는 일부분"
highlight: true
- text: "임을 인지하는 것이 매우 중요"

View File

@@ -0,0 +1,209 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>{{ title|default("compare-vs-rows") }}</title>
<!--
Pattern: compare-vs-rows
Origin: 45:20 / Frame 1171281195
N개의 카테고리별 비교 행. 각 행 = 좌(A 진영) | 중앙(카테고리 라벨 pill) | 우(B 진영)
+ 헤더(타이틀 + icon) + 메인 pill ("A vs. B") + 결론 박스
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: {{ block_w|default(1280) }}px;
--left-color: {{ left_color|default("#5c3714") }}; /* 좌 진영 색 */
--right-color: {{ right_color|default("#285b4a") }}; /* 우 진영 색 */
--header-from: {{ header_from|default("#cc5200") }};
--header-to: {{ header_to|default("#883700") }};
--pill-bg-from: {{ pill_bg_from|default("rgb(40,91,74)") }};
--pill-bg-to: {{ pill_bg_to|default("rgb(74,64,38)") }};
--conclusion-color: {{ conclusion_color|default("#000") }};
--conclusion-highlight: {{ conclusion_highlight|default("#ae3607") }};
--row-font-size: {{ row_font_size|default("1.4rem") }};
--row-sub-font-size: {{ row_sub_font_size|default("1.2rem") }};
--cat-pill-w: {{ cat_pill_w|default("16%") }};
--cat-font-size: {{ cat_font_size|default("1.4rem") }};
--row-gap: {{ row_gap|default("0.8rem") }};
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.block {
width: var(--block-w);
background: #ffffff;
position: relative;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
padding: 1.5rem 1.8rem 1.5rem 1.8rem;
}
/* ─── 헤더 ─── */
.header {
display: flex; align-items: center; gap: 0.6rem;
margin-bottom: 0.8rem;
}
.header-icon {
width: 1.8rem; height: 1.8rem;
flex: none;
}
.header-icon img { width: 100%; height: 100%; object-fit: contain; }
.header-title {
font-weight: 700;
font-size: 1.6rem;
background-image: linear-gradient(180deg, var(--header-from) 0%, var(--header-to) 100%);
-webkit-background-clip: text; background-clip: text;
color: transparent;
text-shadow: 0 0 4px rgba(50,44,30,0.4);
}
/* ─── 메인 pill (A vs B) ─── */
.main-pill {
position: relative;
height: 2.2rem;
border-radius: 1.1rem;
background-image: linear-gradient(270deg,
var(--pill-bg-from) 0%, color-mix(in srgb, var(--pill-bg-from) 80%, transparent) 30%,
color-mix(in srgb, var(--pill-bg-to) 80%, transparent) 70%, var(--pill-bg-to) 100%);
display: grid;
grid-template-columns: 1fr var(--cat-pill-w) 1fr;
align-items: center;
font-weight: 700;
font-size: 1.5rem;
color: #fff;
margin-bottom: 0.6rem;
}
.main-pill .l { text-align: center; }
.main-pill .v { text-align: center; }
.main-pill .r { text-align: center; }
/* ─── 비교 표 ─── */
.cmp-table {
display: flex;
flex-direction: column;
gap: var(--row-gap);
}
.cmp-row {
display: grid;
grid-template-columns: 1fr var(--cat-pill-w) 1fr;
align-items: center;
gap: 0.5rem;
min-height: 2.4rem;
}
/* 좌 텍스트 (text-right) */
.cmp-row .left {
text-align: right;
font-weight: 700;
font-size: var(--row-font-size);
color: var(--left-color);
line-height: 1.3;
padding-right: 0.4rem;
}
.cmp-row .left .sub { font-size: var(--row-sub-font-size); }
/* 우 텍스트 (text-left) */
.cmp-row .right {
text-align: left;
font-weight: 700;
font-size: var(--row-font-size);
color: var(--right-color);
line-height: 1.3;
padding-left: 0.4rem;
}
.cmp-row .right .sub { font-size: var(--row-sub-font-size); }
/* 가운데 카테고리 pill */
.cmp-row .cat {
height: 100%;
min-height: 2rem;
border-radius: 0.4rem;
background-image: linear-gradient(270deg,
color-mix(in srgb, var(--pill-bg-from) 80%, transparent) 0%,
color-mix(in srgb, var(--pill-bg-from) 64%, transparent) 30%,
color-mix(in srgb, var(--pill-bg-to) 64%, transparent) 70%,
color-mix(in srgb, var(--pill-bg-to) 80%, transparent) 100%);
display: flex; align-items: center; justify-content: center;
font-weight: 700;
font-size: var(--cat-font-size);
color: #fff;
text-align: center;
padding: 0.4rem 0.6rem;
}
/* ─── 결론 박스 ─── */
.conclusion {
margin-top: 1rem;
position: relative;
border: 2px solid #4a4028;
background: #fff;
padding: 1rem 1.5rem 1rem 4rem;
border-radius: 0.4rem;
}
.conclusion .arrow {
position: absolute;
left: -0.5rem;
top: 50%;
transform: translateY(-50%);
width: 2.5rem;
height: 2.5rem;
}
.conclusion .arrow img { width: 100%; height: 100%; object-fit: contain; }
.conclusion .text {
font-weight: 700;
font-size: 1.3rem;
line-height: 1.5;
color: var(--conclusion-color);
}
.conclusion .text .hl {
color: var(--conclusion-highlight);
font-size: 1.45rem;
}
</style>
</head>
<body>
<div class="block">
{% if header %}
<div class="header">
{% if header.icon %}<div class="header-icon"><img src="{{ header.icon }}" alt=""></div>{% endif %}
<div class="header-title">{{ header.title }}</div>
</div>
{% endif %}
<div class="main-pill">
<div class="l">{{ left_label }}</div>
<div class="v">{{ vs_label|default("vs.") }}</div>
<div class="r">{{ right_label }}</div>
</div>
<div class="cmp-table">
{% for row in rows %}
<div class="cmp-row">
<div class="left">{{ row.left|safe }}</div>
<div class="cat">{{ row.category }}</div>
<div class="right">{{ row.right|safe }}</div>
</div>
{% endfor %}
</div>
{% if conclusion %}
<div class="conclusion">
{% if conclusion.arrow %}<div class="arrow"><img src="{{ conclusion.arrow }}" alt=""></div>{% endif %}
<div class="text">
{% for seg in conclusion.segments -%}
{%- if seg.highlight -%}<span class="hl">{{ seg.text }}</span>{%- else -%}<span>{{ seg.text }}</span>{%- endif -%}
{%- endfor %}
</div>
</div>
{% endif %}
</div>
</body>
</html>

View File

@@ -0,0 +1,86 @@
pattern_id: compare-vs-rows
category: tables
version: 0.1.0
provenance:
source_frame: "45:20 / Frame 1171281195"
reference_html: ../block-tests/bim-vs-dx-table.html
reference_render: ../block-tests/_renders/bim-vs-dx-table.png
description: |
N개의 카테고리별 비교 행. 각 행 = 좌(A 진영) | 중앙(카테고리 라벨 pill) | 우(B 진영).
+ 헤더(타이틀 + icon, optional) + 메인 pill (A vs. B) + 결론 박스(optional).
좌/우는 색상으로 대조 (A: brown, B: green).
when:
relation_type:
- comparison-2way-categorical
- vs-tabular
- before-after-multiline
- approach-comparison
content_shape:
rows: { min: 2, max: 20 }
has_categories: true
not_for:
- single-statement
- hierarchical-tree
- cyclic-process
slots:
header:
type: object
required: false
properties:
title: { type: string, required: true }
icon: { type: image, required: false }
left_label: { type: string, required: true, description: "예: BIM" }
right_label: { type: string, required: true, description: "예: DX" }
vs_label: { type: string, default: "vs." }
rows:
type: list
required: true
min: 2
max: 20
item:
category: { type: string, required: true }
left: { type: html_string, required: true, description: "<span class=\"sub\">…</span> 가능" }
right: { type: html_string, required: true }
conclusion:
type: object
required: false
properties:
arrow: { type: image, required: false }
segments:
type: list
item:
text: { type: string, required: true }
highlight: { type: boolean, default: false }
# 색상 토큰 (per side)
left_color: { type: color, default: "#5c3714" }
right_color: { type: color, default: "#285b4a" }
pill_bg_from: { type: color, default: "rgb(40,91,74)" }
pill_bg_to: { type: color, default: "rgb(74,64,38)" }
conclusion_color: { type: color, default: "#000" }
conclusion_highlight: { type: color, default: "#ae3607" }
tokens:
block_w: { default: 1280 }
row_font_size: { default: "1.4rem" }
cat_pill_w: { default: "16%" }
min_size_px: { width: 800, height: 400 }
max_size_px: { width: 1920, height: 1500 }
sub_patterns: []
priority: 50
diff_from_reference:
- "absolute pixel positions → CSS grid + flex (반응형)"
- "12 rows hardcoded → {% for row in rows %}"
- "left/right color → CSS 변수"
- "헤더/결론 모두 optional"
- "main pill 텍스트 형식 → 좌/우/vs 별 슬롯"

View File

@@ -0,0 +1,193 @@
# Example data for cycle-3way-intersect template
# Reproduces frame 1171281211 (BIM 안전과 품질 / 생산성 향상 / 소통과 신뢰) content
title: "BIM 3원 교차 다이어그램 (Frame 1171281211) — 템플릿 렌더 검증"
# 기존 1:1 reference의 frame_1171281211 자산 디렉토리 사용
bg_texture: "../../block-tests/assets/frame_1171281211/bg_texture.png"
decoration: true
arcs:
top: "../../block-tests/assets/frame_1171281211/arc_top.png"
left: "../../block-tests/assets/frame_1171281211/arc_side.png"
right: "../../block-tests/assets/frame_1171281211/arc_side.png"
circles:
top: # 안전과 품질 (orange)
label: ["안전과", "품질"]
fill:
angle: "145.28deg"
from: "#FDC69E"
from_pct: "16.04%"
to: "#E0782C"
to_pct: "55.20%"
ring:
angle: "145.28deg"
from: "#BC652B"
from_pct: "16.04%"
to: "#A24200"
to_pct: "55.20%"
text_shadow: "#cc5200"
bot_left: # 생산성 향상 (olive/grey)
label: ["생산성", "향상"]
fill:
angle: "218.84deg"
from: "#D5AA89"
from_pct: "14.08%"
to: "#737373"
to_pct: "92.67%"
ring:
angle: "153.95deg"
from: "#897445"
from_pct: "15.27%"
to: "#3E3523"
to_pct: "61.74%"
bot_right: # 소통과 신뢰 (white→dark green)
label: ["소통과", "신뢰"]
fill:
angle: "145.90deg"
from: "#FFFFFF"
from_pct: "8.47%"
to: "#253E1F"
to_pct: "87.56%"
ring:
angle: "153.95deg"
from: "#296B55"
from_pct: "15.27%"
to: "#123328"
to_pct: "61.74%"
accents:
# 안전과 품질 위 (top-left, top-right) → 安, 質
top_left:
char: "安"
outer:
angle: "145.90deg"
from: "#D9C868"
from_pct: "8.47%"
to: "#DC670E"
to_pct: "87.56%"
inner:
angle: "145.28deg"
from: "#BC652B"
from_pct: "16.04%"
to: "#A24200"
to_pct: "55.20%"
top_right:
char: "質"
outer:
angle: "145.90deg"
from: "#D9C868"
from_pct: "8.47%"
to: "#DC670E"
to_pct: "87.56%"
inner:
angle: "145.28deg"
from: "#BC652B"
from_pct: "16.04%"
to: "#A24200"
to_pct: "55.20%"
# 생산성 향상 좌 (left-top, left-bot) → 速, 利
left_top:
char: "速"
outer:
angle: "218.84deg"
from: "#D5AA89"
from_pct: "14.08%"
to: "#737373"
to_pct: "92.67%"
inner:
angle: "153.95deg"
from: "#897445"
from_pct: "15.27%"
to: "#3E3523"
to_pct: "61.73%"
left_bot:
char: "利"
outer:
angle: "218.84deg"
from: "#D5AA89"
from_pct: "14.08%"
to: "#737373"
to_pct: "92.67%"
inner:
angle: "153.95deg"
from: "#897445"
from_pct: "15.27%"
to: "#3E3523"
to_pct: "61.73%"
# 소통과 신뢰 우 (right-top, right-bot) → 通, 信
right_top:
char: "通"
outer:
angle: "145.90deg"
from: "#60A451"
from_pct: "8.47%"
to: "#253E1F"
to_pct: "87.56%"
inner:
angle: "153.95deg"
from: "#296B55"
from_pct: "15.27%"
to: "#123328"
to_pct: "61.73%"
right_bot:
char: "信"
outer:
angle: "145.90deg"
from: "#60A451"
from_pct: "8.47%"
to: "#253E1F"
to_pct: "87.56%"
inner:
angle: "153.95deg"
from: "#296B55"
from_pct: "15.27%"
to: "#123328"
to_pct: "61.73%"
side_labels:
# 안전과 품질 위 (top)
top_left:
title: "안전성 제고"
color: "#cc5200"
desc:
- "시설물의 요구성능의 만족,"
- "건설중 및 운영중 안전확보"
top_right:
title: "품질 향상"
color: "#cc5200"
desc:
- "Copy & Paste로 하향 평준화된"
- "기존 성과물의 품질 향상"
# 생산성 향상 옆 (mid-left, bot-left)
mid_left:
title: "신속ㆍ정확성 증진"
color: "#604f32"
desc:
- "Analogue 기반 업무를"
- "Digital화 하는 Process 혁신"
bot_left:
title: "비용저감ㆍ부가가치 창출"
color: "#604f32"
desc:
- "건설비용 및 유지관리비 감소,"
- "인력투입 최소화 등 생산성 향상"
# 소통과 신뢰 옆 (mid-right, bot-right)
mid_right:
title: "소통ㆍ이해 원할"
color: "#124133"
desc:
- "성과품, Solution을 통한"
- "사용 편리성, 협업 및 의사소통 강화"
bot_right:
title: "신뢰ㆍ투명성 강화"
color: "#124133"
desc:
- "3D 모델을 통한 오류"
- "최소화 및 Claim 예방"

View File

@@ -0,0 +1,349 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>{{ title|default("cycle-3way-intersect") }}</title>
<!--
============================================================
Pattern: cycle-3way-intersect
Source: figma_to_html_agent/block-tests/bim-goals-3circles.html (1:1 reference)
Origin frame: 66:310 / Frame 1171281211
STRUCTURE: 3개의 큰 원이 교차 (Venn-like)
- 3 main circles at FIXED positions (top, bot-left, bot-right)
- 6 accent circles at corners (top-left, top-right, left-top, left-bot, right-top, right-bot)
- 12 side labels at 6 positions (4 per circle context)
- 3 connecting arcs (PNG, optional)
- Background texture (optional)
- Decoration gradient (optional)
POSITION 고정 이유: 3-way intersect는 기하학적으로 결정되는 패턴.
2-way나 4-way는 별도 패턴 (cycle-2way-intersect, cycle-4way-intersect)으로 분리.
이 템플릿은 콘텐츠만 변수화 (라벨, 색상, 한자, 설명 등).
PRINCIPLES:
- I-3: 모든 슬롯은 기본 optional (bg, deco, arcs, side_labels 등)
- 1:1 reference의 transform: scale 전략 유지
============================================================
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin:0; padding:0; box-sizing:border-box; }
:root {
--block-w: {{ block_w|default(1280) }}px;
--block-h: {{ block_h|default(594) }}px; /* 957 × 0.620694 */
--inner-w: 2062.205px;
--inner-h: 956.998px;
--scale: {{ scale|default(0.620694) }};
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
}
.slide {
width: var(--block-w);
height: 720px;
background: #ffffff;
position: relative;
display: flex; justify-content: center; align-items: center;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
}
.block {
width: var(--block-w);
height: var(--block-h);
background: #ffffff;
position: relative;
overflow: hidden;
}
.inner {
position: absolute;
left: 0; top: 0;
width: var(--inner-w);
height: var(--inner-h);
transform: scale(var(--scale));
transform-origin: top left;
}
/* ─── 배경 텍스처 (optional) ─── */
.bg-texture {
position: absolute;
left: 139px; top: 683px;
width: 1768px; height: 274px;
mix-blend-mode: multiply;
pointer-events: none;
z-index: 0;
}
.bg-texture img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ─── 회전 그라데이션 데코 (optional) ─── */
.deco-wrap {
position: absolute;
left: 71px; top: 38px;
width: 685.475px; height: 836.277px;
display: flex; align-items: center; justify-content: center;
pointer-events: none;
z-index: 1;
}
.deco-rot { flex: none; transform: rotate(-120deg); }
.deco-flip { transform: scaleY(-1); }
.deco-rect {
width: 763px; height: 351px;
border-radius: 175.5px 0 0 175.5px;
background: linear-gradient(235.162deg,
rgba(115,115,115,0) 14.18%,
rgba(213,170,137,0.33) 66.964%);
}
/* ─── 연결 아크 (optional) ─── */
.arc { position: absolute; z-index: 2; display: flex; align-items: center; justify-content: center; }
.arc img { display: block; flex: none; }
.arc--top { left: 926px; top: 134px; width: 209px; height: 99px; }
.arc--top img { width: 209px; height: 99px; transform: rotate(180deg); }
.arc--left { left: 627px; top: 549px; width: 99px; height: 209px; }
.arc--left img { width: 209px; height: 99px; transform: rotate(90deg); }
.arc--right { left: 1329px; top: 549px; width: 99px; height: 209px; }
.arc--right img { width: 209px; height: 99px; transform: rotate(-90deg); }
/* ─── 메인 3원 outer (350×350) ─── */
.big-outer {
position: absolute;
width: 350px; height: 350px;
border-radius: 50%;
mix-blend-mode: multiply;
z-index: 3;
}
.big-outer.top { left: 853px; top: 206px; }
.big-outer.bot-left { left: 694px; top: 480px; }
.big-outer.bot-right{ left: 1009px; top: 480px; }
/* ─── 메인 3원 ring (280 또는 290 with stroke) ─── */
.big-ring {
position: absolute;
border-radius: 50%;
box-shadow: 0 0 10px 0 rgba(0,0,0,1);
z-index: 4;
}
.big-ring.top {
left: 882.06px; top: 235.06px;
width: 290px; height: 290px;
border: 5px solid #FFFFFF;
}
.big-ring.bot-left {
left: 728.06px; top: 514.06px;
width: 280px; height: 280px;
border: 5px solid #FFFFFF;
background-origin: border-box;
background-clip: border-box;
}
.big-ring.bot-right {
left: 1043.06px; top: 514.06px;
width: 280px; height: 280px;
border: 5px solid #FFFFFF;
background-origin: border-box;
background-clip: border-box;
}
/* ─── 메인 원 라벨 (50px Bold) ─── */
.big-title {
position: absolute;
width: 262.923px; height: 114.078px;
font-weight: 700;
font-size: 50px;
line-height: 50px;
color: #ffffff;
text-align: center;
letter-spacing: -2.5px;
display: flex; flex-direction: column; justify-content: center;
z-index: 5;
}
.big-title p { line-height: 50px; }
.big-title.top { left: 896.46px; top: 330.49px; }
.big-title.bot-left { left: 737.46px; top: 604.49px; }
.big-title.bot-right{ left: 1053.63px; top: 597.45px; }
/* ─── 액센트 6원 (130.9 outer + 82.965 inner with border) ─── */
.acc-outer {
position: absolute;
width: 130.901px; height: 130.901px;
border-radius: 50%;
opacity: 0.3;
mix-blend-mode: multiply;
z-index: 6;
}
.acc-outer.top-left { left: 859px; top: 22px; }
.acc-outer.top-right { left: 1071px; top: 22px; }
.acc-outer.left-top { left: 555px; top: 483px; }
.acc-outer.left-bot { left: 555px; top: 689px; }
.acc-outer.right-top { left: 1372px; top: 483px; }
.acc-outer.right-bot { left: 1372px; top: 689px; }
.acc-inner {
position: absolute;
width: 82.965px; height: 82.965px;
border: 2px solid #FFFFFF;
border-radius: 50%;
box-shadow: 0 0 10px 0 rgba(0,0,0,1);
z-index: 7;
}
.acc-inner.top-left { left: 882.47px; top: 45.47px; }
.acc-inner.top-right { left: 1094.47px; top: 45.47px; }
.acc-inner.left-top { left: 578.47px; top: 506.47px; }
.acc-inner.left-bot { left: 578.47px; top: 712.47px; }
.acc-inner.right-top { left: 1395.47px; top: 506.47px; }
.acc-inner.right-bot { left: 1395.47px; top: 712.47px; }
.acc-text {
position: absolute;
width: 98.334px; height: 42.666px;
font-weight: 700;
font-size: 45px;
line-height: 50px;
color: #ffffff;
text-align: center;
letter-spacing: -2.25px;
text-shadow: 0 0 5px #cc5200;
display: flex; align-items: center; justify-content: center;
z-index: 8;
}
.acc-text.top-left { left: 875.25px; top: 63.60px; }
.acc-text.top-right { left: 1087.25px; top: 63.60px; }
.acc-text.left-top { left: 571.25px; top: 524.60px; }
.acc-text.left-bot { left: 571.25px; top: 730.60px; }
.acc-text.right-top { left: 1388.25px; top: 524.60px; }
.acc-text.right-bot { left: 1388.25px; top: 730.60px; }
/* ─── 사이드 텍스트 라벨 (12개, 6 위치 × 2 (title+desc)) ─── */
.side-title {
position: absolute;
font-weight: 700;
font-size: 40px;
line-height: 95px;
white-space: nowrap;
z-index: 5;
}
.side-desc {
position: absolute;
font-weight: 500;
font-size: 30px;
color: #525151;
z-index: 5;
}
.side-desc p { line-height: 35px; padding-bottom: 5px; }
/* 상단 (top) — 안전성 제고 / 품질 향상 */
.side-title.top-left { left: 645px; top: 0; width: 194px; text-align: right; }
.side-title.top-right { left: 1233px; top: 0; width: 157px; text-align: right; }
.side-desc.top-left { left: 331px; top: 78px; width: 508.478px; text-align: right; }
.side-desc.top-right { left: 1233px; top: 78px; width: 508.478px; }
/* 좌측 (mid-left) — 신속·정확성 / 비용저감 */
.side-title.mid-left { left: 0; top: 456px; width: 531.393px; height: 95.345px; text-align: right; white-space: nowrap; }
.side-title.bot-left {
left: 84.67px; top: 661.79px; width: 446.049px; height: 96.418px;
display: flex; flex-direction: column; justify-content: center;
text-align: right;
}
.side-desc.mid-left { left: 52.01px; top: 546px; width: 478.731px; height: 70.561px; text-align: right; }
.side-desc.bot-left {
left: 102.02px; top: 734px; width: 428.315px; height: 91.343px;
display: flex; flex-direction: column; justify-content: center;
text-align: right;
}
/* 우측 (mid-right) — 소통·이해 / 신뢰·투명성 */
.side-title.mid-right { left: 1518px; top: 456px; width: 267.016px; }
.side-title.bot-right { left: 1518px; top: 664px; width: 304.016px; }
.side-desc.mid-right { left: 1518px; top: 541px; width: 429.012px; white-space: nowrap; }
.side-desc.bot-right {
left: 1518px; top: 754.21px; width: 544.198px; height: 70.561px;
display: flex; flex-direction: column; justify-content: center;
}
</style>
</head>
<body>
<div class="slide">
<div class="block">
<div class="inner">
{# ─── Optional 배경 텍스처 ─── #}
{% if bg_texture %}
<div class="bg-texture"><img src="{{ bg_texture }}" alt=""></div>
{% endif %}
{# ─── Optional 데코 그라데이션 ─── #}
{% if decoration %}
<div class="deco-wrap">
<div class="deco-rot"><div class="deco-flip"><div class="deco-rect"></div></div></div>
</div>
{% endif %}
{# ─── Optional 연결 아크 3개 ─── #}
{% if arcs %}
<div class="arc arc--top"><img src="{{ arcs.top }}" alt=""></div>
<div class="arc arc--left"><img src="{{ arcs.left }}" alt=""></div>
<div class="arc arc--right"><img src="{{ arcs.right }}" alt=""></div>
{% endif %}
{# ─── 메인 3원 outer ─── #}
{% for pos, c in [('top', circles.top), ('bot-left', circles.bot_left), ('bot-right', circles.bot_right)] %}
<div class="big-outer {{ pos }}"
style="background: linear-gradient({{ c.fill.angle|default('145deg') }}, {{ c.fill.from }} {{ c.fill.from_pct|default('15%') }}, {{ c.fill.to }} {{ c.fill.to_pct|default('60%') }});">
</div>
<div class="big-ring {{ pos }}"
style="background: linear-gradient({{ c.ring.angle|default('150deg') }}, {{ c.ring.from }} {{ c.ring.from_pct|default('15%') }}, {{ c.ring.to }} {{ c.ring.to_pct|default('60%') }});">
</div>
<div class="big-title {{ pos }}"
{% if c.text_shadow %}style="text-shadow: 0 0 5px {{ c.text_shadow }};"{% endif %}>
<p>{{ c.label[0] }}</p><p>{{ c.label[1] }}</p>
</div>
{% endfor %}
{# ─── 액센트 6원 (3 main circles × 2 corners each) ─── #}
{% for pos, a in [
('top-left', accents.top_left), ('top-right', accents.top_right),
('left-top', accents.left_top), ('left-bot', accents.left_bot),
('right-top', accents.right_top), ('right-bot', accents.right_bot)] %}
{% if a %}
<div class="acc-outer {{ pos }}"
style="background: linear-gradient({{ a.outer.angle|default('145deg') }}, {{ a.outer.from }} {{ a.outer.from_pct|default('10%') }}, {{ a.outer.to }} {{ a.outer.to_pct|default('85%') }});">
</div>
<div class="acc-inner {{ pos }}"
style="background: linear-gradient({{ a.inner.angle|default('150deg') }}, {{ a.inner.from }} {{ a.inner.from_pct|default('15%') }}, {{ a.inner.to }} {{ a.inner.to_pct|default('60%') }});">
</div>
<div class="acc-text {{ pos }}">{{ a.char }}</div>
{% endif %}
{% endfor %}
{# ─── 사이드 라벨 6 위치 × (title + desc) = 최대 12개 ─── #}
{% for pos, lbl in [
('top-left', side_labels.top_left), ('top-right', side_labels.top_right),
('mid-left', side_labels.mid_left), ('mid-right', side_labels.mid_right),
('bot-left', side_labels.bot_left), ('bot-right', side_labels.bot_right)] %}
{% if lbl %}
{% if lbl.title %}
<div class="side-title {{ pos }}" style="color: {{ lbl.color|default('#000') }};">{{ lbl.title }}</div>
{% endif %}
{% if lbl.desc %}
<div class="side-desc {{ pos }}">
{% for line in lbl.desc %}<p>{{ line }}</p>{% endfor %}
</div>
{% endif %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,146 @@
pattern_id: cycle-3way-intersect
category: visuals
version: 0.1.0
provenance:
source_frame: "66:310 / Frame 1171281211"
reference_html: ../block-tests/bim-goals-3circles.html
reference_render: ../block-tests/bim_goals_final.png
description: |
3개의 큰 원이 교차하는 Venn-like 다이어그램. 각 원에 라벨, 컬러,
코너 액센트 (한자/문자), 사이드 텍스트 라벨이 부착됨.
이 패턴은 기하학적으로 3-원에 특화되어 있음. 2-원이나 4-원은 별도 패턴
(cycle-2way-intersect, cycle-4way-intersect)으로 분리.
when:
relation_type:
- intersection # 3개의 개념이 교차/공통
- venn-3 # 3원 벤
- integration # 3 영역의 통합
- holistic-view # 전체적 조감
content_shape:
main_concepts: { exact: 3 }
has_visual_emphasis: true
not_for:
- linear_process
- simple_list
- hierarchical_tree
- parallel_2_or_4
slots:
# 3 main circles at fixed geometric positions
circles:
type: object
required: true
properties:
top:
type: object
required: true
properties:
label: { type: tuple, items: [string, string], required: true } # ["안전과", "품질"]
fill: { type: gradient, required: true } # {from, to, angle?, from_pct?, to_pct?}
ring: { type: gradient, required: true }
text_shadow: { type: color, required: false } # 글로우 효과 색
bot_left:
type: object
required: true
properties:
label: { type: tuple, items: [string, string], required: true }
fill: { type: gradient, required: true }
ring: { type: gradient, required: true }
text_shadow: { type: color, required: false }
bot_right:
type: object
required: true
properties:
label: { type: tuple, items: [string, string], required: true }
fill: { type: gradient, required: true }
ring: { type: gradient, required: true }
text_shadow: { type: color, required: false }
# 6 accent positions, all optional
accents:
type: object
required: false
description: 각 main circle의 코너에 부착되는 작은 액센트 원 + 한자/문자
properties:
top_left: { type: accent, required: false } # 안전과 품질 위 좌
top_right: { type: accent, required: false } # 안전과 품질 위 우
left_top: { type: accent, required: false } # 생산성 향상 좌 위
left_bot: { type: accent, required: false } # 생산성 향상 좌 아래
right_top: { type: accent, required: false } # 소통과 신뢰 우 위
right_bot: { type: accent, required: false } # 소통과 신뢰 우 아래
accent_schema:
char: { type: string, required: true, max_length: 2 }
outer: { type: gradient, required: true }
inner: { type: gradient, required: true }
# 6 side label positions × (title + desc) = max 12
side_labels:
type: object
required: false
description: 각 main circle 옆/위에 붙는 보조 텍스트 라벨
properties:
top_left: { type: label, required: false }
top_right: { type: label, required: false }
mid_left: { type: label, required: false }
mid_right: { type: label, required: false }
bot_left: { type: label, required: false }
bot_right: { type: label, required: false }
label_schema:
title: { type: string, required: false }
color: { type: color, default: "#000" }
desc: { type: list, items: string, required: false, max_lines: 3 }
# Optional decorative elements
bg_texture:
type: image
required: false
description: 하단 배경 텍스처 (multiply blend)
decoration:
type: boolean
required: false
default: false
description: 회전 그라데이션 데코 표시 여부
arcs:
type: object
required: false
description: 원 사이 연결 아크 (PNG)
properties:
top: { type: image, required: false }
left: { type: image, required: false }
right: { type: image, required: false }
# 디자인 토큰
tokens:
block_w: { default: 1280, unit: px }
block_h: { default: 594, unit: px }
scale: { default: 0.620694, description: "1280 / 2062.205 (Figma 원본 너비)" }
# zone 적합성
min_size_px:
width: 960
height: 480
max_size_px:
width: 1920
height: 900
# 적용 sub-pattern
sub_patterns: []
# 우선순위
priority: 60
# 1:1 reference 와의 차이
diff_from_reference:
- "콘텐츠 (라벨/색상/한자/사이드 텍스트) → 슬롯 변수화"
- "위치 hardcoded 유지 (3-way 기하학은 패턴 자체가 결정)"
- "bg_texture / decoration / arcs / accents / side_labels 모두 optional"
# 향후 확장 메모
future_patterns:
- cycle-2way-intersect: 2 원 교차 (별도 템플릿)
- cycle-4way-intersect: 4 원 교차 (별도 템플릿, 정사각 배치)
- cycle-Nway-circular: N 원이 원형으로 둘러싼 형태 (cos/sin 자동 배치)

View File

@@ -0,0 +1,22 @@
title: "현황 및 문제점 (Frame 1171281194)"
header:
title: "현황 및 문제점"
icon: "../../block-tests/assets/shared/b0e9fad5b03f4d9e368524976c20c9886392e17b.png"
pill_bg: "../../block-tests/assets/shared/b47d2977a36ab6a0c180d8f090afff798c44ed27.png"
rows:
- left: { label: "개념 부재", text: "BIM을 Digital 전환의 개념이 아닌, CAD의 확장판으로 해석하여 3D를 그리는 수단 정도로만 인식" }
right: { label: "잘못된 접근방식", text: "단순 업무효율 증진을 위한 도구로만 인식하여, 기술자들이 도구로서 사용만 할 수 있도록 교육시키면 된다고 판단" }
- left: { label: "방향성 상실", text: "대형 S/W 개발 및 판매회사에서 제시된 내용과 방향대로 따라하므로써, 국내는 자체적 목표설정 기능을 상실" }
right: { label: "전제조건 오류", text: "건축과 토목이 유사하다는 전제하에 Library를 활용하는 건축에서 수행하고 있는 방식을 토목에도 동일하게 적용" }
pills_bottom: true
- left: { label: "수행주체 혼란", text: "학자, 발주처 중심으로 S/W 판매회사에서 제시한 기술 수행 방식의 변화를 주도, 실행주체인 기업과 기술자들은 기존의 방식을 고수하면서 눈치만 보는 실정" }
right: { label: "수행방식 무지", text: "기존 2D 설계의 결과가 옳다는 전제와 3D 설계를 수행/검토해본 경험이 없어, 전환설계의 개념으로 수행하므로써 비용과 시간이 추가로 소요, 높은 수준의 품질확보 불가" }
- left: { label: "외산S/W 기술예속", text: "단순 외산 범용S/W만 사용하면 BIM이 될 수 있을 것이라는 안일한 생각으로 접근하므로 외국 대형S/W 회사에 기술예속 가속" }
right: { label: "H/W 미비", text: "도면작성 중심의 기존 설계방식과 동일한 개념으로 생각하여, 탁상용 개인 PC, Monitor 사용기반 정도에 머물러 있어 실무적용에 필요한 높은 수준의 모델 등의 표출은 한계" }
pills_bottom: true

View File

@@ -0,0 +1,185 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>{{ title|default("issues-paired-rows") }}</title>
<!--
Pattern: issues-paired-rows
Origin: 45:19 / Frame 1171281194
구조: flex column (텍스트 양에 따라 박스 유동 조절)
pill: 고정 크기 (25.5% of row width), 박스 border에 걸침 (negative margin)
pill 이미지: R16 (overflow:hidden으로 한쪽 곡선만 보임)
bottom pill: rotate(180) + 이미지 배치 반전
텍스트: pill과 분리된 flex item → 절대 가려지지 않음
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: {{ block_w|default(1280) }}px;
--border-color: {{ border_color|default("#60a451") }};
--box-bg: {{ box_bg|default("rgba(250,237,203,0.15)") }};
--text-color: {{ text_color|default("#0c271e") }};
--pill-text-color: {{ pill_text_color|default("#ffffff") }};
--pill-width: {{ pill_width|default("25.5%") }};
--pill-height: {{ pill_height|default("4.1rem") }};
--pill-overlap: {{ pill_overlap|default("0.8rem") }};
--row-gap: {{ row_gap|default("0.4rem") }};
--font-body: {{ font_body|default("1.05rem") }};
--font-pill: {{ font_pill|default("1.2rem") }};
--divider-color: {{ divider_color|default("rgba(96,164,81,0.4)") }};
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh; padding: 20px;
word-break: keep-all;
}
.block {
width: var(--block-w);
background: #fff;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
padding: 1.2rem 1.8rem;
}
.header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.8rem; }
.header-icon { width: 1.8rem; height: 1.8rem; flex: none; }
.header-icon img { width: 100%; height: 100%; object-fit: contain; }
.header-title {
font-weight: 700; font-size: 1.6rem;
background-image: linear-gradient(180deg, #cc5200 0%, #883700 100%);
-webkit-background-clip: text; background-clip: text; color: transparent;
text-shadow: 0 0 4px rgba(50,44,30,0.4);
}
.rows { display: flex; flex-direction: column; gap: var(--row-gap); }
/* issue-row: 하나의 행 (border 박스) */
.issue-row {
border: 2px solid var(--border-color);
border-radius: 1rem;
background: var(--box-bg);
display: flex;
flex-direction: column;
}
/* pill-row: 좌/우 pill 2개 배치 */
.pill-row {
display: flex;
justify-content: space-between;
}
/* pill이 박스 border 위/아래로 걸침 */
.pill-row.top { margin-top: calc(-1 * var(--pill-overlap)); }
.pill-row.bottom { margin-bottom: calc(-1 * var(--pill-overlap)); }
/* 개별 pill */
.pill-cell {
position: relative;
width: var(--pill-width);
height: var(--pill-height);
overflow: hidden;
flex: none;
}
/* R16: 이미지 프레임 배치 — 한쪽 곡선만 보임 */
.pill-cell.left img {
position: absolute;
top: 0; height: 100%;
left: -45.3%;
width: 145.3%;
}
.pill-cell.right img {
position: absolute;
top: 0; height: 100%;
left: 0;
width: 151.25%;
}
/* bottom pill: rotate(180) + 이미지 배치 반전 */
.pill-row.bottom .pill-cell { transform: rotate(180deg); }
.pill-row.bottom .pill-cell.left img {
left: 0;
width: 151.25%;
}
.pill-row.bottom .pill-cell.right img {
left: -45.3%;
width: 145.3%;
}
.pill-cell .label {
position: absolute; inset: 0;
display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: var(--font-pill); color: var(--pill-text-color);
white-space: nowrap; z-index: 2;
}
.pill-row.bottom .pill-cell .label { transform: rotate(180deg); }
/* 텍스트 영역: 좌/우 나란히 + 가운데 점선 */
.text-row {
display: grid;
grid-template-columns: 1fr 1px 1fr;
padding: 0.5rem 0.8rem;
}
.text-row .divider {
border-left: 1px dashed var(--divider-color);
margin: 0.2rem 0;
}
.text-row .text-cell {
font-weight: 500;
font-size: var(--font-body);
line-height: 1.8;
color: var(--text-color);
padding: 0.3rem 0.6rem;
}
.text-row .text-cell.right { text-align: right; }
</style>
</head>
<body>
<div class="block">
{% if header %}
<div class="header">
{% if header.icon %}<div class="header-icon"><img src="{{ header.icon }}" alt=""></div>{% endif %}
<div class="header-title">{{ header.title }}</div>
</div>
{% endif %}
<div class="rows">
{% for row in rows %}
<div class="issue-row">
{% if not row.pills_bottom %}
<!-- pills top -->
<div class="pill-row top">
<div class="pill-cell left">
{% if pill_bg %}<img src="{{ pill_bg }}" alt="">{% endif %}
<span class="label">{{ row.left.label }}</span>
</div>
<div class="pill-cell right">
{% if pill_bg %}<img src="{{ pill_bg }}" alt="">{% endif %}
<span class="label">{{ row.right.label }}</span>
</div>
</div>
{% endif %}
<div class="text-row">
<div class="text-cell">{{ row.left.text|safe }}</div>
<div class="divider"></div>
<div class="text-cell right">{{ row.right.text|safe }}</div>
</div>
{% if row.pills_bottom %}
<!-- pills bottom -->
<div class="pill-row bottom">
<div class="pill-cell left">
{% if pill_bg %}<img src="{{ pill_bg }}" alt="">{% endif %}
<span class="label">{{ row.left.label }}</span>
</div>
<div class="pill-cell right">
{% if pill_bg %}<img src="{{ pill_bg }}" alt="">{% endif %}
<span class="label">{{ row.right.label }}</span>
</div>
</div>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,33 @@
pattern_id: issues-paired-rows
category: tables
version: 0.1.0
provenance:
source_frame: "45:19 / Frame 1171281194"
reference_html: ../block-tests/bim-issues-paired.html
description: |
N개의 행, 각 행 = 좌 이슈 + 우 이슈 (라벨 pill + 본문). 가운데 세로 구분선.
pill 위치가 행마다 top/bottom 교차 가능. 현황 분석, 문제점 진단, 대조 분석에 적합.
when:
relation_type: [paired-issues, dual-diagnosis, problem-pairs]
content_shape:
rows: { min: 2, max: 8 }
per_row: { exact: 2 }
slots:
header: { type: object, required: false }
pill_bg: { type: image, required: false }
rows:
type: list
required: true
min: 2
max: 8
item:
left: { label: string, text: html_string }
right: { label: string, text: html_string }
pills_bottom: { type: boolean, default: false }
min_size_px: { width: 800, height: 400 }
sub_patterns: []
priority: 45

View File

@@ -0,0 +1,57 @@
# Example: Frame 1171281193 (BIM 수행실정)
title: "BIM 수행실정 — 2x2 진단 (Frame 1171281193)"
card_bg_image: "../../block-tests/assets/shared/fdcafc1b6ab639b9a4c75ce36014f3b16ea0fbc1.png"
quadrants:
- label: "정책 집행"
issues:
- headline: "인정주의 정책 집행"
bullets:
- "수행능력이 없는 업체 선정 후 품질을 낮추어 시행하고 낮은 수준의 성과품을 실적으로 수용"
- "모든 설계사가 할 수 있다는 전제하에 정책 시행"
- "발주처의 책임회피를 위한 제도 운영"
- headline: "적용효과도 사례도 없는 방침부터 남발"
bullets:
- "효과 검증도 없는 지침부터 만들고보는 현실"
- "BIM/DX 적용효과를 판단할 사례 부재"
- "대부분 홍보목적으로 포장되어 투자 대비 효과 없음"
- label: "수행 개념"
issues:
- headline: "공학적 개념 정립 부재"
bullets:
- "DX 개념과 BIM 기술의 차이점의 이해부족으로 전략적 접근방식과 기술적 도구 사이의 혼란만 가중"
- "인프라시설의 DX의 기본은 단순 모델이 아닌 위치기반 3D 모델(BIM)을 활용한 과정(Process)의 혁신"
- "기술적 도구인 3D 모델 제작S/W에 과도하게 의존"
- headline: "'본업 기술력 확보' 우선의 개념 부재"
bullets:
- "깊은 기반지식 바탕의 기술이 축적된 메뉴얼에 대한 중요성 및 필요성에 대한 이해 부족"
- "자체 기술개발 없이 국내 발주처의 지침과 방침에만 의존한 낮은 기술력"
- label: "근본 취지의 이해부족"
issues:
- headline: "기술투자 없는 성과 창출 기대"
bullets:
- "이전의 CAD 도입·확장 시기처럼 상용화된 BIM S/W만 구입·구독하면 될거라는 안일한 생각"
- "기술개발 노력없이 과거처럼 하면 된다는 착각"
- headline: "엔지니어링 S/W에 대한 개념 부재"
bullets:
- "다양한 엔지니어링 S/W의 특성에 대한 깊은 이해없이 단기 비용절감에 치우쳐 범용 S/W 선택"
- "대형 Global S/W 회사에 과도한 의존과 이에 예속되는 방침 남발로 전용S/W 소멸"
- label: "지속적 투자 의지 부재"
issues:
- headline: "근본적인 역할은 회피"
bullets:
- "엔지니어의 근본적인 역할인 과정의 혁신과 결과물의 변화에 대한 고민 부재"
- "기술자가 직접 3D 모델을 만들고 수정하며 설계를 수행해야하는데 정작 모델제작은 외주처리"
- headline: "과거의 타성에 머무르고 있는 업계"
bullets:
- "설계/감리/시공 임직원들의 디지털무지와 전략적 무지"
- "S/W 판매업체의 기능적 사용법을 BIM 교육으로 착각"
- "교육을 통한 인재양성보다는 당장 실무활용이 가능한 타사의 인력을 빼오기에 집중"
center_quote:
text: "Rome wasn't\nBuilt in a day!"
image: "../../block-tests/assets/shared/922ee6f4bea1434652ffc08f962086052286b6c5.png"

View File

@@ -0,0 +1,181 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>{{ title|default("quadrant-2x2-issues") }}</title>
<!--
Pattern: quadrant-2x2-issues
Origin: 45:18 / Frame 1171281193
2×2 카테고리 그리드 (issue/diagnosis 진단). 각 카테고리에 N개의 issue + bullet body.
중앙에 optional 인용구 원.
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: {{ block_w|default(1280) }}px;
--headline-color: {{ headline_color|default("#ff0000") }};
--body-color: {{ body_color|default("#000000") }};
--header-bg: {{ header_bg|default("linear-gradient(90deg, #4a4028 0%, #285b4a 100%)") }};
--header-text-color: {{ header_text_color|default("#ffffff") }};
--card-bg-image: {{ card_bg_image|default("") }};
--row-gap: {{ row_gap|default("0.6rem") }};
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.block {
width: var(--block-w);
background: #ffffff;
position: relative;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.4rem;
padding: 0;
}
.quadrant {
position: relative;
display: flex;
flex-direction: column;
background-color: #2a2a1a;
{% if card_bg_image %}background-image: url('{{ card_bg_image }}');{% endif %}
background-size: cover;
border-radius: 1.5rem;
overflow: hidden;
}
.quadrant.tl, .quadrant.tr { border-radius: 1.5rem 1.5rem 0 0; }
.quadrant.bl, .quadrant.br { border-radius: 0 0 1.5rem 1.5rem; }
/* Header ribbon */
.q-header {
flex: none;
height: 3.4rem;
background: var(--header-bg);
display: flex; align-items: center; justify-content: center;
font-weight: 900;
font-size: 1.7rem;
color: var(--header-text-color);
text-shadow: 0 0 4px #322c1e;
}
/* 카테고리 본문 */
.q-body {
flex: 1;
padding: 1.2rem 1.4rem;
display: flex;
flex-direction: column;
gap: var(--row-gap);
color: #fff;
}
/* Each issue */
.issue {
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.issue .headline {
font-weight: 700;
font-size: 1.55rem;
line-height: 1.2;
color: var(--headline-color);
}
.issue .bullets {
list-style: disc;
padding-left: 1.6rem;
font-weight: 400;
font-size: 1.15rem;
line-height: 1.55;
color: #ffffff;
}
.issue .bullets li {
word-break: keep-all;
}
/* TR/BR alignment: text-right */
.quadrant.tr .issue .headline,
.quadrant.br .issue .headline {
text-align: right;
}
.quadrant.tr .issue .bullets,
.quadrant.br .issue .bullets {
list-style-position: inside;
padding-left: 0;
text-align: right;
}
/* 가운데 인용구 (optional, absolute over the grid) */
.center-quote {
position: absolute;
left: 50%; top: 50%;
transform: translate(-50%, -50%);
width: 28%;
aspect-ratio: 1.1;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 5;
text-align: center;
font-weight: 700;
font-size: 1.8rem;
color: #ffffff;
background-color: rgba(40, 91, 74, 0.95);
box-shadow: 0 0 30px rgba(0,0,0,0.5);
pointer-events: none;
overflow: hidden;
}
.center-quote img {
position: absolute;
inset: 0;
width: 100%; height: 100%;
object-fit: cover;
border-radius: 50%;
}
.center-quote .text {
position: relative;
z-index: 2;
padding: 0 1rem;
line-height: 1.15;
white-space: pre-line;
}
</style>
</head>
<body>
<div class="block">
{% set positions = [('tl', 0), ('tr', 1), ('bl', 2), ('br', 3)] %}
{% for pos, idx in positions %}
{% set q = quadrants[idx] %}
<div class="quadrant {{ pos }}">
<div class="q-header">{{ q.label }}</div>
<div class="q-body">
{% for issue in q.issues %}
<div class="issue">
<div class="headline">{{ issue.headline }}</div>
<ul class="bullets">
{% for b in issue.bullets %}<li>{{ b }}</li>{% endfor %}
</ul>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
{% if center_quote %}
<div class="center-quote">
{% if center_quote.image %}<img src="{{ center_quote.image }}" alt="">{% endif %}
<div class="text">{{ center_quote.text }}</div>
</div>
{% endif %}
</div>
</body>
</html>

View File

@@ -0,0 +1,71 @@
pattern_id: quadrant-2x2-issues
category: emphasis
version: 0.1.0
provenance:
source_frame: "45:18 / Frame 1171281193"
reference_html: ../block-tests/bim-issues-quadrant.html
reference_render: ../block-tests/_renders/bim-issues-quadrant.png
description: |
2×2 그리드 진단 패턴. 4개 카테고리 각각에 N개의 issue (red headline + bullet body).
중앙에 optional 인용구 원 (강조 메시지/명언). 문제 진단, SWOT, 4-quadrant 분석에 적합.
when:
relation_type:
- 4-quadrant-diagnosis
- issue-categorization
- swot
- 2x2-comparison
content_shape:
quadrants: { exact: 4 }
issues_per_quadrant: { min: 1, max: 5 }
not_for:
- linear-process
- single-statement
slots:
quadrants:
type: list
required: true
min: 4
max: 4
item:
label: { type: string, required: true }
issues:
type: list
required: true
min: 1
max: 5
item:
headline: { type: string, required: true }
bullets: { type: list, items: string, min: 1 }
center_quote:
type: object
required: false
properties:
text: { type: string, required: true }
image: { type: image, required: false }
card_bg_image: { type: image, required: false }
headline_color: { type: color, default: "#ff0000" }
body_color: { type: color, default: "#ffffff" }
header_bg: { type: gradient_string, default: "linear-gradient(90deg, #4a4028 0%, #285b4a 100%)" }
header_text_color: { type: color, default: "#ffffff" }
tokens:
block_w: { default: 1280 }
row_gap: { default: "0.6rem" }
min_size_px: { width: 800, height: 600 }
max_size_px: { width: 1920, height: 1500 }
sub_patterns: []
priority: 50
diff_from_reference:
- "absolute pixel positions → CSS grid 2×2"
- "4 quadrants는 fixed (2x2 패턴 정의)"
- "issues[N] 개수 자유"
- "center quote optional"

View File

@@ -0,0 +1,71 @@
"""
Jinja2 템플릿 렌더러 — templates_staging/ 검증용.
사용법:
python render.py {pattern_id} {example_suffix}
예:
python render.py cards-3col-persona example
→ templates_staging/cards-3col-persona.example.yaml 데이터로
templates_staging/cards-3col-persona.html.j2 템플릿 렌더
→ 결과: templates_staging/_renders/cards-3col-persona.example.html
python render.py cards-3col-persona example-no-photos
→ 사진 없는 케이스 검증
작업 디렉토리: figma_to_html_agent/templates_staging/
"""
import os
import sys
from pathlib import Path
try:
import yaml
except ImportError:
print("yaml 미설치. pip install pyyaml")
sys.exit(1)
try:
from jinja2 import Template
except ImportError:
print("jinja2 미설치. pip install jinja2")
sys.exit(1)
def render(pattern_id: str, example_suffix: str = "example") -> str:
base = Path(__file__).parent
template_path = base / f"{pattern_id}.html.j2"
data_path = base / f"{pattern_id}.{example_suffix}.yaml"
output_dir = base / "_renders"
output_dir.mkdir(exist_ok=True)
output_path = output_dir / f"{pattern_id}.{example_suffix}.html"
if not template_path.exists():
raise FileNotFoundError(f"템플릿 없음: {template_path}")
if not data_path.exists():
raise FileNotFoundError(f"데이터 없음: {data_path}")
with open(template_path, "r", encoding="utf-8") as f:
template = Template(f.read())
with open(data_path, "r", encoding="utf-8") as f:
data = yaml.safe_load(f)
html = template.render(**data)
with open(output_path, "w", encoding="utf-8") as f:
f.write(html)
print(f"✓ 렌더 완료: {output_path}")
return str(output_path)
if __name__ == "__main__":
if len(sys.argv) < 2:
print(__doc__)
sys.exit(1)
pattern_id = sys.argv[1]
suffix = sys.argv[2] if len(sys.argv) > 2 else "example"
render(pattern_id, suffix)

View File

@@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>{{ title|default("split-panel-numbered") }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700;900&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: {{ block_w|default(1280) }}px;
--left-w: {{ left_w|default("55%") }};
--right-w: {{ right_w|default("45%") }};
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh; padding: 20px;
word-break: keep-all;
}
.block {
width: var(--block-w);
background: #fff;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
padding: 1.2rem 1.5rem;
}
.header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.8rem; }
.header-icon { width: 1.5rem; height: 1.5rem; flex: none; }
.header-icon img { width: 100%; height: 100%; }
.header-title { font-weight: 900; font-size: 1.5rem; }
.header-title .hl {
font-size: 2rem;
background-image: linear-gradient(180deg, #cc5200, #883700);
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.header-title .sub {
background-image: linear-gradient(180deg, #296b55, #000);
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.content { display: flex; gap: 0.8rem; }
.left-panel {
flex: none; width: var(--left-w);
position: relative; border-radius: 0.8rem; overflow: hidden;
min-height: 20rem;
}
.left-panel .bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.left-panel .categories { position: relative; z-index: 2; padding: 0.8rem; display: flex; flex-direction: column; gap: 0.5rem; }
.cat { }
.cat .cat-header {
font-weight: 700; font-size: 1.15rem; color: #fff;
padding: 0.3rem 0.6rem; border-radius: 0.3rem;
text-shadow: 0 0 4px rgba(0,0,0,0.5);
position: relative; overflow: hidden;
}
.cat .cat-header img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.cat .cat-header .text { position: relative; z-index: 1; }
.cat .sw-list {
font-weight: 500; font-size: 0.95rem; line-height: 1.6;
color: #000; padding: 0.3rem 0.5rem;
text-shadow: 0 0 3px rgba(0,0,0,0.3);
}
.right-panel { flex: 1; display: flex; flex-direction: column; gap: 0.5rem; }
.numbered-item {
display: flex; align-items: center; gap: 0.6rem;
position: relative; padding: 0.5rem 0.8rem;
border-radius: 0.4rem; overflow: hidden;
}
.numbered-item .bar-bg {
position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0;
}
.numbered-item .badge { flex: none; width: 2.5rem; height: 2.6rem; position: relative; z-index: 1; }
.numbered-item .badge img { width: 100%; height: 100%; }
.numbered-item .desc {
flex: 1; font-weight: 500; font-size: 1.15rem;
color: #11231d; position: relative; z-index: 1;
text-shadow: 0 0 3px rgba(0,0,0,0.3);
}
</style>
</head>
<body>
<div class="block">
{% if header %}
<div class="header">
{% if header.icon %}<div class="header-icon"><img src="{{ header.icon }}" alt=""></div>{% endif %}
<div class="header-title">{% for seg in header.segments -%}
{%- if seg.style == 'highlight' -%}<span class="hl">{{ seg.text }}</span>
{%- elif seg.style == 'sub' -%}<span class="sub">{{ seg.text }}</span>
{%- else -%}<span>{{ seg.text }}</span>{%- endif -%}
{%- endfor %}</div>
</div>
{% endif %}
<div class="content">
<div class="left-panel">
{% if left_bg %}<img class="bg" src="{{ left_bg }}" alt="">{% endif %}
<div class="categories">
{% for cat in left_categories %}
<div class="cat">
<div class="cat-header">
{% if cat.header_image %}<img src="{{ cat.header_image }}" alt="">{% endif %}
<span class="text">{{ cat.title }}</span>
</div>
<div class="sw-list">{{ cat.items|join('<br>')|safe }}</div>
</div>
{% endfor %}
</div>
</div>
<div class="right-panel">
{% for item in right_items %}
<div class="numbered-item">
{% if item.bar_bg %}<img class="bar-bg" src="{{ item.bar_bg }}" alt="">{% endif %}
{% if item.badge %}<div class="badge"><img src="{{ item.badge }}" alt=""></div>{% endif %}
<div class="desc">{{ item.text }}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,43 @@
pattern_id: split-panel-numbered
category: cards
version: 0.1.0
provenance:
source_frame: "45:27 / Frame 1171281202"
reference_html: ../block-tests/bim-sw-overview.html
description: |
좌: 카테고리별 리스트 (BG 이미지 + 헤더 bar + 항목 나열)
우: 번호 badge + 설명 텍스트 N개
중간 장식 (optional). 소프트웨어 개요, 도구 설명, 기능 분류 등에 적합.
when:
relation_type: [tool-overview, software-catalog, split-detail]
content_shape:
left_categories: { min: 2, max: 5 }
right_items: { min: 3, max: 8 }
slots:
header: { type: object, required: false }
left_bg: { type: image, required: false }
left_categories:
type: list
required: true
min: 2
max: 5
item:
title: string
header_image: { type: image, required: false }
items: { type: list, items: string }
right_items:
type: list
required: true
min: 3
max: 8
item:
badge: { type: image, required: false }
bar_bg: { type: image, required: false }
text: string
min_size_px: { width: 800, height: 400 }
sub_patterns: []
priority: 40

View File

@@ -0,0 +1,19 @@
title: "시공상세 정보물 (Frame 1171281180)"
title_segments:
- { text: "시공 전 모델 기반 " }
- { text: "시공상세 정보물", highlight: true }
- { text: " 이용한 시공계획 작성 지원" }
arrow_icon: "../../block-tests/assets/shared/29c778b566aca6778f505874f21670de129351f8.svg"
left_decoration:
arc: "../../block-tests/assets/shared/ff649c28fd98518d6b48b9e5451fe1da4c1e95d5.svg"
label: "시공<br>상세<br>정보물"
items:
- { text: "3차원 형상의 정보 모델과 Data Base (D/B)", color: "#fb5915" }
- { text: "목적물, 가시설 등의 단계별 시공 시뮬레이션", color: "#e79000" }
- { text: "시공 및 안전교육에 도움이 되는 영상물 등 성과물", color: "#e9a804" }
- { text: "모델 또는 D/B, 시뮬레이션으로 부터 추출한 도면", color: "#919f00" }
- { text: "모델에서 추출이 곤란한 안전, 유의사항, 개념도 등 상세 표현 도면", color: "#0d6361" }

View File

@@ -0,0 +1,120 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>{{ title|default("stacked-arrow-list") }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700;900&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: {{ block_w|default(1280) }}px;
--title-color: {{ title_color|default("#144838") }};
--title-bar-color: {{ title_bar_color|default("#fbd5b9") }};
--highlight-from: {{ highlight_from|default("#cc5200") }};
--highlight-to: {{ highlight_to|default("#cc5200") }};
--item-bg: {{ item_bg|default("rgba(255,255,255,0.5)") }};
--item-font-size: {{ item_font_size|default("1.25rem") }};
--item-radius: {{ item_radius|default("1.5rem") }};
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh; padding: 20px;
word-break: keep-all;
}
.block {
width: var(--block-w);
background: #fff;
box-shadow: 0 4px 20px rgba(0,0,0,.15);
padding: 1.5rem 2rem 2rem;
position: relative;
}
.title-wrap { position: relative; margin-bottom: 1.2rem; text-align: center; }
.title-bar {
position: absolute; left: 0; right: 0;
top: 55%; height: 0.8rem;
background: var(--title-bar-color);
border-radius: 0.3rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.15);
z-index: 0;
}
.title-text {
position: relative; z-index: 1;
font-weight: 700; font-size: 1.5rem;
color: var(--title-color);
letter-spacing: -0.05em;
white-space: nowrap;
}
.title-text .hl {
font-weight: 900; font-size: 1.7rem;
background-image: linear-gradient(90deg, var(--highlight-from), var(--highlight-to));
-webkit-background-clip: text; background-clip: text;
color: transparent;
}
.content { display: flex; gap: 1rem; }
.left-deco {
flex: none; width: 8%;
display: flex; flex-direction: column;
align-items: center; justify-content: center;
position: relative;
}
.left-deco .arc { width: 100%; }
.left-deco .arc img { width: 100%; height: auto; }
.left-deco .label {
font-weight: 700; font-size: 1.4rem;
color: var(--title-color);
text-align: center;
line-height: 1.5;
text-shadow: 0 2px 4px rgba(0,0,0,0.15);
}
.items { flex: 1; display: flex; flex-direction: column; gap: 0.6rem; }
.item {
background: var(--item-bg);
border-radius: var(--item-radius);
box-shadow: 2px 4px 5px rgba(0,0,0,0.3);
border-bottom-width: 3px;
border-bottom-style: solid;
display: flex; align-items: center;
gap: 0.6rem;
padding: 0.6rem 1rem;
}
.item .arrow { flex: none; width: 0.9rem; height: 1.2rem; transform: rotate(-90deg); }
.item .arrow img { width: 100%; height: 100%; }
.item .text {
font-weight: 500; font-size: var(--item-font-size);
color: #000; letter-spacing: -0.03em;
white-space: nowrap;
}
</style>
</head>
<body>
<div class="block">
<div class="title-wrap">
<div class="title-bar"></div>
<div class="title-text">{% for seg in title_segments -%}
{%- if seg.highlight -%}<span class="hl">{{ seg.text }}</span>{%- else -%}<span>{{ seg.text }}</span>{%- endif -%}
{%- endfor %}</div>
</div>
<div class="content">
{% if left_decoration %}
<div class="left-deco">
<div class="arc"><img src="{{ left_decoration.arc }}" alt=""></div>
{% if left_decoration.label %}
<div class="label">{{ left_decoration.label|safe }}</div>
{% endif %}
</div>
{% endif %}
<div class="items">
{% for item in items %}
<div class="item" style="border-bottom-color: {{ item.color }};">
{% if arrow_icon %}<div class="arrow"><img src="{{ arrow_icon }}" alt=""></div>{% endif %}
<div class="text">{{ item.text }}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,32 @@
pattern_id: stacked-arrow-list
category: cards
version: 0.1.0
provenance:
source_frame: "45:5 / Frame 1171281180"
reference_html: ../block-tests/bim-info-products.html
description: |
N개의 항목이 세로로 쌓인 리스트. 각 항목은 rounded pill + 색상 border-bottom + 화살표 마커.
좌측 optional arc 장식 + 세로 라벨. 항목별 색상이 다른 계단식 시각 리스트.
when:
relation_type: [enumerated-list, tiered-items, stepped-breakdown]
content_shape:
items: { min: 3, max: 8 }
slots:
title_segments: { type: list, item: { text: string, highlight: boolean }, required: true }
arrow_icon: { type: image, required: false }
left_decoration: { type: object, required: false, properties: { arc: image, label: html_string } }
items:
type: list
required: true
min: 3
max: 8
item:
text: { type: string, required: true }
color: { type: color, required: true, description: "border-bottom 색" }
min_size_px: { width: 640, height: 300 }
sub_patterns: []
priority: 40

View File

@@ -0,0 +1,14 @@
# Example: Frame 1171281207 (BIM future statement)
title: "BIM 미래 선언 메시지 (Frame 1171281207) — 템플릿 검증"
bg_image: "../../block-tests/assets/shared/527bd7809f4b2e5f3cd42f2e713ccbfb37537d82.png"
text_segments:
- text: "수행과정 연속화와 관리체계 일원화된 형태의 "
- text: "전용ㆍ전문 S/W 개발"
highlight: true
- text: " 없이는 미래가 없다."
block_w: 1280
block_h: 60
font_size: "1.7rem"

View File

@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>{{ title|default("statement-pill-highlight") }}</title>
<!--
Pattern: statement-pill-highlight
Origin: 51:170 / Frame 1171281207
Single-line statement banner with optional inline highlighted segments.
pill 모양 (border-radius = height/2) + 배경 이미지(또는 단색) + 텍스트 + highlight 색
-->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--block-w: {{ block_w|default(1280) }}px;
--block-h: {{ block_h|default(60) }}px;
--slide-h: {{ slide_h|default(720) }}px;
--font-size: {{ font_size|default("1.6rem") }};
--font-weight: {{ font_weight|default(700) }};
--text-color: {{ text_color|default("#ffffff") }};
--highlight-color: {{ highlight_color|default("#fe3") }};
--bg-color: {{ bg_color|default("#3a4a2f") }};
--text-shadow-color: {{ text_shadow_color|default("rgba(0,0,0,0.5)") }};
--text-shadow-blur: {{ text_shadow_blur|default("4px") }};
--inner-padding-x: {{ inner_padding_x|default("3.5%") }};
}
body {
font-family: 'Noto Sans KR', sans-serif;
background: #e8ecf0;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
padding: 20px;
}
.slide {
width: var(--block-w);
height: var(--slide-h);
background: #ffffff;
position: relative;
display: flex; justify-content: center; align-items: center;
box-shadow: 0 4px 20px rgba(0, 0, 0, .15);
}
.banner-pill {
width: var(--block-w);
height: var(--block-h);
border-radius: calc(var(--block-h) / 2); /* 완전 캡슐 */
background: var(--bg-color);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
padding: 0 var(--inner-padding-x);
}
{% if bg_image %}
.banner-pill .bg {
position: absolute;
inset: 0;
width: 100%; height: 100%;
object-fit: cover;
}
{% endif %}
.banner-pill .text {
position: relative;
z-index: 2;
font-weight: var(--font-weight);
font-size: var(--font-size);
color: var(--text-color);
letter-spacing: -0.01em;
text-shadow: 0 0 var(--text-shadow-blur) var(--text-shadow-color);
white-space: nowrap;
text-align: center;
}
.banner-pill .highlight {
color: var(--highlight-color);
}
</style>
</head>
<body>
<div class="slide">
<div class="banner-pill">
{% if bg_image %}<img class="bg" src="{{ bg_image }}" alt="">{% endif %}
<div class="text">{% for seg in text_segments -%}
{%- if seg.highlight -%}
<span class="highlight">{{ seg.text }}</span>
{%- else -%}
<span>{{ seg.text }}</span>
{%- endif -%}
{%- endfor %}</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,64 @@
pattern_id: statement-pill-highlight
category: emphasis
version: 0.1.0
provenance:
source_frame: "51:170 / Frame 1171281207"
reference_html: ../block-tests/bim-future-statement.html
reference_render: ../block-tests/_renders/bim-future-statement.png
description: |
단일 line 메시지 banner. pill 모양 (border-radius = height/2). 인라인 highlight span 지원.
강조 메시지, 결론, 명언, 슬로건에 적합.
when:
relation_type:
- emphasis-statement
- conclusion-message
- slogan
- quote-emphasis
content_shape:
text_length: { min: 5, max: 80 chars }
has_highlight: optional
not_for:
- multi-line-content
- list
- structured-data
slots:
text_segments:
type: list
required: true
min: 1
item:
text: { type: string, required: true }
highlight: { type: boolean, default: false }
bg_image: { type: image, required: false, description: "배경 PNG (없으면 bg_color 단색)" }
bg_color: { type: color, default: "#3a4a2f" }
text_color: { type: color, default: "#ffffff" }
highlight_color: { type: color, default: "#fe3" }
text_shadow_color: { type: color, default: "rgba(0,0,0,0.5)" }
text_shadow_blur: { type: string, default: "4px" }
font_size: { type: string, default: "1.6rem" }
font_weight: { type: number, default: 700 }
tokens:
block_w: { default: 1280, unit: px }
block_h: { default: 60, unit: px }
slide_h: { default: 720, unit: px }
min_size_px:
width: 480
height: 40
max_size_px:
width: 1920
height: 120
sub_patterns: []
priority: 30
diff_from_reference:
- "bg_image optional → bg_color fallback"
- "text_segments list → 임의 개수의 highlight span 지원"
- "font/색상/그림자 모두 CSS 변수"