/* ==========================================================================
   TACO McSOOMBRERO AND THE GOLDEN SALSA
   Stylesheet. System fonts only, no downloads, no images -- every decoration
   is a CSS shape drawn in code.

   THE A4 RULE
   -----------
   Every sheet (cover, story page, THE END) is a real A4 page: 210mm x 297mm
   with 16mm side and top margins and an 18mm foot. On screen the whole sheet
   is scaled down to fit the window, keeping the exact A4 shape -- what you
   see is a small photograph of the paper, not a different layout.

   The trick is one custom property:

       --u   = ONE MILLIMETRE OF THE SHEET, at whatever size the sheet is
               currently drawn.

   So calc(var(--u) * 210) is always the full width of an A4 sheet, and
   calc(var(--u) * 6.7) is always 19pt type. Change nothing else and the whole
   page scales together. In print, --u is a real millimetre.

   Sections:  1 tokens  2 base  3 top bar  4 contents  5 the sheets
              6 story type  7 back-to-top / footer  7b print controls
              8 mobile  9 dark mode  10 PRINT  11 old-print-engine fallback
   ========================================================================== */

/* --- 1. tokens ---------------------------------------------------------- */
:root {
  --paper:      #fffaf0;
  --paper-edge: #e8d5b5;
  --bg:         #f6e3c5;
  --bg-2:       #f1d7b0;
  --ink:        #2c2018;
  --ink-soft:   #6b5643;
  --chili:      #c62828;
  --chili-dark: #8e1b1b;
  --guac:       #2e7d32;
  --sun:        #e8a317;
  --sky:        #1668a8;
  --radius:     4px;
  color-scheme: light dark;

  /* --- the A4 sheet ---------------------------------------------------- */
  --sheet-w:      210mm;   /* A4 width  */
  --sheet-h:      297mm;   /* A4 height */
  --sheet-top:    16mm;    /* book margins */
  --sheet-side:   16mm;
  --sheet-foot:   18mm;

  /* type sizes, in millimetres of the sheet (1pt = 0.352778mm) */
  --t-story:      6.7028;  /* 19pt   -- narration */
  /* Adhiyan asked for the dialogue to be bigger. It was the SAME size as the
     narration, but it reads smaller because the name column insets it, so a
     matching size was not enough -- it now genuinely outsizes the narration. */
  --t-dialogue:   7.4058;  /* 21pt   -- the spoken lines */
  --t-who:        3.5278;  /* 10pt   -- the speaker's name beside a line */
  --t-title:      3.5278;  /* 10pt   -- the "PAGE 7" header */
  --t-sfx:        9.1722;  /* 26pt   -- DONG!  THUMP.  SPLAT! */
  --t-sign:       4.5861;  /* 13pt   -- PAELLA FORTRESS */
  --t-cover:      12.7000; /* 36pt   -- the book title */
  --t-byline:     4.5861;  /* 13pt   */
  --t-end:        8.4667;  /* 24pt   */

  /* the play-script name column beside every line of dialogue, in sheet mm */
  --who-col: 24;
  --who-gap: 2;

  /* how much room the window leaves either side of the sheet */
  --gutter: 1.4rem;

  /* the width the sheet is actually drawn at, never more than real A4 */
  --sheet-fit: min(210mm, calc(100vw - var(--gutter) - var(--gutter)));

  /* ONE MILLIMETRE OF THE SHEET at the size it is currently drawn */
  --u: calc(var(--sheet-fit) / 210);

  /* --- THE SCREEN-HEIGHT SWITCH (round 8) ------------------------------
     ON PAPER a sheet is always 297mm tall. That never changes: the @page
     box in section 10 is A4, one story page per sheet, and verify.js still
     measures every page against 297mm of real paper before it will pass.

     ON A SCREEN nobody is holding paper. Adhiyan sent a photo of the site
     on his phone: a page that is only half full was drawing the whole 297mm
     anyway, so half of every sheet was empty and you had to scroll past the
     nothing to reach the next page. So on screen a sheet is now only as tall
     as the words on it (plus the same margins), and the stack of sheets
     reads like a book instead of a stack of mostly-blank paper.

     ONE LINE FLIPS IT BACK:
        --sheet-screen-h: auto;                 <- fits the words (now)
        --sheet-screen-h: calc(var(--u) * 297); <- true A4 rectangles
     It is a variable on purpose: a "show me real pages" toggle would just
     set this on <html> and nothing else in the stylesheet would move.
     Print ignores it completely (section 10 sets height: auto anyway).
     --------------------------------------------------------------------- */
  --sheet-screen-h: auto;

  /* a sheet never gets shorter than this, so a one-line page still looks
     like a page and the "Print page n" button keeps its foot margin */
  --sheet-screen-min: calc(var(--u) * 74);
}

/* --- 2. base ------------------------------------------------------------ */
* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5.5rem;   /* so anchors clear the sticky bar */
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

body {
  margin: 0;
  overflow-x: hidden;
  font-family: Georgia, "Iowan Old Style", "Palatino Linotype", "Times New Roman", serif;
  line-height: 1.4;
  color: var(--ink);
  background-color: var(--bg);
  background-image:
    /* faint tile pattern, pure CSS */
    repeating-linear-gradient( 45deg, rgba(198,40,40,.045) 0 12px, transparent 12px 24px),
    repeating-linear-gradient(-45deg, rgba(46,125,50,.045) 0 12px, transparent 12px 24px),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
  background-attachment: fixed;
}

.progress {
  position: fixed; inset: 0 0 auto 0;
  height: 5px; z-index: 60;
  background: rgba(0,0,0,.10);
}
.progress-bar {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--sun), var(--chili) 55%, var(--guac));
  transition: width .1s linear;
}

