{"version":3,"file":"VideoBackground.DDsD57hP.mjs","names":["React.useRef","React.useState"],"sources":["https:/framerusercontent.com/modules/EGSFuaPoIvvzyNqxscqK/iBOT58qcmxhLQp8pyUtr/VideoBackground.js"],"sourcesContent":["import{jsx as _jsx,jsxs as _jsxs}from\"react/jsx-runtime\";import*as React from\"react\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";/**\n * Full-bleed hero backdrop: a looping video, or a static photo.\n *\n * Drop it in as the first child of a hero stack. The footage plays as shot,\n * with a single flat black layer over it so white headline text stays\n * readable over any frame. No colour wash: the client asked for the footage\n * to read as itself rather than being tinted.\n *\n * STATIC PHOTO HEROES. Leave Video URL empty and set Poster URL, and this\n * renders as a still photo hero. That is the client's rule from the\n * 2026-08-18 review: the looping video belongs to the homepage alone and\n * every other page gets a static photo with the same wording, fonts and\n * layout over it. Poster is also what shows under prefers-reduced-motion,\n * so a hero that does keep its video should always carry one anyway.\n *\n * Focus sets object-position. It matters more here than anywhere else on the\n * site: a hero crops almost nothing at desktop width and crops most of the\n * frame on a phone, and River Oaks' photography puts faces in the upper\n * third, so a centred crop lands on torsos. Default is a slight upward bias.\n *\n * Like AuroraBackground, it pins its own Framer wrapper at runtime: canvas\n * pin values do not survive MCP writes, so setting left/top on the instance\n * is not reliable.\n *\n * @framerSupportedLayoutWidth any\n * @framerSupportedLayoutHeight any\n * @framerIntrinsicWidth 1200\n * @framerIntrinsicHeight 800\n */export default function VideoBackground(props){const{src,poster,focus,grayscale,overlay,fillParent,style}=props;const isCanvas=RenderTarget.current()===RenderTarget.canvas;const rootRef=React.useRef(null);const videoRef=React.useRef(null);const[reduced,setReduced]=React.useState(false);React.useEffect(()=>{if(typeof window===\"undefined\"||!window.matchMedia)return;const mq=window.matchMedia(\"(prefers-reduced-motion: reduce)\");const onChange=()=>setReduced(mq.matches);onChange();mq.addEventListener(\"change\",onChange);return()=>mq.removeEventListener(\"change\",onChange);},[]);// Canvas-set pins don't survive MCP writes, so at runtime we pin the\n// Framer wrapper element ourselves to fill the parent section.\nReact.useLayoutEffect(()=>{if(isCanvas||!fillParent||!rootRef.current)return;const wrapper=rootRef.current.parentElement;if(!wrapper||wrapper===document.body)return;Object.assign(wrapper.style,{position:\"absolute\",top:\"0px\",left:\"0px\",right:\"0px\",bottom:\"0px\",width:\"100%\",height:\"100%\",maxWidth:\"none\",transform:\"none\",pointerEvents:\"none\",zIndex:\"0\"});const section=wrapper.parentElement;if(section&&getComputedStyle(section).position===\"static\"){section.style.position=\"relative\";}},[isCanvas,fillParent]);// Autoplay is refused for anything mounted below the fold and is never\n// retried, so play on intersection instead. Pausing offscreen also stops\n// heroes on long pages from decoding video nobody is looking at.\nReact.useEffect(()=>{const el=videoRef.current;if(!el||reduced)return;const tryPlay=()=>{const p=el.play();if(p&&typeof p.catch===\"function\")p.catch(()=>{});};tryPlay();if(typeof window===\"undefined\"||!(\"IntersectionObserver\"in window))return;const io=new IntersectionObserver(entries=>{for(const e of entries){if(e.isIntersecting)tryPlay();else el.pause();}},{rootMargin:\"120px\"});io.observe(el);return()=>io.disconnect();},[reduced,src]);const mediaStyle={position:\"absolute\",inset:0,width:\"100%\",height:\"100%\",objectFit:\"cover\",objectPosition:focus||\"center 35%\",filter:grayscale?\"grayscale(100%)\":\"none\"};return /*#__PURE__*/_jsxs(\"div\",{ref:rootRef,\"aria-hidden\":true,style:{width:\"100%\",height:\"100%\",overflow:\"hidden\",pointerEvents:\"none\",backgroundColor:\"#000000\",...style},children:[src&&!reduced?/*#__PURE__*/_jsx(\"video\",{ref:videoRef,src:src,poster:poster||undefined,autoPlay:true,muted:true,loop:true,playsInline:true,preload:\"auto\",tabIndex:-1,style:mediaStyle}):poster?/*#__PURE__*/_jsx(\"img\",{src:poster,alt:\"\",decoding:\"async\",style:mediaStyle}):null,/*#__PURE__*/_jsx(\"div\",{style:{position:\"absolute\",inset:0,background:`rgba(0, 0, 0, ${overlay})`}})]});}addPropertyControls(VideoBackground,{src:{type:ControlType.String,title:\"Video URL\",defaultValue:\"\",description:\"Muted looping mp4. LEAVE EMPTY for a static photo hero and set Poster URL instead.\"},poster:{type:ControlType.String,title:\"Photo URL\",defaultValue:\"\",description:\"The still image. Used as the whole hero when Video URL is empty, and as the poster/reduced-motion frame when it is not.\"},focus:{type:ControlType.String,title:\"Focus\",defaultValue:\"\",description:\"CSS object-position, e.g. 'center 30%' or 'right 40%'. Defaults to center 35%.\"},grayscale:{type:ControlType.Boolean,title:\"Black & White\",defaultValue:false},overlay:{type:ControlType.Number,title:\"Black Overlay\",min:0,max:1,step:.05,defaultValue:.3,description:\"Opacity of the black layer over the media\"},fillParent:{type:ControlType.Boolean,title:\"Fill Section\",defaultValue:true,description:\"Pin itself to fill the parent section at runtime\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"VideoBackground\",\"slots\":[],\"annotations\":{\"framerSupportedLayoutWidth\":\"any\",\"framerContractVersion\":\"1\",\"framerSupportedLayoutHeight\":\"any\",\"framerIntrinsicWidth\":\"1200\",\"framerIntrinsicHeight\":\"800\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./VideoBackground.map"],"mappings":"2NA4BG,SAAwB,EAAgB,EAAM,CAAC,GAAK,CAAC,MAAI,SAAO,QAAM,YAAU,UAAQ,aAAW,SAAO,EAAY,EAAS,EAAa,QAAQ,IAAI,EAAa,OAAa,EAAQA,EAAa,IAAI,EAAQ,EAASA,EAAa,IAAI,EAAO,CAAC,EAAQ,GAAYC,EAAe,EAAK,EAAE,MAAoB,CAAC,GAAU,IAAS,QAAa,CAAC,EAAO,WAAW,OAAO,IAAM,EAAG,EAAO,WAAW,kCAAkC,EAAQ,MAAa,EAAW,EAAG,OAAO,EAAoD,OAAlD,EAAS,EAAE,EAAG,iBAAiB,SAAS,CAAQ,MAAY,EAAG,oBAAoB,SAAS,CAAQ,CAAE,EAAE,CAAC,CAAC,EAEpkB,MAA0B,CAAC,GAAG,GAAU,CAAC,GAAY,CAAC,EAAQ,QAAQ,OAAO,IAAM,EAAQ,EAAQ,QAAQ,cAAc,GAAG,CAAC,GAAS,IAAU,SAAS,KAAK,OAAO,OAAO,OAAO,EAAQ,MAAM,CAAC,SAAS,WAAW,IAAI,MAAM,KAAK,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,OAAO,OAAO,OAAO,SAAS,OAAO,UAAU,OAAO,cAAc,OAAO,OAAO,GAAG,CAAC,EAAE,IAAM,EAAQ,EAAQ,cAAiB,GAAS,iBAAiB,CAAO,CAAC,CAAC,WAAW,WAAU,EAAQ,MAAM,SAAS,WAAY,EAAE,CAAC,EAAS,CAAU,CAAC,EAG3f,MAAoB,CAAC,IAAM,EAAG,EAAS,QAAQ,GAAG,CAAC,GAAI,EAAQ,OAAO,IAAM,MAAY,CAAC,IAAM,EAAE,EAAG,KAAK,EAAK,GAAG,OAAO,EAAE,OAAQ,YAAW,EAAE,UAAU,CAAC,CAAC,CAAE,EAAY,GAAV,EAAQ,EAAY,IAAS,QAAa,EAAE,yBAAyB,GAAQ,OAAO,IAAM,EAAG,IAAI,qBAAqB,GAAS,CAAC,IAAI,IAAM,KAAK,EAAY,EAAE,eAAe,EAAQ,EAAO,EAAG,MAAM,CAAG,EAAE,CAAC,WAAW,OAAO,CAAC,EAAiB,OAAf,EAAG,QAAQ,CAAE,MAAY,EAAG,WAAW,CAAE,EAAE,CAAC,EAAQ,CAAG,CAAC,EAAE,IAAM,EAAW,CAAC,SAAS,WAAW,MAAM,EAAE,MAAM,OAAO,OAAO,OAAO,UAAU,QAAQ,eAAe,GAAO,aAAa,OAAO,EAAU,kBAAkB,MAAM,EAAE,OAAoB,EAAM,MAAM,CAAC,IAAI,EAAQ,cAAc,GAAK,MAAM,CAAC,MAAM,OAAO,OAAO,OAAO,SAAS,SAAS,cAAc,OAAO,gBAAgB,UAAU,GAAG,CAAK,EAAE,SAAS,CAAC,GAAK,CAAC,EAAqB,EAAK,QAAQ,CAAC,IAAI,EAAa,MAAI,OAAO,GAAQ,IAAA,GAAU,SAAS,GAAK,MAAM,GAAK,KAAK,GAAK,YAAY,GAAK,QAAQ,OAAO,SAAS,GAAG,MAAM,CAAU,CAAC,EAAE,EAAoB,EAAK,MAAM,CAAC,IAAI,EAAO,IAAI,GAAG,SAAS,QAAQ,MAAM,CAAU,CAAC,EAAE,KAAkB,EAAK,MAAM,CAAC,MAAM,CAAC,SAAS,WAAW,MAAM,EAAE,WAAW,iBAAiB,EAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,qBAjC7lC,IAA4B,IAAiE,EAiCigC,EAAoB,EAAgB,CAAC,IAAI,CAAC,KAAK,EAAY,OAAO,MAAM,YAAY,aAAa,GAAG,YAAY,oFAAoF,EAAE,OAAO,CAAC,KAAK,EAAY,OAAO,MAAM,YAAY,aAAa,GAAG,YAAY,yHAAyH,EAAE,MAAM,CAAC,KAAK,EAAY,OAAO,MAAM,QAAQ,aAAa,GAAG,YAAY,gFAAgF,EAAE,UAAU,CAAC,KAAK,EAAY,QAAQ,MAAM,gBAAgB,aAAa,EAAK,EAAE,QAAQ,CAAC,KAAK,EAAY,OAAO,MAAM,gBAAgB,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,aAAa,GAAG,YAAY,2CAA2C,EAAE,WAAW,CAAC,KAAK,EAAY,QAAQ,MAAM,eAAe,aAAa,GAAK,YAAY,kDAAkD,CAAC,CAAC"}