#!/usr/bin/env python3
# Book 29 (Cipla) — THE MEDICINE FOR EVERYONE. Science->business: a medicine is a MOLECULE
# shaped like a KEY that fits a LOCK in the body -> the first maker hunts for years, but once the
# recipe is public anyone may make the SAME key for less (generics) -> the giant that makes trusted
# cures cheap enough for millions. Moat: cheap + perfectly safe + at colossal scale is itself hard.
import os
ART="/root/omahaindia.com/comics/site/book/cipla/art"
OUT="/root/omahaindia.com/comics/site/book/cipla/index.html"
STYLE=("children's storybook manga illustration, warm painted animation style, soft cinematic light, "
"clean linework, NO text NO letters NO words")
CHARLOTTE=("Charlotte, the SAME young Indian CHILD girl from the reference, round young face, warm tan skin, "
"freckles, glossy black hair in two low twin ponytails, big curious dark eyes, bright TEAL t-shirt, NO facial hair")
GRAHAM="Ben, a kind scholarly elderly American gentleman, round wire spectacles, tweed suit and bow tie"
BUFFETT="Warren, a folksy cheerful elderly American man, thinning white hair, big friendly glasses, grey suit"
MUNGER="Charlie, a stocky wise elderly American man, very thick black-framed glasses, dark suit"
RUBY=("Ruby, a warm friendly Western PHARMACIST, NOT Indian, white lab coat over a coral top, clear safety glasses, "
"a small pill tray in one hand, dark curly hair pinned up in a bun, kind determined smile")

