Untitled
unknown
plain_text
a month ago
30 kB
5
Indexable
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.platypus import Paragraph, Frame, BaseDocTemplate, PageTemplate
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
import textwrap
W, H = A4
PINK = colors.HexColor("#B91372")
SAGE = colors.HexColor("#B0C0BC")
BLACK = colors.HexColor("#111111")
GRAY = colors.HexColor("#555555")
LGRAY = colors.HexColor("#EEEEEE")
WHITE = colors.white
OFFWHITE= colors.HexColor("#F8F8F6")
MARGIN_L = 2.2*cm
MARGIN_R = 2.2*cm
MARGIN_T = 2.2*cm
MARGIN_B = 2.0*cm
COL_W = W - MARGIN_L - MARGIN_R
def draw_page_footer(c, page_num, section=""):
c.saveState()
y = MARGIN_B - 8*mm
c.setStrokeColor(LGRAY)
c.setLineWidth(0.4)
c.line(MARGIN_L, MARGIN_B - 2*mm, W - MARGIN_R, MARGIN_B - 2*mm)
c.setFont("Helvetica", 7)
c.setFillColor(GRAY)
if section:
c.drawString(MARGIN_L, y, section.upper())
c.drawRightString(W - MARGIN_R, y, f"{page_num}")
c.restoreState()
def draw_page_header(c, right_text=""):
c.saveState()
y = H - MARGIN_T + 3*mm
c.setStrokeColor(PINK)
c.setLineWidth(1.2)
c.line(MARGIN_L, H - MARGIN_T + 1*mm, MARGIN_L + 8*mm, H - MARGIN_T + 1*mm)
c.setFont("Helvetica-Bold", 7)
c.setFillColor(PINK)
c.drawString(MARGIN_L + 10*mm, H - MARGIN_T + 0.5*mm, "VIDEO REELS")
if right_text:
c.setFont("Helvetica", 7)
c.setFillColor(GRAY)
c.drawRightString(W - MARGIN_R, H - MARGIN_T + 0.5*mm, right_text)
c.restoreState()
def wrap_text(c, text, x, y, max_width, font, size, color, line_height, max_lines=99):
c.setFont(font, size)
c.setFillColor(color)
words = text.split()
lines = []
cur = ""
for w in words:
test = (cur + " " + w).strip()
if c.stringWidth(test, font, size) <= max_width:
cur = test
else:
if cur:
lines.append(cur)
cur = w
if cur:
lines.append(cur)
drawn = 0
for line in lines[:max_lines]:
c.drawString(x, y - drawn * line_height, line)
drawn += 1
return y - drawn * line_height
def text_height(c, text, max_width, font, size, line_height):
words = text.split()
lines = 0
cur = ""
for w in words:
test = (cur + " " + w).strip()
if c.stringWidth(test, font, size) <= max_width:
cur = test
else:
if cur:
lines += 1
cur = w
if cur:
lines += 1
return lines * line_height
def draw_label_pill(c, x, y, text, bg, fg, font_size=6.5):
w = c.stringWidth(text, "Helvetica-Bold", font_size) + 10
h = 11
c.setFillColor(bg)
c.roundRect(x, y - 2, w, h, 3, fill=1, stroke=0)
c.setFillColor(fg)
c.setFont("Helvetica-Bold", font_size)
c.drawString(x + 5, y + 1, text)
return w + 4
def draw_reel_block(c, page_num, reel_num, title, sub, badge,
meta, hook, prob, sol, cta, tip,
section_label="DEO 1 — TEMATSKI REELS"):
c.showPage()
draw_page_header(c, right_text=sub)
draw_page_footer(c, page_num, section_label)
x = MARGIN_L
y = H - MARGIN_T - 6*mm
# Big number + title block
# Number in pink, huge
c.setFont("Helvetica-Bold", 72)
c.setFillColor(LGRAY)
num_str = f"0{reel_num}" if reel_num < 10 else str(reel_num)
c.drawString(x, y - 50, num_str)
# Pink vertical bar
c.setFillColor(PINK)
c.rect(x + 38*mm, y - 58, 3, 62, fill=1, stroke=0)
# Title
title_x = x + 41*mm
title_w = COL_W - 41*mm
c.setFont("Helvetica-Bold", 17)
c.setFillColor(BLACK)
# wrap title
words = title.split()
lines = []
cur = ""
for w in words:
test = (cur+" "+w).strip()
if c.stringWidth(test, "Helvetica-Bold", 17) <= title_w:
cur = test
else:
lines.append(cur); cur = w
if cur: lines.append(cur)
ty = y - 14
for line in lines[:3]:
c.drawString(title_x, ty, line)
ty -= 21
# Badge pill
draw_label_pill(c, title_x, ty - 2, badge, PINK, WHITE)
y = y - 70
# Horizontal rule
c.setStrokeColor(LGRAY)
c.setLineWidth(0.4)
c.line(x, y, x + COL_W, y)
y -= 8
# Meta row — 3 columns
meta_labels = ["Trajanje", "Publika", "Tema"]
col_w3 = COL_W / 3
for i, (val, lbl) in enumerate(zip(meta, meta_labels)):
mx = x + i * col_w3
c.setFont("Helvetica", 7)
c.setFillColor(GRAY)
c.drawString(mx, y, lbl.upper())
c.setFont("Helvetica-Bold", 9)
c.setFillColor(BLACK)
c.drawString(mx, y - 11, val)
if i < 2:
c.setStrokeColor(LGRAY)
c.setLineWidth(0.4)
c.line(mx + col_w3 - 8, y + 2, mx + col_w3 - 8, y - 13)
y -= 26
c.setStrokeColor(LGRAY)
c.setLineWidth(0.4)
c.line(x, y, x + COL_W, y)
y -= 14
# Content sections — 2 column layout
# Left col: labels, right col wider: text
lbl_w = 28*mm
cnt_x = x + lbl_w + 4*mm
cnt_w = COL_W - lbl_w - 4*mm
sections = [
("HOOK", "0–3 sec", hook, PINK),
("PROBLEM", "3–10 sec", prob, SAGE),
("RESENJE", "10–45 sec", sol, BLACK),
("CTA", "poslednje 5 sec", cta, PINK),
]
for sec_name, sec_time, sec_text, sec_color in sections:
# Label column
c.setFont("Helvetica-Bold", 8)
c.setFillColor(sec_color)
c.drawString(x, y, sec_name)
c.setFont("Helvetica", 7)
c.setFillColor(GRAY)
c.drawString(x, y - 11, sec_time)
# Thin vertical accent line
c.setStrokeColor(sec_color)
c.setLineWidth(1.5)
# Content text — measure height first
lh = 13
h_est = text_height(c, sec_text, cnt_w, "Helvetica", 9, lh)
block_h = max(h_est + 6, 28)
c.line(cnt_x - 5, y + 4, cnt_x - 5, y - block_h + 8)
# Draw text
wrap_text(c, sec_text, cnt_x, y, cnt_w, "Helvetica", 9, BLACK, lh)
y -= block_h + 8
# Divider
c.setStrokeColor(LGRAY)
c.setLineWidth(0.3)
c.line(x, y + 2, x + COL_W, y + 2)
y -= 6
# Vizual tip — sage background bar
tip_h = max(text_height(c, f"Vizual: {tip}", COL_W - 20, "Helvetica-Oblique", 8, 12) + 14, 26)
c.setFillColor(colors.HexColor("#EEF2F1"))
c.rect(x, y - tip_h + 8, COL_W, tip_h, fill=1, stroke=0)
c.setFillColor(SAGE)
c.rect(x, y - tip_h + 8, 3, tip_h, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 7)
c.setFillColor(colors.HexColor("#6A8480"))
c.drawString(x + 8, y, "VIZUAL / SNIMANJE")
wrap_text(c, f"— {tip}", x + 8, y - 11, COL_W - 16, "Helvetica-Oblique", 8, GRAY, 12)
def draw_faq_block(c, page_num, faq_num, tema, question, badge,
hook, odg, cta, tip, accent,
section_label="DEO 2 — FAQ REELS"):
c.showPage()
draw_page_header(c, right_text=f"FAQ {faq_num} — {tema}")
draw_page_footer(c, page_num, section_label)
x = MARGIN_L
y = H - MARGIN_T - 6*mm
# Tema badge top-left
draw_label_pill(c, x, y + 2, tema.upper(), SAGE, colors.HexColor("#2C4440"), font_size=6.5)
draw_label_pill(c, x + 28*mm, y + 2, badge, PINK, WHITE, font_size=6.5)
y -= 10
# Big FAQ label
c.setFont("Helvetica-Bold", 9)
c.setFillColor(GRAY)
c.drawString(x, y, f"PITANJE #{faq_num}")
y -= 5
# Question as editorial pullquote
c.setStrokeColor(PINK)
c.setLineWidth(2.5)
c.line(x, y - 2, x, y - 46)
c.setFont("Helvetica-BoldOblique", 13)
c.setFillColor(BLACK)
qw = COL_W - 10*mm
qx = x + 6*mm
words = question.split()
lines = []; cur = ""
for w in words:
test = (cur+" "+w).strip()
if c.stringWidth(test, "Helvetica-BoldOblique", 13) <= qw:
cur = test
else:
lines.append(cur); cur = w
if cur: lines.append(cur)
qy = y - 4
for ln in lines[:3]:
c.drawString(qx, qy, ln); qy -= 17
y = qy - 8
# Horizontal rule
c.setStrokeColor(LGRAY)
c.setLineWidth(0.4)
c.line(x, y, x + COL_W, y)
y -= 14
lbl_w = 32*mm
cnt_x = x + lbl_w + 4*mm
cnt_w = COL_W - lbl_w - 4*mm
lh = 13
sections = [
("HOOK", "0–3 sec", hook, PINK),
("ODGOVOR", "3–40 sec", odg, SAGE),
("CTA", "poslednje 5 sec", cta, PINK),
]
for sec_name, sec_time, sec_text, sec_color in sections:
c.setFont("Helvetica-Bold", 8)
c.setFillColor(sec_color)
c.drawString(x, y, sec_name)
c.setFont("Helvetica", 7)
c.setFillColor(GRAY)
c.drawString(x, y - 11, sec_time)
c.setStrokeColor(sec_color)
c.setLineWidth(1.5)
h_est = text_height(c, sec_text, cnt_w, "Helvetica", 9, lh)
block_h = max(h_est + 6, 28)
c.line(cnt_x - 5, y + 4, cnt_x - 5, y - block_h + 8)
wrap_text(c, sec_text, cnt_x, y, cnt_w, "Helvetica", 9, BLACK, lh)
y -= block_h + 8
c.setStrokeColor(LGRAY)
c.setLineWidth(0.3)
c.line(x, y + 2, x + COL_W, y + 2)
y -= 6
tip_h = max(text_height(c, f"Vizual: {tip}", COL_W - 20, "Helvetica-Oblique", 8, 12) + 14, 26)
c.setFillColor(colors.HexColor("#EEF2F1"))
c.rect(x, y - tip_h + 8, COL_W, tip_h, fill=1, stroke=0)
c.setFillColor(SAGE)
c.rect(x, y - tip_h + 8, 3, tip_h, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 7)
c.setFillColor(colors.HexColor("#6A8480"))
c.drawString(x + 8, y, "VIZUAL / SNIMANJE")
wrap_text(c, f"— {tip}", x + 8, y - 11, COL_W - 16, "Helvetica-Oblique", 8, GRAY, 12)
def draw_cover(c):
c.saveState()
# Full bleed top band
band_h = H * 0.52
c.setFillColor(BLACK)
c.rect(0, H - band_h, W, band_h, fill=1, stroke=0)
# Pink accent horizontal bar
c.setFillColor(PINK)
c.rect(0, H - band_h + 0, W, 6, fill=1, stroke=0)
# Sage thin bar top
c.setFillColor(SAGE)
c.rect(0, H - 4, W, 4, fill=1, stroke=0)
# Big number background — faint
c.setFont("Helvetica-Bold", 260)
c.setFillColor(colors.HexColor("#1A1A1A"))
c.drawString(-8, H - band_h + 10, "13")
# Title
c.setFont("Helvetica-Bold", 38)
c.setFillColor(WHITE)
c.drawString(MARGIN_L, H - MARGIN_T - 28, "VIDEO REELS")
c.setFont("Helvetica-Bold", 38)
c.setFillColor(PINK)
c.drawString(MARGIN_L, H - MARGIN_T - 66, "SKRIPTE")
c.setFont("Helvetica", 13)
c.setFillColor(SAGE)
c.drawString(MARGIN_L, H - MARGIN_T - 90, "Ortodontska ordinacija · Beograd")
# Divider line
c.setStrokeColor(SAGE)
c.setLineWidth(0.6)
c.line(MARGIN_L, H - band_h + 30, W - MARGIN_R, H - band_h + 30)
# Below band — content summary
y = H - band_h - 18
c.setFont("Helvetica-Bold", 11)
c.setFillColor(BLACK)
c.drawString(MARGIN_L, y, "Sadrzaj dokumenta")
y -= 18
items = [
("DEO 1", "5 tematskih reels klipova", "Materijali, folije, fiksni aparat, vrednost cene"),
("DEO 2", "8 FAQ reels klipova", "Doktorka odgovara na pitanja pacijenata"),
("DEO 3", "Saveti za snimanje", "Ton, ritam objave, b-roll, interakcija"),
]
for code, heading, detail in items:
draw_label_pill(c, MARGIN_L, y + 2, code, PINK, WHITE, 7)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(BLACK)
c.drawString(MARGIN_L + 18*mm, y, heading)
c.setFont("Helvetica", 8.5)
c.setFillColor(GRAY)
c.drawString(MARGIN_L + 18*mm, y - 12, detail)
y -= 32
y -= 6
c.setStrokeColor(LGRAY)
c.setLineWidth(0.4)
c.line(MARGIN_L, y, W - MARGIN_R, y)
y -= 18
# Format legend
c.setFont("Helvetica-Bold", 8)
c.setFillColor(BLACK)
c.drawString(MARGIN_L, y, "Format svake skripte:")
y -= 14
steps = ["HOOK 0-3 sec", "PROBLEM 3-10 sec", "RESENJE 10-45 sec", "CTA 5 sec"]
colors_s = [PINK, SAGE, BLACK, PINK]
sx = MARGIN_L
for step, col in zip(steps, colors_s):
sw = c.stringWidth(step, "Helvetica-Bold", 7.5) + 14
c.setFillColor(col)
c.roundRect(sx, y - 3, sw, 14, 3, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 7.5)
c.drawString(sx + 7, y + 1, step)
sx += sw + 5
# Bottom bar
c.setFillColor(PINK)
c.rect(0, 0, W, 5, fill=1, stroke=0)
c.setFillColor(SAGE)
c.rect(0, 5, W, 2.5, fill=1, stroke=0)
c.restoreState()
def draw_section_divider(c, page_num, num, title, subtitle, count):
c.showPage()
draw_page_footer(c, page_num, "")
x = MARGIN_L
# Left column — big section number
c.setFont("Helvetica-Bold", 120)
c.setFillColor(LGRAY)
c.drawString(x - 4, H/2 - 30, f"0{num}")
# Pink vertical accent
c.setFillColor(PINK)
c.rect(x + 52*mm, H/2 - 55, 4, 80, fill=1, stroke=0)
# Title
tx = x + 58*mm
c.setFont("Helvetica-Bold", 28)
c.setFillColor(BLACK)
c.drawString(tx, H/2 + 28, title)
c.setFont("Helvetica", 11)
c.setFillColor(GRAY)
c.drawString(tx, H/2 + 8, subtitle)
c.setStrokeColor(LGRAY)
c.setLineWidth(0.5)
c.line(tx, H/2 - 2, tx + 80*mm, H/2 - 2)
c.setFont("Helvetica-Bold", 9)
c.setFillColor(PINK)
c.drawString(tx, H/2 - 16, f"{count} SKRIPTA")
# Bottom sage bar
c.setFillColor(colors.HexColor("#EEF2F1"))
c.rect(0, MARGIN_B, W, 22, fill=1, stroke=0)
c.setFillColor(SAGE)
c.rect(0, MARGIN_B, W, 3, fill=1, stroke=0)
def draw_tips_page(c, page_num):
c.showPage()
draw_page_header(c, right_text="Saveti za snimanje i objavu")
draw_page_footer(c, page_num, "DEO 3 — PRODUKCIJA")
x = MARGIN_L
y = H - MARGIN_T - 8*mm
c.setFont("Helvetica-Bold", 22)
c.setFillColor(BLACK)
c.drawString(x, y, "Saveti za snimanje")
c.setFillColor(PINK)
c.rect(x, y - 5, 14*mm, 2.5, fill=1, stroke=0)
y -= 24
tips = [
("Ton nastupa",
"Miran, strucan, direktan — kao razgovor jedan na jedan s pacijentom. Bez reklamnog prizvuka. Doktorka govori u prvom licu gledajuci u kameru."),
("Tekst overlay",
"Dodati captions za kljucne recenice jer veliki deo publike gleda bez zvuka. Font treba da bude citljiv i kontrastan na pozadini."),
("B-roll materijal",
"Snimati detalje: ruke doktorke, instrumenti, materijali, modeli vilice, aparat na zubu. Ovi kadrovi drze vizuelnu paznju tokom govora."),
("Ritam objave",
"Preporuceno: 1 tematski reel + 1 FAQ reel nedeljno. Konstantnost je vaznija od frekvencije — bolje 2 kvalitetna klipa nego 5 brzinskih."),
("Interakcija s publikom",
"Odgovarati na komentare u prvih sat vremena od objave — algoritam nagraduje povecanjem dosega. Koristiti komentare kao inspiraciju za sledeci FAQ."),
("Pre / posle format",
"Sledeci korak za razvoj profila: serija pre/posle klipova s pacijentima (uz saglasnost). Ovaj format ima visok viralni potencijal."),
]
col2_x = x + COL_W / 2 + 5*mm
col_w2 = COL_W / 2 - 5*mm
for i, (heading, text) in enumerate(tips):
col_x = x if i % 2 == 0 else col2_x
cw = COL_W / 2 - 5*mm
if i % 2 == 0 and i > 0:
y -= max(
text_height(c, tips[i-2][1], cw, "Helvetica", 9, 13) + 36,
text_height(c, tips[i-1][1], cw, "Helvetica", 9, 13) + 36,
)
# Number circle
c.setFillColor(PINK)
c.circle(col_x + 5*mm, y - 1, 5*mm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(WHITE)
c.drawCentredString(col_x + 5*mm, y - 4, str(i + 1))
c.setFont("Helvetica-Bold", 10)
c.setFillColor(BLACK)
c.drawString(col_x + 12*mm, y, heading)
th = text_height(c, text, cw - 12*mm, "Helvetica", 9, 13)
wrap_text(c, text, col_x + 12*mm, y - 13, cw - 12*mm, "Helvetica", 9, GRAY, 13)
# Sage underline
c.setStrokeColor(SAGE)
c.setLineWidth(0.5)
c.line(col_x, y - th - 20, col_x + cw, y - th - 20)
REELS_DATA = [
dict(
reel_num=1, title="Gumica koja ne traje do sledeceg pregleda",
sub="Fiksni aparat | Materijali | 30-45 sec",
badge="VIRALNI POTENCIJAL",
meta=["30-45 sec", "Pacijenti s aparatom", "Fiksni"],
hook='"Znas li zasto ti gumica puca pre nego sto dodjes na kontrolu?"',
prob='"Mnogi pacijenti dolaze s puknutom gumicom, izblijedjelom bojom ili gumom koja se rastegla za par dana. To nije slucajnost — to je pitanje materijala."',
sol='"Gumice koje koristim moraju da izdrze pritisak svakodnevnog zivota — jelo, pricanje, sport. Biram sertifikovane materijale koji zadrzavaju elasticnost i boju tokom celog perioda izmedju poseta. Jer svaka gumica je deo plana lecenja, ne samo detalj."',
cta='"Ako tvoja gumica ne traje do kontrole — vreme je da postavis prava pitanja. Zapisi u komentar koji problem ti se desava najcesce."',
tip="krupni plan gumice pre/posle · razlicite boje u ordinaciji · doktorka drzi pakovanje",
),
dict(
reel_num=2, title="Sta je zapravo unutar tvoje plombe?",
sub="Restorativna stomatologija | Materijali | 30-45 sec",
badge="EDUKATIVNO",
meta=["30-45 sec", "Sira publika", "Plombe"],
hook='"Nijedna plomba nije ista. I razlika se vidi — ali ne odmah."',
prob='"Pacijenti najcesce ne znaju od cega je plomba napravljena. Ali taj materijal direktno utice na koliko dugo traje, koliko dobro se lepi za zub i da li ce se rubovi s vremenom raspadnuti."',
sol='"Kompozitni materijali koje koristim su sertifikovani i testirani za dugotrajnost. Biram ih prema lokaciji zuba, velicini kaviteta i tvojim potrebama. Plomba nije samo punjenje — to je rekonstrukcija dela zuba koja mora da izdrzi zvakanje godinama."',
cta='"Kad si poslednji put pitao/la sta je u tvojoj plombi? Pitaj — to je tvoj zub. Sacuvaj ovaj video za sledecu posetu."',
tip="prikaz materijala u ruci · close-up postupka · pre-posle rendgen",
),
dict(
reel_num=3, title="Bravice i zice nisu sve iste",
sub="Fiksna ortodontija | Efikasnost lecenja | 30-45 sec",
badge="TRUST-BUILDER",
meta=["30-45 sec", "Pacijenti s fiksnim", "Ortodontija"],
hook='"Dva pacijenta, isti problem, iste godine nosenja aparata — potpuno razliciti rezultati. Znas zasto?"',
prob='"Bravice i zice su srce svakog fiksnog aparata. Kvalitet materijala direktno odredjuje koliko precizno se zub pomera, koliko brzo i da li uopste ide u pravom smeru."',
sol='"Radim iskljucivo s proverenim brendovima cije su karakteristike merljive i predvidive. To mi omogucuje da kontrolisem silu pritiska na svaki zub posebno. Jer ortodontija nije samo estetika — to je precizna mehanika. Materijal je osnova svega."',
cta='"Imas pitanje o svom aparatu? Posalji mi poruku ili ostavi komentar. Zaprati za jos ortodontskih detalja koje niko ne prica."',
tip="prikaz zice u bravici · close-up razlicitih tipova bravica · doktorka pokazuje na modelu",
),
dict(
reel_num=4, title="Zasto folija ima cenu — i zasto to vredi",
sub="GRAPHY providne folije | Cena vs. vrednost | 45-60 sec",
badge="CENA = VREDNOST",
meta=["45-60 sec", "Odrasli 25-45g", "GRAPHY folije"],
hook='"Zasto je ovo skuplje? — Ovo je odgovor koji svaki pacijent zasluzuje da cuje."',
prob='"Kada pricamo o providnim folijama za ispravljanje zuba, cena varira. Ali retko ko objasni sta se krije iza te razlike."',
sol='"Radim s GRAPHY folijama — brendom namenjenim profesionalcima koji sami izradjuju folije u ordinaciji. Materijal je sertifikovan i precizno kontrolisan. Svaku foliju izradim sama, na osnovu detaljnog plana lecenja. Godinama prisustvujem kongresima od Brazila do Evrope — ta znanja koristim svakodnevno."',
cta='"Ako razmatras ispravljanje zuba — razgovaraj sa mnom pre nego sto odlucis. Link za konsultacije je u biju."',
tip="proces izrade folije · doktorka za masinom · pre-posle pacijenta · sertifikat ili kongres fotografija",
),
dict(
reel_num=5, title="Moji radovi na svetskim kongresima",
sub="Autoritet | Strucnost | Personal brand | 30-45 sec",
badge="PERSONAL BRAND",
meta=["30-45 sec", "Svi", "Autoritet"],
hook='"Moji radovi su prikazani u Brazilu, sirom Evrope — i sledeci pacijent kojim se ponosim mozes biti ti."',
prob='"Ortodontija se razvija brze nego sto mnogi misle. Ono sto je bilo standard pre pet godina — danas nije dovoljno."',
sol='"Redovno prisustvujem medjunarodnim kongresima kao aktivni ucesnik — ne samo slusalac. Moji klinicki radovi se prezentuju kolegama iz celog sveta. To me tera da stalno unapredjujem tehnike i materijale. Ta ulaganja direktno se vide u rezultatima mojih pacijenata u Beogradu."',
cta='"Zaprati da pratIs moj rad. Ili mi pisi direktno — konsultacija je uvek prvi korak. Beograd."',
tip="fotografije s kongresa · poster prezentacija · B-roll putovanja + ordinacije · doktorka govori u kameru",
),
]
FAQ_DATA = [
dict(
faq_num=1, tema="Fiksni aparat",
question='"Zasto mi gumica toliko brzo puca?"',
badge="VIRALNI POTENCIJAL",
hook='"Pacijentkinja me pitala: Doktorice, zasto mi gumica puca pre kontrole? Odgovor je jednostavan — ali ga retko ko cuje."',
odg='"Gumica na aparatu nije dekoracija — ona prenosi silu koja pomera zub. Ako popusti ili izgubi elasticnost, taj zub ne ide tamo gde treba. Koristim gumice koje su testirane na izdrzljivost i zadrzavaju svoja svojstva tokom celog perioda izmedju poseta. Jer jedan pokindan element moze usporiti citav plan lecenja."',
cta='"Desava li ti se ovo? Napisi u komentar — i zaprati jer svake nedelje odgovaram na prava pitanja pacijenata."',
tip="krupni plan gumice na bravici · doktorka drzi novu vs. staru gumicu · prikaz na modelu vilice",
accent=PINK,
),
dict(
faq_num=2, tema="Materijali",
question='"Da li je vazno od cega je napravljena plomba?"',
badge="EDUKATIVNO",
hook='"Pa sta ima veze od cega je plomba, svejedno je. — Cujem ovo cesto. I svaki put odgovorim isto."',
odg='"Plomba je direktna rekonstrukcija dela zuba. Materijal odredjuje koliko dobro se veze za zubnu strukturu, koliko podnosi pritisak zvakanja i da li ce rubovi s godinama popustiti. Biram kompozitne materijale prema lokaciji i velicini kaviteta — nije ista situacija prednji zub i kutnjak koji zvace svaki dan."',
cta='"Sacuvaj ovaj video pre sledece posete stomatologu. I slobodno pitaj svog doktora od cega je tvoja plomba — pravo je da znas."',
tip="doktorka pokazuje dve vrste materijala · close-up plombe pre/posle · prikaz na rendgenu",
accent=SAGE,
),
dict(
faq_num=3, tema="Folije",
question='"Kako se folije razlikuju od fiksnog aparata?"',
badge="ODLUKA O TRETMANU",
hook='"Folije ili fiksni — sta je bolje? Ovo je najcesce pitanje na prvom pregledu. Evo iskrenog odgovora."',
odg='"Oba sistema mogu dati odlicne rezultate — ali nisu za iste situacije. Fiksni aparat daje direktnu kontrolu nad svakim zubom i idealan je za kompleksnije korekcije. Providne folije su diskretnije, skidaju se za vreme obroka i higijene, i daju odlicne rezultate kod odredjenih nepravilnosti. Ono sto odredjuje koji sistem je pravi za tebe jeste detaljna analiza tvog zagrizaja, polozaja zuba i tvojih ciljeva."',
cta='"Razmisljas o ispravljanju zuba ali nisi siguran/a koji put? Posalji mi poruku — link za konsultaciju je u biju."',
tip="bravica vs. folija paralelno · doktorka drzi obe opcije · animirani prikaz razlike",
accent=PINK,
),
dict(
faq_num=4, tema="Cena i vrednost",
question='"Zasto je ortodontija skupa?"',
badge="TRUST-BUILDER",
hook='"Zasto je ovo toliko skupo? Ovo pitanje zasluzuje pravi odgovor — ne marketinsku frazu."',
odg='"Ortodontski tretman nije jednokratna intervencija — to je proces koji traje mesecima ili godinama. Cena ukljucuje: kvalitet materijala koji svakodnevno rade u tvojim ustima, preciznost planiranja svakog koraka, vreme i znanje ulozeno u pracenje tvog napretka. Kada biram materijale, biram sertifikovane, predvidive i testirane. To je investicija koja se meri trajnoscu rezultata."',
cta='"Imas pitanje o ceni ili procesu? Pisi mi direktno — uvek odgovorim. Sacuvaj za kad budEs odlucivao/la."',
tip="doktorka govori direktno u kameru · prikaz sertifikata/materijala · pre/posle pacijenta",
accent=SAGE,
),
dict(
faq_num=5, tema="Fiksni aparat",
question='"Koliko dugo treba nositi aparat?"',
badge="CESTA DILEMA",
hook='"Koliko dugo cu nositi aparat? Svi pitaju. I svi dobijaju isti odgovor koji zapravo ne znaci nista — zavisi. Evo sta zapravo zavisi."',
odg='"Trajanje lecenja zavisi od tri stvari: slozEnosti nepravilnosti, biologije pacijenta — jer svako telo reaguje drugacije na pritisak — i od toga koliko se pacijent drzi preporuka. Kvalitet materijala i preciznost planiranja direktno uticu na efikasnost. Dobro postavljen plan s pravim materijalima znaci manje korekcija i predvidiviji tok lecenja."',
cta='"Nosis aparat i imas pitanja? Ostavi komentar ili mi pisi — tu sam. Zaprati za nedeljne odgovore na FAQ."',
tip="timeline grafik lecenja (tekst overlay) · doktorka za stolom s modelom vilice · pre/posle serija",
accent=PINK,
),
dict(
faq_num=6, tema="Folije",
question='"Da li folije bole?"',
badge="STRAH U POVERENJE",
hook='"Da li folije bole? — Ovo je strah broj jedan. Odgovaram iskreno."',
odg='"Svaka nova folija vrsi blagi pritisak jer pomera zube u novu poziciju — to je njen posao. Prvih 24-48 sati uz novu foliju moze biti osecaj stezanja ili blagog nelagodja. To je znak da materijal radi. Folije koje koristim su napravljene od sertifikovanog materijala precizno kalibriranih debljina — sto znaci kontrolisanu silu, ne nasilni pritisak."',
cta='"Imas strah od bola koji te sprecava da krenes? Napisi mi — razgovor kosta nula. Link u biju."',
tip="doktorka stavlja foliju na model · prikaz debljine folije · smirujuci kadar ordinacije",
accent=SAGE,
),
dict(
faq_num=7, tema="Materijali",
question='"Da li su materijali u aparatu bezbedni?"',
badge="POVERENJE",
hook='"Jesu li materijali u aparatu bezbedni — gde su napravljeni? Dobro pitanje. Zasluzuje direktan odgovor."',
odg='"Svaki materijal koji koristim — od bravice do folije do kompozita — mora imati sertifikat o biokompatibilnosti. To znaci da je testiran i odobren za upotrebu u usnoj duplji. Ne biram materijale po ceni — biram ih po poreklu, sertifikaciji i proverenoj klinickoj primeni. Jer sta god stavim u usta svog pacijenta, stoji tamo mesecima. Tu nema kompromisa."',
cta='"Slobodno pitaj svog ortodonta da ti pokaze sertifikate materijala — to je tvoje pravo kao pacijent. Sacuvaj i podeli."',
tip="doktorka drzi pakovanje s vidljivim sertifikatom · close-up CE oznake · prikaz originalnog ambalaze",
accent=PINK,
),
dict(
faq_num=8, tema="Opsthe",
question='"Zasto idete na kongrese ako ste vec doktor?"',
badge="AUTORITET",
hook='"Pacijentkinja me upitala: Zasto idete na kongrese u Brazil ako ste vec doktor? Zavolela sam to pitanje."',
odg='"Ortodontija se razvija brze nego sto mnogi misle. Novi materijali, nove tehnike, novi naucni dokazi o tome kako zubi i kosti reaguju na pritisak — sve to se menja. Idem na kongrese jer ne mogu sebi da dozvolim da radim po znanju od pre pet godina. I ne idem samo da slusam — moji klinicki radovi se tamo prezentuju. To me tera da budem u formi i da svaki tretman mogu da branim pred kolegama s celog sveta."',
cta='"Zaprati da vidIs sta donosim sa sledeceg kongresa. Imas pitanje koje niko nije odgovorio — pisi mi."',
tip="foto/video s kongresa · poster s imenom doktorke · kadar avion/sala · ordinacija posle povratka",
accent=SAGE,
),
]
def build():
OUTPUT = "/mnt/user-data/outputs/skripte_ordinacija_magazine.pdf"
c = canvas.Canvas(OUTPUT, pagesize=A4)
c.setTitle("Video Reels Skripte — Ortodontska ordinacija")
c.setAuthor("Marketing Digital Manager")
page = 1
# Cover
draw_cover(c)
page += 1
# Section 1 divider
draw_section_divider(c, page, 1, "Tematski Reels", "5 tematskih video klipova za drustvene mreze", 5)
page += 1
# Reel pages
for r in REELS_DATA:
draw_reel_block(c, page, **r)
page += 1
# Section 2 divider
draw_section_divider(c, page, 2, "FAQ Reels", "Doktorka odgovara na pitanja pacijenata", 8)
page += 1
# FAQ pages
for f in FAQ_DATA:
draw_faq_block(c, page, **f)
page += 1
# Tips page
draw_tips_page(c, page)
c.save()
print(f"Done: {OUTPUT}")
build()Editor is loading...
Leave a Comment