Marwah Stories Library
Marwah Stories Library turns an author’s page-by-page scripts into illustrated Arabic books a child can leaf through. I built everything between the script and the book: a locked illustration style, AI artwork made against it, Python page tooling and a right-to-left flip-book reader. Two books, 64 pages, are live.
- JavaScript
- StPageFlip
- Python
- Pillow
- RTL
- PDF export
- Netlify
- My part
- Pipeline, tooling, reader
- When
- 2026
- Pages
- 64 illustrated
- Status
- Live, two books

Overview
Marwah Stories Library (مكتبة القصص) collects the illustrated children’s books of Marwah Alhalabi, who writes them as page-scheduled scripts: a table of page number, story text and scene description, and nothing else. No illustrations, no book. I built everything between that file and a book a child can leaf through: a locked illustration style profile, AI-generated artwork produced against it, Python tooling that turns the delivered sheets into individual pages, and a dependency-free right-to-left flip-book library. Two books are live, with 64 pages of artwork and a print-ready PDF built per story.
My role
All of it: the illustration direction and the style system, the prompt work, the page tooling, the reader site and the deployment. The author supplies the script; the rest of the path to a finished book is mine.
LimitThe stories are Marwah Alhalabi’s. The artwork is AI-generated against my style profile, with a human eye on every page.
What shipped
- A style profile: one JSON file that locks the series look (chibi proportions, no black outlines, soft cel shading, warm subjects on cool backgrounds, a radial backlight) and carries prompt templates for Midjourney, Flux and Gemini. It separates style from subject on purpose, so a new story inherits the look without inheriting the last book’s cast.
- Artwork generated with AI against that profile, page by page, from the scene descriptions in the script. The consistency rules in the profile are what stop a character drifting between pages, and between books.
- A Python slicer that cuts a finished contact sheet into page images. The sheets are AI-generated, so the grid is genuinely irregular. Column widths differ from row to row, so dividing the sheet evenly slices through artwork. It detects gutters from the image in three passes, and recomputes columns inside each row band to catch the odd bottom row.
- A dependency-free static library: a shelf of story cards, and a page-flip reader on a pinned copy of StPageFlip, navigable by keyboard, buttons and drag-to-turn.
- One shared page renderer behind both the reader and a headless print harness, so a story whose captions are drawn over the artwork at read time exports to PDF with its words intact instead of silently shipping wordless pages.
- A repeated diagonal watermark carrying the author’s name across every page, in the reader and the exported PDF alike, because the books circulate before they are published.
- Deployed as static files on Netlify: HTML, CSS and plain ES5 JavaScript, no build step, no runtime dependencies.
Making it read like an Arabic book
- StPageFlip only turns pages the Western way: it lifts the right-hand page and swings it leftwards, spine on the left. An Arabic book does the opposite.
- Mirroring it in CSS is the obvious fix and the wrong one: it reverses the Arabic captions baked into the artwork and desynchronises the library’s pointer maths from what the reader actually sees.
- So the page list is handed to the library backwards. Reading a reversed book from its last page to its first is physically the same motion as reading an Arabic book front to back: the spine lands on the right, the cover opens leftwards, the earlier page of a spread sits on the right where an Arabic reader looks first, and corner-dragging still works natively because none of the library’s geometry was touched.
- The cost is two page numbers in play at once, so they are never mixed: moving forward in the story calls the library’s “previous”, and the number shown to the reader is carried on the page object rather than inferred from the library’s index.
- A blank leaf goes in front of the closing page rather than behind the cover, so the story stays paired as (1,2), (3,4), with the odd page on the right, and the spare leaf ends up at the back, like a printed book’s end paper.
DecisionThe flip library only turns pages the Western way. Mirroring it in CSS reverses the Arabic in the artwork, so the page list goes in backwards instead.
UX decisions
- The shelf is the landing page: cover, title, author, one line of summary, and chips for category, age range and page count. That is enough to choose a book without opening one.
- Captions exist in two forms and both are supported: burned into the artwork, or drawn over the page at read time. The second keeps the words selectable and lets a typo be fixed without regenerating a picture.
- A story with no artwork yet stays on the shelf marked “coming soon” instead of disappearing, so the library reads as a series that is growing.
- Arabic-first throughout: interface, fonts and direction. There is no English mode, because the readers are children reading Arabic.
- No framework and no bundler; the catalogue is a plain script rather than JSON fetched at runtime, so the site also works opened straight from disk.
Worth a closer look
What I like most is that the whole thing collapses into a repeatable pipeline. A new story arrives as a script table, and every step after that is either a documented command or a prompt template resolved against the style profile, so the third book costs a fraction of the first and still looks like it belongs beside it. The honest limit is the artwork: AI generation still needs a human eye on every page, and the slicer’s grid detection assumes panels sitting on a white sheet.
LimitThe slicer’s grid detection assumes panels sitting on a white sheet.
Screens