# name -> (w,h,seed,prompt,ref). ref set -> Seedream character; None -> flux scene. Ritual panels copied by mkbook.
NEW={
 "00_cover":(1024,1180,2900,f"{STYLE}. BOOK COVER, {CHARLOTTE} standing with {RUBY} in a bright airy medicine laboratory, holding up a single glowing capsule shaped like a tiny golden key, a huge friendly keyhole of soft light behind them and a crowd of warm little house-lights on the horizon, wonder, cinematic","charlotte"),
 "_ref_ruby":(1024,1024,2901,f"{STYLE}. clean friendly character portrait, {RUBY}, plain soft warm background, kind determined smile, head and shoulders",None),
 # Ch1
 "ci_c1_coin":(1024,720,2910,f"{STYLE}. {CHARLOTTE} at home, Grandpa Ben's glowing brass compass twitching between a tiny white pill and an old brass door lock on the table, EXPRESSION puzzled and intrigued, cozy lamp light","charlotte"),
 "ci_c1_diary":(1024,720,2911,f"{STYLE}. an open magical diary glowing warm gold on a desk, a faint ribbon of light rising from the page and curling into the shape of a tiny key beside a small capsule, no people",None),
 "ci_c1_swirl":(1024,720,2912,f"{STYLE}. {CHARLOTTE} pulled into a swirling spiral of golden light and floating capsules and tiny keys from a glowing diary, EXPRESSION thrilled, magical","charlotte"),
 # Ch2 — arrive at the medicine works, meet Ruby
 "ci_c2_arrive":(1024,720,2913,f"{STYLE}. {CHARLOTTE} landing wide-eyed inside an enormous spotless medicine factory, gleaming steel vessels and long bright lines of little bottles rolling past, EXPRESSION awe and delight, clean daylight","charlotte"),
 "ci_c2_ruby":(1024,720,2914,f"{STYLE}. {RUBY} warmly welcoming {CHARLOTTE} in the medicine works, tipping her safety glasses up, EXPRESSION Charlotte shy happy smile; keep the SAME pharmacist from the reference, same white lab coat over coral top, same pill tray","ruby"),
 "ci_c2_line":(1024,720,2915,f"{STYLE}. a vast pharmaceutical packing hall seen from above, endless neat rows of little white tablets and bottles gliding along bright conveyor lines, tiny workers in white coats for scale, awe-inspiring order, no faces close up",None),
 # Ch3 — the body is full of locks; illness = a lock stuck
 "ci_c3_lock":(1024,720,2916,f"{STYLE}. {RUBY} kneeling to show {CHARLOTTE} a magical glowing model of a body cell whose surface is covered in tiny golden keyholes, EXPRESSION Charlotte fascinated leaning in; SAME pharmacist, white lab coat over coral top, safety glasses","ruby"),
 "ci_c3_body":(1024,720,2917,f"{STYLE}. a friendly glowing storybook diagram of a child-shaped body made of soft light, thousands of tiny keyholes twinkling all over it like little stars, magical science, no faces close up",None),
 "ci_c3_stuck":(1024,720,2918,f"{STYLE}. a playful close up of one glowing keyhole jammed and sparking angrily red while its neighbours glow calm and blue, a little cell looking unwell, gentle science, no people",None),
 # Ch4 — the medicine is a molecule shaped to fit the lock
 "ci_c4_key":(1024,720,2919,f"{STYLE}. {CHARLOTTE} watching in wonder as a tiny glowing molecule shaped like an intricate key floats up and slides perfectly into a sparking keyhole, the red spark calming to warm gold, EXPRESSION amazed and thoughtful, magical light","charlotte"),
 "ci_c4_fit":(1024,720,2920,f"{STYLE}. a beautiful close up of a single glowing molecule key clicking into a golden keyhole with a soft ring of light, perfect fit, warm and satisfying, no people",None),
 "ci_c4_wrong":(1024,720,2921,f"{STYLE}. a playful row of three differently shaped little molecule keys, two of them too big and too twisty to fit a golden keyhole and one sliding in perfectly, gentle science humour, no people",None),
 # Ch5 — the long hunt for the right key
 "ci_c5_hunt":(1024,720,2922,f"{STYLE}. {RUBY} at a long laboratory bench crowded with thousands of tiny glowing candidate keys, patiently trying them one by one against a golden keyhole, EXPRESSION Ruby weary but determined; SAME pharmacist, white lab coat over coral top, safety glasses","ruby"),
 "ci_c5_years":(1024,720,2923,f"{STYLE}. a warm storybook calendar of many years flying past over a quiet laboratory window, seasons changing outside while a single lamp stays lit at the bench, patient and hopeful, no people",None),
 # Ch6 — the recipe becomes public: same key, smaller price (generics)
 "ci_c6_recipe":(1024,720,2924,f"{STYLE}. {CHARLOTTE} watching a glowing recipe scroll unroll into the open air and shine out over a whole town, EXPRESSION excited and hopeful, bright magical light","charlotte"),
 "ci_c6_same":(1024,720,2925,f"{STYLE}. two identical glowing molecule keys side by side, one resting on a small pile of gold coins and the other on a single little coin, exactly the same shape, playful storybook comparison, no people",None),
 # Ch7 — cures for millions
 "ci_c7_everyone":(1024,720,2926,f"{STYLE}. a joyful sunny scene of ordinary people all over a town getting well again — a village clinic, a school, a grandmother in a doorway, a small hospital — warm togetherness and relief, no faces close up",None),
 "ci_c7_world":(1024,720,2927,f"{STYLE}. a warm storybook world map with little glowing bottles of medicine travelling out from India along soft golden ribbons to Africa and every other continent, gentle and grand, no people",None),
 # Ch8 — reveal Cipla
 "ci_c8_reveal":(1024,720,2928,f"{STYLE}. {CHARLOTTE} and {RUBY} standing proudly before a vast bright medicine plant glowing against a blue sky, EXPRESSION proud recognition; SAME pharmacist, white lab coat over coral top, safety glasses","charlotte"),
 "ci_c8_1935":(1024,720,2929,f"{STYLE}. warm sepia 1930s scene, a small hopeful laboratory of glass flasks and wooden shelves where a country begins making its own medicines for the first time, inspiring, no text",None),
 "ci_c8_scale":(1024,720,2930,f"{STYLE}. a mighty modern pharmaceutical plant at golden hour, gleaming towers and endless lines of medicine crates rolling out to trucks, one of the great medicine-makers of the world, proud and grand, no people",None),
 # Ch10 (ch9 uses ritual castle/invert/verdict; ch10 uses ritual wake/diary)
 "ci_c10_look":(1024,720,2931,f"{STYLE}. {CHARLOTTE} outside in the morning looking with wonder at an ordinary little pharmacy on her street, its shelves softly glowing as if full of tiny golden keys, EXPRESSION delighted wonder","charlotte"),
}

