/* ===== ProSkale Success Stories (scoped init, supports multiple blocks) ===== */ (function(){ // Shared data (edit these to your real case studies) const STORIES = [ { id:'fintech', title:'FinTech Platform Modernization', icon:'💰', color:'#0ea5e9', industry:'FinTech', img:'https://orpical.com/wp-content/uploads/2023/07/digital-transformation-in-banking.png', gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(14,165,233,.20), transparent 60%), linear-gradient(135deg, rgba(14,165,233,.12), rgba(99,102,241,.12))', lead:'Legacy monolith with poor UX, slow deployments, and scalability bottlenecks.', solution:[ 'Split monolith to microservices with API gateway', 'React/Next.js front-end with design tokens', 'CI/CD with canary releases and automated QA', 'Observability via OpenTelemetry + Grafana' ], results:['70% faster loads','3× engagement','99.99% uptime','Zero-downtime releases'], stats:{a:'70%',aText:'faster page loads',b:'3×',bText:'increase in engagement'} }, { id:'commerce', title:'E-Commerce PWA Development', icon:'🛍️', color:'#f97316', industry:'E-Commerce', img:'https://img.freepik.com/premium-photo/ecommerce-business-concept_204719-89016.jpg?w=740&q=80', gradient:'radial-gradient(1200px 400px at 0% -10%, rgba(249,115,22,.18), transparent 60%), linear-gradient(135deg, rgba(251,146,60,.12), rgba(236,72,153,.12))', lead:'Mobile-first, offline-capable shopping with lightning performance.', solution:[ 'PWA with Vue 3 + Nuxt, edge caching', 'Headless cart & checkout', 'Image/CDN optimization and code splitting', 'A/B testing pipeline for features' ], results:['+40% mobile conversions','60% faster pages','Offline experience','SEO boost (SSR)'], stats:{a:'+40%',aText:'mobile conversion lift',b:'60%',bText:'faster LCP'} }, { id:'health', title:'Healthcare SaaS Collaboration', icon:'🏥', color:'#10b981', industry:'Healthcare', img:'https://kms-healthcare.com/wp-content/uploads/2023/09/agile-software-development-in-healthcare-2-1024x575.png', gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(16,185,129,.18), transparent 60%), linear-gradient(135deg, rgba(16,185,129,.12), rgba(59,130,246,.12))', lead:'HIPAA-compliant, real-time collaboration app with strict latency targets.', solution:[ 'React + TypeScript + WebRTC for video', 'FastAPI microservices on Azure AKS', 'End-to-end encryption & audit trails', 'Autoscaling with HPA & queues' ], results:['HIPAA compliant','50ms avg latency','10k+ concurrent users','Secure audit logs'], stats:{a:'50ms',aText:'average latency',b:'10k+',bText:'concurrent users'} } ]; // Initialize each block on the page document.querySelectorAll('.ps-stories').forEach((root) => { const $ = (s, el=root) => el.querySelector(s); const $$ = (s, el=root) => Array.from(el.querySelectorAll(s)); const INDUSTRIES = ['All', ...Array.from(new Set(STORIES.map(s=>s.industry)))]; const storyFilters = $('#storyFilters'); const rail = $('#storiesRail'); const dotsWrap = $('#storiesDots'); const btnPrev = $('#storiesPrev'); const btnNext = $('#storiesNext'); const sModal = $('#storyModal'); const sClose = $('#storyClose'); const sIcon = $('#storyIcon'); const sTitle = $('#storyTitle'); const sIndustry = $('#storyIndustry'); const sLead = $('#storyLead'); const sSol = $('#storySolution'); const sRes = $('#storyResults'); const sStatA = $('#storyStatA'); const sStatAT= $('#storyStatAText'); const sStatB = $('#storyStatB'); const sStatBT= $('#storyStatBText'); const sDots = $('#storyDots'); const sPrev = $('#storyPrev'); const sNext = $('#storyNext'); let activeFilter='All', visible=STORIES.slice(), activeIndex=0, modalIndex=0; // Filters storyFilters.innerHTML = INDUSTRIES .map(n=>``) .join(''); storyFilters.addEventListener('click', (e)=>{ const b=e.target.closest('.filter-chip'); if(!b) return; activeFilter=b.dataset.name; $$('.filter-chip', storyFilters).forEach(x=>x.classList.toggle('active', x===b)); renderStories(); }); // Card template function card(s,i){ return `
${s.title}
${s.title}
${s.industry}
${(s.results||[]).slice(0,3).map(b=>`${b}`).join('')}
${s.stats.a}${s.stats.aText}
${s.stats.b}${s.stats.bText}
`; } function renderStories(){ visible = STORIES.filter(s => activeFilter === 'All' || s.industry === activeFilter); rail.innerHTML = visible.map((s,i)=>card(s,i)).join(''); $$('.story-card', rail).forEach(c => c.addEventListener('click', () => openModal(+c.dataset.index))); activeIndex = 0; renderDots(); scrollTo(0, false); } function renderDots(){ dotsWrap.innerHTML = visible.map((_,i)=>``).join(''); $$('.car-dot', dotsWrap).forEach(d => d.addEventListener('click', () => scrollTo(+d.dataset.i))); } function scrollTo(i, smooth=true){ activeIndex = Math.max(0, Math.min(i, visible.length - 1)); const card = rail.children[activeIndex]; if (!card) return; const left = card.offsetLeft - (rail.clientWidth - card.clientWidth)/2; rail.scrollTo({ left, behavior: smooth ? 'smooth' : 'auto' }); renderDots(); } btnPrev.addEventListener('click', () => scrollTo(activeIndex - 1)); btnNext.addEventListener('click', () => scrollTo(activeIndex + 1)); rail.addEventListener('keydown', e => { if (e.key === 'ArrowRight') scrollTo(activeIndex + 1); if (e.key === 'ArrowLeft') scrollTo(activeIndex - 1); }); // Modal function openModal(i){ modalIndex = i; fillModal(); sModal.classList.add('show'); sModal.setAttribute('aria-hidden','false'); document.body.style.overflow = 'hidden'; } function closeModal(){ sModal.classList.remove('show'); sModal.setAttribute('aria-hidden','true'); document.body.style.overflow = ''; } function fillModal(){ const s = visible[modalIndex]; if (!s) return; sIcon.textContent = s.icon; sTitle.textContent = s.title; sIndustry.textContent = s.industry; sLead.textContent = s.lead; sSol.innerHTML = s.solution.map(x=>`
  • ${x}
  • `).join(''); sRes.innerHTML = s.results.map(x=>`${x}`).join(''); sStatA.textContent = s.stats.a; sStatAT.textContent = s.stats.aText; sStatB.textContent = s.stats.b; sStatBT.textContent = s.stats.bText; sDots.innerHTML = visible.map((_,i)=>``).join(''); $$('.car-dot', sDots).forEach(d => d.addEventListener('click', () => { modalIndex = +d.dataset.i; fillModal(); })); } $('#storyClose').addEventListener('click', closeModal); sModal.addEventListener('click', e => { if (e.target === sModal) closeModal(); }); $('#storyPrev').addEventListener('click', () => { modalIndex = (modalIndex - 1 + visible.length) % visible.length; fillModal(); }); $('#storyNext').addEventListener('click', () => { modalIndex = (modalIndex + 1) % visible.length; fillModal(); }); document.addEventListener('keydown', e => { if (sModal.classList.contains('show') && e.key === 'Escape') closeModal(); }); // Init renderStories(); }); })(); function showTab(evt, tabId) { const tabs = document.querySelectorAll(".tab-content"); const buttons = document.querySelectorAll(".tablink"); tabs.forEach(tab => tab.classList.remove("active")); buttons.forEach(btn => btn.classList.remove("active")); document.getElementById(tabId).classList.add("active"); evt.currentTarget.classList.add("active"); } (() => { const STORIES = [ {id:'fintech',title:'FinTech Platform Modernization',icon:'💰',color:'#0ea5e9',industry:'FinTech',img:'https://orpical.com/wp-content/uploads/2023/07/digital-transformation-in-banking.png',gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(14,165,233,.20), transparent 60%), linear-gradient(135deg, rgba(14,165,233,.12), rgba(99,102,241,.12))',lead:'Legacy monolith with poor UX, slow deployments, and scalability bottlenecks.',solution:['Split monolith to microservices with API gateway','React/Next.js front-end with design tokens','CI/CD with canary releases and automated QA','Observability via OpenTelemetry + Grafana'],results:['70% faster loads','3× engagement','99.99% uptime','Zero-downtime releases'],stats:{a:'70%',aText:'faster page loads',b:'3×',bText:'increase in engagement'}}, {id:'commerce',title:'E-Commerce PWA Development',icon:'🛍️',color:'#f97316',industry:'E-Commerce',img:'https://img.freepik.com/premium-photo/ecommerce-business-concept_204719-89016.jpg?w=740&q=80',gradient:'radial-gradient(1200px 400px at 0% -10%, rgba(249,115,22,.18), transparent 60%), linear-gradient(135deg, rgba(251,146,60,.12), rgba(236,72,153,.12))',lead:'Mobile-first, offline-capable shopping with lightning performance.',solution:['PWA with Vue 3 + Nuxt, edge caching','Headless cart & checkout','Image/CDN optimization and code splitting','A/B testing pipeline for features'],results:['+40% mobile conversions','60% faster pages','Offline experience','SEO boost (SSR)'],stats:{a:'+40%',aText:'mobile conversion lift',b:'60%',bText:'faster LCP'}}, {id:'health',title:'Healthcare SaaS Collaboration',icon:'🏥',color:'#10b981',industry:'Healthcare',img:'https://kms-healthcare.com/wp-content/uploads/2023/09/agile-software-development-in-healthcare-2-1024x575.png',gradient:'radial-gradient(1200px 400px at 10% -10%, rgba(16,185,129,.18), transparent 60%), linear-gradient(135deg, rgba(16,185,129,.12), rgba(59,130,246,.12))',lead:'HIPAA-compliant, real-time collaboration app with strict latency targets.',solution:['React + TypeScript + WebRTC for video','FastAPI microservices on Azure AKS','End-to-end encryption & audit trails','Autoscaling with HPA & queues'],results:['HIPAA compliant','50ms avg latency','10k+ concurrent users','Secure audit logs'],stats:{a:'50ms',aText:'average latency',b:'10k+',bText:'concurrent users'}} ]; const INDUSTRIES = ['All', ...Array.from(new Set(STORIES.map(s=>s.industry)))]; const storyFilters = $('#storyFilters'); const rail = $('#storiesRail'); const dotsWrap = $('#storiesDots'); const btnPrev = $('#storiesPrev'); const btnNext = $('#storiesNext'); let activeFilter='All', visible=STORIES.slice(), activeIndex=0; storyFilters.innerHTML = INDUSTRIES.map(n=>``).join(''); storyFilters.addEventListener('click', e=>{ const b=e.target.closest('.filter-chip'); if(!b) return; activeFilter=b.dataset.name; $$('.filter-chip', storyFilters).forEach(x=>x.classList.toggle('active', x===b)); renderStories(); }); function card(s,i){ return `
    ${s.title}
    ${s.title}
    ${s.industry}
    ${(s.results||[]).slice(0,3).map(b=>`${b}`).join('')}
    ${s.stats.a}${s.stats.aText}
    ${s.stats.b}${s.stats.bText}
    `; } function renderStories(){ visible = STORIES.filter(s=>activeFilter==='All' || s.industry===activeFilter); rail.innerHTML = visible.map((s,i)=>card(s,i)).join(''); $$('.story-card', rail).forEach(c=>c.addEventListener('click',()=>openModal(+c.dataset.index))); activeIndex = 0; renderDots(); scrollTo(0,false); } function renderDots(){ dotsWrap.innerHTML = visible.map((_,i)=>``).join(''); $$('.car-dot', dotsWrap).forEach(d=>d.addEventListener('click',()=>scrollTo(+d.dataset.i))); } function scrollTo(i, smooth=true){ activeIndex=Math.max(0,Math.min(i,visible.length-1)); const card = rail.children[activeIndex]; if(!card) return; const left = card.offsetLeft - (rail.clientWidth - card.clientWidth)/2; rail.scrollTo({left,behavior:smooth?'smooth':'auto'}); renderDots(); } btnPrev.addEventListener('click', ()=>scrollTo(activeIndex-1)); btnNext.addEventListener('click', ()=>scrollTo(activeIndex+1)); rail.addEventListener('keydown', e=>{ if(e.key==='ArrowRight')scrollTo(activeIndex+1); if(e.key==='ArrowLeft')scrollTo(activeIndex-1); }); /* modal */ const sModal=$('#storyModal'); const sClose=$('#storyClose'); const sIcon=$('#storyIcon'); const sTitle=$('#storyTitle'); const sIndustry=$('#storyIndustry'); const sLead=$('#storyLead'); const sSol=$('#storySolution'); const sRes=$('#storyResults'); const sStatA=$('#storyStatA'); const sStatAT=$('#storyStatAText'); const sStatB=$('#storyStatB'); const sStatBT=$('#storyStatBText'); const sDots=$('#storyDots'); const sPrev=$('#storyPrev'); const sNext=$('#storyNext'); let modalIndex=0; function openModal(i){ modalIndex=i; fill(); sModal.classList.add('show'); sModal.setAttribute('aria-hidden','false'); document.body.style.overflow='hidden'; } function closeModal(){ sModal.classList.remove('show'); sModal.setAttribute('aria-hidden','true'); document.body.style.overflow=''; } function fill(){ const s=visible[modalIndex]; if(!s) return; sIcon.textContent=s.icon; sTitle.textContent=s.title; sIndustry.textContent=s.industry; sLead.textContent=s.lead; sSol.innerHTML=s.solution.map(x=>`
  • ${x}
  • `).join(''); sRes.innerHTML=s.results.map(x=>`${x}`).join(''); sStatA.textContent=s.stats.a; sStatAT.textContent=s.stats.aText; sStatB.textContent=s.stats.b; sStatBT.textContent=s.stats.bText; sDots.innerHTML=visible.map((_,i)=>``).join(''); $$('.car-dot', sDots).forEach(d=>d.addEventListener('click',()=>{modalIndex=+d.dataset.i; fill();})); } sClose.addEventListener('click',closeModal); sModal.addEventListener('click',e=>{ if(e.target===sModal) closeModal(); }); sPrev.addEventListener('click',()=>{ modalIndex=(modalIndex-1+visible.length)%visible.length; fill(); }); sNext.addEventListener('click',()=>{ modalIndex=(modalIndex+1)%visible.length; fill(); }); document.addEventListener('keydown',e=>{ if(!sModal.classList.contains('show')) return; if(e.key==='Escape') closeModal(); }); renderStories(); })(); Skip to main content

    Our Client provides public sector software to manage local governments. It includes public safety, 911, dispatch, finance, HR/payroll, utilities, property tax, and others. Thousands of municipalities and counties subscribe to their software. Thanks to their growth, the renewals department were manually quoting, emailing and booking approx. 6,000 opportunities per year. It was not possible to keep up and an estimated 7 additional FTEs were needed.

     

    Automating Customer Renewals Improves Retention And Reduces Costs