/* ---------- DARKON story page: two-page flip-book ---------- */
/* Real leaf-turn model: every .leaf is a single physical page anchored at
   the spine (left:50%, transform-origin:left center). Unflipped leaves sit
   flat on the right (rotateY 0deg); flipped ones have swung -180deg onto
   the left. z-index is purely index-based (unflipped: N-i, so the very
   next page to turn is on top of the right-hand stack; flipped: i+1, so
   the most recently turned page is on top of the left-hand pile) - turning
   a page is just incrementing/decrementing `flipped` and re-rendering,
   the CSS transition does the animation. Each leaf carries a front face
   (shown flat/unflipped) and a back face pre-rotated 180deg so it reads
   correctly once the leaf itself is at -180deg, the same content mirrored
   into place - this page doesn't have distinct recto/verso art, so front
   and back show the same content. */

:root{
  --bg-navy:#050a25;
  --gold:#eeb909;
  --font-display:'Cinzel', serif;
}

*{ box-sizing:border-box; }

html{ color-scheme:dark; }

body{
  margin:0;
  min-height:100vh;
  background:
    radial-gradient(ellipse at 20% 15%, rgba(109,76,255,0.12), transparent 55%),
    radial-gradient(ellipse at 85% 80%, rgba(238,185,9,0.08), transparent 50%),
    linear-gradient(180deg, #000 0%, #000 10%, #150c07 45%, #2a1454 85%, #3a1a6e 100%);
  color:#fff;
  font-family:'DM Sans', sans-serif;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  padding:24px 16px;
  overflow-x:hidden;
}

/* Shared positioning for the close/read-aloud/volume trio - one fixed,
   flex-aligned group instead of three independently-positioned elements,
   so they always share a common center regardless of how many there are
   or which way they're laid out. Landscape (including desktop): a column,
   vertically centered on the screen - the book gets matching left
   clearance below (see "orientation: landscape" rule) so it never sits
   under this column. Portrait: a row instead (see the portrait media
   query), anchored near the top since centering 3 small controls in the
   middle of a tall phone screen would read as disconnected from the book. */
.side-controls{
  position:fixed;
  left:20px;
  top:50%;
  transform:translateY(-50%);
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:10px;
  z-index:100;
}

/* Elegant back-to-Darkon control, always reachable while reading. */
.back-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:40px;
  height:40px;
  border-radius:50%;
  background:rgba(10,8,20,0.7);
  border:1px solid rgba(238,185,9,0.35);
  color:#fff;
  text-decoration:none;
  backdrop-filter:blur(6px);
  transition:background .15s ease, border-color .15s ease, transform .15s ease;
  /* backdrop-filter on a position:fixed-ancestor element forces the
     browser to recomposite the blur on every scroll frame, which some
     mobile browsers (iOS Safari especially) can't keep up with - the
     element visibly lags/jitters instead of staying put. Promoting it to
     its own GPU layer up front (translateZ(0) + will-change) fixes that. */
  transform:translateZ(0);
  will-change:transform;
  -webkit-backface-visibility:hidden;
}
.back-btn:hover{
  background:rgba(238,185,9,0.12);
  border-color:var(--gold);
  transform:translateZ(0) scale(1.08);
}
.back-btn-icon{ font-size:22px; line-height:1; font-weight:400; }

.read-btn{
  font-size:17px;
  cursor:pointer;
}
.read-btn .back-btn-icon{ font-size:17px; }
.read-btn.is-playing{ border-color:var(--gold); background:rgba(238,185,9,.12); }
.read-btn.is-playing .back-btn-icon{ animation:read-btn-pulse 1.4s ease-in-out infinite; }
@keyframes read-btn-pulse{ 0%,100%{ opacity:1; } 50%{ opacity:.55; } }

/* Background-music volume control - its own small bordered "card" (music
   note icon + slider) so it reads as a distinct control within the
   side-controls group rather than an extension of the button above it.
   Slider built from plain divs + pointer events rather than a rotated
   <input type=range> - a rotated native range input's drag/touch gesture
   still follows its own pre-rotation horizontal axis in several mobile
   browsers, so it visually looks vertical but doesn't drag like one. This
   also gives a much taller, more precise track (more "travel" = finer
   adjustment) than a native slider's fixed thumb size ever could. */
