/* ============================================================================
 * BOOKLET — STYLESHEET
 *
 * All styles for the PDF flipbook are scoped under `.booklet` so multiple
 * instances on the same page can coexist without selector collisions. The
 * user provides the container element (any block-level element with explicit
 * width and height); everything inside is built and styled by the booklet
 * JavaScript.
 *
 * Theming knobs are exposed as CSS custom properties — set them either via
 * the JS config (which mirrors them onto the container) or directly in CSS:
 *
 *     .booklet {
 *       --booklet-page-color: #faf6e8;
 *       --booklet-vignette-corner-darkness: 0.6;
 *     }
 *
 * Variables (with defaults):
 *   --booklet-backdrop                  transparent  background of the booklet root
 *   --booklet-page-color                #efece6      page wrapper bg
 *   --booklet-frame-line-alpha          0.063        hairline page-edge inner shadow
 *   --booklet-frame-halo-alpha          0.18           …its halo
 *   --booklet-spine-darkness            0.32         spine seam max-alpha (at the spine)
 *   --booklet-vignette-corner-darkness  0.4          vignette outer-corner alpha
 *   --booklet-vignette-fade-start       40%          vignette inner stop, before darkening
 *   --booklet-loader-fade-ms            300ms        loader fade-out duration
 *
 * Section index:
 *   1. Root container
 *   2. Loader
 *   3. Book (page-flip target)
 *   4. Pages, frames, and blank parity-pads
 *   5. Spine seams
 *   6. Vignette
 *   7. Page-edge band
 * ============================================================================
 */


/* -- 1. Root container ------------------------------------------------------
 * The user-provided container gets the `.booklet` class added on
 * construction. Children are absolutely positioned within it. Box-sizing
 * is normalized so width / height of the container can be set in any
 * units without padding surprises. The container itself is positioned
 * relative so descendants with `position: absolute` are anchored to it.
 *
 * `--book-depth` (no `booklet-` prefix — this one is INTERNAL, set by JS
 * based on page count, and used only by `.booklet .book`'s drop-shadow).
 */
.booklet {
  /* Theming defaults — overridable via JS config or your own CSS. */
  --booklet-backdrop:                 transparent;
  --booklet-page-color:               #efece6;
  --booklet-frame-line-alpha:         0.063;
  --booklet-frame-halo-alpha:         0.18;
  --booklet-spine-darkness:           0.32;
  --booklet-vignette-corner-darkness: 0.4;
  --booklet-vignette-fade-start:      40%;
  --booklet-loader-fade-ms:           300ms;

  position: relative;
  width: 100%;
  height: 100%;
  background: var(--booklet-backdrop);
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  --book-depth: 1;
}
.booklet,
.booklet *, .booklet *::before, .booklet *::after { box-sizing: border-box; }


/* -- 2. Loader --------------------------------------------------------------
 * A 'loading' label centered on top of everything else. Visible only during
 * the first paint while the PDF is fetched and the eager-render of the
 * opening pages happens. Fades out when the booklet becomes ready.
 */
.booklet .loader {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #666;
  font: 14px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.12em;
  pointer-events: none;
  z-index: 10;
  transition: opacity var(--booklet-loader-fade-ms) ease;
}
.booklet .loader.hidden { opacity: 0; }


/* -- 3. Book (page-flip target) ---------------------------------------------
 * The element page-flip operates on. Hidden until the first eager-rendered
 * pages are in place, then made visible. The drop-shadow filter scales
 * with `--book-depth` to give thicker magazines more visual weight; the
 * scaling is sub-linear (sqrt of page count) so 8-page vs. 80-page books
 * differ visibly without the shadow dominating the image.
 *
 * Two stacked drop-shadows: a wide soft shadow for ambient lift, and a
 * tighter near shadow for grounding the book against the backdrop.
 */
.booklet .book {
  visibility: hidden;
  position: relative;
  width: 100%;
  height: 100%;
  filter:
    drop-shadow(0 calc(40px * var(--book-depth)) calc(80px * var(--book-depth)) rgba(0, 0, 0, 0.6))
    drop-shadow(0 calc(8px  * var(--book-depth)) calc(24px * var(--book-depth)) rgba(0, 0, 0, 0.4));
}
.booklet .book.ready { visibility: visible; }


