/* Painter's Theme 3.0 — unified direction-safe motion lifecycle.
   Scroll reveals, navigation transitions and interface motion are intentionally
   kept separate so each system has one source of truth. */
@view-transition {
  navigation: auto;
}

:root {
  --lf-motion-distance: 48px;
  --lf-motion-duration: 940ms;
  --lf-motion-fade-duration: 710ms;
  --lf-motion-ease: cubic-bezier(.16,1,.3,1);
  --lf-lightbox-swap-duration: 800ms;
  --lf-lightbox-overlay-duration: 620ms;
  --lf-header-duration: 620ms;
  --lf-page-exit-duration: 180ms;
  --lf-page-transition-duration: 520ms;
  --lf-page-transition-ease: cubic-bezier(.16,1,.3,1);
}

/* Native cross-document transitions: same-origin navigation is handled by the
   browser. Unsupported browsers use the JavaScript fallback below. */
::view-transition-group(root) {
  animation-duration: var(--lf-page-transition-duration);
  animation-timing-function: var(--lf-page-transition-ease);
}
::view-transition-old(root) {
  animation: lf-view-out var(--lf-page-transition-duration) var(--lf-page-transition-ease) both;
}
::view-transition-new(root) {
  animation: lf-view-in var(--lf-page-transition-duration) var(--lf-page-transition-ease) both;
}
@keyframes lf-view-out {
  from { opacity:1; transform:translate3d(0,0,0); }
  to { opacity:0; transform:translate3d(0,-4px,0); }
}
@keyframes lf-view-in {
  from { opacity:0; transform:translate3d(0,6px,0); }
  to { opacity:1; transform:translate3d(0,0,0); }
}

/* Non-View-Transition fallback. The arrival class is applied early in <head>
   for same-origin navigations/back-forward restores, so content does not flash
   visible before the reveal observer is initialized. */
html.lf-page-arriving body {
  opacity:0;
}
html.lf-page-arrived body {
  opacity:1;
  transition:opacity 420ms var(--lf-page-transition-ease);
}
html.lf-page-leaving body {
  opacity:0;
  transition:opacity 180ms var(--lf-page-transition-ease);
}

/* First-paint state: targeted content is hidden before initial paint. JS then
   upgrades every selected target to .lf-motion-item before releasing this state. */
html.lf-motion-pending .works-grid > .work-card:not(.lf-motion-item),
html.lf-motion-pending .work-single > .work-hero-link:not(.lf-motion-item),
html.lf-motion-pending .work-single > .work-details > div:not(.lf-motion-item),
html.lf-motion-pending .work-single > .work-gallery .work-gallery-item:not(.lf-motion-item),
html.lf-motion-pending .work-single > .work-navigation:not(.lf-motion-item),
html.lf-motion-pending .journal-entry .entry-lead:not(.lf-motion-item),
html.lf-motion-pending .journal-entry .entry-main > div:first-child > .journal-meta:not(.lf-motion-item),
html.lf-motion-pending .journal-entry .entry-main > div:first-child > .entry-title:not(.lf-motion-item),
html.lf-motion-pending .journal-entry .entry-main > .journal-post-summary:not(.lf-motion-item),
html.lf-motion-pending .archive-wrap > .page-header:not(.lf-motion-item),
html.lf-motion-pending .archive-wrap > .journal-entry > .entry-date:not(.lf-motion-item),
html.lf-motion-pending .fallback-entry > .entry-header:not(.lf-motion-item),
html.lf-motion-pending .fallback-entry > .entry-content:not(.lf-motion-item),
html.lf-motion-pending .editorial-layout > .editorial-heading:not(.lf-motion-item),
html.lf-motion-pending .editorial-layout > .editorial-text:not(.lf-motion-item),
html.lf-motion-pending .editorial-layout > .editorial-hero:not(.lf-motion-item),
html.lf-motion-pending .exhibition-layout > .exhibition-text:not(.lf-motion-item),
html.lf-motion-pending .exhibition-layout > .exhibition-hero:not(.lf-motion-item),
html.lf-motion-pending .exhibition-left > .exhibition-heading:not(.lf-motion-item),
html.lf-motion-pending .exhibition-events > .exhibition-event:not(.lf-motion-item),
html.lf-motion-pending .exhibition-events > .exhibition-event-credit:not(.lf-motion-item),
html.lf-motion-pending .post-single > .post-header:not(.lf-motion-item),
html.lf-motion-pending .post-single > .post-content > .post-featured-image:not(.lf-motion-item),
html.lf-motion-pending .post-single > .post-content > *:not(.post-featured-image):not(.lf-motion-item),
html.lf-motion-pending .post-single > .post-pagination:not(.lf-motion-item),
html.lf-motion-pending .exhibition-single > .post-pagination:not(.lf-motion-item),
html.lf-motion-pending .editorial-single > .post-pagination:not(.lf-motion-item),
html.lf-motion-pending .page-wrap > .page-header:not(.lf-motion-item),
html.lf-motion-pending .page-wrap > .page-content:not(.vita-content):not(.info-layout) > *:not(.lf-motion-item),
html.lf-motion-pending .page-wrap > p:not(.lf-motion-item),
html.lf-motion-pending .info-layout > .info-intro > *:not(.lf-motion-item),
html.lf-motion-pending .info-layout > .info-image:not(.lf-motion-item),
html.lf-motion-pending .info-layout > .info-contact-block > .info-contact-items > .info-item:not(.lf-motion-item),
html.lf-motion-pending .vita-content > .vita-intro > .vita-row:not(.lf-motion-item),
html.lf-motion-pending .vita-content > .vita-section > .lf-managed-section-heading:not(.lf-motion-item),
html.lf-motion-pending .vita-content > .vita-section > .vita-row:not(.lf-motion-item),
html.lf-motion-pending .site-footer:not(.lf-motion-item) {
  opacity:0;
  transform:translate3d(0,var(--lf-motion-distance),0);
}

