diff --git a/templates/phase_z2/layouts/layouts.yaml b/templates/phase_z2/layouts/layouts.yaml new file mode 100644 index 0000000..b2b234c --- /dev/null +++ b/templates/phase_z2/layouts/layouts.yaml @@ -0,0 +1,130 @@ +# Phase Z 8-preset Layout Catalog +# +# User lock (2026-05-07) — Step 7-A: +# Layout definitions migrated from hardcoded dict (src/phase_z2_composition.py +# LAYOUT_PRESETS) to this catalog. Logic unchanged — backward compat +# (load_layout_presets() returns same dict shape). +# +# Hierarchy: +# slide_base (templates/phase_z2/slide_base.html) +# -> layout (this catalog) +# -> zone (positions) +# -> frame family partial (templates/phase_z2/families/*.html) +# -> slot payload +# +# Per-layout fields: +# render_ready: bool +# - true: layout has full grid definition + verified rendering path +# - false: layout defined but render path incomplete (future-proof marker) +# default_selection: bool +# - true: select_layout_preset() picks this as default for matching unit_count +# - false: defined alternative — not picked by current single-decision logic +# (consumed by Step 7-B multiple-candidate generation, Step 9 fit eval) +# candidate_when: +# unit_count + optional signals (orientation / layout topology hint) +# used by Step 7-B / Step 9 (currently inert — single-decision logic in +# select_layout_preset() ignores this field). +# unit_count = layout placement unit count (Step 4 output) = +# raw section_count + promoted lead_orphans 등. + +single: + zones: 1 + topology: single + positions: [primary] + css_areas: '"primary"' + css_cols: 1fr + css_rows: 1fr + render_ready: true + default_selection: true + candidate_when: + unit_count: 1 + +horizontal-2: + zones: 2 + topology: rows + positions: [top, bottom] + css_areas: '"top" "bottom"' + css_cols: 1fr + css_rows: 1fr 1fr + render_ready: true + default_selection: true + candidate_when: + unit_count: 2 + orientation: horizontal + +vertical-2: + zones: 2 + topology: cols + positions: [left, right] + css_areas: '"left right"' + css_cols: 1fr 1fr + css_rows: 1fr + render_ready: true + default_selection: false + candidate_when: + unit_count: 2 + orientation: vertical + +top-1-bottom-2: + zones: 3 + topology: T + positions: [top, bottom-left, bottom-right] + css_areas: '"top top" "bottom-left bottom-right"' + css_cols: 1fr 1fr + css_rows: 1fr 1fr + render_ready: true + default_selection: true + candidate_when: + unit_count: 3 + layout: T + +top-2-bottom-1: + zones: 3 + topology: inverted-T + positions: [top-left, top-right, bottom] + css_areas: '"top-left top-right" "bottom bottom"' + css_cols: 1fr 1fr + css_rows: 1fr 1fr + render_ready: true + default_selection: false + candidate_when: + unit_count: 3 + layout: inverted-T + +left-1-right-2: + zones: 3 + topology: side-T-left + positions: [left, right-top, right-bottom] + css_areas: '"left right-top" "left right-bottom"' + css_cols: 1fr 1fr + css_rows: 1fr 1fr + render_ready: true + default_selection: false + candidate_when: + unit_count: 3 + layout: side-T-left + +left-2-right-1: + zones: 3 + topology: side-T-right + positions: [left-top, right, left-bottom] + css_areas: '"left-top right" "left-bottom right"' + css_cols: 1fr 1fr + css_rows: 1fr 1fr + render_ready: true + default_selection: false + candidate_when: + unit_count: 3 + layout: side-T-right + +grid-2x2: + zones: 4 + topology: 2x2 + positions: [top-left, top-right, bottom-left, bottom-right] + css_areas: '"top-left top-right" "bottom-left bottom-right"' + css_cols: 1fr 1fr + css_rows: 1fr 1fr + render_ready: true + default_selection: true + candidate_when: + unit_count: 4 diff --git a/templates/phase_z2/layouts/layouts_preview.html b/templates/phase_z2/layouts/layouts_preview.html new file mode 100644 index 0000000..28cd0eb --- /dev/null +++ b/templates/phase_z2/layouts/layouts_preview.html @@ -0,0 +1,121 @@ + + + + +Phase Z 8-preset Layout Catalog Preview + + + + +

