/* hardback.css — the book on the desk.
 *
 * NOT a copy of the journal's leaf.css. That file is 779 lines and is the
 * notebook itself: it carries global chrome, a toolbar, lined-paper ruling,
 * `contenteditable` editor states, an ink layer and a whole reader dialog. A
 * prose reader would have to fight most of it. This is the scoped extraction
 * the plan calls for — the desk, the case, the block, the leaf, and nothing
 * about writing on it. */

:root{
  --desk:#2a211a; --paper:#f8f5ee; --paper2:#ece5d5; --ink:#23201a;
  --ink2:#5c5447; --ink3:#8a8073; --rule:#d9d0bd; --edge:35,32,26;
  --board:#5a3a24; --board2:#3f2817;
  color-scheme:light;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme=light]){
    --desk:#15120f; --paper:#1b1815; --paper2:#242019; --ink:#d9d2c4;
    --ink2:#a89f90; --ink3:#776f63; --rule:#332e27; --edge:236,230,216;
    --board:#3a2616; --board2:#241708;
  }
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%;overflow:hidden;overscroll-behavior:none}
body{background:var(--desk);color:var(--ink);height:100dvh;
  display:flex;flex-direction:column;
  font:14px/1.5 ui-serif,Georgia,"Times New Roman",serif;
  -webkit-font-smoothing:antialiased;
  padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);
  touch-action:none;-webkit-user-select:none;user-select:none}

/* The desk has a grain, procedurally — no image assets anywhere in this repo. */
body::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:
    repeating-linear-gradient(94deg,rgba(0,0,0,.055) 0 2px,transparent 2px 7px),
    repeating-linear-gradient(91deg,rgba(255,255,255,.022) 0 1px,transparent 1px 13px);
  opacity:.9}

.book{flex:1;min-height:0;display:flex;flex-direction:column;
  align-items:stretch;position:relative;padding:14px 16px 10px;gap:8px;z-index:1}
/* THE THICKNESS ON SHOW, as opposed to the thickness the book has. A shut
   book's block is clamped flat between its boards; it is the act of opening
   that lets the leaves splay. `--open` runs 0 to 1 across exactly that turn and
   is a flat 1 everywhere else, so an ordinary page turn pays nothing for this
   and the cover turn gets the book swelling open underneath it. */
.stage{--open:1}
.stage{--tnow:calc(var(--tmax) * var(--open));--sq:calc(var(--sqmax) * var(--open))}
/* THE BOOK'S OWN OFFSET, shared by every layer pinned to the gutter: both
   slots, both boards, the turning leaf and its cast shadow. A shut book is one
   board and belongs in the middle of the screen; an open one puts its GUTTER
   there instead, so the body sits half a page further right.
   This used to be a boolean — `[data-closed] .slot.R{margin-left:-sw/2}` —
   while the thickness and the square rode `--open` continuously. One quantity,
   two clocks. So the block swelled smoothly out of a book that then teleported
   200px sideways on landing, and for the whole of the turn the piles stood in
   the desk, pinned to the OPEN book's edge with the body still centred as a
   shut board. Measured at k=0.40 of the cover turn: body at 520..920, right
   pile at 1120..1206. One clock now. */
.stage{--shift:calc((1 - var(--open)) * var(--sw) / -2)}
.stage{flex:1;min-width:0;position:relative;
  display:flex;align-items:center;justify-content:center;
  /* A lifted leaf comes TOWARD you, so it magnifies and stands past the boards
     at head and tail. That is what a real page does; the vanishing point is
     raised a little so the overhang reads as a page rising rather than as the
     book growing. The stage is NOT clipped, or the leaf would be guillotined
     at the top of its arc. */
  perspective:2600px;perspective-origin:50% 45%}

/* ---- the case: boards the block sits in, drawn under everything ---- */
.case{position:absolute;top:50%;left:50%;
  height:calc(var(--sh) + var(--sq) * 2);
  margin-top:calc((var(--sh) + var(--sq) * 2) / -2);
  background:linear-gradient(104deg,var(--board) 0%,var(--board2) 62%,var(--board) 100%);
  box-shadow:0 3px 10px rgba(10,6,3,.5);z-index:0}
