/* Shared book reader styles. Originally extracted verbatim from the pupăza
   prototype (scratch/story_books/nica-pupaza/pupaza-din-tei.html) -- TT-SB-001.
   tt-004 (general_ux): the palette below now aliases the site's brand tokens
   (web/static/css/globals.css) instead of a disconnected one-off
   brown/gold palette -- Option A from the ticket. Every color in this file
   should trace back to one of these six aliases (or a plain black/white
   rgba); don't add new scattered hex literals here. */

:root{
  --leather: var(--primary-color);          /* cover base -- was #5a2e1c */
  --leather-dark: var(--primary-dark);      /* cover shadow/gradient end -- was #3c1c10 */
  --gold: var(--accent-orange-light);       /* decorative accents ONLY (ornament glyph, frame) -- not reading text, see below. Was #d4af6a */
  --gold-dim: var(--accent-orange);         /* decorative accents ONLY -- was #a9803f */
  --cover-text: var(--primary-light);       /* actual reading text on the cover (title/author/etc) -- orange-on-green read as low-contrast/harsh, this is the fix */
  --paper: var(--shop-bg-cream, #faf8f5);   /* page surface -- was #f4ecd8 */
  --paper-shadow: #e3d9c4;                  /* warm paper-edge shading; no brand token for this, named+scoped here rather than scattered inline -- was #d8c9a3 */
  --ink: var(--text-color);                 /* body text -- was #3a2b1c */
  /* Surrounding stage/void, deliberately darker than --leather and NOT a
     brand token -- the book needs to visibly pop off its background, and
     --primary-color vs --primary-dark alone are too close in luminance for
     that (both are dark greens). Same "not brand colours, stay local"
     precedent as story_dice.css's table-felt scaffolding tokens. */
  --room-void: #04140d;
}

html,body{
  height:100%;
  margin:0;
  background: var(--room-void);
  font-family: 'Palatino Linotype','Book Antiqua', Georgia, serif;
  overflow:hidden;
}

.stage{
  height:100%;
  box-sizing:border-box;
  padding: 60px 0 90px;
  display:flex;
  align-items:center;
  justify-content:center;
  perspective: 2600px;
  position:relative;
}

/* The book is two portrait pages side by side; the spine is the vertical center line. */
.book{
  position:relative;
  /* fill the viewport while keeping a two-page 2.07:1 spread ratio.
     tt-004: widened from 94vw -- smaller left/right margins around the book,
     leaving just enough room for the flip-zones (clamp(44px,5.5%,64px)
     below) plus a touch of breathing room, not a wide empty gutter. */
  /* svh, not vh: on mobile browsers 100vh is the LARGEST viewport (URL bar
     hidden), and this page never scrolls so the bar never hides -- vh-derived
     sizing overflowed the real visible area on-device (tt-001-b-mobile).
     The vh line stays as fallback for pre-svh browsers. */
  --book-w: min(97vw, calc((100vh - 170px) * 2.0714));
  --book-w: min(97vw, calc((100svh - 170px) * 2.0714));
  width: var(--book-w);
  height: calc(var(--book-w) / 2.0714);
  transform-style: preserve-3d;
  transition: transform 1.1s cubic-bezier(.45,.05,.35,1);
}

/* When closed, only the right half (the cover) exists visually — shift left so it appears centered. */
.book.closed{
  transform: translateX(-25%);
}

/* During an edition rebuild the book re-flips to the current page instantly. */
.book.no-anim,
.book.no-anim .page{
  transition:none !important;
}

/* Static back board: always sits under everything on the right half. */
.back-board{
  position:absolute;
  top:0; left:50%;
  width:50%; height:100%;
  z-index:0;
  border-radius: 2px 8px 8px 2px;
}

/* Each leaf is ONE portrait page wide, hinged on the spine (its left edge = book center). */
.page{
  position:absolute;
  top:0; left:50%;
  width:50%;
  height:100%;
  transform-origin: left center;
  transform-style: preserve-3d;
  transition: transform 1.1s cubic-bezier(.45,.05,.35,1);
  box-shadow: 2px 4px 14px rgba(0,0,0,.35);
  border-radius: 2px 8px 8px 2px;
}

.page.flipped{
  transform: rotateY(-180deg);
  box-shadow: -2px 4px 14px rgba(0,0,0,.25);
}

.face{
  position:absolute;
  top:0; left:0;
  width:100%;
  height:100%;
  backface-visibility:hidden;
  -webkit-backface-visibility:hidden;
  overflow:hidden;
  border-radius: 2px 8px 8px 2px;
}

.face.back{
  transform: rotateY(180deg);
  border-radius: 8px 2px 2px 8px;
}

/* Soft gutter shading along the spine, on top of the pages. */
.spine-gutter{
  position:absolute;
  top:0; bottom:0; left:50%;
  width:70px;
  margin-left:-35px;
  background: linear-gradient(to right, rgba(0,0,0,0), rgba(0,0,0,.18) 45%, rgba(0,0,0,.28) 50%, rgba(0,0,0,.18) 55%, rgba(0,0,0,0));
  pointer-events:none;
  z-index: 1500;
  opacity:0;
  transition: opacity .8s ease;
}
.book.open .spine-gutter{ opacity:1; }

/* ---------- Leather ---------- */
.leather{
  /* Flat --leather (not a gradient down to --leather-dark): the room
     behind the book is now --room-void, much darker than either green, so
     the cover no longer needs its own internal darkening to read as
     "forward" of its background -- a gradient toward --leather-dark risked
     matching --room-void at one corner and blending in there. Texture
     overlays (noise + soft highlight) still give it depth. */
  background:
    radial-gradient(ellipse at 30% 20%, rgba(255,255,255,.06), transparent 60%),
    repeating-linear-gradient(115deg, rgba(0,0,0,.05) 0px, rgba(0,0,0,0) 2px, rgba(0,0,0,.05) 4px),
    var(--leather);
  color: var(--cover-text);
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  text-align:center;
  height:100%;
  box-sizing:border-box;
  padding: 30px;
  position:relative;
  box-shadow: 0 0 0 1px rgba(0,0,0,.5), 0 30px 70px rgba(0,0,0,.65);
}

.leather::before{
  content:"";
  position:absolute;
  inset: 16px;
  border: 3px double var(--gold-dim);
  border-radius: 4px;
  box-shadow:
    inset 0 0 0 1px rgba(255,188,72,.25),
    inset 0 2px 6px rgba(0,0,0,.5);
  pointer-events:none;
}

.leather::after{
  content:"";
  position:absolute;
  inset:0;
  background: radial-gradient(ellipse at 50% 0%, rgba(0,0,0,0) 40%, rgba(0,0,0,.45) 100%);
  pointer-events:none;
}

.cover-ornament{
  font-size: clamp(22px, 2vw, 36px);
  letter-spacing: 4px;
  margin-bottom: 16px;
  color: var(--gold);      /* decorative glyph only, not reading text -- accent color is fine here */
  text-shadow: 0 1px 0 rgba(255,222,170,.25), 0 -1px 1px rgba(0,0,0,.6);
  opacity:.9;
}

.cover-kicker{
  font-size: clamp(12px, 1.1vw, 20px);
  letter-spacing: 3px;
  text-transform: uppercase;
  margin-bottom: 10px;
  color: var(--cover-text);
  opacity: .82;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}

.cover-title{
  font-size: clamp(36px, 3.4vw, 64px);
  line-height:1.15;
  font-weight:700;
  letter-spacing: 1px;
  margin: 6px 0 18px;
  text-shadow: 0 2px 6px rgba(0,0,0,.5);
}

.cover-sub{
  font-style: italic;
  font-size: clamp(14px, 1.3vw, 22px);
  color: var(--cover-text);
  opacity: .82;
  margin-bottom: 24px;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}

.cover-author{
  font-size: clamp(16px, 1.5vw, 28px);
  letter-spacing: 2px;
  text-shadow: 0 1px 3px rgba(0,0,0,.5);
}

.cover-levels{
  font-size: clamp(11px, 1vw, 15px);
  letter-spacing: 1px;
  color: var(--cover-text);
  opacity: .7;
  margin-top: 6px;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}

.cover-hint{
  position:absolute;
  bottom: 26px;
  left:0; right:0;
  font-size: 11px;
  letter-spacing: 1px;
  color: var(--cover-text);
  opacity: .55;
  text-transform: uppercase;
}

/* ---------- Paper pages ---------- */
.paper{
  background: linear-gradient(120deg, var(--paper) 0%, var(--paper-shadow) 100%);
  height:100%;
  box-sizing:border-box;
  position:relative;
}

.paper::after{
  content:"";
  position:absolute;
  inset:0;
  box-shadow: inset 0 0 30px rgba(57,50,47,.18);
  pointer-events:none;
}

/* Brand watermark on the endpapers -- tt-004. Moved off the cover (where a
   dark-on-dark mark was invisible) onto the two blank pages right after it
   (inside front cover + blank first page, reader.js buildBook()) -- real
   books often mark the endpapers this way, and there's plenty of blank
   cream space here for it to actually read as an intentional mark rather
   than a barely-visible corner stamp. Same low-opacity/pointer-events:none
   technique as Story Dice's .table-stamp/.help-stamp. */
.endpaper-watermark{
  position:absolute;
  top:50%;
  left:50%;
  transform: translate(-50%,-50%);
  width: 30%;
  max-width: 220px;
  opacity: .16;
  pointer-events:none;
  user-select:none;
  -webkit-user-select:none;
}

/* Text page (left side of a spread). tt-004: left/right padding widened to
   clear the flip-zone's own max width (clamp(...,64px) below) at every
   viewport size -- previously narrower than the zone, so its hover tint/
   arrow could visually sit on top of the text block instead of just its
   margin. */
.text-page{
  display:flex;
  align-items:center;
  padding: 44px 70px 52px;
  box-sizing:border-box;
  height:100%;
}

/* Set by reader.js fitText() when even the floor font size can't fit the
   page's text: pin the block to the page top (align-items:center would clip
   the first AND last lines) and let the page scroll so the tail stays
   reachable instead of cut off. The flip zones only cover the page's outer
   edge strips, so the scrollable middle keeps receiving touches. */
.text-page.overflow-top{
  align-items:flex-start;
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
}

.text-inner{
  width:100%;
  color: var(--ink);
  font-size: 19px;
}

.text-inner p{
  font-size: inherit;
  line-height: 1.55;
  margin: 0 0 0.7em;
  text-align: justify;
}
.text-inner p:last-child{ margin-bottom:0; }

.page-number{
  position:absolute;
  bottom: 16px;
  left:0; right:0;
  text-align:center;
  font-size: 12px;
  color: var(--gold-dim);
  font-style: italic;
}

/* Image page (right side of a spread) — framed plate, no cropping.
   tt-004: left/right padding widened to clear the flip-zone's max width,
   same reasoning as .text-page above -- the framed image itself no longer
   sits under the zone's hover tint/arrow. */
.art-page{
  display:flex;
  align-items:center;
  justify-content:center;
  height:100%;
  box-sizing:border-box;
  padding: 34px 70px;
}

.art-page img{
  max-width:100%;
  max-height:100%;
  display:block;
  border: 5px solid var(--paper);
  outline: 1px solid var(--paper-shadow);
  box-shadow: 0 4px 14px rgba(57,50,47,.35);
}

.end-page{
  display:flex;
  align-items:center;
  justify-content:center;
  height:100%;
  text-align:center;
}

.end-ornament{
  color: var(--gold-dim);
  font-size: 24px;
  letter-spacing: 4px;
}

.end-word{
  font-style: italic;
  font-size: 18px;
  color: var(--ink);
  margin-top: 12px;
}

/* ---------- Nav ---------- */
.nav{
  position:absolute;
  bottom: 24px;
  left:50%;
  transform: translateX(-50%);
  display:flex;
  gap: 18px;
  align-items:center;
  z-index: 3000;
}

.nav button{
  background: linear-gradient(135deg, var(--leather), var(--leather-dark));
  color: var(--gold);
  border: 1px solid var(--gold-dim);
  border-radius: 30px;
  padding: 10px 22px;
  font-family: inherit;
  font-size: 14px;
  letter-spacing: 1px;
  cursor:pointer;
  box-shadow: 0 4px 12px rgba(0,0,0,.4);
  transition: transform .15s ease, box-shadow .15s ease;
}

.nav button:hover:not(:disabled){
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0,0,0,.5);
}

