/* ==========================================================================
   Corafter — Book Pages (Phase 19)
   One reusable scroll-animation system: 3D "book page" section transitions on
   desktop, natural scrolling with light reveals on touch / small screens, and
   no motion at all for prefers-reduced-motion.

   Pairs with assets/js/book-pages.js. Loaded LAST in includes/header.php so it
   can supersede the older Phase 7/9/11/12 stacking rules.

   Mode classes (set on <html> by the inline snippet in header.php and kept in
   sync by book-pages.js):
     .bp-js        JavaScript is available (reveal start-states may apply)
     .bp-book      desktop: sticky stack + 3D page turns
     .bp-lite      touch / narrow: natural flow + light reveals
     .bp-reduced   prefers-reduced-motion: natural flow, nothing animated
     .bp-ready     first measurement finished; sticky stack may engage
     .bp-measure   transient (same task) while geometry is measured
     .bp-failsafe  JS never became ready; everything is forced visible

   Per-section opt-outs (HTML attributes, optional):
     data-book-skip   leave the section completely alone
     data-book-flow   keep natural flow (never pinned / never covered)
   ========================================================================== */

:root {
  --bp-paper: #fff;
  --bp-shadow-rgb: 4, 14, 40;
  --bp-ease: cubic-bezier(.2, .72, .2, 1);
  --bp-reveal-duration: 640ms;
}

/* --------------------------------------------------------------------------
   0. Preserved surface
   The retired Phase 9/11 script tagged top-level sections .page-turn-section and
   the Phase 9/11/12 CSS then gave them a white sheet, border-box sizing and
   clipped overflow. Those visual rules are carried over verbatim (same scope:
   direct children of <main>) so every existing page looks exactly as before.
   -------------------------------------------------------------------------- */
main#main-content > .bp-item {
  box-sizing: border-box;
  overflow: clip;
}

main#main-content > .bp-item:not(.page-hero):not(.portfolio-hero):not(.service-hero):not(.case-hero):not(.article-hero) {
  background-color: #fff;
}

/* --------------------------------------------------------------------------
   1. Reveal start-state (all non-reduced modes)
   Hidden only while the element has not yet been revealed. The reveal itself
   is played by the Web Animations API in book-pages.js, so it never fights the
   hover/transition rules the components already have.
   Keep this list in sync with REVEAL_SELECTOR in book-pages.js.
   -------------------------------------------------------------------------- */
html.bp-js:not(.bp-reduced):not(.bp-failsafe) main#main-content :is(
  .hero-copy,
  .page-hero .container,
  .portfolio-hero .container,
  .service-hero-copy,
  .section-heading,
  .story-grid,
  .split-section,
  .detail-grid,
  .service-feature-card,
  .service-visual-card,
  .contact-list > div,
  .form-card,
  .faq-item,
  .stats-grid > div,
  .rd-poster,
  .process-line > div,
  .process-timeline-v2 article
):not(.bp-in) {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
}

/* --------------------------------------------------------------------------
   2. Fx layer (injected by JS into each stacked section)
   Only visible in book mode. Everything here is opacity/transform driven so it
   stays on the compositor.
   -------------------------------------------------------------------------- */
.bp-fx {
  display: none;
}

html.bp-book .bp-fx {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 100;
  overflow: hidden;
  pointer-events: none;
}

/* Uniform darkening of the page that is being covered. Anchored to the bottom
   so that for very tall sections it tracks the pinned (visible) slice. */
.bp-fx-dim {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: min(100%, 100svh);
  background: linear-gradient(180deg, rgba(var(--bp-shadow-rgb), .92), rgba(var(--bp-shadow-rgb), 1));
  opacity: 0;
  will-change: opacity;
}

