Settings

Standard CSS carries most of a document’s appearance. What it can’t express — how content flows (pages vs scroll), what page furniture prints, what an editor does — rides the same stylesheet as namespaced custom properties. They cascade, condition, and guard exactly like every other declaration (put one inside @media print or a data-spub-* guard — it just works), and a bare browser simply ignores them.

Declare them on the document surface (main), or under any condition:

main { --spub-flow: continuous; --spub-outline: right; }
@media print { main { --spub-numbering: on; --spub-numbering-format: "{n}."; } }
html[data-spub-intent~="edit"] main { --spub-editor-active-block: highlight; }

Renderers resolve them through the engine’s cascade (resolveSettings) — the same result the browser would compute — and read them as one typed Settings object. Unknown values degrade to the default (warn, never fail). This page is the normative vocabulary; how an application’s workspace, panels, and editor chrome realize these values is app documentation.

Pagination and flow

Content is divided into physical pages; a viewport shows one page or a two-page spread.

Property Values (default first)
--spub-page-width length in rem · px · pt · em · % · words, default 34rem — preferred physical-page width; words uses an average five-character word
--spub-page-layout auto · single · spread — responsive, one page, or a two-page spread
--spub-flow flip · continuous · snap — page replacement with no visible scroll (default), free scrolling, or page-snapping scrolling
--spub-direction horizontal · vertical — the axis along which pages scroll, snap, or flip
--spub-flip-sensitivity 10%100% or auto, default 25% — flip threshold; lower values flip sooner
--spub-page-gap length, default 2rem — the gap between pages in a spread
--spub-canvas-margin length, default 3rem — equal horizontal margins for the canvas area, subtracted before pagination
--spub-page-align space-evenly · start · center · end · space-between · space-around · stretch — placement of the page or spread in the content area

A paginating renderer honors the complete CSS Fragmentation page vocabulary from the sheet: page, left, right, recto, verso, and column forced breaks; the avoid family; break-inside; and the legacy page-break-* aliases. Side/folio constraints insert an intentional blank page when needed; column advances one physical page. The reading measure, padding, and margins are real CSS on main (max-width, padding, margin-inline); for a physical-page surface the active print @page margins are subtracted from the page box.

The outline / index navigator beside the document:

Property Values
--spub-outline right · left · hidden — which side holds the outline (hidden removes it)
--spub-outline-width auto or length — preferred outline width; auto uses intrinsic content width capped by --spub-page-width
--spub-outline-display layout · spline — full labels or a compact column of division numbers/dots until expanded
--spub-outline-font-size / --spub-outline-font-family outline typography; unset / inherit follows the document
--spub-outline-text-align start · center · end
--spub-outline-vertical-align top · middle · bottom
--spub-outline-indexes show · fold · hide — the derived index groups (Characters, Locations, …)

Source

The raw document source beside its rendered preview:

Property Values / meaning
--spub-source right · left — which side holds the source panel
--spub-source-width length (default 24em) — source panel width
--spub-source-syntax-color on · off — color recognized syntax tokens
--spub-source-line-numbers on · off — show a line-number gutter
--spub-source-wrap-lines on · off — wrap long lines instead of scrolling horizontally
--spub-source-max-line-width none or length — cap the readable width of each source line

Progress

The optional live reading percentage:

Property Values
--spub-progress percent · none (default percent)
--spub-progress-position bottom · top · left · right of the content column

Informational only — no range control, navigation buttons, or history.

Page furniture

Templates take {n} {pages} {title} {author} {division}:

Property Values
--spub-numbering off · on
--spub-numbering-position bottom-center · bottom-left · bottom-right · top-center · top-left · top-right
--spub-numbering-format template string, default "{n}"
--spub-numbering-from integer (earlier pages unnumbered)
--spub-page-header / --spub-page-footer / --spub-page-watermark template strings
--spub-page-gutter / --spub-page-bleed lengths (beyond the native @page size/margins)
--spub-show-nonprinting hide · show — render blocks with behavior.printing: false (notes, boneyard) in paged / print output

Hiding a whole section is real CSS: footer { display: none; }.

Writing behaviour

Ignored by read-only renderers. Writing uses the same page settings and appearance cascade as reading — entering an editing surface must not change the page geometry configuration (width, flow, fragmentation). The ribbon is an ordinary workspace pane like Outline or Source: it takes a workspace track on its edge (the canvas repaginates to the remaining space, exactly as it does when any pane opens), separated by the pane seam, which drag-resizes it. Write/edit intent rules may supply only the editor properties below.

Property Values
--spub-editor-block-labels off · margin · active — hide labels, label every block in the page margin, or label only the active block
--spub-editor-active-block underline · highlight · margin-line — treatment for the block containing the caret
--spub-ribbon top · bottom · left · right — which workspace edge holds the ribbon pane
--spub-ribbon-size-top length — pane height when docked top; empty sizes to content. Each placement keeps its own size; the seam drag persists it
--spub-ribbon-size-bottom length — pane height when docked bottom
--spub-ribbon-size-left length — pane width when docked left
--spub-ribbon-size-right length — pane width when docked right

Graceful degradation

A renderer that can’t page falls back to continuous flow and honours the rest. Settings a surface has no use for (editor knobs in a reader, panes in a print pass) are simply unread. The machine-readable catalog — names, types, enums, defaults — is SETTINGS in @script-pub/format (sheet/settings.ts), the single source for editor forms and validation’s warnings.