← back to Prestige Hyperframes Promo
my-video/index.html
151 lines
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=1920, height=1080" />
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 1920px; height: 1080px; overflow: hidden; background: #05090f; }
body { font-family: "Inter", "SF Pro Display", system-ui, sans-serif; color: #eaf2ff; }
.full-bleed { position: absolute; inset: 0; width: 1920px; height: 1080px; }
.fill-video { position: absolute; inset: 0; width: 1920px; height: 1080px; object-fit: cover; }
.scene { position: absolute; inset: 0; display: flex; flex-direction: column;
align-items: center; justify-content: center; text-align: center; }
.eyebrow { font-weight: 800; font-size: 30px; letter-spacing: 8px; text-transform: uppercase; color: #38bdf8; }
.title { font-weight: 900; font-size: 130px; line-height: 1; text-shadow: 0 10px 50px rgba(0,0,0,.6); }
.sub { font-weight: 500; font-size: 40px; color: #c2d2e8; margin-top: 18px; }
.left { align-items: flex-start; justify-content: flex-end; text-align: left; padding: 0 0 150px 110px; }
.cat { display: inline-flex; align-items: center; gap: 12px; padding: 10px 20px; border-radius: 999px;
background: rgba(56,189,248,.16); border: 1px solid rgba(56,189,248,.45);
color: #38bdf8; font-weight: 800; font-size: 26px; letter-spacing: 3px; text-transform: uppercase; }
.svc-name { font-weight: 900; font-size: 96px; margin-top: 20px; text-shadow: 0 8px 40px rgba(0,0,0,.8); }
.price { font-weight: 900; font-size: 130px; line-height: .9; color: #38bdf8; text-shadow: 0 0 44px rgba(56,189,248,.5); }
.scrim-lr { background: linear-gradient(90deg, rgba(5,9,15,.92) 0%, rgba(5,9,15,.45) 44%, rgba(5,9,15,0) 70%); }
.stat { font-weight: 900; font-size: 76px; color: #eaf2ff; }
.statlbl { font-weight: 600; font-size: 30px; color: #9fb3cd; letter-spacing: 1px; }
.strike { position: absolute; left: 0; top: 54%; height: 12px; background: #fb7185; border-radius: 8px; }
.row { display: flex; gap: 80px; margin-top: 44px; }
</style>
</head>
<body>
<div id="root" data-composition-id="main" data-start="0" data-duration="28"
data-width="1920" data-height="1080">
<!-- shared animated background (NOT a clip) -->
<div id="bg" class="full-bleed"
style="background: radial-gradient(60% 60% at 30% 30%, #38bdf822 0%, transparent 60%), linear-gradient(160deg,#0a1424 0%,#0b1728 50%,#060c16 100%);"></div>
<!-- host audio: cloned-voice VO (root child) -->
<audio id="vo" src="assets/promo-vo.wav" data-start="0" data-volume="1"></audio>
<!-- service video clips (root children, muted, visibility by data-start/duration) -->
<video id="v-express" class="fill-video" muted playsinline preload="auto"
src="assets/svc-express-wash.mp4" data-start="8.8" data-duration="4.4" data-media-start="0"></video>
<video id="v-hand" class="fill-video" muted playsinline preload="auto"
src="assets/svc-hand-wash.mp4" data-start="13.0" data-duration="4.2" data-media-start="0"></video>
<video id="v-ceramic" class="fill-video" muted playsinline preload="auto"
src="assets/svc-ceramic-coating.mp4" data-start="17.0" data-duration="3.2" data-media-start="0"></video>
<!-- readability scrim over the service montage -->
<div id="scrim" class="clip full-bleed scrim-lr" data-start="8.8" data-duration="11.4" data-track-index="2"></div>
<!-- ── Scene 1: title (0–4.4) ── -->
<section id="s-title" class="clip scene" data-start="0" data-duration="4.2" data-track-index="3">
<div id="t-eyebrow" class="eyebrow">San Fernando Valley</div>
<div id="t-title" class="title">Prestige<br/>Car Wash</div>
<div id="t-sub" class="sub">Hand wash · Detail · Ceramic</div>
</section>
<!-- ── Scene 2: the model (4.2–8.8) ── -->
<section id="s-model" class="clip scene" data-start="4.2" data-duration="4.6" data-track-index="3">
<div style="position:relative; display:inline-block;">
<div id="m-head" class="title" style="font-size:104px;">No Appointments</div>
<div id="m-strike" class="strike" style="width:0;"></div>
</div>
<div id="m-fcfs" class="sub" style="font-weight:800; font-size:56px; color:#38bdf8; margin-top:22px;">First Come · First Served</div>
<div id="m-stats" class="row">
<div><div id="m-6" class="stat">6</div><div class="statlbl">full lines</div></div>
<div><div class="stat">Large</div><div class="statlbl">crew on deck</div></div>
<div><div class="stat">0</div><div class="statlbl">wait to book</div></div>
</div>
</section>
<!-- ── Scene 3: Express (8.8–13) ── -->
<section id="s-express" class="clip scene left" data-start="8.8" data-duration="4.2" data-track-index="3">
<div class="cat"><span style="width:10px;height:10px;border-radius:10px;background:#38bdf8;"></span> Wash</div>
<div class="svc-name">Express Exterior Wash</div>
<div id="p-express" class="price">$19</div>
</section>
<!-- ── Scene 4: Hand Wash (13–17) ── -->
<section id="s-hand" class="clip scene left" data-start="13.0" data-duration="4.0" data-track-index="3">
<div class="cat"><span style="width:10px;height:10px;border-radius:10px;background:#38bdf8;"></span> Signature</div>
<div class="svc-name">Premium Hand Wash</div>
<div id="p-hand" class="price">$79</div>
</section>
<!-- ── Scene 5: Ceramic (17–20.2) ── -->
<section id="s-ceramic" class="clip scene left" data-start="17.0" data-duration="3.2" data-track-index="3">
<div class="cat" style="background:rgba(52,211,153,.16);border-color:rgba(52,211,153,.45);color:#34d399;">
<span style="width:10px;height:10px;border-radius:10px;background:#34d399;"></span> Protection</div>
<div class="svc-name">Ceramic Coating · 9H</div>
<div id="p-ceramic" class="price" style="color:#34d399;text-shadow:0 0 44px rgba(52,211,153,.5);">from $999</div>
</section>
<!-- ── Scene 6: Tips (20.2–24) ── -->
<section id="s-tips" class="clip scene" data-start="20.2" data-duration="3.8" data-track-index="3">
<div id="tip-head" class="title" style="font-size:80px;">Tip the crew directly</div>
<div class="sub" style="margin-top:10px;">Scan their card — 100% goes straight to them.</div>
<img id="tip-card" src="assets/tip-marco.png" style="height:520px; margin-top:26px; border-radius:22px; box-shadow:0 30px 90px rgba(0,0,0,.7);" />
</section>
<!-- ── Scene 7: CTA (24–28) ── -->
<section id="s-cta" class="clip scene" data-start="24.0" data-duration="4.0" data-track-index="3">
<div id="c-eyebrow" class="eyebrow" style="color:#34d399;">No appointment · 6 lines · just drive up</div>
<div id="c-title" class="title" style="font-size:120px;">Come See Us</div>
<div id="c-sub" class="sub" style="font-weight:800;">Prestige Car Wash</div>
</section>
</div>
<script>
window.__timelines = window.__timelines || {};
const tl = gsap.timeline({ paused: true });
// shared background hue drift across the piece
tl.to("#bg", { filter: "hue-rotate(-18deg)", duration: 8.8, ease: "sine.inOut" }, 8.8)
.to("#bg", { filter: "hue-rotate(8deg)", duration: 7.8, ease: "sine.inOut" }, 20.2);
// Scene 1 — title
tl.from("#t-eyebrow", { opacity: 0, y: 20, duration: 0.5 }, 0.2)
.from("#t-title", { opacity: 0, y: 46, duration: 0.7, ease: "power3.out" }, 0.5)
.from("#t-sub", { opacity: 0, y: 20, duration: 0.5 }, 1.1);
// Scene 2 — model
tl.from("#m-head", { opacity: 0, scale: 0.9, duration: 0.5, ease: "back.out(1.6)" }, 4.4)
.to("#m-strike", { width: 620, duration: 0.5, ease: "power2.out" }, 4.9)
.from("#m-fcfs", { opacity: 0, y: 18, duration: 0.5 }, 5.0)
.from("#m-stats", { opacity: 0, y: 24, duration: 0.6 }, 5.6);
// Service scenes — cat + name + price pop
[["express", 8.8], ["hand", 13.0], ["ceramic", 17.0]].forEach(function (row) {
var k = row[0], t = row[1];
tl.from("#s-" + k + " .cat", { opacity: 0, x: -30, duration: 0.4 }, t + 0.15)
.from("#s-" + k + " .svc-name", { opacity: 0, y: 24, duration: 0.5 }, t + 0.3)
.from("#p-" + k, { opacity: 0, scale: 0.6, duration: 0.5, ease: "back.out(1.7)" }, t + 0.5);
});
// Scene 6 — tips
tl.from("#tip-head", { opacity: 0, y: 20, duration: 0.5 }, 20.4)
.from("#tip-card", { opacity: 0, y: 120, duration: 0.7, ease: "power3.out" }, 20.7);
// Scene 7 — CTA
tl.from("#c-eyebrow", { opacity: 0, y: 16, duration: 0.5 }, 24.2)
.from("#c-title", { opacity: 0, scale: 0.85, duration: 0.6, ease: "back.out(1.5)" }, 24.5)
.from("#c-sub", { opacity: 0, y: 16, duration: 0.5 }, 25.1);
window.__timelines["main"] = tl;
</script>
</body>
</html>