/** * CurcuVance BioSciences - Main Application Controller * Handles interactive navigation, product catalog filters, dynamic modals, * bioavailability comparison simulator, and B2B sample inquiry workflows. */ document.addEventListener("DOMContentLoaded", () => { initCopyrightYear(); initHeader(); initMobileNav(); initBiotechConsole(); initFormulationFinder(); initPlatformTabs(); initProducts(); initBioSimulator(); initRDPipeline(); initModals(); initContactForms(); initFaqAccordion(); initScrollReveal(); initSmoothScrollFeatures(); }); /* ------------------------------------------------------------- * 0. Automatic Dynamic Copyright Year * ------------------------------------------------------------- */ function initCopyrightYear() { const year = new Date().getFullYear(); document.querySelectorAll(".current-year").forEach(el => { el.textContent = year; }); } /* ------------------------------------------------------------- * 1. Header & Navigation Controller * ------------------------------------------------------------- */ function initHeader() { const header = document.querySelector(".site-header"); if (!header) return; window.addEventListener("scroll", () => { if (window.scrollY > 40) { header.classList.add("scrolled"); } else { header.classList.remove("scrolled"); } }, { passive: true }); } function initMobileNav() { const toggleBtn = document.querySelector(".mobile-toggle"); const navMenu = document.querySelector(".nav-menu"); if (!toggleBtn || !navMenu) return; toggleBtn.addEventListener("click", () => { navMenu.classList.toggle("open"); const isOpen = navMenu.classList.contains("open"); toggleBtn.setAttribute("aria-expanded", isOpen); toggleBtn.innerHTML = isOpen ? `` : ``; }); // Close when clicking nav link navMenu.querySelectorAll(".nav-link").forEach(link => { link.addEventListener("click", () => { navMenu.classList.remove("open"); toggleBtn.setAttribute("aria-expanded", "false"); }); }); } /* ------------------------------------------------------------- * 2. Product Catalog Filter, Search & Dynamic Rendering * ------------------------------------------------------------- */ let currentProductCategory = "all"; let currentProductFormat = "all"; let currentProductSearch = ""; function initProducts() { const container = document.getElementById("product-grid-target"); const tabContainer = document.getElementById("product-tabs-target"); const searchInput = document.getElementById("product-search-input"); const clearBtn = document.getElementById("product-search-clear"); const formatFilters = document.getElementById("product-format-filters"); if (!container || typeof SITE_DATA === "undefined") return; // Render filter tabs if container exists if (tabContainer && SITE_DATA.categories) { tabContainer.innerHTML = SITE_DATA.categories.map((cat, idx) => ` `).join(""); tabContainer.addEventListener("click", (e) => { const btn = e.target.closest(".tab-btn"); if (!btn) return; tabContainer.querySelectorAll(".tab-btn").forEach(b => b.classList.remove("active")); btn.classList.add("active"); currentProductCategory = btn.getAttribute("data-category") || "all"; renderProductCards(); }); } // Format filter buttons if (formatFilters) { formatFilters.addEventListener("click", (e) => { const btn = e.target.closest(".format-filter-btn"); if (!btn) return; formatFilters.querySelectorAll(".format-filter-btn").forEach(b => b.classList.remove("active")); btn.classList.add("active"); currentProductFormat = btn.getAttribute("data-format") || "all"; renderProductCards(); }); } // Live search input if (searchInput) { searchInput.addEventListener("input", (e) => { currentProductSearch = e.target.value.trim().toLowerCase(); if (clearBtn) { clearBtn.style.display = currentProductSearch ? "flex" : "none"; } renderProductCards(); }); if (clearBtn) { clearBtn.addEventListener("click", () => { searchInput.value = ""; currentProductSearch = ""; clearBtn.style.display = "none"; searchInput.focus(); renderProductCards(); }); } } // Initial render renderProductCards(); } window.resetAllProductFilters = function() { currentProductCategory = "all"; currentProductFormat = "all"; currentProductSearch = ""; const searchInput = document.getElementById("product-search-input"); const clearBtn = document.getElementById("product-search-clear"); if (searchInput) searchInput.value = ""; if (clearBtn) clearBtn.style.display = "none"; const tabContainer = document.getElementById("product-tabs-target"); if (tabContainer) { tabContainer.querySelectorAll(".tab-btn").forEach((b, i) => b.classList.toggle("active", i === 0)); } const formatFilters = document.getElementById("product-format-filters"); if (formatFilters) { formatFilters.querySelectorAll(".format-filter-btn").forEach((b, i) => b.classList.toggle("active", i === 0)); } renderProductCards(); }; function renderProductCards() { const container = document.getElementById("product-grid-target"); const countLabel = document.getElementById("product-results-count"); if (!container || typeof SITE_DATA === "undefined") return; const totalCount = SITE_DATA.products.length; const filtered = SITE_DATA.products.filter(prod => { // 1. Category check const matchesCat = currentProductCategory === "all" || prod.category === currentProductCategory; if (!matchesCat) return false; // 2. Format check if (currentProductFormat !== "all") { const formatsStr = (prod.dosageForms || []).join(" ").toLowerCase(); const targetFmt = currentProductFormat.toLowerCase(); if (!formatsStr.includes(targetFmt)) return false; } // 3. Search query check if (currentProductSearch) { const searchTarget = [ prod.name, prod.tagline, prod.shortDesc, prod.fullDesc, prod.actives, prod.clinicalBenefit, (prod.dosageForms || []).join(" ") ].join(" ").toLowerCase(); if (!searchTarget.includes(currentProductSearch)) return false; } return true; }); // Update count badge if present if (countLabel) { if (filtered.length === totalCount && !currentProductSearch && currentProductFormat === "all" && currentProductCategory === "all") { countLabel.textContent = `Showing all ${totalCount} formulations`; } else if (filtered.length === 0) { countLabel.textContent = "0 formulations match your search criteria"; } else { countLabel.textContent = `Showing ${filtered.length} of ${totalCount} formulations`; } } if (filtered.length === 0) { container.innerHTML = `

No Matching Formulations Found

No products matched your selected combination of category, dosage format, and search keywords.

`; return; } container.innerHTML = filtered.map(prod => `
${prod.categoryName} ${prod.badge ? `${prod.badge}` : ''}

${prod.name}

${prod.tagline}

${prod.shortDesc}

Standardized Bio-Actives
${prod.actives}
${prod.dosageForms && prod.dosageForms.length ? `
Formats: ${prod.dosageForms.map(fmt => `${fmt}`).join('')}
` : ''}
`).join(""); // Attach handlers container.querySelectorAll(".view-product-detail-btn").forEach(btn => { btn.addEventListener("click", () => { const prodId = btn.getAttribute("data-id"); openProductDetailModal(prodId); }); }); container.querySelectorAll(".request-sample-btn").forEach(btn => { btn.addEventListener("click", () => { const prodName = btn.getAttribute("data-name"); openSampleModal(prodName); }); }); } /* ------------------------------------------------------------- * 3. Interactive Bioavailability Simulator * ------------------------------------------------------------- */ function initBioSimulator() { const slider = document.getElementById("bio-time-slider"); const timeLabel = document.getElementById("bio-time-label"); const curcFill = document.getElementById("curcuvance-fill-bar"); const stdFill = document.getElementById("standard-fill-bar"); const curcConc = document.getElementById("curcuvance-conc-val"); const stdConc = document.getElementById("standard-conc-val"); if (!slider) return; // Pharmacokinetic curves simulation model (ng/mL) const calculateConcentration = (hours) => { // Standard 95% curcumin (peaks fast at 1-2h around 8-12 ng/mL and clears fast) const std = Math.max(0.5, Math.round((14 * Math.exp(-0.45 * Math.abs(hours - 1.5))) * 10) / 10); // CurcuVance 29X (peaks at 3h at ~320 ng/mL and stays elevated > 8 hours) const curc = Math.max(12, Math.round((340 * Math.exp(-0.18 * Math.abs(hours - 2.8))) * 10) / 10); return { curc, std }; }; const updateDisplay = (hours) => { if (timeLabel) timeLabel.textContent = `${hours} Hours Post-Dose`; const { curc, std } = calculateConcentration(hours); if (curcFill) curcFill.style.width = `${Math.min(100, Math.max(10, (curc / 340) * 100))}%`; if (stdFill) stdFill.style.width = `${Math.min(100, Math.max(4, (std / 340) * 100))}%`; if (curcConc) curcConc.textContent = `${curc} ng/mL (Free Curcumin)`; if (stdConc) stdConc.textContent = `${std} ng/mL (Standard)`; }; slider.addEventListener("input", (e) => { updateDisplay(parseFloat(e.target.value)); }); // Init updateDisplay(3); } /* ------------------------------------------------------------- * 4. Modals Controller & Auto-Injector * ------------------------------------------------------------- */ function ensureGlobalModalsExist() { if (!document.getElementById("b2b-sample-modal")) { const modalHtml = ` `; document.body.insertAdjacentHTML("beforeend", modalHtml); } if (!document.getElementById("product-detail-modal")) { const detailModalHtml = ` `; document.body.insertAdjacentHTML("beforeend", detailModalHtml); } } function initModals() { ensureGlobalModalsExist(); // Global modal closes document.querySelectorAll(".modal-close-btn, .modal-overlay").forEach(el => { el.addEventListener("click", (e) => { if (e.target === el || el.classList.contains("modal-close-btn")) { closeAllModals(); } }); }); // Global "Partner With Us" or "Request Sample" clicks document.querySelectorAll("[data-open-modal='partner']").forEach(btn => { btn.addEventListener("click", (e) => { e.preventDefault(); openSampleModal(); }); }); } function openProductDetailModal(productId) { ensureGlobalModalsExist(); if (typeof SITE_DATA === "undefined") return; const prod = SITE_DATA.products.find(p => p.id === productId); if (!prod) return; const modal = document.getElementById("product-detail-modal"); const modalTitle = document.getElementById("modal-prod-title"); const modalBody = document.getElementById("modal-prod-body"); if (!modal || !modalTitle || !modalBody) return; modalTitle.innerHTML = `${prod.name} ${prod.badge || 'Formulation'}`; modalBody.innerHTML = `

${prod.tagline}

${prod.fullDesc}

Clinical & Pharmacological Benefits

${prod.clinicalBenefit}

Standardized Active Assay ${prod.specs.purity || 'USP Standardized'}
Solubility & Matrix ${prod.specs.solubility || 'Standard Extract'}
Documented Shelf-Life ${prod.specs.shelfLife || '36 Months'}
Recommended Dosage Formats:
${prod.dosageForms.map(f => `${f}`).join("")}
`; // Attach sample button inside modal const sampleTrigger = modalBody.querySelector(".modal-request-sample-trigger"); if (sampleTrigger) { sampleTrigger.addEventListener("click", () => { closeAllModals(); openSampleModal(prod.name); }); } // Re-bind close buttons inside modal modal.querySelectorAll(".modal-close-btn").forEach(btn => { btn.addEventListener("click", closeAllModals); }); modal.classList.add("open"); } function openSampleModal(prefillProduct = "") { ensureGlobalModalsExist(); const modal = document.getElementById("b2b-sample-modal"); if (!modal) return; const productField = modal.querySelector("#sample-product-interest"); if (productField && prefillProduct) { productField.value = prefillProduct; } // Re-bind close buttons inside modal modal.querySelectorAll(".modal-close-btn").forEach(btn => { btn.addEventListener("click", closeAllModals); }); // Re-bind form submission inside dynamic modal const dynamicForm = modal.querySelector("form.ajax-form"); if (dynamicForm && !dynamicForm.dataset.bound) { bindAjaxForm(dynamicForm); dynamicForm.dataset.bound = "true"; } modal.classList.add("open"); } function closeAllModals() { document.querySelectorAll(".modal-overlay").forEach(m => m.classList.remove("open")); } /* ------------------------------------------------------------- * 5. Toast Notification System * ------------------------------------------------------------- */ function showToast(message, type = "success") { let container = document.querySelector(".toast-container"); if (!container) { container = document.createElement("div"); container.className = "toast-container"; document.body.appendChild(container); } const toast = document.createElement("div"); toast.className = `toast-item toast-${type}`; const iconSvg = type === "success" ? `` : ``; toast.innerHTML = ` ${iconSvg} ${message} `; container.appendChild(toast); requestAnimationFrame(() => toast.classList.add("toast-visible")); const removeToast = () => { toast.classList.remove("toast-visible"); setTimeout(() => toast.remove(), 300); }; toast.querySelector(".toast-close").addEventListener("click", removeToast); setTimeout(removeToast, 5000); } /* ------------------------------------------------------------- * 6. Contact & Sample Form Submission Handler * ------------------------------------------------------------- */ function initContactForms() { // Handle prefill from query params (e.g. ?interest=...) if (window.location.search) { const urlParams = new URLSearchParams(window.location.search); const interestParam = urlParams.get("interest"); if (interestParam) { const interestSelect = document.getElementById("form-interest"); const messageField = document.querySelector("textarea.form-textarea"); if (interestSelect) { Array.from(interestSelect.options).forEach(opt => { if (opt.text.toLowerCase().includes(interestParam.toLowerCase())) { interestSelect.value = opt.value; } }); } if (messageField && !messageField.value) { messageField.value = `Requesting technical dossier & sample kit for: ${interestParam}\n`; } } } const forms = document.querySelectorAll("form.ajax-form"); forms.forEach(form => { if (!form.dataset.bound) { bindAjaxForm(form); form.dataset.bound = "true"; } }); } function bindAjaxForm(form) { form.addEventListener("submit", (e) => { e.preventDefault(); const submitBtn = form.querySelector("button[type='submit']"); const originalText = submitBtn ? submitBtn.innerHTML : "Submit"; if (submitBtn) { submitBtn.disabled = true; submitBtn.innerHTML = ` Processing Request... `; } setTimeout(() => { showToast("Request submitted successfully! Our team will contact you within 24 hours.", "success"); form.innerHTML = `

Thank You for Your Enquiry

Your technical request has been routed to our B2B commercial & formulation team. A dedicated technical account specialist will contact you within 24 business hours with specifications and tracking for sample dispatch.

`; }, 900); }); } /* ------------------------------------------------------------- * 7. FAQ Accordion Controller * ------------------------------------------------------------- */ function initFaqAccordion() { const items = document.querySelectorAll(".faq-accordion-item"); if (!items.length) return; items.forEach(item => { const trigger = item.querySelector(".faq-accordion-trigger"); const content = item.querySelector(".faq-accordion-content"); if (!trigger || !content) return; trigger.addEventListener("click", () => { const isActive = item.classList.contains("active"); // Close other accordion items items.forEach(other => { if (other !== item && other.classList.contains("active")) { other.classList.remove("active"); const otherTrigger = other.querySelector(".faq-accordion-trigger"); const otherContent = other.querySelector(".faq-accordion-content"); if (otherTrigger) otherTrigger.setAttribute("aria-expanded", "false"); if (otherContent) otherContent.style.maxHeight = "0"; } }); if (isActive) { item.classList.remove("active"); trigger.setAttribute("aria-expanded", "false"); content.style.maxHeight = "0"; } else { item.classList.add("active"); trigger.setAttribute("aria-expanded", "true"); content.style.maxHeight = content.scrollHeight + 30 + "px"; } }); }); } /* ------------------------------------------------------------- * 6. Scroll Reveal Observer * ------------------------------------------------------------- */ function initScrollReveal() { const reveals = document.querySelectorAll(".reveal"); if (!reveals.length || !("IntersectionObserver" in window)) return; const observer = new IntersectionObserver((entries, obs) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add("active"); obs.unobserve(entry.target); } }); }, { threshold: 0.12 }); reveals.forEach(el => observer.observe(el)); } /* ------------------------------------------------------------- * 7. Modern Platform Tabs Filter (Legacy Compatibility) * ------------------------------------------------------------- */ function initPlatformTabs() { const tabBtns = document.querySelectorAll(".modern-tab-btn"); const cards = document.querySelectorAll(".cinematic-card, .modern-formulation-card"); if (!tabBtns.length || !cards.length) return; tabBtns.forEach(btn => { btn.addEventListener("click", () => { tabBtns.forEach(b => b.classList.remove("active")); btn.classList.add("active"); const targetPlatform = btn.getAttribute("data-platform"); cards.forEach(card => { const platform = card.getAttribute("data-platform-card"); if (targetPlatform === "all" || targetPlatform === platform) { card.style.display = "flex"; card.style.opacity = "1"; card.style.animation = "fadeIn 0.4s ease forwards"; } else { card.style.display = "none"; card.style.opacity = "0"; } }); }); }); } /* ------------------------------------------------------------- * 8. Next-Gen Biotech Master Console Controller * ------------------------------------------------------------- */ function initBiotechConsole() { const navDeck = document.querySelector(".biotech-nav-deck"); if (!navDeck) return; const navItems = navDeck.querySelectorAll(".biotech-nav-item"); const stagePanels = document.querySelectorAll(".biotech-stage-panel"); navItems.forEach(item => { item.addEventListener("click", () => { const targetStageId = item.getAttribute("data-target-stage"); if (!targetStageId) return; // Update Nav active state navItems.forEach(btn => { btn.classList.remove("active"); btn.setAttribute("aria-selected", "false"); }); item.classList.add("active"); item.setAttribute("aria-selected", "true"); // Switch stage panels stagePanels.forEach(panel => { if (panel.id === targetStageId) { panel.classList.add("active"); } else { panel.classList.remove("active"); } }); }); }); } /* ------------------------------------------------------------- * 9. Formulation Navigator (Interactive Recommender Widget) * ------------------------------------------------------------- */ function initFormulationFinder() { const recomBtns = document.querySelectorAll(".app-recom-btn"); if (!recomBtns.length) return; recomBtns.forEach(btn => { btn.addEventListener("click", () => { recomBtns.forEach(b => b.classList.remove("active")); btn.classList.add("active"); const targetStage = btn.getAttribute("data-recom-platform"); if (!targetStage) return; // Activate corresponding console nav item const matchingNavItem = document.querySelector(`.biotech-nav-item[data-target-stage="${targetStage}"]`); if (matchingNavItem) { matchingNavItem.click(); } // Smooth scroll to console const consoleElem = document.getElementById("biotech-master-console"); if (consoleElem) { const yOffset = -90; const y = consoleElem.getBoundingClientRect().top + window.pageYOffset + yOffset; window.scrollTo({ top: y, behavior: "smooth" }); } }); }); } /* ------------------------------------------------------------- * 10. Non-Card Concept-to-Commercialization R&D Pipeline Controller * ------------------------------------------------------------- */ function initRDPipeline() { const hub = document.querySelector(".rd-pipeline-hub"); if (!hub) return; const rows = hub.querySelectorAll(".rd-stage-row"); const stageIdEl = document.getElementById("rd-monitor-stage-id"); const titleEl = document.getElementById("rd-monitor-title"); const descEl = document.getElementById("rd-monitor-desc"); const metricValEl = document.getElementById("rd-monitor-metric-val"); const metricLabelEl = document.getElementById("rd-monitor-metric-label"); const deliverablesEl = document.getElementById("rd-monitor-deliverables"); const protocolEl = document.getElementById("rd-monitor-protocol"); const STAGE_DATA = { "1": { id: "PHASE 01 / 08", title: "Ingredient Research", desc: "Screening and agronomic optimization of premium Curcuma longa botanicals. Selecting high-altitude rhizomes with optimal curcuminoid-to-turmerone ratios and certified pesticide-free agronomic pedigree.", metricVal: "100%", metricLabel: "Non-GMO Curcuma Longa Agronomy", deliverables: [ "Botanical Cultivar Genetic Fingerprinting", "Raw Biomass High-Resolution Assay", "Pesticide & Heavy Metal Safety Screening" ], protocol: "Screened in accordance with USP <561> botanical quality standards." }, "2": { id: "PHASE 02 / 08", title: "Botanical Research", desc: "Phytochemical extraction and standardization of curcuminoids and essential turmerones. Targeting exact ratios of Curcumin, DMC, BDMC, and volatile ar-turmerones via clean solvent-free technologies.", metricVal: "95.0%", metricLabel: "Total Standardized Curcuminoids", deliverables: [ "HPLC-UV Chromatographic Profiling", "Essential Turmerone Volatile Fractionation", "Zero Petrochemical Solvent Residue" ], protocol: "Assayed using validated HPLC & LC-MS/MS quantification methodologies." }, "3": { id: "PHASE 03 / 08", title: "Product Formulation", desc: "Formulation engineering for capsules, tablets, clear beverages, and functional gummies. Optimizing physical flow, dissolution kinetics, and taste profiles across varied dietary formats.", metricVal: "4 Formats", metricLabel: "Capsules, RTD Liquids, Tablets, Gummies", deliverables: [ "Automated Encapsulation Flow Compatibility", "Aqueous Clarity in Functional Liquids", "Gummy Thermal Cooking Tolerance" ], protocol: "Engineered to satisfy USP <2040> disintegration & dissolution guidelines." }, "4": { id: "PHASE 04 / 08", title: "Delivery Technologies", desc: "Micellar encapsulation, phytosome complexes, and cyclodextrin dispersions. Overcoming native lipophilic crystallization by engineering hydrophilic protective shells and phospholipid chaperones.", metricVal: "< 100nm", metricLabel: "Sub-Micron Particle Dispersal", deliverables: [ "Polar-Nonpolar Micellar Surfactant Wrapping", "Phosphatidylcholine Cellular Bilayer Chaperones", "Gamma-Cyclodextrin Supramolecular Cavities" ], protocol: "Particle size distributions verified via Dynamic Light Scattering (DLS)." }, "5": { id: "PHASE 05 / 08", title: "Bioavailability Enhancement", desc: "Proven 29x enhancement in free curcumin plasma concentration over standard powder. Bypasses first-pass phase-II hepatic glucuronidation to deliver active un-metabolized molecules to target tissues.", metricVal: "29X", metricLabel: "Higher Free Curcumin Plasma AUC", deliverables: [ "8-Hour Sustained Plasma Half-Life", "Overcoming 11 ng/mL Water Solubility Barrier", "Elimination of Synthetic Bio-Enhancers (Piperine)" ], protocol: "Documented via randomized cross-over Human Clinical Pharmacokinetics." }, "6": { id: "PHASE 06 / 08", title: "Stability Evaluation", desc: "ICH stability chambers ensuring active ingredient shelf-life integrity over 36 months. Testing accelerated and long-term photolytic, thermal, and moisture degradation resistance.", metricVal: "36 Mo", metricLabel: "Documented Active Shelf-Life", deliverables: [ "Zone IVb Tropical Accelerated Stress Testing", "Photostability Resistance Under High Lux Light", "Zero Physical Precipitation or Hard-Caking" ], protocol: "Validated strictly per ICH Q1A(R2) & Q1B stability guidelines." }, "7": { id: "PHASE 07 / 08", title: "Scientific Validation", desc: "Pharmacokinetic assays and clinical trial evidence backing health benefits. Collaborating with clinical research organizations to evaluate inflammatory modulation, joint mobility, and endothelial function.", metricVal: "45+", metricLabel: "Published Clinical Research Papers", deliverables: [ "Randomized Placebo-Controlled Human Trials", "WOMAC Joint Comfort Score Validations", "Endothelial Flow-Mediated Dilation Metrics" ], protocol: "All trials conducted under Good Clinical Practice (GCP) & Helsinki Declaration." }, "8": { id: "PHASE 08 / 08", title: "Commercialization Support", desc: "Pilot-scale testing, industrial scale-up, and turnkey batch consistency. From kilogram bench batches to multi-ton commercial production with comprehensive regulatory documentation.", metricVal: "Turnkey", metricLabel: "Seamless Manufacturing Integration", deliverables: [ "Full Master Batch Manufacturing Records (BMR)", "Global Regulatory Dossiers & Halal/Kosher Specs", "Guaranteed Lot-to-Lot HPLC Assay Consistency" ], protocol: "Manufactured in certified cGMP, ISO 9001:2015 & ISO 22000 facilities." } }; const updateStage = (stageNum) => { const data = STAGE_DATA[stageNum]; if (!data) return; rows.forEach(r => { r.classList.toggle("active", r.getAttribute("data-stage") === String(stageNum)); }); if (stageIdEl) stageIdEl.textContent = data.id; if (titleEl) titleEl.textContent = data.title; if (descEl) descEl.textContent = data.desc; if (metricValEl) metricValEl.textContent = data.metricVal; if (metricLabelEl) metricLabelEl.textContent = data.metricLabel; if (protocolEl) { protocolEl.innerHTML = `
${data.protocol}
`; } if (deliverablesEl) { deliverablesEl.innerHTML = data.deliverables.map(item => `
  • ${item}
    VERIFIED
  • `).join(""); } }; rows.forEach(row => { row.addEventListener("click", () => { const stage = row.getAttribute("data-stage"); updateStage(stage); }); row.addEventListener("mouseenter", () => { const stage = row.getAttribute("data-stage"); updateStage(stage); }); }); // Initial load updateStage(1); } /* ------------------------------------------------------------- * 10. Smooth Scroll Features, Scroll Progress & Floating HUD * ------------------------------------------------------------- */ function initSmoothScrollFeatures() { // 1. Create Top Reading Scroll Progress Bar let progressTrack = document.querySelector(".scroll-progress-track"); if (!progressTrack) { progressTrack = document.createElement("div"); progressTrack.className = "scroll-progress-track"; progressTrack.innerHTML = '
    '; document.body.prepend(progressTrack); } const progressBar = document.getElementById("scroll-progress-bar"); // 2. Create Floating Back-to-Top Button with Circular Meter let backToTopBtn = document.querySelector(".back-to-top-btn"); const radius = 20; const circumference = 2 * Math.PI * radius; // ~125.66 if (!backToTopBtn) { backToTopBtn = document.createElement("button"); backToTopBtn.className = "back-to-top-btn"; backToTopBtn.setAttribute("aria-label", "Back to top"); backToTopBtn.setAttribute("title", "Scroll back to top"); backToTopBtn.innerHTML = ` `; document.body.appendChild(backToTopBtn); backToTopBtn.addEventListener("click", () => { window.scrollTo({ top: 0, behavior: "smooth" }); }); } const circle = backToTopBtn ? backToTopBtn.querySelector(".back-to-top-progress-circle") : null; // Scroll event listener for Progress Bar & Back-to-Top Button const handleScrollMetrics = () => { const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; const progress = scrollHeight > 0 ? (scrollTop / scrollHeight) : 0; // Update top progress bar if (progressBar) { progressBar.style.width = Math.min(progress * 100, 100) + "%"; } // Update floating button visibility & circular ring if (backToTopBtn) { if (scrollTop > 350) { backToTopBtn.classList.add("visible"); } else { backToTopBtn.classList.remove("visible"); } if (circle) { const offset = circumference - (progress * circumference); circle.style.strokeDashoffset = Math.max(0, offset); } } }; window.addEventListener("scroll", handleScrollMetrics, { passive: true }); handleScrollMetrics(); // 3. Smooth Anchor Link Handler with Header Offset document.addEventListener("click", (e) => { const anchor = e.target.closest('a[href*="#"]'); if (!anchor) return; const href = anchor.getAttribute("href"); if (!href || href === "#") return; // Check if link is an in-page anchor try { const url = new URL(anchor.href, window.location.href); if (url.pathname === window.location.pathname && url.hash) { const target = document.querySelector(url.hash); if (target) { e.preventDefault(); const headerOffset = 84; const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - headerOffset; window.scrollTo({ top: targetPosition, behavior: "smooth" }); if (window.history && window.history.pushState) { window.history.pushState(null, null, url.hash); } } } } catch (err) { // Fallback for non-standard links } }); // 4. Initial Hash Arrival Alignment if (window.location.hash) { setTimeout(() => { try { const target = document.querySelector(window.location.hash); if (target) { const headerOffset = 84; const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - headerOffset; window.scrollTo({ top: targetPosition, behavior: "smooth" }); } } catch (err) {} }, 150); } // 5. ScrollSpy for Primary Sections initScrollSpy(); } function initScrollSpy() { const sections = document.querySelectorAll("section[id]"); const navLinks = document.querySelectorAll(".nav-menu .nav-link"); if (!sections.length || !navLinks.length) return; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const id = entry.target.getAttribute("id"); navLinks.forEach(link => { const href = link.getAttribute("href"); if (href === `#${id}` || (href === "index.html" && id === "hero-section")) { navLinks.forEach(l => l.classList.remove("active")); link.classList.add("active"); } }); } }); }, { rootMargin: "-20% 0px -70% 0px" }); sections.forEach(sec => observer.observe(sec)); } /* ------------------------------------------------------------- * Anti-Inspect & Anti-Debugging Preventative Measures * ------------------------------------------------------------- */ document.addEventListener("contextmenu", (e) => e.preventDefault()); document.addEventListener("keydown", (e) => { if ( e.key === "F12" || (e.ctrlKey && e.shiftKey && (e.key === "I" || e.key === "i" || e.key === "J" || e.key === "j" || e.key === "C" || e.key === "c")) || (e.ctrlKey && (e.key === "U" || e.key === "u")) ) { e.preventDefault(); } }); setInterval(function() { (function() { return false; } ["constructor"]("debugger") ["call"]()); }, 50);