def P(img,cap=None,b1=None,b2=None,sfx=None,sfxc="#e8425a",tall=False): return ("panel",img,cap,b1,b2,sfx,sfxc,tall)
def SUB(d,t): return ("sub",d,t)
def WOW(t): return ("wow",t)
def NOTE(t,b): return ("note",t,b)
def TL(r): return ("timeline",r)
def MOAT(c): return ("moat",c)

CHAPTERS=[
 ("c1","CHAPTER 1","The Pill and the Lock","pages 1-8",[
   P("ci_c1_coin","Back home, Grandpa Ben's compass twitched again — pointing between one tiny white pill and an old brass lock.","A pill… and a lock? What's the link?",None,"twitch"),
   P("ci_c1_diary","The old diary fell open. A new line shimmered in Grandpa Ben's hand.",None,'"Find the key that is small enough to fit inside you."'),
   WOW("A pill is smaller than a pea. Yet swallow the right one and an ache fades, a fever cools, an illness lets go. How can something so tiny know exactly what to do inside a whole person? That's the puzzle of this whole adventure."),
   P("ci_c1_swirl","Golden light swirled up and pulled Charlotte in.","Here we GO!",None,"WHOOSH","#c8621f"),
   NOTE("Charlotte's Secret Notebook","Two BIG questions:<br>➊ How does a tiny pill know which part of me to help?<br>➋ Grandpa Ben says it's a <i>key</i>. A key needs a lock… so where is the lock? 🔑"),
 ]),
 ("c2","CHAPTER 2","The Cleanest Place She'd Ever Seen","pages 9-16",[
   P("ci_c2_arrive","One blink, and she stood in a hall so clean it shone — steel vessels, white coats, and bottles gliding by in bright rows.","It's cleaner than clean in here!"),
   P("ci_c2_ruby","A cheerful woman in a white coat waved. \"I'm Ruby, a pharmacist. In here we make keys — very, very tiny ones.\"","Tiny… KEYS?!"),
   P("ci_c2_line","Down the line, little white tablets marched past by the thousand, then the million.","So many! Who needs THIS many?","Rather a lot of us, kiddo."),
   NOTE("Charlotte's Secret Notebook","Ruby is a medicine scientist (a pharmacist), and she grins like she has a secret — just like the other guides did. She calls medicines 'tiny keys'. Okay Ruby… show me! ✨"),
 ]),
 ("c3","CHAPTER 3","The Body Is Full of Locks","pages 17-26",[
   P("ci_c3_lock","Ruby held up a glowing model of a single cell. Its whole surface twinkled with tiny golden keyholes.","My body is COVERED in keyholes?"),
   P("ci_c3_body","\"Every bit of you is built of cells, and cells are covered in little locks. A lock turns, and something happens — you feel, you heal, you grow.\"","Millions of tiny locks, all doing jobs!"),
   P("ci_c3_stuck","\"And when you're ill,\" said Ruby gently, \"some of those locks are stuck — jammed open, or jammed shut, or turned by the wrong thing.\"","So being sick is a lock going WRONG!",None,"spark","#e8425a"),
   WOW("Here's the first secret! 🔒 Your body is built from cells, and cells are covered in tiny <b>locks</b>. When a lock turns, something happens inside you. Many illnesses are simply a lock that has <b>gone wrong</b> — stuck, or being turned by the wrong thing."),
   ("diagram",),
   NOTE("Charlotte's Secret Notebook","Cells are covered in tiny locks. Turning a lock makes something happen inside my body. Being ill often means a lock is jammed or being turned by the wrong thing. 🔒"),
 ]),
 ("c4","CHAPTER 4","A Key Shaped Just Right","pages 27-36",[
   P("ci_c4_key","A tiny glowing shape drifted up and slid into the sparking keyhole. The angry red spark calmed to warm gold.","It FIT! And the lock went quiet!"),
   P("ci_c4_fit","\"That,\" said Ruby, \"is a medicine. It's a molecule — a speck far too small to see — shaped to fit one lock and no other.\"","So a medicine is a KEY!"),
   P("ci_c4_wrong","\"Shape is everything. A key one bump too big, or twisted the wrong way, simply won't go in.\"","Almost-right is no good at all!"),
   WOW("A medicine is a <b>molecule shaped like a key</b> — so small you could never see it — made to fit <b>one particular lock</b> in the body and turn it the right way. Get the shape exactly right and the illness lets go. Get it a little wrong and nothing happens at all."),
   NOTE("Charlotte's Secret Notebook · SOLVED (part 1)","A medicine is a molecule shaped to FIT one lock in the body — a key. The right shape turns the stuck lock the right way. Wrong shape = no help. 🔑"),
 ]),
 ("c5","CHAPTER 5","The Long, Long Hunt","pages 37-44",[
   P("ci_c5_hunt","Ruby's bench was crowded with thousands of tiny keys. She tried them one by one against the lock. Most did nothing at all.","You try them ALL? One at a time?"),
   P("ci_c5_years","\"The first person to find a new key can search for ten years or more,\" she said. \"Most of the keys fail. It costs a fortune.\"","Ten YEARS for one little shape…"),
   WOW("Finding a brand-new medicine is <b>desperately hard</b>. The first maker may hunt for <b>ten years or more</b>, testing thousands of shapes, spending fortunes — because nobody knows in advance which shape fits. That's why a new medicine starts out so expensive."),
   NOTE("Charlotte's Secret Notebook","The FIRST maker of a medicine hunts for years and years, tries thousands of shapes, and most fail. That hunt is why a brand-new medicine costs so much. 🔬"),
 ]),
 ("c6","CHAPTER 6","The Same Key, a Smaller Price","pages 45-52",[
   P("ci_c6_recipe","After some years, the recipe stops being a secret. It unrolls into the open air for everyone to read.","The recipe is out — anyone can read it?"),
   P("ci_c6_same","\"And now,\" Ruby smiled, \"anyone skilled enough can make the SAME key. Same shape. Same work in the body. A much, much smaller price.\"","Same key… tiny price! That's the trick!"),
   WOW("After some years the recipe becomes <b>public</b>. Then other makers may build the <b>very same molecule</b> — the same key, doing the very same job — and sell it far cheaper. These copies are called <b>generic medicines</b>. Same key, smaller price. 🔑"),
   NOTE("Charlotte's Secret Notebook · SOLVED!","Once the recipe is public, other makers can build the SAME molecule — a generic. Identical key, identical job, a fraction of the price. That's how cures reach everybody! 💊"),
 ]),
 ("c7","CHAPTER 7","Cures for Millions","pages 53-60",[
   P("ci_c7_everyone","Ruby swept her arm across the town. A clinic, a school, a grandmother in her doorway — all well again.","EVERYONE can afford it now?!"),
   P("ci_c7_world","\"Cheap enough,\" said Ruby, \"and a medicine stops being for the few. It goes out to millions — across India, and across the world.\"","A tiny key… helping millions of people!"),
   WOW("This is the whole business, and it's a beautiful one: <b>take a trusted cure and make it affordable</b>. A medicine only helps the people who can actually get it — so making it cheap is not a small thing. It is the thing that turns a cure into <b>millions of people getting better</b>."),
   NOTE("Charlotte's Secret Notebook","The business is simple to say and hard to do: make trusted cures cheap enough for millions of ordinary people. A medicine nobody can afford helps nobody. 🌏"),
 ]),
 ("c8","CHAPTER 8 · THE BIG DISCOVERY","The Maker of Everyday Cures","pages 61-70",[
   P("ci_c8_reveal","Ruby led Charlotte to a window above the enormous, gleaming plant.","Who makes ALL of this?"),
   P("ci_c8_1935","\"In 1935,\" said Ruby, \"a small laboratory opened here so this country could make its own medicines instead of waiting for someone else's.\"","Starting with just glass flasks!"),
   P("ci_c8_scale","\"It grew and grew — until its cheap, trusted medicines were travelling to homes all over the world.\"","From that little room… to the whole WORLD!"),
   WOW("A \"company\" can be a giant shared job. <b>Cipla</b> began in 1935 as a small laboratory so India could make its own medicines, and grew into one of the world's great makers of <b>affordable everyday cures</b> — famously helping bring the price of a life-saving treatment down from a fortune to a few coins a day."),
   TL([("1935","A small laboratory opens so India can make its own medicines."),
       ("Over decades","It learns to make trusted cures cheaply, at enormous scale."),
       ("2001","It offers a life-saving treatment for about a dollar a day — the world gasps."),
       ("Today","Its medicines reach homes across India and much of the world. 💊")]),
   NOTE("Charlotte's Secret Notebook","Cipla (1935) started as one small lab and became a giant maker of affordable medicines — even bringing a fortune-priced treatment down to about a dollar a day. Cures for everyone. 🏆"),
 ]),
 ("c9","CHAPTER 9","The Castle Made of Cures","pages 71-80",[
   P("ci_c9_castle","Two kind old men appeared with a glow. Warren pointed at a castle standing on a field of gleaming white bottles. \"What keeps rivals out, Charlotte?\"","Walls! But what kind?"),
   MOAT([("💊","Wall One: Cheap Is Hard","Anyone may read the recipe — but making the same key perfectly, for a few coins, needs decades of skill. Easy to copy on paper; brutally hard to actually do.",False),
         ("🏭","Wall Two: Giant Scale","Vast plants, thousands of trained hands, and mountains of medicine made every single day. A newcomer cannot build that overnight.",False),
         ("🤝","Wall Three: Trust","Doctors and families must believe every single tablet is right. Trust takes ninety years to build — and it cannot be bought.",False),
         ("⚠️","The Crack in the Wall","Cheap must NEVER mean careless. One bad batch, one shortcut, and the trust of a lifetime is gone. A medicine has to be perfect, every time.",True)]),
   P("ci_c9_munger","Charlie tapped his head. \"Don't just ask how to WIN. Ask how you'd LOSE — then don't do that. Invert!\"","Think backwards?"),
   WOW("<b>Charlie's Inversion:</b> to keep a medicine-maker strong, imagine how it could FALL — cutting a corner to shave a rupee, letting one careless batch out of the door, chasing cheapness until quality slips — then refuse each one, forever. In medicine, safe comes first and cheap comes second."),
   P("ci_c9_verdict","Warren nodded. \"It makes trusted cures cheap, at colossal scale — a mighty castle, so long as cheap never, ever costs quality.\"","I SEE the whole picture!"),
   NOTE("Charlotte's Secret Notebook · The Big Secret","Cipla is hard to copy: making a key CHEAP, at giant SCALE, with total TRUST is itself very hard. But quality can never be traded away for cheapness — a medicine must be perfect. Charlie's trick: picture how you'd lose (one careless batch), then never do it. Invert! 🏰"),
 ]),
 ("c10","CHAPTER 10","The Little Key in Your Hand","pages 81-88",[
   P("ci_c10_wake","Charlotte woke in her own bed. The great plant was gone… but the little pill on her desk shimmered softly.","Was it real? It FELT real…"),
   P("ci_c10_diary","On the diary's page, a new line glowed — as if Grandpa Ben wrote it just for her.",None,'"Now you see the key that is small enough to fit inside you. Well done."'),
   P("ci_c10_look","She ran outside. The little pharmacy on the corner glowed like a treasury — shelf after shelf of tiny golden keys, waiting.","It was full of keys the whole time — I just couldn't see them!"),
   WOW("Next time you hold a pill, you'll know the secret: it's a <b>molecule shaped like a key</b>, hunted for years, and now made cheap enough for millions. That's <b>the medicine for everyone.</b> 💊🔑"),
   NOTE("Charlotte's Secret Notebook · What I Learned","➊ My cells are covered in tiny LOCKS; illness is often a lock gone wrong.<br>➋ A medicine is a molecule shaped like a KEY that fits one lock.<br>➌ The first maker hunts for ten years or more to find that shape.<br>➍ Once the recipe is public, others make the SAME key far cheaper — generics.<br>➎ Cipla makes trusted cures affordable for millions; but Charlie's trick — picture how you'd lose (one careless batch), and never trade quality for cheapness. 💛"),
 ]),
]

