תמונת פתיחה עם כפתור נגן. בלחיצה היא גדלה למודאל וידאו במעבר רציף מהמקום שלה, ובסגירה חוזרת אליו. הוידאו נטען רק בלחיצה.
מתי משתמשים: הירו עם סרטון תדמית. הדרך הנכונה לשים וידאו בלי להכביד על הטעינה הראשונה.
הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.
הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --accent או --line משלו יורש אותם אוטומטית. הרכיב הזה מסתמך על dir="rtl".
/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.stage{padding:var(--sec, clamp(120px, 12vw, 260px)) var(--gutter, clamp(24px, 5vw, 96px));position:relative}
.stage.tight{padding-block:clamp(48px,5vw,90px)}
.stage.full{padding-inline:0}
.ph{display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;border-radius:var(--r, 14px)}
.ph-b{background:linear-gradient(160deg,#5f3dc4,#9775fa)}
.ph-l{background:rgba(16,18,43,.72);color:#fff;padding:.18em .7em;border-radius:999px;line-height:1.3;font-size:max(.78em,12px)}
/* B60 · וידאו שנפתח מתמונת ההירו */
.hv{max-width:900px;margin-inline:auto}
.hv-thumb{position:relative;display:block;width:100%;aspect-ratio:16/9;border:0;padding:0;border-radius:var(--r, 14px);overflow:hidden;cursor:pointer;background:none;font:inherit}
.hv-thumb .ph{position:absolute;inset:0;font-size:18px;border-radius:0;align-items:flex-end;justify-content:flex-start;padding:22px}
.hv-play{position:absolute;inset:0;display:grid;place-items:center}
.hv-play span{width:84px;height:84px;border-radius:50%;background:rgba(255,255,255,.92);display:grid;place-items:center;color:var(--ink, #16182b);font-size:26px;box-shadow:0 12px 40px rgba(0,0,0,.25);transition:transform .35s cubic-bezier(.2,.6,.2,1)}
@media (hover:hover) and (pointer:fine){.hv-thumb:hover .hv-play span{transform:scale(1.08)}}
.hv-thumb:focus-visible{outline:3px solid var(--accent, #4a3aff);outline-offset:4px}
.hv-modal{position:fixed;inset:0;z-index:50;display:none;place-items:center;padding:24px;background:rgba(10,10,20,0);transition:background-color .4s}
.hv-modal.on{display:grid}.hv-modal.in{background:rgba(10,10,20,.82)}
.hv-frame{width:min(1100px,100%);aspect-ratio:16/9;border-radius:var(--r, 14px);overflow:hidden;background:#000;transform-origin:top left;box-shadow:0 30px 80px rgba(0,0,0,.4)}
.hv-frame video{width:100%;height:100%;display:block;object-fit:cover}
.hv-close{position:absolute;top:18px;inset-inline-end:18px;width:44px;height:44px;border-radius:50%;border:0;background:rgba(255,255,255,.14);color:#fff;font-size:20px;cursor:pointer;opacity:0;transition:opacity .3s .2s}
.hv-modal.in .hv-close{opacity:1}
.hv-close:focus-visible{outline:2px solid #fff}
<div class="stage tight"><div class="hv">
<button class="hv-thumb" aria-label="נגן סרטון תדמית"><div class="ph ph-b"><span class="ph-l">סרטון תדמית</span></div><div class="hv-play"><span>▶</span></div></button>
</div>
<div class="hv-modal" role="dialog" aria-modal="true" aria-label="סרטון תדמית">
<div class="hv-frame"><video data-src="https://liavwebdesign-spec.github.io/motion-vault/assets/media/demo-a.mp4" playsinline controls muted></video></div>
<button class="hv-close" aria-label="סגור">✕</button>
</div></div>
(function(){
const btn=document.querySelector(".hv-thumb"),modal=document.querySelector(".hv-modal"),frame=modal.querySelector(".hv-frame"),video=frame.querySelector("video"),close=modal.querySelector(".hv-close");
const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches,E="cubic-bezier(.2,.6,.2,1)";
function open(){
if(!video.src)video.src=video.dataset.src;
const a=btn.getBoundingClientRect();modal.classList.add("on");
const b=frame.getBoundingClientRect();
if(!reduce){frame.animate([{transform:"translate("+(a.left-b.left)+"px,"+(a.top-b.top)+"px) scale("+(a.width/b.width)+","+(a.height/b.height)+")"},{transform:"none"}],{duration:520,easing:E});}
requestAnimationFrame(()=>modal.classList.add("in"));
video.play().catch(()=>{});close.focus();
document.addEventListener("keydown",onKey);
}
function shut(){
video.pause();modal.classList.remove("in");
const a=btn.getBoundingClientRect(),b=frame.getBoundingClientRect();
const anim=reduce?null:frame.animate([{transform:"none"},{transform:"translate("+(a.left-b.left)+"px,"+(a.top-b.top)+"px) scale("+(a.width/b.width)+","+(a.height/b.height)+")"}],{duration:420,easing:E});
(anim?anim.finished:Promise.resolve()).then(()=>{modal.classList.remove("on");btn.focus();});
document.removeEventListener("keydown",onKey);
}
function onKey(e){if(e.key==="Escape")shut();}
btn.addEventListener("click",open);close.addEventListener("click",shut);
modal.addEventListener("click",e=>{if(e.target===modal)shut();});
})();