Phase Z 8-preset Layout Catalog

+

source: templates/phase_z2/layouts/layouts.yaml / 사람이 8 layout 시각 검증용. default selection = 현재 select_layout_preset() 단일 결정 로직에서 자동 선택. alternative = render_ready 이지만 자동 선택 안 됨 (Step 7-B 후보 활성화 대상).

+ +
+ +
+

single default selection

+
zones: 1 / topology: single / positions: [primary]
+
+
primary
+
+
candidate_when: unit_count = 1
+
+ +
+

horizontal-2 default selection

+
zones: 2 / topology: rows / positions: [top, bottom]
+
+
top
+
bottom
+
+
candidate_when: unit_count = 2 / orientation = horizontal
+
+ +
+

vertical-2 alternative

+
zones: 2 / topology: cols / positions: [left, right]
+
+
left
+
right
+
+
candidate_when: unit_count = 2 / orientation = vertical
+
+ +
+

top-1-bottom-2 default selection

+
zones: 3 / topology: T / positions: [top, bottom-left, bottom-right]
+
+
top
+
bottom-left
+
bottom-right
+
+
candidate_when: unit_count = 3 / layout = T
+
+ +
+

top-2-bottom-1 alternative

+
zones: 3 / topology: inverted-T / positions: [top-left, top-right, bottom]
+
+
top-left
+
top-right
+
bottom
+
+
candidate_when: unit_count = 3 / layout = inverted-T
+
+ +
+

left-1-right-2 alternative

+
zones: 3 / topology: side-T-left / positions: [left, right-top, right-bottom]
+
+
left
+
right-top
+
right-bottom
+
+
candidate_when: unit_count = 3 / layout = side-T-left
+
+ +
+

left-2-right-1 alternative

+
zones: 3 / topology: side-T-right / positions: [left-top, right, left-bottom]
+
+
left-top
+
right
+
left-bottom
+
+
candidate_when: unit_count = 3 / layout = side-T-right
+
+ +
+

grid-2x2 default selection

