/* ==========================================================================
   malikrahmouni.com — motion layer
   --------------------------------------------------------------------------
   Additive layer over the Pixieset "flex" theme. Nothing here edits the
   vendored theme; every rule is scoped so that if motion.js never boots,
   the site renders exactly as it did before.

   Gating classes (added to <html>):
     .mrx-ready  set by the inline head script before first paint, removed
                 by a failsafe if motion.js never boots. ALL hiding depends
                 on it, so a JS failure can never leave the page blank.
     .mrx-fx     hover micro-interactions          (CONFIG.microInteractions)
     .mrx-hdr    sticky hide-on-scroll header      (CONFIG.stickyHeader)

   Element ownership — deliberately kept apart so nothing fights:
     .fb-element                       theme's rotate() — NEVER touched here
     .fb-element__content              reveal: opacity / translateY / clip-path
     .fb-element-type-image            hover zoom on linked images
     .fb-element-type-image__img-wrapper   reveal: scale
     img...__img                       parallax only (inline, JS-owned)
   ========================================================================== */

:root {
  /* Slow and confident — wedding photography is timeless, not urgent. */
  --mrx-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --mrx-dur-text: 900ms;
  --mrx-dur-image: 1100ms;
  --mrx-dur-soft: 700ms;
  --mrx-dur-grid: 900ms;
  --mrx-delay: 0ms;
}

/* --------------------------------------------------------------------------
   1. Scroll reveals
   Only opacity / small transform / clip-path are used. The theme lazily
   initialises its own components (menu, lightbox, image grids, back-to-top)
   with IntersectionObserver, and those observers are purely geometric —
   opacity and clip-path do not affect them, and a 24px shift is negligible
   against their 100px rootMargin. visibility/display would break them.
   -------------------------------------------------------------------------- */

html.mrx-ready [data-mrx] {
  transition-delay: var(--mrx-delay, 0ms);
  transition-timing-function: var(--mrx-ease);
}

/* text ------------------------------------------------------------------- */
html.mrx-ready [data-mrx="text"] {
  transition-property: opacity, transform;
  transition-duration: var(--mrx-dur-text);
}
html.mrx-ready [data-mrx="text"]:not([data-mrx-in]) {
  opacity: 0;
  transform: translateY(24px);
}

/* soft: buttons, shapes, lines, social links ------------------------------ */
html.mrx-ready [data-mrx="soft"] {
  transition-property: opacity, transform;
  transition-duration: var(--mrx-dur-soft);
}
html.mrx-ready [data-mrx="soft"]:not([data-mrx-in]) {
  opacity: 0;
  transform: translateY(16px);
}

/* image: the photograph is unveiled, not faded ---------------------------- */
html.mrx-ready [data-mrx="image"] {
  transition-property: clip-path;
  transition-duration: var(--mrx-dur-image);
}
html.mrx-ready [data-mrx="image"]:not([data-mrx-in]) {
  clip-path: inset(0 0 100% 0);
}
html.mrx-ready [data-mrx="image"] .fb-element-type-image__img-wrapper {
  transition: transform calc(var(--mrx-dur-image) * 1.15) var(--mrx-ease) var(--mrx-delay, 0ms);
}
html.mrx-ready [data-mrx="image"]:not([data-mrx-in]) .fb-element-type-image__img-wrapper {
  transform: scale(1.08);
}

/* gallery grid items ------------------------------------------------------
   The grid container ships inline opacity:0 and reveals itself after Masonry
   settles — never touched here. Only its children animate, and only after
   that reveal has happened. */
html.mrx-ready [data-mrx="grid"] {
  transition-property: opacity, transform;
  transition-duration: var(--mrx-dur-grid);
}
html.mrx-ready [data-mrx="grid"]:not([data-mrx-in]) {
  opacity: 0;
  transform: scale(1.06);
}

/* --------------------------------------------------------------------------
   2. Parallax
   JS writes the transform inline on the <img>. This element is reserved for
   parallax alone so nothing else can clobber it.
   -------------------------------------------------------------------------- */
html.mrx-ready img[data-mrx-parallax] {
  will-change: auto;
}
html.mrx-ready img[data-mrx-parallax][data-mrx-active] {
  will-change: transform;
}

/* --------------------------------------------------------------------------
   3. Hover micro-interactions
   NOTE: the theme ships <style class="js-dom-cleanup"> with
   `a { transition: none !important }`. Two ways round it, both used below:
     - ::after pseudo-elements, which that rule does not match at all
     - higher specificity + !important for the button itself
   -------------------------------------------------------------------------- */

/* nav underline, wiping in from the left */
html.mrx-fx .navigation__link.js-menu-link {
  position: relative;
}
html.mrx-fx .navigation__link.js-menu-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.18em;
  height: 1px;
  background: currentColor;
  opacity: 0.75;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 500ms var(--mrx-ease);
}
html.mrx-fx .navigation__link.js-menu-link:hover::after,
html.mrx-fx .navigation__item--active > .navigation__link-group > .navigation__link.js-menu-link::after {
  transform: scaleX(1);
}
/* the dropdown +/- icon link is not a nav destination — no underline */
html.mrx-fx .navigation__link:not(.js-menu-link)::after {
  content: none;
}

