/* ============================================================
   book.css — the binding: boards, leaves, and the turn itself

   The whole thing is one book sitting on a desk. Seven leaves,
   fourteen faces, each leaf hinged on the spine at its left edge
   and rotated around it. Wide screens get a two-page spread;
   narrow screens get one page at a time. book.js owns
   `transform` on .leaf — this file owns everything else.
   ============================================================ */

/* Two measurements the whole layout depends on, so they are named once:
   --pad is the margin of the desk, and --chrome is the strip the page
   bar and the cassette deck sit in. The book sizes itself against both,
   which is the only way it reliably fits. */
:root {
  --pad: clamp(0.5rem, 2vw, 1.75rem);
  --chrome: clamp(3.4rem, 7vh, 4.6rem);
}

.desk {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--pad);
  padding-bottom: var(--chrome);
  z-index: 1;
}

/* a pool of light on the desk, under the book */
.desk::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 55% at 50% 44%, rgba(255, 244, 214, 0.075), transparent 70%);
  pointer-events: none;
}

/* ─────────────────────────────  THE BOOK  ───────────────────────────── */

.book {
  /* The page proportion. This number is the contract the whole design
     rests on: it NEVER changes, in either layout, at any window size.
     Because of that, a page is always 100cqi by 138.889cqi, every size
     printed on it can be written in cqi, and the line breaks fall in
     the same places however big the book is. Which is how nothing in
     here has to scroll. Change it and every page has to be re-fitted. */
  --pw: 0.72;
  /* 2rem of the width is kept back for the block of page edges and the
     boards, which both stand proud of the leaves on either side. */
  --avail-h: calc(100svh - var(--pad) - var(--chrome));
  --avail-w: calc(100vw - 2 * var(--pad) - 2rem);
  --h: min(var(--avail-h), 52rem, calc(var(--avail-w) / (2 * var(--pw))));

  --dur: 1.05s;
  --turn-ease: cubic-bezier(0.42, 0.04, 0.22, 1);
  --stack-l: 0;
  --stack-r: 1;

  position: relative;
  height: var(--h);
  width: calc(var(--h) * var(--pw) * 2);
  /* perspective here, preserve-3d on the leaf: that way the leaves are
     still ordinary siblings and z-index decides which is on top. */
  perspective: 2600px;
  perspective-origin: 50% 40%;
  touch-action: pan-y;
  transition: transform var(--dur) var(--turn-ease);
}

/* set while the layout is being rebuilt, so nothing slides into place */
.book.is-static,
.book.is-static .leaf,
.book.is-static .book__base,
.book.is-static .book__edges { transition: none; }

/* Shut, the book is only half as wide as it is open, so it slides over
   to sit in the middle of the desk. */
.book.is-closed { transform: translateX(-25%); }
.book.is-done   { transform: translateX(25%); }

/* ---------- the boards underneath, and the block of page edges ---------- */

.book__base {
  position: absolute;
  inset: -0.7% -1%;
  z-index: 0;
  border-radius: 3px 5px 5px 3px;
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,0.025) 0 1px, transparent 1px 3px),
    linear-gradient(170deg, #1d2a3c, #121b27 70%, #0a1017);
  box-shadow:
    0 2px 0 rgba(255,255,255,0.06) inset,
    0 42px 70px -34px rgba(0,0,0,0.95),
    0 14px 34px -16px rgba(0,0,0,0.75);
  transition: transform var(--dur) var(--turn-ease);
}

.book.is-closed .book__base { transform: translateX(25%) scaleX(0.5); }
.book.is-done   .book__base { transform: translateX(-25%) scaleX(0.5); }

