/* Schirete — page-turn lookbook ("flipbook")
   Owns: .flipbook and everything inside it. Do not restyle these selectors
   in style.css — this file is loaded after it and is the single source of
   truth for the flip mechanic.

   Contract this file styles (see docs/flipbook-design.md for the full spec):

     .flipbook[data-flipbook]
       .flipbook__stage
         .flipbook__page[data-index="N"] > picture > img
       .flipbook__ui
         .flipbook__btn--prev / --next
         .flipbook__counter > .flipbook__i / .flipbook__n

   State classes: .is-ready, .is-current, .is-prev, .is-next, .is-hidden,
   .is-turning-fwd, .is-turning-back, .is-dragging. JS drives --turn (0→1)
   on the page that is mid-turn. See the design doc for the geometry model:
   every page shares one anchored box (spine-side edge) and pivots around
   its own left edge whether it is departing (fwd, 0 → -180deg) or
   returning (back, -180 → 0deg) — there is no second, independently
   positioned "left page" element to keep track of. */

.flipbook {
  /* ---------- tunables ---------- */
  --fb-duration: .7s;                       /* click-driven turn */
  --fb-ease: cubic-bezier(.16, .84, .44, 1); /* fast start, paper settles slow */
  --fb-perspective: 1400px;
  --fb-page-ratio: 3 / 4;                   /* single page, portrait print */

  position: relative;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
}

/* ---------- stage ---------- */

.flipbook__stage {
  position: relative;
  width: 100%;
  aspect-ratio: var(--fb-page-ratio);       /* single page on mobile */
  margin: 0 auto;
  perspective: var(--fb-perspective);
  perspective-origin: 50% 50%;
  /* the book itself reads as an object resting on the black page, not a
     panel embedded in it — a soft contact shadow is the only cue available
     on a pure-#000 background. */
  filter: drop-shadow(0 26px 46px rgba(0, 0, 0, .7));
}

/* the spine: a fixed hairline + gutter shadow at the fold, desktop only
   (see below). On mobile there's one page and no fold to draw. */
.flipbook__stage::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 6;
  opacity: 0;
}

/* ---------- pages ---------- */

.flipbook__page {
  position: absolute;
  inset: 0;
  width: 100%;
  transform-style: preserve-3d;
  transform-origin: left center;    /* the spine — every page pivots here */
  background: var(--bg);
  overflow: hidden;
  will-change: transform;
}

/* resting states — also double as the DRAG states. --turn arrives as a
   bare unitless float ("0.42", no unit) written inline on whichever page is
   being dragged, so it's used purely as a multiplier here. It defaults to 0
   via var(--turn, 0), so a page that isn't being dragged just renders its
   plain resting angle — and when the drag ends and JS *removes* the
   --turn property outright (rather than animating it to 0), the value
   falls straight back to that same default, which is what makes the
   transition below read as a spring-back to rest instead of a snap. */
.flipbook__page.is-current {
  z-index: 3;
  cursor: grab;
  transform: rotateY(calc(var(--turn, 0) * -180deg));
}

.flipbook__page.is-prev {
  z-index: 1;
  transform: rotateY(calc(-180deg + var(--turn, 0) * 180deg));  /* swung past the spine — see docs */
}

.flipbook__page.is-next { z-index: 2; transform: rotateY(0deg); }

.flipbook__page.is-hidden { display: none; }

.flipbook.is-dragging .flipbook__page.is-current { cursor: grabbing; }

/* the transform transition lives on the base rule so it covers both cases
   the coordinator flagged: (1) drag spring-back / commit, the instant
   --turn disappears and the value above falls back to its default, and
   (2) click/keyboard turns below, which never touch --turn at all. */
.flipbook__page.is-current,
.flipbook__page.is-prev,
.flipbook__page.is-next {
  transition: transform var(--fb-duration) var(--fb-ease),
              box-shadow var(--fb-duration) var(--fb-ease);
  box-shadow:
    calc(var(--turn, 0) * -18px) 0 calc(8px + var(--turn, 0) * 34px)
      rgba(0, 0, 0, calc(.35 + var(--turn, 0) * .35));
}

/* while a drag is live, the dragged page must track the pointer 1:1 with
   zero lag — every other page (and every OTHER moment, including the
   instant is-dragging is removed) keeps its transition. */
.flipbook.is-dragging .flipbook__page.is-current,
.flipbook.is-dragging .flipbook__page.is-prev {
  transition: none;
}

/* click- and keyboard-driven turns: the JS adds one of these two classes to
   exactly one page and removes it when done — no --turn involved. These
   are plain two-endpoint transitions (declared after the resting rules
   above so they win the tie on specificity) driven entirely by the class
   toggle; the browser animates from whatever the page's previous computed
   transform was to the literal endpoint below. */
.flipbook__page.is-turning-fwd {
  z-index: 5;
  transform: rotateY(-180deg);
  transition: transform var(--fb-duration) var(--fb-ease),
              box-shadow var(--fb-duration) var(--fb-ease);
  box-shadow: -18px 0 42px rgba(0, 0, 0, .7);
}

