/*
 * aj-motion.css — AJ Construction motion layer
 * Scroll reveals · hover states · magnetic CTA · marquee · spotlight
 * No GSAP, no Framer. Pure CSS + one IntersectionObserver.
 */

/* ── 0. Reduced-motion safety net (always first) ───────────────────── */
@media (prefers-reduced-motion: reduce) {
  .aj-rev,
  .aj-rev--in          { opacity: 1 !important; transform: none !important; transition: none !important; }
  .aj-clip,
  .aj-clip--in,
  .aj-clip-up,
  .aj-clip-up--in      { clip-path: none !important; transition: none !important; }
  .aj-word span        { transform: none !important; opacity: 1 !important; transition: none !important; }
  .aj-marquee-track    { animation: none !important; }
  .aj-tilt,
  [data-tilt]          { transform: none !important; transition: none !important; }
  .aj-magnet           { transform: none !important; }
  .aj-float            { animation: none !important; }
  .ajcs-hero,
  .aj-view-enter       { animation: none !important; opacity: 1 !important; transform: none !important; }
  *                    { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ── 1. Scroll reveal — .aj-rev / .aj-rev--in ──────────────────────── */
/*
 * Elements start invisible + shifted up 24px.
 * IntersectionObserver adds .aj-rev--in to trigger the reveal.
 * Stagger delays: .d1 .d2 .d3 .d4
 */
.aj-rev {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.65s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.65s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform;
}

.aj-rev--in {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger delays */
.aj-rev.d1 { transition-delay: 0.08s; }
.aj-rev.d2 { transition-delay: 0.16s; }
.aj-rev.d3 { transition-delay: 0.24s; }
.aj-rev.d4 { transition-delay: 0.36s; }

/* ── 2. Card lift — .aj-tilt ────────────────────────────────────────── */
.aj-tilt {
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 0.25s ease;
}
.aj-tilt:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.35);
}

/* ── 3. Image zoom on hover — .aj-img-zoom ──────────────────────────── */
/*
 * Wrap an <img> or <figure> with .aj-img-zoom.
 * The child image scales on hover.
 */
.aj-img-zoom { overflow: hidden; }
.aj-img-zoom img,
.aj-img-zoom figure { transition: transform 0.55s cubic-bezier(0.25, 0.46, 0.45, 0.94); }
.aj-img-zoom:hover img,
.aj-img-zoom:hover figure { transform: scale(1.06); }

/* ── 4. Underline-from-right — .aj-ul ───────────────────────────────── */
.aj-ul {
  position: relative;
  display: inline;
  text-decoration: none;
}
.aj-ul::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  right: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.aj-ul:hover::after,
a:hover .aj-ul::after {
  transform: scaleX(1);
  transform-origin: left center;
}

/* ── 5. CTA with sliding arrow — .aj-cta + .aj-arrow ───────────────── */
.aj-cta { display: inline-flex; align-items: center; gap: 8px; }
.aj-arrow {
  display: inline-block;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.aj-cta:hover .aj-arrow,
a:hover > .aj-arrow { transform: translateX(5px); }

/* ── 6. Magnetic CTA — .aj-magnet (enhanced via JS) ─────────────────── */
/*
 * Base styles only — the magnetic pull is applied inline by aj-motion.js.
 * Transition provides snap-back on mouse-leave.
 */
.aj-magnet {
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ── 7. Cursor spotlight — .aj-spotlight ────────────────────────────── */
/*
 * Section gets a cobalt radial gradient that follows the cursor.
 * The gradient position is set via CSS custom properties by aj-motion.js.
 */
.aj-spotlight {
  position: relative;
}
.aj-spotlight::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    600px circle at var(--spotlight-x, 50%) var(--spotlight-y, 30%),
    rgba(200, 16, 46, 0.07),
    transparent 70%
  );
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 0;
}
.aj-spotlight.is-lit::before { opacity: 1; }

/* ── 8. Mega-menu item slide — .aj-megaitem ─────────────────────────── */
.aj-megaitem {
  display: flex;
  align-items: center;
  gap: 12px;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1),
              color 0.15s ease;
}
.aj-megaitem:hover { transform: translateX(5px); }

/* ── 9. Infinite marquee — .aj-marquee-track ────────────────────────── */
/*
 * CSS-only animation; speed controlled by --marquee-speed custom property.
 * Set on the track element from render.php / block attributes.
 */
