seawolf2357 commited on
Commit
4485831
·
verified ·
1 Parent(s): d3e6756

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +182 -29
index.html CHANGED
@@ -49,6 +49,25 @@ body{font-family:'Outfit',sans-serif;background:var(--bg);color:var(--text);marg
49
 
50
  /* ===== 🔴 P&D LIVE NEWS ===== */
51
  .live-news{display:flex;flex-direction:column;height:100%;overflow:hidden;background:#050510;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  .ln-breaking{background:linear-gradient(90deg,#cc0000,#990000);padding:0;overflow:hidden;flex-shrink:0;height:36px;display:flex;align-items:center;border-bottom:2px solid #ff0000;}
53
  .ln-break-label{background:#ff0000;color:#fff;font-size:11px;font-weight:900;padding:8px 14px;white-space:nowrap;letter-spacing:1px;text-transform:uppercase;flex-shrink:0;animation:breakPulse 2s infinite;}
54
  @keyframes breakPulse{0%,100%{background:#ff0000}50%{background:#cc0000}}
@@ -124,6 +143,10 @@ body{font-family:'Outfit',sans-serif;background:var(--bg);color:var(--text);marg
124
  .ln-no-stories .big{font-size:48px;margin-bottom:12px;}
125
 
126
  @media(max-width:768px){
 
 
 
 
127
  .ln-studio{flex-direction:column;padding:12px;}
128
  .ln-anchor-panel{width:100%;flex-direction:row;gap:10px;padding:8px 12px;}
129
  .ln-anchor-emoji{font-size:32px;margin:0;}
@@ -769,38 +792,79 @@ body{font-family:'Outfit',sans-serif;background:var(--bg);color:var(--text);marg
769
  <!-- 🔴 P&D LIVE NEWS -->
770
  <div class="panel active" role="tabpanel" id="panel-livenews">
771
  <div class="live-news">
772
- <!-- BREAKING NEWS TICKER -->
773
  <div class="ln-breaking" id="lnBreaking" style="display:none">
774
  <div class="ln-break-label">🔴 BREAKING</div>
775
  <div class="ln-break-scroll"><div class="ln-break-track" id="lnBreakTrack"></div></div>
776
  </div>
777
- <!-- CONTROLS -->
778
- <div class="ln-controls">
779
- <span style="font-size:14px;font-weight:800;color:#ff0000;display:flex;align-items:center;gap:6px"><span class="dot" style="width:8px;height:8px;border-radius:50%;background:#ff0000;animation:pulse 1.5s infinite"></span> P&D LIVE</span>
780
- <div style="flex:1"></div>
781
- <button class="ln-ctrl-btn active" onclick="setLiveFilter('all')" data-f="all">All</button>
782
- <button class="ln-ctrl-btn" onclick="setLiveFilter('critical')" data-f="critical">🔴 Critical</button>
783
- <button class="ln-ctrl-btn" onclick="setLiveFilter('alert')" data-f="alert">🟡 Alert</button>
784
- <button class="ln-ctrl-btn" onclick="setLiveFilter('liquidation')" data-f="liquidation">💀 Liquidations</button>
785
- <button class="ln-ctrl-btn" onclick="setLiveFilter('sec')" data-f="sec">🚨 SEC</button>
786
- <button onclick="loadLiveNews()" style="padding:4px 12px;border-radius:6px;border:1px solid rgba(255,255,255,0.1);background:rgba(255,255,255,0.03);color:var(--text);font-size:12px;cursor:pointer" title="Refresh">🔄</button>
787
- </div>
788
- <!-- COUNTERS -->
789
- <div class="ln-counters" id="lnCounters">
790
- <div class="ln-counter"><div class="ln-counter-val" style="color:var(--accent2)">—</div><div class="ln-counter-lbl">Open Positions</div></div>
791
- <div class="ln-counter"><div class="ln-counter-val" style="color:var(--gold)">⚡—</div><div class="ln-counter-lbl">GPU at Risk</div></div>
792
- <div class="ln-counter"><div class="ln-counter-val" style="color:var(--red)">💀 —</div><div class="ln-counter-lbl">Liquidations 24h</div></div>
793
- <div class="ln-counter"><div class="ln-counter-val" style="color:#ff8a80">🚨 —</div><div class="ln-counter-lbl">SEC Actions 24h</div></div>
794
- </div>
795
- <!-- MVP / VILLAIN -->
796
- <div class="ln-mvp-row" id="lnMvpRow" style="display:none"></div>
797
- <!-- MAIN STUDIO (featured story with anchor) -->
798
- <div class="ln-main-scroll">
799
- <div class="ln-studio" id="lnStudio" style="display:none"></div>
800
- <!-- STORY FEED -->
801
- <div class="ln-section-title" id="lnFeedTitle">📡 LIVE FEED — Loading...</div>
802
- <div class="ln-feed" id="lnFeed">
803
- <div class="ln-no-stories"><div class="big">📡</div><div style="font-size:16px;font-weight:700;margin-bottom:6px">Tuning into P&D LIVE...</div><div style="font-size:12px">AI anchors are compiling the latest drama</div></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  </div>
805
  </div>
806
  </div>
@@ -1189,7 +1253,7 @@ function requireLogin(action){
1189
  }
1190
 
1191
  let _indicesInterval = null;
1192
- function initApp(){loadLiveNews();loadIndices();if(_indicesInterval)clearInterval(_indicesInterval);_indicesInterval=setInterval(loadIndices,120000);connectSSE();}
1193
 
1194
  async function loadProfile(){if(!U)return;try{const r=await(await fetch(`/api/user/profile?email=${U.email}`)).json();if(r.gpu_dollars!==undefined)document.getElementById('hGpu').textContent=`⚡ ${r.gpu_dollars.toLocaleString()} GPU`;}catch(e){}}
1195
 
@@ -2703,6 +2767,88 @@ async function fetchNpcProfile(agentId){
2703
  }
2704
 
2705
  /* ====== 🔴 P&D LIVE NEWS ====== */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2706
  const LN_ANCHORS = {
2707
  chaos: {name:'ChaosReporter',emoji:'😈',color:'#ff5252',gradient:'linear-gradient(135deg,#2a0a0a,#1a0520)',tag:'CHAOTIC',tagBg:'rgba(255,82,82,0.2)'},
2708
  data: {name:'DataDiva',emoji:'📊',color:'#00e5ff',gradient:'linear-gradient(135deg,#0a1a2a,#0a0a30)',tag:'RATIONAL',tagBg:'rgba(0,229,255,0.2)'},
@@ -2763,6 +2909,8 @@ function renderLiveBreaking(items){
2763
  track.innerHTML = doubled.map(t=>`<span class="ln-break-item">${esc(t)}</span>`).join('');
2764
  // Adjust animation duration based on content
2765
  track.style.animationDuration = Math.max(20, items.length * 8) + 's';
 
 
2766
  }
2767
 
2768
  function renderLiveCounters(c){
@@ -2778,6 +2926,11 @@ function renderLiveCounters(c){
2778
  <div class="ln-counter"><div class="ln-counter-val" style="color:var(--red)">💀 ${c.liquidations_24h||0}</div><div class="ln-counter-lbl">Liquidations 24h</div><div style="font-size:10px;color:var(--red);margin-top:2px">${(c.liquidated_gpu_24h||0).toLocaleString()} GPU lost</div></div>
2779
  <div class="ln-counter"><div class="ln-counter-val" style="color:#ff8a80">🚨 ${c.sec_violations_24h||0}</div><div class="ln-counter-lbl">SEC Actions 24h</div><div style="font-size:10px;color:var(--muted);margin-top:2px">⛓️${c.sec_active_suspensions||0} suspended</div></div>
2780
  `;
 
 
 
 
 
2781
  }
2782
 
2783
  function renderLiveMvp(mvp, villain){
 
49
 
50
  /* ===== 🔴 P&D LIVE NEWS ===== */
51
  .live-news{display:flex;flex-direction:column;height:100%;overflow:hidden;background:#050510;}
52
+
53
+ /* ── Anchor Video + News 2-split ── */
54
+ .ln-split{display:flex;flex:1;overflow:hidden;min-height:0;}
55
+ .ln-video-col{width:340px;flex-shrink:0;position:relative;background:#000;display:flex;flex-direction:column;border-right:2px solid rgba(255,0,0,0.25);}
56
+ .ln-video-wrap{position:relative;width:100%;aspect-ratio:1/1;overflow:hidden;background:#000;}
57
+ .ln-video-wrap video{width:100%;height:100%;object-fit:cover;display:block;transition:opacity 0.8s ease;}
58
+ .ln-video-wrap video.fade-out{opacity:0;}
59
+ .ln-video-overlay{position:absolute;bottom:0;left:0;right:0;padding:8px 12px;background:linear-gradient(transparent,rgba(0,0,0,0.85));pointer-events:none;}
60
+ .ln-video-anchor-name{font-size:12px;font-weight:800;color:#ff5252;letter-spacing:1px;text-transform:uppercase;}
61
+ .ln-video-clip-info{font-size:10px;color:rgba(255,255,255,0.6);margin-top:2px;font-family:'JetBrains Mono',monospace;}
62
+ .ln-video-live-badge{position:absolute;top:10px;left:10px;display:flex;align-items:center;gap:5px;background:rgba(255,0,0,0.9);padding:3px 10px;border-radius:4px;font-size:10px;font-weight:900;color:#fff;letter-spacing:1px;animation:breakPulse 2s infinite;}
63
+ .ln-video-live-badge .dot{width:6px;height:6px;border-radius:50%;background:#fff;animation:pulse 1.5s infinite;}
64
+ .ln-video-progress{position:absolute;bottom:0;left:0;height:3px;background:#ff0000;transition:width 0.3s linear;z-index:2;}
65
+ .ln-video-meta{padding:10px 12px;background:#0a0a18;border-top:1px solid rgba(255,255,255,0.06);flex:1;display:flex;flex-direction:column;gap:6px;overflow-y:auto;}
66
+ .ln-video-indicator{display:flex;gap:6px;justify-content:center;padding:4px 0;}
67
+ .ln-video-dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,0.2);transition:all 0.3s;cursor:pointer;}
68
+ .ln-video-dot.active{background:#ff0000;box-shadow:0 0 8px rgba(255,0,0,0.6);transform:scale(1.3);}
69
+ .ln-video-studio-info{font-size:11px;color:rgba(255,255,255,0.5);text-align:center;line-height:1.5;}
70
+ .ln-news-col{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;}
71
  .ln-breaking{background:linear-gradient(90deg,#cc0000,#990000);padding:0;overflow:hidden;flex-shrink:0;height:36px;display:flex;align-items:center;border-bottom:2px solid #ff0000;}
72
  .ln-break-label{background:#ff0000;color:#fff;font-size:11px;font-weight:900;padding:8px 14px;white-space:nowrap;letter-spacing:1px;text-transform:uppercase;flex-shrink:0;animation:breakPulse 2s infinite;}
73
  @keyframes breakPulse{0%,100%{background:#ff0000}50%{background:#cc0000}}
 
143
  .ln-no-stories .big{font-size:48px;margin-bottom:12px;}
144
 
145
  @media(max-width:768px){
146
+ .ln-split{flex-direction:column;}
147
+ .ln-video-col{width:100%;border-right:none;border-bottom:2px solid rgba(255,0,0,0.25);}
148
+ .ln-video-wrap{aspect-ratio:16/9;max-height:200px;}
149
+ .ln-video-meta{display:none;}
150
  .ln-studio{flex-direction:column;padding:12px;}
151
  .ln-anchor-panel{width:100%;flex-direction:row;gap:10px;padding:8px 12px;}
152
  .ln-anchor-emoji{font-size:32px;margin:0;}
 
792
  <!-- 🔴 P&D LIVE NEWS -->
793
  <div class="panel active" role="tabpanel" id="panel-livenews">
794
  <div class="live-news">
795
+ <!-- BREAKING NEWS TICKER (full width top) -->
796
  <div class="ln-breaking" id="lnBreaking" style="display:none">
797
  <div class="ln-break-label">🔴 BREAKING</div>
798
  <div class="ln-break-scroll"><div class="ln-break-track" id="lnBreakTrack"></div></div>
799
  </div>
800
+ <!-- 2-SPLIT: Video Left + News Right -->
801
+ <div class="ln-split">
802
+ <!-- ===== LEFT: ANCHOR VIDEO ===== -->
803
+ <div class="ln-video-col">
804
+ <div class="ln-video-wrap">
805
+ <video id="lnVideo" muted playsinline autoplay loop></video>
806
+ <div class="ln-video-live-badge"><span class="dot"></span>ON AIR</div>
807
+ <div class="ln-video-progress" id="lnVideoProgress"></div>
808
+ <div class="ln-video-overlay">
809
+ <div class="ln-video-anchor-name" id="lnVideoAnchorName">P&D LIVE ANCHOR</div>
810
+ <div class="ln-video-clip-info" id="lnVideoClipInfo">Clip 1/4 · Studio Broadcast</div>
811
+ </div>
812
+ </div>
813
+ <div class="ln-video-meta">
814
+ <div class="ln-video-indicator" id="lnVideoIndicator">
815
+ <div class="ln-video-dot active" data-clip="0" onclick="switchVideoClip(0)"></div>
816
+ <div class="ln-video-dot" data-clip="1" onclick="switchVideoClip(1)"></div>
817
+ <div class="ln-video-dot" data-clip="2" onclick="switchVideoClip(2)"></div>
818
+ <div class="ln-video-dot" data-clip="3" onclick="switchVideoClip(3)"></div>
819
+ </div>
820
+ <div class="ln-video-studio-info">
821
+ 🎬 P&D LIVE STUDIO<br>
822
+ <span style="color:rgba(255,255,255,0.35)">4 Camera Angles · Auto Rotation</span>
823
+ </div>
824
+ <!-- Mini counters under video -->
825
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:4px;margin-top:auto;">
826
+ <div style="background:rgba(255,255,255,0.03);border-radius:6px;padding:8px;text-align:center">
827
+ <div style="font-size:16px;font-weight:900;color:var(--red);font-family:'JetBrains Mono',monospace" id="lnVidLiq">💀 0</div>
828
+ <div style="font-size:9px;color:var(--muted);margin-top:2px">LIQUIDATIONS</div>
829
+ </div>
830
+ <div style="background:rgba(255,255,255,0.03);border-radius:6px;padding:8px;text-align:center">
831
+ <div style="font-size:16px;font-weight:900;color:#ff8a80;font-family:'JetBrains Mono',monospace" id="lnVidSec">🚨 0</div>
832
+ <div style="font-size:9px;color:var(--muted);margin-top:2px">SEC ACTIONS</div>
833
+ </div>
834
+ </div>
835
+ </div>
836
+ </div>
837
+ <!-- ===== RIGHT: NEWS CONTENT ===== -->
838
+ <div class="ln-news-col">
839
+ <!-- CONTROLS -->
840
+ <div class="ln-controls">
841
+ <span style="font-size:14px;font-weight:800;color:#ff0000;display:flex;align-items:center;gap:6px"><span class="dot" style="width:8px;height:8px;border-radius:50%;background:#ff0000;animation:pulse 1.5s infinite"></span> P&D LIVE</span>
842
+ <div style="flex:1"></div>
843
+ <button class="ln-ctrl-btn active" onclick="setLiveFilter('all')" data-f="all">All</button>
844
+ <button class="ln-ctrl-btn" onclick="setLiveFilter('critical')" data-f="critical">🔴 Critical</button>
845
+ <button class="ln-ctrl-btn" onclick="setLiveFilter('alert')" data-f="alert">🟡 Alert</button>
846
+ <button class="ln-ctrl-btn" onclick="setLiveFilter('liquidation')" data-f="liquidation">💀 Liquidations</button>
847
+ <button class="ln-ctrl-btn" onclick="setLiveFilter('sec')" data-f="sec">🚨 SEC</button>
848
+ <button onclick="loadLiveNews()" style="padding:4px 12px;border-radius:6px;border:1px solid rgba(255,255,255,0.1);background:rgba(255,255,255,0.03);color:var(--text);font-size:12px;cursor:pointer" title="Refresh">🔄</button>
849
+ </div>
850
+ <!-- COUNTERS -->
851
+ <div class="ln-counters" id="lnCounters">
852
+ <div class="ln-counter"><div class="ln-counter-val" style="color:var(--accent2)">—</div><div class="ln-counter-lbl">Open Positions</div></div>
853
+ <div class="ln-counter"><div class="ln-counter-val" style="color:var(--gold)">⚡—</div><div class="ln-counter-lbl">GPU at Risk</div></div>
854
+ <div class="ln-counter"><div class="ln-counter-val" style="color:var(--red)">💀 —</div><div class="ln-counter-lbl">Liquidations 24h</div></div>
855
+ <div class="ln-counter"><div class="ln-counter-val" style="color:#ff8a80">🚨 —</div><div class="ln-counter-lbl">SEC Actions 24h</div></div>
856
+ </div>
857
+ <!-- MVP / VILLAIN -->
858
+ <div class="ln-mvp-row" id="lnMvpRow" style="display:none"></div>
859
+ <!-- MAIN STUDIO (featured story with anchor) -->
860
+ <div class="ln-main-scroll">
861
+ <div class="ln-studio" id="lnStudio" style="display:none"></div>
862
+ <!-- STORY FEED -->
863
+ <div class="ln-section-title" id="lnFeedTitle">📡 LIVE FEED — Loading...</div>
864
+ <div class="ln-feed" id="lnFeed">
865
+ <div class="ln-no-stories"><div class="big">📡</div><div style="font-size:16px;font-weight:700;margin-bottom:6px">Tuning into P&D LIVE...</div><div style="font-size:12px">AI anchors are compiling the latest drama</div></div>
866
+ </div>
867
+ </div>
868
  </div>
869
  </div>
870
  </div>
 
1253
  }
1254
 
1255
  let _indicesInterval = null;
1256
+ function initApp(){initVideoPlayer();loadLiveNews();loadIndices();if(_indicesInterval)clearInterval(_indicesInterval);_indicesInterval=setInterval(loadIndices,120000);connectSSE();}
1257
 
1258
  async function loadProfile(){if(!U)return;try{const r=await(await fetch(`/api/user/profile?email=${U.email}`)).json();if(r.gpu_dollars!==undefined)document.getElementById('hGpu').textContent=`⚡ ${r.gpu_dollars.toLocaleString()} GPU`;}catch(e){}}
1259
 
 
2767
  }
2768
 
2769
  /* ====== 🔴 P&D LIVE NEWS ====== */
2770
+
2771
+ /* ── Video Clip Rotation Engine ── */
2772
+ const LN_VIDEO_CLIPS = [
2773
+ {src:'/videos/V1.mp4', label:'Studio Broadcast', anchor:'LIVE ANCHOR'},
2774
+ {src:'/videos/V2.mp4', label:'Breaking Alert', anchor:'ALERT DESK'},
2775
+ {src:'/videos/V3.mp4', label:'Production Floor', anchor:'FIELD REPORT'},
2776
+ {src:'/videos/V4.mp4', label:'Newsroom Command', anchor:'NEWSROOM'},
2777
+ ];
2778
+ let lnVideoIdx = 0, lnVideoRotateTimer = null, lnVideoProgressTimer = null, lnVideoReady = false;
2779
+
2780
+ function initVideoPlayer(){
2781
+ const vid = document.getElementById('lnVideo');
2782
+ if(!vid) return;
2783
+ // Load first clip
2784
+ vid.src = LN_VIDEO_CLIPS[0].src;
2785
+ vid.muted = true;
2786
+ vid.playsInline = true;
2787
+ vid.load();
2788
+ // On canplay, start playback
2789
+ vid.addEventListener('canplay', function onFirstPlay(){
2790
+ vid.play().catch(()=>{});
2791
+ lnVideoReady = true;
2792
+ vid.removeEventListener('canplay', onFirstPlay);
2793
+ });
2794
+ // On ended (if not loop), go to next clip
2795
+ vid.addEventListener('ended', ()=> switchVideoClip((lnVideoIdx+1) % LN_VIDEO_CLIPS.length));
2796
+ // Auto-rotate every 15s regardless of video length
2797
+ startVideoRotation();
2798
+ // Progress bar
2799
+ vid.addEventListener('timeupdate', updateVideoProgress);
2800
+ updateVideoIndicator(0);
2801
+ updateVideoLabel(0);
2802
+ }
2803
+
2804
+ function startVideoRotation(){
2805
+ if(lnVideoRotateTimer) clearInterval(lnVideoRotateTimer);
2806
+ lnVideoRotateTimer = setInterval(()=>{
2807
+ if(cTab !== 'livenews') return; // only rotate when visible
2808
+ switchVideoClip((lnVideoIdx + 1) % LN_VIDEO_CLIPS.length);
2809
+ }, 15000);
2810
+ }
2811
+
2812
+ function switchVideoClip(idx){
2813
+ const vid = document.getElementById('lnVideo');
2814
+ if(!vid || idx === lnVideoIdx && lnVideoReady) return;
2815
+ lnVideoIdx = idx;
2816
+ // Fade out
2817
+ vid.classList.add('fade-out');
2818
+ setTimeout(()=>{
2819
+ vid.src = LN_VIDEO_CLIPS[idx].src;
2820
+ vid.load();
2821
+ vid.play().then(()=>{
2822
+ vid.classList.remove('fade-out');
2823
+ }).catch(()=> vid.classList.remove('fade-out'));
2824
+ }, 400);
2825
+ updateVideoIndicator(idx);
2826
+ updateVideoLabel(idx);
2827
+ // Reset rotation timer on manual switch
2828
+ startVideoRotation();
2829
+ }
2830
+
2831
+ function updateVideoIndicator(idx){
2832
+ const dots = document.querySelectorAll('.ln-video-dot');
2833
+ dots.forEach((d,i)=> d.classList.toggle('active', i===idx));
2834
+ }
2835
+
2836
+ function updateVideoLabel(idx){
2837
+ const clip = LN_VIDEO_CLIPS[idx];
2838
+ const nameEl = document.getElementById('lnVideoAnchorName');
2839
+ const infoEl = document.getElementById('lnVideoClipInfo');
2840
+ if(nameEl) nameEl.textContent = clip.anchor;
2841
+ if(infoEl) infoEl.textContent = `Clip ${idx+1}/${LN_VIDEO_CLIPS.length} · ${clip.label}`;
2842
+ }
2843
+
2844
+ function updateVideoProgress(){
2845
+ const vid = document.getElementById('lnVideo');
2846
+ const bar = document.getElementById('lnVideoProgress');
2847
+ if(!vid || !bar || !vid.duration) return;
2848
+ const pct = (vid.currentTime / vid.duration) * 100;
2849
+ bar.style.width = pct + '%';
2850
+ }
2851
+
2852
  const LN_ANCHORS = {
2853
  chaos: {name:'ChaosReporter',emoji:'😈',color:'#ff5252',gradient:'linear-gradient(135deg,#2a0a0a,#1a0520)',tag:'CHAOTIC',tagBg:'rgba(255,82,82,0.2)'},
2854
  data: {name:'DataDiva',emoji:'📊',color:'#00e5ff',gradient:'linear-gradient(135deg,#0a1a2a,#0a0a30)',tag:'RATIONAL',tagBg:'rgba(0,229,255,0.2)'},
 
2909
  track.innerHTML = doubled.map(t=>`<span class="ln-break-item">${esc(t)}</span>`).join('');
2910
  // Adjust animation duration based on content
2911
  track.style.animationDuration = Math.max(20, items.length * 8) + 's';
2912
+ // Context-aware: Switch to Alert clip (Clip 2) during breaking news
2913
+ if(items.length >= 2 && lnVideoIdx !== 1) switchVideoClip(1);
2914
  }
2915
 
2916
  function renderLiveCounters(c){
 
2926
  <div class="ln-counter"><div class="ln-counter-val" style="color:var(--red)">💀 ${c.liquidations_24h||0}</div><div class="ln-counter-lbl">Liquidations 24h</div><div style="font-size:10px;color:var(--red);margin-top:2px">${(c.liquidated_gpu_24h||0).toLocaleString()} GPU lost</div></div>
2927
  <div class="ln-counter"><div class="ln-counter-val" style="color:#ff8a80">🚨 ${c.sec_violations_24h||0}</div><div class="ln-counter-lbl">SEC Actions 24h</div><div style="font-size:10px;color:var(--muted);margin-top:2px">⛓️${c.sec_active_suspensions||0} suspended</div></div>
2928
  `;
2929
+ // Sync mini counters under video
2930
+ const vLiq = document.getElementById('lnVidLiq');
2931
+ const vSec = document.getElementById('lnVidSec');
2932
+ if(vLiq) vLiq.textContent = `💀 ${c.liquidations_24h||0}`;
2933
+ if(vSec) vSec.textContent = `🚨 ${c.sec_violations_24h||0}`;
2934
  }
2935
 
2936
  function renderLiveMvp(mvp, villain){