.flipbook__page.is-turning-back {
  z-index: 5;
  transform: rotateY(0deg);
  transition: transform var(--fb-duration) var(--fb-ease),
              box-shadow var(--fb-duration) var(--fb-ease);
  box-shadow: 0 0 8px rgba(0, 0, 0, .35);
}

/* ---------- front face (the still) ---------- */

.flipbook__page > picture {
  position: absolute;
  inset: 0;
  display: block;
  backface-visibility: hidden;
  z-index: 1;
}

.flipbook__page img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
  user-select: none;
}

/* self-shading: the face darkens toward the spine as the page lifts away
   from flat, the way a curling print catches less light near its fold.
   Front-face only (backface-visibility: hidden), so it vanishes with the
   photo past the 90-degree mark rather than bleeding onto the paper back.
   The gradient shape is fixed; only its OPACITY moves, because a gradient's
   own color stops don't transition smoothly across browsers — opacity does.
   That opacity is var(--turn, 0) for a drag (tracks the pointer, unitless
   float, no transition while .is-dragging) and a plain 0/1 class toggle for
   click/keyboard turns, which don't set --turn at all. */
.flipbook__page::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  backface-visibility: hidden;
  pointer-events: none;
  background: linear-gradient(
    to right,
    rgba(0, 0, 0, .6) 0%,
    rgba(0, 0, 0, .18) 35%,
    transparent 75%
  );
  opacity: var(--turn, 0);
}

.flipbook__page.is-turning-fwd::before,
.flipbook__page.is-turning-back::before {
  transition: opacity var(--fb-duration) var(--fb-ease);
}

.flipbook__page.is-turning-fwd::before { opacity: 1; }
.flipbook__page.is-turning-back::before { opacity: 0; }

/* a thin catch-light along the curling edge — brand gold, barely there,
   just enough to sell "paper", not enough to look like a UI glow. Lives on
   the <picture> element (not the page) so it doesn't collide with the
   page's own ::before/::after, which are already spoken for by the
   self-shading and paper-back layers above. Same opacity strategy as the
   shading layer, for the same reason. */
.flipbook__page > picture::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to right,
    transparent 0%,
    rgba(245, 184, 0, .16) 8%,
    transparent 16%
  );
  opacity: var(--turn, 0);
}

.flipbook__page.is-turning-fwd > picture::before,
.flipbook__page.is-turning-back > picture::before {
  transition: opacity var(--fb-duration) var(--fb-ease);
}

.flipbook__page.is-turning-fwd > picture::before { opacity: 1; }
.flipbook__page.is-turning-back > picture::before { opacity: 0; }

/* ---------- back face (the paper) ---------- */
/* rotateY(180deg) baked in so that at a parent rotation of -180deg this
   layer's *net* rotation is 0 — it faces the viewer unmirrored, reading as
   the blank verso of the sheet rather than a flipped photograph. Sits
   permanently under .is-prev (see the resting-state rule above): once a
   page is turned, the reader is looking at its paper back, exactly as in a
   single-sided printed lookbook. */
.flipbook__page::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  backface-visibility: hidden;
  transform: rotateY(180deg);
  background:
    linear-gradient(115deg, var(--grey-200) 0%, var(--grey-400) 55%, var(--grey-300) 100%);
  box-shadow: inset 0 0 0 1px var(--line);
}

/* the corner-peel hint, and the catch-light streak above, both use ::after
   on other elements — this rule only needs to add the faint ruled texture
   a blank printed sheet actually has. Kept as a second, layered gradient on
   the same pseudo rather than a fourth element. */
.flipbook__page::after {
  background-image:
    repeating-linear-gradient(
      100deg,
      rgba(30, 30, 30, .05) 0px,
      rgba(30, 30, 30, .05) 1px,
      transparent 1px,
      transparent 5px
    ),
    linear-gradient(115deg, var(--grey-200) 0%, var(--grey-400) 55%, var(--grey-300) 100%);
}

/* ---------- corner-peel affordance ---------- */
/* the tell that the object turns, before anyone touches it. A small
   triangle of "paper" lifts at the outer top corner of the current page on
   hover / keyboard focus, with a shadow of its own. */
.flipbook__page.is-current > picture::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 42px;
  height: 42px;
  z-index: 2;
  clip-path: polygon(100% 0, 0 0, 100% 100%);
  background: linear-gradient(135deg, var(--grey-100) 0%, var(--grey-400) 100%);
  box-shadow: -6px 6px 14px rgba(0, 0, 0, .55);
  opacity: 0;
  transform-origin: 100% 0;
  transform: scale(.001) rotate(2deg);
  transition: opacity .3s ease, transform .3s cubic-bezier(.34, 1.4, .64, 1);
  pointer-events: none;
}

