PageSourceSearch

https://ungovernable.network/js/main.js?v=f6f262f8f1

js ungovernable.network collected 2026-10-06 19:50:52 UTC 2,914 bytes, 86 lines download raw bytes

1// ===========================
2// UGMF — Main JS
3// ===========================
4
5// Mobile nav toggle
6(function() {
7  const toggle = document.getElementById('nav-toggle');
8  const navList = document.getElementById('nav-list');
9  if (!toggle || !navList) return;
10
11  function closeNav() {
12    navList.classList.remove('is-open');
13    toggle.setAttribute('aria-expanded', 'false');
14    document.documentElement.style.overflow = '';
15  }
16
17  toggle.addEventListener('click', function() {
18    const isOpen = navList.classList.toggle('is-open');
19    toggle.setAttribute('aria-expanded', isOpen);
20    document.documentElement.style.overflow = isOpen ? 'hidden' : '';
21  });
22
23  document.addEventListener('keydown', function(e) {
24    if (e.key === 'Escape' && navList.classList.contains('is-open')) {
25      closeNav();
26    }
27  });
28
29  // Close on link click
30  navList.querySelectorAll('.nav__link').forEach(function(link) {
31    link.addEventListener('click', function() {
32      closeNav();
33    });
34  });
35})();
36
37// Show ticker: the track holds two identical sets and slides by exactly half
38// its width, so the loop is seamless only if that half is a whole number of
39// pixels. The sets' natural width is fractional (1252.89px at desktop size),
40// and on a Retina screen the reset then snaps the text by a fraction of a
41// pixel, which reads as a jump. Round each set up to a whole pixel.
42(function() {
43  var sets = document.querySelectorAll('.hero__ticker-set');
44  if (sets.length < 2) return;
45  function fit() {
46    sets.forEach(function(set) { set.style.width = ''; });
47    var width = Math.ceil(sets[0].getBoundingClientRect().width);
48    sets.forEach(function(set) { set.style.width = width + 'px'; });
49  }
50  fit();
51  if (document.fonts && document.fonts.ready) document.fonts.ready.then(fit);
52  var resizeTimer;
53  window.addEventListener('resize', function() {
54    clearTimeout(resizeTimer);
55    resizeTimer = setTimeout(fit, 150);
56  });
57})();
58
59// Scroll reveal
60(function() {
61  var reveals = document.querySelectorAll('.reveal');
62  if (!reveals.length) return;
63
64  if ('IntersectionObserver' in window) {
65    var observer = new IntersectionObserver(function(entries) {
66      entries.forEach(function(entry) {
67        if (entry.isIntersecting) {
68          entry.target.classList.add('is-visible');
69          observer.unobserve(entry.target);
70        }
71      });
72    }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
73
74    reveals.forEach(function(el) { observer.observe(el); });
75  } else {
76    reveals.forEach(function(el) { el.classList.add('is-visible'); });
77  }
78
79  // Once a card has faded in, drop its stagger delay so hovers respond at once.
80  document.addEventListener('transitionend', function(e) {
81    var el = e.target;
82    if (e.propertyName === 'opacity' && el.classList && el.classList.contains('reveal') && el.classList.contains('is-visible')) {
83      el.classList.add('is-revealed');
84    }
85  });
86})();

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.