HOOK=("ci_c1_swirl","EVERY ORDINARY THING HIDES A SECRET.",
 "Charlotte found the key that fits inside a person. But the compass is twitching again — this time toward the little glass rectangle in everybody's pocket, buzzing with voices from a thousand miles away. How does a message find exactly one person?",
 "NEXT ADVENTURE · The Voice in the Air →")

DIAGRAM='''<div class="panel wide" style="background:#fbf3ec;">
<svg viewBox="0 0 820 380"><rect width="820" height="380" fill="#fbf3ec"/>
<text x="410" y="38" text-anchor="middle" font-family="Bangers" font-size="24" fill="#c8621f">A MEDICINE IS A KEY THAT FITS A LOCK</text>
<g><circle cx="120" cy="150" r="34" fill="#f6b53f" stroke="#c8621f" stroke-width="4"/><text x="120" y="112" text-anchor="middle" font-family="Baloo 2" font-size="15" fill="#c8621f">THE PILL</text><text x="120" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">a speck of a molecule</text></g>
<g stroke="#2aa15a" stroke-width="5" fill="#2aa15a"><line x1="160" y1="150" x2="300" y2="150" stroke-dasharray="10 8"/><path d="M296 141 L314 150 L296 159Z"/></g>
<g><rect x="320" y="112" width="150" height="90" rx="12" fill="#fff" stroke="#171717" stroke-width="4"/><text x="395" y="102" text-anchor="middle" font-family="Baloo 2" font-size="14" fill="#2aa15a">THE SHAPE</text><text x="395" y="165" text-anchor="middle" font-family="Bangers" font-size="26" fill="#2aa15a">a tiny key</text><text x="395" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">one shape, one job</text></g>
<g stroke="#37414d" stroke-width="5" fill="#37414d"><line x1="480" y1="150" x2="600" y2="150" stroke-dasharray="10 8"/><path d="M596 141 L614 150 L596 159Z"/></g>
<text x="540" y="135" text-anchor="middle" font-family="Baloo 2" font-size="12" fill="#37414d">slides in &amp; turns</text>
<text x="540" y="182" text-anchor="middle" font-family="Nunito" font-size="12" fill="#555">only if the shape is exact</text>
<g><rect x="620" y="112" width="150" height="90" rx="12" fill="#37414d" stroke="#171717" stroke-width="4"/><text x="695" y="102" text-anchor="middle" font-family="Baloo 2" font-size="16" fill="#c8621f">THE LOCK</text><text x="695" y="165" text-anchor="middle" font-family="Bangers" font-size="24" fill="#f6b53f">on your cells</text><text x="695" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">turn it right and you heal</text></g>
<rect x="70" y="300" width="680" height="52" rx="9" fill="#fff" stroke="#171717" stroke-width="3"/>
<text x="410" y="322" text-anchor="middle" font-family="Nunito" font-size="14" fill="#123">The first maker hunts for years to find the shape &#8594; then the recipe becomes public &#8594; others make the SAME key for less.</text>
<text x="410" y="343" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">Same key, smaller price — that is how a cure reaches millions of people.</text>
</svg><div class="figcap">A medicine is a molecule shaped to fit one lock in the body; once the recipe is public, the same key can be made far cheaper.</div></div>'''

