/* ============================================================
   ANIMATIONS — Karina Zakharash
   ------------------------------------------------------------
   Reveal classes, hover effects, custom cursor, preloader.
   Every animation has a prefers-reduced-motion fallback.
   All durations/easings reference tokens.css — no magic numbers.
   ============================================================ */

/* ============================================================
   1. REVEAL CLASSES
   IntersectionObserver toggles `.is-visible` to play.
   Initial state hides element; final state is identity.
   ============================================================ */

[class*="ds-reveal"] {
  will-change: transform, opacity, clip-path;
}

/* fade-up */
.ds-reveal-fade-up {
  opacity: 0;
  transform: translate3d(0, 32px, 0);
  transition:
    opacity   var(--ds-dur-slower) var(--ds-ease-decelerate),
    transform var(--ds-dur-slower) var(--ds-ease-luxury);
}
.ds-reveal-fade-up.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* fade-left (enters from left) */
.ds-reveal-fade-left {
  opacity: 0;
  transform: translate3d(-40px, 0, 0);
  transition:
    opacity   var(--ds-dur-slower) var(--ds-ease-decelerate),
    transform var(--ds-dur-slower) var(--ds-ease-luxury);
}
.ds-reveal-fade-left.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* fade-right (enters from right) */
.ds-reveal-fade-right {
  opacity: 0;
  transform: translate3d(40px, 0, 0);
  transition:
    opacity   var(--ds-dur-slower) var(--ds-ease-decelerate),
    transform var(--ds-dur-slower) var(--ds-ease-luxury);
}
.ds-reveal-fade-right.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* scale-in — cinematic image reveal */
.ds-reveal-scale-in {
  opacity: 0;
  transform: scale(1.04);
  transition:
    opacity   var(--ds-dur-cinema) var(--ds-ease-decelerate),
    transform var(--ds-dur-cinema) var(--ds-ease-luxury);
}
.ds-reveal-scale-in.is-visible {
  opacity: 1;
  transform: scale(1);
}

/* mask-reveal-up — clip-path inset rising from bottom */
.ds-reveal-mask-up {
  clip-path: inset(0 0 100% 0);
  transform: translate3d(0, 16px, 0);
  transition:
    clip-path var(--ds-dur-cinema) var(--ds-ease-luxury),
    transform var(--ds-dur-cinema) var(--ds-ease-luxury);
}
.ds-reveal-mask-up.is-visible {
  clip-path: inset(0 0 0 0);
  transform: translate3d(0, 0, 0);
}

/* mask-reveal-left — clip-path inset opening leftward */
.ds-reveal-mask-left {
  clip-path: inset(0 100% 0 0);
  transition: clip-path var(--ds-dur-cinema) var(--ds-ease-luxury);
}
.ds-reveal-mask-left.is-visible {
  clip-path: inset(0 0 0 0);
}

/* Stagger helper — set inline `style="--reveal-delay: 120ms"` */
[class*="ds-reveal"].is-visible {
  transition-delay: var(--reveal-delay, 0ms);
}

/* ============================================================
   2. PHOTO CARD HOVER — gold overlay + scale + caption rise
   Markup:
     <a class="ds-photo-card">
       <div class="ds-photo-card-img"><img src="..." alt=""></div>
       <div class="ds-photo-card-overlay"></div>
       <div class="ds-photo-card-caption">
         <span class="ds-photo-card-eyebrow">FLORENCE</span>
         <span class="ds-photo-card-title">Olena & Dmytro</span>
       </div>
     </a>
   ============================================================ */
.ds-photo-card {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--ds-radius-sm);
  background: var(--ds-neutral-200);
  cursor: pointer;
  isolation: isolate;
}

.ds-photo-card-img {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 5;
}
.ds-photo-card-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1.01);
  transition: transform var(--ds-dur-cinema) var(--ds-ease-luxury),
              filter    var(--ds-dur-slow)   var(--ds-ease-standard);
  -webkit-user-drag: none;
  user-select: none;
  pointer-events: none;
}

