/* ==========================================================================
   C7 — motion system
   --------------------------------------------------------------------------
   Three rules govern everything here.

   1. Nothing animates a layout property. Every effect below moves opacity,
      transform, filter or clip-path only, so an element arriving can never
      reflow the page around it and cost Cumulative Layout Shift.

   2. Content is visible by default. The hidden state is only applied once the
      script has added `c7-js-ready` to <html>. If the script fails, the page
      reads normally instead of staying blank — an invisible page is a far worse
      failure than an unanimated one.

   3. No two neighbouring bands use the same entrance. The animation is chosen
      per section on the server, so a visitor scrolling the page sees variety
      rather than the same fade repeated eleven times.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Entrance variants
   -------------------------------------------------------------------------- */
.c7-js-ready [data-anim] {
  opacity: 0;
  transition:
    opacity var(--c7-duration-slow) var(--c7-ease-out),
    transform var(--c7-duration-slow) var(--c7-ease-out),
    filter var(--c7-duration-slow) var(--c7-ease-out),
    clip-path var(--c7-duration-slow) var(--c7-ease-out);
  will-change: opacity, transform;
}

.c7-js-ready [data-anim].is-visible {
  opacity: 1;
  transform: none;
  filter: none;
  clip-path: inset(0 0 0 0);
}

/* Rise from below — the workhorse. */
.c7-js-ready [data-anim="rise"] {
  transform: translateY(28px);
}

/* Settle from above, for bands that follow a tall photograph. */
.c7-js-ready [data-anim="settle"] {
  transform: translateY(-22px);
}

/* Enter from the leading edge. */
.c7-js-ready [data-anim="enter-left"] {
  transform: translateX(-42px);
}

.c7-js-ready [data-anim="enter-right"] {
  transform: translateX(42px);
}

/* Grow gently into place — good for imagery. */
.c7-js-ready [data-anim="expand"] {
  transform: scale(0.93);
}

/* Recede: starts slightly large, settles back. Reads as a camera pulling focus. */
.c7-js-ready [data-anim="recede"] {
  transform: scale(1.06);
}

/* Focus: blurred and slightly raised. Used sparingly — filter is the most
   expensive effect here, so it is reserved for one band per page. */
.c7-js-ready [data-anim="focus"] {
  transform: translateY(16px);
  filter: blur(9px);
}

/* Unveil: a wipe from the bottom edge upward. */
.c7-js-ready [data-anim="unveil"] {
  clip-path: inset(100% 0 0 0);
  transform: translateY(12px);
}

/* Sweep: a wipe from the leading edge across. */
.c7-js-ready [data-anim="sweep"] {
  clip-path: inset(0 100% 0 0);
}

/* Tilt: a small perspective lean, for a band that should feel physical. */
.c7-js-ready [data-anim="tilt"] {
  transform: perspective(1200px) rotateX(7deg) translateY(26px);
  transform-origin: 50% 100%;
}

/* Pivot: leans in from the leading edge on the Y axis. */
.c7-js-ready [data-anim="pivot"] {
  transform: perspective(1400px) rotateY(-9deg) translateX(-24px);
  transform-origin: 0% 50%;
}

/* Plain fade, for anything already carrying its own movement. */
.c7-js-ready [data-anim="fade"] {
  transform: none;
}

/* --------------------------------------------------------------------------
   Staggered children
   --------------------------------------------------------------------------
   Applied to a grid or carousel track so its cards arrive in sequence. The
   delay is capped at eight: past that the last card arrives so late it reads as
   a bug rather than an effect.
   -------------------------------------------------------------------------- */
.c7-js-ready [data-stagger] > * {
  opacity: 0;
  transform: translateY(22px) scale(0.985);
  transition:
    opacity var(--c7-duration-slow) var(--c7-ease-out),
    transform var(--c7-duration-slow) var(--c7-ease-out);
}

.c7-js-ready [data-stagger].is-visible > * {
  opacity: 1;
  transform: none;
}

.c7-js-ready [data-stagger].is-visible > *:nth-child(1) { transition-delay: 60ms; }
.c7-js-ready [data-stagger].is-visible > *:nth-child(2) { transition-delay: 130ms; }
.c7-js-ready [data-stagger].is-visible > *:nth-child(3) { transition-delay: 200ms; }
.c7-js-ready [data-stagger].is-visible > *:nth-child(4) { transition-delay: 270ms; }
.c7-js-ready [data-stagger].is-visible > *:nth-child(5) { transition-delay: 340ms; }
.c7-js-ready [data-stagger].is-visible > *:nth-child(6) { transition-delay: 410ms; }
.c7-js-ready [data-stagger].is-visible > *:nth-child(7) { transition-delay: 480ms; }
.c7-js-ready [data-stagger].is-visible > *:nth-child(n + 8) { transition-delay: 540ms; }

