Acne and acne scar and tanning
acne treatment acne scars hyperpigmentation tanning dark skin South Asian 2025
acne "skin of color" treatment hyperpigmentation
acne vulgaris "post-inflammatory hyperpigmentation" treatment
| Product | Purpose | How to use |
|---|---|---|
| Gentle face wash (salicylic acid 0.5-1%, e.g., CeraVe SA, Neutrogena) | Unclogs pores, mild exfoliation | Twice daily, lukewarm water |
| Broad-spectrum SPF 30-50 sunscreen (non-comedogenic, matte finish) | Prevents PIH from darkening, prevents new tanning | Every morning, reapply if outdoors |
| Non-comedogenic moisturizer | Skin barrier support | After washing |
Create a printable skincare routine guide I can follow daily
ls -la /home/daytona/workspace/
mkdir -p /home/daytona/workspace/skincare-guide
~/skincare-guide/generate_guide.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import KeepTogether
OUTPUT = "/home/daytona/workspace/skincare-guide/Skincare_Routine_Guide.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
DEEP_TEAL = colors.HexColor("#1A5276")
TEAL = colors.HexColor("#2E86AB")
LIGHT_TEAL = colors.HexColor("#D6EAF8")
AMBER = colors.HexColor("#F39C12")
LIGHT_AMBER = colors.HexColor("#FEF9E7")
SOFT_GRAY = colors.HexColor("#F2F3F4")
DARK_GRAY = colors.HexColor("#2C3E50")
MID_GRAY = colors.HexColor("#626567")
WHITE = colors.white
MORNING_BG = colors.HexColor("#FFF3CD")
NIGHT_BG = colors.HexColor("#D5E8D4")
WEEKLY_BG = colors.HexColor("#E8D5F0")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
topMargin=15*mm,
bottomMargin=15*mm,
leftMargin=18*mm,
rightMargin=18*mm,
)
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, parent=styles["Normal"], **kw)
title_style = S("Title",
fontSize=24, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER, spaceAfter=2)
subtitle_style = S("Sub",
fontSize=11, fontName="Helvetica",
textColor=colors.HexColor("#D6EAF8"), alignment=TA_CENTER, spaceAfter=4)
section_header_style = S("SecH",
fontSize=13, fontName="Helvetica-Bold",
textColor=WHITE, alignment=TA_CENTER, spaceAfter=2)
step_num_style = S("StepNum",
fontSize=14, fontName="Helvetica-Bold",
textColor=DEEP_TEAL, alignment=TA_CENTER)
step_title_style = S("StepTitle",
fontSize=11, fontName="Helvetica-Bold",
textColor=DARK_GRAY)
step_body_style = S("StepBody",
fontSize=9.5, fontName="Helvetica",
textColor=MID_GRAY, leading=13)
tip_style = S("Tip",
fontSize=9, fontName="Helvetica-Oblique",
textColor=colors.HexColor("#6C3483"),
leftIndent=8, leading=13)
note_style = S("Note",
fontSize=9, fontName="Helvetica",
textColor=colors.HexColor("#784212"), leading=13)
small_bold = S("SmBold",
fontSize=8.5, fontName="Helvetica-Bold",
textColor=DARK_GRAY)
checkbox_style = S("CB",
fontSize=10, fontName="Helvetica",
textColor=DARK_GRAY, leading=16)
warn_style = S("Warn",
fontSize=9, fontName="Helvetica-Bold",
textColor=colors.HexColor("#C0392B"), leading=13)
# ── Helpers ─────────────────────────────────────────────────────────────────
def header_block(text, sub=None, bg=DEEP_TEAL):
data = [[Paragraph(text, title_style)]]
if sub:
data.append([Paragraph(sub, subtitle_style)])
t = Table(data, colWidths=[174*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [6]),
]))
return t
def section_banner(text, bg=TEAL):
t = Table([[Paragraph(text, section_header_style)]], colWidths=[174*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
return t
def step_row(num, icon, title, detail, tip=None, bg=SOFT_GRAY):
num_cell = Paragraph(f"{icon}<br/><font color='#1A5276'><b>{num}</b></font>", step_num_style)
body = [Paragraph(title, step_title_style), Spacer(1, 2)]
body.append(Paragraph(detail, step_body_style))
if tip:
body.append(Spacer(1, 3))
body.append(Paragraph(f"<i>Tip: {tip}</i>", tip_style))
body_cell = body
t = Table([[num_cell, body_cell]], colWidths=[18*mm, 156*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (0,-1), 8),
("LEFTPADDING", (1,0), (1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("LINEBELOW", (0,0), (-1,-1), 0.5, colors.HexColor("#D5D8DC")),
]))
return t
def checkbox_table(items, cols=2):
# Build rows
row_data = []
row = []
for i, item in enumerate(items):
row.append(Paragraph(f"<font size=12>\u25a1</font> {item}", checkbox_style))
if len(row) == cols:
row_data.append(row)
row = []
if row:
while len(row) < cols:
row.append(Paragraph("", checkbox_style))
row_data.append(row)
col_w = 174*mm / cols
t = Table(row_data, colWidths=[col_w]*cols)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), WHITE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#D5D8DC")),
]))
return t
def info_box(lines, bg=LIGHT_AMBER):
content = []
for l in lines:
content.append(Paragraph(l, note_style))
t = Table([[content]], colWidths=[174*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 1, AMBER),
]))
return t
def progress_table():
headers = ["Week", "What to expect", "Action"]
rows = [
["1-2", "Mild purging / dryness possible with adapalene", "Reduce to every-other-night if irritated"],
["3-4", "Active breakouts reducing", "Add niacinamide or azelaic acid"],
["6-8", "Skin texture improving, PIH slowly fading", "Stay consistent - do not stop!"],
["10-12","PIH marks visibly lighter, tone more even", "Consider adding Vitamin C serum"],
["16+", "Most PIH cleared, scars improving", "Consult dermatologist for deeper scars"],
]
col_w = [20*mm, 80*mm, 74*mm]
data = [[Paragraph(h, small_bold) for h in headers]] + \
[[Paragraph(str(c), step_body_style) for c in r] for r in rows]
t = Table(data, colWidths=col_w)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DEEP_TEAL),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("BACKGROUND", (0,1), (-1,1), LIGHT_TEAL),
("BACKGROUND", (0,2), (-1,2), WHITE),
("BACKGROUND", (0,3), (-1,3), LIGHT_TEAL),
("BACKGROUND", (0,4), (-1,4), WHITE),
("BACKGROUND", (0,5), (-1,5), LIGHT_TEAL),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BFC9CA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("ALIGN", (0,0), (0,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
# ══════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ══════════════════════════════════════════════════════════════════════════════
story = []
# ── TITLE PAGE HEADER ────────────────────────────────────────────────────────
story.append(header_block(
"Daily Skincare Routine Guide",
sub="Personalised for Acne · Acne Scars · Tanning | South Asian Skin | June 2026"
))
story.append(Spacer(1, 6*mm))
# ── SKIN CONCERNS BOX ────────────────────────────────────────────────────────
story.append(info_box([
"<b>Your Skin Concerns:</b> Active acne (papules/pustules) • Post-inflammatory hyperpigmentation (PIH) • Sun tanning / uneven skin tone",
"<b>Skin type:</b> Fitzpatrick IV-V (South Asian) <b>Key risk:</b> PIH darkens quickly with UV — sunscreen is your #1 tool.",
], bg=LIGHT_TEAL))
story.append(Spacer(1, 5*mm))
# ══ MORNING ROUTINE ══════════════════════════════════════════════════════════
story.append(section_banner("☀ MORNING ROUTINE", bg=colors.HexColor("#E67E22")))
story.append(Spacer(1, 2*mm))
morning_steps = [
("1", "🌊", "Gentle Face Wash",
"Use a mild, non-comedogenic cleanser (e.g. CeraVe Foaming, Cetaphil, or salicylic acid 0.5-1% wash). "
"Wash with lukewarm water for 30-60 seconds. Pat dry — do NOT rub.",
"Cold water as a final rinse tightens pores slightly."),
("2", "✨", "Vitamin C Serum (Optional but recommended)",
"Apply 3-4 drops of a 10-15% L-ascorbic acid or ascorbyl glucoside serum to your face and neck. "
"Wait 30-60 seconds to absorb. Brightens tone, inhibits melanin production, fades tanning.",
"Store Vitamin C serum in the fridge to extend shelf life."),
("3", "💧", "Niacinamide Serum",
"Apply 2-3 drops of 5-10% niacinamide serum (e.g. The Ordinary, Minimalist, or Dot & Key). "
"Gently press into skin. Reduces PIH dark marks, controls sebum, and calms redness.",
"Can be mixed with Vitamin C or applied over it after absorption."),
("4", "🧴", "Lightweight Moisturiser",
"Apply a thin layer of oil-free, non-comedogenic moisturiser (e.g. CeraVe AM, Neutrogena Hydro Boost, "
"Minimalist 10% Niacinamide+). Restores skin barrier — never skip, even if skin feels oily.",
"Gel-based moisturisers work best for oily/combination South Asian skin."),
("5", "🌞", "SPF 30-50 Sunscreen — THE MOST IMPORTANT STEP",
"Apply a generous, even layer of broad-spectrum SPF 30-50 (e.g. La Roche-Posay Anthelios, Re'equil Matte, "
"Neutrogena Ultra Sheer). Cover face, neck, and ears. Reapply every 2 hours if outdoors. "
"Without this, PIH marks cannot fade and tanning worsens.",
"Choose a matte-finish, non-comedogenic formula — avoid thick white-cast sunscreens."),
]
for num, icon, title, detail, tip in morning_steps:
story.append(step_row(num, icon, title, detail, tip, bg=MORNING_BG))
story.append(Spacer(1, 5*mm))
# ── MORNING CHECKLIST ────────────────────────────────────────────────────────
story.append(section_banner("Morning Checklist", bg=colors.HexColor("#CA6F1E")))
story.append(checkbox_table([
"Face wash (30-60 sec)",
"Vitamin C serum",
"Niacinamide serum",
"Moisturiser applied",
"SPF 30-50 sunscreen",
"Reapplied SPF (if outdoors)",
], cols=3))
story.append(Spacer(1, 6*mm))
# ══ NIGHT ROUTINE ════════════════════════════════════════════════════════════
story.append(section_banner("🌙 NIGHT ROUTINE", bg=colors.HexColor("#1E8449")))
story.append(Spacer(1, 2*mm))
night_steps = [
("1", "🧼", "Double Cleanse (if wore sunscreen)",
"First cleanse: Use a gentle micellar water or cleansing oil to remove sunscreen fully. "
"Second cleanse: Same gentle face wash as morning. Removing sunscreen properly prevents clogged pores.",
"If you stayed indoors all day without sunscreen, a single cleanse is fine."),
("2", "⚗️", "Azelaic Acid 10-20% (Weeks 1-8)",
"Apply a thin layer of azelaic acid gel/cream (e.g. Paula's Choice, Minimalist, The Ordinary) to the whole face. "
"Wait 5-10 mins to absorb. Dual action: treats active acne AND fades PIH marks. Very well-tolerated.",
"Start with every other night for the first week if your skin is sensitive."),
("3", "🔬", "Adapalene 0.1% Gel — Retinoid (Week 3+)",
"After azelaic acid has absorbed, apply a pea-sized amount of adapalene 0.1% gel (e.g. Differin) "
"to the whole face. Avoid eye area and lips. Unclogs pores, prevents new acne, speeds PIH fading. "
"START slowly: every other night for the first 2 weeks, then nightly.",
"NEVER use both adapalene AND azelaic acid on the same night until your skin is fully adjusted (4+ weeks)."),
("4", "🧴", "Moisturiser — Barrier Repair",
"Apply a slightly richer moisturiser at night (e.g. CeraVe Moisturising Cream, Vanicream, or Sebamed). "
"Lock in hydration and support barrier recovery overnight. "
"Retinoids and azelaic acid can cause dryness — moisturiser prevents this.",
"If skin is very dry from adapalene, apply moisturiser BEFORE adapalene (sandwich method)."),
]
for num, icon, title, detail, tip in night_steps:
story.append(step_row(num, icon, title, detail, tip, bg=NIGHT_BG))
story.append(Spacer(1, 5*mm))
# ── NIGHT CHECKLIST ──────────────────────────────────────────────────────────
story.append(section_banner("Night Checklist", bg=colors.HexColor("#1A5276")))
story.append(checkbox_table([
"Double cleanse (remove SPF)",
"Azelaic acid applied",
"Adapalene (pea size, whole face)",
"Night moisturiser applied",
"Did NOT pick / squeeze pimples",
"Changed pillowcase (weekly)",
], cols=3))
story.append(Spacer(1, 6*mm))
# ══ WEEKLY TREATMENTS ════════════════════════════════════════════════════════
story.append(section_banner("📅 WEEKLY TREATMENTS", bg=colors.HexColor("#7D3C98")))
story.append(Spacer(1, 2*mm))
weekly_steps = [
("2-3x", "🧂", "Gentle Exfoliation (BHA)",
"Use a salicylic acid toner (2%) or gentle exfoliating wash. Apply after cleansing, before other products. "
"Removes dead skin cells, reduces blackheads, and helps actives penetrate better.",
"Do NOT use on nights when you apply adapalene — over-exfoliation damages your skin barrier."),
("1x", "🎭", "Clay Mask (Optional)",
"Apply a bentonite or kaolin clay mask to the T-zone (forehead, nose, chin) for 10-15 minutes. "
"Absorbs excess oil, tightens pores, and reduces breakout frequency.",
"Use on a night when you are NOT applying adapalene or azelaic acid."),
("1x", "💆", "Sheet Mask or Hydration Boost",
"Use a hydrating sheet mask (hyaluronic acid, centella asiatica / cica) on a rest day. "
"Helps replenish moisture if adapalene/azelaic acid is causing dryness.",
"Cica/centella-based masks are especially calming for acne-prone South Asian skin."),
]
for num, icon, title, detail, tip in weekly_steps:
story.append(step_row(num, icon, title, detail, tip, bg=WEEKLY_BG))
story.append(Spacer(1, 6*mm))
# ══ PROGRESS TRACKER ═════════════════════════════════════════════════════════
story.append(section_banner("📈 WHAT TO EXPECT — PROGRESS TIMELINE", bg=DEEP_TEAL))
story.append(Spacer(1, 2*mm))
story.append(progress_table())
story.append(Spacer(1, 5*mm))
# ══ PRODUCT RECOMMENDATIONS ══════════════════════════════════════════════════
story.append(section_banner("🛒 RECOMMENDED PRODUCTS (India / South Asia)", bg=colors.HexColor("#1A5276")))
story.append(Spacer(1, 2*mm))
prod_headers = ["Product Type", "Budget Option", "Mid-Range Option"]
prod_rows = [
["Face Wash", "Cetaphil Gentle\nSkin Cleanser", "CeraVe Foaming\nFacial Cleanser"],
["Vitamin C", "The Ordinary\nAscorbyl Glucoside 12%", "Minimalist 16%\nAscorbyl Glucoside"],
["Niacinamide", "The Ordinary\nNiacinamide 10%+Zinc", "Minimalist 10%\nNiacinamide+Zinc"],
["Azelaic Acid", "The Ordinary\nAzelaic Acid 10%", "Minimalist Azelaic\nAcid 10%"],
["Adapalene", "Differin 0.1%\n(Adapalene)", "Galderma Epiduo (adapalene\n+BPO, Rx)"],
["Moisturiser", "Cetaphil\nMoisturising Cream", "CeraVe Moisturising\nCream"],
["Sunscreen", "Re'equil Oxybenzone-\nfree SPF 50 PA+++","La Roche-Posay\nAnthelios SPF 50+"],
]
col_w = [42*mm, 66*mm, 66*mm]
prod_data = [[Paragraph(h, small_bold) for h in prod_headers]] + \
[[Paragraph(c, step_body_style) for c in r] for r in prod_rows]
prod_table = Table(prod_data, colWidths=col_w)
prod_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DEEP_TEAL),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("BACKGROUND", (0,1), (-1,1), LIGHT_TEAL),
("BACKGROUND", (0,2), (-1,2), WHITE),
("BACKGROUND", (0,3), (-1,3), LIGHT_TEAL),
("BACKGROUND", (0,4), (-1,4), WHITE),
("BACKGROUND", (0,5), (-1,5), LIGHT_TEAL),
("BACKGROUND", (0,6), (-1,6), WHITE),
("BACKGROUND", (0,7), (-1,7), LIGHT_TEAL),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#BFC9CA")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(prod_table)
story.append(Spacer(1, 6*mm))
# ══ DO'S AND DON'TS ══════════════════════════════════════════════════════════
dos_donts = [
[
Paragraph("<b><font color='#1E8449'>✅ DO</font></b>", step_title_style),
Paragraph("<b><font color='#C0392B'>❌ DON'T</font></b>", step_title_style),
],
[
Paragraph(
"• Wear SPF every single day, even indoors near windows<br/>"
"• Change pillowcases at least once a week<br/>"
"• Drink 2-3 litres of water daily<br/>"
"• Keep your phone screen clean<br/>"
"• Let skin breathe — avoid heavy makeup<br/>"
"• Be patient — skin takes 8-12 weeks to change",
step_body_style),
Paragraph(
"• Pick, squeeze, or pop pimples (causes PIH and scars)<br/>"
"• Skip sunscreen — UV makes dark marks 5x worse<br/>"
"• Use more than a pea-size of adapalene<br/>"
"• Apply adapalene around eyes or lips<br/>"
"• Use scrubs or harsh exfoliants on active acne<br/>"
"• Expect overnight results — consistency is key",
step_body_style),
],
]
dd_table = Table(dos_donts, colWidths=[87*mm, 87*mm])
dd_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), colors.HexColor("#D5F5E3")),
("BACKGROUND", (1,0), (1,0), colors.HexColor("#FADBD8")),
("BACKGROUND", (0,1), (0,1), colors.HexColor("#EAFAF1")),
("BACKGROUND", (1,1), (1,1), colors.HexColor("#FEF9F9")),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("BOX", (0,0), (-1,-1), 1, colors.HexColor("#BFC9CA")),
("INNERGRID", (0,0), (-1,-1), 0.5, colors.HexColor("#D5D8DC")),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(section_banner("⚠️ DO'S AND DON'TS", bg=colors.HexColor("#1A5276")))
story.append(Spacer(1,2*mm))
story.append(dd_table)
story.append(Spacer(1, 5*mm))
# ══ SEE A DOCTOR IF ══════════════════════════════════════════════════════════
story.append(info_box([
"<b>See a Dermatologist If:</b>",
"• Acne worsens or does not improve after 8-10 weeks of this routine",
"• You develop deep cysts or nodules (may need oral isotretinoin)",
"• Scars are raised, thickened, or growing (keloid risk in South Asian skin — needs specialist care)",
"• PIH is very dark and not fading after 4 months (may need prescription tretinoin or peel)",
"• You want in-clinic procedures: RF microneedling, chemical peels, or pico laser for deeper scars",
], bg=colors.HexColor("#FADBD8")))
story.append(Spacer(1, 5*mm))
# ── FOOTER ───────────────────────────────────────────────────────────────────
footer = Table([[
Paragraph("Prepared by Orris AI • June 2026 • For educational purposes only — not a substitute for professional medical advice.",
S("Footer", fontSize=8, textColor=MID_GRAY, alignment=TA_CENTER))
]], colWidths=[174*mm])
footer.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 6),
("LINEABOVE", (0,0), (-1,-1), 0.5, MID_GRAY),
]))
story.append(footer)
# ── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
cd /home/daytona/workspace/skincare-guide && python generate_guide.py 2>&1
ls -lh /home/daytona/workspace/skincare-guide/Skincare_Routine_Guide.pdf
Skincare Routine Guide
PDF Document · PDF