.aj-marquee-track {
  display: flex;
  width: max-content;
  animation: aj-marquee-scroll var(--marquee-speed, 40s) linear infinite;
}
.aj-marquee-track:hover { animation-play-state: paused; }

@keyframes aj-marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ── 10. Scroll progress bar ─────────────────────────────────────────── */
.aj-scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  background: var(--wp--preset--color--platinum);
  width: 0%;
  z-index: 9999;
  transition: width 0.1s linear;
  pointer-events: none;
}


/* ═══════════════════════════════════════════════════════════════════════
   2026 MOTION LAYER — additions
   Clip-path reveals · word split · rotating glow · 3-D tilt · countup
   CSS scroll-driven (progressive) · floating bob
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Animatable custom property (Chrome 85+, Firefox 128+, Safari 16.4+) */
@property --glow-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

/* ── 11. Clip-path horizontal wipe — .aj-clip ────────────────────────── */
/*
 * Element starts fully clipped from the right.
 * IntersectionObserver adds .aj-clip--in → wipes open left → right.
 */
.aj-clip {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.9s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: clip-path;
}
.aj-clip--in {
  clip-path: inset(0 0% 0 0);
}

/* Stagger delays reuse .d1–.d4 */
.aj-clip.d1 { transition-delay: 0.10s; }
.aj-clip.d2 { transition-delay: 0.20s; }
.aj-clip.d3 { transition-delay: 0.30s; }
.aj-clip.d4 { transition-delay: 0.45s; }

/* ── 12. Clip-path bottom-up wipe — .aj-clip-up ─────────────────────── */
.aj-clip-up {
  clip-path: inset(100% 0 0 0);
  transition: clip-path 0.75s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: clip-path;
}
.aj-clip-up--in {
  clip-path: inset(0 0 0 0);
}

/* ── 13. Word-by-word reveal — .aj-words / .aj-word ─────────────────── */
/*
 * JS splits plain-text elements into .aj-word spans.
 * Each inner <span> slides up; --word-delay drives per-word stagger.
 * The outer .aj-words wrapper remains in normal flow.
 */
.aj-word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: 0.06em;   /* let descenders breathe */
  margin-bottom: -0.06em;
}
.aj-word span {
  display: inline-block;
  transform: translateY(108%);
  opacity: 0;
  transition:
    transform 0.72s cubic-bezier(0.16, 1, 0.3, 1) var(--word-delay, 0ms),
    opacity   0.4s  ease                           var(--word-delay, 0ms);
  will-change: transform, opacity;
}
.aj-words--in .aj-word span {
  transform: translateY(0);
  opacity: 1;
}

/* ── 14. Rotating glow border — .aj-glow ─────────────────────────────── */
/*
 * Conic-gradient border animated via --glow-angle @property.
 * Appears on hover; requires position:relative on the element.
 */
.aj-glow {
  position: relative;
}
.aj-glow::before {
  content: '';
  position: absolute;
  inset: -2px;
  background: conic-gradient(
    from var(--glow-angle),
    transparent 0deg,
    var(--wp--preset--color--ignition-red) 80deg,
    transparent 120deg
  );
  border-radius: inherit;
  z-index: -1;
  animation: aj-glow-spin 3s linear infinite;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.aj-glow:hover::before { opacity: 1; }

@keyframes aj-glow-spin {
  to { --glow-angle: 360deg; }
}

/* ── 15. 3-D perspective tilt — [data-tilt] ──────────────────────────── */
/*
 * JS reads [data-tilt] value as max-angle (default 8°).
 * The ::after shine layer moves with the tilt for a glint effect.
 */
[data-tilt] {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.55s cubic-bezier(0.23, 1, 0.32, 1),
              box-shadow 0.55s ease;
  will-change: transform;
}
/* tilt lighting overlay removed — pure geometry tilt only */
[data-tilt]::after { content: none; }

/* ── 16. Float bob — .aj-float ───────────────────────────────────────── */
.aj-float {
  animation: aj-float-bob 5s ease-in-out infinite;
  will-change: transform;
}
@keyframes aj-float-bob {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-10px); }
  100% { transform: translateY(0); }
}

/* ── 17. Number countup — .aj-count ─────────────────────────────────── */
/* JS animates textContent; this rule ensures tabular digits while ticking */
.aj-count { font-variant-numeric: tabular-nums; }

