/* ==========================================================================
   CPG PROPERTIES — MOTION
   Entry, scroll and page-transition motion for every module on the site.

   The vocabulary is the one the client asked for, taken from the reference
   site: a soft 0.8s ease for anything that rises into place, a slower 1.6s
   ease for a photograph uncovering itself from its lower edge while the image
   inside it settles from a slight over-scale, and 0.4s for hover.

   Two rules govern everything here.

   1. Nothing is hidden unless the script that reveals it is running. Every
      initial state is scoped to `html.cpg-motion-x`, a class only
      properties-motion.js sets, and the script sets it only after it has an
      IntersectionObserver and the visitor has not asked for reduced motion.
      A script error, an old browser, a printed page or a crawler therefore
      sees the finished page, not an empty one.

   2. It decorates; it never positions. No rule here changes layout, so a
      module's own composition is exactly what it was.
   ========================================================================== */

:root {
  --cpgm-ease: cubic-bezier(.25, .74, .22, .99);
  --cpgm-ease-wipe: cubic-bezier(.55, 0, .1, 1);
  --cpgm-rise: 900ms;
  --cpgm-wipe: 1600ms;
  --cpgm-mask: 1100ms;
}

/* --- Load curtain ---------------------------------------------------------
   The wordmark rises out of the foot of the screen and settles on the header's
   own mark, a rail drawing itself up the left edge behind it. The sheet then
   fades, leaving the page's real wordmark exactly where this one landed.

   Every initial state here lives on the element the inline script un-hides, so
   nothing can be hidden by this unless that script ran.
   -------------------------------------------------------------------------- */
html.cpgm-loading { overflow: hidden; }

