torque-ledger/films/first-bench/index.html

147 lines
6.6 KiB
HTML
Raw Normal View History

2026-07-18 19:36:45 +02:00
<!doctype html>
<html><head><meta charset="UTF-8"/>
<title>The First Bench — Alex Carter</title>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<style>
body{margin:0;background:#0b0f14;color:#fff;font-family:"Inter",system-ui,-apple-system,sans-serif}
#root{position:relative;width:1920px;height:1080px;overflow:hidden}
.clip{position:absolute;inset:0;display:grid;place-items:center}
/* SCENE 1: The Bench — wood grain CSS */
.bench-grain{
width:100%;height:100%;
background:
repeating-linear-gradient(90deg, transparent 0, transparent 58px, rgba(139,69,19,0.15) 59px, rgba(139,69,19,0.08) 60px),
radial-gradient(ellipse at center, #3d2612 0%, #1a0f08 70%);
filter:saturate(1.2) contrast(1.1);
}
.bench-lines{
position:absolute;inset:0;
background:
linear-gradient(0deg, rgba(255,255,255,0.03) 1px, transparent 1px) 0 0 / 100% 120px,
linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px) 0 0 / 80px 100%;
}
/* SCENE 2: The Jig — tolerance markings */
.jig-field{
width:100%;height:100%;
background:radial-gradient(circle at center, #1a1f29 0%, #0b0f14 85%);
}
.jig-circle{
position:absolute;width:860px;height:860px;border-radius:50%;
border:2px solid rgba(255,255,255,0.15);
box-shadow:0 0 60px rgba(255,255,255,0.08), inset 0 0 40px rgba(255,255,255,0.03);
}
.jig-crosshair{
position:absolute;width:100%;height:2px;background:rgba(255,255,255,0.25);
transform:rotate(0deg);
}
.jig-tick{
position:absolute;width:240px;height:2px;background:rgba(255,255,255,0.4);
}
/* SCENE 3: The Team — rhythmic pulses */
.team-field{
width:100%;height:100%;
background:conic-gradient(from 0deg at 50% 50%, #0b0f14 0%, #1a2332 25%, #0b0f14 50%, #1a2332 75%, #0b0f14 100%);
animation:team-spin 12s linear infinite;
}
@keyframes team-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
.pulse-ring{
position:absolute;border-radius:50%;border:2px solid rgba(255,255,255,0.3);
animation:outpulse 4s ease-out infinite;
}
@keyframes outpulse{
0%{width:120px;height:120px;opacity:1}
100%{width:1400px;height:1400px;opacity:0}
}
.overlay{position:absolute;inset:0;background:linear-gradient(180deg,rgba(11,15,20,0.0) 0%,rgba(11,15,20,0.88) 100%)}
h1{font-size:96px;font-weight:300;letter-spacing:-0.02em;margin:0;text-align:center;opacity:0;transform:translateY(40px)}
p{font-size:42px;font-weight:200;letter-spacing:-0.01em;text-align:center;max-width:1400px;line-height:1.4;opacity:0;transform:scale(0.98)}
.credit{position:absolute;bottom:40px;left:40px;font-size:22px;color:rgba(255,255,255,0.5);font-weight:300}
</style> <script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<div id="root" data-composition-id="main" data-start="0" data-width="1920" data-height="1080" data-duration="45">
<!-- SCENE 1: The Bench (0-15s) -->
<section id="s1" class="clip" data-start="0" data-duration="15" data-track-index="1">
<div class="bench-grain"></div>
<div class="bench-lines"></div>
<div class="overlay"></div>
<h1 id="s1-title">The Bench</h1>
<p id="s1-text">Every dome begins with a surface laid square.</p>
</section>
<!-- SCENE 2: The Jig (15-30s) -->
<section id="s2" class="clip" data-start="15" data-duration="15" data-track-index="1">
<div class="jig-field"></div>
<div class="jig-circle"></div>
<div class="jig-crosshair" style="top:50%;left:0;"></div>
<div class="jig-crosshair" style="left:50%;top:0;transform:rotate(90deg);"></div>
<div class="jig-tick" style="top:50%;left:calc(50% - 120px);transform:rotate(30deg);"></div>
<div class="jig-tick" style="top:50%;left:calc(50% - 120px);transform:rotate(-30deg);"></div>
<div class="jig-tick" style="top:calc(50% - 120px);left:50%;transform:rotate(90deg);"></div>
<div class="jig-tick" style="top:calc(50% + 120px);left:50%;transform:rotate(90deg);"></div>
<div class="overlay"></div>
<h1 id="s2-title">The Jig</h1>
<p id="s2-text">Where the tolerance locks in the grain.</p>
</section>
<!-- SCENE 3: The Team (30-45s) -->
<section id="s3" class="clip" data-start="30" data-duration="15" data-track-index="1">
<div class="team-field"></div>
<div class="pulse-ring" style="top:50%;left:50%;transform:translate(-50%,-50%);animation-delay:0s"></div>
<div class="pulse-ring" style="top:50%;left:50%;transform:translate(-50%,-50%);animation-delay:1.3s"></div>
<div class="pulse-ring" style="top:50%;left:50%;transform:translate(-50%,-50%);animation-delay:2.6s"></div>
<div class="overlay"></div>
<h1 id="s3-title">The Team</h1>
<p id="s3-text">And the rhythm that carries us home.</p>
</section>
<div class="credit">Alex Carter • Whittier • 35 years at the bench</div>
<!-- AUDIO TRACKS — required for voice + BGM -->
<audio id="voice-s1" src="audio/s1.wav" data-start="0"></audio>
<audio id="voice-s2" src="audio/s2.wav" data-start="15"></audio>
<audio id="voice-s3" src="audio/s3.wav" data-start="30"></audio>
<audio id="bgm" src="audio/music.mp3" data-start="0" data-volume="0.12"></audio>
</div>
<script>
window.__timelines = window.__timelines || {};
const tl = gsap.timeline({ paused: true });
// Scene 1: The Bench
tl.to(".bench-grain", { filter: "saturate(1.3) contrast(1.15)", duration: 3, ease: "power2.inOut" }, 0);
tl.to("#s1-title", { opacity: 1, y: 0, duration: 1.2, ease: "power3.out" }, 0.8);
tl.to("#s1-text", { opacity: 1, scale: 1, duration: 1.8, ease: "power2.out" }, 3.5);
tl.to(".bench-lines", { opacity: 1, duration: 2, ease: "power1.in" }, 2);
// Scene 2: The Jig
tl.to(".jig-circle", { boxShadow: "0 0 80px rgba(255,255,255,0.15), inset 0 0 60px rgba(255,255,255,0.08)", duration: 2, ease: "power2.out" }, 15);
tl.fromTo("#s2-title",
{ opacity: 0, x: 0, y: 0 },
{ opacity: 1, x: 0, y: 0, duration: 1.2, ease: "power3.out" }, 15.8);
tl.fromTo("#s2-text",
{ opacity: 0, scale: 0.98 },
{ opacity: 1, scale: 1, duration: 1.8, ease: "power2.out" }, 18.5);
tl.to(".jig-tick", { opacity: 1, scaleX: 1.1, duration: 1.5, stagger: 0.3, ease: "power2.out" }, 16.5);
// Scene 3: The Team
tl.fromTo("#s3-title",
{ opacity: 0, x: 0, y: 0 },
{ opacity: 1, x: 0, y: 0, duration: 1.2, ease: "power3.out" }, 30.8);
tl.fromTo("#s3-text",
{ opacity: 0, scale: 0.98 },
{ opacity: 1, scale: 1, duration: 1.8, ease: "power2.out" }, 33.5);
tl.to(".pulse-ring", { opacity: 1, duration: 0.5, stagger: 1.3, ease: "power1.out" }, 31);
// Hold the final frame
tl.to("body", { duration: 2, ease: "none" }, 43);
window.__timelines["main"] = tl;
</script>
</body></html>