# AGENTS.md

## Project overview

mkbooks is a Python CLI tool that converts Markdown chapters into a paginated book (HTML) using [PagedJS](https://github.com/pagedjs/pagedjs) v0.4.3 as a CSS Paged Media polyfill. Configuration lives in `mkbooks.yml`.

## Setup commands

- Install (editable): `uv pip install -e . --force-reinstall --quiet`
- Build book: `uv run mkbooks build --no-open`
- Full rebuild: `uv pip install -e . --force-reinstall --quiet && uv run mkbooks build --no-open`

## Project structure

- `src/mkbooks/templates/book.html.j2` — Main template (HTML + inline CSS)
- `src/mkbooks/templates/book.css.j2` — Standalone CSS template (available but not currently used)
- `src/mkbooks/builder.py` — Build engine
- `src/mkbooks/config.py` — YAML config parsing with dataclasses
- `src/mkbooks/cli.py` — Click CLI (`build`, `init`, `new`, `add-chapter`, `serve`)
- `mkbooks.yml` — Book configuration

## Code style

- Python 3.12+, managed with `uv`
- Type hints with `from __future__ import annotations`
- Dataclasses for config models
- Jinja2 templates for HTML and CSS generation

## PagedJS restrictions (CRITICAL)

PagedJS v0.4.3 has CSS parser bugs that cause the fatal error:

```
Uncaught (in promise) Error: item doesn't belong to list
```

Follow these rules strictly when writing or modifying any CSS in the templates.

### Never use compound multi-selectors

PagedJS crashes on rules with comma-separated selectors that combine pseudo-classes (`:first-of-type`, `:first-child`, etc.) or the `+` (adjacent sibling) combinator.

**Bad — breaks PagedJS:**
```css
.chapter-body > p:first-of-type,
.chapter-body > h1 + p,
.chapter-body > h2 + p {
    text-indent: 0;
}

*, *::before, *::after {
    box-sizing: border-box;
}
```

**Good — one selector per rule:**
```css
.chapter-body > p:first-of-type { text-indent: 0; }
.chapter-body > h1 + p { text-indent: 0; }
.chapter-body > h2 + p { text-indent: 0; }

* { box-sizing: border-box; }
*::before { box-sizing: border-box; }
*::after { box-sizing: border-box; }
```

> Reference: [PR #284 in pagedjs/pagedjs](https://github.com/pagedjs/pagedjs/pull/284) — fix not merged.

### Never use `margin-inside` / `margin-outside`

These are Prince XML proprietary properties. Not standard CSS, not supported by PagedJS. Use `margin-left` / `margin-right` with `@page:left` and `@page:right` for asymmetric margins.

### Never use `var()` inside `@page` rules

PagedJS does not support CSS Custom Properties inside `@page`. All values must be literals.

### Do not mix `@bottom-left`, `@bottom-right` with `@bottom-center`

Declaring margin boxes that were not previously defined in `@page` causes errors. Use one type of margin box consistently.

### CSS must be inline in `<style>`

All styles go inside a `<style>` tag in the HTML. The template `book.html.j2` contains CSS directly. Do not use `<link rel="stylesheet">` to load external CSS with `@page` rules.

## Testing instructions

- After any template change, run the full rebuild command above.
- Open `output/book.html` in a browser to verify PagedJS renders without errors.
- Check the browser console — there should be zero errors from `paged.polyfill.js`.
