/* SeeForth Fire Safety — movement (29 Oct 2026). Rebuilds the main site's Webflow interactions without webflow.js or GSAP:
   slideInLeft / slideInBottom on scroll (1 s, outQuart, 100 px), the rolling button hover, photo zoom on hover, the header
   image drifting on scroll and the page tint shifting with scroll. Only transform, opacity and clip-path move, so nothing
   reflows. Everything that hides content is scoped to html.motion, which the <head> script sets only when it is safe
   (see build.py MOTION_BOOT); without it, and with reduced motion asked for, the page is the static page. */

:root{--fs-ease:cubic-bezier(.25,1,.5,1);--fs-ease-io:cubic-bezier(.77,0,.18,1);--rv-x:-100px;--rv-y:100px}
@media (max-width:767px){:root{--rv-x:-40px;--rv-y:48px}}

/* ---- scroll reveals (data-rv is set by the build; motion.js adds .in, then .done) ---- */
.motion [data-rv]:not(.done){transition:opacity 1s var(--fs-ease),transform 1s var(--fs-ease),clip-path 1.2s var(--fs-ease)}
.motion [data-rv]:not(.in){opacity:0}
.motion [data-rv=left]:not(.in){transform:translate3d(var(--rv-x),0,0)}
.motion [data-rv=up]:not(.in){transform:translate3d(0,var(--rv-y),0)}
.motion img[data-rv=img]{clip-path:inset(0 0 0 0 round 16px)}
.motion img[data-rv=img]:not(.in){clip-path:inset(100% 0 0 0 round 16px)}
/* translated-down content at the very end of the page must not lengthen it */
.footer_component{overflow:hidden;overflow:clip}

