{
"id": "page.cavu.book",
"defs": {
"main": {
"type": "object",
"required": [
"spine"
],
"properties": {
"cover": {
"type": "blob",
"accept": [
"image/*"
],
"maxSize": 1000000,
"description": "Book cover, typically portrait orientation. Share the same blob CID with the frontmatter document's coverImage."
},
"spine": {
"type": "array",
"items": {
"ref": "#spineEntry",
"type": "ref"
},
"maxLength": 10000,
"description": "Ordered entries for the site.standard.document records holding the book's content, in reading order. Chunk boundaries are storage artifacts, invisible to the reader; a chunk is usually chapter-sized but not always."
},
"series": {
"ref": "#seriesRef",
"type": "ref",
"description": "The series this book belongs to, if any."
},
"listing": {
"type": "string",
"format": "at-uri",
"description": "AT-URI of a pub.byline.book record carrying this book's catalog metadata (editions, ISBNs, retailer links, genres). The reading layer stays here; the listing layer stays there."
},
"coverAlt": {
"type": "string",
"maxLength": 5000,
"description": "Alt text describing the cover image, for accessibility.",
"maxGraphemes": 1000
},
"language": {
"type": "string",
"format": "language",
"description": "Primary language of the book's content."
},
"contributors": {
"type": "array",
"items": {
"ref": "pub.byline.defs#contributor",
"type": "ref"
},
"maxLength": 100,
"description": "Credited contributors (author, translator, editor, illustrator, narrator). Reuses byline.pub's contributor shape: name required, AT Protocol DID optional, so off-protocol collaborators can be credited. The repo owner is presumed primary author unless roles say otherwise."
},
"pageProgression": {
"type": "string",
"description": "Direction pages progress in paginated and two-page-spread views, mirroring EPUB's spine-level page-progression-direction. Absent means ltr; rtl for right-to-left books (manga). Chiefly meaningful for pre-paginated page.cavu.pages content, where it decides which side of a spread comes first and which way pages turn.",
"knownValues": [
"ltr",
"rtl"
]
},
"completionStatus": {
"type": "string",
"description": "Whether the book is still being serialized.",
"knownValues": [
"ongoing",
"completed",
"hiatus"
]
}
},
"description": "Book extension object, embedded in a site.standard.publication record as a pass-through `book` property (the Leaflet `theme` pattern). Its presence marks the publication as a book; series publications omit it. The publication's standard fields remain the fallback identity (name = title, description = blurb, icon = square mark)."
},
"seriesRef": {
"type": "object",
"required": [
"publication"
],
"properties": {
"name": {
"type": "string",
"maxLength": 2560,
"description": "Series name, denormalized for display without fetching the series publication.",
"maxGraphemes": 256
},
"index": {
"type": "integer",
"minimum": 0,
"description": "Position of this book within the series reading order."
},
"publication": {
"type": "string",
"format": "at-uri",
"description": "AT-URI of the series' site.standard.publication record."
}
}
},
"spineEntry": {
"type": "object",
"required": [
"document"
],
"properties": {
"roles": {
"type": "array",
"items": {
"type": "string",
"maxLength": 1000,
"knownValues": [
"cover",
"frontmatter",
"toc",
"bodymatter",
"backmatter",
"acknowledgments",
"appendix",
"index",
"glossary",
"notes",
"colophon"
],
"maxGraphemes": 100
},
"maxLength": 10,
"description": "Structural roles of this chunk, inspired by the EPUB structural semantics vocabulary. Readers use these to find special documents without fetching them — notably `toc`, which marks the document containing the page.cavu.blocks.toc block (the role EPUB's properties=\"nav\" manifest flag plays). Untagged entries are ordinary body matter."
},
"linear": {
"type": "boolean",
"description": "Whether this entry is part of the primary continuous reading flow; absent means true, mirroring EPUB's itemref linear attribute. False for supplementary material (appendices, indexes, notes) that should be reachable from the TOC but skipped when paginating straight through."
},
"document": {
"type": "string",
"format": "at-uri",
"description": "AT-URI of the site.standard.document record holding this chunk's content."
}
}
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1
}