/*! WisePal Yearly Savings Widget — standalone embeddable card. * Usage: * * Optional attributes: interval (ms between cards, default 2400), * duration (count-up ms, default 900), title-text (header label). * Self-contained: all icons inlined, styles encapsulated in Shadow DOM. * For best typography add the Poppins font to your page : * */ (function(){ "use strict"; var ICONS = {"phone":"\n\n\n\n\n\n","1":"\n\n\n\n\n\n\n\n\n\n\n","2":"\n\n\n\n\n\n\n\n","3":"\n\n\n\n\n\n\n\n","4":"\n\n\n\n\n\n\n\n\n\n","5":"\n\n\n\n\n\n\n","6":"\n\n\n\n\n\n\n\n\n\n","tv":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","wireless":"\n\n\n\n\n\n\n\n"}; var PRODUCTS = [{"name":"CELL PHONE SERVICE","icon":"phone","before":1344,"after":1087},{"name":"HOME INTERNET","icon":"3","before":1032,"after":528},{"name":"TV SERVICE","icon":"tv","before":1488,"after":977}]; var STYLE = ":host { all: initial; display: inline-block; }\n*, *::before, *::after { box-sizing: border-box; }\n.card {\n width: 335px; height: 164px; max-width: 100%;\n background: #FFF; border: 1px solid #C9E1E4; border-radius: 20px;\n padding: 16px; position: relative; overflow: hidden;\n display: flex; flex-direction: column;\n font-family: \"Poppins\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n -webkit-font-smoothing: antialiased;\n}\n.head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }\n.title { margin: 0; font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: #15201E; }\n.live { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 500; color: #2FA8A2; }\n.live .dot { width: 7px; height: 7px; border-radius: 50%; background: #54C3BD; animation: wp-pulse 1.6s ease-in-out infinite; }\n@keyframes wp-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(84,195,189,.5); } 50% { box-shadow: 0 0 0 6px rgba(84,195,189,0); } }\n.row { display: grid; grid-template-columns: 54px 1fr auto; align-items: center; gap: 12px; padding: 6px 2px; transition: opacity 240ms ease, transform 240ms ease; }\n.row.out { opacity: 0; transform: translateY(8px); }\n.ic { width: 54px; height: 54px; display: block; }\n.ic svg { width: 54px; height: 54px; display: block; }\n.body { min-width: 0; }\n.name { font-size: 11.5px; font-weight: 400; letter-spacing: .05em; text-transform: uppercase; color: #6D9397; margin-bottom: 5px; line-height: 1.15; }\n.prices { display: flex; flex-wrap: nowrap; align-items: baseline; gap: 6px; white-space: nowrap; }\n.before { font-size: 14px; font-weight: 700; color: #000; text-decoration: line-through; text-decoration-thickness: 2px; }\n.before.plain { text-decoration: none; }\n.arrow { color: #2FA8A2; display: inline-flex; align-self: center; flex: 0 0 auto; }\n.after { font-size: 22px; font-weight: 700; color: #169B91; line-height: 1; }\n.after.note { font-size: 12px; font-weight: 700; color: #2FA8A2; white-space: normal; line-height: 1.2; max-width: 132px; }\n.prices.apy .before { font-size: 15px; }\n.after.apy { font-size: 19px; }\n.per { font-size: 11px; font-weight: 300; color: #8B9794; }\n.badge { text-align: right; white-space: nowrap; }\n.badge .amt { font-size: 15px; font-weight: 600; color: #169B91; line-height: 1; }\n.badge .lbl { font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #8B9794; margin-top: 3px; }\n.divider { height: 1px; background: #EDF3F2; margin: auto 4px 0; }\n.dots { display: flex; justify-content: center; gap: 6px; margin-top: 12px; }\n.dots i { width: 6px; height: 6px; border-radius: 999px; background: #E4EEEC; transition: width 300ms ease, background 300ms ease; }\n.dots i.on { width: 18px; background: #54C3BD; }\n@media (prefers-reduced-motion: reduce) { .live .dot { animation: none; } }"; var TEMPLATE = "
\n
\n Yearly Savings\n Finding savings\n
\n
\n \n
\n
\n
\n \n \n \n /yr\n
\n
\n
\n
\n
Saved
\n
\n
\n
\n
\n
"; var RM = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; function fmt(n){ return '$' + Number(n).toLocaleString('en-US'); } function countTo(el, from, to, dur){ if (RM){ el.textContent = fmt(to); return; } var start = null; function step(ts){ if (!start) start = ts; var p = Math.min((ts - start) / dur, 1); var eased = 1 - Math.pow(1 - p, 3); el.textContent = fmt(Math.round(from + (to - from) * eased)); if (p < 1) requestAnimationFrame(step); } requestAnimationFrame(step); } class WisePalSavingsCard extends HTMLElement { connectedCallback(){ if (this._init) return; this._init = true; var root = this.attachShadow({ mode:'open' }); root.innerHTML = '' + TEMPLATE; this.items = PRODUCTS.slice(); this.interval = parseInt(this.getAttribute('interval'), 10) || 2400; this.duration = parseInt(this.getAttribute('duration'), 10) || 900; var title = this.getAttribute('title-text'); if (title) root.querySelector('[data-title]').textContent = title; this.$ = function(s){ return root.querySelector(s); }; this.row = this.$('[data-row]'); this.icEl = this.$('[data-ic]'); this.nameEl = this.$('[data-name]'); this.pricesEl = this.$('[data-prices]'); this.beforeEl = this.$('[data-before]'); this.arrowEl = this.$('[data-arrow]'); this.afterWrap = this.$('[data-afterwrap]'); this.afterEl = this.$('[data-after]'); this.perEl = this.$('[data-per]'); this.badgeEl = this.$('[data-badge]'); this.saveEl = this.$('[data-save]'); this.dotsEl = this.$('[data-dots]'); var self = this; this.items.forEach(function(){ self.dotsEl.appendChild(document.createElement('i')); }); this.dots = this.dotsEl.querySelectorAll('i'); this.i = 0; this.render(0); if (!RM && this.items.length > 1){ this.timer = setInterval(function(){ self.cycle(); }, this.interval); } } disconnectedCallback(){ if (this.timer) clearInterval(this.timer); } render(idx){ var p = this.items[idx]; this.icEl.innerHTML = ICONS[p.icon] || ''; this.nameEl.textContent = p.name; this.beforeEl.classList.remove('plain'); this.afterWrap.classList.remove('note','apy'); this.pricesEl.classList.remove('apy'); this.arrowEl.style.display = ''; this.perEl.style.display = ''; this.badgeEl.style.visibility = 'visible'; if (p.mode === 'note'){ this.beforeEl.classList.add('plain'); this.beforeEl.textContent = fmt(p.before); this.afterWrap.classList.add('note'); this.afterEl.textContent = p.note; this.perEl.style.display = 'none'; this.badgeEl.style.visibility = 'hidden'; } else if (p.mode === 'apy'){ this.pricesEl.classList.add('apy'); this.afterWrap.classList.add('apy'); this.beforeEl.textContent = p.before; this.afterEl.textContent = p.after; this.perEl.style.display = 'none'; this.badgeEl.style.visibility = 'hidden'; } else { this.beforeEl.textContent = fmt(p.before); this.perEl.textContent = '/yr'; this.saveEl.textContent = fmt(p.before - p.after); countTo(this.afterEl, p.before, p.after, this.duration); } for (var k = 0; k < this.dots.length; k++){ this.dots[k].classList.toggle('on', k === idx); } } cycle(){ var self = this; this.row.classList.add('out'); setTimeout(function(){ self.i = (self.i + 1) % self.items.length; self.render(self.i); self.row.classList.remove('out'); }, 240); } goTo(n){ if (this.timer) clearInterval(this.timer); this.i = ((n % this.items.length) + this.items.length) % this.items.length; this.render(this.i); } } if (!customElements.get('wisepal-savings-card')) customElements.define('wisepal-savings-card', WisePalSavingsCard); })();