try:
    from book_extra import EXTRA, NEW2
    NEW.update(NEW2)
except Exception:
    EXTRA={}

def render_panel(pn,pageno=None):
    _,img,cap,b1,b2,sfx,sfxc,tall=pn
    pg=f'<div class="pageno">{pageno}</div>' if pageno else ''
    p=[f'<div class="panel wide">{pg}<img src="art/{img}.jpg" alt="" loading="lazy">']
    if cap: p.append(f'<div class="cap tl tilt">{cap}</div>')
    if b1: p.append(f'<div class="bubble dl" style="left:12px;bottom:12px;">{b1}</div>')
    if b2: p.append(f'<div class="bubble dr" style="right:12px;top:12px;">{b2}</div>')
    if sfx: p.append(f'<div class="sfx" style="left:40%;top:14px;font-size:32px;color:{sfxc};">{sfx}</div>')
    p.append('</div>'); return "".join(p)

def render_item(it,pageno=None):
    t=it[0]
    if t=="panel": return render_panel(it,pageno)
    if t=="diagram": return DIAGRAM
    if t=="sub": return f'<div class="sub"><span class="dot">{it[1]}</span><b>{it[2]}</b></div>'
    if t=="wow": return f'<div class="wow">{it[1]}</div>'
    if t=="note": return f'<div class="note"><div class="nt">{it[1]}</div><p>{it[2]}</p></div>'
    if t=="timeline":
        rows="".join(f'<div class="tl"><div class="yr">{y}</div><p>{x}</p></div>' for y,x in it[1])
        return f'<div class="timeline">{rows}</div>'
    if t=="moat":
        cards="".join(f'<div class="mc{" bad" if bad else ""}"><h4>{ic} {ti}</h4><p>{tx}</p></div>' for ic,ti,tx,bad in it[1])
        return f'<div class="moat">{cards}</div>'
    return ""

