/* ---- EtA Central motion (MOTION.md) ------------------------------------------------------------
   One shared stylesheet for every page: the Next.js pages link it from SiteShell, and the static
   review pack, words tool and report link it in their <head>. Its partner is /motion/motion.js.
   All the values to tune are the variables in :root below; motion.js reads the ones it needs.
   Nothing here hides content unless <html> has the "js" class (set by the boot script), and
   with prefers-reduced-motion there is no movement at all, only content appearing. */

/* The site's own styles sit in these layers (src/app/globals.css). Declared again here so the
   order is the same whichever stylesheet loads first. Unlayered rules beat layered ones, so
   anything below that must yield to the site's own styles goes inside `@layer base`. */
@layer theme, base, components, utilities;

:root {
  /* Easing: the long ease-out of the reference (expo out), a swift in-out for exits, and a
     gentle curve for hover and focus. */
  --motion-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --motion-ease-swift: cubic-bezier(0.7, 0, 0.3, 1);
  --motion-ease-ui: cubic-bezier(0.2, 0, 0, 1);

  /* Durations */
  --motion-duration: 0.8s; /* content easing in */
  --motion-duration-hero: 1s; /* hero lines */
  --motion-duration-fast: 0.25s; /* hover and focus */

  /* Ease-in: how far content rises, how far images settle, and the stagger in a group. */
  --motion-rise: 24px;
  --motion-rise-hero: 32px;
  --motion-scale-from: 1.06;
  --motion-stagger: 70ms;
  --motion-stagger-max: 6; /* items after the sixth start together */
  --motion-hero-stagger: 110ms;
  --motion-hero-delay: 0.1s; /* after the preloader (or the page) is ready */

  /* Parallax: the offset at the edges of the viewport, centred on zero (so nothing shifts when a
     section is in the middle of the screen). Text moves least, blocks and images more. */
  --parallax-text: 6px;
  --parallax-block: 14px; /* at most 8px apart from the text, well inside the tightest gap (18px) */
  --parallax-media: 5%; /* of the image's own height, inside its frame */
  --parallax-media-scale: 1.12; /* covers the media offset, so no frame edge ever shows */

  /* Hero */
  --hero-drift: 16px; /* pointer drift of the decorative glow */
  --hero-drift-photo: 6px; /* pointer drift of the photos in the headline */
  --hero-drift-smoothing: 0.08; /* 0 to 1: lower is smoother and slower */
  --hero-scroll-rise: 64px; /* hero content rises this much as the hero scrolls away (no fade:
                               text stays at full contrast while it can be read) */
  --hero-scroll-bg: 40px; /* the glow sinks this much: the background moving slower */

  /* Preloader */
  --preloader-max: 1.5s; /* never longer (motion.js and the boot script) */
  --preloader-exit: 0.7s;
  --preloader-failsafe: 3s; /* hidden by CSS alone if the scripts never run */

}

/* ---- Hover and focus: smooth, on the site's own styles ---------------------------------------
   In the lowest layer, and :where() keeps it at zero specificity, so any transition the site
   already sets (the ticket's lift, a card's lift) still wins. */
@layer base {
  :where(.site a, .site button, .site summary, .site .pill, .site [class*="card"], .site .acard) {
    transition-property: color, background-color, border-color, text-decoration-color, box-shadow, opacity,
      translate;
    transition-duration: var(--motion-duration-fast);
    transition-timing-function: var(--motion-ease-ui);
  }
}