/* The hidden/armed state never animates. Once completely outside the
   viewport an element is reset instantly, not dragged back across the screen.
   An entering item gets exactly one transition from its correct side. */
.lf-motion-enabled .lf-motion-item {
  opacity:0;
  transform:translate3d(0,var(--lf-motion-distance),0);
  transition:none;
}
.lf-motion-enabled .lf-motion-item.lf-reveal-reverse {
  transform:translate3d(0,calc(-1 * var(--lf-motion-distance)),0);
}
.lf-motion-enabled .lf-motion-item.lf-reveal-visible {
  opacity:1;
  transform:translate3d(0,0,0);
  transition:opacity var(--lf-motion-fade-duration) var(--lf-motion-ease),
             transform var(--lf-motion-duration) var(--lf-motion-ease);
  transition-delay:var(--lf-motion-delay,0ms);
}
/* Initial viewport belongs to the page entrance, not to scroll reveal. */
.lf-motion-enabled .lf-motion-item.lf-reveal-visible.lf-reveal-instant {
  transition:none;
  transition-delay:0ms;
}
.lf-motion-enabled .lf-motion-item.lf-motion-active {
  will-change:opacity,transform;
}

/* Footer inherits the same reveal transitions; no parallel implementation. */

/* Lightbox: one buffered image slides/fades against the other; no src swapping
   on the visible image during an animation. */
.lf-lightbox {
  opacity:0;
  transition:opacity var(--lf-lightbox-overlay-duration) var(--lf-motion-ease);
}
.lf-lightbox.is-open { opacity:1; }
.lf-lightbox.is-closing { opacity:0; }
.lf-lightbox-stage { overflow:hidden; }
.lf-lightbox-stage .lf-lightbox-image {
  transition:opacity var(--lf-lightbox-swap-duration) var(--lf-motion-ease), transform var(--lf-lightbox-swap-duration) var(--lf-motion-ease);
}
.lf-lightbox-stage .lf-lightbox-image.lf-motion-active {
  will-change:opacity,transform;
}
.lf-lightbox-stage .lf-lightbox-image-current {
  position:relative;
  z-index:2;
  opacity:1;
  transform:translate3d(0,0,0);
}
.lf-lightbox-stage .lf-lightbox-image-next {
  position:absolute;
  inset:0;
  z-index:1;
  width:100%;
  height:100%;
  opacity:0;
  transform:translate3d(clamp(48px,6vw,92px),0,0);
  object-fit:contain;
  object-position:center;
  pointer-events:none;
}
.lf-lightbox-stage.is-sliding-next .lf-lightbox-image-current,
.lf-lightbox-stage.is-sliding-prev .lf-lightbox-image-current { opacity:0; }
.lf-lightbox-stage.is-sliding-next .lf-lightbox-image-current { transform:translate3d(clamp(-92px,-6vw,-48px),0,0); }
.lf-lightbox-stage.is-sliding-next .lf-lightbox-image-next { opacity:1; transform:translate3d(0,0,0); }
.lf-lightbox-stage.is-sliding-prev .lf-lightbox-image-current { transform:translate3d(clamp(48px,6vw,92px),0,0); }
.lf-lightbox-stage.is-sliding-prev .lf-lightbox-image-next { opacity:1; transform:translate3d(0,0,0); }
.lf-lightbox-caption { transition:opacity 420ms var(--lf-motion-ease), transform 420ms var(--lf-motion-ease); }
.lf-lightbox-caption.is-changing { opacity:0; transform:translate3d(0,4px,0); }

/* Scroll-reactive header. will-change is enabled only while the header is moving. */
.site-header {
  position:sticky;
  top:0;
  z-index:2000;
  background:#fff;
  transition:transform var(--lf-header-duration) var(--lf-motion-ease);
}
.site-header.lf-header-moving { will-change:transform; }
html.lf-header-hidden .site-header {
  transform:translate3d(0,-105%,0);
}
html.lf-menu-open .site-header {
  transform:translate3d(0,0,0) !important;
}

@media (prefers-reduced-motion:reduce) {
  ::view-transition-group(root),
  ::view-transition-old(root),
  ::view-transition-new(root) { animation:none !important; }
  html.lf-page-arriving body,
  html.lf-page-arrived body,
  html.lf-page-leaving body { opacity:1 !important; transition:none !important; }
  .lf-motion-enabled .lf-motion-item,
  .lf-motion-enabled .lf-motion-item.lf-reveal-visible,
  .lf-motion-enabled .site-footer.lf-motion-item,
  .lf-motion-enabled .site-footer.lf-motion-item.lf-reveal-visible {
    opacity:1 !important;
    transform:none !important;
    transition:none !important;
  }
  .site-header,
  .lf-lightbox,
  .lf-lightbox-stage .lf-lightbox-image,
  .lf-lightbox-caption { transition:none !important; }
}