/* the plain :hover-on-the-whole-page trigger that used to live here has
   been replaced by the corner-only hotspot further down (section 5: the
   hover rule on `picture::after` itself, gated to `(hover: hover)`) — that
   is what keeps this from firing anywhere on the page or on a touch
   device. Dragging still lights it up unconditionally, touch included,
   since a drag already means the reader is actively turning the page. */
.flipbook.is-dragging .flipbook__page.is-current > picture::after {
  opacity: 1;
  transform: scale(1) rotate(0deg) translate(-2px, 2px);
}

/* keyboard users get the same hint when the stage itself is focused —
   the stage is not natively focusable, but if JS makes it so (e.g. to
   support arrow-key turning) this covers it without extra markup. */
.flipbook__stage:focus-within .flipbook__page.is-current > picture::after {
  opacity: 1;
  transform: scale(1) rotate(0deg) translate(-2px, 2px);
}

/* ---------- desktop: two-page spread ---------- */
/* 901px matches the breakpoint style.css already uses everywhere else.
   Below it the book is a single page (see docs/flipbook-design.md for why:
   a 50%-wide leaf under ~450px is too narrow to read a film still). Above
   it, pages widen to a spread and a spine gutter appears at the fold. */
@media (min-width: 901px) {
  .flipbook__stage {
    aspect-ratio: calc(2 * (3 / 4));  /* two pages, same page ratio, side by side */
  }

  .flipbook__page { width: 50%; left: 50%; }

  .flipbook__stage::before {
    opacity: 1;
    background:
      linear-gradient(to right,
        transparent calc(50% - 26px),
        rgba(0, 0, 0, .5) calc(50% - 2px),
        rgba(0, 0, 0, .65) 50%,
        rgba(0, 0, 0, .5) calc(50% + 2px),
        transparent calc(50% + 26px)
      );
  }
}

/* ---------- controls ---------- */

.flipbook__ui {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  margin-top: 24px;
}

.flipbook__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--gold);
  border-radius: 50%;
  color: var(--gold);
  cursor: pointer;
  transition: background .18s ease, color .18s ease, border-color .18s ease,
              transform .18s ease;
}

.flipbook__btn svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

.flipbook__btn:hover {
  background: var(--gold);
  color: #000;
}

.flipbook__btn:active { transform: scale(.94); }

.flipbook__btn:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.flipbook__btn[disabled] {
  opacity: .3;
  border-color: var(--grey-600);
  color: var(--grey-600);
  cursor: not-allowed;
  background: transparent;
  transform: none;
}

.flipbook__counter {
  font-family: var(--f-label);
  font-size: 12px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--grey);
  font-variant-numeric: tabular-nums;
  min-width: 64px;
  text-align: center;
}

.flipbook__i { color: var(--gold); }

/* ---------- pre-boot: static first page, no 3D, nothing to mis-click ---------- */

.flipbook:not(.is-ready) .flipbook__stage { perspective: none; }

.flipbook:not(.is-ready) .flipbook__page {
  display: none;
  position: static;
  transform: none;
  box-shadow: none;
}

.flipbook:not(.is-ready) .flipbook__page::before,
.flipbook:not(.is-ready) .flipbook__page::after,
.flipbook:not(.is-ready) .flipbook__page > picture::after {
  content: none;
}

.flipbook:not(.is-ready) .flipbook__page[data-index="0"] {
  display: block;
  width: 100%;
  height: 100%;
}

.flipbook:not(.is-ready) .flipbook__btn { pointer-events: none; opacity: .35; }

/* ---------- reduced motion: crossfade, no 3D ---------- */

/* Per the JS: under reduced motion it never adds is-turning-fwd/back, never
   sets --turn, and never initiates a drag — it just snaps is-current /
   is-prev / is-next straight onto the next page with no animation classes
   at all. So this path can't key off --turn or the turning classes; the
   crossfade has to come from CSS alone, purely as a side effect of the
   ordinary opacity transition below firing whenever JS reassigns which
   page carries is-current. */
@media (prefers-reduced-motion: reduce) {
  .flipbook__stage { perspective: none; }

  .flipbook__page {
    position: absolute;
    inset: 0;
    transform: none !important;
    transform-style: flat;
    box-shadow: none !important;
    transition: opacity .4s ease;
  }

  .flipbook__page::before,
  .flipbook__page::after,
  .flipbook__page > picture::before {
    content: none;
  }

  .flipbook__page.is-prev,
  .flipbook__page.is-next { opacity: 0; z-index: 1; pointer-events: none; }
  .flipbook__page.is-current { opacity: 1; z-index: 2; }

  /* the corner-peel is still a legitimate, motion-free hover/focus hint —
     fade it, don't fold/scale it. */
  .flipbook__page.is-current > picture::after {
    transition: opacity .2s ease;
    transform: none;
  }
  .flipbook__page.is-current > picture::after:hover,
  .flipbook.is-dragging .flipbook__page.is-current > picture::after,
  .flipbook__stage:focus-within .flipbook__page.is-current > picture::after {
    transform: none;
  }

  .flipbook__btn,
  .flipbook__btn:active { transition: background-color .18s ease, color .18s ease, border-color .18s ease; transform: none; }
}

