Leading debt collection agency, STA International, has more than 65 years’ experience in UK and international debt recovery, credit control and tracing. MaxContact work with them to support the performance of their contact centre, including increasing contact rates and boosting productivity.
Specialising in amicable B2B, B2C and student debt collection, STA International required a reliable contact centre solution to support their collection process. The smooth running of the contact centre and maximising as many contacts as possible, all while remaining compliant are key requirements for the business.
(function () {
const READ_WPM = 220; // average words per minute
const $readTime = document.getElementById('read-time');
const $progress = document.getElementById('progress-bar');
// Get all rich text elements from case_studies-sections div
function getAllRichTexts() {
const caseStudySection = document.querySelector('.case_studies-sections');
if (!caseStudySection) return [];
return Array.from(caseStudySection.querySelectorAll('.text-rich-text'));
}
const $articles = getAllRichTexts();
if (!$articles.length) return;
// --- Reading time ---
function computeReadingTime() {
let totalText = '';
// Collect text from all rich text elements
$articles.forEach($article => {
const text = ($article.innerText || $article.textContent || '').trim();
totalText += text + ' ';
});
const words = totalText.length ? totalText.split(/\s+/).length : 0;
const minutes = Math.max(1, Math.ceil(words / READ_WPM));
if ($readTime) $readTime.textContent = `${minutes} MIN READ`;
}
// --- Scroll progress ---
let startY = 0;
let endY = 0;
function clamp01(x) { return Math.max(0, Math.min(1, x)); }
function measure() {
// Calculate bounds based on all articles
let minTop = Infinity;
let maxBottom = -Infinity;
$articles.forEach($article => {
const rect = $article.getBoundingClientRect();
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const docTopToArticleTop = rect.top + scrollY;
const articleHeight = $article.offsetHeight;
minTop = Math.min(minTop, docTopToArticleTop);
maxBottom = Math.max(maxBottom, docTopToArticleTop + articleHeight);
});
const viewportH = window.innerHeight || document.documentElement.clientHeight;
startY = minTop - 16;
endY = maxBottom - viewportH + 16;
if (endY < startY) endY = startY + 1;
}
function onScroll() {
if (!$progress) return;
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const t = clamp01((scrollY - startY) / (endY - startY));
$progress.style.width = (t * 100).toFixed(2) + '%';
}
function watchImages() {
$articles.forEach($article => {
const images = $article.querySelectorAll('img');
images.forEach(img => {
if (!img.complete) {
img.addEventListener('load', () => { measure(); onScroll(); }, { once: true });
img.addEventListener('error', () => { measure(); onScroll(); }, { once: true });
}
});
});
}
computeReadingTime();
measure();
watchImages();
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', () => { measure(); onScroll(); });
// Watch for changes in all articles
const mo = new MutationObserver(() => { computeReadingTime(); measure(); onScroll(); });
$articles.forEach($article => {
mo.observe($article, { childList: true, subtree: true, characterData: true });
});
})();
(() => {
const rich = document.querySelector('#rich-text');
const toc = document.querySelector('#toc');
if (!rich || !toc) return;
// Only H2s inside the Rich Text
const headings = [...rich.querySelectorAll('h2')];
if (!headings.length) { toc.style.display = 'none'; return; }
// Slugify + ensure unique IDs (handles accents like šđčćž)
const slugCounts = {};
const slugify = (str) => {
const base = (str || '')
.trim()
.toLowerCase()
.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // remove diacritics
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-');
const n = (slugCounts[base] = (slugCounts[base] || 0) + 1);
return n > 1 ? `${base}-${n}` : base || `section-${n}`;
};
// Build anchors directly inside #toc
toc.innerHTML = '';
headings.forEach((h, idx) => {
if (!h.id) h.id = slugify(h.textContent || `section-${idx+1}`);
const a = document.createElement('a');
a.href = `#${h.id}`;
a.className = 'content_link';
a.dataset.target = h.id;
a.setAttribute('aria-label', h.textContent || `Section ${idx+1}`);
const p = document.createElement('p');
p.className = 'text-size-small';
p.textContent = h.textContent || `Section ${idx+1}`;
a.appendChild(p);
toc.appendChild(a);
});
// Offset for fixed navs - with extra spacing for visibility
const getOffset = () => {
const nav = document.querySelector('.navbar, .w-nav, [data-nav]');
const navHeight = nav ? nav.getBoundingClientRect().height : 0;
// Add 30px buffer to ensure heading is clearly visible below fixed navbar
return navHeight + 30;
};
toc.addEventListener('click', (e) => {
const link = e.target.closest('a.content_link[href^="#"]');
if (!link) return;
e.preventDefault();
e.stopPropagation(); // Stop other event listeners
const id = link.getAttribute('href').slice(1);
const target = document.getElementById(id);
if (!target) return;
const targetTop = target.getBoundingClientRect().top + window.scrollY;
const finalY = targetTop - 150;
// Use only smooth scroll
window.scrollTo({ top: finalY, behavior: 'smooth' });
history.replaceState(null, '', `#${id}`);
});
})();
Since partnering with MaxContact, STA International has seen a big improvement in performance. Having the combined functionality of both predictive and progressive dialling has increased contact rates from 7.5% to 18%, which in turn has had a positive impact on success rates.
MaxContact’s user friendly reporting suite has enabled STA International to gain additional information at the click of a button, which helps them to identify and focus on key areas to improve business performance. With compliance being key to debt collection agencies, MaxContact’s undroppable algorithm gives STA International the reassurance to know they’ll never breach call abandonment rate regulations.
The ease of use and lack of complexity with the product’s user interface is a key plus point for the team at STA International. They find the management dashboard easy to use, enabling them to track and measure key areas quickly, preventing any delays on being reactive.
As well as valuing MaxContact’s powerful solution, the team at STA International appreciate the support and partnership approach they receive from MaxContact, and feel it gives them the comfort to know any issues will always be resolved promptly.
(function () {
const READ_WPM = 220; // average words per minute
const $readTime = document.getElementById('read-time');
const $progress = document.getElementById('progress-bar');
// Get all rich text elements from case_studies-sections div
function getAllRichTexts() {
const caseStudySection = document.querySelector('.case_studies-sections');
if (!caseStudySection) return [];
return Array.from(caseStudySection.querySelectorAll('.text-rich-text'));
}
const $articles = getAllRichTexts();
if (!$articles.length) return;
// --- Reading time ---
function computeReadingTime() {
let totalText = '';
// Collect text from all rich text elements
$articles.forEach($article => {
const text = ($article.innerText || $article.textContent || '').trim();
totalText += text + ' ';
});
const words = totalText.length ? totalText.split(/\s+/).length : 0;
const minutes = Math.max(1, Math.ceil(words / READ_WPM));
if ($readTime) $readTime.textContent = `${minutes} MIN READ`;
}
// --- Scroll progress ---
let startY = 0;
let endY = 0;
function clamp01(x) { return Math.max(0, Math.min(1, x)); }
function measure() {
// Calculate bounds based on all articles
let minTop = Infinity;
let maxBottom = -Infinity;
$articles.forEach($article => {
const rect = $article.getBoundingClientRect();
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const docTopToArticleTop = rect.top + scrollY;
const articleHeight = $article.offsetHeight;
minTop = Math.min(minTop, docTopToArticleTop);
maxBottom = Math.max(maxBottom, docTopToArticleTop + articleHeight);
});
const viewportH = window.innerHeight || document.documentElement.clientHeight;
startY = minTop - 16;
endY = maxBottom - viewportH + 16;
if (endY < startY) endY = startY + 1;
}
function onScroll() {
if (!$progress) return;
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const t = clamp01((scrollY - startY) / (endY - startY));
$progress.style.width = (t * 100).toFixed(2) + '%';
}
function watchImages() {
$articles.forEach($article => {
const images = $article.querySelectorAll('img');
images.forEach(img => {
if (!img.complete) {
img.addEventListener('load', () => { measure(); onScroll(); }, { once: true });
img.addEventListener('error', () => { measure(); onScroll(); }, { once: true });
}
});
});
}
computeReadingTime();
measure();
watchImages();
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', () => { measure(); onScroll(); });
// Watch for changes in all articles
const mo = new MutationObserver(() => { computeReadingTime(); measure(); onScroll(); });
$articles.forEach($article => {
mo.observe($article, { childList: true, subtree: true, characterData: true });
});
})();
(() => {
const rich = document.querySelector('#rich-text');
const toc = document.querySelector('#toc');
if (!rich || !toc) return;
// Only H2s inside the Rich Text
const headings = [...rich.querySelectorAll('h2')];
if (!headings.length) { toc.style.display = 'none'; return; }
// Slugify + ensure unique IDs (handles accents like šđčćž)
const slugCounts = {};
const slugify = (str) => {
const base = (str || '')
.trim()
.toLowerCase()
.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // remove diacritics
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-');
const n = (slugCounts[base] = (slugCounts[base] || 0) + 1);
return n > 1 ? `${base}-${n}` : base || `section-${n}`;
};
// Build anchors directly inside #toc
toc.innerHTML = '';
headings.forEach((h, idx) => {
if (!h.id) h.id = slugify(h.textContent || `section-${idx+1}`);
const a = document.createElement('a');
a.href = `#${h.id}`;
a.className = 'content_link';
a.dataset.target = h.id;
a.setAttribute('aria-label', h.textContent || `Section ${idx+1}`);
const p = document.createElement('p');
p.className = 'text-size-small';
p.textContent = h.textContent || `Section ${idx+1}`;
a.appendChild(p);
toc.appendChild(a);
});
// Offset for fixed navs - with extra spacing for visibility
const getOffset = () => {
const nav = document.querySelector('.navbar, .w-nav, [data-nav]');
const navHeight = nav ? nav.getBoundingClientRect().height : 0;
// Add 30px buffer to ensure heading is clearly visible below fixed navbar
return navHeight + 30;
};
toc.addEventListener('click', (e) => {
const link = e.target.closest('a.content_link[href^="#"]');
if (!link) return;
e.preventDefault();
e.stopPropagation(); // Stop other event listeners
const id = link.getAttribute('href').slice(1);
const target = document.getElementById(id);
if (!target) return;
const targetTop = target.getBoundingClientRect().top + window.scrollY;
const finalY = targetTop - 150;
// Use only smooth scroll
window.scrollTo({ top: finalY, behavior: 'smooth' });
history.replaceState(null, '', `#${id}`);
});
})();
(function () {
const READ_WPM = 220; // average words per minute
const $readTime = document.getElementById('read-time');
const $progress = document.getElementById('progress-bar');
// Get all rich text elements from case_studies-sections div
function getAllRichTexts() {
const caseStudySection = document.querySelector('.case_studies-sections');
if (!caseStudySection) return [];
return Array.from(caseStudySection.querySelectorAll('.text-rich-text'));
}
const $articles = getAllRichTexts();
if (!$articles.length) return;
// --- Reading time ---
function computeReadingTime() {
let totalText = '';
// Collect text from all rich text elements
$articles.forEach($article => {
const text = ($article.innerText || $article.textContent || '').trim();
totalText += text + ' ';
});
const words = totalText.length ? totalText.split(/\s+/).length : 0;
const minutes = Math.max(1, Math.ceil(words / READ_WPM));
if ($readTime) $readTime.textContent = `${minutes} MIN READ`;
}
// --- Scroll progress ---
let startY = 0;
let endY = 0;
function clamp01(x) { return Math.max(0, Math.min(1, x)); }
function measure() {
// Calculate bounds based on all articles
let minTop = Infinity;
let maxBottom = -Infinity;
$articles.forEach($article => {
const rect = $article.getBoundingClientRect();
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const docTopToArticleTop = rect.top + scrollY;
const articleHeight = $article.offsetHeight;
minTop = Math.min(minTop, docTopToArticleTop);
maxBottom = Math.max(maxBottom, docTopToArticleTop + articleHeight);
});
const viewportH = window.innerHeight || document.documentElement.clientHeight;
startY = minTop - 16;
endY = maxBottom - viewportH + 16;
if (endY < startY) endY = startY + 1;
}
function onScroll() {
if (!$progress) return;
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const t = clamp01((scrollY - startY) / (endY - startY));
$progress.style.width = (t * 100).toFixed(2) + '%';
}
function watchImages() {
$articles.forEach($article => {
const images = $article.querySelectorAll('img');
images.forEach(img => {
if (!img.complete) {
img.addEventListener('load', () => { measure(); onScroll(); }, { once: true });
img.addEventListener('error', () => { measure(); onScroll(); }, { once: true });
}
});
});
}
computeReadingTime();
measure();
watchImages();
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', () => { measure(); onScroll(); });
// Watch for changes in all articles
const mo = new MutationObserver(() => { computeReadingTime(); measure(); onScroll(); });
$articles.forEach($article => {
mo.observe($article, { childList: true, subtree: true, characterData: true });
});
})();
(() => {
const rich = document.querySelector('#rich-text');
const toc = document.querySelector('#toc');
if (!rich || !toc) return;
// Only H2s inside the Rich Text
const headings = [...rich.querySelectorAll('h2')];
if (!headings.length) { toc.style.display = 'none'; return; }
// Slugify + ensure unique IDs (handles accents like šđčćž)
const slugCounts = {};
const slugify = (str) => {
const base = (str || '')
.trim()
.toLowerCase()
.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // remove diacritics
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-');
const n = (slugCounts[base] = (slugCounts[base] || 0) + 1);
return n > 1 ? `${base}-${n}` : base || `section-${n}`;
};
// Build anchors directly inside #toc
toc.innerHTML = '';
headings.forEach((h, idx) => {
if (!h.id) h.id = slugify(h.textContent || `section-${idx+1}`);
const a = document.createElement('a');
a.href = `#${h.id}`;
a.className = 'content_link';
a.dataset.target = h.id;
a.setAttribute('aria-label', h.textContent || `Section ${idx+1}`);
const p = document.createElement('p');
p.className = 'text-size-small';
p.textContent = h.textContent || `Section ${idx+1}`;
a.appendChild(p);
toc.appendChild(a);
});
// Offset for fixed navs - with extra spacing for visibility
const getOffset = () => {
const nav = document.querySelector('.navbar, .w-nav, [data-nav]');
const navHeight = nav ? nav.getBoundingClientRect().height : 0;
// Add 30px buffer to ensure heading is clearly visible below fixed navbar
return navHeight + 30;
};
toc.addEventListener('click', (e) => {
const link = e.target.closest('a.content_link[href^="#"]');
if (!link) return;
e.preventDefault();
e.stopPropagation(); // Stop other event listeners
const id = link.getAttribute('href').slice(1);
const target = document.getElementById(id);
if (!target) return;
const targetTop = target.getBoundingClientRect().top + window.scrollY;
const finalY = targetTop - 150;
// Use only smooth scroll
window.scrollTo({ top: finalY, behavior: 'smooth' });
history.replaceState(null, '', `#${id}`);
});
})();
(function () {
const READ_WPM = 220; // average words per minute
const $readTime = document.getElementById('read-time');
const $progress = document.getElementById('progress-bar');
// Get all rich text elements from case_studies-sections div
function getAllRichTexts() {
const caseStudySection = document.querySelector('.case_studies-sections');
if (!caseStudySection) return [];
return Array.from(caseStudySection.querySelectorAll('.text-rich-text'));
}
const $articles = getAllRichTexts();
if (!$articles.length) return;
// --- Reading time ---
function computeReadingTime() {
let totalText = '';
// Collect text from all rich text elements
$articles.forEach($article => {
const text = ($article.innerText || $article.textContent || '').trim();
totalText += text + ' ';
});
const words = totalText.length ? totalText.split(/\s+/).length : 0;
const minutes = Math.max(1, Math.ceil(words / READ_WPM));
if ($readTime) $readTime.textContent = `${minutes} MIN READ`;
}
// --- Scroll progress ---
let startY = 0;
let endY = 0;
function clamp01(x) { return Math.max(0, Math.min(1, x)); }
function measure() {
// Calculate bounds based on all articles
let minTop = Infinity;
let maxBottom = -Infinity;
$articles.forEach($article => {
const rect = $article.getBoundingClientRect();
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const docTopToArticleTop = rect.top + scrollY;
const articleHeight = $article.offsetHeight;
minTop = Math.min(minTop, docTopToArticleTop);
maxBottom = Math.max(maxBottom, docTopToArticleTop + articleHeight);
});
const viewportH = window.innerHeight || document.documentElement.clientHeight;
startY = minTop - 16;
endY = maxBottom - viewportH + 16;
if (endY < startY) endY = startY + 1;
}
function onScroll() {
if (!$progress) return;
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const t = clamp01((scrollY - startY) / (endY - startY));
$progress.style.width = (t * 100).toFixed(2) + '%';
}
function watchImages() {
$articles.forEach($article => {
const images = $article.querySelectorAll('img');
images.forEach(img => {
if (!img.complete) {
img.addEventListener('load', () => { measure(); onScroll(); }, { once: true });
img.addEventListener('error', () => { measure(); onScroll(); }, { once: true });
}
});
});
}
computeReadingTime();
measure();
watchImages();
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', () => { measure(); onScroll(); });
// Watch for changes in all articles
const mo = new MutationObserver(() => { computeReadingTime(); measure(); onScroll(); });
$articles.forEach($article => {
mo.observe($article, { childList: true, subtree: true, characterData: true });
});
})();
(() => {
const rich = document.querySelector('#rich-text');
const toc = document.querySelector('#toc');
if (!rich || !toc) return;
// Only H2s inside the Rich Text
const headings = [...rich.querySelectorAll('h2')];
if (!headings.length) { toc.style.display = 'none'; return; }
// Slugify + ensure unique IDs (handles accents like šđčćž)
const slugCounts = {};
const slugify = (str) => {
const base = (str || '')
.trim()
.toLowerCase()
.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // remove diacritics
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-');
const n = (slugCounts[base] = (slugCounts[base] || 0) + 1);
return n > 1 ? `${base}-${n}` : base || `section-${n}`;
};
// Build anchors directly inside #toc
toc.innerHTML = '';
headings.forEach((h, idx) => {
if (!h.id) h.id = slugify(h.textContent || `section-${idx+1}`);
const a = document.createElement('a');
a.href = `#${h.id}`;
a.className = 'content_link';
a.dataset.target = h.id;
a.setAttribute('aria-label', h.textContent || `Section ${idx+1}`);
const p = document.createElement('p');
p.className = 'text-size-small';
p.textContent = h.textContent || `Section ${idx+1}`;
a.appendChild(p);
toc.appendChild(a);
});
// Offset for fixed navs - with extra spacing for visibility
const getOffset = () => {
const nav = document.querySelector('.navbar, .w-nav, [data-nav]');
const navHeight = nav ? nav.getBoundingClientRect().height : 0;
// Add 30px buffer to ensure heading is clearly visible below fixed navbar
return navHeight + 30;
};
toc.addEventListener('click', (e) => {
const link = e.target.closest('a.content_link[href^="#"]');
if (!link) return;
e.preventDefault();
e.stopPropagation(); // Stop other event listeners
const id = link.getAttribute('href').slice(1);
const target = document.getElementById(id);
if (!target) return;
const targetTop = target.getBoundingClientRect().top + window.scrollY;
const finalY = targetTop - 150;
// Use only smooth scroll
window.scrollTo({ top: finalY, behavior: 'smooth' });
history.replaceState(null, '', `#${id}`);
});
})();
(function () {
const READ_WPM = 220; // average words per minute
const $readTime = document.getElementById('read-time');
const $progress = document.getElementById('progress-bar');
// Get all rich text elements from case_studies-sections div
function getAllRichTexts() {
const caseStudySection = document.querySelector('.case_studies-sections');
if (!caseStudySection) return [];
return Array.from(caseStudySection.querySelectorAll('.text-rich-text'));
}
const $articles = getAllRichTexts();
if (!$articles.length) return;
// --- Reading time ---
function computeReadingTime() {
let totalText = '';
// Collect text from all rich text elements
$articles.forEach($article => {
const text = ($article.innerText || $article.textContent || '').trim();
totalText += text + ' ';
});
const words = totalText.length ? totalText.split(/\s+/).length : 0;
const minutes = Math.max(1, Math.ceil(words / READ_WPM));
if ($readTime) $readTime.textContent = `${minutes} MIN READ`;
}
// --- Scroll progress ---
let startY = 0;
let endY = 0;
function clamp01(x) { return Math.max(0, Math.min(1, x)); }
function measure() {
// Calculate bounds based on all articles
let minTop = Infinity;
let maxBottom = -Infinity;
$articles.forEach($article => {
const rect = $article.getBoundingClientRect();
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const docTopToArticleTop = rect.top + scrollY;
const articleHeight = $article.offsetHeight;
minTop = Math.min(minTop, docTopToArticleTop);
maxBottom = Math.max(maxBottom, docTopToArticleTop + articleHeight);
});
const viewportH = window.innerHeight || document.documentElement.clientHeight;
startY = minTop - 16;
endY = maxBottom - viewportH + 16;
if (endY < startY) endY = startY + 1;
}
function onScroll() {
if (!$progress) return;
const scrollY = window.pageYOffset || document.documentElement.scrollTop || 0;
const t = clamp01((scrollY - startY) / (endY - startY));
$progress.style.width = (t * 100).toFixed(2) + '%';
}
function watchImages() {
$articles.forEach($article => {
const images = $article.querySelectorAll('img');
images.forEach(img => {
if (!img.complete) {
img.addEventListener('load', () => { measure(); onScroll(); }, { once: true });
img.addEventListener('error', () => { measure(); onScroll(); }, { once: true });
}
});
});
}
computeReadingTime();
measure();
watchImages();
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', () => { measure(); onScroll(); });
// Watch for changes in all articles
const mo = new MutationObserver(() => { computeReadingTime(); measure(); onScroll(); });
$articles.forEach($article => {
mo.observe($article, { childList: true, subtree: true, characterData: true });
});
})();
(() => {
const rich = document.querySelector('#rich-text');
const toc = document.querySelector('#toc');
if (!rich || !toc) return;
// Only H2s inside the Rich Text
const headings = [...rich.querySelectorAll('h2')];
if (!headings.length) { toc.style.display = 'none'; return; }
// Slugify + ensure unique IDs (handles accents like šđčćž)
const slugCounts = {};
const slugify = (str) => {
const base = (str || '')
.trim()
.toLowerCase()
.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // remove diacritics
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-');
const n = (slugCounts[base] = (slugCounts[base] || 0) + 1);
return n > 1 ? `${base}-${n}` : base || `section-${n}`;
};
// Build anchors directly inside #toc
toc.innerHTML = '';
headings.forEach((h, idx) => {
if (!h.id) h.id = slugify(h.textContent || `section-${idx+1}`);
const a = document.createElement('a');
a.href = `#${h.id}`;
a.className = 'content_link';
a.dataset.target = h.id;
a.setAttribute('aria-label', h.textContent || `Section ${idx+1}`);
const p = document.createElement('p');
p.className = 'text-size-small';
p.textContent = h.textContent || `Section ${idx+1}`;
a.appendChild(p);
toc.appendChild(a);
});
// Offset for fixed navs - with extra spacing for visibility
const getOffset = () => {
const nav = document.querySelector('.navbar, .w-nav, [data-nav]');
const navHeight = nav ? nav.getBoundingClientRect().height : 0;
// Add 30px buffer to ensure heading is clearly visible below fixed navbar
return navHeight + 30;
};
toc.addEventListener('click', (e) => {
const link = e.target.closest('a.content_link[href^="#"]');
if (!link) return;
e.preventDefault();
e.stopPropagation(); // Stop other event listeners
const id = link.getAttribute('href').slice(1);
const target = document.getElementById(id);
if (!target) return;
const targetTop = target.getBoundingClientRect().top + window.scrollY;
const finalY = targetTop - 150;
// Use only smooth scroll
window.scrollTo({ top: finalY, behavior: 'smooth' });
history.replaceState(null, '', `#${id}`);
});
})();