Hurricane Bull

480000  GST Extra

Its gentle, flexible swing movement should delight you and its daily use should be easy.Obviously, good design and safety whilst exercising are all part of this.

[yith_wcwl_add_to_wishlist]
/* ==================================================== JUMPKING — GLOBAL JAVASCRIPT v2.0 ==================================================== Behaviors: - Header scroll state - Hamburger mobile nav toggle - Scroll reveal (IntersectionObserver) - Number counter animation - Filter tag interactions - Copy prompt utility - Smooth scroll for anchor links ==================================================== */(function () { 'use strict';/* ── PROGRESSIVE ENHANCEMENT: mark JS as active ── All reveal elements are visible by default (opacity:1). Adding .jk-ready to enables the animation system. This means if JS never loads, all content stays fully visible. */ document.documentElement.classList.add('jk-js'); document.body.classList.add('jk-ready');/* ── HEADER SCROLL STATE ── */ const hdr = document.getElementById('hdr'); if (hdr) { window.addEventListener('scroll', () => { hdr.classList.toggle('scrolled', window.scrollY > 20); }, { passive: true }); }/* ── HAMBURGER / MOBILE NAV ── */ const hamburger = document.getElementById('hamburger'); const mobileNav = document.getElementById('mobileNav'); if (hamburger && mobileNav) { hamburger.addEventListener('click', () => { hamburger.classList.toggle('open'); mobileNav.classList.toggle('open'); }); // Close on link click mobileNav.querySelectorAll('a').forEach(link => { link.addEventListener('click', () => { hamburger.classList.remove('open'); mobileNav.classList.remove('open'); }); }); }/* ── SCROLL REVEAL ── */ const revealObs = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('visible'); revealObs.unobserve(e.target); } }); }, { threshold: 0.07, rootMargin: '0px 0px -40px 0px' });document.querySelectorAll('.reveal, .reveal-left, .reveal-right').forEach(el => { revealObs.observe(el); });/* ── NUMBER COUNTER ── */ function animateCount(el, target, suffix) { const duration = 1800; const start = performance.now(); const update = (now) => { const elapsed = now - start; const progress = Math.min(elapsed / duration, 1); const ease = 1 - Math.pow(1 - progress, 3); el.textContent = Math.floor(ease * target) + (suffix || ''); if (progress < 1) requestAnimationFrame(update); }; requestAnimationFrame(update); }const countObs = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { const el = e.target; const target = parseInt(el.dataset.count); if (!isNaN(target)) animateCount(el, target, el.dataset.suffix || ''); countObs.unobserve(el); } }); }, { threshold: 0.3 });document.querySelectorAll('[data-count]').forEach(el => countObs.observe(el));/* ── DYNAMIC YEAR ── */ const yrEl = document.getElementById('yr'); if (yrEl) yrEl.textContent = new Date().getFullYear();/* ── COPY PROMPT UTILITY ── */ window.copyPrompt = function (btn, text) { navigator.clipboard.writeText(text).then(() => { const orig = btn.textContent; btn.textContent = '✓ Copied!'; btn.classList.add('copied'); setTimeout(() => { btn.textContent = orig; btn.classList.remove('copied'); }, 2000); }).catch(() => { // Fallback for older browsers const ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); const orig = btn.textContent; btn.textContent = '✓ Copied!'; btn.classList.add('copied'); setTimeout(() => { btn.textContent = orig; btn.classList.remove('copied'); }, 2000); }); };/* ── FILTER TAGS INTERACTION ── */ document.querySelectorAll('.filter-tag').forEach(tag => { tag.addEventListener('click', function () { // Allow multi-select within same group const group = this.closest('.filter-tags'); if (group) { group.querySelectorAll('.filter-tag').forEach(t => t.classList.remove('active')); } this.classList.toggle('active'); }); });/* ── SMOOTH SCROLL FOR ANCHORS ── */ document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { const target = document.querySelector(this.getAttribute('href')); if (target) { e.preventDefault(); const offset = 80; // header height const top = target.getBoundingClientRect().top + window.scrollY - offset; window.scrollTo({ top, behavior: 'smooth' }); } }); });/* ── PARALLAX HERO GRID ── */ const heroGrid = document.getElementById('heroGrid'); if (heroGrid) { window.addEventListener('scroll', () => { const scrollY = window.scrollY; heroGrid.style.transform = `translateY(${scrollY * 0.3}px)`; }, { passive: true }); }/* ── ACTIVE NAV LINK ── */ const sections = document.querySelectorAll('section[id], div[id]'); const navLinks = document.querySelectorAll('.hc-item'); if (sections.length && navLinks.length) { const sectionObs = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { navLinks.forEach(link => { link.classList.remove('active'); if (link.getAttribute('href') === '#' + e.target.id) { link.classList.add('active'); } }); } }); }, { threshold: 0.3 }); sections.forEach(s => sectionObs.observe(s)); }})();