/* THE BOARDS KEEP THE HELD BLOCK; THE PILES DO NOT. There are three splits
   while a block is in the air and the boards take the third: `--pread` and
   `--prest` are the two piles, which do not add to a whole book because what
   is in your hand is in neither of them, and `--pcase` is the plain
   interpolated split. Lifting paper does not move the case, so a board must
   not step when a pile does — it stays put and simply shows beyond its own
   thinned pile, which is what the back board of a real book does when most of
   it is in your hand. Sizing a board off a pile's share jumped its outer edge
   54px at the press: the right board going forward, the left one going back.
   The invariant below holds either way, since `--pcase` is never on the far
   side of a pile's share from the gutter: a board is never narrower than the
   pile beside it.

   THE BOARD IS ALWAYS OUTSIDE THE PAPER, whatever the split. One box sized to
   the whole book does not achieve that: the left pile is `--tnow * --pread`
   wide and grows past half the thickness as you read, so past about 58% of a
   book it walked out of its own cover — measured at 45px over by the last
   page. Each board is sized to ITS OWN side's share of the block, plus the
   square, which is the overhang that makes a case a case. */
.stage[data-mode=spread] .case.L{
  width:calc(var(--sw) + var(--tnow) * var(--pcase) + var(--sq));
  margin-left:calc(var(--shift) - (var(--sw) + var(--tnow) * var(--pcase) + var(--sq)));
  border-radius:calc(var(--pc) * 1.7) 0 0 calc(var(--pc) * 1.7)}
.stage[data-mode=spread] .case.R{
  width:calc(var(--sw) + var(--tnow) * (1 - var(--pcase)) + var(--sq));
  margin-left:var(--shift);
  border-radius:0 calc(var(--pc) * 1.7) calc(var(--pc) * 1.7) 0}
/* Single mode shows one leaf, so one board wide enough for it and its block. */
.stage[data-mode=single] .case.L{display:none}
.stage[data-mode=single] .case.R{
  width:calc(var(--sw) + var(--tnow) + var(--sq) * 2);
  margin-left:calc((var(--sw) + var(--tnow) + var(--sq) * 2) / -2);
  border-radius:calc(var(--pc) * 1.7)}

/* ---- the block of leaves either side ---- */
.stack{position:absolute;top:50%;height:var(--sh);
  margin-top:calc(var(--sh) / -2);pointer-events:none;z-index:1;
  overflow:hidden;filter:drop-shadow(0 2px 4px rgba(20,12,8,.34))}
.stack canvas{display:block;width:100%;height:100%}
.stack.L{border-radius:var(--pc) 0 0 var(--pc)}
.stack.R{border-radius:0 var(--pc) var(--pc) 0}

/* ---- the leaf ---- */
.slot{position:absolute;top:50%;left:50%;width:var(--sw);height:var(--sh);
  margin-top:calc(var(--sh) / -2);z-index:2}
.stage[data-mode=spread] .slot.L{margin-left:calc(var(--shift) - var(--sw))}
.stage[data-mode=spread] .slot.R{margin-left:var(--shift)}
.stage[data-mode=single] .slot.R{margin-left:calc(var(--sw) / -2)}
.stage[data-mode=single] .slot.L{display:none}

.page{position:absolute;inset:0;background:var(--paper);overflow:hidden;
  box-shadow:0 1px 2px rgba(35,32,26,.12),0 10px 26px rgba(35,32,26,.13)}
/* The leaf beneath, showing past this one at the fore-edge and its corners. */
.stage[data-mode=spread] .slot.L .page{border-radius:var(--pc) 0 0 var(--pc);
  box-shadow:calc(var(--nx) * -1) 0 0 0 var(--paper2),0 1px 2px rgba(35,32,26,.12),0 10px 26px rgba(35,32,26,.13)}
