/* Motion — SOURCE, not generated. Paired with assets/js/motion.js.
 *
 * Every rule is scoped under html.mo, which motion.js adds only when motion is
 * allowed. Without it (script blocked, reduced motion, old browser) nothing in
 * this file applies and the page renders exactly as it did before.
 *
 * One curve, two tempos: expo-out everywhere; reveals ~1s, feedback ~0.25s.
 * Short travel: the page must look finished if every animation stopped halfway.
 */
.mo {
  --mo-ease: cubic-bezier(.16, 1, .3, 1);
  --mo-rise: 28px;
}

/* ---- rise: blocks, cards, paragraphs ---- */
.mo [data-mo="rise"] {
  transition: opacity .9s var(--mo-ease), translate 1.1s var(--mo-ease);
  transition-delay: calc(var(--mo-i, 0) * 90ms);
}
.mo [data-mo="rise"]:not([data-mo-in]) { opacity: 0; translate: 0 var(--mo-rise); }

/* ---- head: section headings wipe up from a mask ----
   The open state overshoots the box on every side: Rouge Script's swashes
   and descenders hang outside the line box and must never be clipped. */
.mo [data-mo="head"] {
  clip-path: inset(-20% -12% -35% -12%);
  transition: opacity 1s var(--mo-ease), translate 1.15s var(--mo-ease), clip-path 1.15s var(--mo-ease);
  transition-delay: calc(var(--mo-i, 0) * 90ms);
}
.mo [data-mo="head"]:not([data-mo-in]) { opacity: 0; translate: 0 .35em; clip-path: inset(-20% -12% 100% -12%); }

/* ---- crop: photos open from a soft crop, then the image settles ----
   --mo-r keeps the container's corner radius through the crop; --mo-open lets
   a photo with an outside shadow (the story portrait) open past its box. */
.mo [data-mo="crop"] {
  clip-path: var(--mo-open, inset(0 round var(--mo-r, 0px)));
  transition: clip-path 1.4s var(--mo-ease);
  transition-delay: calc(var(--mo-i, 0) * 90ms);
}
.mo [data-mo="crop"]:not([data-mo-in]) { clip-path: inset(8% 6% round var(--mo-r, 0px)); }
/* !important only to beat the gallery's inline `transition: transform`, which
   would otherwise make the settle jump. transform stays listed so the hover
   zoom keeps its easing. */
.mo [data-mo="crop"] img {
  transition: scale 1.8s var(--mo-ease) calc(var(--mo-i, 0) * 90ms), transform var(--dur-slow) var(--ease-soft) !important;
}
.mo [data-mo="crop"]:not([data-mo-in]) img { scale: 1.12; }

/* ---- draw: brass dividers draw out from their centre ---- */
.mo [data-mo="draw"] {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.3s var(--mo-ease);
  transition-delay: calc(var(--mo-i, 0) * 90ms + .15s);
}
.mo [data-mo="draw"]:not([data-mo-in]) { clip-path: inset(0 50% 0 50%); }

/* ---- palm: the footer palm draws itself, stroke by stroke ---- */
.mo [data-mo="palm"] path {
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.6s var(--mo-ease);
  transition-delay: calc(var(--mo-p, 0) * 110ms);
}
.mo [data-mo="palm"]:not([data-mo-in]) path { stroke-dashoffset: 1; }
.mo [data-mo="palm"] circle { transition: opacity .8s var(--mo-ease) .9s; }
.mo [data-mo="palm"]:not([data-mo-in]) circle { opacity: 0; }

/* ---- hero photo settles as the names are written (never faded: it is the LCP) ---- */
@keyframes mo-settle { from { scale: 1.06; } to { scale: 1; } }
.mo .hero-intro .hero-img { animation: mo-settle 2.4s var(--mo-ease) both; }

/* Printing a page mid-reveal must not print blanks. */
@media print {
  .mo [data-mo] { opacity: 1 !important; translate: none !important; clip-path: none !important; }
  .mo [data-mo] img { scale: none !important; }
}