/* --- 3. top bar --------------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  background: var(--chili);
  color: #fff8ec;
  box-shadow: 0 2px 10px rgba(0,0,0,.22);
  font-size: 1rem;
}
.topbar-inner {
  max-width: 60rem;
  margin: 0 auto;
  padding: .45rem .7rem;
  display: flex; align-items: center; gap: .5rem;
  min-height: 3rem;
}
.brand {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: .02em;
  font-size: clamp(.95rem, 3.4vw, 1.2rem);
  color: #fff8ec;
  text-decoration: none;
  margin-right: auto;
  display: flex; align-items: center; gap: .45rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* little sombrero, drawn with two CSS shapes */
.brand-hat {
  position: relative;
  width: 1.5rem; height: .95rem;
  flex: none;
}
.brand-hat::before {          /* brim */
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 1.5rem; height: .48rem;
  background: var(--sun);
  border-radius: 50%;
  box-shadow: inset 0 -2px 0 rgba(0,0,0,.18);
}
.brand-hat::after {           /* crown */
  content: ""; position: absolute; left: .42rem; bottom: .26rem;
  width: .66rem; height: .55rem;
  background: var(--sun);
  border-radius: .34rem .34rem 0 0;
}

.btn {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .95rem;
  font-weight: 700;
  line-height: 1;
  color: var(--chili-dark);
  background: #fff3dc;
  border: 2px solid #40190f;
  border-radius: 999px;
  padding: .62rem 1rem;
  min-height: 44px;              /* comfortable tap target */
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 0 #40190f;
  list-style: none;
  white-space: nowrap;
}
.btn::-webkit-details-marker { display: none; }
.btn:hover  { background: #ffe9c2; }
.btn:active { transform: translateY(2px); box-shadow: 0 0 0 #40190f; }
.btn:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.btn-print { background: var(--sun); color: #3a2200; }
.btn-print:hover { background: #f5b53a; }

/* papel picado bunting, CSS triangles */
.bunting {
  height: 12px;
  background:
    linear-gradient(135deg, transparent 50%, var(--sun) 50%) 0 0 / 24px 12px repeat-x,
    linear-gradient(45deg, transparent 50%, var(--guac) 50%) 12px 0 / 24px 12px repeat-x;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.25));
}

/* --- 4. contents -------------------------------------------------------- */
.contents { position: relative; }
.contents-panel {
  position: absolute;
  top: calc(100% + .55rem);
  right: 0;
  width: min(92vw, 22rem);
  max-height: min(70vh, 30rem);
  overflow-y: auto;
  background: var(--paper);
  color: var(--ink);
  border: 3px solid #40190f;
  border-radius: 14px;
  box-shadow: 0 12px 26px rgba(0,0,0,.3);
  padding: .8rem;
  z-index: 55;
  font-size: 1rem;
}
.contents-head {
  margin: 0 0 .55rem;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--chili-dark);
}
.toc-list {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(3.4rem, 1fr));
  gap: .4rem;
}
.toc-list a {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .95rem; font-weight: 700;
  text-decoration: none;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--paper-edge);
  border-radius: 9px;
}
.toc-list a:hover { background: var(--sun); border-color: #40190f; }
.toc-list a:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
.toc-list .toc-end { grid-column: 1 / -1; }
.toc-list .toc-end a { font-size: .82rem; letter-spacing: .08em; background: #fff3dc; }

/* --- 5. the sheets ------------------------------------------------------
   A scrollable stack of A4 sheets. Each one is exactly 210 x 297 of --u.
   ------------------------------------------------------------------------ */
#book {
  width: calc(var(--u) * 210);
  margin: 0 auto;
  padding: 1.2rem 0 2.4rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 12);
}

.cover, .page, .the-end {
  /* ---- the sheet of paper ---- */
  width:  calc(var(--u) * 210);
  /* height comes from --sheet-screen-h (section 1). It is "auto" now, so a
     sheet is as tall as its words -- no dead space under a short page. The
     WIDTH is still exactly A4, so every line breaks in the same place it
     will break on paper, and --u still means one millimetre of a real
     sheet. Print flattens both anyway (section 10). */
  height: var(--sheet-screen-h);
  min-height: var(--sheet-screen-min);
  /* The foot margin is 18mm of sheet -- but the "Print page 7" button parked
     in it is a real 44px finger target, and on a phone 18mm of a shrunken
     sheet is only about 35px. Now that a page stops where its words stop,
     that button would sit on the last line. So on screen the foot is never
     allowed to be shorter than the button. Sides and top are untouched, so
     every line still breaks exactly where it breaks on paper, and print
     throws all of this padding away anyway (section 10). */
  padding: calc(var(--u) * 16) calc(var(--u) * 16) max(calc(var(--u) * 18), 3.4rem);
  background: var(--paper);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(64,25,15,.22);
  margin: 0;
  /* if the words ever outgrow the sheet they must SPILL, visibly, so it can
     be seen and fixed -- a sheet that silently swallows a line is a bug.
     verify.js measures every page against the same numbers used here. */
  overflow: visible;
  position: relative;
}