+
zones: 4 / topology: 2x2 / positions: [top-left, top-right, bottom-left, bottom-right]
+
+
top-left
+
top-right
+
bottom-left
+
bottom-right
+
+
candidate_when: unit_count = 4
+
+ +
+ + + diff --git a/templates/phase_z2/regions/display_strategies.yaml b/templates/phase_z2/regions/display_strategies.yaml new file mode 100644 index 0000000..33271e5 --- /dev/null +++ b/templates/phase_z2/regions/display_strategies.yaml @@ -0,0 +1,62 @@ +# Phase Z Display Strategy Catalog +# +# User lock (2026-05-07) — Step 8-A: +# Display strategy vocabulary — how to present content within a region. +# Source: docs/architecture/PHASE-Z-CONTENT-OBJECT-SUBZONE-SPEC.md (4 entry). +# +# Axis separation: +# region_layouts.yaml = how to divide zone into regions (structure axis) +# display_strategies.yaml (this file) = how to display content within region (policy axis) +# The two axes are orthogonal — same region layout can use different strategies. +# +# Absolute user locks (must NOT be violated): +# - Original text/table/image/details content is NEVER dropped or summarized. +# - 오답노트 #5: 텍스트 압축 / trim / restructure 금지. +# - IMPROVEMENT-REDESIGN.md line 110: "본문은 preview, 원문은 popup/detail 무손실 보존". +# - "dropped" applies ONLY to decorative elements — strict forbidden_for enforcement. +# +# Per-entry fields: +# description: str +# applies_to: list[str] (content types that can use this strategy) +# forbidden_for: list[str] (content types that MUST NOT use this strategy) +# preserves_original: bool (true = original content kept somewhere — popup/detail) + + +inline_full: + description: Content fully inline — entire content rendered within region. + applies_to: [text_block, table, image, details, decorative_element] + forbidden_for: [] + preserves_original: true # all content is inline, original = inline + + +inline_preview_with_details: + description: Partial inline preview + remaining content in details/popup. + applies_to: [text_block, table, details] + forbidden_for: [decorative_element] + preserves_original: true # User lock — original content kept in popup + detail_trigger: + placement: top-right # 본문 흐름 방해 X / 보조 동작 위치 / 안정 (user 2026-05-07) + label: details # identifier — display text 는 partial/UI 별 axis + preserves_original_note: "버튼은 원문 대체 X — 원문 전체 진입문" + + +details_only: + description: Summary inline only, full content in popup. + applies_to: [text_block, table, details] + forbidden_for: [decorative_element] + preserves_original: true # User lock — full content in popup + detail_trigger: + placement: top-right # user lock — popup 진입 일관 위치 + label: details + preserves_original_note: "버튼은 원문 대체 X — 원문 전체 진입문" + + +dropped: + description: | + Decorative element omitted due to space constraints. + USER LOCK: applies ONLY to decorative_element. + NEVER drop text_block / table / image / details — original content preservation + is absolute (오답노트 #5, IMPROVEMENT-REDESIGN.md §3.6 line 110). + applies_to: [decorative_element] + forbidden_for: [text_block, table, image, details] + preserves_original: false # decorative only — no original to preserve diff --git a/templates/phase_z2/regions/region_layouts.yaml b/templates/phase_z2/regions/region_layouts.yaml new file mode 100644 index 0000000..8373744 --- /dev/null +++ b/templates/phase_z2/regions/region_layouts.yaml @@ -0,0 +1,95 @@ +# Phase Z Region Layout Catalog (Internal Region structure) +# +# User lock (2026-05-07) — Step 8-A: +# Internal Region (= child zone) layout vocabulary catalog. +# Source: docs/architecture/PHASE-Z-CONTENT-OBJECT-SUBZONE-SPEC.md §2.5 (v1, 6 entry). +# Code connection (2026-05-08, Step 8-conn): +# src/phase_z2_composition.py::load_region_layouts() reads this file. +# src/phase_z2_pipeline.py step08 artifact records select_region_layout_candidates() output +# per zone (placeholder signals: region_count=1, Step 3/4 부재 종속). +# Step 9 v0 (application_plan) consumes the candidate list per unit. +# +# Hierarchy: +# Slide -> Layout (slide-body zone 분배) +# -> Zone -> Internal Region (this catalog) -> Frame -> Frame Slot -> Content +# +# Decision rule (SPEC §2.5 deterministic, AI X): +# 1. region_count == 1 -> region-single +# 2. details_presence == true / large content -> region-preview-details +# 3. region_count == 4 AND 4 equal items -> region-grid-2x2 +# 4. region_count == 2 AND primary+supporting + ratio -> region-main-support +# 5. region_count == 2 AND visual element (image/diagram)-> region-horizontal-split +# 6. fallback -> region-vertical-stack +# +# Per-entry fields: +# region_count: int | str (e.g. 1, 2, 4, "2+") +# topology: vertical | horizontal | grid | weighted | preview-details | single +# default_fallback: bool (true only for region-vertical-stack — SPEC §2.5) +# description: str +# candidate_when: dict (decision rule signals — Step 8-B input) + + +region-single: + region_count: 1 + topology: single + default_fallback: false + description: 1 region (zone entire = single region) + candidate_when: + region_count: 1 + + +region-vertical-stack: + region_count: "2+" + topology: vertical + default_fallback: true + description: Vertical top-bottom stack. Default fallback when no other rule matches. + candidate_when: + region_count_ge: 2 + flow_type: sequential + + +region-horizontal-split: + region_count: 2 + topology: horizontal + default_fallback: false + description: Left-right horizontal split (text + image, text + diagram). + candidate_when: + region_count: 2 + has_visual_element: true # image / diagram in content_type_mix + + +region-main-support: + region_count: 2 + topology: weighted + default_fallback: false + description: Main region + supporting region (asymmetric ratio, e.g. 0.7 / 0.3). + ratios_default: [0.7, 0.3] + candidate_when: + region_count: 2 + role_pattern: primary_supporting + ratio_asymmetric: true # max / min >= 2 + + +region-preview-details: + region_count: 2 + topology: preview-details + default_fallback: false + description: Inline preview region + details/popup region. + # preserves_original 은 display_strategies.yaml 의 책임 (axis 분리 lock 2026-05-07). + # User lock (원문 무손실 보존) 은 display_strategies 의 inline_preview_with_details + # / details_only 의 preserves_original: true 로 single source of truth 박힘. + candidate_when: + or: + - details_presence: true + - large_table: ">= 5 rows" + - long_text: true + + +region-grid-2x2: + region_count: 4 + topology: grid + default_fallback: false + description: 2x2 grid (4 equal regions). + candidate_when: + region_count: 4 + flow_type: parallel_4 diff --git a/templates/phase_z2/regions/regions_preview.html b/templates/phase_z2/regions/regions_preview.html new file mode 100644 index 0000000..36b20d4 --- /dev/null +++ b/templates/phase_z2/regions/regions_preview.html @@ -0,0 +1,166 @@ + + + + +Phase Z Child Zone / Internal Region Catalog Preview + + + + +