.book__edges {
  position: absolute;
  top: 1.4%;
  bottom: 1.4%;
  z-index: 0;
  background-color: #e3d8c0;
  background-image:
    repeating-linear-gradient(90deg,
      #f0e7d4 0 1px, #cdbc9c 1px 2px, #e7ddc6 2px 3px, #d8caad 3px 4px);
  box-shadow: inset 0 0 6px rgba(0,0,0,0.25);
  transition: width var(--dur) var(--turn-ease), opacity 0.5s;
}

.book__edges--r {
  left: 100%;
  width: calc(1px + var(--stack-r) * 0.85rem);
  border-radius: 0 4px 4px 0;
  opacity: calc(var(--stack-r) * 4);
}

.book__edges--l {
  right: 100%;
  width: calc(1px + var(--stack-l) * 0.85rem);
  border-radius: 4px 0 0 4px;
  opacity: calc(var(--stack-l) * 4);
}

/* ─────────────────────────────  LEAVES  ─────────────────────────────── */

.leaf {
  position: absolute;
  top: 0;
  left: 50%;
  width: 50%;
  height: 100%;
  transform-origin: left center;
  transform-style: preserve-3d;
  transition: transform var(--dur) var(--turn-ease);
}

/* Before book.js has had a word, the book is simply shut: leaf 0 on
   top, the rest in order underneath. JS overrides these inline. */
.leaf[data-leaf="0"] { z-index: 9; }
.leaf[data-leaf="1"] { z-index: 8; }
.leaf[data-leaf="2"] { z-index: 7; }
.leaf[data-leaf="3"] { z-index: 6; }
.leaf[data-leaf="4"] { z-index: 5; }
.leaf[data-leaf="5"] { z-index: 4; }
.leaf[data-leaf="6"] { z-index: 3; }
.leaf[data-leaf="7"] { z-index: 2; }
.leaf[data-leaf="8"] { z-index: 1; }

/* while a finger or a mouse is dragging the corner, the page follows it */
.book.is-dragging .leaf { transition: none; }

.book.is-dragging,
.book.is-dragging * {
  user-select: none;
  -webkit-user-select: none;
  cursor: grabbing;
}

/* Each face is nudged half a pixel toward its own front, so that the
   right one wins on depth even in a browser that fumbles
   backface-visibility. At this perspective it is invisible. */
.leaf__face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  transform: translateZ(0.5px);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  background: #0d141c;
  container-type: inline-size;
  container-name: page;
}

.leaf__face--back { transform: rotateY(180deg) translateZ(0.5px); }

/* the gutter: every page is darker where it disappears into the spine */
.leaf__face::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 11%;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(28, 20, 10, 0.34) 0%,
    rgba(28, 20, 10, 0.13) 32%,
    rgba(255, 255, 255, 0.10) 72%,
    transparent 100%);
}

.leaf__face--front::before { left: 0; }
.leaf__face--back::before  { right: 0; transform: scaleX(-1); }

/* a sheen that crosses the page while it is being turned */
.leaf__face::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(105deg,
    rgba(255, 248, 228, 0.5) 0%,
    rgba(255, 248, 228, 0.05) 38%,
    rgba(0, 0, 0, 0.22) 100%);
}

.leaf.is-turning .leaf__face::after {
  animation: page-sheen var(--dur) var(--turn-ease);
}

@keyframes page-sheen {
  0%   { opacity: 0; }
  40%  { opacity: 0.85; }
  100% { opacity: 0; }
}

/* a leaf that has been turned past in single-page mode gets out of the
   way, but only once it has finished travelling */
.leaf.is-away {
  visibility: hidden;
  transition: transform var(--dur) var(--turn-ease), visibility 0s linear var(--dur);
}

/* ───────────────────────────  THE PAPER  ────────────────────────────── */

/* The page. It does not scroll, and it is not allowed to: every page is
   written to fit inside these margins at this one fixed shape. The
   budget is 86cqi across by 126.4cqi down. See pages.css. */
.sheet {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  padding: 5.5cqi 7cqi 7cqi;
  font-size: 3.4cqi;
  line-height: 1.58;
  /* the paper itself — colour, fibre, foxing — is pages.css's business */
}

/* ───────────────────────  GRAB THE OUTER EDGE  ──────────────────────── */

