diff --git a/src/phase_z2_pipeline.py b/src/phase_z2_pipeline.py index 2d03df8..5d46e9e 100644 --- a/src/phase_z2_pipeline.py +++ b/src/phase_z2_pipeline.py @@ -748,7 +748,36 @@ def run_overflow_check(html_path: Path) -> dict: zones.push(m); }); - return { slide: slideM, slide_body: bodyM, zones }; + // B5 v0 — frame_slot_metrics (per-cell measurement of [data-frame-slot-id]) + // 현재 F29 partial 만 marker 보유 (process_column / product_column × 3 cells = 6 entries 기대). + // 다른 frame (F13 / F16) 은 marker 미적용 → entry 0 — 정상. + const frame_slot_metrics = []; + slide.querySelectorAll('[data-frame-slot-id]').forEach((cell) => { + const slotId = cell.getAttribute('data-frame-slot-id'); + const m2 = measure(cell); + const parentZone = cell.closest('.zone'); + const zonePos = parentZone + ? (parentZone.getAttribute('data-zone-position') || 'unknown') + : 'unknown'; + const zoneTid = parentZone + ? (parentZone.getAttribute('data-template-id') || '?') + : '?'; + frame_slot_metrics.push({ + zone_position: zonePos, + zone_template_id: zoneTid, + frame_slot_id: slotId, + class_name: cell.className, + clientWidth: m2.clientWidth, + clientHeight: m2.clientHeight, + scrollWidth: m2.scrollWidth, + scrollHeight: m2.scrollHeight, + excess_x: m2.excess_x, + excess_y: m2.excess_y, + overflowed: m2.overflowed, + }); + }); + + return { slide: slideM, slide_body: bodyM, zones, frame_slot_metrics }; """) screenshot_path = html_path.parent / "preview.png" diff --git a/templates/phase_z2/families/process_product_two_way.html b/templates/phase_z2/families/process_product_two_way.html index ab06f8c..137cdf6 100644 --- a/templates/phase_z2/families/process_product_two_way.html +++ b/templates/phase_z2/families/process_product_two_way.html @@ -209,7 +209,7 @@ slots: title (omitted), banner_left, banner_right, {# ───── Row 1: section 1 ───── #} {% set s1 = slot_payload.process.sections[0] %} -