/* On the very first page there is no .is-prev, so the left half of the spread
   sat empty and the book looked broken. Shift the spread so the lone page
   centres, then slide back once a left-hand page exists. */
@media (min-width: 901px) {
}

@media (prefers-reduced-motion: reduce) {
  .flipbook__stage { transition: none; }
}

/* ---------- the book is the page, so give it the stage ---------- */
/* Previously it sat small between two blocks of placeholder text with a
   duplicate hero above it. Now it is the only thing on the page. */

.film-sheet .flipbook {
  margin: 42px 0 56px;
}

@media (min-width: 901px) {
  .film-sheet .flipbook__stage {
    /* fill the width of the container and stand tall in the viewport */
    min-height: min(62vh, 620px);
  }

  .film-sheet .flipbook__page img {
    max-height: min(62vh, 620px);
  }

  /* first page has no left-hand leaf, so centre it rather than
     leaving half the spread black */
}

.film-sheet .flipbook__ui { margin-top: 26px; }

@media (prefers-reduced-motion: reduce) {
  .film-sheet .flipbook__stage { transition: none; }
}

/* ---------- contact sheet + lightbox ---------- */
/* A photographic contact sheet: every frame visible at once, numbered, click
   to enlarge. Chosen over a page-turn so a producer can scan the whole set
   in one glance rather than clicking through it. */

.sheet-head { padding: 46px 0 8px; }

.sheet-head .kicker {
  font-family: var(--f-label);
  font-size: 12px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--grey);
}

.sheet-head h1 {
  font-family: var(--f-title-black);
  font-size: var(--fs-title-uranium, clamp(34px, 5vw, 62px));
  line-height: 1.02;
  color: var(--white);
  margin-top: 10px;
}

.sheet-head .count {
  font-family: var(--f-label);
  font-size: 13px;
  letter-spacing: 2px;
  color: var(--grey);
  margin-top: 14px;
}


/* ---------- give the book a body ---------- */
/* The turn was failing because there was no page to turn: a bare image on
   black has no edge, no thickness and no shadow. Each still is now mounted
   like a print, the deck shows the stack of leaves underneath, and the whole
   thing sits on a surface. */

.flipbook__deck { position: relative; }

@media (min-width: 901px) {
  .film-sheet .flipbook__deck {
    max-width: 860px;
    margin: 0 auto;
    padding: 0 0 6px;
  }

  /* the stack of pages still to come, peeking out under the current leaf */
  .film-sheet .flipbook__deck::before,
  .film-sheet .flipbook__deck::after {
    content: '';
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 0;
    height: 14px;
    border-radius: 0 0 3px 3px;
    background: #15150f;
    box-shadow: 0 8px 22px rgba(0, 0, 0, .85);
  }

  .film-sheet .flipbook__deck::after {
    left: 7px;
    right: 7px;
    bottom: 5px;
    background: #1d1d15;
  }

  .film-sheet .flipbook__stage { position: relative; z-index: 2; }
}

/* the mounted print itself */
.leaf {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #141410;
  border: 1px solid #2a2a20;
  padding: 18px 18px 0;
  box-shadow:
    0 2px 4px rgba(0, 0, 0, .6),
    0 18px 40px rgba(0, 0, 0, .75);
}

.leaf__win {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  place-items: center;
  background: #000;
  overflow: hidden;
}

.leaf__win picture { display: block; width: 100%; height: 100%; }

.leaf__win img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

/* caption strip along the foot of the mount, like a proof print */
.leaf__cap {
  flex: 0 0 auto;
  font-family: var(--f-label);
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--grey);
  padding: 13px 2px 15px;
  display: flex;
  gap: 12px;
  align-items: baseline;
}

.leaf__no { color: var(--gold); font-weight: 700; }

@media (max-width: 900px) {
  .leaf { padding: 10px 10px 0; }
  .leaf__cap { font-size: 10px; letter-spacing: 2px; padding: 9px 0 11px; }
}

/* ---------- landscape book: pages turn right-to-left across the spine ---------- */