.stage[data-mode=spread] .slot.R .page,
.stage[data-mode=single] .slot.R .page{border-radius:0 var(--pc) var(--pc) 0;
  box-shadow:var(--nx) 0 0 0 var(--paper2),0 1px 2px rgba(35,32,26,.12),0 10px 26px rgba(35,32,26,.13)}

/* The gutter: two leaves meeting flat read as one wide sheet. */
.stage[data-mode=spread] .slot.L .page::after,
.stage[data-mode=spread] .slot.R .page::after{content:'';position:absolute;
  top:0;bottom:0;width:26px;pointer-events:none;z-index:3}
.stage[data-mode=spread] .slot.L .page::after{right:0;
  background:linear-gradient(to right,transparent,rgba(35,32,26,.13))}
.stage[data-mode=spread] .slot.R .page::after{left:0;
  background:linear-gradient(to left,transparent,rgba(35,32,26,.13))}

/* The type frame, in logical units scaled by --s. */
.sheet{position:absolute;left:0;top:0;width:var(--pw);height:var(--ph);
  transform:scale(var(--s));transform-origin:0 0}
.frame{position:absolute;left:var(--pm);top:var(--pm);
  width:calc(var(--pw) - var(--pm) * 2);height:calc(var(--ph) - var(--pm) * 2);
  font:var(--ptext)/var(--prule) ui-serif,Georgia,"Times New Roman",serif;
  color:var(--ink);white-space:pre-wrap;word-break:break-word;
  text-align:left;hyphens:none}
/* Size, leading, indent and inset are written INLINE from the same style table
   the paginator measured with — see dress(). Only what the table does not
   carry belongs here. */
.blk.head{letter-spacing:.02em;color:var(--ink2);font-variant:small-caps}
.blk.quote{color:var(--ink2);font-style:italic}
.blk.verse{font-style:italic}
.blk.pre{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap}
.folio{position:absolute;bottom:calc(var(--pm) * .40);font-size:calc(var(--ptext) * .72);
  color:var(--ink3);font-variant-numeric:tabular-nums}
.slot.L .folio{left:calc(var(--pm) * .55)}
.slot.R .folio{right:calc(var(--pm) * .55)}

/* ---- the fore-edge: the book's own edge, lying under it ---- */
.foreedge{flex:none;height:30px;position:relative;cursor:ew-resize;
  width:var(--railw,70%);align-self:center;touch-action:none}
.foreedge canvas{position:absolute;inset:0;width:100%;height:100%;
  border-radius:3px;box-shadow:0 1px 3px rgba(10,6,3,.45)}
.hud{position:absolute;bottom:calc(100% + 8px);transform:translateX(-50%);
  background:var(--ink);color:var(--paper);border-radius:3px;padding:3px 8px;
  font:11px ui-sans-serif,system-ui,sans-serif;white-space:nowrap;
  opacity:0;transition:opacity .12s;pointer-events:none;z-index:9}
.hud.on{opacity:1}

/* WRAP INTO ROWS, never into columns. Without `flex-wrap` seven items in a
   430px-wide phone cannot shrink sideways, so each one wraps its own text
   instead: "Open an EPUB" became three stacked lines and the facts a 90px
   column, which is TALLER than two honest rows and pushed the build stamp off
   the right edge of the screen — the one thing on this bar you have to be able
   to read to know what you are testing. */
.bar{flex:none;display:flex;flex-wrap:wrap;gap:6px 8px;align-items:center;
  justify-content:center;
  padding:4px 10px;font:11px ui-sans-serif,system-ui,sans-serif;color:var(--ink3);z-index:1}
.bar > *{white-space:nowrap}
.bar button{font:inherit;color:var(--ink2);background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.12);border-radius:3px;padding:4px 9px;cursor:pointer}
.bar button:hover{color:var(--ink)}
.bar b{color:var(--ink2);font-weight:600;font-variant-numeric:tabular-nums}
/* Quiet enough to ignore while reading, legible enough to answer "am I testing
   the right release?" without opening developer tools. */
