PageSourceSearch

https://outwitly.com/wp-content/themes/outwitly/js/general.js?ver=1.0.1

js outwitly.com collected 2026-10-04 01:34:13 UTC 18,045 bytes, 560 lines download raw bytes

1jQuery(function($) {
2    //Add JS class for JS users
3    $('html').addClass('js');
4    $('html').removeClass('no-js');
5
6    // Main menu
7    var fixedHeader = $('.fixed-header');
8    var offset = 500;
9
10    $(window).on('scroll', function () {
11        var st = $(this).scrollTop();
12
13        if (st <= offset) {
14            // At top -> hide fixed header
15            fixedHeader.removeClass('show-header');
16            $('body').removeClass('header-visible');
17        } else {
18            // Past offset -> always show
19            fixedHeader.addClass('show-header');
20            $('body').addClass('header-visible');
21        }
22    });
23
24    $('.mobile-button').click(function() {
25        const $btn = $(this);
26    
27        if ($btn.hasClass('closed')) {
28            $('body').addClass('mobile-nav-open');
29            $btn.removeClass('closed').addClass('open');
30            $('.mobile-overlay').addClass('overlay-open');
31    
32            setTimeout(() => {
33                $('body').addClass('mobile-nav-bg');
34            }, 350); // match slightly shorter than overlay anim
35        } else {
36            $('body').removeClass('mobile-nav-open mobile-nav-bg');
37            $btn.removeClass('open').addClass('closed');
38            $('.mobile-overlay').removeClass('overlay-open');
39            $('.sub-menu').removeClass('active-sub-menu');
40            $('.mobile-back').hide();
41        }
42    });
43
44
45    
46    $(document).on('click', '.global-header .menu-item-has-children > a', function(e) {
47        e.preventDefault();
48        var $parent = $(this).parent();
49
50        // close others first
51        $('.global-header .menu-item-has-children.open').not($parent).removeClass('open');
52
53        // toggle this one
54        $parent.toggleClass('open');
55        $('.global-header.fixed-header').toggleClass('sub-menu-open');
56    });
57
58    // close if click outside
59    $(document).on('click', function(e) {
60        if (!$(e.target).closest('.menu-item-has-children').length) {
61            $('.menu-item-has-children.open').removeClass('open');
62            $('.global-header.fixed-header').removeClass('sub-menu-open');
63        }
64    });
65
66    // Webinar Countdown
67    var $countdown = $(".webinar-countdown");
68
69    if ($countdown.length) {
70        // Only show if cookie NOT set
71        if (Cookies.get("webinarClosed") !== "true") {
72            $countdown.removeClass('hidden').show();
73            $countdown.show();
74        } else {
75            return; // stop here, don't init timer
76        }
77
78        var $timerEl = $countdown.find(".webinar-timer");
79        var eventTime = new Date($countdown.data("event-time")).getTime();
80
81        function updateCountdown() {
82            var now = new Date().getTime();
83            var distance = eventTime - now;
84
85            if (distance <= 0) {
86                $countdown.fadeOut();
87                clearInterval(interval);
88                return;
89            }
90
91            var days = Math.floor(distance / (1000 * 60 * 60 * 24));
92            var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000*60*60));
93            var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000*60));
94            var seconds = Math.floor((distance % (1000 * 60)) / 1000);
95
96            var output = "";
97            if (days > 0) {
98                output += days + "d : ";
99            }
100            output += hours + "h : " + minutes + "m : " + seconds + "s";
101
102            $timerEl.html(output);
103        }
104
105        updateCountdown();
106        var interval = setInterval(updateCountdown, 1000);
107
108        // Close button (manual dismiss)
109        $countdown.find(".webinar-close").on("click", function() {
110            $countdown.fadeOut();
111            // Set cookie for 1 day (adjust as needed)
112            Cookies.set("webinarClosed", "true", { expires: 1 });
113        });
114    }
115
116
117    //Clients
118
119    $('.service-title').click(function() {
120        $(this).parent('.item').toggleClass('open');
121        $(this).parent('.item').find('.service-content').slideToggle(150);
122
123        $(this).parent('.item').siblings('.item').removeClass('open');
124        $(this).parent('.item').siblings('.item').find('.service-content').slideUp(1
12450);
125
126
127        if ($(this).parent('li').hasClass('open')) {
128            $('.service-image').slideDown(150);
129        } else {
130            $('.service-image').slideUp(150);
131        }
132    });
133    
134    $('.testimonials-slider').each(function(){
135        const $t = $(this);
136    
137        $t.slick({
138            slidesToShow: 3,
139            slidesToScroll: 1,
140            infinite: false,
141            variableWidth: false,
142            arrows: true,
143            dots: false,
144            prevArrow: $('.testimonial-arrows .slick-prev'),
145            nextArrow: $('.testimonial-arrows .slick-next'),
146            centerMode: false,
147            responsive: [
148              { breakpoint: 1180, settings: { slidesToShow: 2, centerMode: false, adaptiveHeight: true } },
149              { breakpoint: 768, settings: { slidesToShow: 1, centerMode: false, adaptiveHeight: true } }
150            ]
151        });
152    });
153
154
155    //Card Grid
156    $('.card-grid').slick({
157      slidesToShow: 3,
158      slidesToScroll: 1,
159      infinite: false,
160      arrows: true,
161      dots: false,
162      prevArrow: $('.card-grid-arrows .slick-prev'),
163      nextArrow: $('.card-grid-arrows .slick-next'),
164      centerMode: false,
165      responsive: [
166        {
167          breakpoint: 1040,
168          settings: { slidesToShow: 2 }
169        },
170          {
171          breakpoint: 768,
172          settings: { slidesToShow: 1}
173        }
174      ]
175    });
176    
177    //Metrics
178    $('.metrics').slick({
179        slidesToShow: 3,
180        slidesToScroll: 1,
181        infinite: true,
182        variableWidth: false,
183        arrows: false,
184        dots: false,
185        centerMode: false,
186        autoplay: true,
187        autoplaySpeed: 3000, // 3 seconds
188        pauseOnHover: true,
189        responsive: [
190            {
191                breakpoint: 1040,
192                settings: {
193                    slidesToShow: 2,
194                    centerMode: false,
195                    adaptiveHeight: true
196                }
197            },
198              {
199              breakpoint: 768,
200              settings: { slidesToShow: 1}
201            }
202        ]
203    });
204
205    
206    
207    var $faqs = $(".faqs-list .item");
208    $faqs.first().addClass("open").find(".content").show();
209
210    $(".faqs-list .item .title").on("click", function() {
211        var $item = $(this).closest(".item");
212        var $content = $item.find(".content");
213
214        if ($item.hasClass("open")) {
215            $item.removeClass("open");
216            $content.slideUp(150);
217        } else {
218            $item.siblings(".item").removeClass("open").find(".content").slideUp(150);
219
220            // Open the clicked one
221            $item.addClass("open");
222            $content.slideDown(150);
223        }
224    });
225    
226    // initial state
227    $('.approach-list .icon').removeClass('open');
228    $('.approach-list .icon').first().addClass('open');
229    $('.approach-list .item').removeClass('open').find('.content').hide();
230    $('.approach-list .item').first().addClass('open').find('.content').show();
231
232    // click toggle
233    $('.approach-list .item .title').on('click', function() {
234        var $item = $(this).closest('.item');
235        var index = $item.index();
236        var $list = $item.closest('.approach-list');
237        var $icons = $list.find('.icon');
238
239        // if it's already open, do nothing
240        if ($item.hasClass('open')) {
241            return;
242        }
243
244        // close others
245        $list.find('.item').removeClass('open').find('.content').slideUp(150);
246        $list.find('.plus-minus').removeClass('open');
247        $icons.removeClass('open');
248
249        // open current
250        $item.addClass('open').find('.content').slideDown(150);
251        $item.find('.plus-minus').addClass('open');
252        $icons.eq(index).addClass('open');
253    });
254    
255    // detailed, services
256    /*
257    $('.tabbed-services').each(function() {
258        var $container = $(this);
259
260        $container.find('.tabs li:first').addClass('active');
261        $container.find('.services-wrap .service:first').addClass('active').show();
262
263        $container.find('.tabs li a').on('click', function(e) {
264            e.preventDefault();
265            var $tab = $(this).parent('li');
266            var target = $tab.find('a').data('target');
267
268            $tab.addClass('active').siblings().removeClass('active');
269            $container.find('.services-wrap .service').hide().removeClass('active');
270            $container.find('#' + target).fadeIn(200).addClass('active');
271        });
272    });*/
273    
274    const $slider = $('.tabbed-services .services-wrap');
275    const $tabs = $('.tabbed-services .tabs a');
276
277    $slider.slick({
278        slidesToShow: 1,
279        slidesToScroll: 1,
280        arrows: true,
281        dots: false,
282        infinite: false,
283        adaptiveHeight: true,
284        prevArrow: $('.tabbed-services-arrows .slick-prev'),
285        nextArrow: $('.tabbed-services-arrows .slick-next')
286    });
287
288    // set first tab active on load
289    $tabs.parent('li').removeClass('active').first().addClass('active');
290    
291    $tabs.on('click', function(e) {
292        e.preventDefault();
293        const index = $(this).data('slide');
294        $slider.slick('slickGoTo', index);
295        $tabs.parent('li').removeClass('active');
296        const $activeTab = $(this).parent('li').addClass('active');
297
298        $activeTab[0].scrollIntoView({
299            behavior: 'smooth',
300            inline: 'center',
301            block: 'nearest'
302        });
303    });
304
305        // before slide changes → update active tab instantly
306    $slider.on('beforeChange', function(event, slick, currentSlide, nextSlide) {
307        $tabs.parent('li').removeClass('active');
308        const $activeTab = $tabs.filter('[data-slide="' + nextSlide + '"]').parent('li').addClass('active');
309
310        // scroll that tab into view
311        $activeTab[0].scrollIntoView({
312            behavior: 'smooth',
313            inline: 'center',
314            block: 'nearest'
315        });
316    });
317
318
319    $('.approach-slider').slick({
320        slidesToShow: 4,
321        slidesToScroll: 1,
322        arrows: true,
323        dots: false,
324        infinite: false,
325        prevArrow: $('.approach-slider-arrows .slick-prev'),
326        nextArrow: $('.approach-slider-arrows .slick-next'),
327        responsive: [
328            { breakpoint: 1024, settings: { slidesToShow: 3 } },
329            { breakpoint: 768, settings: { slidesToShow: 1 } }
330        ]
331    });
332    
333    
334    $('.toggle-list').each(function() {
335        var $list = $(this);
336        var $firstItem = $list.find('.item').first();
337
338        // initial state for each list
339        $list.find('.icon').removeClass('open');
340        $list.find('.item').removeClass('open').find('.content').hide();
341
342        $firstItem.addClass('open').find('.content').show();
343        $firstItem.find('.plus-minus').addClass('open');
344        $firstItem.find('.icon').first().addClass('open');
345    });
346
347    // click toggle
348    $('.toggle-list .item .title').on('click', function() {
349        var $item = $(this).closest('.item');
350        var index = $item.index();
351        var $list = $item.closest('.toggle-list');
352        var $icons = $list.find('.icon');
353
354        if ($item.hasClass('open')) {
355            $item.removeClass('open').find('.content').slideUp(150);
356            $item.find('.plus-minus').removeClass('open');
357            $icons.eq(index).removeClass('open');
358            return;
359        }
360
361        $list.find('.item').removeClass('open').find('.content').slideUp(150);
362        $list.find('.plus-minus').removeClass('open');
363        $icons.removeClass('open');
364
365        $item.addClass('open').find('.content').slideDown(150);
366        $item.find('.plus-minus').addClass('open');
367        $icons.eq(index).addClass('open');
368    });
369
370    $('.resources-list').slick({
371        slidesToShow: 3,
372        slidesToScroll: 1,
373        arrows: true,
374        dots: false,
375        infinite: false,
376        prevArrow: `
377            <button type="button" class="slick-prev">
378                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 61.25 61.25">
379                    <defs><style>.prev-arrow1{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:2px;}</style></defs>
380                    <g>
381                        <circle cx="30.63" cy="30.63" r="30.63"/>
382                        <polyline class="prev-arrow1" points="29.57 39.14 20.41 30.63 29.57 22.11"/>
383                        <line class="prev-arrow1" x1="20.41" y1="30.63" x2="42.21" y2="30.63"/>
384                    </g>
385                </svg>
386            </button>
387        `,
388        
389        nextArrow: `
390            <button type="button" class="slick-next">
391                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 61.25 61.25">
392                    <defs><style>.next-arrow1{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:2px;}</style></defs>
393                    <g>
394                        <circle cx="30.63" cy="30.63" r="30.63"/>
395                        <polyline class="next-arrow1" points="31.68 39.14 40.84 30.63 31.68 22.11"/>
396                        <line class="next-arrow1" x1="40.84" y1="30.63" x2="19.04" y2="30.63"/>
397                    </g>
398                </svg>
399            </button>
400        `,
401        responsive: [
402            { breakpoint: 1024, settings: { slidesToShow: 2 } },
403            { breakpoint: 768, settings: { slidesToShow: 1 } }
404        ]
405    });
406    
407    // Our Work
408    var containerEl = $('#case-study-grid');
409    if (containerEl.length) {
410        var mixer = mixitup(containerEl[0], {
411            selectors: {
412                target: '.case-study-item'
413            },
414            animation: {
415                duration: 300,   // quick transition
416                easing: 'ease',
417                
418            },
419        });
420
421        // Handle active button styling manually
422        $('.filter').on('click', function() {
423            $('.filter').removeClass('mixitup-control-active');
424            $(this).addClass('mixitup-control-active');
425        });
426    }
427    
428    // Team
429
430    // Open popup
431      $('.open-team-member-popup').on('click', function(e){
432        e.preventDefault();
433        const id = $(this).attr('id');           // e.g. "sara-fortier"
434        const $popup = $('#popup-' + id);
435
436        if ($popup.length){
437          $('.team-popup').removeClass('is-open'); // close any open one
438          $popup.addClass('is-open');
439          $('body').addClass('popup-open');
440        }
441      });
442
443      // close (X)
444      $(document).on('click', '.team-popup .close', function(){
445        $(this).closest('.team-popup').removeClass('is-open');
446        $('body').removeClass('popup-open');
447      });
448
449      // close when clicking overlay
450      $(document).on('click', function(e){
451        const $p = $('.team-popup.is-open');
452        if ($p.length && !$(e.target).closest('.team-popup .inner, .open-team-member-popup').length){
453          $p.removeClass('is-open');
454          $('body').removeClass('popup-open');
455        }
456      });
457    
458    //
459    $('.archive-dropdown').on('change', function() {
460        var url = $(this).val();
461        if (url) {
462            window.location.href = url;
463        }
464    });
465    
466    $('.events-list').slick({
467        slidesToShow: 2,
468        slidesToScroll: 1,
469        arrows: true,
470        dots: false,
471        infinite: false,
472        prevArrow: $('.events-slider-arrows .slick-prev'),
473        nextArrow: $('.events-slider-arrows .slick-next'),
474        responsive: [
475            { breakpoint: 1024, settings: { slidesToShow: 1 } }
476        ]
477    });
478    
479
480    $('body').on('change', 'input[name="nl_select"]', function(){
481
482        if( $(this).val() === 'digest' ) {
483            $('.form-digest').show();
484            $('.form-wit').hide();
485        } else {
486            $('.form-digest').hide();
487            $('.form-wit').show();
488        }
489
490    });
491    
492    $(document).on('pumAfterOpen', function (event) {
493    
494        // safest way to get the popup DOM element
495        const $popup = $('#' + event.target.id);
496    
497        // get the email from the page
498        const email = $('.newsletter-email-input').val();
499    
500        // wait for the Mailchimp form to exist, then set the email + radio
501        let tries = 0;
502        const maxTries = 20;
503    
504        const tryInit = setInterval(function () {
505    
506            const $digest = $popup.find('input[name="nl_select"][value="digest"]');
507            const $emailField = $popup.find('.yikes-easy-mc-email');
508    
509            // once both exist, apply values
510            if ($digest.length || $emailField.length) {
511    
512                if ($emailField.length && email) {
513                    $emailField.val(email);
514                }
515    
516                if ($digest.length) {
517                    $digest.prop('checked', true).trigger('change');
518                }
519    
520                clearInterval(tryInit);
521            }
522    
523            tries++;
524            if (tries > maxTries) {
525                clearInterval(tryInit);
526            }
527    
528        }, 50);
529    
530    });
531    
532    console.log("%c Designed + Developed by Capari (https://capari.co/)","background: #04060e;
532 color: #fff;");
533
534    $(".faq-group-selector").on("click", function() {
535        var $button = $(this);
536        var group = $button.data("faq-group");
537        var $faqSection = $button.closest(".section-faqs");
538        var $group = $faqSection.find('.faq-group[data-faq-group="' + group + '"]');
539        var $groupFaqs = $group.find(".faqs-list .item");
540    
541        $faqSection.find(".faq-group-selector").attr("aria-selected", "false");
542        $button.attr("aria-selected", "true");
543    
544        $faqSection.find(".faq-group").attr("hidden", true);
545        $group.removeAttr("hidden");
546    
547        $groupFaqs.removeClass("open").find(".content").hide();
548        $groupFaqs.first().addClass("open").find(".content").show();
549    });
550
551
552
553
554    if (window.location.search.indexOf('preview=true') !== -1) {
555        jQuery('.cmplz-cookiebanner').remove();
556    }
557
558    console.log('general js 1.0.1');
559
560});

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.