/* buttons: specificity (0,2,1) beats the `a` cleanup rule (0,0,1) */
html.mrx-fx .fb-element--button a.ps-button {
  transition: transform 450ms var(--mrx-ease), opacity 300ms ease-out !important;
}
html.mrx-fx .fb-element--button a.ps-button:hover {
  transform: translateY(-2px);
}
html.mrx-fx .fb-element--button a.ps-button:active {
  transform: translateY(0);
}

/* linked images: gentle zoom + the theme's own scrim lifting.
   Applied to .fb-element-type-image (a div, so unaffected by the `a` rule),
   clipped by .fb-element__content which is already overflow:hidden. */
html.mrx-fx .fb-element-type-image--link {
  transition: transform 600ms var(--mrx-ease);
}
html.mrx-fx .fb-element-type-image--link:hover {
  transform: scale(1.04);
}
html.mrx-fx .fb-element-type-image--link .fb-element-type-image__overlay {
  transition: opacity 600ms var(--mrx-ease);
}
html.mrx-fx .fb-element-type-image--link:hover .fb-element-type-image__overlay {
  opacity: 0.12;
}

/* gallery thumbnails. The <img> itself carries PhotoSwipe's click handler —
   we only ever change its transform, never its position in the DOM. */
html.mrx-fx .fb-element-type-image-grid__image-wrapper {
  overflow: hidden;
}
html.mrx-fx .fb-element-type-image-grid__image-wrapper img.fb-element-type-image-grid__image {
  transition: transform 700ms var(--mrx-ease);
}
html.mrx-fx .fb-element-type-image-grid__image-wrapper:hover img.fb-element-type-image-grid__image {
  transform: scale(1.04);
}

/* --------------------------------------------------------------------------
   4. Sticky hide-on-scroll header
   The theme already provides `position: sticky` via its own .sticky-header
   class (enabled in the markup). Because it stays in normal flow there is no
   overlay and no layout shift, so the mobile menu keeps positioning normally.
   All we add is a transform.
   -------------------------------------------------------------------------- */
html.mrx-hdr div[role="banner"].sticky-header {
  z-index: 90;
  transition: transform 400ms var(--mrx-ease);
}
html.mrx-hdr div[role="banner"].sticky-header[data-mrx-hidden="1"] {
  transform: translateY(-100%);
}
/* Safety net: whenever the mobile menu is open the header must never move,
   even if the JS guard were bypassed. */
html.ps-no-scroll div[role="banner"].sticky-header,
html.mrx-menu-open div[role="banner"].sticky-header {
  transform: none !important;
}

/* --------------------------------------------------------------------------
   5. Page transitions
   Native cross-document View Transitions. Right tool for a multi-page static
   site: no JS, so Masonry / PhotoSwipe / Swiper are never re-initialised by
   hand, and the back button keeps working. Browsers without it (Firefox) get
   instant navigation plus the entry fade below.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 420ms;
  animation-timing-function: var(--mrx-ease);
}

/* Page entry fade — covers browsers with no view transitions, and the first
   arrival on the site. JS suppresses it when a view transition already ran. */
html.mrx-ready.mrx-enter .theme-container {
  animation: mrx-fade-in 600ms var(--mrx-ease) both;
}
@keyframes mrx-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --------------------------------------------------------------------------
   6. Reduced motion
   The theme has essentially no reduced-motion coverage, so this is ours.
   Everything resolves to its final state instantly.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html.mrx-ready [data-mrx],
  html.mrx-ready [data-mrx]:not([data-mrx-in]) {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }
  html.mrx-ready [data-mrx]:not([data-mrx-in]) .fb-element-type-image__img-wrapper {
    transform: none !important;
    transition: none !important;
  }
  html.mrx-ready img[data-mrx-parallax] {
    transform: none !important;
    will-change: auto !important;
  }
  html.mrx-hdr div[role="banner"].sticky-header {
    transition: none !important;
    transform: none !important;
  }
  html.mrx-ready.mrx-enter .theme-container {
    animation: none !important;
  }
  html.mrx-fx *,
  html.mrx-fx *::after {
    transition: none !important;
  }
}

/* --------------------------------------------------------------------------
   7. Heading semantics without visual change
   The theme sizes body text with TAG-BOUND selectors — e.g.
   `.element-text p.ql-pullquote { font-size: var(--pullquote_font-size) }`.
   Converting such a <p> into the <h1> the page needs would drop that rule and
   fall back to Bootstrap's `h1 { font-size: 3.125rem }`, which measured as a
   20px -> 45px jump. These rules re-declare the p behaviour for the converted
   h1 so the swap is purely semantic.
   `ql-pullquote` is the only class with its own tag-bound size; every other
   text class simply inherits from .text__text, which `inherit` reproduces.
   -------------------------------------------------------------------------- */
.element-text h1.mrx-h1 {
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  margin-bottom: 0;
}
@media screen and (orientation: portrait) {
  .element-text h1.mrx-h1.ql-pullquote { font-size: var(--pullquote_font-size-small); }
}
@media screen and (orientation: landscape) {
  .element-text h1.mrx-h1.ql-pullquote { font-size: var(--pullquote_font-size); }
}
@media screen and (min-width: 1441px) {
  .element-text h1.mrx-h1.ql-pullquote { font-size: var(--pullquote_font-size-large); }
}
