/* fbcwisner.org motion layer
   Loaded on every page. Everything in here is gated on html.motion, which the
   inline head script adds only when the visitor has not asked for reduced
   motion. If GSAP fails to arrive, the loader removes html.motion and every
   rule below stops applying, so the page is plainly visible with no JS at all.
   Intent: quiet confidence. Things settle into place; nothing bounces or flies.
   Dials (frontend-antislop): VARIANCE 3, MOTION 4, DENSITY 3. */

/* ---------- Hidden-until-ready states (released by the JS, or by losing html.motion) ---------- */
html.motion .reveal{opacity:0}
html.motion .reveal.in{opacity:1}
html.motion .hero:not(.is-ready) .hero-content,
html.motion .hero:not(.is-ready) .hero-bg,
html.motion .hero:not(.is-ready) .times-card{opacity:0}
html.motion.home nav:not(.is-ready){opacity:0}
html.motion .page-header:not(.in) > *,
html.motion .page-hero:not(.in) > *{opacity:0}
html.motion .archive-issue:not(.in),
html.motion .trading-card:not(.in),
html.motion .optin-inner:not(.in) > *,
html.motion footer .footer-inner:not(.in) > *,
html.motion .photo-break:not(.in) img{opacity:0}

/* The legacy IntersectionObserver reveal used a CSS transition. GSAP now owns
   the tween, so the transition must go or the two fight over transform. */
html.motion .reveal{transition:none;transform:none}

/* While GSAP owns an element, the site's hover transitions stand aside (see prep() in motion.js). */
html.motion .is-tweening,html.motion .is-tweening *{transition:none!important}

/* ---------- Hero headline: masked lines rise into place ---------- */
.hero-line{display:block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
.hero-line > span{display:block;will-change:transform}
.hero h1 .hero-line .hero-keyword{margin-top:0}
.hero-bg{will-change:transform;transform-origin:50% 40%}

/* ---------- Nav: logo crossfade instead of a hard swap, hide on scroll down ---------- */
nav{transition:padding .3s ease,background .3s ease,box-shadow .3s ease}
nav .nav-logo{transition:height .35s cubic-bezier(.22,1,.36,1),opacity .35s ease}
html.motion.home nav > a[aria-label="Home"]{position:relative;display:block}
html.motion.home nav .nav-logo-white,
html.motion.home nav .nav-logo-color{display:block}
html.motion.home nav .nav-logo-color{position:absolute;top:0;left:0;opacity:0}
html.motion.home nav.scrolled .nav-logo-color{opacity:1}
html.motion.home nav.scrolled .nav-logo-white{opacity:0}
html.motion nav.is-hidden{transform:translateY(-100%)}
html.motion nav{transition:padding .3s ease,background .3s ease,box-shadow .3s ease,transform .45s cubic-bezier(.22,1,.36,1)}

/* ---------- Buttons and links: a press state, and a slightly better curve ---------- */
.btn,.nav-cta,.form-submit,.newsletter-cta a,.connect-link,.widget-link,.archive-link{
  transition-timing-function:cubic-bezier(.22,1,.36,1)}
.btn:active,.nav-cta:active,.form-submit:active,.newsletter-cta a:active{transform:translateY(0) scale(.985)}
.connect-link:active{transform:translateX(2px) scale(.99)}

/* ---------- Cards: image settles in behind its crop ---------- */
.expect-card-img img,.card-photo{will-change:transform}
.photo-break img{will-change:transform,clip-path}

/* ---------- Mobile menu: a fade, and the links arrive in order ---------- */
html.motion .mobile-menu.open{animation:fbc-menu-in .32s cubic-bezier(.22,1,.36,1) both}
@keyframes fbc-menu-in{from{opacity:0}to{opacity:1}}

/* ---------- Reduced motion: belt and braces. html.motion is never added, but
   also kill the hover transforms and the keyframe so nothing moves at all. ---------- */
@media (prefers-reduced-motion: reduce){
  html.motion .reveal,html.motion .hero .hero-content,html.motion .hero .hero-bg,html.motion nav,
  html.motion .page-header > *,html.motion .page-hero > *,html.motion .archive-issue,html.motion .trading-card,
  html.motion .optin-inner > *,html.motion footer .footer-inner > *,html.motion .photo-break img{opacity:1!important;transform:none!important}
  .mobile-menu.open{animation:none!important}
  html{scroll-behavior:auto}
}