.volume-control{
  width:40px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
  padding:10px 0 12px;
  border-radius:16px;
  background:rgba(10,8,20,0.55);
  border:1px solid rgba(238,185,9,0.25);
  backdrop-filter:blur(6px);
}
.volume-control-icon{
  font-size:15px;
  line-height:1;
  opacity:0.85;
}
.volume-slider-wrap{
  width:40px;
  height:170px;
  display:flex;
  align-items:center;
  justify-content:center;
  touch-action:none;
  cursor:pointer;
}
.volume-slider-track{
  position:relative;
  width:6px;
  height:100%;
  border-radius:4px;
  background:rgba(238,185,9,0.15);
  border:1px solid rgba(238,185,9,0.3);
}
.volume-slider-fill{
  position:absolute;
  left:0; right:0; bottom:0;
  height:0%; /* driven live by setFromRatio() in story-page.js, this is just the pre-JS default */
  border-radius:4px;
  background:linear-gradient(180deg, #f0d060, var(--gold));
}
.volume-slider-thumb{
  position:absolute;
  left:50%; bottom:0%; /* driven live by setFromRatio() in story-page.js */
  width:18px; height:18px;
  border-radius:50%;
  background:var(--gold);
  border:2px solid #0a0714;
  box-shadow:0 2px 6px rgba(0,0,0,.5);
  transform:translate(-50%, 50%);
}

/* In landscape, side-controls is a column vertically centered on the
   whole screen (see .side-controls above) - reserve room for it on the
   left so the centered book/nav/progress column never sits under it.
   Harmless on wide desktop viewports too (already had far more margin
   than this to spare there). */
@media (orientation: landscape){
  body{ padding-left:120px; }
}

.story-stage{
  display:flex;
  align-items:center;
  justify-content:center;
  width:100%;
  max-width:820px;
}

/* Page-turn buttons live in their own bar below the book, rather than
   beside it - on landscape phones the sides of the book sit right where
   the volume-control card and back/read buttons are anchored, so a
   side-mounted prev/next button gets covered by them. */
.story-nav-bar{
  display:flex;
  justify-content:center;
  align-items:center;
  gap:24px;
  margin-top:14px;
}

.spread-nav{
  flex:0 0 auto;
  width:52px;
  height:52px;
  border-radius:50%;
  border:1px solid rgba(238,185,9,0.35);
  background:rgba(238,185,9,0.08);
  color:var(--gold);
  font-size:19px;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
  transition:background .12s ease, transform .12s ease, opacity .12s ease;
}
.spread-nav:hover:not(:disabled){
  background:rgba(238,185,9,0.2);
  transform:scale(1.06);
}
.spread-nav:disabled{
  opacity:.25;
  cursor:not-allowed;
}

.book-spread{
  position:relative;
  width:100%;
  max-width:820px;
  aspect-ratio:16/9.2;
  max-height:78vh;
  perspective:2400px;
  border-radius:10px;
  padding:16px;
  overflow:hidden;
  background:
    linear-gradient(135deg, #3a2416, #1c110a 55%, #150c07);
  box-shadow:
    0 30px 70px -15px rgba(0,0,0,0.75),
    inset 0 0 0 1px rgba(238,185,9,0.3),
    inset 0 0 40px rgba(0,0,0,0.55);
}

/* Sits above EVERY leaf, including one mid-turn (which briefly gets
   z-index:9999 while animating - see animateLeaf() in story-page.js), so
   the gutter shadow reads as a fixed physical feature of the book itself
   and never blinks out while a page sweeps past underneath it. */
.spine-shadow{
  position:absolute;
  left:50%;
  top:16px;
  bottom:16px;
  width:14px;
  margin-left:-7px;
  background:linear-gradient(90deg,
    rgba(0,0,0,0) 0%,
    rgba(0,0,0,0.28) 45%,
    rgba(0,0,0,0.28) 55%,
    rgba(0,0,0,0) 100%);
  z-index:10000;
  pointer-events:none;
}

.page-slot{
  position:absolute;
  top:16px;
  bottom:16px;
  width:calc(50% - 16px);
  background:linear-gradient(135deg, #f6ecd6, #ece0c1 60%, #e6d8b8);
  box-shadow:
    inset 0 0 70px 6px rgba(120,75,25,0.4),
    inset 0 0 22px 4px rgba(90,55,15,0.25);
  overflow:hidden;
  padding:clamp(18px, 3vw, 34px) clamp(20px, 3.4vw, 38px);
  display:flex;
  flex-direction:column;
  justify-content:center;
  z-index:0;
}
.page-slot-left{ left:16px; border-radius:8px 2px 2px 8px; }
.page-slot-right{ right:16px; border-radius:2px 8px 8px 2px; }

.page-slot-cover, .page-slot-closing{
  align-items:center;
  text-align:center;
  cursor:default;
}

.leaf{
  position:absolute;
  top:16px;
  bottom:16px;
  left:50%;
  width:calc(50% - 16px);
  transform-style:preserve-3d;
  transform-origin:left center;
  cursor:pointer;
  /* No `transition` here on purpose - the visible turn is driven entirely
     by the .is-turning-forward/backward @keyframes animations below, and
     story-page.js sets the plain resting transform (no transition) once
     that animation ends, so the two never fight or double-animate. */
}

/* Antique paper, styled after a photographed old book (warm, smooth,
   edges browned by age and light exposure) rather than a visible grain
   texture. The edge vignette is done with an INSET box-shadow rather than
   stacked radial-gradient background layers on purpose: .leaf-face--back
   carries its own rotateY(180deg) (needed so its content still reads
   correctly once the whole .leaf is flipped - see below), and a rotated,
   backface-hidden element with several stacked gradient backgrounds hits
   a real Chromium compositing bug that painted a hard, wrong-looking dark
   band through the middle of the page. box-shadow doesn't go through that
   gradient-layer compositing path, so it's not affected. Shared by every
   leaf, the cover/closing cards and the measuring probe. */
.leaf-face,
.page-slot{
  background:linear-gradient(135deg, #f9f1dc, #f2e4bf 55%, #e9d5a0);
}

/* Age stains: one soft blotch per page, cycled through 4 different corner
   positions (see STAIN_VARIANTS in story-page.js) so consecutive pages
   don't all show an identical mark in an identical spot. A single
   gradient layer on its own pseudo-element, not stacked onto the face's
   own background, for the same compositing-safety reason as above. */
.leaf-face::before,
.page-slot::before{
  content:'';
  position:absolute;
  inset:0;
  pointer-events:none;
  background:radial-gradient(circle at 15% 20%, rgba(100,62,18,0.48), transparent 38%);
}
.stain-b::before{ background:radial-gradient(circle at 85% 78%, rgba(100,62,18,0.48), transparent 40%); }
.stain-c::before{ background:radial-gradient(circle at 78% 18%, rgba(90,54,14,0.44), transparent 34%); }
.stain-d::before{ background:radial-gradient(circle at 18% 85%, rgba(90,54,14,0.44), transparent 36%); }

.leaf-face{
  position:absolute;
  inset:0;
  backface-visibility:hidden;
  overflow:hidden;
  /* Bottom padding is deliberately larger than the top/sides - a real,
     fixed gap under the last line, on the box the pagination probe also
     measures against (so it's accounted for automatically, not just a
     cosmetic shift), rather than relying only on the fit-check's safety
     margin to leave room. */
  padding:clamp(18px, 3vw, 34px) clamp(20px, 3.4vw, 38px) clamp(58px, 7.5vw, 84px);
  display:flex;
  flex-direction:column;
  justify-content:flex-start;
  /* No plain "2px 0 14px" side shadow here (unlike earlier) - up to 48+
     leaves can be stacked at the exact same position (all unflipped pages
     waiting on the right, or all flipped ones piled on the left), and a
     non-inset shadow on every one of them bleeds past the shared edge and
     ACCUMULATES across the whole stack. Near the cover/closing, where the
     stack is deeply lopsided (nearly everything piled on one side), that
     added up to a thick, dark band at the spine - while an interior
     spread (~half the leaves on each side) barely showed it, which is
     exactly the "gap looks fine in the middle, gets worse near the ends"
     bug this fixes. The inset vignette below doesn't have this problem -
     it never paints outside its own box, so it can't stack with a
     neighbor's copy. */
  box-shadow:
    inset 0 0 70px 6px rgba(120,75,25,0.4),
    inset 0 0 22px 4px rgba(90,55,15,0.25);
}

/* No animated gradient-based overlay here on purpose (there used to be a
   fold-shadow `::after` with a linear-gradient, animated via opacity).
   That's the same risky combination as the filter bug above: an animated
   gradient effect on .leaf-face--back, which is backface-hidden AND
   carries its own rotateY(180deg) inside a preserve-3d ancestor that's
   itself mid-rotation - and it produced its own visible glitch on the
   left (back-face) page specifically during the turn, never on the
   right. Removed rather than chased further; the box-shadow-based lift
   below is doing the "realism" work now and hasn't shown this problem. */

/* The turn itself is a plain, undistorted rotateY - real book pages are
   fairly stiff, and skewing/squashing actual text (rather than an image)
   just reads as broken rendering, not paper.
   IMPORTANT: don't animate `filter` on this element (or any ancestor of
   the backface-hidden faces) - combining an animated `filter` with
   `backface-visibility:hidden` on a preserve-3d child is a real Chromium
   rendering bug that makes the front face render mirrored mid-rotation
   instead of being hidden past 90deg. The lift/shadow cue below is done
   with `box-shadow` on the faces themselves instead, which doesn't have
   that interaction. */
@keyframes leaf-turn-forward{
  0%{   transform:rotateY(0deg); }
  100%{ transform:rotateY(-180deg); }
}
@keyframes leaf-turn-backward{
  0%{   transform:rotateY(-180deg); }
  100%{ transform:rotateY(0deg); }
}

/* No extra shadow animation during the turn on purpose now - the static
   inset vignette every page already has (see .leaf-face above) is the
   only depth cue. An animated "lift" box-shadow seemed like a nice touch,
   but any box-shadow that isn't purely inset paints outside the leaf's
   own box, and with dozens of leaves stacked at the same position (see
   the note on .leaf-face's box-shadow) that kind of effect is exactly
   the class of bug that caused the spine to look wrong near the
   cover/closing earlier - not worth reintroducing for a transient
   animation flourish. */
.leaf.is-turning-forward{
  animation:leaf-turn-forward .85s cubic-bezier(.45,.05,.55,.95) forwards;
}
.leaf.is-turning-backward{
  animation:leaf-turn-backward .85s cubic-bezier(.45,.05,.55,.95) forwards;
}

.book-page-title-cont{
  font-size:0.6em;
  text-transform:none;
  letter-spacing:normal;
  font-weight:600;
  opacity:.6;
}

/* The measuring probe: an invisible leaf, styled identically to a real one
   by reusing the exact same classes, so its clientHeight/scrollHeight
   always match what a real leaf would show at the current breakpoint -
   this is what story-page.js uses to decide how many physical pages a
   block of prose needs to split into, so no page ever requires scrolling. */
#leafProbe{
  visibility:hidden;
  pointer-events:none;
}
.leaf-face--front{ border-radius:2px 8px 8px 2px; }
.leaf-face--back{
  transform:rotateY(180deg);
  border-radius:8px 2px 2px 8px;
}

.book-page-num{
  font-family:var(--font-display);
  font-size:11px;
  letter-spacing:1.5px;
  color:#a3894f;
  margin-bottom:10px;
}
.book-page-title{
  font-family:var(--font-display);
  font-weight:800;
  font-size:clamp(18px, 2.6vw, 25px);
  letter-spacing:1px;
  color:#3a2610;
  text-transform:uppercase;
  margin:0 0 14px;
  border-bottom:1px solid rgba(58,38,16,0.2);
  padding-bottom:10px;
}
.book-page-body p{
  font-family:Georgia, 'Times New Roman', serif;
  font-size:clamp(13.5px, 1.6vw, 15.5px);
  line-height:1.7;
  color:#2b2013;
  margin:0 0 12px;
}
.book-page-body p:last-child{ margin-bottom:0; }

/* Antique painting dropped into a page's own text flow as just another
   block the pagination probe measures like any paragraph - so it only
   ever appears where it actually fits, and pushes to a continuation page
   like any other content if it doesn't. Sized narrower than the old SVG
   version since the source painting is portrait-oriented (taller than
   wide), so constraining by width alone keeps its height in check too. */
.book-page-illustration{
  margin:14px auto 10px;
  /* Scaled by viewport HEIGHT, not width - the binding constraint is
     vertical space (a short landscape phone has very little of it, a
     portrait phone or desktop has plenty), and 82px is the verified
     floor that still fits alongside a wrapped continuation title on the
     shortest landscape viewport tested (667x375). */
  max-width:clamp(82px, 18vh, 180px);
  width:100%;
}
.book-page-illustration img{
  width:100%; height:auto; display:block;
  border:3px solid #6b4a26;
  border-radius:1px;
  box-shadow:0 3px 10px rgba(0,0,0,.3);
  cursor:zoom-in;
  transition:filter .15s ease;
}
.book-page-illustration img:hover{ filter:brightness(1.08); }
.book-page-illustration svg{ width:100%; height:auto; display:block; }

/* Click-to-zoom overlay for in-page illustrations - escapes the leaf's
   own overflow:hidden by rendering fixed over the whole viewport, rather
   than scaling the thumbnail in place (which the leaf would just clip). */
#imageLightbox{
  position:fixed; inset:0; z-index:20000;
  display:flex; align-items:center; justify-content:center;
  padding:30px;
  background:rgba(8,5,14,.86);
  backdrop-filter:blur(3px);
  opacity:0; pointer-events:none;
  transition:opacity .32s ease;
  cursor:zoom-out;
}
#imageLightbox.is-open{ opacity:1; pointer-events:auto; }
#imageLightbox img{
  max-width:min(92vw, 560px);
  max-height:88vh;
  width:auto; height:auto;
  display:block;
  border:4px solid #6b4a26;
  border-radius:2px;
  box-shadow:0 14px 50px rgba(0,0,0,.6);
  cursor:zoom-out;
  transform:scale(.4);
  transition:transform .32s cubic-bezier(.34,1.2,.4,1);
}
#imageLightbox.is-open img{ transform:scale(1); }
.book-page-illustration figcaption{
  text-align:center;
  font-family:Georgia, 'Times New Roman', serif;
  font-style:italic;
  font-size:10.5px;
  color:#8a6a3a;
  margin-top:5px;
  letter-spacing:.02em;
}

.book-page-quote{
  font-style:italic;
  color:#5a3f14 !important;
  border-left:3px solid var(--gold);
  padding-left:12px;
}
.book-page-label{
  font-family:var(--font-display);
  font-size:11px;
  letter-spacing:2px;
  text-transform:uppercase;
  color:#a3894f !important;
  margin-bottom:4px !important;
}
.book-page-motto{
  font-family:var(--font-display);
  font-weight:800;
  font-size:clamp(15px, 1.8vw, 18px);
  letter-spacing:1.5px;
  color:#7a3d14 !important;
}

.cover-title, .closing-title{
  font-family:var(--font-display);
  font-weight:800;
  font-size:clamp(26px, 3.4vw, 38px);
  letter-spacing:3px;
  color:#3a2610;
  margin:0 0 12px;
}
.cover-subtitle, .closing-subtitle{
  font-family:Georgia, serif;
  font-style:italic;
  font-size:clamp(13px, 1.6vw, 15px);
  color:#5a3f14;
}
.cover-crest{
  font-size:clamp(30px, 4vw, 46px);
  margin-bottom:14px;
}

.story-progress{
  margin-top:16px;
  font-size:12.5px;
  color:#c7c9d6;
  font-variant-numeric:tabular-nums;
  letter-spacing:.03em;
}

/* Below this width a true two-page spread reads too cramped (a real open
   book doesn't fit a phone screen either) - switch to one full-width page
   at a time instead. Same `flipped` counter and leaf elements drive both
   layouts; only their size/position changes here, so story-page.js needs
   no mobile-specific logic. The decorative cover/closing side cards are
   dropped at this width (the 10 content leaves are what matters) rather
   than trying to squeeze them in too. */
@media (max-width: 760px){
  .story-stage{ gap:8px; }
  .spread-nav{ width:40px; height:40px; font-size:15px; }
  .side-controls{ left:12px; }
  .back-btn{ width:34px; height:34px; }
  .back-btn-icon{ font-size:19px; }
  .read-btn .back-btn-icon{ font-size:15px; }
  .volume-control{ width:34px; }
  .volume-slider-wrap{ width:34px; height:130px; }
}

/* Narrow portrait phone: collapses to one full-width page at a time (see
   isSpreadMode() in story-page.js) - a two-page spread doesn't fit legibly
   at this width. Also trims the bottom margins so book + nav bar +
   progress still fit within the viewport with no scrolling. */
@media (max-width: 700px) and (orientation: portrait){
  /* A portrait phone has plenty of vertical room but limited width - let
     the book grow tall to use that space (rather than staying stuck at
     the wide 16/9.2 aspect ratio, which made it tiny and left most of the
     screen empty). */
  .book-spread{ aspect-ratio:auto; height:74vh; max-height:74vh; padding:10px; }

  .page-slot-left, .page-slot-right, .spine-shadow{ display:none; }

  .leaf{
    top:10px;
    bottom:10px;
    left:10px;
    width:calc(100% - 20px);
    transform-origin:left center;
  }

  /* Page-turn buttons above the book instead of below it - body is
     already a flex column (see body{} above), so this is a pure reorder,
     no DOM change needed. */
  .story-nav-bar{ order:-1; margin-top:0; margin-bottom:10px; gap:16px; }
  .story-stage{ order:0; }
  .story-progress{ order:1; margin-top:6px; }

  /* Close/read-aloud/volume go in a row instead of a column here - a
     column pinned near the top makes sense in landscape (see "orientation:
     landscape" below) but centering 3 small controls down the middle of a
     tall phone screen would read as disconnected from the book, so this
     stays anchored near the top instead, just laid out horizontally. */
  .side-controls{ flex-direction:row; top:20px; left:12px; transform:none; gap:10px; }

  /* Horizontal slider instead of vertical - less vertical room to spare
     here now that the nav buttons also live up top, and a horizontal bar
     reads fine within the button stack's own width. The icon gets the
     same 34px width as the back/read circles, so its center lines up with
     theirs exactly rather than drifting off with the icon's own glyph
     padding. */
  .volume-control{ flex-direction:row; width:auto; padding:0 8px 0 0; gap:0; }
  .volume-control-icon{ width:34px; height:34px; display:flex; align-items:center; justify-content:center; flex:none; }
  .volume-slider-wrap{ width:70px; height:34px; }
  .volume-slider-track{ width:100%; height:6px; }
  .volume-slider-fill{ left:0; right:auto; top:0; bottom:0; height:100%; width:0%; }
  .volume-slider-thumb{ left:0%; bottom:50%; transform:translate(-50%, 50%); }

  .leaf-face{
    border-radius:8px !important;
    padding:14px 14px 46px !important;
  }
  .leaf-face .book-page-body p{
    font-size:12.5px;
    line-height:1.5;
    margin:0 0 8px;
  }
  .leaf-face .book-page-title{
    font-size:16px;
    margin-bottom:8px;
    padding-bottom:6px;
  }
}

/* Landscape on a short phone screen: the spread is wide but there isn't
   much vertical room, so relax max-height and tighten the outer padding
   instead of collapsing the layout. */
@media (max-height: 500px) and (orientation: landscape){
  body{ padding:6px 16px 6px 80px; }
  .book-spread{ max-height:78vh; padding:10px; }
  .page-slot{ top:10px; bottom:10px; }
  .leaf{ top:10px; bottom:10px; }
  .spine-shadow{ top:10px; bottom:10px; }
  .side-controls{ left:8px; gap:6px; }
  .back-btn{ width:30px; height:30px; }
  .back-btn-icon{ font-size:17px; }
  .read-btn .back-btn-icon{ font-size:14px; }
  .volume-control{ width:30px; }
  .volume-slider-wrap{ width:30px; height:100px; }
  .spread-nav{ width:36px; height:36px; font-size:14px; }
  .story-nav-bar{ margin-top:6px; gap:14px; }
  .story-progress{ margin-top:4px; }

  /* Shifts the whole content block (title included) higher on short
     landscape screens by trimming the top padding - frees up more room
     at the bottom for the last line, on top of whatever the dynamic
     pagination already reserves there. Bottom padding is also trimmed
     here specifically: the default clamp() (~58-84px) is tuned for
     portrait/desktop's much taller pages and eats a disproportionate
     share of the ~339px total height available on a short landscape
     phone - a smaller fixed value still leaves comfortable breathing
     room under the last line while reclaiming real usable space. */
  .leaf-face,
  .page-slot{
    padding-top:10px;
    padding-bottom:28px;
  }
  .book-page-title{
    margin-bottom:8px;
    padding-bottom:6px;
  }
}