/* ── 18. CSS Scroll-Driven animations (progressive enhancement) ──────── */
/*
 * @supports guards ensure zero impact on non-supporting browsers.
 * Chrome 115+, Edge 115+, Firefox 110+(partial), Safari 17.4+ benefit.
 */
@supports (animation-timeline: scroll()) {
  /*
   * Hero parallax-exit — desktop/landscape only.
   * On portrait/mobile the stats pillars sit inside the hero section, so
   * a scroll-range of 55vh would fade them to near-black while still on screen.
   * Gated at 768px: below that the hero simply stays fully opaque.
   */
  @media (min-width: 768px) {
    .ajcs-hero {
      animation-name: aj-hero-exit;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: scroll(root);
      animation-range: 0 55vh;
    }
  }
  @keyframes aj-hero-exit {
    from { opacity: 1;    transform: scale(1);    }
    to   { opacity: 0.15; transform: scale(0.97); }
  }
}

@supports (animation-timeline: view()) {
  /*
   * .aj-view-enter — per-element entrance driven by the element's own view-timeline.
   * Use instead of .aj-rev when you want a pure CSS (no-JS) reveal.
   */
  .aj-view-enter {
    animation-name: aj-view-rise;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: view();
    animation-range: entry 0% entry 38%;
  }
  @keyframes aj-view-rise {
    from { opacity: 0; transform: translateY(28px); }
    to   { opacity: 1; transform: translateY(0);    }
  }
}

/* ── 20. Logo shape-mask shine ───────────────────────────────────────── */
/*
 * JS (initLogoShine) injects  .aj-logo-shine__mask > .aj-logo-shine__streak
 * into every .aj-logo-shine element at DOM-ready.
 *
 * The mask wrapper receives mask-image set to the logo's own SVG/PNG (via
 * inline style from JS), so the shine beam is clipped to the exact logo
 * silhouette — not a rectangle over it.
 *
 * Architecture:
 *   .aj-logo-shine            — position:relative context (no clip-path needed)
 *     .aj-logo-shine__mask    — inset:0, overflow:hidden, mask-image=logo shape
 *       .aj-logo-shine__streak — gradient beam that translates L→R through mask
 */
.aj-logo-shine {
  position: relative;
}

.aj-logo-shine__mask {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  overflow: hidden;               /* clips streak to element bounds          */
  -webkit-mask-repeat: no-repeat; /* logo shape mask applied by JS            */
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
}

.aj-logo-shine__streak {
  position: absolute;
  top: -20%;
  left: 0;
  width: 100%;
  height: 140%;
  background: linear-gradient(
    105deg,
    transparent         30%,
    rgba(255,255,255,0.72) 50%,
    transparent         70%
  );
  transform: skewX(-12deg) translateX(-250%);
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .aj-logo-shine:hover .aj-logo-shine__streak {
    animation: aj-logo-shine 1.2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  }
}

@keyframes aj-logo-shine {
  from { transform: skewX(-12deg) translateX(-250%); }
  to   { transform: skewX(-12deg) translateX( 250%); }
}

/* CSS-only tilt for the footer logo (JS tilt only binds to [data-tilt]) */
.ajcs-site-footer .wp-block-site-logo {
  display: inline-block;
  transition: transform 0.45s cubic-bezier(0.23, 1, 0.32, 1);
  transform-style: preserve-3d;
}
@media (prefers-reduced-motion: no-preference) {
  .ajcs-site-footer .wp-block-site-logo:hover {
    transform: perspective(600px) rotateY(7deg) rotateX(-3deg) scale(1.05);
  }
}

/* ── Supplementary reduced-motion overrides for new classes ──────────── */
@media (prefers-reduced-motion: reduce) {
  .aj-clip, .aj-clip--in         { clip-path: none !important; transition: none !important; }
  .aj-clip-up, .aj-clip-up--in   { clip-path: none !important; transition: none !important; }
  .aj-word span                  { transform: none !important; opacity: 1 !important; transition: none !important; }
  .aj-glow::before               { animation: none !important; }
  [data-tilt]                    { transform: none !important; transition: none !important; }
  .aj-float                      { animation: none !important; }
  .aj-view-enter                 { animation: none !important; opacity: 1 !important; transform: none !important; }
  .ajcs-hero                     { animation: none !important; opacity: 1 !important; transform: none !important; }
}
