/* Section reveal, paired with section-reveal.js: a block marked data-reveal
   text fades in and rises 8px over 240ms, with a brief 30ms child stagger.
   Photographs keep their existing 24px / 760ms entrance.

   Only the pending state is styled, and the entrance is an animation filling
   backwards rather than a transition, so an arrived block's buttons keep their
   own hover and press states and nothing pins opacity or transform afterwards.
   Everything is gated to screen with motion allowed, and the pending state
   only exists once the script arms a block (or, for data-reveal-hold, from the
   first frame with a fallback), so no-JS, print and reduced motion always show
   content. Prefixed with html.zuvani-js so these outrank a page's own
   "no motion" resets for the same elements. */
@media screen and (prefers-reduced-motion: no-preference) {
  [data-reveal="self"] { --reveal-duration: 760ms; --reveal-rise: 24px; }
  /* A block on screen at load waits hidden from the very first frame: the
     loader marks the page in <head> before anything paints, whereas the
     reveal script is deferred and can run a frame after it. Should that
     script never run, the block rises in on its own after 0.5s. */
  html.zuvani-js [data-reveal-hold]:not([data-reveal-armed], .is-revealed) > :not(dialog) {
    opacity: 0;
    transform: translateY(var(--reveal-rise, 8px));
    animation: section-reveal-late var(--reveal-duration, 240ms) var(--ease-out) calc(0.5s + var(--reveal-delay, 0ms)) both;
  }

  html.zuvani-js [data-reveal-armed]:not(.is-revealed, [data-reveal="self"]) > :not(dialog),
  html.zuvani-js [data-reveal="self"][data-reveal-armed]:not(.is-revealed) {
    opacity: 0;
    transform: translateY(var(--reveal-rise, 8px));
  }

  /* A photograph frame waiting for its pixels is hidden but not shifted, so
     its box stays where the layout put it until the entrance runs. */
  html.zuvani-js [data-reveal="self"][data-reveal-waiting]:not(.is-revealed) {
    transform: none;
  }

  html.zuvani-js [data-reveal-armed].is-revealed:not(.is-revealed-instant, [data-reveal="self"]) > :not(dialog),
  html.zuvani-js [data-reveal="self"][data-reveal-armed].is-revealed:not(.is-revealed-instant) {
    animation: section-reveal var(--reveal-duration, 240ms) var(--ease-out) var(--reveal-delay, 0ms) backwards;
  }

  [data-reveal] > :nth-child(2) { --reveal-delay: 30ms; }
  [data-reveal] > :nth-child(3) { --reveal-delay: 60ms; }
  [data-reveal] > :nth-child(n + 4) { --reveal-delay: 90ms; }
}

@keyframes section-reveal {
  from { opacity: 0; transform: translateY(var(--reveal-rise, 8px)); }
}

@keyframes section-reveal-late {
  from { opacity: 0; transform: translateY(var(--reveal-rise, 8px)); }
  to { opacity: 1; transform: none; }
}
