[object Object]

← back to Fantasea Consulting

videos: add 5 HeyGen brand-film grid (auto-swap as renders land)

b89e56b6272e293712563bdf8188ee1df1ad29e9 · 2026-07-16 12:01:31 -0700 · steve@designerwallcoverings.com

Files touched

Diff

commit b89e56b6272e293712563bdf8188ee1df1ad29e9
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date:   Thu Jul 16 12:01:31 2026 -0700

    videos: add 5 HeyGen brand-film grid (auto-swap as renders land)
---
 build.mjs         | 30 ++++++++++++++++++++++++++++--
 poll-videos.sh    | 23 +++++++++++++++++++++++
 public/index.html | 30 ++++++++++++++++++++++++++++--
 3 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/build.mjs b/build.mjs
index 6ae0c68..9d516f5 100644
--- a/build.mjs
+++ b/build.mjs
@@ -610,10 +610,36 @@ ${DUO}
       <div class="spec"><span>◐ Fade in / out</span><span>♪ Music bed</span><span>▶ Action item</span><span>⛵ Your footage</span><span>15–30s · Reels</span></div>
     </div>
   </div>
+
+  <div style="margin-top:78px"></div>
+  <div class="eyebrow">The five brand films — one per recommendation</div>
+  <h2 class="disp">Presenter shorts, each ending on an action item.</h2>
+  <p class="lead">Generated with HeyGen — fade in / out, music bed, on-screen action item. Each appears here as it finishes rendering (refresh to pick up new ones).</p>
+  <div class="films5">
+    <div class="f5" data-key="reputation"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Reputation</div><div class="fa">▶ Reply to reviews in 48h</div></div>
+    <div class="f5" data-key="advertising"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Advertising</div><div class="fa">▶ Google Ads + The Knot</div></div>
+    <div class="f5" data-key="competitors"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Competitors</div><div class="fa">▶ Own the luxury category</div></div>
+    <div class="f5" data-key="timing"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Timing</div><div class="fa">▶ Pre-sell the season now</div></div>
+    <div class="f5" data-key="social"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Social</div><div class="fa">▶ One handle everywhere</div></div>
+  </div>
+  <style>
+  .films5{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;margin-top:40px}
+  .f5{border:1px solid var(--line);background:var(--panel)}
+  .f5 .fv{position:relative;aspect-ratio:9/16;background:#000;overflow:hidden;cursor:pointer}
+  .f5 .fv video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
+  .f5 .fph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--gold);font-size:11px;letter-spacing:.2em;text-transform:uppercase;background:linear-gradient(160deg,#123829,#0c1512);opacity:.9}
+  .f5 .ft{font-family:'Cormorant Garamond',serif;font-size:19px;color:var(--gold);padding:14px 16px 4px}
+  .f5 .fa{font-size:12.5px;color:var(--dim);padding:0 16px 16px}
+  </style>
 </section>
 <script>
-// swap in the HeyGen brand film if it has rendered
-fetch('/videos/heygen-brandfilm.mp4',{method:'HEAD'}).then(r=>{if(r.ok){var v=document.getElementById('heyfilm');v.src='/videos/heygen-brandfilm.mp4';v.play();document.getElementById('heyph').style.display='none';}}).catch(()=>{});
+(function(){
+  fetch('/videos/heygen-brandfilm.mp4',{method:'HEAD'}).then(function(r){if(r.ok){var v=document.getElementById('heyfilm');if(v){v.src='/videos/heygen-brandfilm.mp4';v.play();var ph=document.getElementById('heyph');if(ph)ph.style.display='none';}}}).catch(function(){});
+  document.querySelectorAll('.f5').forEach(function(card){
+    var key=card.getAttribute('data-key'); var src='/videos/heygen-'+key+'.mp4';
+    fetch(src,{method:'HEAD'}).then(function(r){if(r.ok){var v=card.querySelector('video');v.src=src;v.play();var ph=card.querySelector('.fph');if(ph)ph.style.display='none';card.querySelector('.fv').addEventListener('click',function(){v.muted=!v.muted;});}}).catch(function(){});
+  });
+})();
 </script>
 
 <section id="roadmap">
diff --git a/poll-videos.sh b/poll-videos.sh
new file mode 100755
index 0000000..83a972b
--- /dev/null
+++ b/poll-videos.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Poll the 5 HeyGen renders and download each when complete.
+export HEYGEN_API_KEY=$(grep -iE "HEYGEN" ~/Projects/secrets-manager/.env | head -1 | cut -d= -f2- | tr -d '"'"'"' ')
+cd /Users/macstudio3/Projects/fantasea-consulting
+mkdir -p public/videos
+DONE=0
+for try in $(seq 1 60); do   # up to ~20 min
+  ALL=1
+  while read k id; do
+    out="public/videos/heygen-$k.mp4"
+    [ -s "$out" ] && continue
+    ALL=0
+    json=$(heygen video get "$id" 2>/dev/null)
+    st=$(echo "$json" | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>{try{const j=JSON.parse(d);const o=j.data||j;console.log(o.status||"?")}catch(e){console.log("?")}})')
+    if [ "$st" = "completed" ] || [ "$st" = "success" ]; then
+      url=$(echo "$json" | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>{try{const j=JSON.parse(d);const o=j.data||j;console.log(o.video_url||o.video_url_caption||"")}catch(e){console.log("")}})')
+      if [ -n "$url" ]; then curl -s -L -o "$out" "$url"; echo "$(date +%T) downloaded $k ($(stat -f%z "$out" 2>/dev/null||echo 0) b)"; fi
+    fi
+  done < videos-src/manifest.txt
+  [ "$ALL" = "1" ] && { echo "$(date +%T) ALL 5 DOWNLOADED"; DONE=1; break; }
+  sleep 20
+done
+echo "poller exit (done=$DONE)"
diff --git a/public/index.html b/public/index.html
index 5c924a6..90ed8f3 100644
--- a/public/index.html
+++ b/public/index.html
@@ -384,10 +384,36 @@ footer{padding:60px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
       <div class="spec"><span>◐ Fade in / out</span><span>♪ Music bed</span><span>▶ Action item</span><span>⛵ Your footage</span><span>15–30s · Reels</span></div>
     </div>
   </div>
+
+  <div style="margin-top:78px"></div>
+  <div class="eyebrow">The five brand films — one per recommendation</div>
+  <h2 class="disp">Presenter shorts, each ending on an action item.</h2>
+  <p class="lead">Generated with HeyGen — fade in / out, music bed, on-screen action item. Each appears here as it finishes rendering (refresh to pick up new ones).</p>
+  <div class="films5">
+    <div class="f5" data-key="reputation"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Reputation</div><div class="fa">▶ Reply to reviews in 48h</div></div>
+    <div class="f5" data-key="advertising"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Advertising</div><div class="fa">▶ Google Ads + The Knot</div></div>
+    <div class="f5" data-key="competitors"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Competitors</div><div class="fa">▶ Own the luxury category</div></div>
+    <div class="f5" data-key="timing"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Timing</div><div class="fa">▶ Pre-sell the season now</div></div>
+    <div class="f5" data-key="social"><div class="fv"><video muted loop playsinline></video><div class="fph">● rendering</div></div><div class="ft">Social</div><div class="fa">▶ One handle everywhere</div></div>
+  </div>
+  <style>
+  .films5{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;margin-top:40px}
+  .f5{border:1px solid var(--line);background:var(--panel)}
+  .f5 .fv{position:relative;aspect-ratio:9/16;background:#000;overflow:hidden;cursor:pointer}
+  .f5 .fv video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
+  .f5 .fph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--gold);font-size:11px;letter-spacing:.2em;text-transform:uppercase;background:linear-gradient(160deg,#123829,#0c1512);opacity:.9}
+  .f5 .ft{font-family:'Cormorant Garamond',serif;font-size:19px;color:var(--gold);padding:14px 16px 4px}
+  .f5 .fa{font-size:12.5px;color:var(--dim);padding:0 16px 16px}
+  </style>
 </section>
 <script>
-// swap in the HeyGen brand film if it has rendered
-fetch('/videos/heygen-brandfilm.mp4',{method:'HEAD'}).then(r=>{if(r.ok){var v=document.getElementById('heyfilm');v.src='/videos/heygen-brandfilm.mp4';v.play();document.getElementById('heyph').style.display='none';}}).catch(()=>{});
+(function(){
+  fetch('/videos/heygen-brandfilm.mp4',{method:'HEAD'}).then(function(r){if(r.ok){var v=document.getElementById('heyfilm');if(v){v.src='/videos/heygen-brandfilm.mp4';v.play();var ph=document.getElementById('heyph');if(ph)ph.style.display='none';}}}).catch(function(){});
+  document.querySelectorAll('.f5').forEach(function(card){
+    var key=card.getAttribute('data-key'); var src='/videos/heygen-'+key+'.mp4';
+    fetch(src,{method:'HEAD'}).then(function(r){if(r.ok){var v=card.querySelector('video');v.src=src;v.play();var ph=card.querySelector('.fph');if(ph)ph.style.display='none';card.querySelector('.fv').addEventListener('click',function(){v.muted=!v.muted;});}}).catch(function(){});
+  });
+})();
 </script>
 
 <section id="roadmap">

← 746d72f add Unlikely Revenue Streams section (merch/DTLA/membership/  ·  back to Fantasea Consulting  ·  auto-save: 2026-07-16T12:13:12 (5 files) — public/videos/hey ebb54ae →