@media (min-width: 901px) {
  .film-sheet .flipbook__deck {
    max-width: 1060px;              /* landscape: wider than tall */
    margin: 0 auto;
  }

  .film-sheet .flipbook__stage {
    aspect-ratio: 16 / 9;           /* the whole open book is landscape */
    min-height: 0;
    max-width: none;
    transform: none;
  }

  /* first page has no left leaf yet, so shift the closed book to centre */

  /* slower, so the turn is legible as paper moving rather than a swap */
  .film-sheet .flipbook__page,
  .film-sheet .flipbook__page.is-turning-fwd,
  .film-sheet .flipbook__page.is-turning-back {
    transition-duration: 1.05s;
  }

  /* the turning leaf must sit above both resting pages for its whole sweep */
  .film-sheet .flipbook__page.is-turning-fwd,
  .film-sheet .flipbook__page.is-turning-back { z-index: 9; }

  /* a lit edge on the leading edge of the page catches the eye mid-turn */
  .film-sheet .flipbook__page.is-turning-fwd .leaf,
  .film-sheet .flipbook__page.is-turning-back .leaf {
    box-shadow:
      0 2px 4px rgba(0, 0, 0, .6),
      -18px 24px 60px rgba(0, 0, 0, .9),
      inset 2px 0 0 rgba(255, 255, 255, .16);
  }

  .film-sheet .leaf { padding: 14px 14px 0; }
  .film-sheet .leaf__cap { padding: 10px 2px 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .film-sheet .flipbook__page { transition-duration: .01ms; }
}

/* The .leaf mount sits between the page and the image, so the original
   backface treatment no longer wraps the artwork: the settled left page was
   rendering its FRONT face mirrored (the caption literally read backwards).
   Counter-rotate the mount so the left leaf reads correctly, which is also
   what a photo book's left page should show - the previous plate. */
.flipbook__page.is-prev .leaf { transform: rotateY(180deg); }

/* keep the mount facing the reader through a drag, where --turn drives the
   parent past 90deg */
.flipbook.is-dragging .flipbook__page.is-prev .leaf { transform: rotateY(180deg); }

/* Soul & Sex: the book sits after her prose, so it needs its own heading
   treatment and a little more air above it. */
.sas-book {
  border-top: 1px solid var(--line);
  margin-top: 60px;
  padding-top: 42px;
}

.sheet-head__h2 {
  font-family: var(--f-heading);
  font-weight: 600;
  font-size: clamp(24px, 2.6vw, 36px);
  color: var(--white);
  letter-spacing: .5px;
}

.sas-book .count { margin-bottom: 8px; }

/* ---------- quad book: her real designed pages (East of Crenshaw) ---------- */
/* Scoped to .quad-book on the figure/container so the other books (16/9
   stills, 3/4 portrait) are untouched. Her plates are landscape print pages,
   792 x 612pt = 1.294 ratio — not the 16/9 the base book assumes. */

.quad-book {
  /* client's real accent, confirmed from her design PDF — used ONLY inside
     this book. The site-wide gold (--gold) is left exactly as-is; swapping
     the global accent is a client-facing decision that hasn't been made
     yet, so this token stays local to .quad-book. */
  --client-red: #c00000;
}

@media (min-width: 901px) {
  /* override the 16/9 landscape-book aspect-ratio set further up in this
     file for this book only, so her true page proportion renders complete,
     never letterboxed or stretched. */
  .quad-book.film-sheet .flipbook__stage {
    /* Two of her landscape pages sit side by side, so the OPEN BOOK is twice
       her page ratio. Setting the stage to 1.294 made each half portrait and
       letterboxed her layout in black bands. 2 x 1.294 = 2.588. */
    aspect-ratio: 2.588;
  }
}

/* the plates already carry their own black background baked in — let the
   image fill the leaf flush instead of floating inside the mount's frame */
.quad-book .leaf {
  padding: 0;
}

.quad-book .leaf__cap {
  padding-left: 14px;
  padding-right: 14px;
}

@media (min-width: 901px) {
  .quad-book.film-sheet .leaf { padding: 0; }
  .quad-book.film-sheet .leaf__cap { padding-left: 14px; padding-right: 14px; }
}

/* whole designed page must show complete — never crop her layout */
.quad-book .leaf__win img { object-fit: contain; }

/* her red for the caption number, scoped to this book only */
.quad-book .leaf__no { color: var(--client-red); }

/* ---------- leaf__text: her real words, visually hidden but present ---------- */
/* Standard "visually-hidden" clip technique — NOT display:none, NOT
   visibility:hidden, NOT aria-hidden. Those three all remove content from
   the accessibility tree and/or make search-engine crawlers treat it as
   suppressed content. This keeps the text a real, laid-out, 1px x 1px box
   that screen readers still announce in full and crawlers still index,
   while it stays visually invisible behind the plate image. */
.quad-book .leaf__text {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- bigger book, better turn ---------- */

@media (min-width: 901px) {
  /* Break the book out of the 1240px text container so it can use the
     screen. Capped by height too, so a short window never clips it. */
  .quad-book .flipbook__deck {
    /* Break out of the 1240px text column, centred on the viewport. A width
       is resolved ONCE into a variable, then the negative margin is derived
       from it - setting margin-left:50% first shrank the available width and
       made min() pick a much smaller number. Height-capped so a short
       window never clips the spread. */
    --quad-w: min(1560px, 94vw, calc((100vh - 320px) * 2.588));
    width: var(--quad-w);
    max-width: none;
    margin-left: calc((100% - var(--quad-w)) / 2);
  }

  .quad-book .flipbook__stage { min-height: 0; }

  /* A real page lifts off the spine as it swings rather than pivoting flat,
     so the leaf is pushed toward the reader through the middle of the turn.
     A deeper perspective makes that arc read. */
  .quad-book .flipbook { --fb-perspective: 2200px; }

  .quad-book .flipbook__page.is-turning-fwd,
  .quad-book .flipbook__page.is-turning-back {
    transition-duration: .92s;
    /* slow lift, quick sweep, long settle - paper has mass */
    transition-timing-function: cubic-bezier(.38, .01, .2, 1);
  }

  /* the leaf catches light as it comes off the spine and loses it as it lands */
  .quad-book .flipbook__page.is-turning-fwd .leaf,
  .quad-book .flipbook__page.is-turning-back .leaf {
    animation: quad-lift .92s cubic-bezier(.38, .01, .2, 1);
  }

  @keyframes quad-lift {
    0%   { box-shadow: 0 2px 4px rgba(0,0,0,.6), 0 14px 30px rgba(0,0,0,.7); }
    45%  { box-shadow: -30px 26px 90px rgba(0,0,0,.95),
                       inset 3px 0 0 rgba(255,255,255,.22); }
    100% { box-shadow: 0 2px 4px rgba(0,0,0,.6), 0 14px 30px rgba(0,0,0,.7); }
  }

  /* the spine gutter deepens while a page is in flight */
  .quad-book .flipbook.is-turning .flipbook__stage::before { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .quad-book .flipbook__page.is-turning-fwd .leaf,
  .quad-book .flipbook__page.is-turning-back .leaf { animation: none; }
  .quad-book .flipbook__page { transition-duration: .01ms; }
}

/* ---------- give the turning leaf a real back ---------- */
/* The rotation lives on .flipbook__page but the artwork lives on .leaf inside
   it, so past 90deg the leaf kept facing us and rendered MIRRORED - mid-turn
   frames literally read "WAHSNERC FO TSAE". Hide the leaf's own back face and
   put a paper panel behind it, so turning past 90deg reveals the back of the
   sheet the way a real page does. */

.quad-book .leaf {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  position: relative;
}

/* the reverse of the sheet */
.quad-book .leaf::after {
  content: '';
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  background:
    linear-gradient(100deg, #0d0d0a 0%, #17170f 45%, #0b0b08 100%);
  border: 1px solid #23231a;
  pointer-events: none;
}

/* the settled left page is counter-rotated, so its front faces the reader
   again - keep its back panel behind it, not over it */
.quad-book .flipbook__page.is-prev .leaf::after { transform: rotateY(180deg); }

/* The settled left page is counter-rotated 180deg so it reads correctly, which
   means its OWN back face now points at the reader and the hidden-backface
   rule blanked it. It is already facing us, so it needs no hiding. */
.quad-book .flipbook__page.is-prev .leaf {
  backface-visibility: visible;
  -webkit-backface-visibility: visible;
}

.quad-book .flipbook__page.is-prev .leaf::after { display: none; }

/* ---------- per-film page ratios and accents ---------- */
/* Her three decks are NOT the same shape. East of Crenshaw is 792x612pt
   (1.294); Uranium and Soul & Sex are 1224x792pt (1.545). An open book is
   twice the page ratio, so each needs its own stage aspect or her layout
   letterboxes. Driven off one variable per book. */

.quad-book { --page-ratio: 1.294; }              /* East of Crenshaw */
.uranium-quad { --page-ratio: 1.545; }
.sas-quad-book { --page-ratio: 1.545; }

@media (min-width: 901px) {
  .quad-book.film-sheet .flipbook__stage {
    aspect-ratio: calc(var(--page-ratio) * 2);
  }

  .quad-book .flipbook__deck {
    --quad-w: min(1560px, 94vw, calc((100vh - 320px) * var(--page-ratio) * 2));
  }
}

/* Each film carries its own accent, taken from her own artwork:
   East of Crenshaw #c00000, Soul & Sex #ff0000, Uranium #00b050 green.
   Her gold #ffc000 is the tagline colour across all three - so the site's
   existing gold was NOT wrong, it just was not the whole palette. */
.uranium-quad { --client-red: #00b050; }
.sas-quad-book { --client-red: #ff0000; }

/* the Portuguese deck sits below the English one on the same page */
.deck-pt {
  border-top: 1px solid var(--line);
  margin-top: 70px;
  padding-top: 44px;
}

.deck-pt .sheet-head { padding-top: 0; }

/* ---------- the book does not move ---------- */
/* The stage used to translate -25% whenever there was no left-hand page, so
   the WHOLE BOOK slid sideways on the first turn and slid back on the way
   home. A book does not move when you turn a page - only the leaf does. */

.flipbook__stage { transform: none !important; transition: none !important; }

/* With the book fixed, page one sits on the right leaf exactly as a closed
   book's cover does. Give the empty left leaf an inside-cover face so it
   reads as board, not as a hole you can see through. */
@media (min-width: 901px) {
  .quad-book .flipbook__stage::after {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0; width: 50%;
    z-index: 0;
    background: linear-gradient(100deg, #0a0a07 0%, #131310 60%, #080806 100%);
    border-right: 1px solid #1c1c14;
    pointer-events: none;
  }

  /* once a real left-hand page exists it covers the board */
  .quad-book .flipbook__page.is-prev { z-index: 1; }
}

/* The deck centres itself with a negative margin derived from 100% of its
   PARENT. That parent was 900px while the deck wanted 1504px, so the book
   hung 82px off the left edge. Let the figure fill the column first. */
@media (min-width: 901px) {
  .quad-book .flipbook {
    width: 100%;
    max-width: none;
    margin-left: 0;
    margin-right: 0;
  }

  .quad-book .flipbook__stage { max-width: none; }
}

/* ================================================================
   thumbnail strip / fullscreen / real back face / deck thickness /
   corner-peel hotspot — added on top of the working page-turn above.
   Selectors expected from the markup another agent is adding:
     .flipbook__thumbs                 <ol>, sits below .flipbook__ui
     .flipbook__thumb                  <button>, one per page
     .flipbook__thumb.is-active        current page's thumb
     .flipbook.is-fullscreen           JS toggles this on .flipbook
     .flipbook__page > .leaf-back      per-page back-of-sheet element,
                                        JS sets --back-image on it
   JS-driven custom props consumed here: --progress (0..1, on .flipbook),
   --page-count (on .flipbook, read but not required by the thickness
   maths below), --back-image (per .leaf-back, during a turn).
   ================================================================ */

/* ---------- 1. thumbnail strip ---------- */
/* one scrollable row of small plates so a viewer can jump straight to a
   page. Centred while it fits, scrolls (not wraps) once it doesn't — a
   second row would compete with the book for vertical space. */
.flipbook__thumbs {
  display: flex;
  gap: 8px;
  list-style: none;
  overflow-x: auto;
  overflow-y: hidden;
  justify-content: flex-start;
  max-width: 100%;
  margin: 18px auto 0;
  padding: 4px 2px 10px;
  scrollbar-width: thin;
  scrollbar-color: var(--grey-600) transparent;
}

@media (min-width: 901px) {
  /* once the row is short enough to fit, centre it under the book */
  .flipbook__thumbs { justify-content: center; }
}

.flipbook__thumb {
  flex: 0 0 auto;
  width: 48px;
  /* falls back through the per-book ratio to the base single-page ratio,
     same chain the stage itself uses, so a thumb is never a stretched or
     cropped version of its plate */
  aspect-ratio: var(--page-ratio, var(--fb-page-ratio, 3 / 4));
  padding: 0;
  border: 1px solid var(--line);
  background: #000; /* letterbox for any thumb whose plate doesn't fully fill it */
  overflow: hidden;
  cursor: pointer;
  opacity: .55;
  transition: opacity .18s ease, border-color .18s ease, box-shadow .18s ease;
}

.flipbook__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

.flipbook__thumb:hover { opacity: .85; }

.flipbook__thumb:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  opacity: 1;
}

/* distinct per-book accent, same fallback-to-gold pattern as .leaf__no so a
   book that hasn't set --client-red (the base, non-quad books) still gets a
   visible active state instead of an unset custom property. */
.flipbook__thumb.is-active {
  opacity: 1;
  border-color: var(--client-red, var(--gold));
  box-shadow: 0 0 0 1px var(--client-red, var(--gold));
}

@media (prefers-reduced-motion: reduce) {
  .flipbook__thumb { transition: none; }
}

/* fullscreen gives the book the whole viewport; the strip would either
   shrink the book to make room or float awkwardly over it, so it steps
   aside there rather than competing for the same space. */
.flipbook.is-fullscreen .flipbook__thumbs { display: none; }

/* ---------- 2. fullscreen layout ---------- */
/* JS adds is-fullscreen when the Fullscreen API is active. The deck/stage
   sizing rules above all size against the TEXT COLUMN (max-width: 900/
   1560px, or 100% of a parent that is itself column-width) — none of that
   applies once the flipbook IS the viewport, so this recomputes against
   100vh/100vw instead. Deliberately does NOT touch .flipbook__stage's
   transform (still `none !important`, see below) — only width/height. */
.flipbook.is-fullscreen {
  max-width: none;
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--bg);
}

.flipbook.is-fullscreen .flipbook__deck {
  width: 100%;
  max-width: none;
  margin: 0;
  display: flex;
  justify-content: center;
}

.flipbook.is-fullscreen .flipbook__stage {
  /* pin height to the space left after the controls, leave width auto —
     `aspect-ratio` (already resolved per book by the rules earlier in this
     file: --page-ratio * 2 for the quad books, the 16/9 or --fb-page-ratio
     literals for the others) derives width FROM that height natively, so
     her exact page ratio holds with no duplicated ratio maths here and no
     risk of stretching or cropping a plate. max-width is a safety clamp
     for the rare very-tall/very-narrow viewport where the height-derived
     width would otherwise overrun the screen edge. */
  width: auto;
  height: calc(100vh - 160px);
  max-width: 96vw;
  max-height: calc(100vh - 160px);
  min-height: 0;
  margin: 0 auto;
}

.flipbook.is-fullscreen .flipbook__ui {
  flex: 0 0 auto;
  margin-top: 18px;
}

@media (max-width: 900px) {
  .flipbook.is-fullscreen .flipbook__stage {
    height: calc(100vh - 140px);
    max-height: calc(100vh - 140px);
  }
}

/* ---------- 3. real back face ---------- */
/* .leaf-back is a real element (not a pseudo — every ::before/::after slot
   on .flipbook__page and > picture is already spoken for above), sitting
   alongside .leaf inside each .flipbook__page. Same geometry trick as the
   existing .flipbook__page::after paper-back: pre-rotated 180deg so that
   at the page's resting transform (0deg) its net rotation is 180 — facing
   away from the viewer, and backface-visibility: hidden means a face
   pointed away renders nothing at all. That is what keeps it invisible at
   rest. Once the page turns toward -180deg (mid-turn, dragging, or
   is-turning-fwd's endpoint) net rotation approaches 0 and the face comes
   into view the right way round — never mirrored, because it's a true
   front face at that point, not a flipped back. */
.flipbook__page .leaf-back {
  position: absolute;
  inset: 0;
  z-index: 3; /* level with the existing paper-back pseudo it sits next to */
  transform: rotateY(180deg);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  background-color: var(--grey-300); /* neutral paper fallback before --back-image is set */
  background-image: var(--back-image, none);
  background-size: cover;
  background-position: center;
  pointer-events: none;
}

/* darken/desaturate so the mounted still reads as the REVERSE of a printed
   sheet — a shadowed paper tone over the image — rather than a second
   full-brightness photo staring back through the page. */
.flipbook__page .leaf-back::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(8, 8, 6, .6); /* neutral board shade, not a brand colour */
  mix-blend-mode: multiply;
}

/* once a page has settled into is-prev its FRONT (the previous plate,
   already handled by .leaf's own counter-rotation above) is what should be
   showing, not this page's own back-of-sheet — otherwise the two would sit
   flush at the same net rotation and fight for the same pixels. Matches
   the existing `.leaf::after { display: none; }` pattern used for the
   same reason in the quad books. */
.flipbook__page.is-prev .leaf-back { display: none; }

/* ---------- 4. deck thickness driven by progress ---------- */
/* the two fixed slivers under the deck (.flipbook__deck::before/::after,
   defined above) become a live read on how far into the book you are:
   ::before is the stack still ahead (thins as --progress rises toward 1),
   ::after is the stack already turned (thickens the same amount). Subtle
   by design — a few px of height change read peripherally, not as a
   flashy meter. --page-count is available but not needed for this: a
   continuous 0..1 progress value already gives a smooth read regardless
   of how many leaves are in a given book. */
@media (min-width: 901px) {
  .film-sheet .flipbook__deck::before {
    height: calc(4px + (1 - var(--progress, 0)) * 14px);
    transition: height .3s ease;
  }

  .film-sheet .flipbook__deck::after {
    height: calc(3px + var(--progress, 0) * 14px);
    transition: height .3s ease;
  }
}

@media (prefers-reduced-motion: reduce) {
  .film-sheet .flipbook__deck::before,
  .film-sheet .flipbook__deck::after {
    transition: none;
  }
}

/* ---------- 5. corner-peel hotspot ---------- */
/* Refines the corner-peel triangle already defined above (picture::after)
   into an actual proximity affordance: rather than the whole current page
   triggering it on :hover, the triangle itself becomes the hoverable
   region. clip-path already shapes it to the 42px corner wedge, and
   clip-path also constrains hit-testing to that visible shape — so hover
   only fires when the pointer is genuinely near the outer edge, not
   anywhere on the page. pointer-events stays `none` outside the
   `(hover: hover)` block, which is what keeps it from ever firing on
   touch (a touch device has no real hover to satisfy the media query, and
   the element is non-interactive there regardless). */
@media (hover: hover) {
  .flipbook__page.is-current > picture::after {
    pointer-events: auto;
  }

  .flipbook__page.is-current > picture::after:hover {
    opacity: 1;
    transform: scale(1) rotate(0deg) translate(-2px, 2px);
  }
}

/* The stage sized itself against 100% of the deck, whose own height comes
   FROM the stage - a circular dependency that resolved to zero, so the book
   vanished in fullscreen. Height now comes from the viewport alone and the
   deck simply stretches to hold it. */
.flipbook.is-fullscreen .flipbook__deck {
  height: calc(100vh - 160px);
  align-items: center;
}

.flipbook.is-fullscreen .flipbook__stage {
  height: calc(100vh - 160px);
  max-height: calc(100vh - 160px);
  max-width: 96vw;
}

@media (max-width: 900px) {
  .flipbook.is-fullscreen .flipbook__deck,
  .flipbook.is-fullscreen .flipbook__stage {
    height: calc(100vh - 130px);
    max-height: calc(100vh - 130px);
  }
}
