#!/usr/bin/env python3
# Book 23 (State Bank of India) — THE BANK AS OLD AS THE NATION. Idea->business: a bank is a PROMISE
# (money kept safe, handed back whenever you ask) -> a promise kept millions of times a day -> the older
# and wider the promise, the stronger it grows -> the giant whose branches reach every corner of the land.
import os
ART="/root/omahaindia.com/comics/site/book/sbi/art"
OUT="/root/omahaindia.com/comics/site/book/sbi/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"
CLARA=("Clara, a warm friendly Western SENIOR BANKER, NOT Indian, elderly, a neat grey pinstripe suit, "
"silver hair in a tidy bun, half-moon spectacles, a big old leather ledger under one arm, dignified kind smile")

# name -> (w,h,seed,prompt,ref). ref set -> Seedream character; None -> flux scene. Ritual panels copied by mkbook.
NEW={
 "00_cover":(1024,1180,2300,f"{STYLE}. BOOK COVER, {CHARLOTTE} standing with {CLARA} on the marble steps of a grand old bank, holding up a single silver coin that glows warmly, golden threads of light spreading from the coin out to countless tiny lit windows and little village rooftops across the horizon, wonder, cinematic","charlotte"),
 "_ref_clara":(1024,1024,2301,f"{STYLE}. clean friendly character portrait, {CLARA}, plain soft warm background, kind dignified smile, head and shoulders",None),
 # Ch1
 "sb_c1_coin":(1024,720,2310,f"{STYLE}. {CHARLOTTE} at home, Grandpa Ben's glowing brass compass twitching between a single silver coin and an old brass key on the table, EXPRESSION puzzled and intrigued, cozy lamp light","charlotte"),
 "sb_c1_diary":(1024,720,2311,f"{STYLE}. an open magical diary glowing warm gold on a desk, a faint ribbon of golden light rising from the page and looping around a small silver coin like a handshake, no people",None),
 "sb_c1_swirl":(1024,720,2312,f"{STYLE}. {CHARLOTTE} pulled into a swirling spiral of golden light and glinting silver coins from a glowing diary, EXPRESSION thrilled, magical","charlotte"),
 # Ch2 — arrive at the great old bank, meet Clara
 "sb_c2_arrive":(1024,720,2313,f"{STYLE}. {CHARLOTTE} landing wide-eyed in the vast marble hall of a grand old bank, tall pillars, warm chandeliers, long polished counters, people queueing calmly, EXPRESSION awe and delight, bright morning light","charlotte"),
 "sb_c2_clara":(1024,720,2314,f"{STYLE}. {CLARA} warmly welcoming {CHARLOTTE} in the bank hall, offering a friendly handshake, her old leather ledger tucked under one arm, EXPRESSION Charlotte shy happy smile; keep the SAME senior banker from the reference, same grey pinstripe suit, silver bun, half-moon spectacles","clara"),
 "sb_c2_vault":(1024,720,2315,f"{STYLE}. a huge round polished steel vault door standing open in a grand bank, warm golden light spilling out from inside, neat stacks and boxes glinting, awe-inspiring and safe, no faces close up",None),
 # Ch3 — what a bank really is: a promise
 "sb_c3_promise":(1024,720,2316,f"{STYLE}. {CLARA} kneeling to show {CHARLOTTE} a single silver coin resting on her open palm, a soft golden thread of light linking the coin to the child's hand like a promise, EXPRESSION Charlotte fascinated leaning in; SAME senior banker, grey pinstripe suit, silver bun, half-moon spectacles","clara"),
 "sb_c3_handback":(1024,720,2317,f"{STYLE}. a friendly close up of two hands, one placing a small silver coin into a glowing safe box and the other receiving the very same coin back later, a gentle loop of golden light between them, playful, no faces",None),
 "sb_c3_ledger":(1024,720,2318,f"{STYLE}. a beautiful old leather ledger open on a counter, neat glowing golden lines marching across its pages like tiny keepsafe promises, warm lamp light, no text no letters, no people",None),
 # Ch4 — a promise kept millions of times a day
 "sb_c4_millions":(1024,720,2319,f"{STYLE}. {CHARLOTTE} watching in wonder as countless tiny golden threads of light stream through a giant bank hall — every thread a small promise being kept — swirling gently around her, EXPRESSION amazed and thoughtful, magical warm light","charlotte"),
 "sb_c4_day":(1024,720,2320,f"{STYLE}. a warm storybook montage ring, a farmer at a counter, a shopkeeper counting change, a student at a cash machine, a grandmother receiving her pension, all connected by soft golden threads, gentle and busy, no faces close up",None),
 "sb_c4_trust":(1024,720,2321,f"{STYLE}. a magical glowing tree whose trunk is made of woven golden threads and whose leaves are tiny silver coins, growing stronger and taller as more threads wind in, warm light, no people",None),
 # Ch5 — the older the promise, the stronger it grows
 "sb_c5_old":(1024,720,2322,f"{STYLE}. a warm sepia scene of a very old bank counter from two hundred years ago, oil lamps, quill pens, a heavy ledger, horse carts outside the window, dignified and hopeful, no faces close up",None),
 "sb_c5_grow":(1024,720,2323,f"{STYLE}. {CLARA} showing {CHARLOTTE} a magical timeline ribbon of golden light stretching from an old lamp-lit counter to a bright modern bank hall, growing thicker and brighter as it travels, EXPRESSION Charlotte delighted 'aha'; SAME senior banker, grey pinstripe suit, silver bun, half-moon spectacles","clara"),
 # Ch6 — the wider the promise: branches in every corner
 "sb_c6_village":(1024,720,2324,f"{STYLE}. {CHARLOTTE} standing outside a tiny one-room bank branch in a small green village, a dusty lane, a bicycle leaning by the door, an old couple walking in smiling, EXPRESSION awed and excited, warm afternoon light","charlotte"),
 "sb_c6_net":(1024,720,2325,f"{STYLE}. a warm storybook map of India covered in thousands of tiny glowing dots joined by soft golden threads into one giant gentle web, mountains, deserts, islands and villages all connected, magical, no people",None),
 # Ch7 — reaching every corner, for everyone
 "sb_c7_everyone":(1024,720,2326,f"{STYLE}. a joyful scene of a busy little bank branch serving everyone — a farmer, a schoolteacher, a young shopkeeper, a grandmother — all smiling in a warm queue, togetherness, no faces close up",None),
 "sb_c7_corners":(1024,720,2327,f"{STYLE}. a gentle grand montage, a tiny bank branch in a snowy mountain pass, another on a palm-fringed island shore, another in a golden desert village, each glowing warmly under one big sky, no people",None),
 # Ch8 — reveal State Bank of India
 "sb_c8_reveal":(1024,720,2328,f"{STYLE}. {CHARLOTTE} and {CLARA} standing proudly before a vast grand bank headquarters glowing against a blue sky, golden threads streaming out from it across the land, EXPRESSION proud recognition; SAME senior banker, grey pinstripe suit, silver bun, half-moon spectacles","charlotte"),
 "sb_c8_1806":(1024,720,2329,f"{STYLE}. warm sepia early-1800s scene, a dignified old bank house with tall shuttered windows opening its doors for the very first time, horse carts and lamplighters outside, hopeful and historic, no text",None),
 "sb_c8_scale":(1024,720,2330,f"{STYLE}. a mighty modern bank tower at golden hour with thousands of soft golden threads flowing out of it to tiny lit branches scattered across a whole storybook country, the biggest bank in the land, proud and grand, no people",None),
 # Ch10 (ch9 uses ritual castle/invert/verdict; ch10 uses ritual wake/diary)
 "sb_c10_look":(1024,720,2331,f"{STYLE}. {CHARLOTTE} outside at dusk looking with wonder as every little shop, home and passing person around her is joined by faint warm threads of golden light — promises being kept all around her — 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 Coin and the Key","pages 1-8",[
   P("sb_c1_coin","Back home, Grandpa Ben's compass twitched again — pointing between one small silver coin and an old brass key.","A coin… and a key? What's the link?",None,"twitch"),
   P("sb_c1_diary","The old diary fell open. A new line shimmered in Grandpa Ben's hand.",None,'"Find the promise that millions of people trust every single day."'),
   WOW("Hand a stranger your money and walk away — would you? Yet millions of people do it every morning without a second thought, and it always comes back. What kind of promise is strong enough for that? That's the puzzle of this whole adventure."),
   P("sb_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>➊ Why would anyone hand their money to a stranger?<br>➋ Grandpa Ben says it's a <i>promise</i>. How can a promise be worth so much? 🪙"),
 ]),
 ("c2","CHAPTER 2","The Hall of Marble and Light","pages 9-16",[
   P("sb_c2_arrive","One blink, and she stood in a hall so tall it echoed — pillars, chandeliers, and a long, long polished counter.","It's like a palace… for MONEY!"),
   P("sb_c2_clara","A silver-haired lady in a pinstripe suit smiled over her half-moon spectacles. \"I'm Clara, a banker. In here we look after something very fragile.\"","Fragile? But it's all MARBLE!"),
   P("sb_c2_vault","She led Charlotte past a huge round steel door, open just a crack, warm light spilling out.","Is THAT the fragile thing — all the money inside?","Guess again, dear."),
   NOTE("Charlotte's Secret Notebook","Clara is a banker, and she carries an old leather ledger everywhere. She says the fragile thing ISN'T the money in the vault. Then what on earth is it? 🤔"),
 ]),
 ("c3","CHAPTER 3","A Bank Is a Promise","pages 17-26",[
   P("sb_c3_promise","Clara laid a single coin on her palm. \"Give me this,\" she said, \"and I promise to hand it back the moment you ask. That's all a bank is.\"","That's IT? Just… a promise?"),
   P("sb_c3_handback","\"The vault holds the coins,\" she said. \"But the promise is what people are really giving me — and it's the fragile part.\"","Break it once, and nobody comes back!"),
   P("sb_c3_ledger","She opened her ledger. Every neat line was one small promise, written down and waiting to be kept.","A whole book full of promises!",None,"scritch","#c8621f"),
   WOW("Here's the first secret! 🤝 A bank isn't really a building or a vault. A bank is a <b>promise</b>: <i>give me your money, and I'll keep it safe and hand it back whenever you ask.</i> The marble is just marble. The <b>promise</b> is the whole business."),
   ("diagram",),
   NOTE("Charlotte's Secret Notebook","A bank = a PROMISE. Money in, safe keeping, money back whenever you ask. The vault is strong, but the promise is fragile — and the promise is the real thing. 🤝"),
 ]),
 ("c4","CHAPTER 4","Kept a Million Times a Day","pages 27-36",[
   P("sb_c4_millions","Clara clapped once. Suddenly the hall filled with golden threads — thousands of them, criss-crossing, humming.","What ARE all these threads?"),
   P("sb_c4_day","\"One thread for every promise kept today,\" said Clara. \"A farmer's savings. A shopkeeper's change. A grandmother's pension.\"","Millions of promises — every single day!",None,"hum","#37414d"),
   P("sb_c4_trust","\"And each kept promise makes the next one easier to believe. That's how the threads grow into something big.\"","The promises are growing a TREE!"),
   WOW("A promise kept <b>once</b> is a nice thing. A promise kept <b>millions of times a day, for years</b>, turns into something with a special name: <b>trust</b>. Trust isn't built in a day — it's built one kept promise at a time, over and over and over."),
   NOTE("Charlotte's Secret Notebook · SOLVED (part 1)","Every day the bank keeps MILLIONS of little promises. Each one makes the next easier to believe. Lots of kept promises, stacked up over years = TRUST. 🌳"),
 ]),
 ("c5","CHAPTER 5","The Older the Promise, the Stronger","pages 37-44",[
   P("sb_c5_old","\"This bank,\" said Clara softly, \"was keeping promises before your great-great-grandparents were born. Oil lamps. Quill pens. Horse carts outside.\"","It's older than… almost EVERYTHING!"),
   P("sb_c5_grow","She pulled a golden ribbon of time from the old counter to the bright new hall. It grew thicker and brighter all the way.","The older it gets, the STRONGER it looks!"),
   WOW("Most things get weaker with age. A promise does the opposite. Every year a bank keeps its word, <b>the reason to believe it grows</b> — because now there's a longer record of it never breaking. An <b>old</b> promise is a <b>strong</b> promise. Age is the ingredient you cannot rush."),
   NOTE("Charlotte's Secret Notebook","Old bank = strong bank! Every year of kept promises makes people MORE sure. You can build a shiny new tower in a year — but you cannot build two hundred years of keeping your word. ⏳"),
 ]),
 ("c6","CHAPTER 6","Branches in Every Corner","pages 45-52",[
   P("sb_c6_village","The hall vanished. Charlotte stood in a tiny village lane, outside a one-room branch with a bicycle by the door.","The SAME bank — all the way out HERE?"),
   P("sb_c6_net","\"Mountains, deserts, islands, tiny villages,\" said Clara. \"Thousands of branches, all keeping the same promise.\"","It's one giant web across the whole land!"),
   WOW("Now the second secret. 🕸️ The <b>wider</b> a promise reaches, the more useful it becomes — because your money works wherever you go. And the more people join, the more <b>everyone</b> gets: more branches, more machines, more places to be paid. Bigger makes it better, and better makes it bigger. Grown-ups call that a <b>network</b>."),
   NOTE("Charlotte's Secret Notebook · SOLVED!","Branches in EVERY corner — mountains, deserts, islands, tiny villages. The wider the web, the more useful it is; the more useful it is, the more people join. That makes it wider still! 🕸️"),
 ]),
 ("c7","CHAPTER 7","For Everyone, Everywhere","pages 53-60",[
   P("sb_c7_everyone","In the little branch, a farmer, a teacher, a young shopkeeper and a grandmother waited in the same warm queue.","Everyone's promise is the same size here!"),
   P("sb_c7_corners","\"A snowy pass. An island shore. A desert village,\" said Clara. \"If a place has people, we try to be there.\"","Even where hardly anyone lives?!"),
   WOW("This isn't a small thing. This bank reaches into corners where almost nobody else bothers to go — a mountain pass, an island, a village of a few hundred. For millions of families, it's the <b>first</b> bank they ever trusted, and often the <b>only</b> one nearby."),
   NOTE("Charlotte's Secret Notebook","It goes where nobody else goes — snowy passes, islands, tiny desert villages. For millions of families it's the FIRST bank they ever trusted. 🌏"),
 ]),
 ("c8","CHAPTER 8 · THE BIG DISCOVERY","The Bank as Old as the Nation","pages 61-70",[
   P("sb_c8_reveal","Clara led Charlotte to a viewpoint over the great headquarters, golden threads streaming from it to every horizon.","Who keeps ALL of these promises?"),
   P("sb_c8_1806","\"It opened its doors more than two hundred years ago,\" said Clara, \"and it has been keeping its word ever since.\"","Two HUNDRED years of not breaking a promise!"),
   P("sb_c8_scale","\"It grew and grew — until it became the biggest bank in the whole country, in nearly every corner of it.\"","The biggest keeper of promises in the land!"),
   WOW("A \"company\" can be a promise, shared. The <b>State Bank of India</b> began more than two centuries ago and grew into the country's <b>largest bank</b> — thousands upon thousands of branches, hundreds of millions of people, and the government itself standing behind it. It really is a bank as old as the nation."),
   TL([("Two centuries ago","An old bank opens its doors and begins keeping its word."),
       ("1955","The old bank becomes the State Bank of India, with the country standing behind it."),
       ("Over decades","It spreads into every corner — mountains, deserts, islands, tiny villages."),
       ("Today","The nation's biggest bank: hundreds of millions of promises, kept daily. 🏦")]),
   NOTE("Charlotte's Secret Notebook","The State Bank of India is more than two hundred years old and became the nation's BIGGEST bank, in nearly every corner, with the government standing behind it. 🏆"),
 ]),
 ("c9","CHAPTER 9","The Castle Built of Trust","pages 71-80",[
   P("sb_c9_castle","Two kind old men appeared with a glow. Warren pointed at a castle whose walls shimmered like woven golden thread. \"What keeps rivals out, Charlotte?\"","Walls! But what kind?"),
   MOAT([("⏳","Wall One: Age","Two hundred years of kept promises. A rival can build a tower in a year — but nobody can build two centuries of never breaking their word. Age is the one thing money cannot buy.",False),
         ("🕸️","Wall Two: Reach","Branches in almost every corner of the land, even tiny villages. The wider the web, the more useful it is — and the more useful it is, the more people join it.",False),
         ("🏛️","Wall Three: The Nation Behind It","When the country itself stands behind the promise, people sleep easy. That kind of backing makes the trust enormous — and very, very hard to copy.",False),
         ("⚠️","The Crack in the Wall","A giant is SLOW. Small, nimble rivals move faster. And trust must be re-earned every single day — it takes centuries to build and one broken promise to crack.",True)]),
   P("sb_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 bank giant strong, imagine how it could FALL — lending carelessly to people who can't pay back, moving too slowly while nimbler rivals race ahead, or treating one customer badly enough to crack the promise — then carefully avoid each one, every single day."),
   P("sb_c9_verdict","Warren nodded. \"Age, reach, and a nation behind it — a mighty castle. So long as it stays careful, and keeps earning that trust every morning.\"","I SEE the whole picture!"),
   NOTE("Charlotte's Secret Notebook · The Big Secret","This bank is hard to copy: it's OLD (two centuries of kept promises), it's WIDE (every corner), and the NATION stands behind it. But a giant is SLOW, and trust must be re-earned DAILY. Charlie's trick: picture how you'd lose (careless lending, moving too slow, a broken promise), then never do it. Invert! 🏰"),
 ]),
 ("c10","CHAPTER 10","The Threads All Around Us","pages 81-88",[
   P("sb_c10_wake","Charlotte woke in her own bed. The marble hall was gone… but the little silver coin on her desk shimmered softly.","Was it real? It FELT real…"),
   P("sb_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 promises holding the world together. Well done."'),
   P("sb_c10_look","She ran outside at dusk. The shopkeeper, the bus, the family next door — faint golden threads linked them all, quietly being kept.","The promises were everywhere — I just couldn't see them!"),
   WOW("Next time you walk past a bank, you'll know the secret: it isn't the marble or the vault. It's a <b>promise</b>, kept millions of times a day, for two hundred years, in every corner of the land — until it grew into something enormous called <b>trust</b>. That's <b>the bank as old as the nation.</b> 🪙🤝"),
   NOTE("Charlotte's Secret Notebook · What I Learned","➊ A bank is a PROMISE: your money, kept safe, handed back whenever you ask.<br>➋ Kept millions of times a day, promises stack up into TRUST.<br>➌ The OLDER the promise, the stronger it grows — you cannot rush two centuries.<br>➍ The WIDER it reaches (every corner, even tiny villages), the more useful it becomes to everyone.<br>➎ Age + reach + the nation behind it = an enormous castle; but a giant is slow, and Charlie's trick says picture how you'd lose — then re-earn the trust every single day. 💛"),
 ]),
]

HOOK=("sb_c1_swirl","EVERY ORDINARY THING HIDES A SECRET.",
 "Charlotte found a promise strong enough to hold up a whole nation. But the compass is twitching again — this time toward the tiny glass rectangle in her pocket that somehow knows the way to everywhere. Who taught it the world?",
 "NEXT ADVENTURE · The Map in Your Pocket →")

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 BANK IS A PROMISE</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">YOUR COIN</text><text x="120" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">you hand it over</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 PROMISE</text><text x="395" y="165" text-anchor="middle" font-family="Bangers" font-size="26" fill="#2aa15a">kept safe</text><text x="395" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">back whenever you ask</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">kept millions of times</text>
<text x="540" y="182" text-anchor="middle" font-family="Nunito" font-size="12" fill="#555">every day, for 200 years</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">TRUST</text><text x="695" y="165" text-anchor="middle" font-family="Bangers" font-size="24" fill="#f6b53f">enormous</text><text x="695" y="235" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">the bank's real treasure</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">One kept promise &#8594; millions kept daily &#8594; kept for centuries &#8594; in every corner &#8594; TRUST.</text>
<text x="410" y="343" text-anchor="middle" font-family="Nunito" font-size="13" fill="#555">The vault holds the coins. The promise holds the bank.</text>
</svg><div class="figcap">A coin is handed over on a promise; kept millions of times, for centuries, in every corner, that promise grows into trust.</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_clara"); 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/sbi/_head.html").read()
    tail=open("/root/omahaindia.com/comics/site/book/sbi/_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()
