PageSourceSearch

https://www.limetalentgroup.com/wp-content/themes/limetalentgroup-custom/assets/js/main.js?ver=1779968071

js limetalentgroup.com collected 2026-10-04 13:24:36 UTC 10,100 bytes, 354 lines download raw bytes

1document.addEventListener('DOMContentLoaded', () => {
2	const body = document.body;
3	body.classList.add('js-ready');
4
5	const menu = document.querySelector('.site-menu');
6	const toggle = document.querySelector('.site-header__toggle');
7	const overlay = document.querySelector('[data-menu-overlay]');
8	const drawer = document.querySelector('.site-menu__drawer');
9	const closeButton = document.querySelector('.site-menu__close');
10	let closeAnimationTimer = null;
11	const menuLinks = menu ? Array.from(menu.querySelectorAll('a')) : [];
12	let previousFocus = null;
13
14	const openMenu = () => {
15		if (!menu || !toggle || !drawer) {
16			return;
17		}
18
19		previousFocus = document.activeElement;
20		menu.classList.add('is-open');
21		menu.setAttribute('aria-hidden', 'false');
22		toggle.setAttribute('aria-expanded', 'true');
23		body.classList.add('menu-open');
24
25		window.setTimeout(() => {
26			if (closeButton) {
27				closeButton.focus();
28			}
29		}, 40);
30	};
31
32	const closeMenu = () => {
33		if (!menu || !toggle) {
34			return;
35		}
36
37		menu.classList.remove('is-open');
38		menu.setAttribute('aria-hidden', 'true');
39		toggle.setAttribute('aria-expanded', 'false');
40		body.classList.remove('menu-open');
41
42		if (previousFocus instanceof HTMLElement) {
43			previousFocus.focus();
44		}
45	};
46
47	if (menu && toggle) {
48		toggle.addEventListener('click', () => {
49			const isExpanded = toggle.getAttribute('aria-expanded') === 'true';
50			if (isExpanded) {
51				closeMenu();
52				return;
53			}
54
55			openMenu();
56		});
57
58		if (overlay) {
59			overlay.addEventListener('click', closeMenu);
60		}
61
62		if (closeButton) {
63			closeButton.addEventListener('click', (event) => {
64				event.preventDefault();
65				closeButton.classList.add('is-animating');
66
67				if (closeAnimationTimer) {
68					window.clearTimeout(closeAnimationTimer);
69				}
70
71				closeAnimationTimer = window.setTimeout(() => {
72					closeButton.classList.remove('is-animating');
73					closeMenu();
74				}, 180);
75			});
76		}
77
78		menuLinks.forEach((link) => {
79			link.addEventListener('click', closeMenu);
80		});
81
82		document.addEventListener('keydown', (event) => {
83			if (event.key === 'Escape' && menu.classList.contains('is-open')) {
84				closeMenu();
85			}
86		});
87	}
88
89	const contactTabs = document.querySelector('[data-contact-tabs]');
90
91	if (contactTabs) {
92		const buttons = Array.from(contactTabs.querySelectorAll('[data-contact-tab]'));
93		const panels = Array.from(contactTabs.querySelectorAll('[data-contact-panel]'));
94
95		buttons.forEach((button) => {
96			button.addEventListener('click', () => {
97				const target = button.getAttribute('data-contact-tab');
98
99				buttons.forEach((item) => {
100					const isActive = item === button;
101					item.classList.toggle('is-active', isActive);
102					item.setAttribute('aria-selected', String(isActive));
103				});
104
105				panels.forEach((panel) => {
106					const isActive = panel.getAttribute('data-contact-panel') === target;
107					panel.classList.toggle('is-active', isActive);
108					panel.hidden = !isActive;
109				});
110			});
111		});
112	}
113
114
115	const faqAccordions = Array.from(document.querySelectorAll('[data-faq-accordion]'));
116
117	faqAccordions.forEach((accordion) => {
118		const items = Array.from(accordion.querySelectorAll('[data-faq-item]'));
119
120		items.forEach((item) => {
121			const trigger = item.querySelector('[data-faq-trigger]');
122			const panel = item.querySelector('[data-faq-panel]');
123
124			if (!trigger || !panel) {
125				return;
126			}
127
128			trigger.addEventListener('click', () => {
129				const isOpen = trigger.getAttribute('aria-expanded') === 'true';
130
131				items.forEach((otherItem) => {
132					const otherTrigger = otherItem.querySelector('[data-faq-trigger]');
133					const otherPanel = otherItem.querySelector('[data-faq-panel]');
134
135					if (!otherTrigger || !otherPanel) {
136						return;
137					}
138
139					otherItem.classList.remove('is-open');
140					otherTrigger.setAttribute('aria-expanded', 'false');
141					otherPanel.hidden = true;
142				});
143
144				if (!isOpen) {
145					item.classList.add('is-open');
146					trigger.setAttribute('aria-expanded', 'true');
147					panel.hidden = false;
148				}
149			});
150		});
151	});
152	const portfolioCards = Array.from(document.querySelectorAll('[data-portfolio-card]'));
153
154	portfolioCards.forEach((card) => {
155		const slides = Array.from(card.querySelectorAll('[data-portfolio-slide]'));
156		const mediaSlides = Array.from(card.querySelectorAll('[data-portfolio-media-slide]'));
157		const prev = card.querySelector('[data-portfolio-prev]');
158		const next = card.querySelector('[data-portfolio-next]');
159		let currentIndex = 0;
160
161		if (!slides.length) {
162			return;
163		}
164
165		const setActiveSlide = (index) => {
166			currentIndex = (index + slides.length) % slides.length;
167
168			slides.forEach((slide, slideIndex) => {
169				const isActive = slideIndex === currentIndex;
170				slide.classList.toggle('is-active', isActive);
171				slide.hidden = !isActive;
172			});
173
174			mediaSlides.forEach((slide, slideIndex) => {
175				const isActive = slideIndex === currentIndex;
176				slide.classList.toggle('is-active', isActive);
177				slide.hidden = !isActive;
178			});
179		};
180
181		const resetCard = () => {
182			currentIndex = 0;
183			slides.forEach((slide, slideIndex) => {
184				const isActive = slideIndex === 0;
185				slide.classList.toggle('is-active', isActive);
186				slide.hidden = !isActive;
187			});
188
189			mediaSlides.forEach((slide, slideIndex) => {
190				const isActive = slideIndex === 0;
191				slide.classList.toggle('is-active', isActive);
192				slide.hidden = !isActive;
193			});
194		};
195
196		card.addEventListener('mouseenter', () => setActiveSlide(0));
197		card.addEventListener('mouseleave', resetCard);
198
199		if (prev) {
200			prev.addEventListener('click', (event) => {
201				event.preventDefault();
202				event.stopPropagation();
203				setActiveSlide(currentIndex - 1);
204			});
205		}
206
207		if (next) {
208			next.addEventListener('click', (event) => {
209				event.preventDefault();
210				event.stopPropagation();
211				setActiveSlide(currentIndex + 1);
212			});
213		}
214
215		resetCard();
216	});
217
218	const testimonialSliders = Array.from(document.querySelectorAll('[data-testimonial-slider]'));
219
220	testimonialSliders.forEach((testimonialSlider) => {
221		const slides = Array.from(testimonialSlider.querySelectorAll('[data-testimonial-slide]'));
222		const mediaSlides = Array.from(testimonialSlider.querySelectorAll('[data-testimonial-media-slide]'));
223		const dots = Array.from(testimonialSlider.querySelectorAll('[data-testimonial-dot]'));
224		const prev = testimonialSlider.querySelector('[data-testimonial-prev]');
225		const next = testimonialSlider.querySelector('[data-testimonial-next]');
226		let currentIndex = 0;
227
228		const setActiveSlide = (index) => {
229			if (!slides.length) {
230				return;
231			}
232
233			currentIndex = (index + slides.length) % slides.length;
234
235			slides.forEach((slide, slideIndex) => {
236				const isActive = slideIndex === currentIndex;
237				slide.classList.toggle('is-active', isActive);
238				slide.hidden = !isActive;
239			});
240
241			mediaSlides.forEach((slide, slideIndex) => {
242				const isActive = slideIndex === currentIndex;
243				slide.classList.toggle('is-active', isActive);
244				slide.hidden = !isActive;
245			});
246
247			dots.forEach((dot, dotIndex) => {
248				const isActive = dotIndex === currentIndex;
249				dot.classList.toggle('is-active', isActive);
250				dot.setAttribute('aria-pressed', String(isActive));
251			});
252		};
253
254		if (prev) {
255			prev.addEventListener('click', () => setActiveSlide(currentIndex - 1));
256		}
257
258		if (next) {
259			next.addEventListener('click', () => setActiveSlide(currentIndex + 1));
260		}
261
262		dots.forEach((dot, dotIndex) => {
263			dot.addEventListener('click', () => setActiveSlide(dotIndex));
264		});
265
266		setActiveSlide(0);
267	});
268
269	const fileFieldWrappers = Array.from(document.querySelectorAll(".contact-layout__form .field:has(input[type='file']), .job-single__apply-wrap .job-manager-application-form fieldset:has(input[type='file'])"));
270
271	fileFieldWrappers.forEach((wrapper) => {
272		const input = wrapper.querySelector("input[type='file']");
273
274		if (!input) {
275			return;
276		}
277
278		const defaultLabel = 'Upload your CV';
279
280		const updateLabel = () => {
281			const fileName = input.files && input.files.length ? input.files[0].name : '';
282			wrapper.dataset.uploadLabel = fileName || defaultLabel;
283			wrapper.classList.toggle('is-file-selected', Boolean(fileName));
284		};
285
286		wrapper.dataset.uploadLabel = defaultLabel;
287		updateLabel();
288
289		wrapper.addEventListener('click', (event) => {
290			if (event.target !== input) {
291				input.click();
292			}
293		});
294
295		input.addEventListener('change', updateLabel);
296	});
297
298	if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
299		return;
300	}
301
302	const revealGroups = [
303		{ selector: '.hero__content--home', variant: 'reveal--hero' },
304		{ selector: '.logo-strip--home .logo-strip__item', variant: 'reveal--up', stagger: 0.05 },
305		{ selector: '.home-intro__content', variant: 'reveal--up' },
306		{ selector: '.home-intro__media', variant: 'reveal--right' },
307		{ selector: '.section-heading', variant: 'reveal--up' },
308		{ selector: '.card-grid--functions-home .content-card', variant: 'reveal--up', stagger: 0.08 },
309		{ selector: '.portfolio-grid--home-teasers .content-card', variant: 'reveal--scale', stagger: 0.06 },
310		{ selector: '.home-testimonials', variant: 'reveal--up' },
311		{ selector: '.home-promo', variant: 'reveal--up', stagger: 0.1 }
312	];
313
314	const revealElements = [];
315
316	revealGroups.forEach((group) => {
317		const elements = Array.from(document.querySelectorAll(group.selector));
318		elements.forEach((element, index) => {
319			element.classList.add('reveal', group.variant);
320			const delay = group.stagger ? index * group.stagger : 0;
321			element.style.setProperty('--reveal-delay', `${delay.toFixed(2)}s`);
322			revealElements.push(element);
323		});
324	});
325
326	if (!revealElements.length || !('IntersectionObserver' in window)) {
327		revealElements.forEach((element) => element.classList.add('in-view'));
328		return;
329	}
330
331	const revealObserver = new IntersectionObserver(
332		(entries, observer) => {
333			entries.forEach((entry) => {
334				if (!entry.isIntersecting) {
335					return;
336				}
337
338				entry.target.classList.add('in-view');
339				observer.unobserve(entry.target);
340			});
341		},
342		{
343			threshold: 0.18,
344			rootMargin: '0px 0px -8% 0px'
345		}
346	);
347
348	revealElements.forEach((element) => revealObserver.observe(element));
349});
350
351
352
353
354

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.