Kei API 연동 복구 + 실장 정보구조 분석 + 팀장 role 기반 배치

1단계 (실장):
  - Kei API 연동 복구 (타임아웃 무제한, Kei persona 사고)
  - 정보 구조 파악 단계 추가 (본문 흐름 vs 참조 분리)
  - 각 꼭지에 role(flow/reference) 부여
  - fallback: Anthropic 직접 호출 (info_structure + role 포함)

2단계 (팀장):
  - info_structure + role 기반 배치 규칙 추가
  - flow → 좌측/메인, reference → 우측/사이드
  - detail_target → 본문 제외
  - 중복 방지 규칙

파이프라인:
  - pipeline.py import re 추가

Figma 관련 (다른 Claude Code 작업분):
  - catalog.yaml, figma-screenshots, figma-analysis, 테스트 HTML

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 11:33:17 +09:00
parent 33bd3a56c6
commit 7b034b04b6
24 changed files with 2400 additions and 90 deletions

BIN
docs/bg-texture-only.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 KiB

View File

@@ -0,0 +1 @@
{"status":429,"err":"Rate limit exceeded"}

View File

@@ -0,0 +1 @@
{"status":429,"err":"Rate limit exceeded"}

View File

@@ -0,0 +1 @@
{"status":429,"err":"Rate limit exceeded"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

BIN
docs/test-bg-layer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -0,0 +1,206 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>DX와 BIM의 개념적 구분과 재정립</title>
<style>
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Pretendard Variable', sans-serif; }
.slide {
width: 1280px;
height: 720px;
position: relative;
overflow: hidden;
}
/* Layer 1: 배경 이미지 */
.bg-layer {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: 1;
}
.bg-layer img {
width: 100%; height: 100%;
object-fit: cover;
}
/* Layer 2: 슬라이드 제목 */
.title-layer {
position: absolute;
top: 15px; left: 30px;
z-index: 10;
font-size: 1.6rem;
font-weight: 900;
color: #1e293b;
border-bottom: 3px solid #2563eb;
padding-bottom: 6px;
}
/* Layer 3: 상단 5개 원 위 아이콘 + 텍스트 */
.circle-labels {
position: absolute;
z-index: 10;
text-align: center;
}
.circle-labels .icon {
font-size: 1.8rem;
margin-bottom: 2px;
}
.circle-labels .label {
font-size: 0.95rem;
font-weight: 800;
color: #1e293b;
line-height: 1.3;
}
.circle-labels .desc {
font-size: 0.7rem;
color: #64748b;
line-height: 1.4;
margin-top: 2px;
}
.circle-labels .highlight {
color: #2563eb;
font-weight: 700;
}
/* 각 원 위치 (배경 이미지의 원 위치에 맞춤) */
.circle-1 { top: 175px; left: 52px; width: 120px; }
.circle-2 { top: 95px; left: 245px; width: 120px; }
.circle-3 { top: 50px; left: 460px; width: 120px; }
.circle-4 { top: 95px; left: 680px; width: 120px; }
.circle-5 { top: 175px; left: 870px; width: 140px; }
/* Layer 4: 중앙 큰 원 텍스트 */
.center-label {
position: absolute;
top: 410px; left: 440px;
width: 200px;
z-index: 10;
text-align: center;
}
.center-label .main {
font-size: 1.3rem;
font-weight: 900;
color: #1e293b;
line-height: 1.4;
}
.center-label .sub {
font-size: 0.75rem;
color: #64748b;
margin-top: 4px;
}
/* Layer 5: 좌우 하단 박스 텍스트 */
.bottom-box {
position: absolute;
bottom: 35px;
z-index: 10;
padding: 8px 20px;
text-align: center;
}
.bottom-left {
left: 30px;
width: 260px;
}
.bottom-right {
right: 30px;
width: 260px;
}
.bottom-box .box-title {
font-size: 0.7rem;
color: #64748b;
margin-bottom: 2px;
}
.bottom-box .box-content {
font-size: 0.85rem;
font-weight: 700;
color: #1e293b;
line-height: 1.4;
}
/* Layer 6: 하단 결론 바 */
.conclusion-bar {
position: absolute;
bottom: 0; left: 0; right: 0;
z-index: 10;
background: #1e293b;
color: white;
text-align: center;
padding: 10px 40px;
font-size: 1rem;
font-weight: 700;
letter-spacing: -0.3px;
}
</style>
</head>
<body>
<div class="slide">
<!-- Layer 1: AI 생성 배경 이미지 -->
<div class="bg-layer">
<img src="test-bg-layer.png" alt="background">
</div>
<!-- Layer 2: 슬라이드 제목 -->
<div class="title-layer">DX와 BIM의 개념적 구분과 재정립</div>
<!-- Layer 3: 상단 5개 원 위 텍스트 -->
<div class="circle-labels circle-1">
<div class="icon">📋</div>
<div class="label">용어 혼용</div>
<div class="desc">DX와 BIM 개념이<br>명확히 <span class="highlight">정립되지 않은 채</span><br>혼용되어 사용</div>
</div>
<div class="circle-labels circle-2">
<div class="icon">🏛️</div>
<div class="label">정책 사례</div>
<div class="desc">건설기술진흥 기본계획<br><span class="highlight">BIM 도입 = 디지털화</span><br>로 표현</div>
</div>
<div class="circle-labels circle-3">
<div class="icon">📐</div>
<div class="label">BIM</div>
<div class="desc">3D 모델 기반<br><span class="highlight">정보 통합·관리</span> 도구<br>핵심 인프라 기술</div>
</div>
<div class="circle-labels circle-4">
<div class="icon">🔄</div>
<div class="label">DX</div>
<div class="desc">디지털 기술 기반<br><span class="highlight">산업 패러다임 전환</span><br>업무방식·가치 구조 변혁</div>
</div>
<div class="circle-labels circle-5">
<div class="icon">🔗</div>
<div class="label">기술 융합</div>
<div class="desc"><span class="highlight">GIS + BIM + DT</span><br>기술 융합으로만<br>DX 실현 가능</div>
</div>
<!-- Layer 4: 중앙 큰 원 텍스트 -->
<div class="center-label">
<div class="main">DX와 BIM의<br>관계</div>
<div class="sub">개념적 구분과 재정립</div>
</div>
<!-- Layer 5: 좌우 하단 박스 -->
<div class="bottom-box bottom-left">
<div class="box-title">상위 개념</div>
<div class="box-content">산업 패러다임 전환<br>프로세스 혁신</div>
</div>
<div class="bottom-box bottom-right">
<div class="box-title">핵심 기초 기술</div>
<div class="box-content">건설정보 통합 관리<br>디지털 협업 인프라</div>
</div>
<!-- Layer 6: 결론 바 -->
<div class="conclusion-bar">
BIM은 건설산업의 디지털전환(DX)을 수행하는 과정에서 가장 기초가 되는 일부분이다
</div>
</div>
</body>
</html>

222
docs/test-layered-v2.html Normal file
View File

@@ -0,0 +1,222 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>DX와 BIM의 개념적 구분과 재정립</title>
<style>
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Pretendard Variable', sans-serif; background: #f0f4f8; display: flex; justify-content: center; padding: 20px; }
.slide {
width: 1280px;
height: 720px;
position: relative;
overflow: hidden;
}
/* ═══ Layer 1: 배경 텍스처 ═══ */
.bg { position: absolute; inset: 0; z-index: 1; }
.bg img { width: 100%; height: 100%; object-fit: cover; }
/* ═══ Layer 2: 연결선 (SVG) ═══ */
.lines-layer {
position: absolute; inset: 0; z-index: 2;
}
/* ═══ Layer 3: 원 (각각 개별) ═══ */
.node {
position: absolute; z-index: 5;
display: flex; flex-direction: column; align-items: center;
}
.node-circle {
width: 90px; height: 90px;
border-radius: 50%;
background: white;
border: 3px solid #d0dce8;
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
display: flex; align-items: center; justify-content: center;
font-size: 2rem;
}
.node-label {
margin-top: 8px; text-align: center;
}
.node-label .title {
font-size: 1rem; font-weight: 800; color: #1e293b;
}
.node-label .desc {
font-size: 0.72rem; color: #64748b; line-height: 1.5; margin-top: 3px;
}
.node-label .highlight {
color: #2563eb; font-weight: 700;
}
/* 중앙 큰 원 */
.center-node {
position: absolute; z-index: 5;
left: 530px; top: 390px;
display: flex; flex-direction: column; align-items: center;
}
.center-circle {
width: 160px; height: 160px;
border-radius: 50%;
background: linear-gradient(180deg, #ffffff 0%, #e8f4fd 100%);
border: 4px solid #2563eb;
box-shadow: 0 0 40px rgba(37, 99, 235, 0.3), 0 0 80px rgba(37, 99, 235, 0.1);
display: flex; flex-direction: column;
align-items: center; justify-content: center;
}
.center-circle .main-text {
font-size: 1.2rem; font-weight: 900; color: #1e293b; text-align: center; line-height: 1.4;
}
.center-circle .sub-text {
font-size: 0.7rem; color: #64748b; margin-top: 4px;
}
/* ═══ Layer 4: 제목 ═══ */
.slide-title {
position: absolute; top: 18px; left: 30px; z-index: 10;
font-size: 1.5rem; font-weight: 900; color: #1e293b;
border-bottom: 3px solid #2563eb; padding-bottom: 6px;
}
/* ═══ Layer 5: 하단 좌우 박스 ═══ */
.bottom-box {
position: absolute; z-index: 10; bottom: 45px;
background: rgba(255,255,255,0.85);
border: 1px solid #d0dce8;
border-radius: 25px;
padding: 10px 24px;
text-align: center;
}
.bottom-left { left: 40px; }
.bottom-right { right: 40px; }
.bottom-box .box-label {
font-size: 0.65rem; color: #94a3b8; font-weight: 500;
}
.bottom-box .box-text {
font-size: 0.9rem; font-weight: 700; color: #1e293b; line-height: 1.5;
}
.bottom-box .arrow {
font-size: 1.2rem; color: #2563eb; font-weight: 900;
}
.bottom-left-wrap, .bottom-right-wrap {
display: flex; align-items: center; gap: 12px;
}
/* ═══ Layer 6: 결론 바 ═══ */
.conclusion {
position: absolute; bottom: 0; left: 0; right: 0; z-index: 10;
background: #1e293b;
color: white; text-align: center;
padding: 10px 40px;
font-size: 0.95rem; font-weight: 700;
}
/* ═══ 5개 노드 위치 ═══ */
.node-1 { left: 50px; top: 170px; width: 130px; }
.node-2 { left: 250px; top: 80px; width: 140px; }
.node-3 { left: 510px; top: 40px; width: 130px; }
.node-4 { left: 770px; top: 80px; width: 150px; }
.node-5 { left: 1000px; top: 170px; width: 140px; }
</style>
</head>
<body>
<div class="slide">
<!-- Layer 1: 배경 텍스처만 -->
<div class="bg">
<img src="bg-texture-only.png" alt="">
</div>
<!-- Layer 2: 연결선 SVG -->
<svg class="lines-layer" viewBox="0 0 1280 720" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- 5개 원에서 중앙 원으로 곡선 -->
<path d="M 115,260 Q 300,400 610,470" stroke="#b0c4de" stroke-width="1.5" fill="none" opacity="0.5"/>
<path d="M 320,170 Q 420,350 610,470" stroke="#b0c4de" stroke-width="1.5" fill="none" opacity="0.5"/>
<path d="M 575,130 Q 590,300 610,470" stroke="#b0c4de" stroke-width="1.5" fill="none" opacity="0.5"/>
<path d="M 845,170 Q 750,350 610,470" stroke="#b0c4de" stroke-width="1.5" fill="none" opacity="0.5"/>
<path d="M 1070,260 Q 850,400 610,470" stroke="#b0c4de" stroke-width="1.5" fill="none" opacity="0.5"/>
</svg>
<!-- Layer 3: 슬라이드 제목 -->
<div class="slide-title">DX와 BIM의 개념적 구분과 재정립</div>
<!-- Layer 4: 상단 5개 노드 (각각 원 + 아이콘 + 텍스트) -->
<div class="node node-1">
<div class="node-circle">📋</div>
<div class="node-label">
<div class="title">용어 혼용</div>
<div class="desc">DX와 BIM 개념이<br><span class="highlight">정립되지 않은 채</span><br>혼용되어 사용</div>
</div>
</div>
<div class="node node-2">
<div class="node-circle">🏛️</div>
<div class="node-label">
<div class="title">정책 사례</div>
<div class="desc">건설기술진흥 기본계획<br><span class="highlight">BIM 도입 = 디지털화</span></div>
</div>
</div>
<div class="node node-3">
<div class="node-circle">📐</div>
<div class="node-label">
<div class="title">BIM</div>
<div class="desc">3D 모델 기반<br><span class="highlight">정보 통합·관리</span> 도구</div>
</div>
</div>
<div class="node node-4">
<div class="node-circle">🔄</div>
<div class="node-label">
<div class="title">DX</div>
<div class="desc">디지털 기술 기반<br><span class="highlight">산업 패러다임 전환</span><br>업무방식·가치 구조 변혁</div>
</div>
</div>
<div class="node node-5">
<div class="node-circle">🔗</div>
<div class="node-label">
<div class="title">기술 융합</div>
<div class="desc"><span class="highlight">GIS + BIM + DT</span><br>기술 융합으로만<br>DX 실현 가능</div>
</div>
</div>
<!-- Layer 5: 중앙 큰 원 -->
<div class="center-node">
<div class="center-circle">
<div class="main-text">DX와 BIM의<br>관계</div>
<div class="sub-text">개념적 구분과 재정립</div>
</div>
</div>
<!-- Layer 6: 하단 좌우 박스 -->
<div class="bottom-box bottom-left">
<div class="bottom-left-wrap">
<span class="arrow"></span>
<div>
<div class="box-label">상위 개념</div>
<div class="box-text">산업 패러다임 전환<br>프로세스 혁신</div>
</div>
</div>
</div>
<div class="bottom-box bottom-right">
<div class="bottom-right-wrap">
<div>
<div class="box-label">핵심 기초 기술</div>
<div class="box-text">건설정보 통합 관리<br>디지털 협업 인프라</div>
</div>
<span class="arrow"></span>
</div>
</div>
<!-- Layer 7: 결론 바 -->
<div class="conclusion">
BIM은 건설산업의 디지털전환(DX)을 수행하는 과정에서 가장 기초가 되는 일부분이다
</div>
</div>
</body>
</html>

4
docs/test-relation.html Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Regular/result.css" type="text/css"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Bold/result.css" type="text/css"?>
<svg height="445" width="434.5" style="" font-family="Alibaba PuHuiTi" xmlns="http://www.w3.org/2000/svg" viewBox="-20 -20 434.5 445"><defs /><defs><radialGradient id="#1783ff-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#b0d5ff" /><stop offset="100%" stop-color="#1783ff" /></radialGradient><linearGradient id="#ff6b6b-badge" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#ff6b6b" /><stop offset="100%" stop-color="#ee5a52" /></linearGradient><radialGradient id="#00c9c9-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#63ffff" /><stop offset="100%" stop-color="#00c9c9" /></radialGradient><radialGradient id="#f0884d-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#fce6da" /><stop offset="100%" stop-color="#f0884d" /></radialGradient><radialGradient id="#d580ff-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#ffffff" /><stop offset="100%" stop-color="#d580ff" /></radialGradient></defs><g id="infographic-container"><g><g><g transform="translate(310.5, 150)"><ellipse x="0" y="0" width="80" height="80" fill="url(##1783ff-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">건설산업 DX</span></foreignObject></g></g><g transform="translate(160.5, 300)"><ellipse x="0" y="0" width="80" height="80" fill="url(##00c9c9-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">GIS</span></foreignObject></g></g><g transform="translate(10.5, 150.00000000000003)"><ellipse x="0" y="0" width="80" height="80" fill="url(##f0884d-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">BIM</span></foreignObject></g></g><g transform="translate(160.49999999999997, 0)"><ellipse x="0" y="0" width="80" height="80" fill="url(##d580ff-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">Digital Twin</span></foreignObject></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

4
docs/test-relation.svg Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Regular/result.css" type="text/css"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Bold/result.css" type="text/css"?>
<svg height="445" width="434.5" style="" font-family="Alibaba PuHuiTi" xmlns="http://www.w3.org/2000/svg" viewBox="-20 -20 434.5 445"><defs /><defs><radialGradient id="#1783ff-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#b0d5ff" /><stop offset="100%" stop-color="#1783ff" /></radialGradient><linearGradient id="#ff6b6b-badge" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" stop-color="#ff6b6b" /><stop offset="100%" stop-color="#ee5a52" /></linearGradient><radialGradient id="#00c9c9-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#63ffff" /><stop offset="100%" stop-color="#00c9c9" /></radialGradient><radialGradient id="#f0884d-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#fce6da" /><stop offset="100%" stop-color="#f0884d" /></radialGradient><radialGradient id="#d580ff-icon" cx="50%" cy="30%" r="70%"><stop offset="0%" stop-color="#ffffff" /><stop offset="100%" stop-color="#d580ff" /></radialGradient></defs><g id="infographic-container"><g><g><g transform="translate(310.5, 150)"><ellipse x="0" y="0" width="80" height="80" fill="url(##1783ff-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">건설산업 DX</span></foreignObject></g></g><g transform="translate(160.5, 300)"><ellipse x="0" y="0" width="80" height="80" fill="url(##00c9c9-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">GIS</span></foreignObject></g></g><g transform="translate(10.5, 150.00000000000003)"><ellipse x="0" y="0" width="80" height="80" fill="url(##f0884d-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">BIM</span></foreignObject></g></g><g transform="translate(160.49999999999997, 0)"><ellipse x="0" y="0" width="80" height="80" fill="url(##d580ff-icon)" cx="40" cy="40" rx="40" ry="40" /><ellipse x="60" width="24" height="24" fill="url(##ff6b6b-badge)" cx="72" cy="12" rx="12" ry="12" /><g transform="translate(60, 0)"><text width="24" height="24" x="12" y="12" fill="#ffffff" font-size="10" text-anchor="middle" dominant-baseline="central" font-weight="bold" /></g><g transform="translate(0, 88)"><foreignObject height="17" width="80" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:12px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">Digital Twin</span></foreignObject></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

4
docs/test-simple.html Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Regular/result.css" type="text/css"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Bold/result.css" type="text/css"?>
<svg height="210" width="460" style="" font-family="Alibaba PuHuiTi" xmlns="http://www.w3.org/2000/svg" viewBox="-20 -20 460 210"><defs /><g id="infographic-container"><g><g><g><g><g><foreignObject height="40" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#5a5a5a;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Start</span></foreignObject></g><g transform="translate(0, 40)"><foreignObject height="20" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Step 1</span></foreignObject></g><g transform="translate(0, 70)"><polygon width="140" height="30" fill="#1783ff" points="0,0 130,0 140,15 130,30 0,30 10,15" /><g><text width="140" height="30" x="70" y="15" fill="#ffffff" font-size="16" text-anchor="middle" dominant-baseline="central" font-weight="bold">01</text></g></g></g></g><g transform="translate(140, 0)"><g><g transform="translate(0, 70)"><polygon width="140" height="30" fill="#00c9c9" points="0,0 130,0 140,15 130,30 0,30 10,15" /><g><text width="140" height="30" x="70" y="15" fill="#ffffff" font-size="16" text-anchor="middle" dominant-baseline="central" font-weight="bold">02</text></g></g><g transform="translate(0, 110)"><foreignObject height="20" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">Step 2</span></foreignObject></g><g transform="translate(0, 130)"><foreignObject height="40" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#5a5a5a;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">Progress</span></foreignObject></g></g></g><g transform="translate(280, 0)"><g><g><foreignObject height="40" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#5a5a5a;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Complete</span></foreignObject></g><g transform="translate(0, 40)"><foreignObject height="20" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Step 3</span></foreignObject></g><g transform="translate(0, 70)"><polygon width="140" height="30" fill="#f0884d" points="0,0 130,0 140,15 130,30 0,30 10,15" /><g><text width="140" height="30" x="70" y="15" fill="#ffffff" font-size="16" text-anchor="middle" dominant-baseline="central" font-weight="bold">03</text></g></g></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

4
docs/test-simple.svg Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Regular/result.css" type="text/css"?>
<?xml-stylesheet href="https://assets.antv.antgroup.com/AlibabaPuHuiTi-Bold/result.css" type="text/css"?>
<svg height="210" width="460" style="" font-family="Alibaba PuHuiTi" xmlns="http://www.w3.org/2000/svg" viewBox="-20 -20 460 210"><defs /><g id="infographic-container"><g><g><g><g><g><foreignObject height="40" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#5a5a5a;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Start</span></foreignObject></g><g transform="translate(0, 40)"><foreignObject height="20" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Step 1</span></foreignObject></g><g transform="translate(0, 70)"><polygon width="140" height="30" fill="#1783ff" points="0,0 130,0 140,15 130,30 0,30 10,15" /><g><text width="140" height="30" x="70" y="15" fill="#ffffff" font-size="16" text-anchor="middle" dominant-baseline="central" font-weight="bold">01</text></g></g></g></g><g transform="translate(140, 0)"><g><g transform="translate(0, 70)"><polygon width="140" height="30" fill="#00c9c9" points="0,0 130,0 140,15 130,30 0,30 10,15" /><g><text width="140" height="30" x="70" y="15" fill="#ffffff" font-size="16" text-anchor="middle" dominant-baseline="central" font-weight="bold">02</text></g></g><g transform="translate(0, 110)"><foreignObject height="20" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">Step 2</span></foreignObject></g><g transform="translate(0, 130)"><foreignObject height="40" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#5a5a5a;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-start;align-items:flex-start" xmlns="http://www.w3.org/1999/xhtml">Progress</span></foreignObject></g></g></g><g transform="translate(280, 0)"><g><g><foreignObject height="40" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#5a5a5a;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Complete</span></foreignObject></g><g transform="translate(0, 40)"><foreignObject height="20" width="140" y="0" x="0" overflow="visible"><span style="overflow:visible;color:#262626;font-weight:bold;font-size:14px;line-height:1.4;width:100%;height:100%;display:flex;flex-wrap:wrap;word-break:break-word;white-space:pre-wrap;text-align:center;justify-content:center;align-content:flex-end;align-items:flex-end" xmlns="http://www.w3.org/1999/xhtml">Step 3</span></foreignObject></g><g transform="translate(0, 70)"><polygon width="140" height="30" fill="#f0884d" points="0,0 130,0 140,15 130,30 0,30 10,15" /><g><text width="140" height="30" x="70" y="15" fill="#ffffff" font-size="16" text-anchor="middle" dominant-baseline="central" font-weight="bold">03</text></g></g></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

402
docs/test-slide-output.html Normal file
View File

@@ -0,0 +1,402 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>DX와 BIM의 개념적 구분과 재정립</title>
<style>
/* Design Agent — 디자인 토큰 */
/* CLAUDE.md에 정의된 디자인 원칙을 CSS 변수로 구현 */
:root {
/* 색상 */
--color-primary: #1e293b;
--color-accent: #2563eb;
--color-neutral: #64748b;
--color-bg: #ffffff;
--color-bg-subtle: #f8fafc;
--color-border: #e2e8f0;
--color-danger: #dc2626;
--color-success: #16a34a;
--color-text: #1e293b;
--color-text-secondary: #64748b;
--color-text-light: #94a3b8;
/* 폰트 크기 */
--font-title: 2rem;
--font-subtitle: 1.25rem;
--font-body: 0.95rem;
--font-caption: 0.8rem;
--font-small: 0.7rem;
/* 폰트 두께 */
--weight-normal: 400;
--weight-medium: 500;
--weight-bold: 700;
--weight-black: 900;
/* 여백 */
--spacing-page: 40px;
--spacing-block: 20px;
--spacing-inner: 16px;
--spacing-small: 8px;
/* 기타 */
--radius: 6px;
--border-width: 1px;
--accent-border: 3px;
--line-height-ko: 1.7;
}
/* Design Agent — 기본 슬라이드 스타일 */
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 슬라이드 컨테이너: 16:9 고정 비율 */
.slide {
width: 1280px;
height: 720px;
aspect-ratio: 16 / 9;
overflow: hidden;
background: var(--color-bg);
font-family: 'Pretendard Variable', 'Pretendard', 'Noto Sans KR', sans-serif;
color: var(--color-text);
font-size: var(--font-body);
line-height: var(--line-height-ko);
word-break: keep-all;
padding: var(--spacing-page);
display: grid;
gap: var(--spacing-block);
}
/* 슬라이드 제목 */
.slide-title {
font-size: var(--font-title);
font-weight: var(--weight-black);
color: var(--color-primary);
border-bottom: var(--accent-border) solid var(--color-accent);
padding-bottom: var(--spacing-small);
}
/* 섹션 제목 */
.section-title {
font-size: var(--font-subtitle);
font-weight: var(--weight-bold);
color: var(--color-primary);
margin-bottom: var(--spacing-small);
}
/* 본문 */
.body-text {
font-size: var(--font-body);
color: var(--color-text);
line-height: var(--line-height-ko);
}
/* 캡션/출처 */
.caption {
font-size: var(--font-caption);
color: var(--color-text-light);
font-style: italic;
}
/* 강조 텍스트 */
.highlight {
color: var(--color-accent);
font-weight: var(--weight-bold);
}
/* 경고/문제 강조 */
.danger {
color: var(--color-danger);
font-weight: var(--weight-bold);
}
</style>
<style>
.slide-1 {
grid-template-areas: 'header header' 'left right' 'footer footer';
grid-template-columns: 6.5fr 3.5fr;
grid-template-rows: auto 1fr auto;
}
.slide-1 .area-header {
grid-area: header;
}
.slide-1 .area-left {
grid-area: left;
}
.slide-1 .area-right {
grid-area: right;
}
.slide-1 .area-footer {
grid-area: footer;
}
/* 다중 페이지: 페이지 간 간격 */
.slide + .slide {
margin-top: 40px;
}
/* 인쇄 시 페이지 분리 */
@media print {
.slide {
page-break-after: always;
}
.slide + .slide {
margin-top: 0;
}
}
</style>
</head>
<body>
<div class="slide slide-1">
<div class="slide-title" style="grid-area: header;">DX와 BIM의 개념적 구분과 재정립</div>
<div class="area-header">
<!-- 강조 인용 블록: 문제 제기, 핵심 메시지 -->
<div class="block-quote">
<div class="quote-text">건설산업의 디지털 전환 논의에서 DX와 BIM이 개념적으로 명확히 정립되지 않은 채 혼용되어 사용되고 있으며, BIM 기술의 도입을 DX의 완성으로 오인하거나 DX를 BIM 기술 도입 수준으로 한정하는 인식이 확산되고 있다.</div>
</div>
<style>
.block-quote {
background: var(--color-bg-subtle);
border-left: var(--accent-border) solid var(--color-danger);
padding: var(--spacing-inner) var(--spacing-block);
border-radius: 0 var(--radius) var(--radius) 0;
display: flex;
flex-direction: column;
justify-content: center;
}
.quote-text {
font-size: var(--font-body);
color: var(--color-text);
line-height: var(--line-height-ko);
font-weight: var(--weight-medium);
}
.quote-source {
font-size: var(--font-caption);
color: var(--color-text-light);
font-style: italic;
margin-top: var(--spacing-small);
}
</style>
</div>
<div class="area-left">
<!-- 카드 그리드 블록: 2~4열 카드 배열 -->
<div class="block-card-grid" style="--card-count: 2">
<div class="card" style="border-top-color: None">
<div class="card-title">제7차 건설기술진흥 기본계획</div>
<span class="card-category">국토교통부, 2023</span>
<div class="card-description">추진방향: 디지털 전환을 통한 스마트 건설 확산
추진과제: BIM 도입으로 건설산업 디지털화</div>
</div>
<div class="card" style="border-top-color: None">
<div class="card-title">스마트 건설 활성화 방안</div>
<span class="card-category">국토교통부, 2022</span>
<div class="card-description">추진과제: 건설산업 디지털화
세부내용: BIM 전면 도입 및 제도 정비, BIM 전문인력 양성</div>
</div>
</div>
<style>
.block-card-grid {
display: grid;
grid-template-columns: repeat(var(--card-count, 3), 1fr);
gap: var(--spacing-inner);
height: 100%;
}
.card {
background: var(--color-bg);
border: var(--border-width) solid var(--color-border);
border-top: var(--accent-border) solid var(--color-accent);
border-radius: var(--radius);
padding: var(--spacing-inner);
display: flex;
flex-direction: column;
}
.card-icon {
font-size: 1.5rem;
margin-bottom: var(--spacing-small);
}
.card-title {
font-size: var(--font-subtitle);
font-weight: var(--weight-bold);
color: var(--color-primary);
margin-bottom: 4px;
}
.card-category {
font-size: var(--font-small);
font-weight: var(--weight-medium);
color: var(--color-accent);
background: #dbeafe;
padding: 2px 8px;
border-radius: 12px;
display: inline-block;
margin-bottom: var(--spacing-small);
width: fit-content;
}
.card-description {
font-size: var(--font-body);
color: var(--color-text);
line-height: var(--line-height-ko);
flex: 1;
}
.card-source {
font-size: var(--font-small);
color: var(--color-text-light);
font-style: italic;
margin-top: var(--spacing-small);
border-top: var(--border-width) solid var(--color-border);
padding-top: var(--spacing-small);
}
</style>
</div>
<div class="area-right">
<!-- 카드 그리드 블록: 2~4열 카드 배열 -->
<div class="block-card-grid" style="--card-count: 3">
<div class="card" style="border-top-color: None">
<div class="card-title">BIM</div>
<span class="card-category">디지털 전환 핵심 기술</span>
<div class="card-description">시설물 생애주기 정보를 3D 모델 기반으로 통합·관리하는 인프라 기술</div>
<div class="card-source">건설산업 BIM 기본지침, 국토교통부, 2020</div>
</div>
<div class="card" style="border-top-color: None">
<div class="card-title">건설산업</div>
<span class="card-category">종합산업</span>
<div class="card-description">다양한 시설물을 광범위한 기술을 통합·융합하여 만들어내는 종합산업</div>
</div>
<div class="card" style="border-top-color: None">
<div class="card-title">DX</div>
<span class="card-category">산업 패러다임 변화</span>
<div class="card-description">디지털 기술 기반으로 업무방식과 가치 창출 구조를 전환하는 과정 및 결과</div>
<div class="card-source">IBM, 2011 / Agile Elephant, 2015</div>
</div>
</div>
<style>
.block-card-grid {
display: grid;
grid-template-columns: repeat(var(--card-count, 3), 1fr);
gap: var(--spacing-inner);
height: 100%;
}
.card {
background: var(--color-bg);
border: var(--border-width) solid var(--color-border);
border-top: var(--accent-border) solid var(--color-accent);
border-radius: var(--radius);
padding: var(--spacing-inner);
display: flex;
flex-direction: column;
}
.card-icon {
font-size: 1.5rem;
margin-bottom: var(--spacing-small);
}
.card-title {
font-size: var(--font-subtitle);
font-weight: var(--weight-bold);
color: var(--color-primary);
margin-bottom: 4px;
}
.card-category {
font-size: var(--font-small);
font-weight: var(--weight-medium);
color: var(--color-accent);
background: #dbeafe;
padding: 2px 8px;
border-radius: 12px;
display: inline-block;
margin-bottom: var(--spacing-small);
width: fit-content;
}
.card-description {
font-size: var(--font-body);
color: var(--color-text);
line-height: var(--line-height-ko);
flex: 1;
}
.card-source {
font-size: var(--font-small);
color: var(--color-text-light);
font-style: italic;
margin-top: var(--spacing-small);
border-top: var(--border-width) solid var(--color-border);
padding-top: var(--spacing-small);
}
</style>
</div>
<div class="area-footer">
<!-- 결론 바 블록: 하단 핵심 한 줄 -->
<div class="block-conclusion">
<div class="conclusion-label">핵심 요약</div>
<div class="conclusion-text">BIM은 건설산업의 디지털전환(DX)을 수행하는 과정에서 가장 기초가 되는 일부분이다</div>
</div>
<style>
.block-conclusion {
background: var(--color-primary);
color: white;
padding: var(--spacing-inner) var(--spacing-block);
border-radius: var(--radius);
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
gap: 4px;
}
.conclusion-label {
font-size: var(--font-caption);
color: var(--color-text-light);
font-weight: var(--weight-medium);
text-transform: uppercase;
letter-spacing: 1px;
}
.conclusion-text {
font-size: var(--font-subtitle);
font-weight: var(--weight-bold);
line-height: var(--line-height-ko);
}
</style>
</div>
</div>
</body>
</html>