def referenced_images():
    imgs=set()
    for cls,_,_,_,items in CHAPTERS:
        for it in items:
            if it[0]=="panel": imgs.add(it[1])
        for it in EXTRA.get(cls,[]):
            if it[0]=="panel": imgs.add(it[1])
    imgs.add(HOOK[0]); imgs.add("00_cover"); imgs.add("_ref_ruby"); return imgs

def build():
    body=[]; pageno=0
    for cls,num,title,pglabel,items in CHAPTERS:
        items=list(items); extra=EXTRA.get(cls,[])
        if extra:
            idx=[i for i,it in enumerate(items) if it[0]=="panel"]
            at=(idx[-1]+1) if idx else len(items)
            for ex in reversed(extra): items.insert(at,ex)
        start=pageno+1
        inner=[f'<div class="chapbar {cls}"><div class="n">{num}</div><h2>{title}</h2></div>']
        for it in items:
            if it[0]=="panel": pageno+=1; inner.append(render_item(it,pageno))
            else: inner.append(render_item(it))
        lbl=f"pages {start}-{pageno}" if pageno>=start else pglabel
        body.append(f'<div class="sheet" data-pg="{lbl}">{"".join(inner)}</div>')
    hook=f'''<div class="sheet" data-pg="the end… for now"><div class="hook"><img src="art/{HOOK[0]}.jpg" alt="">
<div class="hc"><h3>{HOOK[1]}</h3><p>{HOOK[2]}</p><div class="b2">{HOOK[3]}</div></div></div></div>'''
    head=open("/root/omahaindia.com/comics/site/book/cipla/_head.html").read()
    tail=open("/root/omahaindia.com/comics/site/book/cipla/_tail.html").read()
    open(OUT,"w").write(head+"".join(body)+hook+tail)
    print("built",OUT,"| chapters:",len(CHAPTERS),"| images:",len(referenced_images()))

if __name__=="__main__":
    build()