.buildstamp{opacity:.42;font-variant-numeric:tabular-nums;white-space:nowrap}
/* The one thing in this bar that is a sentence rather than a control, so it is
   the one thing allowed to wrap — `.bar > *` is nowrap, which on a 390px phone
   would otherwise push a hundred characters into a single unbreakable row and
   take the whole book with it. */
#tip{white-space:normal;max-width:min(42ch,94vw);text-align:center;
  color:var(--ink2);opacity:.9}
.shelfbar .buildstamp{font-size:11px}
.busy{position:fixed;inset:0;display:grid;place-items:center;z-index:50;
  background:var(--desk);color:var(--ink3);font:13px ui-sans-serif,system-ui,sans-serif}

/* ---- the turning leaf -------------------------------------------------------
 * flip.js drives these nodes directly: it writes transform and opacity on
 * `.leafwrap`, toggles `.past-half` on it, sets opacity on `.shade` and
 * `.cast`, and puts `.flipping` plus `data-dir` on the stage. The rules here
 * are what those writes act on, ported from the journal's leaf.css and cut
 * down to a book that is never written on. */
.leafwrap{position:absolute;top:50%;left:50%;width:var(--sw);height:var(--sh);
  margin-top:calc(var(--sh) / -2);
  transform-style:preserve-3d;will-change:transform;pointer-events:none;
  opacity:0;visibility:hidden;z-index:6;
  /* The pivot belongs in CSS, not only in the inline styles flip.js writes.
     `applySingle` and `applySpread` set `transform-origin` every frame, but
     `_fanApply` -- the riffle -- does NOT: it writes only `transform`. So a
     riffle performed before any single-page turn pivots the top leaf about its
     CENTRE, and the leaf appears as a sliver standing in the middle of the
     opposite page. Caught by riffling as the very first interaction after a
     load, which is the only order that reaches it. */
  transform-origin:left center}
.stage[data-mode=spread][data-dir=back] .leafwrap{transform-origin:right center}
.stage.flipping .leafwrap{opacity:1;visibility:visible}
/* A spread's forward turn pivots on the gutter from the RIGHT page; its back
   turn pivots on the same gutter but starts from the LEFT one. A single-page
   turn does not move: both directions pivot on the same edge, forward lifting
   the leaf off it and back bringing the leaf down onto it. */
.stage[data-mode=spread] .leafwrap{margin-left:var(--shift)}
.stage[data-mode=spread][data-dir=back] .leafwrap{margin-left:calc(var(--shift) - var(--sw))}
.stage[data-mode=single] .leafwrap{margin-left:calc(var(--sw) / -2)}
.leafwrap .face{position:absolute;inset:0;backface-visibility:hidden}
.leafwrap .face.back{transform:rotateY(180deg)}
/* A single-page turn never rotates past 90 degrees, so the reverse of the leaf
   is never legitimately seen. Not drawing it is the honest fix. */
.stage[data-mode=single] .leafwrap .face.back{display:none}
.leafwrap .face .page{border-radius:0 var(--pc) var(--pc) 0}
.stage[data-mode=spread][data-dir=back] .leafwrap .face .page{
  border-radius:var(--pc) 0 0 var(--pc)}

.shade{position:absolute;inset:0;opacity:0;pointer-events:none;z-index:4;
  border-radius:0 var(--pc) var(--pc) 0;
  background:linear-gradient(to right,rgba(35,32,26,.55),rgba(35,32,26,.06) 32%,transparent 62%)}
.stage[data-mode=spread][data-dir=back] .shade{border-radius:var(--pc) 0 0 var(--pc);
  background:linear-gradient(to left,rgba(35,32,26,.55),rgba(35,32,26,.06) 32%,transparent 62%)}

.cast{position:absolute;top:50%;left:50%;width:var(--sw);height:var(--sh);
  margin-top:calc(var(--sh) / -2);margin-left:var(--shift);
  opacity:0;pointer-events:none;z-index:3;
  transform-origin:left center;border-radius:var(--pc);
  background:linear-gradient(to right,rgba(35,32,26,.45),rgba(35,32,26,.10) 40%,transparent 70%)}
