/* Built from the five effect stylesheets by tools/build-effects.py - edit those, not this file. */

/* === hero-parallax.css === */
/**
 * Hero parallax: only what is structurally needed (positioning, stacking). Optical values
 * belong in the customer stylesheet and may override these rules. Details in README.md.
 */
.parallax-section {
  position: relative;
  overflow: hidden;
}

.parallax-bg,
.parallax-fg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  will-change: transform;
}

.parallax-bg {
  z-index: 1;
}

.parallax-fg {
  z-index: 2;
  pointer-events: none;
}

/*
  Simple case: .parallax-bg/.parallax-fg sits on an <img> itself. object-fit is therefore
  tag-qualified, or the rule for the container case below would hit nothing - a <div> has no
  object-fit.
*/
img.parallax-bg {
  object-fit: cover;
  object-position: center;
}

img.parallax-fg {
  /* a cut-out subject should usually not be cropped */
  object-fit: contain;
  object-position: center;
}

/*
  Container case: .parallax-bg/.parallax-fg is a <div> holding the image plus further
  children that inherit the same scroll transform. .parallax-media then carries object-fit
  and object-position, which in the simple case sit on the wrapper. Example in README.md.
*/
.parallax-media {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.parallax-fg .parallax-media {
  object-fit: contain;
}

@media (prefers-reduced-motion: reduce) {
  .parallax-bg,
  .parallax-fg {
    will-change: auto;
  }
}

/* === text-reveal.css === */
/**
 * Letter reveal: structure only. Timing and distance are custom properties on
 * .text-reveal-chars and inherit to the letter spans, so one rule in the customer
 * stylesheet changes all of them. Details in README.md.
 */
.text-reveal-chars {
  --reveal-distance: 20px;
  --reveal-duration: 0.8s;
  --reveal-easing: ease-out;
}

.text-reveal-word {
  display: inline-block;
  white-space: nowrap;
}

.text-reveal-chars .text-reveal-char {
  display: inline-block;
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition: opacity var(--reveal-duration) var(--reveal-easing),
              transform var(--reveal-duration) var(--reveal-easing);
}

.text-reveal-chars.is-revealed .text-reveal-char {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .text-reveal-chars .text-reveal-char {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* === sticky-header.css === */
/**
 * Sticky header: structure only. Duration and easing are custom properties, so a
 * customer stylesheet can override them. Details in README.md.
 */
.sticky-header {
  --header-transition-duration: 0.3s;
  --header-transition-easing: ease;

  position: sticky;
  top: 0;
  z-index: 100;
  transform: translateY(0);
  transition: transform var(--header-transition-duration) var(--header-transition-easing);
  will-change: transform;
}

.sticky-header.is-hidden {
  transform: translateY(-100%);
}

@media (prefers-reduced-motion: reduce) {
  .sticky-header {
    transition: none;
    will-change: auto;
  }
}

/* === scroll-reveal.css === */
/**
 * Scroll reveal: structure only. Timing and distance are custom properties with defaults,
 * so a customer stylesheet can override them. Details in README.md.
 */
.reveal-on-scroll {
  --reveal-distance: 24px;
  --reveal-duration: 0.6s;
  --reveal-easing: ease-out;

  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition: opacity var(--reveal-duration) var(--reveal-easing),
              transform var(--reveal-duration) var(--reveal-easing);
}

.reveal-on-scroll.is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal-on-scroll {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* === cursor-dot.css === */
/**
 * Cursor dot: structure and mechanics only (position, stacking, transitions). Size, colour
 * and timing come from the custom properties below. Details in README.md.
 *
 * mix-blend-mode: difference makes the dot contrast with whatever is behind it - which is
 * why no ancestor between it and <body> may create a stacking context (transform, opacity
 * below 1, isolation), or the dot blends with that ancestor instead of the page.
 */
.cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  width: var(--cursor-dot-size, 14px);
  height: var(--cursor-dot-size, 14px);
  border-radius: 50%;
  background: var(--cursor-dot-color, #fff);
  mix-blend-mode: difference;
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transition:
    width var(--cursor-dot-duration, 0.2s) ease,
    height var(--cursor-dot-duration, 0.2s) ease,
    opacity 0.2s ease;
  will-change: transform;
}

.cursor-dot.is-visible {
  opacity: 1;
}

.cursor-dot.is-active {
  width: var(--cursor-dot-active-size, 44px);
  height: var(--cursor-dot-active-size, 44px);
}

/*
  The native cursor stays visible by default - the dot only trails it. Only with
  data-hide-native-cursor does cursor-dot.js add this class and hide the arrow.
*/
html.cursor-dot-hide-native,
html.cursor-dot-hide-native a,
html.cursor-dot-hide-native button,
html.cursor-dot-hide-native .cursor-target {
  cursor: none;
}

@media (prefers-reduced-motion: reduce), (hover: none), (pointer: coarse) {
  .cursor-dot {
    display: none;
  }
  html.cursor-dot-hide-native,
  html.cursor-dot-hide-native a,
  html.cursor-dot-hide-native button,
  html.cursor-dot-hide-native .cursor-target {
    cursor: auto;
  }
}
