PageSourceSearch

https://whaletv.com/whale-tv

html whaletv.com collected 2026-10-01 11:59:15 UTC 46,055 bytes, 887 lines download raw bytes

1<!DOCTYPE html><!-- Last Published: Thu Sep 10 2026 07:58:28 GMT+0000 (Coordinated Universal Time) --><html data-wf-domain="wf.whaletv.com" data-wf-page="6682794fd01e15b9b053d727" data-wf-site="6666d37a275951ae96644f4b" lang="en"><head><meta charset="utf-8"/><link href="https://cdn.prod.website-files.com" rel="preconnect" crossorigin="anonymous"/><title>Whale TV | Smart &amp; Simple</title><link rel="alternate" hrefLang="x-default" href="https://www.whaletv.com/whale-tv"/><link rel="alternate" hrefLang="en" href="https://www.whaletv.com/whale-tv"/><link rel="alternate" hrefLang="zh" href="https://www.whaletv.com/zh/whale-tv"/><link rel="alternate" hrefLang="de" href="https://www.whaletv.com/de/whale-tv"/><link rel="alternate" hrefLang="pt-BR" href="https://www.whaletv.com/pt-br/whale-tv"/><link rel="alternate" hrefLang="es" href="https://www.whaletv.com/es/whale-tv"/><meta content="Whale TV makes television smarter. It combines and organizes all your entertainment on one screen, wether it’s broadcast, streamed or playing on a connected device. Finding the entertainment you love is a snap. Smart and incredibly simple to use, this TV was engineered to entertain and amaze you!" name="description"/><meta content="Whale TV | Smart &amp; Simple" property="og:title"/><meta content="Whale TV makes television smarter. It combines and organizes all your entertainment on one screen, wether it’s broadcast, streamed or playing on a connected device. Finding the entertainment you love is a snap. Smart and incredibly simple to use, this TV was engineered to entertain and amaze you!" property="og:description"/><meta content="Whale TV | Smart &amp; Simple" name="twitter:title"/><meta content="Whale TV makes television smarter. It combines and organizes all your entertainment on one screen, wether it’s broadcast, streamed or playing on a connected device. Finding the entertainment you love is a snap. Smart and incredibly simple to use, this TV was engineered to entertain and amaze you!" name="twitter:description"/><meta property="og:type" content="website"/><meta content="summary_large_image" name="twitter:card"/><meta content="width=device-width, initial-scale=1" name="viewport"/><meta content="mHgTFaOcR8Ojd0ioHdVA40m8EgW2dksH4iFhMNT3TxE" name="google-site-verification"/><link href="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/css/whale-tv-2024-staging.shared.4dc59c41d.min.css" rel="stylesheet" type="text/css" integrity="sha384-TcWcQdyFyrnqalUf21sZj4YkkY6dsplLdfyBvsxn+jdPzxmfY5bjVys3SLptbm9p" crossorigin="anonymous"/>
1<script type="text/javascript">!function(o,c){var n=c.documentElement,t=" w-mod-";n.className+=t+"js",("ontouchstart"in o||o.DocumentTouch&&c instanceof DocumentTouch)&&(n.className+=t+"touch")}(window,document);</script>
1<link href="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/66d03deb03f5275d830eaf7e_Whale%20TV%20Favicon.png" rel="shortcut icon" type="image/x-icon"/><link href="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/66d03def2a2cb3524574e5d4_Whale%20TV%20Webclip.png" rel="apple-touch-icon"/><link href="https://www.whaletv.com/whale-tv" rel="canonical"/><!-- OneTrust Cookies Consent Notice start for whaletv.com -->
2<script src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js"  type="text/javascript" charset="UTF-8" data-domain-script="01993d18-2b78-7ee7-9e6a-165c2d7fd237" ></script>
vendor: 1 bytes, line 2
2
3<script type="text/javascript">
4function OptanonWrapper() { }
5</script>
5
6<!-- OneTrust Cookies Consent Notice end for whaletv.com -->
7
8<style>
9  .line-1.open {
10        transform: translateY(6px) translateX(0) rotate(45deg);
11        -webkit-transform: translateY(6px) translateX(0) rotate(45deg);
12        -moz-transform: translateY(6px) translateX(0) rotate(45deg);
13      }
14      .line-2.open {
15       	transform: scaleX(0);
16        -webkit-transform: scaleX(0);
17        -moz-transform: scaleX(0);
18      }
19      .line-3.open {
20        transform: translateY(-6px) translateX(0) rotate(-45deg);
21        -webkit-transform: translateY(-6px) translateX(0) rotate(-45deg);
22        -moz-transform: translateY(-6px) translateX(0) rotate(-45deg);
23      }
24</style>
25
26<meta name="google-site-verification" content="b1zE8PgWU4LocSApAOhg5hhBV6nW24z9uGc7n9Rr688" />
27
28<!-- Matomo -->
29<script>
30  var _paq = window._paq = window._paq || [];
31  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
32  _paq.push(["disableCookies"]);
33  _paq.push(['trackPageView']);
34  _paq.push(['enableLinkTracking']);
35  (function() {
36    var u="//matomo.whaletv.com/";
37    _paq.push(['setTrackerUrl', u+'matomo.php']);
38    _paq.push(['setSiteId', '2']);
39    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
40    g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
41  })();
42</script>
42
43<!-- End Matomo Code -->
44
45<script src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b%2F66ba5a08efe71070f98dd10a%2F695fad3a6960d470d58358f3%2Fk3dq6274-1.1.1.js" type="text/javascript"></script>
45</head><body class="body"><div data-animation="default" data-collapse="medium" data-duration="400" data-easing="ease-out-quad" data-easing2="ease-in-cubic" role="banner" class="navbar w-nav"><div class="navbar-container w-container"><div id="w-node-_216d007a-540a-78ea-4977-45b09b9d0638-452c60b8" class="navbar-grid-wrapper"><a id="w-node-_1febcca7-7e4e-3637-c7a1-46124138af6c-452c60b8" href="/?r=0" class="w-inline-block"><img loading="lazy" src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/66c44eedc8a8596bbf701a63_whaletv_logo_white_RGB.svg" alt="Whale TV Brand Logo" class="navbar-brand-logo"/></a><nav role="navigation" id="w-node-_216d007a-540a-78ea-4977-45b09b9d063a-452c60b8" class="nav-menu-wrapper w-nav-menu"><nav id="w-node-_216d007a-540a-78ea-4977-45b09b9d063b-452c60b8" class="nav-center"><a href="/?r=0" class="nav-bar-item w-nav-link">Home</a><a href="/whale-tv" aria-current="page" class="nav-bar-item w-nav-link w--current">Whale TV</a><a href="/plus" class="nav-bar-item w-nav-link">Whale TV+</a><div class="dropdown-wrapper"><div data-hover="true" data-delay="0" class="dropdown w-dropdown"><div class="nav-bar-item dropdown w-dropdown-toggle"><div>Other Products</div><div class="icon w-icon-dropdown-toggle"></div></div><nav class="dropdown-list w-dropdown-list"><a href="/g-engine" class="dropdown-link navbar-dropdown w-dropdown-link">G-Engine</a><a href="/whale-framely" class="dropdown-link navbar-dropdown w-dropdown-link">Whale Framely</a></nav></div></div><a href="/news" class="nav-bar-item w-nav-link">News</a><a href="/about-us" class="nav-bar-item w-nav-link">About Us</a></nav></nav><nav role="navigation" id="w-node-_216d007a-540a-78ea-4977-45b09b9d0646-452c60b8" class="nav-menu-wrapper last w-nav-menu"><nav id="w-node-_216d007a-540a-78ea-4977-45b09b9d0647-452c60b8" class="nav-right"><a href="/for-business" class="button small light navbar-cta w-nav-link">For Business</a></nav></nav><div id="w-node-_216d007a-540a-78ea-4977-45b09b9d064a-452c60b8" data-w-id="216d007a-540a-78ea-4977-45b09b9d064a" class="navbar-mobile-menu-button w-nav-button"><div class="mobile-menu-icon"><span class="line line-1"></span><span class="line line-2"></span><span class="line line-3"></span></div></div></div></div></div><section class="hero-section"><div class="w-layout-blockcontainer container hero w-container"><div data-w-id="910cf248-9be1-61d3-3713-823e812cc04a" style="opacity:0" class="home-hero-div"><img src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/66c44eedc8a8596bbf701a63_whaletv_logo_white_RGB.svg" loading="lazy" alt="Whale TV Brand Logo" class="whale-tv-hero-logo"/><h1 data-w-id="910cf248-9be1-61d3-3713-823e812cc04d" style="opacity:0" class="h1-hero">Smart &amp; Simple</h1></div></div><div class="hero-background"><div class="hero-image-overlay home"></div><img src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/695f601e0cd5c4f685b85999_58d62a229bada7013527072f8f084a84_parents-tv_1200x800_Q1-26.jpg" loading="lazy" width="Auto" sizes="100vw" alt="" srcset="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/695f601e0cd5c4f685b85999_58d62a229bada7013527072f8f084a84_parents-tv_1200x800_Q1-26-p-500.jpg 500w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/695f601e0cd5c4f685b85999_58d62a229bada7013527072f8f084a84_parents-tv_1200x800_Q1-26-p-800.jpg 800w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/695f601e0cd5c4f685b85999_58d62a229bada7013527072f8f084a84_parents-tv_1200x800_Q1-26-p-1080.jpg 1080w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/695f601e0cd5c4f685b85999_58d62a229bada7013527072f8f084a84_parents-tv_1200x800_Q1-26-p-1600.jpg 1600w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/695f601e0cd5c4f685b85999_58d62a229bada7013527072f8f084a84_parents-tv_1200x800_Q1-26.jpg 2160w" class="hero-image"/></div></section><section class="content-section"><div class="w-layout-blockcontainer container section first w-container"><div class="content-section-group first-section"><h2 class="h2-section-product-feature whale-tv-product-video">Whale TV makes television smarter</h2><div class="whale-tv-product-video-link w-dyn-list"><div role="list" class="w-dyn-items"><div role="listitem" class="w-dyn-item"><div class="code-embed whale-tv-product-intro w-embed"><div class="video-wrapper" data-video-player>
46
47    <!--
48      WEBFLOW CMS:
49      Replace the src below with your CMS field reference, e.g.:
50      src=""
51    -->
52    <video
53      src="https://d1p6qg0wnb5uvi.cloudfront.net/whaletv-files/videos/Whale%20TV_OS%2010_Product%20Video_1080P.mp4?sign=d-ovibYH-DBtn3kMbR4-ub54tzXxy_xD1GE4yx88IJk=:0"
54      poster="https://cdn.prod.website-files.com/6672dfb3875e810a86b64e89/69b3e9c97a4e3947670bec62_whaleos-product-video-thumbnail.jpg"
55      preload="metadata"
56      playsinline
57      data-video
58    ></video>
59
60     <!-- Custom Play / Pause Overlay -->
61    <div class="play-overlay" data-play-overlay>
62      <div class="glass-btn">
63        <!-- Play Icon -->
64        <svg data-icon-play class="icon-play" width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
65  <path d="M7 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1.5.87l11-7a1 1 0 0 0 0-1.74l-11-7A1 1 0 0 0 7 4Z" fill="#FF0055"/>
66</svg>
67        <!-- Pause Icon (hidden by default) -->
68        <svg data-icon-pause width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="display:none;">
69          <rect x="5" y="3" width="5" height="18" rx="1.5" fill="#FF0055"/>
70          <rect x="14" y="3" width="5" height="18" rx="1.5" fill="#FF0055"/>
71        </svg>
72      </div>
73    </div>
74  </div>
75  
76  <style>
77    /* ─── SCOPED RESET (won't affect Webflow layout) ─── */
78    .video-wrapper, .video-wrapper *, .video-wrapper *::before, .video-wrapper *::after {
79      box-sizing: border-box;
80      margin: 0;
81      padding: 0;
82    }
83
84    /* ─── VIDEO WRAPPER ─── */
85    .video-wrapper {
86      position: relative;
87      width: 100%; height: auto
88      margin: 0 auto; /* center horizontally without flex on body */
89      border-radius: 16px;
90      border: 8px solid #000;
91      overflow: hidden;
92      box-shadow: 0 10px 30px rgba(0, 0, 0, .4);
93    }
94
95    .video-wrapper video {
96      display: block;
97      width: 100%;
98      height: auto;
99    
100      background: #000;
101    }
102
103    /* Hide native controls by default — we toggle via JS */
104    .video-wrapper video::-webkit-media-controls {
105      opacity: 0;
106      transition: opacity 300ms ease-in-out;
107    }
108    .video-wrapper video.show-controls::-webkit-media-controls {
109      opacity: 1;
110    }
111
112    /* ─── CUSTOM PLAY / PAUSE OVERLAY ─── */
113    .play-overlay {
114      position: absolute;
115      inset: 0;
116      display: flex;
117      align-items: center;
118      justify-content: center;
119      z-index: 10;
120      cursor: pointer;
121      opacity: 1;
122      transition: opacity 300ms ease-in-out;
123      pointer-events: auto;
124    }
125
126    .play-overlay.hidden {
127      opacity: 0;
128      pointer-events: none;
129    }
130
131    /* ─── GLASS BUTTON ─── */
132    .glass-btn {
133      position: relative;
134      width: 88px;
135      height: 88px;
136      border-radius: 50%;
137      display: flex;
138      align-items: center;
139      justify-content: center;
140      /* Glass effect */
141      background: rgba(255, 255, 255, 0.08);
142      backdrop-filter: blur(18px) saturate(1.4);
143      -webkit-backdrop-filter: blur(18px) saturate(1.4);
144      border: 1.5px solid rgba(255, 255, 255, 0.7);
145      box-shadow:
146        0 8px 32px rgba(0, 0, 0, 0.35),
147        inset 0 1px 0 rgba(255, 255, 255, 0.12);
148      transition: transform 300ms cubic-bezier(.25,.8,.25,1),
149                  background 300ms ease,
150                  box-shadow 300ms ease;
151    }
152
153    .glass-btn svg {
154      display: block;            /* remove inline SVG spacing */
155  width: 40px;
156  height: 40px;
157  transform-origin: center;  /* for scaling animations */
158  transition: transform 300ms cubic-bezier(.25,.8,.25,1);
159    }
160    .glass-btn svg[data-icon-play] {
161  margin-left: 4px; /* Adjusts for the triangle's weight */
162}
163
164.glass-btn svg[data-icon-pause] {
165    margin-left: 0;
166  }
167
168    /* Hover: enlarge both button & icon */
169    .play-overlay:hover .glass-btn {
170      transform: scale(1.14);
171      background: rgba(255, 255, 255, 0.13);
172      box-shadow:
173        0 12px 48px rgba(0, 0, 0, 0.45),
174        inset 0 1px 0 rgba(255, 255, 255, 0.18);
175    }
176    .play-overlay:hover .glass-btn svg {
177      transform: scale(1.14);
178    }
179
180    /* Active press */
181    .play-overlay:active .glass-btn {
182      transform: scale(1.02);
183    }
184
185    /* ─── CONTROLS FADE OVERLAY (blocks native controls when needed) ─── */
186    .controls-blocker {
187      position: absolute;
188      bottom: 0;
189      left: 0;
190      right: 0;
191      height: 60px;
192      z-index: 5;
193      pointer-events: none;
194    }
195
196    /* ─── RESPONSIVE ─── */
197    @media (max-width: 1024px) {
198      .video-wrapper { width: 70vw; }
199      .glass-btn { width: 72px; height: 72px; }
200    }
201    @media (max-width: 640px) {
202      .video-wrapper { width: 92vw; }
203      .glass-btn { width: 60px; height: 60px; }
204      .glass-btn svg { width: 22px; height: 22px; }
205      .glass-btn svg[data-icon-play] { margin-left: 2px; }
206    }
207
208    /* ─── WEBFLOW INSTRUCTIONS BANNER ─── */
209    .wf-banner {
210      position: fixed;
211      top: 20px;
212      left: 50%;
213      transform: translateX(-50%);
214      background: rgba(255,255,255,0.06);
215      backdrop-filter: blur(14px);
216      -webkit-backdrop-filter: blur(14px);
217      border: 1px solid rgba(255,255,255,0.1);
218      border-radius: 12px;
219      padding: 14px 28px;
220      color: rgba(255,255,255,0.55);
221      font-size: 13px;
222      text-align: center;
223      z-index: 100;
224      max-width: 90vw;
225      line-height: 1.5;
226    }
227    .wf-banner code {
228      background: rgba(255,0,85,0.15);
229      color: #ff4d88;
230      padding: 2px 7px;
231      border-radius: 5px;
232      font-size: 12px;
233    }
234  </style></div></div></div></div><h2 class="description">It combines and organizes all your entertainment on one screen, whether it’s broadcast, streamed or playing on a connected device. Finding the entertainment you love is a snap. Smart and incredibly simple to use, this TV was engineered to entertain and amaze you!</h2></div></div></section><section class="content-section"><div class="w-layout-blockcontainer container section w-container"><div class="content-section-group feature"><div id="w-node-ccdb499b-22c5-c2bf-8f3e-db749f0d767c-b053d727" class="tv-mockup"><img src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/68d26fca16d377e172290bf6_whaletv_apps.jpg" loading="lazy" width="Auto" sizes="(max-width: 767px) 100v
234w, (max-width: 991px) 728px, 940px" alt="" srcset="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/68d26fca16d377e172290bf6_whaletv_apps-p-500.jpg 500w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/68d26fca16d377e172290bf6_whaletv_apps-p-800.jpg 800w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/68d26fca16d377e172290bf6_whaletv_apps-p-1080.jpg 1080w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/68d26fca16d377e172290bf6_whaletv_apps-p-1600.jpg 1600w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/68d26fca16d377e172290bf6_whaletv_apps.jpg 1920w" class="tv-image"/></div><div id="w-node-ccdb499b-22c5-c2bf-8f3e-db749f0d7677-b053d727" class="content-section-block feature"><h2 class="h2-section-product-feature">The entertainment you love</h2><p>Easily download hundreds of free and paid streaming apps from the app store, including Netflix, Prime Video, Youtube and many more.</p></div></div></div></section><section class="content-section alt-background"><div class="w-layout-blockcontainer container section w-container"><div class="content-section-group feature"><div class="content-section-block feature"><h2 class="h2-section-product-feature">Personalized for you</h2><p>With today’s endless viewing options, it’s easy to get overwhelmed. That’s why Whale TV was designed to help consumers navigate this sea of entertainment. The built-in universal search and AI-powered recommendation engine helps you find new things to watch in seconds.</p></div><div id="w-node-fc2decb7-f781-c5cf-5256-7e577691fea4-b053d727" class="personalized-for-you-video w-dyn-list"><div role="list" class="collection-list-7 w-dyn-items"><div role="listitem" class="w-dyn-item"><div class="code-embed whale-tv-product-intro w-embed"><div class="video-wrapper" data-video-player>
235
236    <!--
237      WEBFLOW CMS:
238      Replace the src below with your CMS field reference, e.g.:
239      src=""
240    -->
241    <video
242      src="https://d1p6qg0wnb5uvi.cloudfront.net/whaletv-files/videos/WhaleOS10_Home_2026.mp4?sign=gCf8FySzz_gJ8K7XegQbBVr2RMhMLuJHeBMd2Na1UFA=:0"
243      poster="https://cdn.prod.website-files.com/6672dfb3875e810a86b64e89/69e61847e2bce055ae7e9c31_WhaleOS10.3_Homepage_2026Q1-2_GLOBAL_V4.jpg"
244      preload="metadata"
245      playsinline
246      data-video
247    ></video>
248
249     <!-- Custom Play / Pause Overlay -->
250    <div class="play-overlay" data-play-overlay>
251      <div class="glass-btn">
252        <!-- Play Icon -->
253        <svg data-icon-play class="icon-play" width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
254  <path d="M7 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1.5.87l11-7a1 1 0 0 0 0-1.74l-11-7A1 1 0 0 0 7 4Z" fill="#FF0055"/>
255</svg>
256        <!-- Pause Icon (hidden by default) -->
257        <svg data-icon-pause width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="display:none;">
258          <rect x="5" y="3" width="5" height="18" rx="1.5" fill="#FF0055"/>
259          <rect x="14" y="3" width="5" height="18" rx="1.5" fill="#FF0055"/>
260        </svg>
261      </div>
262    </div>
263  </div>
264  
265  <style>
266    /* ─── SCOPED RESET (won't affect Webflow layout) ─── */
267    .video-wrapper, .video-wrapper *, .video-wrapper *::before, .video-wrapper *::after {
268      box-sizing: border-box;
269      margin: 0;
270      padding: 0;
271    }
272
273    /* ─── GRID STACKING CONTEXT FIX ─── */
274.video-wrapper {
275  contain: none;
276  isolation: auto;
277}
278
279.play-overlay {
280  isolation: auto;
281}
282
283  
284
285    /* ─── VIDEO WRAPPER ─── */
286    .video-wrapper {
287      position: relative;
288      width: 100%; height: auto
289      margin: 0 auto; /* center horizontally without flex on body */
290      border-radius: 16px;
291      border: 8px solid #000;
292      overflow: hidden;
293      box-shadow: 0 10px 30px rgba(0, 0, 0, .4);
294    }
295
296    .video-wrapper video {
297      display: block;
298      width: 100%;
299      height: auto;
300    
301      background: #000;
302    }
303
304    /* Hide native controls by default — we toggle via JS */
305    .video-wrapper video::-webkit-media-controls {
306      opacity: 0;
307      transition: opacity 300ms ease-in-out;
308    }
309    .video-wrapper video.show-controls::-webkit-media-controls {
310      opacity: 1;
311    }
312
313    /* ─── CUSTOM PLAY / PAUSE OVERLAY ─── */
314    .play-overlay {
315      position: absolute;
316      inset: 0;
317      display: flex;
318      align-items: center;
319      justify-content: center;
320      z-index: 10;
321      cursor: pointer;
322      opacity: 1;
323      transition: opacity 300ms ease-in-out;
324      pointer-events: auto;
325    }
326
327    .play-overlay.hidden {
328      opacity: 0;
329      pointer-events: none;
330    }
331
332    /* ─── GLASS BUTTON ─── */
333    .glass-btn {
334      position: relative;
335      width: 88px;
336      height: 88px;
337      border-radius: 50%;
338      display: flex;
339      align-items: center;
340      justify-content: center;
341      /* Glass effect */
342      background: rgba(255, 255, 255, 0.08);
343      backdrop-filter: blur(18px) saturate(1.4);
344      -webkit-backdrop-filter: blur(18px) saturate(1.4);
345      border: 1.5px solid rgba(255, 255, 255, 0.7);
346      box-shadow:
347        0 8px 32px rgba(0, 0, 0, 0.35),
348        inset 0 1px 0 rgba(255, 255, 255, 0.12);
349      transition: transform 300ms cubic-bezier(.25,.8,.25,1),
350                  background 300ms ease,
351                  box-shadow 300ms ease;
352    }
353
354    .glass-btn svg {
355      display: block;            /* remove inline SVG spacing */
356  width: 40px;
357  height: 40px;
358  transform-origin: center;  /* for scaling animations */
359  transition: transform 300ms cubic-bezier(.25,.8,.25,1);
360    }
361    .glass-btn svg[data-icon-play] {
362  margin-left: 4px; /* Adjusts for the triangle's weight */
363}
364
365.glass-btn svg[data-icon-pause] {
366    margin-left: 0;
367  }
368
369    /* Hover: enlarge both button & icon */
370    .play-overlay:hover .glass-btn {
371      transform: scale(1.14);
372      background: rgba(255, 255, 255, 0.13);
373      box-shadow:
374        0 12px 48px rgba(0, 0, 0, 0.45),
375        inset 0 1px 0 rgba(255, 255, 255, 0.18);
376    }
377    .play-overlay:hover .glass-btn svg {
378      transform: scale(1.14);
379    }
380
381    /* Active press */
382    .play-overlay:active .glass-btn {
383      transform: scale(1.02);
384    }
385
386    /* ─── CONTROLS FADE OVERLAY (blocks native controls when needed) ─── */
387    .controls-blocker {
388      position: absolute;
389      bottom: 0;
390      left: 0;
391      right: 0;
392      height: 60px;
393      z-index: 5;
394      pointer-events: none;
395    }
396
397    /* ─── RESPONSIVE ─── */
398    @media (max-width: 1024px) {
399      .video-wrapper { width: 70vw; }
400      .glass-btn { width: 72px; height: 72px; }
401    }
402    @media (max-width: 640px) {
403      .video-wrapper { width: 92vw; }
404      .video-wrapper .glass-btn { width: 60px; height: 60px; backdrop-filter: blur(8px) saturate(1.4);
405    -webkit-backdrop-filter: blur(8px) saturate(1.4);}
406      .video-wrapper .glass-btn svg { width: 22px; height: 22px; }
407      .video-wrapper .glass-btn svg[data-icon-play] { margin-left: 2px; }
408    }
409
410    /* ─── WEBFLOW INSTRUCTIONS BANNER ─── */
411    .wf-banner {
412      position: fixed;
413      top: 20px;
414      left: 50%;
415      transform: translateX(-50%);
416      background: rgba(255,255,255,0.06);
417      backdrop-filter: blur(14px);
418      -webkit-backdrop-filter: blur(14px);
419      border: 1px solid rgba(255,255,255,0.1);
420      border-radius: 12px;
421      padding: 14px 28px;
422      color: rgba(255,255,255,0.55);
423      font-size: 13px;
424      text-align: center;
425      z-index: 100;
426      max-width: 90vw;
427      line-height: 1.5;
428    }
429    .wf-banner code {
430      background: rgba(255,0,85,0.15);
431      color: #ff4d88;
432      padding: 2px 7px;
433      border-radius: 5px;
434      font-size: 12px;
435    }
436  </style></div></div></div></div></div></div></section><section class="content-section"><div class="w-layout-blockcontainer container section w-container"><div class="content-section-group feature"><div id="w-node-_609ca010-f3dc-0010-ba98-b04e6467e050-b053d727" class="tv-mockup"><img src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/6a0c068721fa7c6722f513ef_Homepage_Global_2026_V1.jpg" loading="lazy" width="Auto" sizes="(max-width: 767px) 100v
436w, (max-width: 991px) 728px, 940px" alt="" srcset="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/6a0c068721fa7c6722f513ef_Homepage_Global_2026_V1-p-500.jpg 500w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/6a0c068721fa7c6722f513ef_Homepage_Global_2026_V1-p-800.jpg 800w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/6a0c068721fa7c6722f513ef_Homepage_Global_2026_V1-p-1080.jpg 1080w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/6a0c068721fa7c6722f513ef_Homepage_Global_2026_V1-p-1600.jpg 1600w, https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/6a0c068721fa7c6722f513ef_Homepage_Global_2026_V1.jpg 1920w" class="tv-image"/></div><div class="content-section-block feature"><h2 class="h2-section-product-feature">Choose your voice assistant</h2><p>Whale TV gives you the flexibility to choose your own voice assistant! Opt for Whale TV’s built-in , AI-powered voice assistant, or switch to Alexa. Use your voice to effortlessly find new things to watch or control your TV - “look, Mom, no hands!”</p></div></div></div></section><section class="content-section alt-background"><div class="w-layout-blockcontainer container section w-container"><div class="content-section-group feature"><div class="content-section-block feature"><h2 class="h2-section-product-feature">Smart &amp; Simple</h2><p>We use incredibly complex technologies - like artificial intelligence - to make discovering and finding great entertainment simple and intuitive. But don’t worry, all that complexity works quietly out of sight. We also continuously update and upgrade your TV - watching experience with regular software updates. The result? Seamless and enjoyable viewing every time you sit down.</p></div><div id="w-node-_74f92ed0-11db-1804-4f3c-81f5c652fc6c-b053d727" class="smart-simple-video w-dyn-list"><div role="list" class="collection-list-7 w-dyn-items"><div role="listitem" class="w-dyn-item"><div class="code-embed whale-tv-product-intro w-embed"><div class="video-wrapper" data-video-player>
437
438    <!--
439      WEBFLOW CMS:
440      Replace the src below with your CMS field reference, e.g.:
441      src=""
442    -->
443    <video
444      src="https://d1p6qg0wnb5uvi.cloudfront.net/whaletv-files/videos/Ai%20Voice%20%26%20Search_final-0402.mp4?sign=-lfHX3teTb2MIbw1eBw5WjuqO0YEC1KuNFbo1cma1Tg=:0"
445      poster="https://cdn.prod.website-files.com/6672dfb3875e810a86b64e89/69e618cb28032a19905d43a4_whaletv_home_4.jpg"
446      preload="metadata"
447      playsinline
448      data-video
449    ></video>
450
451     <!-- Custom Play / Pause Overlay -->
452    <div class="play-overlay" data-play-overlay>
453      <div class="glass-btn">
454        <!-- Play Icon -->
455        <svg data-icon-play class="icon-play" width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
456  <path d="M7 4a1 1 0 0 0-1 1v14a1 1 0 0 0 1.5.87l11-7a1 1 0 0 0 0-1.74l-11-7A1 1 0 0 0 7 4Z" fill="#FF0055"/>
457</svg>
458        <!-- Pause Icon (hidden by default) -->
459        <svg data-icon-pause width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="display:none;">
460          <rect x="5" y="3" width="5" height="18" rx="1.5" fill="#FF0055"/>
461          <rect x="14" y="3" width="5" height="18" rx="1.5" fill="#FF0055"/>
462        </svg>
463      </div>
464    </div>
465  </div>
466  
467  <style>
468    /* ─── SCOPED RESET (won't affect Webflow layout) ─── */
469    .video-wrapper, .video-wrapper *, .video-wrapper *::before, .video-wrapper *::after {
470      box-sizing: border-box;
471      margin: 0;
472      padding: 0;
473    }
474
475    /* ─── GRID STACKING CONTEXT FIX ─── */
476.video-wrapper {
477  contain: none;
478  isolation: auto;
479}
480
481.play-overlay {
482  isolation: auto;
483}
484
485    /* ─── VIDEO WRAPPER ─── */
486    .video-wrapper {
487      position: relative;
488      width: 100%; height: auto;
489      margin: 0 auto; /* center horizontally without flex on body */
490      border-radius: 16px;
491      border: 8px solid #000;
492      overflow: hidden;
493      box-shadow: 0 10px 30px rgba(0, 0, 0, .4);
494    }
495
496    .video-wrapper video {
497      display: block;
498      width: 100%;
499      height: auto;
500    
501      background: #000;
502    }
503
504    /* Hide native controls by default — we toggle via JS */
505    .video-wrapper video::-webkit-media-controls {
506      opacity: 0;
507      transition: opacity 300ms ease-in-out;
508    }
509    .video-wrapper video.show-controls::-webkit-media-controls {
510      opacity: 1;
511    }
512
513    /* ─── CUSTOM PLAY / PAUSE OVERLAY ─── */
514    .play-overlay {
515      position: absolute;
516      inset: 0;
517      display: flex;
518      align-items: center;
519      justify-content: center;
520      z-index: 10;
521      cursor: pointer;
522      opacity: 1;
523      transition: opacity 300ms ease-in-out;
524      pointer-events: auto;
525    }
526
527    .play-overlay.hidden {
528      opacity: 0;
529      pointer-events: none;
530    }
531
532    /* ─── GLASS BUTTON ─── */
533    .glass-btn {
534      position: relative;
535      width: 88px;
536      height: 88px;
537      border-radius: 50%;
538      display: flex;
539      align-items: center;
540      justify-content: center;
541      /* Glass effect */
542      background: rgba(255, 255, 255, 0.08);
543      backdrop-filter: blur(18px) saturate(1.4);
544      -webkit-backdrop-filter: blur(18px) saturate(1.4);
545      border: 1.5px solid rgba(255, 255, 255, 0.7);
546      box-shadow:
547        0 8px 32px rgba(0, 0, 0, 0.35),
548        inset 0 1px 0 rgba(255, 255, 255, 0.12);
549      transition: transform 300ms cubic-bezier(.25,.8,.25,1),
550                  background 300ms ease,
551                  box-shadow 300ms ease;
552    }
553
554    .glass-btn svg {
555      display: block;            /* remove inline SVG spacing */
556  width: 40px;
557  height: 40px;
558  transform-origin: center;  /* for scaling animations */
559  transition: transform 300ms cubic-bezier(.25,.8,.25,1);
560    }
561    .glass-btn svg[data-icon-play] {
562  margin-left: 4px; /* Adjusts for the triangle's weight */
563}
564
565.glass-btn svg[data-icon-pause] {
566    margin-left: 0;
567  }
568
569    /* Hover: enlarge both button & icon */
570    .play-overlay:hover .glass-btn {
571      transform: scale(1.14);
572      background: rgba(255, 255, 255, 0.13);
573      box-shadow:
574        0 12px 48px rgba(0, 0, 0, 0.45),
575        inset 0 1px 0 rgba(255, 255, 255, 0.18);
576    }
577    .play-overlay:hover .glass-btn svg {
578      transform: scale(1.14);
579    }
580
581    /* Active press */
582    .play-overlay:active .glass-btn {
583      transform: scale(1.02);
584    }
585
586    /* ─── CONTROLS FADE OVERLAY (blocks native controls when needed) ─── */
587    .controls-blocker {
588      position: absolute;
589      bottom: 0;
590      left: 0;
591      right: 0;
592      height: 60px;
593      z-index: 5;
594      pointer-events: none;
595    }
596
597    /* ─── RESPONSIVE ─── */
598    @media (max-width: 1024px) {
599      .glass-btn { width: 72px; height: 72px; }
600    }
601    @media (max-width: 640px) {
602      .glass-btn { width: 60px; height: 60px; }
603      .glass-btn svg { width: 22px; height: 22px; }
604      .glass-btn svg[data-icon-play] { margin-left: 2px; }
605    }
606
607    /* ─── WEBFLOW INSTRUCTIONS BANNER ─── */
608    .wf-banner {
609      position: fixed;
610      top: 20px;
611      left: 50%;
612      transform: translateX(-50%);
613      background: rgba(255,255,255,0.06);
614      backdrop-filter: blur(14px);
615      -webkit-backdrop-filter: blur(14px);
616      border: 1px solid rgba(255,255,255,0.1);
617      border-radius: 12px;
618      padding: 14px 28px;
619      color: rgba(255,255,255,0.55);
620      font-size: 13px;
621      text-align: center;
622      z-index: 100;
623      max-width: 90vw;
624      line-height: 1.5;
625    }
626    .wf-banner code {
627      background: rgba(255,0,85,0.15);
628      color: #ff4d88;
629      padding: 2px 7px;
630      border-radius: 5px;
631      font-size: 12px;
632    }
633  </style></div></div></div></div></div></div></section><section class="content-section cta"><div data-w-id="009f7db0-3483-f37c-31bd-cb18573456ff" style="opacity:0" class="w-layout-blockcontainer container section w-container"><div class="cta-block"><h2 class="h2-business-cta">Are you a TV Brand or ODM and looking to license a smart, simple and affordable TV OS?</h2><a href="/for-business" class="button cta light w-button">Partner With Us!</a></div></div></section><footer class="section footer"><div class="w-layout-blockcontainer container footer w-container"><div class="w-layout-grid footer-flex"><div id="w-node-_3d5cd192-1642-285b-a3f7-d0a0f29de1b6-f29de1ac" class="footer-cell"><div class="locales-wrapper w-locales-list"><div data-hover="false" data-delay="0" data-w-id="568cbf70-5b37-6e6d-9296-b248297e7002" class="language-dropdown w-dropdown"><div class="language-switcher-dropdown-toggle w-dropdown-toggle"><div class="globe-icon-wrapper"><img src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/69149e89403d4cb0064e4296_dade380262bdd7e10c94bbaa787bdf82_language.svg" loading="lazy" alt="" class="image-6"/></div><div class="language-dropdown-button-label">English</div><div data-w-id="568cbf70-5b37-6e6d-9296-b248297e7004" class="language-dropdown-arrow w-icon-dropdown-toggle"></div></div><nav data-w-id="568cbf70-5b37-6e6d-9296-b248297e7007" class="language-dropdown-list w-dropdown-list"><div role="list" class="w-locales-items"><div role="listitem" class="w-locales-item"><a hreflang="en" href="/?r=0" class="locale-link-row w-inline-block w--current"><div class="checkmark-wrapper"><div class="checkmark">✓</div></div><div class="locale-link language-switcher">English</div></a></div><div role="listitem" class="w-locales-item"><a hreflang="zh" href="/zh" class="locale-link-row w-inline-block"><div class="checkmark-wrapper"></div><div class="locale-link language-switcher">中文</div></a></div><div role="listitem" class="w-locales-item"><a hreflang="de" href="/de" class="locale-link-row w-inline-block"><div class="checkmark-wrapper"></div><div class="locale-link language-switcher">
633Deutsch</div></a></div><div role="listitem" class="w-locales-item"><a hreflang="pt-BR" href="/pt-br" class="locale-link-row w-inline-block"><div class="checkmark-wrapper"></div><div class="locale-link language-switcher">Português</div></a></div><div role="listitem" class="w-locales-item"><a hreflang="es" href="/es" class="locale-link-row w-inline-block"><div class="checkmark-wrapper"></div><div class="locale-link language-switcher">Español</div></a></div></div></nav></div></div><img src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/66c46126fb5cbcdb3a67473b_whaletv_logo_pink_RGB.svg" loading="lazy" id="w-node-_23e2ae37-f2b4-395e-6feb-2ff965661bbf-f29de1ac" alt="Whale TV Brand Logo" class="footer-logo"/></div><div class="footer-cell"><h6 class="heading-6-footer">Products</h6><a href="/whale-tv" aria-current="page" class="nav-link footer w--current">Whale TV</a><a href="/plus" class="nav-link footer">Whale TV+</a><a href="/g-engine" class="nav-link footer">G-Engine</a><a href="/whale-framely" class="nav-link footer">Whale Framely</a></div><div class="footer-cell"><h6 class="heading-6-footer">Developers</h6><a href="https://developer.whaletv.com/" class="nav-link footer">Developer Portal</a></div><div class="footer-cell"><h6 class="heading-6-footer">About Us</h6><a href="/about-us" class="nav-link footer">Who We Are</a><a href="/careers" class="nav-link footer">Careers</a><a href="/news" class="nav-link footer">News</a><a href="/news#press-room" class="nav-link footer">Press Room</a></div><div class="footer-cell"><h6 class="heading-6-footer">Legal</h6><a href="/privacy-policy" class="nav-link footer">Privacy Policy</a><a href="/terms-of-use" class="nav-link footer">Terms of Use</a><a href="https://beian.miit.gov.cn/" target="_blank" class="nav-link footer">京ICP备11012483号-9</a><a href="/coordinated-vulnerability-disclosure-policy" class="nav-link footer">CVD Policy</a></div><div class="footer-cell"><h6 class="heading-6-footer">Contact</h6><a href="mailto:[email protected]" class="nav-link footer">Support</a><a href="mailto:[email protected]" class="nav-link footer">Press Inquiries</a><a href="/for-business" class="nav-link footer">Partner With Us</a><a href="/security-reporting" class="nav-link footer">Security Reporting</a><div class="socials"><a href="https://www.linkedin.com/company/whaletv/" target="_blank" class="nav-link social w-inline-block"><img src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/66c7affa9dec0055debbe428_linkedin-in.svg" loading="lazy" alt="" class="socials-logo"/></a></div></div></div></div></footer>
633<script src="https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.5.1.min.dc5e7f18c8.js?site=6666d37a275951ae96644f4b" type="text/javascript" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
633<script src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/js/whale-tv-2024-staging.schunk.f2efb3c5440a81cf.js" type="text/javascript" integrity="sha384-VK02VJvMib7ytrF5M2joPWNtDQs366FZgEQ5B+Iwnjx0WBnwQXfootyziSYxdrmS" crossorigin="anonymous"></script>
633<script src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/js/whale-tv-2024-staging.schunk.4847666aefa94cb3.js" type="text/javascript" integrity="sha384-YTFcj8Ing9v2X6gtcZ9O0URS2ZR16xgRwpHOdSMQ08xbA+CEZ0TPyHCUplOQX9Vs" crossorigin="anonymous"></script>
633<script src="https://cdn.prod.website-files.com/6666d37a275951ae96644f4b/js/whale-tv-2024-staging.f0d3a4bc.8899dff87ece4cdb.js" type="text/javascript" integrity="sha384-4ggiEFGx4uasuQh0AhMf5vysw8npmkltpfgMuAKUi58lMLexA+l553wvAOcpZsAi" crossorigin="anonymous"></script>
633<script>
634document.addEventListener('DOMContentLoaded', () => {
635 document.querySelectorAll('.navbar-mobile-menu-button').forEach(trigger => {
636  trigger.addEventListener('click', function(){ 
637    this.x = ((this.x || 0) + 1)%2; 
638    if(this.x){
639      document.querySelectorAll('.line').forEach(target => target.classList.add('open'));
640      }
641      else{
642      document.querySelectorAll('.line').forEach(target => target.classList.remove('open'));
643      } 
644    });
645 });
646});
647</script>
vendor: 68 bytes, lines 647-649
647
648
649<script async="" src="https://www.googletagmanager.com/gtag/js?id=
649G-ZC9BHCP1QG
vendor: 65 bytes, lines 649-650
649" fs-consent-categories="analytics" type="fs-consent"></script>
650
651<script fs-consent-categories="analytics" type="fs-consent">
652  
vendor: 134 bytes, lines 652-656
652window.dataLayer = window.dataLayer || [];
653  function gtag(){dataLayer.push(arguments);}
654  gtag('js', new Date());
655
656  gtag('config', '
656G-ZC9BHCP1QG
vendor: 4 bytes, line 656
656');
657</script>
657
658
659
660<script>
661const supportedLocales = ["en", "de", "zh", "es", "pt-br"];
662const defaultLocale = "en"; // Primary locale used without a path prefix (no /en/ prefix in URL)
663
664// --- Utility Functions ---
665
666/**
667 * Detects the current locale from the URL path.
668 * Returns the detected prefix or the defaultLocale ('en') if no prefix is found.
669 */
670function getCurrentLocale() {
671  const path = window.location.pathname.toLowerCase();
672  
673  // Reliably matches a prefix like /de/, /zh/, /pt-br/ at the start of the path
674  const match = path.match(/^\/([a-z]{2,5}(?:-[a-z]{2,5})?)(?:$|\/)/);
675  
676  const matchedLocale = match ? match[1] : null;
677
678  // If a supported locale is matched, return it.
679  if (matchedLocale && supportedLocales.includes(matchedLocale)) {
680    return matchedLocale;
681  }
682  // Otherwise, if no prefix is found, the current page is considered the default locale.
683  return defaultLocale;
684}
685
686/**
687 * Replaces the existing locale prefix in the path with a new one.
688 * If the newLocale is the default, the path is stripped of any prefix.
689 */
690function replaceLocaleInPath(newLocale) {
691  const url = new URL(window.location.href);
692  let path = url.pathname;
693  const currentLocale = getCurrentLocale();
694  
695  // 1. Remove existing locale prefix (only if it was detected and is not the default 'en' which has no prefix)
696  if (currentLocale !== defaultLocale) {
697    const currentLocaleEscaped = currentLocale.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
698    
699    // Strips the prefix and leaves the subpath (e.g., /plus)
700    path = path.replace(new RegExp(`^/${currentLocaleEscaped}`), "") || "/";
701  }
702
703  // 2. Prepend new locale (Conditional)
704  if (newLocale !== defaultLocale) {
705    // ONLY prepend the prefix if the new locale is NOT the default
706    path = `/${newLocale}${path.startsWith('/') ? path : '/' + path}`;
707    path = path.replace(/\/\/+/g, '/'); // Clean up any double slashes
708  }
709  // If newLocale IS the default ('en'), 'path' remains the stripped subpath (e.g., /plus or /)
710
711  return path + url.search + url.hash;
712}
713
714// --- Event Handlers ---
715
716document.addEventListener("click", function (e) {
717  const link = e.target.closest("a[hreflang]");
718  if (!link) return;
719
720  // Normalize locale to lowercase
721  const selectedLocale = link.getAttribute("hreflang").toLowerCase(); 
722  
723  if (!supportedLocales.includes(selectedLocale)) return;
724
725  // Save the user's explicit choice
726  localStorage.setItem("preferredLocale", selectedLocale);
727
728  e.preventDefault();
729  window.location.href = replaceLocaleInPath(selectedLocale);
730});
731
732document.addEventListener("DOMContentLoaded", function () {
733  const savedLocale = localStorage.getItem("preferredLocale");
734  const currentLocale = getCurrentLocale();
735  
736  let targetLocale = null;
737
738  // --- 1. Determine Target Locale ---
739  
740  // A. Priority 1: Saved Preference Check
741  if (savedLocale && supportedLocales.includes(savedLocale)) {
742    targetLocale = savedLocale;
743  } 
744  // B. Priority 2: Browser Language Check (Only if no saved preference AND current URL is the default)
745  else if (currentLocale === defaultLocale && !savedLocale) {
746    const browserLang = navigator.language.toLowerCase();
747    const primaryBrowserLang = browserLang.split('-')[0];
748    
749    // Check for full locale match (e.g., "pt-br")
750    if (supportedLocales.includes(browserLang)) {
751        targetLocale = browserLang;
752    } 
753    // Check for primary code match (e.g., "de")
754    else if (supportedLocales.includes(primaryBrowserLang)) {
755        targetLocale = primaryBrowserLang;
756    }
757    
758    // If a supported language is found, save it for future visits
759    if (targetLocale && targetLocale !== defaultLocale) {
760      localStorage.setItem("preferredLocale", targetLocale);
761    }
762  }
763
764  // --- 2. Execute Redirect ---
765  
766  // If a target locale was found and it conflicts with the current URL locale, redirect.
767  if (targetLocale && targetLocale !== currentLocale) {
768    window.location.href = replaceLocaleInPath(targetLocale);
769  }
770});
771</script>
771<script>
772    document.addEventListener('DOMContentLoaded', () => {
773
774      // Support multiple players on one page
775      document.querySelectorAll('[data-video-player]').forEach(wrapper => {
776
777        const video      = wrapper.querySelector('[data-video]');
778        const overlay    = wrapper.querySelector('[data-play-overlay]');
779        const iconPlay   = wrapper.querySelector('[data-icon-play]');
780        const iconPause  = wrapper.querySelector('[data-icon-pause]');
781
782        let hasPlayedOnce = false;   // tracks first-ever play
783        let pauseTimer    = null;    // 5-second pause timer
784        let isShowingOverlay = true;
785
786        // ── Helpers ──
787        function showOverlay(showPause) {
788          if (isShowingOverlay) return;
789          isShowingOverlay = true;
790
791          if (showPause) {
792            iconPlay.style.display  = 'none';
793            iconPause.style.display = 'block';
794          } else {
795            iconPlay.style.display  = 'block';
796            iconPause.style.display = 'none';
797          }
798
799          overlay.classList.remove('hidden');
800        }
801
802        function hideOverlay() {
803          if (!isShowingOverlay) return;
804          isShowingOverlay = false;
805          overlay.classList.add('hidden');
806        }
807
808        function enableNativeControls() {
809          video.setAttribute('controls', '');
810          video.classList.add('show-controls');
811        }
812
813        function disableNativeControls() {
814          video.classList.remove('show-controls');
815          // Small delay so CSS transition finishes before attribute removal
816          setTimeout(() => {
817            video.removeAttribute('controls');
818          }, 320);
819        }
820
821        // ── Overlay Click ──
822        overlay.addEventListener('click', () => {
823          if (video.paused) {
824            video.play();
825          } else {
826            video.pause();
827          }
828        });
829
830        // ── Play Event ──
831        video.addEventListener('play', () => {
832          clearTimeout(pauseTimer);
833          hasPlayedOnce = true;
834
835          // Fade out overlay, fade in native controls
836          hideOverlay();
837          enableNativeControls();
838        });
839
840        // ── Pause Event ──
841        video.addEventListener('pause', () => {
842          // Don't show overlay if video ended
843          if (video.ended) return;
844
845          // After 5 seconds of being paused → show custom overlay again
846          pauseTimer = setTimeout(() => {
847            disableNativeControls();
848            // Show pause icon since video is paused
849            showOverlay(false); // show play icon so user can resume
850          }, 5000);
851        });
852
853        // ── Ended Event ──
854        video.addEventListener('ended', () => {
855          clearTimeout(pauseTimer);
856          disableNativeControls();
857          // Reset to play icon
858          showOverlay(false);
859        });
860
861        // ── Seeked / Playing — cancel the pause timer if user resumes ──
862        video.addEventListener('playing', () => {
863          clearTimeout(pauseTimer);
864        });
865      });
866    });
867  </script>
867
868  
869   
869<script>
870document.querySelectorAll('[data-video-player]').forEach(player => {
871  const video = player.querySelector('[data-video]');
872  const overlay = player.querySelector('[data-play-overlay]');
873  const iconPlay = player.querySelector('[data-icon-play]');
874  const iconPause = player.querySelector('[data-icon-pause]');
875
876  video.addEventListener('ended', () => {
877    video.pause();
878    video.currentTime = 0;   // reset to start
879    video.load();            // forces poster to show again
880
881    overlay.classList.remove('hidden');
882
883    if (iconPlay) iconPlay.style.display = 'block';
884    if (iconPause) iconPause.style.display = 'none';
885  });
886});
887</script>
887</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.