#!/usr/bin/env python3
# Book 20 (ITC) — THE MANY-HEADED GIANT. Nature->business: a banyan tree is ONE root with MANY
# branches (branches drop roots -> new trunks -> one tree becomes a forest) -> many branches hold
# it steady when one branch has a bad season = DIVERSIFICATION -> the giant that grew foods,
# notebooks, soaps, hotels and farm friendships from one old root.
import os
ART="/root/omahaindia.com/comics/site/book/itc/art"
OUT="/root/omahaindia.com/comics/site/book/itc/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"
OSCAR=("Oscar, a warm friendly Western FARMER-ENTREPRENEUR orchard keeper, NOT Indian, cheerful ruddy face, "
"kind crinkly smile, wide straw hat, green apron over rolled-up sleeves, carrying a woven basket "
"overflowing with many different goods — apples, a honey jar, a loaf, flowers")

# name -> (w,h,seed,prompt,ref). ref set -> Seedream character; None -> flux scene. Ritual panels copied by mkbook.
NEW={
 "00_cover":(1024,1180,2000,f"{STYLE}. BOOK COVER, {CHARLOTTE} standing with {OSCAR} beneath a colossal magical banyan tree with many mighty trunks, its branches cradling a warm loaf, a stack of notebooks, glowing soap bubbles and a tiny lantern-lit palace hotel, golden evening light, wonder, cinematic","charlotte"),
 "_ref_oscar":(1024,1024,2001,f"{STYLE}. clean friendly character portrait, {OSCAR}, plain soft warm background, kind smile, head and shoulders",None),
 # Ch1
 "it_c1_coin":(1024,720,2010,f"{STYLE}. {CHARLOTTE} at home, Grandpa Ben's glowing brass compass spinning in circles between a biscuit packet, a school notebook and a bar of soap on the table, EXPRESSION puzzled and intrigued, cozy lamp light","charlotte"),
 "it_c1_diary":(1024,720,2011,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 tree with many branches, no people",None),
 "it_c1_swirl":(1024,720,2012,f"{STYLE}. {CHARLOTTE} pulled into a swirling spiral of golden light and green leaves from a glowing diary, EXPRESSION thrilled, magical","charlotte"),
 # Ch2 — arrive at the orchard, meet Oscar
 "it_c2_arrive":(1024,720,2013,f"{STYLE}. {CHARLOTTE} landing wide-eyed in a vast sunlit orchard valley, long rows of MANY different trees and crops stretching to the horizon, EXPRESSION awe and delight, bright morning light","charlotte"),
 "it_c2_oscar":(1024,720,2014,f"{STYLE}. {OSCAR} warmly welcoming {CHARLOTTE} at the orchard gate, tipping his straw hat, his basket full of many different goods, EXPRESSION Charlotte shy happy smile; keep the SAME orchard keeper from the reference, same straw hat, same green apron, same woven basket","oscar"),
 "it_c2_orchard":(1024,720,2015,f"{STYLE}. a grand orchard valley seen from a hilltop, neat rows of apple trees, berry bushes, golden wheat, beehives and a duck pond, tiny wheelbarrows for scale, joyful and abundant, no faces close up",None),
 # Ch3 — the banyan: one root, many trunks, a forest from one tree
 "it_c3_sprout":(1024,720,2016,f"{STYLE}. {OSCAR} kneeling to show {CHARLOTTE} a tiny banyan sapling in his palm while a COLOSSAL ancient banyan tree towers behind them, EXPRESSION Charlotte fascinated leaning in; SAME orchard keeper, straw hat, green apron","oscar"),
 "it_c3_banyan":(1024,720,2017,f"{STYLE}. a majestic giant banyan tree, long aerial roots dropping gently from its wide branches down to the soil, each root thickening into a brand new trunk, magical warm green light, no people",None),
 "it_c3_forest":(1024,720,2018,f"{STYLE}. one single enormous banyan tree spread so wide it looks like a whole forest, dozens of trunks under one vast shared canopy, shafts of golden light, breathtaking, no people",None),
 # Ch4 — the storm lesson: many branches carry a bad season
 "it_c4_storm":(1024,720,2019,f"{STYLE}. {CHARLOTTE} watching a dark hailstorm batter the apple rows on ONE side of the orchard while the other side still glows in sunshine, EXPRESSION worried biting her lip, dramatic split sky","charlotte"),
 "it_c4_harvest":(1024,720,2020,f"{STYLE}. {OSCAR} cheerfully lining up full baskets of pears, berries, honey jars and golden wheat beside one half-empty apple basket, EXPRESSION Charlotte relieved bright smile; SAME orchard keeper, straw hat, green apron","oscar"),
 "it_c4_roots":(1024,720,2021,f"{STYLE}. the giant banyan standing calm and steady in a howling storm wind, its many trunks gripping the earth like strong legs while smaller single-trunk trees bend, powerful and reassuring, no people",None),
 # Ch5 — the kitchen branch: flour, biscuits, snacks
 "it_c5_flour":(1024,720,2022,f"{STYLE}. {OSCAR} showing {CHARLOTTE} golden wheat grain pouring into a friendly mill and flowing out as soft white flour, sacks stacked high, EXPRESSION Charlotte hungry happy grin; SAME orchard keeper, straw hat, green apron","oscar"),
 "it_c5_biscuit":(1024,720,2023,f"{STYLE}. a cheerful magical bakery line, rivers of golden biscuits and crunchy snacks rolling out of warm ovens toward waiting baskets, delicious cozy steam, no people",None),
 # Ch6 — the notebook branch and the soap branch
 "it_c6_notebook":(1024,720,2024,f"{STYLE}. {CHARLOTTE} hugging a crisp new blank notebook among tall friendly stacks of colourful notebooks and smooth paper reams, EXPRESSION gleeful, bright clean light","charlotte"),
 "it_c6_soap":(1024,720,2025,f"{STYLE}. a playful sunny bathroom scene, pretty bars of soap and bottles sending up drifting rainbow bubbles that catch the light, fresh and sparkling clean, no people",None),
 # Ch7 — the hotel branch and the road to a million little shops
 "it_c7_hotel":(1024,720,2026,f"{STYLE}. a grand beautiful palace-like hotel glowing warm at dusk, fountains and gardens, tiny travellers arriving with suitcases for scale, welcoming and magnificent, no faces close up",None),
 "it_c7_shops":(1024,720,2027,f"{STYLE}. a warm storybook map of India at dawn dotted with thousands of tiny glowing shop lanterns, little delivery vans fanning out along winding roads to every corner, gentle and grand, no people",None),
 # Ch8 — reveal ITC
 "it_c8_reveal":(1024,720,2028,f"{STYLE}. {CHARLOTTE} and {OSCAR} standing proudly before the colossal many-trunked banyan, each great branch cradling a different glowing gift — a loaf, a notebook, a soap bubble, a tiny palace hotel, a sheaf of wheat, EXPRESSION proud recognition; SAME orchard keeper, straw hat, green apron","charlotte"),
 "it_c8_1910":(1024,720,2029,f"{STYLE}. warm sepia scene of the year 1910, a small young trading company by a great river in an old city, clerks planting a little sapling outside the office door, hopeful beginnings, no text",None),
 "it_c8_scale":(1024,720,2030,f"{STYLE}. a proud golden-hour montage of one giant company's many works — a busy bakery, a paper mill, a grand hotel, green farm fields, delivery vans rolling out — all connected by one glowing root underground, grand and warm, no people",None),
 # Ch10 (ch9 uses ritual castle/invert/verdict; ch10 uses ritual wake/diary)
 "it_c10_look":(1024,720,2031,f"{STYLE}. {CHARLOTTE} at her breakfast table at sunrise, gazing at the biscuit in her hand, the notebook in her school bag and the soap by the sink, each glowing softly like leaves of one hidden tree, 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 Compass That Couldn't Choose","pages 1-8",[
   P("it_c1_coin","Back home, Grandpa Ben's compass spun in circles — a biscuit, a notebook, a bar of soap. It simply could not pick ONE.","A biscuit, a notebook AND a soap? What could they share?",None,"spin"),
   P("it_c1_diary","The old diary fell open. A new line shimmered in Grandpa Ben's hand.",None,'"Find the tree that grew into a whole forest, all by itself."'),
   WOW("A biscuit from breakfast, a notebook from school, a soap from bath time — three things that seem to have NOTHING to do with each other. Yet the compass says they are connected. How can such different things belong to one story? That's the puzzle of this whole adventure."),
   P("it_c1_swirl","Golden light swirled up and pulled Charlotte in.","Here we GO!",None,"WHOOSH","#2aa15a"),
   NOTE("Charlotte's Secret Notebook","Two BIG questions:<br>➊ How can a biscuit, a notebook and a soap all be part of ONE story?<br>➋ Grandpa Ben says a tree can become a whole FOREST by itself. How?! 🌳"),
 ]),
 ("c2","CHAPTER 2","The Orchard of a Hundred Baskets","pages 9-16",[
   P("it_c2_arrive","One blink, and she stood in the biggest orchard she'd ever seen — row after row of trees, and every row DIFFERENT.","It's not one farm… it's a hundred farms in one!"),
   P("it_c2_oscar","A cheerful man in a straw hat waved, his basket piled with apples, honey, bread and flowers. \"I'm Oscar. I keep this orchard — and I never, EVER grow just one thing.\"","Never just ONE thing? Why not?"),
   P("it_c2_orchard","From the hilltop she saw it all: apples, berries, wheat, beehives, even a duck pond, stretching to the horizon.","So many different crops — all in ONE orchard?","Stick with me, little sprout."),
   NOTE("Charlotte's Secret Notebook","Oscar is an orchard keeper, and he grins like he has a secret — just like the other guides did. His rule: never grow just ONE thing. Okay Oscar… show me WHY! ✨"),
 ]),
 ("c3","CHAPTER 3","The Tree That Became a Forest","pages 17-26",[
   P("it_c3_sprout","Oscar held up a tiny sapling beside a tree as big as a hill. \"Meet the banyan. It starts as one little seed, like anybody else.\"","THAT giant started this small?!"),
   P("it_c3_banyan","\"But watch its trick: its branches drop long roots down to the ground — and each root grows into a brand NEW trunk.\"","The branches are planting THEMSELVES!"),
   P("it_c3_forest","\"Give it time, and one banyan spreads so wide it looks like a whole forest. Many trunks — one tree.\"","One tree… that became a FOREST!",None,"grow","#2aa15a"),
   WOW("Here's the first secret! 💡 A banyan doesn't stay one thin trunk. Its <b>branches drop roots</b>, the roots become <b>new trunks</b>, and the new trunks feed the whole tree. One root at the start — <b>many strong legs</b> in the end. That's how one tree becomes a forest."),
   NOTE("Charlotte's Secret Notebook","The banyan's trick: branch → drops a root → root becomes a NEW trunk → the tree spreads wider and stands stronger. One seed, one root, MANY trunks. A forest from one tree! 🌳🌳🌳"),
 ]),
 ("c4","CHAPTER 4","The Storm That Couldn't Win","pages 27-36",[
   P("it_c4_storm","Suddenly a hailstorm crashed over the orchard — but only on the apple side. Charlotte gasped as the fruit tumbled.","Oh no — the apples! Is the whole harvest ruined?!",None,"CRASH","#37414d"),
   P("it_c4_harvest","Oscar just smiled and lined up his baskets: pears, berries, honey, wheat — all full. Only the apple basket sat half-empty.","One bad basket… but look at all the OTHERS!"),
   P("it_c4_roots","And the great banyan? It stood calm in the howling wind, its many trunks gripping the earth like strong legs.","The extra trunks HOLD it steady!"),
   WOW("This is the big idea, and grown-ups call it <b>DIVERSIFICATION</b>: grow MANY branches, not one. If a storm hurts one branch, the others still carry the harvest. One trunk snaps in the wind — <b>many trunks stand.</b>"),
   ("diagram",),
   NOTE("Charlotte's Secret Notebook · SOLVED (part 1)","Oscar's rule makes sense now! Many different crops = many branches. A bad season can hurt ONE branch, but the other branches carry you through. DIVERSIFICATION = many trunks to stand on! 🧺🧺🧺"),
 ]),
 ("c5","CHAPTER 5","The Kitchen Branch","pages 37-44",[
   P("it_c5_flour","\"Now,\" said Oscar, \"imagine a company that grows like my banyan. Its first new branch? FOOD. It buys golden wheat from farmers and mills it into soft flour.\"","Straight from the farmers' fields!"),
   P("it_c5_biscuit","\"Then its ovens bake rivers of biscuits and crunchy snacks that travel into millions of kitchens.\"","So THAT'S where my biscuit comes from!",None,"mmm","#c8621f"),
   WOW("A company can grow a branch just like a banyan! The <b>foods branch</b> buys wheat from real farmers, mills it into flour, and bakes biscuits and snacks for <b>millions of homes</b>. One branch — feeding breakfast tables across a whole country."),
   NOTE("Charlotte's Secret Notebook","Branch #1: FOOD. Wheat from farmers → flour → biscuits and snacks → millions of kitchens. My breakfast biscuit is a LEAF on somebody's giant tree! 🍪"),
 ]),
 ("c6","CHAPTER 6","The Notebook and the Soap Bubble","pages 45-52",[
   P("it_c6_notebook","\"Another branch grows PAPER,\" said Oscar, \"smooth sheets and sturdy notebooks for schools everywhere.\"","My school notebook is a branch TOO?!"),
   P("it_c6_soap","\"And another branch makes soaps and shampoos — so bath time everywhere gets its bubbles.\"","Biscuits, notebooks, bubbles… the tree keeps growing!"),
   WOW("Branch after branch! The <b>paper branch</b> fills school bags with notebooks. The <b>soap branch</b> fills bathrooms with bubbles. Each branch is a whole different job — but they all drink from the <b>same deep root</b>: one company that learned to grow."),
   NOTE("Charlotte's Secret Notebook","Branch #2: PAPER & NOTEBOOKS — for every school bag. Branch #3: SOAPS & SHAMPOOS — for every bath. Different branches, same root. The compass wasn't confused… it was pointing at ONE TREE all along! 📓🫧"),
 ]),
 ("c7","CHAPTER 7","The Hotel and the Million Little Shops","pages 53-60",[
   P("it_c7_hotel","\"Some branches grow TALL,\" Oscar grinned. \"This company even keeps grand hotels, where travellers rest like guests of a palace.\"","A HOTEL growing on the same tree?!"),
   P("it_c7_shops","\"And here's the quiet superpower: its little vans reach MILLIONS of tiny shops, in big cities and far villages, corner after corner.\"","It reaches shops EVERYWHERE — even tiny ones!"),
   WOW("Two more wonders: a <b>hotels branch</b>, where travellers sleep like royalty — and a delivery web that reaches <b>millions of little shops</b> across the land. A branch is only useful if its fruit can REACH people. This giant's roads reach nearly everyone."),
   NOTE("Charlotte's Secret Notebook","Branch #4: grand HOTELS. And the secret superpower: a delivery web to MILLIONS of small shops — that's how one tree's fruit lands in every corner of India. 🏨🛒"),
 ]),
 ("c8","CHAPTER 8 · THE BIG DISCOVERY","The Many-Headed Giant","pages 61-70",[
   P("it_c8_reveal","Oscar led Charlotte back to the great banyan. In its branches she now saw them all — the loaf, the notebook, the bubbles, the tiny palace.","It's all ONE company… isn't it?"),
   P("it_c8_1910","\"It was born in 1910,\" said Oscar, \"more than a hundred years ago — one small company, one thin trunk, by a great river.\"","Older than my great-great-grandparents!"),
   P("it_c8_scale","\"And year after year it grew new branches — food, paper, soaps, hotels, farm friendships — until it became one of India's mightiest giants.\"","One root… and SO many heads!"),
   WOW("A \"company\" can grow like a banyan. <b>ITC</b> was born in <b>1910</b> — over a century ago — and slowly grew branch after branch: foods and biscuits, notebooks and paper, soaps, grand hotels, and deep friendships with farmers. Many businesses — <b>one giant tree.</b>"),
   TL([("1910","Born as one small company — a single thin trunk by a great river."),
       ("1975","A tall new branch: it opens its first grand hotels."),
       ("2000s","Big new branches unfurl — flour and biscuits, school notebooks, soaps."),
       ("Today","One of India's mightiest giants, its fruit in millions of homes and shops. 🌳")]),
   NOTE("Charlotte's Secret Notebook","ITC (born 1910) grew like a banyan: branch after branch — FOODS, PAPER & NOTEBOOKS, SOAPS, HOTELS, farm friendships — over more than a HUNDRED years. The many-headed giant! 🏆"),
 ]),
 ("c9","CHAPTER 9","The Castle of Many Branches","pages 71-80",[
   P("it_c9_castle","Two kind old men appeared with a glow. Warren pointed at a castle wrapped in the arms of a great banyan. \"What keeps rivals out, Charlotte?\"","Walls! But what kind?"),
   MOAT([("🏷️","Wall One: Names Everyone Trusts","Its biscuits, flour and notebooks are old friends in millions of homes. Trust like that is built over YEARS — a rival can't bake it overnight.",False),
         ("🛒","Wall Two: A Road to Every Shop","Its vans and helpers reach millions of tiny shops in every corner of the land. Building that web again would take a lifetime.",False),
         ("🌾","Wall Three: Deep Farm Friendships","It works hand in hand with farmers — buying their wheat, helping their harvests. Roots that deep don't pull out easily.",False),
         ("⚠️","The Crack in the Wall","Some of its branches make things only for grown-ups, and people debate whether those branches are good ones. A giant must choose its branches WISELY — and keep growing the good ones.",True)]),
   P("it_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 many-branched giant strong, imagine how it could FADE — leaning too long on a branch people debate, or growing so many branches it forgets to tend each one properly — then carefully avoid each mistake, and feed the freshest, kindest branches first."),
   P("it_c9_verdict","Warren nodded. \"Trusted names, roads to every shop, deep farm roots — a mighty castle, so long as the giant keeps choosing its branches wisely.\"","I SEE the whole picture!"),
   NOTE("Charlotte's Secret Notebook · The Big Secret","ITC is hard to copy: famous names families TRUST, a road to MILLIONS of shops, and deep farm friendships. But some branches are debated grown-up stuff — the giant must keep choosing wisely. Charlie's trick: picture how you'd lose (a wilting branch, too many heads), then never do it. Invert! 🏰"),
 ]),
 ("c10","CHAPTER 10","The Forest at the Breakfast Table","pages 81-88",[
   P("it_c10_wake","Charlotte woke in her own bed. The orchard was gone… but a single green banyan leaf lay on her desk, glowing softly.","Was it real? It FELT real…"),
   P("it_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 forest hiding inside one tree. Well done."'),
   P("it_c10_look","At breakfast she looked again: the biscuit, the notebook, the soap by the sink. Different things — leaves of one enormous, invisible tree.","They were branches of one giant the whole time — I just couldn't see it!"),
   WOW("Next time you hold a biscuit, a notebook or a bar of soap, you'll know the secret: they may be <b>leaves of one giant tree</b>. One old root, many strong branches — and when a storm hits one branch, the others carry the harvest. That's <b>the many-headed giant.</b> 🌳🍪📓"),
   NOTE("Charlotte's Secret Notebook · What I Learned","➊ A banyan drops roots from its branches — one tree becomes a forest of trunks.<br>➋ Many branches = DIVERSIFICATION: a bad season on one branch is carried by the others.<br>➌ ITC (born 1910) grew branch after branch — foods, notebooks &amp; paper, soaps, hotels, farm friendships.<br>➍ Its walls: trusted names, roads to millions of shops, deep farm roots.<br>➎ Charlie's trick — picture how you'd lose (a debated branch, too many heads), then choose your branches wisely. 💛"),
 ]),
]

HOOK=("it_c1_swirl","EVERY ORDINARY THING HIDES A SECRET.",
 "Charlotte found a whole forest hiding inside one tree. But the compass is twitching again — toward the tall cranes and rumbling machines raising bridges and towers at the edge of town. Who builds the giant things a country stands on?",
 "NEXT ADVENTURE · The Master Builders →")

DIAGRAM='''<div class="panel wide" style="background:#f0f7ee;">
<svg viewBox="0 0 820 380"><rect width="820" height="380" fill="#f0f7ee"/>
<text x="410" y="38" text-anchor="middle" font-family="Bangers" font-size="24" fill="#2aa15a">ONE ROOT, MANY BRANCHES</text>
<g><circle cx="120" cy="150" r="34" fill="#c8621f" stroke="#8a4413" stroke-width="4"/><text x="120" y="112" text-anchor="middle" font-family="Baloo 2" font-size="15" fill="#8a4413">ONE SEED</text><text x="120" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">one root goes down</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 BANYAN</text><text x="395" y="165" text-anchor="middle" font-family="Bangers" font-size="26" fill="#2aa15a">grows trunks</text><text x="395" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">branches drop new roots</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">branch after branch</text>
<text x="540" y="182" text-anchor="middle" font-family="Nunito" font-size="12" fill="#555">over a hundred years</text>
<g><rect x="620" y="112" width="150" height="90" rx="12" fill="#2aa15a" stroke="#171717" stroke-width="4"/><text x="695" y="102" text-anchor="middle" font-family="Baloo 2" font-size="16" fill="#c8621f">THE GIANT</text><text x="695" y="165" text-anchor="middle" font-family="Bangers" font-size="24" fill="#fff7e6">many heads</text><text x="695" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">foods · paper · soaps · hotels</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">If a storm hurts ONE branch, the other branches still carry the harvest &#8594; that is DIVERSIFICATION.</text>
<text x="410" y="343" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">One trunk snaps in the wind — many trunks stand steady.</text>
</svg><div class="figcap">One seed grows one root; the banyan drops new trunks from its branches; many branches hold the giant steady through any storm.</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_oscar"); 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/itc/_head.html").read()
    tail=open("/root/omahaindia.com/comics/site/book/itc/_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()
