/* ==========================================================================
   APM Bricks and Pavers — Animations
   Keyframes + scroll-reveal states. Reveal classes are only active when
   JS adds .js to <html>, so content is always visible without JavaScript.
   ========================================================================== */

@keyframes heroKenBurns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.08) translate3d(-1.5%, -1%, 0); }
}

@keyframes bondDrift {
  from { background-position: 0 0; }
  to   { background-position: 192px 96px; }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes marquee {
  to { transform: translateX(-50%); }
}

@keyframes scrollCue {
  0%   { transform: scaleY(0); opacity: 1; }
  60%  { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1); opacity: 0; }
}

@keyframes pulseRing {
  0%   { transform: scale(1); opacity: 0.7; }
  100% { transform: scale(1.6); opacity: 0; }
}

@keyframes lineUp {
  from { transform: translateY(105%); }
  to   { transform: translateY(0); }
}

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}

@keyframes tileIn {
  from { opacity: 0; transform: translateY(40px) rotate(-3deg) scale(0.94); }
  to   { opacity: 1; transform: none; }
}

@keyframes gradientShift {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

@keyframes floatY {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

/* ---------- Hero entrance (runs once on load) ---------- */
.js .hero h1 .line > span {
  transform: translateY(105%);
  animation: lineUp 1.1s var(--ease) forwards;
}

.js .hero h1 .line:nth-child(2) > span { animation-delay: 0.12s; }
.js .hero h1 .line:nth-child(3) > span { animation-delay: 0.24s; }
.js .hero h1 .line:nth-child(4) > span { animation-delay: 0.36s; }

.js .hero__tag,
.js .hero__text,
.js .hero .btn-row,
.js .hero__meta {
  opacity: 0;
  animation: fadeUp 0.9s var(--ease) forwards;
}

.js .hero__tag   { animation-delay: 0.05s; }
.js .hero__text  { animation-delay: 0.5s; }
.js .hero .btn-row { animation-delay: 0.65s; }
.js .hero__meta  { animation-delay: 0.8s; }

.js .hero__card {
  opacity: 0;
  animation: tileIn 1.2s var(--ease) forwards;
}

.js .hero__card--a { animation-delay: 0.3s; }
.js .hero__card--b { animation-delay: 0.5s; }
.js .hero__card--c { animation-delay: 0.7s; }

.js .hero__badge {
  opacity: 0;
  animation: fadeUp 1s var(--ease) 1s forwards;
}

/* Page hero */
.js .page-hero h1,
.js .page-hero p,
.js .page-hero .breadcrumb {
  opacity: 0;
  animation: fadeUp 0.9s var(--ease) forwards;
}

.js .page-hero .breadcrumb { animation-delay: 0.05s; }
.js .page-hero h1 { animation-delay: 0.15s; }
.js .page-hero p  { animation-delay: 0.3s; }

/* ---------- Scroll reveal ---------- */
.js [data-reveal] {
  opacity: 0;
  transition:
    opacity 0.9s var(--ease),
    transform 0.9s var(--ease),
    clip-path 1.1s var(--ease-in-out);
  transition-delay: var(--delay, 0s);
}

.js [data-reveal="up"]    { transform: translateY(40px); }
.js [data-reveal="left"]  { transform: translateX(-50px); }
.js [data-reveal="right"] { transform: translateX(50px); }
.js [data-reveal="zoom"]  { transform: scale(0.92); }
.js [data-reveal="tile"]  { transform: translateY(40px) rotate(-2deg) scale(0.96); }

/* Clip-path wipe for imagery.
   The clip is applied to the children, not the observed element itself,
   because a fully clipped target never reports as intersecting. */
.js [data-reveal="clip"],
.js [data-reveal="clip-up"] {
  opacity: 1;
  transform: none;
}

.js [data-reveal="clip"] > * {
  clip-path: inset(0 100% 0 0 round var(--r-lg));
  transition: clip-path 1.1s var(--ease-in-out);
  transition-delay: var(--delay, 0s);
}

.js [data-reveal="clip-up"] > * {
  clip-path: inset(100% 0 0 0 round var(--r-md));
  transition: clip-path 1s var(--ease-in-out), opacity 0.4s;
  transition-delay: var(--delay, 0s);
}

.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

.js [data-reveal="clip"].is-in > *,
.js [data-reveal="clip-up"].is-in > * {
  clip-path: inset(-40px -40px -40px -40px);
}

/* Section headings: words slide up from a mask */
.js [data-split] .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

.js [data-split] .w > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 0.9s var(--ease);
  transition-delay: calc(var(--i, 0) * 45ms);
}

.js [data-split].is-in .w > span {
  transform: none;
}

/* Animated underline below section titles */
.title-bar {
  display: block;
  width: 64px;
  height: 5px;
  margin-top: 1rem;
  border-radius: 3px;
  background: var(--grad-brand);
  background-size: 200% 100%;
  animation: gradientShift 4s ease infinite;
  transform-origin: left;
}

.js .title-bar {
  transform: scaleX(0);
  transition: transform 1s var(--ease) 0.3s;
}

.js .is-in .title-bar,
.js .title-bar.is-in {
  transform: scaleX(1);
}

.section-head--center .title-bar {
  margin-inline: auto;
  transform-origin: center;
}

.float-slow {
  animation: floatY 6s ease-in-out infinite;
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .js [data-reveal],
  .js [data-split] .w > span,
  .js .hero h1 .line > span,
  .js .hero__card,
  .js .title-bar,
  .js [data-reveal] > * {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  .marquee__track {
    animation: none;
  }

  .hero__bg img {
    animation: none;
  }
}
