From 7ac9eea21a69aef688e6c5efb11346c96754b411 Mon Sep 17 00:00:00 2001 From: kyeongmin Date: Wed, 25 Mar 2026 19:15:28 +0900 Subject: [PATCH] =?UTF-8?q?=EB=9F=B0=ED=83=80=EC=9E=84=20=ED=92=88?= =?UTF-8?q?=EC=A7=88=20=EA=B0=9C=EC=84=A0:=20Kei=20JSON=20=ED=8C=8C?= =?UTF-8?q?=EC=8B=B1=20+=20=EB=86=92=EC=9D=B4=20=EC=98=88=EC=82=B0=20?= =?UTF-8?q?=EA=B0=95=EC=A0=9C=20+=20conclusion=20=EA=B0=95=EC=A0=9C=20+=20?= =?UTF-8?q?FAISS=20=ED=94=84=EB=A6=AC=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. kei_client.py: Kei API가 마크다운 리스트(- ) 접두사로 JSON 응답 시 전처리하여 파싱 2. image_utils.py: base_path+상대경로 이중 시 파일명 rglob 재탐색 3. design_director.py: - conclusion 꼭지 → footer zone + conclusion-accent-bar 코드 레벨 강제 - _validate_height_budget(): zone별 height_cost 합산 검증, 초과 시 큰 블록 자동 교체 - Opus 추천 프롬프트에 zone 배정 규칙 명시 (conclusion→footer 등) 4. main.py: 서버 startup 시 FAISS 인덱스 + bge-m3 모델 미리 로드 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/content_editor.py | 8 - src/design_director.py | 138 +- src/main.py | 11 + templates/blocks/_legacy/card-grid.html | 65 - templates/blocks/_legacy/card-image.html | 95 -- templates/blocks/_legacy/circle-label.html | 56 - templates/blocks/_legacy/compare-box.html | 67 - .../blocks/_legacy/comparison-table.html | 97 -- templates/blocks/_legacy/comparison.html | 51 - templates/blocks/_legacy/conclusion-bar.html | 38 - templates/blocks/_legacy/image-row.html | 39 - templates/blocks/_legacy/process.html | 61 - templates/blocks/_legacy/quote-block.html | 29 - templates/blocks/_legacy/relationship.html | 88 -- templates/blocks/_legacy/section-title.html | 69 - templates/blocks/_legacy/topic-header.html | 38 - templates/blocks/cards/card-text-grid.html | 66 - .../emphasis/conclusion-accent-bar.html | 38 - templates/blocks/emphasis/details-block.html | 67 - .../blocks/emphasis/quote-left-border.html | 30 - templates/blocks/visuals/layer-diagram.html | 50 - .../blocks/visuals/pyramid-hierarchy.html | 40 - .../blocks/visuals/timeline-horizontal.html | 37 - .../blocks/visuals/timeline-vertical.html | 74 - templates/catalog.yaml | 1285 ++++++++--------- 25 files changed, 741 insertions(+), 1896 deletions(-) delete mode 100644 templates/blocks/_legacy/card-grid.html delete mode 100644 templates/blocks/_legacy/card-image.html delete mode 100644 templates/blocks/_legacy/circle-label.html delete mode 100644 templates/blocks/_legacy/compare-box.html delete mode 100644 templates/blocks/_legacy/comparison-table.html delete mode 100644 templates/blocks/_legacy/comparison.html delete mode 100644 templates/blocks/_legacy/conclusion-bar.html delete mode 100644 templates/blocks/_legacy/image-row.html delete mode 100644 templates/blocks/_legacy/process.html delete mode 100644 templates/blocks/_legacy/quote-block.html delete mode 100644 templates/blocks/_legacy/relationship.html delete mode 100644 templates/blocks/_legacy/section-title.html delete mode 100644 templates/blocks/_legacy/topic-header.html delete mode 100644 templates/blocks/cards/card-text-grid.html delete mode 100644 templates/blocks/emphasis/conclusion-accent-bar.html delete mode 100644 templates/blocks/emphasis/details-block.html delete mode 100644 templates/blocks/emphasis/quote-left-border.html delete mode 100644 templates/blocks/visuals/layer-diagram.html delete mode 100644 templates/blocks/visuals/pyramid-hierarchy.html delete mode 100644 templates/blocks/visuals/timeline-horizontal.html delete mode 100644 templates/blocks/visuals/timeline-vertical.html diff --git a/src/content_editor.py b/src/content_editor.py index 74561fc..8b78d35 100644 --- a/src/content_editor.py +++ b/src/content_editor.py @@ -244,7 +244,6 @@ def _apply_defaults(blocks: list[dict[str, Any]]) -> None: "topic-numbered": {"number": "1", "title": "(단계)"}, # cards/ "card-image-3col": {"cards": []}, - "card-text-grid": {"cards": []}, "card-dark-overlay": {"cards": []}, "card-tag-image": {"cards": []}, "card-icon-desc": {"cards": []}, @@ -264,15 +263,9 @@ def _apply_defaults(blocks: list[dict[str, Any]]) -> None: "process-horizontal": {"steps": []}, "flow-arrow-horizontal": {"steps": []}, "keyword-circle-row": {"keywords": []}, - "layer-diagram": {"layers": []}, - "timeline-vertical": {"events": []}, - "timeline-horizontal": {"events": []}, - "pyramid-hierarchy": {"levels": []}, # emphasis/ - "quote-left-border": {"quote_text": "(인용)"}, "quote-big-mark": {"quote_text": "(인용)"}, "quote-question": {"question": "(질문)"}, - "conclusion-accent-bar": {"conclusion_text": "(결론)"}, "comparison-2col": {"left_title": "A", "left_content": "-", "right_title": "B", "right_content": "-"}, "banner-gradient": {"text": "(배너)"}, "dark-bullet-list": {"bullets": []}, @@ -287,7 +280,6 @@ def _apply_defaults(blocks: list[dict[str, Any]]) -> None: "image-side-text": {"image_src": ""}, "image-full-caption": {"src": ""}, "image-before-after": {"before_src": "", "after_src": ""}, - "details-block": {"summary_text": "(상세 내용)", "detail_content": ""}, } for block in blocks: if "data" not in block: diff --git a/src/design_director.py b/src/design_director.py index 9f5485c..8556f2c 100644 --- a/src/design_director.py +++ b/src/design_director.py @@ -12,6 +12,7 @@ from pathlib import Path from typing import Any import anthropic +import yaml from src.config import settings @@ -29,7 +30,6 @@ BLOCK_SLOTS = { "topic-numbered": {"required": ["number", "title"], "optional": ["description", "color"]}, # cards/ (10개) "card-image-3col": {"required": ["cards"], "optional": []}, - "card-text-grid": {"required": ["cards"], "optional": []}, "card-dark-overlay": {"required": ["cards"], "optional": []}, "card-tag-image": {"required": ["cards"], "optional": []}, "card-icon-desc": {"required": ["cards"], "optional": []}, @@ -49,15 +49,9 @@ BLOCK_SLOTS = { "process-horizontal": {"required": ["steps"], "optional": []}, "flow-arrow-horizontal": {"required": ["steps"], "optional": []}, "keyword-circle-row": {"required": ["keywords"], "optional": []}, - "layer-diagram": {"required": ["layers"], "optional": ["title"]}, - "timeline-vertical": {"required": ["events"], "optional": []}, - "timeline-horizontal": {"required": ["events"], "optional": []}, - "pyramid-hierarchy": {"required": ["levels"], "optional": []}, # emphasis/ (12개) - "quote-left-border": {"required": ["quote_text"], "optional": ["source"]}, "quote-big-mark": {"required": ["quote_text"], "optional": ["source"]}, "quote-question": {"required": ["question"], "optional": ["description"]}, - "conclusion-accent-bar": {"required": ["conclusion_text"], "optional": ["label"]}, "comparison-2col": {"required": ["left_title", "left_content", "right_title", "right_content"], "optional": ["left_subtitle", "right_subtitle"]}, "banner-gradient": {"required": ["text"], "optional": ["sub_text"]}, "dark-bullet-list": {"required": ["bullets"], "optional": ["title"]}, @@ -66,7 +60,6 @@ BLOCK_SLOTS = { "callout-warning": {"required": ["title", "description"], "optional": ["icon"]}, "tab-label-row": {"required": ["tabs"], "optional": []}, "divider-text": {"required": ["text"], "optional": []}, - "details-block": {"required": ["summary_text", "detail_content"], "optional": ["label"]}, # media/ (5개) "image-row-2col": {"required": ["images"], "optional": []}, "image-grid-2x2": {"required": ["images"], "optional": []}, @@ -306,7 +299,13 @@ async def _opus_block_recommendation( prompt = ( f"슬라이드 디자인 블록 추천을 해줘.\n\n" f"## 프리셋: {preset_name}\n{preset['description']}\n\n" - f"## Zone 구조\n{zone_desc}\n\n" + f"## Zone 구조 (반드시 이 zone에 배정하라)\n{zone_desc}\n\n" + f"## Zone 배정 규칙 (절대 규칙)\n" + f"- flow 꼭지 → body / left / hero zone\n" + f"- reference 꼭지 → sidebar zone\n" + f"- conclusion 꼭지 → **반드시 footer zone** + block_type은 **conclusion-accent-bar**\n" + f"- detail_target 꼭지 → details-block\n" + f"- sidebar(35%)에는 시각화 블록 금지\n\n" f"## 꼭지 목록\n{topics_text}\n\n" f"## 블록 후보 (FAISS 검색 결과)\n{block_candidates}\n\n" f"## 요청\n" @@ -531,6 +530,28 @@ async def create_layout_concept( ) block["area"] = default_zone + # 6번: conclusion 꼭지 → footer zone + conclusion-accent-bar 강제 + for block in blocks: + topic = next( + (t for t in analysis.get("topics", []) + if t.get("id") == block.get("topic_id")), + None, + ) + if topic and topic.get("layer") == "conclusion": + if block.get("area") != "footer": + logger.warning( + f"conclusion 꼭지 {block.get('topic_id')} → footer 강제 이동" + ) + block["area"] = "footer" + if block.get("type") != "conclusion-accent-bar": + logger.warning( + f"conclusion 블록 {block.get('type')} → conclusion-accent-bar 강제" + ) + block["type"] = "conclusion-accent-bar" + + # 5번: zone별 height_cost 합산 검증 — 초과 시 큰 블록 교체 + _validate_height_budget(blocks, preset) + logger.info( f"[Step B] 블록 매핑 완료: {preset_name}, {len(blocks)}개 블록" ) @@ -550,6 +571,7 @@ async def create_layout_concept( logger.error(f"Step B 호출 실패: {e}", exc_info=True) # fallback: 프리셋 기반 기본 배치 + # (검증 함수는 아래에 정의) return _fallback_layout(analysis, preset_name, preset) @@ -605,6 +627,104 @@ def _fallback_layout( } +# height_cost → px 변환 (결정론적) +HEIGHT_COST_PX = { + "compact": 70, + "medium": 150, + "large": 250, + "xlarge": 400, +} + +# xlarge/large → medium/compact 교체 후보 +DOWNGRADE_MAP = { + "venn-diagram": "card-text-grid", + "pyramid-hierarchy": "card-numbered", + "card-step-vertical": "card-numbered", + "image-grid-2x2": "image-row-2col", + "compare-3col-badge": "comparison-2col", + "card-image-3col": "card-text-grid", + "card-tag-image": "card-text-grid", + "card-compare-3col": "comparison-2col", + "card-image-round": "card-icon-desc", +} + + +def _get_block_height(block_type: str) -> int: + """블록 타입의 height_cost를 px로 반환.""" + catalog_map = _load_catalog_map_for_height() + cost_label = catalog_map.get(block_type, "medium") + return HEIGHT_COST_PX.get(cost_label, 150) + + +def _load_catalog_map_for_height() -> dict[str, str]: + """catalog.yaml에서 id → height_cost 매핑을 로드.""" + catalog_path = Path(__file__).parent.parent / "templates" / "catalog.yaml" + if not catalog_path.exists(): + return {} + try: + with open(catalog_path, encoding="utf-8") as f: + data = yaml.safe_load(f) + return {b["id"]: b.get("height_cost", "medium") for b in data.get("blocks", [])} + except Exception: + return {} + + +def _validate_height_budget(blocks: list[dict], preset: dict) -> None: + """zone별 height_cost 합산을 검증하고, 초과 시 큰 블록을 교체한다. + + 코드 레벨 검증 — Sonnet이 높이 예산을 안 지켜도 강제 교정. + """ + zones = preset.get("zones", {}) + gap_px = 20 # --spacing-block + + # zone별 블록 그룹핑 + zone_blocks: dict[str, list[dict]] = {} + for block in blocks: + area = block.get("area", "body") + if area not in zone_blocks: + zone_blocks[area] = [] + zone_blocks[area].append(block) + + for area, area_blocks in zone_blocks.items(): + zone_info = zones.get(area, {}) + budget = zone_info.get("budget_px", 490) + + # 총 높이 계산 + total = sum(_get_block_height(b.get("type", "")) for b in area_blocks) + total += gap_px * max(0, len(area_blocks) - 1) + + if total <= budget: + continue + + logger.warning( + f"[높이 예산 초과] {area}: {total}px > {budget}px. " + f"블록: {[b.get('type') for b in area_blocks]}" + ) + + # 가장 큰 블록부터 교체 시도 + area_blocks.sort(key=lambda b: _get_block_height(b.get("type", "")), reverse=True) + + for block in area_blocks: + block_type = block.get("type", "") + block_height = _get_block_height(block_type) + + if block_type in DOWNGRADE_MAP and block_height >= 250: + replacement = DOWNGRADE_MAP[block_type] + old_height = block_height + new_height = _get_block_height(replacement) + + block["type"] = replacement + total = total - old_height + new_height + + logger.info( + f"[높이 교체] {block_type}({old_height}px) → " + f"{replacement}({new_height}px). 잔여: {total}px/{budget}px" + ) + + if total <= budget: + break + + def _parse_json(text: str) -> dict[str, Any] | None: """텍스트에서 JSON을 추출한다.""" patterns = [ diff --git a/src/main.py b/src/main.py index cd18404..28821ed 100644 --- a/src/main.py +++ b/src/main.py @@ -19,6 +19,17 @@ logger = logging.getLogger(__name__) app = FastAPI(title="Design Agent", version="0.1.0") + +@app.on_event("startup") +async def startup_preload(): + """서버 시작 시 FAISS 인덱스 + 임베딩 모델 미리 로드.""" + try: + from src.block_search import _ensure_loaded + _ensure_loaded() + logger.info("FAISS 인덱스 + bge-m3 모델 미리 로드 완료") + except Exception as e: + logger.warning(f"FAISS 미리 로드 실패 (첫 요청 시 로드): {e}") + app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:5174", "http://localhost:5173"], diff --git a/templates/blocks/_legacy/card-grid.html b/templates/blocks/_legacy/card-grid.html deleted file mode 100644 index a10c1ed..0000000 --- a/templates/blocks/_legacy/card-grid.html +++ /dev/null @@ -1,65 +0,0 @@ - -
- {% for card in cards %} -
- {% if card.icon %}
{{ card.icon }}
{% endif %} -
{{ card.title }}
- {% if card.category %}{{ card.category }}{% endif %} -
{{ card.description }}
- {% if card.source %}
{{ card.source }}
{% endif %} -
- {% endfor %} -
- - diff --git a/templates/blocks/_legacy/card-image.html b/templates/blocks/_legacy/card-image.html deleted file mode 100644 index 4cd2373..0000000 --- a/templates/blocks/_legacy/card-image.html +++ /dev/null @@ -1,95 +0,0 @@ - - -
- {% for card in cards %} -
- {% if card.image %} - {{ card.title }} - {% endif %} -
-
{{ card.title }}
- {% if card.title_en %}
{{ card.title_en }}
{% endif %} -
-
    - {% for item in card.bullets %} -
  • {{ item }}
  • - {% endfor %} -