.turn {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 30;
  width: clamp(1.9rem, 4.5%, 3.4rem);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  opacity: 1;
  transition: opacity 0.4s var(--ease-soft);
}

.turn--prev { left: 0; }
.turn--next { right: 0; }

.turn:hover,
.turn:focus-visible { opacity: 1; outline: none; }

.turn:disabled { opacity: 0; pointer-events: none; }

/* These sit on top of the outer edge of the paper, so a pale chevron on a
   pale page was all but invisible. It is a disc now: dark, gold-rimmed, the
   same family as the little page bar, and it reads against the paper and
   against the desk equally. */
.turn__arrow {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(198, 162, 74, 0.55);
  background: rgba(12, 18, 28, 0.82);
  color: var(--gold-bright);
  box-shadow:
    0 6px 16px -6px rgba(0, 0, 0, 0.85),
    0 1px 0 rgba(255, 255, 255, 0.08) inset;
  transition:
    translate 0.4s var(--ease-soft),
    scale 0.3s var(--ease-soft),
    background 0.3s, border-color 0.3s, color 0.3s;
}

/* Drawn rather than typed. The ‹ › glyphs carry their own side bearings, so
   they never sit centred in a circle, and they shift again when the web font
   finally lands. A path is symmetric about the middle of its viewBox and
   stays that way. Shared with the buttons in the little page bar, which had
   exactly the same problem in a smaller square. */