.cover {
  text-align: center;
  overflow: hidden;              /* only so the sun rays stay on the paper */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.cover::before {   /* sun rays behind the title */
  content: ""; position: absolute; inset: -20% -20% auto -20%; height: 140%;
  background: repeating-conic-gradient(from 0deg at 50% 34%,
    rgba(232,163,23,.16) 0deg 9deg, rgba(232,163,23,0) 9deg 18deg);
  pointer-events: none;
}
.book-title {
  position: relative;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: calc(var(--u) * var(--t-cover));
  line-height: 1.1;
  letter-spacing: -.01em;
  margin: 0 0 calc(var(--u) * 8);
  color: var(--chili);
  text-shadow: calc(var(--u) * .7) calc(var(--u) * .7) 0 var(--sun);
  text-wrap: balance;
}
.byline {
  position: relative;
  margin: 0;
  font-size: calc(var(--u) * var(--t-byline));
  color: var(--ink-soft);
  font-style: italic;
}
.cover-hat {          /* big sombrero, pure CSS */
  position: relative;
  width:  calc(var(--u) * 62);
  height: calc(var(--u) * 35);
  margin: 0 auto calc(var(--u) * 10);
  flex: none;
}
.cover-hat::before {  /* brim */
  content: ""; position: absolute; left: 0; bottom: 0;
  width: calc(var(--u) * 62); height: calc(var(--u) * 18);
  background: linear-gradient(180deg, var(--sun), #c8801a);
  border: calc(var(--u) * 1.2) solid #40190f;
  border-radius: 50%;
}
.cover-hat::after {   /* crown */
  content: ""; position: absolute; left: calc(var(--u) * 18); bottom: calc(var(--u) * 10);
  width: calc(var(--u) * 26); height: calc(var(--u) * 21);
  background: linear-gradient(180deg, #f2b642, var(--sun));
  border: calc(var(--u) * 1.2) solid #40190f;
  border-radius: calc(var(--u) * 12) calc(var(--u) * 12) calc(var(--u) * 3) calc(var(--u) * 3);
}

/* the running head on every story sheet: PAGE 7 */
.page-title {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: calc(var(--u) * var(--t-title));
  font-weight: 700;
  letter-spacing: .18em;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--chili-dark);
  margin: 0 0 calc(var(--u) * 6);
  padding-bottom: calc(var(--u) * 2);
  border-bottom: calc(var(--u) * .35) solid var(--paper-edge);
  display: flex; align-items: center; gap: calc(var(--u) * 2);
}
.page-title::before {   /* chilli-pepper dot, CSS only */
  content: ""; flex: none;
  width: calc(var(--u) * 2.2); height: calc(var(--u) * 2.2);
  background: var(--chili);
  border-radius: 60% 60% 60% 0;
  transform: rotate(-45deg);
}
.page-title::after {    /* rule that fills the row */
  content: ""; flex: 1 1 auto; height: calc(var(--u) * .7);
  background: repeating-linear-gradient(90deg,
    var(--sun) 0 calc(var(--u) * 2), transparent calc(var(--u) * 2) calc(var(--u) * 4));
  opacity: .8;
}

/* --- 6. story typography ------------------------------------------------ */
.line, .d, .sfx, .sign {
  font-size: calc(var(--u) * var(--t-story));
  line-height: 1.4;
  margin: 0 0 calc(var(--u) * 2.4);
  max-width: none;               /* the sheet margins ARE the measure */
}
.d {                       /* dialogue */
  font-size: calc(var(--u) * var(--t-dialogue));
  padding-left: calc(var(--u) * 3.5);
  border-left: calc(var(--u) * .9) solid rgba(198,40,40,.28);
  color: #37261c;
}

/* --- who is speaking -----------------------------------------------------
   Adhiyan's dialogue is bare quoted lines with no "said Taco" attached, so
   every quoted line is set like a play script: a small name in a column on
   the left, then his line, exactly as he wrote it. The NAME is the mechanism
   -- it is real text and it prints in black and white. The colour is only a
   bonus on screen. Nothing here is inside his sentence.
   ------------------------------------------------------------------------ */
.say {
  --speaker: var(--ink-soft);          /* every character overrides this */
  display: grid;
  grid-template-columns: calc(var(--u) * var(--who-col)) 1fr;
  column-gap: calc(var(--u) * var(--who-gap));
  align-items: baseline;
  break-inside: avoid;
  page-break-inside: avoid;
}
.who {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: calc(var(--u) * var(--t-who));
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: right;
  color: var(--speaker);
  margin: 0 0 calc(var(--u) * 2.4);
  max-width: none;
  overflow-wrap: break-word;
}
/* a name I was not certain about: it keeps its "?" and sits back a little */
.who.guess { font-weight: 600; opacity: .78; }

/* the little rule beside the line picks up the speaker's colour too */
.say > .d {
  border-left-color: var(--speaker);
  border-left-color: color-mix(in srgb, var(--speaker) 42%, transparent);
}

/* ---- the speaker colours ------------------------------------------------
   One colour per character, the same on every page of the book.
   To add a character: one "cast" line in speakers.txt + one rule here.
   ------------------------------------------------------------------------ */
.say-taco     { --speaker: #a8371a; }   /* Taco McSoombrero  -- chilli red   */
.say-gazpacho { --speaker: #14568c; }   /* Don Gazpacho      -- deep blue    */
.say-mayor    { --speaker: #6b3fa0; }   /* the Mayor         -- purple       */
.say-monster  { --speaker: #2c6e35; }   /* the Bean Monster  -- bean green   */
.say-nacho    { --speaker: #0f6b6b; }   /* Nacho  (Book 2)   -- cool teal    */
.say-paellon,
.say-raider   { --speaker: #8a6508; }   /* Captain Paellon and his pan       */
                                        /* raiders -- paella gold, the same  */
                                        /* way the Riders share one colour   */
.say-guard    { --speaker: #3f6470; }   /* the guard captain -- slate        */
.say-worker   { --speaker: #7c5230; }   /* the worker        -- brown        */
.say-rider,
.say-riders   { --speaker: #b21e63; }   /* Jalapeno Riders   -- hot pink     */
.say-tamale,
.say-tamales  { --speaker: #6f6413; }   /* the slow tamale, and the tamales  */
                                        /* stirring the volcano -- olive     */
.say-masked,
.say-voice    { --speaker: #4a3f6b; }   /* the shadowy ones  -- dark violet  */
.say-master,
.say-scoville { --speaker: #7d1240; }   /* Book 2's villain -- dark pepper   */
                                        /* wine. TWO ids, ONE colour: he is  */
                                        /* "Master" until he says his name   */
                                        /* and "Scoville" after it, so the   */
                                        /* label tells you, and the colour   */
                                        /* says it was him all along.        */
.say-town     { --speaker: #6b5643; }   /* townsfolk / crowd -- soft ink     */
.say-unknown  { --speaker: #8a7d70; }   /* nobody can tell   -- grey         */
.sfx {                     /* DONG!  THUMP.  SQUISH!  BOOM!  SPLAT! */
  font-family: "Trebuchet MS", "Segoe UI Black", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: calc(var(--u) * var(--t-sfx));
  line-height: 1.15;
  letter-spacing: .04em;
  color: var(--chili);
  text-shadow:
    calc(var(--u) * .7) calc(var(--u) * .7) 0 var(--sun),
    calc(var(--u) * 1.4) calc(var(--u) * 1.4) 0 rgba(64,25,15,.22);
  margin: calc(var(--u) * 4) 0 calc(var(--u) * 4.5);
  transform: rotate(-1.6deg);
  transform-origin: left center;
}
.sign {                    /* PAELLA FORTRESS -- the sign above the entrance */
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  letter-spacing: .22em;
  font-size: calc(var(--u) * var(--t-sign));
  line-height: 1.3;
  text-align: center;
  color: #3a2200;
  background: repeating-linear-gradient(90deg,
    rgba(232,163,23,.28) 0 calc(var(--u) * 3), rgba(232,163,23,.14) calc(var(--u) * 3) calc(var(--u) * 6));
  border: calc(var(--u) * .7) solid #40190f;
  border-radius: calc(var(--u) * 1.5);
  padding: calc(var(--u) * 2);
  margin: calc(var(--u) * 4) auto calc(var(--u) * 4.5);
  max-width: calc(var(--u) * 110);
}
/* first line of page 1 gets a drop cap */
#p1 .line:first-of-type::first-letter {
  float: left;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: 2.6em;
  line-height: .82;
  padding: .06em .1em 0 0;
  color: var(--chili);
}

.the-end {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.the-end-line {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: calc(var(--u) * var(--t-end));
  line-height: 1.2;
  letter-spacing: .1em;
  color: var(--chili);
  margin: 0;
  max-width: none;
}
.the-end::after {
  content: "";
  display: block;
  width: 60%;
  height: calc(var(--u) * 1.2);
  margin: calc(var(--u) * 8) auto 0;
  background: repeating-linear-gradient(90deg,
    var(--sun) 0 calc(var(--u) * 4), var(--guac) calc(var(--u) * 4) calc(var(--u) * 8));
}

/* --- 7. back to top + footer -------------------------------------------- */
.totop {
  position: fixed;
  right: .8rem; bottom: .8rem;
  z-index: 40;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--sky);
  color: #fff;
  border: 3px solid #10344f;
  text-decoration: none;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .78rem; font-weight: 700; line-height: 1;
  box-shadow: 0 3px 0 #10344f;
  transition: opacity .18s ease, transform .18s ease;
}
.totop span { font-size: .6rem; letter-spacing: .06em; }
.totop.hidden { opacity: 0; pointer-events: none; transform: translateY(8px); }

.site-foot {
  max-width: 46rem;
  margin: 0 auto;
  padding: 0 .8rem 4.5rem;
  text-align: center;
  color: var(--ink-soft);
  font-size: 1rem;
}
.site-foot p { margin: 0 0 .9rem; font-style: italic; }

/* --- 7b. printing one page, or a few ------------------------------------
   Adhiyan: "can we print only one page at a time are many at once".

   Every sheet carries its own small "Print page 7" button, parked in the
   18mm foot margin of the paper where no story text ever goes -- so it can
   never sit on top of a word, on any screen size. The footer has a "pages
   N to M" box. Both need JavaScript to do anything, so both stay hidden
   until book.js puts the "js" class on <html>: a button that cannot work is
   worse than no button. None of this ever prints (section 10 hides it).
   ------------------------------------------------------------------------ */
.page-tools { display: none; }
.print-range { display: none; }

html.js .page-tools {
  display: flex;
  justify-content: flex-end;
  position: absolute;
  right: calc(var(--u) * 16);
  bottom: calc(var(--u) * 3);
  margin: 0;
  z-index: 2;
}
.btn-page {
  min-height: 44px;              /* a real finger target, even though it is small */
  min-width: 44px;
  padding: 0 .55rem;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  /* ROUND 8: this used to be opacity .55, which on Adhiyan's phone was a grey
     smudge you could barely read. The button is now drawn at FULL opacity and
     kept quiet by its colour instead: real ink on a faint tint of the paper,
     with a visible edge. Quiet is a colour choice, not a transparency -- so it
     stays legible in dark mode, where .55 was the worst. */
  color: var(--ink);
  background: rgba(140, 105, 60, .10);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius);
  cursor: pointer;
  opacity: 1;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.btn-page:hover, .btn-page:focus-visible {
  background: #fff3dd;
  border-color: var(--chili);
  color: var(--chili-dark);
}
.btn-page:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }

html.js .print-range {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  margin: 0 0 1rem;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .9rem;
}
.print-range input {
  width: 4.5rem;
  min-height: 44px;
  padding: .3rem .4rem;
  font: inherit;
  text-align: center;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid #40190f;
  border-radius: var(--radius);
}
.print-range input:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
.range-msg {
  flex-basis: 100%;
  margin: .1rem 0 0;
  min-height: 1.3em;
  font-style: normal;
  font-size: .85rem;
}
.range-msg.bad { color: var(--chili-dark); font-weight: 700; }

/* --- 7c. READ ALOUD (round 10) ------------------------------------------
   Adhiyan: "include and speaking button that repeat the story in either
             tamil or english".

   A bar parked along the bottom of the SCREEN -- play, stop, and the Voices
   panel that lists what this particular phone can actually say. It never
   covers a word: the book and the footer are given extra room underneath
   while the bar is up, and the back-to-top button steps up out of its way.

   NOTHING HERE EXISTS WITHOUT speak.js. The bar and the per-sheet "Read page
   n" buttons are display:none until speak.js has proved the browser really
   has a speech engine and then puts "speak" on <html> -- exactly the rule the
   print controls follow with "js". A button that cannot work is worse than no
   button, so the one case where the bar DOES appear disabled is when speech
   is missing entirely: then it appears with the reason written next to it.

   None of it prints (section 10 hides the lot).
   ------------------------------------------------------------------------ */
.speak-bar   { display: none; }
.speak-tools { display: none; }

html.speak .speak-bar {
  display: block;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 55;
  padding: .5rem .6rem;
  /* clear of the home-bar gesture area on a phone. Its own declaration, so a
     browser that has never heard of env() simply keeps the line above. */
  padding-bottom: calc(.5rem + env(safe-area-inset-bottom, 0px));
  background: var(--paper);
  border-top: 3px solid #40190f;
  box-shadow: 0 -4px 14px rgba(64, 25, 15, .18);
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  /* a very long voice list must scroll inside the bar, never off the screen */
  max-height: 92vh;
  overflow-y: auto;
}
/* while it is actually reading, the bar wears the guacamole stripe */
html.speak .speak-bar.is-reading { border-top-color: var(--guac); }
.speak-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .4rem;
}
.btn-speak { background: var(--guac); color: #10280f; }
.btn-speak:hover { background: #7fd08a; }
.btn-speak[disabled] { opacity: .55; cursor: not-allowed; box-shadow: none; }
.btn-voices { background: var(--sky); color: #fff; }
.btn-voices:hover { background: #3f9ad8; }

.speak-status {
  margin: .35rem 0 0;
  text-align: center;
  font-size: .82rem;
  font-style: normal;
  line-height: 1.35;
  color: var(--ink-soft);
}
.speak-bar.no-speech .speak-status { color: var(--chili-dark); font-weight: 700; }

/* the line being spoken. Chrome only: a wash and an outline, never a border
   and never a size change, so not one word can move on the page. */
.speaking-now {
  background: rgba(232, 163, 23, .28);
  outline: 3px solid var(--sun);
  outline-offset: 3px;
  border-radius: var(--radius);
  transition: background-color .2s ease;
}

/* the panel of voices, above the bar */
.speak-panel {
  max-width: 34rem;
  margin: .5rem auto 0;
  max-height: 58vh;
  overflow-y: auto;
  padding: .6rem .7rem;
  background: #fff8ea;
  border: 2px solid var(--paper-edge);
  border-radius: var(--radius);
  font-size: .86rem;
  line-height: 1.45;
}
.speak-panel[hidden] { display: none; }
.speak-head { margin: 0 0 .4rem; font-weight: 800; font-style: normal; font-size: .95rem; }
.speak-verdict {
  margin: 0 0 .5rem;
  padding: .45rem .55rem;
  font-style: normal;
  border-radius: var(--radius);
  border-left: 5px solid var(--ink-soft);
  background: rgba(140, 105, 60, .10);
}
.speak-verdict.has-ta { border-left-color: var(--guac);  background: rgba(46, 125, 50, .12); font-weight: 700; }
.speak-verdict.no-ta  { border-left-color: var(--chili); background: rgba(198, 40, 40, .10); }
.speak-langs { margin: 0 0 .6rem; font-style: normal; color: var(--ink); }
.speak-field {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .45rem;
  margin: 0 0 .5rem;
  font-style: normal;
}
.speak-field label { font-weight: 700; }
.speak-field select,
.speak-field input[type="range"] {
  flex: 1 1 12rem;
  min-width: 0;
  min-height: 44px;                /* a real finger target */
}
.speak-field select {
  font: inherit;
  padding: .3rem .4rem;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid #40190f;
  border-radius: var(--radius);
  max-width: 100%;
}
.speak-check label { display: flex; align-items: center; gap: .5rem; font-weight: 400; }
.speak-check input { width: 22px; height: 22px; }
.speak-list { margin: 0 0 .5rem; }
.speak-list summary { cursor: pointer; font-weight: 700; min-height: 44px; display: flex; align-items: center; }
.speak-all {
  margin: .3rem 0 0;
  padding: .5rem;
  max-height: 40vh;
  overflow: auto;
  white-space: pre-line;           /* one voice per line, straight from the device */
  font-family: "Courier New", ui-monospace, monospace;
  font-size: .78rem;
  font-style: normal;
  line-height: 1.5;
  background: rgba(140, 105, 60, .10);
  border-radius: var(--radius);
}
.speak-note { margin: 0; font-style: normal; font-size: .8rem; color: var(--ink-soft); }

/* the bar takes room from the page instead of sitting on top of the words */
html.speak #book      { padding-bottom: 7.5rem; }
html.speak .site-foot { padding-bottom: 8.5rem; }
html.speak .totop     { bottom: 6.2rem; }

/* "Read page 12" -- the other end of the same foot margin the print button
   lives in, so neither of them can ever sit on a line of the story */
html.speak .speak-tools {
  display: flex;
  justify-content: flex-start;
  position: absolute;
  left: calc(var(--u) * 16);
  bottom: calc(var(--u) * 3);
  margin: 0;
  z-index: 2;
}
.btn-speak-page { letter-spacing: .02em; }

@media (max-width: 420px) {
  html.speak .speak-bar { padding: .4rem .35rem; padding-bottom: calc(.4rem + env(safe-area-inset-bottom, 0px)); }
  .speak-row .btn { padding: .6rem .7rem; font-size: .85rem; }
  .speak-status { font-size: .76rem; }
}

/* --- 8. mobile ----------------------------------------------------------
   The sheet does NOT change shape on a phone. It is the same A4 rectangle,
   drawn smaller. All that changes is how much gutter we waste around it.
   ------------------------------------------------------------------------ */
@media (max-width: 700px) {
  :root { --gutter: .7rem; }
  #book { padding: .8rem 0 2rem; }
}
@media (max-width: 420px) {
  :root { --gutter: .35rem; }
  .topbar-inner { padding: .4rem .5rem; gap: .35rem; }
  .btn { padding: .6rem .75rem; font-size: .88rem; }
  .brand { font-size: .92rem; }
  .totop { width: 46px; height: 46px; right: .5rem; bottom: .5rem; }
}
@media (max-width: 360px) {
  :root { --gutter: .25rem; }
  .brand { font-size: .84rem; }
  .btn { padding: .55rem .65rem; font-size: .84rem; }
  .toc-list { grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr)); }
}

/* --- 9. dark mode (screen only -- print is always black on white) -------- */
@media (prefers-color-scheme: dark) {
  :root {
    --paper:      #221b16;
    --paper-edge: #4a3a2c;
    --bg:         #171210;
    --bg-2:       #100c0a;
    --ink:        #f0e5d8;
    --ink-soft:   #bda98f;
    --chili:      #ff7a6b;
    --chili-dark: #ffb0a3;
    --sun:        #f0b43c;
    --guac:       #7bc47f;
    --sky:        #2b7fc4;
  }
  body { background-image:
    repeating-linear-gradient( 45deg, rgba(255,122,107,.05) 0 12px, transparent 12px 24px),
    repeating-linear-gradient(-45deg, rgba(123,196,127,.05) 0 12px, transparent 12px 24px),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%); }
  .topbar { background: #7a1f1a; }
  .btn { background: #ffe1b8; color: #5a1410; border-color: #170c08; box-shadow: 0 2px 0 #170c08; }
  .btn-print { background: var(--sun); color: #3a2200; }
  .toc-list a { background: #2c231c; color: var(--ink); border-color: var(--paper-edge); }
  .toc-list a:hover { color: #2b2018; }
  .d { color: #e6d8c8; border-left-color: rgba(255,122,107,.35); }
  /* the same cast, lit for a dark page */
  .say-taco     { --speaker: #ff9a7a; }
  .say-gazpacho { --speaker: #7fc4ff; }
  .say-mayor    { --speaker: #c9a7ff; }
  .say-monster  { --speaker: #86d18b; }
  .say-nacho    { --speaker: #5fd6d0; }
  .say-paellon,
  .say-raider   { --speaker: #e6b84a; }
  .say-guard    { --speaker: #8fc3d4; }
  .say-worker   { --speaker: #d6a97a; }
  .say-rider,
  .say-riders   { --speaker: #ff92bd; }
  .say-tamale,
  .say-tamales  { --speaker: #ccc06a; }
  .say-masked,
  .say-voice    { --speaker: #a9a0d8; }
  .say-master,
  .say-scoville { --speaker: #f07ba8; }
  .say-town     { --speaker: #bda98f; }
  .say-unknown  { --speaker: #9b8d7e; }
  .sfx { text-shadow: calc(var(--u) * .7) calc(var(--u) * .7) 0 rgba(240,180,60,.45); }
  .sign { color: #ffe6c0; border-color: #6b533c; }
  .cover, .page, .the-end { box-shadow: 0 6px 18px rgba(0,0,0,.5); }
  /* the same "quiet but readable" idea, lit for a dark page: warm ink on a
     slightly lifted panel, never a faded-out grey */
  .btn-page { color: #f0e5d8; background: rgba(255, 240, 214, .10); border-color: #6b543f; }
  .btn-page:hover, .btn-page:focus-visible {
    background: #3a2e22; border-color: var(--chili); color: #ffd9c9;
  }
  /* read aloud, lit for a dark page */
  html.speak .speak-bar { background: #241a14; border-top-color: #170c08; box-shadow: 0 -4px 14px rgba(0,0,0,.55); }
  .btn-speak  { background: #57a05c; color: #06210a; border-color: #170c08; }
  .btn-voices { background: #2b6f9e; color: #fff; border-color: #170c08; }
  .speak-panel { background: #2c231c; border-color: var(--paper-edge); }
  .speak-verdict { background: rgba(255, 240, 214, .08); }
  .speak-verdict.has-ta { background: rgba(123, 196, 127, .16); }
  .speak-verdict.no-ta  { background: rgba(255, 122, 107, .14); }
  .speak-all { background: rgba(255, 240, 214, .08); }
  .speak-field select { background: #2c231c; color: var(--ink); border-color: #6b543f; }
  .speaking-now { background: rgba(240, 180, 60, .22); outline-color: var(--sun); }
}

/* --- 10. PRINT ----------------------------------------------------------
   Real A4. One story page per physical sheet. The page box supplies the
   margins, so the sheet boxes above are flattened back to "just content" --
   otherwise a 297mm box inside a 263mm page box would spill onto a second
   sheet. Black text on white paper, no colour, no UI, no JavaScript.
   ------------------------------------------------------------------------ */
@page {
  size: A4;
  margin: 16mm 16mm 18mm;
}

@media print {
  :root {
    color-scheme: light;
    --u: 1mm;              /* on paper, one millimetre is one millimetre */
  }

  html, body {
    background: #fff !important;
    background-image: none !important;
    color: #000 !important;
    font-size: 19pt;
    line-height: 1.4;
    margin: 0; padding: 0;
    overflow: visible !important;
  }

  /* hide all the screen furniture */
  .topbar, .bunting, .progress, .progress-bar, .contents, .contents-panel,
  .totop, .btn, .btn-print, button, .site-foot, .cover::before, .brand-hat,
  .page-tools, .btn-page, .print-range, .range-msg,
  /* round 10: not one pixel of the read-aloud machinery reaches the paper */
  .speak-bar, .speak-row, .speak-status, .speak-panel, .speak-head,
  .speak-verdict, .speak-langs, .speak-field, .speak-check, .speak-list,
  .speak-all, .speak-note, .speak-tools, .btn-speak, .btn-speak-page {
    display: none !important;
  }

  /* The line being read keeps its class while the print dialog is open (and
     speak.js also clears it on beforeprint). Either way it must leave no mark
     on the paper: the highlight is screen chrome, not part of the story. */
  .speaking-now {
    background: none !important;
    outline: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
  }

  /* the bar is gone, so the room that was made for it goes too */
  html.speak #book, html.speak .site-foot { padding-bottom: 0 !important; }

  /* --- printing ONE page, or a few of them -----------------------------
     book.js puts "print-scope" on <body> and "print-me" on the sheets you
     asked for, calls window.print(), and takes both off again the moment
     the dialog closes (and on a timer, in case it never says so). With no
     class on <body> NOTHING below applies and the whole book prints, exactly
     as it always did -- which is also what happens with JS switched off.
     --------------------------------------------------------------------- */
  body.print-scope .cover,
  body.print-scope .the-end,
  body.print-scope .page:not(.print-me) {
    display: none !important;
  }
  /* the first sheet you asked for must not push a blank sheet out ahead of
     itself: every .page normally forces a page break BEFORE it. */
  body.print-scope .print-first {
    break-before: auto !important;
    page-break-before: auto !important;
  }

  #book {
    max-width: none;
    width: auto !important;
    margin: 0;
    padding: 0;
    display: block;
    gap: 0;
  }

  /* flatten the screen sheet back to plain content: the @page box is the
     sheet now, and it is already exactly A4 with the same margins. */
  .cover, .page, .the-end {
    width: auto !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    padding: 0 !important;
    margin: 0 !important;
    background: none !important;
    border: 0 !important;
    box-shadow: none !important;
    border-radius: 0;
    overflow: visible !important;
    display: block;
  }

  /* --- the cover sheet --- */
  .cover {
    padding: 40mm 0 0 !important;
    text-align: center;
    break-after: page;
    page-break-after: always;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .cover-hat { display: none !important; }
  .book-title {
    color: #000 !important;
    text-shadow: none !important;
    font-size: 34pt;
    line-height: 1.15;
    margin: 0 0 8mm;
  }
  .byline { color: #000 !important; font-size: 13pt; }

  /* --- one story page per sheet --- */
  .page {
    break-before: page;
    page-break-before: always;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* the page number stays on the printed sheet, as a plain line-art header */
  .page-title {
    color: #000 !important;
    font-size: 10pt;
    letter-spacing: .16em;
    border-bottom: 0.5pt solid #000 !important;
    padding-bottom: 2mm;
    margin: 0 0 6mm;
    break-after: avoid;
    page-break-after: avoid;
  }
  .page-title::before {
    background: #000 !important;   /* line-art chilli dot */
    width: 2.2mm; height: 2.2mm;
  }
  .page-title::after {
    background: none !important;
    height: 0;
  }

  .line, .d, .sfx, .sign {
    color: #000 !important;
    font-size: 19pt;
    line-height: 1.4;
    max-width: none;
    margin: 0 0 2.4mm;
    orphans: 2;
    widows: 2;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .d {
    /* ROUND 9: the spoken lines are set LARGER than the narration, on paper
       exactly as on screen. The rule above sets every story line to 19pt;
       this one comes after it and lifts dialogue to --t-dialogue (21pt).
       Without it the book would print its dialogue at narration size -- and
       the pagination budget in verify.js, which measures dialogue at 21pt,
       would be budgeting for a page that never prints. */
    font-size: 21pt;
    border-left: 0.5pt solid #000 !important;
    padding-left: 3.5mm;
  }

  /* the speaker's name is TEXT, so it prints. On paper it is plain black --
     the name does the work, the colour was only ever a screen bonus.

     ON PAPER THE TWO COLUMNS ARE A FLOAT, NOT A GRID (round 6).
     The screen still uses CSS grid (section 6) -- browsers are excellent at
     it. Printers and PDF engines are not: several of them ANSWER YES to
     "do you support grid?" and then lay it out wrongly, which would drop the
     speaker's name on top of Adhiyan's line. A float is the one two-column
     trick every print engine ever built gets right, so print uses that and
     nothing else. Same 24mm column, same 2mm gap, same look. */
  .say {
    display: block;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .say::after { content: ""; display: block; clear: both; }
  .say > .who {
    float: left;
    width: 24mm;
    margin: 0;
  }
  .say > .d { margin-left: 26mm; }     /* 24mm column + 2mm gap */
  .who {
    color: #000 !important;
    font-size: 10pt;
    line-height: 1.4;
    letter-spacing: .06em;
    margin: 0 0 2.4mm;
    text-align: right;
    orphans: 2;
    widows: 2;
  }
  .who.guess { opacity: 1; font-weight: 400; }
  .say > .d { border-left-color: #000 !important; }
  .sfx {
    color: #000 !important;
    text-shadow: none !important;
    transform: none !important;
    font-size: 26pt;
    line-height: 1.15;
    letter-spacing: .08em;
    margin: 4mm 0 4.5mm;
  }
  .sign {
    background: none !important;
    border: 0.5pt solid #000 !important;
    color: #000 !important;
    font-size: 13pt;
    line-height: 1.3;
    letter-spacing: .18em;
    padding: 2mm;
    margin: 4mm auto 4.5mm;
    max-width: 110mm;
  }
  #p1 .line:first-of-type::first-letter { color: #000 !important; }

  .the-end {
    break-before: page;
    page-break-before: always;
    break-inside: avoid;
    page-break-inside: avoid;
    padding: 90mm 0 0 !important;
    text-align: center;
  }
  .the-end-line { color: #000 !important; font-size: 24pt; }
  .the-end::after { background: none !important; height: 0; margin: 0; }

  a { color: #000 !important; text-decoration: none !important; }
}

/* --- 11. why there is no @supports block here any more -------------------
   Round 4 and 5 printed the speaker column with CSS grid and kept a float
   version behind  @supports not (display: grid)  as a safety net. That net
   had a hole in it: an engine only falls into it if it ADMITS it cannot do
   grid. The print engines that actually get grid wrong (old wkhtmltopdf and
   friends) claim they support it, sail past the @supports test, and lay the
   name on top of the line.

   So round 6 turned it round: print uses the float ALWAYS (see section 10),
   and there is no fallback to get wrong. Screen keeps the grid. Nothing on
   screen changed at all.
   ------------------------------------------------------------------------ */

/* --- 12. the shelf, the books menu, and a book that is not written yet ----
   The site is a series now, not one book. index.html is the shelf; each book
   is its own page; every page carries a "Books" menu to hop between them.
   books.js is the only place that knows what exists -- this is just paint.
   ------------------------------------------------------------------------ */

/* the books menu in the top bar (it reuses the contents panel) */
.book-list { list-style: none; margin: 0; padding: 0; }
.book-list li + li { margin-top: .4rem; }
.book-list a {
  display: flex; align-items: center; flex-wrap: wrap; gap: .4rem;
  min-height: 44px;
  padding: .5rem .7rem;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .95rem; font-weight: 700;
  text-decoration: none;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--paper-edge);
  border-radius: 9px;
}
.book-list a:hover { background: var(--sun); border-color: #40190f; }
.book-list a:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
.book-list a.here { background: #fff3dc; border-color: #40190f; }
.book-list a.here::after { content: "you are here"; font-size: .7rem; font-weight: 400; font-style: italic; color: var(--ink-soft); }
.soon-tag {
  font-size: .7rem; font-weight: 700; font-style: normal;
  letter-spacing: .04em; text-transform: uppercase;
  color: #5b4636;
  background: var(--sun);
  border-radius: 999px;
  padding: .12rem .5rem;
}
.toc-none { margin: 0; font-style: italic; color: var(--ink-soft); }

/* the shelf page */
.shelf { max-width: 46rem; margin: 0 auto; padding: 1.2rem var(--gutter) 2.4rem; }
.shelf-head { text-align: center; margin: 0 0 1.6rem; }
.shelf-head .cover-hat {
  width: calc(var(--u) * 46);
  height: calc(var(--u) * 26);
  margin: 0 auto calc(var(--u) * 6);
}
.shelf-title {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: clamp(1.5rem, 7vw, 2.6rem);
  line-height: 1.1;
  margin: 0 0 .4rem;
  color: var(--chili);
  text-shadow: 2px 2px 0 var(--sun);
  text-wrap: balance;
}
.shelf-sub { margin: 0; font-style: italic; color: var(--ink-soft); }

.books { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; }
.book-card {
  background: var(--paper);
  border: 3px solid var(--paper-edge);
  border-radius: 16px;
  box-shadow: 0 6px 0 rgba(64,25,15,.16);
  padding: 1rem 1rem 1.1rem;
}
.book-card.is-soon { border-style: dashed; box-shadow: none; }
.book-num {
  margin: 0 0 .2rem;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .8rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-soft);
  font-style: normal;
}
.book-name {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: clamp(1.15rem, 5vw, 1.6rem);
  line-height: 1.15;
  margin: 0 0 .35rem;
  text-wrap: balance;
}
.book-name a { color: var(--chili-dark); text-decoration: none; }
.book-name a:hover { text-decoration: underline; }
.book-sub { margin: 0 0 .45rem; font-style: italic; color: var(--ink-soft); font-size: .95rem; }
.book-status { margin: 0 0 .6rem; font-size: .9rem; color: var(--ink-soft); }
.pill {
  display: inline-block;
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: .72rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  padding: .18rem .55rem;
  border-radius: 999px;
  background: var(--sun);
  color: #40190f;
  margin-right: .35rem;
}
.is-soon .pill { background: #e6ded2; }
.book-blurb { margin: 0 0 .9rem; line-height: 1.5; }
.book-go { margin: 0; }
.btn-read {
  text-decoration: none;
  color: var(--chili-dark);
}
.shelf-extra {
  margin: 1.4rem 0 0;
  font-size: .95rem;
  line-height: 1.5;
  color: var(--ink-soft);
  text-align: center;
}
.shelf-extra a { color: var(--chili-dark); }

/* A book that has no story in it yet. It is still a real A4 sheet -- an
   empty one, waiting -- so Book 2 looks like it belongs on the same shelf.
   The dashed border is the only thing saying "nothing here yet". */
.soon {
  width:  calc(var(--u) * 210);
  height: calc(var(--u) * 297);
  padding: calc(var(--u) * 16) calc(var(--u) * 16) calc(var(--u) * 18);
  background: var(--paper);
  border: 2px dashed var(--paper-edge);
  border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(64,25,15,.14);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: visible;
  position: relative;
}
.soon-head {
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-weight: 800;
  font-size: calc(var(--u) * 9);
  color: var(--chili);
  margin: 0 0 calc(var(--u) * 8);
}
.soon-line {
  max-width: calc(var(--u) * 150);
  margin: 0 0 calc(var(--u) * 5);
  font-size: calc(var(--u) * 5);
  line-height: 1.55;
}
.soon-links { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin-top: calc(var(--u) * 6); }

.foot-shelf { margin: 1.2rem 0 0 !important; font-style: normal !important; }
.foot-shelf a { color: var(--chili-dark); font-weight: 700; text-decoration: none; }
.foot-shelf a:hover { text-decoration: underline; }

/* the shelf never needs the sheet machinery */
.shelf-body #book { display: none; }

/* the brand shortens itself rather than squeezing the buttons off a phone */
.brand-short { display: none; }
@media (max-width: 420px) {
  .brand-long  { display: none; }
  .brand-short { display: inline; }
}

@media (prefers-color-scheme: dark) {
  .book-list a { background: #241a14; color: var(--ink); border-color: #3a2b21; }
  .book-list a.here { background: #33241a; }
  .book-card { background: #241a14; border-color: #3a2b21; box-shadow: none; }
  .is-soon .pill { background: #3a2b21; color: #e8dccd; }
  .book-name a, .btn-read, .shelf-extra a, .foot-shelf a { color: var(--sun); }
}

@media print {
  .shelf, .shelf-body .topbar, .shelf-body .site-foot,
  .book-list, .soon-links, .foot-shelf { display: none !important; }
  .soon, .soon-head, .soon-line { display: block; }
}