Phase Z Child Zone / Internal Region Catalog

+

source: region_layouts.yaml + display_strategies.yaml / 사람이 두 axis (구조 + 정책) 시각 검증.

+

SPEC: docs/architecture/PHASE-Z-CONTENT-OBJECT-SUBZONE-SPEC.md §2.5 (region 6 entry, display 4 entry)

+ +

1. Region Layouts (zone 안 분할 구조 — 6 entry)

+ +
+ +
+

region-single 1 region

+
topology: single / region_count: 1
+
+
single region
+
+
candidate_when: region_count = 1
+
+ +
+

region-vertical-stack default fallback

+
topology: vertical / region_count: 2+
+
+
region 1 (top)
+
region 2 (bottom)
+
+
candidate_when: region_count >= 2 AND flow_type = sequential. Default fallback when no other rule matches.
+
+ +
+

region-horizontal-split 2 region

+
topology: horizontal / region_count: 2 / has_visual_element: true
+
+
region 1 (left)
+
region 2 (right)
+
+
candidate_when: region_count = 2 AND visual element (image / diagram) in content_type_mix
+
+ +
+

region-main-support 2 region weighted

+
topology: weighted / ratios: [0.7, 0.3]
+
+
main (0.7)
+
support (0.3)
+
+
candidate_when: region_count = 2 AND role = [primary, supporting] AND ratio max/min >= 2
+
+ +
+

region-preview-details preview + popup

+
topology: preview-details / preserves_original: true
+
+
preview (inline)
+
details / popup
+
+
candidate_when: details_presence = true OR large_table (>=5 rows) OR long_text. User lock: 원문 무손실 보존.
+
+ +
+

region-grid-2x2 4 region

+
topology: grid / region_count: 4
+
+
region 1
+
region 2
+
region 3
+
region 4
+
+
candidate_when: region_count = 4 AND content type 4 equal items
+
+ +
+ +

2. Display Strategies (콘텐츠 처리 정책 — 4 entry)

+ +
+ +
+

inline_full all content types

+
Content fully inline — entire content rendered within region.
+
applies_to: text_block table image details decorative_element
+
preserves_original: true (all inline = original is inline)
+
+ +
+

inline_preview_with_details popup preserved

+
Partial inline preview + remaining in details/popup. User lock: 원문 popup 보존.
+
applies_to: text_block table details
+
preserves_original: true (popup 안에 보존)
+
+
details
+
preview content (일부 inline)
+
preview content ...
+
+
detail_trigger: placement: top-right / label: details / 버튼은 원문 대체 X — 원문 전체 진입문
+
+ +
+

details_only popup preserved

+
Summary inline only, full content in popup. User lock: 전체 popup 보존.
+
applies_to: text_block table details
+
preserves_original: true (popup)
+
+
details
+
summary inline only
+
+
detail_trigger: placement: top-right / label: details / 전체 원문 popup 안 보존
+
+ +
+

dropped decorative only

+
Decorative element omitted due to space constraints.
+
applies_to: decorative_element
+
+ FORBIDDEN_FOR (절대 금지): + text_block table image details
+ + User lock — 사용자 절대 룰. 텍스트 / 표 / 이미지 / details 콘텐츠는 절대 dropped X.
+ 오답노트 #5 / IMPROVEMENT-REDESIGN.md §3.6 line 110 — 원문 무손실 보존. +
+
+
+ +
+ + +