Cover before the spreads
spreadStartIndex is the page every spread is counted from. The default 0 pairs the pages from the very first one, while the 1 used here leaves the first page on its own as a cover and pairs the pages that follow it. The data-page-side variants on the page set, the page slot, and the page are what keep a page left unpaired at either end on the half of the spread it belongs to.
Source code
import * as ComicViewer from "@publira/comic-viewer";
export const Reader = ({ pages }) => (
<ComicViewer.Root pages={pages} spreadStartIndex={1}>
<ComicViewer.Viewport>
<ComicViewer.ViewportTrack>
<ComicViewer.ViewportPageSet className="data-[page-side=left]:justify-start data-[page-side=right]:justify-end">
<ComicViewer.ViewportPageSlot className="data-[page-side=left]:justify-end data-[page-side=right]:justify-start">
<ComicViewer.ViewportPage className="data-[page-side=left]:justify-end data-[page-side=right]:justify-start">
<ComicViewer.PageCanvas />
</ComicViewer.ViewportPage>
</ComicViewer.ViewportPageSlot>
</ComicViewer.ViewportPageSet>
</ComicViewer.ViewportTrack>
</ComicViewer.Viewport>
<ComicViewer.Toolbar />
<ComicViewer.PageNavigation />
</ComicViewer.Root>
);