.stage[data-mode=spread][data-dir=back] .cast{transform-origin:right center;
  margin-left:calc(var(--shift) - var(--sw));
  background:linear-gradient(to left,rgba(35,32,26,.45),rgba(35,32,26,.10) 40%,transparent 70%)}
.stage[data-mode=single] .cast{margin-left:calc(var(--sw) / -2)}

/* The pastedown and the endpaper: before the first leaf and after the last
   there is still paper. Bare board there is the one thing a real book never
   shows, and page one is a recto, so the opening spread has an empty left. */
.endpaper{background:var(--paper2);
  box-shadow:inset 0 0 40px rgba(35,32,26,.07),0 1px 2px rgba(35,32,26,.10)}

.bar .open{font:inherit;color:var(--ink2);background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.12);border-radius:3px;padding:4px 9px;cursor:pointer}
.bar .open:hover{color:var(--ink)}

/* ---- the riffling block -----------------------------------------------------
 * Going twenty leaves at once is not twenty turns; it is ONE turn of a wedge.
 * What makes it read as a stack rather than one thick sheet is the splay, which
 * flip.js writes onto these elements per frame. */
.fan{position:absolute;top:50%;left:50%;width:var(--sw);height:var(--sh);
  margin-top:calc(var(--sh) / -2);margin-left:0;
  transform-style:preserve-3d;pointer-events:none;opacity:0;visibility:hidden;z-index:7}
.stage.fanning .fan{opacity:1;visibility:visible}
.stage[data-mode=spread][data-dir=back] .fan{margin-left:calc(var(--sw) * -1)}
.stage[data-mode=single] .fan{margin-left:calc(var(--sw) / -2)}
.fan i{position:absolute;inset:0;border-radius:0 var(--pc) var(--pc) 0;
  background:var(--paper);transform-origin:left center;
  box-shadow:0 1px 2px rgba(35,32,26,.20),0 8px 22px rgba(35,32,26,.18);
  background-image:linear-gradient(to right,rgba(35,32,26,.16),rgba(35,32,26,0) 16%)}
.stage[data-mode=spread][data-dir=back] .fan i{transform-origin:right center;
  border-radius:var(--pc) 0 0 var(--pc);
  background-image:linear-gradient(to left,rgba(35,32,26,.16),rgba(35,32,26,0) 16%)}
/* THE PIVOT, which the fanback was missing entirely. flip.js rotates it with
   `pose(c.deep)` — a bare rotateY — and with no transform-origin it turned
   about its own CENTRE while every other leaf turned about the spine. A sheet
   rotating 180 degrees about its middle reads as a full spin in place, which
   is what "the last page does a 360" was.
   `transform-style:preserve-3d` belongs here too: without a 3D context on the
   fanback, its two faces cannot be backface-culled, so the mirrored reverse
   paints through the front. Same two misses as the leafwrap had. */
.fan .fanback{position:absolute;inset:0;border-radius:0 var(--pc) var(--pc) 0;
  transform-origin:left center;transform-style:preserve-3d;
  background:var(--paper);box-shadow:0 1px 2px rgba(35,32,26,.20)}
.stage[data-mode=spread][data-dir=back] .fan .fanback{
  border-radius:var(--pc) 0 0 var(--pc);transform-origin:right center}
/* Past edge-on you are looking at the block from underneath, so the leaves
   nearest you are the deep ones: the whole block paints above the leaf that
   led it in. */
.stage.fanning .fan.past-half{z-index:9}
/* Flat evenly-lit paper is what makes a fan look like a diagram. Each leaf
   darkens ITSELF, which also survives the 180-degree point where a leaf shows
   its back — flip.js publishes `--fanshade` per frame. The underside carries
   the page you are arriving at, so it takes the shading at half strength and
   stays readable as it comes down. */
.fan i::after,.fan .fanback::after{content:'';position:absolute;inset:0;
  border-radius:inherit;background:#231f19;
  opacity:var(--fanshade,0);pointer-events:none;z-index:2}
