|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Renovate Story</title> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script> |
|
<style> |
|
:root { |
|
--bg: #050a14; |
|
--text: #ffffff; |
|
--gemini-blue: #4285f4; |
|
--gemini-purple: #9b72f3; |
|
--gemini-teal: #4db6ac; |
|
--accent: #8ab4f8; |
|
--card-bg: rgba(255, 255, 255, 0.05); |
|
--success: #34a853; |
|
} |
|
body, html { |
|
margin: 0; |
|
padding: 0; |
|
width: 1920px; |
|
height: 1080px; |
|
background-color: var(--bg); |
|
color: var(--text); |
|
font-family: 'Google Sans', 'Inter', sans-serif; |
|
overflow: hidden; |
|
} |
|
#root { |
|
width: 1920px; |
|
height: 1080px; |
|
position: relative; |
|
background: linear-gradient(135deg, #050a14 0%, #0d1b3e 100%); |
|
} |
|
/* Gemini Gradient for accents */ |
|
.gemini-gradient { |
|
background: linear-gradient(90deg, var(--gemini-blue), var(--gemini-purple), var(--gemini-teal)); |
|
-webkit-background-clip: text; |
|
-webkit-text-fill-color: transparent; |
|
} |
|
.clip { |
|
position: absolute; |
|
display: flex; |
|
flex-direction: column; |
|
justify-content: center; |
|
align-items: center; |
|
width: 100%; |
|
height: 100%; |
|
} |
|
h1 { |
|
font-size: 90px; |
|
font-weight: 700; |
|
margin: 0 0 40px 0; |
|
letter-spacing: -1px; |
|
} |
|
p { |
|
font-size: 48px; |
|
max-width: 1300px; |
|
line-height: 1.5; |
|
color: #e8eaed; |
|
margin: 0; |
|
font-weight: 400; |
|
} |
|
.card-container { |
|
display: flex; |
|
gap: 40px; |
|
margin-top: 60px; |
|
justify-content: center; |
|
} |
|
.card { |
|
background: var(--card-bg); |
|
backdrop-filter: blur(20px); |
|
padding: 50px; |
|
border-radius: 32px; |
|
border: 1px solid rgba(255,255,255,0.1); |
|
width: 420px; |
|
text-align: center; |
|
box-shadow: 0 20px 50px rgba(0,0,0,0.5); |
|
} |
|
.card .title { |
|
font-size: 32px; |
|
font-weight: 500; |
|
color: var(--accent); |
|
margin-bottom: 24px; |
|
text-transform: uppercase; |
|
letter-spacing: 2px; |
|
} |
|
.card .value { |
|
font-size: 80px; |
|
font-weight: 800; |
|
} |
|
.icon { |
|
font-size: 120px; |
|
margin-bottom: 40px; |
|
filter: drop-shadow(0 0 20px rgba(138, 180, 248, 0.4)); |
|
} |
|
.code-block { |
|
background: #000; |
|
padding: 40px; |
|
border-radius: 20px; |
|
font-family: 'JetBrains Mono', 'Roboto Mono', monospace; |
|
font-size: 26px; |
|
color: #fff; |
|
border: 1px solid var(--gemini-purple); |
|
margin-top: 50px; |
|
width: 900px; |
|
text-align: left; |
|
line-height: 1.6; |
|
box-shadow: 0 0 40px rgba(155, 114, 243, 0.2); |
|
} |
|
.footer-credit { |
|
position: absolute; |
|
bottom: 60px; |
|
font-size: 24px; |
|
color: rgba(255,255,255,0.4); |
|
display: flex; |
|
align-items: center; |
|
gap: 12px; |
|
} |
|
.sparkle { |
|
color: var(--gemini-purple); |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div id="root" class="clip" |
|
data-composition-id="renovate-story" |
|
data-width="1920" |
|
data-height="1080" |
|
data-start="0" |
|
data-duration="66" |
|
data-track-index="0"> |
|
|
|
<!-- Audio Tracks --> |
|
<audio id="audio1" class="clip" data-start="0.5" data-duration="11.8" data-track-index="1" src="audio/scene1-intro.wav"></audio> |
|
<audio id="audio2" class="clip" data-start="14.0" data-duration="11.1" data-track-index="2" src="audio/scene2-manual.wav"></audio> |
|
<audio id="audio3" class="clip" data-start="27.0" data-duration="12.3" data-track-index="3" src="audio/scene3-solution.wav"></audio> |
|
<audio id="audio4" class="clip" data-start="41.0" data-duration="11.2" data-track-index="4" src="audio/scene4-automation.wav"></audio> |
|
<audio id="audio5" class="clip" data-start="54.0" data-duration="11.4" data-track-index="5" src="audio/scene5-conclusion.wav"></audio> |
|
|
|
<!-- Scene 1 Clips (0 - 13.5s) --> |
|
<div id="s1-content" class="clip" data-start="0" data-duration="13.5" data-track-index="10"> |
|
<div class="icon" id="s1-icon">🏠</div> |
|
<h1 id="s1-title" class="gemini-gradient">Homelab Maintenance</h1> |
|
<p id="s1-p">The joy of self-hosting often comes with the burden of manual updates.</p> |
|
</div> |
|
|
|
<!-- Scene 2 Clips (13.5 - 26.5s) --> |
|
<div id="s2-content" class="clip" data-start="13.5" data-duration="13" data-track-index="11"> |
|
<h1 id="s2-title">The Manual Era</h1> |
|
<p id="s2-p">Tracking versions and creating pull requests manually is slow and error-prone.</p> |
|
<div class="card-container" id="s2-cards"> |
|
<div class="card"> |
|
<div class="title">Updates / 2 Months</div> |
|
<div class="value">13</div> |
|
</div> |
|
<div class="card"> |
|
<div class="title">Process</div> |
|
<div class="value">Manual</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<!-- Scene 3 Clips (26.5 - 40.5s) --> |
|
<div id="s3-content" class="clip" data-start="26.5" data-duration="14" data-track-index="12"> |
|
<h1 id="s3-title" class="gemini-gradient">Self-Hosted Renovate</h1> |
|
<p id="s3-p">Deployed on K3s with ArgoCD, running a daily cron job to keep everything fresh.</p> |
|
<div class="code-block" id="s3-code"> |
|
<span style="color: var(--gemini-purple)">schedule:</span> "0 1 * * *"<br> |
|
<span style="color: var(--gemini-purple)">image:</span> renovate/renovate:43.168.5<br> |
|
<span style="color: var(--gemini-purple)">env:</span> RENOVATE_APP_ID |
|
</div> |
|
</div> |
|
|
|
<!-- Scene 4 Clips (40.5 - 53.5s) --> |
|
<div id="s4-content" class="clip" data-start="40.5" data-duration="13" data-track-index="13"> |
|
<h1 id="s4-title">Beyond Simple PRs</h1> |
|
<p id="s4-p">A custom wrapper script automates manifest rendering using Kustomize and Helm.</p> |
|
<div class="code-block" id="s4-code"> |
|
<span style="color: #666"># bin/renovate-wrapper.sh</span><br> |
|
install-tool kustomize 5.8.1<br> |
|
install-tool helm 4.1.4<br> |
|
./bin/render-manifests.sh |
|
</div> |
|
</div> |
|
|
|
<!-- Scene 5 Clips (53.5 - 66s) --> |
|
<div id="s5-content" class="clip" data-start="53.5" data-duration="12.5" data-track-index="14"> |
|
<div class="icon" id="s5-icon">🚀</div> |
|
<h1 id="s5-title" class="gemini-gradient">Automated Success</h1> |
|
<p id="s5-p">27 updates in just a few weeks. Secure, current, and completely hands-off.</p> |
|
<div class="card-container" id="s5-cards"> |
|
<div class="card" style="border-color: var(--success)"> |
|
<div class="title" style="color: var(--success)">Updates / 3 Weeks</div> |
|
<div class="value">27</div> |
|
</div> |
|
<div class="card" style="border-color: var(--gemini-blue)"> |
|
<div class="title" style="color: var(--gemini-blue)">Process</div> |
|
<div class="value">Automated</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
/** |
|
* Composition: Renovate Story |
|
* Framework: HyperFrames (HTML/CSS/GSAP) |
|
* Management: Gemini CLI |
|
*/ |
|
|
|
const tl = gsap.timeline(); |
|
const DURATION = 66; |
|
|
|
// Required registration for HyperFrames discovery |
|
window.__timelines = { "renovate-story": tl }; |
|
|
|
/* --- Scene 1: Homelab Maintenance (0 - 13.5s) --- */ |
|
tl.from("#s1-icon", { scale: 0, duration: 0.8, ease: "back.out(1.7)" }, 0.5); |
|
tl.from("#s1-title", { opacity: 0, y: 50, duration: 0.8, ease: "power3.out" }, 1.0); |
|
tl.from("#s1-p", { opacity: 0, y: 30, duration: 0.8, ease: "power3.out" }, 1.5); |
|
tl.to("#s1-content", { opacity: 0, duration: 0.5 }, 13.0); |
|
|
|
/* --- Scene 2: The Manual Era (13.5 - 26.5s) --- */ |
|
tl.from("#s2-title", { opacity: 0, x: -50, duration: 0.8 }, 14.5); |
|
tl.from("#s2-p", { opacity: 0, x: 50, duration: 0.8 }, 15.0); |
|
tl.from("#s2-cards", { opacity: 0, y: 100, duration: 0.8 }, 16.0); |
|
tl.to("#s2-content", { opacity: 0, duration: 0.5 }, 26.0); |
|
|
|
/* --- Scene 3: Self-Hosted Renovate (26.5 - 40.5s) --- */ |
|
tl.from("#s3-title", { opacity: 0, scale: 0.8, duration: 0.8 }, 27.5); |
|
tl.from("#s3-p", { opacity: 0, y: 20, duration: 0.8 }, 28.0); |
|
tl.from("#s3-code", { opacity: 0, width: 0, duration: 1, ease: "power4.out" }, 29.0); |
|
tl.to("#s3-content", { opacity: 0, duration: 0.5 }, 40.0); |
|
|
|
/* --- Scene 4: Beyond Simple PRs (40.5 - 53.5s) --- */ |
|
tl.from("#s4-title", { opacity: 0, y: -30, duration: 0.8 }, 41.5); |
|
tl.from("#s4-p", { opacity: 0, y: 30, duration: 0.8 }, 42.0); |
|
tl.from("#s4-code", { opacity: 0, x: -100, duration: 0.8 }, 43.0); |
|
tl.to("#s4-content", { opacity: 0, duration: 0.5 }, 53.0); |
|
|
|
/* --- Scene 5: Automated Success (53.5 - 66s) --- */ |
|
tl.from("#s5-icon", { rotate: 360, scale: 0, duration: 1 }, 54.5); |
|
tl.from("#s5-title", { opacity: 0, y: -50, duration: 0.8 }, 55.0); |
|
tl.from("#s5-p", { opacity: 0, duration: 0.8 }, 55.5); |
|
tl.from("#s5-cards", { opacity: 0, scale: 0.5, duration: 0.8, ease: "back.out" }, 56.5); |
|
|
|
// Enforce total duration |
|
tl.set({}, {}, DURATION); |
|
</script> |
|
</body> |
|
</html> |
renovate-story.mp4