feat(services/insta-render): card_renderer.py + templates (SP-3)
NAS insta-lab/app/card_renderer.py 이식 + DB 의존성 제거. slate 데이터는 worker가 NAS API에서 fetch해 인자로 전달. 결과 PNG는 INSTA_MEDIA_ROOT (/mnt/nas/webpage/data/insta/)에 직접 저장. Browser pool + Semaphore(1) reuse (동시 Chromium 1개). templates는 NAS와 동기화 (default theme + minimal theme). .gitignore에 services/ 추적 예외 추가 (코드는 추적, .env는 유지). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
55
services/insta-render/templates/default/card.html.j2
Normal file
@@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700;900&display=swap');
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1080px; height: 1350px;
|
||||
font-family: 'Noto Sans KR', sans-serif;
|
||||
background: #F7F7FA; color: #14171A;
|
||||
}
|
||||
.card {
|
||||
width: 1080px; height: 1350px;
|
||||
padding: 80px 72px;
|
||||
display: flex; flex-direction: column; justify-content: space-between;
|
||||
background: linear-gradient(180deg, #FFFFFF 0%, #F7F7FA 100%);
|
||||
border-top: 16px solid {{ accent_color }};
|
||||
}
|
||||
.badge {
|
||||
display: inline-block; padding: 8px 20px; border-radius: 999px;
|
||||
background: {{ accent_color }}; color: #fff;
|
||||
font-size: 28px; font-weight: 700; letter-spacing: -0.02em;
|
||||
}
|
||||
.headline {
|
||||
font-size: {{ 96 if page_type == 'cover' else 72 }}px;
|
||||
font-weight: 900; line-height: 1.15; letter-spacing: -0.04em;
|
||||
margin-top: 32px;
|
||||
}
|
||||
.body {
|
||||
font-size: 40px; font-weight: 400; line-height: 1.55;
|
||||
margin-top: 40px; color: #2A2F35;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.footer {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
font-size: 28px; color: #6B7280; font-weight: 500;
|
||||
}
|
||||
.cta { font-weight: 700; color: {{ accent_color }}; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div>
|
||||
<span class="badge">{{ page_type|upper }}</span>
|
||||
<h1 class="headline">{{ headline }}</h1>
|
||||
<p class="body">{{ body }}</p>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<span>{{ page_no }} / {{ total_pages }}</span>
|
||||
{% if cta %}<span class="cta">{{ cta }}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
788
services/insta-render/templates/minimal/card.html.j2
Normal file
@@ -0,0 +1,788 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Hedgy Card News – {{ page_no }}/10</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;700;900&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
background: #d0d0d0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
font-family: 'Noto Sans KR', sans-serif;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
width: 1080px;
|
||||
height: 1350px;
|
||||
overflow: hidden;
|
||||
border-radius: 48px;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
/* ── shared overlay layer ── */
|
||||
.mask {
|
||||
position: absolute;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 1 insta_card_start.png
|
||||
bg: #f2f2f0 (light warm white)
|
||||
═══════════════════════════════════════════ */
|
||||
.p1-headline-mask {
|
||||
top: 222px; left: 48px;
|
||||
width: 580px; height: 150px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p1-headline-text {
|
||||
position: absolute;
|
||||
top: 222px; left: 48px;
|
||||
width: 580px; height: 150px;
|
||||
padding: 8px;
|
||||
font-size: 108px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p1-body-mask {
|
||||
top: 400px; left: 48px;
|
||||
width: 460px; height: 120px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p1-body-text {
|
||||
position: absolute;
|
||||
top: 400px; left: 48px;
|
||||
width: 460px; height: 120px;
|
||||
padding: 8px;
|
||||
font-size: 34px;
|
||||
font-weight: 500;
|
||||
color: #4a4e5e;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
.p1-cta-mask {
|
||||
top: 562px; left: 48px;
|
||||
width: 260px; height: 76px;
|
||||
background: #2f6ef7;
|
||||
border-radius: 38px;
|
||||
padding: 8px;
|
||||
}
|
||||
.p1-cta-text {
|
||||
position: absolute;
|
||||
top: 562px; left: 48px;
|
||||
width: 260px; height: 76px;
|
||||
border-radius: 38px;
|
||||
padding: 8px 24px;
|
||||
font-size: 34px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 2 insta_card_keyword.png
|
||||
bg: #3a3fdb (blue gradient)
|
||||
═══════════════════════════════════════════ */
|
||||
.p2-headline-mask {
|
||||
top: 148px; left: 56px;
|
||||
width: 880px; height: 200px;
|
||||
background: #3a3fdb;
|
||||
padding: 8px;
|
||||
}
|
||||
.p2-headline-text {
|
||||
position: absolute;
|
||||
top: 148px; left: 56px;
|
||||
width: 880px; height: 200px;
|
||||
padding: 8px;
|
||||
font-size: 88px;
|
||||
font-weight: 900;
|
||||
color: #ffffff;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p2-body-mask {
|
||||
top: 370px; left: 56px;
|
||||
width: 880px; height: 80px;
|
||||
background: #3a3fdb;
|
||||
padding: 8px;
|
||||
}
|
||||
.p2-body-text {
|
||||
position: absolute;
|
||||
top: 370px; left: 56px;
|
||||
width: 880px; height: 80px;
|
||||
padding: 8px;
|
||||
font-size: 38px;
|
||||
font-weight: 500;
|
||||
color: #e0e4ff;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 3 insta_card_highlight.png
|
||||
bg: #3a3fdb
|
||||
═══════════════════════════════════════════ */
|
||||
.p3-headline-mask {
|
||||
top: 148px; left: 56px;
|
||||
width: 880px; height: 260px;
|
||||
background: #3a3fdb;
|
||||
padding: 8px;
|
||||
}
|
||||
.p3-headline-text {
|
||||
position: absolute;
|
||||
top: 148px; left: 56px;
|
||||
width: 880px; height: 260px;
|
||||
padding: 8px;
|
||||
font-size: 88px;
|
||||
font-weight: 900;
|
||||
color: #ffffff;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
.p3-body-mask {
|
||||
top: 430px; left: 56px;
|
||||
width: 880px; height: 80px;
|
||||
background: #3a3fdb;
|
||||
padding: 8px;
|
||||
}
|
||||
.p3-body-text {
|
||||
position: absolute;
|
||||
top: 430px; left: 56px;
|
||||
width: 880px; height: 80px;
|
||||
padding: 8px;
|
||||
font-size: 38px;
|
||||
font-weight: 500;
|
||||
color: #e0e4ff;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 4 insta_card_observation.png
|
||||
bg: #f2f2f0
|
||||
═══════════════════════════════════════════ */
|
||||
.p4-label-mask {
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p4-label-text {
|
||||
position: absolute;
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
padding: 8px;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #2f6ef7;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p4-headline-mask {
|
||||
top: 148px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p4-headline-text {
|
||||
position: absolute;
|
||||
top: 148px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
padding: 8px;
|
||||
font-size: 72px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p4-body-mask {
|
||||
top: 290px; left: 56px;
|
||||
width: 700px; height: 180px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p4-body-text {
|
||||
position: absolute;
|
||||
top: 290px; left: 56px;
|
||||
width: 700px; height: 180px;
|
||||
padding: 8px;
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
color: #3a3e50;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 5 insta_card_memo.png
|
||||
bg: #f2f2f0
|
||||
═══════════════════════════════════════════ */
|
||||
.p5-label-mask {
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p5-label-text {
|
||||
position: absolute;
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
padding: 8px;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #2f6ef7;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p5-headline-mask {
|
||||
top: 160px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p5-headline-text {
|
||||
position: absolute;
|
||||
top: 160px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
padding: 8px;
|
||||
font-size: 70px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p5-body-mask {
|
||||
top: 308px; left: 56px;
|
||||
width: 700px; height: 180px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p5-body-text {
|
||||
position: absolute;
|
||||
top: 308px; left: 56px;
|
||||
width: 700px; height: 180px;
|
||||
padding: 8px;
|
||||
font-size: 34px;
|
||||
font-weight: 400;
|
||||
color: #3a3e50;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 6 insta_card_oneline.png
|
||||
bg: #f5f4f2
|
||||
═══════════════════════════════════════════ */
|
||||
.p6-headline-mask {
|
||||
top: 188px; left: 96px;
|
||||
width: 820px; height: 240px;
|
||||
background: #f5f4f2;
|
||||
padding: 8px;
|
||||
}
|
||||
.p6-headline-text {
|
||||
position: absolute;
|
||||
top: 188px; left: 96px;
|
||||
width: 820px; height: 240px;
|
||||
padding: 8px;
|
||||
font-size: 68px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
.p6-body-mask {
|
||||
top: 448px; left: 96px;
|
||||
width: 620px; height: 120px;
|
||||
background: #f5f4f2;
|
||||
padding: 8px;
|
||||
}
|
||||
.p6-body-text {
|
||||
position: absolute;
|
||||
top: 448px; left: 96px;
|
||||
width: 620px; height: 120px;
|
||||
padding: 8px;
|
||||
font-size: 34px;
|
||||
font-weight: 400;
|
||||
color: #5a5e70;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 7 insta_card_checklist.png
|
||||
bg: #f5f4f2
|
||||
═══════════════════════════════════════════ */
|
||||
.p7-headline-mask {
|
||||
top: 110px; left: 56px;
|
||||
width: 740px; height: 110px;
|
||||
background: #f5f4f2;
|
||||
padding: 8px;
|
||||
}
|
||||
.p7-headline-text {
|
||||
position: absolute;
|
||||
top: 110px; left: 56px;
|
||||
width: 740px; height: 110px;
|
||||
padding: 8px;
|
||||
font-size: 74px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
/* checklist items – 4 rows */
|
||||
.p7-item1-mask { top: 258px; left: 164px; width: 720px; height: 80px; background: #f5f4f2; padding: 8px; }
|
||||
.p7-item1-text { position: absolute; top: 258px; left: 164px; width: 720px; height: 80px; padding: 8px; font-size: 40px; font-weight: 500; color: #2a2d3e; word-wrap: break-word; overflow: hidden; display: flex; align-items: center; }
|
||||
.p7-item2-mask { top: 388px; left: 164px; width: 720px; height: 80px; background: #f5f4f2; padding: 8px; }
|
||||
.p7-item2-text { position: absolute; top: 388px; left: 164px; width: 720px; height: 80px; padding: 8px; font-size: 40px; font-weight: 500; color: #2a2d3e; word-wrap: break-word; overflow: hidden; display: flex; align-items: center; }
|
||||
.p7-item3-mask { top: 518px; left: 164px; width: 720px; height: 80px; background: #f5f4f2; padding: 8px; }
|
||||
.p7-item3-text { position: absolute; top: 518px; left: 164px; width: 720px; height: 80px; padding: 8px; font-size: 40px; font-weight: 500; color: #2a2d3e; word-wrap: break-word; overflow: hidden; display: flex; align-items: center; }
|
||||
.p7-item4-mask { top: 648px; left: 164px; width: 720px; height: 80px; background: #f5f4f2; padding: 8px; }
|
||||
.p7-item4-text { position: absolute; top: 648px; left: 164px; width: 720px; height: 80px; padding: 8px; font-size: 40px; font-weight: 500; color: #2a2d3e; word-wrap: break-word; overflow: hidden; display: flex; align-items: center; }
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 8 insta_card_study.png
|
||||
bg: #f2f2f0
|
||||
═══════════════════════════════════════════ */
|
||||
.p8-label-mask {
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p8-label-text {
|
||||
position: absolute;
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
padding: 8px;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #2f6ef7;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p8-headline-mask {
|
||||
top: 160px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p8-headline-text {
|
||||
position: absolute;
|
||||
top: 160px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
padding: 8px;
|
||||
font-size: 72px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p8-body-mask {
|
||||
top: 306px; left: 56px;
|
||||
width: 700px; height: 180px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p8-body-text {
|
||||
position: absolute;
|
||||
top: 306px; left: 56px;
|
||||
width: 700px; height: 180px;
|
||||
padding: 8px;
|
||||
font-size: 34px;
|
||||
font-weight: 400;
|
||||
color: #3a3e50;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 9 insta_card_cta.png
|
||||
bg: #f5f4f2
|
||||
═══════════════════════════════════════════ */
|
||||
.p9-headline-mask {
|
||||
top: 182px; left: 56px;
|
||||
width: 970px; height: 120px;
|
||||
background: #f5f4f2;
|
||||
padding: 8px;
|
||||
}
|
||||
.p9-headline-text {
|
||||
position: absolute;
|
||||
top: 182px; left: 56px;
|
||||
width: 970px; height: 120px;
|
||||
padding: 8px;
|
||||
font-size: 82px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
.p9-cta-mask {
|
||||
top: 332px; left: 180px;
|
||||
width: 720px; height: 88px;
|
||||
background: #2244cc;
|
||||
border-radius: 44px;
|
||||
padding: 8px;
|
||||
}
|
||||
.p9-cta-text {
|
||||
position: absolute;
|
||||
top: 332px; left: 180px;
|
||||
width: 720px; height: 88px;
|
||||
border-radius: 44px;
|
||||
padding: 8px;
|
||||
font-size: 42px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.p9-body-mask {
|
||||
top: 980px; left: 56px;
|
||||
width: 860px; height: 60px;
|
||||
background: #f5f4f2;
|
||||
padding: 8px;
|
||||
}
|
||||
.p9-body-text {
|
||||
position: absolute;
|
||||
top: 980px; left: 56px;
|
||||
width: 860px; height: 60px;
|
||||
padding: 8px;
|
||||
font-size: 30px;
|
||||
font-weight: 400;
|
||||
color: #5a5e70;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════
|
||||
PAGE 10 insta_card_finish.png
|
||||
bg: #f2f2f0
|
||||
═══════════════════════════════════════════ */
|
||||
.p10-label-mask {
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p10-label-text {
|
||||
position: absolute;
|
||||
top: 72px; left: 64px;
|
||||
width: 200px; height: 52px;
|
||||
padding: 8px;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #2f6ef7;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p10-headline-mask {
|
||||
top: 155px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p10-headline-text {
|
||||
position: absolute;
|
||||
top: 155px; left: 56px;
|
||||
width: 700px; height: 110px;
|
||||
padding: 8px;
|
||||
font-size: 72px;
|
||||
font-weight: 900;
|
||||
color: #1e2235;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.p10-body-mask {
|
||||
top: 302px; left: 56px;
|
||||
width: 680px; height: 180px;
|
||||
background: #f2f2f0;
|
||||
padding: 8px;
|
||||
}
|
||||
.p10-body-text {
|
||||
position: absolute;
|
||||
top: 302px; left: 56px;
|
||||
width: 680px; height: 180px;
|
||||
padding: 8px;
|
||||
font-size: 34px;
|
||||
font-weight: 400;
|
||||
color: #3a3e50;
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* checklist icon (page 7) */
|
||||
.check-icon {
|
||||
position: absolute;
|
||||
width: 76px; height: 76px;
|
||||
background: #3366ee;
|
||||
border-radius: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.check-icon svg { width: 44px; height: 44px; }
|
||||
|
||||
/* quote mark (page 2 & 3) */
|
||||
.quote-mark {
|
||||
position: absolute;
|
||||
font-size: 100px;
|
||||
font-weight: 900;
|
||||
color: #ffffff;
|
||||
line-height: 1;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
/* left bar (page 6) */
|
||||
.left-bar {
|
||||
position: absolute;
|
||||
top: 196px; left: 64px;
|
||||
width: 10px; height: 232px;
|
||||
background: #7c5ce0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% if page_no == 1 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 1 · COVER · insta_card_start.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_start.png');">
|
||||
<!-- headline mask + text -->
|
||||
<div class="mask p1-headline-mask"></div>
|
||||
<div class="mask p1-headline-text">{{ headline }}</div>
|
||||
<!-- body mask + text -->
|
||||
<div class="mask p1-body-mask"></div>
|
||||
<div class="mask p1-body-text">{{ body }}</div>
|
||||
<!-- cta mask + text -->
|
||||
<div class="mask p1-cta-mask"></div>
|
||||
<div class="mask p1-cta-text">{{ cta }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 2 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 2 · insta_card_keyword.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_keyword.png');">
|
||||
<!-- quote mark mask -->
|
||||
<div class="mask" style="top:60px;left:48px;width:120px;height:100px;background:#3a3fdb;padding:8px;"></div>
|
||||
<div class="quote-mark" style="top:52px;left:50px;">"</div>
|
||||
<!-- headline -->
|
||||
<div class="mask p2-headline-mask"></div>
|
||||
<div class="mask p2-headline-text">{{ headline }}</div>
|
||||
<!-- body -->
|
||||
<div class="mask p2-body-mask"></div>
|
||||
<div class="mask p2-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 3 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 3 · insta_card_highlight.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_highlight.png');">
|
||||
<!-- quote mark mask -->
|
||||
<div class="mask" style="top:60px;left:48px;width:120px;height:100px;background:#3a3fdb;padding:8px;"></div>
|
||||
<div class="quote-mark" style="top:52px;left:50px;">"</div>
|
||||
<!-- headline -->
|
||||
<div class="mask p3-headline-mask"></div>
|
||||
<div class="mask p3-headline-text">{{ headline }}</div>
|
||||
<!-- body -->
|
||||
<div class="mask p3-body-mask"></div>
|
||||
<div class="mask p3-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 4 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 4 · insta_card_observation.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_observation.png');">
|
||||
<!-- day label -->
|
||||
<div class="mask p4-label-mask"></div>
|
||||
<div class="mask p4-label-text">{{ label }}</div>
|
||||
<!-- headline -->
|
||||
<div class="mask p4-headline-mask"></div>
|
||||
<div class="mask p4-headline-text">{{ headline }}</div>
|
||||
<!-- body -->
|
||||
<div class="mask p4-body-mask"></div>
|
||||
<div class="mask p4-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 5 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 5 · insta_card_memo.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_memo.png');">
|
||||
<!-- day label -->
|
||||
<div class="mask p5-label-mask"></div>
|
||||
<div class="mask p5-label-text">{{ label }}</div>
|
||||
<!-- headline -->
|
||||
<div class="mask p5-headline-mask"></div>
|
||||
<div class="mask p5-headline-text">{{ headline }}</div>
|
||||
<!-- body -->
|
||||
<div class="mask p5-body-mask"></div>
|
||||
<div class="mask p5-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 6 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 6 · insta_card_oneline.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_oneline.png');">
|
||||
<!-- purple left bar -->
|
||||
<div class="left-bar"></div>
|
||||
<!-- headline -->
|
||||
<div class="mask p6-headline-mask"></div>
|
||||
<div class="mask p6-headline-text">{{ headline }}</div>
|
||||
<!-- body -->
|
||||
<div class="mask p6-body-mask"></div>
|
||||
<div class="mask p6-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 7 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 7 · insta_card_checklist.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_checklist.png');">
|
||||
<!-- section title -->
|
||||
<div class="mask p7-headline-mask"></div>
|
||||
<div class="mask p7-headline-text">{{ headline }}</div>
|
||||
|
||||
<!-- check icons -->
|
||||
<div class="check-icon" style="top:252px;left:56px;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
</div>
|
||||
<div class="check-icon" style="top:382px;left:56px;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
</div>
|
||||
<div class="check-icon" style="top:512px;left:56px;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
</div>
|
||||
<div class="check-icon" style="top:642px;left:56px;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
</div>
|
||||
|
||||
<!-- checklist items -->
|
||||
<div class="mask p7-item1-mask"></div>
|
||||
<div class="mask p7-item1-text">{{ item1 }}</div>
|
||||
<div class="mask p7-item2-mask"></div>
|
||||
<div class="mask p7-item2-text">{{ item2 }}</div>
|
||||
<div class="mask p7-item3-mask"></div>
|
||||
<div class="mask p7-item3-text">{{ item3 }}</div>
|
||||
<div class="mask p7-item4-mask"></div>
|
||||
<div class="mask p7-item4-text">{{ item4 }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 8 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 8 · insta_card_study.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_study.png');">
|
||||
<!-- day label -->
|
||||
<div class="mask p8-label-mask"></div>
|
||||
<div class="mask p8-label-text">{{ label }}</div>
|
||||
<!-- headline -->
|
||||
<div class="mask p8-headline-mask"></div>
|
||||
<div class="mask p8-headline-text">{{ headline }}</div>
|
||||
<!-- body -->
|
||||
<div class="mask p8-body-mask"></div>
|
||||
<div class="mask p8-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 9 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 9 · insta_card_cta.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_cta.png');">
|
||||
<!-- headline -->
|
||||
<div class="mask p9-headline-mask"></div>
|
||||
<div class="mask p9-headline-text">{{ headline }}</div>
|
||||
<!-- cta button -->
|
||||
<div class="mask p9-cta-mask"></div>
|
||||
<div class="mask p9-cta-text">{{ cta }}</div>
|
||||
<!-- body / next episode teaser -->
|
||||
<div class="mask p9-body-mask"></div>
|
||||
<div class="mask p9-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page_no == 10 %}
|
||||
<!-- ══════════════════════════════════════
|
||||
PAGE 10 · insta_card_finish.png
|
||||
══════════════════════════════════════ -->
|
||||
<div class="card" style="background-image: url('pages/insta_card_finish.png');">
|
||||
<!-- day label -->
|
||||
<div class="mask p10-label-mask"></div>
|
||||
<div class="mask p10-label-text">{{ label }}</div>
|
||||
<!-- headline -->
|
||||
<div class="mask p10-headline-mask"></div>
|
||||
<div class="mask p10-headline-text">{{ headline }}</div>
|
||||
<!-- body -->
|
||||
<div class="mask p10-body-mask"></div>
|
||||
<div class="mask p10-body-text">{{ body }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
12
services/insta-render/templates/minimal/pages/_order.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"insta_card_start.png": 1,
|
||||
"insta_card_keyword.png": 2,
|
||||
"insta_card_highlight.png": 3,
|
||||
"insta_card_observation.png": 4,
|
||||
"insta_card_memo.png": 5,
|
||||
"insta_card_oneline.png": 6,
|
||||
"insta_card_checklist.png": 7,
|
||||
"insta_card_study.png": 8,
|
||||
"insta_card_cta.png": 9,
|
||||
"insta_card_finish.png": 10
|
||||
}
|
||||
|
After Width: | Height: | Size: 1010 KiB |
BIN
services/insta-render/templates/minimal/pages/insta_card_cta.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.3 MiB |