- {% if card.source %}
{{ card.source }}
{% endif %} -
-
- {% endfor %} -
- - diff --git a/templates/blocks/_legacy/circle-label.html b/templates/blocks/_legacy/circle-label.html deleted file mode 100644 index d71321f..0000000 --- a/templates/blocks/_legacy/circle-label.html +++ /dev/null @@ -1,56 +0,0 @@ - - -
-
-
-
{{ label }}
- {% if sub_label %}
{{ sub_label }}
{% endif %} -
-
-
- - diff --git a/templates/blocks/_legacy/compare-box.html b/templates/blocks/_legacy/compare-box.html deleted file mode 100644 index 38267fb..0000000 --- a/templates/blocks/_legacy/compare-box.html +++ /dev/null @@ -1,67 +0,0 @@ - - -
-
-
-
{{ left_label }}
- {% if left_sub %}
{{ left_sub }}
{% endif %} -
-
-
VS
-
-
-
{{ right_label }}
- {% if right_sub %}
{{ right_sub }}
{% endif %} -
-
-
- - diff --git a/templates/blocks/_legacy/comparison-table.html b/templates/blocks/_legacy/comparison-table.html deleted file mode 100644 index b52bc74..0000000 --- a/templates/blocks/_legacy/comparison-table.html +++ /dev/null @@ -1,97 +0,0 @@ - - -
- - - - {% for header in headers %} - - {% endfor %} - - - - {% for row in rows %} - - {% for cell in row %} - - {% endfor %} - - {% endfor %} - -
- {% if loop.index == 2 %}{{ header }}{% else %}{{ header }}{% endif %} -
{{ cell }}
-
- - diff --git a/templates/blocks/_legacy/comparison.html b/templates/blocks/_legacy/comparison.html deleted file mode 100644 index a9eb1fa..0000000 --- a/templates/blocks/_legacy/comparison.html +++ /dev/null @@ -1,51 +0,0 @@ - -
-
-
{{ left_title }}
- {% if left_subtitle %}
{{ left_subtitle }}
{% endif %} -
{{ left_content }}
-
-
-
-
{{ right_title }}
- {% if right_subtitle %}
{{ right_subtitle }}
{% endif %} -
{{ right_content }}
-
-
- - diff --git a/templates/blocks/_legacy/conclusion-bar.html b/templates/blocks/_legacy/conclusion-bar.html deleted file mode 100644 index 98be32b..0000000 --- a/templates/blocks/_legacy/conclusion-bar.html +++ /dev/null @@ -1,38 +0,0 @@ - - -
- {% if label %}
{{ label }}
{% endif %} -
{{ conclusion_text }}
-
- - diff --git a/templates/blocks/_legacy/image-row.html b/templates/blocks/_legacy/image-row.html deleted file mode 100644 index 30366aa..0000000 --- a/templates/blocks/_legacy/image-row.html +++ /dev/null @@ -1,39 +0,0 @@ - - -
- {% for img in images %} -
- {{ img.alt | default('') }} - {% if img.caption %}
{{ img.caption }}
{% endif %} -
- {% endfor %} -
- - diff --git a/templates/blocks/_legacy/process.html b/templates/blocks/_legacy/process.html deleted file mode 100644 index e3d2a4b..0000000 --- a/templates/blocks/_legacy/process.html +++ /dev/null @@ -1,61 +0,0 @@ - -
- {% for step in steps %} -
-
{{ step.number | default(loop.index) }}
-
{{ step.title }}
- {% if step.description %}
{{ step.description }}
{% endif %} -
- {% if not loop.last %} -
- {% endif %} - {% endfor %} -
- - diff --git a/templates/blocks/_legacy/quote-block.html b/templates/blocks/_legacy/quote-block.html deleted file mode 100644 index 83e5680..0000000 --- a/templates/blocks/_legacy/quote-block.html +++ /dev/null @@ -1,29 +0,0 @@ - -
-
{{ quote_text }}
- {% if source %}
{{ source }}
{% endif %} -
- - diff --git a/templates/blocks/_legacy/relationship.html b/templates/blocks/_legacy/relationship.html deleted file mode 100644 index 06962c8..0000000 --- a/templates/blocks/_legacy/relationship.html +++ /dev/null @@ -1,88 +0,0 @@ - -
-
-
- {{ center_label }} - {{ center_sub }} -
- {% for item in items %} -
- {{ item.label }} -
- {% endfor %} -
- {% if description %} -
- {{ description }} -
- {% endif %} -
- - diff --git a/templates/blocks/_legacy/section-title.html b/templates/blocks/_legacy/section-title.html deleted file mode 100644 index 3b25aba..0000000 --- a/templates/blocks/_legacy/section-title.html +++ /dev/null @@ -1,69 +0,0 @@ - - -
- {% if bg_image %} - - {% else %} -
- {% endif %} - {% if breadcrumb %} -
{{ breadcrumb }}
- {% endif %} -
- {% if title_en %}
{{ title_en }}
{% endif %} -
{{ title_ko }}
-
-
- - diff --git a/templates/blocks/_legacy/topic-header.html b/templates/blocks/_legacy/topic-header.html deleted file mode 100644 index 2c3b6b2..0000000 --- a/templates/blocks/_legacy/topic-header.html +++ /dev/null @@ -1,38 +0,0 @@ - - -
-
{{ title }}
-
{{ description }}
-
- - diff --git a/templates/blocks/cards/card-text-grid.html b/templates/blocks/cards/card-text-grid.html deleted file mode 100644 index 7936dad..0000000 --- a/templates/blocks/cards/card-text-grid.html +++ /dev/null @@ -1,66 +0,0 @@ - -
- {% for card in cards %} -
- {% if card.icon %}
{{ card.icon }}
{% endif %} -
{{ card.title }}
- {% if card.category %}{{ card.category }}{% endif %} -
{{ card.description }}
- {% if card.source %}
{{ card.source }}
{% endif %} -
- {% endfor %} -
- - diff --git a/templates/blocks/emphasis/conclusion-accent-bar.html b/templates/blocks/emphasis/conclusion-accent-bar.html deleted file mode 100644 index 98be32b..0000000 --- a/templates/blocks/emphasis/conclusion-accent-bar.html +++ /dev/null @@ -1,38 +0,0 @@ - - -
- {% if label %}
{{ label }}
{% endif %} -
{{ conclusion_text }}
-
- - diff --git a/templates/blocks/emphasis/details-block.html b/templates/blocks/emphasis/details-block.html deleted file mode 100644 index ddc34d9..0000000 --- a/templates/blocks/emphasis/details-block.html +++ /dev/null @@ -1,67 +0,0 @@ - - -
- - {% if label %}{{ label }}{% endif %} - {{ summary_text }} - -
{{ detail_content }}
-
- - diff --git a/templates/blocks/emphasis/quote-left-border.html b/templates/blocks/emphasis/quote-left-border.html deleted file mode 100644 index 2e34870..0000000 --- a/templates/blocks/emphasis/quote-left-border.html +++ /dev/null @@ -1,30 +0,0 @@ - -
-
{{ quote_text }}
- {% if source %}
{{ source }}
{% endif %} -
- - diff --git a/templates/blocks/visuals/layer-diagram.html b/templates/blocks/visuals/layer-diagram.html deleted file mode 100644 index 51d5b3a..0000000 --- a/templates/blocks/visuals/layer-diagram.html +++ /dev/null @@ -1,50 +0,0 @@ - - -
- {% if title %}
{{ title }}
{% endif %} - - - {% for layer in layers %} - - - - - {% endfor %} - - - - - {% for layer in layers %} - {% set y = (layers|length - loop.index) * 55 + 20 %} - {% set offset = loop.index0 * 15 %} - - - {{ layer.label }} - {% endfor %} - -
- - diff --git a/templates/blocks/visuals/pyramid-hierarchy.html b/templates/blocks/visuals/pyramid-hierarchy.html deleted file mode 100644 index e770ceb..0000000 --- a/templates/blocks/visuals/pyramid-hierarchy.html +++ /dev/null @@ -1,40 +0,0 @@ - - -
- - - {% for level in levels %} - - - - - {% endfor %} - - - - - {% for level in levels %} - {% set i = loop.index0 %} - {% set y = i * 65 + 10 %} - {% set w_half = 60 + i * 55 %} - - {{ level.label }} - {% endfor %} - -
- - diff --git a/templates/blocks/visuals/timeline-horizontal.html b/templates/blocks/visuals/timeline-horizontal.html deleted file mode 100644 index 703465b..0000000 --- a/templates/blocks/visuals/timeline-horizontal.html +++ /dev/null @@ -1,37 +0,0 @@ - - -
- - - - {% for event in events %} - {% set x = loop.index0 * 160 + 60 %} - - - - - {{ event.year }} - - {{ event.title }} - {% if event.sub %} - {{ event.sub }} - {% endif %} - {% endfor %} - -
- - diff --git a/templates/blocks/visuals/timeline-vertical.html b/templates/blocks/visuals/timeline-vertical.html deleted file mode 100644 index 44b3e5c..0000000 --- a/templates/blocks/visuals/timeline-vertical.html +++ /dev/null @@ -1,74 +0,0 @@ - - -
- {% for event in events %} -
-
- - - - - {% if not loop.last %}
{% endif %} -
-
-
{{ event.year }}
-
{{ event.title }}
- {% if event.description %}
{{ event.description }}
{% endif %} -
-
- {% endfor %} -
- - diff --git a/templates/catalog.yaml b/templates/catalog.yaml index faa57c0..5ecead9 100644 --- a/templates/catalog.yaml +++ b/templates/catalog.yaml @@ -1,739 +1,656 @@ -# Design Agent 블록 카탈로그 (45개) -# 디자인 팀장이 콘텐츠에 적합한 블록을 선택할 때 참조하는 메뉴판 -# -# 블록별 height_cost 참고 (슬라이드 720px 기준): -# compact: ~70px (인라인 강조, 구분선) -# medium: ~150px (카드, 인용, 헤더) -# large: ~200px (비교표, 이미지, 다이어그램) -# xlarge: ~400px (SVG 벤 다이어그램, 풀 이미지) -# -# 규칙: -# - when: 이 블록을 선택해야 하는 구체적 상황 -# - not_for: 이 블록을 선택하면 안 되는 상황 + 대신 사용할 블록 -# - visual: AI가 상상할 수 있도록 시각적 형태를 구체적으로 설명 - -version: "2.0" - +version: '2.0' blocks: +- id: section-title-with-bg + name: 배경 이미지 타이틀 + template: blocks/headers/section-title-with-bg.html + height_cost: large + visual: 전체 너비 배경 이미지(파란 그라데이션+웨이브) 위에 흰색 영문 소제목(15px) + 한글 대제목(35px). 높이 약 500px. + when: '자세히보기 페이지의 맨 첫 화면. 배경 이미지가 있고 그 위에 타이틀을 올릴 때. 페이지의 주제를 시각적으로 강렬하게 선언할 때. - # ═══════════════════════════════ - # headers/ — 타이틀, 꼭지 헤더 - # ═══════════════════════════════ + ' + not_for: '슬라이드 내부의 소제목 → topic-left-right 또는 topic-center 사용. 배경 이미지 없이 텍스트만 → topic-center + 사용. 높이 예산이 200px 이하일 때 → section-header-bar 사용. - - id: section-title-with-bg - name: 배경 이미지 타이틀 - template: blocks/headers/section-title-with-bg.html - height_cost: large - visual: "전체 너비 배경 이미지(파란 그라데이션+웨이브) 위에 흰색 영문 소제목(15px) + 한글 대제목(35px). 높이 약 500px." - when: > - 자세히보기 페이지의 맨 첫 화면. - 배경 이미지가 있고 그 위에 타이틀을 올릴 때. - 페이지의 주제를 시각적으로 강렬하게 선언할 때. - not_for: > - 슬라이드 내부의 소제목 → topic-left-right 또는 topic-center 사용. - 배경 이미지 없이 텍스트만 → topic-center 사용. - 높이 예산이 200px 이하일 때 → section-header-bar 사용. - slots: - required: [title_ko] - optional: [title_en, breadcrumb, bg_image] + ' + slots: + required: + - title_ko + optional: + - title_en + - breadcrumb + - bg_image +- id: section-header-bar + name: 섹션 헤더 바 + template: blocks/headers/section-header-bar.html + height_cost: compact + visual: 전체 너비 파란 배경 바(높이 ~50px) + 중앙 흰색 제목. 섹션 구분용. 컴팩트. + when: '섹션 시작을 가볍게 표시할 때. 같은 페이지 안에서 주제가 전환될 때. 높이 예산이 적을 때 섹션 구분이 필요할 때. - - id: section-header-bar - name: 섹션 헤더 바 - template: blocks/headers/section-header-bar.html - height_cost: compact - visual: "전체 너비 파란 배경 바(높이 ~50px) + 중앙 흰색 제목. 섹션 구분용. 컴팩트." - when: > - 섹션 시작을 가볍게 표시할 때. - 같은 페이지 안에서 주제가 전환될 때. - 높이 예산이 적을 때 섹션 구분이 필요할 때. - not_for: > - 페이지 전체 타이틀 → section-title-with-bg 사용. - 꼭지별 소제목 → topic-left-right 또는 topic-numbered 사용. - slots: - required: [title] - optional: [subtitle] + ' + not_for: '페이지 전체 타이틀 → section-title-with-bg 사용. 꼭지별 소제목 → topic-left-right 또는 topic-numbered + 사용. - - id: topic-left-right - name: 좌우 꼭지 헤더 - template: blocks/headers/topic-left-right.html - height_cost: compact - visual: "좌측에 파란 굵은 제목(24px, 240px 너비) + 우측에 본문 설명. 가로 2단 배치." - when: > - 꼭지 시작부에 질문형 제목 + 답변형 설명 구조일 때. - 예: '단순 BIM의 적용이 D/X가 아닙니다' + '설명...' - 좌측에 핵심 주장, 우측에 근거/설명을 배치할 때. - not_for: > - 중앙 정렬 대제목 → topic-center 사용. - 번호가 붙은 순서형 꼭지 → topic-numbered 사용. - 섹션 전체 타이틀 → section-title-with-bg 사용. - slots: - required: [title, description] - optional: [] + ' + slots: + required: + - title + optional: + - subtitle +- id: topic-left-right + name: 좌우 꼭지 헤더 + template: blocks/headers/topic-left-right.html + height_cost: compact + visual: 좌측에 파란 굵은 제목(24px, 240px 너비) + 우측에 본문 설명. 가로 2단 배치. + when: '꼭지 시작부에 질문형 제목 + 답변형 설명 구조일 때. 예: ''단순 BIM의 적용이 D/X가 아닙니다'' + ''설명...'' 좌측에 + 핵심 주장, 우측에 근거/설명을 배치할 때. - - id: topic-center - name: 중앙 정렬 꼭지 헤더 - template: blocks/headers/topic-center.html - height_cost: medium - visual: "중앙 정렬 대제목(26px 굵게) + 파란 서브타이틀 + 하단 설명. 단독 강조." - when: > - 하나의 주제를 페이지 중심에 크게 선언할 때. - 예: '디지털전환을 위한 S/W 필요성' - 서브타이틀이나 부연 설명이 함께 올 때. - not_for: > - 좌:제목 우:설명 구조 → topic-left-right 사용. - 번호 순서 → topic-numbered 사용. - slots: - required: [title] - optional: [subtitle, description] + ' + not_for: '중앙 정렬 대제목 → topic-center 사용. 번호가 붙은 순서형 꼭지 → topic-numbered 사용. 섹션 전체 + 타이틀 → section-title-with-bg 사용. - - id: topic-numbered - name: 번호 꼭지 헤더 - template: blocks/headers/topic-numbered.html - height_cost: compact - visual: "파란 원형 번호(①②③) + 굵은 제목 + 파란 구분선 + 설명. 세로 배치." - when: > - 순서가 있는 꼭지를 시작할 때. 1번, 2번, 3번 식의 단계별 섹션. - 실행 조건, 요구사항 등을 순서대로 설명할 때. - not_for: > - 순서 없는 꼭지 → topic-left-right 또는 topic-center 사용. - 카드 안의 순서 → card-numbered 사용. - slots: - required: [number, title] - optional: [description, color] + ' + slots: + required: + - title + - description + optional: [] +- id: topic-center + name: 중앙 정렬 꼭지 헤더 + template: blocks/headers/topic-center.html + height_cost: medium + visual: 중앙 정렬 대제목(26px 굵게) + 파란 서브타이틀 + 하단 설명. 단독 강조. + when: '하나의 주제를 페이지 중심에 크게 선언할 때. 예: ''디지털전환을 위한 S/W 필요성'' 서브타이틀이나 부연 설명이 함께 올 때. - # ═══════════════════════════════ - # cards/ — 카드 계열 - # ═══════════════════════════════ + ' + not_for: '좌:제목 우:설명 구조 → topic-left-right 사용. 번호 순서 → topic-numbered 사용. - - id: card-image-3col - name: 이미지 카드 3열 - template: blocks/cards/card-image-3col.html - height_cost: large - visual: "3열 카드. 각 카드 상단에 이미지(160px) + 하단에 색상 밑줄 제목 + 영문 + 불릿 목록." - when: > - 3개 항목을 각각 고유 이미지와 함께 설명할 때. - 예: 설계단계(3D 모델) / 시공단계(현장) / 유지관리(자산) - 단계별 설명에 이미지가 핵심인 경우. - not_for: > - 이미지 없이 텍스트만 → card-text-grid 사용. - 키워드+짧은 설명만 강조 → card-dark-overlay 사용. - 2개 비교 → compare-pill-pair + comparison-table 조합 사용. - slots: - required: ["cards[]"] - optional: [] + ' + slots: + required: + - title + optional: + - subtitle + - description +- id: topic-numbered + name: 번호 꼭지 헤더 + template: blocks/headers/topic-numbered.html + height_cost: compact + visual: 파란 원형 번호(①②③) + 굵은 제목 + 파란 구분선 + 설명. 세로 배치. + when: '순서가 있는 꼭지를 시작할 때. 1번, 2번, 3번 식의 단계별 섹션. 실행 조건, 요구사항 등을 순서대로 설명할 때. - - id: card-text-grid - name: 텍스트 카드 그리드 - template: blocks/cards/card-text-grid.html - height_cost: medium - visual: "2~4열 카드. 각 카드 상단 파란 액센트 라인 + 제목 + 카테고리 뱃지 + 설명 + 출처." - when: > - 용어를 여러 개 정의할 때 (2~4개). - 예: 건설산업/BIM/DX 각각의 정의와 출처 - 이미지 없이 텍스트 정보만 나열할 때. - not_for: > - 이미지가 핵심 → card-image-3col 사용. - 키워드만 강조 → card-dark-overlay 사용. - 순서 번호가 필요 → card-numbered 사용. - slots: - required: ["cards[]"] - optional: [] + ' + not_for: '순서 없는 꼭지 → topic-left-right 또는 topic-center 사용. 카드 안의 순서 → card-numbered + 사용. - - id: card-dark-overlay - name: 다크 오버레이 카드 - template: blocks/cards/card-dark-overlay.html - height_cost: medium - visual: "3~5열 카드. 다크 배경 이미지 + 그라데이션 오버레이 + 흰색 굵은 제목 + 짧은 설명." - when: > - 키워드+짧은 설명(2줄 이내)을 시각적으로 강조할 때. - 예: 협업지원/오류감소/생산성향상/비용절감/데이터관리 - 배경 이미지가 있는 키워드 나열. - not_for: > - 긴 설명(3줄 이상) → card-text-grid 사용. - 이미지가 핵심(크게 보여야 함) → card-image-3col 사용. - slots: - required: ["cards[]"] - optional: [] + ' + slots: + required: + - number + - title + optional: + - description + - color +- id: card-image-3col + name: 이미지 카드 3열 + template: blocks/cards/card-image-3col.html + height_cost: large + visual: 3열 카드. 각 카드 상단에 이미지(160px) + 하단에 색상 밑줄 제목 + 영문 + 불릿 목록. + when: '3개 항목을 각각 고유 이미지와 함께 설명할 때. 예: 설계단계(3D 모델) / 시공단계(현장) / 유지관리(자산) 단계별 설명에 + 이미지가 핵심인 경우. - - id: card-tag-image - name: 태그 이미지 카드 - template: blocks/cards/card-tag-image.html - height_cost: large - visual: "3열 카드. 좌상단 색상 태그 라벨 + 이미지 + 제목 + 설명." - when: > - 카테고리별 분류가 핵심일 때. 태그로 구분. - 예: 제조업(파란) / 건축(초록) / 인프라·토목(빨간) - not_for: > - 태그 불필요 → card-image-3col 사용. - 이미지 없음 → card-text-grid 사용. - slots: - required: ["cards[]"] - optional: [] + ' + not_for: '이미지 없이 텍스트만 → card-text-grid 사용. 키워드+짧은 설명만 강조 → card-dark-overlay 사용. + 2개 비교 → compare-pill-pair + comparison-table 조합 사용. - - id: card-icon-desc - name: 아이콘 설명 카드 - template: blocks/cards/card-icon-desc.html - height_cost: medium - visual: "2~4열. 중앙 큰 이모지 아이콘(2.5rem) + 굵은 제목 + 설명. 밝은 배경." - when: > - 기능/특성/장점을 아이콘과 함께 나열. - 예: 🔧기술기반 / 💻S/W역량 / 🌏여건조성 - not_for: > - 이미지(사진) 필요 → card-image-3col 사용. - 순서 번호 → card-numbered 사용. - slots: - required: ["cards[]"] - optional: [] + ' + slots: + required: + - cards[] + optional: [] +- id: card-dark-overlay + name: 다크 오버레이 카드 + template: blocks/cards/card-dark-overlay.html + height_cost: medium + visual: 3~5열 카드. 다크 배경 이미지 + 그라데이션 오버레이 + 흰색 굵은 제목 + 짧은 설명. + when: '키워드+짧은 설명(2줄 이내)을 시각적으로 강조할 때. 예: 협업지원/오류감소/생산성향상/비용절감/데이터관리 배경 이미지가 있는 키워드 + 나열. - - id: card-compare-3col - name: 3단 비교 카드 - template: blocks/cards/card-compare-3col.html - height_cost: large - visual: "3열 카드. 각 카드 상단 색상 헤더(제목+서브) + 이미지 + 불릿." - when: > - 3개 카테고리를 비교. 각 카테고리에 다른 색상 헤더. - 예: 상용SW(회색) vs 3rd Party(파랑) vs 전문SW(빨강) - not_for: > - 2개 비교 → compare-pill-pair + comparison-table 사용. - 다항목 표 → compare-3col-badge 사용. - slots: - required: ["cards[]"] - optional: [] + ' + not_for: '긴 설명(3줄 이상) → card-text-grid 사용. 이미지가 핵심(크게 보여야 함) → card-image-3col 사용. - - id: card-step-vertical - name: 세로 단계 카드 - template: blocks/cards/card-step-vertical.html - height_cost: xlarge - visual: "세로 나열. 좌측 색상 마커(단계명) + 우측 콘텐츠 박스(제목+이미지+설명). 연결선." - when: > - 생애주기 단계별 설명. 각 단계에 이미지+상세 설명. - 예: 설계단계 → 시공단계 → 운영단계 - not_for: > - 가로 흐름(간단) → process-horizontal 사용. - 높이 예산 부족 → card-numbered 사용. - slots: - required: ["steps[]"] - optional: [] + ' + slots: + required: + - cards[] + optional: [] +- id: card-tag-image + name: 태그 이미지 카드 + template: blocks/cards/card-tag-image.html + height_cost: large + visual: 3열 카드. 좌상단 색상 태그 라벨 + 이미지 + 제목 + 설명. + when: '카테고리별 분류가 핵심일 때. 태그로 구분. 예: 제조업(파란) / 건축(초록) / 인프라·토목(빨간) - - id: card-image-round - name: 원형 이미지 카드 - template: blocks/cards/card-image-round.html - height_cost: large - visual: "2~3열. 원형 이미지(140px, 테두리+그림자) + 제목 + 설명. 중앙 정렬." - when: > - 포트폴리오형 나열. 비전/가치 표현. 원형 이미지. - not_for: > - 사각형 이미지 → card-image-3col 사용. - 이미지 없음 → card-icon-desc 사용. - slots: - required: ["cards[]"] - optional: [] + ' + not_for: '태그 불필요 → card-image-3col 사용. 이미지 없음 → card-text-grid 사용. - - id: card-stat-number - name: 통계 숫자 카드 - template: blocks/cards/card-stat-number.html - height_cost: medium - visual: "2~4열. 매우 큰 숫자(36px, 색상) + 단위 + 라벨 + 설명." - when: > - KPI, 성과 수치, 목표 달성률, 비용 절감율. - 예: 30% 절감 / 40% 감소 / 220명+ 인력 - not_for: > - 숫자가 아닌 텍스트 → card-text-grid 사용. - slots: - required: ["stats[]"] - optional: [] + ' + slots: + required: + - cards[] + optional: [] +- id: card-icon-desc + name: 아이콘 설명 카드 + template: blocks/cards/card-icon-desc.html + height_cost: medium + visual: 2~4열. 중앙 큰 이모지 아이콘(2.5rem) + 굵은 제목 + 설명. 밝은 배경. + when: '기능/특성/장점을 아이콘과 함께 나열. 예: 🔧기술기반 / 💻S/W역량 / 🌏여건조성 - - id: card-numbered - name: 번호 항목 카드 - template: blocks/cards/card-numbered.html - height_cost: medium - visual: "세로 나열. 색상 원형 번호(①②③④) + 제목 + 설명. 밝은 배경." - when: > - 순서가 있는 항목을 세로로 나열 (실행 단계, 조건, 요구사항). - 예: 1.요구사항분석 → 2.SW개발 → 3.System통합 → 4.교육 - not_for: > - 순서 없음 → card-text-grid 사용. - 이미지 포함 단계 → card-step-vertical 사용. - 가로 흐름 → process-horizontal 사용. - slots: - required: ["items[]"] - optional: [] + ' + not_for: '이미지(사진) 필요 → card-image-3col 사용. 순서 번호 → card-numbered 사용. - # ═══════════════════════════════ - # tables/ — 표/비교 계열 - # ═══════════════════════════════ + ' + slots: + required: + - cards[] + optional: [] +- id: card-compare-3col + name: 3단 비교 카드 + template: blocks/cards/card-compare-3col.html + height_cost: large + visual: 3열 카드. 각 카드 상단 색상 헤더(제목+서브) + 이미지 + 불릿. + when: '3개 카테고리를 비교. 각 카테고리에 다른 색상 헤더. 예: 상용SW(회색) vs 3rd Party(파랑) vs 전문SW(빨강) - - id: compare-3col-badge - name: VS 배지 비교표 - template: blocks/tables/compare-3col-badge.html - height_cost: large - visual: "3단 테이블. 좌(하늘색 헤더) | 중앙(파란 VS 배지) | 우(파란 헤더). 행별 비교." - when: > - 두 개념 다항목 비교 (5행 이상). 중앙에 VS 배지. - 예: BIM vs DX — S/W, 프로세스, 성과물, 활용 비교 - not_for: > - 시각적 대비(짧음) → compare-pill-pair 사용. - 2단 분할 → compare-2col-split 사용. - 범용 데이터 → table-simple-striped 사용. - slots: - required: ["headers[]", "rows[][]"] - optional: [] + ' + not_for: '2개 비교 → compare-pill-pair + comparison-table 사용. 다항목 표 → compare-3col-badge + 사용. - - id: compare-2col-split - name: 2단 분할 비교표 - template: blocks/tables/compare-2col-split.html - height_cost: large - visual: "파란 헤더(좌/구분/우) + 행별 좌:항목 | 중앙:기준라벨(파란) | 우:항목." - when: > - 두 기술의 항목별 상세 비교. - 예: GIS vs BIM — 개념/분석/도면/발전 - not_for: > - VS 배지 필요 → compare-3col-badge 사용. - 범용 데이터 → table-simple-striped 사용. - slots: - required: [left_title, right_title, "rows[]"] - optional: [] + ' + slots: + required: + - cards[] + optional: [] +- id: card-step-vertical + name: 세로 단계 카드 + template: blocks/cards/card-step-vertical.html + height_cost: xlarge + visual: 세로 나열. 좌측 색상 마커(단계명) + 우측 콘텐츠 박스(제목+이미지+설명). 연결선. + when: '생애주기 단계별 설명. 각 단계에 이미지+상세 설명. 예: 설계단계 → 시공단계 → 운영단계 - - id: table-simple-striped - name: 범용 줄무늬 테이블 - template: blocks/tables/table-simple-striped.html - height_cost: medium - visual: "진한 남색 헤더 + 줄무늬 행 교차. 첫 열 굵은 글씨. 범용." - when: > - 비교가 아닌 일반 데이터 표. - 예: 구분/현재/목표/비고, 스펙표, 일정표 - not_for: > - A vs B 비교 → compare-3col-badge 사용. - slots: - required: ["headers[]", "rows[][]"] - optional: [] + ' + not_for: '가로 흐름(간단) → process-horizontal 사용. 높이 예산 부족 → card-numbered 사용. - # ═══════════════════════════════ - # visuals/ — 시각 요소 (SVG) - # ═══════════════════════════════ + ' + slots: + required: + - steps[] + optional: [] +- id: card-image-round + name: 원형 이미지 카드 + template: blocks/cards/card-image-round.html + height_cost: large + visual: 2~3열. 원형 이미지(140px, 테두리+그림자) + 제목 + 설명. 중앙 정렬. + when: '포트폴리오형 나열. 비전/가치 표현. 원형 이미지. - - id: venn-diagram - name: SVG 벤 다이어그램 - template: blocks/visuals/venn-diagram.html - height_cost: xlarge - visual: "SVG. 진한 파란 큰 원(동심원 링, 입체감) + 3개 작은 원(주황/민트/골드). 그라데이션+글로우." - when: > - 상위-하위 포함 관계. 기술 융합 구조. - 예: 건설산업DX 안에 GIS/BIM/디지털트윈 - ★ 반드시 단독 배치. 다른 블록과 같은 zone에 쌓지 마라. - not_for: > - 텍스트로 관계 설명 가능하면 사용 금지. - sidebar(35%) 배치 금지. 높이 300px 미만 금지. - slots: - required: [center_label, "items[]"] - optional: [center_sub, description] + ' + not_for: '사각형 이미지 → card-image-3col 사용. 이미지 없음 → card-icon-desc 사용. - - id: circle-gradient - name: 원형 라벨 - template: blocks/visuals/circle-gradient.html - height_cost: compact - visual: "파란 그라데이션 원(190px) + 이중 테두리 + 중앙 흰색 텍스트." - when: > - 섹션 전환점 키워드 강조. 아래에 카드/표 올 때 주제 선언. - not_for: > - 본문 텍스트 → topic-header 계열. 결론 → conclusion-accent-bar. - slots: - required: [label] - optional: [sub_label] + ' + slots: + required: + - cards[] + optional: [] +- id: card-stat-number + name: 통계 숫자 카드 + template: blocks/cards/card-stat-number.html + height_cost: medium + visual: 2~4열. 매우 큰 숫자(36px, 색상) + 단위 + 라벨 + 설명. + when: 'KPI, 성과 수치, 목표 달성률, 비용 절감율. 예: 30% 절감 / 40% 감소 / 220명+ 인력 - - id: compare-pill-pair - name: 둥근 박스 VS - template: blocks/visuals/compare-pill-pair.html - height_cost: compact - visual: "이중 테두리 둥근 박스 2개 나란히 + 'VS'. 하늘색 테두리 + 시안 텍스트." - when: > - 2개 개념 시각적 대비 (비교 테이블 위 헤더로). - 예: 'DX 협업 프로세스' VS 'BIM 정보 관리' - not_for: > - 상세 비교(5행+) → compare-3col-badge 사용. - 3개 이상 → card-compare-3col 사용. - slots: - required: [left_label, right_label] - optional: [left_sub, right_sub] + ' + not_for: '숫자가 아닌 텍스트 → card-text-grid 사용. - - id: process-horizontal - name: 가로 단계 흐름 - template: blocks/visuals/process-horizontal.html - height_cost: medium - visual: "가로 방향. 파란 원형 번호 + 제목 + 설명(카드). → 화살표." - when: > - 논리적 순서를 가로로 (1→2→3→4). 프로세스 흐름. - not_for: > - 시간 기반(연도) → timeline 사용. - 세로 나열 → card-numbered 사용. - slots: - required: ["steps[]"] - optional: [] + ' + slots: + required: + - stats[] + optional: [] +- id: card-numbered + name: 번호 항목 카드 + template: blocks/cards/card-numbered.html + height_cost: medium + visual: 세로 나열. 색상 원형 번호(①②③④) + 제목 + 설명. 밝은 배경. + when: '순서가 있는 항목을 세로로 나열 (실행 단계, 조건, 요구사항). 예: 1.요구사항분석 → 2.SW개발 → 3.System통합 → + 4.교육 - - id: flow-arrow-horizontal - name: 가로 흐름 화살표 - template: blocks/visuals/flow-arrow-horizontal.html - height_cost: compact - visual: "SVG. 색상 둥근 캡슐이 가로 나열 + 사이 화살표. 컴팩트." - when: > - 기술 발전/전환 흐름을 간결하게. - 예: GIS → SPCC → 토공 → BIM - not_for: > - 각 단계에 설명 필요 → process-horizontal 사용. - slots: - required: ["steps[]"] - optional: [] + ' + not_for: '순서 없음 → card-text-grid 사용. 이미지 포함 단계 → card-step-vertical 사용. 가로 흐름 → + process-horizontal 사용. - - id: keyword-circle-row - name: 키워드 원형 행 - template: blocks/visuals/keyword-circle-row.html - height_cost: medium - visual: "SVG 그라데이션 원 안에 큰 글자(G,S,I,M) + 아래 라벨 + 설명." - when: > - 약어 풀이. 핵심 키워드를 원형으로 시각 강조. - 예: G(Geographic) + S(Structure) + I(Information) + M(Model) - not_for: > - 아이콘+설명 → card-icon-desc 사용. 용어 정의 → card-text-grid 사용. - slots: - required: ["keywords[]"] - optional: [] + ' + slots: + required: + - items[] + optional: [] +- id: compare-3col-badge + name: VS 배지 비교표 + template: blocks/tables/compare-3col-badge.html + height_cost: large + visual: 3단 테이블. 좌(하늘색 헤더) | 중앙(파란 VS 배지) | 우(파란 헤더). 행별 비교. + when: '두 개념 다항목 비교 (5행 이상). 중앙에 VS 배지. 예: BIM vs DX — S/W, 프로세스, 성과물, 활용 비교 - - id: layer-diagram - name: 레이어 다이어그램 - template: blocks/visuals/layer-diagram.html - height_cost: large - visual: "SVG. 겹쳐진 사다리꼴 레이어(3D 효과). 각 레이어에 라벨+색상." - when: > - 기술 레이어/스택 구조. - 예: Digital Twin / BIM / GIS / 실세계 인프라 - not_for: > - 포함 관계(원형) → venn-diagram. 좁은→넓은 → pyramid-hierarchy. - slots: - required: ["layers[]"] - optional: [title] + ' + not_for: '시각적 대비(짧음) → compare-pill-pair 사용. 2단 분할 → compare-2col-split 사용. 범용 데이터 + → table-simple-striped 사용. - - id: timeline-vertical - name: 세로 타임라인 - template: blocks/visuals/timeline-vertical.html - height_cost: large - visual: "좌측 세로 선 + SVG 원형 마커(색상별) + 우측 연도+제목+설명." - when: > - 연혁, 정책 시행 일정, 로드맵 (4개+ 이벤트). - 예: 2020→2022→2023→2025 - not_for: > - 이벤트 3개 이하 → timeline-horizontal 사용. - 논리적 순서 → process-horizontal 사용. - slots: - required: ["events[]"] - optional: [] + ' + slots: + required: + - headers[] + - rows[][] + optional: [] +- id: compare-2col-split + name: 2단 분할 비교표 + template: blocks/tables/compare-2col-split.html + height_cost: large + visual: 파란 헤더(좌/구분/우) + 행별 좌:항목 | 중앙:기준라벨(파란) | 우:항목. + when: '두 기술의 항목별 상세 비교. 예: GIS vs BIM — 개념/분석/도면/발전 - - id: timeline-horizontal - name: 가로 타임라인 - template: blocks/visuals/timeline-horizontal.html - height_cost: compact - visual: "SVG. 가로 선 + 원형 마커 + 위 연도 + 아래 제목. 컴팩트." - when: > - 짧은 일정/마일스톤 (3~5개). 높이 예산 적을 때. - not_for: > - 6개 이상 → timeline-vertical 사용. - slots: - required: ["events[]"] - optional: [] + ' + not_for: 'VS 배지 필요 → compare-3col-badge 사용. 범용 데이터 → table-simple-striped 사용. - - id: pyramid-hierarchy - name: 피라미드 계층 - template: blocks/visuals/pyramid-hierarchy.html - height_cost: large - visual: "SVG. 위→아래 넓어지는 사각형(그라데이션). 상위→하위 위계." - when: > - 위계, 우선순위, 좁은(핵심)→넓은(기반). - 예: DX → BIM+GIS+DT → 프로세스혁신 → 기반인프라 - not_for: > - 포함 관계 → venn-diagram. 레이어 스택 → layer-diagram. - slots: - required: ["levels[]"] - optional: [] + ' + slots: + required: + - left_title + - right_title + - rows[] + optional: [] +- id: table-simple-striped + name: 범용 줄무늬 테이블 + template: blocks/tables/table-simple-striped.html + height_cost: medium + visual: 진한 남색 헤더 + 줄무늬 행 교차. 첫 열 굵은 글씨. 범용. + when: '비교가 아닌 일반 데이터 표. 예: 구분/현재/목표/비고, 스펙표, 일정표 - # ═══════════════════════════════ - # emphasis/ — 강조, 인용, 결론 - # ═══════════════════════════════ + ' + not_for: 'A vs B 비교 → compare-3col-badge 사용. - - id: quote-left-border - name: 좌측 라인 인용 - template: blocks/emphasis/quote-left-border.html - height_cost: compact - visual: "좌측 빨간 세로 라인(3px) + 연한 배경 + 인용 텍스트 + 출처(기울임)." - when: > - 짧은 인용문 + 출처. 문제 제기, 핵심 주장. - not_for: > - 큰따옴표 장식 → quote-big-mark. 질문형 → quote-question. 결론 → conclusion-accent-bar. - slots: - required: [quote_text] - optional: [source] + ' + slots: + required: + - headers[] + - rows[][] + optional: [] +- id: venn-diagram + name: SVG 벤 다이어그램 + template: blocks/visuals/venn-diagram.html + height_cost: xlarge + visual: SVG. 진한 파란 큰 원(동심원 링, 입체감) + 3개 작은 원(주황/민트/골드). 그라데이션+글로우. + when: '상위-하위 포함 관계. 기술 융합 구조. 예: 건설산업DX 안에 GIS/BIM/디지털트윈 ★ 반드시 단독 배치. 다른 블록과 같은 + zone에 쌓지 마라. - - id: quote-big-mark - name: 큰따옴표 인용 - template: blocks/emphasis/quote-big-mark.html - height_cost: medium - visual: "좌상단 ❝ + 우하단 ❞ 큰따옴표 장식. 연한 배경 박스 + 인용문 + 우측 출처." - when: > - 임팩트 있는 문제 제기. 시각적으로 인용임을 명확히. - not_for: > - 짧은 인용 → quote-left-border. 질문 → quote-question. - slots: - required: [quote_text] - optional: [source] + ' + not_for: '텍스트로 관계 설명 가능하면 사용 금지. sidebar(35%) 배치 금지. 높이 300px 미만 금지. - - id: quote-question - name: 질문형 강조 - template: blocks/emphasis/quote-question.html - height_cost: medium - visual: "밝은 파란 배경 + 파란 테두리 + 큰 질문 텍스트(22px) + 부연 설명." - when: > - 독자에게 질문. 문제 인식 유도, 전환점. - 예: '지금의 방식으로도 가능할까?' - not_for: > - 인용(출처) → quote-left-border. 결론 → conclusion-accent-bar. - slots: - required: [question] - optional: [description] + ' + slots: + required: + - center_label + - items[] + optional: + - center_sub + - description +- id: circle-gradient + name: 원형 라벨 + template: blocks/visuals/circle-gradient.html + height_cost: compact + visual: 파란 그라데이션 원(190px) + 이중 테두리 + 중앙 흰색 텍스트. + when: '섹션 전환점 키워드 강조. 아래에 카드/표 올 때 주제 선언. - - id: conclusion-accent-bar - name: 결론 액센트 바 - template: blocks/emphasis/conclusion-accent-bar.html - height_cost: compact - visual: "밝은 회색 배경 + 좌측 파란 세로 라인(4px) + 파란 라벨 + 진한 결론 텍스트." - when: > - 페이지 하단 핵심 한 줄 요약. - not_for: > - 본문 중간 강조 → banner-gradient. 인용 → quote 계열. - slots: - required: [conclusion_text] - optional: [label] + ' + not_for: '본문 텍스트 → topic-header 계열. 결론 → conclusion-accent-bar. - - id: comparison-2col - name: 2단 병렬 비교 - template: blocks/emphasis/comparison-2col.html - height_cost: medium - visual: "좌우 2단. 좌 파란 헤더 + 우 빨간 헤더. 중앙 구분선. 서브타이틀+본문." - when: > - A vs B 직접 비교. 장단점, Before/After. - not_for: > - 다항목 표(5행+) → compare-3col-badge. 시각 대비 → compare-pill-pair. - slots: - required: [left_title, left_content, right_title, right_content] - optional: [left_subtitle, right_subtitle] + ' + slots: + required: + - label + optional: + - sub_label +- id: compare-pill-pair + name: 둥근 박스 VS + template: blocks/visuals/compare-pill-pair.html + height_cost: compact + visual: 이중 테두리 둥근 박스 2개 나란히 + 'VS'. 하늘색 테두리 + 시안 텍스트. + when: '2개 개념 시각적 대비 (비교 테이블 위 헤더로). 예: ''DX 협업 프로세스'' VS ''BIM 정보 관리'' - - id: banner-gradient - name: 그라데이션 배너 - template: blocks/emphasis/banner-gradient.html - height_cost: compact - visual: "전체 너비 파란 그라데이션 배경(둥근 모서리) + 중앙 흰색 텍스트." - when: > - 섹션 구분, 핵심 선언, 강조 문구. - not_for: > - 하단 결론 → conclusion-accent-bar. 인용 → quote 계열. - slots: - required: [text] - optional: [sub_text] + ' + not_for: '상세 비교(5행+) → compare-3col-badge 사용. 3개 이상 → card-compare-3col 사용. - - id: dark-bullet-list - name: 다크 배경 불릿 - template: blocks/emphasis/dark-bullet-list.html - height_cost: medium - visual: "짙은 남색 배경 + 파란 제목 + 흰 텍스트 불릿. 파란 불릿 마커." - when: > - 핵심 포인트를 짙은 배경 위에 강조. 시각적 무게감. - not_for: > - 밝은 배경 → card-text-grid 또는 card-numbered. - slots: - required: ["bullets[]"] - optional: [title] + ' + slots: + required: + - left_label + - right_label + optional: + - left_sub + - right_sub +- id: process-horizontal + name: 가로 단계 흐름 + template: blocks/visuals/process-horizontal.html + height_cost: medium + visual: 가로 방향. 파란 원형 번호 + 제목 + 설명(카드). → 화살표. + when: '논리적 순서를 가로로 (1→2→3→4). 프로세스 흐름. - - id: highlight-strip - name: 강조 분류 스트립 - template: blocks/emphasis/highlight-strip.html - height_cost: compact - visual: "가로 색상 구간들. 각 구간에 흰 라벨. 카테고리 색상 분류 바." - when: > - 카테고리별 색상 분류를 한 줄로. - 예: 상용(회색) | 3rd Party(파랑) | 전문SW(빨강) - not_for: > - 탭 전환 → tab-label-row. 결론 → banner-gradient. - slots: - required: ["segments[]"] - optional: [] + ' + not_for: '시간 기반(연도) → timeline 사용. 세로 나열 → card-numbered 사용. - - id: callout-solution - name: 솔루션 콜아웃 - template: blocks/emphasis/callout-solution.html - height_cost: medium - visual: "밝은 파란 배경 + 파란 테두리 + 아이콘 + 파란 제목 + 설명 + 출처." - when: > - 핵심 해결책, 솔루션, 방향성 강조. - 예: '💡 Solution 제시 포인트' - not_for: > - 경고/문제 → callout-warning. 인용 → quote 계열. - slots: - required: [title, description] - optional: [icon, source] + ' + slots: + required: + - steps[] + optional: [] +- id: flow-arrow-horizontal + name: 가로 흐름 화살표 + template: blocks/visuals/flow-arrow-horizontal.html + height_cost: compact + visual: SVG. 색상 둥근 캡슐이 가로 나열 + 사이 화살표. 컴팩트. + when: '기술 발전/전환 흐름을 간결하게. 예: GIS → SPCC → 토공 → BIM - - id: callout-warning - name: 경고 콜아웃 - template: blocks/emphasis/callout-warning.html - height_cost: medium - visual: "연한 빨간 배경 + 빨간 테두리 + 아이콘 + 빨간 제목 + 진한 빨간 설명." - when: > - 문제점 지적, 주의사항, 잘못된 접근 경고. - 예: '⚠️ 현재 접근 방식의 한계' - not_for: > - 해결책 → callout-solution. 인용 → quote 계열. - slots: - required: [title, description] - optional: [icon] + ' + not_for: '각 단계에 설명 필요 → process-horizontal 사용. - - id: tab-label-row - name: 탭 라벨 행 - template: blocks/emphasis/tab-label-row.html - height_cost: compact - visual: "가로 탭 버튼. 선택됨=색상 배경+흰 텍스트, 나머지=회색. 밝은 바탕." - when: > - 카테고리 전환/분류 표시. - 예: 제조 | 건축 | [인프라/토목] - not_for: > - 색상 바 → highlight-strip. 실제 클릭 전환 미지원. - slots: - required: ["tabs[]"] - optional: [] + ' + slots: + required: + - steps[] + optional: [] +- id: keyword-circle-row + name: 키워드 원형 행 + template: blocks/visuals/keyword-circle-row.html + height_cost: medium + visual: SVG 그라데이션 원 안에 큰 글자(G,S,I,M) + 아래 라벨 + 설명. + when: '약어 풀이. 핵심 키워드를 원형으로 시각 강조. 예: G(Geographic) + S(Structure) + I(Information) + + M(Model) - - id: divider-text - name: 텍스트 구분선 - template: blocks/emphasis/divider-text.html - height_cost: compact - visual: "좌우 가는 회색 선 + 중앙 작은 회색 텍스트. 시각적 휴식점." - when: > - 섹션 구분, 주제 전환점에 가벼운 구분. - 예: ── 핵심 요약 ── - not_for: > - 강한 구분 → section-header-bar. 결론 → conclusion-accent-bar. - slots: - required: [text] - optional: [] + ' + not_for: '아이콘+설명 → card-icon-desc 사용. 용어 정의 → card-text-grid 사용. - - id: details-block - name: 자세히보기 (접기/펼치기) - template: blocks/emphasis/details-block.html - height_cost: compact - visual: "접힌 요약 1줄 + 좌측 파란 액센트 라인. 클릭하면 상세 내용 펼침. HTML 네이티브
사용." - when: > - 너무 구체적/세부적인 내용을 접어서 보여줄 때. - 본문 흐름을 끊지 않으면서 상세 데이터(비교표, 스펙 등)를 제공할 때. - detail_target 꼭지. - not_for: > - 본문 핵심 내용 (접으면 안 됨). 결론 → conclusion-accent-bar. - 일반 텍스트 → topic-header 또는 card 사용. - slots: - required: [summary_text, detail_content] - optional: [label] + ' + slots: + required: + - keywords[] + optional: [] +- id: quote-big-mark + name: 큰따옴표 인용 + template: blocks/emphasis/quote-big-mark.html + height_cost: medium + visual: 좌상단 ❝ + 우하단 ❞ 큰따옴표 장식. 연한 배경 박스 + 인용문 + 우측 출처. + when: '임팩트 있는 문제 제기. 시각적으로 인용임을 명확히. - # ═══════════════════════════════ - # media/ — 이미지/미디어 - # ═══════════════════════════════ + ' + not_for: '짧은 인용 → quote-left-border. 질문 → quote-question. - - id: image-row-2col - name: 이미지 2열 - template: blocks/media/image-row-2col.html - height_cost: large - visual: "이미지 2장 나란히. 높이 354px. 캡션 선택." - when: > - 시공 사진 2장, 현장 비교 나란히. - not_for: > - 4장 → image-grid-2x2. 이미지+텍스트 → image-side-text. 1장 → image-full-caption. - slots: - required: ["images[]"] - optional: [] + ' + slots: + required: + - quote_text + optional: + - source +- id: quote-question + name: 질문형 강조 + template: blocks/emphasis/quote-question.html + height_cost: medium + visual: 밝은 파란 배경 + 파란 테두리 + 큰 질문 텍스트(22px) + 부연 설명. + when: '독자에게 질문. 문제 인식 유도, 전환점. 예: ''지금의 방식으로도 가능할까?'' - - id: image-grid-2x2 - name: 이미지 2x2 그리드 - template: blocks/media/image-grid-2x2.html - height_cost: large - visual: "이미지 4장 2x2 격자. 높이 200px 각. 캡션 선택." - when: > - 현장 사진 4장, 4개 관점 이미지. - not_for: > - 2장 → image-row-2col. 이미지+텍스트 → image-side-text. - slots: - required: ["images[]"] - optional: [] + ' + not_for: '인용(출처) → quote-left-border. 결론 → conclusion-accent-bar. - - id: image-side-text - name: 이미지+텍스트 가로 - template: blocks/media/image-side-text.html - height_cost: medium - visual: "좌측 이미지(320px) + 우측 제목+설명+불릿. 가로 배치." - when: > - 이미지에 대한 설명. 제품/시스템 소개. - not_for: > - 이미지만 → image-row-2col. 여러 장 → image-grid-2x2. - slots: - required: [image_src] - optional: [image_alt, title, description, bullets] + ' + slots: + required: + - question + optional: + - description +- id: comparison-2col + name: 2단 병렬 비교 + template: blocks/emphasis/comparison-2col.html + height_cost: medium + visual: 좌우 2단. 좌 파란 헤더 + 우 빨간 헤더. 중앙 구분선. 서브타이틀+본문. + when: 'A vs B 직접 비교. 장단점, Before/After. - - id: image-full-caption - name: 전체 너비 이미지 - template: blocks/media/image-full-caption.html - height_cost: large - visual: "전체 너비 이미지 1장(둥근 모서리) + 하단 캡션." - when: > - 핵심 도표, 대형 다이어그램, 전경 사진을 크게. - not_for: > - 2장+ → image-row-2col/image-grid-2x2. 이미지+텍스트 → image-side-text. - slots: - required: [src] - optional: [alt, caption] + ' + not_for: '다항목 표(5행+) → compare-3col-badge. 시각 대비 → compare-pill-pair. - - id: image-before-after - name: Before/After 이미지 - template: blocks/media/image-before-after.html - height_cost: large - visual: "좌 Before(회색 라벨) + → 화살표(파란) + 우 After(파란 라벨). 각각 이미지." - when: > - 변화 전후 비교. 디지털 전환 전후, 공정 개선. - not_for: > - 이미지 단순 나열 → image-row-2col. 텍스트 비교 → comparison-2col. - slots: - required: [before_src, after_src] - optional: [before_label, after_label, caption] + ' + slots: + required: + - left_title + - left_content + - right_title + - right_content + optional: + - left_subtitle + - right_subtitle +- id: banner-gradient + name: 그라데이션 배너 + template: blocks/emphasis/banner-gradient.html + height_cost: compact + visual: 전체 너비 파란 그라데이션 배경(둥근 모서리) + 중앙 흰색 텍스트. + when: '섹션 구분, 핵심 선언, 강조 문구. -# ═══════════════════════════════ -# 레이아웃 옵션 -# ═══════════════════════════════ + ' + not_for: '하단 결론 → conclusion-accent-bar. 인용 → quote 계열. + + ' + slots: + required: + - text + optional: + - sub_text +- id: dark-bullet-list + name: 다크 배경 불릿 + template: blocks/emphasis/dark-bullet-list.html + height_cost: medium + visual: 짙은 남색 배경 + 파란 제목 + 흰 텍스트 불릿. 파란 불릿 마커. + when: '핵심 포인트를 짙은 배경 위에 강조. 시각적 무게감. + + ' + not_for: '밝은 배경 → card-text-grid 또는 card-numbered. + + ' + slots: + required: + - bullets[] + optional: + - title +- id: highlight-strip + name: 강조 분류 스트립 + template: blocks/emphasis/highlight-strip.html + height_cost: compact + visual: 가로 색상 구간들. 각 구간에 흰 라벨. 카테고리 색상 분류 바. + when: '카테고리별 색상 분류를 한 줄로. 예: 상용(회색) | 3rd Party(파랑) | 전문SW(빨강) + + ' + not_for: '탭 전환 → tab-label-row. 결론 → banner-gradient. + + ' + slots: + required: + - segments[] + optional: [] +- id: callout-solution + name: 솔루션 콜아웃 + template: blocks/emphasis/callout-solution.html + height_cost: medium + visual: 밝은 파란 배경 + 파란 테두리 + 아이콘 + 파란 제목 + 설명 + 출처. + when: '핵심 해결책, 솔루션, 방향성 강조. 예: ''💡 Solution 제시 포인트'' + + ' + not_for: '경고/문제 → callout-warning. 인용 → quote 계열. + + ' + slots: + required: + - title + - description + optional: + - icon + - source +- id: callout-warning + name: 경고 콜아웃 + template: blocks/emphasis/callout-warning.html + height_cost: medium + visual: 연한 빨간 배경 + 빨간 테두리 + 아이콘 + 빨간 제목 + 진한 빨간 설명. + when: '문제점 지적, 주의사항, 잘못된 접근 경고. 예: ''⚠️ 현재 접근 방식의 한계'' + + ' + not_for: '해결책 → callout-solution. 인용 → quote 계열. + + ' + slots: + required: + - title + - description + optional: + - icon +- id: tab-label-row + name: 탭 라벨 행 + template: blocks/emphasis/tab-label-row.html + height_cost: compact + visual: 가로 탭 버튼. 선택됨=색상 배경+흰 텍스트, 나머지=회색. 밝은 바탕. + when: '카테고리 전환/분류 표시. 예: 제조 | 건축 | [인프라/토목] + + ' + not_for: '색상 바 → highlight-strip. 실제 클릭 전환 미지원. + + ' + slots: + required: + - tabs[] + optional: [] +- id: divider-text + name: 텍스트 구분선 + template: blocks/emphasis/divider-text.html + height_cost: compact + visual: 좌우 가는 회색 선 + 중앙 작은 회색 텍스트. 시각적 휴식점. + when: '섹션 구분, 주제 전환점에 가벼운 구분. 예: ── 핵심 요약 ── + + ' + not_for: '강한 구분 → section-header-bar. 결론 → conclusion-accent-bar. + + ' + slots: + required: + - text + optional: [] +- id: image-row-2col + name: 이미지 2열 + template: blocks/media/image-row-2col.html + height_cost: large + visual: 이미지 2장 나란히. 높이 354px. 캡션 선택. + when: '시공 사진 2장, 현장 비교 나란히. + + ' + not_for: '4장 → image-grid-2x2. 이미지+텍스트 → image-side-text. 1장 → image-full-caption. + + ' + slots: + required: + - images[] + optional: [] +- id: image-grid-2x2 + name: 이미지 2x2 그리드 + template: blocks/media/image-grid-2x2.html + height_cost: large + visual: 이미지 4장 2x2 격자. 높이 200px 각. 캡션 선택. + when: '현장 사진 4장, 4개 관점 이미지. + + ' + not_for: '2장 → image-row-2col. 이미지+텍스트 → image-side-text. + + ' + slots: + required: + - images[] + optional: [] +- id: image-side-text + name: 이미지+텍스트 가로 + template: blocks/media/image-side-text.html + height_cost: medium + visual: 좌측 이미지(320px) + 우측 제목+설명+불릿. 가로 배치. + when: '이미지에 대한 설명. 제품/시스템 소개. + + ' + not_for: '이미지만 → image-row-2col. 여러 장 → image-grid-2x2. + + ' + slots: + required: + - image_src + optional: + - image_alt + - title + - description + - bullets +- id: image-full-caption + name: 전체 너비 이미지 + template: blocks/media/image-full-caption.html + height_cost: large + visual: 전체 너비 이미지 1장(둥근 모서리) + 하단 캡션. + when: '핵심 도표, 대형 다이어그램, 전경 사진을 크게. + + ' + not_for: '2장+ → image-row-2col/image-grid-2x2. 이미지+텍스트 → image-side-text. + + ' + slots: + required: + - src + optional: + - alt + - caption +- id: image-before-after + name: Before/After 이미지 + template: blocks/media/image-before-after.html + height_cost: large + visual: 좌 Before(회색 라벨) + → 화살표(파란) + 우 After(파란 라벨). 각각 이미지. + when: '변화 전후 비교. 디지털 전환 전후, 공정 개선. + + ' + not_for: '이미지 단순 나열 → image-row-2col. 텍스트 비교 → comparison-2col. + + ' + slots: + required: + - before_src + - after_src + optional: + - before_label + - after_label + - caption layouts: - - id: "65-35" - name: "6.5:3.5 좌우 분할" - grid_columns: "6.5fr 3.5fr" - when: "좌측 메인 + 우측 보조" - - id: "50-50" - name: "5:5 균등 분할" - grid_columns: "1fr 1fr" - when: "대등한 비교" - - id: "single" - name: "단일 컬럼" - grid_columns: "1fr" - when: "순차 구조" - - id: "35-65" - name: "3.5:6.5 좌우 분할" - grid_columns: "3.5fr 6.5fr" - when: "좌측 요약 + 우측 메인" - - id: "40-60" - name: "4:6 좌우 분할" - grid_columns: "4fr 6fr" - when: "좌측 설명 + 우측 시각화" - - id: "60-40" - name: "6:4 좌우 분할" - grid_columns: "6fr 4fr" - when: "좌측 메인 + 우측 보조" - -# Phase 2 추가 예정 -# - circle-orbit: 원형 궤도 배치 (SVG, N개 자동) -# - details-block: 자세히보기 (
/) +- id: 65-35 + name: 6.5:3.5 좌우 분할 + grid_columns: 6.5fr 3.5fr + when: 좌측 메인 + 우측 보조 +- id: 50-50 + name: 5:5 균등 분할 + grid_columns: 1fr 1fr + when: 대등한 비교 +- id: single + name: 단일 컬럼 + grid_columns: 1fr + when: 순차 구조 +- id: 35-65 + name: 3.5:6.5 좌우 분할 + grid_columns: 3.5fr 6.5fr + when: 좌측 요약 + 우측 메인 +- id: 40-60 + name: 4:6 좌우 분할 + grid_columns: 4fr 6fr + when: 좌측 설명 + 우측 시각화 +- id: 60-40 + name: 6:4 좌우 분할 + grid_columns: 6fr 4fr + when: 좌측 메인 + 우측 보조