.chev {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.turn:hover .turn__arrow,
.turn:focus-visible .turn__arrow {
  background: rgba(198, 162, 74, 0.94);
  border-color: var(--gold-bright);
  color: #0e1520;
  scale: 1.08;
}

.turn--next:hover .turn__arrow { translate: -34% -50%; }
.turn--prev:hover .turn__arrow { translate: -66% -50%; }

/* the corner of the page lifting slightly, the way it does */
.turn__curl {
  position: absolute;
  bottom: 0;
  width: 0;
  height: 0;
  opacity: 0;
  transition: opacity 0.4s var(--ease-soft), border-width 0.4s var(--ease-soft);
}

.turn--next .turn__curl {
  right: 0;
  border-bottom: 0 solid rgba(0, 0, 0, 0.25);
  border-left: 0 solid transparent;
}

.turn--next:hover .turn__curl {
  opacity: 1;
  border-bottom-width: 2.6rem;
  border-left-width: 2.6rem;
  border-bottom-color: rgba(243, 234, 217, 0.55);
}

.turn--prev .turn__curl {
  left: 0;
  border-bottom: 0 solid rgba(0, 0, 0, 0.25);
  border-right: 0 solid transparent;
}

.turn--prev:hover .turn__curl {
  opacity: 1;
  border-bottom-width: 2.6rem;
  border-right-width: 2.6rem;
  border-bottom-color: rgba(243, 234, 217, 0.55);
}

/* ───────────────────  THE "NEXT PAGE" ARROW  ────────────────────────── */

/* Pencil in the outer margin of the very first spread, pointing at the
   chevron. It is drawn in ink rather than gold because unlike the one by
   the cassette deck, this one lies on the paper. book.js shows it while
   exactly one leaf has been turned, and retires it permanently the first
   time the reader turns a page themselves. */

.pagehint {
  position: absolute;
  z-index: 31;
  top: 50%;
  right: 3.4rem;
  width: 9.5rem;
  translate: 0 -122%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.6s var(--ease-soft);
}

.book.show-next-hint .pagehint { opacity: 1; }

.pagehint__label {
  margin: 0 0 0.1rem;
  padding-right: 1.2rem;
  text-align: right;
  font-family: var(--hand);
  font-size: 1.35rem;
  line-height: 1.1;
  color: var(--faded-blue);
  rotate: -2.5deg;
}

.pagehint__arrow {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.pagehint__shaft,
.pagehint__barb {
  fill: none;
  stroke: var(--faded-blue);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* a second pass of the pencil, slightly off the first */
.pagehint__shaft--ghost { stroke-width: 1.2; opacity: 0.45; }

.pagehint__shaft { stroke-dasharray: 190; stroke-dashoffset: 190; }
.pagehint__barb  { stroke-dasharray: 26;  stroke-dashoffset: 26; }

/* drawn on when the class arrives, not when the page loads */
.book.show-next-hint .pagehint__shaft {
  animation: pagehint-draw 0.9s var(--ease-out) 0.45s forwards;
}

.book.show-next-hint .pagehint__barb {
  animation: pagehint-draw 0.3s var(--ease-out) 1.3s forwards;
}

@keyframes pagehint-draw { to { stroke-dashoffset: 0; } }

/* ──────────────────────────  THE LITTLE BAR  ────────────────────────── */

.bookbar {
  position: fixed;
  left: clamp(0.7rem, 2vw, 1.6rem);
  bottom: clamp(0.7rem, 2vw, 1.6rem);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.55rem;
  border: 1px solid rgba(198, 162, 74, 0.2);
  border-radius: 4px;
  background: rgba(10, 16, 23, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.bookbar__btn {
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  border: 1px solid rgba(198, 162, 74, 0.28);
  border-radius: 3px;
  background: none;
  color: var(--gold-bright);
  cursor: pointer;
  transition: background 0.3s, border-color 0.3s, opacity 0.3s;
}

.bookbar__btn .chev {
  width: 0.82rem;
  height: 0.82rem;
  stroke-width: 2.8;
}

.bookbar__btn:hover { background: rgba(198, 162, 74, 0.14); }
.bookbar__btn:disabled { opacity: 0.25; cursor: default; }

.bookbar__readout {
  min-width: min(13rem, 38vw);
  padding: 0 0.3rem;
}

.bookbar__label {
  display: block;
  font-family: var(--label);
  font-weight: 300;
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(232, 205, 132, 0.72);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bookbar__rule {
  display: block;
  height: 1px;
  margin-top: 0.42rem;
  background: rgba(198, 162, 74, 0.2);
}

.bookbar__rule i {
  display: block;
  width: 0;
  height: 100%;
  background: var(--gold);
  transition: width var(--dur, 1s) var(--ease-soft);
}

/* ───────────────────────  ONE PAGE AT A TIME  ───────────────────────── */

/* One page instead of two. The page keeps exactly the same shape — only
   the book around it is narrower — so every page still fits. */

@media (max-width: 56rem) {
  .book {
    /* the page bar has moved to the top, so there is chrome at both ends */
    --avail-h: calc(100svh - 2 * var(--chrome));
    --h: min(var(--avail-h), 46rem, calc(var(--avail-w) / var(--pw)));
    width: calc(var(--h) * var(--pw));
  }

  /* The cassette deck lives bottom-right, and when there is only one page
     it covers the foot of it. So the page bar goes up to the top instead,
     and the book is given room at both ends rather than fighting either. */
  .desk { padding-top: var(--chrome); }
  .bookbar { top: clamp(0.7rem, 2vw, 1.6rem); bottom: auto; }

  .leaf { left: 0; width: 100%; }

  .book.is-closed,
  .book.is-done { transform: none; }

  .book.is-closed .book__base,
  .book.is-done .book__base { transform: none; }

  .turn { width: clamp(1.6rem, 9%, 2.8rem); }
}

/* ─────────────────────────  A SHORT WINDOW  ──────────────────────────── */

/* Height is what decides how big the book can be, so a short window makes
   a small book — the pages keep their shape and their typography scales
   with them, the way a photograph of a page does. What it must never do
   is change --pw to claw back width: that would re-proportion every page
   and the fitting would all have to be done again. */

/* ────────────────────────────  STILLNESS  ───────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .book,
  .book__base,
  .book__edges,
  .leaf { transition: none; }

  .leaf.is-away { transition: none; visibility: hidden; }
  .leaf.is-turning .leaf__face::after { animation: none; }
}