/* Soft shadow cast by the incoming page onto the page beneath it. */
.bp-fx-cast {
  position: absolute;
  left: -4%;
  right: -4%;
  top: 0;
  height: 170px;
  background:
    radial-gradient(120% 100% at 50% 100%, rgba(var(--bp-shadow-rgb), .55) 0%, rgba(var(--bp-shadow-rgb), .22) 38%, rgba(var(--bp-shadow-rgb), 0) 72%);
  opacity: 0;
  will-change: transform, opacity;
}

/* Paper curl: the leading edge of the incoming page is shaded like a bent
   sheet (dark crease fading away), with a thin lit lip along the very edge. */
.bp-fx-curl {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 190px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .55) 0, rgba(255, 255, 255, 0) 3px),
    radial-gradient(130% 100% at 50% 0%, rgba(var(--bp-shadow-rgb), .34) 0%, rgba(var(--bp-shadow-rgb), .12) 46%, rgba(var(--bp-shadow-rgb), 0) 78%);
  opacity: 0;
}

/* --------------------------------------------------------------------------
   3. Book mode: sticky stack
   Each section is sticky inside the stack root (main, .service-page or
   .home-scroll-stack). Later sections are opaque and sit above earlier ones, so
   they slide over the pinned page. --bp-top is measured by JS:
     taller than viewport -> pinned by its BOTTOM edge  (top = vh - height)
     shorter than viewport -> pinned at the top          (top = 0)
   so a section's content is never trapped behind its own pin.
   -------------------------------------------------------------------------- */
html.bp-book.bp-ready main#main-content .bp-item {
  position: sticky !important;
  top: var(--bp-top, 0px) !important;
  z-index: var(--bp-z, 1) !important;
  isolation: isolate;
}

/* Fills any transparent section so a covered page never shows through. */

html.bp-book.bp-ready main#main-content .bp-item.bp-needs-paper {
  background-color: var(--bp-paper);
}

/* Forms and opted-out sections stay in natural flow (never pinned/covered). */
html.bp-book.bp-ready main#main-content .bp-item.bp-flow {
  position: relative !important;
  top: auto !important;
}

/* Stable compositor layer for pages that can transform. Kept on permanently so
   layers are never created/destroyed mid-scroll (that shows up as white flashes). */
html.bp-book.bp-ready main#main-content .bp-item.bp-layer {
  will-change: transform;
}

/* `overflow: hidden` on an ancestor turns it into the sticky scroll container,
   which silently disables the stack. `clip` keeps the same visual clipping
   without creating a scroll container. */
html.bp-book.bp-ready main#main-content :is(.service-page, .home-scroll-stack, .bp-stack-root) {
  overflow: clip !important;
}

/* Transient measuring state: sections are put in plain flow for a moment so
   their natural positions can be read (restored in the same task). */
html.bp-measure main#main-content .bp-item {
  position: relative !important;
  top: auto !important;
  transform: none !important;
}

/* --------------------------------------------------------------------------
   4. Lite / reduced: natural flow
   Neutralises older sticky rules so small screens and reduced-motion users get
   a plain, fully scrollable page with nothing pinned.
   -------------------------------------------------------------------------- */
html.bp-lite main#main-content .bp-item,
html.bp-reduced main#main-content .bp-item {
  position: relative !important;
  top: auto !important;
  transform: none !important;
}

/* --------------------------------------------------------------------------
   5. Safety nets
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .bp-fx,
  .bp-fx * {
    display: none !important;
  }
}

@media print {
  .bp-fx { display: none !important; }
  main#main-content .bp-item {
    position: relative !important;
    top: auto !important;
    transform: none !important;
  }
  html.bp-js main#main-content :is(
    .hero-copy, .page-hero .container, .portfolio-hero .container, .service-hero-copy,
    .section-heading, .story-grid, .split-section, .detail-grid, .service-feature-card,
    .service-visual-card, .contact-list > div, .form-card, .faq-item, .stats-grid > div,
    .rd-poster, .process-line > div, .process-timeline-v2 article
  ) {
    opacity: 1 !important;
    transform: none !important;
  }
}
