/*! RevealKit 1.0 — accessible scroll reveals (WCAG 2.2 conscious)
 *  Attribute API : <div data-reveal="fade-up">
 *  Class API     : <div class="reveal reveal-fade-up">
 *
 *  Nothing is hidden until the `rv-active` class lands on <html>.
 *  If JS is off, blocked, or broken, every element stays fully visible.
 */

/* ---------------------------------------------------------------
   1. Tokens — override these anywhere (:root, a section, an element)
   --------------------------------------------------------------- */
:root {
  --rv-duration: 600ms;
  --rv-delay: 0ms;
  --rv-easing: cubic-bezier(0.22, 0.61, 0.36, 1);
  --rv-distance: 24px; /* travel for fade-*/ /*slide-* */
  --rv-scale: 0.94; /* start scale for zoom-in */
  --rv-scale-out: 1.06; /* start scale for zoom-out */
  --rv-angle: 12deg; /* start angle for flip-*/ /*rotate-* */
  --rv-blur: 8px; /* start blur for blur-in */
  --rv-perspective: 1200px;
  --rv-hidden-opacity: 0.01; /* resting opacity — never a flat 0 */
}

/* ---------------------------------------------------------------
   2. Base — transition setup (applies only while JS is driving)
   --------------------------------------------------------------- */
.rv-active :where([data-reveal], .reveal) {
  transition-property: opacity, transform, filter;
  transition-duration: var(--rv-duration);
  transition-delay: var(--rv-delay);
  transition-timing-function: var(--rv-easing);
}

/* The resting (pre-reveal) state. Opacity + transform only, so an element
   never changes the layout of the page — no reflow, no cumulative shift. */
.rv-active :where([data-reveal], .reveal):not(.rv-visible) {
  opacity: var(--rv-opacity, var(--rv-hidden-opacity));
  transform: perspective(var(--rv-perspective))
    translate3d(var(--rv-tx, 0), var(--rv-ty, 0), 0) scale(var(--rv-sc, 1))
    rotateX(var(--rv-rx, 0)) rotateY(var(--rv-ry, 0)) rotate(var(--rv-rz, 0));
  will-change: opacity, transform;
}

/* Cleared once revealed so long pages don't hold GPU layers open. */
.rv-active :where([data-reveal], .reveal).rv-visible {
  will-change: auto;
}

/* Used by JS to jump an element to its final state with no motion —
   on keyboard focus, on find-in-page, when motion is switched off. */
.rv-active :where([data-reveal], .reveal).rv-instant {
  transition: none !important;
}

/* ---------------------------------------------------------------
   3. Effects
   --------------------------------------------------------------- */

/* Fades ---------------------------------------------------------- */
/* "fade" needs no custom properties — opacity alone is the effect. */
[data-reveal="fade-up"],
.reveal-fade-up {
  --rv-ty: var(--rv-distance);
}
[data-reveal="fade-down"],
.reveal-fade-down {
  --rv-ty: calc(var(--rv-distance) * -1);
}
[data-reveal="fade-left"],
.reveal-fade-left {
  --rv-tx: var(--rv-distance);
}
[data-reveal="fade-right"],
.reveal-fade-right {
  --rv-tx: calc(var(--rv-distance) * -1);
}
[data-reveal="fade-up-left"],
.reveal-fade-up-left {
  --rv-ty: var(--rv-distance);
  --rv-tx: var(--rv-distance);
}
[data-reveal="fade-up-right"],
.reveal-fade-up-right {
  --rv-ty: var(--rv-distance);
  --rv-tx: calc(var(--rv-distance) * -1);
}

/* Slides — position only, opacity stays at 1 ---------------------- */
[data-reveal="slide-up"],
.reveal-slide-up {
  --rv-opacity: 1;
  --rv-ty: var(--rv-distance);
}
[data-reveal="slide-down"],
.reveal-slide-down {
  --rv-opacity: 1;
  --rv-ty: calc(var(--rv-distance) * -1);
}
[data-reveal="slide-left"],
.reveal-slide-left {
  --rv-opacity: 1;
  --rv-tx: var(--rv-distance);
}
[data-reveal="slide-right"],
.reveal-slide-right {
  --rv-opacity: 1;
  --rv-tx: calc(var(--rv-distance) * -1);
}

