/* HTMX transition stylesheet.
 *
 * Strategy: rely on @keyframes (not class-toggled opacity) for swap-in.
 * @keyframes with `animation-fill-mode: backwards` apply their first frame
 * synchronously when the element mounts, so there's no flash-of-visible
 * content before HTMX gets a chance to add `.htmx-added`. Class-toggled
 * opacity has a one-frame race that paints the new content fully visible
 * before the class lands — that's the "blink" you'd otherwise see.
 *
 * Class summary:
 *   .htmx-swapping  — old content during swap-out (set by hx-swap "swap:Xms")
 *   .htmx-added     — newly inserted content (~next frame after insert)
 *   .htmx-settling  — new content during settle window (set by "settle:Yms")
 */

/* ---------- Swap-out: fade old content before removal ---------- */

.htmx-swapping {
  opacity: 0;
  transition: opacity 140ms ease-in;
}

/* ---------- Swap-in: keyframe-driven, no class-timing race ---------- */

.htmx-added {
  animation: htmx-fade-in 220ms ease-out backwards;
}
@keyframes htmx-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ---------- Row enter / leave ---------- */

.row.htmx-added    { animation: row-grow   220ms ease-out backwards; }
.row.htmx-swapping { animation: row-shrink 180ms ease-in forwards; }

@keyframes row-grow {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes row-shrink {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-6px); }
}

/* ---------- Drawer + scrim ----------
 * Compound selectors so these win over the generic .htmx-added rule when
 * the drawer/scrim are first inserted. Single `animation` property, so
 * specificity ties (same number of class selectors) are resolved by the
 * later declaration. Keep these blocks AFTER the .htmx-added rule. */

.drawer,
.drawer.htmx-added {
  animation: drawer-in 180ms ease-out backwards;
}
.drawer-scrim,
.drawer-scrim.htmx-added {
  animation: scrim-in 160ms ease backwards;
}

@keyframes drawer-in {
  from { transform: translateX(100%); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
@keyframes scrim-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Mobile: drawer becomes a bottom sheet — slide up from the bottom. */
@media (max-width: 720px) {
  .drawer,
  .drawer.htmx-added {
    animation: sheet-in 200ms cubic-bezier(.2, .8, .2, 1) backwards;
  }
  @keyframes sheet-in {
    from { transform: translateY(100%); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
  }
}

/* ---------- Cross-page navigation (top-bar links) ---------- */

@view-transition { navigation: auto; }

/* ---------- prefer-reduced-motion: collapse all animations to ~0ms ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