.nav button:disabled{
  opacity:.35;
  cursor:default;
}

.nav .counter{
  color: var(--gold-dim);
  font-size:13px;
  letter-spacing:1px;
  min-width: 100px;
  text-align:center;
  cursor:pointer;
  padding-bottom: 2px;
  border-bottom: 1px dashed rgba(254,126,31,.35);
  transition: color .2s ease, border-color .2s ease;
  user-select:none;
  -webkit-user-select:none;
}

.nav .counter:hover{
  color: var(--gold);
  border-bottom-color: rgba(255,188,72,.7);
}

/* Inline page-jump input, swapped in place of the counter. */
.nav .page-input{
  display:none;
  width: 100px;
  box-sizing:border-box;
  text-align:center;
  background: rgba(0,0,0,.4);
  color: var(--gold);
  border: 1px solid var(--gold-dim);
  border-radius: 20px;
  padding: 7px 10px;
  font-family: inherit;
  font-size: 14px;
  letter-spacing: 1px;
  outline:none;
}
.nav .page-input:focus{
  border-color: var(--gold);
  box-shadow: 0 0 8px rgba(255,188,72,.35);
}
.nav .page-input::placeholder{
  color: rgba(254,126,31,.45);
}
.nav .page-input::-webkit-outer-spin-button,
.nav .page-input::-webkit-inner-spin-button{
  -webkit-appearance:none;
  margin:0;
}
.nav .page-input{
  -moz-appearance:textfield;
  appearance:textfield;
}