/* -- 4. Pages, frames, and blank parity-pads --------------------------------
 * Each .page wraps an <img> (the rendered PDF bitmap) and a .frame overlay
 * (the hairline edge). The wrapper provides the page background color and
 * clips its own contents.
 *
 * `.stf__item` is the wrapper page-flip itself adds around each page. We
 * give it the lift box-shadow that floats the page above the underlying
 * spread; it can't go on .page directly because page-flip overrides the
 * wrapper's transform / shadow during flips.
 *
 * `.blank` is our own modifier on the parity-pad pages — invisible pages
 * added at the start (and end, if the total would otherwise be odd) so
 * the cover sits 'alone' on the right side of the first spread, like a
 * closed magazine. Page-flip controls the wrapper's background, so we
 * can't suppress it directly; making the .page transparent and hiding
 * the <img>, the .frame, and the spine pseudo-elements is enough — the
 * wrapper has no visible paint of its own.
 *
 * The `.page.blank` specificity is intentional: it has to win against
 * the later-declared `.booklet .book .page img { display: block }` rule.
 *
 * The .frame is rendered ON TOP of the <img> (z-index 3) instead of as
 * a pseudo-element on the wrapper — page-flip's spine pseudos already
 * use ::before/::after on the wrapper, and an inset box-shadow on the
 * wrapper would be occluded by the replaced <img> child anyway. The
 * inset box-shadow has two stops: a hard 1px line for the edge plus a
 * 6px halo so the seam reads even when two light pages overlap mid-curl.
 */
.booklet .book .page {
  background: var(--booklet-page-color);
  overflow: hidden;
}
.booklet .book .stf__item {
  box-shadow:
    0 4px 12px rgba(0, 0, 0, 0.35),
    0 1px 3px  rgba(0, 0, 0, 0.25);
}

/* Parity-pad blanks: render the wrapper with the BACKDROP color (not
 * transparent) so the curl's shadow has a real surface to land on, and
 * so we don't reveal the page-flip-controlled wrapper background. The
 * .page child stays transparent and the <img> / .frame are hidden, so
 * visually the slot reads as continuous backdrop space. */
.booklet .book .stf__item.blank {
  background: var(--booklet-backdrop, #0a0a0a) !important;
  box-shadow: none !important;
}
.booklet .book .stf__item.blank .page { background: transparent; }
.booklet .book .page.blank img,
.booklet .book .page.blank .frame { display: none; }
.booklet .book .stf__item.blank.--left::after,
.booklet .book .stf__item.blank.--right::before { display: none; }

/* Edge-blanking — JS toggles `.edge-blanking` on .book only for cover and
 * back-cover edge turns. Static interior slots are re-skinned as backdrop,
 * while the animated PageFlip wrappers are made transparent so they cannot
 * leak destination-page bitmaps into the curl. */
.booklet .book.edge-blanking
  .stf__item.--simple:not(.cover):not(.back-cover):not(.blank) {
  background: var(--booklet-backdrop, #0a0a0a) !important;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.05),
    0 6px 18px rgba(0, 0, 0, 0.7) !important;
}
.booklet .book.edge-blanking
  .stf__item.--simple:not(.cover):not(.back-cover):not(.blank) .page {
  background: transparent !important;
}
.booklet .book.edge-blanking
  .stf__item.--simple:not(.cover):not(.back-cover):not(.blank) img,
.booklet .book.edge-blanking
  .stf__item.--simple:not(.cover):not(.back-cover):not(.blank) .frame {
  display: none !important;
}
.booklet .book.edge-blanking
  .stf__item.--simple:not(.cover):not(.back-cover):not(.blank)::before,
.booklet .book.edge-blanking
  .stf__item.--simple:not(.cover):not(.back-cover):not(.blank)::after {
  display: none !important;
}
.booklet .book.edge-blanking .stf__item:not(.--simple) {
  background: transparent !important;
}
.booklet .book.edge-blanking .stf__item:not(.--simple) .page {
  background: transparent !important;
}
.booklet .book.edge-blanking .stf__item:not(.--simple) img {
  visibility: hidden !important;
}

/* During a close-to-cover turn PageFlip does not draw the destination cover
 * as a static page. JS positions this clone underneath the transparent curl
 * so the destination face can appear progressively instead of popping in at
 * the end. */
.booklet .book .edge-cover-clone {
  position: absolute;
  display: none;
  overflow: hidden;
  pointer-events: none;
  z-index: 2;
  background: var(--booklet-page-color);
  box-shadow:
    0 4px 12px rgba(0, 0, 0, 0.35),
    0 1px 3px rgba(0, 0, 0, 0.25);
}
.booklet .book .edge-cover-clone.active { display: block; }
.booklet .book .edge-cover-clone img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}

.booklet .book .page .frame {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, var(--booklet-frame-line-alpha)),
    inset 0 0 6px 0 rgba(206, 206, 206, var(--booklet-frame-halo-alpha));
}
.booklet .book .page img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}


