/* Shared motion for the four static pages.
 *
 * The rule that matters here: this file never hides anything on its own. The
 * resting state below only applies once motion.js has added [data-reveal], so
 * if the script fails, is blocked, or never runs, every word on the page is
 * still on screen. A civic information site must not depend on JavaScript to
 * be readable.
 *
 * Everything animated is opacity or transform, which the compositor handles
 * without re-laying out the page.
 */

[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  will-change: opacity, transform;
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity 520ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Once it has arrived there is nothing left to composite. */
[data-reveal].is-done {
  will-change: auto;
}

/* A tab panel swap is a change of content in place, not an arrival from
 * off screen, so it gets a shorter fade with no travel. */
.panel[data-swap] {
  animation: chipoli-swap 260ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@keyframes chipoli-swap {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* The red underline under the selected tab grows from the middle rather than
 * simply appearing. */
.subtabs button,
.tabs a {
  transition: color 180ms ease;
}

/* Cards already lift on hover; this just makes the lift match the reveal
 * curve, and adds the same treatment to the monogram inside. */
.card .monogram {
  transition: transform 220ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.card:hover .monogram {
  transform: scale(1.06);
}

/* Citation jumps land softly instead of teleporting. */
html {
  scroll-behavior: smooth;
}

.sources li:target {
  animation: chipoli-flash 1400ms ease-out both;
}

@keyframes chipoli-flash {
  0%,
  30% {
    background: color-mix(in srgb, var(--flag-red) 14%, transparent);
  }
  100% {
    background: transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  /* Belt and braces: motion.js already returns early, so these attributes
     should never be present, but if one is the content still shows. */
  [data-reveal],
  [data-reveal].is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .panel[data-swap] {
    animation: none;
  }

  .card:hover .monogram {
    transform: none;
  }

  .sources li:target {
    animation: none;
  }
}