/* ---------- Edition switcher ---------- */
.lang-select{
  position:absolute;
  top: 16px;
  right: 24px;
  /* The edition descriptor is content-driven and can outgrow the viewport
     (it did on a 412px phone -- tt-001-b-mobile); cap it and ellipsize.
     text-overflow works on <select> in Chromium/WebKit; Firefox clips,
     which is an acceptable fallback. */
  max-width: min(56vw, calc(100vw - 104px));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 3000;
  background: linear-gradient(135deg, var(--leather), var(--leather-dark));
  color: var(--gold);
  border: 1px solid var(--gold-dim);
  border-radius: 20px;
  padding: 6px 12px;
  font-family: inherit;
  font-size: 13px;
  letter-spacing: 1px;
  cursor:pointer;
  outline:none;
  box-shadow: 0 3px 10px rgba(0,0,0,.4);
}
.lang-select:focus{
  border-color: var(--gold);
}
/* The OPEN dropdown list is native OS/browser chrome -- most browsers
   ignore the <select>'s own background there but still inherit its text
   color, so the gold text above renders on a plain white list with no way
   to darken that background from CSS. Explicit dark-on-white on the
   <option>s themselves (which browsers do respect) fixes the contrast
   instead of fighting the native popup. */
.lang-select option{
  color: var(--ink);
  background: var(--bg-white, #fff);
}

/* ---------- Flip zones (outer page edges) ---------- */
/* Page turning is confined to these strips, like grabbing a real page edge. */
.flip-zone{
  position:absolute;
  top:0; bottom:0;
  width: clamp(44px, 5.5%, 64px);
  z-index: 2500;
  cursor:pointer;
  opacity:0;
  pointer-events:none;
  transition: opacity .6s ease;
  overflow:hidden;
  user-select:none;
  -webkit-user-select:none;
  -webkit-tap-highlight-color: transparent;
}
.book.open .flip-zone.active{
  opacity:1;
  pointer-events:auto;
}
.flip-zone.left{ left:0; }
.flip-zone.right{ right:0; }

/* Faint edge band marking the touchable strip; deepens on hover. */
.flip-zone::before{
  content:"";
  position:absolute;
  inset:0;
  transition: background-color .25s ease, box-shadow .25s ease;
}
.flip-zone.left::before{
  border-radius: 2px 0 0 2px;
  border-left: 1px solid rgba(57,50,47,.35);
  background: linear-gradient(to right, rgba(57,50,47,.10), rgba(57,50,47,0));
}
.flip-zone.right::before{
  border-radius: 0 8px 8px 0;
  border-right: 1px solid rgba(57,50,47,.35);
  background: linear-gradient(to left, rgba(57,50,47,.10), rgba(57,50,47,0));
}
.flip-zone.left:hover::before{
  background: linear-gradient(to right, rgba(57,50,47,.20), rgba(57,50,47,0));
}
.flip-zone.right:hover::before{
  background: linear-gradient(to left, rgba(57,50,47,.20), rgba(57,50,47,0));
}

/* Chevron hint, vertically centered in the strip. */
.zone-arrow{
  position:absolute;
  top:50%;
  left:50%;
  transform: translate(-50%,-50%);
  font-size: 30px;
  line-height:1;
  color: rgba(57,50,47,.4);
  transition: color .25s ease, transform .25s ease;
  pointer-events:none;
}
.flip-zone:hover .zone-arrow{
  color: rgba(57,50,47,.85);
}
.flip-zone.left:hover .zone-arrow{ transform: translate(-58%,-50%); }
.flip-zone.right:hover .zone-arrow{ transform: translate(-42%,-50%); }

/* "Grab the page here" — quarter-circle curl at the TOP outer corner,
   where people actually grab a page to flip it. */
.corner-curl{
  position:absolute;
  top:0;
  width: 84px;
  height: 84px;
  border-radius:50%;
  background:
    radial-gradient(circle at 35% 35%, var(--paper) 0%, var(--paper) 55%, var(--paper-shadow) 100%);
  border: 1px solid rgba(57,50,47,.5);
  box-shadow: 0 2px 8px rgba(57,50,47,.3);
  transition: transform .25s ease, box-shadow .25s ease;
  pointer-events:none;
}
.flip-zone.left .corner-curl{
  left:0;
  transform: translate(-50%, -50%);
}
.flip-zone.right .corner-curl{
  right:0;
  transform: translate(50%, -50%);
}
.flip-zone.left:hover .corner-curl{
  transform: translate(-50%, -50%) scale(1.12);
  box-shadow: 0 4px 12px rgba(57,50,47,.4);
}
.flip-zone.right:hover .corner-curl{
  transform: translate(50%, -50%) scale(1.12);
  box-shadow: 0 4px 12px rgba(57,50,47,.4);
}

/* ---------- Definitions ---------- */
/* Subtle dotted underline on defined words; text-decoration keeps the text
   fully selectable and copyable (copies without any extra characters). */
.defined{
  text-decoration: underline dotted rgba(57,50,47,.55);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  cursor: help;
}

.def-tooltip{
  position: fixed;
  z-index: 4000;
  max-width: 300px;
  background: var(--leather-dark);
  color: var(--gold);
  border: 1px solid var(--gold-dim);
  border-radius: 8px;
  padding: 10px 14px;
  font-family: inherit;
  font-size: 14px;
  line-height: 1.45;
  box-shadow: 0 6px 18px rgba(0,0,0,.5);
  pointer-events: none;
  opacity: 0;
  transition: opacity .18s ease;
}
.def-tooltip.visible{ opacity:1; }
.def-tooltip .def-term{
  display:block;
  color: var(--gold);
  font-weight:700;
  letter-spacing: .5px;
  margin-bottom: 4px;
}

/* Glossary pages at the back of the book */
/* tt-004: left/right padding widened, same flip-zone clearance reasoning
   as .text-page/.art-page above. */
.gloss-page{
  display:flex;
  flex-direction:column;
  height:100%;
  box-sizing:border-box;
  padding: 38px 70px 52px;
}

.gloss-title{
  text-align:center;
  color: var(--ink);
  font-size: 15px;
  letter-spacing: 3px;
  text-transform: uppercase;
}

.gloss-rule{
  text-align:center;
  color: var(--gold-dim);
  font-size: 12px;
  letter-spacing: 4px;
  margin: 4px 0 14px;
}

.gloss-list{
  flex:1;
  overflow:hidden;
  column-count: 2;
  column-gap: 32px;
  font-size: 13px;
  color: var(--ink);
}

.gloss-entry{
  break-inside: avoid;
  margin-bottom: .55em;
  line-height: 1.35;
}

.gloss-entry b{
  color: var(--ink);
}

.gloss-entry .gloss-def{
  font-style: italic;
  color: var(--leather);   /* was --gold-dim (orange) -- too bright/low-contrast on cream, per feedback */
}

.title-bar{
  position:absolute;
  top: 22px;
  left:50%;
  transform:translateX(-50%);
  color: var(--gold-dim);
  font-size:13px;
  letter-spacing:2px;
  text-transform:uppercase;
  opacity:.7;
  z-index: 3000;
  /* Keep the centered title from wrapping and running under the lang pill
     at mid widths (tt-001-b-mobile); below 1024px it's hidden entirely. */
  max-width: 40vw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── TT-001-B: shared site nav integration ─────────────────────────────
   Trigger top-left, mirroring .lang-select's top-right placement. The
   z-index overrides lift the drawer above ALL reader chrome -- pager/
   title-bar/lang-select (3000) and .def-tooltip (4000) -- because "when
   the drawer opens, everything under it is hidden except the X" is the
   component's approved contract (tt-001 plan doc). Reader-internal
   z-ordering (pages/spine/flip zones) is untouched. */
:root{
  --site-nav-z-scrim: 4100;
  --site-nav-z-panel: 4200;
  --site-nav-z-trigger: 4300;
}
.site-nav-header-left{
  position: absolute;
  top: 10px;
  left: 24px;
}

/* ── TT-001-B-mobile: narrow/short-viewport fixes ──────────────────────
   Everything above was tuned on desktop; this file previously had NO
   responsive rules at all. Two constraint families:

   1. Narrow header (width-driven): trigger + lang pill must share one
      top row on a phone; the centered title bar has no honest place to
      fit, so it's hidden -- the cover art and document.title carry it.

   2. Small PAGE BOXES (width- OR height-driven): --book-w is height-
      derived in landscape and width-derived in portrait, so a phone hits
      small pages in BOTH orientations while only portrait matches a
      max-width query -- hence the OR'd max-height arm ("mobile fixes"
      is really "small-page fixes", see tt-001-b-mobile-fixes.md). */

@media (max-width: 1024px){
  .title-bar{ display:none; }
}

@media (max-width: 560px){
  .site-nav-header-left{ left: 12px; }
  .lang-select{ top: 12px; right: 12px; max-width: calc(100vw - 104px); }
  /* Compact pager: the desktop row is ~480px wide and was clipping at
     both edges of a 412px screen. */
  .nav{ gap: 8px; }
  .nav button{ padding: 8px 12px; font-size: 12px; white-space: nowrap; }
  .nav .counter{ min-width: 60px; font-size: 11px; white-space: nowrap; }
}

@media (max-width: 768px), (max-height: 520px){
  /* Trim the stage chrome so the height-derived book gets more room on
     short viewports (the 170px offset mirrors the old 60+90 padding). */
  .stage{ padding: 46px 0 72px; }
  .book{
    --book-w: min(97vw, calc((100vh - 126px) * 2.0714));
    --book-w: min(97vw, calc((100svh - 126px) * 2.0714));
  }
  .nav{ bottom: 12px; }

  /* Page innards: the desktop 70px side padding existed to clear the
     flip-zone hint graphics, but on a ~200px-wide page it left a 60px
     text column. Hide the hover-only hints (touch devices anyway) and
     reclaim the space; zones stay tappable. */
  .flip-zone::before,
  .zone-arrow,
  .corner-curl{ display:none; }
  .text-page{ padding: 16px 24px 26px; }
  .art-page{ padding: 12px 22px; }
  .gloss-page{ padding: 14px 22px 26px; }
  .gloss-list{ column-count: 1; }
  .page-number{ bottom: 6px; font-size: 10px; }

  /* Cover typography: the desktop clamp() minimums (36px title etc.) are
     bigger than a phone-sized cover can hold -- they're what piled the
     hint/author/audience lines on top of each other. Scale with the book
     instead; caps keep tablets (768px arm, large --book-w) sane. */
  /* Extra bottom padding keeps the centered text column clear of the
     absolute-positioned tap hint. */
  .leather{ padding: 14px 14px 30px; }
  .leather::before{ inset: 8px; }
  .cover-ornament{ font-size: clamp(12px, calc(var(--book-w) * 0.05), 24px); letter-spacing: 2px; margin-bottom: 6px; }
  .cover-kicker{ font-size: clamp(9px, calc(var(--book-w) * 0.026), 16px); letter-spacing: 2px; margin-bottom: 4px; }
  .cover-title{ font-size: clamp(17px, calc(var(--book-w) * 0.065), 34px); margin: 4px 0 8px; }
  .cover-sub{ font-size: clamp(10px, calc(var(--book-w) * 0.03), 16px); margin-bottom: 10px; }
  .cover-author{ font-size: clamp(11px, calc(var(--book-w) * 0.034), 20px); letter-spacing: 1px; }
  .cover-levels{ font-size: clamp(9px, calc(var(--book-w) * 0.024), 13px); margin-top: 4px; }
  .cover-hint{ font-size: 9px; bottom: 12px; letter-spacing: .5px; }
}

/* Phone-portrait covers are ~200px wide -- even the scaled-down cover
   stack above overflows and piles onto the tap hint. Drop the purely
   decorative ornament row and tighten the title. (After the combined
   block above so these win the cascade.) */
@media (max-width: 560px){
  .cover-ornament{ display:none; }
  .cover-title{ font-size: clamp(16px, calc(var(--book-w) * 0.055), 26px); }
  .cover-sub{ margin-bottom: 6px; }
  /* The one-line hint is wider than a ~200px cover; give it side insets
     so it wraps inside the frame instead of crossing the border art. */
  .cover-hint{ font-size: 8px; left: 16px; right: 16px; }
}
