1/* PlaysOut uplift â shared interactions 2 Vanilla JS, no dependencies. Safe to drop into any stack. */ 3(function () { 4 "use strict"; 5 6 /* Sticky nav background on scroll */ 7 var nav = document.querySelector(".nav"); 8 function onScroll() { 9 if (!nav) return; 10 nav.classList.toggle("scrolled", window.scrollY > 24); 11 } 12 window.addEventListener("scroll", onScroll, { passive: true }); 13 onScroll(); 14 15 /* Mobile menu */ 16 var burger = document.querySelector(".nav-burger"); 17 if (burger && nav) { 18 burger.addEventListener("click", function () { 19 nav.classList.toggle("open"); 20 }); 21 nav.querySelectorAll(".nav-links a").forEach(function (a) { 22 a.addEventListener("click", function () { nav.classList.remove("open"); }); 23 }); 24 } 25 26 /* Scroll reveal */ 27 var reveals = document.querySelectorAll(".reveal"); 28 if ("IntersectionObserver" in window && reveals.length) { 29 var io = new IntersectionObserver(function (entries) { 30 entries.forEach(function (e) { 31 if (e.isIntersecting) { 32 e.target.classList.add("in"); 33 io.unobserve(e.target); 34 } 35 }); 36 }, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" }); 37 reveals.forEach(function (el) { io.observe(el); }); 38 } else { 39 reveals.forEach(function (el) { el.classList.add("in"); }); 40 } 41 42 /* Hub category filter (only on pages with .chip + [data-cat]) */ 43 var chips = document.querySelectorAll(".chip[data-filter]"); 44 var items = document.querySelectorAll("[data-cat]"); 45 if (chips.length && items.length) { 46 chips.forEach(function (chip) { 47 chip.addEventListener("click", function () { 48 chips.forEach(function (c) { c.classList.remove("active"); }); 49 chip.classList.add("active"); 50 var f = chip.getAttribute("data-filter"); 51 items.forEach(function (it) { 52 var show = f === "all" || it.getAttribute("data-cat").indexOf(f) !== -1; 53 it.style.display = show ? "" : "none"; 54 }); 55 }); 56 }); 57 } 58 59 /* Prevent dead-link jumps on demo buttons */ 60 document.querySelectorAll('a[href="#"]').forEach(function (a) { 61 a.addEventListener("click", function (e) { e.preventDefault(); }); 62 }); 63})(); 64 65 66/* News rail arrows */ 67(function(){ 68 var rail=document.getElementById("newsRail"); 69 if(!rail) return; 70 function step(){ return Math.max(rail.clientWidth*0.8, 360); } 71 var n=document.getElementById("newsNext"), p=document.getElementById("newsPrev"); 72 if(n) n.addEventListener("click",function(){ rail.scrollBy({left:step(),behavior:"smooth"}); }); 73 if(p) p.addEventListener("click",function(){ rail.scrollBy({left:-step(),behavior:"smooth"}); }); 74})(); 75 76/* Gameplay reels â autoplay muted loops only while on screen */ 77(function(){ 78 var vids = document.querySelectorAll('video.reel-vid'); 79 if(!vids.length) return; 80 if(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; 81 if(!('IntersectionObserver' in window)) return; 82 var io = new IntersectionObserver(function(entries){ 83 entries.forEach(function(e){ 84 var v = e.target; 85 if(e.isIntersecting){ v.play().catch(function(){}); } 86 else { v.pause(); } 87 }); 88 }, { threshold: 0.35 }); 89 vids.forEach(function(v){ io.observe(v); }); 90})();
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.