.cpgm-load {
  position: fixed;
  inset: 0;
  /* Above the header: the sheet covers the whole page, and the wordmark it
     carries lands on the header's own once it lifts. */
  z-index: calc(var(--cpg-z-overlay, 400) + 10);
  background: var(--cpg-panel-fixed, #16181b);
  transition: opacity 640ms var(--cpgm-ease), transform 640ms var(--cpgm-ease);
}
.cpgm-load[hidden] { display: none; }

.cpgm-load__rail {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 4px;
  background: var(--cpg-bone, #F0EAE2);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform 1150ms var(--cpgm-ease);
}
.cpgm-load.is-running .cpgm-load__rail { transform: scaleY(1); }

/* The box travels; the mark inside it is unmasked by the same movement. */
.cpgm-load__logo {
  position: absolute;
  inset-block-start: var(--cpgm-load-top, 2rem);
  inset-inline-start: var(--cpgm-load-left, 1.5rem);
  overflow: hidden;
  transform: translate3d(0, var(--cpgm-load-travel, 60vh), 0) scale(var(--cpgm-load-scale, 2.4));
  transform-origin: 0 0;
  transition: transform 1200ms var(--cpgm-ease);
  will-change: transform;
}
.cpgm-load.is-running .cpgm-load__logo { transform: translate3d(0, 0, 0) scale(1); }

.cpgm-load__logo-inner {
  display: block;
  transform: translate3d(0, 108%, 0);
  transition: transform 1000ms var(--cpgm-ease) 80ms;
  will-change: transform;
}
.cpgm-load.is-running .cpgm-load__logo-inner { transform: translate3d(0, 0, 0); }

/* The mark reads on the sheet's own ground, whatever the page theme is. */
.cpgm-load .cpg-wordmark { color: #FFFFFF; }
.cpgm-load .cpg-wordmark__mark { color: #FFFFFF; }
.cpgm-load .cpg-wordmark__qualifier { color: rgba(255, 255, 255, .72); }

.cpgm-load.is-done { opacity: 0; transform: translate3d(0, -1.5%, 0); pointer-events: none; }
.cpgm-load.is-done .cpgm-load__logo { opacity: 0; transition: transform 1200ms var(--cpgm-ease), opacity 380ms linear; }

@media (prefers-reduced-motion: reduce) {
  .cpgm-load { display: none !important; }
  html.cpgm-loading { overflow: auto; }
}

/* --- Rise: text, cards, controls ----------------------------------------- */
html.cpg-motion-x [data-cpgm="rise"] {
  opacity: 0;
  transform: translate3d(0, 42px, 0);
  transition:
    opacity var(--cpgm-rise) var(--cpgm-ease) var(--cpgm-delay, 0ms),
    transform var(--cpgm-rise) var(--cpgm-ease) var(--cpgm-delay, 0ms);
  will-change: opacity, transform;
}
html.cpg-motion-x [data-cpgm="rise"].is-inview {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* --- Mask: a heading rising out of its own line ---------------------------
   The signature of the reference the client supplied. No wrapper markup: the
   heading is clipped to its own box and lifted out of it, so a section opens
   with its title stepping into place.
   -------------------------------------------------------------------------- */
html.cpg-motion-x [data-cpgm="mask"] {
  clip-path: inset(-30% -20% 100% -20%);
  transform: translate3d(0, 42%, 0);
  transition:
    clip-path var(--cpgm-mask) var(--cpgm-ease) var(--cpgm-delay, 0ms),
    transform var(--cpgm-mask) var(--cpgm-ease) var(--cpgm-delay, 0ms);
  will-change: clip-path, transform;
}
html.cpg-motion-x [data-cpgm="mask"].is-inview {
  clip-path: inset(-30% -20% -10% -20%);
  transform: none;
  will-change: auto;
}

/* --- Wipe: a photograph uncovering itself from its lower edge -------------- */
/* The frame fades up as a whole rather than being uncovered by a clip: an
   uncovering frame shows its own empty ground for as long as it runs, and the
   client asked for that grey never to be seen. */
html.cpg-motion-x [data-cpgm="wipe"] {
  opacity: 0;
  transition: opacity var(--cpgm-wipe) var(--cpgm-ease-wipe) var(--cpgm-delay, 0ms);
}
html.cpg-motion-x [data-cpgm="wipe"].is-inview { opacity: 1; }
/* The image inside settles out of a slight over-scale as the frame opens. A
   module that animates its own image on hover keeps that hover: this only
   sets the resting scale while the frame is still opening. */
html.cpg-motion-x [data-cpgm="wipe"] > picture > img,
html.cpg-motion-x [data-cpgm="wipe"] > img {
  transform: scale(1.08);
  transition: transform var(--cpgm-wipe) var(--cpgm-ease-wipe) var(--cpgm-delay, 0ms);
}
html.cpg-motion-x [data-cpgm="wipe"].is-inview > picture > img,
html.cpg-motion-x [data-cpgm="wipe"].is-inview > img {
  transform: scale(1);
}

/* --- Rule: a hairline drawing itself across ------------------------------- */
html.cpg-motion-x [data-cpgm="rule"] {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--cpgm-wipe) var(--cpgm-ease-wipe) var(--cpgm-delay, 0ms);
}
html.cpg-motion-x [data-cpgm="rule"].is-inview { transform: scaleX(1); }

/* --- Page transition ------------------------------------------------------
   A single curtain in the brand's own ink, closing over the page as it leaves
   for another. It only ever covers a page that is already on its way out, so
   a stalled navigation cannot leave content hidden behind it, and it never
   takes pointer events, so it cannot swallow a click. Arrival is carried by
   the reveals above instead. */
.cpgm-curtain {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: none;
  background: var(--cpg-ink-surface, #0D0D0C);
  opacity: 0;
  pointer-events: none;
}
html.cpg-motion-x .cpgm-curtain {
  display: block;
  transition: opacity 520ms var(--cpgm-ease);
}
html.cpg-motion-x.is-leaving .cpgm-curtain { opacity: 1; }

/* --- Reduced motion, print ------------------------------------------------
   Belt and braces: the script already refuses to add its root class under
   reduced motion, and these reset anything that somehow slipped through. */
@media (prefers-reduced-motion: reduce) {
  html [data-cpgm] {
    opacity: 1 !important;
    clip-path: none !important;
    transform: none !important;
    transition: none !important;
  }
  html [data-cpgm="wipe"] > picture > img,
  html [data-cpgm="wipe"] > img { transform: none !important; transition: none !important; }
  .cpgm-curtain { display: none !important; }
}

@media print {
  [data-cpgm] { opacity: 1 !important; clip-path: none !important; transform: none !important; }
  .cpgm-curtain { display: none !important; }
}

/* The loading screen's wordmark, larger to match the header's step up. */
.cpgm-load .cpg-wordmark { --cpg-wordmark-size: clamp(2.5rem, 1.6rem + 3.2vw, 4rem); }
