/* ==========================================================================
   Animations — keyframes, scroll reveals, typewriter, reduced motion
   Reveal elements are only hidden when JS is running (html.js), so content
   is never invisible if scripts fail.
   ========================================================================== */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes shimmer { to { background-position: -200% 0; } }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes caret-blink { 50% { opacity: 0; } }
@keyframes toast-in { from { opacity: 0; transform: translateY(12px) scale(.96); } }
@keyframes fade-up { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ken-burns { from { transform: scale(1); } to { transform: scale(1.08) translate(-1%, -1%); } }
@keyframes float { 50% { transform: translateY(-10px); } }
@keyframes float-rotate { 50% { transform: translateY(-8px) rotate(2deg); } }
@keyframes bounce-down { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(8px); } }
@keyframes marquee { to { transform: translateX(-50%); } }
@keyframes paw-step { from { opacity: 0; transform: scale(.4) rotate(var(--r, 0deg)); } to { opacity: .55; transform: scale(1) rotate(var(--r, 0deg)); } }
@keyframes blob-morph {
  0% { border-radius: 62% 38% 46% 54% / 55% 44% 56% 45%; }
  50% { border-radius: 42% 58% 60% 40% / 45% 58% 42% 55%; }
  100% { border-radius: 55% 45% 38% 62% / 60% 40% 60% 40%; }
}

/* Page-load sequence (hero) ---------------------------------------------- */
.js .load-in { opacity: 0; animation: fade-up 900ms var(--ease-out) forwards; animation-delay: calc(var(--i, 0) * 120ms + 150ms); }

/* Scroll reveal ----------------------------------------------------------- */
/* Uses the individual `translate` / `scale` properties so reveals never
   conflict with hover effects that use `transform` on the same element. */
.reveal-on [data-reveal] {
  --reveal-delay: calc(var(--stagger, 0) * 90ms);
  opacity: 0;
  transition-property: opacity, translate, scale, transform, box-shadow, background-color;
  transition-duration: var(--dur-slow), 900ms, 900ms, var(--dur-base), var(--dur-base), var(--dur-base);
  transition-timing-function: var(--ease-out);
  transition-delay: var(--reveal-delay), var(--reveal-delay), var(--reveal-delay), 0s, 0s, 0s;
}
.reveal-on [data-reveal="up"] { translate: 0 36px; }
.reveal-on [data-reveal="left"] { translate: -24px 0; }
.reveal-on [data-reveal="right"] { translate: 24px 0; }
@media (min-width: 64em) {
  .reveal-on [data-reveal="left"] { translate: -44px 0; }
  .reveal-on [data-reveal="right"] { translate: 44px 0; }
}
.reveal-on [data-reveal="zoom"] { scale: .92; }
.reveal-on [data-reveal].is-visible { opacity: 1; translate: none; scale: none; }

/* Heading ornament that draws itself in */
.title-ornament { display: block; width: 88px; height: 14px; color: var(--caramel-400); }
.title-ornament path { stroke-dasharray: 120; stroke-dashoffset: 120; transition: stroke-dashoffset 1.1s var(--ease-out) .25s; }
.is-visible .title-ornament path, .title-ornament.is-visible path { stroke-dashoffset: 0; }
.no-js .title-ornament path { stroke-dashoffset: 0; }

/* Floating decoration */
.floaty { animation: float 6s ease-in-out infinite; }
.floaty--slow { animation-duration: 8s; animation-delay: -2s; }
.floaty--rotate { animation: float-rotate 7s ease-in-out infinite; }

/* Typewriter -------------------------------------------------------------- */
.typewriter-wrap { position: relative; display: block; }
.typewriter { white-space: pre-wrap; }
.typewriter__caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 3px;
  vertical-align: -.12em;
  background: var(--caramel-400);
  animation: caret-blink 1s steps(1) infinite;
}
.typewriter.is-typing + .typewriter__caret,
.typewriter.is-typing .typewriter__caret { animation: none; }

/* Marquee ----------------------------------------------------------------- */
.marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
  display: flex;
  gap: 1.5rem;
  width: max-content;
  animation: marquee var(--marquee-dur, 60s) linear infinite;
}
.marquee:hover .marquee__track, .marquee:focus-within .marquee__track { animation-play-state: paused; }

/* Paw trail divider ------------------------------------------------------- */
.paw-trail { display: flex; justify-content: center; gap: clamp(1rem, 3vw, 2.25rem); padding-block: 1rem; color: var(--caramel-400); }
.paw-trail svg { width: 26px; height: 26px; opacity: 0; }
.paw-trail svg:nth-child(odd) { --r: -18deg; translate: 0 -8px; }
.paw-trail svg:nth-child(even) { --r: 18deg; translate: 0 8px; }
.paw-trail.is-visible svg { animation: paw-step 500ms var(--ease-out) forwards; }
.paw-trail.is-visible svg:nth-child(2) { animation-delay: 180ms; }
.paw-trail.is-visible svg:nth-child(3) { animation-delay: 360ms; }
.paw-trail.is-visible svg:nth-child(4) { animation-delay: 540ms; }
.paw-trail.is-visible svg:nth-child(5) { animation-delay: 720ms; }
.paw-trail.is-visible svg:nth-child(6) { animation-delay: 900ms; }
.no-js .paw-trail svg { opacity: .55; }

/* Reduced motion ---------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal-on [data-reveal] { opacity: 1; translate: none; scale: none; }
  .js .load-in { opacity: 1; animation: none; }
  .marquee__track { animation: none; flex-wrap: wrap; width: auto; justify-content: center; }
  .marquee { -webkit-mask-image: none; mask-image: none; }
  .blob, .floaty, .floaty--slow, .floaty--rotate { animation: none; }
  .scribble path, .title-ornament path { stroke-dashoffset: 0; animation: none; }
  .paw-trail svg { opacity: .55; }
  .typewriter__caret { display: none; }
}

/* Site images (Admin → Site Images) fade in once the right photo is known,
   so visitors never see a placeholder flash. A 2.5s fallback in <head>
   reveals them even if settings can't load. */
.js img[data-slot] { opacity: 0; transition: opacity 600ms var(--ease-out); }
.js.slots-ready img[data-slot] { opacity: 1; }