.fan .fanback::after{opacity:calc(var(--fanshade,0) * .45)}
.stage.fanning .leafwrap{opacity:1;visibility:visible;z-index:8}

/* ---- the shelf --------------------------------------------------------------
 * Spine-on, standing on a board. A spine's WIDTH is the book's thickness on
 * the same millimetre model the open book uses — so a long novel is visibly a
 * long novel before you open it, and the Large Print edition of one is visibly
 * fatter than its Regular. That is the whole reason the shelf exists rather
 * than a list of titles. */
.shelf{position:fixed;inset:0;z-index:60;background:var(--desk);
  display:flex;flex-direction:column;overflow:hidden}
/* `hidden` sets display:none from a UA rule, which ANY author display rule
   beats — so `.shelf{display:flex}` left a hidden, full-screen, transparent
   overlay sitting on top of the book and swallowing every click. The app was
   dead on arrival and looked fine. */
.shelf[hidden]{display:none}
.shelf::before{content:'';position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(94deg,rgba(0,0,0,.055) 0 2px,transparent 2px 7px)}
.shelfbar{flex:none;display:flex;gap:10px;align-items:center;padding:14px 18px;
  font:12px ui-sans-serif,system-ui,sans-serif;color:var(--ink3);z-index:1}
.shelfbar b{color:var(--ink2);letter-spacing:.14em;text-transform:uppercase;font-size:11px}
.shelfbar .note{flex:1;font-style:italic;opacity:.8}
.shelfbar button{font:inherit;color:var(--ink2);background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.12);border-radius:3px;padding:5px 10px;cursor:pointer}
.shelfbar button:hover{color:var(--ink)}

.shelf{justify-content:center}
.books{flex:0 1 auto;display:flex;align-items:flex-end;justify-content:center;
  gap:2px;padding:0 24px;overflow-x:auto;overflow-y:hidden;z-index:1}
.plank{flex:none;height:14px;width:min(900px,92vw);margin:0 auto;border-radius:2px;z-index:1;
  background:linear-gradient(180deg,#7a5536,#3a2616 58%,#241608);
  box-shadow:0 8px 22px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,255,255,.10)}

/* Bookbinding colours, not a hue wheel. A random hue at full spread puts a
   lilac and a lime on a shelf next to each other, which no binder ever did —
   cloth and leather live in a narrow, dark, desaturated band. */
.spine{flex:none;position:relative;cursor:pointer;border:none;padding:0;
  border-radius:2px 2px 0 0;
  background:linear-gradient(100deg,
    hsl(var(--h) var(--sat) calc(var(--lum) + 5%)),
    hsl(var(--h) var(--sat) var(--lum)) 58%,
    hsl(var(--h) var(--sat) calc(var(--lum) - 4%)));
  box-shadow:inset -2px 0 5px rgba(0,0,0,.45),inset 2px 0 3px rgba(255,255,255,.08),
             inset 0 3px 6px rgba(0,0,0,.30),
             0 4px 14px rgba(0,0,0,.45);
  transition:transform .14s}
/* The bands a case-bound spine is tooled with, top and bottom. */
.spine::before,.spine::after{content:'';position:absolute;left:0;right:0;height:1px;
  background:rgba(236,220,186,.26)}
.spine::before{top:9%} .spine::after{bottom:9%}
.spine:hover,.spine:focus-visible{transform:translateY(-10px);outline:none}
.spine .t{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  writing-mode:vertical-rl;text-orientation:mixed;
  font:11px/1 ui-serif,Georgia,serif;color:#e8dcc6;opacity:.92;
  padding:12px 0;overflow:hidden;white-space:nowrap;text-shadow:0 1px 2px rgba(0,0,0,.6)}
/* Too thin to set type on is a real case: a short story is 4mm. The title
   still has to be reachable, so it moves to the tooltip and the spine keeps
   its honest width rather than being padded to fit the words. */
