# Changelog

## [Unreleased]

### Added
- **Release installer** — `Installer\Bindery.iss` (Inno Setup) packages the Release build into `Bindery-<version>-Setup.exe`, checking for the .NET 9 Windows Desktop Runtime at install time and offering to clean up `%AppData%\Bindery` on uninstall (leaves `Documents\Bindery Projects` untouched). `Installer\build-release.ps1` builds Release, compiles the installer via ISCC, and copies the installer + `CHANGELOG.md` to `D:\AbnormalitySoftware\wwwroot\apps\Bindery`. Added `<Version>1.0.0</Version>` to `Bindery.csproj` as the single source of truth the script reads.

### Fixed
- **App looked visually inconsistent with AbigailsMediaRenamer despite sharing theme names** — Bindery's theme files (`AbigailTheme`/`BoringTheme`/`BoringDarkTheme`) used different, more saturated hex values than Renamer's, and — the bigger factor — only defined *named* styles that individual windows had to explicitly opt into (only 32/69 buttons and 7/14 textboxes did, the rest fell back to plain default Windows chrome). Rewrote all three theme files to match Renamer's exact palette and to add Renamer's global unkeyed `Window`/`Button`/`TextBox`/`ComboBox`/`CheckBox`/etc. styles, so every control reskins automatically app-wide like Renamer's does. Also fixed a latent gap where `BoringTheme`/`BoringDarkTheme` were missing several resource keys (`WindowHeaderBannerBackground`, `WatcherBadgeBackground`, etc.) that the About window and others depend on — switching to Light/Dark theme would have left those unresolved. Verified by launching the app under all three themes.
- **About window's Close button didn't match the Ko-Fi/Website/Email buttons** — restyled to the same solid-color pill shape (padding, rounded corners, hand cursor) using the app's existing accent color, instead of a plain default button.
- **Duplicate DLLs in build output (`Libraries\` subfolder)** — dependency DLLs existed both in the output root and in `Libraries\`, because the post-build step *copied* them instead of moving them, so .NET resolved everything from the root before the `AssemblyResolveHelper` fallback ever got a chance to run. Since the whole point of `Libraries\` is a tidy install/output folder (just the exe + a few files at the top level), changed the build step to *move* dependency DLLs into `Libraries\` instead of copying them — verified with a full clean rebuild + launch that the app still starts fine and resolves everything from `Libraries\` (root is now just `Bindery.exe/.dll/.pdb`, config files, and native runtime folders).
- **About window unreachable — build was broken** — `MainWindow.xaml`'s About button was wired to `Click="About_Click"`, but that handler didn't exist in `MainWindow.xaml.cs`, so the whole solution failed to compile (CS1061). `AboutWindow` itself was already fully built and correct; nothing ever constructed it. Added the missing `About_Click` handler (mirrors `Settings_Click`): opens `AboutWindow` as an owned dialog with the current `AppSettings` and the assembly's version string.
- **Copyright field swallowing Dedication and the entire Table of Contents; DOCX spacing/line breaks stripped on extraction** — root cause was `DocumentParserService.ParseDocx` silently dropping every blank paragraph, which made `FrontMatterDetectionService.CollectSectionEnd`'s 3-consecutive-blank-line stop condition permanently dead code. With that safety net inert, a Copyright section's scan only stopped at a fixed set of heading regexes — and a manuscript whose dedication heading reads "Dedications –" (not "For/To/…") and whose Word-generated TOC has no "Contents" header line at all matched none of them, so the scan just kept consuming everything (dedication, title reprise, all 17 TOC entries) until the next real Heading1 85 paragraphs later. Fixed by: keeping blank paragraphs in the parsed list (filtered back out at the two places that only want prose — chapter detection and chapter body rendering — so no stray empty lines appear in exported books); mapping Word's own `TOC1`/`TOC2` paragraph style to a new `ParagraphStyle.TableOfContents` and using it as a real detection/boundary signal instead of relying on a "Contents" text match; adding a "Dedication(s)" heading pattern; and having `ExtractText` preserve single blank-line gaps instead of collapsing all of them (the actual fix for "spacing stripped"). Verified against the user's real manuscript and real project via the scratchpad harness — Copyright/Dedication/TOC are now three clean, correctly-bounded sections, and chapter detection still finds exactly the 17 chapters the manuscript's own TOC lists.
- **Silent parse failure on a locked source file produced a "complete" book with all prose missing** — `DocumentParserService.ParseFile` caught every exception (including the file simply being open in Word) and returned an empty paragraph list, indistinguishable from a legitimately short/empty file. The export pipeline doesn't treat "no source paragraphs" as an error, so it silently produced a structurally-correct PDF (right chapter headings, right TOC, right front/back matter — those come from a saved snapshot) with every chapter's actual prose missing, no warning anywhere. Now throws a clear, user-facing error when a file can't be opened at all (locked/permission denied) instead of swallowing it; `ExportWindow` and the preview's Refresh already had proper error handling in place and just needed a real exception to catch.
- **Refresh not re-syncing everything from the source files** — the preview body itself was never stale (the parser always reads straight from disk), but two things Refresh didn't touch: the word/page count summary, and front/back matter text (Copyright, Dedication, About the Author, etc.), which is a saved snapshot from whenever the Layout window last ran detection — editing the manuscript directly had no effect on it. "↻ Refresh" now also recalculates the word count and re-syncs front/back matter text from the current source files (confirmed with the user: this intentionally overwrites a manual edit typed directly into the Layout window if it's since diverged from the manuscript — chapters are unaffected, they keep the separately-chosen "persist once, re-scan only via Chapter Setup" behavior).
- **Chapter detection picking up back matter as a fake chapter** — `ChapterDetectionService.DetectChapters` had no way to know where the story body *ends*, only where it starts, so a short heading like "About the Author" immediately followed by a long bio paragraph scored exactly like a real chapter break and got misdetected as one. Added a `backMatterStartLine` bound, wired through PDF/EPUB export and Chapter Setup's live scan.
- **PDF ignoring Blank Page inserts and Front/Back Matter order entirely** — confirmed against a real project: `PdfExportService` used a hardcoded fixed section sequence with zero Blank Page support and no regard for the actual order configured in the Layout window, unlike EPUB and the preview which already respected it. Rewrote to iterate `FrontMatterOrder`/`BackMatterOrder` the same way `EpubExportService` already does. Also added a `Colophon` PDF page (existed in EPUB, never in PDF).
- **"Apply"/"Done" not actually saving to disk** — every settings dialog (Layout, Chapter Setup, Font Selection, Artwork Manager) only wrote into in-memory settings and marked the project dirty; the real save only happened via a separate, easy-to-forget toolbar click. Renamed these buttons to "Save" and wired them to actually persist the project to disk immediately on click.
- **App icon not applied** — csproj referenced a nonexistent `Resources\AppIcon.ico` with `ApplicationIcon` commented out; the real file is `Resources\app.ico`. Wired it up as both `ApplicationIcon` (exe/taskbar icon) and `MainWindow.Icon` (in-app title bar icon).
- **Layout window section reordering** — replaced the drag-and-drop reorder in the Layout window's Front/Back Matter lists (which didn't reliably commit the drop position) with simple ▲/▼ move buttons per row, matching the existing source-file list reorder pattern.
- **Cover art rendering tiny in preview** — `PreviewRenderService` set `MaxWidth`/`MaxHeight` on the cover `Image` without `Width`/`Height`, so `Stretch=Uniform` only ever shrank oversized images and never scaled small ones up — leaving small cover art stranded in a mostly-blank page. Now sets explicit `Width`/`Height` so the image always scales to fill the available page area.
- **Project save losing Title/Author on load** — `MainViewModel.CurrentProject`'s setter never raised `PropertyChanged` for `ProjectTitle`/`ProjectAuthor`/`ProjectIsbn`/`ProjectYear`/`PaperSizeLabel`, so opening or creating a project left the bound Title/Author textboxes showing stale values from the previous project even though the underlying data was intact. Save wasn't actually losing data — the UI just wasn't reflecting what was loaded.
- **Blank pages / back matter missing from preview** — `PreviewRenderService` rendered a hardcoded front-matter sequence (title → copyright → dedication → epigraph → foreword → TOC) and never looked at `FrontMatterOrder`/`BackMatterOrder` at all, so custom ordering, inserted Blank Page entries, and every back-matter section (About the Author, Also By, Acknowledgements, Colophon) were silently dropped from the preview even though they exported correctly. The preview now walks both order lists exactly like the EPUB/PDF exporters do.
- **Layout window redesign** — merged the "Page Layout" (paper size) and "Sections" tabs into a single scrollable window (880×840, up from 700×700) so paper size, front matter, and back matter are all visible in one place without tab-switching. Front Matter and Back Matter are now collapsible `Expander` sections (Front open, Back collapsed by default) instead of two always-open lists competing for space, and the nested list scrollbars were removed in favor of one outer scrollbar.
- **KDP PDF export missing cover art** — `PdfExportService` never embedded the front cover image at all, unlike EPUB and the preview. Now renders it as a full-bleed first page (`Image(...).FitArea()`, no margins) before the title page.
- **KDP PDF export ignoring font choices** — none of `PdfExportService`'s `Text()` calls set `FontFamily`, so every page rendered in QuestPDF's default font regardless of the Font Selection window. All text now carries `fonts.BodyFontFamily`/`fonts.HeadingFontFamily`, and heading weight (Regular/SemiBold/Bold) is applied via a new `ApplyHeadingWeight` helper (QuestPDF exposes weight as named methods, not a settable property).
- **Page numbering config** — added `LayoutSettings.PageNumberPosition` (None/Bottom-Left/Bottom-Center/Bottom-Right/Top-Left/Top-Center/Top-Right) and `PageNumberStart` (After Front Matter — new default / From the Very First Page), configurable from the Layout window. Previously PDF export always showed a centered page number starting on the title page itself; the default now shows no number until the first chapter, numbered from 1. Also fixed the Dedication page, which had no page-number call at all in the old code.
- **Table of Contents page numbers + config** — the KDP PDF's TOC now shows each chapter's real page number, right-aligned, resolved via QuestPDF's `Section`/`BeginPageNumberOfSection` (accurate regardless of how many physical pages front matter ends up taking). Added `LayoutSettings.TocTitle` (heading text, default "Contents") and `TocShowPageNumbers` toggle, both configurable from the Layout window and respected by PDF, EPUB, and the preview.
- **Artwork Manager drop zones** — the front/back cover, spine, and chapter-header wells only registered a drag/drop when aimed at the centered placeholder text, because their `Border` had no `Background` set and WPF doesn't hit-test transparent-by-omission areas. Added `Background="Transparent"` to all four wells so the entire frame is a valid drop target. (Browse… buttons for a non-drag-and-drop path already existed on each well.)
- **Front/back matter doubling on project load** — `LayoutSettings.FrontMatterOrder`/`BackMatterOrder` are field-initialized with real default entries, and Newtonsoft.Json's default `ObjectCreationHandling.Auto` *appends* deserialized items to an existing non-null collection instead of replacing it — so every load doubled up every non-blank-page section. `ProjectService.Load` now deserializes with `ObjectCreationHandling.Replace`, and `LayoutSettings.DeduplicateSections()` runs on every load as a self-healing repair for `.bindery` files already saved with the bug baked in.
- **PDF page numbers showing "1" on every page** — the previous fix used a manually-incremented counter baked into static footer text per `container.Page()` call. QuestPDF's page containers aren't one physical PDF page each — long chapters overflow across many physical pages using the same repeating footer template, so every overflow page inherited the same baked-in number. Replaced with QuestPDF's own dynamic `CurrentPageNumber().Format(...)`, which resolves correctly per actual physical page. The TOC's page numbers (`BeginPageNumberOfSection`) now use the same offset formatter as the footer, so they agree — previously the TOC showed the raw physical page (e.g. "5") while AfterFrontMatter numbering restarted the footer at "1" for the same page.
- **Detected sections (About the Author etc.) not auto-enabling** — `LayoutWindow`'s detection badge logic required extracted text to be non-blank before it would flip a section's checkbox on, so a section that was *found* but only weakly *extracted* (confirmed case: About the Author, whose extraction previously even included the trigger heading itself, sometimes leaving little behind it) showed the green "Detected" badge but silently stayed disabled. Detection and safe-to-enable are now independent — a detected section always gets enabled (as long as the user hasn't already customized the field), regardless of extraction quality.
- **Detected section text duplicating its own heading** — Foreword/About the Author/Acknowledgements/Also By extraction included the trigger heading line itself (e.g. "About the Author") as the first line of extracted text, which then rendered twice since every export service already prints its own heading for these sections. Extraction now starts after the heading line.
- **Epigraph detection missing entirely** — `FrontMatterDetectionService` had zero code for it despite the Layout window already supporting an Epigraph text + attribution field. Added: a short paragraph immediately followed by an attribution line (`— Author Name`) is now detected and both parts extracted.
- **PDF missing Epigraph and Also By This Author entirely** — both rendered in EPUB but had no PDF page at all; a detected/enabled Epigraph or Also By section would silently vanish from the PDF. Added, matching the existing front/back matter page structure.
- **Auto-Detect chapter scan not persisted** — Chapter Setup's "Detected chapters" grid was a disposable live preview (blank until you clicked Refresh, no path into anything saved), while export re-ran detection fresh every time regardless. Now the scan is saved into the project (`ChapterSettings.ManualChapters`) on Apply and reused at export instead of re-scanning live, falling back to a live scan only for brand-new projects that have never had Chapter Setup opened. Trade-off, confirmed with the user: no longer auto-adapts if you edit your manuscript without reopening Chapter Setup to re-scan.

### Added
- **Per-section vertical position (PDF)** — Copyright, Dedication, Epigraph, Foreword, About the Author, Also By, and Acknowledgements can each be set to Top/Middle/Bottom placement on their page from the Layout window, with sensible per-type defaults (Dedication/Epigraph default to Middle, matching how they always rendered before this was configurable). EPUB is unaffected — reflowable HTML has no fixed page to position within.
- **Paragraph alignment** — new Left/Justify/Center/Right setting in the Font Selection window (with a live preview), applied to body paragraphs in both PDF and EPUB export.
- **Live PDF/EPUB preview** — the Preview pane no longer runs a separate hand-built approximation of the book layout (`PreviewRenderService`, now deleted). It renders the project through the *actual* `PdfExportService`/`EpubExportService` into a scratch temp file and displays it in an embedded `WebView2` control, with a PDF/EPUB toggle and Prev/Next spine navigation for EPUB. This guarantees the preview always matches real export output exactly — fonts, cover art, page numbers, section order, everything — since it's the same code path, not a second implementation kept in sync by hand.
- **Real PDF chapter bookmarks** — the PDF's "Bookmarks" panel previously showed raw PDF structure instead of chapters, because QuestPDF has no outline API. A new post-processing pass (`PdfExportService.ApplyBookmarksAndPageLayout`, using `PdfPig` to locate each chapter's page via an invisible marker and `PdfSharpCore` to write real `Outlines` entries) makes it a genuine, working chapter list that jumps to the right page.
- **EPUB toolbar parity** — the EPUB preview gained a chapter-jump dropdown, zoom in/out, and print, to feel closer to the PDF viewer's chrome instead of a bare browser view. A shared fullscreen button now sits in the preview header for either mode. Search and page rotation were deliberately not added — no built-in primitive for EPUB search, and rotation doesn't apply to reflowable HTML.

### Known limitation
- **PDF two-page spread can't be forced as the default** — every generated PDF now carries a `PageLayout=TwoPageLeft` viewer preference (verified written correctly), but live-testing showed Chromium's built-in PDF viewer (same engine WebView2 uses) doesn't honor that on load — it always opens single-page regardless. Two-page view still works well when manually toggled via the viewer's own "Page Layout" button (kept visible, since hiding it would remove the only way to reach two-page view at all).
- **FrontMatterDetectionService** — scans manuscript for copyright, TOC, dedication, foreword, about-author, etc.; returns BodyStartLine and BackMatterStartLine.
- **LayoutSettings model** — holds PaperSize + ordered front/back matter section lists. Rendering order and enabled state are driven by `FrontMatterOrder` / `BackMatterOrder` (List<LayoutSectionEntry>). The `Include*` computed properties remain so export services are unchanged.
- **LayoutWindow** (📐 toolbar button) — single "Sections" tab with two drag-reorderable lists (Front Matter and Back Matter) separated by a Body separator. Each row shows: drag handle (≡), checkbox, name, Detected badge, and inline text editor. `+ Blank Page` buttons insert blank-page entries anywhere in either list. Drag a row to reorder; ✕ removes Blank Page entries.
- **EPUB cover page** — `cover_page.xhtml` is now the first spine item when a front cover image exists. The manifest item carries `properties="cover-image"` (EPUB3). Previously the image was in the manifest but never rendered as a page.
- **EPUB Table of Contents page** — visible `ch000b_toc.xhtml` inserted in the spine after front matter when IncludeTableOfContents is enabled. Separate from the nav/NCX which only drives e-reader menus.
- **PDF Table of Contents page** — QuestPDF page listing all chapter titles, inserted after front matter.
- **Preview TOC section** — Contents heading + chapter list shown in the two-page preview when TOC is enabled.
- **Back matter in order** — EPUB and PDF now render back matter sections in the order defined by BackMatterOrder, with BlankPage support.
- **BookPreset templates** (⚡ toolbar button) — five built-in presets: Novel, Short Story Collection, Novella, Poetry Collection, Non-Fiction. Each configures chapter detection mode, numbering, and front/back matter toggles. Opens a chooser dialog from a new toolbar button.
- **Artwork size recommendations** — ArtworkManagerWindow now receives the project's PaperSize. Front Cover well shows recommended pixel dimensions (trim × 300 DPI) and EPUB minimum (2560 px). Info line shows ✅/⚠️ per requirement. Cover and Back Cover borders display at the correct book aspect ratio. Refreshes when browsing or dropping a new image.

### Fixed
- **Back matter doubling** — `FrontMatterDetectionResult` now carries `BackMatterStartLine`. All three services (EPUB, PDF, Preview) filter body paragraphs to `LineNumber < BackMatterStartLine`, so detected About Author / Acknowledgements no longer appear in both the chapter content and the back matter page.
- **Copyright detection not pre-populating** — `LayoutWindow.ApplyDetectionBadges` now overwrites the text box when it still contains `[Year]` or `[Author]` placeholder tokens (not just when it is empty). About Author already worked because its default is empty.
- **Chapter detection skip** — `DetectChapters` already received `bodyStartLine`; BackMatterStartLine now also prevents back matter headings from being misidentified as chapters.

### Changed
- **PaperSize enum** — moved from `ExportSettings` to `LayoutSettings`. All references updated.
- **Chapter Setup window** — Front/Back Matter tabs removed. Those settings now live in the Layout window. Note added pointing users there.
- **FrontMatterDetectionResult** — added `BackMatterStartLine` property.

### Build
0 errors, 0 warnings.