/* A stagger that comes in sideways, for carousels. */
.c7-js-ready [data-stagger="slide"] > * {
  transform: translateX(34px);
}

/* A stagger that scales, for icon tiles. */
.c7-js-ready [data-stagger="pop"] > * {
  transform: scale(0.9);
}

.c7-js-ready [data-stagger="pop"].is-visible > * {
  transition-timing-function: var(--c7-ease-spring);
}

/* --------------------------------------------------------------------------
   Hero entrance
   --------------------------------------------------------------------------
   A scripted timeline rather than a scroll trigger: the hero is above the fold,
   so it must play on load. Each line arrives on its own beat.
   -------------------------------------------------------------------------- */
.c7-js-ready .c7-hero [data-hero-step] {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 720ms var(--c7-ease-out),
    transform 720ms var(--c7-ease-out);
}

.c7-hero.is-ready [data-hero-step] {
  opacity: 1;
  transform: none;
}

.c7-hero.is-ready [data-hero-step="1"] { transition-delay: 80ms; }
.c7-hero.is-ready [data-hero-step="2"] { transition-delay: 200ms; }
.c7-hero.is-ready [data-hero-step="3"] { transition-delay: 330ms; }
.c7-hero.is-ready [data-hero-step="4"] { transition-delay: 440ms; }
.c7-hero.is-ready [data-hero-step="5"] { transition-delay: 560ms; }
.c7-hero.is-ready [data-hero-step="6"] { transition-delay: 680ms; }

/* The photograph drifts almost imperceptibly for the first few seconds, which
   stops a still image reading as a flat backdrop. It runs once and stops. */
.c7-js-ready .c7-hero__backdrop img {
  transform: scale(1.08);
  transition: transform 2600ms cubic-bezier(0.16, 1, 0.3, 1);
}

.c7-hero.is-ready .c7-hero__backdrop img {
  transform: scale(1);
}

/* The accent clause draws its gradient across after the headline lands. */
.c7-js-ready .c7-hero__title-accent {
  background-size: 0% 100%;
  background-repeat: no-repeat;
  transition: background-size 900ms var(--c7-ease-out) 520ms;
}

.c7-hero.is-ready .c7-hero__title-accent {
  background-size: 100% 100%;
}

/* --------------------------------------------------------------------------
   Continuous and interaction motion
   -------------------------------------------------------------------------- */

/* Section eyebrow rule draws itself in. */
.c7-js-ready [data-anim].is-visible .c7-eyebrow::before {
  animation: c7-rule-in 620ms var(--c7-ease-out) both;
}

@keyframes c7-rule-in {
  from { transform: scaleX(0); transform-origin: 0 50%; }
  to   { transform: scaleX(1); transform-origin: 0 50%; }
}

/* Numbered process steps count themselves in. */
.c7-js-ready [data-stagger].is-visible .c7-step::before {
  animation: c7-step-in 700ms var(--c7-ease-spring) both;
}

@keyframes c7-step-in {
  from { opacity: 0; transform: translateY(-10px) scale(0.85); }
  to   { opacity: 1; transform: none; }
}

[data-parallax] {
  will-change: transform;
}

/* The value is server-rendered; the script only counts up to it. */
[data-count] {
  font-variant-numeric: tabular-nums;
}

/* Editorial link underline sweep. */
.c7-underline {
  background-image: linear-gradient(var(--c7-gold-500), var(--c7-gold-500));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 2px;
  text-decoration: none;
  transition: background-size var(--c7-duration-base) var(--c7-ease);
}

.c7-underline:hover {
  background-size: 100% 2px;
}

/* Logo strip marquee. */
.c7-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.c7-marquee__track {
  display: flex;
  align-items: center;
  gap: clamp(2rem, 5vw, 4rem);
  width: max-content;
  animation: c7-marquee 42s linear infinite;
}

.c7-marquee:hover .c7-marquee__track {
  animation-play-state: paused;
}

