/* ============================================================
   LBMG MOTION PACK — motion.css
   Load AFTER styles.css (and hud.css). Pairs with motion.js.

   Two jobs:
   1) RE-ENABLE the site's existing reveal/entrance motion for
      visitors whose OS requests reduced motion — UNLESS the site
      has explicitly opted out via <html class="lb-no-motion">.
      (This brand is a motion studio; motion is the product demo.)
   2) Provide a cohesive HOVER + accent vocabulary used site-wide.

   Accessibility hook: add class "lb-no-motion" to <html> to honor
   reduced-motion fully and disable everything here.
   2026-06-06
   ============================================================ */

/* ---------- 1. Re-enable existing motion under OS reduced-motion ----------
   These mirror the base states in styles.css but win because they come
   later in the cascade, carry higher specificity (:not(.lb-no-motion)),
   and use !important to beat the original reduced-motion overrides.
   Gated on html.lb-js so a no-JS load can never leave content hidden. */
@media (prefers-reduced-motion: reduce){
  html.lb-js:not(.lb-no-motion) body.js-anim .ra{
    opacity:0 !important;
    transform:translateY(32px) !important;
    transition:opacity .8s ease, transform .8s cubic-bezier(.2,.8,.25,1.04) !important;
    transition-delay:var(--d,0s) !important;
  }
  html.lb-js:not(.lb-no-motion) body.js-anim .ra.pop{
    transform:translateY(10px) scale(.84) !important;
  }
  html.lb-js:not(.lb-no-motion) body.js-anim .ra.ra-in{
    opacity:1 !important; transform:none !important;
  }

  html.lb-js:not(.lb-no-motion) .lb-reveal,
  html.lb-js:not(.lb-no-motion) .lb-reveal-up,
  html.lb-js:not(.lb-no-motion) .lb-reveal-left,
  html.lb-js:not(.lb-no-motion) .lb-reveal-right,
  html.lb-js:not(.lb-no-motion) .lb-reveal-scale,
  html.lb-js:not(.lb-no-motion) .lb-reveal-blur{
    opacity:0 !important;
    transition:opacity .8s ease, transform .8s cubic-bezier(.2,.7,.2,1), filter .8s ease !important;
  }
  html.lb-js:not(.lb-no-motion) .lb-reveal-up   { transform:translateY(40px) !important; }
  html.lb-js:not(.lb-no-motion) .lb-reveal-left { transform:translateX(-40px) !important; }
  html.lb-js:not(.lb-no-motion) .lb-reveal-right{ transform:translateX(40px) !important; }
  html.lb-js:not(.lb-no-motion) .lb-reveal-scale{ transform:scale(.96) !important; }
  html.lb-js:not(.lb-no-motion) .lb-reveal-blur { filter:blur(8px) !important; }
  html.lb-js:not(.lb-no-motion) .lb-reveal.in,
  html.lb-js:not(.lb-no-motion) .lb-reveal-up.in,
  html.lb-js:not(.lb-no-motion) .lb-reveal-left.in,
  html.lb-js:not(.lb-no-motion) .lb-reveal-right.in,
  html.lb-js:not(.lb-no-motion) .lb-reveal-scale.in{ opacity:1 !important; transform:none !important; }
  html.lb-js:not(.lb-no-motion) .lb-reveal-blur.in { opacity:1 !important; filter:blur(0) !important; }
}

/* ---------- 2. Motion.js targets (initial state set inline by JS) ----------
   will-change hints only; the JS owns opacity/transform during play. */
html.lb-js:not(.lb-no-motion) [data-m]{ will-change:opacity, transform; }
html.lb-js:not(.lb-no-motion) [data-m="break"] > *{ will-change:opacity, transform; }

/* ---------- 3. Cohesive HOVER vocabulary (works regardless of OS flag) ----
   These are plain transitions (not @keyframes), so the OS reduced-motion
   flag does not suppress them; the lb-no-motion opt-out still disables. */
.m-lift{ transition:transform .38s cubic-bezier(.2,.7,.2,1), box-shadow .38s ease; will-change:transform; }
.m-lift:hover{ transform:translateY(-6px); box-shadow:0 16px 44px -12px rgba(0,0,0,.6); }