/* Zooms ---------------------------------------------------------- */
[data-reveal="zoom-in"],
.reveal-zoom-in {
  --rv-sc: var(--rv-scale);
}
[data-reveal="zoom-out"],
.reveal-zoom-out {
  --rv-sc: var(--rv-scale-out);
}
[data-reveal="zoom-in-up"],
.reveal-zoom-in-up {
  --rv-sc: var(--rv-scale);
  --rv-ty: var(--rv-distance);
}
[data-reveal="zoom-out-up"],
.reveal-zoom-out-up {
  --rv-sc: var(--rv-scale-out);
  --rv-ty: var(--rv-distance);
}

/* Flips & rotates ------------------------------------------------ */
[data-reveal="flip-up"],
.reveal-flip-up {
  --rv-rx: var(--rv-angle);
}
[data-reveal="flip-down"],
.reveal-flip-down {
  --rv-rx: calc(var(--rv-angle) * -1);
}
[data-reveal="flip-left"],
.reveal-flip-left {
  --rv-ry: var(--rv-angle);
}
[data-reveal="flip-right"],
.reveal-flip-right {
  --rv-ry: calc(var(--rv-angle) * -1);
}
[data-reveal="rotate-in"],
.reveal-rotate-in {
  --rv-rz: var(--rv-angle);
  --rv-sc: var(--rv-scale);
}

/* Blur ----------------------------------------------------------- */
.rv-active :where([data-reveal="blur-in"], .reveal-blur-in):not(.rv-visible) {
  filter: blur(var(--rv-blur));
}

/* ---------------------------------------------------------------
   4. Duration & delay — stack one of these on an element alongside
   its effect class to control timing without touching the JS or
   writing custom CSS:

     <div class="reveal reveal-fade-up reveal-duration-900">

   These work with the class API directly. With the attribute API,
   add the class for the same effect: it only supplies timing, so it's
   safe to combine with data-reveal="fade-up" on the same element.

   Precedence, highest to lowest:
     1. data-reveal-duration / data-reveal-delay on the element (JS-set inline style)
     2. a .reveal-duration-* / .reveal-delay-* class, or any custom selector
        setting --rv-duration / --rv-delay (normal CSS cascade)
     3. the :root default, or RevealKit.init({ duration, delay }) if used
   --------------------------------------------------------------- */
.reveal-duration-150 {
  --rv-duration: 150ms;
}
.reveal-duration-300 {
  --rv-duration: 300ms;
}
.reveal-duration-450 {
  --rv-duration: 450ms;
}
.reveal-duration-600 {
  --rv-duration: 600ms;
} /* same as the default — spelled out for clarity */
.reveal-duration-900 {
  --rv-duration: 900ms;
}
.reveal-duration-1200 {
  --rv-duration: 1200ms;
}
.reveal-duration-1500 {
  --rv-duration: 1500ms;
} /* library ceiling, see maxDuration in JS */

.reveal-delay-100 {
  --rv-delay: 100ms;
}
.reveal-delay-200 {
  --rv-delay: 200ms;
}
.reveal-delay-300 {
  --rv-delay: 300ms;
}
.reveal-delay-500 {
  --rv-delay: 500ms;
}
.reveal-delay-750 {
  --rv-delay: 750ms;
}
.reveal-delay-1000 {
  --rv-delay: 1000ms;
} /* library ceiling, see maxDelay in JS */

/* ---------------------------------------------------------------
   5. Accessibility guards — these are the point of the library
   --------------------------------------------------------------- */

/* 4a. Operating-system reduced-motion preference.
   Hard backstop in CSS as well as JS, so a scripting failure can never
   leave a motion-sensitive visitor with animation. `rv-motion-on` is
   added only when the visitor has deliberately overridden the OS
   setting using an in-page control. */
@media (prefers-reduced-motion: reduce) {
  .rv-active:not(.rv-motion-on) :where([data-reveal], .reveal),
  .rv-active:not(.rv-motion-on)
    :where([data-reveal], .reveal):not(.rv-visible) {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    transition: none !important;
    will-change: auto !important;
  }
}

/* 4b. Motion switched off from an in-page control. */
.rv-motion-off :where([data-reveal], .reveal),
.rv-motion-off :where([data-reveal], .reveal):not(.rv-visible) {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
  transition: none !important;
  will-change: auto !important;
}

/* 4c. Keyboard focus must never land on invisible content.
   JS also reveals focused ancestors; this is the no-script-race version. */
.rv-active :where([data-reveal], .reveal):focus-within {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
}

/* 4d. Print and forced-colors: show everything. */
@media print {
  :where([data-reveal], .reveal) {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
}

/* ---------------------------------------------------------------
   6. Optional: the motion toggle control (style it however you like)
   --------------------------------------------------------------- */
[data-reveal-toggle] {
  cursor: pointer;
}
[data-reveal-toggle]:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 2px;
}