.ds-photo-card-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(44, 36, 28, 0) 0%,
    rgba(44, 36, 28, 0) 45%,
    rgba(44, 36, 28, 0.55) 100%
  );
  opacity: 0;
  transition: opacity var(--ds-dur-slow) var(--ds-ease-standard);
  pointer-events: none;
  z-index: 1;
}

/* Gold wash — applies on hover */
.ds-photo-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ds-overlay-gold);
  mix-blend-mode: multiply;
  opacity: 0;
  transition: opacity var(--ds-dur-slow) var(--ds-ease-standard);
  pointer-events: none;
  z-index: 1;
}

.ds-photo-card-caption {
  position: absolute;
  left: var(--ds-space-5);
  right: var(--ds-space-5);
  bottom: var(--ds-space-5);
  z-index: 2;
  color: var(--ds-text-inverse);
  transform: translate3d(0, 12px, 0);
  opacity: 0;
  transition:
    transform var(--ds-dur-slow) var(--ds-ease-luxury),
    opacity   var(--ds-dur-slow) var(--ds-ease-decelerate);
  pointer-events: none;
}
.ds-photo-card-eyebrow {
  display: block;
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-micro);
  letter-spacing: var(--ds-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--ds-accent-on-dark);
  margin-bottom: var(--ds-space-2);
}
.ds-photo-card-title {
  display: block;
  font-family: var(--ds-font-display);
  font-size: var(--ds-text-h3);
  font-weight: var(--ds-fw-light);
  line-height: var(--ds-lh-heading);
  font-style: italic;
}

/* Hover (and keyboard focus) */
.ds-photo-card:hover .ds-photo-card-img img,
.ds-photo-card:focus-visible .ds-photo-card-img img {
  transform: scale(1.06);
}
.ds-photo-card:hover .ds-photo-card-overlay,
.ds-photo-card:focus-visible .ds-photo-card-overlay {
  opacity: 1;
}
.ds-photo-card:hover::before,
.ds-photo-card:focus-visible::before {
  opacity: 1;
}
.ds-photo-card:hover .ds-photo-card-caption,
.ds-photo-card:focus-visible .ds-photo-card-caption {
  transform: translate3d(0, 0, 0);
  opacity: 1;
}
.ds-photo-card:focus-visible {
  outline: 2px solid var(--ds-accent);
  outline-offset: 4px;
}

/* ============================================================
   3. CUSTOM CURSOR — desktop, fine pointer only
   Two layers: dot (instant) + ring (lerped via JS).
   Add `.ds-has-cursor` to <html> after JS init.
   ============================================================ */
.ds-cursor-dot,
.ds-cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: var(--ds-z-cursor);
  border-radius: 50%;
  transform: translate3d(-50%, -50%, 0);
  opacity: 0;
  transition: opacity var(--ds-dur-fast) var(--ds-ease-standard);
  mix-blend-mode: difference;
}
.ds-cursor-dot {
  width: 6px;
  height: 6px;
  background: var(--ds-neutral-50);
}
.ds-cursor-ring {
  width: 36px;
  height: 36px;
  border: 1px solid var(--ds-neutral-50);
  transition:
    opacity   var(--ds-dur-fast) var(--ds-ease-standard),
    width     var(--ds-dur-normal) var(--ds-ease-standard),
    height    var(--ds-dur-normal) var(--ds-ease-standard),
    border-color var(--ds-dur-normal) var(--ds-ease-standard);
}
.ds-has-cursor .ds-cursor-dot,
.ds-has-cursor .ds-cursor-ring { opacity: 1; }
.ds-has-cursor { cursor: none; }
.ds-has-cursor a,
.ds-has-cursor button,
.ds-has-cursor [role="button"],
.ds-has-cursor input,
.ds-has-cursor textarea { cursor: none; }

/* Magnetic state — when hovering interactive elements */
.ds-cursor-ring.is-magnetic {
  width: 60px;
  height: 60px;
  border-color: var(--ds-accent);
}
.ds-cursor-ring.is-view {
  width: 84px;
  height: 84px;
  background: rgba(184, 153, 104, 0.15);
  border-color: transparent;
}

