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

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:16:33 +09:00

350 lines
12 KiB
Django/Jinja
Raw Permalink Blame History

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