PageSourceSearch

https://mastercollective.ai/site.js?v=20260821-services-team-mobile

js mastercollective.ai collected 2026-10-05 13:09:04 UTC 7,596 bytes, 198 lines download raw bytes

1// Master Collective — progressive enhancement only. The full experience and all meaningful content remain available in static HTML.
2(() => {
3  const header = document.querySelector('[data-header]');
4  const menuToggle = document.querySelector('[data-menu-toggle]');
5  const primaryNav = document.querySelector('#primary-navigation');
6
7  const updateHeader = () => {
8    if (!header) return;
9    header.classList.toggle('is-scrolled', window.scrollY > 16);
10  };
11
12  updateHeader();
13  window.addEventListener('scroll', updateHeader, { passive: true });
14
15  if (menuToggle && primaryNav) {
16    const mobileBreakpoint = window.matchMedia('(max-width: 820px)');
17    const firstMenuLink = primaryNav.querySelector('.nav-links a');
18
19    const setMenuState = (open) => {
20      const active = Boolean(open && mobileBreakpoint.matches);
21      document.body.classList.toggle('menu-open', active);
22      menuToggle.setAttribute('aria-expanded', String(active));
23      primaryNav.setAttribute('aria-hidden', String(!active && mobileBreakpoint.matches));
24
25      if ('inert' in primaryNav) primaryNav.inert = !active && mobileBreakpoint.matches;
26      if (active) window.requestAnimationFrame(() => firstMenuLink?.focus());
27    };
28
29    const closeMenu = () => setMenuState(false);
30    const syncMenuState = () => {
31      if (mobileBreakpoint.matches) closeMenu();
32      else {
33        document.body.classList.remove('menu-open');
34        menuToggle.setAttribute('aria-expanded', 'false');
35        primaryNav.setAttribute('aria-hidden', 'false');
36        if ('inert' in primaryNav) primaryNav.inert = false;
37      }
38    };
39
40    syncMenuState();
41    mobileBreakpoint.addEventListener('change', syncMenuState);
42    menuToggle.addEventListener('click', () => setMenuState(!document.body.classList.contains('menu-open')));
43    primaryNav.querySelectorAll('a').forEach((item) => item.addEventListener('click', closeMenu));
44    window.addEventListener('keydown', (event) => {
45      if (event.key === 'Escape') closeMenu();
46    });
47  }
48
49  const considerationForm = document.querySelector('[data-club-consideration-form]');
50  if (considerationForm) {
51    considerationForm.addEventListener('submit', async (event) => {
52      event.preventDefault();
53      if (!considerationForm.reportValidity()) return;
54
55      const endpointReady = considerationForm.dataset.endpointReady === 'true';
56      const endpoint = considerationForm.dataset.endpoint || '';
57      const status = considerationForm.querySelector('.club-form-status');
58      const button = considerationForm.querySelector('button[type="submit"]');
59      if (!endpointReady || !endpoint) {
60        if (status) status.textContent = considerationForm.dataset.errorLabel || 'Secure submission is not yet available.';
61        return;
62      }
63
64      if (button) {
65        button.disabled = true;
66        button.dataset.label = button.textContent;
67        button.textContent = considerationForm.dataset.processingLabel || 'Submitting…';
68      }
69
70      try {
71        const body = new URLSearchParams(new FormData(considerationForm));
72        await fetch(endpoint, {
73          method: 'POST',
74          mode: 'no-cors',
75          headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },
76          body,
77          keepalive: true,
78        });
79        window.location.assign(considerationForm.dataset.thankYouPath || '/club-consideration-received/');
80      } catch (error) {
81        if (status) status.textContent = considerationForm.dataset.errorLabel || 'Secure submission could not be completed.';
82        if (button) {
83          button.disabled = false;
84          button.textContent = button.dataset.label || button.textContent;
85        }
86      }
87    });
88  }
89
90  const spotlightForm = document.querySelector('[data-spotlight-form]');
91  if (spotlightForm) {
92    spotlightForm.addEventListener('submit', (event) => {
93      event.preventDefault();
94      if (!spotlightForm.reportValidity()) return;
95
96      const thanks = document.querySelector('[data-spotlight-thanks]');
97      spotlightForm.hidden = true;
98      if (thanks) {
99        thanks.hidden = false;
100        thanks.focus();
101      }
102    });
103  }
104
105  const universityForm = document.querySelector('[data-university-form]');
106  if (universityForm) {
107    universityForm.addEventListener('submit', (event) => {
108      event.preventDefault();
109      if (!universityForm.reportValidity()) return;
110
111      const thanks = document.querySelector('[data-university-thanks]');
112      universityForm.hidden = true;
113      if (thanks) {
114        thanks.hidden = false;
115        thanks.focus();
116      }
117    });
118  }
119
120  const partnerForm = document.querySelector('[data-partner-form]');
121  if (partnerForm) {
122    partnerForm.addEventListener('submit', (event) => {
123      event.preventDefault();
124      if (!partnerForm.reportValidity()) return;
125
126      const thanks = document.querySelector('[data-partner-thanks]');
127      partnerForm.hidden = true;
128      if (thanks) {
129        thanks.hidden = false;
130        thanks.focus();
131      }
132    });
133  }
134
135  const mAndAForm = document.querySelector('[data-m-and-a-form]');
136  if (mAndAForm) {
137    mAndAForm.addEventListener('submit', (event) => {
138      event.preventDefault();
139      if (!mAndAForm.reportValidity()) return;
140      window.location.assign(mAndAForm.dataset.thankYouPath || '/m-and-a-application-received/');
141    });
142  }
143
144  const postFundingForm = document.querySelector('[data-post-funding-form]');
145  if (postFundingForm) {
146    postFundingForm.addEventListener('submit', (event) => {
147      event.preventDefault();
148      if (!postFundingForm.reportValidity()) return;
149
150      const thanks = document.querySelector('[data-post-funding-thanks]');
151      postFundingForm.hidden = true;
152      if (thanks) {
153        thanks.hidden = false;
154        thanks.focus();
155      }
156    });
157  }
158
159  const insightsFilter = document.querySelector('[data-insights-filter]');
160  if (insightsFilter) {
161    const search = insightsFilter.querySelector('[data-insights-search]');
162    const topicButtons = [...insightsFilter.querySelectorAll('[data-insights-topic]')];
163    const cards = [...document.querySelectorAll('[data-insights-card]')];
164    const emptyState = document.querySelector('[data-insights-empty]');
165    let activeTopic = '';
166    const normalize = (value) => String(value || '').trim().toLocaleLowerCase();
167
168    const applyFilters = () => {
169      const query = normalize(search?.value);
170      let visibleCount = 0;
171      cards.forEach((card) => {
172        const matchesQuery = !query || normalize(card.dataset.search).includes(query);
173        const topics = String(card.dataset.topic || '').split('|').map(normalize).filter(Boolean);
174        const matchesTopic = !activeTopic || topics.includes(activeTopic);
175        const visible = matchesQuery && matchesTopic;
176        card.hidden = !visible;
177        card.classList.toggle('is-filtered-out', !visible);
178        card.setAttribute('aria-hidden', String(!visible));
179        if (visible) visibleCount += 1;
180      });
181      if (emptyState) emptyState.hidden = visibleCount !== 0;
182    };
183
184    search?.addEventListener('input', applyFilters);
185    search?.addEventListener('search', applyFilters);
186    topicButtons.forEach((button) => button.addEventListener('click', () => {
187      activeTopic = normalize(button.dataset.insightsTopic);
188      topicButtons.forEach((item) => {
189        const active = item === button;
190        item.classList.toggle('is-active', active);
191        item.setAttribute('aria-pressed', String(active));
192      });
193      applyFilters();
194    }));
195    insightsFilter.dataset.ready = 'true';
196    applyFilters();
197  }
198})();

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.