/* ---- Preloader (SiteShell) ------------------------------------------------------------------- */
.eta-preloader {
  display: none;
}
html.js.pl-on .eta-preloader,
html.js.pl-out .eta-preloader {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  background: var(--g900, #0b2b1d);
  pointer-events: none;
}
html.js.pl-on .eta-preloader {
  /* If nothing removes it (the scripts fail), CSS hides it on its own. */
  animation: eta-pl-failsafe 0.3s linear var(--preloader-failsafe) forwards;
}
html.js.pl-out .eta-preloader {
  transform: translate3d(0, -100%, 0);
  transition: transform var(--preloader-exit) var(--motion-ease-swift);
}
html.js.pl-on {
  overflow: hidden;
  scrollbar-gutter: stable;
}
.eta-preloader__inner {
  display: grid;
  justify-items: center;
  gap: 22px;
}
.eta-preloader__logo {
  overflow: hidden;
  display: block;
}
.eta-preloader__logo img {
  display: block;
  width: 132px;
  height: auto;
  animation: eta-pl-logo 0.9s var(--motion-ease) 0.05s backwards;
}
.eta-preloader__bar {
  width: 132px;
  height: 2px;
  background: rgba(255, 253, 247, 0.18);
  overflow: hidden;
}
.eta-preloader__bar span {
  display: block;
  height: 100%;
  background: var(--gold, #fbb03b);
  transform-origin: left;
  animation: eta-pl-bar var(--preloader-max) var(--motion-ease) forwards;
}
html.pl-out .eta-preloader__inner {
  opacity: 0;
  transition: opacity 0.3s ease;
}
@keyframes eta-pl-logo {
  from {
    transform: translate3d(0, 105%, 0);
  }
}
@keyframes eta-pl-bar {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}
@keyframes eta-pl-failsafe {
  to {
    opacity: 0;
    visibility: hidden;
  }
}

/* ---- Hero reveal (every page's opening) ------------------------------------------------------
   Played by CSS on load, so it runs even if motion.js doesn't; it waits under the preloader and
   starts as the preloader leaves. fill-mode "backwards" hands each element back to its own
   styles when it ends. */
@keyframes eta-rise {
  from {
    opacity: 0;
    translate: 0 var(--motion-rise-hero);
  }
}
@keyframes eta-settle {
  from {
    opacity: 0;
    scale: var(--motion-scale-from);
  }
}
@keyframes eta-fade {
  from {
    opacity: 0;
  }
}
.eta-hero,
.eta-mhero,
.eta-phero,
.eta-ahero,
.eta-lhero,
.eta-fhero,
.eta-pthero {
  --hero-i: 0;
}
@media (prefers-reduced-motion: no-preference) {
  /* :where() keeps these at the lowest specificity, so the rules after them can adjust. */
  html.js
    :where(.eta-hero, .eta-mhero, .eta-phero, .eta-ahero, .eta-lhero, .eta-fhero, .eta-pthero)
    :where(.eyebrow, .crumb, .flogo, h1, p:not(.below p, .crumb, .eyebrow), .below, .pill:not(.below .pill)) {
    animation: eta-rise var(--motion-duration-hero) var(--motion-ease) backwards;
    animation-delay: calc(var(--motion-hero-delay) + var(--hero-i) * var(--motion-hero-stagger));
  }
  html.js :where(.eta-hero, .eta-mhero, .eta-phero, .eta-ahero, .eta-lhero, .eta-fhero, .eta-pthero) h1 {
    --hero-i: 1;
  }
  html.js :where(.eta-hero, .eta-mhero, .eta-phero, .eta-ahero, .eta-lhero, .eta-fhero, .eta-pthero) :where(p:not(.below p, .crumb, .eyebrow), .below) {
    --hero-i: 3;
  }
  html.js :where(.eta-hero, .eta-mhero, .eta-phero, .eta-ahero, .eta-lhero, .eta-fhero, .eta-pthero) .pill {
    --hero-i: 4;
  }
  /* The home headline rises word by word (the words are spans in HomeHero). */
  html.js .eta-hero h1 {
    animation: none;
  }
  html.js .eta-hero h1 .hw {
    display: inline-block;
    animation: eta-rise var(--motion-duration-hero) var(--motion-ease) backwards;
    animation-delay: calc(var(--motion-hero-delay) + (1 + var(--i, 0)) * var(--motion-hero-stagger));
  }
  /* Photos and pictures in a hero settle into place. */
  html.js :is(.eta-hero h1 .ph, .eta-phero .eta-photo) {
    animation: eta-settle calc(var(--motion-duration-hero) * 1.3) var(--motion-ease) backwards;
    animation-delay: calc(var(--motion-hero-delay) + 2 * var(--motion-hero-stagger));
  }
  html.js .eta-hero .hero-glow {
    animation: eta-fade 1.6s ease backwards;
    animation-delay: var(--motion-hero-delay);
  }
  /* Under the preloader everything waits on its first frame. */
  html.js.pl-on :where(.eta-hero, .eta-mhero, .eta-phero, .eta-ahero, .eta-lhero, .eta-fhero, .eta-pthero) * {
    animation-play-state: paused;
  }
}

/* ---- Home hero: the glow, pointer drift and the scroll link ----------------------------------- */
.eta-hero {
  position: relative;
  isolation: isolate;
  overflow-x: clip; /* the glow reaches past the edges to drift; never into a sideways scroll */
}
.eta-hero .hero-glow {
  position: absolute;
  inset: -10%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(38% 46% at 18% 28%, rgba(60, 138, 98, 0.320) 0%, rgba(60, 138, 98, 0.315) 8%, rgba(60, 138, 98, 0.299) 17%, rgba(60, 138, 98, 0.273) 25%, rgba(60, 138, 98, 0.240) 33%, rgba(60, 138, 98, 0.201) 42%, rgba(60, 138, 98, 0.160) 50%, rgba(60, 138, 98, 0.119) 58%, rgba(60, 138, 98, 0.080) 67%, rgba(60, 138, 98, 0.047) 75%, rgba(60, 138, 98, 0.021) 83%, rgba(60, 138, 98, 0.005) 92%, rgba(60, 138, 98, 0.000) 100%),
    radial-gradient(34% 42% at 84% 74%, rgba(251, 176, 59, 0.110) 0%, rgba(251, 176, 59, 0.108) 8%, rgba(251, 176, 59, 0.103) 17%, rgba(251, 176, 59, 0.094) 25%, rgba(251, 176, 59, 0.083) 33%, rgba(251, 176, 59, 0.069) 42%, rgba(251, 176, 59, 0.055) 50%, rgba(251, 176, 59, 0.041) 58%, rgba(251, 176, 59, 0.028) 67%, rgba(251, 176, 59, 0.016) 75%, rgba(251, 176, 59, 0.007) 83%, rgba(251, 176, 59, 0.002) 92%, rgba(251, 176, 59, 0.000) 100%);
}
@media (prefers-reduced-motion: no-preference) {
  /* motion.js sets --hx/--hy (pointer, -1 to 1) and --hero-s (0 as the hero sits, 1 once it has
     scrolled away). The content rises a little; the glow sinks, moving slower. */
  html.js .eta-hero .hero-glow {
    transform: translate3d(
      calc(var(--hx, 0) * var(--hero-drift) * -1),
      calc(var(--hy, 0) * var(--hero-drift) * -1 + var(--hero-s, 0) * var(--hero-scroll-bg)),
      0
    );
  }
  html.js .eta-hero h1 .ph {
    transform: translate3d(
      calc(var(--hx, 0) * var(--hero-drift-photo) * -1),
      calc(var(--hy, 0) * var(--hero-drift-photo) * -1),
      0
    );
  }
  html.js :is(.eta-hero, .eta-mhero, .eta-ahero, .eta-lhero, .eta-fhero, .eta-pthero) > :not(.hero-glow),
  html.js .eta-phero > :not(.eta-photo) {
    transform: translate3d(0, calc(var(--hero-s, 0) * var(--hero-scroll-rise) * -1), 0);
  }
  html.js .eta-phero > .eta-photo {
    transform: translate3d(0, calc(var(--hero-s, 0) * var(--hero-scroll-bg)), 0);
  }
}
/* ---- Parallax (motion.js marks the layers and sets --px on each section, -1 to 1) ------------- */
[data-px-band] {
  overflow-x: clip;
}
@media (prefers-reduced-motion: no-preference) {
  html.js [data-px="text"] {
    transform: translate3d(0, calc(var(--px, 0) * var(--parallax-text)), 0);
  }
  html.js [data-px="block"] {
    transform: translate3d(0, calc(var(--px, 0) * var(--parallax-block)), 0);
  }
  html.js [data-px="media"] {
    transform: translate3d(0, calc(var(--px, 0) * var(--parallax-media)), 0) scale(var(--parallax-media-scale));
  }
}

/* ---- Ease-in as content enters the viewport (motion.js marks it [data-rv]) -------------------- */
@media (prefers-reduced-motion: no-preference) {
  html.js [data-rv]:not([data-rv-in]) {
    opacity: 0;
  }
  html.js [data-rv="rise"]:not([data-rv-in]) {
    translate: 0 var(--motion-rise);
  }
  html.js [data-rv="img"]:not([data-rv-in]) {
    scale: var(--motion-scale-from);
  }
  html.js [data-rv="lite"]:not([data-rv-in]) {
    translate: 0 calc(var(--motion-rise) / 2);
  }
  html.js [data-rv] {
    transition:
      opacity var(--motion-duration) var(--motion-ease) var(--rv-delay, 0s),
      translate var(--motion-duration) var(--motion-ease) var(--rv-delay, 0s),
      scale calc(var(--motion-duration) * 1.4) var(--motion-ease) var(--rv-delay, 0s);
  }
}

/* ---- Reduced motion: no movement, nothing looping; content simply appears ------------------- */

/* Printing shows everything where it belongs. */
@media print {
  [data-rv],
  [data-px] {
    opacity: 1 !important;
    translate: none !important;
    scale: none !important;
    transform: none !important;
  }
  .eta-preloader {
    display: none !important;
  }
}
