{"version":3,"file":"ArticleVideoPlayer.BpXzX4te.mjs","names":["useRef"],"sources":["https:/framerusercontent.com/modules/lEcIy12elVDgvkcXTyVJ/bDhGvhQAOffSLOrBVZyg/ArticleVideoPlayer.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef}from\"react\";/**\n * Article hero video player — /learn/:Learn §02 · Media\n *\n * The site had no working video player. Home §05 · Video is a drawing: a black\n * frame with a controls bar painted on it and no video element behind it.\n * /product 01 · Hero has a real clip but its Video Controls frame is empty, so\n * the play/pause half of HeroVideo.tsx never runs there. This is the first one\n * that plays, pauses, mutes and seeks, built from that §05 drawing.\n *\n * WHY THE ICONS ARE SWAPPED IN CSS, not with Framer's `visible`. Framer renders\n * a Lucide icon as `<svg><use href=\"#…\">` pointing at a document sprite, so the\n * glyph cannot be changed by setting an attribute — both icons have to exist in\n * the node and one is hidden. `visible` would unmount the node, and an override\n * cannot bring back something that was never rendered. Same conclusion\n * HeroVideo.tsx reached; the selectors below are its trick, extended to a\n * second pair. Defaults match the element's own initial state — paused and\n * unmuted — so the first paint is right with no flash.\n *\n * Both the icon and the label name the ACTION, not the state: paused shows\n * \"PLAY\", unmuted shows \"MUTE\". The drawing on home pairs a No Sound icon with\n * the word UNMUTE, which reads as state-then-action and cannot be right in both\n * halves at once.\n */const STYLE_ID=\"fp-article-video-player\";const ROOT=\"fp-avp\";const PLAYING=\"fp-avp-playing\";const MUTED=\"fp-avp-muted\";const SCRUBBER=\"fp-avp-scrubber\";const CHROME=\"fp-avp-chrome\";/** How long the bar lingers after the last movement. */const CHROME_MS=4e3;/** How long the centre glyph stays before it is gone. */const FLASH_MS=1e3;const FLASH=\"fp-avp-flash\";const CUE=\"fp-avp-cue\";/** Dropped the first time the clip plays, and never restored. */const FRESH=\"fp-avp-fresh\";const TEASER=\"fp-avp-teaser\";/**\n * ico-play-16, copied verbatim from TestimonialRail.tsx so the two video\n * surfaces on the site show the same glyph. Not the circled play in the\n * control bar — that one belongs to the bar.\n *\n * The design system has no pause to match it, so the second glyph is derived\n * from the first: same 16 box, same 3 → 13.26 horizontal and 2.27 → 13.73\n * vertical extent, same ~1.37 corner radius the play path curves at. If a real\n * ico-pause-16 turns up, swap the two rects for its path.\n */const GLYPHS={play:'<path d=\"M5.5266 2.26535C4.43727 1.56049 3 2.3424 3 3.63988V12.3601C3 13.6576 4.43727 14.4395 5.5266 13.7346L12.265 9.37453C13.262 8.72941 13.262 7.27064 12.265 6.62547L5.5266 2.26535Z\" fill=\"currentColor\"/>',pause:'<rect x=\"3\" y=\"2.27\" width=\"3.1\" height=\"11.46\" rx=\"1.37\" fill=\"currentColor\"/><rect x=\"10.16\" y=\"2.27\" width=\"3.1\" height=\"11.46\" rx=\"1.37\" fill=\"currentColor\"/>'};const style=`\n/* Both icons of a pair live in the node and one is hidden. Framer renders an\n   icon as a div wrapping an <img>, not as an <svg>, so the pair cannot be\n   addressed by element type — hence the layer names, which Framer emits as\n   data-framer-name. HeroVideo.tsx targets svg and therefore matches nothing;\n   it survives only because its own controls bar was deleted.\n\n   visible is not an option either: it unmounts the node, and an override\n   cannot bring back something that was never rendered.\n\n   Defaults match the element's own initial state — paused, unmuted — so the\n   first paint is right with no flash.\n\n   The two buttons answer different questions on purpose. Play/Pause shows the\n   ACTION, because a triangle on a paused clip is what every player in the\n   world means by \"press me\". Mute shows the STATE: a crossed-out speaker says\n   the sound is off, and the word beside it, UNMUTE, says what pressing does.\n   Icon and label together, one reading each. */\n.${ROOT} [data-framer-name=\"Icon Pause\"] { display: none; }\n.${ROOT}.${PLAYING} [data-framer-name=\"Icon Play\"] { display: none; }\n.${ROOT}.${PLAYING} [data-framer-name=\"Icon Pause\"] { display: block; }\n.${ROOT} [data-framer-name=\"Icon Sound Off\"] { display: none; }\n.${ROOT}.${MUTED} [data-framer-name=\"Icon Sound Off\"] { display: block; }\n.${ROOT}.${MUTED} [data-framer-name=\"Icon Sound On\"] { display: none; }\n\n/* The Icon component has one control, its variant — no colour — so the glyph\n   arrives with whatever colour the asset was drawn in, which on this bar is\n   invisible. The filter drives any source colour to white without needing to\n   know it: brightness(0) flattens to black, invert(1) lifts it to white. */\n.${ROOT} [data-framer-name^=\"Icon \"] { filter: brightness(0) invert(1); }\n\n.${ROOT} [data-framer-name=\"Play Pause\"],\n.${ROOT} [data-framer-name=\"Mute Unmute\"] { cursor: pointer; user-select: none; }\n\n/* The Figma component carries Static / Hover / Pressed, and only the colour\n   changes: text/primary #E5E5E5 at rest, brand/white on hover, text/secondary\n   #B5B5B5 while held. The rest colour is set on the node, so only the two\n   reactions live here; the glyph follows with opacity, since it is already\n   forced to white. */\n.${ROOT} [data-framer-name=\"Play Pause\"]:hover p,\n.${ROOT} [data-framer-name=\"Mute Unmute\"]:hover p { color: #FFFFFF !important; }\n.${ROOT} [data-framer-name=\"Play Pause\"]:active p,\n.${ROOT} [data-framer-name=\"Mute Unmute\"]:active p { color: #B5B5B5 !important; }\n.${ROOT} [data-framer-name=\"Play Pause\"]:active [data-framer-name^=\"Icon \"],\n.${ROOT} [data-framer-name=\"Mute Unmute\"]:active [data-framer-name^=\"Icon \"] { opacity: 0.71; }\n\n.${ROOT} [data-framer-name=\"Play Pause\"]:focus-visible,\n.${ROOT} [data-framer-name=\"Mute Unmute\"]:focus-visible,\n.${ROOT} .${SCRUBBER}:focus-visible { outline: 2px solid #7AC9CB; outline-offset: 3px; }\n\n/* The whole picture is the play/pause target, so it has to look like one.\n   The rule covers the descendants too: the <video> element fills the stage,\n   sits on top of it, and Framer gives it cursor:auto — which beats the\n   stage's own cursor everywhere the pointer actually is, including under the\n   centre button. Naming only the stage looked right and did nothing.\n\n   The !important is the part that actually does the work: Framer writes\n   cursor:auto as an INLINE style on the video, and no stylesheet rule beats\n   an inline one without it. The descendant selector alone measured as a no-op\n   on the live page. */\n.${ROOT} [data-framer-name=\"Video Stage\"],\n.${ROOT} [data-framer-name=\"Video Stage\"] * { cursor: pointer !important; }\n.${ROOT} [data-framer-name=\"Veil\"] { pointer-events: none; }\n\n/* Teaser mode. The section leads with a short silent loop so it reads as\n   alive, and the first click swaps in the full film with sound. The loop is\n   half a megabyte against the film's 34, which is the whole reason the home\n   page can autoplay anything at all.\n\n   The second Video instance is never seen — it exists to carry the film's URL\n   to this code, because a Framer component has one source control and the\n   override has no other way to be told a second one.\n\n   The bar stays out while the loop runs: there is nothing to scrub and\n   nothing to mute. The centre button stays, because it is the only thing\n   saying that a click buys you the real film. */\n.${ROOT} [data-framer-name=\"Video Full\"] { display: none !important; }\n.${ROOT}.${TEASER} [data-framer-name=\"Controls Bar\"],\n.${ROOT}.${TEASER} [data-framer-name=\"Scrubber\"] {\n    opacity: 0 !important;\n    pointer-events: none !important;\n}\n\n/* Opt-in: let the player take the clip's own shape instead of a fixed height.\n   The article keeps its 1200x720 box, where the measure is capped and the\n   crop is 6% off the sides. The home section is a different animal — fluid\n   width against a fixed 768px, so the box stretches to 2.29 on a wide monitor\n   and cover eats 22% off the top and bottom of a film full of faces.\n\n   Framer cannot express this: the DSL rejects aspectRatio unless width and\n   height are both fixed, which is exactly what a fluid player is not. Same\n   reason HeroVideo.tsx carries the ratio for /product.\n\n   The hook is the layer name, because that is the only per-instance handle an\n   override gets — the class is on the element the override is attached to, so\n   it and the attribute sit on the same node. !important because the fixed\n   height is written inline by Framer. */\n.${ROOT}[data-framer-name=\"Video Player 16x9\"] {\n    height: auto !important;\n    aspect-ratio: 16 / 9;\n}\n\n/* The centre glyph is a receipt, not a control: it says the click landed and\n   then gets out of the way. Never interactive, so it can never swallow the\n   next click on the picture. */\n.${FLASH} {\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    width: 96px;\n    height: 96px;\n    margin: -48px 0 0 -48px;\n    display: none;\n    place-items: center;\n    border-radius: 50%;\n    background: rgba(7, 7, 7, 0.55);\n    color: #FFFFFF;\n    pointer-events: none;\n    z-index: 3;\n}\n/* The centre play button exists for one reason: before anything has played,\n   a poster frame is indistinguishable from a photograph. The bar already\n   carries a PLAY control and it is easy to miss at 16px in the corner.\n   \n   It is deliberately NOT interactive. The stage under it already toggles\n   playback on click, so pointer-events: none lets the press fall through —\n   one handler, no double toggle — and it adds no second tab stop beside the\n   bar's real button, which is the one screen readers should find.\n   \n   It leaves on first play and does not come back. After that the reader knows\n   what this is, and a big button reappearing on every pause would fight the\n   bar instead of helping it. */\n.${CUE} {\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    transform: translate(-50%, -50%);\n    /* Same chip as the video testimonials: 72px, 54 on phone, glyph at half\n       the chip, optical nudge at an eighth of the glyph. Every one of those is\n       in PIXELS, as the rail has them, and the first attempt here learned why.\n       A percentage padding resolves against the CONTAINING BLOCK's width — the\n       video stage, ~1200px — so a tidy-looking 6.25% became ~75px of padding\n       inside a 72px circle, collapsing the content box to zero and leaving a\n       disc with nothing in it. The glyph's own percentage width had nothing to\n       resolve against either, in a grid track sized by its content.\n\n       The nudge is not fussiness: the play triangle starts at x=3 of a 16 box,\n       so a perfectly centred box reads as sitting left. */\n    width: 72px;\n    height: 72px;\n    padding-left: 4.5px;\n    box-sizing: border-box;\n    display: grid;\n    place-items: center;\n    border-radius: 999px;\n    background: rgba(14, 15, 17, 0.55);\n    -webkit-backdrop-filter: blur(8px);\n    backdrop-filter: blur(8px);\n    color: #FFFFFF;\n    pointer-events: none;\n    opacity: 0;\n    transition: opacity 0.3s cubic-bezier(0.2, 0, 0.15, 1);\n    z-index: 3;\n}\n@media (max-width: 809.98px) {\n    .${CUE} { width: 54px; height: 54px; padding-left: 3.4px; }\n    .${CUE} > svg { width: 27px; height: 27px; }\n}\n.${ROOT}.${FRESH} .${CUE} { opacity: 1; }\n@media (prefers-reduced-motion: reduce) {\n    .${CUE} { transition: none; }\n}\n}\n\n.${FLASH}.on {\n    display: grid;\n    animation: ${FLASH}-out ${FLASH_MS}ms cubic-bezier(0.2, 0, 0.15, 1) forwards;\n}\n@keyframes ${FLASH}-out {\n    0% { opacity: 0; transform: scale(0.88); }\n    18% { opacity: 1; transform: scale(1); }\n    100% { opacity: 0; transform: scale(1.3); }\n}\n@media (prefers-reduced-motion: reduce) {\n    @keyframes ${FLASH}-out {\n        0%, 70% { opacity: 1; transform: none; }\n        100% { opacity: 0; transform: none; }\n    }\n}\n\n/* A 3px track is not a target. The pseudo-element belongs to the scrubber's own\n   box, so it enlarges the hit area to 23px without moving anything. */\n.${ROOT} .${SCRUBBER} { position: relative; cursor: pointer; touch-action: none; }\n.${ROOT} .${SCRUBBER}::after {\n    content: \"\";\n    position: absolute;\n    left: 0; right: 0; top: -10px; bottom: -10px;\n}\n.${ROOT} .${SCRUBBER} > div:first-child { flex-shrink: 0; }\n\n/* The bar is chrome only while the clip is running: it belongs to the moment\n   someone reaches for it, not to the article. Paused or never started, it\n   stays put — a poster frame with no visible control reads as a photograph,\n   and the reader has no way to learn there is anything to press.\n\n   The scrubber is never chrome. It reports where the clip is, so it stays\n   whatever the pointer does, which is also why the two are siblings rather\n   than one block.\n\n   Nothing here touches layout: only opacity moves, so the video never reflows\n   and the scrubber never shifts under the cursor mid-drag. */\n.${ROOT} [data-framer-name=\"Controls Bar\"] {\n    opacity: 0;\n    transition: opacity 0.3s cubic-bezier(0.2, 0, 0.15, 1);\n    pointer-events: none;\n}\n.${ROOT}.${CHROME} [data-framer-name=\"Controls Bar\"],\n.${ROOT}:not(.${PLAYING}) [data-framer-name=\"Controls Bar\"] {\n    opacity: 1;\n    pointer-events: auto;\n}\n@media (prefers-reduced-motion: reduce) {\n    .${ROOT} [data-framer-name=\"Controls Bar\"] { transition: none; }\n}\n\n/* A hidden bar must not keep eating clicks over the bottom of the video, and\n   its container spans that whole strip. So the strip goes transparent to the\n   pointer and the scrubber, which is always live, opts back in. */\n.${ROOT} [data-framer-name=\"Video Controls\"] { pointer-events: none; }\n.${ROOT} .${SCRUBBER} { pointer-events: auto; }\n`;const clamp=n=>n<0?0:n>1?1:n;export const withArticleVideoPlayer=Component=>{return props=>{const host=useRef(null);useEffect(()=>{if(typeof document===\"undefined\")return;if(!document.getElementById(STYLE_ID)){const tag=document.createElement(\"style\");tag.id=STYLE_ID;tag.textContent=style;document.head.appendChild(tag);}const wrapper=host.current;const root=wrapper?.firstElementChild;if(!root)return;const video=root.querySelector(\"video\");if(!video)return;root.classList.add(ROOT);const q=name=>root.querySelector(`[data-framer-name=\"${name}\"]`);const playPause=q(\"Play Pause\");const muteUnmute=q(\"Mute Unmute\");const scrubber=q(\"Scrubber\");const played=q(\"Played\");const cleanups=[];const on=(el,type,fn,opts)=>{if(!el)return;el.addEventListener(type,fn,opts);cleanups.push(()=>el.removeEventListener(type,fn,opts));};const label=(el,text)=>{const p=el?.querySelector(\"p\");if(p&&p.textContent!==text)p.textContent=text;};const syncPlay=()=>{const playing=!video.paused&&!video.ended;root.classList.toggle(PLAYING,playing);label(playPause,playing?\"PAUSE\":\"PLAY\");playPause?.setAttribute(\"aria-label\",playing?\"Pause the video\":\"Play the video\");};const syncMute=()=>{root.classList.toggle(MUTED,video.muted);label(muteUnmute,video.muted?\"UNMUTE\":\"MUTE\");muteUnmute?.setAttribute(\"aria-label\",video.muted?\"Unmute the video\":\"Mute the video\");};const syncProgress=()=>{if(!played)return;const total=video.duration;const ratio=Number.isFinite(total)&&total>0?clamp(video.currentTime/total):0;played.style.width=`${ratio*100}%`;scrubber?.setAttribute(\"aria-valuenow\",String(Math.round(ratio*100)));};const togglePlay=event=>{event?.preventDefault();event?.stopPropagation();// A rejected play() is normal — autoplay policy, a backgrounded\n// tab — and must never throw.\nif(video.paused)video.play()?.catch?.(()=>{});else video.pause();};const toggleMute=event=>{event?.preventDefault();event?.stopPropagation();video.muted=!video.muted;syncMute();};const activate=(el,fn,role)=>{if(!el)return;el.setAttribute(\"role\",role);el.setAttribute(\"tabindex\",\"0\");on(el,\"click\",fn);on(el,\"keydown\",event=>{const key=event.key;if(key!==\"Enter\"&&key!==\" \")return;fn(event);});};activate(playPause,togglePlay,\"button\");activate(muteUnmute,toggleMute,\"button\");// Clicking the picture toggles playback, the way every player\n// behaves. The listener goes on the stage, not on the <video>: the\n// 30% veil the design puts over the clip is painted on top of it\n// and swallows every click, so a handler on the element itself\n// never fires. From the stage the click arrives either way —\n// through the veil, which is now transparent to the pointer, or by\n// bubbling up from the video.\n//\n// Only one listener, and it is this one. Keeping the <video> one as\n// well would toggle twice for a single click and look like nothing\n// happened.\nconst stage=q(\"Video Stage\");/**\n             * The centre glyph, built here rather than drawn on the canvas.\n             * It has no resting state — it exists for one second after a click\n             * on the picture and is invisible the rest of the time — so a node\n             * on the canvas would be a permanently hidden layer that every\n             * future editor has to wonder about.\n             *\n             * Only clicks on the picture raise it. Pressing the bar's own\n             * Play/Pause already shows its result in the bar, and a glyph\n             * thrown across the video for that would be an echo.\n             *//**\n             * The film's URL rides on a hidden second instance. Reading it\n             * from the DOM rather than a prop keeps the override's contract\n             * with the canvas to layer names, which is the only per-instance\n             * handle it has.\n             */const fullEl=q(\"Video Full\");const fullVideo=fullEl?.querySelector(\"video\");const fullSrc=fullVideo?.getAttribute(\"src\")||fullVideo?.currentSrc||\"\";const quietMotion=typeof matchMedia===\"function\"&&matchMedia(\"(prefers-reduced-motion: reduce)\").matches;// Someone who asked for less motion gets the poster and the button,\n// not a loop running on its own behind the text.\nlet teasing=Boolean(fullSrc)&&!quietMotion;if(teasing){root.classList.add(TEASER);video.muted=true;video.loop=true;video.playsInline=true;video.play()?.catch?.(()=>{});}const trocarPeloFilme=()=>{teasing=false;root.classList.remove(TEASER,FRESH);video.loop=false;video.muted=false;video.setAttribute(\"src\",fullSrc);video.load();video.play()?.catch?.(()=>{});syncMute();};let cue=null;if(stage){root.classList.add(FRESH);cue=document.createElement(\"div\");cue.className=CUE;cue.setAttribute(\"aria-hidden\",\"true\");// Pixels, not percentages: see the note on .fp-avp-cue.\ncue.innerHTML='<svg width=\"36\" height=\"36\" viewBox=\"0 0 16 16\" fill=\"none\" style=\"display:block\">'+GLYPHS.play+\"</svg>\";stage.appendChild(cue);cleanups.push(()=>cue?.remove());// The loop plays on its own; only a real play clears the cue.\non(video,\"play\",()=>{if(!teasing)root.classList.remove(FRESH);});}let flash=null;if(stage){flash=document.createElement(\"div\");flash.className=FLASH;flash.setAttribute(\"aria-hidden\",\"true\");stage.appendChild(flash);cleanups.push(()=>flash?.remove());}const showFlash=which=>{if(!flash)return;flash.innerHTML='<svg width=\"56\" height=\"56\" viewBox=\"0 0 16 16\" fill=\"none\" style=\"display:block\">'+GLYPHS[which]+\"</svg>\";// Restart the animation on a rapid second click: dropping the\n// class and reading layout forces the browser to treat the\n// next frame as a fresh run instead of ignoring it.\nflash.classList.remove(\"on\");void flash.offsetWidth;flash.classList.add(\"on\");};on(stage??video,\"click\",event=>{// The centre button vanishing IS the feedback for that first\n// press. Throwing the same glyph across the video on top of it\n// would be the same message twice, in the same place.\nif(teasing){event.preventDefault();event.stopPropagation();trocarPeloFilme();return;}const first=root.classList.contains(FRESH);togglePlay(event);if(first)return;// Read the state AFTER the toggle: pause() lands immediately\n// and play() clears `paused` before it resolves, so this is the\n// state the click produced, which is what the glyph reports.\nshowFlash(video.paused?\"pause\":\"play\");});// Seeking. Pointer events cover mouse, touch and pen in one path;\n// the capture keeps a drag alive after the finger leaves the 3px\n// track, which is most of any real drag.\nif(scrubber){// The stylesheet reaches the track by class, not by Framer's\n// layer name: the hit area and the flex rule below belong to\n// this player, and `[data-framer-name=\"Scrubber\"]` is a name\n// any other page is free to reuse.\nscrubber.classList.add(SCRUBBER);scrubber.setAttribute(\"role\",\"slider\");scrubber.setAttribute(\"tabindex\",\"0\");scrubber.setAttribute(\"aria-label\",\"Seek\");scrubber.setAttribute(\"aria-valuemin\",\"0\");scrubber.setAttribute(\"aria-valuemax\",\"100\");let seeking=false;const seekTo=clientX=>{const rect=scrubber.getBoundingClientRect();if(!rect.width)return;const total=video.duration;if(!Number.isFinite(total)||total<=0)return;video.currentTime=clamp((clientX-rect.left)/rect.width)*total;syncProgress();};on(scrubber,\"pointerdown\",event=>{const e=event;e.preventDefault();seeking=true;scrubber.setPointerCapture?.(e.pointerId);seekTo(e.clientX);});on(scrubber,\"pointermove\",event=>{if(!seeking)return;seekTo(event.clientX);});const stop=event=>{if(!seeking)return;seeking=false;const e=event;scrubber.releasePointerCapture?.(e.pointerId);};on(scrubber,\"pointerup\",stop);on(scrubber,\"pointercancel\",stop);on(scrubber,\"keydown\",event=>{const key=event.key;const step=key===\"ArrowRight\"?5:key===\"ArrowLeft\"?-5:0;if(!step)return;event.preventDefault();const total=video.duration;if(!Number.isFinite(total)||total<=0)return;video.currentTime=Math.min(Math.max(video.currentTime+step,0),total);syncProgress();});}// The bar follows the pointer, the scrubber does not. A timer\n// rather than plain :hover, because someone who stops moving over\n// the video is reading it, not aiming at a control — and because\n// touch has no hover at all, so a tap has to count as reaching.\nlet hideAt=0;let armed=0;/**\n             * Keyboard focus holds the bar open; a mouse click must not.\n             *\n             * The first version asked only whether focus was inside the\n             * player, and the bar then never hid again after the first play:\n             * pressing Play focuses the button — it carries tabindex — so the\n             * answer stayed yes for the rest of the visit. `:focus-visible` is\n             * the browser's own read of that difference, true for the keyboard\n             * and false for a click. Where it is unsupported the old, safer\n             * behaviour returns.\n             */const focusHolds=()=>{const el=document.activeElement;if(!el||!root.contains(el))return false;try{return el.matches(\":focus-visible\");}catch{return true;}};const hideChrome=()=>{if(focusHolds())return;root.classList.remove(CHROME);};const tick=()=>{armed=0;const left=hideAt-Date.now();if(left>0){armed=window.setTimeout(tick,left);return;}hideChrome();};const showChrome=()=>{root.classList.add(CHROME);hideAt=Date.now()+CHROME_MS;// One timer that re-arms itself, instead of clearing and\n// resetting on every mousemove.\nif(!armed)armed=window.setTimeout(tick,CHROME_MS);};on(root,\"pointerenter\",showChrome);on(root,\"pointermove\",showChrome);on(root,\"pointerdown\",showChrome);on(root,\"focusin\",showChrome);on(root,\"pointerleave\",()=>{hideAt=0;hideChrome();});cleanups.push(()=>{if(armed)window.clearTimeout(armed);});on(video,\"play\",syncPlay);on(video,\"pause\",syncPlay);on(video,\"ended\",syncPlay);on(video,\"volumechange\",syncMute);on(video,\"timeupdate\",syncProgress);on(video,\"loadedmetadata\",syncProgress);on(video,\"seeked\",syncProgress);// The element may already be further along than this effect knows:\n// a remount, or metadata that landed first.\nsyncPlay();syncMute();syncProgress();return()=>{for(const off of cleanups)off();root.classList.remove(ROOT,PLAYING,MUTED);};},[]);return /*#__PURE__*/_jsx(\"div\",{ref:host,style:{display:\"contents\"},children:/*#__PURE__*/_jsx(Component,{...props})});};};\nexport const __FramerMetadata__ = {\"exports\":{\"withArticleVideoPlayer\":{\"type\":\"reactHoc\",\"name\":\"withArticleVideoPlayer\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./ArticleVideoPlayer.map"],"mappings":"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"}