/* -- 5. Spine seams ---------------------------------------------------------
 * Pseudo-element on the inner edge (spine side) of each page, suggesting
 * light reflecting off the inside curve of the binding. The gradient
 * runs from a dark band at the spine, through a faint highlight, out to
 * transparent over ~7% of the page width. Sits above the page bitmap
 * (z-index 2) but below the frame (3) so the bottom edge of the seam
 * doesn't crash into the page's hairline frame.
 *
 * The dark stop is parameterized via `--booklet-spine-darkness`. The
 * highlight stops are baked in — they read as a faint paper sheen and
 * users rarely tweak them.
 */
.booklet .book .stf__item.--left::after,
.booklet .book .stf__item.--right::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 7%;
  pointer-events: none;
  z-index: 2;
}
.booklet .book .stf__item.--left::after {
  right: 0;
  background: linear-gradient(
    268deg,
    rgba(0,   0,   0,   var(--booklet-spine-darkness)) 0%,
    rgba(0,   0,   0,   0.14)  10%,
    rgba(0,   0,   0,   0.04)  24%,
    rgba(255, 255, 255, 0.05)  42%,
    rgba(255, 255, 255, 0.018) 70%,
    transparent                100%
  );
}
.booklet .book .stf__item.--right::before {
  left: 0;
  background: linear-gradient(
    92deg,
    rgba(0,   0,   0,   var(--booklet-spine-darkness)) 0%,
    rgba(0,   0,   0,   0.14)  10%,
    rgba(0,   0,   0,   0.04)  24%,
    rgba(255, 255, 255, 0.05)  42%,
    rgba(255, 255, 255, 0.018) 70%,
    transparent                100%
  );
}


/* -- 6. Vignette ------------------------------------------------------------
 * Radial darkening at the corners. Inner stop keeps the central area
 * unaffected; outer corners get tinted. Sits above the book (z-index 5)
 * so it can darken page-edge artifacts and the band's outer ends into
 * shadow.
 *
 * Scoped to the booklet root via `position: absolute` (not `fixed`) so
 * each instance gets its own vignette confined to its own area. For a
 * full-viewport booklet, this looks identical to a viewport-wide
 * vignette; for embedded use, only the booklet darkens.
 */
.booklet .vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse at center,
    transparent          var(--booklet-vignette-fade-start),
    rgba(0, 0, 0, var(--booklet-vignette-corner-darkness)) 100%
  );
  pointer-events: none;
  z-index: 5;
}


/* -- 7. Page-edge band ------------------------------------------------------
 * Vertical hairlines anchored OUTSIDE each page's outer edge — one line
 * per page in the corresponding stack. The left band fills with read
 * pages as the user advances; the right band shrinks accordingly. The
 * band's `width`, `background` (a repeating-linear-gradient producing
 * the hairlines), and `mask-image` (the alpha gradient that fades the
 * outer end into shadow) are all set in JS based on the current count
 * and the side — see `_setEdge` in booklet.js.
 *
 * z-index 4 keeps the band below the vignette so the corner darkening
 * softens the band's outer end naturally — the eye reads it as the
 * stack receding into shadow.
 */
.booklet .edge-left,
.booklet .edge-right {
  position: absolute;
  z-index: 4;
  pointer-events: none;
}