.m-glow{ transition:box-shadow .4s ease, border-color .4s ease; }
.m-glow:hover{ border-color:var(--rust-2,#D6362A); box-shadow:0 0 0 1px rgba(214,54,42,.5), 0 0 30px -8px rgba(214,54,42,.55); }

.m-sweep{ position:relative; overflow:hidden; isolation:isolate; }
.m-sweep::after{ content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(120deg, transparent 32%, rgba(214,54,42,.16) 50%, transparent 68%);
  transform:translateX(-120%); transition:transform .75s cubic-bezier(.2,.7,.2,1); }
.m-sweep:hover::after{ transform:translateX(120%); }

/* underline-grow for inline/nav links */
.m-underline{ position:relative; }
.m-underline::after{ content:""; position:absolute; left:0; right:0; bottom:-3px; height:1.5px;
  background:var(--rust-2,#D6362A); transform:scaleX(0); transform-origin:left center;
  transition:transform .35s cubic-bezier(.2,.7,.2,1); }
.m-underline:hover::after{ transform:scaleX(1); }

/* image/tile zoom on hover (pairs with overflow:hidden parent) */
.m-zoom{ overflow:hidden; }
.m-zoom > img, .m-zoom > video, .m-zoom .m-zoom-target{ transition:transform 1.1s cubic-bezier(.22,.61,.36,1); will-change:transform; }
.m-zoom:hover > img, .m-zoom:hover > video, .m-zoom:hover .m-zoom-target{ transform:scale(1.06); }

/* hard opt-out: kill everything this pack adds */
html.lb-no-motion [data-m]{ opacity:1 !important; transform:none !important; filter:none !important; }
html.lb-no-motion .m-lift, html.lb-no-motion .m-glow, html.lb-no-motion .m-sweep,
html.lb-no-motion .m-underline, html.lb-no-motion .m-zoom > img,
html.lb-no-motion .m-zoom > video{ transition:none !important; }
html.lb-no-motion .m-sweep::after, html.lb-no-motion .m-underline::after{ display:none !important; }

/* ============================================================
   TUNING PACK (2026-06-06) — bolder, slower, more readable
   Knobs live here so motion can be felt and adjusted in one place.
   ============================================================ */

/* A. Entrance reveals — more travel + a soft settle (applies to everyone).
   The existing .ra entrance was a subtle 16px lift; bump to 32px with a
   gentle overshoot so section content clearly rises into place. */
html.lb-js:not(.lb-no-motion) body.js-anim .ra{
  transform:translateY(32px);
  transition:opacity .8s ease, transform .8s cubic-bezier(.2,.8,.25,1.04);
}
html.lb-js:not(.lb-no-motion) body.js-anim .ra.pop{ transform:translateY(18px) scale(.82); }

/* B. Image push-ins — slow + stable everywhere (was a mix of fast timings).
   One uniform, cinematic ease-out so every hover zoom feels intentional. */
html:not(.lb-no-motion) .lb-video-tile video,
html:not(.lb-no-motion) .lb-video-tile img,
html:not(.lb-no-motion) .campus .img.has-photo img,
html:not(.lb-no-motion) .img.has-photo > img,
html:not(.lb-no-motion) .lb-frame img,
html:not(.lb-no-motion) .team-card .team-photo,
html:not(.lb-no-motion) .reel .reel-vid,
html:not(.lb-no-motion) .m-zoom > img,
html:not(.lb-no-motion) .m-zoom > video{
  transition:transform 1.15s cubic-bezier(.22,.61,.36,1) !important;
}

/* C. Parallax overscan — give the bolder drift (script.js --py / CTA TRAVEL)
   room so a fast scroll never reveals a hard top/bottom edge. */
html:not(.lb-no-motion) .herovideo{ top:-20% !important; bottom:-20% !important; }
html:not(.lb-no-motion) section.campus-section::before,
html:not(.lb-no-motion) section.ai-section::before{ top:-20% !important; bottom:-20% !important; }
html:not(.lb-no-motion) .cta-band .cta-bg{ top:-18% !important; bottom:-18% !important; height:auto !important; }

/* ===== Footer-nav active state (matches top nav red) ===== */
.ft-nav a.active{ color:var(--rust-2,#D6362A); }

/* ===== Mobile: disable heavy background parallax for stability/perf ===== */
@media (max-width:760px){
  html:not(.lb-no-motion) .herovideo,
  html:not(.lb-no-motion) section.campus-section::before,
  html:not(.lb-no-motion) section.ai-section::before,
  html:not(.lb-no-motion) .cta-band .cta-bg{ transform:none !important; }
}

/* ===== Mobile CTA fill (2026-06-07) =====
   The desktop parallax rule above (height:auto + top/bottom:-18%) leaves the
   bg <video> at its intrinsic 16:9 height — fine on wide desktop, but on a
   phone it collapses to a strip at the top with black below. Parallax is
   already disabled on mobile (block above), so here we give the section an
   explicit viewport height and fill it. Same specificity as line ~130,
   placed later, so it wins. KNOB: the clamp() controls the CTA height. */
@media (max-width:760px){
  html:not(.lb-no-motion) .cta-band{
    height:clamp(460px,78vh,640px) !important;
    min-height:0 !important;
    overflow:hidden !important;
  }
  html:not(.lb-no-motion) .cta-band .cta-bg{
    top:0 !important; bottom:auto !important; left:0 !important; right:0 !important;
    width:100% !important;
    height:clamp(460px,78vh,640px) !important;   /* vh resolves independent of parent; matches section */
    object-fit:cover !important;
  }
}

/* ============================================================
   LAUNCH-CLEAN — neutralize unfilled media placeholders (2026-06-06)
   Hidden by default. To REVEAL every empty frame + its "Insert ·"
   label for editing, add ?frames to any page URL (or run
   document.documentElement.classList.add('lb-show-frames') in console).
   ============================================================ */
html:not(.lb-show-frames) .img:not(.has-photo) .imgtag,
html:not(.lb-show-frames) .lbwm-phtag{ display:none !important; }
html:not(.lb-show-frames) .img:not(.has-photo){ background:#0e0f12 !important; background-image:none !important; }
html:not(.lb-show-frames) .img:not(.has-photo)::before,
html:not(.lb-show-frames) .img:not(.has-photo)::after{ background-image:none !important; }
html:not(.lb-show-frames) .lbwm-photo.placeholder{ background:#0e0f12 !important; background-image:none !important; }
/* fully-hidden standalone placeholder frames (re-appear under ?frames) */
html:not(.lb-show-frames) .ph-frame{ display:none !important; }