/* Hide on touch / coarse pointers */
@media (hover: none), (pointer: coarse) {
  .ds-cursor-dot,
  .ds-cursor-ring { display: none; }
  .ds-has-cursor,
  .ds-has-cursor a,
  .ds-has-cursor button { cursor: auto; }
}

/* ============================================================
   4. PRELOADER — brand logo + gold hairline draw
   Markup:
     <div class="ds-preloader" id="dsPreloader">
       <div class="ds-preloader-mark">
         <span class="ds-preloader-name">Каріна <em>Захараш</em></span>
         <span class="ds-preloader-line"></span>
         <span class="ds-preloader-meta">Wedding Photographer</span>
       </div>
     </div>
   JS removes `.ds-preloader` or adds `.is-loaded` after window.load.
   ============================================================ */
.ds-preloader {
  position: fixed;
  inset: 0;
  z-index: var(--ds-z-preloader);
  background: var(--ds-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    opacity var(--ds-dur-slow) var(--ds-ease-standard),
    visibility 0s linear var(--ds-dur-slow);
}
.ds-preloader.is-loaded {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.ds-preloader-mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ds-space-4);
}
.ds-preloader-name {
  font-family: var(--ds-font-display);
  font-size: var(--ds-text-h2);
  font-weight: var(--ds-fw-light);
  letter-spacing: var(--ds-tracking-wide);
  color: var(--ds-text);
  opacity: 0;
  transform: translateY(12px);
  animation: dsPreloaderFadeIn var(--ds-dur-slower) var(--ds-ease-decelerate) 80ms forwards;
}
.ds-preloader-name em {
  font-style: italic;
  color: var(--ds-accent);
}
.ds-preloader-line {
  display: block;
  width: 0;
  height: 1px;
  background: var(--ds-accent);
  animation: dsPreloaderLine 1100ms var(--ds-ease-luxury) 240ms forwards;
}
.ds-preloader-meta {
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-micro);
  font-weight: var(--ds-fw-medium);
  letter-spacing: var(--ds-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--ds-text-muted);
  opacity: 0;
  animation: dsPreloaderFadeIn var(--ds-dur-slow) var(--ds-ease-decelerate) 600ms forwards;
}

@keyframes dsPreloaderFadeIn {
  to { opacity: 1; transform: translateY(0); }
}
@keyframes dsPreloaderLine {
  to { width: 96px; }
}

/* ============================================================
   5. UTILITY ANIMATIONS — subtle, optional
   ============================================================ */

/* Scroll-down indicator (gentle bob) */
.ds-scroll-indicator {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ds-space-2);
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-micro);
  letter-spacing: var(--ds-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--ds-text-muted);
  animation: dsScrollBob 2.6s var(--ds-ease-standard) infinite;
}
.ds-scroll-indicator::after {
  content: "";
  width: 1px;
  height: 32px;
  background: linear-gradient(
    180deg,
    var(--ds-accent) 0%,
    transparent 100%
  );
}
@keyframes dsScrollBob {
  0%, 100% { transform: translateY(0); opacity: 0.7; }
  50%      { transform: translateY(6px); opacity: 1; }
}

/* Soft pulse — for "now booking" badges */
.ds-pulse {
  position: relative;
}
.ds-pulse::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: inherit;
  border: 1px solid var(--ds-accent);
  opacity: 0;
  animation: dsPulse 2.4s var(--ds-ease-standard) infinite;
}
@keyframes dsPulse {
  0%   { transform: scale(0.9); opacity: 0.6; }
  100% { transform: scale(1.15); opacity: 0; }
}

/* Underline draw on hover (links) */
.ds-link-draw {
  position: relative;
  display: inline-block;
  color: inherit;
}
.ds-link-draw::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: var(--ds-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--ds-dur-slow) var(--ds-ease-luxury);
}
.ds-link-draw:hover::after,
.ds-link-draw:focus-visible::after {
  transform: scaleX(1);
}