.spine.thin .t{display:none}
.spine .mark{position:absolute;left:0;right:0;height:2px;background:var(--accent,#b4452f);
  box-shadow:0 0 4px rgba(0,0,0,.5)}
.shelf .empty{margin:auto;color:var(--ink3);font:13px ui-sans-serif,system-ui,sans-serif;
  text-align:center;line-height:1.7;z-index:1}

/* The underside of a turning block. Its BACK is what matters: coming out of
   the block that is the last leaf down, and the page you end up reading. Its
   FRONT is the reverse of a leaf inside the block — plain paper — and must NOT
   be a copy of the leaf that leads, or every block turned from the cover
   carries a second cover at its bottom. */
.fan .fanback .face{position:absolute;inset:0;backface-visibility:hidden}
.fan .fanback .face.back{transform:rotateY(180deg)}
.stage[data-mode=single] .fan .fanback .face.back{display:none}
.fan .fanback .face .page{border-radius:0 var(--pc) var(--pc) 0}
.stage[data-mode=spread][data-dir=back] .fan .fanback .face .page{
  border-radius:var(--pc) 0 0 var(--pc)}

/* ---- the cover --------------------------------------------------------------
 * A board, not a leaf: it is the outermost thing there is, so it takes the
 * case's rounding rather than the paper's, and nothing peeks past it. */
.page.cover{background:
    linear-gradient(104deg,hsl(var(--h) var(--sat) calc(var(--lum) + 6%)),
                    hsl(var(--h) var(--sat) var(--lum)) 60%,
                    hsl(var(--h) var(--sat) calc(var(--lum) - 5%)));
  border-radius:calc(var(--pc) * 1.7) !important;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06),0 10px 30px rgba(10,6,3,.5);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.9em;padding:14% 12%;text-align:center}
.page.cover.hasart{background-size:cover;background-position:center}
.page.cover .ct{font:600 calc(var(--ptext) * 1.5)/1.25 ui-serif,Georgia,serif;
  color:#f0e6d2;letter-spacing:.02em;text-shadow:0 1px 3px rgba(0,0,0,.55)}
.page.cover .ca{font:calc(var(--ptext) * .95)/1.3 ui-serif,Georgia,serif;
  color:#e3d5ba;opacity:.85;font-style:italic;text-shadow:0 1px 2px rgba(0,0,0,.5)}
/* The boards are tooled with a rule inside their edge, as a case-bound book is. */
.page.cover:not(.hasart)::after{content:'';position:absolute;inset:7%;
  border:1px solid rgba(240,230,205,.22);border-radius:calc(var(--pc) * .9);
  pointer-events:none}

/* ---- a shut book ------------------------------------------------------------
 * Shown ALONE and centred: there is one board to look at and it belongs in the
 * middle of the screen, not off to one side of a gutter that is not open yet.
 *
 * These live at the END of the file on purpose. They have exactly the same
 * specificity as the `[data-mode=spread]` rules above — (0,3,1) either way —
 * so the only thing deciding between them is source order. Declared earlier,
 * they lost, and the shut book sat 200px off centre with its board somewhere
 * else again. */
/* What is left of `data-closed` once `--shift` does the recentring: hiding the
   half of the book a shut one does not have, for the WHOLE of the turn.
   It was briefly released early, so the left half unfurled from the gutter as
   the cover rose. That was wrong, and the journal's leaf.css says why in a
   comment I had already quoted: "clearing that early put a blank cream leaf on
   the left before the cover had swung anywhere near it." Which is exactly what
   the reader saw — "a white rectangle that looks like a shadow only with the
   wrong color unfolds on the left of the cover as it opens."
   It is wrong physically too. The left board of an open book IS the front
   cover, the thing currently in the air; anything drawn there before it lands
   is a second copy of it. Nothing is owed: the leaf ends the turn lying on
   exactly the left slot's box — measured, 320..720 against 320..720 — so the
   handover is invisible without drawing anything underneath. */
.stage[data-closed] .slot.L,.stage[data-closed] .case.L{display:none}