/* ---- header: plays on load, no script needed ---- */
@keyframes fsUp{from{opacity:0;transform:translate3d(0,var(--rv-y),0)}to{opacity:1;transform:none}}
@keyframes fsWord{from{transform:translate3d(0,110%,0)}to{transform:none}}
@keyframes fsLine{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes fsCurtain{from{clip-path:inset(100% 0 0 0)}to{clip-path:inset(0 0 0 0)}}
@keyframes fsZoom{from{scale:1.3}to{scale:1.12}}
@keyframes fsPop{from{opacity:0;transform:scale(.6)}to{opacity:1;transform:none}}
.motion .section_header .eyebrow_wrapper{position:relative;border-bottom-color:transparent;animation:fsUp .9s var(--fs-ease) both}
.motion .section_header .eyebrow_wrapper::after{content:"";position:absolute;left:0;right:0;bottom:calc(-1 * var(--_ui-styles---stroke--border-width,2px));height:var(--_ui-styles---stroke--border-width,2px);background:var(--light--border);transform-origin:0 50%;animation:fsLine 1.2s .3s var(--fs-ease) both}
.motion .header_heading .hw{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.12em;margin-bottom:-.12em}
.motion .header_heading .hw>span{display:inline-block;animation:fsWord 1s calc(.12s + var(--i,0) * .06s) var(--fs-ease) both}
.motion .section_header .hero_paragraph{animation:fsUp 1s .5s var(--fs-ease) both}
.motion .section_header .button_group_wrap{animation:fsUp 1s .65s var(--fs-ease) both}
.motion .assessor-strip picture{display:block;animation:fsPop .7s var(--fs-ease) both}
.motion .assessor-strip picture:nth-child(1){animation-delay:.8s}
.motion .assessor-strip picture:nth-child(2){animation-delay:.88s}
.motion .assessor-strip picture:nth-child(3){animation-delay:.96s}
.motion .assessor-strip p{animation:fsUp 1s 1s var(--fs-ease) both}
.motion .header_image-wrapper{animation:fsCurtain 1.3s .15s var(--fs-ease-io) both}
.motion .header_image{scale:1.12;animation:fsZoom 1.8s .15s var(--fs-ease) both}
/* parallax drift (motion.js writes the translate property; scale above leaves room so no edge shows) */
.motion [data-par]{will-change:translate}

/* ---- footer heading: the purple sheen moves once it is on screen ---- */
@keyframes fsSheen{from{background-position:0% 50%}to{background-position:100% 50%}}
.motion .purple-sheen.in{background-size:220% 100%;animation:fsSheen 7s ease-in-out infinite alternate}

/* ---- menus ---- */
@keyframes fsDrop{from{opacity:0;transform:translate3d(0,-10px,0)}to{opacity:1;transform:none}}
.motion .navbar_dropdown-list.w--open{animation:fsDrop .35s var(--fs-ease) both}
@media (max-width:991px){.motion .navbar_menu.w--open{animation:fsDrop .4s var(--fs-ease) both}}

/* ---- page tint (motion.js adds the layer and sets its opacity from scroll) ---- */
.fs-tint{position:fixed;inset:0;z-index:-1;pointer-events:none;background:var(--_colors---lighter-purple,#d7e0fb);opacity:0}

/* ---- hover: only where there is a real pointer, so phones never get stuck states ---- */
@media (hover:hover) and (pointer:fine){
  /* the button's rolling text and arrow, as Webflow's "Button Hover In/Out - 18" */
  .button-text.is-absolute,.button-icon.is-absolute{display:flex}
  .button-text,.button-icon{transition:transform .5s var(--fs-ease)}
  .button-text.is-absolute{transform:translate3d(0,180%,0)}
  .button-icon.is-absolute{transform:translate3d(-250%,0,0)}
  .button-block{transition:transform .5s var(--fs-ease)}
  .button-block:hover,.button-block:focus-visible{transform:scale(1.05)}
  .button-block:hover .button-text:not(.is-absolute),.button-block:focus-visible .button-text:not(.is-absolute){transform:translate3d(0,-180%,0)}
  .button-block:hover .button-text.is-absolute,.button-block:focus-visible .button-text.is-absolute{transform:none}
  .button-block:hover .button-icon:not(.is-absolute),.button-block:focus-visible .button-icon:not(.is-absolute){transform:translate3d(250%,0,0)}
  .button-block:hover .button-icon.is-absolute,.button-block:focus-visible .button-icon.is-absolute{transform:none}

  /* cards lift, as the main site's services cards */
  .frg-card{transition:transform .4s var(--fs-ease),background-color .4s,border-color .4s,box-shadow .4s}
  .frg-card:hover{transform:translate3d(0,-6px,0);background-color:var(--_colors---seeforth-grey,#eaeffe);border-color:var(--_colors---rich-purple);box-shadow:0 22px 40px -28px rgba(51,38,129,.55)}

  /* assessor photos zoom inside their frame, as "Scale profile image" */
  .team-stack .image,.team-stack .image-2{transition:transform .6s ease}
  .team-stack .w-layout-cell:hover .image,.team-stack .w-layout-cell:hover .image-2{transform:scale(1.1)}

  .fs_accordion-1_item{transition:border-color .3s,background-color .3s}
  .fs_accordion-1_item:hover{border-color:var(--_colors---rich-purple)}
}
/* the zoom stays inside the photo's own box */
.team-stack picture{display:block;overflow:hidden;margin-bottom:1rem}
.team-stack picture .image,.team-stack picture .image-2{margin-bottom:0}

/* ---- FAQ opens and closes smoothly (grid-rows; snaps where unsupported) ---- */
.fs_accordion-1_content{display:grid;grid-template-rows:0fr;visibility:hidden;transition:grid-template-rows .45s var(--fs-ease),visibility 0s .45s}
.fs_accordion-1_content.is-open{grid-template-rows:1fr;visibility:visible;transition:grid-template-rows .45s var(--fs-ease),visibility 0s}
.fs_accordion-1_content>.fs_accordion-1_body{min-height:0;overflow:hidden;padding-top:0;padding-bottom:0}
.fs_accordion-1_content>.fs_accordion-1_body>.fs_accordion-1_paragraph{padding:1rem 0}

/* ---- page-to-page cross-fade where the browser supports it ---- */
@media (prefers-reduced-motion:no-preference){@view-transition{navigation:auto}}

@media print{
  .motion [data-rv],.motion .section_header *,.motion .header_image-wrapper{opacity:1!important;transform:none!important;clip-path:none!important;animation:none!important}
  .fs-tint{display:none}
}