/* Image parallax wrapper (JS sets --parallax-y from scroll) */
.ds-parallax {
  overflow: hidden;
}
.ds-parallax-inner {
  transform: translate3d(0, var(--parallax-y, 0), 0) scale(1.08);
  will-change: transform;
}

/* ============================================================
   5b. SCREEN-READER ONLY UTILITY
   Visually hides an element while keeping it in the a11y tree.
   .sr-only-focusable:focus reveals the element at top-left.
   ============================================================ */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.sr-only-focusable:focus {
  position: fixed;
  top: 0;
  left: 0;
  width: auto;
  height: auto;
  padding: 8px 16px;
  margin: 0;
  overflow: visible;
  clip: auto;
  white-space: normal;
  background: var(--ds-ink, #1a1612);
  color: var(--ds-bone, #f4f0e8);
  font-family: var(--ds-font-body, sans-serif);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  border: 0;
  outline: 2px solid var(--ds-gold-600, #9b7f53);
  outline-offset: 0;
  z-index: 99999;
}

/* ============================================================
   5c. GLOBAL FOCUS-VISIBLE RING
   One rule to cover all interactive elements.
   Gold ring (#9b7f53 = ds-gold-600) on 2px offset — AA on all
   site backgrounds. Pairs with outline: none removal in style.css.
   ============================================================ */
:focus-visible {
  outline: 2px solid var(--ds-gold-600, #9b7f53);
  outline-offset: 2px;
}

/* When browser doesn't support :focus-visible, suppress default
   only on elements that have explicit :focus styles already.
   We do NOT suppress focus globally — only where the gold ring
   serves as replacement. */
.booking-form .form-group input:focus,
.booking-form .form-group textarea:focus,
.booking-form .form-group select:focus,
.form-input:focus,
.admin-service-card input:focus,
.admin-service-card textarea:focus,
.admin-testimonial-card input:focus,
.admin-testimonial-card textarea:focus,
.admin-settings-section input:focus,
.admin-about-section textarea:focus,
.admin-about-section input:focus {
  outline: none; /* border-color change in style.css is the visible indicator */
}

/* ============================================================
   6. REDUCED MOTION — neutralize everything cleanly
   Each pattern above has a fallback here. We keep `is-visible`
   end-states intact so content is always readable.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {

  [class*="ds-reveal"] {
    opacity: 1;
    transform: none;
    clip-path: none;
    transition: none;
  }

  .ds-photo-card-img img,
  .ds-photo-card-overlay,
  .ds-photo-card::before,
  .ds-photo-card-caption {
    transition: none;
  }
  .ds-photo-card:hover .ds-photo-card-img img,
  .ds-photo-card:focus-visible .ds-photo-card-img img {
    transform: none;
  }
  .ds-photo-card-caption {
    transform: none;
    opacity: 1;
    background: linear-gradient(
      0deg,
      rgba(44, 36, 28, 0.65),
      rgba(44, 36, 28, 0) 80%
    );
    padding-top: var(--ds-space-9);
  }

  .ds-cursor-dot,
  .ds-cursor-ring { display: none; }
  .ds-has-cursor,
  .ds-has-cursor a,
  .ds-has-cursor button { cursor: auto; }

  .ds-preloader { transition: opacity 1ms linear, visibility 0s linear 1ms; }
  .ds-preloader-name,
  .ds-preloader-line,
  .ds-preloader-meta {
    animation: none;
    opacity: 1;
    transform: none;
    width: 96px;
  }

  .ds-scroll-indicator,
  .ds-pulse::after,
  .ds-kinetic-word,
  .ds-kinetic-char {
    animation: none;
    transition: none;
    transform: none;
    opacity: 1;
  }

  .ds-link-draw::after { transform: scaleX(1); }

  .ds-parallax-inner {
    transform: none;
  }

  *,
  *::before,
  *::after {
    animation-duration: 1ms;
    animation-iteration-count: 1;
    transition-duration: 1ms;
    scroll-behavior: auto;
  }
}