@keyframes c7-marquee {
  from { transform: translateX(0); }
  /* The track holds the logo set twice, so -50% lands exactly on the seam. */
  to   { transform: translateX(-50%); }
}

/* --------------------------------------------------------------------------
   Reduced motion
   --------------------------------------------------------------------------
   Everything resolves instantly and nothing is left hidden. Continuous motion
   stops entirely.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .c7-js-ready [data-anim],
  .c7-js-ready [data-stagger] > *,
  .c7-js-ready .c7-hero [data-hero-step] {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    clip-path: none !important;
    transition: none !important;
  }

  .c7-js-ready .c7-hero__backdrop img,
  .c7-js-ready .c7-hero__title-accent {
    transform: none !important;
    background-size: 100% 100% !important;
    transition: none !important;
  }

  .c7-marquee__track {
    animation: none;
  }

  [data-parallax] {
    transform: none !important;
  }
}

/* --------------------------------------------------------------------------
   More staggers (September 2026). reveal.js hands these out in rotation to
   grids the templates did not give an entrance, so two neighbouring grids of
   cards never arrive the same way.
   -------------------------------------------------------------------------- */

/* Fan: cards swing up from a slight angle, like a hand of cards being laid out. */
.c7-js-ready [data-stagger="fan"] > * {
  transform: translateY(26px) rotate(-2.5deg);
  transform-origin: 0% 100%;
}

/* Flip: each card turns up towards the reader. */
.c7-js-ready [data-stagger="flip"] > * {
  transform: perspective(900px) rotateX(18deg) translateY(18px);
  transform-origin: 50% 0%;
}

/* Drop: cards settle down from above. */
.c7-js-ready [data-stagger="drop"] > * {
  transform: translateY(-20px) scale(0.98);
}

/* --------------------------------------------------------------------------
   Page banner entrance — plays on load, the way the hero does. The picture
   settles from a slight zoom and the wording rises in, line by line.
   -------------------------------------------------------------------------- */
.c7-js-ready .c7-banner.is-animated .c7-banner__image img {
  transform: scale(1.08);
  transition: transform 1.8s var(--c7-ease-out);
}

.c7-js-ready .c7-banner.is-animated .c7-banner__inner > * {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity var(--c7-duration-slow) var(--c7-ease-out),
    transform var(--c7-duration-slow) var(--c7-ease-out);
}

.c7-js-ready .c7-banner.is-animated.is-ready .c7-banner__image img {
  transform: none;
}

.c7-js-ready .c7-banner.is-animated.is-ready .c7-banner__inner > * {
  opacity: 1;
  transform: none;
}

.c7-js-ready .c7-banner.is-ready .c7-banner__inner > :nth-child(1) { transition-delay: 80ms; }
.c7-js-ready .c7-banner.is-ready .c7-banner__inner > :nth-child(2) { transition-delay: 180ms; }
.c7-js-ready .c7-banner.is-ready .c7-banner__inner > :nth-child(3) { transition-delay: 300ms; }
.c7-js-ready .c7-banner.is-ready .c7-banner__inner > :nth-child(4) { transition-delay: 420ms; }
.c7-js-ready .c7-banner.is-ready .c7-banner__inner > :nth-child(n + 5) { transition-delay: 520ms; }

@media (prefers-reduced-motion: reduce) {
  .c7-js-ready .c7-banner.is-animated .c7-banner__image img,
  .c7-js-ready .c7-banner.is-animated .c7-banner__inner > * {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* A rotated card is wider than its box, and on a phone that shows up as the
   page sliding sideways. Below 48rem the fan keeps its rise and drops the
   tilt — the movement still reads, and nothing scrolls sideways. */
@media (max-width: 48rem) {
  .c7-js-ready [data-stagger="fan"] > * {
    transform: translateY(26px);
  }

  .c7-js-ready [data-anim="tilt"],
  .c7-js-ready [data-anim="pivot"] {
    transform: translateY(24px);
  }

  /* Same reason: a block that slides in from the side is briefly wider than
     the screen it slides into. On a phone it rises instead. */
  .c7-js-ready [data-anim="enter-left"],
  .c7-js-ready [data-anim="enter-right"] {
    transform: translateY(24px);
  }

  /* And the sideways stagger, which is what carousel rows and tile grids
     use: until a row is scrolled into view its cards sit 34px to the right,
     which on a phone is 34px of page nobody asked for. */
  .c7-js-ready [data-stagger="slide"] > * {
    transform: translateY(24px);
  }
}
