- 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>
182 lines
4.3 KiB
Django/Jinja
182 lines
4.3 KiB
Django/Jinja
<!DOCTYPE html>
|
||
<html lang="ko">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>{{ title|default("quadrant-2x2-issues") }}</title>
|
||
<!--
|
||
Pattern: quadrant-2x2-issues
|
||
Origin: 45:18 / Frame 1171281193
|
||
2×2 카테고리 그리드 (issue/diagnosis 진단). 각 카테고리에 N개의 issue + bullet body.
|
||
중앙에 optional 인용구 원.
|
||
-->
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet">
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
:root {
|
||
--block-w: {{ block_w|default(1280) }}px;
|
||
--headline-color: {{ headline_color|default("#ff0000") }};
|
||
--body-color: {{ body_color|default("#000000") }};
|
||
--header-bg: {{ header_bg|default("linear-gradient(90deg, #4a4028 0%, #285b4a 100%)") }};
|
||
--header-text-color: {{ header_text_color|default("#ffffff") }};
|
||
--card-bg-image: {{ card_bg_image|default("") }};
|
||
--row-gap: {{ row_gap|default("0.6rem") }};
|
||
}
|
||
body {
|
||
font-family: 'Noto Sans KR', sans-serif;
|
||
background: #e8ecf0;
|
||
display: flex; justify-content: center; align-items: center;
|
||
min-height: 100vh;
|
||
padding: 20px;
|
||
}
|
||
.block {
|
||
width: var(--block-w);
|
||
background: #ffffff;
|
||
position: relative;
|
||
box-shadow: 0 4px 20px rgba(0,0,0,.15);
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 0.4rem;
|
||
padding: 0;
|
||
}
|
||
|
||
.quadrant {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background-color: #2a2a1a;
|
||
{% if card_bg_image %}background-image: url('{{ card_bg_image }}');{% endif %}
|
||
background-size: cover;
|
||
border-radius: 1.5rem;
|
||
overflow: hidden;
|
||
}
|
||
.quadrant.tl, .quadrant.tr { border-radius: 1.5rem 1.5rem 0 0; }
|
||
.quadrant.bl, .quadrant.br { border-radius: 0 0 1.5rem 1.5rem; }
|
||
|
||
/* Header ribbon */
|
||
.q-header {
|
||
flex: none;
|
||
height: 3.4rem;
|
||
background: var(--header-bg);
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-weight: 900;
|
||
font-size: 1.7rem;
|
||
color: var(--header-text-color);
|
||
text-shadow: 0 0 4px #322c1e;
|
||
}
|
||
|
||
/* 카테고리 본문 */
|
||
.q-body {
|
||
flex: 1;
|
||
padding: 1.2rem 1.4rem;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--row-gap);
|
||
color: #fff;
|
||
}
|
||
|
||
/* Each issue */
|
||
.issue {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.3rem;
|
||
}
|
||
.issue .headline {
|
||
font-weight: 700;
|
||
font-size: 1.55rem;
|
||
line-height: 1.2;
|
||
color: var(--headline-color);
|
||
}
|
||
.issue .bullets {
|
||
list-style: disc;
|
||
padding-left: 1.6rem;
|
||
font-weight: 400;
|
||
font-size: 1.15rem;
|
||
line-height: 1.55;
|
||
color: #ffffff;
|
||
}
|
||
.issue .bullets li {
|
||
word-break: keep-all;
|
||
}
|
||
|
||
/* TR/BR alignment: text-right */
|
||
.quadrant.tr .issue .headline,
|
||
.quadrant.br .issue .headline {
|
||
text-align: right;
|
||
}
|
||
.quadrant.tr .issue .bullets,
|
||
.quadrant.br .issue .bullets {
|
||
list-style-position: inside;
|
||
padding-left: 0;
|
||
text-align: right;
|
||
}
|
||
|
||
/* 가운데 인용구 (optional, absolute over the grid) */
|
||
.center-quote {
|
||
position: absolute;
|
||
left: 50%; top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 28%;
|
||
aspect-ratio: 1.1;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 5;
|
||
text-align: center;
|
||
font-weight: 700;
|
||
font-size: 1.8rem;
|
||
color: #ffffff;
|
||
background-color: rgba(40, 91, 74, 0.95);
|
||
box-shadow: 0 0 30px rgba(0,0,0,0.5);
|
||
pointer-events: none;
|
||
overflow: hidden;
|
||
}
|
||
.center-quote img {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%; height: 100%;
|
||
object-fit: cover;
|
||
border-radius: 50%;
|
||
}
|
||
.center-quote .text {
|
||
position: relative;
|
||
z-index: 2;
|
||
padding: 0 1rem;
|
||
line-height: 1.15;
|
||
white-space: pre-line;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="block">
|
||
{% set positions = [('tl', 0), ('tr', 1), ('bl', 2), ('br', 3)] %}
|
||
{% for pos, idx in positions %}
|
||
{% set q = quadrants[idx] %}
|
||
<div class="quadrant {{ pos }}">
|
||
<div class="q-header">{{ q.label }}</div>
|
||
<div class="q-body">
|
||
{% for issue in q.issues %}
|
||
<div class="issue">
|
||
<div class="headline">{{ issue.headline }}</div>
|
||
<ul class="bullets">
|
||
{% for b in issue.bullets %}<li>{{ b }}</li>{% endfor %}
|
||
</ul>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
|
||
{% if center_quote %}
|
||
<div class="center-quote">
|
||
{% if center_quote.image %}<img src="{{ center_quote.image }}" alt="">{% endif %}
|
||
<div class="text">{{ center_quote.text }}</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|