PageSourceSearch

https://revitin.com/products/revitin-natural-toothpaste/Citrus

html revitin.com collected 2026-09-30 14:07:19 UTC 766,004 bytes, 12,808 lines download raw bytes

1<!doctype html>
2<html class="no-js" lang="en">
3  <head>
4
5
6               
6<script type='text/javascript'>var easylockdownLocationDisabled = true;</script>
6 
6<script type='text/javascript'> window.easyLockdownLoginMode = 'classic'; var isShopifyPreviewHost = window.location.hostname.indexOf('shopifypreview.com') !== -1; if( isShopifyPreviewHost ) { window.easyLockdownLoginMode = 'classic'; } </script>
6 
6<script type='text/javascript' src='//revitin.com/apps/easylockdown/easylockdown-1.0.8.min.js?v=202609170844' data-no-instant></script>
6 
6<script type='text/javascript'>document.addEventListener('easylockdown_loaded', function() { if(typeof InstantClick == 'object') easylockdown.clearData(); }, {once: true});</script>
6 
6<script type='text/javascript'>(function() { function tryFallback() { if(typeof easylockdown == 'object' && typeof easylockdown.onLoaded != 'function') { var event = document.createEvent('Event'); event.initEvent('easylockdown_loaded', true, true); document.dispatchEvent(event); return true; } return typeof easylockdown == 'object'; } function onReady() { if(!tryFallback()) { var attempts = 0; var interval = setInterval(function() { if(tryFallback() || ++attempts >= 10) clearInterval(interval); }, 100); } } if(document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', onReady, {once: true}); } else { onReady(); } })();</script>
6 <style type="text/css" id="easylockdown-plugin-style">#easylockdown-password-form{padding:30px 0;text-align:center}#easylockdown-wrapper,.easylockdown-form-holder{display:inline-block}#easylockdown-password{vertical-align:top;margin-bottom:16px;padding:8px 15px;line-height:1.2em;outline:0;box-shadow:none}#easylockdown-password-error{display:none;color:#fb8077;text-align:left}#easylockdown-password-error.easylockdown-error{border:1px solid #fb8077}#easylockdown-password-form-button:not(.easylockdown-native-styles){vertical-align:top;display:inline-block!important;height:auto!important;padding:8px 15px;background:#777;border-radius:3px;color:#fff!important;line-height:1.2em;text-decoration:none!important}.easylockdown-instantclick-fix,.easylockdown-item-selector{position:absolute;z-index:-999;display:none;height:0;width:0;font-size:0;line-height:0}.easylockdown-collection-item[data-eld-loc-can],.easylockdown-item-selector+*,.easylockdown-item[data-eld-loc-can]{display:none}.easylockdown404-content-container{padding:50px;text-align:center}.easylockdown404-title-holder .easylockdown-title-404{display:block;margin:0 0 1rem;font-size:2rem;line-height:2.5rem}</style> 
7
8
9
10
11
12
13
14<script type='text/javascript'> if(typeof easylockdown == 'object') { easylockdown.hideLinks.push('*[href$="/products/"],*[href*="/products//"],*[href*="/products/?"],*[href*="/products/#"],*[data-eld-product-handle=""]');}</script>
14
15
16
17
18
19
20<script type='text/javascript'> if(typeof easylockdown == 'object') { easylockdown.hideLinks.push('*[href$="/collections/professionals"],*[data-eld-collection-handle="professionals"]');}</script>
20
21
22
23
24
25
26<script type='text/javascript'>
27  document.addEventListener('easylockdown_loaded', function() {
28    easylockdown.localeRootUrl = '';
29    easylockdown.routerByLocation(); 
30
31    easylockdown.onReady(function(e){
32      setTimeout(function() {
33        easylockdown.hideAllLinks();
34      }, 0);
35    });
36  }, {once: true});
37</script>
37
38
39<!-- Start of Shoplift scripts -->
40    <!-- 2026-09-10T11:45:02.6702537Z -->
41<style>.shoplift-hide { opacity: 0 !important; }</style>
42<style id="sl-preview-bar-hide">#preview-bar-iframe, #PBarNextFrameWrapper { display: none !important; }</style>
43<script type="text/javascript">(function(rootPath, template, themeRole, themeId, isThemePreview){ /* Generated on 2026-09-30T13:45:02.8931035Z */(function(){"use strict";var te=document.createElement("style");te.textContent=`#shoplift-preview-control{position:fixed;max-width:332px;height:56px;background-color:#141414;z-index:9999;bottom:20px;display:flex;border-radius:8px;box-shadow:13px 22px 7px #0000,9px 14px 7px #00000003,5px 8px 6px #0000000d,2px 4px 4px #00000017,1px 1px 2px #0000001a,0 0 #0000001a;align-items:center;margin:0 auto;left:16px;right:16px;opacity:0;transform:translateY(20px);visibility:hidden;transition:opacity .4s ease-in-out,transform .4s ease-in-out,visibility 0s .4s}#shoplift-preview-control.visible{opacity:1;transform:translateY(0);visibility:visible;transition:opacity .4s ease-in-out,transform .4s ease-in-out,visibility 0s 0s}#shoplift-preview-control *{font-family:Inter,sans-serif;color:#fff;box-sizing:border-box;font-size:16px}#shoplift-preview-variant-title{font-weight:400;line-height:140%;font-size:16px;text-align:start;letter-spacing:-.16px;flex-grow:1;text-wrap:nowrap;overflow:hidden;text-overflow:ellipsis}#shoplift-preview-variant-selector{position:relative;display:block;padding:6px 0;height:100%;min-width:0;flex:1 1 auto}#shoplift-preview-variant-menu-trigger{border:none;cursor:pointer;width:100%;background-color:transparent;padding:0 16px;border-left:1px solid #333;border-right:1px solid #333;height:100%;display:flex;align-items:center;justify-content:start;gap:8px}#shoplift-preview-variant-selector .menu-variant-label{width:24px;height:24px;border-radius:50%;padding:6px;display:flex;justify-content:center;align-items:center;font-size:12px;font-style:normal;font-weight:600;line-height:100%;letter-spacing:-.12px;flex-shrink:0}#shoplift-preview-variant-selector .preview-variant-menu{position:absolute;bottom:110%;transform:translate3d(0,20px,0);visibility:hidden;pointer-events:none;opacity:0;cursor:pointer;background-color:#141414;border:1px solid #141414;border-radius:6px;width:100%;max-height:156px;overflow-y:auto;box-shadow:0 8px 16px #0003;z-index:1;transition:opacity .3s ease-in-out,transform .3s ease-in-out,visibility 0s .3s}#shoplift-preview-variant-selector .preview-variant-menu.preview-variant-menu__visible{visibility:visible;pointer-events:auto;opacity:100;transform:translateZ(0);transition:opacity .3s ease-in-out,transform .3s ease-in-out,visibility 0s 0s}@media screen and (max-width:400px){#shoplift-preview-variant-selector .preview-variant-menu{position:fixed;left:0;right:0;width:auto;bottom:110%}}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item{padding:12px 16px;display:flex;overflow:hidden}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item .menu-variant-label{margin-right:6px}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item span{overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;color:#f6f6f6;font-size:14px;font-style:normal;font-weight:500}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item:hover{background-color:#545454}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item:last-of-type{border-bottom-left-radius:6px;border-bottom-right-radius:6px}#shoplift-preview-variant-selector .preview-variant-menu .preview-variant-menu--item:first-of-type{border-top-left-radius:6px;border-top-right-radius:6px}#shoplift-preview-control div:has(#shoplift-exit-preview-button){padding:0 16px}#shoplift-exit-preview-button{padding:6px 8px;font-weight:500;line-height:75%;border-radius:4px;background-color:transparent;border:none;text-decoration:none}#shoplift-exit-preview-button:hover{cursor:pointer;background-color:#333}#shoplift-preview-subscription-warning{position:relative;display:flex;align-items:center;gap:6px;padding:6px 10px;margin:0 4px;border-left:1px solid #333;cursor:help;outline:none}#shoplift-preview-subscription-warning__icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background-color:#f59e0b;color:#141414!important;font-weight:700;font-size:12px!important;line-height:1;flex-shrink:0}#shoplift-preview-subscription-warning__label{font-size:13px!important;font-weight:500;color:#fbbf24!important;text-wrap:nowrap;white-space:nowrap}#shoplift-preview-subscription-warning__tooltip{position:absolute;bottom:calc(100% + 8px);right:0;max-width:320px;width:max-content;padding:10px 12px;border-radius:6px;background-color:#1f1f1f;color:#fff!important;font-size:12px!important;line-height:1.4!important;box-shadow:0 8px 16px #0000004d;z-index:10000;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .2s ease-in-out,transform .2s ease-in-out,visibility 0s .2s;pointer-events:none}#shoplift-preview-subscription-warning__tooltip.shoplift-preview-subscription-warning__tooltip--visible{opacity:1;visibility:visible;transform:translateY(0);transition:opacity .2s ease-in-out,transform .2s ease-in-out,visibility 0s 0s}#shoplift-preview-subscription-warning:focus-visible{box-shadow:inset 0 0 0 2px #f59e0b;border-radius:4px}#shoplift-preview-control:has(#shoplift-preview-subscription-warning){max-width:480px}/*$vite$:1*/`,document.head.appendChild(te);var fe=" daum[ /]| deusu/|(?:^|[^g])news(?!sapphire)|(?<! channel/|google/)google(?!(?:wv|app|/google| pixel))|(?<! cu)bots?(?:\\b|_)|(?<!cam)scan|(?<!lib)http|24x
437|;\\s\\w+;$|@[a-z][\\w-]+\\.|\\(\\)|\\.com\\b|\\b\\w+/1\\.0;|\\bbw/|\\bdlc\\b|\\bort/|\\bperl\\b|\\btime/|\\||^[<\\(;]|^[\\w \\.\\-\\(?:\\):%]+(?:/v?\\d+(?:\\.\\d+)?(?:\\.\\d{1,10})*?)?(?:,|$)|^[\\w\\-]+/[\\w]+$|^[^ ]{50,}$|^\\d+\\b|^\\w*search\\b|^\\w+/[\\w\\(\\)]*$|^\\w+/\\d\\.\\d\\s\\([\\w@]+\\)$|^active|^ad muncher|^amaya|^apache/|^avsdevicesdk/|^azure|^biglotron|^blackbox exporter|^bot|^clamav[ /]|^claude-code/|^client/|^cobweb/|^custom|^ddg[_-]android|^discourse|^dispatch/\\d|^downcast/|^duckduckgo|^email|^exodusmovement|^facebook|^getright/|^gozilla/|^hobbit|^hotzonu|^hwcdn/|^igetter/|^jeode/|^jetty/|^jigsaw|^microsoft bits|^movabletype|^mozilla/\\d\\.\\d\\s[\\w\\.-]+$|^mozilla/\\d\\.\\d\\s\\((?:compatible;)?(?:\\s?[\\w\\d-.]+\\/\\d+\\.\\d+)?\\)$|^navermailapp|^netsurf|^offline|^openai/|^owler|^php|^postman|^ps_daily/|^python|^rank|^read|^reed|^remove\\.bg/|^rest|^rss|^snapchat|^sora |^space bison|^stape/|^svn|^swcd |^taringa|^thumbor/|^track|^w3c|^webbandit/|^webcopier|^wget|^whatsapp|^wordpress|^xenu link sleuth|^yahoo|^yandex|^zdm/\\d|^zoom marketplace/|abuse|advisor|agent\\b|analyzer|archive|ask jeeves/teoma|attracta|audit|bluecoat drtr|browsex|burpcollaborator|capture|catch|check\\b|checker|chrome-lighthouse|chromeframe|classifier|cloudflare|collapsify\\b|convertify|cookiehubverify/|crawl|cursor/|cypress/|dareboost|datanyze|dejaclick|detect|discovery|dmbrowser|download|exaleadcloudview|feed|firephp|foregenix|functionize|grab|hardenize\\b|headless|hotjar|httrack|hubspot marketing grader|ibisbrowser|infrawatch|insight|inspect|iplabel|java(?!;)|library|linkcheck|linktiger|mail\\.ru/|manager|manus-user/|marketgoo/|measure|monitor\\b|neustar wpm|node\\b|nutch|offbyone|openvas|optimize|pageburst|pagespeed|parser|phantomjs|pingdom|playwright|powermarks|preview|productfinder|prospectingstudio|proxy|ptst[ /]\\d|radar|readable/|retriever|rexx;|rigor|rss\\b|scrape|securityheaders|selenium|server|silktide|sindup/|sogou|sparkler/|speedcurve|spider|splash|statuscake|supercleaner|synapse|synthetic|testlocally|tools|torrent|transcoder|url|validator|virtuoso|wappalyzer|watchtowr|webglance|webkit2png|whatcms/|xtate/",ge=/bot|crawl|http|lighthouse|scan|search|spider/i,z;function me(){if(z instanceof RegExp)return z;try{z=new RegExp(fe,"i")}catch{z=ge}return z}var ye=a=>typeof a=="string"&&a!=="";function ve(a){return ye(a)&&me().test(a)}var we=ve;class X{timestamp;constructor(){this.timestamp=new Date}}class be extends X{type;testId;hypothesisId;constructor(e,t,i){super(),this.type=3,this.testId=e,this.hypothesisId=t,this.timestamp=i}}class Se extends X{type;path;constructor(e){super(),this.type=4,this.path=e}}class Ce extends X{type;cart;constructor(e){super(),this.type=5,this.cart=e}}class ie extends Error{isBot;constructor(){super(),this.isBot=!0}}function Te(a,e,t){for(const i of e.selectors){const s=a.querySelectorAll(i.cssSelector);for(let r=0;r<s.length;r++)t(e.testId,e.hypothesisId)}re(a,e,(i,s,r,o,n)=>n(s,r),t)}function U(a,e,t){for(const i of e.selectors)ne(a,e.testId,e.hypothesisId,i,t??(()=>{}));re(a,e,ne,t??(()=>{}))}function se(a){return a.urlPatterns.reduce((e,t)=>{switch(t.operator){case"contains":return e+`.*${t}.*`;case"endsWith":return e+`.*${t}`;case"startsWith":return e+`${t}.*`}},"")}function re(a,e,t,i){new MutationObserver(()=>{for(const r of e.selectors)t(a,e.testId,e.hypothesisId,r,i)}).observe(a.documentElement,{childList:!0,subtree:!0})}function ne(a,e,t,i,s){const r=a.querySelectorAll(i.cssSelector);for(let o=0;o<r.length;o++){let n=r.item(o);if(n instanceof HTMLElement&&n.dataset.shoplift!==""){n.dataset.shoplift="";for(const l of i.actions.sort(Re))n=Ie(a,i.cssSelector,n,l)}}return r.length>0&&s?(s(e,t),!0):!1}function Ie(a,e,t,i){switch(i.type){case"innerHtml":t.innerHTML=i.value;break;case"attribute":Pe(t,i.scope,i.value);break;case"css":Ae(a,e,i.value);break;case"js":ke(a,t,i);break;case"copy":return Ee(t);case"remove":xe(t);break;case"move":_e(t,parseInt(i.value));break}return t}function Pe(a,e,t){a.setAttribute(e,t)}function Ae(a,e,t){const i=a.createElement("style");i.innerHTML=`${e} { ${t} }`,a.getElementsByTagName("head")[0]?.appendChild(i)}function ke(a,e,t){Function("document","element",`"use strict"; ${t.value}`)(a,e)}function Ee(a){const e=a.cloneNode(!0);if(!a.parentNode)throw"Can't copy node outside of DOM";return a.parentNode.insertBefore(e,a.nextSibling),e}function xe(a){a.remove()}function _e(a,e){if(e===0)return;const t=Array.prototype.slice.call(a.parentElement.children).indexOf(a),i=Math.min(Math.max(t+e,0),a.parentElement.children.length-1);a.parentElement.children.item(i).insertAdjacentElement(e>0?"afterend":"beforebegin",a)}function Re(a,e){return oe(a)-oe(e)}function oe(a){return a.type==="copy"||a.type==="remove"?0:1}
43const M={Template:0,UrlRedirect:2,Script:3,Price:5},De="data:image/svg+xml,%3csvg%20width='12'%20height='12'%20viewBox='0%200%2012%2012'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M9.96001%207.90004C9.86501%207.90004%209.77001%207.86504%209.69501%207.79004L6.43501%204.53004C6.19501%204.29004%205.80501%204.29004%205.56501%204.53004L2.30501%207.79004C2.16001%207.93504%201.92001%207.93504%201.77501%207.79004C1.63001%207.64504%201.63001%207.40504%201.77501%207.26004L5.03501%204.00004C5.56501%203.47004%206.43001%203.47004%206.96501%204.00004L10.225%207.26004C10.37%207.40504%2010.37%207.64504%2010.225%207.79004C10.15%207.86004%2010.055%207.90004%209.96001%207.90004Z'%20fill='white'/%3e%3c/svg%3e",Ve="data:image/svg+xml,%3csvg%20width='14'%20height='24'%20viewBox='0%200%2014%2024'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12.3976%2014.5255C12.2833%2013.8788%2012.0498%2013.3024%2011.6952%2012.7961C11.3416%2012.2898%2010.9209%2011.8353%2010.4353%2011.4317C9.94868%2011.0291%209.43546%2010.6488%208.89565%2010.292C8.48487%2010.049%208.09577%209.78565%207.72637%209.50402C7.35697%209.2224%207.08016%208.89503%206.89694%208.51987C6.71273%208.14471%206.67826%207.69533%206.79055%207.1697C6.86345%206.83216%206.97476%206.54647%207.12351%206.31162C7.27324%206.07778%207.47124%205.89986%207.7175%205.77684C7.96377%205.65483%208.21989%205.59383%208.48389%205.59383C8.88087%205.59383%209.17639%205.7016%209.3734%205.91714C9.56943%206.13268%209.68271%206.42345%209.71424%206.78946C9.74576%207.15547%209.72015%207.55401%209.63839%207.98509C9.55663%208.41617%209.43645%208.84724%209.27687%209.27934L13.5127%208.80149C13.9638%207.52656%2014.1017%206.42447%2013.9264%205.49725C13.751%204.56901%2013.2664%203.85122%2012.4724%203.34491C12.239%203.19648%2011.9779%203.07041%2011.6893%202.96569L12.0026%201.50979L9.86397%200L7.3875%201.50979L7.11169%202.78878C6.65166%202.8874%206.21724%203.01957%205.8114%203.19038C4.85292%203.594%204.06684%204.15115%203.45117%204.86385C2.83452%205.57655%202.42571%206.40108%202.22378%207.33847C2.06616%208.06947%202.04942%208.70796%202.17551%209.25087C2.30061%209.7948%202.52028%2010.2828%202.8355%2010.7139C3.14974%2011.145%203.51816%2011.5344%203.93977%2011.881C4.36039%2012.2288%204.782%2012.5521%205.20164%2012.851C5.68334%2013.1702%206.13844%2013.5169%206.56497%2013.8921C6.99052%2014.2672%207.31954%2014.7125%207.55004%2015.228C7.78055%2015.7445%207.81502%2016.3769%207.65347%2017.1262C7.56482%2017.5389%207.43676%2017.8765%207.27028%2018.1388C7.10381%2018.4011%206.89596%2018.5983%206.64772%2018.7295C6.3985%2018.8606%206.12071%2018.9267%205.8114%2018.9267C5.21641%2018.9267%204.79776%2018.6034%204.62833%2018.1632C4.4589%2017.7229%204.47367%2017.2583%204.60075%2016.5639C4.72782%2015.8705%205.05092%2015.1395%205.37107%2014.3699H1.17665C1.17665%2014.3699%200.207341%2016.1115%200.0310135%2017.6762C-0.0655232%2018.5302%200.0635208%2019.2653%200.41519%2019.8844C0.76686%2020.5036%201.33032%2020.9814%202.10655%2021.319C2.39222%2021.443%202.7104%2021.5447%203.05813%2021.623L2.54589%2024H7.17473L7.7047%2021.5386C8.08493%2021.442%208.43857%2021.3231%208.76562%2021.1787C9.73985%2020.7476%2010.52%2020.1427%2011.1071%2019.3649C11.6932%2018.5871%2012.0873%2017.7291%2012.2892%2016.7917C12.4744%2015.9295%2012.5099%2015.1741%2012.3966%2014.5275L12.3976%2014.5255Z'%20fill='white'/%3e%3c/svg%3e";async function Oe(a){let e=a.replace(/-/g,"+").replace(/_/g,"/");for(;e.length%4;)e+="=";const t=atob(e),i=Uint8Array.from(t,o=>
43o.charCodeAt(0)),s=new Blob([i]).stream().pipeThrough(new DecompressionStream("gzip")),r=await new Response(s).text();return JSON.parse(r)}function F(a,e){return typeof e=="string"&&/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+(?:Z|[+-]\d+)/.test(e)?new Date(e):e}function ee(a,e){return e}function q(a,e=!1,t=!1,i=","){const s=a/100;if(t){const o=Math.round(s).toLocaleString("en-US");return i!==","?o.replace(/,/g,i):o}else{const r=e?",":".",o=s.toFixed(2).split("."),n=parseInt(o[0],10),l=o[1]??"00",c=n.toLocaleString("en-US");return i!==","?`${c.replace(/,/g,i)}${r}${l}`:e?`${c.replace(/,/g,".")}${r}${l}`:`${c}${r}${l}`}}function H(a,e,t,i){const s=e.replace("{{amount}}",q(a,!1,!1)).replace("{{amount_no_decimals}}",q(a,!1,!0)).replace("{{amount_with_comma_separator}}",q(a,!0,!1)).replace("{{amount_no_decimals_with_comma_separator}}",q(a,!0,!0)).replace("{{amount_with_space_separator}}",q(a,!1,!1," ")).replace("{{amount_no_decimals_with_space_separator}}",q(a,!1,!0," ")).replace("{{amount_with_apostrophe_separator}}",q(a,!1,!1,"'")).replace("{{amount_no_decimals_with_apostrophe_separator}}",q(a,!1,!0,"'")).replace("{{amount_with_period_and_space_separator}}",q(a,!1,!1,". ")).replace("{{amount_no_decimals_with_period_and_space_separator}}",q(a,!1,!0,". "));return i?`${s} ${t}`:s}function ae(a){return a.replace(/[^\d.,\s-]/g,"").trim()}function j(a){const e=new Map;for(const[t,i,s]of a.variants)e.set(t,{priceInCents:i,compareAtPriceInCents:s});return e}function Le(a,e,t,i){const{priceInCents:s,compareAtPriceInCents:r}=t,{moneyFormat:o,currency:n,currencyCodeEnabled:l}=i;if(a.getAttribute("data-sl-attribute-p")===e)a.innerHTML=H(s,o,n,l);else if(a.getAttribute("data-sl-attribute-cap")===e)r<=0||r<=s?a.remove():a.innerHTML=H(r,o,n,l);else if(a.getAttribute("data-sl-attribute-discount")===e&&!(r<=0||r<=s)){const d=Math.round((r-s)/r*100),u=ae(H(r-s,o,n,!1)),h=a.getAttribute("data-sl-format")||"percent";h==="percent"?a.textContent=`-${d}%`:h==="amount"?a.textContent=`-${u}`:h==="both"&&(a.textContent=`-${d}% (-${u})`)}}function $e(a){const e=[],t={id:"url-pattern",operator:"contains",value:"/"};for(const[i,s,r]of a.variants){e.push({id:`p-${i}`,cssSelector:`[data-sl-attribute-p="${i}"]`,urlPatterns:[t],actions:[{id:`p-action-${i}`,type:"innerHtml",scope:"price",value:H(s,a.moneyFormat,a.currency,a.currencyCodeEnabled)}]});const o=r<=0||r<=s;if(e.push({id:`cap-${i}`,cssSelector:`[data-sl-attribute-cap="${i}"]`,urlPatterns:[t],actions:[{id:`cap-action-${i}`,type:o?"remove":"innerHtml",scope:"compare-at-price",value:o?"":H(r,a.moneyFormat,a.currency,a.currencyCodeEnabled)}]}),!o&&r>s){const n=Math.round((r-s)/r*100),l=ae(H(r-s,a.moneyFormat,a.currency,!1));e.push({id:`d-${i}`,cssSelector:`[data-sl-attribute-discount="${i}"]`,urlPatterns:[t],actions:[{id:`d-action-${i}`,type:"js",scope:null,value:`var format = element.getAttribute('data-sl-format') || 'percent';                    if (format === 'percent') {                      element.textContent = '-${n}%';                    } else if (format === 'amount') {                      element.textContent = '-${l}';                    } else if (format === 'both') {                      element.textContent = '-${n}% (-${l})';                    }`}]})}}return e}const Me=a=>{let e=5381;for(let t=0;t<a.length;t++)e=(e*33^a.charCodeAt(t))>>>0;return e.toString(36)},qe=()=>Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4),He=a=>btoa(JSON.stringify(a)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""),K=a=>a.replace(/#slr-[a-z0-9]+$/,""),tt="modulepreload",it=function(a){return"/"+a},st={},Ne=function(e,t,i){let s=Promise.resolve();function r(o){const n=new Event("vite:preloadError",{cancelable:!0});if(n.payload=o,window.dispatchEvent(n),!n.defaultPrevented)throw o}return s.then(o=>{for(const n of o||[])n.status==="rejected"&&r(n.reason);return e().catch(r)})};function le(a,e,t){const i=t?a.plans.filter(c=>!c.variantId||c.variantId===t):a.plans,s=[],r=[];for(const c of i)c.direction==="decrease"?(s.push(c.existingShopifyPlanId),r.push(c.createdShopifyPlanId)):(s.push(c.createdShopifyPlanId),r.push(c.existingShopifyPlanId));const o=e?s:r,n=e?r:s;if(t)for(const c of a.plans)for(const d of[c.existingShopifyPlanId,c.createdShopifyPlanId])d&&!o.includes(d)&&!n.includes(d)&&n.push(d);const l={};for(let c=0;c<n.length;c++){const d=n[c],u=o[c];d&&u&&(l[d]=u)}return{showPlanIds:o,hidePlanIds:n,swapMap:l}}function ce(a,e,t){const i=e?a.plans.find(r=>r.variantId===e):void 0;if(i)return i.direction;if(t){const r=a.plans.find(o=>o.productId===t);if(r)return r.direction}return a.plans.find(r=>!r.variantId)?.direction??null}function J(a,e){const t=e?a.plans.filter(r=>!r.productId||r.productId===e):a.plans,i={};for(const r of t)i[r.existingShopifyPlanId]=r.existingDiscountAmount,i[r.createdShopifyPlanId]=r.existingDiscountAmount;
43const s=Math.max(...Object.values(i),0);return{discountMap:i,maxDiscount:s}}function W(a){const e=document.querySelector('form[action*="/cart/add"] input[name="product-id"]')?.value;if(e)return e;if(a){for(const r of Array.from(document.querySelectorAll("[data-sl-attribute-p]"))){const o=r.getAttribute("data-sl-attribute-p");if(!o)continue;const n=a.variants.find(l=>l[0]===o);if(n?.[3])return n[3]}const s=document.querySelector('form[action*="/cart/add"] input[name="id"]')?.value;if(s){const r=a.variants.find(o=>o[0]===s);if(r?.[3])return r[3]}}const t=window,i=t.ShopifyAnalytics?.meta?.product?.id??t.meta?.product?.id;return i!=null?String(i):null}function D(a,e){return a.widget.selectors[e]??[]}function N(a,e){return a.replace(/[\d.]+%/,`${e}%`)}function $(a,e){const t=document.createTreeWalker(a,NodeFilter.SHOW_TEXT);let i=t.nextNode();for(;i;){if(i.nodeValue!==null){const s=e(i.nodeValue);if(s!==i.nodeValue){i.nodeValue=s;return}}i=t.nextNode()}}function de(a,e){return a===null?!1:a==="decrease"?!e:e}async function Ue(a){if(a.subscriptionSwapDone)return;const e=a.getActiveAssignment();if(!e)return;const t=a.getHypothesis(e.hypothesisId);if(!t?.subscriptionData)return;a.subscriptionSwapDone=!0;const i=t.subscriptionData,s=t.isControl,r=[...new Set(i.plans.map(d=>d.direction))].join(",");a.log(`[SUB-SWAP] ${s?"A":"B"} side, directions=${r}`);const o=i.plans.some(d=>d.variantId);let n=!1,l=!1;function c(){if(!l){l=!0;try{const d=o?document.querySelector("select[name='id'], input[name='id']")?.value:void 0,{showPlanIds:u,hidePlanIds:h,swapMap:p}=le(i,s,d);a.swapMap=p;const b=D(i,"widgetParent"),E=D(i,"subscriptionPlans"),S=D(i,"subscriptionInput");if(!b.length||!E.length||!S.length)return;const C=document.querySelector(b[0].selector);if(!C?.shadowRoot)return;const _=C.shadowRoot.querySelector(E[0].selector);if(!_?.shadowRoot)return;const T=S[0].selector;let m=null;if(i.widget.widgetType==="buttons"||i.widget.widgetType==="radio"){const y=Array.from(_.shadowRoot.querySelectorAll(T));if(!y.length)return;for(const v of y){const g=v.closest("label");g&&(u.includes(v.value)?g.style.display="":h.includes(v.value)&&(g.style.display="none"))}const w=y.some(v=>u.includes(v.value)&&v.checked),I=y.some(v=>h.includes(v.value)&&v.checked);if((w||I)&&(n=!1),!w&&!n){n=!0;for(const v of y)if(u.includes(v.value)){v.closest("label")?.click(),v.dispatchEvent(new Event("change",{bubbles:!0}));break}}const f=y.find(v=>v.checked);m=f&&u.includes(f.value)?f.value:u[0]??null}else if(i.widget.widgetType==="dropdown"){const y=_.shadowRoot.querySelector("select");if(!y)return;for(const w of Array.from(y.options))h.includes(w.value)&&(w.style.display="none",w.disabled=!0);if(h.includes(y.value)){const w=Array.from(y.options).find(I=>u.includes(I.value));w&&(y.value=w.value,y.dispatchEvent(new Event("change",{bubbles:!0})))}m=u.includes(y.value)?y.value:u[0]??null}if(m){const y=Array.from(document.querySelectorAll('input[name="selling_plan"]'));for(const w of y)w.value!==m&&(w.value=m)}}finally{l=!1}}}if(a.subscriptionHideWrongPlans=c,a.swapMap=le(i,s).swapMap,c(),o){const d=document.querySelector("select[name='id'], input[name='id']");d&&d.addEventListener("change",c)}}function B(a){const e=D(a,"widgetParent");return e.length?document.querySelector(e[0].selector)?.shadowRoot??null:null}function Y(a,e){const t=D(a,"subscriptionPlans");return t.length?e.querySelector(t[0].selector)?.shadowRoot??null:null}function Z(a,e){const t=new URLSearchParams(window.location.search).get("variant");if(t)return t;{const i=document.querySelector('form[action*="/cart/add"] input[name="id"]')?.value;if(i)return i}return a.size>0?[...a.keys()][0]:void 0}function G(a,e){return H(a,e.moneyFormat,e.currency,e.currencyCodeEnabled)}function Fe({originalFetch:a,swapMap:e,slptValue:t,getSelectedPlanId:i,log:s}){if(window.fetch.__shoplift_intercepted)return s("[SUB-INTERCEPT] already installed — skipping"),()=>{};function r(n){if(i){const l=i();if(l)return e[l]??l}return e[n]??n}const o=function(n,l){if((typeof n=="string"?n:n instanceof URL?n.href:n.url).includes("/cart/add")&&l?.body)try{if(l.body instanceof FormData){const d=l.body.get("selling_plan");d?l.body.set("selling_plan",r(String(d))):(!d||d==="")&&t&&l.body.set("properties[_slpt]",t)}
43else if(typeof l.body=="string"){const d=JSON.parse(l.body);if(d.items)for(const u of d.items){const h=String(u.selling_plan??"");h?u.selling_plan=r(h):!u.selling_plan&&t&&(u.properties||(u.properties={}),u.properties._slpt=t)}else if(d.id){const u=String(d.selling_plan??"");u?d.selling_plan=r(u):!d.selling_plan&&t&&(d.properties||(d.properties={}),d.properties._slpt=t)}l.body=JSON.stringify(d)}}catch(d){s("[SUB-INTERCEPT] body parse failed; cart-add proceeds with un-swapped plan",d)}return a.call(window,n,l)};return o.__shoplift_intercepted=!0,window.fetch=o,function(){window.fetch===o&&(window.fetch=a)}}function Be({log:a}){if(window.fetch.__shoplift_intercepted)return a("[SUB-PREVIEW-BLOCK] already installed — skipping"),()=>{};const e=window.fetch,t=function(i,s){const r=typeof i=="string"?i:i instanceof URL?i.href:i.url;return r.includes("/cart/add")?(a("[SUB-PREVIEW-BLOCK] cart-add blocked in preview mode",{url:r}),Promise.resolve(new Response(JSON.stringify({id:0,properties:{},quantity:0,variant_id:0,key:"preview",title:"Preview — cart-add blocked",price:0,original_price:0,line_price:0,original_line_price:0,total_discount:0,discounts:[],preview:!0}),{status:200,headers:{"Content-Type":"application/json"}}))):e.call(window,i,s)};return t.__shoplift_intercepted=!0,window.fetch=t,function(){window.fetch===t&&(window.fetch=e)}}function pe({data:a,runUpdates:e,debounceMs:t=150}){let i=null;function s(){i&&clearTimeout(i),e(),i=setTimeout(e,t)}let r=null;const o=[],n={childList:!0,subtree:!0,characterData:!0,attributes:!0};function l(h){for(const p of o)p.disconnect();o.length=0;for(const p of Array.from(h.querySelectorAll("*")))if(p.shadowRoot){const b=new MutationObserver(s);b.observe(p.shadowRoot,n),o.push(b)}}function c(){const h=B(a);return h?(r&&r.disconnect(),l(h),r=new MutationObserver(p=>{p.some(b=>b.type==="childList"&&b.addedNodes.length>0)&&l(h),s()}),r.observe(h,n),!0):!1}const d=document.body||document.documentElement,u=new MutationObserver(()=>{c()&&s()});return u.observe(d,{childList:!0,subtree:!0}),c()&&s(),e(),function(){i&&(clearTimeout(i),i=null),u.disconnect(),r&&(r.disconnect(),r=null);for(const p of o)p.disconnect();o.length=0}}async function ze(a){if(a.subscriptionPriceDone)return;const e=a.getActiveAssignment(),t=e?a.getHypothesis(e.hypothesisId):void 0,i=t?.subscriptionData?null:a.findActiveSubscriptionTestControl(),s=t?.subscriptionData?t:i?.hypothesis;if(!s?.subscriptionData)return;const r=t?.subscriptionData?e.testId:i.testId;a.subscriptionPriceDone=!0;const o=s.subscriptionData,n=s.isControl,l=s.priceData,c=o.widget.widgetType;let d=W(l),u=J(o,d),h=u.discountMap,p=u.maxDiscount;function b(){const g=W(l);g!==d&&(d=g,u=J(o,d),h=u.discountMap,p=u.maxDiscount,a.log(`[SUB-PRICE] scope refreshed side=${n?"A":"B"}, currentProductId=${d??"n/a"}, maxDiscount=${p}`))}a.log(`[SUB-PRICE] side=${n?"A":"B"}, currentProductId=${d??"n/a"}, maxDiscount=${p}`),a.updatePriceTestHiddenInputs(r,n?"control":"variant",!1);function E(){if(!l)return null;const g=j(l),P=Z(g),A=ce(o,P,d);if(!de(A,n))return null;const k=P?g.get(P):void 0;return k?{formattedVariantPrice:G(k.priceInCents,l),formattedDiscounted:G(k.priceInCents*(1-p/100),l)}:null}Fe({originalFetch:a.fetch,swapMap:a.swapMap??{},slptValue:a.slptValue??void 0,log:a.log,getSelectedPlanId:()=>{const g=B(o);if(!g)return null;const P=Y(o,g);if(!P)return null;const A=D(o,"subscriptionInput"),k=A.length?A[0].selector:'input[name="rc_plan"]';return P.querySelector(`${k}:checked`)?.value??null}});function S(g){const P=D(o,"subscriptionDiscount");for(const A of P)if(A.selector.includes("badge")||A.selector.includes("__badge")){const k=g.querySelector(A.selector);k?.textContent&&!k.textContent.includes(`${p}%`)&&$(k,x=>N(x,p))}}function C(g){const P=E();if(!P)return;const A=D(o,"subscriptionCompareAt");for(const k of A){const x=g.querySelector(k.selector)||g.querySelector(`[part~="${k.selector}"]`);x?.textContent&&!x.textContent.includes(P.formattedVariantPrice)&&$(x,R=>/\d/.test(R)?P.formattedVariantPrice:R)}}function _(g,P){const A=D(o,"subscriptionCompareAt"),k=P===0?"none":"";for(const x of A){const R=g.querySelector(x.selector)||g.querySelector(`[part~="${x.selector}"]`);R&&(k==="none"?R.style.display!=="none"&&(R.style.display="none"):R.style.display==="none"&&(R.style.display=""))}}function T(g){const P=D(o,"subscriptionInput"),A=P.length?P[0].selector:'input[name="rc_plan"]',k=D(o,"subscriptionPlanDiscount"),x=k.length?k[0].selector:".rc-plans-button__discount";for(const R of Array.from(g.querySelectorAll("label"))){const O=R.querySelector(A),V=R.querySelector(x);
43if(O&&V){const L=h[O.value];if(L!==void 0){if(L===0)V.style.display!=="none"&&(V.style.display="none");else if(V.style.display==="none"&&(V.style.display=""),V.textContent){const Q=V.textContent.match(/[\d.]+%/)?.[0];Q&&Q!==`${L}%`&&$(V,et=>N(et,L))}}}}}function m(g){const P=g.querySelector("select");if(P)for(const A of Array.from(P.options)){const k=h[A.value];if(k!==void 0&&A.textContent){const x=A.textContent.match(/[\d.]+%/)?.[0];x&&x!==`${k}%`&&(A.textContent=N(A.textContent,k))}}}function y(g,P){const k=D(o,"subscriptionDiscount").filter(x=>x.selector.includes("benefit")||x.selector==="rc-benefits");for(const x of k){const R=g.querySelector(x.selector);if(R?.shadowRoot){for(const O of Array.from(R.shadowRoot.querySelectorAll("li")))if(O.textContent?.includes("Save")){const V=O;if(P===0)V.style.display!=="none"&&(V.style.display="none");else{V.style.display==="none"&&(V.style.display="");const L=O.textContent.match(/[\d.]+%/)?.[0];L&&L!==`${P}%`&&$(O,Q=>N(Q,P))}}}}}let w=!1;function I(){if(!w){w=!0;try{if(b(),d!==null&&Object.keys(h).length===0)return;const g=B(o);if(!g)return;S(g),l&&C(g);const P=Y(o,g);let A=p;if(P){const k=D(o,"subscriptionInput"),x=k.length?k[0].selector:'input[name="rc_plan"]',R=P.querySelector(`${x}:checked`);if(R){const O=h[R.value];O!==void 0&&(A=O)}c==="buttons"||c==="radio"?T(P):m(P)}_(g,A),y(g,A)}finally{w=!1}}}function f(){const g=E();if(!g)return;const P=B(o);if(!P)return;const A=D(o,"onetimeToggle"),k=A.length?A[0].selector:'input[value="onetime"]';if(!P.querySelector(k)?.checked)return;const R=D(o,"subscriptionPrice");for(const O of R){const V=P.querySelector(O.selector)||P.querySelector(`[part~="${O.selector}"]`);V?.textContent&&!V.textContent.includes(g.formattedDiscounted)&&$(V,L=>/\d/.test(L)?g.formattedDiscounted:L)}}function v(){a.subscriptionHideWrongPlans&&a.subscriptionHideWrongPlans(),I(),a.subscriptionUpdateOneTime&&a.subscriptionUpdateOneTime(),f()}pe({data:o,runUpdates:v})}async function We(a){if(a.subscriptionOneTimeDone)return;const e=a.getActiveAssignment(),t=e?a.getHypothesis(e.hypothesisId):void 0,i=!!(t?.subscriptionData&&t.priceData),s=i?null:a.findActiveSubscriptionTestControl(),r=i?t:s?.hypothesis;if(!r?.subscriptionData||!r.priceData)return;const o=i?e.testId:s.testId;a.subscriptionOneTimeDone=!0;const n=r.subscriptionData,l=r.priceData,c=j(l),d=r.isControl,u=d?"control":"variant";a.slptValue=`${o}:${u}:f`,a.updatePriceTestHiddenInputs(o,u,!1);function h(){const p=B(n);if(!p)return;const b=Z(c);if(!b)return;const E=W(l),S=ce(n,b,E);if(!de(S,d))return;const C=c.get(b);if(!C)return;const _=H(C.priceInCents,l.moneyFormat,l.currency,l.currencyCodeEnabled),T=D(n,"onetimePrice");if(!T.length)return;const m=D(n,"onetimeContainer"),y=m.length?m[0].selector:'[part~="rc-purchase-option__onetime"]',I=p.querySelector(y)??p;for(const f of T){let v=null;try{v=I.querySelector(f.selector)}catch{v=null}v??=I.querySelector(`[part~="${f.selector}"]`),v&&v.textContent&&!v.textContent.includes(_)&&$(v,g=>/\d/.test(g)?_:g)}}a.subscriptionUpdateOneTime=h,h()}async function Ge(a,e){const{subscriptionPreviewRender:t}=await Ne(async()=>{const{subscriptionPreviewRender:i}=await Promise.resolve().then(()=>Xe);return{subscriptionPreviewRender:i}},void 0);return t(a.subscriptionData,a.priceData,a.isControl,e)}function je(a,e){const t=a.widget.selectors.widgetParent??[],i=a.widget.selectors.subscriptionPlans??[],s=a.widget.selectors.subscriptionInput??[];if(!t.length||!i.length||!s.length){e("[SUB-GLOBAL-HIDE] Missing required selectors — skipping");return}const r=t[0].selector,o=i[0].selector,n=s[0].selector;let l=!1,c=null,d=!1;function u(){if(!d){d=!0;try{h()}finally{d=!1}}}function h(){const C=document.querySelector(r);if(!C?.shadowRoot)return;const _=C.shadowRoot.querySelector(o);if(!_?.shadowRoot)return;_.shadowRoot!==c&&(c=_.shadowRoot,l=!1);let T=0;if(a.widget.widgetType==="buttons"||a.widget.widgetType==="radio"){const m=Array.from(_.shadowRoot.querySelectorAll(n));for(const f of m)if(a.planIds.includes(f.value)){f.disabled||(f.disabled=!0);const v=f.closest("label");v&&v.style.display!=="none"&&(v.style.display="none",T++)}const y=m.filter(f=>!a.planIds.includes(f.value));if(!y.some(f=>f.checked)&&!l&&y.length>0){l=!0;const f=y[0];f.closest("label")?.click(),f.dispatchEvent(new Event("change",{bubbles:!0})),e(`[SUB-GLOBAL-HIDE] Preselected first visible plan input=${f.value}`)}const I=y.find(f=>f.checked)??y[0];
43if(I){const f=Array.from(document.querySelectorAll('input[name="selling_plan"]'));for(const v of f)v.value!==I.value&&(v.value=I.value,e(`[SUB-GLOBAL-HIDE] Mirrored plan id ${I.value} to form selling_plan input`))}}else if(a.widget.widgetType==="dropdown"){const m=_.shadowRoot.querySelector("select");if(!m)return;for(const I of Array.from(m.options))a.planIds.includes(I.value)&&(I.style.display!=="none"&&(I.style.display="none"),I.disabled||(I.disabled=!0),T++);const y=Array.from(m.options).filter(I=>!a.planIds.includes(I.value)),w=y.some(I=>I.value===m.value);y.length>0&&!w&&!l&&(l=!0,m.value=y[0].value,m.dispatchEvent(new Event("change",{bubbles:!0})),e(`[SUB-GLOBAL-HIDE] Preselected first visible option=${y[0].value}`))}T>0&&e(`[SUB-GLOBAL-HIDE] Hidden ${T} B-side plan buttons`)}const p={childList:!0,subtree:!0,characterData:!0};let b=null;function E(C){b?.disconnect(),b=new MutationObserver(()=>u()),b.observe(C,p)}function S(){const C=document.querySelector(r);if(!C?.shadowRoot)return!1;u(),new MutationObserver(()=>{u();const m=C.shadowRoot.querySelector(o);m?.shadowRoot&&E(m.shadowRoot)}).observe(C.shadowRoot,p);const T=C.shadowRoot.querySelector(o);return T?.shadowRoot&&E(T.shadowRoot),!0}if(!S()){e("[SUB-GLOBAL-HIDE] Widget not in DOM yet — waiting via MutationObserver");const C=new MutationObserver(()=>{S()&&C.disconnect()});C.observe(document.body??document.documentElement,{childList:!0,subtree:!0})}}const ue="Limited preview",Ke="Add-to-cart and checkout prices won't reflect this test until it launches — test selling plans are not created in your subscription app until after a test is launched.",Je=5e3;function Ye(){const a=document.createElement("div");a.id="shoplift-preview-subscription-warning";const e=document.createElement("span");e.id="shoplift-preview-subscription-warning__icon",e.setAttribute("aria-hidden","true"),e.textContent="!";const t=document.createElement("span");t.id="shoplift-preview-subscription-warning__label",t.textContent=ue;const i=document.createElement("div");i.id="shoplift-preview-subscription-warning__tooltip",i.setAttribute("role","tooltip"),i.textContent=Ke,a.appendChild(e),a.appendChild(t),a.appendChild(i),a.setAttribute("tabindex","0"),a.setAttribute("aria-describedby",i.id),a.setAttribute("aria-label",ue);let s=null;function r(){s!==null&&(clearTimeout(s),s=null)}function o(){i.classList.add("shoplift-preview-subscription-warning__tooltip--visible")}function n(){i.classList.remove("shoplift-preview-subscription-warning__tooltip--visible")}function l(){o(),r(),s=setTimeout(()=>{n(),s=null},Je)}function c(){r(),o()}function d(){s===null&&n()}a.addEventListener("mouseenter",c),a.addEventListener("mouseleave",d),a.addEventListener("focus",c),a.addEventListener("blur",d);function u(p){try{const b=p.target;if(!(b instanceof Element))return;(b.closest('form[action*="/cart/add"] button[type="submit"], form[action*="/cart/add"] input[type="submit"]')!==null||b.closest('[name="add"], button[name="add"], [data-add-to-cart], button[data-add-to-cart]')!==null)&&l()}catch{}}document.addEventListener("click",u,!0);function h(){r(),document.removeEventListener("click",u,!0),a.removeEventListener("mouseenter",c),a.removeEventListener("mouseleave",d),a.removeEventListener("focus",c),a.removeEventListener("blur",d),a.remove()}return{root:a,tooltip:i,cleanup:h}}let he=!1;class Ze{DATA_SL_ATTRIBUTE_P="data-sl-attribute-p";DATA_SL_TEST_ID="data-sl-test-id";VIEWPORT_TRACK_THRESHOLD=.5;temporarySessionKey="Shoplift_Session";essentialSessionKey="Shoplift_Essential";analyticsSessionKey="Shoplift_Analytics";priceSelectorsSessionKey="Shoplift_PriceSelectors_v2";shop;host;eventHost;disableReferrerOverride;legacySessionKey;cssHideClass;testConfigs;inactiveTestConfigs;hiddenSubscriptionPlans;testsFilteredByAudience;sendPageView;shopliftDebug;gaConfig;telemetryEnabled;getCountryTimeout;geoViaShopify;resolvedRegion=null;state;subscriptionPreviewWarningCleanup=null;shopifyAnalyticsId;cookie=document.cookie;isSyncing=!1;isSyncingGA=!1;fetch;localStorageSet;localStorageGet;sessionStorageSet=window.sessionStorage.setItem.bind(window.sessionStorage);sessionStorageGet=window.sessionStorage.getItem.bind(window.sessionStorage);
43urlParams=new URLSearchParams(window.location.search);device;logHistory;activeViewportObservers=new Map;clientIdRetryCount=0;constructor(e,t,i,s,r,o,n,l,c,d,u,h,p,b=!1){this.shop=e,this.host=t,this.eventHost=i,this.disableReferrerOverride=l,this.logHistory=[],this.legacySessionKey=`SHOPLIFT_SESSION_${this.shop}`,this.cssHideClass=s?"shoplift-hide":"",this.testConfigs=u.map(S=>({...S,startAt:new Date(S.startAt),statusHistory:S.statusHistory.map(C=>({...C,createdAt:new Date(C.createdAt)}))})),this.inactiveTestConfigs=h,this.hiddenSubscriptionPlans=p,this.sendPageView=!!r,this.shopliftDebug=o===!0,this.telemetryEnabled=c===!0,this.geoViaShopify=b===!0,this.gaConfig=n!=={"sendEvents":false,"mode":"gtag"}?n:{sendEvents:!1},this.fetch=window.fetch.bind(window),this.localStorageSet=window.localStorage.setItem.bind(window.localStorage),this.localStorageGet=window.localStorage.getItem.bind(window.localStorage);const E=this.getDeviceType();this.device=E!=="tablet"?E:"mobile",this.state=this.loadState(),this.shopifyAnalyticsId=this.getShopifyAnalyticsId(),this.testsFilteredByAudience=u.filter(S=>
43S.status=="active"),this.getCountryTimeout=d===1000?1e3:d,window.__slReadCookie=S=>{const C=this.getCookie(S);if(C===null)return null;try{return decodeURIComponent(C)}catch{return C}},this.log("State Loaded",JSON.stringify(this.state))}deriveCategoryFromExistingTests(){if(!this.state.temporary.testCategory&&this.state.essential.visitorTests.length>0){const e=this.state.essential.visitorTests.some(t=>{if(!t.hypothesisId)return!1;const i=this.getHypothesis(t.hypothesisId);return i&&["theme","basicScript","price"].includes(i.type)});this.state.temporary.testCategory=e?"global":"conditional",this.persistTemporaryState(),this.log("Derived test category from existing visitorTests: %s",this.state.temporary.testCategory)}}async init(){try{if(this.log("Shoplift script initializing"),window.Shopify&&window.Shopify.designMode){this.log("Skipping script for design mode");return}if(window.location.href.includes("slScreenshot=true")){this.log("Skipping script for screenshot");return}if(window.location.hostname.endsWith(".edgemesh.com")){this.log("Skipping script for preview");return}if(window.location.href.includes("isShopliftMerchant")){const o=this.urlParams.get("isShopliftMerchant")==="true";this.log("Setting merchant session to %s",o),this.state.temporary.isMerchant=o,this.persistTemporaryState()}if(this.state.temporary.isMerchant){this.log("Setting up preview for merchant"),typeof window.shoplift!="object"&&this.setShopliftStub(),this.state.temporary.previewConfig||this.hidePage(),await this.initPreview(),document.querySelector("#sl-preview-bar-hide")?.remove();return}if(this.state.temporary.previewConfig=void 0,we(navigator.userAgent))return;const e=Date.now(),t=!this.state.temporary.lastSeen||e-this.state.temporary.lastSeen>1800*1e3;(!this.state.temporary.entryPage||t)&&(this.state.temporary.entryPage=K(window.location.href)),this.state.temporary.lastSeen=e,this.persistTemporaryState(),window.__slEntryPage=this.state.temporary.entryPage??"";const i=this.state.essential.visitorTests.filter(o=>o.hypothesisId&&+o.createdAt>Date.now()-6e4);if(i.length===0)this.sendDiagnosticTelemetry("page-landed",null);else for(const o of i)this.sendDiagnosticTelemetry("page-landed",o.testId,{hypothesisId:o.hypothesisId,isControl:o.assignedTo==="control",testType:o.testType??"unknown"});if(navigator.userAgent.includes("Chrome/118")){this.log("Random: %o",[Math.random(),Math.random(),Math.random()]);const o=await this.makeRequest({url:`${this.eventHost}/api/v0/events/ip`,method:"get"}).then(n=>n?.json());this.log(`IP: ${o}`),this.makeRequest({url:`${this.eventHost}/api/v0/logs`,method:"post",data:JSON.stringify(this.debugState(),ee)}).catch()}if(this.shopifyAnalyticsId=this.getShopifyAnalyticsId(),this.monitorConsentChange(),this.checkForThemePreview())return;if(!this.disableReferrerOverride&&this.state.temporary.originalReferrer!=null){this.log(`Overriding referrer from '${document.referrer}' to '${this.state.temporary.originalReferrer}'`);const o=this.state.temporary.originalReferrer;delete this.state.temporary.originalReferrer,this.persistTemporaryState(),Object.defineProperty(document,"referrer",{get:()=>o,enumerable:!0,configurable:!0})}if(await this.refreshVisitor(this.shopifyAnalyticsId),await this.handleVisitorTest()){this.log("Redirecting for visitor test");return}this.setShoplift(),this.showPage(),this.ensureCartAttributesForExistingPriceTests(!1);const r=this.state.essential.visitorTests.some(o=>(o.hypothesisId?this.getHypothesis(o.hypothesisId):void 0)?.subscriptionData!=null)||Object.values(this.state.temporary.testReservations??{}).some(o=>this.getHypothesis(o.hypothesisId)?.subscriptionData!=null);this.hiddenSubscriptionPlans&&!r&&(this.log(`[SUB-GLOBAL] Visitor not in subscription test — hiding ${this.hiddenSubscriptionPlans.planIds.length} B-side plans`),je(this.hiddenSubscriptionPlans,o=>this.log(o))),await this.subscriptionSwap(),await this.subscriptionOneTimePrice(),await this.subscriptionPriceChange(),await this.finalize(),console.log("SHOPLIFT SCRIPT INITIALIZED!")}catch(e){if(e instanceof ie)return;throw e}finally{typeof window.shoplift!="object"&&this.setShopliftStub()}}getVariantColor(e){switch(e){case"a":return{text:"#141414",bg:"#E2E2E2"};case"b":return{text:"rgba(255, 255, 255, 1)",bg:"rgba(37, 99, 235, 1)"}}}getDefaultVariantTitle(e){return e.title?e.title:e.type==="price"?e.isControl?"Original prices":"Variant prices":e.isControl?"Original":"Untitled variant "+e.label.toUpperCase()}
43async initPreview(){const e=this.urlParams.get("previewConfig");if(e){this.state.temporary.previewConfig=void 0,this.log("Setting up the preview"),this.log("Found preview config, writing to temporary state");const t=await Oe(e);if(this.state.temporary.previewConfig=t,this.state.temporary.previewConfig.testTypeCategory===M.Price){this.hidePage(!0);const s=this.state.temporary.previewConfig;let r=`${this.host}/api/dom-selectors/${s.storeId}/${s.testId}/${s.isDraft||!1}`;s.shopifyProductId&&(r+=`?productId=${s.shopifyProductId}`);const o=await this.makeJsonRequest({method:"get",url:r}).catch(n=>(this.log("Error getting domSelectors",n),null));if(s.variants.forEach(n=>n.domSelectors=o[n.id]?.domSelectors),s.isDraft){const n=`${this.host}/api/dom-selectors/${s.storeId}/${s.testId}/subscription-preview`,l=await this.makeJsonRequest({method:"get",url:n}).catch(c=>(this.log("No subscription preview data for draft (test may not have a subscription widget)",c),null));l?.subscriptionData&&s.variants.forEach(c=>{c.subscriptionData=l.subscriptionData,c.priceData=l.priceData})}}this.persistTemporaryState();const i=new URL(window.location.toString());i.searchParams.delete("previewConfig"),this.queueRedirect(i)}else if(this.state.temporary.previewConfig){this.showPage();const t=this.state.temporary.previewConfig;if(t.testTypeCategory===M.Template&&this.handleTemplatePreview(t)&&this.initPreviewControls(t),t.testTypeCategory===M.UrlRedirect&&this.handleUrlPreview(t)&&this.initPreviewControls(t),t.testTypeCategory===M.Script&&this.handleScriptPreview(t)&&this.initPreviewControls(t),t.testTypeCategory===M.Price){const i=await this.handlePricePreview(t);t.isDraft?await this.handleSubscriptionPricePreview(t):await this.handleSubscriptionLivePreview(t),i&&this.initPreviewControls(t)}}}initPreviewControls(e){document.addEventListener("DOMContentLoaded",()=>{const t=e.variants.find(b=>b.id===e.currentVariant),i=t?.label||"a",s=e.variants,r=document.createElement("div");r.id="shoplift-preview-control";const o=document.createElement("div"),n=document.createElement("img");n.src=Ve,n.height=24,n.width=14,o.style.padding="0 16px",o.style.lineHeight="100%",o.appendChild(n),r.appendChild(o);const l=document.createElement("div");l.id="shoplift-preview-variant-selector";const c=document.createElement("button");c.id="shoplift-preview-variant-menu-trigger";const d=document.createElement("div");d.className="menu-variant-label",d.style.backgroundColor=this.getVariantColor(i).bg,d.style.color=this.getVariantColor(i).text,d.innerText=i.toUpperCase(),c.appendChild(d);const u=document.createElement("span");if(u.id="shoplift-preview-variant-title",u.innerText=t?this.getDefaultVariantTitle(t):"Untitled variant "+i.toUpperCase(),c.appendChild(u),s.length>1){const b=document.createElement("img");b.src=De,b.width=12,b.height=12,b.style.height="12px",b.style.width="12px",c.appendChild(b);const E=document.createElement("div");E.className="preview-variant-menu";for(const S of e.variants.filter(C=>C.id!==e.currentVariant)){const C=document.createElement("div");C.className="preview-variant-menu--item";const _=document.createElement("div");_.className="menu-variant-label",_.style.backgroundColor=this.getVariantColor(S.label).bg,_.style.color=this.getVariantColor(S.label).text,_.style.flexShrink="0",_.innerText=S.label.toUpperCase(),C.appendChild(_);const T=document.createElement("span");T.innerText=this.getDefaultVariantTitle(S),C.appendChild(T),C.addEventListener("click",()=>{this.pickVariant(S.id)}),E.appendChild(C)}l.appendChild(E),c.addEventListener("click",()=>{E.className!=="preview-variant-menu preview-variant-menu__visible"?E.classList.add("preview-variant-menu__visible"):E.classList.remove("preview-variant-menu__visible")}),document.addEventListener("click",S=>{S.target instanceof Element&&!c.contains(S.target)&&E.className==="preview-variant-menu preview-variant-menu__visible"&&E.classList.remove("preview-variant-menu__visible")})}else c.style.pointerEvents="none",d.style.margin="0";if(l.appendChild(c),r.appendChild(l),e.hasSubscription){this.subscriptionPreviewWarningCleanup?.();const b=Ye();r.appendChild(b.root),this.subscriptionPreviewWarningCleanup=b.cleanup}const h=document.createElement("div"),p=document.createElement("button");p.id="shoplift-exit-preview-button",p.innerText="Exit",h.appendChild(p),p.addEventListener("click",()=>{this.exitPreview()}),r.appendChild(h),document.body.appendChild(r),requestAnimationFrame(()=>{r.classList.add("visible")})}),this.ensureCartAttributesForExistingPriceTests(!0)}pickVariant(e){if(this.state.temporary.previewConfig){const t=this.state.temporary.previewConfig,i=new URL(window.location.toString());if(t.testTypeCategory===M.UrlRedirect){const s=t.variants.find(r=>r.id===t.currentVariant)?.redirectUrl;if(i.pathname===s){const r=t.variants.find(o=>o.id===e)?.redirectUrl;r&&(i.pathname=r)}}if(t.testTypeCategory===M.Template){const s=t.variants.find(r=>r.id===t.currentVariant)?.pathName;if(s&&i.pathname===s){const r=t.variants.find(o=>o.id===e)?.pathName;r&&r!==s&&(i.pathname=r)}}t.currentVariant=e,this.persistTemporaryState(),this.queueRedirect(i)}}exitPreview(){const e=new URL(window.location.toString());if(this.state.temporary.previewConfig?.testTypeCategory===M.Template&&e.searchParams.delete("view"),this.state.temporary.previewConfig?.testTypeCategory===M.Script&&e.searchParams.delete("slVariant"),this.state.temporary.previewConfig?.testTypeCategory===M.UrlRedirect){const i=this.state.temporary.previewConfig.variants.filter(r=>!r.isControl&&r.redirectUrl!==null).map(r=>r.redirectUrl),s=this.state.temporary.previewConfig.variants.find(r=>r.label==="a")?.redirectUrl;i.includes(e.pathname)&&s&&(e.pathname=s)}this.state.temporary.isMerchant=!1,e.searchParams.delete("isShopliftMerchant"),this.state.temporary.previewConfig=void 0,this.persistTemporaryState(),this.subscriptionPreviewWarningCleanup?.(),this.subscriptionPreviewWarningCleanup=null,this.hidePage(),this.queueRedirect(e)}handleTemplatePreview(e){const t=e.currentVariant,i=e.variants.find(l=>l.id===t);if(!i)return!1;const s=e.variants.find(l=>l.isControl);if(!s)return!1;this.log("Setting up template preview for type",s.type);
43const r=new URL(window.location.toString()),o=r.searchParams.get("view"),n=i.type===s.type;return!n&&!i.isControl&&template.suffix===s.affix&&this.typeFromTemplate()===s.type&&i.pathName!==null?(this.log("Hit control template type, redirecting to the variant url"),this.hidePage(),r.pathname=i.pathName,this.queueRedirect(r),!0):(!i.isControl&&this.typeFromTemplate()==i.type&&template.suffix===s.affix&&n&&o!==(i.affix||"__DEFAULT__")&&(this.log("Template type and affix match control, updating the view param"),r.searchParams.delete("view"),this.log("Setting the new viewParam to",i.affix||"__DEFAULT__"),this.hidePage(),r.searchParams.set("view",i.affix||"__DEFAULT__"),this.queueRedirect(r)),o!==null&&o!==(i.affix||"__DEFAULT__")&&(r.searchParams.delete("view"),this.hidePage(),this.queueRedirect(r)),!0)}handleUrlPreview(e){const t=e.currentVariant,i=e.variants.find(o=>o.id===t),s=e.variants.find(o=>o.isControl)?.redirectUrl;if(!i)return!1;this.log("Setting up URL redirect preview");const r=new URL(window.location.toString());return r.pathname===s&&!i.isControl&&i.redirectUrl!==null&&(this.log("Url matches control, redirecting"),this.hidePage(),r.pathname=i.redirectUrl,this.queueRedirect(r)),!0}handleScriptPreview(e){const t=e.currentVariant,i=e.variants.find(o=>o.id===t);if(!i)return!1;this.log("Setting up script preview");const s=new URL(window.location.toString());return s.searchParams.get("slVariant")!==i.id&&(this.log("current id doesn't match the variant, redirecting"),s.searchParams.delete("slVariant"),this.log("Setting the new slVariantParam"),this.hidePage(),s.searchParams.set("slVariant",i.id),this.queueRedirect(s)),!0}async handlePricePreview(e){const t=e.currentVariant,i=e.variants.find(s=>s.id===t);return i?(this.log("Setting up price preview"),i.domSelectors&&i.domSelectors.length>0&&(U(document,{testId:e.testId,hypothesisId:i.id,selectors:i.domSelectors}),this.ensureCartAttributesForExistingPriceTests(!0)),!0):!1}async handleSubscriptionPricePreview(e){const t=e.variants.find(i=>i.id===e.currentVariant);t?.subscriptionData&&(this.log("Setting up subscription price preview"),await Ge({id:t.id,isControl:t.isControl,subscriptionData:t.subscriptionData,priceData:t.priceData},(i,...s)=>this.log(i,...s)))}async handleSubscriptionLivePreview(e){this.testConfigs.find(s=>s.id===e.testId)?.hypotheses.find(s=>s.id===e.currentVariant)?.subscriptionData&&(this.log("Setting up subscription live preview"),this.subscriptionSwapDone=!1,this.subscriptionOneTimeDone=!1,this.subscriptionPriceDone=!1,await this.subscriptionSwap(),await this.subscriptionOneTimePrice(),await this.subscriptionPriceChange())}async finalize(){const e=await this.getCartState();e!==null&&this.queueCartUpdate(e),this.pruneStateAndSave(),await this.syncAllEvents()}setShoplift(){this.log("Setting up public API");const t=this.urlParams.get("slVariant")==="true",i=t?null:this.urlParams.get("slVariant");window.shoplift={isHypothesisActive:async s=>{if(this.log("Script checking variant for hypothesis '%s'",s),t)return this.log("Forcing variant for hypothesis '%s'",s),!0;if(i!==null)return this.log("Forcing hypothesis '%s'",i),s===i;const r=this.testConfigs.find(n=>n.hypotheses.some(l=>l.id===s));if(!r)return this.log("No test found for hypothesis '%s'",s),!1;const o=this.state.essential.visitorTests.find(n=>n.testId===r.id);return o?(this.log("Active visitor test found",s),o.hypothesisId===s):(await this.manuallySplitVisitor(r),this.testConfigs.some(n=>n.hypotheses.some(l=>l.id===s&&this.state.essential.visitorTests.some(c=>c.hypothesisId===l.id))))},setAnalyticsConsent:async s=>{await this.onConsentChange(s,!0)},getVisitorData:()=>({visitor:this.state.analytics.visitor,visitorTests:this.state.essential.visitorTests.filter(s=>!s.isInvalid).map(s=>{const{shouldSendToGa:r,savedAt:o,...n}=s;return n})})}}setShopliftStub(){this.log("Setting up stubbed public API");const t=this.urlParams.get("slVariant")==="true",i=t?null:this.urlParams.get("slVariant");window.shoplift={isHypothesisActive:s=>Promise.resolve(t||s===i),setAnalyticsConsent:()=>Promise.resolve(),getVisitorData:()=>({visitor:null,visitorTests:[]})}}async manuallySplitVisitor(e){this.log("Starting manual split for test '%s'",e.id),await this.handleVisitorTest([e]);const t=this.getReservationForTest(e.id);t&&!t.isRealized&&t.entryCriteriaKey&&(this.log("Realizing manual API reservation for test '%s'",e.id),this.realizeReservationForCriteria(t.entryCriteriaKey)),this.saveState(),this.syncAllEvents()}async handleVisitorTest(e){await this.filterTestsByAudience(this.testConfigs,this.state.analytics.visitor??this.buildBaseVisitor(),this.state.essential.visitorTests),this.pruneStaleVisitorTests(),this.deriveC
43ategoryFromExistingTests(),this.clearStaleReservations();let t=e?e.filter(i=>this.testsFilteredByAudience.some(s=>s.id===i.id)):[...this.testsForUrl(this.testsFilteredByAudience),...this.domTestsForUrl(this.testsFilteredByAudience)];try{if(t.length===0)return this.log("No tests found"),!1;this.log("Checking for existing visitor test on page");const i=this.getCurrentVisitorHypothesis(t);if(i){this.log("Found current visitor test");const l=this.considerRedirect(i);return l&&(this.log("Redirecting for current visitor test"),this.redirect(i)),l}const s=this.getReservationForCurrentPage();if(s){this.log("Found matching reservation for current page: %s",s.testId);const l=this.getHypothesis(s.hypothesisId);if(l){l.type!=="price"&&this.realizeReservationForCriteria(s.entryCriteriaKey);const c=this.considerRedirect(l);return c&&this.redirect(l),c}}this.log("No active test relation for test page");const r=this.testsForUrl(this.inactiveTestConfigs.filter(l=>this.testIsPaused(l)&&l.hypotheses.some(c=>this.state.essential.visitorTests.some(d=>d.hypothesisId===c.id)))).map(l=>l.id);if(r.length>0)return this.log("Visitor has paused tests for test page, skipping test assignment: %o",r),!1;if(!this.state.temporary.testCategory){const l=this.testsFilteredByAudience.filter(d=>this.isGlobalEntryCriteria(this.getEntryCriteriaKey(d))),c=this.testsFilteredByAudience.filter(d=>!this.isGlobalEntryCriteria(this.getEntryCriteriaKey(d)));if(this.log("Category dice roll - global tests: %o, conditional tests: %o",l.map(d=>({id:d.id,title:d.title,criteria:this.getEntryCriteriaKey(d)})),c.map(d=>({id:d.id,title:d.title,criteria:this.getEntryCriteriaKey(d)}))),l.length>0&&c.length>0){const d=l.length,u=c.length,h=d+u,p=Math.random()*h;this.state.temporary.testCategory=p<d?"global":"conditional",this.log("Category dice roll: rolled %.2f of %d (global weight: %d, conditional weight: %d), selected '%s'",p,h,d,u,this.state.temporary.testCategory)}else l.length>0?(this.state.temporary.testCategory="global",this.log("Only global tests available, setting category to global")):(this.state.temporary.testCategory="conditional",this.log("Only conditional tests available, setting category to conditional"));this.persistTemporaryState()}const o=this.state.temporary.testCategory;if(this.log("Visitor test category: %s",o),o==="global"){const l=this.testsFilteredByAudience.filter(c=>!this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)));for(const c of l)this.markTestAsBlocked(c,"category:global");t=t.filter(c=>this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)))}else{const l=this.testsFilteredByAudience.filter(c=>this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)));for(const c of l)this.markTestAsBlocked(c,"category:conditional");t=t.filter(c=>!this.isGlobalEntryCriteria(this.getEntryCriteriaKey(c)))}if(t.length===0)return this.log("No tests remaining after category filter"),!1;this.createReservations(t);const n=this.getReservationForCurrentPage();if(n&&!n.isRealized){const l=this.getHypothesis(n.hypothesisId);if(l){l.type!=="price"&&this.realizeReservationForCriteria(n.entryCriteriaKey);const c=this.considerRedirect(l);return c&&(this.log("Redirecting for new test"),this.redirect(l)),c}}return!1}finally{this.includeInDomTests(),this.saveState()}}includeInDomTests(){this.applyControlForAudienceFilteredPriceTests();const e=this.getDomTestsForCurrentUrl(),t=this.getVisitorDomHypothesis(e);for(const i of e){this.log("Evaluating dom test '%s'",i.id);const s=i.hypotheses.some(p=>p.type==="price");if(this.state.essential.visitorTests.find(p=>p.testId===i.id&&p.isInvalid&&!p.hypothesisId)){if(this.log("Visitor is blocked from test '%s', applying control prices if price test",i.id),s){const p=i.hypotheses.find(b=>b.isControl);p?.priceData&&(this.applyPriceTestWithMapLookup(i.id,p,[p],()=>{this.log("Control prices applied for blocked visitor, no metrics tracked")}),this.updatePriceTestHiddenInputs(i.id,"control",!1))}continue}const o=this.getReservationForTest(i.id);let n=null,l=!1;const c=t.find(p=>i.hypotheses.some(b=>p.id===b.id));if(o)n=this.getHypothesis(o.hypothesisId)??null,this.log("Using reserved hypothesis '%s' for test '%s'",o.hypothesisId,i.id);else if(c)n=c,this.log("Using existing hypothesis assignment for test '%s'",i.id);else if(s){const p=this.visitorActiveTestTypeWithReservations();p?(l=!0,this.log("Visitor already in test type '%s', treating as non-test for price test '%s'",p,i.id)):n=this.pickHypothesis(i)}else n=this.pickHypothesis(i);if(l&&s){const p=i.hypotheses.find(b=>b.isControl);p?.priceData&&(this.log("Applying control prices for non-test visitor on price test '%s' (Map-based)",i.id),this.applyPriceTestWithMapLookup(i.id,p,[p],()=>{this.log("Control prices applied for non-test visitor, no metrics tracked")}
43),this.updatePriceTestHiddenInputs(i.id,"control",!1));continue}if(!n){this.log("Failed to pick hypothesis for test");continue}this.sendDiagnosticTelemetry("assignment",i.id,{hypothesisId:n.id,isControl:n.isControl,testType:n.type});const d=i.bayesianRevision??4,u=n.type==="price",h=d>=5;if(u&&h){if(this.log(`Price test with Map-based lookup (v${d}): ${i.id}`),!n.priceData){this.log("No price data for hypothesis '%s', skipping",n.id);continue}const p=n.isControl?"control":"variant";this.log(`Setting up Map-based price test for ${p} (test: ${i.id})`),this.applyPriceTestWithMapLookup(i.id,n,i.hypotheses,b=>{const E=this.getReservationForTest(b);E&&!E.isRealized&&E.entryCriteriaKey?this.realizeReservationForCriteria(E.entryCriteriaKey):this.queueAddVisitorToTest(b,n),this.saveState(),this.queuePageView(window.location.pathname),this.syncAllEvents()});continue}if(u&&!h){this.log(`Price test without viewport tracking (v${d}): ${i.id}`);const p=this.getDomSelectorsForHypothesis(n);if(p.length===0)continue;U(document,{testId:i.id,hypothesisId:n.id,selectors:p},b=>{this.queueAddVisitorToTest(b,n),this.saveState(),this.queuePageView(window.location.pathname),this.syncAllEvents()});continue}if(!n.domSelectors||n.domSelectors.length===0){this.log("No selectors found, skipping hypothesis");continue}U(document,{testId:i.id,hypothesisId:n.id,selectors:n.domSelectors},p=>{this.queueAddVisitorToTest(p,n),this.saveState(),this.queuePageView(window.location.pathname),this.syncAllEvents()})}}considerRedirect(e){if(this.log("Considering redirect for hypothesis '%s'",e.id),e.isControl)return this.log("Skipping redirect for control"),!1;if(e.type==="basicScript"||e.type==="manualScript")return this.log("Skipping redirect for script test"),!1;const t=this.state.essential.visitorTests.find(o=>o.hypothesisId===e.id),i=new URL(window.location.toString()),r=new URLSearchParams(window.location.search).get("view");if(e.type==="theme"){if(!(e.themeId===themeId)){if(this.log("Theme id '%s' is not hypothesis theme ID '%s'",e.themeId,themeId),this.isAppProxyPath())return this.log("On App Proxy path, skipping theme redirect to avoid infinite loop"),!1;if(t&&t.themeId!==e.themeId&&(t.themeId===themeId||!this.isThemePreview()))this.log("On old theme, redirecting and updating local visitor"),t.themeId=e.themeId;else if(this.isThemePreview())return this.log("On non-test theme, skipping redirect"),!1;return this.log("Hiding page to redirect for theme test"),this.hidePage(),!0}return!1}else if(e.type!=="dom"&&e.type!=="price"&&e.affix!==template.suffix&&e.affix!==r||e.redirectPath&&!i.pathname.endsWith(e.redirectPath))return this.log("Hiding page to redirect for template test"),this.hidePage(),!0;return this.log("Not redirecting"),!1}redirect(e){if(this.log("Redirecting to hypothesis '%s'",e.id),e.isControl)return;const t=new URL(window.location.toString());if(t.searchParams.delete("view"),e.redirectPath){const n=RegExp("^(/w{2}-w{2})/").exec(t.pathname);if(n&&n.length>1){const l=n[1];t.pathname=`${l}${e.redirectPath}`}else t.pathname=e.redirectPath}else e.type==="theme"?(t.searchParams.set("_ab","0"),t.searchParams.set("_fd","0"),t.searchParams.set("_sc","1"),t.searchParams.set("preview_theme_id",e.themeId.toString())):e.type!=="urlRedirect"&&t.searchParams.set("view",e.affix);const i=this.state.essential.visitorTests.find(n=>n.hypothesisId===e.id)?.testId,s=t.pathname+t.search,r=window.location.pathname+window.location.search,o=K(t.hash);if(i&&s!==r&&!o){const n=qe(),l=He({v:2,t:i,n,fh:Me(window.location.pathname+window.location.search)});t.hash=`slr-${n}`;const c=new Date(Date.now()+3e4).toUTCString();document.cookie=`shoplift_redirect=${l};domain=.${window.location.hostname};path=/;SameSite=Strict;expires=${c}`}s===r&&this.showPage(),this.queueRedirect(t)}async refreshVisitor(e){if(e===null||!this.state.essential.isFirstLoad||!this.testConfigs.some(i=>i.visitorOption!=="all"))return;this.log("Refreshing visitor"),this.hidePage();const t=await this.getVisitor(e);t&&t.id&&this.updateLocalVisitor(t)}buildBaseVisitor(){return{shopifyAnalyticsId:this.shopifyAnalyticsId,device:this.device,country:null,...this.state.essential.initialState}}getInitialState(){const e=this.getUTMValue("utm_source")??"",t=this.getUTMValue("utm_medium")??"",i=this.getUTMValue("utm_campaign")??"",s=this.getUTMValue("utm_content")??"",r=window.document.referrer,o=this.device;return{createdAt:new Date,utmSource:e,utmMedium:t,utmCampaign:i,utmContent:s,referrer:r,device:o}}checkForThemePreview(){return this.log("Checking for theme preview"),window.location.hostname.endsWith(".shopifypreview.com")?(this.log("on shopify preview domain"),this.clearThemeBar(!0,!1,this.state),document.querySelector("#sl-preview-bar-hide")?.remove(),!1):this.isThemePreview()?this.state.essential.visitorTests.some(e=>e.isThemeTest&&e.hypothesisId!=null&&this.getHypothesis(e.hypothesisId)&&e.themeId===themeId)?(this.log("On active theme test, remov
43ing theme bar"),this.clearThemeBar(!1,!0,this.state),!1):this.state.essential.visitorTests.some(e=>e.isThemeTest&&e.hypothesisId!=null&&!this.getHypothesis(e.hypothesisId)&&e.themeId===themeId)?(this.log("Visitor is on an inactive theme test, redirecting to main theme"),this.redirectToMainTheme(),!0):this.state.essential.isFirstLoad?(this.log("No visitor found on theme preview, redirecting to main theme"),this.redirectToMainTheme(),!0):this.inactiveTestConfigs.some(e=>e.hypotheses.some(t=>t.themeId===themeId))?(this.log("Current theme is an inactive theme test, redirecting to main theme"),this.redirectToMainTheme(),!0):this.testConfigs.some(e=>e.hypotheses.some(t=>t.themeId===themeId))?(this.log("Falling back to clearing theme bar"),this.clearThemeBar(!1,!0,this.state),!1):(this.log("No tests on current theme, skipping script"),this.clearThemeBar(!0,!1,this.state),document.querySelector("#sl-preview-bar-hide")?.remove(),!0):(this.log("Not on theme preview"),this.clearThemeBar(!0,!1,this.state),!1)}redirectToMainTheme(){this.hidePage();const e=new URL(window.location.toString());e.searchParams.set("preview_theme_id",""),this.queueRedirect(e)}testsForUrl(e){const t=new URL(window.location.href),i=this.typeFromTemplate();return e.filter(s=>s.hypotheses.some(r=>r.type!=="dom"&&r.type!=="price"&&(r.isControl&&r.type===i&&r.affix===template.suffix||r.type==="theme"||r.isControl&&r.type==="urlRedirect"&&r.redirectPath&&t.pathname.endsWith(r.redirectPath)||r.type==="basicScript"))&&(s.ignoreTestViewParameterEnforcement||!t.searchParams.has("view")||s.hypotheses.map(r=>r.affix).includes(t.searchParams.get("view")??"")))}domTestsForUrl(e){const t=new URL(window.location.href);return e.filter(i=>i.hypotheses.some(s=>s.type!=="dom"&&s.type!=="price"?!1:s.type==="price"&&s.priceData&&s.priceData.variants.length>0?!0:s.domSelectors&&s.domSelectors.some(r=>new RegExp(se(r)).test(K(t.toString())))))}async filterTestsByAudience(e,t,i){const s=[],r=e.some(n=>(n.requiresRegion||this.geoViaShopify&&n.requiresCountry)&&!i.some(l=>l.testId===n.id));this.resolvedRegion===null&&r&&(this.log("Hiding page to wait for Shopify region resolution"),this.hidePage(),await this.waitForResolvedRegion()),window.__slRegion=this.resolvedRegion??"";let o=t.country;this.geoViaShopify?o=this.resolvedRegion?this.resolvedRegion.slice(0,2):o:!o&&e.some(n=>n.requiresCountry&&!i.some(l=>l.testId===n.id))&&(this.log("Hiding page to check geoip"),this.hidePage(),o=await this.makeJsonRequest({method:"get",url:`${this.eventHost}/api/v0/visitors/get-country`,signal:AbortSignal.timeout(this.getCountryTimeout)}).catch(n=>(this.log("Error getting country",n),null)));for(const n of e){if(this.log("Checking audience for test '%s'",n.id),this.state.essential.visitorTests.some(d=>d.testId===n.id&&d.hypothesisId==null)){console.log(`Skipping blocked test '${n.id}'`);continue}const l=this.visitorCreatedDuringTestActive(n.statusHistory);(i.some(d=>d.testId===n.id&&(n.device==="all"||n.device===t.device&&n.device===this.device))||this.isTargetAudience(n,t,l,o))&&(this.log("Visitor is in audience for test '%s'",n.id),s.push(n))}this.testsFilteredByAudience=s}async waitForResolvedRegion(e=1500,t=50){const i=Date.now();for(;this.resolvedRegion===null&&Date.now()-i<e;)await new Promise(s=>window.setTimeout(s,t))}isTargetAudience(e,t,i,s){const r=this.getChannel(t);return(e.device==="all"||e.device===t.device&&e.device===this.device)&&(e.visitorOption==="all"||e.visitorOption==="new"&&i||e.visitorOption==="returning"&&!i)&&(e.targetAudiences.length===0||e.targetAudiences.reduce((o,n)=>o||n.reduce((l,c)=>l&&c(t,i,r,s),!0),!1))}visitorCreatedDuringTestActive(e){let t="";for(const i of e){if(this.state.analytics.visitor!==null&&this.state.analytics.visitor.createdAt<i.createdAt||this.state.essential.initialState.createdAt<i.createdAt)break;t=i.status}return t==="active"}getDomTestsForCurrentUrl(){return this.domTestsForUrl(this.testsFilteredByAudience)}getCurrentVisitorHypothesis(e){return e.flatMap(t=>t.hypotheses).find(t=>t.type!=="dom"&&t.type!=="price"&&this.state.essential.visitorTests.some(i=>i.hypothesisId===t.id))}getVisitorDomHypothesis(e){return e.flatMap(t=>t.hypotheses).filter(t=>(t.type==="dom"||t.type==="price")&&this.state.essential.visitorTests.some(i=>i.hypothesisId===t.id))}getHypothesis(e){return this.testConfigs.filter(t=>t.hypotheses.some(i=>i.id===e)).map(t=>t.hypotheses.find(i=>i.id===e))[0]}getActiveAssignment(){if(this.state.temporary.isMerchant&&this.state.temporary.previewConfig){const t=this.state.temporary.previewConfig;return t.currentVariant&&t.testId?{testId:t.testId,hypothesisId:t.currentVariant}:null}const e=this.state.essential.visitorTests.find(t=>t.hypothesisId);return e?.hypothesisId?{testId:e.testId,hypothesisId:e.hypothesisId}:null}findActiveSubscriptionTestControl(){for(const e of this.testConfigs){const t=e.hypotheses.find(i=>i.isControl);if(t?.subscriptionData)return{testId:e.id,hypothesis:t}}return null}getDomSelectorsForHypothesis(e){if(!e)return[];if(e.domSelectors&&e.domSelectors.length>0)return e.domSelectors;if(e.priceData){const t=`${this.priceSelectorsSessionKey}_${e.id}`;try{const s=sessionStorage.getItem(t);if(s){const r=JSON.parse(s);return e.domSelectors=r,this.log("Loaded %d price selectors from cache for hypothesis '%s'",r.length,e.id),r}}catch{}const i=$e(e.priceData);e.domSelectors=i;try{sessionStorage.setItem(t,JSON.stringify(i)),this.log("Generated and cached %d price selectors for hypothesis '%s'",i.length,e.id)}catch{this.log("Generated %d price selectors for hypothesis '%s' (cache unavailable)",i.length,e.id)}return i}return[]}hasThemeTest(e){return e.some(t=>t.hypotheses.some(i=>i.type==="theme"))}hasTestThatIsNotThemeTest(e){return e.some(t=>t.hypotheses.some(i=>i.type!=="theme"&&i.type!=="dom"&&i.type!=="price"))}hasThemeAndOtherTestTypes(e){return this.hasThemeTest(e)&&this.hasTestThatIsNotThemeTest(e)}testIsPaused(e){return e.status==="paused"||e.status==="incompatible"||e.status==="suspended"}visitorActiveTestType(){const e=this.state.essential.visitorTests.filter(t=>this.testConfigs.some(i=>i.hypotheses.some(s=>s.id==t.hypothesisId)));return e.length===0?null:e.some(t=>t.isThemeTest)?"theme":"templateOrUrlRedirect"}getReservationType(e){return e==="price"||this.isTemplateTestType(e)?"deferred":"immediate"}isTemplateTestType(e){return["product","collection","landing","index","cart","search","blog","article","collectionList"].includes(e)}getEntryCriteriaKey(e){const t=e.hypotheses.find(i=>i.isControl);if(!t)return`unknown:${e.id}`;switch(t.type){case"theme":return"global:theme";case"basicScript":return"global:autoApi";case"price":return"global:price";case"manualScript":return`conditional:manualApi:${e.id}`;case"urlRedirect":return`conditional:url:${t.redirectPath||"unknown"}`;default:return`conditional:template:${t.type}`}}isGlobalEntryCriteria(e){return e.startsWith("global:")}groupTestsByEntryCriteria(e){const t=new Map;for(const i of e){const s=this.getEntryCriteriaKey(i),r=t.get(s)||[];r.push(i),t.set(s,r)}return t}doesCurrentPageMatchEntryCriteria(e){if(this.isGlobalEntryCriteria(e))return!0;
43if(e==="conditional:manualApi")return!1;if(e.startsWith("conditional:url:")){const t=e.replace("conditional:url:","");return window.location.pathname.endsWith(t)}if(e.startsWith("conditional:template:")){const t=e.replace("conditional:template:","");return this.typeFromTemplate()===t}return!1}hasActiveReservation(){const e=this.getActiveReservations();return Object.values(e).some(t=>!t.isRealized)}getActiveReservation(){const e=this.getActiveReservations();return Object.values(e).find(t=>!t.isRealized)??null}clearStaleReservations(){const e=this.state.temporary.testReservations;if(!e)return;let t=!1;for(const[i,s]of Object.entries(e)){const r=this.testConfigs.find(n=>n.id===s.testId);if(!r){this.log("Test '%s' no longer in config, clearing reservation for criteria '%s'",s.testId,i),delete e[i],t=!0;continue}if(r.status!=="active"){this.log("Test '%s' status is '%s', clearing reservation for criteria '%s'",s.testId,r.status,i),delete e[i],t=!0;continue}this.testsFilteredByAudience.some(n=>n.id===s.testId)||(this.log("Visitor no longer passes audience for test '%s', clearing reservation for criteria '%s'",s.testId,i),delete e[i],t=!0)}t&&this.persistTemporaryState()}createReservations(e){if(this.state.temporary.testReservations||(this.state.temporary.testReservations={}),this.state.temporary.rolledEntryCriteria||(this.state.temporary.rolledEntryCriteria=[]),this.state.temporary.testCategory==="global"){this.createSingleReservation(e,"global");return}const i=e.filter(n=>this.doesCurrentPageMatchEntryCriteria(this.getEntryCriteriaKey(n))),s=e.filter(n=>!this.doesCurrentPageMatchEntryCriteria(this.getEntryCriteriaKey(n)));this.log("Conditional tests split - matching current page: %d, not matching: %d",i.length,s.length),i.length>0&&this.log("Tests matching current page (same pool): %o",i.map(n=>({id:n.id,title:n.title,criteria:this.getEntryCriteriaKey(n)})));const r=`conditional:current-page:${this.typeFromTemplate()}`;if(i.length>0&&!this.state.temporary.rolledEntryCriteria.includes(r)){this.createSingleReservation(i,r);for(const n of i){const l=this.getEntryCriteriaKey(n);this.state.temporary.rolledEntryCriteria.includes(l)||this.state.temporary.rolledEntryCriteria.push(l)}}const o=this.groupTestsByEntryCriteria(s);for(const[n,l]of o){if(this.state.temporary.rolledEntryCriteria.includes(n)){this.log("Already rolled for criteria '%s', skipping",n);continue}if(l.some(S=>this.state.essential.visitorTests.some(C=>C.testId===S.id))){this.log("Visitor already has VT for criteria '%s', skipping",n),this.state.temporary.rolledEntryCriteria.push(n);continue}const d=[...l].sort((S,C)=>S.id.localeCompare(C.id));this.log("Test dice roll for criteria '%s' - available tests: %o",n,d.map(S=>({id:S.id,title:S.title})));const u=Math.floor(Math.random()*d.length),h=d[u];this.log("Test dice roll: picked index %d of %d, selected test '%s' (%s)",u+1,l.length,h.id,h.title);const p=this.pickHypothesis(h);if(!p){this.log("No hypothesis picked for test '%s'",h.id);continue}this.sendDiagnosticTelemetry("assignment",h.id,{hypothesisId:p.id,isControl:p.isControl,testType:p.type});const b=this.getReservationType(p.type),E={testId:h.id,hypothesisId:p.id,testType:p.type,reservationType:b,isThemeTest:p.type==="theme",themeId:p.themeId,createdAt:new Date,isRealized:!1,entryCriteriaKey:n};this.state.temporary.testReservations[n]=E,this.state.temporary.rolledEntryCriteria.push(n),this.log("Created %s reservation for test '%s' (criteria: %s)",b,h.id,n);for(const S of l)S.id!==h.id&&this.markTestAsBlocked(S,n)}this.persistTemporaryState()}createSingleReservation(e,t){if(this.state.temporary.rolledEntryCriteria.includes(t)){this.log("Already rolled for pool '%s', skipping",t);return}if(e.some(u=>this.state.essential.visitorTests.some(h=>h.testId===u.id&&!h.isInvalid))){this.log("Visitor already has VT for pool '%s', skipping",t),this.state.temporary.rolledEntryCriteria.push(t);return}if(e.length===0){this.log("No tests in pool '%s'",t);return}const s=[...e].sort((u,h)=>u.id.localeCompare(h.id));this.log("Test dice roll for pool '%s' - available tests: %o",t,s.map(u=>({id:u.id,title:u.title,criteria:this.getEntryCriteriaKey(u)})));const r=Math.floor(Math.random()*s.length),o=s[r];this.log("Test dice roll: picked index %d of %d, selected test '%s' (%s)",r,e.length,o.id,o.title);const n=this.pickHypothesis(o);if(!n){this.log("No hypothesis picked for test '%s'",o.id);return}this.sendDiagnosticTelemetry("assignment",o.id,{hypothesisId:n.id,isControl:n.isControl,testType:n.type});const l=this.getReservationType(n.type),c=this.getEntryCriteriaKey(o),d={testId:o.id,hypothesisId:n.id,testType:n.type,reservationType:l,isThemeTest:n.type==="theme",themeId:n.themeId,createdAt:new Date,isRealized:!1,entryCriteriaKey:c};this.state.temporary.testReservations[c]=d,this.state.temporary.rolledEntryCriteria.push(t),this.log("Created %s reservation for test '%s' from pool '%s' (criteria: %s)",l,o.id,t,c);for(const u of e)u.id!==o.id&&this.markTestAsBlocked(u,`pool:${t}`);this.persistTemporaryState()}markTestAsBlocked(e,t){this.state.essential.visitorTests.some(i=>i.testId===e.id)||(this.log("Blocking visitor from test '%s' (reason: %s)",e.id,t),this.state.essential.visitorTests.push({createdAt:new Date,testId:e.id,hypothesisId:null,isThemeTest:e.hypotheses.some(i=>
43i.type==="theme"),shouldSendToGa:!1,isSaved:!0,isInvalid:!0,themeId:void 0}))}realizeReservationForCriteria(e){const t=this.state.temporary.testReservations?.[e];if(!t)return this.log("No reservation found for criteria '%s'",e),!1;if(t.isRealized)return this.log("Reservation already realized for criteria '%s'",e),!1;if(this.state.essential.visitorTests.some(s=>s.testId===t.testId&&!s.isInvalid))return this.log("Visitor already assigned to test '%s'",t.testId),!1;const i=this.getHypothesis(t.hypothesisId);return i?(t.isRealized=!0,this.persistTemporaryState(),this.queueAddVisitorToTest(t.testId,i),this.saveState(),this.log("Realized reservation for test '%s' (criteria: %s)",t.testId,e),!0):(this.log("Hypothesis '%s' not found",t.hypothesisId),!1)}getActiveReservations(){return this.state.temporary.testReservations??{}}getReservationForCurrentPage(){const e=this.getActiveReservations();for(const[t,i]of Object.entries(e)){if(i.isRealized)continue;const s=this.testConfigs.find(r=>r.id===i.testId);if(!(!s||s.status!=="active")&&this.doesCurrentPageMatchEntryCriteria(t))return i}return null}getReservationForTest(e){const t=this.getActiveReservations();return Object.values(t).find(i=>i.testId===e)??null}getReservationTestType(){const e=this.getActiveReservations(),t=Object.values(e);if(t.length===0)return null;for(const i of t)if(i.isThemeTest)return"theme";for(const i of t)if(i.testType==="price")return"price";return t.some(i=>!i.isRealized)?"templateOrUrlRedirect":null}hasPriceTests(e){return e.some(t=>t.hypotheses.some(i=>i.type==="price"))}_priceTestProductIds=null;getPriceTestProductIds(){if(this._priceTestProductIds)return this._priceTestProductIds;const e=new Set;for(const t of this.testConfigs)for(const i of t.hypotheses)if(i.type==="price"){for(const s of i.domSelectors||[]){const r=s.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);r?.[1]&&e.add(r[1])}if(i.priceData?.variants)for(const[s]of i.priceData.variants)e.add(s)}return this._priceTestProductIds=e,this.log("Built price test product ID cache with %d products",e.size),e}isProductInAnyPriceTest(e){return this.getPriceTestProductIds().has(e)}visitorActiveTestTypeWithReservations(){const e=this.getActiveReservations();for(const r of Object.values(e)){if(r.isThemeTest)return"theme";if(r.testType==="price")return"price"}if(Object.values(e).some(r=>!r.isRealized)){if(this.state.temporary.testCategory==="global")for(const o of Object.values(e)){if(o.testType==="theme")return"theme";if(o.testType==="price")return"price";if(o.testType==="basicScript")return"theme"}return"templateOrUrlRedirect"}const i=this.state.essential.visitorTests.filter(r=>!r.isInvalid&&this.testConfigs.some(o=>o.hypotheses.some(n=>n.id===r.hypothesisId)));return i.length===0?null:i.some(r=>this.getHypothesis(r.hypothesisId)?.type==="price")?"price":i.some(r=>r.isThemeTest)?"theme":"templateOrUrlRedirect"}applyControlForAudienceFilteredPriceTests(){const e=this.testConfigs.filter(s=>s.status==="active"&&s.hypotheses.some(r=>r.type==="price"));if(e.length===0)return;const t=this.testsFilteredByAudience.filter(s=>s.hypotheses.some(r=>r.type==="price")),i=e.filter(s=>!t.some(r=>r.id===s.id));if(i.length!==0){this.log("Found %d price tests filtered by audience, applying control selectors",i.length);for(const s of i){const r=s.hypotheses.find(c=>c.isControl),o=this.getDomSelectorsForHypothesis(r);if(o.length===0){this.log("No control selectors for audience-filtered price test '%s'",s.id);continue}const n=new URL(window.location.href);o.some(c=>{try{return new RegExp(se(c)).test(K(n.toString()))}catch{return!1}})&&(this.log("Applying control selectors for audience-filtered price test '%s'",s.id),U(document,{testId:s.id,hypothesisId:r.id,selectors:o},()=>{}),this.updatePriceTestHiddenInputs(s.id,"control",!1))}}}pickHypothesis(e){let t=Math.random();const i=e.hypotheses.reduce((r,o)=>r+o.visitorCount,0);return e.hypotheses.sort((r,o)=>r.isControl?o.isControl?0:-1:o.isControl?1:0).reduce((r,o)=>{if(r!==null)return r;const l=e.hypotheses.reduce((c,d)=>c&&d.visitorCount>20,!0)?o.visitorCount/i-o.trafficPercentage:0;return t<=o.trafficPercentage-l?o:(t-=o.trafficPercentage-l,null)},null)}typeFromTemplate(){switch(template.type){case"list-collections":return"collectionList";case"page":return"landing";case"article":case"blog":case"cart":case"collection":case"index":case"product":case"search":return template.type;default:return null}}queueRedirect(e){this.saveState(),this.disableReferrerOverride||(this.log(`Saving temporary referrer override '${document.referrer}'`),this.state.temporary.originalReferrer=document.referrer,this.persistTemporaryState()),window.setTimeout(()=>window.location.assign(e),0),window.setTimeout(()=>{this.syncAllEvents()},2e3)}scheduleRetrySync(){this.clientIdRetryCount>=5||(this.clientIdRetryCount++,window.setTimeout(()=>{this.syncAllEvents()},500))}async syncAllEvents(){const e=async()=>
43{if(this.isSyncing){window.setTimeout(()=>{(async()=>await e())()},500);return}try{if(this.isSyncing=!0,this.syncGAEvents(),this.shopifyAnalyticsId||(this.shopifyAnalyticsId=this.getShopifyAnalyticsId()),!this.shopifyAnalyticsId){this.scheduleRetrySync();return}await this.syncEvents()}finally{this.isSyncing=!1}};await e()}async syncEvents(){if(!this.state.essential.consentApproved||!this.shopifyAnalyticsId||this.state.analytics.queue.length===0)return;const e=this.state.analytics.queue.length,t=this.state.analytics.queue.splice(0,e);this.log("Syncing %s events",e);try{const i={shop:this.shop,visitorDetails:{shopifyAnalyticsId:this.shopifyAnalyticsId,device:this.state.analytics.visitor?.device??this.device,country:this.state.analytics.visitor?.country??null,...this.state.essential.initialState},events:this.state.essential.visitorTests.filter(r=>!r.isInvalid&&!r.isSaved&&r.hypothesisId!=null).map(r=>new be(r.testId,r.hypothesisId,r.createdAt)).concat(t)};await this.sendEvents(i);for(const r of this.state.essential.visitorTests.filter(o=>!o.isInvalid&&!o.isSaved&&o.hypothesisId!=null))this.sendDiagnosticTelemetry("event-delivered",r.testId,{hypothesisId:r.hypothesisId,isControl:r.assignedTo==="control",testType:r.testType??"unknown"});const s=await this.getVisitor(this.shopifyAnalyticsId);s!==null&&this.updateLocalVisitor(s);for(const r of this.state.essential.visitorTests.filter(o=>!o.isInvalid&&!o.isSaved))r.isSaved=!0,r.savedAt=Date.now()}catch{this.state.analytics.queue.splice(0,0,...t)}finally{this.saveState()}}syncGAEvents(){if(!this.gaConfig.sendEvents){if(he)return;he=!0,this.log("UseGtag is false — skipping GA Events");return}if(this.isSyncingGA){this.log("Already syncing GA - skipping GA events");return}const e=this.state.essential.visitorTests.filter(t=>t.shouldSendToGa);e.length!==0&&(this.isSyncingGA=!0,this.log("Syncing %s GA Events",e.length),Promise.allSettled(e.map(t=>this.sendGAEvent(t))).then(()=>this.log("All gtag events sent")).finally(()=>this.isSyncingGA=!1))}sendGAEvent(e){return new Promise(t=>{this.log("Sending GA Event for test %s, hypothesis %s",e.testId,e.hypothesisId);const i=()=>{this.log("GA acknowledged event for hypothesis %s",e.hypothesisId),e.shouldSendToGa=!1,this.persistEssentialState(),t()},s={exp_variant_string:`SL-${e.testId}-${e.hypothesisId}`};
43this.shopliftDebug&&Object.assign(s,{debug_mode:!0});function r(o,n,l){window.dataLayer=window.dataLayer||[],window.dataLayer.push(arguments)}this.gaConfig.mode==="gtag"?r("event","experience_impression",{...s,event_callback:i}):(window.dataLayer=window.dataLayer||[],window.dataLayer.push({event:"experience_impression",...s,eventCallback:i}))})}updateLocalVisitor(e){let t;({visitorTests:t,...this.state.analytics.visitor}=e),this.log("updateLocalVisitor - server returned %d tests: %o",t.length,t.map(s=>({testId:s.testId,hypothesisId:s.hypothesisId,isInvalid:s.isInvalid}))),this.log("updateLocalVisitor - local has %d tests: %o",this.state.essential.visitorTests.length,this.state.essential.visitorTests.map(s=>({testId:s.testId,hypothesisId:s.hypothesisId,isSaved:s.isSaved,isInvalid:s.isInvalid})));const i=300*1e3;for(const s of this.state.essential.visitorTests.filter(r=>r.isSaved&&(!r.savedAt||Date.now()-r.savedAt>i)&&!t.some(o=>o.testId===r.testId)))this.log("updateLocalVisitor - marking LOCAL test as INVALID (isSaved && not in server): testId=%s, hypothesisId=%s",s.testId,s.hypothesisId),s.isInvalid=!0;for(const s of t){const r=this.state.essential.visitorTests.findIndex(n=>n.testId===s.testId);if(!(r!==-1))this.log("updateLocalVisitor - ADDING server test (not found locally): testId=%s, hypothesisId=%s",s.testId,s.hypothesisId),this.state.essential.visitorTests.push(s);else{const n=this.state.essential.visitorTests.at(r);this.log("updateLocalVisitor - REPLACING local test with server test: testId=%s, local hypothesisId=%s -> server hypothesisId=%s, local isInvalid=%s -> false",s.testId,n?.hypothesisId,s.hypothesisId,n?.isInvalid),s.isInvalid=!1,s.shouldSendToGa=n?.shouldSe
43ndToGa??!1,s.testType=n?.testType,s.assignedTo=n?.assignedTo,s.testTitle=n?.testTitle,this.state.essential.visitorTests.splice(r,1,s)}}this.log("updateLocalVisitor - FINAL local tests: %o",this.state.essential.visitorTests.map(s=>({testId:s.testId,hypothesisId:s.hypothesisId,isSaved:s.isSaved,isInvalid:s.isInvalid}))),this.state.analytics.visitor.storedAt=new Date}async getVisitor(e){try{return await this.makeJsonRequest({method:"get",url:`${this.eventHost}/api/v0/visitors/by-key/${this.shop}/${e}`})}catch{return null}}async sendEvents(e){await this.makeRequest({method:"post",url:`${this.eventHost}/api/v0/events`,data:JSON.stringify(e)})}sendDiagnosticTelemetry(e,t,i){if(!this.telemetryEnabled||!navigator.sendBeacon)return;const s=this.state.essential.consentApproved,r=JSON.stringify({shop:this.shop,testId:t,checkpoint:e,device:this.device,...s?{visitorId:this.shopifyAnalyticsId??"unknown"}:{},clientTimestamp:Date.now(),consentApproved:s,hasConsentInteraction:this.state.essential.hasConsentInteraction,...i});navigator.sendBeacon(`${this.eventHost}/api/v0/telemetry`,new Blob([r],{type:"text/plain"}))}getUTMValue(e){const i=decodeURIComponent(window.location.search.substring(1)).split("&");for(let s=0;s<i.length;s++){const r=i[s].split("=");if(r[0]===e)return r[1]||null}return null}hidePage(e){this.log("Hiding page"),this.cssHideClass&&!window.document.documentElement.classList.contains(this.cssHideClass)&&(window.document.documentElement.classList.add(this.cssHideClass),e||setTimeout(this.removeAsyncHide(this.cssHideClass),2e3))}showPage(){this.cssHideClass&&this.removeAsyncHide(this.cssHideClass)()}getDeviceType(){function e(){let i=!1;return(function(s){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(s)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(s.substr(0,4)))&&(i=!0)})(navigator.userAgent||navigator.vendor),i}function t(){let i=!1;return(function(s){(/android|ipad|playbook|silk/i.test(s)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
43sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(s.substr(0,4)))&&(i=!0)})(navigator.userAgent||navigator.vendor),i}return e()?"mobile":t()?"tablet":"desktop"}removeAsyncHide(e){return()=>{e&&window.document.documentElement.classList.remove(e)}}async getCartState(){try{let e=await this.makeJsonRequest({method:"get",url:`${window.location.origin}/cart.js`});return e===null||(e.note===null&&(e=await this.makeJsonRequest({method:"post",url:`${window.location.origin}/cart/update.js`,data:JSON.stringify({note:""})})),e==null)?null:{token:e.token,total_price:e.total_price,total_discount:e.total_discount,currency:e.currency,items_subtotal_price:e.items_subtotal_price,items:e.items.map(t=>({quantity:t.quantity,variant_id:t.variant_id,key:t.key,price:t.price,final_line_price:t.final_line_price,sku:t.sku,product_id:t.product_id}))}}catch(e){return this.log("Error sending cart info",e),null}}ensureCartAttributesForExistingPriceTests(e){try{if(this.log("Checking visitor assignments for active price tests"),e&&this.state.temporary.previewConfig){const t=this.state.temporary.previewConfig;this.log("Using preview config for merchant:",t.testId);let i="variant";if(t.variants&&t.variants.length>0){const s=t.variants.find(r=>r.id===t.currentVariant);s&&s.isControl&&(i="control")}this.log("Merchant preview - updating hidden inputs:",t.testId,i),this.updatePriceTestHiddenInputs(t.testId,i,!0);return}for(const t of this.state.essential.visitorTests){const i=this.testConfigs.find(o=>o.id===t.testId);if(!i){this.log("Test config not found:",t.testId);continue}const s=i.hypotheses.find(o=>o.id===t.hypothesisId);if(!s||s.type!=="price")continue;const r=s.isControl?"control":"variant";this.log("Updating hidden inputs for price test:",t.testId,r),this.updatePriceTestHiddenInputs(t.testId,r,e)}}catch(t){this.log("Error ensuring cart attributes for existing price tests:",t)}}subscriptionSwapDone=!1;subscriptionHideWrongPlans=null;subscriptionPriceDone=!1;subscriptionUpdateOneTime=null;subscriptionOneTimeDone=!1;swapMap=null;slptValue=null;async subscriptionSwap(){await Ue(this)}async subscriptionPriceChange(){await ze(this)}async subscriptionOneTimePrice(){await We(this)}updatePriceTestHiddenInputs(e,t,i){try{this.cleanupPriceTestObservers();const s=`${e}:${t}:${i?"t":"f"}`,r=T=>{const m=T.getAttribute("data-sl-pid");if(!m)return!0;if(i&&this.state.temporary.previewConfig){const w=this.state.temporary.previewConfig,I=t==="control"?"a":"b",f=w.variants.find(v=>v.label===I);if(!f)return!1;for(const v of f.domSelectors||[]){const g=v.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);if(g){const P=g[1];if(this.log(`Extracted ID from selector: ${P}, comparing to: ${m}`),P===m)return this.log("Product ID match found in preview config:",m,"variant:",f.label),!0}else this.log(`Could not extract ID from selector: ${v.cssSelector}`)}return this.log("No product ID match in preview config for:",m,"variant:",I),!1}const y=this.testConfigs.find(w=>w.id===e);if(!y)return this.log("Test config not found for testId:",e),!1;for(const w of y.hypotheses||[]){for(const I of w.domSelectors||[]){const f=I.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);if(f&&f[1]===m)return this.log("Product ID match found in domSelectors:",m,"for test:",e),!0}if(w.priceData?.variants){for(const I of w.priceData.variants)if(I[0]===m)return this.log("Product ID match found in priceData:",m,"for test:",e),!0}}return this.log("No product ID match for:",m,"in test:",e),!1},o=new Set;let n=!1,l=null;const c=(T,m)=>{if(document.querySelectorAll("[data-sl-attribute-p]").forEach(w=>{if(w instanceof Element&&w.nodeType===Node.ELEMENT_NODE&&w.isConnected&&document.contains(w))try{T.observe(w,{childList:!0,subtree:!0,characterData:!0,characterDataOldValue:!0,attributes:!1})}catch(I){this.log(`Failed to observe element (${m}):`,I)}}),document.body&&document.body.isConnected)try{T.observe(document.body,{childList:!0,subtree:!0,characterData:!0,characterDataOldValue:!0,attributes:!1})}catch(w){this.log(`Failed to observe document.body (${m}):`,w)}},d=(T,m,y,w)=>{const I=T.filter(f=>{const v=f.cssSelector.match(/data-sl-attribute-(?:p|cap)="(\d+)"/);return v&&v[1]===w});this.log(`Applying ${y} DOM selectors, total: ${T.length}, filtered: ${I.length}`),I.length>0&&U(document,{testId:e,hypothesisId:m,selectors:I})},u=(T,m)=>{this.log(`Applying DOM selector changes for product ID: ${T}`),m.disconnect(),n=!0;try{if(i&&this.state.temporary.previewConfig){const y=t==="control"?"a":"b",w=this.state.temporary.previewConfig.variants.find(I=>I.label===y);if(!w?.domSelectors){this.log(`No DOM selectors found for preview variant: ${y}`);return}d(w.domSelectors,w.id,"preview config",T)}else{const y=this.testConfigs.find(I=>I.id===e);if(!y){this.log(`No test config found for testId: ${e}`);return}const w=y.hypotheses.find(I=>t==="control"?I.isControl:!I.isControl);if(!w?.domSelectors){this.log(`No DOM selectors found for assignment: ${t}`);return}d(w.domSelectors,w.id,"live config",T)}}finally{l!==null&&clearTimeout(l),l=window.setTimeout(()=>{n=!1,l=null,c(m,"reconnection"),this.log("Re-established innerHTML observer after DOM changes")}
43,50)}},h=new MutationObserver(T=>{if(!n)for(const m of T){if(m.type!=="childList"&&m.type!=="characterData")continue;let y=m.target;m.type==="characterData"&&(y=m.target.parentElement||m.target.parentNode);let w=y,I=w.getAttribute("data-sl-attribute-p");for(;!I&&w.parentElement;)w=w.parentElement,I=w.getAttribute("data-sl-attribute-p");if(!I)continue;const f=w.innerHTML||w.textContent||"";let v="";m.type==="characterData"&&m.oldValue!==null&&(v=m.oldValue),this.log(`innerHTML changed on element with data-sl-attribute-p="${I}"`),v&&this.log(`Previous content: "${v}"`),this.log(`Current content: "${f}"`),u(I,h)}});c(h,"initial setup"),o.add(h);const p=new MutationObserver(T=>{T.forEach(m=>{m.addedNodes.forEach(y=>{if(y.nodeType===Node.ELEMENT_NODE){const w=y;E(w);const I=w.matches('input[name="properties[_slpt]"]')?[w]:w.querySelectorAll('input[name="properties[_slpt]"]');I.length>0&&this.log(`MutationObserver found ${I.length} new hidden input(s)`),I.forEach(f=>{const v=f.getAttribute("data-sl-pid");if(this.log(`MutationObserver checking new input with data-sl-pid="${v}"`),r(f))f.value!==s&&(f.value=s,this.log("Updated newly added hidden input:",s)),S(f);else{const g=f.getAttribute("data-sl-pid");g&&this.isProductInAnyPriceTest(g)?this.log("Preserving hidden input for product ID '%s' - belongs to a different price test",g):(f.remove(),this.log("Removed newly added non-matching hidden input for product ID:",g))}})}})})});o.add(p);const b=new MutationObserver(T=>{T.forEach(m=>{if(m.type==="attributes"&&m.attributeName==="data-sl-pid"){const y=m.target;if(this.log("AttributeObserver detected data-sl-pid attribute change on:",y.tagName),y.matches('input[name="properties[_slpt]"]')){const w=y,I=m.oldValue,f=w.getAttribute("data-sl-pid");this.log(`data-sl-pid changed from "${I}" to "${f}" - triggering payment placement updates`),r(w)?(w.value!==s&&(w.value=s,this.log("Updated hidden input after data-sl-pid change:",s)),f&&u(f,h),this.log("Re-running payment placement updates after variant change"),E(document.body)):f&&this.isProductInAnyPriceTest(f)?this.log("Preserving hidden input for product ID '%s' - belongs to a different price test",f):(w.remove(),this.log("Removed non-matching hidden input after data-sl-pid change:",f))}}})});o.add(b);const E=T=>{T.tagName==="SHOPIFY-PAYMENT-TERMS"&&(this.log("MutationObserver found new shopify-payment-terms element"),this.updateShopifyPaymentTerms(e,t));const m=T.querySelectorAll("shopify-payment-terms");m.length>0&&(this.log(`MutationObserver found ${m.length} shopify-payment-terms in added node`),this.updateShopifyPaymentTerms(e,t)),T.tagName==="AFTERPAY-PLACEMENT"&&(this.log("MutationObserver found new afterpay-placement element"),this.updateAfterpayPlacements(e,t,"afterpay"));const y=T.querySelectorAll("afterpay-placement");y.length>0&&(this.log(`MutationObserver found ${y.length} afterpay-placement in added node`),this.updateAfterpayPlacements(e,t,"afterpay")),T.tagName==="SQUARE-PLACEMENT"&&(this.log("MutationObserver found new square-placement element"),this.updateAfterpayPlacements(e,t,"square"));const w=T.querySelectorAll("square-placement");w.length>0&&(this.log(`MutationObserver found ${w.length} square-placement in added node`),this.updateAfterpayPlacements(e,t,"square")),T.tagName==="KLARNA-PLACEMENT"&&(this.log("MutationObserver found new klarna-placement element"),this.updateKlarnaPlacements(e,t));const I=T.querySelectorAll("klarna-placement");I.length>0&&(this.log(`MutationObserver found ${I.length} klarna-placement in added node`),this.updateKlarnaPlacements(e,t))},S=T=>{b.observe(T,{attributes:!0,attributeFilter:["data-sl-pid"],attributeOldValue:!0,subtree:!1});const m=T.getAttribute("data-sl-pid");this.log(`Started AttributeObserver on specific input with data-sl-pid="${m}"`)},C=()=>{const T=document.querySelectorAll('input[name="properties[_slpt]"]');this.log(`Found ${T.length} existing hidden inputs to check`),T.forEach(m=>{const y=m.getAttribute("data-sl-pid");this.log(`Checking existing input with data-sl-pid="${y}"`),r(m)?(m.value=s,this.log("Updated existing hidden input:",s),y&&(this.log("Applying initial DOM selector changes for existing product"),u(y,h)),S(m)):y&&this.isProductInAnyPriceTest(y)?this.log("Preserving hidden input for product ID '%s' - belongs to a different price test",
43y):(m.remove(),this.log("Removed non-matching hidden input for product ID:",y))})},_=()=>{document.body?(p.observe(document.body,{childList:!0,subtree:!0}),this.log("Started MutationObserver on document.body"),C(),E(document.body)):document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{document.body&&(p.observe(document.body,{childList:!0,subtree:!0}),this.log("Started MutationObserver after DOMContentLoaded"),C(),E(document.body))}):(this.log("Set timeout on observer"),setTimeout(_,10))};_(),window.__shopliftPriceTestObservers=o,window.__shopliftPriceTestValue=s,this.log("Set up DOM observer for price test hidden inputs")}catch(s){this.log("Error updating price test hidden inputs:",s)}}updateKlarnaPlacements(e,t){this.updatePlacementElements(e,t,"klarna-placement",(i,s)=>{i.setAttribute("data-purchase-amount",s.toString())})}cleanupPriceTestObservers(){const e=window.__shopliftPriceTestObservers;e&&(e.forEach(t=>{t.disconnect()}),e.clear(),this.log("Cleaned up existing price test observers")),delete window.__shopliftPriceTestObservers,delete window.__shopliftPriceTestValue}updateAfterpayPlacements(e,t,i="afterpay"){const s=i==="square"?"square-placement":"afterpay-placement";if(document.querySelectorAll(s).length===0){this.log(`No ${s} elements found on page - early return`);return}this.updatePlacementElements(e,t,s,(o,n)=>{if(i==="afterpay"){const l=(n/100).toFixed(2);o.setAttribute("data-amount",l)}else o.setAttribute("data-amount",n.toString())}),this.log("updateAfterpayPlacements completed")}updatePlacementElements(e,t,i,s){const r=document.querySelectorAll(i);if(r.length===0){this.log(`No ${i} elements found - early return`);return}let o;if(this.state.temporary.isMerchant&&this.state.temporary.previewConfig){const l=t==="control"?"a":"b",c=this.state.temporary.previewConfig.variants.find(d=>d.label===l);if(!c?.domSelectors){this.log(`No variant found for label ${l} in preview config for ${i}`);return}o=c.domSelectors,this.log(`Using preview config for ${i} in merchant mode, variant: ${l}`)}else{const l=this.testConfigs.find(d=>d.id===e);if(!l){this.log(`No testConfig found for id: ${e} - early return`);return}
43const c=l.hypotheses.find(d=>t==="control"?d.isControl:!d.isControl);if(!c?.domSelectors){this.log(`No hypothesis or domSelectors found for assignment: ${t} - early return`);return}o=c.domSelectors}const n=new RegExp(`${this.DATA_SL_ATTRIBUTE_P}=["'](\\d+)["']`);r.forEach(l=>{let c=null;const d=l.parentElement;if(d&&(c=d.querySelector('input[name="properties[_slpt]"]')),c||(c=l.querySelector('input[name="properties[_slpt]"]')),!c){this.log(`No hidden input found for ${i} element`);return}const u=c.getAttribute("data-sl-pid");if(!u){this.log("Hidden input has no data-sl-pid attribute - skipping");return}const h=o.find(S=>{const C=S.cssSelector.match(n);return C&&C[1]===u});if(!h){this.log(`No matching selector found for productId: ${u} - skipping element`);return}const p=h.actions.find(S=>S.scope==="price");if(!p?.value){this.log("No price action or value found - skipping element");return}const b=parseFloat(p.value.replace(/[^0-9.]/g,""));if(Number.isNaN(b)){this.log(`Invalid price "${p.value}" for product ${u} - skipping`);return}const E=Math.round(b*100);s(l,E)}),this.log(`updatePlacementElements completed for ${i}`)}updateShopifyPaymentTerms(e,t){const i=document.querySelectorAll("shopify-payment-terms");if(i.length===0)return;this.log("Store using shopify payments");let s;if(this.state.temporary.isMerchant&&this.state.temporary.previewConfig){const o=t==="control"?"a":"b",n=this.state.temporary.previewConfig.variants.find(l=>l.label===o);if(!n||!n.domSelectors){this.log(`No variant found for label ${o} in preview config`);return}s=n.domSelectors,this.log(`Using preview config for shopify-payment-terms in merchant mode, variant: ${o}`)}else{const o=this.testConfigs.find(l=>l.id===e);if(!o)return;const n=o.hypotheses.find(l=>t==="control"?l.isControl===!0:l.isControl===!1);if(!n||!n.domSelectors)return;s=n.domSelectors}const r=new RegExp(`${this.DATA_SL_ATTRIBUTE_P}=["'](\\d+)["']`);i.forEach(o=>{const n=o.getAttribute("variant-id");if(!n)return;const l=s.find(c=>{const d=c.cssSelector.match(r);return d&&d[1]===n});if(l){const c=l.actions.find(d=>d.scope==="price");if(c&&c.value){const d=o.getAttribute("shopify-meta");if(d)try{const u=JSON.parse(d);if(u.variants&&Array.isArray(u.variants)){const h=u.variants.find(p=>p.id?.toString()===n);if(h){h.full_price=c.value;const p=parseFloat(c.value.replace(/[^0-9.]/g,""));if(h.number_of_payment_terms&&h.number_of_payment_terms>1){const b=p/h.number_of_payment_terms;h.price_per_term=`$${b.toFixed(2)}`}o.setAttribute("shopify-meta",JSON.stringify(u))}}}catch(u){this.log("Error parsing/updating shoplift-meta:",u)}}}})}async makeJsonRequest(e){const t=await this.makeRequest(e);return t===null?null:JSON.parse(await t.text(),F)}async makeRequest(e){const{url:t,method:i,headers:s,data:r,signal:o}=e,n=new Headers;if(s)for(const c in s)n.append(c,s[c]);(!s||!s.Accept)&&n.append("Accept","application/json"),(!s||!s["Content-Type"])&&n.append("Content-Type","application/json"),(this.eventHost.includes("ngrok.io")||this.eventHost.includes("ngrok-free.app"))&&n.append("ngrok-skip-browser-warning","1234");const l=await this.fetch(t,{method:i,headers:n,body:r,signal:o});if(!l.ok){if(l.status===204)return null;if(l.status===422){const c=await l.json();if(typeof c<"u"&&c.isBot)throw new ie}throw new Error(`Error sending shoplift request ${l.status}`)}return l}queueAddVisitorToTest(e,t){if(this.state.essential.visitorTests.some(s=>s.testId===e))return;const i=this.testConfigs.find(s=>s.id===e);if(this.state.essential.visitorTests.push({createdAt:new Date,testId:e,hypothesisId:t.id,isThemeTest:t.type==="theme",themeId:t.themeId,isSaved:!1,isInvalid:!1,shouldSendToGa:!0,testType:t.type,assignedTo:t.isControl?"control":"variant",testTitle:i?.title}),t.type==="price"){const s=t.isControl?"control":"variant";this.log("Price test assignment detected, updating cart attributes:",e,s),this.updatePriceTestHiddenInputs(e,s,!1)}}queueCartUpdate(e){this.queueEvent(new Ce(e))}queuePageView(e){this.queueEvent(new Se(e))}queueEvent(e){!this.state.essential.consentApproved&&this.state.essential.hasConsentInteraction||this.state.analytics.queue.length>10||this.state.analytics.queue.push(e)}legacyGetLocalStorageVisitor(){const e=this.localStorageGet(this.legacySessionKey);if(e)try{return JSON.parse(e,F)}catch{}return null}pruneStaleVisitorTests(){this.state.essential.visitorTests=this.state.essential.visitorTests.filter(e=>this.testConfigs.some(t=>t.id==e.testId)||this.inactiveTestConfigs.filter(t=>this.testIsPaused(t)).some(t=>t.id===e.testId))}pruneStateAndSave(){this.pruneStaleVisitorTests(),this.saveState()}saveState(){this.persistEssentialState(),this.persistAnalyticsState()}loadState(){const e=this.loadAnalyticsState(),t={analytics:e,essential:this.loadEssentialState(e),temporary:this.loadTemporaryState()},i=this.legacyGetLocalStorageVisitor(),s=this.legacyGetCookieVisitor(),r=[i,s].filter(o=>o!==null).sort((o,n)=>+n.storedAt-+o.storedAt)[0];return t.analytics.visitor===null&&r&&({visitorTests:t.essential.visitorTests,...t.analytics.visitor}=r,t.essential.isFirstLoad=!1,t.essential.initialState={createdAt:r.createdAt,referrer:r.referrer,utmCampaign:r.utmCampaign,utmContent:r.utmContent,utmMedium:r.utmMedium,utmSource:r.utmSource,device:r.device},this.deleteCookie("SHOPLIFT"),this.deleteLocalStorage(this.legacySessionKey)),!t.essential.consentApproved&&t.essential.hasConsentInteraction&&this.deleteLocalStorage(this.analyticsSessionKey),t}loadEssentialState(e){const t=this.loadLocalStorage(this.essentialSessionKey),i=this.loadCookie(this.essentialSessionKey),s=this.getInitialState();e.visitor?.device&&(s.device=e.visitor.device);const r={timestamp:new Date,consentApproved:!1,hasConsentInteraction:!1,debugMode:!1,initialState:s,visitorTests:[],isFirstLoad:!0},o=[t,i].filter(n=>n!==null).sort((n,l)=>+l.timestamp-+n.timestamp)[0]??r;return o.initialState||(e.visitor!==null?o.initialState=e.visitor:(o.initialState=s,o.initialState.createdAt=o.timestamp)),o}loadAnalyticsState(){const e=this.loadLocalStorage(this.analyticsSessionKey),t=this.loadCookie(this.analyticsSessionKey),i={timestamp:new Date,visitor:null,queue:[]},s=[e,t].filter(r=>r!==null).sort((r,o)=>+o.timestamp-+r.timestamp)[0]??i;return s.queue.length===0&&e&&e.queue.length>1&&(s.queue=e.queue),s}loadTemporaryState(){const e=this.sessionStorageGet(this.temporarySessionKey),t=e?JSON.parse(e,F):null,i=this.loadCookie(this.temporarySessionKey);return t??i??{isMerchant:!1,timestamp:new Date}}persistEssentialState(){this.log("Persisting essential state"),this.state.essential.isFirstLoad=!1,this.state.essential.timestamp=new Date,this.persistLocalStorageState(this.essentialSessionKey,this.state.essential),this.persist
43CookieState(this.essentialSessionKey,this.state.essential)}persistAnalyticsState(){this.log("Persisting analytics state"),this.state.essential.consentApproved&&(this.state.analytics.timestamp=new Date,this.persistLocalStorageState(this.analyticsSessionKey,this.state.analytics),this.persistCookieState(this.analyticsSessionKey,{...this.state.analytics,queue:[]}))}persistTemporaryState(){this.log("Setting temporary session state"),this.state.temporary.timestamp=new Date,this.sessionStorageSet(this.temporarySessionKey,JSON.stringify(this.state.temporary)),this.persistCookieState(this.temporarySessionKey,this.state.temporary,!0)}loadLocalStorage(e){const t=this.localStorageGet(e);if(t===null)return null;try{return JSON.parse(t,F)}catch{return null}}loadCookie(e){const t=this.getCookie(e);if(t===null)return null;try{return JSON.parse(t,F)}catch{return null}}persistLocalStorageState(e,t){this.localStorageSet(e,JSON.stringify(t))}persistCookieState(e,t,i=!1){const s=JSON.stringify(t),r=i?"":`expires=${new Date(new Date().getTime()+864e5*365).toUTCString()};`;document.cookie=`${e}=${s};domain=.${window.location.hostname};path=/;SameSite=Strict;${r}`}deleteCookie(e){const t=new Date(0).toUTCString();document.cookie=`${e}=;domain=.${window.location.hostname};path=/;expires=${t};`}deleteLocalStorage(e){window.localStorage.removeItem(e)}getChannel(e){return[{"name":"cross-network","test":(v) => new RegExp(".*cross-network.*", "i").test(v.utmCampaign)},{"name":"direct","test":(v) => v.utmSource === "" && v.utmMedium === ""},{"name":"paid-shopping","test":(v) => (new RegExp("^(?:Google|IGShopping|aax-us-east\.amazon-adsystem\.com|aax\.amazon-adsystem\.com|alibaba|alibaba\.com|amazon|amazon\.co\.uk|amazon\.com|apps\.shopify\.com|checkout\.shopify\.com|checkout\.stripe\.com|cr\.shopping\.naver\.com|cr2\.shopping\.naver\.com|ebay|ebay\.co\.uk|ebay\.com|ebay\.com\.au|ebay\.de|etsy|etsy\.com|m\.alibaba\.com|m\.shopping\.naver\.com|mercadolibre|mercadolibre\.com|mercadolibre\.com\.ar|mercadolibre\.com\.mx|message\.alibaba\.com|msearch\.shopping\.naver\.com|nl\.shopping\.net|no\.shopping\.net|offer\.alibaba\.com|one\.walmart\.com|order\.shopping\.yahoo\.co\.jp|partners\.shopify\.com|s3\.amazonaws\.com|se\.shopping\.net|shop\.app|shopify|shopify\.com|shopping\.naver\.com|shopping\.yahoo\.co\.jp|shopping\.yahoo\.com|shopzilla|shopzilla\.com|simplycodes\.com|store\.shopping\.yahoo\.co\.jp|stripe|stripe\.com|uk\.shopping\.net|walmart|walmart\.com)$", "i").test(v.utmSource) || new RegExp("^(.*(([^a-df-z]|^)shop|shopping).*)$", "i").test(v.utmCampaign)) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"paid-search","test":(v) => new RegExp("^(?:360\.cn|alice|aol|ar\.search\.yahoo\.com|ask|at\.search\.yahoo\.com|au\.search\.yahoo\.com|auone|avg|babylon|baidu|biglobe|biglobe\.co\.jp|biglobe\.ne\.jp|bing|br\.search\.yahoo\.com|ca\.search\.yahoo\.com|centrum\.cz|ch\.search\.yahoo\.com|cl\.search\.yahoo\.com|cn\.bing\.com|cnn|co\.search\.yahoo\.com|comcast|conduit|daum|daum\.net|de\.search\.yahoo\.com|dk\.search\.yahoo\.com|dogpile|dogpile\.com|duckduckgo|ecosia\.org|email\.seznam\.cz|eniro|es\.search\.yahoo\.com|espanol\.search\.yahoo\.com|exalead\.com|excite\.com|fi\.search\.yahoo\.com|firmy\.cz|fr\.search\.yahoo\.com|globo|go\.mail\.ru|google|google-play|hk\.search\.yahoo\.com|id\.search\.yahoo\.com|in\.search\.yahoo\.com|incredimail|it\.search\.yahoo\.com|kvasir|lens\.google\.com|lite\.qwant\.com|lycos|m\.baidu\.com|m\.naver\.com|m\.search\.naver\.com|m\.sogou\.com|mail\.rambler\.ru|mail\.yandex\.ru|malaysia\.search\.yahoo\.com|msn|msn\.com|mx\.search\.yahoo\.com|najdi|naver|naver\.com|news\.google\.com|nl\.search\.yahoo\.com|no\.search\.yahoo\.com|ntp\.msn\.com|nz\.search\.yahoo\.com|onet|onet\.pl|pe\.search\.yahoo\.com|ph\.search\.yahoo\.com|pl\.search\.yahoo\.com|play\.google\.com|qwant|qwant\.com|rakuten|rakuten\.co\.jp|rambler|rambler\.ru|se\.search\.yahoo\.com|search-results|search\.aol\.co\.uk|search\.aol\.com|search\.google\.com|search\.smt\.docomo\.ne\.jp|search\.ukr\.net|secureurl\.ukr\.net|seznam|seznam\.cz|sg\.search\.yahoo\.com|so\.com|sogou|sogou\.com|sp-web\.search\.auone\.jp|startsiden|startsiden\.no|suche\.aol\.de|terra|th\.search\.yahoo\.com|tr\.search\.yahoo\.com|tut\.by|tw\.search\.yahoo\.com|uk\.search\.yahoo\.com|ukr|us\.search\.yahoo\.com|virgilio|vn\.search\.yahoo\.com|wap\.sogou\.com|webmaster\.yandex\.ru|websearch\.rakuten\.co\.jp|yahoo|yahoo\.co\.jp|yahoo\.com|yandex|yandex\.by|yandex\.com|yandex\.com\.tr|yandex\.fr|yandex\.kz|yandex\.ru|yandex\.ua|y
43andex\.uz|zen\.yandex\.ru)$", "i").test(v.utmSource) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"paid-social","test":(v) => new RegExp("^(?:43things|43things\.com|51\.com|5ch\.net|Hatena|ImageShack|academia\.edu|activerain|activerain\.com|activeworlds|activeworlds\.com|addthis|addthis\.com|airg\.ca|allnurses\.com|allrecipes\.com|alumniclass|alumniclass\.com|ameba\.jp|ameblo\.jp|americantowns|americantowns\.com|amp\.reddit\.com|ancestry\.com|anobii|anobii\.com|answerbag|answerbag\.com|answers\.yahoo\.com|aolanswers|aolanswers\.com|apps\.facebook\.com|ar\.pinterest\.com|artstation\.com|askubuntu|askubuntu\.com|asmallworld\.com|athlinks|athlinks\.com|away\.vk\.com|awe\.sm|b\.hatena\.ne\.jp|baby-gaga|baby-gaga\.com|babyblog\.ru|badoo|badoo\.com|bebo|bebo\.com|beforeitsnews|beforeitsnews\.com|bharatstudent|bharatstudent\.com|biip\.no|biswap\.org|bit\.ly|blackcareernetwork\.com|blackplanet|blackplanet\.com|blip\.fm|blog\.com|blog\.feedspot\.com|blog\.goo\.ne\.jp|blog\.naver\.com|blog\.yahoo\.co\.jp|blogg\.no|bloggang\.com|blogger|blogger\.com|blogher|blogher\.com|bloglines|bloglines\.com|blogs\.com|blogsome|blogsome\.com|blogspot|blogspot\.com|blogster|blogster\.com|blurtit|blurtit\.com|bookmarks\.yahoo\.co\.jp|bookmarks\.yahoo\.com|br\.pinterest\.com|brightkite|brightkite\.com|brizzly|brizzly\.com|business\.facebook\.com|buzzfeed|buzzfeed\.com|buzznet|buzznet\.com|cafe\.naver\.com|cafemom|cafemom\.com|camospace|camospace\.com|canalblog\.com|care\.com|care2|care2\.com|caringbridge\.org|catster|catster\.com|cbnt\.io|cellufun|cellufun\.com|centerblog\.net|chat\.zalo\.me|chegg\.com|chicagonow|chicagonow\.com|chiebukuro\.yahoo\.co\.jp|classmates|classmates\.com|classquest|classquest\.com|co\.pinterest\.com|cocolog-nifty|cocolog-nifty\.com|copainsdavant\.linternaute\.com|couchsurfing\.org|cozycot|cozycot\.com|cross\.tv|crunchyroll|crunchyroll\.com|cyworld|cyworld\.com|cz\.pinterest\.com|d\.hatena\.ne\.jp|dailystrength\.org|deluxe\.com|deviantart|deviantart\.com|dianping|dianping\.com|digg|digg\.com|diigo|diigo\.com|discover\.hubpages\.com|disqus|disqus\.com|dogster|dogster\.com|dol2day|dol2day\.com|doostang|doostang\.com|dopplr|dopplr\.com|douban|douban\.com|draft\.blogger\.com|draugiem\.lv|drugs-forum|drugs-forum\.com|dzone|dzone\.com|edublogs\.org|elftown|elftown\.com|epicurious\.com|everforo\.com|exblog\.jp|extole|extole\.com|facebook|facebook\.com|faceparty|faceparty\.com|fandom\.com|fanpop|fanpop\.com|fark|fark\.com|fb|fb\.me|fc2|fc2\.com|feedspot|feministing|feministing\.com|filmaffinity|filmaffinity\.com|flickr|flickr\.com|flipboard|flipboard\.com|folkdirect|folkdirect\.com|foodservice|foodservice\.com|forums\.androidcentral\.com|forums\.crackberry\.com|forums\.imore\.com|forums\.nexopia\.com|forums\.webosnation\.com|forums\.wpcentral\.com|fotki|fotki\.com|fotolog|fotolog\.com|foursquare|foursquare\.com|free\.facebook\.com|friendfeed|friendfeed\.com|fruehstueckstreff\.org|fubar|fubar\.com|gaiaonline|gaiaonline\.com|gamerdna|gamerdna\.com|gather\.com|geni\.com|getpocket\.com|glassboard|glassboard\.com|glassdoor|glassdoor\.com|godtube|godtube\.com|goldenline\.pl|goldstar|goldstar\.com|goo\.gl|gooblog|goodreads|goodreads\.com|google\+|googlegroups\.com|googleplus|govloop|govloop\.com|gowalla|gowalla\.com|gree\.jp|groups\.google\.com|gulli\.com|gutefrage\.net|habbo|habbo\.com|hi5|hi5\.com|hootsuite|hootsuite\.com|houzz|houzz\.com|hoverspot|hoverspot\.com|hr\.com|hu\.pinterest\.com|hubculture|hubculture\.com|hubpages\.com|hyves\.net|hyves\.nl|ibibo|ibibo\.com|id\.pinterest\.com|identi\.ca|ig|imageshack\.com|imageshack\.us|imvu|imvu\.com|in\.pinterest\.com|insanejournal|insanejournal\.com|instagram|instagram\.com|instapaper|instapaper\.com|internations\.org|interpals\.net|intherooms|intherooms\.com|irc-galleria\.net|is\.gd|italki|italki\.com|jammerdirect|jammerdirect\.com|jappy\.com|jappy\.de|kaboodle\.com|kakao|kakao\.com|kakaocorp\.com|kaneva|kaneva\.com|kin\.naver\.com|l\.facebook\.com|l\.instagram\.com|l\.messenger\.com|last\.fm|librarything|librarything\.com|lifestream\.aol\.com|line|line\.me|linkedin|linkedin\.com|listal|listal\.com|listography|listography\.com|livedoor\.com|livedoorblog|livejournal|livejournal\.com|lm\.facebook\.com|lnkd\.in|m\.blog\.naver\.com|m\.cafe\.naver\.com|m\.facebook\.com|m\.kin\.naver\.com|m\.vk\.com|m\.yelp\.com|mbga\.jp|medium\.com|meetin\.org|meetup|meetup\.com|meinvz\.net|meneame\.net|menuism\.com|messages\.google\.com|messages\.yahoo\.co\.jp|messenger|messenger\.com|mix\.com|mixi\.jp|mobile\.facebook\.com|mocospace|mocospace\.com|mouthshut|mouthshut\.com|movabletype|movabletype\.com|mubi|mubi\.com|my\.o
43pera\.com|myanimelist\.net|myheritage|myheritage\.com|mylife|mylife\.com|mymodernmet|mymodernmet\.com|myspace|myspace\.com|netvibes|netvibes\.com|news\.ycombinator\.com|newsshowcase|nexopia|ngopost\.org|niconico|nicovideo\.jp|nightlifelink|nightlifelink\.com|ning|ning\.com|nl\.pinterest\.com|odnoklassniki\.ru|odnoklassniki\.ua|okwave\.jp|old\.reddit\.com|oneworldgroup\.org|onstartups|onstartups\.com|opendiary|opendiary\.com|oshiete\.goo\.ne\.jp|out\.reddit\.com|over-blog\.com|overblog\.com|paper\.li|partyflock\.nl|photobucket|photobucket\.com|pinboard|pinboard\.in|pingsta|pingsta\.com|pinterest|pinterest\.at|pinterest\.ca|pinterest\.ch|pinterest\.cl|pinterest\.co\.kr|pinterest\.co\.uk|pinterest\.com|pinterest\.com\.au|pinterest\.com\.mx|pinterest\.de|pinterest\.es|pinterest\.fr|pinterest\.it|pinterest\.jp|pinterest\.nz|pinterest\.ph|pinterest\.pt|pinterest\.ru|pinterest\.se|pixiv\.net|pl\.pinterest\.com|playahead\.se|plurk|plurk\.com|plus\.google\.com|plus\.url\.google\.com|pocket\.co|posterous|posterous\.com|pro\.homeadvisor\.com|pulse\.yahoo\.com|qapacity|qapacity\.com|quechup|quechup\.com|quora|quora\.com|qzone\.qq\.com|ravelry|ravelry\.com|reddit|reddit\.com|redux|redux\.com|renren|renren\.com|researchgate\.net|reunion|reunion\.com|reverbnation|reverbnation\.com|rtl\.de|ryze|ryze\.com|salespider|salespider\.com|scoop\.it|screenrant|screenrant\.com|scribd|scribd\.com|scvngr|scvngr\.com|secondlife|secondlife\.com|serverfault|serverfault\.com|shareit|sharethis|sharethis\.com|shvoong\.com|sites\.google\.com|skype|skyrock|skyrock\.com|slashdot\.org|slideshare\.net|smartnews\.com|snapchat|snapchat\.com|social|sociallife\.com\.br|socialvibe|socialvibe\.com|spaces\.live\.com|spoke|spoke\.com|spruz|spruz\.com|ssense\.com|stackapps|stackapps\.com|stackexchange|stackexchange\.com|stackoverflow|stackoverflow\.com|stardoll\.com|stickam|stickam\.com|studivz\.net|suomi24\.fi|superuser|superuser\.com|sweeva|sweeva\.com|t\.co|t\.me|tagged|tagged\.com|taggedmail|taggedmail\.com|talkbiznow|talkbiznow\.com|taringa\.net|techmeme|techmeme\.com|tencent|tencent\.com|tiktok|tiktok\.com|tinyurl|tinyurl\.com|toolbox|toolbox\.com|touch\.facebook\.com|tr\.pinterest\.com|travellerspoint|travellerspoint\.com|tripadvisor|tripadvisor\.com|trombi|trombi\.com|trustpilot|tudou|tudou\.com|tuenti|tuenti\.com|tumblr|tumblr\.com|tweetdeck|tweetdeck\.com|twitter|twitter\.com|twoo\.com|typepad|typepad\.com|unblog\.fr|urbanspoon\.com|ushareit\.com|ushi\.cn|vampirefreaks|vampirefreaks\.com|vampirerave|vampirerave\.com|vg\.no|video\.ibm\.com|vk\.com|vkontakte\.ru|wakoopa|wakoopa\.com|wattpad|wattpad\.com|web\.facebook\.com|web\.skype\.com|webshots|webshots\.com|wechat|wechat\.com|weebly|weebly\.com|weibo|weibo\.com|wer-weiss-was\.de|weread|weread\.com|whatsapp|whatsapp\.com|wiki\.answers\.com|wikihow\.com|wikitravel\.org|woot\.com|wordpress|wordpress\.com|wordpress\.org|xanga|xanga\.com|xing|xing\.com|yahoo-mbga\.jp|yammer|yammer\.com|yelp|yelp\.co\.uk|yelp\.com|youroom\.in|za\.pinterest\.com|zalo|zoo\.gr|zooppa|zooppa\.com)$", "i").test(v.utmSource) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"paid-video","test":(v) => new RegExp("^(?:blog\.twitch\.tv|crackle|crackle\.com|curiositystream|curiositystream\.com|d\.tube|dailymotion|dailymotion\.com|dashboard\.twitch\.tv|disneyplus|disneyplus\.com|fast\.wistia\.net|help\.hulu\.com|help\.netflix\.com|hulu|hulu\.com|id\.twitch\.tv|iq\.com|iqiyi|iqiyi\.com|jobs\.netflix\.com|justin\.tv|m\.twitch\.tv|m\.youtube\.com|music\.youtube\.com|netflix|netflix\.com|player\.twitch\.tv|player\.vimeo\.com|ted|ted\.com|twitch|twitch\.tv|utreon|utreon\.com|veoh|veoh\.com|viadeo\.journaldunet\.com|vimeo|vimeo\.com|wistia|wistia\.com|youku|youku\.com|youtube|youtube\.com)$", "i").test(v.utmSource) && new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)},{"name":"display","test":(v) => new RegExp("^(?:display|banner|expandable|interstitial|cpm)$", "i").test(v.utmMedium)},{"name":"paid-other","test":(v) => new RegExp("^(.*cp.*|ppc|retargeting|paid.*)$", "i").test(v.utmMedium)}
43,{"name":"organic-shopping","test":(v) => new RegExp("^(?:360\.cn|alice|aol|ar\.search\.yahoo\.com|ask|at\.search\.yahoo\.com|au\.search\.yahoo\.com|auone|avg|babylon|baidu|biglobe|biglobe\.co\.jp|biglobe\.ne\.jp|bing|br\.search\.yahoo\.com|ca\.search\.yahoo\.com|centrum\.cz|ch\.search\.yahoo\.com|cl\.search\.yahoo\.com|cn\.bing\.com|cnn|co\.search\.yahoo\.com|comcast|conduit|daum|daum\.net|de\.search\.yahoo\.com|dk\.search\.yahoo\.com|dogpile|dogpile\.com|duckduckgo|ecosia\.org|email\.seznam\.cz|eniro|es\.search\.yahoo\.com|espanol\.search\.yahoo\.com|exalead\.com|excite\.com|fi\.search\.yahoo\.com|firmy\.cz|fr\.search\.yahoo\.com|globo|go\.mail\.ru|google|google-play|hk\.search\.yahoo\.com|id\.search\.yahoo\.com|in\.search\.yahoo\.com|incredimail|it\.search\.yahoo\.com|kvasir|lens\.google\.com|lite\.qwant\.com|lycos|m\.baidu\.com|m\.naver\.com|m\.search\.naver\.com|m\.sogou\.com|mail\.rambler\.ru|mail\.yandex\.ru|malaysia\.search\.yahoo\.com|msn|msn\.com|mx\.search\.yahoo\.com|najdi|naver|naver\.com|news\.google\.com|nl\.search\.yahoo\.com|no\.search\.yahoo\.com|ntp\.msn\.com|nz\.search\.yahoo\.com|onet|onet\.pl|pe\.search\.yahoo\.com|ph\.search\.yahoo\.com|pl\.search\.yahoo\.com|play\.google\.com|qwant|qwant\.com|rakuten|rakuten\.co\.jp|rambler|rambler\.ru|se\.search\.yahoo\.com|search-results|search\.aol\.co\.uk|search\.aol\.com|search\.google\.com|search\.smt\.docomo\.ne\.jp|search\.ukr\.net|secureurl\.ukr\.net|seznam|seznam\.cz|sg\.search\.yahoo\.com|so\.com|sogou|sogou\.com|sp-web\.search\.auone\.jp|startsiden|startsiden\.no|suche\.aol\.de|terra|th\.search\.yahoo\.com|tr\.search\.yahoo\.com|tut\.by|tw\.search\.yahoo\.com|uk\.search\.yahoo\.com|ukr|us\.search\.yahoo\.com|virgilio|vn\.search\.yahoo\.com|wap\.sogou\.com|webmaster\.yandex\.ru|websearch\.rakuten\.co\.jp|yahoo|yahoo\.co\.jp|yahoo\.com|yandex|yandex\.by|yandex\.com|yandex\.com\.tr|yandex\.fr|yandex\.kz|yandex\.ru|yandex\.ua|yandex\.uz|zen\.yandex\.ru)$", "i").test(v.utmSource) || new RegExp("^(.*(([^a-df-z]|^)shop|shopping).*)$", "i").test(v.utmCampaign)},{"name":"organic-social","test":(v) => new RegExp("^(?:43things|43things\.com|51\.com|5ch\.net|Hatena|ImageShack|academia\.edu|activerain|activerain\.com|activeworlds|activeworlds\.com|addthis|addthis\.com|airg\.ca|allnurses\.com|allrecipes\.com|alumniclass|alumniclass\.com|ameba\.jp|ameblo\.jp|americantowns|americantowns\.com|amp\.reddit\.com|ancestry\.com|anobii|anobii\.com|answerbag|answerbag\.com|answers\.yahoo\.com|aolanswers|aolanswers\.com|apps\.facebook\.com|ar\.pinterest\.com|artstation\.com|askubuntu|askubuntu\.com|asmallworld\.com|athlinks|athlinks\.com|away\.vk\.com|awe\.sm|b\.hatena\.ne\.jp|baby-gaga|baby-gaga\.com|babyblog\.ru|badoo|badoo\.com|bebo|bebo\.com|beforeitsnews|beforeitsnews\.com|bharatstudent|bharatstudent\.com|biip\.no|biswap\.org|bit\.ly|blackcareernetwork\.com|blackplanet|blackplanet\.com|blip\.fm|blog\.com|blog\.feedspot\.com|blog\.goo\.ne\.jp|blog\.naver\.com|blog\.yahoo\.co\.jp|blogg\.no|bloggang\.com|blogger|blogger\.com|blogher|blogher\.com|bloglines|bloglines\.com|blogs\.com|blogsome|blogsome\.com|blogspot|blogspot\.com|blogster|blogster\.com|blurtit|blurtit\.com|bookmarks\.yahoo\.co\.jp|bookmarks\.yahoo\.com|br\.pinterest\.com|brightkite|brightkite\.com|brizzly|brizzly\.com|business\.facebook\.com|buzzfeed|buzzfeed\.com|buzznet|buzznet\.com|cafe\.naver\.com|cafemom|cafemom\.com|camospace|camospace\.com|canalblog\.com|care\.com|care2|care2\.com|caringbridge\.org|catster|catster\.com|cbnt\.io|cellufun|cellufun\.com|centerblog\.net|chat\.zalo\.me|chegg\.com|chicagonow|chicagonow\.com|chiebukuro\.yahoo\.co\.jp|classmates|classmates\.com|classquest|classquest\.com|co\.pinterest\.com|cocolog-nifty|cocolog-nifty\.com|copainsdavant\.linternaute\.com|couchsurfing\.org|cozycot|cozycot\.com|cross\.tv|crunchyroll|crunchyroll\.com|cyworld|cyworld\.com|cz\.pinterest\.com|d\.hatena\.ne\.jp|dailystrength\.org|deluxe\.com|deviantart|deviantart\.com|dianping|dianping\.com|digg|digg\.com|diigo|diigo\.com|discover\.hubpages\.com|disqus|disqus\.com|dogster|dogster\.com|dol2day|dol2day\.com|doostang|doostang\.com|dopplr|dopplr\.com|douban|douban\.com|draft\.blogger\.com|draugiem\.lv|drugs-forum|drugs-forum\.com|dzone|dzone\.com|edublogs\.org|elftown|elftown\.com|epicurious\.com|everforo\.com|exblog\.jp|extole|extole\.com|facebook|facebook\.com|faceparty|faceparty\.com|fandom\.com|fanpop|fanpop\.com|fark|fark\.com|fb|fb\.me|fc2|fc2\.com|feedspot|feministing|feministing\.com|filmaffinity|filmaffinity\.com|flickr|flickr\.com|flipboard|flipboard\.com|folkdirect|folkdirect\.com|foodservice|foodservice\.com|forums\.androidcentral\.com|forums\.crackberry\.com|forums\.imore\.com|forums\.nexopia\.com|forums\.webosnation\.com|forums\.wpcentral\.com|fotki|fotki\.com|fotolog|fotolog\.com|foursquare|foursquare\.com|free\.facebook\.com|friendfeed|friendfeed\.com|fruehstueckstreff\.org|fubar|fubar\.com|gaiaonline|gaiaonline\.com|gamerdna|gamerdna\.com|gather\.com|geni\.com|getpocket\.com|glassboard|glassboard\.com|glassdoor|glassdoor\.com|godtube|godtube\.com|goldenline\.pl|goldstar|goldstar\.com|goo\.gl|gooblog|goodreads|goodreads\.com|google\+|googlegroups\.com|googleplus|govloop|govloop\.com|gowalla|gowalla\.com|gree\.jp|groups\.google\.com|gulli\.com|gutefrage\.net|habbo|habbo\.com|hi5|hi5\.com|hootsuite|hootsuite\.com|houzz|houzz\.com|hoverspot|hoverspot\.com|hr\.com|hu\.pinterest\.com|hubculture|hubculture\.com|hubpages\.com|hyves\.net|hyves\.nl|ibibo|ibibo\.com|id\.pinterest\.com|identi\.ca|ig|imageshack\.com|imageshack\.us|imvu|imvu\.com|in\.pinterest\.com|insanejournal|insanejournal\.com|instagram|instagram\.com|instapaper|instapaper\.com|internations\.org|interpals\.net|intherooms|intherooms\.com|irc-galleria\.net|is\.gd|italki|italki\.com|jammerdirect|jammerdirect\.com|jappy\.com|jappy\.de|kaboodle\.com|k
43akao|kakao\.com|kakaocorp\.com|kaneva|kaneva\.com|kin\.naver\.com|l\.facebook\.com|l\.instagram\.com|l\.messenger\.com|last\.fm|librarything|librarything\.com|lifestream\.aol\.com|line|line\.me|linkedin|linkedin\.com|listal|listal\.com|listography|listography\.com|livedoor\.com|livedoorblog|livejournal|livejournal\.com|lm\.facebook\.com|lnkd\.in|m\.blog\.naver\.com|m\.cafe\.naver\.com|m\.facebook\.com|m\.kin\.naver\.com|m\.vk\.com|m\.yelp\.com|mbga\.jp|medium\.com|meetin\.org|meetup|meetup\.com|meinvz\.net|meneame\.net|menuism\.com|messages\.google\.com|messages\.yahoo\.co\.jp|messenger|messenger\.com|mix\.com|mixi\.jp|mobile\.facebook\.com|mocospace|mocospace\.com|mouthshut|mouthshut\.com|movabletype|movabletype\.com|mubi|mubi\.com|my\.opera\.com|myanimelist\.net|myheritage|myheritage\.com|mylife|mylife\.com|mymodernmet|mymodernmet\.com|myspace|myspace\.com|netvibes|netvibes\.com|news\.ycombinator\.com|newsshowcase|nexopia|ngopost\.org|niconico|nicovideo\.jp|nightlifelink|nightlifelink\.com|ning|ning\.com|nl\.pinterest\.com|odnoklassniki\.ru|odnoklassniki\.ua|okwave\.jp|old\.reddit\.com|oneworldgroup\.org|onstartups|onstartups\.com|opendiary|opendiary\.com|oshiete\.goo\.ne\.jp|out\.reddit\.com|over-blog\.com|overblog\.com|paper\.li|partyflock\.nl|photobucket|photobucket\.com|pinboard|pinboard\.in|pingsta|pingsta\.com|pinterest|pinterest\.at|pinterest\.ca|pinterest\.ch|pinterest\.cl|pinterest\.co\.kr|pinterest\.co\.uk|pinterest\.com|pinterest\.com\.au|pinterest\.com\.mx|pinterest\.de|pinterest\.es|pinterest\.fr|pinterest\.it|pinterest\.jp|pinterest\.nz|pinterest\.ph|pinterest\.pt|pinterest\.ru|pinterest\.se|pixiv\.net|pl\.pinterest\.com|playahead\.se|plurk|plurk\.com|plus\.google\.com|plus\.url\.google\.com|pocket\.co|posterous|posterous\.com|pro\.homeadvisor\.com|pulse\.yahoo\.com|qapacity|qapacity\.com|quechup|quechup\.com|quora|quora\.com|qzone\.qq\.com|ravelry|ravelry\.com|reddit|reddit\.com|redux|redux\.com|renren|renren\.com|researchgate\.net|reunion|reunion\.com|reverbnation|reverbnation\.com|rtl\.de|ryze|ryze\.com|salespider|salespider\.com|scoop\.it|screenrant|screenrant\.com|scribd|scribd\.com|scvngr|scvngr\.com|secondlife|secondlife\.com|serverfault|serverfault\.com|shareit|sharethis|sharethis\.com|shvoong\.com|sites\.google\.com|skype|skyrock|skyrock\.com|slashdot\.org|slideshare\.net|smartnews\.com|snapchat|snapchat\.com|social|sociallife\.com\.br|socialvibe|socialvibe\.com|spaces\.live\.com|spoke|spoke\.com|spruz|spruz\.com|ssense\.com|stackapps|stackapps\.com|stackexchange|stackexchange\.com|stackoverflow|stackoverflow\.com|stardoll\.com|stickam|stickam\.com|studivz\.net|suomi24\.fi|superuser|superuser\.com|sweeva|sweeva\.com|t\.co|t\.me|tagged|tagged\.com|taggedmail|taggedmail\.com|talkbiznow|talkbiznow\.com|taringa\.net|techmeme|techmeme\.com|tencent|tencent\.com|tiktok|tiktok\.com|tinyurl|tinyurl\.com|toolbox|toolbox\.com|touch\.facebook\.com|tr\.pinterest\.com|travellerspoint|travellerspoint\.com|tripadvisor|tripadvisor\.com|trombi|trombi\.com|trustpilot|tudou|tudou\.com|tuenti|tuenti\.com|tumblr|tumblr\.com|tweetdeck|tweetdeck\.com|twitter|twitter\.com|twoo\.com|typepad|typepad\.com|unblog\.fr|urbanspoon\.com|ushareit\.com|ushi\.cn|vampirefreaks|vampirefreaks\.com|vampirerave|vampirerave\.com|vg\.no|video\.ibm\.com|vk\.com|vkontakte\.ru|wakoopa|wakoopa\.com|wattpad|wattpad\.com|web\.facebook\.com|web\.skype\.com|webshots|webshots\.com|wechat|wechat\.com|weebly|weebly\.com|weibo|weibo\.com|wer-weiss-was\.de|weread|weread\.com|whatsapp|whatsapp\.com|wiki\.answers\.com|wikihow\.com|wikitravel\.org|woot\.com|wordpress|wordpress\.com|wordpress\.org|xanga|xanga\.com|xing|xing\.com|yahoo-mbga\.jp|yammer|yammer\.com|yelp|yelp\.co\.uk|yelp\.com|youroom\.in|za\.pinterest\.com|zalo|zoo\.gr|zooppa|zooppa\.com)$", "i").test(v.utmSource) || new RegExp("^(?:social|social-network|social-media|sm|social network|social media)$", "i").test(v.utmMedium)},{"name":"organic-video","test":(v) => new RegExp("^(?:blog\.twitch\.tv|crackle|crackle\.com|curiositystream|curiositystream\.com|d\.tube|dailymotion|dailymotion\.com|dashboard\.twitch\.tv|disneyplus|disneyplus\.com|fast\.wistia\.net|help\.hulu\.com|help\.netflix\.com|hulu|hulu\.com|id\.twitch\.tv|iq\.com|iqiyi|iqiyi\.com|jobs\.netflix\.com|justin\.tv|m\.twitch\.tv|m\.youtube\.com|music\.youtube\.com|netflix|netflix\.com|player\.twitch\.tv|player\.vimeo\.com|ted|ted\.com|twitch|twitch\.tv|utreon|utreon\.com|veoh|veoh\.com|viadeo\.journaldunet\.com|vimeo|vimeo\.com|wistia|wistia\.com|youku|youku\.com|youtube|youtube\.com)$", "i").test(v.utmSource) || new RegExp("^(.*video.*)$", "i").test(v.utmMedium)},{"name":"organic-search","test":(v) => new RegExp("^(?:360\.cn|alice|aol|ar\.search\.yahoo\.com|ask|at\.search\.yahoo\.com|au\.search\.yahoo\.com|auone|avg|babylon|baidu|biglobe|biglobe\.co\.jp|biglobe\.ne\.jp|bing|br\.search\.yahoo\.com|ca\.search\.yahoo\.com|centrum\.cz|ch\.search\.yahoo\.com|cl\.search\.yahoo\.com|cn\.bing\.com|cnn|co\.search\.yahoo\.com|comcast|conduit|daum|daum\.net|de\.search\.yahoo\.com|dk\.search\.yahoo\.com|dogpile|dogpile\.com|duckduckgo|ecosia\.org|email\.seznam\.cz|eniro|es\.search\.yahoo\.com|espanol\.search\.yahoo\.com|exalead\.com|excite\.com|fi\.search\.yahoo\.com|firmy\.cz|fr\.search\.yahoo\.com|globo|go\.mail\.ru|google|google-play|hk\.search\.yahoo\.com|id\.search\.yahoo\.com|in\.search\.yahoo\.com|incredimail|it\.search\.yahoo\.com|kvasir|lens\.google\.com|lite\.qwant\.com|lycos|m\.baidu\.com|m\.naver\.com|m\.search\.naver\.com|m\.sogou\.com|mail\.rambler\.ru|mail\.yandex\.ru|malaysia\.search\.yahoo\.com|msn|msn\.com|mx\.search\.yahoo\.com|najdi|naver|naver\.com|news\.google\.com|nl\.search\.yahoo\.com|no\.search\.yahoo\.com|ntp\.msn\.com|nz\.search\.yahoo\.com|onet|onet\.pl|pe\.search\.yahoo\.com|ph\.search\.yahoo\.com|pl\.search\.yahoo\.com|play\.google\.com|qwant|qwant\.com|rakuten|rakuten\.co\.jp|rambler|rambler\.ru|se\.search\.yahoo\.com|search-results|search\.aol\.co\.uk|search\.aol\.com|search\.google\.com|search\.smt\.docomo\.ne\.jp|search\.ukr\.net|secureurl\.ukr\.net|seznam|seznam\.cz|sg\.search\.yahoo\.com|so\.com|sogou|sogou\.com|sp-web\.search\.auone\.jp|startsiden|startsiden\.no|suche\.aol\.de|terra|th\.search\.yahoo\.com|tr\.search\.yahoo\.com|tut\.by|tw\.search\.yahoo\.com|uk\.search\.yahoo\.com|ukr|us\.search\.yahoo\.com|virgilio|vn\.search\.yahoo\.com|wap\.sogou\.com|webmaster\.yandex\.ru|websearch\.rakuten\.co\.jp|yahoo|yahoo\.co\.jp|yahoo\.com|yandex|yandex\.by|yandex\.com|yandex\.com\.tr|yandex\.fr|yandex\.kz|yandex\.ru|yandex\.ua|y
43andex\.uz|zen\.yandex\.ru)$", "i").test(v.utmSource) || v.utmMedium.toLowerCase() === "organic"},{"name":"referral","test":(v) => new RegExp("^(?:referral|app|link)$", "i").test(v.utmMedium)},{"name":"email","test":(v) => new RegExp("^(?:email|e-mail|e_mail|e mail)$", "i").test(v.utmMedium) || new RegExp("^(?:email|e-mail|e_mail|e mail)$", "i").test(v.utmSource)},{"name":"affiliate","test":(v) => v.utmMedium.toLowerCase() === "affiliate"},{"name":"audio","test":(v) => v.utmMedium.toLowerCase() === "audio"},{"name":"sms","test":(v) => v.utmSource.toLowerCase() === "sms" || v.utmMedium.toLowerCase() === "sms"},{"name":"mobile-push-notification","test":(v) => v.utmSource.toLowerCase() === "firebase" || new RegExp("(?:.*mobile.*|.*notification.*|push$)", "i").test(v.utmMedium)}].find(i=>i.test(e))?.name??"other"}getShopifyAnalyticsId(){const e=this.getCookie("_shopify_y");if(e)return e;try{const t=this.localStorageGet("Shoplift_ClientId");if(t)return t}catch{}return null}legacyGetCookieVisitor(){const e=this.getCookie("SHOPLIFT");return e===null?null:JSON.parse(e,F)}getCookie(e){const t=this.cookie.split("; ").filter(i=>i.split("=").at(0)===e).at(0);return t===void 0?null:t.split("=").slice(1).join("=")}monitorConsentChange(){document.addEventListener("visitorConsentCollected",e=>{(async()=>await this.onConsentChange(e.detail.analyticsAllowed,!0))()}),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.loadShopifyConsentApiWithRetry()):this.loadShopifyConsentApiWithRetry()}loadShopifyConsentApiWithRetry(){let e=0;const t=()=>{this.loadShopifyConsentApi()||e++<10&&window.setTimeout(t,100)};t()}loadShopifyConsentApi(){if(window.Shopify){this.log("Loading Shopify features");const e=async()=>{if(!window.Shopify){this.log("Shopify object missing... suddenly?");return}if(window.Shopify.customerPrivacy===void 0){this.log("Shopify CustomerPrivacy api still missing, trying again in 1000ms"),t=window.setTimeout(()=>{(async()=>await e())()},1e3);return}if(this.geoViaShopify){const s=window.Shopify.customerPrivacy.getRegion?.();this.resolvedRegion=typeof s=="string"?s.replace(/-/g,""):""}const i=window.Shopify.customerPrivacy.getTrackingConsent();await this.onConsentChange(window.Shopify.customerPrivacy.analyticsProcessingAllowed(),i==="yes")};let t=window.setTimeout(()=>{(async()=>await e())()},5e3);return window.Shopify.loadFeatures([{name:"consent-tracking-api",version:"0.1"}],i=>{(async()=>{if(window.clearTimeout(t),i){this.log("Error loading consent tracking",i);return}await e()})()}),!0}return!1}async onConsentChange(e,t){try{if(this.log("Consent change detected",e,t),this.state.essential.consentApproved=e,this.state.essential.hasConsentInteraction=t,!this.state.essential.consentApproved){this.state.essential.hasConsentInteraction&&(this.state.analytics.queue.length=0),this.saveState();return}this.cookie=document.cookie,this.shopifyAnalyticsId=this.getShopifyAnalyticsId(),this.saveState(),await this.syncAllEvents()}catch(i){this.log("Error syncing on consent change",i)}}isThemePreview(){return isThemePreview||themeRole!=="main"}isAppProxyPath(){const e=["/apps/","/tools/","/a/"],t=window.location.pathname;return e.some(i=>t.startsWith(i))}clearThemeBar(e,t,i){const s=structuredClone(i);this.log("Looking for theme bar"),this.waitForElement(null,"body").then(r=>this.waitForElement(r,"#preview-bar-iframe, #PBarNextFrameWrapper").then(o=>(this.log("Found theme bar"),t&&(this.log("Removing theme bar"),o.remove()),e?this.makeRequest({url:`${this.eventHost}/api/v0/logs`,method:"post",data:JSON.stringify({...this.debugState(),stateAtEvaluation:s},ee)}):Promise.resolve(null)))).catch(r=>console.error(r))}waitForElement(e,t){return new Promise(i=>{const s=document.querySelector(t);if(s){i(s);return}const r=new MutationObserver(o=>{const n=document.querySelector(t);if(n){r.disconnect(),i(n);return}});r.observe(e??document.documentElement,{childList:!0})})}setDebug(e){this.state.essential.debugMode=e,this.saveState()}log(e,...t){let i=0;const s=e.replace(/%[sdoOfF]/g,r=>{if(i>=t.length)return r;const o=t[i++];return r==="%o"||r==="%O"?JSON.stringify(o):String(o)});this.logHistory.push(`[${new Date().toISOString()}][SL] ${s}`),!(!this.state.essential.debugMode&&!this.shopliftDebug)&&console.debug(`[SL] ${e}`,...t)}debugState(){return{state:this.state,storage:{essential:this.loadLocalStorage(this.essentialSessionKey),analytics:this.loadLocalStorage(this.analyticsSessionKey)},params:{shop:this.shop,host:this.host,eventHost:this.eventHost,cssHideClass:this.cssHideClass,testConfigs:this.testConfigs,inactiveTestConfigs:this.inactiveTestConfigs,sendPageView:this.sendPageView,isShopifyMerchantCookie
43:this.getCookie("is_shopify_merchant"),themeId,url:window.location.href,isThemePreview,themeRole,gaConfig:this.gaConfig},logHistory:this.logHistory}}createViewportObserver(e,t={}){const{threshold:i=this.VIEWPORT_TRACK_THRESHOLD,triggerOnce:s=!0}=t,r=new Set;return new IntersectionObserver(o=>{o.forEach(n=>{if(n.isIntersecting&&!r.has(n.target)){const l=n.target,c=l.getAttribute(this.DATA_SL_TEST_ID);c&&(e(c,l),s&&r.add(l))}})},{threshold:i})}applyChangesWithViewport(e,t,i,s){const r=t.selectorsForViewportTracking??t.selectors,o=n=>{if(this.state.essential.visitorTests.some(h=>h.testId===n)||this.activeViewportObservers.has(n))return;const l=[];if(r.forEach(h=>{e.querySelectorAll(h.cssSelector).forEach(b=>l.push(b))}),l.length===0)return;let c=!1;const d=()=>{c||(c=!0,i(n),u.disconnect(),this.activeViewportObservers.delete(n))},u=this.createViewportObserver(()=>{d()},{triggerOnce:!0,...s});this.activeViewportObservers.set(n,u),this.log(`Created viewport observer for test ${n}, observing ${l.length} elements`),l.forEach(h=>{h.setAttribute(this.DATA_SL_TEST_ID,String(n)),u.observe(h)}),setTimeout(()=>{c||l.forEach(h=>{const p=h.getBoundingClientRect(),b=s?.threshold??this.VIEWPORT_TRACK_THRESHOLD,E=Math.min(p.bottom,window.innerHeight)-Math.max(p.top,0),S=Math.min(p.right,window.innerWidth)-Math.max(p.left,0);p.top<window.innerHeight&&p.bottom>0&&p.left<window.innerWidth&&p.right>0&&E>0&&S>0&&E>=p.height*b&&(this.log(`Price element already visible in viewport for test ${n}:`,h),d())})},100)};t.selectors.length>0&&U(e,t,()=>{}),Te(e,{testId:t.testId,hypothesisId:t.hypothesisId,selectors:r},n=>{o(n)})}applyPriceTestWithMapLookup(e,t,i,s){if(!t.priceData){this.log("No price data for hypothesis '%s'",t.id);return}this.log("Hypothesis '%s' isControl=%s, priceData has %d variants",t.id,t.isControl,t.priceData.variants.length);const r=t.priceData.variants.slice(0,3);for(const[S,C,_]of r)this.log("  Sample priceData: variant=%s, price=%d, compareAt=%d",S,C,_);const o=j(t.priceData),n=new Set;for(const S of i)if(S.priceData)for(const[C]of S.priceData.variants)n.add(C);this.log("Price test Map lookup: %d products in hypothesis, %d total products to track",o.size,n.size);const l=t.priceData,c=new WeakSet;let d=!1;const u="[data-sl-attribute-p], [data-sl-attribute-cap], [data-sl-attribute-discount]",h=S=>{if(c.has(S))return;const C=S.getAttribute("data-sl-attribute-p"),_=S.getAttribute("data-sl-attribute-cap"),T=S.getAttribute("data-sl-attribute-discount"),m=C||_||T;if(!m||!n.has(m))return;c.add(S);const y=o.get(m);y&&(this.log("Applying price for product %s: %d cents (compare at: %d cents)",m,y.priceInCents,y.compareAtPriceInCents),Le(S,m,y,l),this.log("Applied price to element for product %s",m)),!d&&!this.state.essential.visitorTests.some(w=>w.testId===e)&&(S.setAttribute(this.DATA_SL_TEST_ID,String(e)),this.setupElementViewportTracking(S,e,()=>{d||(d=!0,s(e))}))},p=()=>{const S=document.querySelectorAll(u);this.log("Scanning for price elements, found: %d",S.length),S.forEach(h)},b=new MutationObserver(S=>{for(const C of S)C.type==="childList"&&C.addedNodes.forEach(_=>{if(_.nodeType===Node.ELEMENT_NODE){const T=_;(T.hasAttribute("data-sl-attribute-p")||T.hasAttribute("data-sl-attribute-cap")||T.hasAttribute("data-sl-attribute-discount"))&&h(T),T.querySelectorAll(u).forEach(h)}}),C.type==="attributes"&&C.target instanceof Element&&h(C.target)}),E=document.body||document.documentElement;b.observe(E,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-sl-attribute-p","data-sl-attribute-cap","data-sl-attribute-discount"]}),this.log("MutationObserver started for price elements"),p(),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",()=>{this.log("DOMContentLoaded - rescanning for price elements"),p()}),setTimeout(()=>{this.log("Delayed rescan for price elements"),p()},100),setTimeout(()=>{this.log("Final rescan for price elements"),p()},500)}setupElementViewportTracking(e,t,i){const s=this.VIEWPORT_TRACK_THRESHOLD,r=e.getBoundingClientRect(),o=Math.min(r.bottom,window.innerHeight)-Math.max(r.top,0),n=Math.min(r.right,window.innerWidth)-Math.max(r.left,0);if(r.top<window.innerHeight&&r.bottom>0&&r.left<window.innerWidth&&r.right>0&&o>0&&n>0&&o>=r.height*s){this.log("Price element already visible for test %s",t),i();return}const c=new IntersectionObserver(d=>{for(const u of d)if(u.isIntersecting&&u.intersectionRatio>=s){this.log("Price element entered viewport for test %s",t),c.disconnect(),i();break}},{threshold:s});c.observe(e)}debug(){const e=this.debugState();console.log(JSON.stringify(e,ee,2))}}(async function(){window.shopliftInstance||(window.shopliftInstance=new Ze("revitin.myshopify.com","https://app.shoplift.ai","https://events.shoplift.ai",false,false,false,{"sendEvents":false,"mode":"gtag"},false,false,1000,[],[{"id":"019e64e9-ad77-7cf4-a909-f8c4d75ff6ca","bayesianRevision":5,"status":"cancelled","hypotheses":[{"id":"019e64e6-57b6-73d6-86b0-8faa336f3aa3","type":"theme","themeId":153996034186,"affix":"","isControl":true,"redirectPath":null},{"id":"019e64e8-705c-7c99-ac18-a4ed8c34775a","type":"theme","themeId":154185007242,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"2e9c5625-ec4d-456a-934f-31b40c7d7d44","bayesianRevision":3,"status":"cancelled","hypotheses":[{"id":"6fe99f17-afb1-4a4
436-b8ff-4cb218a0c561","type":"theme","themeId":142784397450,"affix":"","isControl":true,"redirectPath":null},{"id":"19af5f1d-8113-47e8-914e-a26ec8cd002a","type":"theme","themeId":143245672586,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"019beb7e-cb56-766e-9f1d-fcc359034aa6","bayesianRevision":5,"status":"cancelled","hypotheses":[{"id":"019beb7d-26ac-7b79-8f84-de017773cca2","type":"theme","themeId":149199421578,"affix":"","isControl":true,"redirectPath":null},{"id":"019beb7d-4ef0-7274-a5ee-16b90c94434e","type":"theme","themeId":150987178122,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"019b028d-1cdf-71bd-b451-0eed4ef409b8","bayesianRevision":5,"status":"cancelled","hypotheses":[{"id":"019b028b-c0dd-7689-a159-d038d73b9c7a","type":"theme","themeId":149199421578,"affix":"","isControl":true,"redirectPath":null},{"id":"019b028c-1fbf-77b4-a95e-1118c0568c06","type":"theme","themeId":149195653258,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"5524dab4-f662-4fdf-bad4-1f8993b0fbdd","bayesianRevision":3,"status":"cancelled","hypotheses":[{"id":"7f23efa0-c3b9-4d8e-bc8d-ce367e38cb19","type":"theme","themeId":142784397450,"affix":"","isControl":true,"redirectPath":null},{"id":"acb75071-4e66-494a-b067-0659764a3b4f","type":"theme","themeId":143254388874,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"019c8605-1b2e-784a-85b6-cbbbdac5eb0e","bayesianRevision":5,"status":"cancelled","hypotheses":[{"id":"019c806d-cfae-712a-bc57-c77fb853df85","type":"theme","themeId":151416242314,"affix":"","isControl":true,"redirectPath":null},{"id":"019c8604-be84-7a73-af35-ce1cc8fd2205","type":"theme","themeId":151890460810,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"01c5c788-303f-4467-8dc9-bfafd3155d95","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"58615777-8062-456c-881b-204b3c835c99","type":"theme","themeId":142784397450,"affix":"","isControl":true,"redirectPath":null},{"id":"f284de3b-eb8e-4c3f-8321-e077e0374b13","type":"theme","themeId":144210133130,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"564b21f9-c88f-4af2-a688-ebd7b5127b33","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"9d92bd30-8af2-43c1-9eab-31a0e2a427c9","type":"theme","themeId":142784397450,"affix":"","isControl":true,"redirectPath":null},{"id":"11c6ff46-c713-4196-a3ca-032dcbab6db0","type":"theme","themeId":143587246218,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"c89f76bc-0224-41e8-a078-918b1c65545b","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"230e109e-040e-4923-9a26-24b022b5d946","type":"theme","themeId":144790487178,"affix":"","isControl":true,"redirectPath":null},{"id":"ff165228-e2fe-4037-b014-585f7f5cf86f","type":"theme","themeId":145298063498,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"4c50d46e-082c-4449-ae34-3e09724542ca","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"70e25a68-b08d-4019-b4d3-00aefce14946","type":"theme","themeId":144790487178,"affix":"","isControl":true,"redirectPath":null},{"id":"6ffe7a37-37b0-4f8c-9306-9fff0d599d2c","type":"theme","themeId":145180655754,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"631e1f7b-be13-4500-8c37-cf2de0ec78c4","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"4a18aa00-7c48-4f0c-b6c4-4e3e11038948","type":"theme","themeId":146684379274,"affix":"","isControl":true,"redirectPath":null},{"id":"e63193e8-0408-4cd6-a005-27f6de6a1e4c","type":"theme","themeId":146649415818,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"8f52e54d-d000-49e2-9000-d68f4f143e2d","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"822ae8d0-27cc-4aea-a54f-d22f43bda408","type":"theme","themeId":144790487178,"affix":"","isControl":true,"redirectPath":null},{"id":"5c36149a-6035-432c-8055-6cb3ff0dec91","type":"theme","themeId":145512104074,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false}
43,{"id":"1a7d037a-961e-42a1-b86e-acc6122bae21","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"95b400ec-b013-4fca-84b9-4faceb97bb3c","type":"theme","themeId":144790487178,"affix":"","isControl":true,"redirectPath":null},{"id":"ec79c7ef-0cc0-459c-85a7-29c14dd43805","type":"theme","themeId":145483628682,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"c7d79f11-63bb-4c56-9803-8e3cc1b9e376","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"37b5cf95-c01f-48da-a9b8-8fac90c099f2","type":"theme","themeId":146684379274,"affix":"","isControl":true,"redirectPath":null},{"id":"6cabf295-0cb5-4e7c-b5b9-9b50ac9d8383","type":"theme","themeId":146364137610,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"3ad08a9f-4126-47bd-8259-d659dfa0c5d0","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"bf83841a-f86d-46a3-a0ee-15ccc13ce767","type":"theme","themeId":146649415818,"affix":"","isControl":true,"redirectPath":null},{"id":"e14ae338-b593-42e9-ab99-badaa000b573","type":"theme","themeId":146809356426,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"019aa715-4316-7ea8-a024-0667ec13e1f9","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"019aa713-49b3-72a3-aecd-fe2e45ce3905","type":"theme","themeId":149060321418,"affix":"","isControl":true,"redirectPath":null},{"id":"019aa713-63ff-73ea-9d81-a3b1ce6f27fd","type":"theme","themeId":148999635082,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"019e64ee-d0a5-7077-9d6c-dc5f255c2a5b","bayesianRevision":5,"status":"cancelled","hypotheses":[{"id":"019e64ed-c06e-7e37-90ea-05b30e0f1da6","type":"theme","themeId":153996034186,"affix":"","isControl":true,"redirectPath":null},{"id":"019e64ee-007b-7601-a160-3c4597afb609","type":"theme","themeId":154185040010,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"019aa716-5403-73df-ade6-14273ad1a69c","bayesianRevision":4,"status":"cancelled","hypotheses":[{"id":"019aa715-712f-7cd4-94b9-f708b554a4ed","type":"theme","themeId":149060321418,"affix":"","isControl":true,"redirectPath":null},{"id":"019aa715-8cef-7e37-93a5-1b83fa66f171","type":"theme","themeId":148959232138,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false},{"id":"019ef4e5-07ef-7d8e-a04c-7db4753a9faa","bayesianRevision":5,"status":"cancelled","hypotheses":[{"id":"019ef4e3-fea1-7f8b-ae63-3810652dc48a","type":"theme","themeId":153996034186,"affix":"","isControl":true,"redirectPath":null},{"id":"019ef4e4-3117-7f62-ae74-dedc7fd71d10","type":"theme","themeId":155127873674,"affix":"","isControl":false,"redirectPath":null}],"ignoreTestViewParameterEnforcement":false}],null,false),await window.shopliftInstance.init())})();async function Qe(a,e,t,i){const s=Be({log:i});if(t)return i("[SUB-PREVIEW] A side — no overlay applied; widget renders naturally"),s;const r=a.widget.widgetType,o=e?j(e):null;let n=W(e),l=J(a,n),c=l.discountMap,d=l.maxDiscount;function u(){const f=W(e);f!==n&&(n=f,l=J(a,n),c=l.discountMap,d=l.maxDiscount,i(`[SUB-PREVIEW] scope refreshed currentProductId=${n??"n/a"}, maxDiscount=${d}`))}i(`[SUB-PREVIEW] side=B, currentProductId=${n??"n/a"}, maxDiscount=${d}`);function h(f){if(!e||!o)return null;const v=Z(o),g=v?o.get(v):void 0;return g?{formattedVariantPrice:G(g.priceInCents,e),formattedDiscounted:G(g.priceInCents*(1-f/100),e)}:null}function p(f){const v=Y(a,f);if(!v)return d;const g=D(a,"subscriptionInput"),P=g.length?g[0].selector:'input[name="rc_plan"]',A=v.querySelector(`${P}:checked`);if(A){const k=c[A.value];if(k!==void 0)return k}return d}function b(f){const v=D(a,"subscriptionDiscount");for(const g of v)if(g.selector.includes("badge")||g.selector.includes("__badge")){const P=f.querySelector(g.selector);P?.textContent&&!P.textContent.includes(`${d}%`)&&$(P,A=>N(A,d))}}function E(f,v){const g=h(v);if(!g)return;const P=D(a,"subscriptionCompareAt");for(const A of P){const k=f.querySelector(A.selector)||f.querySelector(`[part~="${A.selector}"]`);k?.textContent&&!k.textContent.includes(g.formattedVariantPrice)&&$(k,x=>/\d/.test(x)?g.formattedVariantPrice:x)}}function S(f,v){const g=h(v);if(!g)return;const P=D(a,"subscriptionPrice");for(const A of P){const k=f.querySelector(A.selector)||f.querySelector(`[part~="${A.selector}"]`);k?.textContent&&!k.textContent.includes(g.formattedDiscounted)&&$(k,x=>/\d/.test(x)?g.formattedDiscounted:x)}}function C(f){const v=D(a,"subscriptionInput"),g=v.length?v[0].selector:'input[name="rc_plan"]',P=D(a,"subscriptionPlanDiscount"),A=P.length?P[0].selector:".rc-plans-button__discount";for(const k of Array.from(f.querySelectorAll("label"))){const x=k.querySelector(g),R=k.querySelector(A);if(x&&R?.textContent){const O=c[x.value];if(O!==void 0){const V=R.textContent.match(/[\d.]+%/)?.[0];V&&V!==`${O}%`&&$(R,L=>N(L,O))}}}}function _(f){const v=f.querySelector("select");if(v)for(const g of Array.from(v.options)){const P=c[g.value];if(P!==void 0&&g.textContent){const A=g.textContent.match(/[\d.]+%/)?.[0];A&&A!==`${P}%`&&(g.textContent=N(g.textContent,P))}}}function T(f){const v=D(a,"onetimePrice");if(!v.length||!e||!o)return;const g=Z(o),P=g?o.get(g):void 0;if(!P)return;const A=G(P.priceInCents,e),k=D(a,"onetimeContainer"),x=k.length?k[0].selector:'[part~="rc-purchase-option__onetime"]',R=f.querySelector(x);if(R)for(const O of v){const V=R.querySelector(`[part~="${O.selector}"]`);V?.textContent&&!V.textContent.includes(A)&&$(V,L=>/\d/.test(L)?A:L)}}function m(f,v){const P=D(a,"subscriptionDiscount").filter(A=>A.selector.includes("benefit")||A.selector==="rc-benefits");for(const A of P){const k=f.querySelector(A.selector);if(k?.shadowRoot){for(const x of Array.from(k.shadowRoot.querySelectorAll("li")))if(x.textContent?.includes("Save")){const R=x.textContent.match(/[\d.]+%/)?.[0];R&&R!==`${v}%`&&$(x,O=>N(O,v))}}}}let y=!1;function w(){if(!y){y=!0;try{u();const f=B(a);if(!f)return;const v=p(f);b(f),E(f,v),S(f,v),T(f);const g=Y(a,f);g&&(r==="buttons"||r==="radio"?C(g):_(g)),m(f,v)}finally{y=!1}}}const I=pe({data:a,runUpdates:w});return function(){I(),s()}}const Xe=Object.freeze(Object.defineProperty({__proto__:null,subscriptionPreviewRender:Qe},Symbol.toStringTag,{value:"Module"}))})(); })("/", { suffix: "", type: "product" }, "main", 153996034186, false)</script>
43
44    <!-- End of Shoplift scripts -->
45
46    <meta name="google-site-verification" content="MXnRc1jmvxm9zsLYqRnkToZnYziGVUxU09LeCl1NvfA">
47    <meta charset="utf-8">
48    <meta http-equiv="X-UA-Compatible" content="IE=edge">
49    <meta name="viewport" content="width=device-width,initial-scale=1">
50    <meta name="theme-color" content="">
51
52    
53    
54    
55      <link rel="canonical" href="https://revitin.com/products/revitin-natural-toothpaste">
56    
57
58    <link rel="preconnect" href="https://cdn.shopify.com" crossorigin>
59
60    <link
61      rel="preload"
62      as="image"
63      href="https://revitin.myshopify.com/cdn/shop/t/36/assets/main-orange.png"
64    >
65    <link
66      rel="preload"
67      as="image"
68      href="https://revitin.myshopify.com/cdn/shop/t/36/assets/main-grapefruit.png"
69    >
70    <link
71      rel="preload"
72      as="image"
73      href="https://revitin.myshopify.com/cdn/shop/t/36/assets/main-papaya.png"
74    >
75    <link
76      rel="preload"
77      as="image"
78      href="https://revitin.myshopify.com/cdn/shop/t/36/assets/main-lemon.png"
79    ><link
80        rel="icon"
81        type="image/png"
82        href="//revitin.com/cdn/shop/files/citrus-logo.png?crop=center&height=32&v=1730052959&width=32"
83      ><title>Revitin | SLS-Free Toothpaste | Buy Fluoride-Free Toothpaste Online
84</title>
85
86    
87      <meta name="description" content="Buy Revitin SLS-free, fluoride-free toothpaste online. Prebiotic formula with Vitamin C, CoQ10 &amp; cranberry seed oil supports enamel &amp; fresh breath">
88    
89
90    
91
92<meta property="og:site_name" content="Revitin">
93<meta property="og:url" content="https://revitin.com/products/revitin-natural-toothpaste">
94<meta property="og:title" content="Revitin | SLS-Free Toothpaste | Buy Fluoride-Free Toothpaste Online">
95<meta property="og:type" content="product">
96<meta property="og:description" content="Buy Revitin SLS-free, fluoride-free toothpaste online. Prebiotic formula with Vitamin C, CoQ10 &amp; cranberry seed oil supports enamel &amp; fresh breath"><meta property="og:image" content="https://cdn.shopify.com/s/files/1/0376/8972/0970/files/Revitin_Mint_tube_box_product_shot.png?v=1790079103">
97    <meta property="og:image:secure_url" content="https://cdn.shopify.com/s/files/1/0376/8972/0970/files/Revitin_Mint_tube_box_product_shot.png?v=1790079103">
98    <meta property="og:image:width" content="630">
99    <meta property="og:image:height" content="1200"><meta property="og:price:amount" content="17.00">
100  <meta property="og:price:currency" content="USD"><meta name="twitter:card" content="summary_large_image">
101<meta name="twitter:title" content="Revitin | SLS-Free Toothpaste | Buy Fluoride-Free Toothpaste Online">
102<meta name="twitter:description" content="Buy Revitin SLS-free, fluoride-free toothpaste online. Prebiotic formula with Vitamin C, CoQ10 &amp; cranberry seed oil supports enamel &amp; fresh breath">
103
104    
104<script src="//revitin.com/cdn/shop/t/129/assets/swiper-bundle.min.js?v=87330480114418983271777542405" defer></script>
104
105    
105<script src="//revitin.com/cdn/shop/t/129/assets/web-components.js?v=42699711469469777231785948103" defer></script>
105
106    
106<script src="//revitin.com/cdn/shop/t/129/assets/gwp.js?v=91107431928599107341787719402" defer></script>
106<script>
107      window.RevitinGWP = Object.assign(window.RevitinGWP || {}, {
108        enabled: false,
109        isWholesale: false,
110        handle: "variety-travel-2-pack-of-1-oz",
111        productId: 9208964186250,
112        variantId: 49777251877002
113      });
114    </script>
114
115    
115<script src="//revitin.com/cdn/shop/t/129/assets/swiper.js?v=169847002317838591371777542405"></script>
115
116
117    
118    
118<script>window.performance && window.performance.mark && window.performance.mark('shopify.content_for_header.start');</script>
118<meta name="google-site-verification" content="TM7UwSLIsjzSApI0vz9CDDNBxARLzowvI9ah-R2lztQ">
119<meta name="google-site-verification" content="ysyTOABQ_pw1KSMnMjHUU7SSBUlUFjbpLVl0F5TBgWU">
120<meta id="shopify-digital-wallet" name="shopify-digital-wallet" content="/37689720970/digital_wallets/dialog">
121<link rel="ucp" href="/.well-known/ucp" version="2026-08-25"><link rel="buy" href="/cart/45594631471242:1?ucp/version=2026-08-25&amp;context/payment/0/handler=dev.shopify.shop_pay" payment="dev.shopify.shop_pay com.google.pay dev.shopify.card"><link rel="alternate" type="application/json+oembed" href="https://revitin.com/products/revitin-natural-toothpaste.oembed">
122<script async="async" src="/checkouts/internal/preloads.js?locale=en-US&default_configuration_id=8028298"></script>
122
123<link rel="preconnect" href="https://shop.app" crossorigin="anonymous">
124<script async="async" src="https://shop.app/checkouts/internal/preloads.js?locale=en-US&default_configuration_id=8028298&shop_id=37689720970" crossorigin="anonymous"></script>
vendor: 1 bytes, line 124
124
125<script id="apple-pay-shop-capabilities" type="application/json">{"shopId":37689720970,"countryCode":"US","currencyCode":"USD","merchantCapabilities":["supports3DS"],"merchantId":"gid:\/\/shopify\/Shop\/37689720970","merchantName":"Revitin","requiredBillingContactFields":["postalAddress","email"],"requiredShippingContactFields":["postalAddress","email"],"shippingType":"shipping","supportedNetworks":["visa","masterCard","amex","discover","elo","jcb"],"total":{"type":"pending","label":"Revitin","amount":"1.00"},"shopifyPaymentsEnabled":true,"supportsSubscriptions":true}</script>
vendor: 1 bytes, line 125
125
126<script id="shopify-features" type="application/json">{"accessToken":"a7e8321f0c73cc9d743a2fc8b66839ac","betas":["rich-media-storefront-analytics"],"domain":"revitin.com","predictiveSearch":true,"shopId":37689720970,"locale":"en"}</script>
vendor: 1 bytes, line 126
126
127<script>var Shopify = Shopify || {};
128Shopify.shop = "revitin.myshopify.com";
129Shopify.locale = "en";
130Shopify.currency = {"active":"USD","rate":"1.0"};
131Shopify.country = "US";
132Shopify.theme = {"name":"Revitin-Shopify\/main","id":153996034186,"schema_name":"Dawn","schema_version":"6.0.2","theme_store_id":null,"role":"main"};
133Shopify.theme.handle = "null";
134Shopify.theme.style = {"id":null,"handle":null};
135Shopify.cdnHost = "revitin.com/cdn";
136Shopify.routes = Shopify.routes || {};
137Shopify.routes.root = "/";
138Shopify.shopJsCdnBaseUrl = "https://cdn.shopify.com/shopifycloud/shop-js";
139Shopify.SignInWithShop = Shopify.SignInWithShop || {};
140Shopify.SignInWithShop.User = Shopify.SignInWithShop.User || {};
141Shopify.SignInWithShop.User.recognized = false;</script>
vendor: 1 bytes, line 141
141
142<script type="module">!function(o){(o.Shopify=o.Shopify||{}).modules=!0}(window);</script>
vendor: 1 bytes, line 142
142
143<script>!function(o){function n(){var o=[];function n(){o.push(Array.prototype.slice.apply(arguments))}return n.q=o,n}var t=o.Shopify=o.Shopify||{};t.loadFeatures=n(),t.autoloadFeatures=n()}(window);</script>
vendor: 1 bytes, line 143
143
144<script>
145  window.ShopifyPay = window.ShopifyPay || {};
146  window.ShopifyPay.apiHost = "shop.app\/pay";
147  window.ShopifyPay.redirectState = null;
148</script>
vendor: 1 bytes, line 148
148
149<script>
150  window.Shopify = window.Shopify || {};
151  window.Shopify.SignInWithShop = window.Shopify.SignInWithShop || {};
152  window.Shopify.SignInWithShop.assetMetrics = { sampleRate: 0.25 };
153  window.Shopify.SignInWithShop.eligible = true;
154</script>
vendor: 1 bytes, line 154
154
155<script id="shop-js-analytics" type="application/json">{"pageType":"product"}</script>
vendor: 1 bytes, line 155
155
156<script defer="defer" async type="module" src="https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.init-shop-cart-sync.en.esm.js"></script>
vendor: 1 bytes, line 156
156
157<script type="module">
158  await import("https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.init-shop-cart-sync.en.esm.js");
159
160  window.Shopify.SignInWithShop?.initShopCartSync?.({"fedCMEnabled":true,"windoidEnabled":true});
161
162</script>
vendor: 1 bytes, line 162
162
163<script>
164  window.Shopify = window.Shopify || {};
165  if (!window.Shopify.featureAssets) window.Shopify.featureAssets = {};
166  window.Shopify.featureAssets['shop-js'] = {"avatar":["modules/v2/loader.avatar.en.esm.js"],"checkout-modal":["modules/v2/loader.checkout-modal.en.esm.js"],"init-customer-accounts-sign-up":["modules/v2/loader.init-customer-accounts-sign-up.en.esm.js"],"init-customer-accounts":["modules/v2/loader.init-customer-accounts.en.esm.js"],"init-fed-cm":["modules/v2/loader.init-fed-cm.en.esm.js"],"init-shop-cart-sync":["modules/v2/loader.init-shop-cart-sync.en.esm.js"],"init-shop-email-lookup-coordinator":["modules/v2/loader.init-shop-email-lookup-coordinator.en.esm.js"],"init-shop-for-new-customer-accounts":["modules/v2/loader.init-shop-for-new-customer-accounts.en.esm.js"],"init-shop-user-recognition":["modules/v2/loader.init-shop-user-recognition.en.esm.js"],"init-windoid":["modules/v2/loader.init-windoid.en.esm.js"],"lead-capture":["modules/v2/loader.lead-capture.en.esm.js"],"listener":["modules/v2/loader.listener.en.esm.js"],"pay-button":["modules/v2/loader.pay-button.en.esm.js"],"payment-terms":["modules/v2/loader.payment-terms.en.esm.js"],"shop-button":["modules/v2/loader.shop-button.en.esm.js"],"shop-cart-sync":["modules/v2/loader.shop-cart-sync.en.esm.js"],"shop-cash-offers":["modules/v2/loader.shop-cash-offers.en.esm.js"],"shop-follow-button":["modules/v2/loader.shop-follow-button.en.esm.js"],"shop-login-button":["modules/v2/loader.shop-login-button.en.esm.js"],"shop-login":["modules/v2/loader.shop-login.en.esm.js"],"shop-toast-manager":["modules/v2/loader.shop-toast-manager.en.esm.js"],"shop-user-recognition":["modules/v2/loader.shop-user-recognition.en.esm.js"]};
167</script>
vendor: 1 bytes, line 167
167
168<script>(function() {
169  var isLoaded = false;
170  function asyncLoad() {
171    if (isLoaded) return;
172    isLoaded = true;
173    var urls = ["https:\/\/cdn1.stamped.io\/files\/widget.min.js?shop=revitin.myshopify.com","\/\/secure.apps.shappify.com\/apps\/csp\/customer_pricing.php?shop=revitin.myshopify.com","https:\/\/cp.boldapps.net\/csp_install_check.js?shop=revitin.myshopify.com","https:\/\/cp.boldapps.net\/js\/cspqb.js?shop=revitin.myshopify.com","https:\/\/secureddatasystem.com\/ShopifyApps\/aispeed_2\/store-assets\/js\/aispeed.js?shop=revitin.myshopify.com","https:\/\/secureddatasystem.com\/ShopifyApps\/aispeed_2\/store-assets\/js\/aispeed.js?shop=revitin.myshopify.com","https:\/\/secureddatasystem.com\/ShopifyApps\/aispeed_2\/store-assets\/js\/aispeed.js?shop=revitin.myshopify.com","https:\/\/static.klaviyo.com\/onsite\/js\/klaviyo.js?company_id=YmxebZ\u0026shop=revitin.myshopify.com","https:\/\/formbuilder.hulkapps.com\/skeletopapp.js?shop=revitin.myshopify.com","https:\/\/static.klaviyo.com\/onsite\/js\/klaviyo.js?company_id=WSqXYN\u0026shop=revitin.myshopify.com","https:\/\/static.klaviyo.com\/onsite\/js\/klaviyo.js?company_id=WSqXYN\u0026shop=revitin.myshopify.com","https:\/\/static.shareasale.com\/json\/shopify\/deduplication.js?shop=revitin.myshopify.com","https:\/\/static.shareasale.com\/json\/shopify\/shareasale-tracking.js?sasmid=65308\u0026ssmtid=19038\u0026shop=revitin.myshopify.com","https:\/\/static.rechargecdn.com\/static\/js\/recharge.js?rev=b8f816a11c7e36039898a7e01ce2c51af24f486c\u0026shop=revitin.myshopify.com","https:\/\/cdn.nfcube.com\/instafeed-da16887788b96861a8e7a831fdc68a91.js?shop=revitin.myshopify.com","https:\/\/cdn-bundler.nice-team.net\/app\/js\/bundler.js?shop=revitin.myshopify.com","https:\/\/static.rechargecdn.com\/assets\/js\/widget.min.js?shop=revitin.myshopify.com","\/\/cdn.shopify.com\/proxy\/9e2536e0fa9a3978eb238b6e0ce8a737b9c337692837744cd02a0d8d36665ce1\/api.goaffpro.com\/loader.js?shop=revitin.myshopify.com\u0026sp-cache-control=cHVibGljLCBtYXgtYWdlPTkwMA","https:\/\/cdn.hextom.com\/js\/quickannouncementbar.js?shop=revitin.myshopify.com"];
174    for (var i = 0; i < urls.length; i++) {
175      var s = document.createElement('script');
176      s.type = 'text/javascript';
177      s.async = true;
178      s.src = urls[i];
179      var x = document.getElementsByTagName('script')[0];
180      x.parentNode.insertBefore(s, x);
181    }
182  };
183  if(window.attachEvent) {
184    window.attachEvent('onload', asyncLoad);
185  } else {
186    window.addEventListener('load', asyncLoad, false);
187  }
188})();</script>
vendor: 1 bytes, line 188
188
189<script id="__st">var __st={"a":37689720970,"offset":-14400,"reqid":"92b14f4a-92cf-4ca7-868f-2d3322189ab5-1790777238","pageurl":"revitin.com\/products\/revitin-natural-toothpaste\/Citrus","u":"b3679641a969","p":"product","rtyp":"product","rid":6606432174218};</script>
vendor: 1 bytes, line 189
189
190<script>window.ShopifyPaypalV4VisibilityTracking = true;</script>
vendor: 1 bytes, line 190
190
191<script id="form-persister">!function(){'use strict';const t='contact',e='new_comment',n=[[t,t],['blogs',e],['comments',e],[t,'customer']],o='password',r='form_key',c=['recaptcha-v3-token','g-recaptcha-response','h-captcha-response',o],s=()=>{try{return window.sessionStorage}catch{return}},i='__shopify_v',u=t=>t.elements[r],a=function(){const t=[...n].map((([t,e])=>`form[action*='/${t}']:not([data-nocaptcha='true']) input[name='form_type'][value='${e}']`)).join(',');var e;return e=t,()=>e?[...document.querySelectorAll(e)].map((t=>t.form)):[]}();function m(t){const e=u(t);a().includes(t)&&(!e||!e.value)&&function(t){try{if(!s())return;!function(t){const e=s();if(!e)return;const n=u(t);if(!n)return;const o=n.value;o&&e.removeItem(o)}(t);const e=Array.from(Array(32),(()=>Math.random().toString(36)[2])).join('');!function(t,e){u(t)||t.append(Object.assign(document.createElement('input'),{type:'hidden',name:r})),t.elements[r].value=e}(t,e),function(t,e){const n=s();if(!n)return;const r=[...t.querySelectorAll(`input[type='${o}']`)].map((({name:t})=>t)),u=[...c,...r],a={};for(const[o,c]of new FormData(t).entries())u.includes(o)||(a[o]=c);n.setItem(e,JSON.stringify({[i]:1,action:t.action,data:a}))}(t,e)}catch(e){console.error('failed to persist form',e)}}(t)}const f=t=>{if('true'===t.dataset.persistBound)return;const e=function(t,e){const n=function(t){return'function'==typeof t.submit?t.submit:HTMLFormElement.prototype.submit}(t).bind(t);return function(){let t;return()=>{t||(t=!0,(()=>{try{e(),n()}catch(t){(t=>{console.error('form submit failed',t)})(t)}})(),setTimeout((()=>t=!1),250))}}()}(t,(()=>{m(t)}));!function(t,e){if('function'==typeof t.submit&&'function'==typeof e)try{t.submit=e}catch{}}(t,e),t.addEventListener('submit',(t=>{t.preventDefault(),e()})),t.dataset.persistBound='true'};!function(){function t(t){const e=(t=>{const e=t.target;return e instanceof HTMLFormElement?e:e&&e.form})(t);e&&m(e)}document.addEventListener('submit',t),document.addEventListener('DOMContentLoaded',(()=>{const e=a();for(const t of e)f(t);var n;n=document.body,new window.MutationObserver((t=>{for(const e of t)if('childList'===e.type&&e.addedNodes.length)for(const t of e.addedNodes)1===t.nodeType&&'FORM'===t.tagName&&a().includes(t)&&f(t)})).observe(n,{childList:!0,subtree:!0,attributes:!1}),document.removeEventListener('submit',t)}))}()}();</script>
vendor: 1 bytes, line 191
191
192<script integrity="sha256-JjoPp5ZfB1sSAs5SQaol1x1GgvveM+BgmRzyDexInEQ=" data-source-attribution="shopify.loadfeatures" defer="defer" src="//revitin.com/cdn/shopifycloud/storefront/assets/storefront/load_feature-1bd60354.js" crossorigin="anonymous"></script>
vendor: 1 bytes, line 192
192
193<script>(function () {var userAgent = navigator.userAgent;var platform = navigator.platform;var maxTouchPoints = navigator.maxTouchPoints || 0;var isIOS = /iPad|iPhone|iPod/.test(platform) || (platform === 'MacIntel' && maxTouchPoints > 1);var isMacSafari = platform.indexOf('Mac') === 0 && /Safari/.test(userAgent) && !/Chrome|Chromium|CriOS|FxiOS|Edg|OPR|Android/.test(userAgent);var isAppleSafari = isIOS || isMacSafari;if (isAppleSafari) {fetch('/sf_private_access_tokens' + location.search).catch(function () {});}function browserMajorVersion(pattern) {var match = userAgent.match(pattern);return match ? parseInt(match[1], 10) : null;}function shouldLoadAutosizesPolyfill() {if (!window.PerformanceObserver?.supportedEntryTypes?.includes('paint')) {return false;}var chromeVersion = browserMajorVersion(/Chrome\/(\d+)/);if (chromeVersion !== null) {return chromeVersion < 126;}var firefoxVersion = browserMajorVersion(/Firefox\/(\d+)/);if (firefoxVersion !== null) {return firefoxVersion < 150;}var safariVersion = isAppleSafari ? browserMajorVersion(/Version\/(\d+).*Safari\//) : null;if (safariVersion !== null) {return safariVersion < 27;}return true;}if (shouldLoadAutosizesPolyfill()) {var autosizesScript = document.createElement('script');autosizesScript.async = true;autosizesScript.crossOrigin = 'anonymous';autosizesScript.src = "//revitin.com/cdn/shopifycloud/storefront/assets/storefront/autosizes-84416378.js";(document.head || document.documentElement).appendChild(autosizesScript);}window.ShopifyAnalytics = window.ShopifyAnalytics || {};window.ShopifyAnalytics.performance = window.ShopifyAnalytics.performance || {};(function () {var LONG_FRAME_THRESHOLD = 50;var longAnimationFrames = [];var activeRafId = null;function collectLongFrames() {var previousTime = null;function rafMonitor(now) {if (activeRafId === null) {return;}var delta = now - previousTime;if (delta > LONG_FRAME_THRESHOLD) {longAnimationFrames.push({startTime: previousTime,endTime: now,});}previousTime = now;activeRafId = requestAnimationFrame(rafMonitor);}previousTime = performance.now();activeRafId = requestAnimationFrame(rafMonitor);}if (!window.PerformanceObserver?.supportedEntryTypes?.includes('long-animation-frame')) {collectLongFrames();var timeoutId = setTimeout(function () {cancelAnimationFrame(activeRafId);}, 10000);window.ShopifyAnalytics.performance.getLongAnimationFrames = function (stopCollection) {if (stopCollection === undefined) {stopCollection = false;}if (stopCollection) {clearTimeout(timeoutId);cancelAnimationFrame(activeRafId);}return longAnimationFrames;};}})();})();</script>
193<script crossorigin="anonymous" defer="defer" src="//revitin.com/cdn/shopifycloud/storefront/assets/shopify_pay/storefront-616277c7.js?v=20250812"></script>
vendor: 1 bytes, line 193
193
194<script id="shopify-origin-trials" async="async" integrity="sha256-qJbe/jEZBHtr5W/BlA2cKAz3vkXu6vJQyLjgvgCC86g=" src="//cdn.shopify.com/shopifycloud/storefront/assets/storefront/origin_trials-318ab40a.js" crossorigin="anonymous" onload="window.__shopifyOriginTrialsDone = true" onerror="window.__shopifyOriginTrialsDone = true"></script>
vendor: 1 bytes, line 194
194
195<script>
196  window.Shopify = window.Shopify || {};
197  window.Shopify.MCP = window.Shopify.MCP || {};
198  window.Shopify.MCP.enabled = true;
199  window.Shopify.MCP.shop = "revitin.myshopify.com";
200  window.Shopify.MCP.mcpEndpoint = "https:\/\/revitin.com\/api\/mcp";
201  window.Shopify.MCP.tools = [{"name":"search_shop_policies_and_faqs","description":"Used to get facts about the stores policies, products, or services.\nSome examples of questions you can ask are:\n  - What is your return policy?\n  - What is your shipping policy?\n  - What is your phone number?\n  - What are your hours of operation?\"\n","inputSchema":{"$schema":"https:\/\/json-schema.org\/draft\/2020-12\/schema","type":"object","properties":{"query":{"type":"string","description":"A natural language query."},"context":{"type":"string","description":"Additional information about the request such as user demographics, mood, location, or other relevant details that could help in tailoring the response appropriately."}},"required":["query"]}}];
202</script>
vendor: 1 bytes, line 202
202
203<script>(()=>{var d="shopify:webmcp_adapter_loaded",n=Symbol.for("shopify.webmcp_adapter_loading");function s(c,a,{win:r=window,doc:o=document}={}){function p(){try{return r.localStorage.getItem(d)==="true"}catch{return!1}}function l(){try{r.localStorage.setItem(d,"true")}catch{}}function u(){return typeof(o.modelContext||r.navigator?.modelContext)?.registerTool=="function"}function f(){if(r[n]||!u())return;let t=o.head||o.getElementsByTagName("head")[0];if(!t)return;let e=o.createElement("script");e.type="module",e.crossOrigin="anonymous",a&&(e.integrity=a),e.src=c,e.addEventListener("load",l,{once:!0}),e.addEventListener("error",()=>{r[n]=!1},{once:!0}),t.appendChild(e),r[n]=!0}function _(t){let e=o.getElementById("shopify-origin-trials");if(!e||r.__shopifyOriginTrialsDone){t();return}e.addEventListener("load",t,{once:!0}),e.addEventListener("error",t,{once:!0})}function i(){_(()=>r.setTimeout(f,0))}function m(){o.addEventListener("DOMContentLoaded",i,{once:!0})}p()?i():m()}s("\/\/revitin.com\/cdn\/shopifycloud\/storefront\/assets\/storefront\/webmcp-c6b62ece.js","sha256-ke4DDuBjdvea3vxLWxHc9E9nq8zihuG4IfYEGbb77ys=");})();
204</script>
vendor: 1 bytes, line 204
204
205<script data-source-attribution="shopify.dynamic_checkout.dynamic.init">var Shopify=Shopify||{};Shopify.PaymentButton=Shopify.PaymentButton||{isStorefrontPortableWallets:!0,init:function(){window.Shopify.PaymentButton.init=function(){};var t=document.createElement("script");t.src="https://revitin.com/cdn/shopifycloud/portable-wallets/latest/portable-wallets.en.js",t.type="module",document.head.appendChild(t)}};
206</script>
vendor: 1 bytes, line 206
206
207<script data-source-attribution="shopify.dynamic_checkout.buyer_consent">
208  function portableWalletsHideBuyerConsent(e){var t=document.getElementById("shopify-buyer-consent"),n=document.getElementById("shopify-subscription-policy-button");t&&n&&(t.classList.add("hidden"),t.setAttribute("aria-hidden","true"),n.removeEventListener("click",e))}function portableWalletsShowBuyerConsent(e){var t=document.getElementById("shopify-buyer-consent"),n=document.getElementById("shopify-subscription-policy-button");t&&n&&(t.classList.remove("hidden"),t.removeAttribute("aria-hidden"),n.addEventListener("click",e))}window.Shopify?.PaymentButton&&(window.Shopify.PaymentButton.hideBuyerConsent=portableWalletsHideBuyerConsent,window.Shopify.PaymentButton.showBuyerConsent=portableWalletsShowBuyerConsent);
209</script>
vendor: 1 bytes, line 209
209
210<script data-source-attribution="shopify.dynamic_checkout.cart.bootstrap">document.addEventListener("DOMContentLoaded",(function(){function t(){return document.querySelector("shopify-accelerated-checkout-cart, shopify-accelerated-checkout")}if(t())Shopify.PaymentButton.init();else{new MutationObserver((function(e,n){t()&&(Shopify.PaymentButton.init(),n.disconnect())})).observe(document.body,{childList:!0,subtree:!0})}}));
211</script>
211
212<link id="shopify-accelerated-checkout-styles" rel="stylesheet" media="screen" href="https://revitin.com/cdn/shopifycloud/portable-wallets/latest/accelerated-checkout-backwards-compat.css" crossorigin="anonymous">
213<style id="shopify-accelerated-checkout-cart">
214        #shopify-buyer-consent {
215  margin-top: 1em;
216  display: inline-block;
217  width: 100%;
218}
219
220#shopify-buyer-consent.hidden {
221  display: none;
222}
223
224#shopify-subscription-policy-button {
225  background: none;
226  border: none;
227  padding: 0;
228  text-decoration: underline;
229  font-size: inherit;
230  cursor: pointer;
231}
232
233#shopify-subscription-policy-button::before {
234  box-shadow: none;
235}
236
237      </style>
238
239<script id="shopify-cfh-end">window.performance && window.performance.mark && window.performance.mark('shopify.content_for_header.end');</script>
239
240
241    <link rel="stylesheet" href="//revitin.com/cdn/shop/t/129/assets/tailwind.style.css?v=17529247885522139811786010445">
242    <link
243      rel="preload"
244      href="//revitin.com/cdn/shop/t/129/assets/swiper-bundle.min.css?v=95102680675147881971777542404"
245      as="style"
246      onload="this.onload=null;this.rel='stylesheet'"
247    >
248    <style>
249      .form_container div input {
250        background: #FFFBEF !important;
251      }
252     
253      @font-face {
254        font-family: "Basis Regular";
255        src: url("https://cdn.shopify.com/s/files/1/0376/8972/0970/files/basis-grotesque-regular-trial.woff2?v=1724768478");
256        font-style: normal;
257        font-weight: normal;
258        font-display: swap;
259      }
260      @font-face {
261        font-family: "Basis Medium";
262        src: url("https://cdn.shopify.com/s/files/1/0376/8972/0970/files/basis-grotesque-medium-trial.woff2?v=1724768478");
263        font-style: normal;
264        font-weight: normal;
265        font-display: swap;
266      }
267      @font-face {
268        font-family: "Rza Trial";
269        src: url("https://cdn.shopify.com/s/files/1/0376/8972/0970/files/Rza-Trial-Light.woff2?v=1724768478");
270        font-style: normal;
271        font-weight: normal;
272        font-display: swap;
273      }
274      @media (max-width: 640px){
275        iframe#podium-bubble, iframe#podium-prompt{
276          z-index: 99 !important;
277        }
278        /* iframe#podium-prompt { display: none !important;} */
279      }
280    </style>
281    
281<script>
vendor: 455 bytes, lines 281-291
281
282      (function (w, d, s, l, i) {
283        w[l] = w[l] || [];
284        w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
285        var f = d.getElementsByTagName(s)[0],
286          j = d.createElement(s),
287          dl = l != 'dataLayer' ? '&l=' + l : '';
288        j.async = true;
289        j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
290        f.parentNode.insertBefore(j, f);
291      })(window, document, 'script', 'dataLayer', '
291GTM-MX86RPVR
vendor: 8 bytes, lines 291-292
291');
292    
292</script>
vendor: 69 bytes, lines 292-294
292
293
294    <script async src="https://www.googletagmanager.com/gtag/js?id=
294G-WMDYXD9CTG
vendor: 16 bytes, lines 294-295
294"></script>
295    
295<script>
296      
vendor: 162 bytes, lines 296-301
296window.dataLayer = window.dataLayer || [];
297      function gtag() {
298        dataLayer.push(arguments);
299      }
300      gtag('js', new Date());
301      gtag('config', '
301G-WMDYXD9CTG
vendor: 4 bytes, line 301
301'); 
301// Replace with your GA4 Measurement ID
302    </script>
302
303
304    
304<script>
305      
306    </script>
306
307
308    
308<script>
309      window.addEventListener('klaviyoForms', function (e) {
310        if (e.detail.type == 'open' || e.detail.type == 'embedOpen') {
311          gtag('event', 'form_open', { form: 'Klaviyo form', form_id: e.detail.formId });
312        }
313        if (e.detail.type == 'submit') {
314          gtag('event', 'form_submit', { form: 'Klaviyo form', form_id: e.detail.formId });
315        }
316        if (e.detail.type == 'stepSubmit') {
317          gtag('event', 'form_step_submit', { form: 'Klaviyo form', step_name: e.detail.metaData.$step_name });
318        }
319        if (e.detail.type == 'redirectedToUrl') {
320          gtag('event', 'form_url_redirect', { form: 'Klaviyo form', form_id: e.detail.formId });
321        }
322        if (e.detail.type == 'close') {
323          gtag('event', 'form_close', { form: 'Klaviyo form', form_id: e.detail.formId });
324        }
325      });
326    </script>
326
327    
327<script type="text/javascript">
328      (function (c, l, a, r, i, t, y) {
329        c[a] =
330          c[a] ||
331          function () {
332            (c[a].q = c[a].q || []).push(arguments);
333          };
334        t = l.createElement(r);
335        t.async = 1;
336        t.src = 'https://www.clarity.ms/tag/' + i;
337        y = l.getElementsByTagName(r)[0];
338        y.parentNode.insertBefore(t, y);
339      })(window, document, 'clarity', 'script', 'rbrmbn89qv');
340    </script>
340
341
342    <!-- structured data -->
343    
343<script type="application/ld+json">
344{
345  "@context": "https://schema.org",
346  "@type": "Organization",
347  "name": "Revitin",
348  "url": "https://revitin.com",
349  "logo": "https://revitin.com/cdn/shop/t/47/assets/citrus-logo.png?v=12133043602477412821745386983",
350  "sameAs": [
351    "https://www.facebook.com/RevitinOralTherapy/",
352    "https://www.instagram.com/revitin/?hl=en"
353  ]
354}
355</script>
355
356
357
358  
358<script type="application/ld+json">
359  {
360    "@context": "https://schema.org",
361    "@type": "FAQPage",
362    "mainEntity": [
363      {
364        "@type": "Question",
365        "name": "How is Revitin different from other toothpastes?",
366        "acceptedAnswer": {
367          "@type": "Answer",
368          "text": "Revitin uses all-natural ingredients for healthier teeth without the use of harsh chemicals. It supports an oral cavity with less inflammation and plaque buildup by encouraging a healthy microbial environment."
369        }
370      },
371      {
372        "@type": "Question",
373        "name": "Can you swallow Revitin?",
374        "acceptedAnswer": {
375          "@type": "Answer",
376          "text": "Yes. Revitin is safe to swallow."
377        }
378      },
379      {
380        "@type": "Question",
381        "name": "Is Revitin fluoride-free?",
382        "acceptedAnswer": {
383          "@type": "Answer",
384          "text": "Yes, Revitin is fluoride-free. There are no toxic ingredients in our formula."
385        }
386      },
387      {
388        "@type": "Question",
389        "name": "What else is Revitin free from?",
390        "acceptedAnswer": {
391          "@type": "Answer",
392          "text": "Revitin is free from fluoride, SLS, gluten, dyes, peanuts, sugar, xylitol, and GMOs."
393        }
394      },
395      {
396        "@type": "Question",
397        "name": "Does Revitin whiten teeth?",
398        "acceptedAnswer": {
399          "@type": "Answer",
400          "text": "Revitin is proven to reduce film buildup and plaque on teeth that leads to discoloration. Additionally, natural fruit enzymes like the ones in Revitin are proven to whiten teeth without harsh chemicals."
401        }
402      },
403      {
404        "@type": "Question",
405        "name": "Is Revitin vegan?",
406        "acceptedAnswer": {
407          "@type": "Answer",
408          "text": "Yes."
409        }
410      },
411      {
412        "@type": "Question",
413        "name": "Is Revitin safe for children?",
414        "acceptedAnswer": {
415          "@type": "Answer",
416          "text": "Yes, Revitin is a great choice for teeth brushers of all ages."
417        }
418      }
419    ]
420  }
421  </script>
421
422
423
424
425
426    
426<script type="application/ld+json">
427  
428
429    
430
431    {
432      "@context": "https://schema.org",
433      "@type": "BreadcrumbList",
434      "itemListElement": [
435        {
436          "@type": "ListItem",
437          "position": 1,
438          "name": "Home",
439          "item": "https:\/\/revitin.com"
440        },
441        {
442          "@type": "ListItem",
443          "position": 2,
444          "name": "Shop Revitin",
445          "item": "https:\/\/revitin.com\/collections\/shop-all"
446        },
447        {
448          "@type": "ListItem",
449          "position": 3,
450          "name": "Revitin Toothpaste Single Tube",
451          "item": "https:\/\/revitin.com\/products\/revitin-natural-toothpaste"
452        }
453      ]
454    }
455  
456</script>
456
457
458    
459<script type="application/ld+json">
460{
461  "@context": "https://schema.org",
462  "@type": "Product",
463  "name": "Revitin Toothpaste Single Tube",
464  "image": [
465    "files/citrus-gallery-render-mobile_11zon.jpg"
466  ],
467  "description": "<p>Revitin supports<span> </span><strong>strong white teeth</strong>,<span> </span><strong>healthy gums</strong>, and<span> </span><strong>fresher breath</strong>. What’s more, Revitin tastes great! Revitin is<span> </span><strong>fluoride-free</strong>,<span> </span><strong>without Sodium Lauryl Sulfate (SLS free)</strong>, and you won't find<span> </span><strong>Triclosan either!</strong></p>",
468  "sku": "CITRUS1",
469  "brand": {
470    "@type": "Brand",
471    "name": "Revitin® Natural Toothpaste"
472  },
473  
474    "aggregateRating": {
475      "@type": "AggregateRating",
476      "ratingValue": "4.54",
477      "reviewCount": 869
478    },
479  
480  "offers": {
481    "@type": "Offer",
482    "url": "https://revitin.com/products/revitin-natural-toothpaste",
483    "priceCurrency": "USD",
484    "price": "17.00",
485    "itemCondition": "https://schema.org/NewCondition",
486    "availability": "https://schema.org/InStock"
487  }
488}
489</script>
489
490
491  <!-- BEGIN app block: shopify://apps/klaviyo-email-marketing-sms/blocks/klaviyo-onsite-embed/2632fe16-c075-4321-a88b-50b567f42507 -->
492
493
494
495
496
497
498
499
500
501
502
503
504  
504<script async src="https://static.klaviyo.com/onsite/js/YmxebZ/klaviyo.js?company_id=YmxebZ"></script>
504
505  
505<script>!function(){if(!window.klaviyo){window._klOnsite=window._klOnsite||[];try{window.klaviyo=new Proxy({},{get:function(n,i){return"push"===i?function(){var n;(n=window._klOnsite).push.apply(n,arguments)}:function(){for(var n=arguments.length,o=new Array(n),w=0;w<n;w++)o[w]=arguments[w];var t="function"==typeof o[o.length-1]?o.pop():void 0,e=new Promise((function(n){window._klOnsite.push([i].concat(o,[function(i){t&&t(i),n(i)}]))}));return e}}})}catch(n){window.klaviyo=window.klaviyo||[],window.klaviyo.push=function(){var n;(n=window._klOnsite).push.apply(n,arguments)}}}}();</script>
505
506
507  
508    
508<script id="viewed_product">
509      if (item == null) {
510        var _learnq = _learnq || [];
511
512        var MetafieldReviews = null
513        var MetafieldYotpoRating = null
514        var MetafieldYotpoCount = null
515        var MetafieldLooxRating = null
516        var MetafieldLooxCount = null
517        var okendoProduct = null
518        var okendoProductReviewCount = null
519        var okendoProductReviewAverageValue = null
520        try {
521          // The following fields are used for Customer Hub recently viewed in order to add reviews.
522          // This information is not part of __kla_viewed. Instead, it is part of __kla_viewed_reviewed_items
523          MetafieldReviews = {"rating":{"scale_min":"1.0","scale_max":"5.0","value":"4.54"},"rating_count":869};
524          MetafieldYotpoRating = null
525          MetafieldYotpoCount = null
526          MetafieldLooxRating = null
527          MetafieldLooxCount = null
528
529          okendoProduct = null
530          // If the okendo metafield is not legacy, it will error, which then requires the new json formatted data
531          if (okendoProduct && 'error' in okendoProduct) {
532            okendoProduct = null
533          }
534          okendoProductReviewCount = okendoProduct ? okendoProduct.reviewCount : null
535          okendoProductReviewAverageValue = okendoProduct ? okendoProduct.reviewAverageValue : null
536        } catch (error) {
537          console.error('Error in Klaviyo onsite reviews tracking:', error);
538        }
539
540        var item = {
541          Name: "Revitin Toothpaste Single Tube",
542          ProductID: 6606432174218,
543          Categories: ["Home page","Shop Revitin","Toothpaste"],
544          ImageURL: "https://revitin.com/cdn/shop/files/citrus-gallery-render-mobile_11zon_grande.jpg?v=1742298905",
545          URL: "https://revitin.com/products/revitin-natural-toothpaste",
546          Brand: "Revitin® Natural Toothpaste",
547          Price: "$17.00",
548          Value: "17.00",
549          CompareAtPrice: "$17.00"
550        };
551        _learnq.push(['track', 'Viewed Product', item]);
552        _learnq.push(['trackViewedItem', {
553          Title: item.Name,
554          ItemId: item.ProductID,
555          Categories: item.Categories,
556          ImageUrl: item.ImageURL,
557          Url: item.URL,
558          Metadata: {
559            Brand: item.Brand,
560            Price: item.Price,
561            Value: item.Value,
562            CompareAtPrice: item.CompareAtPrice
563          },
564          metafields:{
565            reviews: MetafieldReviews,
566            yotpo:{
567              rating: MetafieldYotpoRating,
568              count: MetafieldYotpoCount,
569            },
570            loox:{
571              rating: MetafieldLooxRating,
572              count: MetafieldLooxCount,
573            },
574            okendo: {
575              rating: okendoProductReviewAverageValue,
576              count: okendoProductReviewCount,
577            }
578          }
579        }]);
580      }
581    </script>
581
582  
583
584
585
586
587  
587<script>
588    window.klaviyoReviewsProductDesignMode = false
589  </script>
589
590
591
592
593
594
595
596
597
598
599<!-- END app block --><!-- BEGIN app block: shopify://apps/triplewhale/blocks/triple_pixel_snippet/483d496b-3f1a-4609-aea7-8eee3b6b7a2a --><link rel='preconnect dns-prefetch' href='https://api.config-security.com/' crossorigin />
600<link rel='preconnect dns-prefetch' href='https://conf.config-security.com/' crossorigin />
601<script>
602/* >> TriplePixel :: start*/
603window.TriplePixelData={TripleName:"revitin.myshopify.com",ver:"2.16",plat:"SHOPIFY",isHeadless:false,src:'SHOPIFY_EXT',product:{id:"6606432174218",name:`Revitin Toothpaste Single Tube`,price:"17.00",variant:"45594631471242",av:{ "45594631471242":true }},search:"",collection:"",cart:"notification",template:"product",curr:"USD" || "USD", market:"3341025418"},function(W,H,A,L,E,_,B,N){function O(U,T,P,H,R){void 0===R&&(R=!1),H=new XMLHttpRequest,P?(H.open("POST",U,!0),H.setRequestHeader("Content-Type","text/plain")):H.open("GET",U,!0),H.send(JSON.stringify(P||{})),H.onreadystatechange=function(){4===H.readyState&&200===H.status?(R=H.responseText,U.includes("/first")?eval(R):P||(N[B]=R)):(299<H.status||H.status<200)&&T&&!R&&(R=!0,O(U,T-1,P))}}if(N=window,!N[H+"sn"]){N[H+"sn"]=1,L=function(){return Date.now().toString(36)+"_"+Math.random().toString(36)};try{A.setItem(H,1+(0|A.getItem(H)||0)),(E=JSON.parse(A.getItem(H+"U")||"[]")).push({u:location.href,r:document.referrer,t:Date.now(),id:L()}),A.setItem(H+"U",JSON.stringify(E))}catch(e){}var i,m,p;A.getItem('"!nC`')||(_=A,A=N,A[H]||(E=A[H]=function(t,e,i){return void 0===i&&(i=[]),"State"==t?E.s:(W=L(),(E._q=E._q||[]).push([W,t,e].concat(i)),W)},E.s="Installed",E._q=[],E.ch=W,B="configSecurityConfModel",N[B]=1,O("https://conf.config-security.com/model",5),i=L(),m=A[atob("c2NyZWVu")],_.setItem("di_pmt_wt",i),p={id:i,action:"profile",avatar:_.getItem("auth-security_rand_salt_"),time:m[atob("d2lkdGg=")]+":"+m[atob("aGVpZ2h0")],host:A.TriplePixelData.TripleName,plat:A.TriplePixelData.plat,url:window.location.href.slice(0,500),ref:document.referrer,ver:A.TriplePixelData.ver},O("https://api.config-security.com/event",5,p),O("https://api.config-security.com/first?host=".concat(p.host,"&plat=").concat(p.plat),5)))}}("","TriplePixel",localStorage);
604/* << TriplePixel :: end*/
605</script>
605
606
607
608
609<!-- END app block --><!-- BEGIN app block: shopify://apps/judge-me-reviews/blocks/judgeme_core/61ccd3b1-a9f2-4160-9fe9-4fec8413e5d8 --><!-- Start of Judge.me Core -->
610
611
612
613
614
615
616
617<link rel="dns-prefetch" href="https://cdn.judge.me">
618<link rel="dns-prefetch" href="https://cdn1.judge.me">
619<link rel="dns-prefetch" href="https://api.judge.me">
620
621<script data-cfasync='false' class='jdgm-settings-script'>window.jdgmSettings={"pagination":5,"disable_web_reviews":false,"coupon_receiving_condition":"any_review","coupon_value_type":"percentage","coupon_value_percentage":10,"coupon_value_fixed_amount":0,"coupon_discount_type":"single","coupon_tier_text_enabled":false,"coupon_tier_text_percentage":10,"coupon_tier_text_fixed_amount":0,"coupon_tier_photo_enabled":false,"coupon_tier_photo_percentage":10,"coupon_tier_photo_fixed_amount":0,"coupon_tier_video_enabled":false,"coupon_tier_video_percentage":10,"coupon_tier_video_fixed_amount":0,"enable_coupons":false,"badge_no_review_text":"No reviews","badge_n_reviews_text":"{{ n }} review/reviews","badge_star_color":"#7E8F72","hide_badge_preview_if_no_reviews":true,"badge_hide_text":false,"enforce_center_preview_badge":false,"widget_title":"Customer Reviews","widget_open_form_text":"Write a review","widget_close_form_text":"Cancel review","widget_refresh_page_text":"Refresh page","widget_summary_text":"Based on {{ number_of_reviews }} review/reviews","widget_no_review_text":"Be the first to write a review","widget_name_field_text":"Display name","widget_verified_name_field_text":"Verified Name (public)","widget_name_placeholder_text":"Display name","widget_required_field_error_text":"This field is required.","widget_email_field_text":"Email address","widget_verified_email_field_text":"Verified Email (private, can not be edited)","widget_email_placeholder_text":"Your email address","widget_email_field_error_text":"Please enter a valid email address.","widget_rating_field_text":"Rating","widget_review_title_field_text":"Review Title","widget_review_title_placeholder_text":"Give your review a title","widget_review_body_field_text":"Review content","widget_review_body_placeholder_text":"Start writing here...","widget_pictures_field_text":"Picture/Video (optional)","widget_submit_review_text":"Submit Review","widget_submit_verified_review_text":"Submit Verified Review","widget_submit_success_msg_with_auto_publish":"Thank y
621ou! Please refresh the page in a few moments to see your review. You can remove or edit your review by logging into \u003ca href='https://judge.me/login' target='_blank' rel='nofollow noopener'\u003eJudge.me\u003c/a\u003e","widget_submit_success_msg_no_auto_publish":"Thank you! Your review will be published as soon as it is approved by the shop admin. You can remove or edit your review by logging into \u003ca href='https://judge.me/login' target='_blank' rel='nofollow noopener'\u003eJudge.me\u003c/a\u003e","widget_show_default_reviews_out_of_total_text":"Showing {{ n_reviews_shown }} out of {{ n_reviews }} reviews.","widget_show_all_link_text":"Show all","widget_show_less_link_text":"Show less","widget_author_said_text":"{{ reviewer_name }} said:","widget_days_text":"{{ n }} days ago","widget_weeks_text":"{{ n }} week/weeks ago","widget_months_text":"{{ n }} month/months ago","widget_years_text":"{{ n }} year/years ago","widget_yesterday_text":"Yesterday","widget_today_text":"Today","widget_replied_text":"\u003e\u003e {{ shop_name }} replied:","widget_read_more_text":"Read more","widget_reviewer_name_as_initial":"","widget_rating_filter_color":"#5F471D","widget_rating_filter_see_all_text":"See all reviews","widget_sorting_most_recent_text":"Most Recent","widget_sorting_highest_rating_text":"Highest Rating","widget_sorting_lowest_rating_text":"Lowest Rating","widget_sorting_with_pictures_text":"Only Pictures","widget_sorting_most_helpful_text":"Most Helpful","widget_open_question_form_text":"Ask a question","widget_reviews_subtab_text":"Reviews","widget_questions_subtab_text":"Questions","widget_question_label_text":"Question","widget_answer_label_text":"Answer","widget_question_placeholder_text":"Write your question here","widget_submit_question_text":"Submit Question","widget_question_submit_success_text":"Thank you for your question! We will notify you once it gets answered.","widget_star_color":"#7E8F72","verified_badge_text":"Verified","verified_badge_bg_color":"#FFDEA3","verified_badge_text_color":"","verified_badge_placement":"left-of-reviewer-name","widget_review_max_height":"","widget_hide_border":false,"widget_social_share":false,"widget_thumb":false,"widget_review_location_show":false,"widget_location_format":"","all_reviews_include_out_of_store_products":true,"all_reviews_out_of_store_text":"(out of store)","all_reviews_pagination":100,"all_reviews_product_name_prefix_text":"about","enable_review_pictures":true,"enable_question_anwser":false,"widget_theme":"default","review_date_format":"mm/dd/yyyy","default_sort_method":"most-recent","enable_ai_review_visibility":true,"widget_product_reviews_subtab_text":"Product Reviews","widget_shop_reviews_subtab_text":"Shop Reviews","widget_other_products_reviews_text":"Reviews for other products","widget_store_reviews_subtab_text":"Store reviews","widget_product_variant_reference_text":"Review for","widget_no_store_reviews_text":"This store hasn't received any reviews yet","widget_web_restriction_product_reviews_text":"This product hasn't received any reviews yet","widget_no_items_text":"No items found","widget_show_more_text":"Show more","widget_write_a_store_review_text":"Write a Store Review","widget_product_and_store_reviews_text":"Product and store reviews","widget_reviews_in_collection_text":"Reviews in this collection","widget_other_languages_heading":"Reviews in Other Languages","widget_translate_review_text":"Translate review to {{ language }}","widget_translating_review_text":"Translating...","widget_show_original_translation_text":"Show original ({{ language }})","widget_translate_review_failed_text":"Review couldn't be translated.","widget_translate_review_retry_text":"Retry","widget_translate_review_try_again_later_text":"Try again later","show_product_url_for_grouped_product":false,"widget_sorting_pictures_first_text":"Pictures First","show_pictures_on_all_rev_page_mobile":false,"show_pictures_on_all_rev_page_desktop":false,"floating_tab_hide_mobile_install_preference":false,"floating_tab_button_name":"★ Reviews","floating_tab_title":"Let customers speak for us","floating_tab_button_color":"","floating_tab_button_background_color":"","floating_tab_url":"","floating_tab_url_enabled":false,"floating_tab_tab_style":"text","all_reviews_text_badge_text":"Customers rate us {{ shop.metafields.judgeme.all_reviews_rating | round: 1 }}/5 based on {{ shop.metafields.judgeme.all_reviews_count }} reviews.","all_reviews_text_badge_text_branded_style":"{{ shop.metafields.judgeme.all_reviews_rating | round: 1 }} out of 5 stars based on {{ shop.metafields.judgeme.all_reviews_count }} reviews","is_all_reviews_text_badge_a_link":false,"show_stars_for_all_reviews_text_badge":false,"all_reviews_text_badge_url":"","all_reviews_text_style":"branded","all_reviews_text_color_style":"judgeme_brand_color","all_reviews_text_color":"#108474","all_reviews_text_show_jm_brand":false,"featured_carousel_show_header":true,"featured_carousel_title":"Let customers speak for us","testimonials_carousel_title":"Customers are saying","videos_carousel_title":"Real customer stories","cards_carousel_title":"Customers are saying","featured_carousel_count_text":"from {{ n }} reviews","featured_carousel_add_link_to_all_reviews_page":false,"featured_carousel_url":"","featured_carousel_show_images":true,"featured_carousel_autoslide_interval":5,"featured_carousel_arrows_on_the_sides":false,"featured_carousel_height":250,"featured_carousel_width":80,"featured_carousel_image_size":0,"featured_carousel_image_height":250,"featured_carousel_arrow_color":"#eeeeee","verified_count_badge_style":"branded","verified_count_badge_orientation":"horizontal","verified_count_badge_color_style":"judgeme_brand_color","verified_count_badge_color":"#108474","is_verified_count_badge_a_link":false,"verified_count_badge_url":"","verified_count_badge_show_jm_brand":true,"widget_rating_preset_default":5,"widget_first_sub_tab":"product-reviews","widget_show_histogram":true,"widget_histogram_use_custom_color":true,"widget_pagination_use_custom_color":true,"widget_star_use_custom_color":false,"widget_verified_badge_use_custom_color":false,"widget_write_review_use_custom_color":false,"picture_reminder_submit_button":"Upload Pictures","enable_review_videos":false,"mute_video_by_default":false,"widget_sorting_videos_first_text":"Videos First","widget_review_pending_text":"Pending","featured_carousel_items_for_large_screen":3,"social_share_options_order":"Facebook,Twitter","remove_microdata_snippet":true,"disable_json_ld":false,"enable_json_ld_products":false,"preview_badge_show_question_text":false,"preview_badge_no_question_text":"No questions","preview_badge_n_question_text":"{{ number_of_questions }} question/questions","qa_badge_show_icon":false,"qa_badge_position":"same-row","remove_judgeme_branding":true,"widget_add_search_bar":false,"widget_search_bar_placeholder":"Search","widget_sorting_verified_only_text":"Verified only","widget_sorting_most_relevant_text":"Most Relevant","featured_carousel_theme":"default","featured_carousel_show_rating":true,"featured_carousel_show_title":true,"featured_carousel_show_body":true,"featured_carousel_show_date":false,"featured_carousel_show_reviewer":true,"featured_carousel_show_product":false,"featured_carousel_header_background_color":"#108474","featured_carousel_header_text_color":"#ffffff","featured_carousel_name_product_separator":"reviewed","featured_carousel_full_star_background":"#108474","featured_carousel_empty_star_background":"#dadada","featured_carousel_vertical_theme_background":"#f9fafb","featured_carousel_verified_badge_enable":true,"featured_carousel_verified_badge_color":"#108474","featured_carousel_border_style":"round","featured_carousel_review_line_length_limit":3,"featured_carousel_more_reviews_button_text":"Read more reviews","featured_carousel_view_product_button_text":"View product","all_reviews_page_load_reviews_on":"button_click","all_reviews_page_load_more_text":"Load More","disable_fb_tab_reviews":false,"enable_ajax_cdn_cache":false,"widget_advanced_speed_features":5,"widget_public_name_text":"displayed publicly like","default_reviewer_name":"John Smith","default_reviewer_name_has_non_latin":true,"widget_reviewer_anonymous":"Anonymous","medals_widget_title":"Judge.me Review Medals","medals_widget_background_color":"#f9fafb","medals_widget_position":"footer_all_pages","medals_widget_border_color":"#f9fafb","medals_widget_verified_text_position":"left","medals_widget_use_monochromatic_version":false,"medals_widget_elements_color":"#108474","show_reviewer_avatar":false,"widget_invalid_yt_video_url_error_text":"Not a YouTube video URL","widget_max_length_field_error_text":"Please enter no more than {0} characters.","widget_show_country_flag":false,"widget_show_collected_via_shop_app":true,"widget_verified_by_shop_badge_style":"light","widget_verified_by_shop_text":"Verified by Shop","widget_show_photo_gallery":false,"widget_load_with_code_splitting":true,"widget_ugc_install_preference":false,"widget_ugc_title":"Made by us, Shared by you","widget_ugc_subt
621itle":"Tag us to see your picture featured in our page","widget_ugc_arrows_color":"#ffffff","widget_ugc_primary_button_text":"Buy Now","widget_ugc_primary_button_background_color":"#108474","widget_ugc_primary_button_text_color":"#ffffff","widget_ugc_primary_button_border_width":"0","widget_ugc_primary_button_border_style":"none","widget_ugc_primary_button_border_color":"#108474","widget_ugc_primary_button_border_radius":"25","widget_ugc_secondary_button_text":"Load More","widget_ugc_secondary_button_background_color":"#ffffff","widget_ugc_secondary_button_text_color":"#108474","widget_ugc_secondary_button_border_width":"2","widget_ugc_secondary_button_border_style":"solid","widget_ugc_secondary_button_border_color":"#108474","widget_ugc_secondary_button_border_radius":"25","widget_ugc_reviews_button_text":"View Reviews","widget_ugc_reviews_button_background_color":"#ffffff","widget_ugc_reviews_button_text_color":"#108474","widget_ugc_reviews_button_border_width":"2","widget_ugc_reviews_button_border_style":"solid","widget_ugc_reviews_button_border_color":"#108474","widget_ugc_reviews_button_border_radius":"25","widget_ugc_reviews_button_link_to":"judgeme-reviews-page","widget_ugc_show_post_date":true,"widget_ugc_max_width":"800","widget_rating_metafield_value_type":true,"widget_primary_color":"#FFDEA3","widget_enable_secondary_color":false,"widget_secondary_color":"#edf5f5","widget_summary_average_rating_text":"{{ average_rating }}","widget_media_grid_title":"Customer photos \u0026 videos","widget_media_grid_see_more_text":"See more","widget_round_style":false,"widget_show_product_medals":false,"widget_verified_by_judgeme_text":"Verified by Judge.me","widget_show_store_medals":false,"widget_verified_by_judgeme_text_in_store_medals":"Verified by Judge.me","widget_media_field_exceed_quantity_message":"Sorry, we can only accept {{ max_media }} for one review.","widget_media_field_exceed_limit_message":"{{ file_name }} is too large, please select a {{ media_type }} less than {{ size_limit }}MB.","widget_review_submitted_text":"Review Submitted!","widget_question_submitted_text":"Question Submitted!","widget_close_form_text_question":"Cancel","widget_write_your_answer_here_text":"Write your answer here","widget_enabled_branded_link":true,"widget_show_collected_by_judgeme":false,"widget_reviewer_name_color":"#5F471D","widget_write_review_text_color":"#5F471D","widget_write_review_bg_color":"#FFDEA3","widget_collected_by_judgeme_text":"collected by Judge.me","widget_pagination_type":"load_more","widget_load_more_text":"Load More","widget_load_more_color":"#FFDEA3","widget_full_review_text":"Full Review","widget_read_more_reviews_text":"Read More Reviews","widget_read_questions_text":"Read Questions","widget_questions_and_answers_text":"Questions \u0026 Answers","widget_verified_by_text":"Verified by","widget_verified_text":"Verified","widget_number_of_reviews_text":"{{ number_of_reviews }} reviews","widget_back_button_text":"Back","widget_next_button_text":"Next","widget_custom_forms_filter_button":"Filters","custom_forms_style":"horizontal","widget_show_review_information":false,"how_reviews_are_collected":"How reviews are collected?","widget_show_review_keywords":false,"widget_gdpr_statement":"How we use your data: We'll only contact you about the review you left, and only if necessary. By submitting your review, you agree to Judge.me's \u003ca href='https://judge.me/terms' target='_blank' rel='nofollow noopener'\u003eterms\u003c/a\u003e, \u003ca href='https://judge.me/privacy' target='_blank' rel='nofollow noopener'\u003eprivacy\u003c/a\u003e and \u003ca href='https://judge.me/content-policy' target='_blank' rel='nofollow noopener'\u003econtent\u003c/a\u003e policies.","widget_multilingual_sorting_enabled":false,"widget_translate_review_content_enabled":false,"widget_translate_review_content_method":"manual","popup_widget_review_selection":"automatically_with_pictures","popup_widget_round_border_style":true,"popup_widget_show_title":true,"popup_widget_show_body":true,"popup_widget_show_reviewer":false,"popup_widget_show_product":true,"popup_widget_show_pictures":true,"popup_widget_use_review_picture":true,"popup_widget_show_on_home_page":true,"popup_widget_show_on_product_page":true,"popup_widget_show_on_collection_page":true,"popup_widget_show_on_cart_page":true,"popup_widget_position":"bottom_left","popup_widget_first_review_delay":5,"popup_widget_duration":5,"popup_widget_interval":5,"popup_widget_review_count":5,"popup_widget_hide_on_mobile":true,"review_snippet_widget_round_border_style":true,"review_snippet_widget_card_color":"#FFFFFF","review_snippet_widget_text_color":"#000000","review_snippet_widget_lighter_text_color":"#7B7B7B","review_snippet_widget_slider_arrows_background_color":"#FFFFFF","review_snippet_widget_slider_arrows_color":"#000000","review_snippet_widget_star_color":"#FFDEA3","show_product_variant":false,"all_reviews_product_variant_label_text":"Variant: ","widget_show_verified_branding":false,"widget_ai_summary_title":"Customers say","widget_ai_summary_disclaimer":"AI-powered review summary based on recent customer reviews","widget_show_ai_summary":false,"widget_show_ai_summary_bg":false,"write_review_button_visibility":"everyone","store_summary_widget_heading":"Customers rate this store","store_summary_widget_button_text":"View customer reviews","store_summary_widget_button_theme_text":"See AI reviews summary","widget_show_review_title_input":true,"widget_autofill_review_title":true,"redirect_reviewers_invited_via_email":"external_form","request_store_review_after_product_review":false,"request_review_other_products_in_order":false,"review_form_color_scheme":"default","review_form_corner_style":"square","review_form_star_color":"#FFDEA3","review_form_text_color":"#333333","review_form_background_color":"#ffffff","review_form_field_background_color":"#fafafa","review_form_button_color":"#FFDEA3","review_form_button_text_color":"#ffffff","review_form_modal_overlay_color":"#000000","review_form_theme":"multi_step","review_form_location":"in_store_popup","review_form_external_page_background_color":"#C5F7F0","review_content_screen_title_text":"How would you rate this product?","review_content_introduction_text":"We would love it if you would share a bit about your experience.","store_review_form_title_text":"How would you rate this store?","store_review_form_introduction_text":"We would love it if you would share a bit about your experience.","show_review_guidance_text":true,"one_star_review_guidance_text":"Poor","five_star_review_guidance_text":"Great","customer_information_screen_title_text":"About you","customer_information_introduction_text":"Please tell us more about you.","custom_questions_screen_title_text":"Your experience in more detail","custom_questions_introduction_text":"Here are a few questions to help us understand more about your experience.","review_submitted_screen_title_text":"Thanks for your review!","review_submitted_screen_thank_you_text":"We are processing it and it will appear on the store soon.","review_submitted_screen_email_verification_text":"Please confirm your email by clicking the link we just sent you. This helps us keep reviews authentic.","confirm_email_screen_title_text":"Confirm your email","confirm_email_screen_message_text":"To help keep reviews authentic, we'll send you a secure link to continue writing your review. It only takes a moment.","check_email_screen_title_text":"Check your email","check_email_screen_message_text":"We sent you an email to {{ email }}. Click the button on the email to continue.","check_email_screen_resend_message_text":"Email resent!","check_email_resend_hint_text":"Didn't get the email? Check your spam folder or [resend the email].","verification_email_rate_limit_error_text":"You've reached the limit for review attempts on this product. Please check your inbox or try again later.","review_submitted_request_store_review_text":"Would you like to share your experience of shopping with us?","review_submitted_review_other_products_text":"Would you like to review these products?","store_review_screen_title_text":"Would you like to share your experience of shopping with us?","store_review_introduction_text":"We value your feedback and use it to improve. Please share any thoughts or suggestions you have.","reviewer_media_screen_title_picture_text":"Share a picture","reviewer_media_introduction_picture_text":"Upload a photo to support your review.","reviewer_media_screen_title_video_text":"Share a video","reviewer_media_introduction_video_text":"Upload a video to support your review.","reviewer_media_screen_title_picture_or_video_text":"Share a picture or video","reviewer_media_introduction_picture_or_video_text":"Upload a photo or video to support your review.","reviewer_media_
621youtube_url_text":"Paste your Youtube URL here","advanced_settings_next_step_button_text":"Next","advanced_settings_close_review_button_text":"Close","modal_write_review_flow":false,"write_review_flow_required_text":"Required","write_review_flow_privacy_message_text":"We respect your privacy.","write_review_flow_anonymous_text":"Post review as anonymous","write_review_flow_visibility_text":"This won't be visible to other customers.","write_review_flow_multiple_selection_help_text":"Select as many as you like","write_review_flow_single_selection_help_text":"Select one option","write_review_flow_required_field_error_text":"This field is required","write_review_flow_invalid_email_error_text":"Please enter a valid email address","write_review_flow_max_length_error_text":"Max. {{ max_length }} characters.","write_review_flow_media_upload_text":"\u003cb\u003eClick to upload\u003c/b\u003e or drag and drop","write_review_flow_gdpr_statement":"We'll only contact you about your review if necessary. By submitting your review, you agree to our \u003ca href='https://judge.me/terms' target='_blank' rel='nofollow noopener'\u003eterms and conditions\u003c/a\u003e and \u003ca href='https://judge.me/privacy' target='_blank' rel='nofollow noopener'\u003eprivacy policy\u003c/a\u003e.","rating_only_reviews_enabled":false,"show_negative_reviews_help_screen":false,"new_review_flow_help_screen_rating_threshold":3,"negative_review_resolution_screen_title_text":"Tell us more","negative_review_resolution_text":"Your experience matters to us. If there were issues with your purchase, we're here to help. Feel free to reach out to us, we'd love the opportunity to make things right.","negative_review_resolution_button_text":"Contact us","negative_review_resolution_proceed_with_review_text":"Leave a review","negative_review_resolution_subject":"Issue with purchase from {{ shop_name }}.{{ order_name }}","coupon_promo_intro_any_review_text":"Write a review and get a coupon for {{ amount }} off your next purchase","coupon_promo_intro_with_photo_text":"Write a review and add a photo or video to get a coupon for {{ amount }} off your next purchase","coupon_promo_intro_with_video_text":"Write a review and add a video to get a coupon for {{ amount }} off your next purchase","coupon_promo_intro_up_to_any_review_text":"Write a review and get a coupon for up to {{ amount }} off your next purchase","coupon_promo_intro_up_to_with_photo_text":"Write a review and add a photo or video to get a coupon for up to {{ amount }} off your next purchase","coupon_promo_intro_external_text":"Write a review and get a reward for your next purchase","coupon_promo_intro_external_with_photo_text":"Write a review and add a photo or video to get a reward for your next purchase","coupon_promo_intro_external_with_video_text":"Write a review and add a video to get a reward for your next purchase","coupon_promo_media_photo_text":"Add a photo or video and get a coupon for {{ amount }} off your next purchase","coupon_promo_media_photo_only_text":"Add a photo and get a coupon for {{ amount }} off your next purchase","coupon_promo_media_video_text":"Add a video and get a coupon for {{ amount }} off your next purchase","coupon_promo_media_external_photo_text":"Add a photo or video and get a reward for your next purchase","coupon_promo_media_external_photo_only_text":"Add a photo and get a reward for your next purchase","coupon_promo_media_external_video_text":"Add a video and get a reward for your next purchase","coupon_promo_success_text":"You've got a coupon for your next purchase at {{ shop_name }}!","coupon_promo_success_subtext":"You'll receive your coupon email within the hour.","preview_badge_collection_page_install_status":false,"widget_review_custom_css":".jdgm-rev-widg{\nmax-width: 1200px;\nmargin-left:auto;\nmargin-right:auto;\n}\n.jdgm-rev-widg__header .jdgm-row-stars{\njustify-content:space-between!important;\n}\n@media (min-width: 768px){\n.jdgm-rev-widg {\npadding-left:2.5rem;\npadding-right:2.5rem;\n}\n}\n@media only screen and (min-width: 992px) {\n.jdgm-rev-widg__title {\ntext-align: left;\n}
621\n.jdgm-rev-widg__summary,.jdgm-widget-actions-wrapper{\n  width: auto!important;\n }\n.jdgm-histogram{\n  width:55%!important;\n  align-items:flex-start!important;\n }\n}","preview_badge_custom_css":"span.jdgm-prev-badge__stars {\n    font-size: 11px;\n}\n.jdgm-prev-badge__text {\n    font-size: 15px;\n    margin-left: 5px;\n    color: #7e8f72;\n}\n.jdgm-preview-badge .jdgm-star.jdgm-star {\n    margin: 0 2px !important;\n}","preview_badge_stars_count":"5-stars","featured_carousel_custom_css":"","floating_tab_custom_css":"","all_reviews_widget_custom_css":"","medals_widget_custom_css":"","verified_badge_custom_css":"","all_reviews_text_custom_css":"","transparency_badges_collected_via_store_invite":false,"transparency_badges_from_another_provider":false,"transparency_badges_collected_from_store_visitor":false,"transparency_badges_collected_by_verified_review_provider":true,"transparency_badges_earned_reward":false,"transparency_badges_collected_via_store_invite_text":"Review collected via store invitation","transparency_badges_from_another_provider_text":"Review collected from another provider","transparency_badges_collected_from_store_visitor_text":"Review collected from a store visitor","transparency_badges_written_in_google_text":"Review written in Google","transparency_badges_written_in_etsy_text":"Review written in Etsy","transparency_badges_written_in_shop_app_text":"Review written in Shop App","transparency_badges_earned_reward_text":"Review earned a reward for future purchase","product_review_widget_per_page":6,"widget_other_languages_reviews_per_page":3,"widget_store_review_label_text":"Review about the store","widget_cart_mode_aggregate_heading_text":"Customers rate this store","checkout_comment_extension_title_on_product_page":"Customer Comments","checkout_comment_extension_num_latest_comment_show":5,"checkout_comment_extension_format":"name_and_timestamp","checkout_comment_customer_name":"last_initial","checkout_comment_comment_notification":true,"preview_badge_collection_page_install_preference":false,"preview_badge_home_page_install_preference":false,"preview_badge_product_page_install_preference":false,"review_widget_install_preference":"","review_carousel_install_preference":false,"floating_reviews_tab_install_preference":"none","verified_reviews_count_badge_install_preference":false,"all_reviews_text_install_preference":false,"review_widget_best_location":false,"judgeme_medals_install_preference":false,"review_widget_revamp_enabled":false,"review_widget_qna_enabled":false,"review_widget_header_theme":"minimal","review_widget_widget_title_enabled":true,"review_widget_header_text_size":"medium","review_widget_header_text_weight":"regular","review_widget_average_rating_style":"compact","review_widget_bar_chart_enabled":true,"review_widget_bar_chart_type":"numbers","review_widget_bar_chart_style":"standard","review_widget_expanded_media_gallery_enabled":false,"review_widget_show_review_highlights":false,"review_widget_show_review_keywords_in_gray":false,"review_widget_reviews_section_theme":"standard","review_widget_image_style":"thumbnails","review_widget_review_image_ratio":"square","review_widget_stars_size":"medium","review_widget_verified_badge":"standard_text","review_widget_review_title_text_size":"medium","review_widget_review_text_size":"medium","review_widget_review_text_length":"medium","review_widget_number_of_columns_desktop":3,"review_widget_carousel_transition_speed":5,"review_widget_custom_questions_answers_display":"always","review_widget_card_section_size":"small","review_widget_button_text_color":"#FFFFFF","review_widget_text_color":"#000000","review_widget_lighter_text_color":"#7B7B7B","review_widget_corner_styling":"soft","review_widget_review_word_singular":"review","review_widget_review_word_plural":"reviews","review_widget_voting_label":"Helpful?","review_widget_shop_reply_label":"Reply from {{ shop_name }}:","review_widget_filters_title":"Filters","review_widget_filter_rating_title":"Rating","review_widget_filter_keyword_title":"Keyword","review_widget_clear_filters_text":"Clear filters","review_widget_expand_more_text":"More","review_widget_review_highlights_title":"Review highlights","qna_widget_question_word_singular":"Question","qna_widget_question_word_plural"
621:"Questions","qna_widget_answer_reply_label":"Answer from {{ answerer_name }}:","qna_content_screen_title_text":"Ask a question about this product","qna_widget_question_required_field_error_text":"Please enter your question.","qna_widget_flow_gdpr_statement":"We'll only contact you about your question if necessary. By submitting your question, you agree to our \u003ca href='https://judge.me/terms' target='_blank' rel='nofollow noopener'\u003eterms and conditions\u003c/a\u003e and \u003ca href='https://judge.me/privacy' target='_blank' rel='nofollow noopener'\u003eprivacy policy\u003c/a\u003e.","qna_widget_question_submitted_text":"Thanks for your question!","qna_widget_close_form_text_question":"Close","qna_widget_question_submit_success_text":"We’ll notify you by email when your question is answered.","all_reviews_widget_v2025_enabled":false,"all_reviews_widget_v2025_header_theme":"default","all_reviews_widget_v2025_widget_title_enabled":true,"all_reviews_widget_v2025_header_text_size":"medium","all_reviews_widget_v2025_header_text_weight":"regular","all_reviews_widget_v2025_average_rating_style":"compact","all_reviews_widget_v2025_bar_chart_enabled":true,"all_reviews_widget_v2025_bar_chart_type":"numbers","all_reviews_widget_v2025_bar_chart_style":"standard","all_reviews_widget_v2025_expanded_media_gallery_enabled":false,"all_reviews_widget_v2025_show_store_medals":true,"all_reviews_widget_v2025_show_photo_gallery":true,"all_reviews_widget_v2025_show_review_keywords":false,"all_reviews_widget_v2025_show_ai_summary":false,"all_reviews_widget_v2025_show_ai_summary_bg":false,"all_reviews_widget_v2025_show_review_highlights":false,"all_reviews_widget_v2025_show_review_keywords_in_gray":false,"all_reviews_widget_v2025_add_search_bar":false,"all_reviews_widget_v2025_default_sort_method":"most-recent","all_reviews_widget_v2025_reviews_per_page":10,"all_reviews_widget_v2025_reviews_section_theme":"default","all_reviews_widget_v2025_image_style":"thumbnails","all_reviews_widget_v2025_review_image_ratio":"square","all_reviews_widget_v2025_stars_size":"medium","all_reviews_widget_v2025_verified_badge":"standard_text","all_reviews_widget_v2025_review_title_text_size":"medium","all_reviews_widget_v2025_review_text_size":"medium","all_reviews_widget_v2025_review_text_length":"medium","all_reviews_widget_v2025_number_of_columns_desktop":3,"all_reviews_widget_v2025_carousel_transition_speed":5,"all_reviews_widget_v2025_custom_questions_answers_display":"always","all_reviews_widget_v2025_review_dates":false,"all_reviews_widget_v2025_card_section_size":"small","all_reviews_widget_v2025_show_product_variant":false,"all_reviews_widget_v2025_show_reviewer_avatar":true,"all_reviews_widget_v2025_reviewer_name_as_initial":"","all_reviews_widget_v2025_review_location_show":false,"all_reviews_widget_v2025_location_format":"","all_reviews_widget_v2025_show_country_flag":false,"all_reviews_widget_v2025_widget_thumb":false,"all_reviews_widget_v2025_verified_by_shop_badge_style":"light","all_reviews_widget_v2025_social_share":false,"all_reviews_widget_v2025_social_share_options_order":"Facebook,Twitter,LinkedIn,Pinterest","all_reviews_widget_v2025_pagination_type":"standard","all_reviews_widget_v2025_button_text_color":"#FFFFFF","all_reviews_widget_v2025_text_color":"#000000","all_reviews_widget_v2025_lighter_text_color":"#7B7B7B","all_reviews_widget_v2025_corner_styling":"soft","all_reviews_widget_v2025_title":"Customer reviews","all_reviews_widget_v2025_ai_summary_title":"Customers say about this store","all_reviews_widget_v2025_no_review_text":"Be the first to write a review","all_reviews_widget_v2025_review_highlights_title":"Review highlights","reviews_grid_widget_show_sample_reviews":false,"reviews_grid_widget_review_selection":"all","reviews_grid_widget_select_products":[],"reviews_grid_widget_show_media_only":false,"reviews_grid_widget_display_order":"media_first","reviews_grid_widget_card_grouping":"per_media","reviews_grid_widget_columns_desktop":3,"reviews_grid_widget_rows_desktop":3,"reviews_grid_widget_columns_mobile":2,"reviews_grid_widget_rows_mobile":6,"reviews_grid_widget_show_stars":true,"reviews_grid_widget_show_reviewer_name":true,"reviews_grid_widget_show_review_title_on_hover_desktop":true,"reviews_grid_widget_corner_styling":"soft","reviews_grid_widget_card_spacing":"medium","reviews_grid_widget_header_text_color":"#000000","reviews_grid_widget_star_and_reviewer_name_color":"#F9F9F9","reviews_grid_widget_overlay_and_background_color":"#000000","reviews_grid_widget_content_color":"#F9F9F9","reviews_grid_widget_header_text":"From our customers","reviews_grid_widget_show_average_rating":true,"trust_badge_enabled":false,"trust_badge_structure":"outline","trust_badge_color":"black","trust_badge_star":"black","trust_badge_rating_display_default":"show_avg_text","platform":"shopify","branding_url":"https://app.judge.me/reviews","branding_text":"Powered by Judge.me","locale":"en","reply_name":"Revitin","shop_currency":"USD","widget_version":"3.0","footer":true,"autopublish":true,"review_dates":true,"enable_custom_form":false,"shop_locale":"en","enable_multi_locales_translations":true,"show_review_title_input":true,"autofill_review_title":true,"review_verification_email_status":"always","require_verification_before_submit":false,"sign_in_with_
621shop_enabled":false,"customer_account_validation_enabled":true,"most_relevant_sort_enabled":false,"coupon_promo_invited_eligible":true,"coupon_promo_web_eligible":false,"uses_coupon_integration":false,"uses_external_coupon":false,"can_be_branded":true,"rtl_stars_enabled_ar":true,"rtl_stars_enabled_he":true,"reply_name_text":"Revitin"};</script>
621 <style class='jdgm-settings-style'>.jdgm-xx{left:0}:root{--jdgm-primary-color: #FFDEA3;--jdgm-secondary-color: rgba(255,222,163,0.1);--jdgm-star-color: #7E8F72;--jdgm-write-review-text-color: #5F471D;--jdgm-write-review-bg-color: #FFDEA3;--jdgm-paginate-color: #FFDEA3;--jdgm-border-radius: 0;--jdgm-reviewer-name-color: #5F471D}.jdgm-histogram__bar-content{background-color:#5F471D}.jdgm-rev[data-verified-buyer=true] .jdgm-rev__icon.jdgm-rev__icon:after,.jdgm-rev__buyer-badge.jdgm-rev__buyer-badge{color:white;background-color:#FFDEA3}.jdgm-review-widget--small .jdgm-gallery.jdgm-gallery .jdgm-gallery__thumbnail-link:nth-child(8) .jdgm-gallery__thumbnail-wrapper.jdgm-gallery__thumbnail-wrapper:before{content:"See more"}@media only screen and (min-width: 768px){.jdgm-gallery.jdgm-gallery .jdgm-gallery__thumbnail-link:nth-child(8) .jdgm-gallery__thumbnail-wrapper.jdgm-gallery__thumbnail-wrapper:before{content:"See more"}}.jdgm-preview-badge .jdgm-star.jdgm-star{color:#7E8F72}.jdgm-prev-badge[data-average-rating='0.00']{display:none !important}.jdgm-rev .jdgm-rev__icon{display:none !important}.jdgm-author-all-initials{display:none !important}.jdgm-author-last-initial{display:none !important}.jdgm-rev-widg__title{visibility:hidden}.jdgm-rev-widg__summary-text{visibility:hidden}.jdgm-prev-badge__text{visibility:hidden}.jdgm-rev__prod-link-prefix:before{content:'about'}.jdgm-rev__variant-label:before{content:'Variant: '}.jdgm-rev__out-of-store-text:before{content:'(out of store)'}@media only screen and (min-width: 768px){.jdgm-rev__pics .jdgm-rev_all-rev-page-picture-separator,.jdgm-rev__pics .jdgm-rev__product-picture{display:none}}@media only screen and (max-width: 768px){.jdgm-rev__pics .jdgm-rev_all-rev-page-picture-separator,.jdgm-rev__pics .jdgm-rev__product-picture{display:none}}.jdgm-preview-badge[data-template="product"]{display:none !important}.jdgm-preview-badge[data-template="collection"]{display:none !important}.jdgm-preview-badge[data-template="index"]{display:none !important}.jdgm-review-widget[data-from-snippet="true"]{display:none !important}.jdgm-verified-count-badget[data-from-snippet="true"]{display:none !important}.jdgm-carousel-wrapper[data-from-snippet="true"]{display:none !important}.jdgm-all-reviews-text[data-from-snippet="true"]{display:none !important}.jdgm-medals-section[data-from-snippet="true"]{display:none !important}.jdgm-ugc-media-wrapper[data-from-snippet="true"]{display:none !important}.jdgm-rev__transparency-badge[data-badge-type="review_collected_via_store_invitation"]{display:none !important}.jdgm-rev__transparency-badge[data-badge-type="review_collected_from_another_provider"]{display:none !important}.jdgm-rev__transparency-badge[data-badge-type="review_collected_from_store_visitor"]{display:none !important}.jdgm-rev__transparency-badge[data-badge-type="review_earned_for_future_purchase"]{display:none !important}.jdgm-review-snippet-widget{--jdgm-snippet-card-color: #fff;--jdgm-snippet-text-color: #000;--jdgm-snippet-lighter-text-color: #7B7B7B;--jdgm-snippet-star-color: #FFDEA3;--jdgm-snippet-border-radius: 8px;--jdgm-snippet-arrows-bg-color: #fff;--jdgm-snippet-arrows-color: #000}.jdgm-review-snippet-widget .jdgm-rev-snippet-widget__cards-container .jdgm-rev-snippet-card{border-radius:8px;background:#fff}.jdgm-review-snippet-widget .jdgm-rev-snippet-widget__cards-container .jdgm-rev-snippet-card__rev-rating .jdgm-star{color:#FFDEA3}.jdgm-review-snippet-widget .jdgm-rev-snippet-widget__prev-btn,.jdgm-review-snippet-widget .jdgm-rev-snippet-widget__next-btn{border-radius:50%;background:#fff}.jdgm-review-snippet-widget .jdgm-rev-snippet-widget__prev-btn>svg,.jdgm-review-snippet-widget .jdgm-rev-snippet-widget__next-btn>svg{fill:#000}.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jm-mfp-content,.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jdgm-full-rev__icon,.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jdgm-full-rev__pic-img,.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jdgm-full-rev__reply{border-radius:8px}.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jdgm-full-rev[data-verified-buyer="true"] .jdgm-full-rev__icon::after{border-radius:8px}.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jdgm-full-rev .jdgm-rev__buyer-badge{border-radius:calc( 8px / 2 )}.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jdgm-full-rev .jdgm-full-rev__replier::before{content:'Revitin'}.jdgm-full-rev-modal.rev-snippet-widget .jm-mfp-container .jdgm-full-rev .jdgm-full-rev__product-button{border-radius:calc( 8px * 6 )}
622</style> <style class='jdgm-settings-style'>.jdgm-review-widget .jdgm-rev-widg{max-width:1200px;margin-left:auto;margin-right:auto}.jdgm-review-widget .jdgm-rev-widg__header .jdgm-row-stars{justify-content:space-between !important}@media (min-width: 768px){.jdgm-review-widget .jdgm-rev-widg{padding-left:2.5rem;padding-right:2.5rem}}@media only screen and (min-width: 992px){.jdgm-review-widget .jdgm-rev-widg__title{text-align:left}.jdgm-review-widget .jdgm-rev-widg__summary,.jdgm-review-widget .jdgm-widget-actions-wrapper{width:auto !important}.jdgm-review-widget .jdgm-histogram{width:55% !important;align-items:flex-start !important}}.jdgm-preview-badge span.jdgm-prev-badge__stars{font-size:11px}.jdgm-preview-badge .jdgm-prev-badge__text{font-size:15px;margin-left:5px;color:#7e8f72}.jdgm-preview-badge .jdgm-preview-badge .jdgm-star.jdgm-star{margin:0 2px !important}
623</style>
624
625  
626  
627  
628  <style class='jdgm-miracle-styles'>
629  @-webkit-keyframes jdgm-spin{0%{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);-ms-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes jdgm-spin{0%{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);-ms-transform:rotate(359deg);transform:rotate(359deg)}}@font-face{font-family:'JudgemeStar';src:url("data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAScAA0AAAAABrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEgAAAABoAAAAcbyQ+3kdERUYAAARgAAAAHgAAACAAMwAGT1MvMgAAAZgAAABGAAAAVi+vS9xjbWFwAAAB8AAAAEAAAAFKwBMjvmdhc3AAAARYAAAACAAAAAj//wADZ2x5ZgAAAkAAAAEJAAABdH33LXtoZWFkAAABMAAAAC0AAAA2BroQKWhoZWEAAAFgAAAAHAAAACQD5QHQaG10eAAAAeAAAAAPAAAAFAYAAABsb2NhAAACMAAAAA4AAAAOAO4AeG1heHAAAAF8AAAAHAAAACAASgAvbmFtZQAAA0wAAADeAAABkorWfVZwb3N0AAAELAAAACkAAABEp3ubLXgBY2BkYADhPPP4OfH8Nl8ZuJkYQODS2fRrCPr/aSYGxq1ALgcDWBoAO60LkwAAAHgBY2BkYGDc+v80gx4TAwgASaAICmABAFB+Arl4AWNgZGBgYGPQYWBiAAIwyQgWc2AAAwAHVQB6eAFjYGRiYJzAwMrAwejDmMbAwOAOpb8ySDK0MDAwMbByMsCBAAMCBKS5pjA4PGB4wMR44P8BBj3GrQymQGFGkBwAjtgK
629/gAAeAFjYoAAEA1jAwAAZAAHAHgB3crBCcAwDEPRZydkih567CDdf4ZskmLwFBV8xBfCaC4BXkOUmx4sU0h2ngNb9V0vQCxaRKIAevT7fGWuBrEAAAAAAAAAAAA0AHgAugAAeAF9z79Kw1AUx/FzTm7un6QmJtwmQ5Bg1abgEGr/BAqlU6Gju+Cgg1MkQ/sA7Vj7BOnmO/gUvo2Lo14NqIO6/IazfD8HEODtmQCfoANwNsyp2/GJt3WKQrd1NLiYYWx2PBqOsmJMEOznPOTzfSCrhAtbbLdmeFLJV9eKd63WLrZcIcuaEVdssWCKM6pLCfTVOYbz/0pNSMSZKLIZpvh78sAUH6PlMrreTCabP9r+Z/puPZ2ur/RqpQHgh+MIegCnXeM4MRAPjYN//5tj4ZtTjkFqEdmeMShlEJ7tVAly2TAkx6R68Fl4E/aVvn8JqHFQ4JS1434gXKcuL31dDhzs3YbsEOAd/IU88gAAAHgBfY4xTgMxEEVfkk0AgRCioKFxQYd2ZRtpixxgRU2RfhU5q5VWseQ4JdfgAJyBlmNwAM7ABRhZQ0ORwp7nr+eZAa54YwYg9zm3ynPOeFRe8MCrciXOh/KSS76UV5L/iDmrLiS5AeU519wrL3jmSbkS5115yR2fyivJv9kx0ZMZ2RLZw27q87iNQi8EBo5FSPIMw3HqBboi5lKTGAGDp8FKXWP+t9TU01Lj5His1Ba6uM9dTEMwvrFmbf5GC/q2drW3ruXUhhsCiQOjznFlCzYhHUZp4xp76vsvQh89CQAAeAFjYGJABowM6IANLMrEyMTIzMjCXpyRWJBqZshWXJJYBKOMAFHFBucAAAAAAAAB//8AAngBY2BkYGDgA2IJBhBgAvKZGViBJAuYxwAABJsAOgAAeAFjYGBgZACCk535hiD60tn0azAaAEqpB6wAAA==") format("woff");font-weight:normal;font-style:normal}.jdgm-star{font-family:'JudgemeStar';display:inline !important;text-decoration:none !important;padding:0 4px 0 0 !important;margin:0 !important;font-weight:bold;opacity:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.jdgm-star:hover{opacity:1}.jdgm-star:last-of-type{padding:0 !important}.jdgm-star.jdgm--on:before{content:"\e000"}.jdgm-star.jdgm--off:before{content:"\e001"}.jdgm-star.jdgm--half:before{content:"\e002"}.jdgm-widget *{margin:0;line-height:1.4;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-overflow-scrolling:touch}.jdgm-hidden{display:none !important;visibility:hidden !important}.jdgm-temp-hidden{display:none}.jdgm-spinner{width:40px;height:40px;margin:auto;border-radius:50%;border-top:2px solid #eee;border-right:2px solid #eee;border-bottom:2px solid #eee;border-left:2px solid #ccc;-webkit-animation:jdgm-spin 0.8s infinite linear;animation:jdgm-spin 0.8s infinite linear}.jdgm-spinner:empty{display:block}.jdgm-prev-badge{display:block !important}
630
631</style>
632
633
634  
635  
636   
637
638
639
640
641<script data-cfasync='false' class='jdgm-script'>
642!function(e){window.jdgm=window.jdgm||{};
643/* INF-1976 */
644var _jdgmBlocked=function(){var raw=(window.jdgmSettings||{}).hostname_allowlist;var list=(raw==null?"":""+raw).split(/[\s,]+/).map(function(h){return h.trim().toLowerCase().replace(/\.$/,"");}).filter(function(h){return h;});if(!list.length)return false;var host=(e.location.hostname||"").toLowerCase().replace(/\.$/,"");if(/(^|\.)shopifypreview\.com$/.test(host))return false;var bare=host.replace(/^www\./,"");for(var i=0;i<list.length;i++){var en=list[i];if(en.indexOf("*.")===0){var b=en.slice(2);if(host===b||host.slice(-(b.length+1))==="."+b)return false;}else if(bare===en.replace(/^www\./,""))return false;}return true;}();
645if(_jdgmBlocked){jdgm._loaderExecuted=true;jdgm._blocked=true;var _jdgmS=e.createElement("style");_jdgmS.textContent='[class^="jdgm-"],[class*=" jdgm-"]{display:none !important}';(e.head||e.documentElement).appendChild(_jdgmS);return;}
646jdgm.CDN_HOST="https://cdnwidget.judge.me/",jdgm.CDN_HOST_ALT="https://cdn2.judge.me/cdn/widget_frontend/",jdgm.API_HOST="https://api.judge.me/",jdgm.CDN_BASE_URL="https://cdn.shopify.com/extensions/01a0f14c-14c3-7c54-8630-ec498be121ab/judgeme-770/assets/",jdgm.CDN_API_HOST="https://cdn.judge.me/",
647jdgm.docReady=function(d){(e.attachEvent?"complete"===e.readyState:"loading"!==e.readyState)?
648setTimeout(d,0):e.addEventListener("DOMContentLoaded",d)},jdgm.loadCSS=function(d,t,o,a){
649!o&&jdgm.loadCSS.requestedUrls.indexOf(d)>=0||(jdgm.loadCSS.requestedUrls.push(d),
650(a=e.createElement("link")).rel="stylesheet",a.class="jdgm-stylesheet",a.media="nope!",
651a.href=d,a.onload=function(){this.media="all",t&&setTimeout(t)},e.body.appendChild(a))},
652jdgm.loadCSS.requestedUrls=[],jdgm.loadJS=function(e,d){var t=new XMLHttpRequest;
653t.onreadystatechange=function(){4===t.readyState&&t.status>=200&&t.status<300&&(Function(t.response)(),d&&d(t.response))},
654t.open("GET",e),t.onerror=function(){if(e.indexOf(jdgm.CDN_HOST)===0&&jdgm.CDN_HOST_ALT!==jdgm.CDN_HOST){var f=e.replace(jdgm.CDN_HOST,jdgm.CDN_HOST_ALT);jdgm.loadJS(f,d)}},t.send()},jdgm.docReady((function(){(window.jdgmLoadCSS||e.querySelectorAll(
655".jdgm-widget, .jdgm-all-reviews-page").length>0)&&(jdgmSettings.widget_load_with_code_splitting?
656parseFloat(jdgmSettings.widget_version)>=3?jdgm.loadCSS(jdgm.CDN_BASE_URL+"widget_v3_base.css"):
657jdgm.loadCSS(jdgm.CDN_BASE_URL+"widget_base.css"):jdgm.loadCSS(jdgm.CDN_BASE_URL+"shopify_v2.css")
658)}))}(document);
659</script>
659
660<noscript><link rel="stylesheet" type="text/css" media="all" href="https://cdn.shopify.com/extensions/01a0f14c-14c3-7c54-8630-ec498be121ab/judgeme-770/assets/shopify_v2.css"></noscript>
661
662<!-- BEGIN app snippet: theme_fix_tags -->
662<script>
663  (function() {
664    var jdgmThemeFixes = null;
665    if (!jdgmThemeFixes) return;
666
667    // "All themes" fix: CSS and JS applied on every theme. CSS is injected
668    // before the per-theme fix so the theme-specific CSS wins the cascade.
669    // HTML is never applied globally (too risky).
670    var allThemesFix = jdgmThemeFixes['all'];
671    if (allThemesFix && allThemesFix.css) {
672      var allStyleTag = document.createElement('style');
673      allStyleTag.classList.add('jdgm-theme-fix-style-all');
674      allStyleTag.innerHTML = allThemesFix.css;
675      document.head.append(allStyleTag);
676    };
677
678    if (allThemesFix && allThemesFix.js) {
679      var allScriptTag = document.createElement('script');
680      allScriptTag.classList.add('jdgm-theme-fix-script-all');
681      allScriptTag.innerHTML = allThemesFix.js;
682      document.head.append(allScriptTag);
683    };
684
685    var thisThemeFix = jdgmThemeFixes[Shopify.theme.id];
686    if (!thisThemeFix) return;
687
688    if (thisThemeFix.html) {
689      document.addEventListener("DOMContentLoaded", function() {
690        var htmlDiv = document.createElement('div');
691        htmlDiv.classList.add('jdgm-theme-fix-html');
692        htmlDiv.innerHTML = thisThemeFix.html;
693        document.body.append(htmlDiv);
694      });
695    };
696
697    if (thisThemeFix.css) {
698      var styleTag = document.createElement('style');
699      styleTag.classList.add('jdgm-theme-fix-style');
700      styleTag.innerHTML = thisThemeFix.css;
701      document.head.append(styleTag);
702    };
703
704    if (thisThemeFix.js) {
705      var scriptTag = document.createElement('script');
706      scriptTag.classList.add('jdgm-theme-fix-script');
707      scriptTag.innerHTML = thisThemeFix.js;
708      document.head.append(scriptTag);
709    };
710  })();
711</script>
711
712<!-- END app snippet -->
713<!-- End of Judge.me Core -->
714
715
716
717<!-- END app block -->
717<script src="https://cdn.shopify.com/extensions/01a0f14c-14c3-7c54-8630-ec498be121ab/judgeme-770/assets/loader.js" type="text/javascript" defer="defer"></script>
717
718<link href="https://monorail-edge.shopifysvc.com" rel="dns-prefetch">
719<script>(function(){if ("sendBeacon" in navigator && "performance" in window) {try {var session_token_from_headers = performance.getEntriesByType('navigation')[0].serverTiming.find(x => x.name == '_s').description;} catch {var session_token_from_headers = undefined;}var session_cookie_matches = document.cookie.match(/_shopify_s=([^;]*)/);var session_token_from_cookie = session_cookie_matches && session_cookie_matches.length === 2 ? session_cookie_matches[1] : "";var session_token = session_token_from_headers || session_token_from_cookie || "";function handle_abandonment_event(e) {var entries = performance.getEntries().filter(function(entry) {return /monorail-edge.shopifysvc.com/.test(entry.name);});if (!window.abandonment_tracked && entries.length === 0) {window.abandonment_tracked = true;var currentMs = Date.now();var navigation_start = performance.timing.navigationStart;var payload = {shop_id: 37689720970,url: window.location.href,navigation_start,duration: currentMs - navigation_start,session_token,page_type: "product"};window.navigator.sendBeacon("https://monorail-edge.shopifysvc.com/v1/produce", JSON.stringify({schema_id: "online_store_buyer_site_abandonment/1.1",payload: payload,metadata: {event_created_at_ms: currentMs,event_sent_at_ms: currentMs}}));}}window.addEventListener('pagehide', handle_abandonment_event);}}());</script>
vendor: 1 bytes, line 719
719
720<script>
721  window.__TREKKIE_SHIM_QUEUE = window.__TREKKIE_SHIM_QUEUE || [];
722</script>
vendor: 1 bytes, line 722
722
723<script>(function(){var wpmLoader=function(){"use strict";var e=/Googlebot|Storebot-Google|bingbot|Baiduspider|YandexBot|DuckDuckBot|Slurp|facebookexternalhit|Twitterbot|LinkedInBot|Applebot|AdsBot-Google|Mediapartners-Google|APIs-Google|PetalBot|SemrushBot|AhrefsBot|MJ12bot|DotBot|Acunetix|PerplexityBot|Perplexity-User/i,t=/bytedance/i;function i(){try{var e=document.cookie;if(!e||"string"!=typeof e)return;for(var t=0,i=e.split(";");t<i.length;t++){var n=i[t],r=n.indexOf("=");if(-1!==r){var o=n.slice(0,r).trim();if(o){var a=void 0;try{a=decodeURIComponent(o)}catch(e){a=o}if("_shopify_s"===a){var d=n.slice(r+1).trim();try{return decodeURIComponent(d)}catch(e){return d}}}}}return}catch(e){return}}function n(e){try{"undefined"!=typeof console&&"function"==typeof console.warn&&console.warn(e)}catch(e){}}function r(e,t){return"string"==typeof e&&e.length>0&&e.length<=t?e:void 0}function o(e){var t;switch(null==(t=null==e?void 0:e.navigation)?void 0:t.type){case 0:return"navigate";case 1:return"reload";case 2:return"back_forward";default:return}}function a(){var e,t,i;try{var n=null==(i=null==(t=null==(e=self.ShopifyAnalytics)?void 0:e.lib)?void 0:t.trekkie)?void 0:i.state;return"awaiting-consent"===n||"initialized"===n?n:void 0}catch(e){return}}return function(d,s,u,l){var c=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};try{var p=c.trekkieShim;!0!==p&&"true"!==p||null!=window.__TREKKIE_SHIM_QUEUE||(window.__TREKKIE_SHIM_QUEUE=[])}catch(e){}var f,v,h,y,g=(v=(f={modern:/Edge?\/(1{2}[4-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Firefox\/(1{2}[4-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Chrom(ium|e)\/(9{2}|\d{3,})\.\d+(\.\d+|)|(Maci|X1{2}).+ Version\/(15\.\d+|(1[6-9]|[2-9]\d|\d{3,})\.\d+)([,.]\d+|)( \(\w+\)|)( Mobile\/\w+|) Safari\/|Chrome.+OPR\/(9{2}|\d{3,})\.\d+\.\d+|(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(15[._]\d+|(1[6-9]|[2-9]\d|\d{3,})[._]\d+)([._]\d+|)|Android:?[ /-](14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})(\.\d+|)(\.\d+|)|Android.+Firefox\/(15\d|1[6-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Android.+Chrom(ium|e)\/(14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|SamsungBrowser\/([2-9]\d|\d{3,})\.\d+/,legacy:/Edge?\/(1[6-9]|[2-9]\d|\d{3,})\.\d+(\.\d+|)|Firefox\/(5[4-9]|[6-9]\d|\d{3,})\.\d+(\.\d+|)|Chrom(ium|e)\/(5[1-9]|[6-9]\d|\d{3,})\.\d+(\.\d+|)([\d.]+$|.*Safari\/(?![\d.]+ Edge\/[\d.]+$))|(Maci|X1{2}).+ Version\/(10\.\d+|(1[1-9]|[2-9]\d|\d{3,})\.\d+)([,.]\d+|)( \(\w+\)|)( Mobile\/\w+|) Safari\/|Chrome.+OPR\/(3[89]|[4-9]\d|\d{3,})\.\d+\.\d+|(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(10[._]\d+|(1[1-9]|[2-9]\d|\d{3,})[._]\d+)([._]\d+|)|Android:?[ /-](14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})(\.\d+|)(\.\d+|)|Mobile Safari.+OPR\/([89]\d|\d{3,})\.\d+\.\d+|Android.+Firefox\/(15\d|1[6-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Android.+Chrom(ium|e)\/(14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Android.+(UC? ?Browser|UCWEB|U3)[ /]?(15\.([5-9]|\d{2,})|(1[6-9]|[2-9]\d|\d{3,})\.\d+)\.\d+|SamsungBrowser\/(5\.\d+|([6-9]|\d{2,})\.\d+)|Android.+MQ{2}Browser\/(14(\.(9|\d{2,})|)|(1[5-9]|[2-9]\d|\d{3,})(\.\d+|))(\.\d+|)|K[Aa][Ii]OS\/(3\.\d+|([4-9]|\d{2,})\.\d+)(\.\d+|)/}).modern,h=f.legacy,(y=navigator.userAgent).match(e)?"bot":y.match(v)?"modern":y.match(h)?"legacy":y.match(t)?"bot":"unknown"),m=function(e){var t,i,n=r(e,128);try{var a=window.performance,d=null==(t=null==a?void 0:a.getEntriesByType)?void 0:t.call(a,"navigation")[0];if(!d)return{requestId:n,navigationType:o(a)};var s="type"in d?r(d.type,64):void 0,u="serverTiming"in d&&Array.isArray(d.serverTiming)?d.serverTiming:[];return{requestId:null!=n?n:r(null==(i=u.find(function(e){return"requestID"===e.name}))?void 0:i.description,128),navigationType:s}}catch(e){return{requestId:n}}}(c.requestId),w=function(e){var t=e.version,r=e.browserTarget,o=e.surface,a=e.shopId,d=e.monorailEndpoint,s=window.location.href;return{emit:function(e){var u=e.status,l=e.errorMsg,c=e.failureReason,p=e.useKeepaliveFallback,f=void 0!==p&&p,v=e.navigationType,h=e.pagehidePersisted,y=e.requestId,g=e.trekkieState;if(d){var m,w;try{var b=(new Date).getTime();m=JSON.stringify({metadata:{event_sent_at_ms:b},events:[{schema_id:"web_pixels_manager_load/3.3",payload:{version:t,bundle_target:r,page_url:s,status:u,surface:o,error_msg:l,failure_reason:c,navigation_type:v,pagehide_persisted:h,request_id:y,trekkie_state:g,shop_id:a,visit_token:i()},metadata:{event_created_at_ms:b}}]})}catch(e){return}try{if("function"==typeof window.navigator.sendBeacon&&-1===(w=window.navigator.userAgent).indexOf("iPhone; CPU iPhone OS 12_")&&-1===w.indexOf("iPad; CPU OS 12_")&&-1===w.indexOf("iPod touch; CPU iPhone OS 12_")&&window.navigator.sendBeacon.bind(window.navigator)(d,m))return}catch(e){}if(f)try{"function"==typeof window.fetch&&window.fetch(d,{method:"POST",headers:{"Content-Type":"text/plain"},body:m,keepalive:!0}
723).catch(function(){})}catch(e){}else try{var _=new XMLHttpRequest;_.open("POST",d,!0),_.setRequestHeader("Content-Type","text/plain"),_.send(m)}catch(e){n("[Web Pixels Manager] Got an unhandled error while logging to Monorail.")}}else n("[Web Pixels Manager] No Monorail endpoint provided, skipping logging.")}}}({version:u,browserTarget:g,surface:d.surface,shopId:d.shopId,monorailEndpoint:d.monorailEndpoint});if(Boolean(null==(_=null==(b=window.Shopify)?void 0:b.analytics)?void 0:_.replayQueue))w.emit({status:"setup-skipped",errorMsg:"replay queue already initialized."});else{var b,_;w.emit({status:"setup-started"}),window.Shopify=window.Shopify||{};var S=window.Shopify;S.analytics=S.analytics||{};var P=S.analytics;P.replayQueue=[],P.publish=function(e,t,i){return P.replayQueue.push([e,t,i]),!0};try{self.performance.mark("wpm:start")}catch(e){}var k,C="modern"===g?"modern":"legacy",E=(null!=l?l:{modern:"",legacy:""})[C],I=[(k={baseUrl:s,hashVersion:u,buildTarget:C}).baseUrl,"/wpm","/b",k.hashVersion,"modern"===k.buildTarget?"m":"l",".js"].join(""),O=!1,T=!1;try{c.browserTarget=g,function(){O=!0;try{window.addEventListener("pagehide",M)}catch(e){O=!1}}(),R(function(){try{R(x)}catch(e){D(e)}}),w.emit({status:"loading",requestId:m.requestId,navigationType:m.navigationType,trekkieState:a()})}catch(e){D(e)}}function U(){var e;if(q(),!function(){var e,t;return Boolean(null==(t=null==(e=window.Shopify)?void 0:e.analytics)?void 0:t.initialized)}()){var t,i,n;try{if("function"!=typeof(null==(e=window.webPixelsManager)?void 0:e.init))return void A();if(!(null!==(n=i=t=window.webPixelsManager.init(d))&&"function"!=typeof n&&Object(n)===n&&"publish"in i&&"function"==typeof i.publish&&"publishCustomEvent"in i&&"function"==typeof i.publishCustomEvent&&"visitor"in i&&"function"==typeof i.visitor))return void A()}catch(e){return void A(e)}var r=window.Shopify.analytics;r.replayQueue.forEach(function(e){var i=e[0],n=e[1],r=e[2];t.publishCustomEvent(i,n,r)}),r.replayQueue=[],r.publish=t.publishCustomEvent,r.visitor=t.visitor,r.initialized=!0}}function A(e){B("manager_api_unavailable",void 0===e?void 0:Q(e))}function x(){B("script_load_failed","".concat(I," has failed to load"))}function B(e,t){T||(T=!0,q(),w.emit({status:"failed",errorMsg:t,failureReason:e,requestId:m.requestId,navigationType:m.navigationType,trekkieState:a()}))}function M(e){O&&(q(),w.emit({status:"pagehide-while-loading",useKeepaliveFallback:!0,pagehidePersisted:e.persisted,requestId:m.requestId,navigationType:m.navigationType,trekkieState:a()}))}function q(){O=!1;try{window.removeEventListener("pagehide",M)}catch(e){}}function R(e){var t;!function(e){var t=e.src,i=e.async,n=void 0===i||i,r=e.onload,o=e.onerror,a=e.sri,d=e.scriptDataAttributes,s=void 0===d?{}:d,u=document.createElement("script"),l=document.querySelector("head"),c=document.querySelector("body");if(u.async=n,u.src=t,a&&(u.integrity=a,u.crossOrigin="anonymous"),s)for(var p in s)if(Object.prototype.hasOwnProperty.call(s,p))try{u.dataset[p]=String(s[p])}catch(e){}if(r&&u.addEventListener("load",r),o&&u.addEventListener("error",o),l)l.appendChild(u);else{if(!c)throw new Error("Did not find a head or body element to append the script");c.appendChild(u)}}({src:I,async:!0,onload:U,onerror:e,sri:(t=E,"string"==typeof t&&/^sha384-[A-Za-z0-9+/=]+$/.test(t)?E:""),scriptDataAttributes:c})}function D(e){B("script_append_failed",Q(e))}function Q(e){return e instanceof Error?e.message:"Unknown error"}}}();wpmLoader({shopId: 37689720970,storefrontBaseUrl: "https://revitin.com",extensionsBaseUrl: "https://extensions.shopifycdn.com/cdn/shopifycloud/web-pixels-manager",monorailEndpoint: "https://revitin.com/.well-known/shopify/monorail/unstable/produce_batch",surface: "storefront-renderer",enabledBetaFlags: ["4c64608a","16072cab","8450a54b","7ee89bf1"],webPixelsConfigList: [{"id":"2540273802","configuration":"{\"pixelCode\":\"D86B8BRC77U37PM8G87G\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"22e92c2ad45662f435e4801458fb78cc","type":"APP","apiClientId":4383523,"privacyPurposes":["ANALYTICS","MARKETING","SALE_OF_DATA"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized"},{"id":"2094989450","configuration":"{}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"f92d7cfd1521456d481ee553d236893f","type":"APP","apiClientId":30400643073,"privacyPurposes":["ANALYTICS"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]}
723,"dataSharingState":"unrestricted"},{"id":"1953923210","configuration":"{\"shopId\":\"revitin.myshopify.com\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"7093dff47f098f6de2afb75b62011ebe","type":"APP","apiClientId":2753413,"privacyPurposes":["ANALYTICS","MARKETING"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized"},{"id":"1474461834","configuration":"{\"debug\":\"false\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"a9a83cf44fb282052ff936f7ab101058","type":"APP","apiClientId":4539653,"privacyPurposes":["ANALYTICS"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"unrestricted"},{"id":"1439137930","configuration":"{\"accountID\":\"YmxebZ\",\"webPixelConfig\":\"eyJlbmFibGVBZGRlZFRvQ2FydEV2ZW50cyI6IHRydWV9\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"c63c5b72c8d77be5f2d27d14c081da38","type":"APP","apiClientId":123074,"privacyPurposes":["ANALYTICS","MARKETING"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized","enabledFlags":["9a3ed68a"]},{"id":"1161724042","configuration":"{\"projectId\":\"rbrmbn89qv\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"d8a2bb2ccbb513dc8e8b6937f4b8033e","type":"APP","apiClientId":240074326017,"privacyPurposes":[],"capabilities":["advanced_dom_events"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_personal_data"],"dataSharingControls":["share_all_events"]},"dataSharingState":"unrestricted"},{"id":"880607370","configuration":"{\"webPixelName\":\"Judge.me\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"8acc938b1a30dc7624e304493ca567d7","type":"APP","apiClientId":683015,"privacyPurposes":["ANALYTICS"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"unrestricted"},{"id":"880476298","configuration":"{\"shop\":\"revitin.myshopify.com\", \"shopliftUrl\":\"https:\/\/events.shoplift.ai\/api\/events\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"dabcda9558be25394b12ce3ce899568b","type":"APP","apiClientId":7521861633,"privacyPurposes":["ANALYTICS"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"unrestricted"},{"id":"752156810","configuration":"{\"config\":\"{\\\"google_tag_ids\\\":[\\\"AW-16882923746\\\",\\\"GT-K522JRNQ\\\"],\\\"target_country\\\":\\\"US\\\",\\\"gtag_events\\\":[{\\\"type\\\":\\\"begin_checkout\\\",\\\"action_label\\\":\\\"AW-16882923746\\\/uL1iCIXCp6oaEOLxs_I-\\\"},{\\\"type\\\":\\\"search\\\",\\\"action_label\\\":\\\"AW-16882923746\\\/Dg4iCInDp6oaEOLxs_I-\\\"},{\\\"type\\\":\\\"view_item\\\",\\\"action_label\\\":[\\\"AW-16882923746\\\/9MT5CI7Cp6oaEOLxs_I-\\\",\\\"MC-W1XEHCZVPX\\\"]},{\\\"type\\\":\\\"purchase\\\",\\\"action_label\\\":[\\\"AW-16882923746\\\/kcG4CILCp6oaEOLxs_I-\\\",\\\"MC-W1XEHCZVPX\\\"]},{\\\"type\\\":\\\"page_view\\\",\\\"action_label\\\":[\\\"AW-16882923746\\\/y5QNCIvCp6oaEOLxs_I-\\\",\\\"MC-W1XEHCZVPX\\\"]},{\\\"type\\\":\\\"add_payment_info\\\",\\\"action_label\\\":\\\"AW-16882923746\\\/nU05CIzDp6oaEOLxs_I-\\\"},{\\\"type\\\":\\\"add_to_cart\\\",\\\"action_label\\\":\\\"AW-16882923746\\\/Ua8GCIjCp6oaEOLxs_I-\\\"}],\\\"enable_monitoring_mode\\\":false}\"}","eventPayloadVersion":"v1","runtimeContext":"OPEN","scriptVersion":"a3321ca85cf5aaf6b57585fcd8d67b3a","type":"APP","apiClientId":1780363,"privacyPurposes":[],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized","enabledFlags":["9a3ed68a"]},{"id":"585957514","configuration":"{\"masterTagID\":\"19038\",\"merchantID\":\"65308\",\"appPath\":\"https:\/\/daedalus.shareasale.com\",\"storeID\":\"NaN\",\"xTypeMode\":\"NaN\",\"xTypeValue\":\"NaN\",\"channelDedup\":\"NaN\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"f300cca684872f2df140f714437af558","type":"APP","apiClientId":4929191,"privacyPurposes":["ANALYTICS","MARKETING"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_personal_data"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized"},{"id":"494829706","configuration":"{\"pixel_id\":\"1036206484636196\",\"pixel_type\":\"facebook_pixel\"}","eventPayloadVersion":"v1","runtimeContext":"OPEN","scriptVersion":"96420dbe9ea96c426a1b7f364f977719","type":"APP","apiClientId":2329312,"privacyPurposes":["ANALYTICS","MARKETING","SALE_OF_DATA"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized","enabledFlags":["9a3ed68a"]},{"id":"67666058","eventPayloadVersion":"v1","runtimeContext":"LAX","scriptVersion":"1","type":"CUSTOM","privacyPurposes":["ANALYTICS"],"name":"Google Analytics tag (migrated)","dataSharingAdjustments":{"protectedCustomerApprovalScopes":[],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized"}
723,{"id":"159023242","eventPayloadVersion":"1","runtimeContext":"LAX","scriptVersion":"4","type":"CUSTOM","privacyPurposes":["ANALYTICS","MARKETING","SALE_OF_DATA"],"name":"Add Shipping Info Event","dataSharingAdjustments":{"protectedCustomerApprovalScopes":[],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized"},{"id":"shopify-app-pixel","configuration":"{}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"0530","apiClientId":"shopify-pixel","type":"APP","privacyPurposes":["ANALYTICS","MARKETING"]},{"id":"shopify-custom-pixel","eventPayloadVersion":"v1","runtimeContext":"LAX","scriptVersion":"0530","apiClientId":"shopify-pixel","type":"CUSTOM","privacyPurposes":["ANALYTICS","MARKETING"]}],isMerchantRequest: false,initData: {"shop":{"name":"Revitin","paymentSettings":{"currencyCode":"USD"},"myshopifyDomain":"revitin.myshopify.com","countryCode":"US","storefrontUrl":"https:\/\/revitin.com"},"customer":null,"cart":null,"checkout":null,"productVariants":[{"price":{"amount":17.0,"currencyCode":"USD"},"product":{"title":"Revitin Toothpaste Single Tube","vendor":"Revitin® Natural Toothpaste","id":"6606432174218","untranslatedTitle":"Revitin Toothpaste Single Tube","url":"\/products\/revitin-natural-toothpaste","type":"Toothpaste"},"id":"45594631471242","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551"},"sku":"CITRUS1","title":"Citrus","untranslatedTitle":"Citrus"}],"products":[{"id":"6606432174218","handle":"revitin-natural-toothpaste","isCollective":null,"title":"Revitin Toothpaste Single Tube","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste Single Tube","url":"\/products\/revitin-natural-toothpaste","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45594631471242","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551"},"price":{"amount":17.0,"currencyCode":"USD"},"sku":"CITRUS1","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"9208964186250","handle":"variety-travel-2-pack-of-1-oz","isCollective":null,"title":"Variety Travel 2-Pack of 1 oz","type":null,"untranslatedTitle":"Variety Travel 2-Pack of 1 oz","url":"\/products\/variety-travel-2-pack-of-1-oz","vendor":"Revitin","remoteShopId":null,"variants":[{"id":"49777251877002","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Group248_1.png?v=1785832769"},"price":{"amount":12.0,"currencyCode":"USD"},"sku":"VarietyTravel2-pk","title":"Default Title","untranslatedTitle":"Default Title"}]},{"id":"7609245171850","handle":"revitin-toothpaste-5-tubes","isCollective":null,"title":"Revitin Toothpaste (5 Tubes)","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (5 Tubes)","url":"\/products\/revitin-toothpaste-5-tubes","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45594652901514","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e9fa6364-9bfe-4cd7-b0af-1a95d93ee5ba.png?v=1774337705"},"price":{"amount":70.0,"currencyCode":"USD"},"sku":"CITRUS5","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"8334203355274","handle":"revitin-toothpaste-single-tube-mint","isCollective":null,"title":"Revitin Toothpaste Single Tube","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste Single Tube","url":"\/products\/revitin-toothpaste-single-tube-mint","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45622706602122","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_99a4be1b-921c-4bbc-96f1-3bc4d0999926.png?v=1774337594"},"price":{"amount":17.0,"currencyCode":"USD"},"sku":"MINT1","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"6606431420554","handle":"revitin-natural-toothpaste-family-pack-3tubes","isCollective":null,"title":"Revitin Toothpaste (3 Tubes)","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (3 Tubes)","url":"\/products\/revitin-natural-toothpaste-family-pack-3tubes","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45594633666698","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus.png?v=1773920437"},"price":{"amount":46.0,"currencyCode":"USD"},"sku":"CITRUS3","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"8333322846346","handle":"revitin-toothpaste-3-tubes-mint","isCollective":null,"title":"Revitin Toothpaste (3 Tubes)","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (3 Tubes)","url":"\/products\/revitin-toothpaste-3-tubes-mint","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45618606080138","
723image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint.png?v=1774282946"},"price":{"amount":46.0,"currencyCode":"USD"},"sku":"MINT3","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"8333359808650","handle":"revitin-toothpaste-5-tubes-mint","isCollective":null,"title":"Revitin Toothpaste (5 Tubes)","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (5 Tubes)","url":"\/products\/revitin-toothpaste-5-tubes-mint","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45618689310858","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_37b5d288-2b5a-42a4-bd87-71596a6bf4b4.png?v=1774337756"},"price":{"amount":70.0,"currencyCode":"USD"},"sku":"MINT5","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"7890501009546","handle":"copy-of-revitin-toothpaste-25-tubes-gm","isCollective":null,"title":"Revitin Toothpaste (25 Tubes)","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (25 Tubes)","url":"\/products\/copy-of-revitin-toothpaste-25-tubes-gm","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45594657161354","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_5dd0e011-ff5d-4356-80a8-debbb8fbaa63.png?v=1774338062"},"price":{"amount":350.0,"currencyCode":"USD"},"sku":"CITRUS25","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"8334207778954","handle":"revitin-toothpaste-25-tubes-mint","isCollective":null,"title":"Revitin Toothpaste (25 Tubes)","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (25 Tubes)","url":"\/products\/revitin-toothpaste-25-tubes-mint","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45622715121802","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_5fc8e8a0-5904-477c-9a1d-4ef752e21613.png?v=1774337996"},"price":{"amount":350.0,"currencyCode":"USD"},"sku":"MINT25","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"8580142694538","handle":"revitin-toothpaste-travel-3-tubes","isCollective":null,"title":"Citrus Travel 3-Pack of 1oz","type":null,"untranslatedTitle":"Citrus Travel 3-Pack of 1oz","url":"\/products\/revitin-toothpaste-travel-3-tubes","vendor":"Revitin","remoteShopId":null,"variants":[{"id":"46346187341962","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Travel_Size_Citrus.png?v=1774338377"},"price":{"amount":18.0,"currencyCode":"USD"},"sku":"CitrTravel3-pk","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"8658322555018","handle":"citrus-travel-case-100-count","
723isCollective":null,"title":"Citrus Travel Case (100 count)","type":null,"untranslatedTitle":"Citrus Travel Case (100 count)","url":"\/products\/citrus-travel-case-100-count","vendor":"Revitin","remoteShopId":null,"variants":[{"id":"46994967527562","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Travel_Size_Citrus.png?v=1774338377"},"price":{"amount":300.0,"currencyCode":"USD"},"sku":"CITRUSTRAVEL100","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"8580143349898","handle":"revitin-toothpaste-travel-3-tubes-1","isCollective":null,"title":"Mint Travel 3-Pack of 1oz","type":null,"untranslatedTitle":"Mint Travel 3-Pack of 1oz","url":"\/products\/revitin-toothpaste-travel-3-tubes-1","vendor":"Revitin","remoteShopId":null,"variants":[{"id":"46346189045898","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Travel_Size_Mint.png?v=1774338342"},"price":{"amount":18.0,"currencyCode":"USD"},"sku":"MintTravel3-pk","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"8658320261258","handle":"mint-travel-case-100-count","isCollective":null,"title":"Mint Travel Case (100 count)","type":null,"untranslatedTitle":"Mint Travel Case (100 count)","url":"\/products\/mint-travel-case-100-count","vendor":"Revitin","remoteShopId":null,"variants":[{"id":"46994955272330","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Travel_Size_Mint.png?v=1774338342"},"price":{"amount":300.0,"currencyCode":"USD"},"sku":"MINTTRAVEL100","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"6803929432202","handle":"replacement-adult-brush-head","isCollective":null,"title":"Replacement Adult Brush Head","type":"Toothbrush Replacement Heads","untranslatedTitle":"Replacement Adult Brush Head","url":"\/products\/replacement-adult-brush-head","vendor":"Revitin","remoteShopId":null,"variants":[{"id":"40896700186762","image":{"src":"\/\/revitin.com\/cdn\/shop\/products\/ReplacementHead.png?v=1662485289"},"price":{"amount":5.5,"currencyCode":"USD"},"sku":"R-H6W-RH","title":"Default Title","untranslatedTitle":"Default Title"}]},{"id":"6606431617162","handle":"revitin-natural-toothpaste-fullcase-25tubes","isCollective":null,"title":"Revitin Toothpaste (25 Tubes)","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (25 Tubes)","url":"\/products\/revitin-natural-toothpaste-fullcase-25tubes","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"39792313729162","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_75330201-6111-4242-bac7-eb4703f1b300.png?v=1774338517"},"price":{"amount":350.0,"currencyCode":"USD"},"sku":"CITRUS25","title":"Default Title","untranslatedTitle":"Default Title"}]},{"id":"8335794307210","handle":"revitin-toothpaste-25-tubes-wholesale","isCollective":null,"title":"Revitin Toothpaste (25 Tubes) Wholesale","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (25 Tubes) Wholesale","url":"\/products\/revitin-toothpaste-25-tubes-wholesale","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45628453814410","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_75330201-6111-4242-bac7-eb4703f1b300.png?v=1774338517"},"price":{"amount":212.5,"currencyCode":"USD"},"sku":"CITRUS25","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"8335801548938","handle":"revitin-toothpaste-25-tubes-wholesale-mint","isCollective":null,"title":"Revitin Toothpaste (25 Tubes) Wholesale","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste (25 Tubes) Wholesale","url":"\/products\/revitin-toothpaste-25-tubes-wholesale-mint","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"45628533604490","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_1318037a-3b7a-4e15-84c3-e22323a5e8cc.png?v=1774337830"},"price":{"amount":212.5,"currencyCode":"USD"},"sku":"MINT25","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"8332405899402","handle":"citrus-mint-4-tubes","isCollective":null,"title":"Revitin Toothpaste Variety 3 Tubes","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste Variety 3 Tubes","url":"\/products\/citrus-mint-4-tubes","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"46765298909322","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Variety_2citrus1mint.png?v=1774338212"},"price":{"amount":46.0,"currencyCode":"USD"},"sku":"VARIETYPACK2C-1M","title":"Citrus","untranslatedTitle":"Citrus"}]},{"id":"8645075763338","handle":"variety-pack-2-mint-1-citrus","isCollective":null,"title":"Revitin Toothpaste Variety 3 Tubes","type":"Toothpaste","untranslatedTitle":"Revitin Toothpaste Variety 3 Tubes","url":"\/products\/variety-pack-2-mint-1-citrus","vendor":"Revitin® Natural Toothpaste","remoteShopId":null,"variants":[{"id":"46765283049610","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Variety_1citrus2mint.png?v=1774338246"},"price":{"amount":46.0,"currencyCode":"USD"},"sku":"VARIETYPACK2M-1C","title":"Mint","untranslatedTitle":"Mint"}]},{"id":"8909392904330","handle":"variety-travel-4-pack-of-1-oz","
723isCollective":null,"title":"Variety Travel 4-Pack of 1 oz","type":null,"untranslatedTitle":"Variety Travel 4-Pack of 1 oz","url":"\/products\/variety-travel-4-pack-of-1-oz","vendor":"Revitin","remoteShopId":null,"variants":[{"id":"47799599759498","image":{"src":"\/\/revitin.com\/cdn\/shop\/files\/revitin2.png?v=1777964527"},"price":{"amount":24.0,"currencyCode":"USD"},"sku":"VarietyTravel4-pk","title":"Default Title","untranslatedTitle":"Default Title"}]}],"purchasingCompany":null},},"https://revitin.com/cdn","fff817eew048894c6p0347dc4em7b2d6332",{"modern":"","legacy":""},{"trekkieShim":true,"agentContext":true,"apiClientId":"580111","facebookCapiEnabled":"false","themeId":"153996034186","themePublished":"true","eventMetadataId":"f364b3b5-3c8e-4542-9bbb-e44c411d0b91","pageType":"product","resourceId":"6606432174218","shopId":"37689720970","storefrontBaseUrl":"https:\/\/revitin.com","extensionBaseUrl":"https:\/\/extensions.shopifycdn.com\/cdn\/shopifycloud\/web-pixels-manager","surface":"storefront-renderer","enabledBetaFlags":"[\"4c64608a\", \"16072cab\", \"8450a54b\", \"7ee89bf1\"]","isMerchantRequest":"false","hashVersion":"fff817eew048894c6p0347dc4em7b2d6332","publish":"custom","events":"[[\"page_viewed\",{}],[\"product_viewed\",{\"productVariant\":{\"price\":{\"amount\":17.0,\"currencyCode\":\"USD\"},\"product\":{\"title\":\"Revitin Toothpaste Single Tube\",\"vendor\":\"Revitin® Natural Toothpaste\",\"id\":\"6606432174218\",\"untranslatedTitle\":\"Revitin Toothpaste Single Tube\",\"url\":\"\/products\/revitin-natural-toothpaste\",\"type\":\"Toothpaste\"},\"id\":\"45594631471242\",\"image\":{\"src\":\"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551\"},\"sku\":\"CITRUS1\",\"title\":\"Citrus\",\"untranslatedTitle\":\"Citrus\"}}]]"});})();</script>
723<script>
724  window.ShopifyAnalytics = window.ShopifyAnalytics || {};
725  window.ShopifyAnalytics.meta = window.ShopifyAnalytics.meta || {};
726  window.ShopifyAnalytics.meta.currency = 'USD';
727  var meta = {"product":{"id":6606432174218,"gid":"gid:\/\/shopify\/Product\/6606432174218","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","handle":"revitin-natural-toothpaste","variants":[{"id":45594631471242,"price":1700,"name":"Revitin Toothpaste Single Tube - Citrus","public_title":"Citrus","sku":"CITRUS1"}],"remote":false},"page":{"pageType":"product","resourceType":"product","resourceId":6606432174218,"requestId":"92b14f4a-92cf-4ca7-868f-2d3322189ab5-1790777238"}};
728  for (var attr in meta) {
729    window.ShopifyAnalytics.meta[attr] = meta[attr];
730  }
731</script>
vendor: 1 bytes, line 731
731
732<script class="analytics">
733  (function () {
734    var customDocumentWrite = function(content) {
735      var jquery = null;
736
737      if (window.jQuery) {
738        jquery = window.jQuery;
739      } else if (window.Checkout && window.Checkout.$) {
740        jquery = window.Checkout.$;
741      }
742
743      if (jquery) {
744        jquery('body').append(content);
745      }
746    };
747
748    var hasLoggedConversion = function(token) {
749      if (token) {
750        return document.cookie.indexOf('loggedConversion=' + token) !== -1;
751      }
752      return false;
753    }
754
755    var setCookieIfConversion = function(token) {
756      if (token) {
757        var twoMonthsFromNow = new Date(Date.now());
758        twoMonthsFromNow.setMonth(twoMonthsFromNow.getMonth() + 2);
759
760        document.cookie = 'loggedConversion=' + token + '; expires=' + twoMonthsFromNow;
761      }
762    }
763
764    var trekkie = window.ShopifyAnalytics.lib = window.trekkie = window.trekkie || [];
765    window.ShopifyAnalytics.lib.trekkie = window.trekkie;
766    if (trekkie.integrations) {
767      return;
768    }
769    trekkie.methods = [
770      'identify',
771      'page',
772      'ready',
773      'track',
774      'trackForm',
775      'trackLink'
776    ];
777    trekkie.factory = function(method) {
778      return function() {
779        var args = Array.prototype.slice.call(arguments);
780        args.unshift(method);
781        trekkie.push(args);
782        if (method == 'track' || method == 'page') {
783          var pageUrl;
784          try {
785            pageUrl = window.location.href;
786          } catch (e) {}
787          var pageReferrer;
788          try {
789            pageReferrer = document.referrer;
790          } catch (e) {}
791          try {
792            if (window.__TREKKIE_SHIM_QUEUE == null) {
793              window.__TREKKIE_SHIM_QUEUE = [];
794            }
795            window.__TREKKIE_SHIM_QUEUE.push({
796              from: 'trekkie-stub',
797              method: method,
798              args: args.slice(1),
799              pageContext: {
800                url: pageUrl,
801                referrer: pageReferrer
802              }
803            });
804          } catch (e) {
805            // no-op
806          }
807        }
808        return trekkie;
809      };
810    };
811    for (var i = 0; i < trekkie.methods.length; i++) {
812      var key = trekkie.methods[i];
813      trekkie[key] = trekkie.factory(key);
814    }
815    trekkie.load = function(config) {
816      trekkie.config = config || {};
817      trekkie.config.initialDocumentCookie = document.cookie;
818      var first = document.getElementsByTagName('script')[0];
819var script = document.createElement('script');
820script.type = 'text/javascript';
821script.onerror = function(e) {
822  var scriptFallback = document.createElement('script');
823  scriptFallback.type = 'text/javascript';
824  scriptFallback.onerror = function(error) {
825          var Monorail = {
826      produce: function produce(monorailDomain, schemaId, payload) {
827        var currentMs = new Date().getTime();
828        var event = {
829          schema_id: schemaId,
830          payload: payload,
831          metadata: {
832            event_created_at_ms: currentMs,
833            event_sent_at_ms: currentMs
834          }
835        };
836        return Monorail.sendRequest("https://" + monorailDomain + "/v1/produce", JSON.stringify(event));
837      },
838      sendRequest: function sendRequest(endpointUrl, payload) {
839        // Try the sendBeacon API
840        if (window && window.navigator && typeof window.navigator.sendBeacon === 'function' && typeof window.Blob === 'function' && !Monorail.isIos12()) {
841          var blobData = new window.Blob([payload], {
842            type: 'text/plain'
843          });
844
845          if (window.navigator.sendBeacon(endpointUrl, blobData)) {
846            return true;
847          } // sendBeacon was not successful
848
849        } // XHR beacon
850
851        var xhr = new XMLHttpRequest();
852
853        try {
854          xhr.open('POST', endpointUrl);
855          xhr.setRequestHeader('Content-Type', 'text/plain');
856          xhr.send(payload);
857        } catch (e) {
858          console.log(e);
859        }
860
861        return false;
862      },
863      isIos12: function isIos12() {
864        return window.navigator.userAgent.lastIndexOf('iPhone; CPU iPhone OS 12_') !== -1 || window.navigator.userAgent.lastIndexOf('iPad; CPU OS 12_') !== -1;
865      }
866    };
867    Monorail.produce('monorail-edge.shopifysvc.com',
868      'trekkie_storefront_load_errors/1.1',
869      {shop_id: 37689720970,
870      theme_id: 153996034186,
871      app_name: "storefront",
872      context_url: window.location.href,
873      source_url: "//revitin.com/cdn/s/trekkie.storefront.f1ba865b3fecd812ad617f74ac079261075e9edb.min.js"});
874
875  };
876  scriptFallback.async = true;
877  scriptFallback.src = '//revitin.com/cdn/s/trekkie.storefront.f1ba865b3fecd812ad617f74ac079261075e9edb.min.js';
878  first.parentNode.insertBefore(scriptFallback, first);
879};
880script.async = true;
881script.src = '//revitin.com/cdn/s/trekkie.storefront.f1ba865b3fecd812ad617f74ac079261075e9edb.min.js';
882first.parentNode.insertBefore(script, first);
883
884    };
885    trekkie.load(
886      {"Trekkie":{"appName":"storefront","development":false,"defaultAttributes":{"shopId":37689720970,"isMerchantRequest":null,"themeId":153996034186,"themeCityHash":"10361271689453374424","contentLanguage":"en","currency":"USD","eventMetadataId":"f364b3b5-3c8e-4542-9bbb-e44c411d0b91"},"isServerSideCookieWritingEnabled":true,"monorailRegion":"shop_domain","enabledBetaFlags":["764d78cb","8450a54b","7ee89bf1","4c64608a"]},"Session Attribution":{},"S2S":{"facebookCapiEnabled":false,"source":"trekkie-storefront-renderer","apiClientId":580111}}
887    );
888
889    var loaded = false;
890    trekkie.ready(function() {
891      if (loaded) return;
892      loaded = true;
893
894      window.ShopifyAnalytics.lib = window.trekkie;
895
896      var originalDocumentWrite = document.write;
897      document.write = customDocumentWrite;
898      try { window.ShopifyAnalytics.merchantGoogleAnalytics.call(this); } catch(error) {};
899      document.write = originalDocumentWrite;
900
901      var match = window.location.pathname.match(/checkouts\/(.+)\/(thank_you|post_purchase)/)
902      var token = match? match[1]: undefined;
903      if (!hasLoggedConversion(token)) {
904        setCookieIfConversion(token);
905        window.ShopifyAnalytics.lib.track("Viewed Product",{"currency":"USD","variantId":45594631471242,"productId":6606432174218,"productGid":"gid:\/\/shopify\/Product\/6606432174218","name":"Revitin Toothpaste Single Tube - Citrus","price":"17.00","sku":"CITRUS1","brand":"Revitin® Natural Toothpaste","variant":"Citrus","category":"Toothpaste","nonInteraction":true,"remote":false,"available":true},undefined,undefined,{"shopifyEmitted":true});
906      }
907    });
908
909    window.ShopifyAnalytics.lib.page(null,{"pageType":"product","resourceType":"product","resourceId":6606432174218,"requestId":"92b14f4a-92cf-4ca7-868f-2d3322189ab5-1790777238","shopifyEmitted":true});
910
911    var eventsListenerScript = document.createElement('script');
912    eventsListenerScript.async = true;
913    eventsListenerScript.src = "//revitin.com/cdn/shopifycloud/storefront/assets/shop_events_listener-4e26a9ce.js";
914    document.getElementsByTagName('head')[0].appendChild(eventsListenerScript);
915})();</script>
915
916  
916<script>
917  if (!window.ga || (window.ga && typeof window.ga !== 'function')) {
918    window.ga = function ga() {
919      (window.ga.q = window.ga.q || []).push(arguments);
920      if (window.Shopify && window.Shopify.analytics && typeof window.Shopify.analytics.publish === 'function') {
921        window.Shopify.analytics.publish("ga_stub_called", {}, {sendTo: "google_osp_migration"});
922      }
923      console.error("Shopify's Google Analytics stub called with:", Array.from(arguments), "\nSee https://help.shopify.com/manual/promoting-marketing/pixels/pixel-migration#google for more information.");
924    };
925    if (window.Shopify && window.Shopify.analytics && typeof window.Shopify.analytics.publish === 'function') {
926      window.Shopify.analytics.publish("ga_stub_initialized", {}, {sendTo: "google_osp_migration"});
927    }
928  }
929</script>
vendor: 1 bytes, line 929
929
930<script
931  defer
932  src="https://revitin.com/cdn/shopifycloud/perf-kit/shopify-perf-kit-3.9.4.min.js"
933  data-application="storefront-renderer"
934  data-shop-id="37689720970"
935  data-render-region="gcp-europe-west1"
936  data-page-type="product"
937  data-theme-instance-id="153996034186"
938  data-theme-name="Dawn"
939  data-theme-version="6.0.2"
940  data-monorail-region="shop_domain"
941  data-resource-timing-sampling-rate="10"
942  data-shs="true"
943  data-shs-beacon="true"
944  data-shs-export-with-fetch="true"
945  data-shs-logs-sample-rate="1"
946  data-shs-beacon-endpoint="https://revitin.com/api/collect"
947></script>
947
948<meta name="shopify-y" content="6c0774b0-a6f5-4fff-857b-ac1e66466252" data-expiration="1822334838000"><meta name="shopify-s" content="61d8c39a-13e1-4425-ae2e-b617443c286f" data-expiration="1790779038000"><meta name="new-cookie-storage-activated" content="t">
949</head><body
950    class="pt-[6px] bg-light-tan text-sm lg:text-[0.9375rem]"
951    data-gwp-enabled="false"
952  >
953    <main>
954      <div class="fixed top-0 left-0 right-0 z-40 border-[3px] border-olive rounded-md"></div>
955      <div id="shopify-section-announcement" class="shopify-section"><section style="display: none;">
956  
957    <div class="announcement text-center text-brown">
958      <p><a href="https://revitin.com/products/revitin-natural-toothpaste/Citrus" title="Revitin Travel Size">New Product Drop: Travel Size is Here</a></p>
959    </div>
960  
961</section>
962
963<style> #shopify-section-announcement .announcement {background-color: #ffdea3;} #shopify-section-announcement .announcement p {padding-top: 0; padding-bottom: 0;} #shopify-section-announcement .announcement a {text-decoration: none; display: block; padding-top: 0.5rem; padding-bottom: 0.5rem;} </style></div>
964      
965        <header id="shopify-section-header" class="shopify-section"><div class="site-header w-full max-w-none transition-all duration-500 ease-in-out text-primary bg-light-tan rounded-b-lg">
966  <section>
967      <div class="announcement text-center text-brown flex items-center justify-center">
968        <p><a href="https://revitin.com/products/revitin-natural-toothpaste/Mint" title="https://revitin.com/products/revitin-natural-toothpaste/Mint">Subscribe & Get Free Shipping on Every Order</a></p>
969        
970          
971        
972      </div>
973    
974  </section>
975  <mobile-menu>
976    <div class="h-16 lg:h-20 flex items-center lg:block">
977      <div class="h-full site-container grid items-center transition-all grid-cols-4">
978        <button id="hamburger-icon" class="md:hidden">
979          <span>
980            <svg width="22" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg">
981              <g fill="#5F471D" fill-rule="evenodd">
982                <rect y="3" width="26" height="2" rx="1"/>
983                <rect y="12" width="26" height="2" rx="1"/>
984                <rect y="21" width="26" height="2" rx="1"/>
985              </g>
986            </svg>
987          </span>
988          <span>
989            <svg
990              class="relative left-[1px]"
991              width="20"
992              viewBox="0 0 20 20"
993              fill="none"
994              xmlns="http://www.w3.org/2000/svg"
995            >
996              <rect x="1.51471" y="0.100586" width="26" height="2" rx="1" transform="rotate(45 1.51471 0.100586)" fill="#5F471D" />
997              <rect x="0.100525" y="18.4854" width="26" height="2" rx="1" transform="rotate(-45 0.100525 18.4854)" fill="#5F471D" />
998            </svg>
999          </span>
1000        </button>
1001        
1002          <nav class="hidden items-center gap-8 md:flex">
1003            
1004              <div class="shop-dropdown">
1005                <a href=/products/revitin-natural-toothpaste/Mint>
1006                  <div class="shop-dropdown-trigger flex items-center gap-2">
1007                    Shop
1008                    <svg xmlns="http://www.w3.org/2000/svg" width="10" height="7" viewBox="0 0 10 7" fill="none">
1009                      <path d="M1.39036 0.421997L4.82215 3.7439L7.97438 0.539985L9.13896 1.7067L5.42193 5.48438L4.86098 6.0755L4.85086 6.06481L4.84096 6.07574L4.23631 5.4703L0.254501 1.6172L1.39036 0.421997Z" fill="#5F471D"/>
1010                    </svg>
1011                  </div>
1012                </a>
1013                <div class="shop-dropdown-content">
1014                  <div class="gap__box"></div>
1015                  <div class="flex gap-2">
1016                    
1017                      <div class="shop-dropdown-item">
1018                        <a href="/products/revitin-natural-toothpaste/Citrus">
1019                          <img
1020                            src="//revitin.com/cdn/shop/files/full-size.png?v=1759475549"
1021                            srcset="
1022                              //revitin.com/cdn/shop/files/full-size_400x.png?v=1759475549 400w,
1023                              //revitin.com/cdn/shop/files/full-size_800x.png?v=1759475549 800w,
1024                              //revitin.com/cdn/shop/files/full-size_1200x.png?v=1759475549 1200w,
1025                              //revitin.com/cdn/shop/files/full-size_1600x.png?v=1759475549 1600w,
1026                              //revitin.com/cdn/shop/files/full-size_2000x.png?v=1759475549 2000w
1027                            "
1028                            sizes="100vw"
1029                            alt="Full Size Toothpaste"
1030                            loading="lazy"
1031                            class="responsive-img"
1032                          >
1033                          <span class="dropdown-link-title">Full Size Toothpaste</span>
1034                        </a>
1035                      </div>
1036                    
1037
1038                    
1039                      <div class="shop-dropdown-item">
1040                        <a href="/products/revitin-natural-toothpaste/Citrus?size=travel">
1041                          <img
1042                            src="//revitin.com/cdn/shop/files/travel-size_1200x.png?v=1759475549"
1043                            alt="Travel Size Toothpaste"
1044                          >
1045                          <span class="dropdown-link-title">Travel Size Toothpaste</span>
1046                        </a>
1047                      </div>
1048                    
1049                  </div>
1050                </div>
1051              </div>
1052            
1053            
1054              
1055                
1056              
1057            
1058              
1059                <a class="lg:hover:opacity-70 transition-opacity duration-300" href="/pages/about">About</a>
1060              
1061            
1062              
1063                <a class="lg:hover:opacity-70 transition-opacity duration-300" href="/pages/ingredients">Ingredients</a>
1064              
1065            
1066          </nav>
1067        
1068        <div class="col-span-2">
1069          <a href="/" class="flex justify-center relative z-20">
1070            <div class="w-[120px] lg:w-[140px]">
1071              <svg
1072                xmlns="http://www.w3.org/2000/svg"
1073                x="0"
1074                y="0"
1075                viewBox="0 0 504 232.3"
1076                style="enable-background:new 0 0 504 232.3"
1077                xml:space="preserve"
1078                fill="currentColor"
1079              >
1080                <path d="M132.33 157.14c0 1.5-1.12 2.24-3.24 2.24h-10.72c-3.86 0-5.85-1.62-8.35-4.61l-30.78-36.14v30.28c0 5.36 6.23 4.36 6.23 8.47 0 1-.87 1.99-2.49 1.99H60.79c-1.62 0-2.49-1-2.49-1.99 0-3.61 6.36-2.99 6.36-8.47V82.36c0-5.36-6.36-4.36-6.36-8.47 0-1 1-1.99 2.49-1.99h29.79c24.42 0 35.89 9.22 35.89 23.68 0 11.84-8.35 21.44-32.28 22.93 3.12.87 5.24 2.37 7.23 4.49l20.81 23.93c5.74 6.47 10.1 6.47 10.1 10.21zm-53.09-44.37c2.37.37 5.11.5 7.6.5 16.07 0 23.68-5.86 23.68-17.07 0-11.46-6.6-18.32-23.43-18.32h-3.86c-2.62 0-3.99 1.37-3.99 3.61v31.28zM131.8 129.35c0-18.57 11.96-31.53 29.17-31.53 15.58 0 24.8 10.59 24.8 21.56 0 5.24-1.99 6.98-5.86 6.98h-35.64c.38 15.08 8.85 23.43 21.56 23.43 12.09 0 16.07-7.85 19.32-7.85 1.24 0 1.87 1.25.99 3.49-3.37 9.1-12.34 15.45-24.67 15.45-16.7 0-29.67-11.97-29.67-31.53zm37.02-8.85c2.37 0 3.62-1.12 3.62-3.37 0-6.98-3.37-13.58-12.46-13.58-8.6 0-14.83 5.86-15.57 16.95h24.41zM250.55 100.81c0 2.37-4.86 4.48-7.1 10.09l-19.19 46.36c-1.12 2.49-3.12 3.62-5.23 3.62-2.12 0-4.12-1.12-5.11-3.62l-19.07-46.23c-2.49-5.74-7.23-7.85-7.23-10.09 0-1 .75-1.62 2.12-1.62h22.56c1.24 0 1.87.63 1.87 1.5 0 2.37-5.36 3.74-5.36 7.98 0 1 .25 1.99.74 3.24l12.71 33.4 13.34-33.28c.5-1.37.74-2.37.74-3.49 0-3.99-4.86-5.86-4.86-7.98 0-.87.63-1.37 1.87-1.37h15.45c1.13-.01 1.75.62 1.75 1.49zM255.02 157.26c0-3.24 5.73-2.99 5.73-6.35v-36.27c0-4.49-6.85-3.24-6.85-6.85 0-1 .74-1.87 1.99-2.49l13.71-6.85c2.74-1.37 4.49-.38 4.49 2.24v50.22c0 3.36 5.6 3.11 5.6 6.35 0 1.12-1.12 2.12-2.62 2.12H257.5c-1.48 0-2.48-1-2.48-2.12zm1.37-77.51c0-5.11 4.24-9.35 9.48-9.35 5.11 0 9.34 4.24 9.34 9.35 0 5.24-4.23 9.47-9.34 9.47-5.24 0-9.48-4.24-9.48-9.47zM295.13 145.42v-37.39c0-2.24-1.24-3.49-3.49-3.49h-4.24c-3.24 0-4.24-2.74-1.62-4.86l18.44-15.08c2.12-1.87 4.24-1 4.24 1.87v12.84h18.7c1.49 0 2.24.75 2.24 2.12v1.74c0 1.37-.75 2.12-2.24 2.12h-18.7v40c0 5.49 2.37 7.6 7.98 7.6 5.11 0 7.85-1.37 9.47-1.37 1.12 0 1.62.62 1.62 1.49 0 3.49-8.6 7.85-17.57 7.85-9.34.02-14.83-4.6-14.83-15.44zM334.38 157.26c0-3.24 5.73-2.99 5.73-6.35v-36.27c0-4.49-6.85-3.24-6.85-6.85 0-1 .75-1.87 1.99-2.49l13.71-6.85c2.74-1.37 4.49-.38 4.49 2.24v50.22c0 3.36 5.61 3.11 5.61 6.35 0 1.12-1.12 2.12-2.62 2.12h-19.57c-1.49 0-2.49-1-2.49-2.12zm1.37-77.51c0-5.11 4.24-9.35 9.47-9.35 5.11 0 9.35 4.24 9.35 9.35 0 5.24-4.24 9.47-9.35 9.47a9.47 9.47 0 0 1-9.47-9.47zM432.44 157.26c0 1.12-.87 2.12-2.49 2.12h-19.57c-1.62 0-2.49-1-2.49-2.12 0-3.12 5.6-2.99 5.6-5.98v-30.91c0-9.59-2.99-12.96-10.71-12.96-4.49 0-9.6 1-15.58 3.74v40.13c0 2.74 5.61 2.87 5.61 5.98 0 1.12-.87 2.12-2.49 2.12h-19.69c-1.62 0-2.49-1-2.49-2.12 0-2.99 5.61-3.12 5.61-5.98v-36.51c0-4.61-6.73-3.62-6.73-6.85 0-.87.75-1.75 1.99-2.49l13.71-6.98c2.12-1.25 4.49-.62 4.49 2.24v5.36c7.85-4.98 17.45-8.22 24.93-8.22 9.97 0 14.7 5.73 14.7 16.08v37.39c-.01 2.72 5.6 2.97 5.6 5.96z"/>
1081                <path d="M447.66 76.53c.75.08 1.52.07 2.26.26.42.11.85.15 1.26.28.63.2 1.26.44 1.88.7.48.2.95.42 1.39.69.6.36 1.19.74 1.74 1.18.58.46 1.12.96 1.64 1.48.63.64 1.2 1.34 1.65 2.12.35.6.72 1.19 1.01 1.82.48 1.01.84 2.06 1.05 3.16.12.61.23 1.21.26 1.83.01.2.02.39.04.59.01.01.02.03.02.04v1.08c-.01.01-.02.03-.03.04-.02.88-.13 1.75-.32 2.61-.22.98-.53 1.92-.93 2.84-.45 1.03-1.01 1.99-1.71 2.87-.41.52-.84 1.04-1.3 1.51-.69.7-1.44 1.35-2.29 1.87-.6.37-1.21.74-1.84 1.05-.52.26-1.08.45-1.63.65-.45.16-.91.29-1.37.4-.4.1-.8.14-1.2.22-1.01.19-2.03.16-3.05.14-.42-.01-.84-.08-1.26-.15-.56-.09-1.12-.18-1.66-.34-.73-.22-1.45-.47-2.15-.77-.49-.21-.96-.49-1.42-.75-.39-.23-.78-.47-1.15-.72-.32-.22-.62-.46-.91-.72-.32-.28-.65-.56-.94-.87-.68-.7-1.31-1.44-1.84-2.26-.41-.63-.78-1.27-1.1-1.96-.34-.75-.66-1.51-.84-2.32-.16-.72-.31-1.43-.44-2.15-.04-.22-.03-.46-.05-.68l-.03-.48c0-.08 0-.15.01-.23v-.97c.06-.58.08-1.17.19-1.74.15-.78.33-1.55.57-2.31.2-.64.49-1.25.78-1.85.43-.9.98-1.72 1.59
1081-2.51.5-.65 1.05-1.25 1.66-1.8.55-.49 1.15-.95 1.76-1.37.48-.33.99-.6 1.5-.89.63-.35 1.3-.63 1.99-.84.45-.14.9-.27 1.36-.37.57-.12 1.15-.22 1.73-.3.35-.05.7-.06 1.05-.08.08-.01.15-.01.23-.02h.63c.06.01.13.01.21.02zm12.37 14.07c-.01-.03-.02-.05-.02-.08 0-.16.01-.33-.01-.49-.06-.45-.13-.89-.23-1.33-.12-.53-.23-1.07-.41-1.58-.23-.63-.51-1.24-.8-1.84-.2-.42-.43-.83-.69-1.21-.35-.5-.75-.96-1.13-1.44-.48-.6-1.07-1.1-1.67-1.57-.67-.53-1.37-.99-2.15-1.34-.58-.27-1.17-.54-1.77-.74a12.57 12.57 0 0 0-3.44-.62c-.04-.01-.08-.02-.11-.03-.04 0-.08 0-.11.01h-.78c-.06.01-.13.01-.19.02-.18.01-.36.02-.53.04-.61.08-1.23.12-1.83.28-.76.2-1.5.46-2.23.75-.72.29-1.4.69-2.04 1.13-.88.61-1.68 1.31-2.39 2.11-.55.61-1.03 1.27-1.45 1.97-.5.82-.9 1.7-1.19 2.61-.33 1.01-.55 2.05-.59 3.1-.04.83-.01 1.66.07 2.49.06.64.23 1.28.39 1.91.32 1.21.85 2.33 1.51 3.38.42.67.89 1.3 1.45 1.87.46.46.93.93 1.43 1.34.71.58 1.48 1.09 2.32 1.47.58.26 1.17.53 1.78.73.65.21 1.32.35 2 .48.4.08.81.08 1.22.11.01 0 .03 0 .04-.01h1.38c.01 0 .03 0 .04.01.21-.01.43 0 .64-.04.62-.11 1.24-.24 1.85-.37.7-.15 1.36-.42 2.01-.71.72-.32 1.41-.7 2.06-1.15.76-.52 1.47-1.11 2.08-1.81.46-.53.93-1.07 1.33-1.66.36-.53.65-1.11.95-1.69.36-.7.61-1.44.8-2.19.21-.83.37-1.68.4-2.54.01-.03.01-.05.02-.08v-1.27c-.01 0-.01-.01-.01-.02zM432.4 90.6v.34c.01-.12 0-.23 0-.34z"/><path class="st0" d="M432.41 91.57c0 .08 0 .15-.01.23 0-.08.01-.16.01-.23zM446.8 76.51c-.08.01-.15.01-.23.02.08-.01.15-.01.23-.02zM447.66 76.53c-.08-.01-.15-.02-.23-.02.08.01.15.01.23.02zM461.86 90.67a.076.076 0 0 1-.02-.04c0 .02.01.03.02.04zM461.84 91.8c.01-.01.02-.03.03-.04-.02.01-.02.03-.03.04zM447.7 78.36h-.11v-.03c.03.01.07.02.11.03zM446.69 78.35c-.06.01-.13.01-.19.02.06-.01.12-.02.19-.02zM460.01 91.98v-.08h.02c-.01.03-.02.06-.02.08zM460 90.6c0-.03 0-.05.01-.08.01.03.02.05.02.08H460zM447.58 78.33v.03c-.04-.01-.08-.02-.12-.02.05 0 .08 0 .12-.01zM446.84 78.34h-.08.08zM460 90.6h.03v.04c-.01-.02-.02-.03-.03-.04z"/><path class="st0" d="M460.03 91.91h-.02c.01-.01.02-.03.03-.04-.01.01-.01.02-.01.04zM446.42 104.13c.01 0 .03 0 .04-.01-.01.01-.02.01-.04.01zM447.84 104.13c.01 0 .03 0 .04.01-.01-.01-.02-.01-.04-.01zM447.73 83.5c.03.01.07.03.1.03.8 0 1.57.12 2.31.41.85.33 1.59.82 2.09 1.62.35.56.56 1.16.62 1.81.04.45.07.91.03 1.35-.06.71-.25 1.39-.68 1.99-.53.77-1.24 1.29-2.09 1.66-.01 0-.02.02-.04.04.12.24.25.49.38.73l1.17 2.16c.52.97 1.05 1.94 1.57 2.91.12.21.23.43.34.65.01.03.01.07.01.11l-.03.03c-.95 0-1.89 0-2.84-.01-.01-.01-.02-.02-.03-.02-.19-.36-.38-.73-.58-1.09-.16-.31-.33-.61-.49-.91-.3-.57-.6-1.15-.89-1.72-.29-.55-.58-1.1-.86-1.65-.09-.17-.18-.35-.26-.52-.01-.01-.02-.02-.03-.02-.58 0-1.17-.01-1.75-.01-.4 0-.8.01-1.19.01l-.03.03v.14c0 .04-.01.
108109-.01.13v5.36c0 .04.01.09.01.13 0 .05-.01.1-.01.15-.01.01-.02.02-.04.03h-2.61l-.03-.03c0-.06-.01-.12-.01-.19V83.72c0-.08-.07-.22.11-.22.06.01.11.02.17.02h5.34c.04 0 .07-.01.11-.01h.1c.01-.02.02-.02.04-.01zm-3.16 7.32.03.03h2.99c.16-.01.34.01.49-.04.35-.11.69-.24 1.02-.4.49-.23.78-.65.95-1.14.18-.5.19-1.02.12-1.54-.07-.5-.24-.95-.6-1.3-.53-.51-1.18-.7-1.9-.72-.01-.01-.03-.01-.04-.02-1.01 0-2.02 0-3.03-.01l-.03.03v.37c0 .07-.01.14-.01.2v4.12c0 .07.01.14.01.2v.22zM447.59 83.48c-.04 0-.07.01-.11.01h-5.34c-.06 0-.11-.01-.17-.02.06-.01.12-.02.18-.02h5.24c.07 0 .13.02.2.03z"/><path class="st0" d="M444.56 98.83c0-.04-.01-.09-.01-.13v-5.36c0-.04.01-.09.01-.13.01.06.03.12.03.18v5.26c0 .06-.02.12-.03.18zM444.57 93.07l.03-.03-.03.03zM447.54 93.05c.01.01.02.02.03.02-.01-.01-.02-.02-.03-.02zM447.73 83.5c-.01 0-.02-.01-.03-.01 0 0 .01 0 .03.01zM441.87 98.98l.03.03c-.01-.02-.02-.03-.03-.03zM444.51 99c.01-.01.02-.02.04-.03-.01.02-.02.03-.04.03zM450.66 98.97c.01.01.02.02.03.02-.01 0-.02-.01-.03-.02zM453.53 99l.03-.03-.03.03zM444.56 86.07c.01.05.03.11.03.16v4.21c0 .05-.02.11-.03.16 0-.07-.01-.14-.01-.2v-4.12c0-.07.01-.14.01-.21zM444.57 90.82l.03.03-.03-.03zM447.54 90.85h.04-.04zM447.66 85.7c-.01-.01-.03-.01-.04-.02.01 0 .03.01.04.02zM444.59 85.67l-.03.03c.02-.01.02-.02.03-.03z"/>
1082              </svg>
1083            </div>
1084          </a>
1085        </div>
1086        <div class="mobile-menu fixed top-[92px] left-0 w-full h-screen z-20 text-primary bg-light-tan opacity-0 invisible transition-all duration-500 ease py-8 pt-5">
1087  <nav style="padding-left: 0px; padding-right: 0px;" class="site-container grid content-start pt-4">
1088    
1089      <a href="/products/revitin-natural-toothpaste/Mint" class="button button--light-green mx-auto">
1090    
1091      Shop Toothpaste
1092    </a>
1093    <img
1094        class="w-full h-full nav-menu-bg-img"
1095        src="//revitin.com/cdn/shop/t/129/assets/nav-menu-bg.jpg?v=89763950694445791721777542404"
1096        alt=""
1097        width="1200px"
1098        height="1200px"
1099      >
1100    <div class="border-b border-primary grid content-start gap-8 pt-8 pb-8 px-3">
1101      <div class="grid content-start gap-4">
1102        
1103          
1104            
1105              <a href="https://revitin.com/products/revitin-natural-toothpaste/Citrus" class="flex justify-between items-center">
1106            
1107          
1108            <div class="text-primary heading-2">Revitin Toothpaste</div>
1109            <svg
1110  width="17"
1111  height="13"
1112  viewBox="0 0 17 13"
1113  fill="none"
1114  xmlns="http://www.w3.org/2000/svg">
1115  <path
1116    d="M1.39474 6.5H15.6053"
1117    stroke="#5F471D"
1118    stroke-width="1.5"
1119    stroke-linecap="round" />
1120  <path
1121    d="M10 1L15.5 6.5"
1122    stroke="#5F471D"
1123    stroke-width="1.5"
1124    stroke-linecap="round" />
1125  <path
1126    d="M10 12L15.5 6.5"
1127    stroke="#5F471D"
1128    stroke-width="1.5"
1129    stroke-linecap="round" />
1130</svg>
1131          </a>
1132        
1133          
1134            <a href="/pages/about" class="flex justify-between items-center">
1135          
1136            <div class="text-primary heading-2">About Us</div>
1137            <svg
1138  width="17"
1139  height="13"
1140  viewBox="0 0 17 13"
1141  fill="none"
1142  xmlns="http://www.w3.org/2000/svg">
1143  <path
1144    d="M1.39474 6.5H15.6053"
1145    stroke="#5F471D"
1146    stroke-width="1.5"
1147    stroke-linecap="round" />
1148  <path
1149    d="M10 1L15.5 6.5"
1150    stroke="#5F471D"
1151    stroke-width="1.5"
1152    stroke-linecap="round" />
1153  <path
1154    d="M10 12L15.5 6.5"
1155    stroke="#5F471D"
1156    stroke-width="1.5"
1157    stroke-linecap="round" />
1158</svg>
1159          </a>
1160        
1161          
1162            <a href="/pages/ingredients" class="flex justify-between items-center">
1163          
1164            <div class="text-primary heading-2">Ingredients</div>
1165            <svg
1166  width="17"
1167  height="13"
1168  viewBox="0 0 17 13"
1169  fill="none"
1170  xmlns="http://www.w3.org/2000/svg">
1171  <path
1172    d="M1.39474 6.5H15.6053"
1173    stroke="#5F471D"
1174    stroke-width="1.5"
1175    stroke-linecap="round" />
1176  <path
1177    d="M10 1L15.5 6.5"
1178    stroke="#5F471D"
1179    stroke-width="1.5"
1180    stroke-linecap="round" />
1181  <path
1182    d="M10 12L15.5 6.5"
1183    stroke="#5F471D"
1184    stroke-width="1.5"
1185    stroke-linecap="round" />
1186</svg>
1187          </a>
1188        
1189          
1190            <a href="/pages/about/#meet-dr-gerry" class="flex justify-between items-center">
1191          
1192            <div class="text-primary heading-2">Meet Dr. Gerry</div>
1193            <svg
1194  width="17"
1195  height="13"
1196  viewBox="0 0 17 13"
1197  fill="none"
1198  xmlns="http://www.w3.org/2000/svg">
1199  <path
1200    d="M1.39474 6.5H15.6053"
1201    stroke="#5F471D"
1202    stroke-width="1.5"
1203    stroke-linecap="round" />
1204  <path
1205    d="M10 1L15.5 6.5"
1206    stroke="#5F471D"
1207    stroke-width="1.5"
1208    stroke-linecap="round" />
1209  <path
1210    d="M10 12L15.5 6.5"
1211    stroke="#5F471D"
1212    stroke-width="1.5"
1213    stroke-linecap="round" />
1214</svg>
1215          </a>
1216        
1217      </div>
1218    </div>
1219    <div class="grid content-start gap-3 pt-8 px-3">
1220      
1221        <a href="/pages/contact-us" class="flex justify-between items-center">
1222          <div class="text-primary text-lg">Contact Us</div>
1223        </a>
1224      
1225        <a href="/pages/wholesale" class="flex justify-between items-center">
1226          <div class="text-primary text-lg">Wholesale</div>
1227        </a>
1228      
1229        <a href="/account" class="flex justify-between items-center">
1230          <div class="text-primary text-lg">Account</div>
1231        </a>
1232      
1233        <a href="/blogs/all" class="flex justify-between items-center">
1234          <div class="text-primary text-lg">Blogs</div>
1235        </a>
1236      
1237    </div>
1238  </nav>
1239</div>
1240
1241<style>
1242  .nav-menu-bg-img {
1243    width: 100%;          
1244    height: 10rem;         
1245    display: block;
1246    object-fit: cover;     
1247    object-position: center;
1248    margin-top: 1rem;
1249  }
1250</style>
1251        <div class="md:flex md:justify-end md:gap-8">
1252          <nav class="hidden items-center gap-8 md:flex">
1253            <a href="/account" class="text-primary lg:hover:opacity-70 transition-opacity duration-300">Account</a>
1254          </nav>
1255          <cart-open>
1256            <div class="grid justify-end transition-all">
1257              <cart-toggle>
1258  <button id="cart-icon-bubble" class="group">
1259    <div class="flex items-center gap-1">
1260      <div class="lg:group-hover:opacity-70 transition-opacity duration-300">Cart</div>
1261      <div class="w-[30px] h-[30px] text-center relative mb-1">
1262        <span class="block text-white text-[0.8125rem] font-body-medium relative z-10 h-full grid items-center">
1263          <span class="relative top-[2px] -left-[2px] variety-cart-count [text-shadow:_0_1px_0_rgb(0_0_3_/_10%)]">0</span>
1264        </span>
1265        <img src="//revitin.com/cdn/shop/t/129/assets/citrus-logo.png?v=12133043602477412821777542404" alt="" class="absolute top-0 left-0 right-0 mx-auto h-full" />
1266      </div>
1267    </div>
1268  </button>
1269</cart-toggle>
1270
1271            </div>
1272          </cart-open>
1273        </div>
1274      </div>
1275    </div>
1276  </mobile-menu>
1277</div>
1278
1279<style>
1280    .countdown-container {
1281      display: flex !important;
1282      gap: 11px;
1283    }
1284
1285    .timer-container {
1286      padding: 0 !important;
1287    }
1288
1289    .timer {
1290      display: flex;
1291      flex-direction: column;
1292      padding: 4px 4px !important;
1293      border: 1px solid #5F471D;
1294      width: max-content;
1295      border-radius: 5px;
1296      gap: 2px;
1297    }
1298
1299    .timer .count{
1300      font-size: 1.4rem;
1301      line-height: 1 !important;
1302    }
1303
1304    .timer .text{
1305      font-size: 0.6rem;
1306      line-height: 1 !important;
1307    }
1308
1309    .announcement {
1310      background-color: #ffdea3;
1311      display: flex !important;
1312      gap: 1rem;
1313      padding: 4px !important;
1314    }
1315
1316    .announcement a {
1317      text-decoration: none;
1318      display: block;
1319      padding-top: 0.5rem;
1320      padding-bottom: 0.3rem;
1321    }
1322
1323    .gap__box {
1324     width: 100%;
1325      height: 28px;
1326      background: #ff000000;
1327      flex-shrink: 0;
1328
1329    }
1330
1331    .dropdown-link-title {
1332      display: inline-block;
1333      font-size: 15.73px;
1334      padding: 12px 12px;
1335      color: #5F471D;
1336    }
1337
1338    .shop-dropdown {
1339    position: relative;
1340    display: inline-block;
1341  }
1342  .shop-dropdown-content {
1343    display: none;
1344    position: absolute;
1345    background-color: #FFFBEF;
1346    top: 100%;
1347    left: 0;
1348    width: max-content;
1349    border-radius: 0px 0px 16px 16px;
1350    z-index: 1000;
1351    flex-direction: column;
1352  }
1353  .shop-dropdown:hover .shop-dropdown-content {
1354    display: flex;
1355    gap: 2px;
1356  }
1357  .shop-dropdown-item {
1358    text-align: center;
1359    flex: 1;
1360  }
1361  .shop-dropdown-item img {
1362    max-width: 17.1rem;
1363    min-width: 17rem;
1364  }
1365  .shop-dropdown-item a {
1366    display: block;
1367    color: #333;
1368    text-decoration: none;
1369    font-weight: 500;
1370  }
1371  .shop-dropdown-trigger {
1372    cursor: pointer;
1373    font-weight: 500;
1374  }
1375
1376  @media (max-width: 768px) {
1377    .announcement {
1378      flex-direction: column;
1379      gap: 0rem;
1380      padding: 0px 0px 10px 0px !important;
1381    }
1382  }
1383</style>
1384
1385<script>
1386  document.addEventListener('DOMContentLoaded', function () {
1387    const el = document.querySelector('[data-countdown-date]');
1388    const date = el?.dataset.countdownDate;
1389    const time = el?.dataset.countdownTime;
1390    if (!date || !time) return;
1391
1392    // Target EST datetime with proper timezone (America/New_York handles DST)
1393    const targetDate = new Date(`${date}T${time}:00`);
1394
1395    function updateCountdown() {
1396      const nowEST = new Date().toLocaleString('en-US', { timeZone: 'America/New_York' });
1397      const now = new Date(nowEST);
1398
1399      const distance = targetDate - now;
1400
1401      if (distance <= 0) {
1402        document.querySelector('.hours').textContent = '00';
1403        document.querySelector('.minutes').textContent = '00';
1404        document.querySelector('.seconds').textContent = '00';
1405        clearInterval(timer);
1406        return;
1407      }
1408
1409      const hours = Math.floor(distance / (1000 * 60 * 60));
1410      const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
1411      const seconds = Math.floor((distance % (1000 * 60)) / 1000);
1412
1413      document.querySelector('.hours').textContent = String(hours).padStart(2, '0');
1414      document.querySelector('.minutes').textContent = String(minutes).padStart(2, '0');
1415      document.querySelector('.seconds').textContent = String(seconds).padStart(2, '0');
1416    }
1417
1418    updateCountdown();
1419    const timer = setInterval(updateCountdown, 1000);
1420  });
1421</script>
1421
1422
1423<script>
1424  const header = document.querySelector('.site-header');
1425
1426  function handleScroll() {
1427    const scrollY = window.scrollY || window.pageYOffset;
1428
1429    if (scrollY >= 40) {
1430      header.classList.add('active');
1431    } else {
1432      header.classList.remove('active');
1433    }
1434  }
1435
1436  window.addEventListener('scroll', handleScroll);
1437</script>
1437
1438
1439
1440</header>
1441      
1442      
1443
1444
1445
1446
1447  <div class='easylockdown-content' style='display:none;'><section id="shopify-section-template--21146535100554__main" class="shopify-section product-section"><style>
1448  .jdgm-rev-widg__header {
1449    border-bottom: 1px solid;
1450  }
1451  .jdgm-review-widget .jdgm-rev-widg__title{
1452    font-family: Rza Trial !important;
1453    font-size: 1.875rem !important;
1454    line-height: 2.25rem !important;
1455    letter-spacing: -.025em !important;
1456  }
1457  .jdgm-widget a[role="button"]:not(.jdgm-star), .jdgm-form__fieldset input[type="submit"].jdgm-btn{
1458    border-radius: 5px !important;
1459    color: #5F471D;
1460    font-weight: 400;
1461    transition: all ease-in-out 0.3s;
1462    padding: 1rem 3rem;
1463    font-family: Basis Medium !important;
1464  }
1465  .jdgm-widget a[role="button"]:hover, .jdgm-form__fieldset input[type="submit"]:hover{
1466    border-color: #5F471D;
1467    color: #5F471D!important;
1468    background-color: transparent !important;
1469  }
1470  span.jdgm-star, .jdgm-rev-widg__summary .jdgm-rev-widg__summary-stars .jdgm-star, .jdgm-row-stars .jdgm-histogram .jdgm-star {
1471    font-size: 11px;
1472  }
1473  .jdgm-rev-widg__body .jdgm-rev__header span.jdgm-rev__rating {
1474    display: block;
1475  }
1476  .jdgm-rev-widg__body .jdgm-rev__timestamp{
1477    float: none;
1478  }
1479  .jdgm-rev__author{
1480    font-family: Basis Medium !important;
1481  }
1482  .jdgm-rev__body p{
1483    font-family: 'Open Sans', Verdana, sans-serif;
1484  }
1485  .jdgm-review-widget .jdgm-rev-widg, .jdgm-review-widget.jdgm-review-widget--small .jdgm-rev-widg, .jdgm-review-widget.jdgm-review-widget--medium .jdgm-rev-widg{
1486    padding-top: 50px;
1487    padding-left: 16px;
1488    padding-right: 16px;
1489  }
1490  span.jdgm-rev-widg__summary-average {
1491    font-size: 30px;
1492    line-height: 30px;
1493    font-family: Basis Medium;
1494  }
1495  .jdgm-rev-widg__summary-text {
1496    clear: both;
1497  }
1498  @media (min-width: 992px){
1499    span.jdgm-rev-widg__summary-average {
1500      float: left;
1501      padding-right: 10px;
1502      font-size: 37px;
1503      margin-bottom: 10px;
1504    }
1505    .jdgm-review-widget .jdgm-rev-widg{
1506      padding-top: 70px;
1507    }
1508    .jdgm-rev__body p {
1509      font-size: 20px;
1510    }
1511    .jdgm-rev-widg__reviews {
1512      display: grid;
1513      grid-template-columns: repeat(2, 1fr);
1514      gap: 30px;
1515    }
1516  }
1517</style>
1518<link href="//revitin.com/cdn/shop/t/129/assets/toothpaste-slider.css?v=57238974732765893061785235958" rel="stylesheet" type="text/css" media="all" />
1519<style>
1520  /* Custom Slider Styles */
1521  .slides-container {
1522    position: relative;
1523    width: 100%;
1524  }
1525  
1526  .slides-wrapper {
1527    height: 100%;
1528  }
1529  
1530  .slide {
1531    position: absolute;
1532    top: 0;
1533    left: 0;
1534    width: 100%;
1535    height: 100%;
1536    opacity: 0;
1537    transition: opacity 0.5s ease-in-out;
1538    pointer-events: none;
1539  }
1540  
1541  .slide.active {
1542    opacity: 1;
1543    position: relative;
1544    pointer-events: auto;
1545  }
1546  
1547  /* Progress Dots Styles - Exact Oura Style */
1548  .progress-slider-dots-wrapper {
1549    padding: 8px 0;
1550  }
1551  
1552  .progress-slider-dots {
1553    height: 12px;
1554  }
1555  
1556  .progress-slider-dot {
1557    position: relative;
1558    width: 10px;
1559    height: 10px;
1560    border-radius: 50%;
1561    border: 1.5px solid #5f471D;
1562    background: transparent;
1563    padding: 0;
1564    cursor: pointer;
1565    transition: all 0.3s ease;
1566    overflow: hidden;
1567  }
1568  
1569  /* Active dot becomes a pill */
1570  .progress-slider-dot.active {
1571    width: 52px;
1572    height: 10px;
1573    border-radius: 999px;
1574    border-color: #5f471D;
1575    background: transparent;
1576  }
1577  
1578  /* Progress fill inside the dot */
1579  .dot-progress {
1580    position: absolute;
1581    top: 0;
1582    left: 0;
1583    width: 0%;
1584    height: 100%;
1585    background: #5f471D;
1586    border-radius: inherit;
1587    z-index: 1;
1588    /* Smooth animation */
1589    animation: none;
1590  }
1591  
1592  /* Only show progress fill on active dots */
1593  .progress-slider-dot:not(.active) .dot-progress {
1594    display: none;
1595  }
1596  
1597  /* Dot hover effect */
1598  .progress-slider-dot:hover {
1599    transform: scale(1.1);
1600  }
1601
1602  .ts-variety-selector-btn {
1603    padding: 8px 16px 8px 8px;
1604  }
1605
1606  .ts_variety_tab_btn {
1607    background: #F5EEE0;
1608    border-radius: 25px;
1609    padding: 2px 4px;
1610  }
1611
1612  .ts_variety_tab_btn img {
1613    max-width: 2.5rem;
1614  }
1615
1616  .sticky-shop-now__btn:hover {
1617    background: #5f471D !important;
1618    color: #fff !important;
1619  }
1620
1621  /* Wholesale travel: match full-size (no fade transitions) */
1622  #pdp-container.ws-travel-no-transition [data-swap-flavor],
1623  #pdp-container.ws-travel-no-transition [data-swap-flavor] img,
1624  #pdp-container.ws-travel-no-transition .slide {
1625    transition: none !important;
1626  }
1627</style>
1628 
1629
1630
1631<div id="pdp-container" class="pdp-container pb-16 lg:pb-20">
1632<script>
1633  window.RevitinGalleryRight2 = {
1634    enabled: false,
1635    citrusRight: "",
1636    citrusRightMobile: ""
1637  };
1638</script>
1638
1639 <div class="relative pdp_slider_container">
1640  
1641  
1642<div
1643      data-swap-flavor="Citrus"
1644      class="opacity-0 relative z-10 !opacity-100 transition-opacity "
1645    >
1646      <div class="lg:hidden">
1647        <!-- Custom Slider -->
1648        <div class="custom-slider" data-slider-id="gallery_PneosD">
1649          <!-- Slides Container -->
1650          <div class="slides-container relative overflow-hidden rounded-2xl">
1651            <div class="slides-wrapper relative">
1652              <!-- Slide 1 -->
1653              <div class="slide active" data-index="0">
1654                <div class="aspect-square">
1655                  <img
1656                    class="w-full h-full object-cover mobile_main_variety_image"
1657                    src="//revitin.com/cdn/shop/files/citrus-gallery-render-mobile_13zon_1000x.jpg?v=1760614313"
1658                    loading="lazy"
1659                    alt=""
1660                  >
1661                </div>
1662              </div>
1663              
1664              <!-- Slide 2 -->
1665              <div class="slide" data-index="1">
1666                <div class="aspect-square">
1667                  <img
1668                    class="w-full h-full object-cover mobile_left_variety_image"
1669                    src="//revitin.com/cdn/shop/files/citrus-gallery-mobile-2_11zon_1000x.jpg?v=1729883824"
1670                    loading="lazy"
1671                    alt=""
1672                  >
1673                </div>
1674              </div>
1675              
1676              <!-- Slide 3 -->
1677              <div class="slide" data-index="2">
1678                <div class="aspect-square">
1679                  <img
1680                    class="w-full h-full object-cover mobile_right_variety_image"
1681                    src="//revitin.com/cdn/shop/files/citrus-gallery-mobile-3_11zon_1000x.jpg?v=1729883824"
1682                    loading="lazy"
1683                    alt=""
1684                  >
1685                    <img
1686                      style="display: none;"
1687                      class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl tote_bag_image_mobile"
1688                      src="//revitin.com/cdn/shop/t/129/assets/tote-bag-banner-mobile.jpg?v=140778272410589426611777542404"
1689                      alt="Free Tote Bag"
1690                    >
1691                </div>
1692              </div>
1693            </div>
1694          </div>
1695          
1696          <!-- Progress Dots Container -->
1697          <div class="progress-slider-dots-wrapper mt-6 mb-8">
1698            <div class="progress-slider-dots flex justify-center items-center gap-2">
1699              <!-- Dot 1 -->
1700              <button class="progress-slider-dot active" data-slide-index="0">
1701                <span class="dot-progress"></span>
1702              </button>
1703              
1704              <!-- Dot 2 -->
1705              <button class="progress-slider-dot" data-slide-index="1">
1706                <span class="dot-progress"></span>
1707              </button>
1708              
1709              <!-- Dot 3 -->
1710                <button class="progress-slider-dot" data-slide-index="2">
1711                <span class="dot-progress"></span>
1712              </button>
1713            </div>
1714          </div>
1715        </div>
1716      </div>
1717    </div>
1718  
1719<div
1720      data-swap-flavor="Mint"
1721      class="opacity-0 absolute top-0 left-0 w-full h-full object-cover object-center transition-opacity "
1722    >
1723      <div class="lg:hidden">
1724        <!-- Custom Slider -->
1725        <div class="custom-slider" data-slider-id="gallery_SNeidp">
1726          <!-- Slides Container -->
1727          <div class="slides-container relative overflow-hidden rounded-2xl">
1728            <div class="slides-wrapper relative">
1729              <!-- Slide 1 -->
1730              <div class="slide active" data-index="0">
1731                <div class="aspect-square">
1732                  <img
1733                    class="w-full h-full object-cover mobile_main_variety_image"
1734                    src="//revitin.com/cdn/shop/files/mint-gallery-render_13zon_1000x.jpg?v=1760614345"
1735                    loading="lazy"
1736                    alt=""
1737                  >
1738                </div>
1739              </div>
1740              
1741              <!-- Slide 2 -->
1742              <div class="slide" data-index="1">
1743                <div class="aspect-square">
1744                  <img
1745                    class="w-full h-full object-cover mobile_left_variety_image"
1746                    src="//revitin.com/cdn/shop/files/mint-gallery-mobile-2_11zon_1000x.jpg?v=1729883825"
1747                    loading="lazy"
1748                    alt=""
1749                  >
1750                </div>
1751              </div>
1752              
1753              <!-- Slide 3 -->
1754              <div class="slide" data-index="2">
1755                <div class="aspect-square">
1756                  <img
1757                    class="w-full h-full object-cover mobile_right_variety_image"
1758                    src="//revitin.com/cdn/shop/files/mint-gallery-mobile-3_11zon_1000x.jpg?v=1729883824"
1759                    loading="lazy"
1760                    alt=""
1761                  >
1762                    <img
1763                      style="display: none;"
1764                      class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl tote_bag_image_mobile"
1765                      src="//revitin.com/cdn/shop/t/129/assets/tote-bag-banner-mobile.jpg?v=140778272410589426611777542404"
1766                      alt="Free Tote Bag"
1767                    >
1768                </div>
1769              </div>
1770            </div>
1771          </div>
1772          
1773          <!-- Progress Dots Container -->
1774          <div class="progress-slider-dots-wrapper mt-6 mb-8">
1775            <div class="progress-slider-dots flex justify-center items-center gap-2">
1776              <!-- Dot 1 -->
1777              <button class="progress-slider-dot active" data-sli
1777de-index="0">
1778                <span class="dot-progress"></span>
1779              </button>
1780              
1781              <!-- Dot 2 -->
1782              <button class="progress-slider-dot" data-slide-index="1">
1783                <span class="dot-progress"></span>
1784              </button>
1785              
1786              <!-- Dot 3 -->
1787                <button class="progress-slider-dot" data-slide-index="2">
1788                <span class="dot-progress"></span>
1789              </button>
1790            </div>
1791          </div>
1792        </div>
1793      </div>
1794    </div>
1795  
1796</div>
1797
1798  <div class="site-container grid lg:grid-cols-[1.25fr_1fr] lg:gap-5">
1799    <div class="hidden lg:block">
1800      <div class="relative image_update_container">
1801        
1802        
1803<div
1804            data-swap-flavor="Citrus"
1805            class="opacity-0 relative z-10 !opacity-100 transition-opacity"
1806          >
1807            <div>
1808              <div class="aspect-[1.4] relative">
1809                <img
1810                  class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl main_variety_image"
1811                  src="//revitin.com/cdn/shop/files/citrus-gallery-render_12zon_1600x.jpg?v=1760509789"
1812                >
1813              </div>
1814              <div class="grid grid-cols-2 mt-5 gap-6">
1815                <div class="aspect-[0.8] relative">
1816                  <img
1817                    class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl left_variety_image"
1818                    src="//revitin.com/cdn/shop/files/citrus-gallery-2_11zon_1600x.jpg?v=1729881153"
1819                  >
1820                </div>
1821                <div class="aspect-[0.8] relative">
1822                  <img
1823                    class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl right_variety_image"
1824                    src="//revitin.com/cdn/shop/files/citrus-gallery-3_11zon_1600x.jpg?v=1751389467"
1825                  >
1826                  <img
1827                    style="display: none;"
1828                    class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl tote_bag_image"
1829                    src="//revitin.com/cdn/shop/t/129/assets/tote-bag-banner.jpg?v=134313350378901709861777542404"
1830                    alt="Free Tote Bag"
1831                  >
1832                </div>
1833              </div>
1834            </div>
1835          </div>
1836        
1837<div
1838            data-swap-flavor="Mint"
1839            class="opacity-0 absolute top-0 left-0 w-full h-full object-cover object-center transition-opacity"
1840          >
1841            <div>
1842              <div class="aspect-[1.4] relative">
1843                <img
1844                  class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl main_variety_image"
1845                  src="//revitin.com/cdn/shop/files/mint-render-gallery_12zon_1600x.jpg?v=1760510022"
1846                >
1847              </div>
1848              <div class="grid grid-cols-2 mt-5 gap-6">
1849                <div class="aspect-[0.8] relative">
1850                  <img
1851                    class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl left_variety_image"
1852                    src="//revitin.com/cdn/shop/files/mint-gallery-2_11zon_1600x.jpg?v=1751389546"
1853                  >
1854                </div>
1855                <div class="aspect-[0.8] relative">
1856                  <img
1857                    class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl right_variety_image"
1858                    src="//revitin.com/cdn/shop/files/mint-gallery-3_11zon_1600x.jpg?v=1729881153"
1859                  >
1860                  <img
1861                    style="display: none;"
1862                    class="absolute top-0 left-0 w-full h-full object-cover object-center rounded-2xl tote_bag_image"
1863                    src="//revitin.com/cdn/shop/t/129/assets/tote-bag-banner.jpg?v=134313350378901709861777542404"
1864                    alt="Free Tote Bag"
1865                  >
1866                </div>
1867              </div>
1868            </div>
1869          </div>
1870        
1871      </div>
1872    </div>
1873
1874    <div class="text-base lg:text-lg lg:my-24 lg:max-w-md lg:px-0 mx-auto">
1875      <div class="pdp-headline mb-4 grid gap-3">
1876        
1877        <h3 class="text-[1.5rem] lg:text-[1.75rem] main_pdp_size_heading">
1878          Revitin Natural Toothpaste
1879        </h3>
1880      </div>
1881
1882      <div style="display: block !important;" class="jdgm-widget jdgm-preview-badge mt-2 mb-2">
1883        <div style='display:none' class='jdgm-prev-badge' data-average-rating='4.54' data-number-of-reviews='869' data-number-of-questions='0'> <span class='jdgm-prev-badge__stars' data-score='4.54' tabindex='0' aria-label='4.54 stars' role='button'> <span class='jdgm-star jdgm--on'></span><span class='jdgm-star jdgm--on'></span><span class='jdgm-star jdgm--on'></span><span class='jdgm-star jdgm--on'></span><span class='jdgm-star jdgm--half'></span> </span> <span class='jdgm-prev-badge__text'> 869 reviews </span> </div>
1884      </div>
1885
1886      
1887        <div class="mb-6">
1888          <p>Promote a healthy balance of your oral ecology to support oral health and wellness for whiter teeth and fresher breath.</p>
1889        </div>
1890      
1891
1892      <div class="selection_btn_container pdp-size-selector">
1893        <div>
1894          <button class="size_selection_btn full-size-btn font-body-medium text-base lg:text-lg">Full Size</button>
1895        </div>
1896        <div>
1897          <button class="size_selection_btn travel-size-btn font-body-medium text-base lg:text-lg">Travel Size</button>
1898        </div>
1899      </div>
1900
1901      <div>
1902        
1903        <div class="full__size__container">
1903<script src="//revitin.com/cdn/shop/t/129/assets/web-components-product-form.js?v=118024866748551223521789645463" defer></script>
1903<style>
1904  .pos-rel {
1905    position: relative;
1906    top: 10px;
1907  }
1908
1909  .up {
1910    position: relative;
1911    top: -10px;
1912  }
1913
1914  @media screen and (max-width: 560px) {
1915    .pos-rel {
1916      position: relative;
1917      top: 4px;
1918    }
1919  }
1920</style>
1921
1922
1923
1924
1925
1926              
1927
1928            
1929
1930  
1931  
1932  
1933
1934  
1935  
1936
1937  
1938    
1939  
1940
1941 
1941<script type="application/json" id="product-variants-test">
1942    [{"id":6606432174218,"title":"Revitin Toothpaste Single Tube","handle":"revitin-natural-toothpaste","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e","published_at":"2024-10-16T06:49:11-04:00","created_at":"2021-08-06T06:37:22-04:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Toothpaste","wholesale"],"price":1700,"price_min":1700,"price_max":1700,"available":true,"price_varies":false,"compare_at_price":1700,"compare_at_price_min":1700,"compare_at_price_max":1700,"compare_at_price_varies":false,"variants":[{"id":45594631471242,"title":"Citrus","option1":"Citrus","option2":null,"option3":null,"sku":"CITRUS1","requires_shipping":true,"taxable":true,"featured_image":{"id":40562040373386,"product_id":6606432174218,"position":8,"created_at":"2026-03-24T03:32:29-04:00","updated_at":"2026-03-24T03:32:31-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551","variant_ids":[45594631471242]},"available":true,"name":"Revitin Toothpaste Single Tube - Citrus","public_title":"Citrus","options":["Citrus"],"price":1700,"weight":136,"compare_at_price":1700,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":31853180453002,"position":8,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-render-mobile_11zon.jpg?v=1742298905","\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/citrus-render.png?v=1751390073","\/\/revitin.com\/cdn\/shop\/files\/citrus-featured-mobile_11zon.jpg?v=1742298805","\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/main-grapefruit_90add639-f630-489f-9558-ad382aba44cc.png?v=1741690920","\/\/revitin.com\/cdn\/shop\/files\/10001.jpg?v=1742293659","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-render-mobile_11zon.jpg?v=1742298905","options":["Flavor"],"media":[{"alt":null,"id":28303268577418,"position":1,"preview_image":{"aspect_ratio":1.0,"height":1881,"width":1881,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-render-mobile_11zon.jpg?v=1742298905"},"aspect_ratio":1.0,"height":1881,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-render-mobile_11zon.jpg?v=1742298905","width":1881},{"alt":null,"id":28285089742986,"position":2,"preview_image":{"aspect_ratio":1.333,"height":1714,"width":2285,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467"},"aspect_ratio":1.333,"height":1714,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467","width":2285},{"alt":null,"id":28274202902666,"position":3,"preview_image":{"aspect_ratio":0.296,"height":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render.png?v=1751390073"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render.png?v=1751390073","width":560},{"alt":null,"id":28285201186954,"position":4,"preview_image":{"aspect_ratio":1.0,"height":1881,"width":188
19421,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured-mobile_11zon.jpg?v=1742298805"},"aspect_ratio":1.0,"height":1881,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured-mobile_11zon.jpg?v=1742298805","width":1881},{"alt":null,"id":28285089546378,"position":5,"preview_image":{"aspect_ratio":0.8,"height":1301,"width":1041,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467"},"aspect_ratio":0.8,"height":1301,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467","width":1041},{"alt":null,"id":29258749935754,"position":6,"preview_image":{"aspect_ratio":0.872,"height":825,"width":719,"src":"\/\/revitin.com\/cdn\/shop\/files\/main-grapefruit_90add639-f630-489f-9558-ad382aba44cc.png?v=1741690920"},"aspect_ratio":0.872,"height":825,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/main-grapefruit_90add639-f630-489f-9558-ad382aba44cc.png?v=1741690920","width":719},{"alt":null,"id":29315872293002,"position":7,"preview_image":{"aspect_ratio":1.333,"height":1500,"width":2000,"src":"\/\/revitin.com\/cdn\/shop\/files\/10001.jpg?v=1742293659"},"aspect_ratio":1.333,"height":1500,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/10001.jpg?v=1742293659","width":2000},{"alt":null,"id":31853180453002,"position":8,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551","width":4320}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e"},{"id":8334203355274,"title":"Revitin Toothpaste Single Tube","handle":"revitin-toothpaste-single-tube-mint","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e","published_at":"2026-05-20T10:37:39-04:00","created_at":"2024-10-24T17:20:10-04:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Toothpaste","wholesale"],"price":1700,"price_min":1700,"price_max":1700,"available":true,"price_varies":false,"compare_at_price":1700,"compare_at_price_min":1700,"compare_at_price_max":1700,"compare_at_price_varies":false,"variants":[{"id":45622706602122,"title":"Mint","option1":"Mint","option2":null,"option3":null,"sku":"MINT1","requires_shipping":true,"taxable":true,"featured_image":{"id":40562043945098,"product_id":8334203355274,"position":5,"created_at":"2026-03-24T03:33:11-04:00","updated_at":"2026-03-24T03:33:14-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_99a4be1b-921c-4bbc-96f1-3bc4d0999926.png?v=1774337594","variant_ids":[45622706602122]},"available":true,"name":"Revitin Toothpaste Single Tube - Mint","public_title":"Mint","options":["Mint"],"price":1700,"weight":136,"compare_at_price":1700,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":31853183565962,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_99a4be1b-921c-4bbc-96f1-3bc4d0999926.png?v=1774337594"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/mint-render.png?v=1751387541","\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_99a4be1b-921c-4bbc-96f1-3bc4d0999926.png?v=1774337594","\/\/revitin.com\/cdn\/shop\/files\/Screenshot_2026-05-13_at_4.25.54_PM.png?v=1778704121","\/\/revitin.com\/cdn\/shop\/files\/Screenshot_2026-05-13_at_4.33.10_PM.png?v=1778704398"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546","options":["Flavor"],"media":[{"alt":null,"id":28285089611914,"position":1,"preview_image":{"aspect_ratio":1.468,"height":1281,"width":188
19421,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546"},"aspect_ratio":1.468,"height":1281,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546","width":1881},{"alt":null,"id":28274203558026,"position":2,"preview_image":{"aspect_ratio":0.296,"height":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render.png?v=1751387541"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render.png?v=1751387541","width":560},{"alt":null,"id":28285089579146,"position":3,"preview_image":{"aspect_ratio":0.8,"height":1301,"width":1041,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546"},"aspect_ratio":0.8,"height":1301,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546","width":1041},{"alt":null,"id":28285089775754,"position":4,"preview_image":{"aspect_ratio":1.333,"height":1714,"width":2285,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546"},"aspect_ratio":1.333,"height":1714,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546","width":2285},{"alt":null,"id":31853183565962,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_99a4be1b-921c-4bbc-96f1-3bc4d0999926.png?v=1774337594"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_99a4be1b-921c-4bbc-96f1-3bc4d0999926.png?v=1774337594","width":4320},{"alt":null,"id":32312983978122,"position":6,"preview_image":{"aspect_ratio":1.101,"height":456,"width":502,"src":"\/\/revitin.com\/cdn\/shop\/files\/Screenshot_2026-05-13_at_4.25.54_PM.png?v=1778704121"},"aspect_ratio":1.101,"height":456,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Screenshot_2026-05-13_at_4.25.54_PM.png?v=1778704121","width":502},{"alt":null,"id":32313027166346,"position":7,"preview_image":{"aspect_ratio":0.672,"height":958,"width":644,"src":"\/\/revitin.com\/cdn\/shop\/files\/Screenshot_2026-05-13_at_4.33.10_PM.png?v=1778704398"},"aspect_ratio":0.672,"height":958,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Screenshot_2026-05-13_at_4.33.10_PM.png?v=1778704398","width":644}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e"},{"id":6606431420554,"title":"Revitin Toothpaste (3 Tubes)","handle":"revitin-natural-toothpaste-family-pack-3tubes","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e\n","published_at":"2024-10-16T06:50:24-04:00","created_at":"2021-08-06T06:33:37-04:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Toothpaste","wholesale"],"price":4600,"price_min":4600,"price_max":4600,"available":true,"price_varies":false,"compare_at_price":5100,"compare_at_price_min":5100,"compare_at_price_max":5100,"compare_at_price_varies":false,"variants":[{"id":45594633666698,"title":"Citrus","option1":"Citrus","option2":null,"option3":null,"sku":"CITRUS3","requires_shipping":true,"taxable":true,"featured_image":{"id":40538658177162,"product_id":6606431420554,"position":5,"created_at":"2026-03-19T07:40:34-04:00","updated_at":"2026-03-19T07:40:37-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus.png?v=1773920437","variant_ids":[45594633666698]},"available":true,"name":"Revitin Toothpaste (3 Tubes) - Citrus","public_title":"Citrus","options":["Citrus"],"price":4600,"weight":363,"compare_at_price":5100,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":3183
19421695982730,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus.png?v=1773920437"}},"requires_selling_plan":false,"selling_plan_allocations":[{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2436038794,"selling_plan_group_id":"5932612a299fdbcf90454d75cd44c2c3fb5726b3"},{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2435973258,"selling_plan_group_id":"2e26c9c13ed68026e86060667b90391f07cc0bff"},{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2436071562,"selling_plan_group_id":"699d3d748cc52413eab2420d291604b2288a92dc"},{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2436006026,"selling_plan_group_id":"a21da03fb770221fe1d8bd17d0add53d52d1cad7"}],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-1_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus.png?v=1773920437"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","options":["Flavor"],"media":[{"alt":null,"id":30027639292042,"position":1,"preview_image":{"aspect_ratio":0.296,"height":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","width":560},{"alt":null,"id":28285089644682,"position":2,"preview_image":{"aspect_ratio":1.468,"height":1281,"width":1881,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-1_11zon.jpg?v=1751389467"},"aspect_ratio":1.468,"height":1281,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-1_11zon.jpg?v=1751389467","width":1881},{"alt":null,"id":28285089546378,"position":3,"preview_image":{"aspect_ratio":0.8,"height":1301,"width":1041,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467"},"aspect_ratio":0.8,"height":1301,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467","width":1041},{"alt":null,"id":28285089742986,"position":4,"preview_image":{"aspect_ratio":1.333,"height":1714,"width":2285,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467"},"aspect_ratio":1.333,"height":1714,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467","width":2285},{"alt":null,"id":31831695982730,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus.png?v=1773920437"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus.png?v=1773920437","width":4320}],"requires_selling_plan":false,"selling_plan_groups":[{"id":"5932612a299fdbcf90454d75cd44c2c3fb5726b3","name":"Delivery every 1 month","options":[{"name":"Recharge Plan ID","position":1,"values":["17296259"]},{"name":"Order Frequency and Unit","position":2,"values":["1-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436038794,"name":"Delivery every 1 month","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296259"},{"name":"Order Frequency and Unit","position":2,"value":"1-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"2e26c9c13ed68026e86060667b90391f07cc0bff","name":"Delivery every 2 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296260"]},{"name":"Order Frequency and Unit","position":2,"values":["2-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2435973258,"name":"Delivery every 2 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296260"},{"name":"Order Frequency and Unit","position":2,"value":"2-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"699d3d748cc52413eab2420d291604b2288a92dc","name":"Delivery every 3 months","options":[{"name":"Recharge Plan ID","position":1,"values":["12148491"]},{"name":"Order Frequency and Unit","position":2,"values":["3-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436071562,"name":"Delivery every 3 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"12148491"},{"name":"Order Frequency and Unit","position":2,"value":"3-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"a21da03fb770221fe1d8bd17d0add53d52d1cad7","name":"Delivery every 6 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296261"]},{"name":"Order Frequency and Unit","position":2,"values":["6-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436006026,"name":"Delivery every 6 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296261"},{"name":"Order Frequency and Unit","position":2,"value":"6-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"}],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e\n"},{"id":8333322846346,"title":"Revitin Toothpaste (3 Tubes)","handle":"revitin-toothpaste-3-tubes-mint","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e","published_at":"2024-10-23T11:54:51-04:00","created_at":"2024-10-23T11:52:39-04:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Toothpaste","wholesale"],"price":4600,"price_min":4600,"price_max":4600,"available":true,"price_varies":false,"compare_at_price":5100,"compare_at_price_min":5100,"compare_at_price_max":5100,"compare_at_price_varies":false,"variants":[{"id":45618606080138,"title":"Mint","option1":"Mint","option2":null,"option3":null,"sku":"MINT3","requires_shipping":true,"taxable":true,"featured_image":{"id":40558673756298,"product_id":8333322846346,"position":5,"created_at":"2026-03-23T12:22:23-04:00","updated_at":"2026-03-23T12:22:26-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint.png?v=1774282946","variant_ids":[45618606080138]},"available":true,"name":"Revitin Toothpaste (3 Tubes) - Mint","public_title":"Mint","options":["Mint"],"price":4600,"weight":363,"compare_at_price":5100,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":31850726850698,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint.png?v=1774282946"}},"requires_selling_plan":false,"selling_plan_allocations":[{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2436497546,"selling_plan_group_id":"5932612a299fdbcf90454d75cd44c2c3fb5726b3"},{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2436300938,"selling_plan_group_id":"2e26c9c13ed68026e86060667b90391f07cc0bff"},{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2436530314,"selling_plan_group_id":"699d3d748cc52413eab2420d291604b2288a92dc"},{"price_adjustments":[{"position":1,"price":4200}],"price":4200,"compare_at_price":4600,"per_delivery_price":4200,"selling_plan_id":2436563082,"selling_plan_group_id":"a21da03fb770221fe1d8bd17d0add53d52d1cad7"}],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint.png?v=1774282946"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","options":["Flavor"],"media":[{"alt":null,"id":30027583029386,"position":1,"preview_image":{"aspect_ratio":0.296,"he
1942ight":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","width":560},{"alt":null,"id":28285089611914,"position":2,"preview_image":{"aspect_ratio":1.468,"height":1281,"width":1881,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546"},"aspect_ratio":1.468,"height":1281,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546","width":1881},{"alt":null,"id":28285089579146,"position":3,"preview_image":{"aspect_ratio":0.8,"height":1301,"width":1041,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546"},"aspect_ratio":0.8,"height":1301,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546","width":1041},{"alt":null,"id":28285089775754,"position":4,"preview_image":{"aspect_ratio":1.333,"height":1714,"width":2285,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546"},"aspect_ratio":1.333,"height":1714,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546","width":2285},{"alt":null,"id":31850726850698,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint.png?v=1774282946"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint.png?v=1774282946","width":4320}],"requires_selling_plan":false,"selling_plan_groups":[{"id":"5932612a299fdbcf90454d75cd44c2c3fb5726b3","name":"Delivery every 1 month","options":[{"name":"Recharge Plan ID","position":1,"values":["17296246"]},{"name":"Order Frequency and Unit","position":2,"values":["1-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436497546,"name":"Delivery every 1 month","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296246"},{"name":"Order Frequency and Unit","position":2,"value":"1-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"2e26c9c13ed68026e86060667b90391f07cc0bff","name":"Delivery every 2 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296247"]},{"name":"Order Frequency and Unit","position":2,"values":["2-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436300938,"name":"Delivery every 2 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296247"},{"name":"Order Frequency and Unit","position":2,"value":"2-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"699d3d748cc52413eab2420d291604b2288a92dc","name":"Delivery every 3 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296248"]},{"name":"Order Frequency and Unit","position":2,"values":["3-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436530314,"name":"Delivery every 3 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296248"},{"name":"Order Frequency and Unit","position":2,"value":"3-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"a21da03fb770221fe1d8bd17d0add53d52d1cad7","name":"Delivery every 6 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296249"]},{"name":"Order Frequency and Unit","position":2,"values":["6-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436563082,"name":"Delivery every 6 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296249"},{"name":"Order Frequency and Unit","position":2,"value":"6-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"8.69"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"}],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e"},{"id":7609245171850,"title":"Revitin Toothpaste (5 Tubes)","handle":"revitin-toothpaste-5-tubes","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e","published_at":"2024-10-16T06:49:01-04:00","created_at":"2022-12-09T17:51:22-05:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Subscription","Toothpaste","wholesale"],"price":7000,"price_min":7000,"price_max":7000,"available":true,"price_varies":false,"compare_at_price":8500,"compare_at_price_min":8500,"compare_at_price_max":8500,"compare_at_price_varies":false,"variants":[{"id":45594652901514,"title":"Citrus","option1":"Citrus","option2":null,"option3":null,"sku":"CITRUS5","requires_shipping":true,"taxable":true,"featured_image":{"id":40562055217290,"product_id":7609245171850,"position":5,"created_at":"2026-03-24T03:35:02-04:00","updated_at":"2026-03-24T03:35:05-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e9fa6364-9bfe-4cd7-b0af-1a95d93ee5ba.png?v=1774337705","variant_ids":[45594652901514]},"available":true,"name":"Revitin Toothpaste (5 Tubes) - Citrus","public_title":"Citrus","options":["Citrus"],"price":7000,"weight":136,"compare_at_price":8500,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":31853193199754,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e9fa6364-9bfe-4cd7-b0af-1a95d93ee5ba.png?v=1774337705"}},"requires_selling_plan":false,"selling_plan_allocations":[{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436137098,"selling_plan_group_id":"5932612a299fdbcf90454d75cd44c2c3fb5726b3"},{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436104330,"selling_plan_group_id":"2e26c9c13ed68026e86060667b90391f07cc0bff"},{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436202634,"selling_plan_group_id":"699d3d748cc52413eab2420d291604b2288a92dc"},{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436169866,"selling_plan_group_id":"a21da03fb770221fe1d8bd17d0add53d52d1cad7"}],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-1_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e9fa6364-9bfe-4cd7-b0af-1a95d93ee5ba.png?v=1774337705"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","options":["Flavor"],"media":[{"alt":null,"id":30027639292042,"position":1,"preview_image":{"aspect_ratio":0.296,"he
1942ight":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","width":560},{"alt":null,"id":28285089644682,"position":2,"preview_image":{"aspect_ratio":1.468,"height":1281,"width":1881,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-1_11zon.jpg?v=1751389467"},"aspect_ratio":1.468,"height":1281,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-1_11zon.jpg?v=1751389467","width":1881},{"alt":null,"id":28285089546378,"position":3,"preview_image":{"aspect_ratio":0.8,"height":1301,"width":1041,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467"},"aspect_ratio":0.8,"height":1301,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-gallery-3_11zon.jpg?v=1751389467","width":1041},{"alt":null,"id":28285089742986,"position":4,"preview_image":{"aspect_ratio":1.333,"height":1714,"width":2285,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467"},"aspect_ratio":1.333,"height":1714,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-featured_11zon.jpg?v=1751389467","width":2285},{"alt":null,"id":31853193199754,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e9fa6364-9bfe-4cd7-b0af-1a95d93ee5ba.png?v=1774337705"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_e9fa6364-9bfe-4cd7-b0af-1a95d93ee5ba.png?v=1774337705","width":4320}],"requires_selling_plan":false,"selling_plan_groups":[{"id":"5932612a299fdbcf90454d75cd44c2c3fb5726b3","name":"Delivery every 1 month","options":[{"name":"Recharge Plan ID","position":1,"values":["17296263"]},{"name":"Order Frequency and Unit","position":2,"values":["1-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436137098,"name":"Delivery every 1 month","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296263"},{"name":"Order Frequency and Unit","position":2,"value":"1-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"2e26c9c13ed68026e86060667b90391f07cc0bff","name":"Delivery every 2 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296264"]},{"name":"Order Frequency and Unit","position":2,"values":["2-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436104330,"name":"Delivery every 2 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296264"},{"name":"Order Frequency and Unit","position":2,"value":"2-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"699d3d748cc52413eab2420d291604b2288a92dc","name":"Delivery every 3 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296265"]},{"name":"Order Frequency and Unit","position":2,"values":["3-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436202634,"name":"Delivery every 3 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296265"},{"name":"Order Frequency and Unit","position":2,"value":"3-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"a21da03fb770221fe1d8bd17d0add53d52d1cad7","name":"Delivery every 6 months","options":[{"name":"Recharge Plan ID","position":1,"values":["17296266"]},{"name":"Order Frequency and Unit","position":2,"values":["6-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436169866,"name":"Delivery every 6 months","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296266"},{"name":"Order Frequency and Unit","position":2,"value":"6-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"}],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e"},{"id":8333359808650,"title":"Revitin Toothpaste (5 Tubes)","handle":"revitin-toothpaste-5-tubes-mint","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e","published_at":"2024-10-23T12:06:34-04:00","created_at":"2024-10-23T12:06:35-04:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Subscription","Toothpaste","wholesale"],"price":7000,"price_min":7000,"price_max":7000,"available":true,"price_varies":false,"compare_at_price":8500,"compare_at_price_min":8500,"compare_at_price_max":8500,"compare_at_price_varies":false,"variants":[{"id":45618689310858,"title":"Mint","option1":"Mint","option2":null,"option3":null,"sku":"MINT5","requires_shipping":true,"taxable":true,"featured_image":{"id":40562064162954,"product_id":8333359808650,"position":5,"created_at":"2026-03-24T03:35:53-04:00","updated_at":"2026-03-24T03:35:56-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_37b5d288-2b5a-42a4-bd87-71596a6bf4b4.png?v=1774337756","variant_ids":[45618689310858]},"available":true,"name":"Revitin Toothpaste (5 Tubes) - Mint","public_title":"Mint","options":["Mint"],"price":7000,"weight":136,"compare_at_price":8500,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":31853201653898,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_37b5d288-2b5a-42a4-bd87-71596a6bf4b4.png?v=1774337756"}},"requires_selling_plan":false,"selling_plan_allocations":[{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436333706,"selling_plan_group_id":"c0f50a62bfd9e3ac72834b6fb633f35bd3c14993"},{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436399242,"selling_plan_group_id":"7071418883f10d584b0e3b2e54d3b89463db3f25"},{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436366474,"selling_plan_group_id":"8f901073b4a7857c567b4d2de0c8c025f5fa5274"},{"price_adjustments":[{"position":1,"price":6800}],"price":6800,"compare_at_price":7000,"per_delivery_price":6800,"selling_plan_id":2436595850,"selling_plan_group_id":"13abe440ede87c4bd3a6b9bac60769eb374fc963"}],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_37b5d288-2b5a-42a4-bd87-71596a6bf4b4.png?v=1774337756"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","options":["Flavor"],"media":[{"alt":null,"id":30027583029386,"position":1,"preview_image":{"aspect_ratio":0.296,"he
1942ight":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","width":560},{"alt":null,"id":28285089611914,"position":2,"preview_image":{"aspect_ratio":1.468,"height":1281,"width":1881,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546"},"aspect_ratio":1.468,"height":1281,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-1_11zon.jpg?v=1751389546","width":1881},{"alt":null,"id":28285089579146,"position":3,"preview_image":{"aspect_ratio":0.8,"height":1301,"width":1041,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546"},"aspect_ratio":0.8,"height":1301,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-gallery-2_11zon.jpg?v=1751389546","width":1041},{"alt":null,"id":28285089775754,"position":4,"preview_image":{"aspect_ratio":1.333,"height":1714,"width":2285,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546"},"aspect_ratio":1.333,"height":1714,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-featured_11zon.jpg?v=1751389546","width":2285},{"alt":null,"id":31853201653898,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_37b5d288-2b5a-42a4-bd87-71596a6bf4b4.png?v=1774337756"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_37b5d288-2b5a-42a4-bd87-71596a6bf4b4.png?v=1774337756","width":4320}],"requires_selling_plan":false,"selling_plan_groups":[{"id":"c0f50a62bfd9e3ac72834b6fb633f35bd3c14993","name":"Delivery every 1 month with 17.65% discount","options":[{"name":"Recharge Plan ID","position":1,"values":["17296301"]},{"name":"Order Frequency and Unit","position":2,"values":["1-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436333706,"name":"Delivery every 1 month with 17.65% discount","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296301"},{"name":"Order Frequency and Unit","position":2,"value":"1-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"7071418883f10d584b0e3b2e54d3b89463db3f25","name":"Delivery every 2 months with 17.65% discount","options":[{"name":"Recharge Plan ID","position":1,"values":["17296302"]},{"name":"Order Frequency and Unit","position":2,"values":["2-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436399242,"name":"Delivery every 2 months with 17.65% discount","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296302"},{"name":"Order Frequency and Unit","position":2,"value":"2-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"},{"id":"8f901073b4a7857c567b4d2de0c8c025f5fa5274","name":"Delivery every 3 months with 17.65% discount","options":[{"name":"Recharge Plan ID","position":1,"values":["17296303"]},{"name":"Order Frequency and Unit","position":2,"values":["3-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436366474,"name":"Delivery every 3 months with 17.65% discount","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296303"},{"name":"Order Frequency and Unit","position":2,"value":"3-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"}
1942,{"id":"13abe440ede87c4bd3a6b9bac60769eb374fc963","name":"Delivery every 6 months with 17.65% discount","options":[{"name":"Recharge Plan ID","position":1,"values":["17296304"]},{"name":"Order Frequency and Unit","position":2,"values":["6-month"]},{"name":"Product Quantity","position":3,"values":["0"]}],"selling_plans":[{"id":2436595850,"name":"Delivery every 6 months with 17.65% discount","description":null,"options":[{"name":"Recharge Plan ID","position":1,"value":"17296304"},{"name":"Order Frequency and Unit","position":2,"value":"6-month"},{"name":"Product Quantity","position":3,"value":"0"}],"recurring_deliveries":true,"price_adjustments":[{"order_count":null,"position":1,"value_type":"percentage","value":"2.86"}],"checkout_charge":{"value_type":"percentage","value":100}}],"app_id":"294517"}],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e"},{"id":7890501009546,"title":"Revitin Toothpaste (25 Tubes)","handle":"copy-of-revitin-toothpaste-25-tubes-gm","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e","published_at":"2024-10-16T06:49:40-04:00","created_at":"2024-01-24T12:24:11-05:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Max25","Toothpaste","wholesale"],"price":35000,"price_min":35000,"price_max":35000,"available":true,"price_varies":false,"compare_at_price":42500,"compare_at_price_min":42500,"compare_at_price_max":42500,"compare_at_price_varies":false,"variants":[{"id":45594657161354,"title":"Citrus","option1":"Citrus","option2":null,"option3":null,"sku":"CITRUS25","requires_shipping":true,"taxable":true,"featured_image":{"id":40562095194250,"product_id":7890501009546,"position":5,"created_at":"2026-03-24T03:40:59-04:00","updated_at":"2026-03-24T03:41:02-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_5dd0e011-ff5d-4356-80a8-debbb8fbaa63.png?v=1774338062","variant_ids":[45594657161354]},"available":true,"name":"Revitin Toothpaste (25 Tubes) - Citrus","public_title":"Citrus","options":["Citrus"],"price":35000,"weight":2939,"compare_at_price":42500,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":31853227442314,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_5dd0e011-ff5d-4356-80a8-debbb8fbaa63.png?v=1774338062"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901","\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901","\/\/revitin.com\/cdn\/shop\/files\/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_5dd0e011-ff5d-4356-80a8-debbb8fbaa63.png?v=1774338062"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","options":["Flavor"],"media":[{"alt":null,"id":30027639292042,"position":1,"preview_image":{"aspect_ratio":0.296,"he
1942ight":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/citrus-render_cream_bg.png?v=1751390073","width":560},{"alt":null,"id":25983153111178,"position":2,"preview_image":{"aspect_ratio":1.0,"height":500,"width":500,"src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901"},"aspect_ratio":1.0,"height":500,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901","width":500},{"alt":"Full Case (25 Tubes)","id":25983153143946,"position":3,"preview_image":{"aspect_ratio":1.0,"height":650,"width":650,"src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901"},"aspect_ratio":1.0,"height":650,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901","width":650},{"alt":null,"id":25983153275018,"position":4,"preview_image":{"aspect_ratio":1.0,"height":960,"width":960,"src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901"},"aspect_ratio":1.0,"height":960,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901","width":960},{"alt":null,"id":31853227442314,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_5dd0e011-ff5d-4356-80a8-debbb8fbaa63.png?v=1774338062"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Citrus_5dd0e011-ff5d-4356-80a8-debbb8fbaa63.png?v=1774338062","width":4320}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e"},{"id":8334207778954,"title":"Revitin Toothpaste (25 Tubes)","handle":"revitin-toothpaste-25-tubes-mint","description":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e","published_at":"2024-10-24T17:33:44-04:00","created_at":"2024-10-24T17:33:44-04:00","vendor":"Revitin® Natural Toothpaste","type":"Toothpaste","tags":["Max25","Toothpaste","wholesale"],"price":35000,"price_min":35000,"price_max":35000,"available":true,"price_varies":false,"compare_at_price":42500,"compare_at_price_min":42500,"compare_at_price_max":42500,"compare_at_price_varies":false,"variants":[{"id":45622715121802,"title":"Mint","option1":"Mint","option2":null,"option3":null,"sku":"MINT25","requires_shipping":true,"taxable":true,"featured_image":{"id":40562091294858,"product_id":8334207778954,"position":5,"created_at":"2026-03-24T03:39:53-04:00","updated_at":"2026-03-24T03:39:56-04:00","alt":null,"width":4320,"height":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_5fc8e8a0-5904-477c-9a1d-4ef752e21613.png?v=1774337996","variant_ids":[45622715121802]},"available":true,"name":"Revitin Toothpaste (25 Tubes) - Mint","public_title":"Mint","options":["Mint"],"price":35000,"weight":2939,"compare_at_price":42500,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":31853224460426,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_5fc8e8a0-5904-477c-9a1d-4ef752e21613.png?v=1774337996"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901","\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901","\/\/revitin.com\/cdn\/shop\/files\/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901","\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_5fc8e8a0-5904-477c-9a1d-4ef752e21613.png?v=1774337996"],"featured_image":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","options":["Flavor"],"media":[{"alt":null,"id":30027583029386,"position":1,"preview_image":{"aspect_ratio":0.296,"he
1942ight":1890,"width":560,"src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753"},"aspect_ratio":0.296,"height":1890,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/mint-render_cream_bg.png?v=1751389753","width":560},{"alt":null,"id":25983153111178,"position":2,"preview_image":{"aspect_ratio":1.0,"height":500,"width":500,"src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901"},"aspect_ratio":1.0,"height":500,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901","width":500},{"alt":"Full Case (25 Tubes)","id":25983153143946,"position":3,"preview_image":{"aspect_ratio":1.0,"height":650,"width":650,"src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901"},"aspect_ratio":1.0,"height":650,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901","width":650},{"alt":null,"id":25983153275018,"position":4,"preview_image":{"aspect_ratio":1.0,"height":960,"width":960,"src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901"},"aspect_ratio":1.0,"height":960,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901","width":960},{"alt":null,"id":31853224460426,"position":5,"preview_image":{"aspect_ratio":1.0,"height":4320,"width":4320,"src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_5fc8e8a0-5904-477c-9a1d-4ef752e21613.png?v=1774337996"},"aspect_ratio":1.0,"height":4320,"media_type":"image","src":"\/\/revitin.com\/cdn\/shop\/files\/Full_Size_Mint_5fc8e8a0-5904-477c-9a1d-4ef752e21613.png?v=1774337996","width":4320}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cp\u003eRevitin supports\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003estrong white teeth\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ehealthy gums\u003c\/strong\u003e, and\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efresher breath\u003c\/strong\u003e. What’s more, Revitin tastes great! Revitin is\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003efluoride-free\u003c\/strong\u003e,\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003ewithout Sodium Lauryl Sulfate (SLS free)\u003c\/strong\u003e, and you won't find\u003cspan\u003e \u003c\/span\u003e\u003cstrong\u003eTriclosan either!\u003c\/strong\u003e\u003c\/p\u003e"}]
1943    
1944  </script>
1944 
1945
1946  
1946<script type="application/json" id="product-variants">
1947    [
1948    
1949
1950    
1951
1952    
1953      
1954      {
1955        "variantId": 45594631471242,
1956        "productTitle": "Revitin Toothpaste Single Tube",
1957        "variantTitle": "Citrus",
1958        "variantPrice": 1700,
1959        "compareAtPrice": 1700,
1960        "sellingPlans": []
1961      },
1962    
1963      
1964      {
1965        "variantId": 45622706602122,
1966        "productTitle": "Revitin Toothpaste Single Tube",
1967        "variantTitle": "Mint",
1968        "variantPrice": 1700,
1969        "compareAtPrice": 1700,
1970        "sellingPlans": []
1971      },
1972    
1973      
1974      {
1975        "variantId": 45594633666698,
1976        "productTitle": "Revitin Toothpaste (3 Tubes)",
1977        "variantTitle": "Citrus",
1978        "variantPrice": 4600,
1979        "compareAtPrice": 5100,
1980        "sellingPlans": [{
1981                    "id": 2436038794,
1982                    "price": 4200,
1983                    "name": "1-month"
1984                  },{
1985                    "id": 2435973258,
1986                    "price": 4200,
1987                    "name": "2-months"
1988                  },{
1989                    "id": 2436071562,
1990                    "price": 4200,
1991                    "name": "3-months"
1992                  },{
1993                    "id": 2436006026,
1994                    "price": 4200,
1995                    "name": "6-months"
1996                  }]
1997      },
1998    
1999      
2000      {
2001        "variantId": 45618606080138,
2002        "productTitle": "Revitin Toothpaste (3 Tubes)",
2003        "variantTitle": "Mint",
2004        "variantPrice": 4600,
2005        "compareAtPrice": 5100,
2006        "sellingPlans": [{
2007                    "id": 2436497546,
2008                    "price": 4200,
2009                    "name": "1-month"
2010                  },{
2011                    "id": 2436300938,
2012                    "price": 4200,
2013                    "name": "2-months"
2014                  },{
2015                    "id": 2436530314,
2016                    "price": 4200,
2017                    "name": "3-months"
2018                  },{
2019                    "id": 2436563082,
2020                    "price": 4200,
2021                    "name": "6-months"
2022                  }]
2023      },
2024    
2025      
2026      {
2027        "variantId": 45594652901514,
2028        "productTitle": "Revitin Toothpaste (5 Tubes)",
2029        "variantTitle": "Citrus",
2030        "variantPrice": 7000,
2031        "compareAtPrice": 8500,
2032        "sellingPlans": [{
2033                    "id": 2436137098,
2034                    "price": 6800,
2035                    "name": "1-month"
2036                  },{
2037                    "id": 2436104330,
2038                    "price": 6800,
2039                    "name": "2-months"
2040                  },{
2041                    "id": 2436202634,
2042                    "price": 6800,
2043                    "name": "3-months"
2044                  },{
2045                    "id": 2436169866,
2046                    "price": 6800,
2047                    "name": "6-months"
2048                  }]
2049      },
2050    
2051      
2052      {
2053        "variantId": 45618689310858,
2054        "productTitle": "Revitin Toothpaste (5 Tubes)",
2055        "variantTitle": "Mint",
2056        "variantPrice": 7000,
2057        "compareAtPrice": 8500,
2058        "sellingPlans": [{
2059                    "id": 2436333706,
2060                    "price": 6800,
2061                    "name": "1-month"
2062                  },{
2063                    "id": 2436399242,
2064                    "price": 6800,
2065                    "name": "2-months"
2066                  },{
2067                    "id": 2436366474,
2068                    "price": 6800,
2069                    "name": "3-months"
2070                  },{
2071                    "id": 2436595850,
2072                    "price": 6800,
2073                    "name": "6-months"
2074                  }]
2075      },
2076    
2077      
2078      {
2079        "variantId": 45594657161354,
2080        "productTitle": "Revitin Toothpaste (25 Tubes)",
2081        "variantTitle": "Citrus",
2082        "variantPrice": 35000,
2083        "compareAtPrice": 42500,
2084        "sellingPlans": []
2085      },
2086    
2087      
2088      {
2089        "variantId": 45622715121802,
2090        "productTitle": "Revitin Toothpaste (25 Tubes)",
2091        "variantTitle": "Mint",
2092        "variantPrice": 35000,
2093        "compareAtPrice": 42500,
2094        "sellingPlans": []
2095      }
2096    
2097    ]
2098  </script>
2098
2099
2100  <product-form>
2101    <flavor-selector>
2102      <div class="w-full grid grid-flow-col justify-start gap-2 lg:gap-4 items-center flavour__selector">
2103        <button
2104          type="button"
2105          data-flavor="Citrus"
2106          style="border: 1px solid #C6C6C6;"
2107          class="flavour-custom flex items-center gap-3 text-brown rounded-[50px] py-2 pl-2 pr-6 lg:hover:bg-gold lg:hover:border-gold transition-colors duration-300 active"
2108        >
2109          <div class="relative w-8 h-8 bg-gold rounded-full flex items-center justify-center p-0.5">
2110            <img class="rounded-full" src="//revitin.com/cdn/shop/t/129/assets/citrus-teaser.png?v=69425243372235278621777542405" loading="lazy">
2111          </div>
2112          <div class="font-body-medium text-sm lg:text-lg">Citrus</div>
2113        </button>
2114        <button
2115          type="button"
2116          data-flavor="Mint"
2117          style="border: 1px solid #C6C6C6;"
2118          class="flavour-custom flex items-center gap-3 text-brown rounded-[50px] py-2 pl-2 pr-6 lg:hover:bg-light-green lg:hover:border-light-green transition-colors duration-300"
2119        >
2120          <div class="relative w-8 h-8 bg-light-green rounded-full flex items-center justify-center p-0.5">
2121            <img class="rounded-full" src="//revitin.com/cdn/shop/t/129/assets/mint-teaser.png?v=43172182657372155721777542403" loading="lazy">
2122          </div>
2123          <div class="font-body-medium text-sm lg:text-lg">Mint</div>
2124        </button>
2125        <button
2126          type="button"
2127          data-flavor="Variety"
2128          style="border: 1px solid #C6C6C6;"
2129          class="flex items-center variety-selector-btn gap-1 text-brown rounded-[50px] py-2 pl-1 pr-6 lg:hover:bg-light-green lg:hover:border-light-green transition-colors duration-300"
2130        >
2131          <div class="relative flex items-center justify-center variety_tab_btn">
2132            <img class="" src="//revitin.com/cdn/shop/t/129/assets/mix-match.png?v=98254657463874453371777542404" loading="lazy">
2133          </div>
2134          <div class="font-body-medium text-sm lg:text-lg">Variety</div>
2135        </button>
2136      </div>
2137    </flavor-selector>
2138    
2139
2140
2141
2142
2143
2144
2145<script type="application/json" id="all-products-json">
2146  [
2147    
2148      {
2149        "id": "8580142694538",
2150        "title": "Citrus Travel 3-Pack of 1oz",
2151        "handle": "revitin-toothpaste-travel-3-tubes",
2152        "description": "",
2153        "vendor": "Revitin",
2154        "product_type": "",
2155        "tags": [],
2156        "url": "/products/revitin-toothpaste-travel-3-tubes",
2157        "aestheticTitle": "Revitin Travel Size Toothpaste",
2158        "homepage_image": "",
2159        "featured_image": {
2160          "src": "//revitin.com/cdn/shop/files/citrus-1oz_1ab1a647-7adc-41ce-8f84-9b64065d72a8.jpg?v=1760422500",
2161          "alt": "Citrus Travel 3-Pack of 1oz"
2162        },
2163
2164        "images": [
2165          
2166            {
2167              "src": "//revitin.com/cdn/shop/files/citrus-1oz_1ab1a647-7adc-41ce-8f84-9b64065d72a8.jpg?v=1760422500",
2168              "alt": "Citrus Travel 3-Pack of 1oz"
2169            },
2170          
2171            {
2172              "src": "//revitin.com/cdn/shop/files/citrus-1oz-bottom.png?v=1760422500",
2173              "alt": "Citrus Travel 3-Pack of 1oz"
2174            },
2175          
2176            {
2177              "src": "//revitin.com/cdn/shop/files/glbF4rXA.jpg?v=1760615020",
2178              "alt": "Citrus Travel 3-Pack of 1oz"
2179            },
2180          
2181            {
2182              "src": "//revitin.com/cdn/shop/files/citrus-1oz-bottom-mobile.png?v=1760615020",
2183              "alt": "Citrus Travel 3-Pack of 1oz"
2184            },
2185          
2186            {
2187              "src": "//revitin.com/cdn/shop/files/Travel_Size_Citrus.png?v=1774338377",
2188              "alt": "Citrus Travel 3-Pack of 1oz"
2189            }
2190          
2191        ],
2192
2193        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
2194
2195        "variants": [
2196          
2197            {
2198              "id": "46346187341962",
2199              "title": "Citrus",
2200              "sku": "CitrTravel3-pk",
2201              "available": true,
2202              "price": "18.00",
2203              "compare_at_price": "",
2204              "inventory_quantity": "880",
2205              "sellingPlans": []
2206            }
2207          
2208        ]
2209      },
2210    
2211      {
2212        "id": "8658322555018",
2213        "title": "Citrus Travel Case (100 count)",
2214        "handle": "citrus-travel-case-100-count",
2215        "description": "",
2216        "vendor": "Revitin",
2217        "product_type": "",
2218        "tags": ["wholesale"],
2219        "url": "/products/citrus-travel-case-100-count",
2220        "aestheticTitle": "",
2221        "homepage_image": "",
2222        "featured_image": {
2223          "src": "//revitin.com/cdn/shop/files/citrus-1oz_1ab1a647-7adc-41ce-8f84-9b64065d72a8.jpg?v=1760422500",
2224          "alt": "Citrus Travel Case (100 count)"
2225        },
2226
2227        "images": [
2228          
2229            {
2230              "src": "//revitin.com/cdn/shop/files/citrus-1oz_1ab1a647-7adc-41ce-8f84-9b64065d72a8.jpg?v=1760422500",
2231              "alt": "Citrus Travel Case (100 count)"
2232            },
2233          
2234            {
2235              "src": "//revitin.com/cdn/shop/files/Travel_Size_Citrus.png?v=1774338377",
2236              "alt": "Citrus Travel Case (100 count)"
2237            }
2238          
2239        ],
2240
2241        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
2242
2243        "variants": [
2244          
2245            {
2246              "id": "46994967527562",
2247              "title": "Citrus",
2248              "sku": "CITRUSTRAVEL100",
2249              "available": true,
2250              "price": "300.00",
2251              "compare_at_price": "600.00",
2252              "inventory_quantity": "597",
2253              "sellingPlans": []
2254            }
2255          
2256        ]
2257      },
2258    
2259      {
2260        "id": "8580143349898",
2261        "title": "Mint Travel 3-Pack of 1oz",
2262        "handle": "revitin-toothpaste-travel-3-tubes-1",
2263        "description": "",
2264        "vendor": "Revitin",
2265        "product_type": "",
2266        "tags": [],
2267        "url": "/products/revitin-toothpaste-travel-3-tubes-1",
2268        "aestheticTitle": "Revitin Travel Size Toothpaste",
2269        "homepage_image": "",
2270        "featured_image": {
2271          "src": "//revitin.com/cdn/shop/files/mint-1oz.jpg?v=1760421639",
2272          "alt": "Mint Travel 3-Pack of 1oz"
2273        },
2274
2275        "images": [
2276          
2277            {
2278              "src": "//revitin.com/cdn/shop/files/mint-1oz.jpg?v=1760421639",
2279              "alt": "Mint Travel 3-Pack of 1oz"
2280            },
2281          
2282            {
2283              "src": "//revitin.com/cdn/shop/files/KacptZKA.jpg?v=1760614976",
2284              "alt": "Mint Travel 3-Pack of 1oz"
2285            },
2286          
2287            {
2288              "src": "//revitin.com/cdn/shop/files/XKZRPDJQ.jpg?v=1760614976",
2289              "alt": "Mint Travel 3-Pack of 1oz"
2290            },
2291          
2292            {
2293              "src": "//revitin.com/cdn/shop/files/mint-1oz-bottom-mobile.jpg?v=1760614976",
2294              "alt": "Mint Travel 3-Pack of 1oz"
2295            },
2296          
2297            {
2298              "src": "//revitin.com/cdn/shop/files/Travel_Size_Mint.png?v=1774338342",
2299              "alt": "Mint Travel 3-Pack of 1oz"
2300            }
2301          
2302        ],
2303
2304        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
2305
2306        "variants": [
2307          
2308            {
2309              "id": "46346189045898",
2310              "title": "Mint",
2311              "sku": "MintTravel3-pk",
2312              "available": true,
2313              "price": "18.00",
2314              "compare_at_price": "",
2315              "inventory_quantity": "484",
2316              "sellingPlans": []
2317            }
2318          
2319        ]
2320      },
2321    
2322      {
2323        "id": "8658320261258",
2324        "title": "Mint Travel Case (100 count)",
2325        "handle": "mint-travel-case-100-count",
2326        "description": "",
2327        "vendor": "Revitin",
2328        "product_type": "",
2329        "tags": ["wholesale"],
2330        "url": "/products/mint-travel-case-100-count",
2331        "aestheticTitle": "",
2332        "homepage_image": "",
2333        "featured_image": {
2334          "src": "//revitin.com/cdn/shop/files/mint-1oz.jpg?v=1760421639",
2335          "alt": "Mint Travel Case (100 count)"
2336        },
2337
2338        "images": [
2339          
2340            {
2341              "src": "//revitin.com/cdn/shop/files/mint-1oz.jpg?v=1760421639",
2342              "alt": "Mint Travel Case (100 count)"
2343            },
2344          
2345            {
2346              "src": "//revitin.com/cdn/shop/files/Travel_Size_Mint.png?v=1774338342",
2347              "alt": "Mint Travel Case (100 count)"
2348            }
2349          
2350        ],
2351
2352        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
2353
2354        "variants": [
2355          
2356            {
2357              "id": "46994955272330",
2358              "title": "Mint",
2359              "sku": "MINTTRAVEL100",
2360              "available": true,
2361              "price": "300.00",
2362              "compare_at_price": "600.00",
2363              "inventory_quantity": "611",
2364              "sellingPlans": []
2365            }
2366          
2367        ]
2368      },
2369    
2370      {
2371        "id": "6803929432202",
2372        "title": "Replacement Adult Brush Head",
2373        "handle": "replacement-adult-brush-head",
2374        "description": "Replacement head for the Revitin Professional Sonic Toothbrush",
2375        "vendor": "Revitin",
2376        "product_type": "Toothbrush Replacement Heads",
2377        "tags": ["Replacement Heads"],
2378        "url": "/products/replacement-adult-brush-head",
2379        "aestheticTitle": "",
2380        "homepage_image": "",
2381        "featured_image": {
2382          "src": "//revitin.com/cdn/shop/products/ReplacementHead.png?v=1662485289",
2383          "alt": "Replacement Adult Brush Head"
2384        },
2385
2386        "images": [
2387          
2388            {
2389              "src": "//revitin.com/cdn/shop/products/ReplacementHead.png?v=1662485289",
2390              "alt": "Replacement Adult Brush Head"
2391            }
2392          
2393        ],
2394
2395        "options": [{"name":"Title","position":1,"values":["Default Title"]}],
2396
2397        "variants": [
2398          
2399            {
2400              "id": "40896700186762",
2401              "title": "Default Title",
2402              "sku": "R-H6W-RH",
2403              "available": true,
2404              "price": "5.50",
2405              "compare_at_price": "",
2406              "inventory_quantity": "90",
2407              "sellingPlans": []
2408            }
2409          
2410        ]
2411      },
2412    
2413      {
2414        "id": "6606431617162",
2415        "title": "Revitin Toothpaste (25 Tubes)",
2416        "handle": "revitin-natural-toothpaste-fullcase-25tubes",
2417        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and 
2417you won't find Triclosan either!",
2418        "vendor": "Revitin® Natural Toothpaste",
2419        "product_type": "Toothpaste",
2420        "tags": ["Max25","Toothpaste","wholesale"],
2421        "url": "/products/revitin-natural-toothpaste-fullcase-25tubes",
2422        "aestheticTitle": "Revitin Natural Toothpaste",
2423        "homepage_image": "",
2424        "featured_image": {
2425          "src": "//revitin.com/cdn/shop/files/Full_Size_Citrus_75330201-6111-4242-bac7-eb4703f1b300.png?v=1774338517",
2426          "alt": "Revitin Toothpaste (25 Tubes)"
2427        },
2428
2429        "images": [
2430          
2431            {
2432              "src": "//revitin.com/cdn/shop/files/Full_Size_Citrus_75330201-6111-4242-bac7-eb4703f1b300.png?v=1774338517",
2433              "alt": "Revitin Toothpaste (25 Tubes)"
2434            },
2435          
2436            {
2437              "src": "//revitin.com/cdn/shop/products/revitin-case-25A_3a9c3300-7f44-4a68-a2b7-0fd137cfa073-removebg-preview.png?v=1774338517",
2438              "alt": "Revitin Toothpaste (25 Tubes)"
2439            },
2440          
2441            {
2442              "src": "//revitin.com/cdn/shop/products/revitin-case-25A_3a9c3300-7f44-4a68-a2b7-0fd137cfa073.jpg?v=1774338517",
2443              "alt": "Full Case (25 Tubes)"
2444            },
2445          
2446            {
2447              "src": "//revitin.com/cdn/shop/products/revitin-case1_7bb35865-2ba5-41bb-afab-c2fcd7a697a9.jpg?v=1774338517",
2448              "alt": "Revitin Toothpaste (25 Tubes)"
2449            }
2450          
2451        ],
2452
2453        "options": [{"name":"Title","position":1,"values":["Default Title"]}],
2454
2455        "variants": [
2456          
2457            {
2458              "id": "39792313729162",
2459              "title": "Default Title",
2460              "sku": "CITRUS25",
2461              "available": true,
2462              "price": "350.00",
2463              "compare_at_price": "425.00",
2464              "inventory_quantity": "1474",
2465              "sellingPlans": []
2466            }
2467          
2468        ]
2469      },
2470    
2471      {
2472        "id": "7890501009546",
2473        "title": "Revitin Toothpaste (25 Tubes)",
2474        "handle": "copy-of-revitin-toothpaste-25-tubes-gm",
2475        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and you won't find Triclosan either!",
2476        "vendor": "Revitin® Natural Toothpaste",
2477        "product_type": "Toothpaste",
2478        "tags": ["Max25","Toothpaste","wholesale"],
2479        "url": "/products/copy-of-revitin-toothpaste-25-tubes-gm",
2480        "aestheticTitle": "Revitin Natural Toothpaste",
2481        "homepage_image": "",
2482        "featured_image": {
2483          "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2484          "alt": "Revitin Toothpaste (25 Tubes)"
2485        },
2486
2487        "images": [
2488          
2489            {
2490              "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2491              "alt": "Revitin Toothpaste (25 Tubes)"
2492            },
2493          
2494            {
2495              "src": "//revitin.com/cdn/shop/files/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901",
2496              "alt": "Revitin Toothpaste (25 Tubes)"
2497            },
2498          
2499            {
2500              "src": "//revitin.com/cdn/shop/files/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901",
2501              "alt": "Full Case (25 Tubes)"
2502            },
2503          
2504            {
2505              "src": "//revitin.com/cdn/shop/files/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901",
2506              "alt": "Revitin Toothpaste (25 Tubes)"
2507            },
2508          
2509            {
2510              "src": "//revitin.com/cdn/shop/files/Full_Size_Citrus_5dd0e011-ff5d-4356-80a8-debbb8fbaa63.png?v=1774338062",
2511              "alt": "Revitin Toothpaste (25 Tubes)"
2512            }
2513          
2514        ],
2515
2516        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
2517
2518        "variants": [
2519          
2520            {
2521              "id": "45594657161354",
2522              "title": "Citrus",
2523              "sku": "CITRUS25",
2524              "available": true,
2525              "price": "350.00",
2526              "compare_at_price": "425.00",
2527              "inventory_quantity": "1474",
2528              "sellingPlans": []
2529            }
2530          
2531        ]
2532      },
2533    
2534      {
2535        "id": "8334207778954",
2536        "title": "Revitin Toothpaste (25 Tubes)",
2537        "handle": "revitin-toothpaste-25-tubes-mint",
2538        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and 
2538you won't find Triclosan either!",
2539        "vendor": "Revitin® Natural Toothpaste",
2540        "product_type": "Toothpaste",
2541        "tags": ["Max25","Toothpaste","wholesale"],
2542        "url": "/products/revitin-toothpaste-25-tubes-mint",
2543        "aestheticTitle": "Revitin Natural Toothpaste",
2544        "homepage_image": "",
2545        "featured_image": {
2546          "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2547          "alt": "Revitin Toothpaste (25 Tubes)"
2548        },
2549
2550        "images": [
2551          
2552            {
2553              "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2554              "alt": "Revitin Toothpaste (25 Tubes)"
2555            },
2556          
2557            {
2558              "src": "//revitin.com/cdn/shop/files/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901",
2559              "alt": "Revitin Toothpaste (25 Tubes)"
2560            },
2561          
2562            {
2563              "src": "//revitin.com/cdn/shop/files/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901",
2564              "alt": "Full Case (25 Tubes)"
2565            },
2566          
2567            {
2568              "src": "//revitin.com/cdn/shop/files/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901",
2569              "alt": "Revitin Toothpaste (25 Tubes)"
2570            },
2571          
2572            {
2573              "src": "//revitin.com/cdn/shop/files/Full_Size_Mint_5fc8e8a0-5904-477c-9a1d-4ef752e21613.png?v=1774337996",
2574              "alt": "Revitin Toothpaste (25 Tubes)"
2575            }
2576          
2577        ],
2578
2579        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
2580
2581        "variants": [
2582          
2583            {
2584              "id": "45622715121802",
2585              "title": "Mint",
2586              "sku": "MINT25",
2587              "available": true,
2588              "price": "350.00",
2589              "compare_at_price": "425.00",
2590              "inventory_quantity": "1889",
2591              "sellingPlans": []
2592            }
2593          
2594        ]
2595      },
2596    
2597      {
2598        "id": "8335794307210",
2599        "title": "Revitin Toothpaste (25 Tubes) Wholesale",
2600        "handle": "revitin-toothpaste-25-tubes-wholesale",
2601        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and you won't find Triclosan either!",
2602        "vendor": "Revitin® Natural Toothpaste",
2603        "product_type": "Toothpaste",
2604        "tags": ["Max25","Toothpaste","wholesale"],
2605        "url": "/products/revitin-toothpaste-25-tubes-wholesale",
2606        "aestheticTitle": "Revitin Natural Toothpaste",
2607        "homepage_image": "",
2608        "featured_image": {
2609          "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2610          "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2611        },
2612
2613        "images": [
2614          
2615            {
2616              "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2617              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2618            },
2619          
2620            {
2621              "src": "//revitin.com/cdn/shop/files/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901",
2622              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2623            },
2624          
2625            {
2626              "src": "//revitin.com/cdn/shop/files/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901",
2627              "alt": "Full Case (25 Tubes)"
2628            },
2629          
2630            {
2631              "src": "//revitin.com/cdn/shop/files/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901",
2632              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2633            },
2634          
2635            {
2636              "src": "//revitin.com/cdn/shop/files/Full_Size_Citrus_75330201-6111-4242-bac7-eb4703f1b300.png?v=1774338517",
2637              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2638            }
2639          
2640        ],
2641
2642        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
2643
2644        "variants": [
2645          
2646            {
2647              "id": "45628453814410",
2648              "title": "Citrus",
2649              "sku": "CITRUS25",
2650              "available": true,
2651              "price": "212.50",
2652              "compare_at_price": "425.00",
2653              "inventory_quantity": "1473",
2654              "sellingPlans": []
2655            }
2656          
2657        ]
2658      },
2659    
2660      {
2661        "id": "8335801548938",
2662        "title": "Revitin Toothpaste (25 Tubes) Wholesale",
2663        "handle": "revitin-toothpaste-25-tubes-wholesale-mint",
2664        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and 
2664you won't find Triclosan either!",
2665        "vendor": "Revitin® Natural Toothpaste",
2666        "product_type": "Toothpaste",
2667        "tags": ["Max25","Toothpaste","wholesale"],
2668        "url": "/products/revitin-toothpaste-25-tubes-wholesale-mint",
2669        "aestheticTitle": "Revitin Natural Toothpaste",
2670        "homepage_image": "",
2671        "featured_image": {
2672          "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2673          "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2674        },
2675
2676        "images": [
2677          
2678            {
2679              "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2680              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2681            },
2682          
2683            {
2684              "src": "//revitin.com/cdn/shop/files/revitin-case-25A-removebg-preview_1eb996a0-5ac0-41ba-8838-5bc2ce0fc7b4.png?v=1751389901",
2685              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2686            },
2687          
2688            {
2689              "src": "//revitin.com/cdn/shop/files/revitin-case-25A_7536a270-a73f-4686-ab65-56c666719954.jpg?v=1751389901",
2690              "alt": "Full Case (25 Tubes)"
2691            },
2692          
2693            {
2694              "src": "//revitin.com/cdn/shop/files/revitin-case1_c93e3dd8-eaa7-413e-97d2-5ce9d0d257fa.jpg?v=1751389901",
2695              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2696            },
2697          
2698            {
2699              "src": "//revitin.com/cdn/shop/files/Full_Size_Mint_1318037a-3b7a-4e15-84c3-e22323a5e8cc.png?v=1774337830",
2700              "alt": "Revitin Toothpaste (25 Tubes) Wholesale"
2701            }
2702          
2703        ],
2704
2705        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
2706
2707        "variants": [
2708          
2709            {
2710              "id": "45628533604490",
2711              "title": "Mint",
2712              "sku": "MINT25",
2713              "available": true,
2714              "price": "212.50",
2715              "compare_at_price": "425.00",
2716              "inventory_quantity": "1889",
2717              "sellingPlans": []
2718            }
2719          
2720        ]
2721      },
2722    
2723      {
2724        "id": "6606431420554",
2725        "title": "Revitin Toothpaste (3 Tubes)",
2726        "handle": "revitin-natural-toothpaste-family-pack-3tubes",
2727        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and you won't find Triclosan either!\n",
2728        "vendor": "Revitin® Natural Toothpaste",
2729        "product_type": "Toothpaste",
2730        "tags": ["Toothpaste","wholesale"],
2731        "url": "/products/revitin-natural-toothpaste-family-pack-3tubes",
2732        "aestheticTitle": "Revitin Natural Toothpaste",
2733        "homepage_image": "",
2734        "featured_image": {
2735          "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2736          "alt": "Revitin Toothpaste (3 Tubes)"
2737        },
2738
2739        "images": [
2740          
2741            {
2742              "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2743              "alt": "Revitin Toothpaste (3 Tubes)"
2744            },
2745          
2746            {
2747              "src": "//revitin.com/cdn/shop/files/citrus-gallery-1_11zon.jpg?v=1751389467",
2748              "alt": "Revitin Toothpaste (3 Tubes)"
2749            },
2750          
2751            {
2752              "src": "//revitin.com/cdn/shop/files/citrus-gallery-3_11zon.jpg?v=1751389467",
2753              "alt": "Revitin Toothpaste (3 Tubes)"
2754            },
2755          
2756            {
2757              "src": "//revitin.com/cdn/shop/files/citrus-featured_11zon.jpg?v=1751389467",
2758              "alt": "Revitin Toothpaste (3 Tubes)"
2759            },
2760          
2761            {
2762              "src": "//revitin.com/cdn/shop/files/Full_Size_Citrus.png?v=1773920437",
2763              "alt": "Revitin Toothpaste (3 Tubes)"
2764            }
2765          
2766        ],
2767
2768        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
2769
2770        "variants": [
2771          
2772            {
2773              "id": "45594633666698",
2774              "title": "Citrus",
2775              "sku": "CITRUS3",
2776              "available": true,
2777              "price": "46.00",
2778              "compare_at_price": "51.00",
2779              "inventory_quantity": "12860",
2780              "sellingPlans": [{
2781                        "id": 2436038794,
2782                        "name": "Delivery every 1 month",
2783                        "price": 4200
2784                      },{
2785                        "id": 2435973258,
2786                        "name": "Delivery every 2 months",
2787                        "price": 4200
2788                      },{
2789                        "id": 2436071562,
2790                        "name": "Delivery every 3 months",
2791                        "price": 4200
2792                      },{
2793                        "id": 2436006026,
2794                        "name": "Delivery every 6 months",
2795                        "price": 4200
2796                      }]
2797            }
2798          
2799        ]
2800      },
2801    
2802      {
2803        "id": "8333322846346",
2804        "title": "Revitin Toothpaste (3 Tubes)",
2805        "handle": "revitin-toothpaste-3-tubes-mint",
2806        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and 
2806you won't find Triclosan either!",
2807        "vendor": "Revitin® Natural Toothpaste",
2808        "product_type": "Toothpaste",
2809        "tags": ["Toothpaste","wholesale"],
2810        "url": "/products/revitin-toothpaste-3-tubes-mint",
2811        "aestheticTitle": "Revitin Natural Toothpaste",
2812        "homepage_image": "",
2813        "featured_image": {
2814          "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2815          "alt": "Revitin Toothpaste (3 Tubes)"
2816        },
2817
2818        "images": [
2819          
2820            {
2821              "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2822              "alt": "Revitin Toothpaste (3 Tubes)"
2823            },
2824          
2825            {
2826              "src": "//revitin.com/cdn/shop/files/mint-gallery-1_11zon.jpg?v=1751389546",
2827              "alt": "Revitin Toothpaste (3 Tubes)"
2828            },
2829          
2830            {
2831              "src": "//revitin.com/cdn/shop/files/mint-gallery-2_11zon.jpg?v=1751389546",
2832              "alt": "Revitin Toothpaste (3 Tubes)"
2833            },
2834          
2835            {
2836              "src": "//revitin.com/cdn/shop/files/mint-featured_11zon.jpg?v=1751389546",
2837              "alt": "Revitin Toothpaste (3 Tubes)"
2838            },
2839          
2840            {
2841              "src": "//revitin.com/cdn/shop/files/Full_Size_Mint.png?v=1774282946",
2842              "alt": "Revitin Toothpaste (3 Tubes)"
2843            }
2844          
2845        ],
2846
2847        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
2848
2849        "variants": [
2850          
2851            {
2852              "id": "45618606080138",
2853              "title": "Mint",
2854              "sku": "MINT3",
2855              "available": true,
2856              "price": "46.00",
2857              "compare_at_price": "51.00",
2858              "inventory_quantity": "17282",
2859              "sellingPlans": [{
2860                        "id": 2436497546,
2861                        "name": "Delivery every 1 month",
2862                        "price": 4200
2863                      },{
2864                        "id": 2436300938,
2865                        "name": "Delivery every 2 months",
2866                        "price": 4200
2867                      },{
2868                        "id": 2436530314,
2869                        "name": "Delivery every 3 months",
2870                        "price": 4200
2871                      },{
2872                        "id": 2436563082,
2873                        "name": "Delivery every 6 months",
2874                        "price": 4200
2875                      }]
2876            }
2877          
2878        ]
2879      },
2880    
2881      {
2882        "id": "7609245171850",
2883        "title": "Revitin Toothpaste (5 Tubes)",
2884        "handle": "revitin-toothpaste-5-tubes",
2885        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and you won't find Triclosan either!",
2886        "vendor": "Revitin® Natural Toothpaste",
2887        "product_type": "Toothpaste",
2888        "tags": ["Subscription","Toothpaste","wholesale"],
2889        "url": "/products/revitin-toothpaste-5-tubes",
2890        "aestheticTitle": "Revitin Natural Toothpaste",
2891        "homepage_image": "",
2892        "featured_image": {
2893          "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2894          "alt": "Revitin Toothpaste (5 Tubes)"
2895        },
2896
2897        "images": [
2898          
2899            {
2900              "src": "//revitin.com/cdn/shop/files/citrus-render_cream_bg.png?v=1751390073",
2901              "alt": "Revitin Toothpaste (5 Tubes)"
2902            },
2903          
2904            {
2905              "src": "//revitin.com/cdn/shop/files/citrus-gallery-1_11zon.jpg?v=1751389467",
2906              "alt": "Revitin Toothpaste (5 Tubes)"
2907            },
2908          
2909            {
2910              "src": "//revitin.com/cdn/shop/files/citrus-gallery-3_11zon.jpg?v=1751389467",
2911              "alt": "Revitin Toothpaste (5 Tubes)"
2912            },
2913          
2914            {
2915              "src": "//revitin.com/cdn/shop/files/citrus-featured_11zon.jpg?v=1751389467",
2916              "alt": "Revitin Toothpaste (5 Tubes)"
2917            },
2918          
2919            {
2920              "src": "//revitin.com/cdn/shop/files/Full_Size_Citrus_e9fa6364-9bfe-4cd7-b0af-1a95d93ee5ba.png?v=1774337705",
2921              "alt": "Revitin Toothpaste (5 Tubes)"
2922            }
2923          
2924        ],
2925
2926        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
2927
2928        "variants": [
2929          
2930            {
2931              "id": "45594652901514",
2932              "title": "Citrus",
2933              "sku": "CITRUS5",
2934              "available": true,
2935              "price": "70.00",
2936              "compare_at_price": "85.00",
2937              "inventory_quantity": "284",
2938              "sellingPlans": [{
2939                        "id": 2436137098,
2940                        "name": "Delivery every 1 month",
2941                        "price": 6800
2942                      },{
2943                        "id": 2436104330,
2944                        "name": "Delivery every 2 months",
2945                        "price": 6800
2946                      },{
2947                        "id": 2436202634,
2948                        "name": "Delivery every 3 months",
2949                        "price": 6800
2950                      },{
2951                        "id": 2436169866,
2952                        "name": "Delivery every 6 months",
2953                        "price": 6800
2954                      }]
2955            }
2956          
2957        ]
2958      },
2959    
2960      {
2961        "id": "8333359808650",
2962        "title": "Revitin Toothpaste (5 Tubes)",
2963        "handle": "revitin-toothpaste-5-tubes-mint",
2964        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and you won't find Triclosan either!",
2965        "vendor": "Revitin® Natural Toothpaste",
2966        "product_type": "Toothpaste",
2967        "tags": ["Subscription","Toothpaste","wholesale"],
2968        "url": "/products/revitin-toothpaste-5-tubes-mint",
2969        "aestheticTitle": "Revitin Natural Toothpaste",
2970        "homepage_image": "",
2971        "featured_image": {
2972          "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2973          "alt": "Revitin Toothpaste (5 Tubes)"
2974        },
2975
2976        "images": [
2977          
2978            {
2979              "src": "//revitin.com/cdn/shop/files/mint-render_cream_bg.png?v=1751389753",
2980              "alt": "Revitin Toothpaste (5 Tubes)"
2981            },
2982          
2983            {
2984              "src": "//revitin.com/cdn/shop/files/mint-gallery-1_11zon.jpg?v=1751389546",
2985              "alt": "Revitin Toothpaste (5 Tubes)"
2986            },
2987          
2988            {
2989              "src": "//revitin.com/cdn/shop/files/mint-gallery-2_11zon.jpg?v=1751389546",
2990              "alt": "Revitin Toothpaste (5 Tubes)"
2991            },
2992          
2993            {
2994              "src": "//revitin.com/cdn/shop/files/mint-featured_11zon.jpg?v=1751389546",
2995              "alt": "Revitin Toothpaste (5 Tubes)"
2996            },
2997          
2998            {
2999              "src": "//revitin.com/cdn/shop/files/Full_Size_Mint_37b5d288-2b5a-42a4-bd87-71596a6bf4b4.png?v=1774337756",
3000              "alt": "Revitin Toothpaste (5 Tubes)"
3001            }
3002          
3003        ],
3004
3005        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
3006
3007        "variants": [
3008          
3009            {
3010              "id": "45618689310858",
3011              "title": "Mint",
3012              "sku": "MINT5",
3013              "available": true,
3014              "price": "70.00",
3015              "compare_at_price": "85.00",
3016              "inventory_quantity": "2097",
3017              "sellingPlans": [{
3018                        "id": 2436333706,
3019                        "name": "Delivery every 1 month with 17.65% discount",
3020                        "price": 6800
3021                      },{
3022                        "id": 2436399242,
3023                        "name": "Delivery every 2 months with 17.65% discount",
3024                        "price": 6800
3025                      },{
3026                        "id": 2436366474,
3027                        "name": "Delivery every 3 months with 17.65% discount",
3028                        "price": 6800
3029                      },{
3030                        "id": 2436595850,
3031                        "name": "Delivery every 6 months with 17.65% discount",
3032                        "price": 6800
3033                      }]
3034            }
3035          
3036        ]
3037      },
3038    
3039      {
3040        "id": "6606432174218",
3041        "title": "Revitin Toothpaste Single Tube",
3042        "handle": "revitin-natural-toothpaste",
3043        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and 
3043you won't find Triclosan either!",
3044        "vendor": "Revitin® Natural Toothpaste",
3045        "product_type": "Toothpaste",
3046        "tags": ["Toothpaste","wholesale"],
3047        "url": "/products/revitin-natural-toothpaste",
3048        "aestheticTitle": "Revitin Natural Toothpaste",
3049        "homepage_image": "",
3050        "featured_image": {
3051          "src": "//revitin.com/cdn/shop/files/citrus-gallery-render-mobile_11zon.jpg?v=1742298905",
3052          "alt": "Revitin Toothpaste Single Tube"
3053        },
3054
3055        "images": [
3056          
3057            {
3058              "src": "//revitin.com/cdn/shop/files/citrus-gallery-render-mobile_11zon.jpg?v=1742298905",
3059              "alt": "Revitin Toothpaste Single Tube"
3060            },
3061          
3062            {
3063              "src": "//revitin.com/cdn/shop/files/citrus-featured_11zon.jpg?v=1751389467",
3064              "alt": "Revitin Toothpaste Single Tube"
3065            },
3066          
3067            {
3068              "src": "//revitin.com/cdn/shop/files/citrus-render.png?v=1751390073",
3069              "alt": "Revitin Toothpaste Single Tube"
3070            },
3071          
3072            {
3073              "src": "//revitin.com/cdn/shop/files/citrus-featured-mobile_11zon.jpg?v=1742298805",
3074              "alt": "Revitin Toothpaste Single Tube"
3075            },
3076          
3077            {
3078              "src": "//revitin.com/cdn/shop/files/citrus-gallery-3_11zon.jpg?v=1751389467",
3079              "alt": "Revitin Toothpaste Single Tube"
3080            },
3081          
3082            {
3083              "src": "//revitin.com/cdn/shop/files/main-grapefruit_90add639-f630-489f-9558-ad382aba44cc.png?v=1741690920",
3084              "alt": "Revitin Toothpaste Single Tube"
3085            },
3086          
3087            {
3088              "src": "//revitin.com/cdn/shop/files/10001.jpg?v=1742293659",
3089              "alt": "Revitin Toothpaste Single Tube"
3090            },
3091          
3092            {
3093              "src": "//revitin.com/cdn/shop/files/Full_Size_Citrus_e232e154-1f22-47a5-97a3-a93e8238766d.png?v=1774337551",
3094              "alt": "Revitin Toothpaste Single Tube"
3095            }
3096          
3097        ],
3098
3099        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
3100
3101        "variants": [
3102          
3103            {
3104              "id": "45594631471242",
3105              "title": "Citrus",
3106              "sku": "CITRUS1",
3107              "available": true,
3108              "price": "17.00",
3109              "compare_at_price": "17.00",
3110              "inventory_quantity": "36855",
3111              "sellingPlans": []
3112            }
3113          
3114        ]
3115      },
3116    
3117      {
3118        "id": "8334203355274",
3119        "title": "Revitin Toothpaste Single Tube",
3120        "handle": "revitin-toothpaste-single-tube-mint",
3121        "description": "Revitin supports strong white teeth, healthy gums, and fresher breath. What’s more, Revitin tastes great! Revitin is fluoride-free, without Sodium Lauryl Sulfate (SLS free), and you won't find Triclosan either!",
3122        "vendor": "Revitin® Natural Toothpaste",
3123        "product_type": "Toothpaste",
3124        "tags": ["Toothpaste","wholesale"],
3125        "url": "/products/revitin-toothpaste-single-tube-mint",
3126        "aestheticTitle": "Revitin Natural Toothpaste",
3127        "homepage_image": "",
3128        "featured_image": {
3129          "src": "//revitin.com/cdn/shop/files/mint-gallery-1_11zon.jpg?v=1751389546",
3130          "alt": "Revitin Toothpaste Single Tube"
3131        },
3132
3133        "images": [
3134          
3135            {
3136              "src": "//revitin.com/cdn/shop/files/mint-gallery-1_11zon.jpg?v=1751389546",
3137              "alt": "Revitin Toothpaste Single Tube"
3138            },
3139          
3140            {
3141              "src": "//revitin.com/cdn/shop/files/mint-render.png?v=1751387541",
3142              "alt": "Revitin Toothpaste Single Tube"
3143            },
3144          
3145            {
3146              "src": "//revitin.com/cdn/shop/files/mint-gallery-2_11zon.jpg?v=1751389546",
3147              "alt": "Revitin Toothpaste Single Tube"
3148            },
3149          
3150            {
3151              "src": "//revitin.com/cdn/shop/files/mint-featured_11zon.jpg?v=1751389546",
3152              "alt": "Revitin Toothpaste Single Tube"
3153            },
3154          
3155            {
3156              "src": "//revitin.com/cdn/shop/files/Full_Size_Mint_99a4be1b-921c-4bbc-96f1-3bc4d0999926.png?v=1774337594",
3157              "alt": "Revitin Toothpaste Single Tube"
3158            },
3159          
3160            {
3161              "src": "//revitin.com/cdn/shop/files/Screenshot_2026-05-13_at_4.25.54_PM.png?v=1778704121",
3162              "alt": "Revitin Toothpaste Single Tube"
3163            },
3164          
3165            {
3166              "src": "//revitin.com/cdn/shop/files/Screenshot_2026-05-13_at_4.33.10_PM.png?v=1778704398",
3167              "alt": "Revitin Toothpaste Single Tube"
3168            }
3169          
3170        ],
3171
3172        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
3173
3174        "variants": [
3175          
3176            {
3177              "id": "45622706602122",
3178              "title": "Mint",
3179              "sku": "MINT1",
3180              "available": true,
3181              "price": "17.00",
3182              "compare_at_price": "17.00",
3183              "inventory_quantity": "47196",
3184              "sellingPlans": []
3185            }
3186          
3187        ]
3188      },
3189    
3190      {
3191        "id": "8332405899402",
3192        "title": "Revitin Toothpaste Variety 3 Tubes",
3193        "handle": "citrus-mint-4-tubes",
3194        "description": "Promote a healthy balance of your oral ecology to support oral health and wellness for whiter teeth and fresher breath.",
3195        "vendor": "Revitin® Natural Toothpaste",
3196        "product_type": "Toothpaste",
3197        "tags": ["Toothpaste","wholesale"],
3198        "url": "/products/citrus-mint-4-tubes",
3199        "aestheticTitle": "2 Citrus & 1 Mint",
3200        "homepage_image": "",
3201        "featured_image": {
3202          "src": "//revitin.com/cdn/shop/files/jiCerJfg.jpg?v=1760511199",
3203          "alt": "Revitin Toothpaste Variety 3 Tubes"
3204        },
3205
3206        "images": [
3207          
3208            {
3209              "src": "//revitin.com/cdn/shop/files/jiCerJfg.jpg?v=1760511199",
3210              "alt": "Revitin Toothpaste Variety 3 Tubes"
3211            },
3212          
3213            {
3214              "src": "//revitin.com/cdn/shop/files/IMG-0976_9e04b0b0-bc26-4aed-8d9b-0267e461713e.jpg?v=1760511199",
3215              "alt": "Revitin Toothpaste Variety 3 Tubes"
3216            },
3217          
3218            {
3219              "src": "//revitin.com/cdn/shop/files/IMG-0977_0a2566a9-f325-40ee-993e-bbdf733e13fa.jpg?v=1760511199",
3220              "alt": "Revitin Toothpaste Variety 3 Tubes"
3221            },
3222          
3223            {
3224              "src": "//revitin.com/cdn/shop/files/hm-2-citrus-1-mint.png?v=1760511199",
3225              "alt": "Revitin Toothpaste Variety 3 Tubes"
3226            },
3227          
3228            {
3229              "src": "//revitin.com/cdn/shop/files/Z9RFJa7w.jpg?v=1760614753",
3230              "alt": "Revitin Toothpaste Variety 3 Tubes"
3231            },
3232          
3233            {
3234              "src": "//revitin.com/cdn/shop/files/Full_Size_Variety_2citrus1mint.png?v=1774338212",
3235              "alt": "Revitin Toothpaste Variety 3 Tubes"
3236            },
3237          
3238            {
3239              "src": "//revitin.com/cdn/shop/files/mint-gallery-mobile-3_11zon.jpg?v=1729883824",
3240              "alt": "Revitin Toothpaste Variety 3 Tubes"
3241            }
3242          
3243        ],
3244
3245        "options": [{"name":"Flavor","position":1,"values":["Citrus"]}],
3246
3247        "variants": [
3248          
3249            {
3250              "id": "46765298909322",
3251              "title": "Citrus",
3252              "sku": "VARIETYPACK2C-1M",
3253              "available": true,
3254              "price": "46.00",
3255              "compare_at_price": "51.00",
3256              "inventory_quantity": "1844",
3257              "sellingPlans": [{
3258                        "id": 2436235402,
3259                        "name": "Delivery every 1 month",
3260                        "price": 4200
3261                      },{
3262                        "id": 2436464778,
3263                        "name": "Delivery every 2 months",
3264                        "price": 4200
3265                      },{
3266                        "id": 2436432010,
3267                        "name": "Delivery every 3 months",
3268                        "price": 4200
3269                      },{
3270                        "id": 2436268170,
3271                        "name": "Delivery every 6 months",
3272                        "price": 4200
3273                      }]
3274            }
3275          
3276        ]
3277      },
3278    
3279      {
3280        "id": "8645075763338",
3281        "title": "Revitin Toothpaste Variety 3 Tubes",
3282        "handle": "variety-pack-2-mint-1-citrus",
3283        "description": "Promote a healthy balance of your oral ecology to support oral health and wellness for whiter teeth and fresher breath.",
3284        "vendor": "Revitin® Natural Toothpaste",
3285        "product_type": "Toothpaste",
3286        "tags": ["Toothpaste","wholesale"],
3287        "url": "/products/variety-pack-2-mint-1-citrus",
3288        "aestheticTitle": "2 Mint & 1 Citrus",
3289        "homepage_image": "",
3290        "featured_image": {
3291          "src": "//revitin.com/cdn/shop/files/R13eeryg.jpg?v=1760511151",
3292          "alt": "Revitin Toothpaste Variety 3 Tubes"
3293        },
3294
3295        "images": [
3296          
3297            {
3298              "src": "//revitin.com/cdn/shop/files/R13eeryg.jpg?v=1760511151",
3299              "alt": "Revitin Toothpaste Variety 3 Tubes"
3300            },
3301          
3302            {
3303              "src": "//revitin.com/cdn/shop/files/IMG-0976.jpg?v=1760511151",
3304              "alt": "Revitin Toothpaste Variety 3 Tubes"
3305            },
3306          
3307            {
3308              "src": "//revitin.com/cdn/shop/files/IMG-0977.jpg?v=1760511151",
3309              "alt": "Revitin Toothpaste Variety 3 Tubes"
3310            },
3311          
3312            {
3313              "src": "//revitin.com/cdn/shop/files/hm-2-citrus-1-mint.png?v=1760511199",
3314              "alt": "Revitin Toothpaste Variety 3 Tubes"
3315            },
3316          
3317            {
3318              "src": "//revitin.com/cdn/shop/files/qpMuKh-Q.jpg?v=1760614727",
3319              "alt": "Revitin Toothpaste Variety 3 Tubes"
3320            },
3321          
3322            {
3323              "src": "//revitin.com/cdn/shop/files/Full_Size_Variety_1citrus2mint.png?v=1774338246",
3324              "alt": "Revitin Toothpaste Variety 3 Tubes"
3325            },
3326          
3327            {
3328              "src": "//revitin.com/cdn/shop/files/mint-gallery-mobile-3_11zon.jpg?v=1729883824",
3329              "alt": "Revitin Toothpaste Variety 3 Tubes"
3330            }
3331          
3332        ],
3333
3334        "options": [{"name":"Flavor","position":1,"values":["Mint"]}],
3335
3336        "variants": [
3337          
3338            {
3339              "id": "46765283049610",
3340              "title": "Mint",
3341              "sku": "VARIETYPACK2M-1C",
3342              "available": true,
3343              "price": "46.00",
3344              "compare_at_price": "51.00",
3345              "inventory_quantity": "25302",
3346              "sellingPlans": [{
3347                        "id": 2436726922,
3348                        "name": "Delivery every 1 month",
3349                        "price": 4200
3350                      },{
3351                        "id": 2436694154,
3352                        "name": "Delivery every 2 months",
3353                        "price": 4200
3354                      },{
3355                        "id": 2436628618,
3356                        "name": "Delivery every 3 months",
3357                        "price": 4200
3358                      },{
3359                        "id": 2436661386,
3360                        "name": "Delivery every 6 months",
3361                        "price": 4200
3362                      }]
3363            }
3364          
3365        ]
3366      },
3367    
3368      {
3369        "id": "8909392904330",
3370        "title": "Variety Travel 4-Pack of 1 oz",
3371        "handle": "variety-travel-4-pack-of-1-oz",
3372        "description": "",
3373        "vendor": "Revitin",
3374        "product_type": "",
3375        "tags": [],
3376        "url": "/products/variety-travel-4-pack-of-1-oz",
3377        "aestheticTitle": "",
3378        "homepage_image": "",
3379        "featured_image": {
3380          "src": "//revitin.com/cdn/shop/files/revitin2.png?v=1777964527",
3381          "alt": "Variety Travel 4-Pack of 1 oz"
3382        },
3383
3384        "images": [
3385          
3386            {
3387              "src": "//revitin.com/cdn/shop/files/revitin2.png?v=1777964527",
3388              "alt": "Variety Travel 4-Pack of 1 oz"
3389            },
3390          
3391            {
3392              "src": "//revitin.com/cdn/shop/files/revitin1.png?v=1777964527",
3393              "alt": "Variety Travel 4-Pack of 1 oz"
3394            }
3395          
3396        ],
3397
3398        "options": [{"name":"Title","position":1,"values":["Default Title"]}],
3399
3400        "variants": [
3401          
3402            {
3403              "id": "47799599759498",
3404              "title": "Default Title",
3405              "sku": "VarietyTravel4-pk",
3406              "available": true,
3407              "price": "24.00",
3408              "compare_at_price": "",
3409              "inventory_quantity": "518",
3410              "sellingPlans": []
3411            }
3412          
3413        ]
3414      }
3415    
3416  ]
3417</script>
3417
3418
3419<div class="variety-selection-container">
3420  <label class="variety-box variety-active" id="variety-subscribeBox">
3421    <input class="variety-radio-input" type="radio" name="variety-purchaseType" value="subscribe" checked>
3422    <div class="variety-radio-group">
3423      <span class="variety-radio-dot"></span>
3424      Subscribe & Save
3425      <div class="variety-save-tag subscribe-save"></div>
3426      <span class="subs-variety-price variety-price"><span class="variety-original-price opacity-50"></span></span>
3427    </div>
3428    <div class="variety-description">
3429      <div class="variety-selling-plan-dropdown">
3430        <label for="subscribe-selling-plan">Delivered every</label>
3431        <select id="subscribe-selling-plan" class="variety-selling-plan-select font-body-medium"></select>
3432      </div>
3433      Free shipping. Cancel anytime.
3434    </div>
3435    <div class="variety-flavor-options subs-btn" id="variety-subscribeFlavors">
3436      
3437
3438      
3439      
3440
3441      <button
3442        data-citrus-count="2"
3443        data-mint-count="1"
3444        class="variety-qty subs font-body-medium active"
3445      >
3446        2 Citrus & 1 Mint
3447      </button>
3448
3449      <button
3450        data-citrus-count="1"
3451        data-mint-count="2"
3452        class="variety-qty subs"
3453      >
3454        2 Mint & 1 Citrus
3455      </button>
3456    </div>
3457  </label>
3458
3459  <label class="variety-box variety-active" id="variety-oneTimeBox">
3460    <input class="variety-radio-input" type="radio" name="variety-purchaseType" value="onetime">
3461    <div class="variety-radio-group">
3462      <span class="variety-radio-dot"></span>
3463      One-time Purchase
3464      <div class="variety-save-tag one-time"></div>
3465      <span class="once-variety-price variety-price"><span class="variety-original-price opacity-50"></span></span>
3466    </div>
3467    <div class="variety-flavor-options" id="variety-oneTimeFlavors">
3468      <button data-citrus-count="2" data-mint-count="1" class="variety-qty once active font-body-medium">
3469        2 Citrus & 1 Mint
3470      </button>
3471      <button data-citrus-count="1" data-mint-count="2" class="variety-qty once">2 Mint & 1 Citrus</button>
3472    </div>
3473  </label>
3474
3475  <!-- Add to Cart Button -->
3476  <button id="variety-add-to-cart" class="!w-full button mt-6">
3477    <span class="variety_atc_text">Add to Cart</span>
3478    <span class="variety_atc_btn"></span>
3479  </button>
3480</div>
3481
3482<script>
3483  document.addEventListener("DOMContentLoaded", function () {
3484    const flavorButtons = document.querySelectorAll('.flavour-custom');
3485    const varietyButton = document.querySelector('.variety-selector-btn');
3486    const oneTimeContainer = document.querySelector('.one_time_container');
3487    const varietySelectionContainer = document.querySelector('.variety-selection-container');
3488    const purchaseTypeRadios = document.querySelectorAll('input[name="variety-purchaseType"]');
3489    const addToCartButton = document.getElementById('variety-add-to-cart');
3490    const subscribeSelectContainer = document.getElementById('subscribe-selling-plan');
3491    const subscribeOriginalPrice = document.querySelector('.subs-variety-price');
3492    const oneTimeOriginalPrice = document.querySelector('.once-variety-price');
3493    const subscriptionSave = document.querySelector('.variety-save-tag.subscribe-save');
3494    const oneTimeSave = document.querySelector('.variety-save-tag.one-time');
3495    const activeSubscription = document.querySelector('.variety-flavor-options .variety-qty.subs.active');
3496
3497    function lockVarietyActiveClass() {
3498      document.querySelectorAll('#variety-subscribeBox, #variety-oneTimeBox').forEach((box) => {
3499        box.classList.add('variety-active');
3500      });
3501    }
3502
3503    function protectVarietyActiveClass() {
3504      document.querySelectorAll('#variety-subscribeBox, #variety-oneTimeBox').forEach((box) => {
3505        lockVarietyActiveClass();
3506        new MutationObserver(() => {
3507          if (!box.classList.contains('variety-active')) {
3508            box.classList.add('variety-active');
3509          }
3510        }).observe(box, { attributes: true, attributeFilter: ['class'] });
3511      });
3512    }
3513
3514    protectVarietyActiveClass();
3515
3516    const citrusGroupImgUrl = "//revitin.com/cdn/shop/t/129/assets/citrus-group.png?v=161376326643237091681777542403";
3517    const citrusSeparatedImgUrl = "//revitin.com/cdn/shop/t/129/assets/citrus-separated.png?v=152161151921604416161777542404";
3518    const mintGroupImgUrl = "//revitin.com/cdn/shop/t/129/assets/mint-group.png?v=163306762873594723801777542406";
3519
3520    // Check for URL parameter and auto-select variety
3521    const urlParams = new URLSearchParams(window.location.search);
3522    const pathname = window.location.pathname;
3523
3524    if (urlParams.get('pack') === 'variety' || pathname.includes("variety-pack-2-mint-1-citrus")) {
3525      // Use setTimeout to ensure all elements are properly loaded
3526      setTimeout(() => {
3527        handleVarietyButtonClick();
3528        addSubscriptionsHtml();
3529        updateSubscriptionPrice();
3530        updateOneTimePrice();
3531        updateBannerImages();
3532      }, 100);
3533    }
3534    
3535    // Store product data
3536    let productsData = [];
3537    
3538    function getAllProducts() {
3539      const products = JSON.parse(document.getElementById('all-products-json').textContent);
3540      
3541      productsData = products.filter((item) => item.title.toLowerCase().includes("var") || item.handle.toLowerCase().includes("var"));
3542      updateAddToCartButton();
3543    }
3544
3545    getAllProducts();
3546
3547    const citrusImages = ["//revitin.com/cdn/shop/files/citrus-gallery-render_12zon_1600x.jpg",
3548      "//revitin.com/cdn/shop/files/citrus-gallery-2_11zon_1600x.jpg?v=1729881153",
3549      "//revitin.com/cdn/shop/files/citrus-gallery-3_11zon_1600x.jpg?v=1751389467",
3550      "//revitin.com/cdn/shop/files/citrus-render_560x.png?v=1751390073",
3551      "//revitin.com/cdn/shop/files/mint-render_560x.png?v=1751387541",
3552      "//revitin.com/cdn/shop/files/citrus-gallery-render-mobile_13zon_1000x.jpg"
3553    ];
3554
3555    function hideSubscribeContainers(sections) {
3556        const hideFunc = () => {
3557          sections.forEach((btn) => btn.classList.add("hidden"));
3558        };
3559
3560        // Run immediately once
3561        hideFunc();
3562
3563        // Observe for future DOM changes
3564        const observer = new MutationObserver(() => {
3565          hideFunc();
3566        });
3567
3568        observer.observe(document.body, {
3569          childList: true,
3570          subtree: true,
3571        });
3572    }
3573    
3574    document.body.addEventListener("click", function (event) {
3575      if (!event.target || typeof event.target.closest !== 'function') return;
3576      if (event.target.closest('.variety-selector-btn')) {
3577        const sections = document.querySelectorAll(
3578              `.subscription-box`
3579        );
3580        hideSubscribeContainers(sections);
3581        handleVarietyButtonClick();
3582        addSubscriptionsHtml();
3583        updateSubscriptionPrice();
3584        updateOneTimePrice();
3585        updateBannerImages();
3586      } else if (event.target.closest('.flavour-custom')) {
3587        handleFlavorButtonClick(event.target.closest('.flavour-custom'));
3588      } else if (event.target.closest('.variety-qty')) {
3589        const clickedQuantity = event.target.closest('.variety-qty');
3590
3591        updateBannerImages(clickedQuantity);
3592        addSubscriptionsHtml(clickedQuantity);
3593        handleVarietyQtyClick(clickedQuantity);
3594        updateAddToCartButton();
3595      } else if (event.target.closest('.variety-box')) {
3596      const varietyBox = event.target.closest('.variety-box');
3597      if (varietyBox.id === 'variety-subscribeBox') {
3598        const subsButtons = document.querySelectorAll('#variety-subscribeFlavors .variety-qty.subs');
3599        const hasActiveSubsButton = Array.from(subsButtons).some(btn => btn.classList.contains('active'));
3600        if (!hasActiveSubsButton) {
3601          setTimeout(() => {
3602            const citrusMintButton = document.querySelector('#variety-subscribeFlavors .variety-qty[data-citrus-count="2"][data-mint-count="1"]');
3603            if (citrusMintButton) {
3604              citrusMintButton.click();
3605              handleVarietyQtyClick(citrusMintButton);
3606              updateSubscriptionPrice();
3607              updateBannerImages(citrusMintButton);
3608              addSubscriptionsHtml(citrusMintButton);
3609              updateAddToCartButton();
3610            }
3611          }, 50);
3612        }
3613      }
3614    }
3615    });
3616    
3617    document.body.addEventListener("change", function (event) {
3618      if (event.target.name === "variety-purchaseType" && event.target.type === "radio") {
3619        handlePurchaseTypeBehaviour(event.target);
3620        handlePurchaseTypeChange(event.target.value === "subscribe");
3621        updateAddToCartButton();
3622        updateBannerImages();
3623      } else if (event.target.id === "subscribe-selling-plan") {
3624        updateAddToCartButton();
3625        updateBannerImages();
3626      }
3627    });
3628    
3629    // Initialize on load
3630    const checkedRadio = document.querySelector('input[name="variety-purchaseType"]:checked');
3631    if (checkedRadio) {
3632      handlePurchaseTypeChange(checkedRadio.value === "subscribe");
3633    }
3634    
3635    // Add to cart functionality
3636    addToCartButton.addEventListener('click', function() {
3637      const isSubscription = document.querySelector('input[name="variety-purchaseType"]:checked').value === "subscribe";
3638      const activeQtyButton = document.querySelector(`.variety-flavor-options${isSubscription ? '.subs-btn' : ''} .variety-qty.${isSubscription ? "subs":"once"}.active`);
3639      const sellingPlanValue = document.getElementById('subscribe-selling-plan').value;
3640      const cartCount = document.querySelector(".variety-cart-count");
3641      
3642      const citrusCount = parseInt(activeQtyButton.dataset.citrusCount);
3643      const mintCount = parseInt(activeQtyButton.dataset.mintCount);
3644      
3645      const items = [];
3646
3647      if(citrusCount === 2 && mintCount === 1){
3648        const varietyProduct = productsData.filter((product) => product.handle === "citrus-mint-4-tubes");
3649        
3650        items.push({
3651          id: varietyProduct?.[0]?.variants?.[0]?.id,
3652          quantity: 1,
3653          selling_plan: isSubscription ? sellingPlanValue: null
3654        })
3655      }
3656
3657      if(citrusCount === 1 && mintCount === 2){
3658        const varietyProduct = productsData.filter((product) => product.handle === "variety-pack-2-mint-1-citrus");
3659        
3660        items.push({
3661          id: varietyProduct?.[0]?.variants?.[0]?.id,
3662          quantity: 1,
3663          selling_plan: isSubscription ? sellingPlanValue: null
3664        })
3665      }
3666      
3667      addMultipleItemsToCart(items);
3668      
3669    });
3670
3671    function handlePurchaseTypeBehaviour(radioBtn) {
3672      const subsButtons = document.querySelectorAll(".variety-qty.subs");
3673
3674      if(radioBtn.value === "onetime") {
3675        subsButtons.forEach(btn => {
3676          btn.classList.remove("active", "font-body-medium");
3677        });
3678      }
3679      
3680      if (radioBtn.value === "subscribe") {
3681        const hasActive = Array.from(subsButtons).some(btn => btn.classList.contains("active"));
3682
3683        if (!hasActive && subsButtons.length > 0) {
3684          subsButtons[0].classList.add("active", "font-body-medium");
3685        }
3686      }
3687    }
3688
3689    function updateBannerImages(clickedQuantity = null) {
3690      const isSubscription =
3691        document.querySelector('input[name="variety-purchaseType"]:checked').value ===
3692        "subscribe";
3693
3694      const selectedQtyBtn = document.querySelector(
3695        `.variety-flavor-options${isSubscription ? ".subs-btn" : ""} .variety-qty.${
3696          isSubscription ? "subs" : "once"
3697        }.active`
3698      );
3699
3700      const activeQtyButton = clickedQuantity ? clickedQuantity : selectedQtyBtn;
3701
3702      const mainVarietyImage = document.querySelector(".main_variety_image");
3703      const leftVarietyImage = document.querySelector(".left_variety_image");
3704      const rightVarietyImage = document.querySelector(".right_variety_image");
3705
3706      const allMainVarietyImages = document.querySelectorAll(".main_variety_image");
3707      
3708      const homePageBgCitrusImgElement = document.querySelector(".hm_bg_image_citrus");
3709      const homePageBgMintImgElement = document.querySelector(".hm_bg_image_mint");
3710
3711      const mobileMainVarietyImage = document.querySelector(".mobile_main_variety_image");
3712      const mobileLeftVarietyImage = document.querySelector(".mobile_left_variety_image");
3713      const mobileRightVarietyImage = document.querySelector(".mobile_right_variety_image");
3714      const isTravelVarietyBtnActive = document.querySelector(".ts-flavor-btn.ts-variety.active");
3715      const isTravelVarietyUrlActive = urlParams.get('pack') === 'variety' && urlParams.get('size') === 'travel';
3716
3717      
3718
3719      const citrusCount = parseInt(activeQtyButton.dataset.citrusCount);
3720      const mintCount = parseInt(activeQtyButton.dataset.mintCount);
3721
3722      let currentProductImages = [];
3723      let currentHomePageImage = "";
3724      let homePageDisplay = "";
3725      let currentTravelImages = [];
3726
3727
3728      if (citrusCount === 2 && mintCount === 1) {
3729        const varietyProduct = productsData.filter(
3730          (product) => product.handle === "citrus-mint-4-tubes"
3731        );
3732        currentHomePageImage = varietyProduct?.homepage_image;
3733        currentProductImages = varietyProduct?.[0]?.images || [];
3734        homePageDisplay = citrusGroupImgUrl;
3735      }
3736
3737      if (citrusCount === 1 && mintCount === 2) {
3738        const varietyProduct = productsData.filter(
3739          (product) => product.handle === "variety-pack-2-mint-1-citrus"
3740        );
3741        currentHomePageImage = varietyProduct?.homepage_image;
3742        currentProductImages = varietyProduct?.[0]?.images || [];
3743        homePageDisplay = mintGroupImgUrl;
3744      }
3745
3746      if (isTravelVarietyBtnActive || isTravelVarietyUrlActive) {
3747        const varietyTravelProduct = productsData.filter(
3748          (product) => product.handle === "variety-travel-4-pack-of-1-oz"
3749        );
3750        currentTravelImages = varietyTravelProduct?.[0]?.images || [];
3751      }
3752
3753      
3754
3755      // ✅ update DOM if images exist
3756      if (currentProductImages.length >= 3) {
3757        if(isTravelVarietyBtnActive || isTravelVarietyUrlActive) {
3758          if(mainVarietyImage) mainVarietyImage.src = currentTravelImages[0].src;
3759          if(mainVarietyImage) mainVarietyImage.alt = currentTravelImages[0].alt;        
3760        } else {
3761          allMainVarietyImages.forEach((element) => {
3762            if(element) element.src = currentProductImages[0].src;
3763            if(element) element.alt = currentProductImages[0].alt;
3764          })
3765        }
3766
3767        if(isTravelVarietyBtnActive || isTravelVarietyUrlActive) {
3768          if(mobileMainVarietyImage) mobileMainVarietyImage.src = currentTravelImages[1].src;
3769          if(mobileMainVarietyImage) mobileMainVarietyImage.alt = currentTravelImages[1].alt;       
3770        } else {
3771          if(mobileMainVarietyImage) mobileMainVarietyImage.src = currentProductImages[4].src;
3772          if(mobileMainVarietyImage) mobileMainVarietyImage.alt = currentProductImages[4].alt;
3773        }
3774
3775        
3776
3777        if(leftVarietyImage) leftVarietyImage.src = currentProductImages[1].src;
3778        if(leftVarietyImage) leftVarietyImage.alt = currentProductImages[1].alt;
3779
3780        if(mobileLeftVarietyImage) mobileLeftVarietyImage.src = currentProductImages[1].src;
3781        if(mobileLeftVarietyImage) mobileLeftVarietyImage.alt = currentProductImages[1].alt;
3782
3783        // Normal PDP: Variety uses Citrus gallery right-2 / right-2-mob overrides.
3784        // On travel Variety, skip these overrides so the "Right Image 2" gallery image is NOT shown.
3785        const right2 = window.RevitinGalleryRight2;
3786        const isTravelVarietyActive = isTravelVarietyBtnActive || isTravelVarietyUrlActive;
3787        const useCitrusRight2 = !isTravelVarietyActive && right2?.enabled && right2?.citrusRight;
3788        const useCitrusRight2Mobile = !isTravelVarietyActive && right2?.enabled && right2?.citrusRightMobile;
3789
3790        if (rightVarietyImage) {
3791          rightVarietyImage.src = useCitrusRight2 ? right2.citrusRight : currentProductImages[2].src;
3792          if (!useCitrusRight2) rightVarietyImage.alt = currentProductImages[2].alt;
3793        }
3794
3795        if (mobileRightVarietyImage) {
3796          mobileRightVarietyImage.src = useCitrusRight2Mobile
3797            ? right2.citrusRightMobile
3798            : currentProductImages[6].src;
3799          if (!useCitrusRight2Mobile) mobileRightVarietyImage.alt = currentProductImages[6].alt;
3800        }
3801
3802        if(homePageBgCitrusImgElement && homePageDisplay) homePageBgCitrusImgElement.src = homePageDisplay;
3803        if(homePageBgCitrusImgElement) homePageBgCitrusImgElement.classList.add("transform-image");
3804        
3805        if(homePageBgMintImgElement && homePageDisplay) homePageBgMintImgElement.src = homePageDisplay;
3806        if(homePageBgMintImgElement) homePageBgMintImgElement.classList.add("transform-image");
3807      }
3808    }
3809
3810    function formatPrice(value) {
3811      const dollars = value / 100;
3812      return dollars % 1 === 0 ? `$${dollars.toFixed(0)}` : `$${dollars.toFixed(2)}`;
3813    }
3814
3815    function trimZeroes(price) {
3816      return Number(price) % 1 === 0 
3817        ? Number(price).toString()        // show as integer (51)
3818        : Number(price).toFixed(2);       // keep 2 decimals if needed
3819    }
3820
3821    function addSubscriptionsHtml(clickedQuantity = null) {
3822      const activeQtyButton = clickedQuantity ? clickedQuantity : activeSubscription;
3823      const citrusCount = parseInt(activeQtyButton.dataset.citrusCount);
3824      const mintCount = parseInt(activeQtyButton.dataset.mintCount);
3825      const isSubscribedBtn = activeQtyButton.classList.contains("subs");
3826
3827      let subscriptions = [];
3828
3829      if(citrusCount === 2 && mintCount === 1){
3830        const varietyProduct = productsData.filter((product) => product.handle === "citrus-mint-4-tubes");
3831        const sellingPlans = varietyProduct?.[0]?.variants?.[0]?.sellingPlans;
3832        subscriptions = sellingPlans;
3833      }
3834
3835      if(citrusCount === 1 && mintCount === 2){
3836        const varietyProduct = productsData.filter((product) => product.handle === "variety-pack-2-mint-1-citrus");
3837        const sellingPlans = varietyProduct?.[0]?.variants?.[0]?.sellingPlans;
3838        subscriptions = sellingPlans;
3839      }
3840
3841      if(!subscriptions?.length) return;
3842      if(!isSubscribedBtn) return;
3843
3844      const subscriptionsHtml = subscriptions.map((subscription) => {
3845        const monthFormatter = (text) => {
3846          // Extract the number from the subscription name
3847          const match = text.match(/(\d+)/); 
3848          if (!match) return text; // fallback if no number found
3849
3850          const num = parseInt(match[1], 10);
3851          return num === 1 ? "month" : `${num} months`;
3852        };
3853
3854        const formattedMonth = monthFormatter(subscription?.name);
3855
3856        // Example: select 3 months by default
3857        const isSelected = formattedMonth === "3 months";
3858
3859        return `<option value="${subscription?.id}" ${isSelected ? "selected" : ""}>${formattedMonth}</option>`;
3860      });
3861
3862      subscribeSelectContainer.innerHTML = subscriptionsHtml.join("");
3863    }
3864
3865    function updateOneTimePrice() {
3866      const activeQtyButton = document.querySelector('.variety-qty.once.active');
3867      if (!activeQtyButton) return;
3868
3869      const { compare_at_price: compareAtPrice, price } = productsData?.[0]?.variants?.[0] || {};
3870
3871      if (!price || !compareAtPrice) return;
3872
3873      if (!oneTimeOriginalPrice) return;
3874
3875      const formatPrice = (price) => {
3876        let formatted = (typeof price === 'number' ? price.toFixed(2) : price);
3877
3878        if (formatted.endsWith('.00')) {
3879          formatted = formatted.replace('.00', '');
3880        }
3881
3882        return formatted;
3883      };
3884
3885      const savingPercentage = Math.round(((compareAtPrice - price) / compareAtPrice) * 100);
3886
3887      console.log("compare", compareAtPrice, price, savingPercentage);
3888
3889      if(oneTimeSave) oneTimeSave.textContent = `Save ${savingPercentage}%`;
3890
3891      oneTimeOriginalPrice.innerHTML = `$${formatPrice(price)}<span class="variety-original-price opacity-50">$${formatPrice(compareAtPrice)}</span>`;
3892    }
3893
3894    function updateSubscriptionPrice() {
3895      const { compare_at_price: compareAtPrice } = productsData?.[0]?.variants?.[0] || {};
3896      const { price } = productsData?.[1]?.variants?.[0].sellingPlans?.[0] || {};
3897
3898      if (!price || !compareAtPrice) return;
3899
3900      const savingPercentage = Math.round(
3901        ((compareAtPrice - price / 100) / compareAtPrice) * 100
3902      );
3903
3904      if (!subscribeOriginalPrice) return;
3905      if(!subscriptionSave) return;
3906
3907      subscriptionSave.textContent = `Save ${savingPercentage}%`;
3908      const formatPrice = (priceInCents) => {
3909        const dollars = priceInCents / 100;
3910        return dollars % 1 === 0 ? dollars : dollars.toFixed(2);
3911      };
3912
3913      const formatCompareAtPrice = (price) => {
3914        let formatted = (typeof price === 'number' ? price.toFixed(2) : price);
3915
3916        if (formatted.endsWith('.00')) {
3917          formatted = formatted.replace('.00', '');
3918        }
3919
3920        return formatted;
3921      };
3922
3923      subscribeOriginalPrice.innerHTML = `$${formatPrice(price)}<span class="variety-original-price opacity-50">$${formatCompareAtPrice(compareAtPrice)}</span>`;
3924    }
3925    
3926    function addMultipleItemsToCart(items) {
3927        const cartCount = document.querySelector(".variety-cart-count");
3928        const isSubscriptionAdd = items.some((item) => !!item.selling_plan);
3929
3930        const finalizeAdd = (payloadItems) => {
3931          fetch('/cart/add.js', {
3932              method: 'POST',
3933              headers: {
3934                  'Content-Type': 'application/json'
3935              },
3936              body: JSON.stringify({ items: payloadItems })
3937          })
3938          .then(response => response.json())
3939          .then((cart) => {
3940              if (window.updateCartUI) {
3941                  window.updateCartUI(cart);
3942              } else {
3943                  window.dispatchEvent(new Event('cart:refresh'));
3944              }
3945
3946              if(cart.items){
3947                document.querySelector('.site-cart').classList.add("active");
3948                cartCount.textContent = parseInt(cartCount?.textContent) + 1;
3949              }
3950          })
3951          .catch(error => {
3952              console.error('Error:', error);
3953          });
3954        };
3955
3956        // GWP: stamp line-item properties on PDP variety subscription ATC (no gift product)
3957        // Skip on wholesale / blocked landing templates
3958        if (
3959          isSubscriptionAdd &&
3960          window.RevitinGWP &&
3961          window.RevitinGWP.enabled !== false &&
3962          typeof window.RevitinGWP.getPdpGwpProperties === 'function'
3963        ) {
3964          fetch('/cart.js')
3965            .then((r) => r.json())
3966            .then((cartData) => {
3967              const gwpProperties = window.RevitinGWP.getPdpGwpProperties(cartData);
3968              let stamped = false;
3969              const payloadItems = items.map((item) => {
3970                if (!item.selling_plan || !gwpProperties || stamped) return item;
3971                stamped = true;
3972                return Object.assign({}, item, {
3973                  properties: Object.assign({}, item.properties || {}, gwpProperties),
3974                });
3975              });
3976              return { payloadItems, stamped: !!gwpProperties && stamped };
3977            })
3978            .then(({ payloadItems, stamped }) => {
3979              fetch('/cart/add.js', {
3980                method: 'POST',
3981                headers: { 'Content-Type': 'application/json' },
3982                body: JSON.stringify({ items: payloadItems }),
3983              })
3984                .then((response) => response.json())
3985                .then(async (cart) => {
3986                  if (window.updateCartUI) {
3987                    window.updateCartUI(cart);
3988                  } else {
3989                    window.dispatchEvent(new Event('cart:refresh'));
3990                  }
3991
3992                  if (cart.items) {
3993                    document.querySelector('.site-cart').classList.add('active');
3994                    cartCount.textContent = parseInt(cartCount?.textContent) + 1;
3995                  }
3996
3997                  try {
3998                    if (
3999                      stamped &&
4000                      typeof window.RevitinGWP.ensureGiftAttributes === 'function'
4001                    ) {
4002                      await window.RevitinGWP.ensureGiftAttributes();
4003                    } else if (
4004                      !stamped &&
4005                      typeof window.RevitinGWP.markGiftFromPdp === 'function'
4006                    ) {
4007                      // Fallback: stamp after add if properties were not included in payload
4008                      await window.RevitinGWP.markGiftFromPdp();
4009                    }
4010                  } catch (_) {}
4011                })
4012                .catch((error) => {
4013                  console.error('Error:', error);
4014                });
4015            })
4016            .catch(() => finalizeAdd(items));
4017          return;
4018        }
4019
4020        finalizeAdd(items);
4021    }
4022    
4023    function updateAddToCartButton() {}
4024
4025    function addVarietyToUrl() {
4026      const url = new URL(window.location);
4027      url.searchParams.set('pack', 'variety');
4028      window.history.replaceState({}, '', url);
4029    }
4030
4031    function resetSliderDots(currentTab) {
4032      // Get the main container
4033      const container = document.querySelector('.pdp_slider_container');
4034      if (!container) return;
4035
4036      // Find both flavor sections within the container
4037      const citrusSection = container.querySelector('[data-swap-flavor="Citrus"]');
4038      const mintSection = container.querySelector('[data-swap-flavor="Mint"]');
4039
4040      console.log("currentTab", currentTab);
4041
4042      if(currentTab === "Variety") {
4043        mintSection.classList.remove("!opacity-100");
4044        mintSection.classList.add("opacity-0");
4045
4046        citrusSection.classList.add("!opacity-100");
4047        citrusSection.classList.remove("opacity-0");
4048      }
4049
4050      // Reset Mint dots
4051      if (mintSection) {
4052        const mintDots = mintSection.querySelectorAll('.progress-slider-dot');
4053        mintDots.forEach(dot => {
4054          dot.classList.remove('active');
4055          
4056          // Reset the progress width to 0
4057          const progressSpan = dot.querySelector('.dot-progress');
4058          if (progressSpan) {
4059            progressSpan.style.width = '0%';
4060            progressSpan.style.transition = 'none';
4061          }
4062        });
4063        
4064        // Activate the first dot in Mint
4065        if (mintDots.length > 0) {
4066          mintDots[0].classList.add('active');
4067          mintDots[0].click();
4068        }
4069      }
4070
4071      // Reset Citrus dots
4072      if (citrusSection) {
4073        const citrusDots = citrusSection.querySelectorAll('.progress-slider-dot');
4074        citrusDots.forEach(dot => {
4075          dot.classList.remove('active');
4076          
4077          // Reset the progress width to 0
4078          const progressSpan = dot.querySelector('.dot-progress');
4079          if (progressSpan) {
4080            progressSpan.style.width = '0%';
4081            progressSpan.style.transition = 'none';
4082          }
4083        });
4084        
4085        // Activate the first dot in Citrus
4086        if (citrusDots.length > 0) {
4087          citrusDots[0].classList.add('active');
4088          citrusDots[0].click();
4089        }
4090      }
4091    }
4092    
4093    function handleVarietyButtonClick() {
4094      varietySelectionContainer.style.display = 'block';
4095      varietyButton.style.background = '#F5EEE0'; 
4096      varietyButton.style.borderColor = '#5F471D';
4097      document.querySelector('.main__atc__button').style.display = 'none';
4098      const detailsLink = document.querySelector('.ts-details-link');
4099
4100      if(detailsLink){
4101        detailsLink.href = `/products/revitin-natural-toothpaste/Citrus?pack=variety`;
4102      }
4103
4104      if (oneTimeContainer) {
4105        oneTimeContainer.style.display = 'none';
4106      }
4107
4108      document.querySelectorAll('.once_tube_container').forEach(el => el.classList.add('hidden'));
4109      document.querySelectorAll('.subscription-box').forEach(el => el.style.display = 'none');
4110
4111      addVarietyToUrl();
4112      resetFlavorButtons();
4113      updateAddToCartButton();
4114      resetSliderDots("Variety");
4115    }
4116
4117    function updateDetailsLink(flavor) {
4118      const detailsLink = document.querySelector(".ts-details-link");
4119
4120      if (detailsLink) {
4121        detailsLink.style.display = 'block';
4122        detailsLink.href = `/products/revitin-natural-toothpaste/${flavor}`;
4123      }
4124    }
4125
4126    function handleFlavorButtonClick(clickedButton) {
4127      const mainVarietyImage = document.querySelector(".main_variety_image");
4128      const leftVarietyImage = document.querySelector(".left_variety_image");
4129      const rightVarietyImage = document.querySelector(".right_variety_image");
4130
4131      const mobileMainVarietyImage = document.querySelector(".mobile_main_variety_image");
4132      const mobileLeftVarietyImage = document.querySelector(".mobile_left_variety_image");
4133      const mobileRightVarietyImage = document.querySelector(".mobile_right_variety_image");
4134
4135      const homePageBgCitrusImgElement = document.querySelector(".hm_bg_image_citrus");
4136      const homePageBgMintImgElement = document.querySelector(".hm_bg_image_mint");
4137
4138      varietySelectionContainer.style.display = 'none';
4139      varietyButton.classList.remove('active');
4140      varietyButton.style.border = '1px solid #C6C6C6';
4141      varietyButton.style.background = 'transparent';
4142      document.querySelector('.main__atc__button').style.display = 'flex';
4143
4144      if (oneTimeContainer) {
4145        oneTimeContainer.style.display = 'flex';
4146      }
4147      
4148      resetFlavorButtons();
4149      resetSliderDots();
4150      
4151      clickedButton.classList.add('active');
4152
4153      if (clickedButton.dataset.flavor === 'Citrus') {
4154        clickedButton.style.background = '#ffdea3'; 
4155        clickedButton.style.borderColor = '#FFBB42';
4156
4157        if(mainVarietyImage) mainVarietyImage.src = citrusImages?.[0];
4158        if(leftVarietyImage) leftVarietyImage.src = citrusImages?.[1];
4159        if(rightVarietyImage) {
4160          rightVarietyImage.src = (window.RevitinGalleryRight2?.enabled && window.RevitinGalleryRight2?.citrusRight)
4161            ? window.RevitinGalleryRight2.citrusRight
4162            : citrusImages?.[2];
4163        }
4164
4165        
4166        if(mobileMainVarietyImage) mobileMainVarietyImage.src = citrusImages?.[5];
4167        if(mobileLeftVarietyImage) mobileLeftVarietyImage.src = citrusImages?.[1];
4168        if(mobileRightVarietyImage) {
4169          mobileRightVarietyImage.src = (window.RevitinGalleryRight2?.enabled && window.RevitinGalleryRight2?.citrusRightMobile)
4170            ? window.RevitinGalleryRight2.citrusRightMobile
4171            : citrusImages?.[2];
4172        }
4173        if(homePageBgCitrusImgElement) homePageBgCitrusImgElement.src = citrusImages?.[3];
4174        if(homePageBgCitrusImgElement) homePageBgCitrusImgElement.classList.remove("transform-image");
4175        updateDetailsLink("Citrus");
4176      } else if (clickedButton.dataset.flavor === 'Mint') {
4177        const products = JSON.parse(document.getElementById('all-products-json').textContent);
4178        const targetProduct = products.find(product => {
4179          const productTitle = product.title?.toLowerCase();
4180
4181          if (!productTitle?.includes("single tube")) return false;
4182
4183          return product.variants?.some(variant =>
4184            variant.title?.toLowerCase().includes("mint")
4185          );
4186        });
4187
4188        const mintMainVarietyImage = document.querySelector(
4189          '.image_update_container [data-swap-flavor="Mint"] .main_variety_image'
4190        );
4191
4192        console.log('productsData', targetProduct?.images?.[0]?.src);
4193        if(mintMainVarietyImage) mintMainVarietyImage.src = targetProduct?.images?.[0]?.src;
4194
4195        if(homePageBgMintImgElement) homePageBgMintImgElement.src = citrusImages?.[4];
4196        if(homePageBgMintImgElement) homePageBgMintImgElement.classList.remove("transform-image");
4197        clickedButton.style.background = '#e5ecd1'; 
4198        clickedButton.style.borderColor = '#9ca975';
4199        updateDetailsLink("Mint");
4200      }
4201    }
4202
4203    function handleVarietyQtyClick(clickedButton) {
4204      const parentContainer = clickedButton.closest('.variety-flavor-options');
4205      parentContainer.querySelectorAll('.variety-qty').forEach(btn => {
4206        btn.classList.remove('active');
4207        btn.classList.remove('font-body-medium');
4208      });
4209
4210      clickedButton.classList.add('active');
4211      clickedButton.classList.add('font-body-medium');
4212      
4213      // NEW CODE: Select the parent radio button
4214      const parentLabel = clickedButton.closest('.variety-box');
4215      const radioInput = parentLabel.querySelector('.variety-radio-input');
4216      if (radioInput) {
4217        radioInput.checked = true;
4218        // Trigger the change event to update the UI
4219        const event = new Event('change', { bubbles: true });
4220        radioInput.dispatchEvent(event);
4221      }
4222    }
4223
4224    function handlePurchaseTypeChange(isSubscribe) {
4225      const subscribeBox = document.getElementById("variety-subscribeBox");
4226      const oneTimeBox = document.getElementById("variety-oneTimeBox");
4227      const subscribeFlavors = document.getElementById("variety-subscribeFlavors");
4228      const oneTimeFlavors = document.getElementById("variety-oneTimeFlavors");
4229
4230      subscribeBox.classList.add("variety-active");
4231      oneTimeBox.classList.add("variety-active");
4232
4233      subscribeBox.classList.toggle("transparent-box", !isSubscribe);
4234      oneTimeBox.classList.toggle("transparent-box", isSubscribe);
4235
4236      
4237      if (isSubscribe) {
4238        subscribeFlavors.classList.add("variety-show");
4239        oneTimeFlavors.classList.remove("variety-show");
4240      } else {
4241        subscribeFlavors.classList.remove("variety-show");
4242        oneTimeFlavors.classList.add("variety-show");
4243      }
4244    }
4245
4246    function resetFlavorButtons() {
4247      flavorButtons.forEach(button => {
4248        button.classList.remove('active');
4249        button.style.border = '1px solid #C6C6C6';
4250        button.style.background = 'transparent';
4251        
4252      });
4253    }
4254  });
4255</script>
4255
4256
4257<style>
4258      @media (min-width: 1024px) {
4259        .transform-image {
4260          transform: scale(1.8) translate(10%, 10%);
4261        }
4262      }
4263
4264
4265      @media (max-width: 768px) {
4266        .variety-original-price {
4267          font-size: 12px !important;
4268        }
4269
4270        .variety-price {
4271          position: relative;
4272        }
4273
4274        .variety-flavor-options button {
4275          font-size: 13px !important;
4276          padding: 0.6rem 0.8rem !important;
4277        }
4278
4279        .variety-flavor-options {
4280          margin-top: 1.4rem;
4281        }
4282      }
4283
4284
4285      .variety-qty.active{
4286          border: 1.3px solid #5F471D;
4287      }
4288
4289      .variety-selling-plan-select {
4290        outline: none;
4291        border: none;
4292        appearance: none;
4293        -webkit-appearance: none;
4294        -moz-appearance: none;
4295        padding: 0px 0px 0px 1px;
4296        background: #ff000000;
4297        text-decoration: underline;
4298      }
4299
4300      .variety-selection-container {
4301        margin-top: 2.1rem;
4302        display: none;
4303      }
4304
4305      .variety-box {
4306        display: block;
4307        border: 1px solid #5F471D;
4308        border-radius: 10px;
4309        padding: 1.1rem 1rem 1.7rem 1rem;
4310        margin-bottom: 1rem;
4311        position: relative;
4312        cursor: pointer;
4313      }
4314
4315      .variety-box.variety-active {
4316        border: 1px solid #5F471D;
4317        background-color: #F7EEDE;
4318      }
4319
4320      #variety-subscribeBox.transparent-box,
4321      #variety-oneTimeBox.transparent-box  {
4322        background-color: transparent;
4323      }
4324
4325      .variety-radio-group {
4326        display: flex;
4327        align-items: center;
4328        gap: 10px;
4329        font-weight: bold;
4330        position: relative;
4331      }
4332
4333      .variety-save-tag {
4334        position: absolute;
4335        background-color: #FEFBF0;
4336        color: #5F471D;
4337        padding: 6px 9px !important;
4338        font-size: 12px;
4339        font-weight: normal;
4340        border-radius: 15px;
4341        bottom: -1.45rem;
4342        right: 0rem;
4343        line-height: 1;
4344      }
4345
4346      .variety-price {
4347        margin-left: auto;
4348        font-weight: bold;
4349      }
4350
4351      .variety-original-price {
4352        text-decoration: line-through;
4353        font-weight: normal;
4354        margin-right: 5px;
4355        font-size: 14px;
4356        padding-left: 4px;
4357      }
4358
4359      .variety-flavor-options {
4360        margin-top: 1.7rem;
4361        display: none;
4362        gap: 0.5rem;
4363      }
4364
4365      .variety-flavor-options.variety-show {
4366        display: flex;
4367      }
4368
4369      .variety-flavor-options button {
4370        padding: 0.6rem 1rem;
4371        background: rgb(255 251 239 / var(--tw-bg-opacity));
4372        border: 1px solid #5F471D80;
4373        border-radius: 6px;
4374        cursor: pointer;
4375        font-size: 16px;
4376        line-height: 1;
4377      }
4378
4379      .variety-description {
4380        margin-top: 0.5rem;
4381        font-size: 0.9rem;
4382      }
4383
4384      .variety-radio-input {
4385        display: none;
4386      }
4387
4388      .variety-radio-dot {
4389        height: 16px;
4390        width: 16px;
4391        border-radius: 50%;
4392        border: 1px solid  #5F471D;
4393        display: inline-block;
4394        position: relative;
4395      }
4396
4397      .variety-box input[type="radio"]:checked + .variety-radio-group .variety-radio-dot::after {
4398      content: "";
4399      position: absolute;
4400      top: 50%;
4401      left: 50%;
4402      transform: translate(-50%, -50%);
4403      width: 8px;
4404      height: 8px;
4405      background: #5F471D;
4406      border-radius: 50%;
4407      }
4408
4409      .variety-selector-btn {
4410        padding: 8px 16px 8px 8px;
4411      }
4412
4413      .variety-flavor-options.subs-btn {
4414         display: flex;
4415      }
4416
4417
4418      /* Hide by default */
4419  #variety-subscribeBox .variety-flavor-options,
4420  #variety-subscribeBox .variety-description {
4421    display: none;
4422  }
4423
4424  /* Show only when .variety-box has .variety-active */
4425  #variety-subscribeBox.variety-active .variety-flavor-options,
4426  #variety-subscribeBox.variety-active .variety-description {
4427    display: block;
4428  }
4429
4430  #variety-oneTimeBox:not(.variety-active) .once-variety-price {
4431        transform: translateY(-4px);
4432  }
4433
4434  #variety-oneTimeBox:not(.variety-active) .variety-save-tag.one-time {
4435        bottom: -1.15rem;
4436  }
4437
4438  #variety-oneTimeBox:not(.variety-active) .variety-save-tag {
4439    background-color: #F7EEDE;
4440  }
4441</style>
4442
4443    <form>
4444      <cadence-selector>
4445        <div class="grid grid-flow-col justify-start gap-3 mt-8 hidden">
4446          <button
4447            type="button"
4448            data-cadence="Subscribe"
4449            class="font-body-medium text-xs px-4 lg:px-6 py-2 rounded-t-md border-x border-t border-brown relative top-[1px] active"
4450          >
4451            Subscribe & Save
4452          </button>
4453        </div>
4454      </cadence-selector>
4455      <div class="rounded-r-lg rounded-b-lg product-form-container">
4456        <variant-selector>
4457          <div class=" subscription-box hidden" data-flavor="Citrus" data-cadence="Subscribe">
4458            <div>
4459              <div class="save_20">Subscribe & Save up to 20%</div>
4460              <div>
4461                <div class="benifit_text">Free shipping. Save on every order.</div>
4462                <div class="benifit_text">Easily edit, skip, or cancel anytime.</div>
4463                
4464              </div></div>
4465            
4466
4467             
4468
4469            
4470
4471            
4472
4473            
4474            
4475            
4476              
4477              
4478
4479              
4480
4481              
4482                
4483                  
4484                  
4485                  
4486                
4487              
4488                
4489                  
4490                  
4491                  
4492                
4493              
4494                
4495                  
4496                  
4497                  
4498                    
4499                      <button
4500                        type="button"
4501                        data-variant-id="45594633666698"
4502                        data-flavor="Citrus"
4503                        class="variant-price-btn remove_one_time w-full"
4504                      >
4505                        <div class=" grid grid-cols-[16px_1fr] gap-3 items-start border-b border-brown/20 subscriptions_selection">
4506                          <div class="flex w-4 h-4 rounded-full border items-center pos-rel  justify-center cursor-pointer border border-brown">
4507                            <div class="bg-transparent appearance-none rounded-full w-2 h-2 cursor-pointer"></div>
4508                          </div>
4509                          <div>
4510                            <div class="grid grid-flow-col justify-between items-center">
4511                              <span class="text-base lg:text-lg">
4512                                
4513
4514                                
4515                                
4516                                  
4517                                    
4518                                    
4519                                    
4520                                      
4521                                    
4522                                  
4523                                  
4524                                
4525                                  
4526                                    
4527                                    
4528                                    
4529                                      
4530                                    
4531                                  
4532                                  
4533                                
4534                                  
4535                                    
4536                                    
4537                                    
4538                                      
4539                                        
4540                                        
4541                                  
4542                                    
4543                                
4544
4545                                
4546                                  Trio - 3 tubes
4547                                  <span class="most-popular-pill">Most Popular</span>
4548                                
4549                              </span>
4550                              <div class="grid grid-flow-col gap-1 justify-end text-sm lg:text-[0.9375rem] relative">
4551                                
4552                                  <span class="subscription_original">
4553                                    
4554                                    
4555                                      
4556                                    
4557                                      
4558                                    
4559                                      
4560                                        
4561                                        
4562                                    $42
4563                                  </span>
4564                                  <span class="line-through opacity-50">$51</span>
4565                                  
4566                                  
4567                                    
4568                                    
4569                                    <div class="save__amount">
4570                                      <p>Save 18%</p>
4571                                    </div>
4572                                  
4573
4574                                
4575                              </div>
4576                            </div>
4577                            <div
4578                              style="display: flex !important;"
4579                              class="delivery-options flex flex-col gap-2.5 items-start hidden"
4580                            >
4581                              <div class="flex gap-1 month-frequency">
4582                                <label for="subscribe-plan" class="flex text-brown cursor-pointer">
4583                                  <p>Delivered every</p>
4584                                </label>
4585                                <div class="relative">
4586                                  <select-input>
4587                                    <div class="frequency-selector">
4588                                      <select style="" class="frequency-select">
4589                                        <optgroup label="Select Frequency of delivery">
4590                                          
4591                                            
4592                                              
4593                                              
4594                                              
4595                                              
4596                                              <option
4597                                                value="1-month"
4598                                                
4599                                              >
4600                                                
4601                                                  month
4602                                                
4603                                              </option>
4604                                            
4605                                          
4606                                            
4607                                              
4608                                              
4609                                              
4610                                              
4611                                              <option
4612                                                value="2-months"
4613                                                
4614                                              >
4615                                                
4616                                                  2 months
4617                                                
4618                                              </option>
4619                                            
4620                                          
4621                                            
4622                                              
4623                                              
4624                                              
4625                                              
4626                                              <option
4627                                                value="3-months"
4628                                                
4629                                                  selected
4630                                                
4631                                              >
4632                                                
4633                                                  3 months
4634                                                
4635                                              </option>
4636                                            
4637                                          
4638                                            
4639                                              
4640                                              
4641                                              
4642                                              
4643                                              <option
4644                                                value="6-months"
4645                                                
4646                                              >
4647                                                
4648                                                  6 months
4649                                                
4650                                              </option>
4651                                            
4652                                          
4653                                        </optgroup>
4654                                      </select>
4655                                      <div class="flex items-center gap-2.5 border-b border-sand">
4656                                        <span
4657                                          style="text-transform: lowercase; font-weight: normal;"
4658                                          class="select-target text-sm text-sand month_selector"
4659                                        >
4660                                          
4661                                          
4662                                          
4663                                            3 months
4664                                          
4665                                        </span>
4666                                      </div>
4667                                    </div>
4668                                  </select-input>
4669                                </div>
4670                              </div>
4671                              <div class="flex flex-col items-start">
4672                                
4673                              </div>
4674                            </div>
4675                          </div>
4676                        </div>
4677                      </button>
4678                    
4679                  
4680                
4681              
4682                
4683                  
4684                  
4685                  
4686                    
4687                  
4688                
4689              
4690                
4691                  
4692                  
4693                  
4694                    
4695                  
4696                
4697              
4698                
4699                  
4700                  
4701                  
4702                    
4703                  
4704                
4705              
4706                
4707                  
4708                  
4709                  
4710                    
4711                  
4712                
4713              
4714                
4715                  
4716                  
4717                  
4718                    
4719                  
4720                
4721              
4722            
4723              
4724              
4725
4726              
4727
4728              
4729                
4730                  
4731                  
4732                  
4733                
4734              
4735                
4736                  
4737                  
4738                  
4739                
4740              
4741                
4742                  
4743                  
4744                  
4745                    
4746                  
4747                
4748              
4749                
4750                  
4751                  
4752                  
4753                    
4754                  
4755                
4756              
4757                
4758                  
4759                  
4760                  
4761                    
4762                      <button
4763                        type="button"
4764                        data-variant-id="45594652901514"
4765                        data-flavor="Citrus"
4766                        class="variant-price-btn remove_one_time w-full"
4767                      >
4768                        <div class=" grid grid-cols-[16px_1fr] gap-3 items-start border-b border-brown/20 subscriptions_selection">
4769                          <div class="flex w-4 h-4 rounded-full border items-center pos-rel  justify-center cursor-pointer border border-brown">
4770                            <div class="bg-transparent appearance-none rounded-full w-2 h-2 cursor-pointer"></div>
4771                          </div>
4772                          <div>
4773                            <div class="grid grid-flow-col justify-between items-center">
4774                              <span class="text-base lg:text-lg">
4775                                
4776
4777                                
4778                                
4779                                  
4780                                    
4781                                    
4782                                    
4783                                      
4784                                    
4785                                  
4786                                  
4787                                
4788                                  
4789                                    
4790                                    
4791                                    
4792                                      
4793                                    
4794                                  
4795                                  
4796                                
4797                                  
4798                                    
4799                                    
4800                                    
4801                                      
4802                                        
4803                                        
4804                                  
4805                                    
4806                                
4807
4808                                
4809                                  Family pack - 5 tubes
4810                                
4811                              </span>
4812                              <div class="grid grid-flow-col gap-1 justify-end text-sm lg:text-[0.9375rem] relative">
4813                                
4814                                  <span class="subscription_original">
4815                                    
4816                                    
4817                                      
4818                                    
4819                                      
4820                                    
4821                                      
4822                                        
4823                                        
4824                                    $68
4825                                  </span>
4826                                  <span class="line-through opacity-50">$85</span>
4827                                  
4828                                  
4829                                    
4830                                    
4831                                    <div class="save__amount">
4832                                      <p>Save 20%</p>
4833                                    </div>
4834                                  
4835
4836                                
4837                              </div>
4838                            </div>
4839                            <div
4840                              style="display: flex !important;"
4841                              class="delivery-options flex flex-col gap-2.5 items-start hidden"
4842                            >
4843                              <div class="flex gap-1 month-frequency">
4844                                <label for="subscribe-plan" class="flex text-brown cursor-pointer">
4845                                  <p>Delivered every</p>
4846                                </label>
4847                                <div class="relative">
4848                                  <select-input>
4849                                    <div class="frequency-selector">
4850                                      <select style="" class="frequency-select">
4851                                        <optgroup label="Select Frequency of delivery">
4852                                          
4853                                            
4854                                              
4855                                              
4856                                              
4857                                              
4858                                              <option
4859                                                value="1-month"
4860                                                
4861                                              >
4862                                                
4863                                                  month
4864                                                
4865                                              </option>
4866                                            
4867                                          
4868                                            
4869                                              
4870                                              
4871                                              
4872                                              
4873                                              <option
4874                                                value="2-months"
4875                                                
4876                                              >
4877                                                
4878                                                  2 months
4879                                                
4880                                              </option>
4881                                            
4882                                          
4883                                            
4884                                              
4885                                              
4886                                              
4887                                              
4888                                              <option
4889                                                value="3-months"
4890                                                
4891                                                  selected
4892                                                
4893                                              >
4894                                                
4895                                                  3 months
4896                                                
4897                                              </option>
4898                                            
4899                                          
4900                                            
4901                                              
4902                                              
4903                                              
4904                                              
4905                                              <option
4906                                                value="6-months"
4907                                                
4908                                              >
4909                                                
4910                                                  6 months
4911                                                
4912                                              </option>
4913                                            
4914                                          
4915                                        </optgroup>
4916                                      </select>
4917                                      <div class="flex items-center gap-2.5 border-b border-sand">
4918                                        <span
4919                                          style="text-transform: lowercase; font-weight: normal;"
4920                                          class="select-target text-sm text-sand month_selector"
4921                                        >
4922                                          
4923                                          
4924                                          
4925                                            3 months
4926                                          
4927                                        </span>
4928                                      </div>
4929                                    </div>
4930                                  </select-input>
4931                                </div>
4932                              </div>
4933                              <div class="flex flex-col items-start">
4934                                
4935                              </div>
4936                            </div>
4937                          </div>
4938                        </div>
4939                      </button>
4940                    
4941                  
4942                
4943              
4944                
4945                  
4946                  
4947                  
4948                    
4949                  
4950                
4951              
4952                
4953                  
4954                  
4955                  
4956                    
4957                  
4958                
4959              
4960                
4961                  
4962                  
4963                  
4964                    
4965                  
4966                
4967              
4968            
4969          </div>
4970        </variant-selector>
4971        <variant-selector>
4972          <div class="subscription-box hidden" data-flavor="Mint" data-cadence="Subscribe">
4973            <div>
4974              <div class="save_20">Subscribe & Save up to 20%</div>
4975              <div>
4976                <div class="benifit_text">Free shipping. Save on every order.</div>
4977                <div class="benifit_text">Easily edit, skip, or cancel anytime.</div>
4978                
4979              </div></div>
4980            
4981
4982            
4983
4984            
4985            
4986
4987            
4988            
4989            
4990              
4991              
4992              
4993                
4994                  
4995                  
4996                  
4997                
4998              
4999                
5000                  
5001                  
5002                  
5003                
5004              
5005                
5006                  
5007                  
5008                  
5009                    
5010                  
5011                
5012              
5013                
5014                  
5015                  
5016                  
5017                    
5018                      <button
5019                        type="button"
5020                        data-variant-id="45618606080138"
5021                        data-flavor="Mint"
5022                        class="variant-price-btn remove_one_time w-full"
5023                      >
5024                        <div class="grid grid-cols-[16px_1fr] gap-3 items-start border-b border-brown/20 subscriptions_selection py-3">
5025                          <div class="flex w-4 h-4 rounded-full border items-center pos-rel justify-center cursor-pointer border border-brown">
5026                            <div class="bg-transparent appearance-none rounded-full w-2 h-2 cursor-pointer"></div>
5027                          </div>
5028                          <div>
5029                            <div class="grid grid-flow-col justify-between items-center">
5030                              <span class="text-base lg:text-lg">
5031                                
5032
5033                                
5034                                
5035                                  
5036                                    
5037                                    
5038                                    
5039                                      
5040                                    
5041                                  
5042                                  
5043                                
5044                                  
5045                                    
5046                                    
5047                                    
5048                                      
5049                                    
5050                                  
5051                                  
5052                                
5053                                  
5054                                    
5055                                    
5056                                    
5057                                      
5058                                        
5059                                        
5060                                  
5061                                    
5062                                
5063                                
5064                                  Trio - 3 tubes
5065                                  <span class="most-popular-pill">Most Popular</span>
5066                                
5067                              </span>
5068                              <div class="grid grid-flow-col gap-1 justify-end text-sm lg:text-[0.9375rem] relative">
5069                                
5070                                  <span class="subscription_original">
5071                                    
5072                                    
5073                                      
5074                                    
5075                                      
5076                                    
5077                                      
5078                                        
5079                                        
5080                                    $42
5081                                  </span>
5082                                  <span class="line-through opacity-50">$51</span>
5083                                  
5084                                  
5085                                    
5086                                    
5087                                    <div class="save__amount">
5088                                      <p>Save 18%</p>
5089                                    </div>
5090                                  
5091
5092                                
5093                              </div>
5094                            </div>
5095                            <div
5096                              style="display: flex !important;"
5097                              class="delivery-options flex flex-col gap-2.5 items-start hidden"
5098                            >
5099                              <div class="flex gap-1 month-frequency">
5100                                <label for="subscribe-plan" class="flex text-brown cursor-pointer">
5101                                  <p>Delivered every</p>
5102                                </label>
5103                                <div class="relative">
5104                                  <select-input>
5105                                    <div class="frequency-selector">
5106                                      <select style="" class="frequency-select">
5107                                        <optgroup label="Select Frequency of delivery">
5108                                          
5109                                            
5110                                              
5111                                              
5112                                              
5113                                              
5114                                              <option
5115                                                value="1-month"
5116                                                
5117                                              >
5118                                                
5119                                                  month
5120                                                
5121                                              </option>
5122                                            
5123                                          
5124                                            
5125                                              
5126                                              
5127                                              
5128                                              
5129                                              <option
5130                                                value="2-months"
5131                                                
5132                                              >
5133                                                
5134                                                  2 months
5135                                                
5136                                              </option>
5137                                            
5138                                          
5139                                            
5140                                              
5141                                              
5142                                              
5143                                              
5144                                              <option
5145                                                value="3-months"
5146                                                
5147                                                  selected
5148                                                
5149                                              >
5150                                                
5151                                                  3 months
5152                                                
5153                                              </option>
5154                                            
5155                                          
5156                                            
5157                                              
5158                                              
5159                                              
5160                                              
5161                                              <option
5162                                                value="6-months"
5163                                                
5164                                              >
5165                                                
5166                                                  6 months
5167                                                
5168                                              </option>
5169                                            
5170                                          
5171                                        </optgroup>
5172                                      </select>
5173                                      <div class="flex items-center gap-2.5 border-b border-sand">
5174                                        <span
5175                                          style="text-transform: lowercase; font-weight: normal;"
5176                                          class="select-target text-sm text-sand month_selector"
5177                                        >
5178                                          
5179                                          
5180                                          
5181                                            3 months
5182                                          
5183                                        </span>
5184                                      </div>
5185                                    </div>
5186                                  </select-input>
5187                                </div>
5188                              </div>
5189                              <div class="flex flex-col items-start">
5190                                
5191                              </div>
5192                            </div>
5193                          </div>
5194                        </div>
5195                      </button>
5196                    
5197                  
5198                
5199              
5200                
5201                  
5202                  
5203                  
5204                    
5205                  
5206                
5207              
5208                
5209                  
5210                  
5211                  
5212                    
5213                  
5214                
5215              
5216                
5217                  
5218                  
5219                  
5220                    
5221                  
5222                
5223              
5224                
5225                  
5226                  
5227                  
5228                    
5229                  
5230                
5231              
5232            
5233              
5234              
5235              
5236                
5237                  
5238                  
5239                  
5240                
5241              
5242                
5243                  
5244                  
5245                  
5246                
5247              
5248                
5249                  
5250                  
5251                  
5252                    
5253                  
5254                
5255              
5256                
5257                  
5258                  
5259                  
5260                    
5261                  
5262                
5263              
5264                
5265                  
5266                  
5267                  
5268                    
5269                  
5270                
5271              
5272                
5273                  
5274                  
5275                  
5276                    
5277                      <button
5278                        type="button"
5279                        data-variant-id="45618689310858"
5280                        data-flavor="Mint"
5281                        class="variant-price-btn remove_one_time w-full"
5282                      >
5283                        <div class="grid grid-cols-[16px_1fr] gap-3 items-start border-b border-brown/20 subscriptions_selection py-3">
5284                          <div class="flex w-4 h-4 rounded-full border items-center pos-rel justify-center cursor-pointer border border-brown">
5285                            <div class="bg-transparent appearance-none rounded-full w-2 h-2 cursor-pointer"></div>
5286                          </div>
5287                          <div>
5288                            <div class="grid grid-flow-col justify-between items-center">
5289                              <span class="text-base lg:text-lg">
5290                                
5291
5292                                
5293                                
5294                                  
5295                                    
5296                                    
5297                                    
5298                                      
5299                                    
5300                                  
5301                                  
5302                                
5303                                  
5304                                    
5305                                    
5306                                    
5307                                      
5308                                    
5309                                  
5310                                  
5311                                
5312                                  
5313                                    
5314                                    
5315                                    
5316                                      
5317                                        
5318                                        
5319                                  
5320                                    
5321                                
5322                                
5323                                  Family pack - 5 tubes
5324                                
5325                              </span>
5326                              <div class="grid grid-flow-col gap-1 justify-end text-sm lg:text-[0.9375rem] relative">
5327                                
5328                                  <span class="subscription_original">
5329                                    
5330                                    
5331                                      
5332                                    
5333                                      
5334                                    
5335                                      
5336                                        
5337                                        
5338                                    $68
5339                                  </span>
5340                                  <span class="line-through opacity-50">$85</span>
5341                                  
5342                                  
5343                                    
5344                                    
5345                                    <div class="save__amount">
5346                                      <p>Save 20%</p>
5347                                    </div>
5348                                  
5349
5350                                
5351                              </div>
5352                            </div>
5353                            <div
5354                              style="display: flex !important;"
5355                              class="delivery-options flex flex-col gap-2.5 items-start hidden"
5356                            >
5357                              <div class="flex gap-1 month-frequency">
5358                                <label for="subscribe-plan" class="flex text-brown cursor-pointer">
5359                                  <p>Delivered every</p>
5360                                </label>
5361                                <div class="relative">
5362                                  <select-input>
5363                                    <div class="frequency-selector">
5364                                      <select style="" class="frequency-select">
5365                                        <optgroup label="Select Frequency of delivery">
5366                                          
5367                                            
5368                                              
5369                                              
5370                                              
5371                                              
5372                                              <option
5373                                                value="1-month"
5374                                                
5375                                              >
5376                                                
5377                                                  month
5378                                                
5379                                              </option>
5380                                            
5381                                          
5382                                            
5383                                              
5384                                              
5385                                              
5386                                              
5387                                              <option
5388                                                value="2-months"
5389                                                
5390                                              >
5391                                                
5392                                                  2 months
5393                                                
5394                                              </option>
5395                                            
5396                                          
5397                                            
5398                                              
5399                                              
5400                                              
5401                                              
5402                                              <option
5403                                                value="3-months"
5404                                                
5405                                                  selected
5406                                                
5407                                              >
5408                                                
5409                                                  3 months
5410                                                
5411                                              </option>
5412                                            
5413                                          
5414                                            
5415                                              
5416                                              
5417                                              
5418                                              
5419                                              <option
5420                                                value="6-months"
5421                                                
5422                                              >
5423                                                
5424                                                  6 months
5425                                                
5426                                              </option>
5427                                            
5428                                          
5429                                        </optgroup>
5430                                      </select>
5431                                      <div class="flex items-center gap-2.5 border-b border-sand">
5432                                        <span
5433                                          style="text-transform: lowercase; font-weight: normal;"
5434                                          class="select-target text-sm text-sand month_selector"
5435                                        >
5436                                          
5437                                          
5438                                          
5439                                            3 months
5440                                          
5441                                        </span>
5442                                      </div>
5443                                    </div>
5444                                  </select-input>
5445                                </div>
5446                              </div>
5447                              <div class="flex flex-col items-start">
5448                                
5449                              </div>
5450                            </div>
5451                          </div>
5452                        </div>
5453                      </button>
5454                    
5455                  
5456                
5457              
5458                
5459                  
5460                  
5461                  
5462                    
5463                  
5464                
5465              
5466                
5467                  
5468                  
5469                  
5470                    
5471                  
5472                
5473              
5474            
5475          </div>
5476        </variant-selector>
5477
5478        <cadence-selector>
5479          <div class="flex justify-between items-center pt-1 pb-6 bg-sand one_time_container">
5480            <div style="margin-left: 12px; padding-top: 15px;" class="flex items-center gap-2">
5481              <div>
5482                <!-- Radio Button -->
5483                <div class="flex w-4 h-4 rounded-full border items-center justify-center cursor-pointer border border-brown one_time_radio">
5484                  <div
5485                    style="background-color: rgb(95, 71, 29);"
5486                    class="bg-transparent appearance-none rounded-full w-2 h-2 cursor-pointer"
5487                  ></div>
5488                </div>
5489              </div>
5490              <div class="">
5491                <button
5492                  type="button"
5493                  data-cadence="Once"
5494                  class="one_time_heading"
5495                >
5496                  One-Time Purchase
5497                </button>
5498              </div>
5499            </div>
5500            <div
5501              style="padding: 3px 14px; transform: translateY(6px);"
5502              class="one_time_price_meta grid grid-flow-col gap-1 justify-end text-sm lg:text-[0.9375rem] relative"
5503            >
5504              <span style="font-size: 18px;" class="one_time_price font-body-medium">$17</span>
5505              <span class="line-through opacity-50 one_time_before"></span><div style="display: none;" class="save__amount one_time_saving">
5506                <p>Save</p>
5507              </div>
5508            </div>
5509          </div>
5510        </cadence-selector>
5511        <variant-selector>
5512          <div
5513            class="flex gap-2 justify-between bg-sand once_tube_container relative"
5514            data-flavor="Mint"
5515            data-cadence="Once"
5516          >
5517
5518            
5519            
5520
5521            
5522            
5523
5524            
5525            
5526
5527             
5528
5529            
5530            
5531              
5532              
5533               
5534              
5535                
5536                  
5537                  
5538                
5539              
5540                
5541                  
5542                  
5543                    
5544                    
5545                    
5546                    
5547                    
5548                    <button
5549                      style="width: 100%;"
5550                      type="button"
5551                      data-variant-id="45622706602122"
5552                      data-flavor="Mint"
5553                      data-price="1700"
5554                      data-pack-size="Single Tube"
5555                      data-compare-at-price="1700"
5556                      class="variant-price-btn temp border-remove-btn w-full active "
5557                    >
5558                      <div class="tube-category">
5559                        <div class="max">
5560                          <div>
5561                            <span
5562                              style="width: max-content; display: inline-block;"
5563                              class="font-body-medium text-xs lg:text-sm"
5564                            >Single Tube</span>
5565                          </div>
5566                        </div></div>
5567                    </button>
5568                    
5569                  
5570                
5571              
5572                
5573                  
5574                  
5575                
5576              
5577                
5578                  
5579                  
5580                
5581              
5582                
5583                  
5584                  
5585                
5586              
5587                
5588                  
5589                  
5590                
5591              
5592                
5593                  
5594                  
5595                
5596              
5597                
5598                  
5599                  
5600                
5601              
5602            
5603              
5604              
5605               
5606              
5607                
5608                  
5609                  
5610                
5611              
5612                
5613                  
5614                  
5615                
5616              
5617                
5618                  
5619                  
5620                
5621              
5622                
5623                  
5624                  
5625                    
5626                    
5627                    
5628                    
5629                    
5630                    <button
5631                      style="width: 100%;"
5632                      type="button"
5633                      data-variant-id="45618606080138"
5634                      data-flavor="Mint"
5635                      data-price="4600"
5636                      data-pack-size="3 Tubes"
5637                      data-compare-at-price="5100"
5638                      class="variant-price-btn temp border-remove-btn w-full "
5639                    >
5640                      <div class="tube-category">
5641                        <div class="max">
5642                          <div>
5643                            <span
5644                              style="width: max-content; display: inline-block;"
5645                              class="font-body-medium text-xs lg:text-sm"
5646                            >3 Tubes</span>
5647                          </div>
5648                        </div><span class="custom-badge family one_time_saving_badge">Save 10%</span></div>
5649                    </button>
5650                    
5651                  
5652                
5653              
5654                
5655                  
5656                  
5657                
5658              
5659                
5660                  
5661                  
5662                
5663              
5664                
5665                  
5666                  
5667                
5668              
5669                
5670                  
5671                  
5672                
5673              
5674            
5675              
5676              
5677               
5678              
5679                
5680                  
5681                  
5682                
5683              
5684                
5685                  
5686                  
5687                
5688              
5689                
5690                  
5691                  
5692                
5693              
5694                
5695                  
5696                  
5697                
5698              
5699                
5700                  
5701                  
5702                
5703              
5704                
5705                  
5706                  
5707                    
5708                    
5709                    
5710                    
5711                    
5712                    <button
5713                      style="width: 100%;"
5714                      type="button"
5715                      data-variant-id="45618689310858"
5716                      data-flavor="Mint"
5717                      data-price="7000"
5718                      data-pack-size="5 Tubes"
5719                      data-compare-at-price="8500"
5720                      class="variant-price-btn temp border-remove-btn w-full "
5721                    >
5722                      <div class="tube-category">
5723                        <div class="max">
5724                          <div>
5725                            <span
5726                              style="width: max-content; display: inline-block;"
5727                              class="font-body-medium text-xs lg:text-sm"
5728                            >5 Tubes</span>
5729                          </div>
5730                        </div><span class="custom-badge family one_time_saving_badge">Save 18%</span></div>
5731                    </button>
5732                    
5733                  
5734                
5735              
5736                
5737                  
5738                  
5739                
5740              
5741                
5742                  
5743                  
5744                
5745              
5746            
5747              
5748              
5749               
5750              
5751                
5752                  
5753                  
5754                
5755              
5756                
5757                  
5758                  
5759                
5760              
5761                
5762                  
5763                  
5764                
5765              
5766                
5767                  
5768                  
5769                
5770              
5771                
5772                  
5773                  
5774                
5775              
5776                
5777                  
5778                  
5779                
5780              
5781                
5782                  
5783                  
5784                
5785              
5786                
5787                  
5788                  
5789                    
5790                    
5791                    
5792                    
5793                    
5794                    <button
5795                      style="width: 100%;"
5796                      type="button"
5797                      data-variant-id="45622715121802"
5798                      data-flavor="Mint"
5799                      data-price="35000"
5800                      data-pack-size="25 Tubes"
5801                      data-compare-at-price="42500"
5802                      class="variant-price-btn temp border-remove-btn w-full "
5803                    >
5804                      <div class="tube-category">
5805                        <div class="max">
5806                          <div>
5807                            <span
5808                              style="width: max-content; display: inline-block;"
5809                              class="font-body-medium text-xs lg:text-sm"
5810                            >25 Tubes</span>
5811                          </div>
5812                        </div><span class="custom-badge family one_time_saving_badge">Save 18%</span></div>
5813                    </button>
5814                    
5815                  
5816                
5817              
5818            
5819          </div>
5820        </variant-selector>
5821        <variant-selector>
5822          <div
5823            class="flex gap-2 justify-between bg-sand once_tube_container relative"
5824            data-flavor="Citrus"
5825            data-cadence="Once"
5826          >
5827            
5828
5829            
5830            
5831
5832            
5833            
5834            
5835              
5836              
5837              
5838              
5839                
5840                  
5841                  
5842                    
5843                    
5844                    
5845                    
5846                    
5847                    <button
5848                      style="width: 100%;"
5849                      type="button"
5850                      data-variant-id="45594631471242"
5851                      data-flavor="Citrus"
5852                      data-price="1700"
5853                      data-pack-size="Single Tube"
5854                      data-compare-at-price="1700"
5855                      class="variant-price-btn border-remove-btn w-full active "
5856                    >
5857                      <div
5858                        style=""
5859                        class="tube-category"
5860                      >
5861                        <div class="max">
5862                          <div>
5863                            <span
5864                              style="width: max-content; display: inline-block;"
5865                              class="font-body-medium text-xs lg:text-sm"
5866                            >Single Tube</span>
5867                          </div>
5868                        </div></div>
5869                    </button>
5870                    
5871                  
5872                
5873              
5874                
5875                  
5876                  
5877                
5878              
5879                
5880                  
5881                  
5882                
5883              
5884                
5885                  
5886                  
5887                
5888              
5889                
5890                  
5891                  
5892                
5893              
5894                
5895                  
5896                  
5897                
5898              
5899                
5900                  
5901                  
5902                
5903              
5904                
5905                  
5906                  
5907                
5908              
5909            
5910              
5911              
5912              
5913              
5914                
5915                  
5916                  
5917                
5918              
5919                
5920                  
5921                  
5922                
5923              
5924                
5925                  
5926                  
5927                    
5928                    
5929                    
5930                    
5931                    
5932                    <button
5933                      style="width: 100%;"
5934                      type="button"
5935                      data-variant-id="45594633666698"
5936                      data-flavor="Citrus"
5937                      data-price="4600"
5938                      data-pack-size="3 Tubes"
5939                      data-compare-at-price="5100"
5940                      class="variant-price-btn border-remove-btn w-full "
5941                    >
5942                      <div
5943                        style=""
5944                        class="tube-category"
5945                      >
5946                        <div class="max">
5947                          <div>
5948                            <span
5949                              style="width: max-content; display: inline-block;"
5950                              class="font-body-medium text-xs lg:text-sm"
5951                            >3 Tubes</span>
5952                          </div>
5953                        </div><span class="custom-badge family one_time_saving_badge">Save 10%</span></div>
5954                    </button>
5955                    
5956                  
5957                
5958              
5959                
5960                  
5961                  
5962                
5963              
5964                
5965                  
5966                  
5967                
5968              
5969                
5970                  
5971                  
5972                
5973              
5974                
5975                  
5976                  
5977                
5978              
5979                
5980                  
5981                  
5982                
5983              
5984            
5985              
5986              
5987              
5988              
5989                
5990                  
5991                  
5992                
5993              
5994                
5995                  
5996                  
5997                
5998              
5999                
6000                  
6001                  
6002                
6003              
6004                
6005                  
6006                  
6007                
6008              
6009                
6010                  
6011                  
6012                    
6013                    
6014                    
6015                    
6016                    
6017                    <button
6018                      style="width: 100%;"
6019                      type="button"
6020                      data-variant-id="45594652901514"
6021                      data-flavor="Citrus"
6022                      data-price="7000"
6023                      data-pack-size="5 Tubes"
6024                      data-compare-at-price="8500"
6025                      class="variant-price-btn border-remove-btn w-full "
6026                    >
6027                      <div
6028                        style=""
6029                        class="tube-category"
6030                      >
6031                        <div class="max">
6032                          <div>
6033                            <span
6034                              style="width: max-content; display: inline-block;"
6035                              class="font-body-medium text-xs lg:text-sm"
6036                            >5 Tubes</span>
6037                          </div>
6038                        </div><span class="custom-badge family one_time_saving_badge">Save 18%</span></div>
6039                    </button>
6040                    
6041                  
6042                
6043              
6044                
6045                  
6046                  
6047                
6048              
6049                
6050                  
6051                  
6052                
6053              
6054                
6055                  
6056                  
6057                
6058              
6059            
6060              
6061              
6062              
6063              
6064                
6065                  
6066                  
6067                
6068              
6069                
6070                  
6071                  
6072                
6073              
6074                
6075                  
6076                  
6077                
6078              
6079                
6080                  
6081                  
6082                
6083              
6084                
6085                  
6086                  
6087                
6088              
6089                
6090                  
6091                  
6092                
6093              
6094                
6095                  
6096                  
6097                    
6098                    
6099                    
6100                    
6101                    
6102                    <button
6103                      style="width: 100%;"
6104                      type="button"
6105                      data-variant-id="45594657161354"
6106                      data-flavor="Citrus"
6107                      data-price="35000"
6108                      data-pack-size="25 Tubes"
6109                      data-compare-at-price="42500"
6110                      class="variant-price-btn border-remove-btn w-full "
6111                    >
6112                      <div
6113                        style=""
6114                        class="tube-category"
6115                      >
6116                        <div class="max">
6117                          <div>
6118                            <span
6119                              style="width: max-content; display: inline-block;"
6120                              class="font-body-medium text-xs lg:text-sm"
6121                            >25 Tubes</span>
6122                          </div>
6123                        </div><span class="custom-badge family one_time_saving_badge">Save 18%</span></div>
6124                    </button>
6125                    
6126                  
6127                
6128              
6129                
6130                  
6131                  
6132                
6133              
6134            
6135          </div>
6136        </variant-selector>
6137      </div>
6138      <div class="">
6139        
6140        
6141
6142        
6143        
6144
6145        
6146          <cart-add>
6147            <form class="">
6148              <input type="hidden" name="id" value="45594633666698">
6149              
6150
6151              <input
6152                type="hidden"
6153                name="selling_plan"
6154                class="cart_selling_plan"
6155                value="2436038794"
6156              >
6157              <button class="!w-full main__atc__button button button--gold mt-6 ">
6158                <span style="display: none;" class="atc-price">4200</span>
6159                <span class="atc_btn"></span>
6160                <span class="px-1">—</span><span class="atc_text">Add to Bag</span>
6161              </button>
6162            </form>
6163          </cart-add>
6164        
6165      </div>
6166    </form>
6167  </product-form>
6168
6169
6170<script>
6171  document.addEventListener('DOMContentLoaded', function () {
6172    const flavorButtons = document.querySelectorAll('[data-flavor]');
6173    var clickBtn = document.querySelectorAll('.flavour-custom');
6174    let pricegg = document.querySelector('.atc-price');
6175    const oneTimeContainer = document.querySelector('.one_time_container');
6176    const onceTubeContainer = document.querySelector('.once_tube_container');
6177    const oneTimeRadio = document.querySelector('.one_time_radio');
6178    const oneTimeBefore = document.querySelector('.one_time_before');
6179    const oneTimePrice = document.querySelector('.one_time_price');
6180    const oneTimeSavings = document.querySelector('.one_time_saving');
6181
6182    let currentUrl = window.location.pathname.split('/');
6183
6184    let CurrentLastPart = currentUrl[currentUrl.length - 1];
6185
6186    let urlAfter = new URL(window.location.href);
6187    let searchParamsInitial = urlAfter.search;
6188    let SearchFlavorInitial = searchParamsInitial.includes('flavor=Mint') ? 'Mint' : 'Citrus';
6189
6190    function simulateClick(element) {
6191      if (!element) return;
6192      try {
6193        const event = new MouseEvent('click', {
6194          bubbles: true,
6195          cancelable: true,
6196          view: window,
6197        });
6198        element.dispatchEvent(event);
6199      } catch (e) {
6200        console.warn('Click simulation encountered an issue in a listener:', e);
6201      }
6202    }
6203
6204    function getActiveFlavor() {
6205      const activeBtn = document.querySelector('.flavour-custom.active');
6206      return activeBtn ? activeBtn.dataset.flavor : null;
6207    }
6208
6209    function getActiveOnceVariantId() {
6210      let flavorUrl = window.location.pathname.split('/');
6211      let currentFlavor = flavorUrl[flavorUrl.length - 1];
6212      let truncateFlavor = currentFlavor === "Mint" || currentFlavor === "Citrus" ? currentFlavor : "Citrus";
6213
6214      const activeFlavorBtn = getActiveFlavor();
6215      const flavourValue = activeFlavorBtn ? activeFlavorBtn : truncateFlavor;
6216
6217      const subscriptionBox = document.querySelector(`div[data-cadence="Once"][data-flavor=${flavourValue}]`);
6218
6219      if (!subscriptionBox) {
6220        console.error('Subscription box not found');
6221        return null;
6222      }
6223
6224      const activeButton = subscriptionBox.querySelector('button.active');
6225
6226      if (!activeButton) {
6227        console.error('No active button found in subscription box');
6228        return null;
6229      }
6230
6231      return activeButton.getAttribute('data-variant-id');
6232    }
6233
6234    function getVariantOncePrice(variantId) {
6235      const variantsData = JSON.parse(document.getElementById('product-variants').textContent);
6236
6237      const filteredData = variantsData.filter((item) => parseInt(item.variantId) === parseInt(variantId));
6238
6239      const oncePrice = filteredData?.[0]?.variantPrice;
6240
6241      return oncePrice;
6242    }
6243
6244    function isSubscribed() {
6245      const subscriptionBox = document.querySelector('div[data-cadence="Subscribe"]');
6246
6247      if (!subscriptionBox) {
6248        console.error('Subscription box not found');
6249        return null;
6250      }
6251
6252      const activeButton = subscriptionBox.querySelector('button.active');
6253
6254      return activeButton ? true : false;
6255    }
6256
6257    function getActiveVidBySubs(value, flavor) {
6258      const isSubscribe = value ? 'Subscribe' : 'Once';
6259      const subscriptionBox = document.querySelector(`div[data-cadence=${isSubscribe}][data-flavor="${flavor}"]`);
6260
6261      if (!subscriptionBox) {
6262        console.error('Subscription box not found');
6263        return null;
6264      }
6265
6266      let activeButton;
6267      if (isSubscribe === 'Once') {
6268        // For "Once", check both active class and data-flavor attribute
6269        activeButton = subscriptionBox.querySelector(`button.active[data-flavor="${flavor}"]`);
6270      } else {
6271        // For "Subscribe", just check active class
6272        activeButton = subscriptionBox.querySelector('button.active');
6273      }
6274
6275      if (!activeButton) {
6276        console.error('No active button found in subscription box with the required criteria');
6277        return null;
6278      }
6279
6280      return activeButton.getAttribute('data-variant-id');
6281    }
6282
6283    oneTimeContainer?.addEventListener(
6284      'click',
6285      function () {
6286        const targetFlavor = 'Citrus';
6287
6288        const showBox = () => {
6289          const subsBox = document.querySelector(`.subscription-box[data-flavor="${targetFlavor}"]`);
6290          if (subsBox) {
6291            subsBox.classList.remove('hidden');
6292          } else {
6293            console.log('Subscription box not found yet');
6294          }
6295        };
6296
6297        // Initial attempt
6298        showBox();
6299
6300        // Observe DOM changes if it's being injected later
6301        const observer = new MutationObserver(() => {
6302          showBox();
6303        });
6304
6305        observer.observe(document.body, { childList: true, subtree: true });
6306      },
6307      { once: true }
6308    );
6309
6310    let isSimulating = false;
6311
6312    function simulateClickTwo(element) {
6313      if (!element) return;
6314      if (isSimulating) return;
6315      isSimulating = true;
6316
6317      try {
6318        element.click(); // or dispatch custom event
6319      } catch (e) {
6320        console.warn('Click simulation two encountered an issue:', e);
6321      }
6322
6323      setTimeout(() => {
6324        isSimulating = false;
6325      }, 0); // reset after call stack clears
6326    }
6327
6328    oneTimeContainer?.addEventListener('click', () => {
6329      const vId = getActiveOnceVariantId();
6330      const oneTimePrice = getVariantOncePrice(vId);
6331      const mintButton = document.querySelector('.flavour-custom[data-flavor="Mint"]');
6332      const flavorInUrl = window.location.pathname;
6333      let actualFlavour = '';
6334
6335      if (flavorInUrl.includes('Mint')) {
6336        actualFlavour = 'Mint';
6337      } else if (flavorInUrl.includes('Citrus')) {
6338        actualFlavour = 'Citrus';
6339      }
6340
6341      
6342
6343      oneTimeContainer.style.borderWidth = '1px 1px 0px 1px';
6344      oneTimeContainer.style.borderRadius = '10px 10px 0px 0px';
6345      if (oneTimeRadio) {
6346        const oTimeDiv = oneTimeRadio.querySelector('div');
6347        if (oTimeDiv) oTimeDiv.style.backgroundColor = '#5F471D';
6348      }
6349      document.querySelectorAll('.variant-price-btn.remove_one_time.active').forEach((el) => {
6350        el.classList.remove('active');
6351      });
6352      const oneTimeButton = document.querySelector('.one_time_heading');
6353      document.querySelector('.atc_text').textContent = 'Add to Bag';
6354
6355      document.querySelector('.atc_btn').textContent = `${formatPrice(oneTimePrice)}`;
6356
6357      simulateClickTwo(oneTimeButton);
6358
6359      if(actualFlavour === "Mint" && mintButton){
6360          mintButton.click();
6361      }
6362    });
6363
6364    function updateFlavorHandle(flavor) {
6365      const currentUrl = window.location.pathname;
6366      
6367
6368      let newUrl;
6369
6370      if (currentUrl == '/') {
6371        const baseUrl = 'https://revitin.com';
6372        //newUrl = `${baseUrl}/${flavor}`;
6373        newUrl = `${baseUrl}?flavor=${flavor}`;
6374        window.history.replaceState({}, '', newUrl);
6375      } else if (currentUrl == '?flavor=Citrus' || currentUrl == '?flavor=Mint') {
6376        const baseUrl = 'https://revitin.com';
6377        newUrl = `${baseUrl}?flavor=${flavor}`;
6378        window.history.replaceState({}, '', newUrl);
6379      } else if (currentUrl == '?flavor=Citrus' || currentUrl == '?flavor=citrus') {
6380        const baseUrl = 'https://revitin.com';
6381        newUrl = `${baseUrl}?flavor=${flavor}`;
6382        window.history.replaceState({}, '', newUrl);
6383      } else if (currentUrl == '?flavor=Mint' || currentUrl == '?flavor=mint') {
6384        const baseUrl = 'https://revitin.com';
6385        newUrl = `${baseUrl}?flavor=${flavor}`;
6386        window.history.replaceState({}, '', newUrl);
6387      } else {
6388        const baseUrl = '/products/revitin-natural-toothpaste';
6389        newUrl = `${baseUrl}/${flavor}`;
6390        window.history.replaceState({}, '', newUrl);
6391      }
6392    }
6393
6394    function setActiveFlavor(flavor) {
6395      // console.log('setActiveFlavor--->',flavor)
6396      clickBtn.forEach((button) => {
6397        // Remove active class from all buttons
6398        button.classList.remove('active');
6399        // Remove background colors
6400        if (button.dataset.flavor === 'Citrus') {
6401          button.classList.remove('bg-gold', 'border-gold');
6402        } else if (button.dataset.flavor === 'Mint') {
6403          button.classList.remove('bg-light-green', 'border-light-green');
6404        }
6405
6406        // Add active class to selected flavor
6407        if (button.dataset.flavor === flavor) {
6408          button.classList.add('active');
6409          // Add background color to selected button
6410          if (flavor === 'Citrus' || flavor === 'citrus') {
6411            button.classList.add('bg-gold', 'border-gold');
6412          } else if (flavor === 'Mint' || flavor === 'mint') {
6413            button.classList.add('bg-light-green', 'border-light-green');
6414            // pricegg = document.querySelector('.atc-price');
6415
6416            // pricegg.classList.add('up');
6417          }
6418        }
6419      });
6420
6421      const galleryElements = document.querySelectorAll('[data-swap-flavor]');
6422
6423      
6424
6425      galleryElements.forEach((element) => {
6426        // Hide all galleries
6427        element.classList.add('opacity-0');
6428        element.classList.remove('!opacity-100', 'z-10', 'relative');
6429        element.classList.add('absolute', 'top-0', 'left-0', 'w-full', 'h-full');
6430
6431        // Show only the gallery that matches the selected flavor
6432        if (element.dataset.swapFlavor === flavor) {
6433          element.classList.remove('opacity-0', 'absolute', 'top-0', 'left-0');
6434          element.classList.add('!opacity-100', 'z-10', 'relative');
6435        }
6436      });
6437
6438      const variantSelectors = document.querySelectorAll('variant-selector > div');
6439
6440      // Get the current cadence from the active cadence option
6441      const activeCadenceElement = document.querySelector('.cadence-option.active');
6442      const currentCadence = activeCadenceElement ? activeCadenceElement.dataset.cadence : 'Once';
6443
6444      variantSelectors.forEach((selector) => {
6445        // Get the selector's flavor and cadence without converting to lowercase
6446        const selectorFlavor = selector.dataset.flavor || '';
6447        const selectorCadence = selector.dataset.cadence;
6448
6449        // Hide the selector by default
6450        selector.classList.add('hidden');
6451
6452        // Show only the selector that matches both the selected flavor and current cadence
6453        // Use exact case matching
6454        if (selectorFlavor === flavor && selectorCadence === currentCadence) {
6455          selector.classList.remove('hidden');
6456        }
6457      });
6458    }
6459
6460    function getVariantDataBySubs(variantId, value) {
6461      const variantsData = JSON.parse(document.getElementById('product-variants').textContent);
6462
6463      const filteredData = variantsData.filter((item) => parseInt(item.variantId) === parseInt(variantId));
6464
6465      const price = value ? filteredData?.[0]?.sellingPlans?.[0]?.price : filteredData?.[0]?.variantPrice;
6466
6467      return price;
6468    }
6469
6470    function getVariantData(variantId) {
6471      const variantsData = JSON.parse(document.getElementById('product-variants').textContent);
6472
6473      const filteredData = variantsData.filter((item) => parseInt(item.variantId) === parseInt(variantId));
6474
6475      const subscribedPrice = filteredData?.[0]?.sellingPlans?.[0]?.price;
6476
6477      return subscribedPrice;
6478    }
6479
6480    function getActiveVariantDataByFlavor(flavor) {
6481      const container = document.querySelector(`.once_tube_container[data-flavor="${flavor}"]`);
6482      if (!container) return null;
6483
6484      const activeButton = container.querySelector('button.active');
6485      if (!activeButton) return null;
6486
6487      return activeButton.dataset;
6488    }
6489
6490    const formatPrice = (price) => {
6491      const formatted = (price / 100).toFixed(2);
6492      return formatted.endsWith('.00') 
6493        ? `$${parseInt(formatted)}` 
6494        : `$${formatted}`;
6495    };
6496
6497    const mutationObserverPrice = (price, classname) => {
6498      if (price) {
6499        const observer = new MutationObserver(() => {
6500          const selectElement = document.querySelector(classname);
6501          if (selectElement) {
6502            selectElement.textContent = price;
6503            observer.disconnect(); // Stop observing after found
6504          }
6505        });
6506        observer.observe(document.body, { childList: true, subtree: true });
6507      }
6508    };
6509
6510    function setActiveSubscription(currentFlavor) {
6511      // Determine the target flavor (opposite of current)
6512      const targetFlavor = currentFlavor === 'Mint' ? 'Citrus' : 'Mint';
6513
6514      // Find the subscription box for the target flavor
6515      const targetSubscriptionBox = document.querySelector(`.subscription-box[data-flavor="${targetFlavor}"]`);
6516
6517      // Check if any button is active in the target subscription box
6518      const activeButtonInTarget = targetSubscriptionBox.querySelector('.variant-price-btn.active');
6519
6520      // If there's an active button in the target box, we need to activate the first button in current flavor's box
6521      if (activeButtonInTarget) {
6522        // Find the current flavor's subscription box
6523        const currentSubscriptionBox = document.querySelector(`.subscription-box[data-flavor="${currentFlavor}"]`);
6524
6525        // Find all buttons in current flavor's box
6526        const buttonsInCurrent = currentSubscriptionBox.querySelectorAll('.variant-price-btn');
6527
6528        // Remove active class from all buttons in current flavor
6529        buttonsInCurrent.forEach((btn) => btn.classList.remove('active'));
6530
6531        // Add active class to first button in current flavor
6532        if (buttonsInCurrent.length > 0) {
6533          buttonsInCurrent[0].classList.add('active');
6534        }
6535      }
6536    }
6537
6538    const calculateSavingPercentage = (compareAtPrice, price, inCents = true) => {
6539      // Convert strings to numbers
6540      let original = typeof compareAtPrice === 'string' ? parseFloat(compareAtPrice) : compareAtPrice;
6541      let discounted = typeof price === 'string' ? parseFloat(price) : price;
6542
6543      if (inCents) {
6544        original = original / 100;
6545        discounted = discounted / 100;
6546      }
6547
6548      if (isNaN(original) || isNaN(discounted) || original === 0) return '0%';
6549
6550      // Calculate saving percentage and round
6551      const savingPercent = Math.round(((original - discounted) / original) * 100);
6552
6553      return `${savingPercent}%`;
6554    };
6555
6556    clickBtn.forEach((button) => {
6557      button.addEventListener('click', function () {
6558        // console.log('click')
6559        pricegg.classList.remove('up');
6560        const flavor = this.dataset.flavor;
6561
6562        setActiveSubscription(flavor);
6563
6564        const isSubscribe = isSubscribed();
6565
6566        const activeVid = getActiveVidBySubs(isSubscribe, flavor);
6567
6568        const activeButtonPrice = getVariantDataBySubs(activeVid, isSubscribe);
6569
6570        document.querySelector('.atc_btn').textContent = `${formatPrice(activeButtonPrice)}`;
6571
6572        const activeOneTimeButtonData = getActiveVariantDataByFlavor(flavor);
6573
6574        if (activeOneTimeButtonData.price && activeOneTimeButtonData.compareAtPrice) {
6575          oneTimePrice.textContent = formatPrice(activeOneTimeButtonData.price);
6576
6577        const savingPercentage = calculateSavingPercentage(activeOneTimeButtonData?.compareAtPrice, activeOneTimeButtonData.price);
6578
6579        if (activeOneTimeButtonData.compareAtPrice) {
6580            oneTimeBefore.textContent =
6581              activeOneTimeButtonData?.compareAtPrice === activeOneTimeButtonData.price
6582                ? ''
6583                : formatPrice(activeOneTimeButtonData.compareAtPrice);
6584            oneTimeSavings.textContent =  `Save ${savingPercentage}`;  
6585            oneTimeBefore.style.display = 'inline';
6586
6587            if(savingPercentage === "0%"){
6588              oneTimeSavings.style.display = 'none';
6589            }else{
6590              oneTimeSavings.style.display = 'block';
6591            }
6592          } else {
6593            oneTimeBefore.style.display = 'none';
6594            oneTimeSavings.style.display = 'none';
6595          }
6596        }
6597
6598        setActiveFlavor(flavor);
6599        updateFlavorHandle(flavor);
6600      });
6601    });
6602
6603    let subscribeButtonUp = document.querySelector('button[data-cadence="Subscribe"]');
6604    let oneTimeButtonUp = document.querySelector('button[data-cadence="Once"]');
6605    let variantSelectAllBtn = document.querySelectorAll('.variant-price-btn');
6606    let oneTimeRemoveButton = document.querySelectorAll('.remove_one_time');
6607    let oneTimeBorderemove = document.querySelectorAll('.border-remove-btn');
6608    const oneTimeButtonHeading = document.querySelector('.one_time_heading');
6609
6610    function udpateBorder() {
6611      if (onceTubeContainer && onceTubeContainer.classList.contains('hidden')) {
6612        oneTimeContainer.style.borderWidth = '1px 1px 1px 1px';
6613        oneTimeContainer.style.borderRadius = '10px 10px 10px 10px';
6614      } else {
6615        oneTimeContainer.style.borderWidth = '1px 1px 0px 1px';
6616        oneTimeContainer.style.borderRadius = '10px 10px 0px 0px';
6617      }
6618    }
6619
6620    subscribeButtonUp?.addEventListener('click', () => {
6621      pricegg.classList.remove('up');
6622      // udpateBorder();
6623    });
6624
6625    oneTimeButtonUp?.addEventListener('click', () => {
6626      pricegg.classList.remove('up');
6627      // udpateBorder();
6628    });
6629
6630    variantSelectAllBtn?.forEach((button) => {
6631      button.addEventListener('click', () => {
6632        pricegg.classList.remove('up');
6633        udpateBorder();
6634      });
6635    });
6636
6637    oneTimeRemoveButton?.forEach((button) => {
6638      button.addEventListener('click', () => {
6639        const activeVariantId = button?.dataset?.variantId;
6640
6641        subscribeButtonUp?.click();
6642        if (oneTimeRadio) {
6643          const radioDiv = oneTimeRadio.querySelector('div');
6644          if (radioDiv) radioDiv.style.backgroundColor = '#f7f7f700';
6645        }
6646        const atcTextEl = document.querySelector('.atc_text');
6647        if (atcTextEl) atcTextEl.textContent = 'Add to Bag';
6648        if (oneTimeContainer) {
6649          oneTimeContainer.style.borderWidth = '1px 1px 1px 1px';
6650          oneTimeContainer.style.borderRadius = '10px 10px 10px 10px';
6651        }
6652
6653        if (activeVariantId) {
6654          const subscribePrice = getVariantData(activeVariantId);
6655          const atcBtnEl = document.querySelector('.atc_btn');
6656          if (atcBtnEl) atcBtnEl.textContent = `${formatPrice(subscribePrice)}`;
6657        }
6658        // udpateBorder();
6659      });
6660    });
6661
6662    function updateOneTimeHeaderFromButton(button) {
6663      if (!button || !oneTimePrice) return;
6664
6665      const data = button.dataset;
6666
6667      if (data.compareAtPrice) {
6668        const savingPercentage = calculateSavingPercentage(data?.compareAtPrice, data.price);
6669
6670        oneTimeBefore.textContent = data?.compareAtPrice === data.price ? '' : formatPrice(data.compareAtPrice);
6671        oneTimeSavings.textContent = `Save ${savingPercentage}`;
6672        oneTimeBefore.style.display = 'inline';
6673        oneTimeSavings.style.display = savingPercentage === '0%' ? 'none' : 'block';
6674      } else {
6675        oneTimeBefore.style.display = 'none';
6676        oneTimeSavings.style.display = 'none';
6677      }
6678
6679      oneTimePrice.textContent = formatPrice(data.price);
6680    }
6681
6682    oneTimeBorderemove.forEach((button) => {
6683      button.addEventListener('click', () => {
6684        updateOneTimeHeaderFromButton(button);
6685        document.querySelector('.atc_text').textContent = 'Add to Cart';
6686        mutationObserverPrice(formatPrice(button.dataset.price), '.atc_btn');
6687
6688        // Update container styling
6689        oneTimeContainer.style.borderWidth = '1px 1px 0px 1px';
6690        oneTimeContainer.style.borderRadius = '10px 10px 0px 0px';
6691      });
6692    });
6693
6694    if (
6695      CurrentLastPart === 'Mint' ||
6696      CurrentLastPart === 'mint' ||
6697      SearchFlavorInitial === 'Mint' ||
6698      SearchFlavorInitial === 'mint'
6699    ) {
6700      const sellId = document.querySelectorAll('input[name="id"]');
6701      const variantsJsonMint = document.getElementById('product-variants').innerText;
6702
6703      this.variants = JSON.parse(variantsJsonMint);
6704
6705      let mintVariantId = (this.variantId = this.variants[1].variantId);
6706
6707      this.variantInput = this.querySelector('input[name="id"]');
6708      this.variantInput.value = mintVariantId;
6709      //console.log('VariantInputMint',this.variantInput)
6710    }
6711
6712    if (
6713      CurrentLastPart === 'Citrus' ||
6714      CurrentLastPart === 'Mint' ||
6715      CurrentLastPart === 'citrus' ||
6716      CurrentLastPart === 'mint'
6717    ) {
6718      let formattedFlavor = CurrentLastPart.charAt(0).toUpperCase() + CurrentLastPart.slice(1).toLowerCase();
6719
6720      if (CurrentLastPart === 'Mint' || CurrentLastPart === 'mint') {
6721        pricegg.classList.add('up');
6722      }
6723      setActiveFlavor(formattedFlavor);
6724    }
6725
6726    // Check URL path on page load
6727    const pathParts = window.location.pathname.split('/');
6728    //console.log("onPageLoad--->",pathParts)
6729    const lastPart = pathParts[pathParts.length - 1];
6730    //console.log("onPageLoadLastPart--->",lastPart);
6731
6732    const url = new URL(window.location.href);
6733
6734    const searchParams = url.search;
6735    const SearchFlavor = searchParams.includes('flavor=Mint') ? 'Mint' : 'Citrus';
6736    // console.log('SearchFlavor:',SearchFlavor);
6737
6738    if (lastPart === 'Citrus' || lastPart === 'Mint') {
6739      const flavor = lastPart.charAt(0) + lastPart.slice(1);
6740      //console.log("Flavor from URL:", flavor);
6741      setActiveFlavor(flavor);
6742    } else if (SearchFlavor === 'Mint' || SearchFlavor === 'Citrus') {
6743      setActiveFlavor(SearchFlavor);
6744
6745      if (SearchFlavor === 'Mint') {
6746        pricegg = document.querySelector('.atc-price');
6747
6748        pricegg.classList.add('up');
6749      }
6750    }
6751
6752    const firstButtonCitrus = oneTimeRemoveButton[0];
6753    const firstButtonMint = oneTimeRemoveButton[Math.ceil(oneTimeRemoveButton.length / 2)];
6754
6755    if (firstButtonCitrus) {
6756      
6757      simulateClick(firstButtonCitrus);
6758    }
6759
6760    if (firstButtonMint) {
6761      
6762      simulateClick(firstButtonMint);
6763    }
6764
6765    
6766
6767    
6768    
6769    
6770const isWholesaleCustomer = false;
6771    // Back-compat alias used below (was wrongly comparing full tags string to "wholesale")
6772    const customerTag = isWholesaleCustomer ? "wholesale" : "";
6773    
6774    const pageConfigs = [
6775      {
6776        url: "revitin-natural-toothpaste-fullcase-25tubes",
6777        flavor: "Citrus",
6778        packSize: "25 Tubes",
6779      },
6780      {
6781        url: "copy-of-revitin-toothpaste-25-tubes-gm",
6782        flavor: "Citrus",
6783        packSize: "25 Tubes",
6784      },
6785      {
6786        url: "revitin-natural-toothpaste-family-pack-3tubes",
6787        flavor: "Citrus",
6788        packSize: "3 Tubes",
6789      },
6790      {
6791        url: "revitin-toothpaste-5-tubes-mint",
6792        flavor: "Mint",
6793        packSize: "5 Tubes",
6794      },
6795      {
6796        url: "revitin-toothpaste-5-tubes",
6797        flavor: "Citrus",
6798        packSize: "5 Tubes",
6799      },
6800      {
6801        url: "revitin-toothpaste-3-tubes-mint",
6802        flavor: "Mint",
6803        packSize: "3 Tubes",
6804      },
6805      {
6806        url: "revitin-toothpaste-25-tubes-mint",
6807        flavor: "Mint",
6808        packSize: "25 Tubes",
6809      },
6810      {
6811        url: "revitin-toothpaste-single-tube-mint",
6812        flavor: "Mint",
6813        packSize: "Single Tube",
6814      },
6815      // add more URLs as needed
6816    ];
6817
6818    const urlFState = {
6819      product: getAllProducts(),
6820    }
6821
6822    function getAllProducts() {
6823      const allProductsElement = document.getElementById('all-products-json');
6824      const productsData = allProductsElement ? JSON.parse(allProductsElement?.textContent) : [];
6825      return productsData;
6826    }
6827
6828    // Utility functions
6829    function removeActiveClass(flavor) {
6830      document
6831        .querySelectorAll(`.variant-price-btn.remove_one_time[data-flavor="${flavor}"]`)
6832        .forEach((el) => el.classList.remove("active"));
6833    }
6834
6835    function activateOneTimeSection(flavor) {
6836      const sections = document.querySelectorAll(
6837        `.once_tube_container[data-flavor="${flavor}"]`
6838      );
6839      sections.forEach((btn) => btn.classList.remove("hidden"));
6840
6841      const oppositeFlavor = flavor === "Citrus" ? "Mint" : "Citrus";
6842      const oppositeSection = document.querySelector(
6843        `.once_tube_container[data-flavor="${oppositeFlavor}"]`
6844      );
6845      oppositeSection.classList.add("hidden");
6846    }
6847
6848    function activateSubscribeSection(flavor) {
6849      const toggleSections = () => {
6850        const sections = document.querySelectorAll(
6851          `.subscription-box[data-flavor="${flavor}"]`
6852        );
6853        sections.forEach((btn) => btn.classList.remove("hidden"));
6854
6855        const oppositeFlavor = flavor === "Citrus" ? "Mint" : "Citrus";
6856        const oppositeSection = document.querySelector(
6857          `.subscription-box[data-flavor="${oppositeFlavor}"]`
6858        );
6859
6860        if (oppositeSection) {
6861          oppositeSection.classList.add("hidden");
6862        } else {
6863          console.log("Opposite section not found yet");
6864        }
6865      };
6866
6867      // Run immediately once
6868      toggleSections();
6869
6870      // Observe for future DOM changes
6871      const observer = new MutationObserver(() => {
6872        toggleSections();
6873      });
6874
6875      observer.observe(document.body, {
6876        childList: true,
6877        subtree: true,
6878      });
6879    }
6880
6881    function addActiveClass(flavor, packSize) {
6882      const buttons = document.querySelectorAll(
6883        `.variant-price-btn.border-remove-btn[data-flavor="${flavor}"]`
6884      );
6885      buttons.forEach((btn) => btn.classList.remove("active"));
6886
6887      const activeButton = document.querySelector(
6888        `.variant-price-btn.border-remove-btn[data-flavor="${flavor}"][data-pack-size="${packSize}"]`
6889      );
6890
6891      activateOneTimeSection(flavor);
6892      activateSubscribeSection(flavor);
6893
6894      if (activeButton) {
6895        activeButton.classList.add("active");
6896        
6897        // Get price data from the active button
6898        const price = activeButton.getAttribute('data-price');
6899        const compareAtPrice = activeButton.getAttribute('data-compare-at-price');
6900         const variantId = activeButton.getAttribute('data-variant-id');
6901        const sellingPlanInput = document.querySelector('.cart_selling_plan');
6902
6903
6904        if (sellingPlanInput) {
6905          const cartForm = sellingPlanInput.closest('cart-add');
6906          if (cartForm) {
6907            const variantInput = cartForm.querySelector('input[name="id"]');
6908            if (variantInput && variantId) {
6909              variantInput.value = variantId;
6910            }
6911          }
6912        }
6913        
6914        // Convert prices from cents to dollars and remove .00 if no cents
6915        const formatPrice = (priceInCents) => {
6916          const dollars = priceInCents / 100;
6917          // Check if it's a whole number
6918          if (dollars % 1 === 0) {
6919            return dollars.toString(); // No decimal places
6920          } else {
6921            return dollars.toFixed(2); // Keep 2 decimal places
6922          }
6923        };
6924        
6925        const priceFormatted = formatPrice(price);
6926        const compareAtPriceFormatted = compareAtPrice ? formatPrice(compareAtPrice) : null;
6927        
6928        // Update current price
6929        const currentPriceElement = document.querySelector('.one_time_price');
6930        const atcButton = document.querySelector('.atc_btn');
6931        if (currentPriceElement) {
6932          currentPriceElement.textContent = `$${priceFormatted}`;
6933          atcButton.textContent = `$${priceFormatted}`;
6934        }
6935        
6936        // Update compare-at price (if exists)
6937        const comparePriceElement = document.querySelector('.one_time_before');
6938        if (comparePriceElement && compareAtPriceFormatted) {
6939          comparePriceElement.textContent = `$${compareAtPriceFormatted}`;
6940          comparePriceElement.style.display = 'inline';
6941        } else if (comparePriceElement) {
6942          comparePriceElement.style.display = 'none';
6943        }
6944        
6945        // Update savings badge if both prices exist
6946        const savingsElement = document.querySelector('.one_time_saving');
6947        if (savingsElement && compareAtPrice && price && compareAtPrice > price) {
6948          const savingsAmount = ((1 - price / compareAtPrice) * 100).toFixed(0);
6949          savingsElement.textContent = `Save ${savingsAmount}%`;
6950          savingsElement.style.display = 'block';
6951        } else if (savingsElement) {
6952          savingsElement.style.display = 'none';
6953        }
6954      }
6955
6956      console.log("activeButton", activeButton);
6957    }
6958
6959    function updateFlavorButtonUi(flavor){
6960      const flavorBtn = isWholesaleCustomer ? ".whole_flavor_btn" : ".flavour-custom";
6961
6962      const oneTimeSavingBadge = document.querySelectorAll(
6963        `.variant-price-btn.border-remove-btn[data-flavor="${flavor}"] .one_time_saving_badge`
6964      );
6965      const mainFlavorBtn = document.querySelectorAll(flavorBtn);
6966      const oneTimeSavingHeader = document.querySelector(
6967        `.one_time_saving`
6968      );
6969      const mainAtcBtn = document.querySelector(
6970        `.main__atc__button`
6971      );
6972      const currentFlavorBtn = document.querySelector(
6973        `${flavorBtn}[data-flavor="${flavor}"]`
6974      );
6975      const oppositeFlavor = flavor === "Citrus" ? "Mint" : "Citrus"; 
6976      const oppositeFlavorBtn = document.querySelector(
6977        `${flavorBtn}[data-flavor="${oppositeFlavor}"]`
6978      );
6979
6980      mainFlavorBtn?.forEach((btn) => {
6981        btn.classList.remove("active");
6982        btn.style.background = "";
6983        btn.style.borderColor = "";
6984      });
6985      currentFlavorBtn?.classList.add("active");
6986      oppositeFlavorBtn?.classList.remove("bg-gold");
6987      oneTimeSavingBadge?.forEach((btn) => {
6988        btn.style.backgroundColor = flavor === "Mint" ? "#e6ecd3": "#FFDEA3";
6989      });
6990      oneTimeSavingHeader ? oneTimeSavingHeader.style.backgroundColor = flavor === "Mint" ? "#e6ecd3": "#FFDEA3" : null;
6991      mainAtcBtn ? mainAtcBtn.style.backgroundColor = flavor === "Mint" ? "#e6ecd3": "#FFDEA3" : null;
6992    }
6993
6994    function updateBannerImages(flavor) {
6995      const singleTubes = urlFState?.product.filter(p => p?.title.includes("Single"));
6996      const activeFlavour = singleTubes?.find(p => p?.variants?.[0]?.title === flavor);
6997      const activeFlavourImages = activeFlavour?.images;
6998
6999      const containers = [
7000        document.querySelector(`.image_update_container div[data-swap-flavor="${flavor}"]`),
7001        document.querySelector(`.pdp_slider_container div[data-swap-flavor="${flavor}"]`),
7002        document.querySelector(`.pdp_banner_container img[data-swap-flavor="${flavor}"]`),
7003      ];
7004
7005      document.querySelectorAll("[data-swap-flavor]").forEach(el => {
7006        el?.classList.add("opacity-0");
7007        el?.classList.remove("!opacity-100", "z-10");
7008      });
7009
7010      containers.forEach(el => {
7011        if (!el) return;
7012        el?.classList.remove("opacity-0");
7013        el?.classList.add("!opacity-100", "z-10");
7014      });
7015
7016    }
7017
7018    // Main logic
7019    const currentPath = window.location.pathname;
7020    const matchedConfig = pageConfigs.find((cfg) => currentPath.includes(cfg.url));
7021
7022    if(isWholesaleCustomer && currentPath.includes("revitin-toothpaste-25-tubes-wholesale-mint")) {
7023      document.querySelectorAll(".wholesale_item").forEach((el) => el.classList.add("hidden"));
7024
7025      const mintProduct = document.querySelector(".wholesale_item[data-wholesale-flavor='Mint']");
7026      if (mintProduct) mintProduct.classList.remove("hidden");
7027      
7028      updateFlavorButtonUi("Mint");
7029      updateBannerImages("Mint");
7030    }
7031
7032    if (matchedConfig) {
7033      const { flavor, packSize } = matchedConfig;
7034
7035      removeActiveClass(flavor);
7036      updateFlavorButtonUi(flavor);
7037      updateBannerImages(flavor);
7038
7039      // simulate click if needed (wrapped in a safe check)
7040      if (typeof simulateClickTwo === "function" && oneTimeButtonHeading) {
7041        simulateClickTwo(oneTimeButtonHeading);
7042      }
7043
7044      addActiveClass(flavor, packSize);
7045    };
7046    
7047  });
7048</script>
7048
7049
7050<script>
7051  const flavorButtons = document.querySelectorAll('.flavour-custom');
7052  const subscriptionBoxes = document.querySelectorAll('.subscription-box');
7053
7054  const productPaths = [
7055    "revitin-natural-toothpaste-fullcase-25tubes",
7056    "revitin-natural-toothpaste-family-pack-3tubes",
7057    "revitin-toothpaste-5-tubes",
7058    "copy-of-revitin-toothpaste-25-tubes-gm",
7059    "revitin-toothpaste-3-tubes-mint",
7060    "revitin-toothpaste-25-tubes-mint",
7061    "revitin-toothpaste-single-tube-mint"
7062  ];
7063
7064  if (!productPaths.some(path => window.location.pathname.includes(path))) {
7065    flavorButtons.forEach((button) => {
7066      button.addEventListener('click', () => {
7067        // Remove 'active' class from all buttons
7068
7069        flavorButtons.forEach((btn) => btn.classList.remove('active'));
7070
7071        // Add 'active' class to the clicked one
7072        button.classList.add('active');
7073
7074        // Get active flavor
7075        const activeFlavor = button.getAttribute('data-flavor');
7076
7077        // Show matching subscription box, hide others
7078        subscriptionBoxes.forEach((box) => {
7079          const boxFlavor = box.getAttribute('data-flavor');
7080          if (boxFlavor === activeFlavor) {
7081            box.style.setProperty('display', 'block', 'important');
7082          } else {
7083            box.style.setProperty('display', 'none', 'important');
7084          }
7085        });
7086
7087        if (activeFlavor === 'Mint') {
7088          document
7089            .querySelectorAll('.save__amount')
7090            .forEach((el) => el.style.setProperty('background-color', '#E6ECD3', 'important'));
7091          document
7092            .querySelectorAll('.one_time_saving_badge')
7093            .forEach((el) => el.style.setProperty('background-color', '#E6ECD3', 'important'));
7094          document.querySelector('.main__atc__button').style.setProperty('background-color', '#E6ECD3', 'important');
7095        }
7096
7097        if (activeFlavor === 'Citrus') {
7098          document
7099            .querySelectorAll('.save__amount')
7100            .forEach((el) => el.style.setProperty('background-color', '#FFDEA3', 'important'));
7101          document
7102            .querySelectorAll('.one_time_saving_badge')
7103            .forEach((el) => el.style.setProperty('background-color', '#FFDEA3', 'important'));
7104          document.querySelector('.main__atc__button').style.setProperty('background-color', '#FFDEA3', 'important');
7105        }
7106      });
7107    });
7108
7109    document.addEventListener('DOMContentLoaded', function () {
7110      function getAllProducts() {
7111          const productsData = JSON.parse(document.getElementById('product-variants').textContent);
7112          return productsData;
7113      }
7114
7115      function getActiveFlavor() {
7116        const activeBtn = document.querySelector('.flavour-custom.active');
7117        return activeBtn ? activeBtn.dataset.flavor : null;
7118      }
7119
7120      const activeFlavor = getActiveFlavor();
7121      const flavorVal = activeFlavor ? activeFlavor : "Citrus";
7122
7123      function activateSecondButton() {
7124          const subscriptionBoxes = document.querySelectorAll(`.subscription-box[data-flavor=${flavorVal}]`);
7125          
7126          subscriptionBoxes.forEach((box) => {
7127              const buttons = box.querySelectorAll('.variant-price-btn');
7128
7129              if (buttons.length >= 2) {
7130                  const productsData = getAllProducts();
7131                  const urlFlavor = window.location.pathname.split("/").filter(Boolean).pop();
7132                  const actualFlavour = flavorVal;
7133                  const secondProduct = productsData?.filter(
7134                      (item) => item.productTitle.includes('3 Tubes') && item.variantTitle === actualFlavour
7135                  )?.[0];
7136                  const secondVid = secondProduct?.variantId;
7137                  const thirdMonthSpId = secondProduct?.sellingPlans?.[2]?.id;
7138
7139                  
7140
7141                  // Wait a bit to ensure cart-add elements are rendered
7142                  setTimeout(() => {
7143                      const cartAddElements = document.querySelectorAll('cart-add');
7144                      
7145                      cartAddElements.forEach(cartAddElement => {
7146                          const variantIdElem = cartAddElement.querySelector('input[name="id"]');
7147                          const sellingPlanIdElem = cartAddElement.querySelector('input[name="selling_plan"]');
7148                          const cartSellingPlanElem = cartAddElement.querySelector('.cart_selling_plan');
7149
7150                          if (variantIdElem && secondVid) {
7151                              variantIdElem.value = secondVid;
7152                          }
7153
7154                          if (thirdMonthSpId) {
7155                              // Set all selling plan inputs
7156                              if (sellingPlanIdElem) {
7157                                  sellingPlanIdElem.value = thirdMonthSpId;
7158                              }
7159                              if (cartSellingPlanElem) {
7160                                  cartSellingPlanElem.value = thirdMonthSpId;
7161                              }
7162                              
7163                              // Also try to set any other selling plan inputs
7164                              document.querySelectorAll('input[name="selling_plan"]').forEach(input => {
7165                                  input.value = thirdMonthSpId;
7166                              });
7167                              document.querySelectorAll('.cart_selling_plan').forEach(input => {
7168                                  input.value = thirdMonthSpId;
7169                              });
7170                          }
7171                      });
7172                  }, 100);
7173
7174                  // Update button states
7175                  buttons.forEach((btn) => btn.classList.remove('active'));
7176                  buttons[0].classList.add('active');
7177              }
7178          });
7179      }
7180
7181      // More robust observer with retry mechanism
7182      const observer = new MutationObserver(function (mutations, obs) {
7183          const citrusBoxes = document.querySelectorAll(`.subscription-box[data-flavor=${flavorVal}]`);
7184          if (citrusBoxes.length > 0) {
7185              // Try multiple times with delays to ensure elements are ready
7186              setTimeout(activateSecondButton, 100);
7187              setTimeout(activateSecondButton, 500);
7188              obs.disconnect();
7189          }
7190      });
7191
7192      observer.observe(document.body, {
7193          childList: true,
7194          subtree: true,
7195      });
7196
7197      // Initial attempts with delays
7198      setTimeout(activateSecondButton, 100);
7199      setTimeout(activateSecondButton, 500);
7200      setTimeout(activateSecondButton, 1000);
7201    });
7202  }
7203</script>
7203
7204
7205<style>
7206  .one_time_saving {
7207    font-size: 11px;
7208    padding: 1px 12px !important;
7209    transform: translate(-13px, -3px);
7210  }
7211
7212  .subscription-box:has(.variant-price-btn.active) {
7213    background-color: #f7eede;
7214  }
7215
7216  .one_time_container:has(.one_time_radio > div[style*='rgba(247, 247, 247, 0)']) {
7217    background-color: #0b070700;
7218  }
7219
7220  .one_time_container:has(.one_time_radio > div[style*='rgba(247, 247, 247, 0)']) .one_time_heading {
7221    background-color: #ff000000 !important;
7222  }
7223
7224  .border-radius-2 {
7225    border-radius: 4px;
7226  }
7227
7228  .variant-price-btn.active div {
7229    font-weight: bold;
7230    font-size: 14px;
7231    z-index: 39;
7232  }
7233
7234  .variant-price-btn {
7235    position: relative;
7236  }
7237
7238  .custom-badge {
7239    position: absolute;
7240    top: 1.6rem;
7241    left: 50%;
7242    transform: translateX(-50%);
7243    background-color: #ffdea3;
7244    padding: 5px 10px;
7245    font-size: 12px;
7246    border-radius: 11px;
7247    z-index: 10;
7248    width: max-content;
7249    height: max-content;
7250    line-height: 1;
7251    font-weight: normal !important;
7252  }
7253
7254  .one_time_heading {
7255    font-size: 18px;
7256    font-weight: bold;
7257  }
7258
7259  .once_tube_container {
7260    border-radius: 0px 0px 10px 10px;
7261    border-width: 0px 1px 1px 1px;
7262    border-style: solid;
7263    border-color: black;
7264    padding: 0rem 0.5rem 1rem 0.5rem;
7265  }
7266
7267  .one_time_container {
7268    border-radius: 10px 10px 0px 0px;
7269    border-width: 1px 1px 0px 1px;
7270    border-style: solid;
7271    border-color: black;
7272    margin-top: 10px;
7273  }
7274
7275  .subscription-box {
7276    border: 1px solid #5f471d;
7277    border-radius: 14px;
7278    margin-top: 2.1rem;
7279    padding: 12px 18px 0px 12px;
7280    background: rgba(247, 238, 222, 0);
7281  }
7282
7283  .subscription-box.active {
7284    display: block !important;
7285  }
7286
7287  .save_20 {
7288    font-weight: bold;
7289    font-size: 18px;
7290    margin-bottom: 7px;
7291  }
7292
7293  .benifit_text {
7294    font-size: 14px;
7295    line-height: 1;
7296    padding: 5.1px 0px;
7297  }
7298
7299  .month-frequency {
7300    font-size: 14px !important;
7301    font-weight: normal !important;
7302    transform: translateY(8px);
7303  }
7304
7305  .border-sand {
7306    border-color: #5f471d;
7307  }
7308
7309  .tube-category {
7310    border: 1px solid #80808052;
7311    background: #fffbef;
7312    padding: 4px 20px;
7313    border-radius: 4px;
7314    position: relative;
7315  }
7316
7317  .variant-price-btn.temp.active div {
7318    border-color: #5f471d;
7319  }
7320
7321  .frequency-select {
7322    position: absolute;
7323    transform: translateX(-29px);
7324    opacity: 0;
7325  }
7326
7327  .frequency-selector {
7328    position: relative;
7329  }
7330
7331  .frequency-label {
7332    display: block;
7333    margin-bottom: 10px;
7334    font-weight: bold;
7335    font-weight: normal;
7336  }
7337
7338  .font-italic {
7339    font-style: italic;
7340    font-size: 12px;
7341  }
7342
7343  .frequency-options {
7344    display: flex;
7345    flex-direction: column;
7346    gap: 8px;
7347  }
7348
7349  .frequency-option {
7350    display: flex;
7351    align-items: center;
7352  }
7353
7354  .frequency-radio {
7355    appearance: none;
7356    -webkit-appearance: none;
7357    width: 18px;
7358    height: 18px;
7359    border: 1px solid #ccc;
7360    border-radius: 50%;
7361    margin-right: 10px;
7362    position: relative;
7363    cursor: pointer;
7364  }
7365
7366  .frequency-radio:checked {
7367    border-color: #000;
7368  }
7369
7370  .frequency-radio:checked::after {
7371    content: '';
7372    position: absolute;
7373    top: 3px;
7374    left: 3px;
7375    width: 10px;
7376    height: 10px;
7377    background: #000;
7378    border-radius: 50%;
7379  }
7380
7381  .frequency-option label {
7382    cursor: pointer;
7383  }
7384
7385  .frequency-dropdown-container {
7386    background: #fffbef;
7387    width: max-content;
7388    height: max-content;
7389    position: absolute;
7390    top: 0;
7391    left: 0;
7392    z-index: 1000;
7393    display: none;
7394    border-radius: 9px;
7395    padding: 5px 10px;
7396  }
7397
7398  .select_quantity {
7399    position: absolute;
7400    top: -5px;
7401    left: 50%;
7402    transform: translateX(-50%);
7403    font-size: 14px;
7404    font-weight: bold;
7405  }
7406
7407  .variant-price-btn.active.border-remove-btn {
7408    border: 1px solid #5f471d;
7409    border-radius: 5px;
7410  }
7411
7412  .save__amount {
7413    position: absolute;
7414    top: 1.7rem;
7415    right: 0px;
7416    width: max-content;
7417    background: #ffdea3;
7418    padding: 3px 11px;
7419    border-radius: 11px;
7420  }
7421
7422  .save__amount p {
7423    font-size: 12px !important;
7424    font-weight: normal !important;
7425  }
7426
7427  .subscriptions_selection {
7428    padding: 18px 0px;
7429  }
7430  .most-popular-pill {
7431    width: max-content;
7432    padding: 7px 15px;
7433    border-radius: 20px;
7434    color: #fff;
7435    font-size: 12px;
7436    line-height: 1;
7437    font-weight: normal !important;
7438    white-space: nowrap;
7439  }
7440  .subscription_original {
7441    font-size: 18px;
7442  }
7443
7444  .remove_one_time:not(.active) .subscriptions_selection {
7445    padding: 14px 0px 17px 0px;
7446  }
7447
7448  flavor-selector button[data-flavor='Citrus'].active {
7449    border-color: #ffbb42 !important;
7450    border-width: 2px;
7451  }
7452
7453  flavor-selector button[data-flavor='Mint'].active {
7454    border-color: #9ca975 !important;
7455    border-width: 2px;
7456  }
7457
7458  .remove_one_time.variant-price-btn:not(.active) .month-frequency {
7459    pointer-events: none;
7460    opacity: 0.5; /* Optional */
7461  }
7462
7463  .main__atc__button {
7464    border-radius: 25px;
7465  }
7466
7467  #variety-add-to-cart {
7468    border-radius: 25px;
7469    background: linear-gradient(to right, #ffdea3, #ffdea3, #e6ecd3, #e6ecd3) !important;
7470  }
7471
7472  .variety_tab_btn {
7473    background: #f5eee0;
7474    border-radius: 25px;
7475    padding: 2px 4px;
7476  }
7477
7478  .variety_tab_btn img {
7479    max-width: 2.5rem;
7480  }
7481
7482  button[data-flavor='Mint'] .save__amount {
7483    background-color: rgb(230, 236, 211) !important;
7484  }
7485
7486  button[data-flavor='Citrus'] .save__amount {
7487    background-color: rgb(255, 222, 163) !important;
7488  }
7489  button[data-flavor='Mint'] .most-popular-pill {
7490    background-color: #8A9D7C;
7491  }
7492
7493  button[data-flavor='Citrus'] .most-popular-pill {
7494    background-color: #FBAA4A;
7495  }
7496  product-form:has(.flavour-custom[data-flavor='Mint'].active) .main__atc__button {
7497    background-color: #e6ecd3 !important;
7498  }
7499
7500  @media (max-width: 767px) {
7501    .one_time_heading {
7502      font-size: 14px;
7503    }
7504
7505    .once_tube_container {
7506      padding: 0.5rem 0.5rem 1.5rem 0.5rem;
7507    }
7508
7509    .custom-badge {
7510      top: 1.6rem;
7511      font-size: 11px;
7512    }
7513
7514    .product-form-container {
7515      max-width: 380px;
7516    }
7517
7518    .tube-category {
7519      padding: 4px 8px;
7520    }
7521    .most-popular-pill {
7522      padding: 5px 9px;
7523      border-radius: 14px;
7524      font-size: 10px;
7525      line-height: 1;
7526      transform: translateY(-1px);
7527    }
7528  }
7529</style>
7530
7531        </div>
7532        
7533        <div class="travel__size__container" style="display:none;">
7534          
7535            <div class="ts-flavor-toggle">
7536              <button
7537                type="button"
7538                data-flavor="Citrus"
7539                class="flex items-center gap-3 text-brown rounded-[50px] py-2 pl-2 pr-3 lg:pr-6 lg:hover:bg-gold lg:hover:border-gold transition-colors duration-300 ts-flavor-btn ts-citrus"
7540              >
7541                <div class="relative w-8 h-8 bg-gold rounded-full flex items-center justify-center p-0.5">
7542                  <img class="rounded-full" src="//revitin.com/cdn/shop/t/129/assets/citrus-teaser.png?v=69425243372235278621777542405" loading="lazy">
7543                </div>
7544                <div class="font-body-medium text-sm lg:text-lg">Citrus</div>
7545              </button>
7546              <button
7547                type="button"
7548                data-flavor="Mint"
7549                class="flex items-center gap-3 text-brown rounded-[50px] py-2 pl-2 pr-3 lg:pr-6 lg:hover:bg-light-green lg:hover:border-light-green transition-colors duration-300 ts-flavor-btn ts-mint"
7550              >
7551                <div class="relative w-8 h-8 bg-light-green rounded-full flex items-center justify-center p-0.5">
7552                  <img class="rounded-full" src="//revitin.com/cdn/shop/t/129/assets/mint-teaser.png?v=43172182657372155721777542403" loading="lazy">
7553                </div>
7554                <div class="font-body-medium text-sm lg:text-lg">Mint</div>
7555              </button>
7556              <button
7557                type="button"
7558                data-flavor="Variety"
7559                style="border: 1px solid #C6C6C6;"
7560                class="flex items-center variety-selector-btn gap-1 text-brown rounded-[50px] py-2 pl-1 pr-3 lg:pr-6 lg:hover:bg-light-green lg:hover:border-light-green transition-colors duration-300 ts-flavor-btn ts-variety"
7561              >
7562                <div class="relative flex items-center justify-center ts_variety_tab_btn">
7563                  <img class="" src="//revitin.com/cdn/shop/t/129/assets/mix-match.png?v=98254657463874453371777542404" loading="lazy">
7564                </div>
7565                <div class="font-body-medium text-sm lg:text-lg">Variety</div>
7566              </button>
7567            </div>
7568
7569            <div class="ts-pack-options">
7570              <div>
7571                <label class="flex gap-2">
7572                  <input class="travel_size_checkbox" type="radio" name="ts-pack" value="1" checked>
7573                  <span class="ts-option-label font-body-medium">Citrus 3-pack</span>
7574                </label>
7575                <span class="ts-option-price font-body-medium">$16</span>
7576              </div>
7577            </div>
7578
7579            <button class="ts-add-to-bag-btn ts-citrus-btn font-body-medium">$16 — Add to Bag</button>
7580          
7581        </div>
7582      </div>
7583
7584      <div class="main-product__disclaimer text-brown text-center mt-4">
7585        <p class="text-xs">30-Day Money Back Guarantee</p>
7586        
7587      </div>
7588
7589        
7590    </div>
7591  </div>
7592</div>
7593
7594<script>
7595  document.addEventListener('DOMContentLoaded', function () {
7596    function roundToOneDecimal() {
7597      const ratingEl = document.querySelector('.jdgm-rev-widg__summary-average');
7598
7599      if (ratingEl) {
7600        const text = ratingEl.textContent.trim();
7601        const value = parseFloat(text);
7602
7603        if (!isNaN(value)) {
7604          ratingEl.textContent = value.toFixed(1); // Round to 1 decimal place
7605        } else {
7606          setTimeout(roundToOneDecimal, 300); // Retry if text isn't a number yet
7607        }
7608      } else {
7609        setTimeout(roundToOneDecimal, 300); // Retry if element not loaded yet
7610      }
7611    }
7612
7613    roundToOneDecimal();
7614  });
7615</script>
7615
7616
7617<script>
7618  document.addEventListener("DOMContentLoaded", () => {
7619    const flavourWrapper = document.querySelector(".flavour__selector");
7620    if (!flavourWrapper) return;
7621
7622    flavourWrapper.addEventListener("click", (e) => {
7623      if (!e.target || typeof e.target.closest !== 'function') return;
7624      const button = e.target.closest("button");
7625
7626      if (!button || !flavourWrapper.contains(button)) {
7627        e.stopPropagation();
7628        return;
7629      }
7630    });
7631  });
7632</script>
7632
7633
7634<script>
7635  document.addEventListener('DOMContentLoaded', () => {
7636    const boxes = document.querySelectorAll('.subscription-box');
7637    if (!boxes.length) return;
7638
7639    // Get the size selection container
7640    const sizeContainer = document.querySelector('.selection_btn_container');
7641    // Get the flavor selector container
7642    const flavorSelector = document.querySelector('.flavour__selector');
7643
7644    boxes.forEach((box, index) => {
7645      let lastState = null;
7646      let debounceTimer = null;
7647
7648      const getState = () => {
7649        // 1. Check subscription state (within subscription-box)
7650        const isSubscribed = box.querySelector('.variant-price-btn.remove_one_time.active') ? 'subscribed' : 'one-time';
7651        
7652        // 2. Check size selection (travel-size or full-size)
7653        const isTravelSize = sizeContainer && sizeContainer.querySelector('.travel-size-btn.active') ? 'travel-size' : 'full-size';
7654        
7655        // 3. Check if variety pack is selected
7656        const isVarietySelected = flavorSelector && flavorSelector.querySelector('[data-flavor="Variety"].active') ? 'variety' : 'single-flavor';
7657        
7658        // 4. Check if subscribe box is active in variety container
7659        const varietySubscribeBox = document.querySelector('#variety-subscribeBox');
7660        const isVarietySubscribeActive = varietySubscribeBox && varietySubscribeBox.classList.contains('variety-active') ? 'variety-subscribed' : 'variety-one-time';
7661        
7662        // 5. Check if one-time box is active in variety container
7663        const varietyOneTimeBox = document.querySelector('#variety-oneTimeBox');
7664        const isVarietyOneTimeActive = varietyOneTimeBox && varietyOneTimeBox.classList.contains('variety-active') ? 'one-time-active' : 'subscribe-active';
7665        
7666        return { isSubscribed, isTravelSize, isVarietySelected, isVarietySubscribeActive, isVarietyOneTimeActive };
7667      };
7668
7669      const logFinalState = () => {
7670        const currentState = getState();
7671        const stateString = `${currentState.isSubscribed}-${currentState.isTravelSize}-${currentState.isVarietySelected}-${currentState.isVarietySubscribeActive}-${currentState.isVarietyOneTimeActive}`;
7672        if (stateString === lastState) return;
7673
7674        const rightImages = document.querySelectorAll('.right_variety_image');
7675        const toteImages = document.querySelectorAll('.tote_bag_image');
7676        const rightMobileImages = document.querySelectorAll('.mobile_right_variety_image');
7677        const toteMobileImages = document.querySelectorAll('.tote_bag_image_mobile');
7678
7679        // Show tote images when ALL conditions are met:
7680        // 1. User is subscribed (either regular OR variety)
7681        // 2. Full-size is selected (NOT travel-size)
7682        // 3. If variety pack: variety is selected AND variety subscribe is active
7683        // 4. NOT when variety pack is selected but one-time purchase is active
7684        
7685        let showTote = false;
7686        
7687        
7688
7689        if (showTote) {
7690          rightImages.forEach((img) => (img.style.display = 'none'));
7691          toteImages.forEach((img) => (img.style.display = 'block'));
7692          rightMobileImages.forEach((img) => (img.style.display = 'none'));
7693          toteMobileImages.forEach((img) => (img.style.display = 'block'));
7694        } else {
7695          rightImages.forEach((img) => (img.style.display = 'block'));
7696          toteImages.forEach((img) => (img.style.display = 'none'));
7697          rightMobileImages.forEach((img) => (img.style.display = 'block'));
7698          toteMobileImages.forEach((img) => (img.style.display = 'none'));
7699        }
7700
7701        lastState = stateString;
7702      };
7703
7704      const debounceLog = () => {
7705        clearTimeout(debounceTimer);
7706        debounceTimer = setTimeout(logFinalState, 50);
7707      };
7708
7709      // Initial check
7710      debounceLog();
7711
7712      // Listen to subscription box clicks
7713      box.addEventListener('click', (e) => {
7714        if (e.target && typeof e.target.closest === 'function' && e.target.closest('.variant-price-btn.remove_one_time')) {
7715          debounceLog();
7716        }
7717      });
7718
7719      // Listen to size button clicks if container exists
7720      if (sizeContainer) {
7721        sizeContainer.addEventListener('click', (e) => {
7722          if (e.target && typeof e.target.closest === 'function' && e.target.closest('.size_selection_btn')) {
7723            debounceLog();
7724          }
7725        });
7726        
7727        // Observe size container for class changes
7728        const sizeObserver = new MutationObserver(debounceLog);
7729        sizeObserver.observe(sizeContainer, {
7730          attributes: true,
7731          subtree: true,
7732          attributeFilter: ['class'],
7733        });
7734      }
7735
7736      // Listen to flavor selector clicks
7737      if (flavorSelector) {
7738        flavorSelector.addEventListener('click', (e) => {
7739          if (e.target && typeof e.target.closest === 'function' && (e.target.closest('.flavour-custom') || e.target.closest('.variety-selector-btn'))) {
7740            debounceLog();
7741          }
7742        });
7743        
7744        // Observe flavor selector for class changes
7745        const flavorObserver = new MutationObserver(debounceLog);
7746        flavorObserver.observe(flavorSelector, {
7747          attributes: true,
7748          subtree: true,
7749          attributeFilter: ['class'],
7750        });
7751      }
7752
7753      // Listen to variety container changes
7754      const varietyContainer = document.querySelector('.variety-selection-container');
7755      if (varietyContainer) {
7756        varietyContainer.addEventListener('click', (e) => {
7757          if (e.target && typeof e.target.closest === 'function' && (e.target.closest('.variety-radio-input') || e.target.closest('.variety-box'))) {
7758            debounceLog();
7759          }
7760        });
7761        
7762        // Observe variety container for changes
7763        const varietyObserver = new MutationObserver(debounceLog);
7764        varietyObserver.observe(varietyContainer, {
7765          attributes: true,
7766          subtree: true,
7767          attributeFilter: ['class'],
7768        });
7769      }
7770
7771      // Observe subscription box for changes
7772      const observer = new MutationObserver(debounceLog);
7773      observer.observe(box, {
7774        attributes: true,
7775        subtree: true,
7776        attributeFilter: ['class'],
7777      });
7778    });
7779  });
7780</script>
7780
7781
7782<script>
7783  class OuraStyleSlider {
7784    constructor(container) {
7785      this.container = container;
7786      this.slides = container.querySelectorAll('.slide');
7787      this.dots = container.querySelectorAll('.progress-slider-dot');
7788      this.currentIndex = 0;
7789      this.totalSlides = this.slides.length;
7790      this.progressDuration = 5000; // 5 seconds
7791      this.progressStartTime = null;
7792      this.animationFrame = null;
7793      this.isAnimating = false;
7794      
7795      this.init();
7796    }
7797    
7798    init() {
7799      // Initialize first slide
7800      this.updateSlides();
7801      
7802      // Setup event listeners for dots
7803      this.dots.forEach(dot => {
7804        dot.addEventListener('click', (e) => {
7805          const index = parseInt(e.currentTarget.dataset.slideIndex);
7806          this.goToSlide(index);
7807        });
7808      });
7809      
7810      // Setup touch/swipe events
7811      this.setupTouchEvents();
7812      
7813      // Setup mouse events (but don't pause on hover)
7814      this.setupMouseEvents();
7815      
7816      // Start autoplay - NEVER STOPS
7817      this.startAutoPlay();
7818    }
7819    
7820    goToSlide(index) {
7821      if (index === this.currentIndex) return;
7822      
7823      // Stop current animation frame
7824      if (this.animationFrame) {
7825        cancelAnimationFrame(this.animationFrame);
7826        this.animationFrame = null;
7827      }
7828      
7829      // Update current index
7830      this.currentIndex = index;
7831      
7832      // Update slides visibility
7833      this.updateSlides();
7834      
7835      // Immediately restart autoplay - NO PAUSE
7836      this.startAutoPlay();
7837    }
7838    
7839    nextSlide() {
7840      const nextIndex = (this.currentIndex + 1) % this.totalSlides;
7841      this.goToSlide(nextIndex);
7842    }
7843    
7844    prevSlide() {
7845      const prevIndex = (this.currentIndex - 1 + this.totalSlides) % this.totalSlides;
7846      this.goToSlide(prevIndex);
7847    }
7848    
7849    updateSlides() {
7850      // Hide all slides
7851      this.slides.forEach(slide => {
7852        slide.classList.remove('active');
7853      });
7854      
7855      // Remove active class from all dots
7856      this.dots.forEach(dot => {
7857        dot.classList.remove('active');
7858        const progress = dot.querySelector('.dot-progress');
7859        if (progress) {
7860          progress.style.width = '0%';
7861        }
7862      });
7863      
7864      // Show current slide
7865      this.slides[this.currentIndex].classList.add('active');
7866      
7867      // Activate current dot
7868      this.dots[this.currentIndex].classList.add('active');
7869    }
7870    
7871    startAutoPlay() {
7872      // Cancel any existing animation
7873      if (this.animationFrame) {
7874        cancelAnimationFrame(this.animationFrame);
7875      }
7876      
7877      const activeDot = this.dots[this.currentIndex];
7878      const progressBar = activeDot.querySelector('.dot-progress');
7879      
7880      if (!progressBar) return;
7881      
7882      // Reset progress
7883      progressBar.style.transition = 'none';
7884      progressBar.style.width = '0%';
7885      
7886      // Force reflow
7887      progressBar.offsetHeight;
7888      
7889      // Start smooth progress animation
7890      this.progressStartTime = Date.now();
7891      this.isAnimating = true;
7892      
7893      const animate = () => {
7894        if (!this.isAnimating) return;
7895        
7896        const elapsed = Date.now() - this.progressStartTime;
7897        const progress = Math.min(elapsed / this.progressDuration, 1);
7898        
7899        // Update width smoothly
7900        progressBar.style.width = `${progress * 100}%`;
7901        
7902        if (progress < 1) {
7903          // Continue animation
7904          this.animationFrame = requestAnimationFrame(animate);
7905        } else {
7906          // Animation complete - go to next slide
7907          this.nextSlide();
7908        }
7909      };
7910      
7911      // Start the smooth animation
7912      this.animationFrame = requestAnimationFrame(animate);
7913    }
7914    
7915    stopAutoPlay() {
7916      this.isAnimating = false;
7917      if (this.animationFrame) {
7918        cancelAnimationFrame(this.animationFrame);
7919        this.animationFrame = null;
7920      }
7921    }
7922    
7923    setupTouchEvents() {
7924      const slidesContainer = this.container.querySelector('.slides-container');
7925      let touchStartX = 0;
7926      let isSwiping = false;
7927      
7928      slidesContainer.addEventListener('touchstart', (e) => {
7929        touchStartX = e.touches[0].clientX;
7930        isSwiping = true;
7931        // NO PAUSE - just continue
7932      });
7933      
7934      slidesContainer.addEventListener('touchmove', (e) => {
7935        if (!isSwiping) return;
7936        e.preventDefault();
7937      });
7938      
7939      slidesContainer.addEventListener('touchend', (e) => {
7940        if (!isSwiping) return;
7941        
7942        const touchEndX = e.changedTouches[0].clientX;
7943        const diffX = touchStartX - touchEndX;
7944        const threshold = 30;
7945        
7946        if (Math.abs(diffX) > threshold) {
7947          if (diffX > 0) {
7948            // Swipe left - next slide
7949            this.nextSlide();
7950          } else {
7951            // Swipe right - previous slide
7952            this.prevSlide();
7953          }
7954        }
7955        
7956        isSwiping = false;
7957      });
7958    }
7959    
7960    setupMouseEvents() {
7961      const slidesContainer = this.container.querySelector('.slides-container');
7962      
7963      // NO PAUSE on hover - just continue playing
7964      // We still want to allow dragging/swiping with mouse
7965      
7966      let isMouseDown = false;
7967      let mouseStartX = 0;
7968      
7969      slidesContainer.addEventListener('mousedown', (e) => {
7970        isMouseDown = true;
7971        mouseStartX = e.clientX;
7972        e.preventDefault();
7973      });
7974      
7975      slidesContainer.addEventListener('mousemove', (e) => {
7976        if (!isMouseDown) return;
7977        e.preventDefault();
7978      });
7979      
7980      slidesContainer.addEventListener('mouseup', (e) => {
7981        if (!isMouseDown) return;
7982        
7983        const mouseEndX = e.clientX;
7984        const diffX = mouseStartX - mouseEndX;
7985        const threshold = 30;
7986        
7987        if (Math.abs(diffX) > threshold) {
7988          if (diffX > 0) {
7989            this.nextSlide();
7990          } else {
7991            this.prevSlide();
7992          }
7993        }
7994        
7995        isMouseDown = false;
7996      });
7997      
7998      slidesContainer.addEventListener('mouseleave', () => {
7999        isMouseDown = false;
8000      });
8001    }
8002  }
8003
8004  // Initialize all sliders when DOM is loaded
8005  document.addEventListener('DOMContentLoaded', () => {
8006    setTimeout(() => {
8007      const sliders = document.querySelectorAll('.custom-slider');
8008      sliders.forEach(slider => {
8009        new OuraStyleSlider(slider);
8010      });
8011    }, 100);
8012  });
8013</script>
8013
8014
8015
8016
8017<script>  
8018
8019  document.addEventListener('DOMContentLoaded', function () {
8020    const onLoadParams = new URLSearchParams(window.location.search);
8021    const isWholesaleCustomer = false;
8022
8023    if (isWholesaleCustomer && onLoadParams.get('pack') === 'variety') {
8024      onLoadParams.delete('pack');
8025      const query = onLoadParams.toString();
8026      window.history.replaceState({}, '', `${window.location.pathname}${query ? `?${query}` : ''}`);
8027    }
8028
8029    // Configuration and Constants
8030    const CONFIG = {
8031      flavors: isWholesaleCustomer ? ['Citrus', 'Mint'] : ['Citrus', 'Mint', 'Variety'],
8032      sizes: ['full', 'travel'],
8033      images: {
8034        Citrus: [
8035          "//revitin.com/cdn/shop/files/citrus-gallery-render_12zon_1600x.jpg",
8036          "//revitin.com/cdn/shop/files/citrus-gallery-2_11zon_1600x.jpg?v=1729881153",
8037          
8038          "//revitin.com/cdn/shop/files/citrus-gallery-3_11zon_1600x.jpg?v=1751389467",
8039          
8040        ],
8041        MobileCitrus: [
8042          "//revitin.com/cdn/shop/files/citrus-gallery-mobile-2_11zon_1000x.jpg?v=1729883824",
8043          
8044          "//revitin.com/cdn/shop/files/citrus-gallery-mobile-3_11zon_1000x.jpg?v=1729883824"
8045          
8046        ],
8047        Mint: [
8048          "//revitin.com/cdn/shop/files/mint-render-gallery_11zon_1600x.jpg?v=1730192833",
8049          "//revitin.com/cdn/shop/files/mint-gallery-2_11zon_1600x.jpg?v=1751389546",
8050          "//revitin.com/cdn/shop/files/mint-gallery-3_11zon_1600x.jpg?v=1729881153",
8051        ],
8052        MobileMint: [
8053          "//revitin.com/cdn/shop/files/mint-gallery-mobile-2_11zon_1000x.jpg?v=1729883825",
8054          "//revitin.com/cdn/shop/files/mint-gallery-mobile-3_11zon_1000x.jpg?v=1729883824"
8055        ]
8056      }
8057    };
8058
8059    // State Management
8060    const state = {
8061      products: [],
8062      allProducts: [],
8063      selectedFlavor: 'Citrus',
8064      selectedPack: '1',
8065      selectedSize: 'full'
8066    };
8067 
8068    // DOM Elements Cache
8069    const elements = {
8070      sidebar: document.querySelector('.sb-sidebar'),
8071      openBtns: document.querySelectorAll('.sb-open-btn'),
8072      closeBtn: document.querySelector('.sb-close-btn'),
8073      sizeBtns: document.querySelectorAll('.size_selection_btn'),
8074      fullContainer: document.querySelector('.full__size__container'),
8075      travelContainer: document.querySelector('.travel__size__container'),
8076      mainPdpSizeHeading: document.querySelector('.main_pdp_size_heading'),
8077      pricingRadioTab: document.querySelector('.ts-option-price'),
8078      flavorBtns: document.querySelectorAll('.ts-flavor-btn'),
8079      addBtn: document.querySelector('.ts-add-to-bag-btn'),
8080      packOptions: document.querySelectorAll('input[name="ts-pack"]'),
8081      activePackRadioLabel: document.querySelector('.ts-option-label'),
8082      mainVarietyImage: document.querySelector(".main_variety_image"),
8083      mobileMainVarietyImage: document.querySelector(".mobile_main_variety_image"),
8084      leftVarietyImage: document.querySelector(".left_variety_image"),
8085      mobileLeftVarietyImage: document.querySelector(".mobile_left_variety_image"),
8086      rightVarietyImage: document.querySelector(".right_variety_image"),
8087      mobileRightVarietyImage: document.querySelector(".mobile_right_variety_image"),
8088      cartCount: document.querySelector(".variety-cart-count"),
8089      mainAtcBtn: document.querySelector(".main__atc__button"),
8090      pdpSellingInput: document.querySelector(".cart_selling_plan"),
8091      travelVarietyButton: document.querySelector('.ts-flavor-toggle button[data-flavor="Variety"]'),
8092    };
8093
8094    const editorMainImages = { Citrus: {}, Mint: {} };
8095    let wholesaleTravelFeatured = {};
8096
8097    if (isWholesaleCustomer) {
8098      const featuredEl = document.getElementById('wholesale-travel-featured-images');
8099      if (featuredEl) {
8100        try {
8101          wholesaleTravelFeatured = JSON.parse(featuredEl.textContent);
8102        } catch (error) {
8103          wholesaleTravelFeatured = {};
8104        }
8105      }
8106
8107      document.querySelectorAll('[data-swap-flavor]').forEach((container) => {
8108        const flavor = container.dataset.swapFlavor;
8109        if (!flavor || flavor === 'Variety') return;
8110
8111        const main = container.querySelector('.main_variety_image');
8112        const mobileMain = container.querySelector('.mobile_main_variety_image');
8113
8114        if (main) editorMainImages[flavor].desktop = main.getAttribute('src');
8115        if (mobileMain) editorMainImages[flavor].mobile = mobileMain.getAttribute('src');
8116      });
8117    }
8118
8119    // Utility Functions
8120    const utils = {
8121      formatPrice(price) {
8122        let formatted = (typeof price === 'number' ? price.toFixed(2) : String(price));
8123        return formatted.endsWith('.00') ? formatted.replace('.00', '') : formatted;
8124      },
8125
8126      getUrlParams() {
8127        return new URLSearchParams(window.location.search);
8128      },
8129
8130      getFlavorFromPath() {
8131        const path = window.location.pathname;
8132        const parts = path.split("/").filter(Boolean);
8133        return parts[parts.length - 1];
8134      },
8135
8136      updateUrlParam(key, value) {
8137        const params = utils.getUrlParams();
8138        if (value) {
8139          params.set(key, value);
8140        } else {
8141          params.delete(key);
8142        }
8143        window.history.replaceState({}, "", `${window.location.pathname}?${params.toString()}`);
8144      },
8145
8146      updateUrlPath(flavor) {
8147        const path = window.location.pathname.split("/").filter(Boolean);
8148        if (path[0] === "products") {
8149          path[path.length - 1] = flavor;
8150          const newPath = "/" + path.join("/");
8151          const query = window.location.search;
8152          window.history.replaceState({}, "", newPath + query);
8153        }
8154      },
8155
8156      updateFlavorUrl(){
8157        const currentUrl = window.location.pathname + window.location.search;
8158
8159        const [path, query] = currentUrl.split("?");
8160        
8161        const hasFlavor = /\/(Citrus|Mint)(\/|$)/i.test(path);
8162
8163        if (!hasFlavor && query === "size=travel") {
8164          const newPath = path.endsWith("/") ? `${path}Citrus` : `${path}/Citrus`;
8165          const newUrl = query ? `${newPath}?${query}` : newPath;
8166
8167          window.history.replaceState({}, "", newUrl);
8168        }
8169      }
8170    };
8171
8172    // Product Data Management
8173    const productManager = {
8174      init() {
8175        this.loadProducts();
8176        state.selectedFlavor = utils.getFlavorFromPath() || 'Citrus';
8177        state.selectedSize = utils.getUrlParams().get("size") ? "travel" : "full";
8178      },
8179
8180      loadProducts() {
8181        try {
8182          const products = JSON.parse(document.getElementById('all-products-json').textContent);
8183          state.products = products.filter(item => 
8184            item.title.toLowerCase().includes("travel") || item.handle.toLowerCase().includes("travel")
8185          );
8186          state.allProducts = products;
8187        } catch (error) {
8188          
8189          state.products = [];
8190        }
8191      },
8192
8193      getAllProducts() {
8194        try {
8195          return JSON.parse(document.getElementById('all-products-json').textContent);
8196        } catch (error) {
8197          
8198          return [];
8199        }
8200      },
8201
8202      getProduct(flavor, size = 'travel') {
8203        if (flavor === 'Variety') {
8204          return state.allProducts.find(item => 
8205            item.title.includes(flavor) && item.title.includes(size === 'travel' ? 'Travel' : '')
8206          );
8207        } else {
8208          return state.products.find(item => 
8209            item.title.includes(flavor) && item.title.includes(size === 'travel' ? 'Travel' : '')
8210          );
8211        }
8212      },
8213
8214      getVariantId(flavor) {
8215        const product = this.getProduct(flavor);
8216        return product ? product.variants[0].id : null;
8217      },
8218
8219      getProductPrice(flavor, pack) {
8220        const product = this.getProduct(flavor);
8221        
8222        const price = product?.variants[0]?.price || 18; // Fallback price
8223        return utils.formatPrice(price);
8224      }
8225    };
8226
8227    // UI Update Functions
8228    const uiUpdater = {
8229      updateSidebarPdpTitle(size) {
8230        if (!elements.mainPdpSizeHeading) return;
8231
8232        const products = productManager.getAllProducts();
8233        const travelProduct = state.products[0];
8234        const fullProduct = products?.find(item => 
8235          item.aestheticTitle && !item?.aestheticTitle.toLowerCase().includes("travel")
8236        );
8237
8238        elements.mainPdpSizeHeading.textContent = size === "travel" 
8239          ? (travelProduct?.aestheticTitle || 'Revitin Natural Toothpaste')
8240          : (fullProduct?.aestheticTitle || 'Revitin Natural Toothpaste');
8241      },
8242
8243      updateActiveButtons(buttons, activeButton, className = 'active') {
8244        buttons.forEach(btn => btn.classList.remove(className));
8245        activeButton?.classList.add(className);
8246      },
8247
8248      updateAddButton(flavor, pack) {
8249        if (!elements.addBtn) return;
8250
8251        const price = productManager.getProductPrice(flavor, pack);
8252        
8253        elements.addBtn.textContent = `$${price} — Add to Bag`;
8254        elements.addBtn.className = `ts-add-to-bag-btn ts-${flavor.toLowerCase()}-btn`;
8255        
8256        if (elements.pricingRadioTab) {
8257          elements.pricingRadioTab.textContent = `$${price}`;
8258        }
8259        
8260        if (elements.activePackRadioLabel) {
8261          if(flavor === 'Variety') {
8262            elements.activePackRadioLabel.textContent = `2 Mint & 2 Citrus`;
8263          } else {
8264            elements.activePackRadioLabel.textContent = `${flavor} 3-pack`;
8265          }
8266        }
8267      },
8268
8269      applyWholesaleTravelMainImage(flavor) {
8270        if (!isWholesaleCustomer) return;
8271
8272        const featuredUrl = wholesaleTravelFeatured[flavor];
8273        if (!featuredUrl) return;
8274
8275        document.querySelectorAll(`[data-swap-flavor="${flavor}"]`).forEach((container) => {
8276          const main = container.querySelector('.main_variety_image');
8277          const mobileMain = container.querySelector('.mobile_main_variety_image');
8278          if (main) main.src = featuredUrl;
8279          if (mobileMain) mobileMain.src = featuredUrl;
8280        });
8281      },
8282
8283      restoreWholesaleEditorMainImages() {
8284        if (!isWholesaleCustomer) return;
8285
8286        Object.keys(editorMainImages).forEach((flavor) => {
8287          document.querySelectorAll(`[data-swap-flavor="${flavor}"]`).forEach((container) => {
8288            const main = container.querySelector('.main_variety_image');
8289            const mobileMain = container.querySelector('.mobile_main_variety_image');
8290            if (main && editorMainImages[flavor].desktop) main.src = editorMainImages[flavor].desktop;
8291            if (mobileMain && editorMainImages[flavor].mobile) mobileMain.src = editorMainImages[flavor].mobile;
8292          });
8293        });
8294      },
8295
8296      setActiveFlavorImages(flavor) {
8297        // Update flavor-specific images in containers
8298        const flavorImages = document.querySelectorAll('[data-swap-flavor]');
8299        const params = utils.getUrlParams();
8300        const isTravelUrl = params.get('size');
8301
8302        const refineVariety = flavor === "Variety" ? "Citrus"  : flavor;
8303
8304        if(!isTravelUrl) return;
8305
8306        if (isWholesaleCustomer) {
8307          const opposite = refineVariety === 'Citrus' ? 'Mint' : 'Citrus';
8308          document.querySelectorAll(`[data-swap-flavor="${refineVariety}"]`).forEach((el) => {
8309            el.classList.remove('opacity-0');
8310            el.classList.add('!opacity-100', 'z-10');
8311          });
8312          document.querySelectorAll(`[data-swap-flavor="${opposite}"]`).forEach((el) => {
8313            el.classList.add('opacity-0');
8314            el.classList.remove('!opacity-100', 'z-10');
8315          });
8316          this.applyWholesaleTravelMainImage(refineVariety);
8317          return;
8318        }
8319
8320        flavorImages.forEach(img => {
8321          const hasMainImage = img.querySelector('.main_variety_image');
8322          const hasMobileMainImage = img.querySelector('.mobile_main_variety_image');
8323          const swapFlav = img.dataset.swapFlavor;
8324          const isActive = swapFlav  === refineVariety;
8325
8326          const parent = img.parentElement;
8327          
8328
8329          
8330
8331          
8332
8333          if(hasMainImage || hasMobileMainImage) {
8334             if(swapFlav === "Citrus") {
8335                img.classList.remove("opacity-0");
8336                img.classList.add("!opacity-100");
8337             }
8338             if(swapFlav === "Mint") {
8339                img.classList.add("opacity-0");
8340                img.classList.remove("!opacity-100");
8341                img.classList.remove("z-10");
8342             }
8343          }else {
8344              img.classList.toggle('!opacity-100', isActive);
8345              img.classList.toggle('opacity-0', !isActive);
8346          }
8347        });
8348
8349        // Update variety images
8350        this.updateVarietyImages(refineVariety);
8351      },
8352
8353      updateMainVarietyImage(flavor, newImageUrl) {
8354        const container = document.querySelector(`.image_update_container [data-swap-flavor="${flavor}"]`);
8355        if (!container) {
8356          console.warn(`Flavor "${flavor}" not found.`);
8357          return;
8358        }
8359
8360        const mainImage = container.querySelector('.main_variety_image');
8361        if (!mainImage) {
8362          console.warn(`Main variety image not found for flavor "${flavor}".`);
8363          return;
8364        }
8365
8366        mainImage.src = newImageUrl;
8367      },
8368
8369      updateVarietyImages(flavor) {
8370        const product = productManager.getProduct(flavor);
8371        const flavorImages = CONFIG.images[flavor];
8372        const mobileFlavorImages = CONFIG.images[`Mobile${flavor}`];
8373
8374        // Desktop
8375        const imgForMainVariety = product?.images?.[0]?.src;
8376        const imgForRightVariety = product?.images?.[1]?.src;
8377        const imgForLeftVariety = product?.images?.[2]?.src;
8378
8379        
8380
8381        // Mobile
8382        const imgForMobileMainVariety = flavor === "Citrus" ? product?.images?.[2]?.src : product?.images?.[1]?.src;
8383        const imgForMobileBottom = product?.images?.[3]?.src;
8384
8385        if (imgForMainVariety && elements.mainVarietyImage) {
8386          elements.mainVarietyImage.src = imgForMainVariety;
8387        }
8388
8389        if (imgForMobileMainVariety && elements.mobileMainVarietyImage) {
8390          elements.mobileMainVarietyImage.src = imgForMobileMainVariety;
8391        }
8392
8393        // Travel Citrus / Variety: do NOT apply the Right Image 2 override.
8394        // Use the actual travel product image so the "Right Image 2" gallery override is skipped in travel mode.
8395        if (imgForRightVariety && elements.rightVarietyImage && flavor === 'Citrus') {
8396          elements.rightVarietyImage.src = imgForRightVariety;
8397        }
8398
8399        if (flavorImages && elements.leftVarietyImage && elements.rightVarietyImage) {
8400          if(flavor === 'Mint'){
8401            elements.rightVarietyImage.src = flavorImages[2];
8402            elements.leftVarietyImage.src = imgForLeftVariety;
8403          }else{
8404            elements.leftVarietyImage.src = flavorImages[1];
8405          }
8406        }
8407
8408        if (mobileFlavorImages && elements.mobileRightVarietyImage) {
8409          elements.mobileLeftVarietyImage.src = mobileFlavorImages[0];
8410          // Travel Citrus / Variety: skip Right Image 2 Mobile override — use the travel product's own image.
8411          elements.mobileRightVarietyImage.src = imgForMobileBottom;
8412        }
8413
8414      },
8415
8416      updateSizeContainers(size) {
8417        if (!elements.fullContainer || !elements.travelContainer) return;
8418
8419        const isTravel = size === 'travel';
8420        elements.fullContainer.style.display = isTravel ? 'none' : 'block';
8421        elements.travelContainer.style.display = isTravel ? 'block' : 'none';
8422      }
8423    };
8424
8425    function getCart() {
8426      return fetch('/cart.js')
8427        .then(res => res.json());
8428    }
8429
8430    const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
8431
8432    // Event Handlers
8433    const eventHandlers = {
8434      addToteBag() {
8435        elements.mainAtcBtn.addEventListener('click', async () => {
8436          const sellingPlanId = elements.pdpSellingInput?.value;
8437          if (!sellingPlanId) return;
8438
8439          const cart = await getCart();
8440
8441          const toteExists = cart.items.some(item =>
8442            item.handle?.includes('tote')
8443          );
8444
8445          if (toteExists) return;
8446
8447          const products = productManager.getAllProducts();
8448          const freeToBag = products.find(p =>
8449            p.handle?.toLowerCase().includes('tote')
8450          );
8451
8452          const variantId = freeToBag?.variants?.[0]?.id;
8453          if (!variantId) return;
8454
8455          await sleep(1500);
8456
8457          eventHandlers.addToCart(variantId);
8458        });
8459      },
8460
8461      initSidebar() {
8462        if (!elements.sidebar || !elements.closeBtn) return;
8463
8464        elements.openBtns.forEach(btn => {
8465          btn.addEventListener('click', () => elements.sidebar.classList.add('sb-active'));
8466        });
8467
8468        elements.closeBtn.addEventListener('click', () => elements.sidebar.classList.remove('sb-active'));
8469
8470        document.addEventListener('click', (event) => {
8471          if (!event.target || typeof event.target.closest !== 'function') return;
8472          if (!elements.sidebar.contains(event.target) && !event.target.closest('.sb-open-btn')) {
8473            elements.sidebar.classList.remove('sb-active');
8474          }
8475        });
8476      },
8477
8478      initSizeSelection() {
8479        if (!elements.sizeBtns.length) return;
8480        utils.updateFlavorUrl();
8481
8482        elements.sizeBtns.forEach(btn => {
8483          btn.addEventListener('click', () =>
8483 this.handleSizeSelection(btn));
8484        });
8485
8486        // Initialize based on URL params
8487        this.initializeSizeFromParams();
8488      },
8489
8490      initializeSizeFromParams() {
8491        const sizeBtn = state.selectedSize === 'travel' 
8492          ? document.querySelector('.travel-size-btn')
8493          : document.querySelector('.full-size-btn');
8494
8495        if (sizeBtn) {
8496          this.handleSizeSelection(sizeBtn, true);
8497        }
8498      },
8499
8500      handleSizeSelection(btn, isInitial = false) {
8501        const appliedStyles = window.getComputedStyle(btn);
8502
8503        const visibleBtn = Array.from(elements.sizeBtns).find(
8504          btn => window.getComputedStyle(btn).display !== "none"
8505        );
8506
8507        const actualButton = appliedStyles.display === "none" ?  visibleBtn : btn;
8508
8509        uiUpdater.updateActiveButtons(elements.sizeBtns, actualButton);
8510        
8511        const isTravel = actualButton.classList.contains('travel-size-btn');
8512        state.selectedSize = isTravel ? 'travel' : 'full';
8513
8514        // Wholesale travel: remove image fade transitions to match full-size feel
8515        if (isWholesaleCustomer) {
8516          const pdpContainer = document.getElementById('pdp-container');
8517          if (pdpContainer) {
8518            pdpContainer.classList.toggle('ws-travel-no-transition', isTravel);
8519          }
8520        }
8521
8522        uiUpdater.updateSizeContainers(state.selectedSize);
8523        utils.updateUrlParam('size', isTravel ? 'travel' : '');
8524        uiUpdater.updateSidebarPdpTitle(state.selectedSize);
8525
8526        
8527
8528        // Update this section:
8529        if (isTravel) {
8530          // Get flavor from URL instead of hardcoding to Citrus
8531          utils.updateFlavorUrl();
8532          let flavorFromUrl = utils.getFlavorFromPath() || 'Citrus';
8533          const params = utils.getUrlParams();
8534          const isVariety = params.get('pack');
8535          const isTravelUrl = params.get('size');
8536
8537          // Wholesale: inherit flavor from full-size wholesale buttons when switching to travel
8538          if (isWholesaleCustomer) {
8539            const activeFullBtn = document.querySelector('.whole_flavor_btn.active');
8540            if (activeFullBtn?.dataset.flavor) {
8541              flavorFromUrl = activeFullBtn.dataset.flavor;
8542            }
8543            if (typeof window.__revitinSetWholesaleTravelFlavor === 'function') {
8544              window.__revitinSetWholesaleTravelFlavor(flavorFromUrl);
8545            }
8546          }
8547
8548          state.selectedFlavor = flavorFromUrl;
8549          
8550          // Find and activate the correct flavor button
8551          const flavorBtn = Array.from(elements.flavorBtns).find(btn => 
8552            btn.dataset.flavor === flavorFromUrl || 
8553            btn.classList.contains(`ts-${flavorFromUrl.toLowerCase()}`)
8554          );
8555          
8556          uiUpdater.updateActiveButtons(elements.flavorBtns, flavorBtn);
8557          uiUpdater.setActiveFlavorImages(flavorFromUrl);
8558          if(isVariety && isTravelUrl) {
8559            utils.updateUrlParam('pack');
8560          }
8561        } else {
8562          if (isWholesaleCustomer) {
8563            uiUpdater.restoreWholesaleEditorMainImages();
8564
8565            // Sync full-size wholesale UI to the travel flavor that was active
8566            const travelActive = document.querySelector(
8567              '.travel__size__container .ts-flavor-btn.active'
8568            );
8569            const flavor =
8570              travelActive?.dataset.flavor ||
8571              utils.getFlavorFromPath() ||
8572              'Citrus';
8573
8574            document.querySelectorAll('.whole_flavor_btn').forEach((btn) => {
8575              btn.classList.toggle('active', btn.dataset.flavor === flavor);
8576              btn.style.background = '';
8577              btn.style.borderColor = '';
8578            });
8579            document.querySelectorAll('.wholesale_item').forEach((item) => {
8580              item.classList.toggle(
8581                'hidden',
8582                item.dataset.wholesaleFlavor !== flavor
8583              );
8584            });
8585            document.querySelectorAll('[data-swap-flavor]').forEach((el) => {
8586              const isActive = el.getAttribute('data-swap-flavor') === flavor;
8587              el.classList.toggle('opacity-0', !isActive);
8588              el.classList.toggle('!opacity-100', isActive);
8589              el.classList.toggle('z-10', isActive);
8590            });
8591            state.selectedFlavor = flavor;
8592          } else if (!isInitial) {
8593            this.simulateFlavourClick();
8594            if(elements.travelVarietyButton) {
8595              elements.travelVarietyButton.classList.remove("active");
8596            }
8597          }
8598        }
8599
8600        if (!isInitial) {
8601          uiUpdater.updateAddButton(state.selectedFlavor, state.selectedPack);
8602        }
8603      },
8604
8605      initFlavorSelection() {
8606        if (!elements.flavorBtns.length) return;
8607
8608        elements.flavorBtns.forEach(btn => {
8609          btn.addEventListener('click', () =>
8609 this.handleFlavorSelection(btn));
8610        });
8611
8612        // Initialize based on URL params
8613        this.initializeFlavorFromParams();
8614      },
8615
8616      initializeFlavorFromParams() {
8617        const currentFlavor = utils.getFlavorFromPath();
8618
8619        const flavorBtn = Array.from(elements.flavorBtns).find(btn => 
8620          btn.dataset.flavor === currentFlavor || 
8621          btn.classList.contains(`ts-${currentFlavor.toLowerCase()}`)
8622        );
8623
8624        if (flavorBtn) {
8625          this.handleFlavorSelection(flavorBtn, true);
8626        }
8627      },
8628
8629      handleFlavorSelection(btn, isInitial = false) {
8630        const flavor = btn.dataset.flavor;
8631
8632        if(!isWholesaleCustomer && isInitial && onLoadParams.get('pack') === "variety" && onLoadParams.get('size') === "travel") {
8633        uiUpdater.updateActiveButtons(elements.flavorBtns, elements.travelVarietyButton);
8634
8635          state.selectedFlavor = "Variety";
8636        } else {
8637        uiUpdater.updateActiveButtons(elements.flavorBtns, btn);
8638
8639          state.selectedFlavor = flavor;
8640        }
8641
8642        uiUpdater.updateAddButton(state.selectedFlavor, state.selectedPack);
8643        
8644        if (!isInitial && flavor !== 'Variety') {
8645          utils.updateUrlPath(state.selectedFlavor);
8646          utils.updateUrlParam('pack');
8647        }
8648        
8649        uiUpdater.setActiveFlavorImages(state.selectedFlavor);
8650      },
8651
8652      initPackSelection() {
8653        if (!elements.packOptions.length) return;
8654
8655        elements.packOptions.forEach(option => {
8656          option.addEventListener('change', (e) => {
8657            state.selectedPack = e.target.value;
8658            uiUpdater.updateAddButton(state.selectedFlavor, state.selectedPack);
8659          });
8660        });
8661      },
8662
8663      initAddToCart() {
8664        if (!elements.addBtn) return;
8665
8666        elements.addBtn.addEventListener('click', () => {
8667          const variantId = productManager.getVariantId(state.selectedFlavor);
8668          
8669          if (variantId) {
8670            this.addToCart(variantId, parseInt(state.selectedPack));
8671          } else {
8672            console.error('Variant not found for flavor:', state.selectedFlavor);
8673          }
8674        });
8675      },
8676
8677      simulateFlavourClick() {
8678        const path = window.location.pathname;
8679        const parts = path.split("/").filter(Boolean);
8680        const flavorParam = parts[parts.length - 1];
8681
8682        let button;
8683        if (flavorParam === "Variety") {
8684          button = document.querySelector(".variety-selector-btn");
8685        } else {
8686          button = document.querySelector(`.flavour-custom[data-flavor="${flavorParam}"]`);
8687        }
8688
8689        button?.click();
8690      },
8691
8692      addToCart(variantId, quantity = 1) {
8693        fetch('/cart/add.js', {
8694          method: 'POST',
8695          headers: { 'Content-Type': 'application/json' },
8696          body: JSON.stringify({ items: [{ id: variantId, quantity }] })
8697        })
8698        .then(response => response.json())
8699        .then(cart => {
8700          
8701          this.handleCartUpdate(cart, quantity);
8702          return cart;
8703        })
8704        .catch(error => console.error('Error adding to cart:', error));
8705      },
8706
8707      handleCartUpdate(cart, quantity) {
8708        if (window.updateCartUI) {
8709          window.updateCartUI(cart);
8710        } else {
8711          window.dispatchEvent(new Event('cart:refresh'));
8712        }
8713        
8714        document.querySelector('.site-cart')?.classList.add("active");
8715        
8716        if (elements.cartCount) {
8717          const currentCount = parseInt(elements.cartCount.textContent || '0');
8718
8719          
8720          if(cart.items){
8721            elements.cartCount.textContent = currentCount + quantity;
8722          }
8723        }
8724      },
8725
8726      activateSubscribeSection(flavor) {
8727        const toggleSections = () => {
8728          const sections = document.querySelectorAll(
8729            `.subscription-box[data-flavor="${flavor}"]`
8730          );
8731          sections.forEach((btn) => btn.classList.remove("hidden"));
8732          sections.forEach((btn) => btn.style.display = "");
8733
8734          const oppositeFlavor = flavor === "Citrus" ? "Mint" : "Citrus";
8735          const oppositeSection = document.querySelector(
8736            `.subscription-box[data-flavor="${oppositeFlavor}"]`
8737          );
8738
8739          if (oppositeSection) {
8740            oppositeSection.classList.add("hidden");
8741          } else {
8742            console.log("Opposite section not found yet");
8743          }
8744        };
8745
8746        // Run immediately once
8747        toggleSections();
8748
8749        // Observe for future DOM changes
8750        const observer = new MutationObserver(() => {
8751          toggleSections();
8752        });
8753
8754        observer.observe(document.body, {
8755          childList: true,
8756          subtree: true,
8757        });
8758      }
8759      
8760    };
8761
8762    // Main Initialization
8763    function init() {
8764      document.querySelectorAll('.flavour-custom').forEach(button => {
8765        button.addEventListener('click', (e) => {
8766          const selectedFlavor = e.currentTarget.getAttribute('data-flavor');
8767          eventHandlers.activateSubscribeSection(selectedFlavor);
8768          elements.mainAtcBtn.style.backgroundColor = selectedFlavor === "Mint" ? "#e6ecd3": "#FFDEA3";
8769        });
8770      });
8771
8772      productManager.init();
8773      
8774      eventHandlers.initSidebar();
8775      eventHandlers.initSizeSelection();
8776      eventHandlers.initFlavorSelection();
8777      eventHandlers.initPackSelection();
8778      eventHandlers.initAddToCart();
8779      
8780
8781      // Initial UI updates
8782      uiUpdater.updateSidebarPdpTitle(state.selectedSize);
8783      uiUpdater.updateAddButton(state.selectedFlavor, state.selectedPack);
8784    }
8785
8786    // Start the application
8787    init();
8788  });
8789</script>
8789
8790
8791
8792</section><div id="shopify-section-template--21146535100554__282fbcdf-ee69-456c-b112-cab113b9ab73" class="shopify-section"><section class="site-container bg-light-tan pb-16 lg:pb-20 text-base lg:text-lg" data-buckthorn-image="//revitin.com/cdn/shop/t/129/assets/buckthorn.png?v=74098705003111698641777542406"
8793  data-seaweed-image="//revitin.com/cdn/shop/t/129/assets/seaweed.png?v=114691001103030255781777542404">
8794
8795  <div class="text-center pt-16 lg:pt-20 border-t border-brown">
8796    <span class="tag bg-light-green text-green mb-5">Key Ingredients</span>
8797  </div>
8798
8799  <h3 class="heading-2 text-center mx-auto max-w-md py-5 lg:max-w-4xl !tracking-tight">Our first-of-its-kind formula is backed by 15 years of clinical research. Here’s what goes into it:</h3>
8800
8801  <div class="grid gap-y-6 mt-8 md:grid-cols-2 lg:grid-cols-3 md:gap-y-8 md:gap-x-20 md:mt-16">
8802    
8803      <div>
8804        <h3 class="text-[1.5rem] lg:text-[1.75rem] mb-1">Vitamin C</h3>
8805        <p class="mb-4 font-body-medium">
8806          Antioxidant
8807        </p>
8808
8809        <div class="flex gap-2.5">
8810          <p class="w-full">
8811            Vitamin C is an essential vitamin used by your gums and natural microbes. It demonstrates a strong defense against bacteria associated with dental decay and gingivitis.
8812          </p>
8813
8814          <div class="relative w-28">
8815            <div>
8816              <img
8817                class="object-contain"
8818                src="//revitin.com/cdn/shop/files/grapefruit.png?v=1694011206"
8819                alt="Grapefruit illustration"
8820                width="auto"
8821                height="auto"
8822                loading="eager" />
8823            </div>
8824          </div>
8825        </div>
8826      </div>
8827    
8828      <div>
8829        <h3 class="text-[1.5rem] lg:text-[1.75rem] mb-1">CoQ10</h3>
8830        <p class="mb-4 font-body-medium">
8831          Anti-inflammatory enzyme
8832        </p>
8833
8834        <div class="flex gap-2.5">
8835          <p class="w-full">
8836            Coenzyme Q10 is a naturally occurring coenzyme found in every cell on the planet. It’s an essential factor in cellular regeneration. Increasing concentration of CoQ10 in gums supports healthy cell function and suppresses inflammation.
8837          </p>
8838
8839          <div class="relative w-28">
8840            <div>
8841              <img
8842                class="object-contain"
8843                src="//revitin.com/cdn/shop/files/lemon_7b9db330-2efe-4537-8020-fec8e016a43a.png?v=1694011678"
8844                alt="Lemon illustration"
8845                width="auto"
8846                height="auto"
8847                loading="eager" />
8848            </div>
8849          </div>
8850        </div>
8851      </div>
8852    
8853      <div>
8854        <h3 class="text-[1.5rem] lg:text-[1.75rem] mb-1">Vitamin D</h3>
8855        <p class="mb-4 font-body-medium">
8856          Mineralization
8857        </p>
8858
8859        <div class="flex gap-2.5">
8860          <p class="w-full">
8861            Vitamin D is an essential vitamin that supports the mineralization of teeth and bones by encouraging optimal absorption of calcium, iron, magnesium, phosphate, and zinc. Vitamin D also strengthens the immune system and reduces periodontal inflammation.
8862          </p>
8863
8864          <div class="relative w-28">
8865            <div>
8866              <img
8867                class="object-contain"
8868                src="//revitin.com/cdn/shop/files/papaya.png?v=1694011600"
8869                alt="Papaya illustration"
8870                width="auto"
8871                height="auto"
8872                loading="eager" />
8873            </div>
8874          </div>
8875        </div>
8876      </div>
8877    
8878      <div>
8879        <h3 class="text-[1.5rem] lg:text-[1.75rem] mb-1">Cranberry Seed Oil</h3>
8880        <p class="mb-4 font-body-medium">
8881          Prebiotic
8882        </p>
8883
8884        <div class="flex gap-2.5">
8885          <p class="w-full">
8886            Cranberry Seed oil is a prebiotic nutrient that contains essential fatty acids that support the resolution of inflamed gums and a healthy oral microbiome.
8887          </p>
8888
8889          <div class="relative w-28">
8890            <div>
8891              <img
8892                class="object-contain"
8893                src="//revitin.com/cdn/shop/files/crans.png?v=1694011645"
8894                alt="Cranberry illustration"
8895                width="auto"
8896                height="auto"
8897                loading="eager" />
8898            </div>
8899          </div>
8900        </div>
8901      </div>
8902    
8903      <div>
8904        <h3 class="text-[1.5rem] lg:text-[1.75rem] mb-1">Quillaja Saponaria Extract</h3>
8905        <p class="mb-4 font-body-medium">
8906          Lifting agent
8907        </p>
8908
8909        <div class="flex gap-2.5">
8910          <p class="w-full">
8911            Quillaja Saponaria Extract is a natural foaming agent that gives our formula a sudsy foam without soap. It’s also a gentle cleaning agent that helps break up unhealthy biofilms.
8912          </p>
8913
8914          <div class="relative w-28">
8915            <div>
8916              <img
8917                class="object-contain"
8918                src="//revitin.com/cdn/shop/files/tangerine.png?v=1694011108"
8919                alt="Tangerine illustration"
8920                width="auto"
8921                height="auto"
8922                loading="eager" />
8923            </div>
8924          </div>
8925        </div>
8926      </div>
8927    
8928      <div>
8929        <h3 class="text-[1.5rem] lg:text-[1.75rem] mb-1">Chondrus Crispus</h3>
8930        <p class="mb-4 font-body-medium">
8931          Prebiotic
8932        </p>
8933
8934        <div class="flex gap-2.5">
8935          <p class="w-full">
8936            Otherwise known as seaweed, Chondrus Crispus is a prebiotic used to balance the oral ecology and gives our formula 
8936its texture.
8937          </p>
8938
8939          <div class="relative w-28">
8940            <div>
8941              <img
8942                class="object-contain"
8943                src="//revitin.com/cdn/shop/files/seaweed.png?v=1694011555"
8944                alt="Seaweed illustration"
8945                width="auto"
8946                height="auto"
8947                loading="eager" />
8948            </div>
8949          </div>
8950        </div>
8951      </div>
8952    
8953  </div>
8954
8955  
8956    <div class="mt-10 lg:mt-16 grid md:justify-center">
8957      <a
8958        href="/pages/ingredients"
8959        title="All ingredients"
8960        class="button button--gold">All ingredients</a>
8961    </div>
8962  
8963
8964
8965</section>
8966
8967
8968
8969<script>
8970
8971  document.addEventListener('DOMContentLoaded', function() {
8972    // Get flavor buttons
8973    const flavorButtonsBellow = document.querySelectorAll('[data-flavor]');
8974    
8975    let currentUrlBellow = window.location.pathname.split('/');
8976    let CurrentLastPartBellow = currentUrlBellow[currentUrlBellow.length - 1].toLowerCase();
8977
8978    const sectionEl = document.querySelector('.site-container.bg-light-tan');
8979    const buckhornImageUrl = sectionEl.dataset.buckthornImage;
8980    const seaweedImageUrl = sectionEl.dataset.seaweedImage;
8981    
8982    // Function to update ingredient content based on flavor
8983    function updateIngredientContent(flavor) {
8984      
8985      // Get all ingredient blocks
8986      const ingredientBlocks = document.querySelectorAll('.grid.gap-y-6 > div');
8987      
8988      // Find the specific ingredient to replace (Chondrus Crispus)
8989      ingredientBlocks.forEach(block => {
8990        const titleEl = block.querySelector('h3');
8991        
8992        // Check if this is the Chondrus Crispus block
8993        if (titleEl && titleEl.textContent.trim() === "Chondrus Crispus" || 
8994            titleEl && titleEl.textContent.trim() === "Sea Buckthorn Berry") { // Also check for already changed title
8995          
8996          const subheadingEl = block.querySelector('p.mb-4');
8997          const textEl = block.querySelector('div.flex > p');
8998          const imageEl = block.querySelector('img');
8999          
9000          if (flavor === 'Mint') {
9001            // Update to Sea Buckthorn Berry for Mint flavor
9002            titleEl.textContent = "Sea Buckthorn Berry";
9003            if (subheadingEl) subheadingEl.textContent = "Antioxidant";
9004            if (textEl) textEl.textContent = "Rich in vitamins, antioxidants, and essential fatty acids, Sea Buckthorn Berry supports gum health, fights oxidative stress, and promotes a balanced oral microbiome while reducing inflammation and aiding tissue repair.";
9005            if (imageEl) {
9006              imageEl.src = "//revitin.com/cdn/shop/files/buckthorn.png?v=1741083804"; // Update with correct image path
9007              imageEl.alt = "Sea Buckthorn Berry";
9008            }
9009          } else if (flavor === 'Citrus') {
9010            // Reset to default for Citrus flavor
9011            titleEl.textContent = "Chondrus Crispus";
9012            if (subheadingEl) subheadingEl.textContent = "Prebiotic";
9013            if (textEl) textEl.textContent = "Otherwise known as seaweed, Chondrus Crispus is a prebiotic used to balance the oral ecology and gives our formula its texture.";
9014            if (imageEl) {
9015              imageEl.src = "//revitin.com/cdn/shop/files/seaweed.png?v=1694011555"; // Update with correct image path
9016              imageEl.alt = "Chondrus Crispus";
9017            }
9018          }
9019        }
9020      });
9021    }
9022    
9023    // Check URL on page load
9024    if (CurrentLastPartBellow === 'citrus' || CurrentLastPartBellow === 'mint') {
9025      // Capitalize first letter of flavor
9026      const flavor = CurrentLastPartBellow.charAt(0).toUpperCase() + CurrentLastPartBellow.slice(1);
9027      updateIngredientContent(flavor);
9028    }
9029    
9030    // Add click event listeners to flavor buttons
9031    flavorButtonsBellow.forEach(button => {
9032      button.addEventListener('click', function() {
9033        // Use the button's flavor attribute directly
9034        const flavorBellow = this.dataset.flavor;
9035        updateIngredientContent(flavorBellow);
9036      });
9037    });
9038  });
9039</script>
9039
9040
9041
9042
9043</div><section id="shopify-section-template--21146535100554__9d3df497-edc9-4e2b-b60c-72c6fd50b533" class="shopify-section"><div class="site-container pt-5 pb-16 lg:pb-20">
9044  <div class="relative aspect-[1.4] bg-sand rounded-2xl pdp_banner_container">
9045    
9046      <img
9047        data-swap-flavor="Citrus"
9048        class="absolute top-0 left-0 w-full h-full object-cover object-center opacity-0 !opacity-100 transition-opacity duration-300 rounded-2xl"
9049        src="//revitin.com/cdn/shop/files/citrus-featured_11zon_2000x.jpg?v=1751389467"
9050        loading="lazy" />
9051    
9052    
9053      <img
9054        data-swap-flavor="Mint"
9055        class="absolute top-0 left-0 w-full h-full object-cover object-center z-10 opacity-0 transition-opacity duration-300 rounded-2xl"
9056        src="//revitin.com/cdn/shop/files/mint-featured_11zon_2000x.jpg?v=1751389546"
9057        loading="lazy" />
9058    
9059  </div>
9060  <div class="mt-4 grid md:grid-cols-2 md:gap-6 md:mt-6">
9061    
9062      <div class="site-container bg-gold text-center flex flex-col  pb-2 pt-8 lg:pt-8 lg:pb-4 rounded-t-2xl   lg:rounded-2xl justify-between">
9063        <div class="order-2 md:order-1">
9064          <div class="tag-ghost mx-auto mb-4 hidden md:block">Meet Dr. Gerry</div>
9065          <div class="text-2xl lg:text-3xl mb-4">Our Founder</div>
9066          <p class="mx-auto max-w-lg md:mb-4">
9067            Revitin founder Dr. Gerry Curatola is an internationally renown biologic dentist and pioneering researcher of the oral microbiome. He invented Revitin because he knew there was a better way to give his patients the results they wanted.
9068          </p>
9069        </div>
9070
9071        <div class="order-1 md:order-2">
9072          <div class="w-28 h-32 mx-auto relative">
9073            <img class="m-auto max-h-[110px]" src="//revitin.com/cdn/shop/files/DR_G_TRANSP_RGB_200x.png?v=1695836984" loading="lazy" />
9074          </div>
9075        </div>
9076      </div>
9077    
9078      <div class="site-container bg-gold text-center flex flex-col   pt-2 pb-8 lg:pt-8 lg:pb-4 rounded-b-2xl   lg:rounded-2xl justify-between">
9079        <div class="order-2 md:order-1">
9080          <div class="tag-ghost mx-auto mb-4 hidden md:block">Backed by research</div>
9081          <div class="text-2xl lg:text-3xl mb-4">Our Mission</div>
9082          <p class="mx-auto max-w-lg md:mb-4">
9083            Create brighter smiles, stronger teeth, and healthier lives with all natural, non-toxic ingredients. Your oral microbiome is a critical piece of overall health, and the right toothpaste makes a real difference.
9084          </p>
9085        </div>
9086
9087        <div class="order-1 md:order-2">
9088          <div class="w-28 h-32 mx-auto relative">
9089            <img class="m-auto max-h-[110px]" src="//revitin.com/cdn/shop/files/TOOTHBRUSH_SPARKLEB_1_200x.png?v=1695847673" loading="lazy" />
9090          </div>
9091        </div>
9092      </div>
9093    
9094  </div>
9095</div>
9096
9097
9098</section><section id="shopify-section-template--21146535100554__a40b57ad-ca7b-4ae4-ba3e-44a719073e79" class="shopify-section"><section class="bg-sand">
9099  <div class="site-container grid lg:grid-cols-[1fr_1.625fr] gap-6 lg:justify-between py-16 lg:py-20 rounded-2xl">
9100    <div class="grid content-start">
9101      <div class="bg-light-green text-green tag mb-5">You’re not alone</div>
9102      <h3 class="heading-1 font-heading text-primary">
9103        Frequently Asked Questions
9104      </h3>
9105    </div>
9106    <div class="border-t border-primary mt-6 md:mt-0 ">
9107          <accordion-item>
9108            <div class="grid border-b border-primary">
9109              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9110                <h2 class="font-body-medium text-primary lg:text-base">
9110How is Revitin different from other toothpastes?</h2>
9111                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9112                  <div class="w-3 h-3 relative">
9113                    <svg
9114                      class="transition-all duration-300"
9115                      width="12"
9116                      viewBox="0 0 8 9"
9117                      fill="none"
9118                      xmlns="http://www.w3.org/2000/svg">
9119                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9120                    </svg>
9121                  </div>
9122                </div>
9123              </button>
9124              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9125                <div class="pb-5">
9126                  <p>Revitin uses all natural ingredients for healthier teeth without the use of harsh chemicals. Revitin supports an oral cavity with less inflammation and plaque buildup by encouraging a healthy microbial environment.</p>
9127                </div>
9128              </div>
9129            </div>
9130          </accordion-item>
9131        
9132
9133          <accordion-item>
9134            <div class="grid border-b border-primary">
9135              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9136                <h2 class="font-body-medium text-primary lg:text-base">What should I do if I accidentally swallow Revitin?</h2>
9137                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9138                  <div class="w-3 h-3 relative">
9139                    <svg
9140                      class="transition-all duration-300"
9141                      width="12"
9142                      viewBox="0 0 8 9"
9143                      fill="none"
9144                      xmlns="http://www.w3.org/2000/svg">
9145                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9146                    </svg>
9147                  </div>
9148                </div>
9149              </button>
9150              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9151                <div class="pb-5">
9152                  <p>Revitin is designed for oral use and is safe if swallowed. Please follow the usage instructions provided with the product.</p>
9153                </div>
9154              </div>
9155            </div>
9156          </accordion-item>
9157        
9158
9159          <accordion-item>
9160            <div class="grid border-b border-primary">
9161              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9162                <h2 class="font-body-medium text-primary lg:text-base">Is Revitin fluoride-free?</h2>
9163                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9164                  <div class="w-3 h-3 relative">
9165                    <svg
9166                      class="transition-all duration-300"
9167                      width="12"
9168                      viewBox="0 0 8 9"
9169                      fill="none"
9170                      xmlns="http://www.w3.org/2000/svg">
9171                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9172                    </svg>
9173                  </div>
9174                </div>
9175              </button>
9176              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9177                <div class="pb-5">
9178                  <p>Yes, Revitin is fluoride-free. There are no toxic ingredients in our formula.</p>
9179                </div>
9180              </div>
9181            </div>
9182          </accordion-item>
9183        
9184
9185          <accordion-item>
9186            <div class="grid border-b border-primary">
9187              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9188                <h2 class="font-body-medium text-primary lg:text-base">What else is Revitin free from?</h2>
9189                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9190                  <div class="w-3 h-3 relative">
9191                    <svg
9192                      class="transition-all duration-300"
9193                      width="12"
9194                      viewBox="0 0 8 9"
9195                      fill="none"
9196                      xmlns="http://www.w3.org/2000/svg">
9197                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9198                    </svg>
9199                  </div>
9200                </div>
9201              </button>
9202              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9203                <div class="pb-5">
9204                  <p>Revitin is free from fluoride, SLS, gluten, dyes, peanuts, sugar, xylitol, and GMOs.</p>
9205                </div>
9206              </div>
9207            </div>
9208          </accordion-item>
9209        
9210
9211          <accordion-item>
9212            <div class="grid border-b border-primary">
9213              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9214                <h2 class="font-body-medium text-primary lg:text-base">Does Revitin whiten teeth?</h2>
9215                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9216                  <div class="w-3 h-3 relative">
9217                    <svg
9218                      class="transition-all duration-300"
9219                      width="12"
9220                      viewBox="0 0 8 9"
9221                      fill="none"
9222                      xmlns="http://www.w3.org/2000/svg">
9223                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9224                    </svg>
9225                  </div>
9226                </div>
9227              </button>
9228              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9229                <div class="pb-5">
9230                  <p>Revitin is proven to reduce film build up and plaque on teeth that leads to discoloration. Additionally, natural fruit enzymes like the ones in Revitin, are proven to whiten teeth without harsh chemicals.</p>
9231                </div>
9232              </div>
9233            </div>
9234          </accordion-item>
9235        
9236
9237          <accordion-item>
9238            <div class="grid border-b border-primary">
9239              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9240                <h2 class="font-body-medium text-primary lg:text-base">Is Revitin vegan?</h2>
9241                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9242                  <div class="w-3 h-3 relative">
9243                    <svg
9244                      class="transition-all duration-300"
9245                      width="12"
9246                      viewBox="0 0 8 9"
9247                      fill="none"
9248                      xmlns="http://www.w3.org/2000/svg">
9249                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9250                    </svg>
9251                  </div>
9252                </div>
9253              </button>
9254              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9255                <div class="pb-5">
9256                  <p>Yes.</p>
9257                </div>
9258              </div>
9259            </div>
9260          </accordion-item>
9261        
9262
9263          <accordion-item>
9264            <div class="grid border-b border-primary">
9265              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9266                <h2 class="font-body-medium text-primary lg:text-base">Is Revitin safe for children?</h2>
9267                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9268                  <div class="w-3 h-3 relative">
9269                    <svg
9270                      class="transition-all duration-300"
9271                      width="12"
9272                      viewBox="0 0 8 9"
9273                      fill="none"
9274                      xmlns="http://www.w3.org/2000/svg">
9275                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9276                    </svg>
9277                  </div>
9278                </div>
9279              </button>
9280              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9281                <div class="pb-5">
9282                  <p>Yes, Revitin is a great choice for teeth brushers of all ages.</p>
9283                </div>
9284              </div>
9285            </div>
9286          </accordion-item>
9287        
9288
9289          <accordion-item>
9290            <div class="grid border-b border-primary">
9291              <button type="button" class="grid grid-cols-[1fr,auto] accordion-button justify-between gap-5 items-start text-left py-4">
9292                <h2 class="font-body-medium text-primary lg:text-base">Do you ship internationally?</h2>
9293                <div class="grid grid-flow-col items-center justify-end gap-0 relative top-1">
9294                  <div class="w-3 h-3 relative">
9295                    <svg
9296                      class="transition-all duration-300"
9297                      width="12"
9298                      viewBox="0 0 8 9"
9299                      fill="none"
9300                      xmlns="http://www.w3.org/2000/svg">
9301                      <path d="M0.096 3.552H3.328V0.32H4.656V3.552H7.888V4.832H4.656V8.048H3.328V4.832H0.096V3.552Z" fill="#5F471D" />
9302                    </svg>
9303                  </div>
9304                </div>
9305              </button>
9306              <div class="text-primary max-h-0 overflow-hidden transition-all duration-200 w-full max-w-4xl">
9307                <div class="pb-5">
9308                  <p>Yes.</p>
9309                </div>
9310              </div>
9311            </div>
9312          </accordion-item>
9313        
9314</div>
9315  </div>
9316
9317</section>
9318
9319
9320</section><div id="shopify-section-template--21146535100554__1702056462da008a1e" class="shopify-section">
9321
9322
9323
9324</div><div id="shopify-section-template--21146535100554__judgeme_reviews_pq8yep" class="shopify-section"><section
9325  class="jm-section jm-section-template--21146535100554__judgeme_reviews_pq8yep exp-padding"
9326  data-jm-section
9327  data-shop-domain="revitin.myshopify.com"
9328  data-per-page="20"
9329>
9330  <style>
9331    :root{
9332      --jm-bg: #E5ECD1CC;
9333      --jm-green: #C9DAB5;
9334      --jm-divider: #c8ccbe;
9335      --jm-bar-track: #d5d8ce;
9336      --jm-text: #5F471D;
9337      --jm-muted: #6b6f67;
9338      --jm-red: #b23b3b;
9339    }
9340
9341    .jm-section{
9342      background: var(--jm-bg);
9343      padding-top: 50px;
9344      padding-bottom: 45px;
9345      border-radius: 32px;
9346    }
9347
9348    .jm-container{
9349      max-width: 1400px;
9350      margin: 0 auto;
9351    }
9352
9353    .jm-title{
9354      font-size: 30px;
9355      line-height: 1;
9356      text-align: center;
9357      margin: 0 0 45px;
9358    }
9359
9360    .jm-top{
9361      display: grid;
9362      grid-template-columns: 1fr 1fr;
9363      gap: 60px;
9364      align-items: start;
9365      padding-bottom: 26px;
9366    }
9367    .jm-top-left{
9368      display: grid;
9369      grid-template-columns: 1fr 2fr;
9370      gap:30px;
9371    }
9372    .jm-divider{
9373      border: 0;
9374      border-top: 1px solid var(--jm-divider);
9375      margin: 0;
9376    }
9377
9378    .jm-score{
9379      display: flex;
9380      flex-direction: column;
9381      align-items: flex-start;
9382      gap: 10px;
9383      width: fit-content;
9384    }
9385
9386    .jm-score-row{
9387      display: flex;
9388      align-items: center;
9389      gap: 14px;
9390    }
9391
9392    .jm-score-number{
9393      line-height: 1;
9394      font-family: "Basis Regular";
9395      font-weight: 700;
9396    }
9397
9398    .jm-stars{
9399      display: inline-flex;
9400      
9401      transform: translateY(3px);
9402    }
9403
9404    .jm-star{
9405      width: 20px;
9406      height: 20px;
9407      fill: #7E8F72;
9408    }
9409
9410    .jm-pill{
9411      display: inline-flex;
9412      align-items: center;
9413      justify-content: center;
9414      background: var(--jm-green);
9415      color: #5F471D;
9416      border-radius: 4px;
9417      padding: 8px 12px;
9418      font-size: 15px;
9419      white-space: nowrap;
9420      width: 100%;
9421    }
9422
9423    .jm-breakdown{
9424      display: flex;
9425      flex-direction: column;
9426      gap: 10px;
9427      padding-top: 6px;
9428    }
9429
9430    .jm-breakdown-row{
9431      display: grid;
9432      grid-template-columns: 104px 1fr 35px;
9433      gap: 10px;
9434      align-items: center;
9435      font-size: 13px;
9436      color: #5F471D;
9437    }
9438
9439    .jm-breakdown-stars{
9440      display: inline-flex;
9441      gap: 2px;
9442      justify-content: flex-end;
9443      color: #5F471D;
9444    }
9445    .jm-breakdown-stars .jm-star{
9446      width: 20px;
9447      height: 20px;
9448    }
9449
9450    .jm-bar{
9451      height: 16px;
9452      background: #7E8F724D;
9453      
9454      overflow: hidden;
9455      position: relative;
9456    }
9457
9458    .jm-bar > span{
9459      position: absolute;
9460      left: 0;
9461      top: 0;
9462      bottom: 0;
9463      width: 0%;
9464      background: #7E8F72;
9465      
9466    }
9467
9468    .jm-count{
9469      text-align: center;
9470      color: #5F471D99;
9471    }
9472
9473    .jm-summary{
9474      text-align: right;
9475      display: flex;
9476      flex-direction: column;
9477      align-items: center;
9478      gap: 10px;
9479    }
9480    .jm-summary .jm-btn{
9481      margin-top: 15px;
9482      max-width: 220px;
9483      width: 100%;
9484      padding: 10px;
9485      border: 1px solid var(--jm-text);
9486      color: var(--jm-text);
9487    }
9488    .jm-summary h3{
9489      margin: 0;
9490      font-size: 25px;
9491      color: var(--jm-text);
9492    }
9493
9494    .jm-summary p{
9495      margin: 0;
9496      color: var(--jm-text);
9497      text-align: center;
9498      max-width: 100%;
9499      align-self: center;
9500      line-height: 26px;
9501      font-size: 18px;
9502    }
9503
9504    .jm-btn{
9505      display: inline-flex;
9506      align-items: center;
9507      justify-content: center;
9508      border: 1px solid var(--jm-green);
9509      background: transparent;
9510      color: var(--jm-text);
9511      border-radius: 999px;
9512      padding: 10px 24px;
9513      font-size: 14px;
9514      cursor: pointer;
9515      transition: background-color 0.2s ease, color 0.2s ease;
9516      text-decoration: none;
9517      user-select: none;
9518    }
9519    .jm-footer .jm-btn{
9520      max-width: 330px;
9521      width: 100%;
9522      padding: 12px;
9523      font-size: 16px;
9524      line-height: 26px;
9525      border-radius: 8px;
9526      background: #C9DAB5;
9527      transition: all 0.2s ease;
9528      margin-top: 50px;
9529    }
9530    .jm-footer .jm-btn:hover{
9531      background: transparent;
9532      border-color: var(--jm-text);
9533    }
9534
9535    .jm-btn:hover{
9536      background: var(--jm-green);
9537    }
9538
9539    .jm-controls{
9540      display: flex;
9541      justify-content: flex-end;
9542      padding: 16px 0 0;
9543    }
9544
9545    /* Custom select (fully styleable) */
9546    .jm-select{
9547      position: relative;
9548      width: 152px;
9549
9550      color: #5F471D;
9551    }
9552    .jm-select-btn{
9553      width: 100%;
9554      display: inline-flex;
9555      align-items: center;
9556      justify-content: space-between;
9557      gap: 10px;
9558      border: 0;
9559      border-radius: 4px;
9560      padding: 12px 10px;
9561      background: #C9DAB5;
9562      color: #5F471D;
9563      cursor: pointer;
9564      user-select: none;
9565    }
9566    .jm-select-btn:focus{
9567      outline: 2px solid rgba(95,71,29,0.25);
9568      outline-offset: 2px;
9569    }
9570    .jm-select-caret{
9571      width: 10px;
9572      height: 5px;
9573      fill: #5F471D;
9574      transition: transform 0.15s ease;
9575      flex: 0 0 auto;
9576    }
9577    .jm-select.is-open .jm-select-caret{ transform: rotate(180deg); }
9578    .jm-select-list{
9579      position: absolute;
9580      top: calc(100% + 2px);
9581      right: 0;
9582      width: 100%;
9583      background: #c9dab5;
9584      border: 1px solid rgba(95,71,29,0.18);
9585      border-radius: 8px;
9586      box-shadow: 0 10px 24px rgba(0,0,0,0.10);
9587      padding: 6px;
9588      margin: 0;
9589      list-style: none;
9590      display: none;
9591      z-index: 20;
9592    }
9593    .jm-select.is-open .jm-select-list{ display: block; }
9594    .jm-select-opt{
9595      padding: 10px 10px;
9596      border-radius: 6px;
9597      cursor: pointer;
9598      font-size: 14px;
9599      color: #5F471D;
9600    }
9601    .jm-select-opt:hover{ background: rgba(95,71,29,0.08); }
9602    .jm-select-opt[aria-selected="true"]{
9603      background: rgba(95,71,29,0.12);
9604      font-weight: 600;
9605    }
9606
9607    .jm-grid{
9608      margin-top: 40px;
9609      display: grid;
9610      grid-template-columns: repeat(2, minmax(0, 1fr));
9611      gap: 24px;
9612      column-gap: 50px;
9613      row-gap: 60px;
9614    }
9615
9616    .jm-card{
9617      padding: 0;
9618      margin: 0;
9619    }
9620
9621    .jm-card-stars{
9622      display: inline-flex;
9623      gap: 3px;
9624    }
9625
9626    .jm-card-date{
9627      margin-top: 6px;
9628      font-size: 12px;
9629      color: #7B7B7B;
9630    }
9631
9632    .jm-card-meta{
9633      margin-top: 8px;
9634      display: flex;
9635      flex-wrap: wrap;
9636      align-items: center;
9637      gap: 8px;
9638
9639      color: var(--jm-text);
9640      font-size: 15px;
9641    }
9642
9643    .jm-verified{
9644      border: 0.53px solid #5F471D;
9645      border-radius: 20px;
9646      font-size: 9px;
9647      padding: 2px 6px;
9648      color: var(--jm-text);
9649      display: inline-flex;
9650      align-items: center;
9651      gap: 4px;
9652    }
9653
9654    .jm-card-title{
9655      margin-top: 25px;
9656      font-weight: 700;
9657      font-size: 24px;
9658      color: var(--jm-text);
9659
9660    }
9661
9662    .jm-card-body{
9663      margin-top: 25px;
9664      font-size: 20px;
9665      line-height: 1.3;
9666      white-space: pre-line;
9667    }
9668
9669    .jm-footer{
9670      display: flex;
9671      justify-content: center;
9672      margin-top: 28px;
9673    }
9674
9675    .jm-empty,
9676    .jm-error{
9677      text-align: center;
9678      padding: 28px 0;
9679
9680    }
9681
9682    .jm-empty{
9683      color: var(--jm-muted);
9684    }
9685
9686    .jm-error{
9687      color: var(--jm-red);
9688      font-size: 14px;
9689    }
9690
9691    /* Skeleton */
9692    .jm-skeleton-grid{
9693      margin-top: 22px;
9694      display: grid;
9695      grid-template-columns: repeat(2, minmax(0, 1fr));
9696      gap: 24px;
9697    }
9698
9699    .jm-skel{
9700      height: 170px;
9701      border-radius: 10px;
9702      background: rgba(0,0,0,0.06);
9703      overflow: hidden;
9704      position: relative;
9705    }
9706
9707    .jm-skel:before{
9708      content: "";
9709      position: absolute;
9710      inset: 0;
9711      transform: translateX(-100%);
9712      background: linear-gradient(90deg, transparent, rgba(255,255,255,0.35), transparent);
9713      animation: jm-pulse 1.2s infinite;
9714    }
9715
9716    @keyframes jm-pulse{
9717      100% { transform: translateX(100%); }
9718    }
9719
9720    /* Write-a-review dropdown form */
9721    .jm-form-wrap{
9722      max-height: 0;
9723      overflow: hidden;
9724      transition: max-height 0.4s ease, opacity 0.3s ease;
9725      opacity: 0;
9726    }
9727    .jm-form-wrap.is-open{
9728      max-height: 900px;
9729      opacity: 1;
9730    }
9731    .jm-form{
9732      max-width: 420px;
9733      margin: 0 auto;
9734      padding: 32px 0 8px;
9735    }
9736    .jm-form-heading{
9737      text-align: center;
9738      font-family: Georgia, "Times New Roman", Times, serif;
9739      font-style: italic;
9740      font-size: 20px;
9741      color: var(--jm-text);
9742      margin: 0 0 20px;
9743    }
9744    .jm-form-label{
9745      display: block;
9746      text-align: center;
9747      font-size: 13px;
9748      color: var(--jm-muted);
9749      margin-bottom: 6px;
9750
9751    }
9752    .jm-form-group{
9753      margin-bottom: 18px;
9754    }
9755    .jm-form-input,
9756    .jm-form-textarea{
9757      width: 100%;
9758      border: 1px solid var(--jm-divider);
9759      border-radius: 6px;
9760      padding: 10px 14px;
9761      font-size: 14px;
9762
9763      color: var(--jm-text);
9764      background: #fff;
9765      box-sizing: border-box;
9766      outline: none;
9767      transition: border-color 0.2s;
9768    }
9769    .jm-form-input:focus,
9770    .jm-form-textarea:focus{
9771      border-color: var(--jm-green);
9772    }
9773    .jm-form-textarea{
9774      min-height: 100px;
9775      resize: vertical;
9776    }
9777    .jm-form-stars{
9778      display: flex;
9779      justify-content: center;
9780      gap: 6px;
9781      margin-bottom: 18px;
9782    }
9783    .jm-form-star{
9784      width: 26px;
9785      height: 26px;
9786      cursor: pointer;
9787      fill: #ccc;
9788      transition: fill 0.15s;
9789    }
9790    .jm-form-star.active{
9791      fill: #7e8f72;
9792    }
9793    .jm-form-star:hover{
9794      fill: var(--jm-green);
9795    }
9796    .jm-form-upload{
9797      display: flex;
9798      flex-direction: column;
9799      align-items: center;
9800      justify-content: center;
9801      border: 2px dashed var(--jm-divider);
9802      border-radius: 8px;
9803      padding: 20px;
9804      cursor: pointer;
9805      transition: border-color 0.2s;
9806      position: relative;
9807    }
9808    .jm-form-upload:hover{
9809      border-color: var(--jm-green);
9810    }
9811    .jm-form-upload input[type="file"]{
9812      position: absolute;
9813      inset: 0;
9814      opacity: 0;
9815      cursor: pointer;
9816    }
9817    .jm-form-upload-icon{
9818      width: 32px;
9819      height: 32px;
9820      color: var(--jm-muted);
9821      margin-bottom: 4px;
9822    }
9823    .jm-form-upload-text{
9824      font-size: 12px;
9825      color: var(--jm-muted);
9826    }
9827    .jm-form-previews{
9828      display: flex;
9829      flex-wrap: wrap;
9830      gap: 8px;
9831      margin-top: 8px;
9832    }
9833    .jm-form-previews img{
9834      width: 56px;
9835      height: 56px;
9836      object-fit: cover;
9837      border-radius: 6px;
9838      border: 1px solid var(--jm-divider);
9839    }
9840    .jm-form-actions{
9841      display: flex;
9842      justify-content: center;
9843      gap: 12px;
9844      margin-top: 22px;
9845    }
9846    .jm-form-cancel{
9847      border: 1px solid var(--jm-text);
9848      background: transparent;
9849      color: var(--jm-text);
9850      border-radius: 999px;
9851      padding: 10px 22px;
9852      font-size: 14px;
9853      cursor: pointer;
9854
9855    }
9856    .jm-form-submit{
9857      border: none;
9858      background: var(--jm-text);
9859      color: #eaefd7;
9860      border-radius: 999px;
9861      padding: 10px 22px;
9862      font-size: 14px;
9863      cursor: pointer;
9864
9865      transition: opacity 0.2s;
9866    }
9867    .jm-form-submit:disabled{
9868      opacity: 0.5;
9869      cursor: not-allowed;
9870    }
9871    .jm-form-submit .jm-spinner{
9872      display: none;
9873      width: 16px;
9874      height: 16px;
9875      border: 2px solid rgba(234,239,215,0.35);
9876      border-top-color: #eaefd7;
9877      border-radius: 50%;
9878      animation: jm-spin 0.6s linear infinite;
9879      margin-right: 6px;
9880    }
9881    .jm-form-submit.is-loading .jm-spinner{ display: inline-block; }
9882    .jm-form-submit.is-loading{ display: inline-flex; align-items: center; }
9883    @keyframes jm-spin{ to{ transform: rotate(360deg); } }
9884
9885    .jm-toast{
9886      position: fixed;
9887      bottom: 30px;
9888      left: 50%;
9889      transform: translateX(-50%) translateY(20px);
9890      background: var(--jm-text, #5F471D);
9891      color: #eaefd7;
9892      padding: 12px 24px;
9893      border-radius: 8px;
9894      font-size: 14px;
9895      z-index: 9999;
9896      opacity: 0;
9897      pointer-events: none;
9898      transition: opacity 0.3s ease, transform 0.3s ease;
9899      box-shadow: 0 4px 16px rgba(0,0,0,0.18);
9900    }
9901    .jm-toast.is-visible{
9902      opacity: 1;
9903      transform: translateX(-50%) translateY(0);
9904    }
9905
9906    .jm-form-msg{
9907      text-align: center;
9908      font-size: 13px;
9909      margin-top: 10px;
9910
9911    }
9912    .jm-form-msg.success{ color: var(--jm-green); }
9913    .jm-form-msg.error{ color: var(--jm-red); }
9914    .jm-form-disclaimer{
9915      text-align: center;
9916      font-size: 11px;
9917      color: var(--jm-muted);
9918      margin-top: 16px;
9919      line-height: 1.5;
9920
9921    }
9922    .jm-form-disclaimer a{
9923      color: var(--jm-text);
9924      text-decoration: underline;
9925    }
9926    @media (max-width: 1024px){
9927      .jm-top{
9928        grid-template-columns: 1fr;
9929      }
9930
9931    }
9932
9933    @media (max-width: 768px){
9934      .jm-section{ padding: 60px 20px; }
9935      .jm-top{ grid-template-columns: 1fr; text-align: left;gap: 30px; }
9936      .jm-summary{ align-items: center; text-align: center; gap: 20px; }
9937      .jm-summary p{ max-width: none; }
9938      .jm-grid{ grid-template-columns: 1fr; }
9939      .jm-skeleton-grid{ grid-template-columns: 1fr; }
9940      .jm-form{ padding: 24px 0 8px; }
9941      .jm-top-left{
9942        display: flex;
9943        flex-direction: column;
9944        align-items: center;
9945        justify-content: center;
9946        gap: 30px;
9947      }
9948      .jm-breakdown-row,.jm-breakdown{
9949        width: 100%;
9950      }
9951      .jm-title{
9952        margin: 0 0 20px;
9953      }
9954      .jm-summary h3{
9955        font-size: 18px;
9956      }
9957      .jm-summary p{
9958        font-size: 16px;
9959      }
9960      .jm-card-title{
9961        font-size: 18px;
9962      }
9963      .jm-card-body{
9964        font-size: 14px;
9965        line-height: 18px;
9966        margin-top: 14px;
9967      }
9968      .jm-grid{
9969        row-gap: 40px;
9970      }
9971    }
9972  </style>
9973
9974  <div class="jm-container">
9975    <h2 class="jm-title font-heading">Customer Reviews</h2>
9976
9977    <div class="jm-top" data-jm-top>
9978      <div class="jm-top-left">
9979        <div class="jm-score-container">
9980          <div class="jm-score">
9981            <div class="jm-score-row">
9982              <h2 class="jm-score-number heading-1" data-jm-average>—</h2>
9983              <div class="jm-stars" aria-hidden="true" data-jm-average-stars></div>
9984            </div>
9985            <div class="jm-pill" data-jm-total>— Reviews</div>
9986          </div>
9987        </div>
9988        <div class="jm-breakdown" data-jm-breakdown>
9989          <!-- rows injected -->
9990        </div>
9991      </div>
9992      <div class="jm-summary">
9993        <h3 class="font-heading">Reviews Summary ✨</h3>
9994        <p data-jm-summary>Most customers find Revitin toothpaste to be a refreshing alternative to conventional formulas, praising its clean, natural taste and the way their mouth feels balanced rather than stripped. Many report healthier-feeling gums, improved sensitivity, and peace of mind from the non-toxic ingredient profile, with parents noting positive experiences for their children.</p>
9995        <button type="button" class="jm-btn" data-jm-toggle-form>Write a Review</button>
9996      </div>
9997    </div>
9998
9999    <!-- Inline write-a-review dropdown -->
10000    <div class="jm-form-wrap" data-jm-form-wrap>
10001      <form class="jm-form" data-jm-form autocomplete="off" novalidate>
10002        <div class="jm-form-heading">Write a review</div>
10003
10004        <div class="jm-form-group">
10005          <label class="jm-form-label">Rating</label>
10006          <div class="jm-form-stars" data-jm-form-stars>
10007            <svg class="jm-form-star" data-star="1" viewBox="0 0 24 24">
10008              <path d="M12 17.3l-6.18 3.7 1.64-7.03L2 9.24l7.19-.61L12 2l2.81 6.63 7.19.61-5.46 4.73 1.64 7.03z"/>
10009            </svg>
10010            <svg class="jm-form-star" data-star="2" viewBox="0 0 24 24">
10011              <path d="M12 17.3l-6.18 3.7 1.64-7.03L2 9.24l7.19-.61L12 2l2.81 6.63 7.19.61-5.46 4.73 1.64 7.03z"/>
10012            </svg>
10013            <svg class="jm-form-star" data-star="3" viewBox="0 0 24 24">
10014              <path d="M12 17.3l-6.18 3.7 1.64-7.03L2 9.24l7.19-.61L12 2l2.81 6.63 7.19.61-5.46 4.73 1.64 7.03z"/>
10015            </svg>
10016            <svg class="jm-form-star" data-star="4" viewBox="0 0 24 24">
10017              <path d="M12 17.3l-6.18 3.7 1.64-7.03L2 9.24l7.19-.61L12 2l2.81 6.63 7.19.61-5.46 4.73 1.64 7.03z"/>
10018            </svg>
10019            <svg class="jm-form-star" data-star="5" viewBox="0 0 24 24">
10020              <path d="M12 17.3l-6.18 3.7 1.64-7.03L2 9.24l7.19-.61L12 2l2.81 6.63 7.19.61-5.46 4.73 1.64 7.03z"/>
10021            </svg>
10022          </div>
10023        </div>
10024
10025        <div class="jm-form-group">
10026          <label class="jm-form-label" for="jm-rev-title-template--21146535100554__judgeme_reviews_pq8yep">Review Title</label>
10027          <input
10028            class="jm-form-input"
10029            id="jm-rev-title-template--21146535100554__judgeme_reviews_pq8yep"
10030            type="text"
10031            placeholder="Give your review a title"
10032            data-jm-rev-title
10033          >
10034        </div>
10035
10036        <div class="jm-form-group">
10037          <label class="jm-form-label" for="jm-rev-body-template--21146535100554__judgeme_reviews_pq8yep">Review content</label>
10038          <textarea
10039            class="jm-form-textarea"
10040            id="jm-rev-body-template--21146535100554__judgeme_reviews_pq8yep"
10041            placeholder="Start writing here..."
10042            data-jm-rev-body
10043          ></textarea>
10044        </div>
10045
10046        <div class="jm-form-group">
10047          <label class="jm-form-label">Picture/Video (optional)</label>
10048          <div class="jm-form-upload" data-jm-upload-zone>
10049            <input type="file" accept="image/*,video/*" multiple data-jm-file-input>
10050            <svg class="jm-form-upload-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
10051              <path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/>
10052            </svg>
10053            <span class="jm-form-upload-text">
10053Click or drag to upload</span>
10054          </div>
10055          <div class="jm-form-previews" data-jm-previews></div>
10056        </div>
10057
10058        <div class="jm-form-group">
10059          <label class="jm-form-label" for="jm-rev-name-template--21146535100554__judgeme_reviews_pq8yep">Display name (displayed publicly)</label>
10060          <input
10061            class="jm-form-input"
10062            id="jm-rev-name-template--21146535100554__judgeme_reviews_pq8yep"
10063            type="text"
10064            placeholder="Display name"
10065            data-jm-rev-name
10066          >
10067        </div>
10068
10069        <div class="jm-form-group">
10070          <label class="jm-form-label" for="jm-rev-email-template--21146535100554__judgeme_reviews_pq8yep">Email address</label>
10071          <input
10072            class="jm-form-input"
10073            id="jm-rev-email-template--21146535100554__judgeme_reviews_pq8yep"
10074            type="email"
10075            placeholder="Your email address"
10076            data-jm-rev-email
10077          >
10078        </div>
10079
10080        <div style="position:absolute;left:-9999px;top:-9999px;height:0;width:0;overflow:hidden;" aria-hidden="true">
10081          <label for="jm-hp-template--21146535100554__judgeme_reviews_pq8yep">Leave empty</label>
10082          <input type="text" id="jm-hp-template--21146535100554__judgeme_reviews_pq8yep" name="website_url" tabindex="-1" autocomplete="off" data-jm-honeypot>
10083        </div>
10084
10085        <div class="jm-form-disclaimer">
10086          How we use your data: We'll only contact you about the review you left, and only if necessary. By submitting
10087          your review, you agree to Judge.me's
10088          <a href="https://judge.me/terms" target="_blank">terms, privacy and content policies</a>.
10089        </div>
10090
10091        <div class="jm-form-actions">
10092          <button type="button" class="jm-form-cancel" data-jm-form-cancel>Cancel review</button>
10093          <button type="submit" class="jm-form-submit" data-jm-form-submit><span class="jm-spinner"></span>Submit Review</button>
10094        </div>
10095
10096        <div class="jm-form-msg" data-jm-form-msg></div>
10097      </form>
10098    </div>
10099
10100    <hr class="jm-divider">
10101
10102    <div class="jm-controls">
10103      <div class="jm-select" data-jm-sort>
10104        <button type="button" class="jm-select-btn" data-jm-sort-btn aria-haspopup="listbox" aria-expanded="false">
10105          <span data-jm-sort-label>Highest Rating</span>
10106          <svg
10107            class="jm-select-caret"
10108            xmlns="http://www.w3.org/2000/svg"
10109            width="10"
10110            height="5"
10111            viewBox="0 0 10 5"
10112            fill="none"
10113            aria-hidden="true"
10114          >
10115            <path d="M0 0L5 5L10 0H0Z" fill="#5F471D"/>
10116          </svg>
10117        </button>
10118        <ul class="jm-select-list" data-jm-sort-list role="listbox" aria-label="Sort reviews">
10119          <li class="jm-select-opt" role="option" tabindex="0" data-value="highest" aria-selected="true">
10120            Highest Rating
10121          </li>
10122          <li class="jm-select-opt" role="option" tabindex="-1" data-value="lowest" aria-selected="false">
10123            Lowest Rating
10124          </li>
10125          <li class="jm-select-opt" role="option" tabindex="-1" data-value="recent" aria-selected="false">
10126            Most Recent
10127          </li>
10128          <li class="jm-select-opt" role="option" tabindex="-1" data-value="oldest" aria-selected="false">Oldest</li>
10129        </ul>
10130      </div>
10131    </div>
10132
10133    <div data-jm-content>
10134      <div class="jm-skeleton-grid" data-jm-skeleton>
10135        <div class="jm-skel"></div>
10136        <div class="jm-skel"></div>
10137      </div>
10138    </div>
10139
10140    <div class="jm-footer">
10141      <button type="button" class="jm-btn" data-jm-load-more style="display:none;">Load More</button>
10142    </div>
10143  </div>
10144
10145  <div class="jm-toast" data-jm-toast></div>
10146
10147  
10147<script>
10148    (function () {
10149      // Entrypoint for this section instance (scoped by `section.id` in the selector).
10150      var root = document.querySelector('.jm-section-template--21146535100554__judgeme_reviews_pq8yep');
10151      if (!root) return;
10152
10153      // Store + section settings (passed via data-attributes / Liquid).
10154      var shopDomain = root.dataset.shopDomain;
10155      var apiToken = "mzqYkvygrnD1sGLcdnSIgK-p2lE";
10156      // How many reviews the user sees at once in the grid / revealed per
10157      // "Load More" click. Stays small for a clean UI.
10158      var perPage = Math.max(5, Math.min(50, parseInt(root.dataset.perPage || '20', 10) || 20));
10159      // How many reviews we actually fetch per API request. A large value means
10160      // we typically only need ONE call to cover the whole review dataset,
10161      // which makes sorting correct immediately and avoids N/10 round-trips.
10162      var FETCH_BATCH_SIZE = 250;
10163      var defaultSummaryText = "Most customers find Revitin toothpaste to be a refreshing alternative to conventional formulas, praising its clean, natural taste and the way their mouth feels balanced rather than stripped. Many report healthier-feeling gums, improved sensitivity, and peace of mind from the non-toxic ingredient profile, with parents noting positive experiences for their children.";
10164
10165      // Fetch wrapper that hard-stops slow/hanging requests.
10166      function fetchWithTimeout(url, options, timeoutMs) {
10167        var ms = timeoutMs || 15000;
10168        var controller = new AbortController();
10169        var timer = null;
10170
10171        var timeoutPromise = new Promise(function (_, reject) {
10172          timer = setTimeout(function () {
10173            try { controller.abort(); } catch (e) {}
10174            reject(new Error('Stopped after ' + ms / 1000 + 's'));
10175          }, ms);
10176        });
10177
10178        var fetchPromise = fetch(url, Object.assign({}, options || {}, { signal: controller.signal })).then(
10179          function (res) { if (timer) clearTimeout(timer); return res; },
10180          function (err) { if (timer) clearTimeout(timer); throw err; }
10181        );
10182
10183        return Promise.race([fetchPromise, timeoutPromise]);
10184      }
10185
10186      var els = {
10187        avg: root.querySelector('[data-jm-average]'),
10188        avgStars: root.querySelector('[data-jm-average-stars]'),
10189        total: root.querySelector('[data-jm-total]'),
10190        breakdown: root.querySelector('[data-jm-breakdown]'),
10191        summary: root.querySelector('[data-jm-summary]'),
10192        content: root.querySelector('[data-jm-content]'),
10193        skeleton: root.querySelector('[data-jm-skeleton]'),
10194        sort: root.querySelector('[data-jm-sort]'),
10195        sortBtn: root.querySelector('[data-jm-sort-btn]'),
10196        sortLabel: root.querySelector('[data-jm-sort-label]'),
10197        sortList: root.querySelector('[data-jm-sort-list]'),
10198        loadMore: root.querySelector('[data-jm-load-more]'),
10199        toggleFormBtns: root.querySelectorAll('[data-jm-toggle-form]'),
10200        formWrap: root.querySelector('[data-jm-form-wrap]'),
10201        form: root.querySelector('[data-jm-form]'),
10202        formStars: root.querySelector('[data-jm-form-stars]'),
10203        formTitle: root.querySelector('[data-jm-rev-title]'),
10204        formBody: root.querySelector('[data-jm-rev-body]'),
10205        formName: root.querySelector('[data-jm-rev-name]'),
10206        formEmail: root.querySelector('[data-jm-rev-email]'),
10207        formFileInput: root.querySelector('[data-jm-file-input]'),
10208        formPreviews: root.querySelector('[data-jm-previews]'),
10209        formCancel: root.querySelector('[data-jm-form-cancel]'),
10210        formSubmit: root.querySelector('[data-jm-form-submit]'),
10211        formMsg: root.querySelector('[data-jm-form-msg]'),
10212      };
10213
10214      var state = {
10215        currentPage: 1,
10216        totalPages: 1,
10217        reviews: [],
10218        sort: 'highest',
10219        hasLoadedOnce: false,
10220        // How many reviews to show on screen right now (grows when the user
10221        // clicks "Load More"). We keep this separate from how many are loaded
10222        // into `reviews` so sorting can span the full dataset.
10223        displayCount: 0,
10224        // Whether we've finished background-prefetching every page. Until this
10225        // is true, sort/load-more might need to wait for more data.
10226        allLoaded: false,
10227        // Tracks the in-flight background prefetch promise (if any).
10228        prefetchPromise: null,
10229        // Authoritative totals / rating-breakdown captured from the Judge.me
10230        // widget header on the FIRST response. These represent the full review
10231        // dataset (e.g. 900+) and must NOT be overwritten with partial counts
10232        // from subsequent paginated responses.
10233        totalCount: 0,
10234        rawHistogram: null,     // { "1": n, "2": n, ... "5": n } from API
10235        ratingAverage: null,    // number from API
10236      };
10237
10238      function escapeHtml(str) {
10239        return String(str == null ? '' : str)
10240          .replace(/&/g, '&amp;')
10241          .replace(/</g, '&lt;')
10242          .replace(/>/g, '&gt;')
10243          .replace(/"/g, '&quot;')
10244          .replace(/'/g, '&#039;');
10245      }
10246
10247      function formatDate(iso) {
10248        try {
10249          var d = new Date(iso);
10250          if (isNaN(d.getTime())) return '';
10251          var mm = ('0' + (d.getMonth() + 1)).slice(-2);
10252          var dd = ('0' + d.getDate()).slice(-2);
10253          var yy = String(d.getFullYear()).slice(-2);
10254          return mm + '/' + dd + '/' + yy;
10255        } catch (e) {
10256          return '';
10257        }
10258      }
10259
10260      function starSvg(filled) {
10261        var opacity = filled ? '1' : '0.22';
10262        return '<svg class="jm-star" viewBox="0 0 24 24" aria-hidden="true" style="opacity:' + opacity + '">' +
10263          '<path d="M12 17.3l-6.18 3.7 1.64-7.03L2 9.24l7.19-.61L12 2l2.81 6.63 7.19.61-5.46 4.73 1.64 7.03z"></path>' +
10264          '</svg>';
10265      }
10266
10267      function starsInline(count) {
10268        var n = Math.max(0, Math.min(5, Number(count) || 0));
10269        var html = '';
10270        for (var i = 0; i < n; i++) html += starSvg(true);
10271        return html;
10272      }
10273
10274      function renderStarsInto(container, rating, outOf) {
10275        outOf = outOf || 5;
10276        var r = Math.max(0, Math.min(outOf, Math.round(Number(rating) || 0)));
10277        var html = '';
10278        for (var i = 1; i <= outOf; i++) html += starSvg(i <= r);
10279        container.innerHTML = html;
10280      }
10281
10282      function showError(msg) {
10283        els.content.innerHTML = '<div class="jm-error">' + escapeHtml(msg) + '</div>';
10284      }
10285
10286      function showEmpty() {
10287        els.content.innerHTML =
10288          '<div class="jm-empty">' +
10289            '<div>No reviews yet. Be the first to write one!</div>' +
10290            '<div style="margin-top:14px;">' +
10291              '<button type="button" class="jm-btn" data-jm-toggle-form>Write a Review</button>' +
10292            '</div>' +
10293          '</div>';
10294        var btns = els.content.querySelectorAll('[data-jm-toggle-form]');
10295        for (var i = 0; i < btns.length; i++) btns[i].addEventListener('click', toggleForm);
10296      }
10297
10298      function renderSkeleton(show) {
10299        if (!els.skeleton) return;
10300        els.skeleton.style.display = show ? '' : 'none';
10301      }
10302
10303      function computeHistogram(reviews) {
10304        var counts = { 1:0, 2:0, 3:0, 4:0, 5:0 };
10305        for (var i = 0; i < reviews.length; i++) {
10306          var rating = Math.round(Number(reviews[i].rating) || 0);
10307          if (rating >= 1 && rating <= 5) counts[rating] += 1;
10308        }
10309        return counts;
10310      }
10311
10312      function renderTop(opts) {
10313        var average = opts.average;
10314        var totalCount = opts.totalCount;
10315        var histogram = opts.histogram;
10316        var avg = (typeof average === 'number' && !isNaN(average)) ? average : null;
10317        els.avg.textContent = avg ? avg.toFixed(1) : '\u2014';
10318
10319        if (avg) {
10320          renderStarsInto(els.avgStars, Math.round(avg));
10321        } else {
10322          els.avgStars.innerHTML = starSvg(false) + starSvg(false) + starSvg(false) + starSvg(false) + starSvg(false);
10323        }
10324
10325        var total = Number(totalCount) || state.reviews.length;
10326        els.total.textContent = total.toLocaleString() + ' Reviews';
10327
10328        // Bar widths are based on TOTAL reviews (total = 100%).
10329        var totalForBars = 0;
10330        for (var s = 1; s <= 5; s++) totalForBars += (histogram[s] || 0);
10331        if (!totalForBars) totalForBars = total || 1;
10332
10333        var rows = '';
10334        for (var star = 5; star >= 1; star--) {
10335          var count = histogram[star] || 0;
10336          var pct = Math.round((count / totalForBars) * 100);
10337          rows +=
10338            '<div class="jm-breakdown-row">' +
10339              '<div class="jm-breakdown-stars" aria-hidden="true">' + starsInline(star) + '</div>' +
10340              '<div class="jm-bar" aria-hidden="true"><span style="width:' + pct + '%"></span></div>' +
10341              '<div class="jm-count">' + count.toLocaleString() + '</div>' +
10342            '</div>';
10343        }
10344        els.breakdown.innerHTML = rows;
10345      }
10346
10347      function sortReviews(reviews, sortKey) {
10348        var copy = reviews.slice();
10349        copy.sort(function (a, b) {
10350          if (sortKey === 'highest') return (b.rating - a.rating) || (new Date(b.created_at) - new Date(a.created_at));
10351          if (sortKey === 'lowest') return (a.rating - b.rating) || (new Date(b.created_at) - new Date(a.created_at));
10352          if (sortKey === 'recent') return new Date(b.created_at) - new Date(a.created_at);
10353          if (sortKey === 'oldest') return new Date(a.created_at) - new Date(b.created_at);
10354          return 0;
10355        });
10356        return copy;
10357      }
10358
10359      function renderGrid() {
10360        // Sort the full loaded dataset locally, then slice to the number of
10361        // reviews the user has asked to see. This ensures sorting applies across
10362        // ALL reviews (not just the first page), while still paginating 10 at a
10363        // time via "Load More".
10364        var sortedAll = sortReviews(state.reviews, state.sort);
10365        var limit = Math.max(0, Math.min(sortedAll.length, state.displayCount || perPage));
10366        var sorted = sortedAll.slice(0, limit);
10367        var cards = '';
10368        for (var i = 0; i < sorted.length; i++) {
10369          var r = sorted[i];
10370          var created = formatDate(r.created_at);
10371          var name = escapeHtml((r.reviewer && r.reviewer.name) || r.reviewer_name || 'Anonymous');
10372          var title = escapeHtml(r.title || '');
10373          var body = escapeHtml(r.body || r.review || '');
10374          var verified = !!(r.verified || r.verified_buyer);
10375          var rating = Math.max(0, Math.min(5, Math.round(Number(r.rating) || 0)));
10376
10377          var stars = '';
10378          for (var j = 1; j <= 5; j++) stars += starSvg(j <= rating);
10379
10380          cards +=
10381            '<article class="jm-card">' +
10382              '<div class="jm-card-stars" aria-hidden="true">' + stars + '</div>' +
10383              '<div class="jm-card-date">' + created + '</div>' +
10384              '<div class="jm-card-meta">' +
10385                '<span>' + name + '</span>' +
10386                (verified ? '<span class="jm-verified">Verified by shop</span>' : '') +
10387              '</div>' +
10388              (title ? '<div class="jm-card-title">' + title + '</div>' : '') +
10389              (body ? '<div class="jm-card-body">' + body + '</div>' : '') +
10390            '</article>';
10391        }
10392
10393        els.content.innerHTML = cards ? '<div class="jm-grid">' + cards + '</div>' : '';
10394      }
10395
10396      function updateLoadMoreVisibility() {
10397        // Show "Load More" if there are more loaded reviews to reveal OR more
10398        // pages waiting to be fetched in the background.
10399        var moreLoadedToShow = state.displayCount < state.reviews.length;
10400        var morePagesAvailable = state.currentPage < state.totalPages;
10401        var hasMore = moreLoadedToShow || morePagesAvailable;
10402        els.loadMore.style.display = hasMore ? '' : 'none';
10403      }
10404
10405      // Background-prefetch every remaining page so local sorting covers the
10406      // entire review dataset, not just the first page.
10407      async function prefetchAllPages() {
10408        if (state.prefetchPromise) return state.prefetchPromise;
10409
10410        state.prefetchPromise = (async function () {
10411          while (state.currentPage < state.totalPages) {
10412            var nextPage = state.currentPage + 1;
10413            try {
10414              var data = await fetchReviewsPage(nextPage);
10415              var reviews = Array.isArray(data && data.reviews) ? data.reviews : [];
10416
10417              state.currentPage = Number(data && data.current_page) || nextPage;
10418              var tp = Number(data && data.total_pages) || 0;
10419              var tc = Number(data && data.total_count) || 0;
10420              if (!tp && tc > 0) tp = Math.ceil(tc / FETCH_BATCH_SIZE);
10421              if (!tp && reviews.length >= FETCH_BATCH_SIZE) tp = state.currentPage + 1;
10422              if (tp) state.totalPages = tp;
10423              if (!reviews.length) { state.totalPages = state.currentPage; break; }
10424
10425              state.reviews = state.reviews.concat(reviews);
10426
10427              // NOTE: do NOT call renderTop here. The header (total count,
10428              // average, histogram) was already populated from the
10429              // authoritative widget-header values during initialLoad, which
10430              // reflect the ENTIRE review dataset (e.g. 900 reviews). Using
10431              // state.reviews.length here would overwrite that with the
10432              // partial count we've loaded so far (e.g. 100).
10433
10434              // Re-render in case the user's current sort changes which reviews
10435              // appear in the top `displayCount` now that more data is loaded.
10436              renderGrid();
10437              updateLoadMoreVisibility();
10438            } catch (e) {
10439              // One page failed—stop the prefetch loop but keep what we have.
10440              break;
10441            }
10442          }
10443          state.allLoaded = true;
10444          updateLoadMoreVisibility();
10445        })();
10446
10447        return state.prefetchPromise;
10448      }
10449
10450      function normalizeReviewsPayload(json) {
10451        // Judge.me responses vary by endpoint; normalize to { reviews, meta }.
10452        if (!json || typeof json !== 'object') return { raw: json, reviews: [], meta: {} };
10453        var reviews = [];
10454        if (Array.isArray(json.reviews)) reviews = json.reviews;
10455        else if (Array.isArray(json.data)) reviews = json.data;
10456        else if (Array.isArray(json.review)) reviews = json.review;
10457        return {
10458          raw: json,
10459          reviews: reviews,
10460          meta: {
10461            current_page: json.current_page != null ? json.current_page : (json.page != null ? json.page : json.currentPage),
10462            total_pages: json.total_pages != null ? json.total_pages : (json.totalPages != null ? json.totalPages : json.pages),
10463            total_count: json.total_count != null ? json.total_count : (json.total_reviews != null ? json.total_reviews : json.total),
10464            rating_average: json.rating_average != null ? json.rating_average : json.average_rating,
10465            rating_distribution: json.rating_distribution || json.ratings_breakdown,
10466            reviews_summary: json.reviews_summary || json.summary,
10467          },
10468        };
10469      }
10470
10471      // Judge.me's cache CDN serves widget endpoints with proper CORS headers.
10472      // This is how Judge.me's own storefront script (jdgm-widget.js) fetches reviews.
10473      var CACHE_BASE = 'https://cache.judge.me';
10474
10475      function buildCacheUrl(widgetPath, params) {
10476        var url = new URL(CACHE_BASE + '/widgets/' + widgetPath);
10477        url.searchParams.set('shop_domain', shopDomain);
10478        url.searchParams.set('api_token', apiToken);
10479        if (params) {
10480          var keys = Object.keys(params);
10481          for (var i = 0; i < keys.length; i++) {
10482            if (params[keys[i]] != null) url.searchParams.set(keys[i], String(params[keys[i]]));
10483          }
10484        }
10485        return url.toString();
10486      }
10487
10488      function parseWidgetHtml(html) {
10489        // Widget endpoints return HTML markup inside JSON; we parse that HTML into review objects.
10490        var doc = new DOMParser().parseFromString(html, 'text/html');
10491        var cards = doc.querySelectorAll('.jdgm-rev');
10492        var reviews = [];
10493        for (var i = 0; i < cards.length; i++) {
10494          var card = cards[i];
10495          var ratingEl = card.querySelector('.jdgm-rev__rating');
10496          var rating = ratingEl ? (ratingEl.getAttribute('data-score') || ratingEl.querySelectorAll('.jdgm-star.jdgm--on').length) : 0;
10497          var titleEl = card.querySelector('.jdgm-rev__title');
10498          var bodyEl = card.querySelector('.jdgm-rev__body');
10499          var authorEl = card.querySelector('.jdgm-rev__author');
10500          var dateEl = card.querySelector('.jdgm-rev__timestamp');
10501          var verifiedEl = card.querySelector('.jdgm-rev__buyer-badge');
10502          var verifiedAttr = card.getAttribute('data-verified-buyer');
10503          reviews.push({
10504            rating: Number(rating) || 0,
10505            title: titleEl ? titleEl.textContent.trim() : '',
10506            body: bodyEl ? bodyEl.textContent.trim() : '',
10507            reviewer_name: authorEl ? authorEl.textContent.trim() : 'Anonymous',
10508            created_at: dateEl ? (dateEl.getAttribute('data-content') || dateEl.textContent.trim()) : '',
10509            verified: verifiedAttr === 'true' || !!verifiedEl,
10510          });
10511        }
10512        return reviews;
10513      }
10514
10515      function parseWidgetHeader(html) {
10516        // Parses totals / average / histogram from the widget "header" HTML (if provided).
10517        if (!html) return {};
10518        var doc = new DOMParser().parseFromString(html, 'text/html');
10519        var header = doc.querySelector('.jdgm-all-reviews__header') || doc.documentElement;
10520        var totalCount = Number(header.getAttribute('data-number-of-reviews')) || 0;
10521        var average = parseFloat(header.getAttribute('data-average-rating')) || 0;
10522        var distribution = {};
10523        var rows = doc.querySelectorAll('.jdgm-histogram__row[data-rating]');
10524        for (var i = 0; i < rows.length; i++) {
10525          var star = rows[i].getAttribute('data-rating');
10526          var freq = Number(rows[i].getAttribute('data-frequency')) || 0;
10527          if (star && star !== 'null') distribution[star] = freq;
10528        }
10529        return { totalCount: totalCount, average: average, distribution: distribution };
10530      }
10531
10532      function widgetParams(page) {
10533        return {
10534          page: page,
10535          per_page: FETCH_BATCH_SIZE,
10536          review_type: 'product-reviews'
10537        };
10538      }
10539
10540      function parseResponse(rawBody, page) {
10541        var trimmedBody = String(rawBody || '').replace(/^\uFEFF/, '').trim();
10542        var json;
10543        try {
10544          json = JSON.parse(trimmedBody);
10545        } catch (e) {
10546          throw new Error('Invalid JSON from Judge.me');
10547        }
10548
10549        var reviews, headerInfo;
10550
10551        if (json.all_reviews && typeof json.all_reviews === 'string') {
10552          reviews = parseWidgetHtml(json.all_reviews);
10553          headerInfo = parseWidgetHeader(json.all_reviews_header || '');
10554          return {
10555            reviews: reviews,
10556            current_page: page,
10557            total_count: headerInfo.totalCount,
10558            rating_average: headerInfo.average,
10559            rating_distribution: headerInfo.distribution,
10560          };
10561        }
10562
10563        var norm = normalizeReviewsPayload(json);
10564        return {
10565          reviews: norm.reviews,
10566          current_page: norm.meta.current_page || page,
10567          total_pages: norm.meta.total_pages,
10568          total_count: norm.meta.total_count,
10569          rating_average: norm.meta.rating_average,
10570          rating_distribution: norm.meta.rating_distribution,
10571          reviews_summary: norm.meta.reviews_summary,
10572        };
10573      }
10574
10575      async function fetchReviewsPage(page) {
10576        var candidates = [
10577          buildCacheUrl('all_reviews_page', widgetParams(page)),
10578          CACHE_BASE.replace('cache.', 'api.') + '/api/v1/widgets/all_reviews_page?shop_domain=' +
10579            encodeURIComponent(shopDomain) + '&api_token=' + encodeURIComponent(apiToken) +
10580            '&per_page=' + FETCH_BATCH_SIZE + '&page=' + page + '&review_type=product-reviews',
10581        ];
10582
10583        var lastErr;
10584        for (var i = 0; i < candidates.length; i++) {
10585          try {
10586            var res = await fetchWithTimeout(candidates[i], { headers: { Accept: 'application/json' } }, 10000);
10587            var rawBody = await res.text();
10588            if (!res.ok) throw new Error('HTTP ' + res.status);
10589            return parseResponse(rawBody, page);
10590          } catch (e) {
10591            lastErr = e;
10592          }
10593        }
10594        throw lastErr || new Error('Failed to fetch reviews');
10595      }
10596
10597      function extractSummaryText(reviews) {
10598        var n = reviews.length;
10599        if (!n) return 'No reviews yet.';
10600        var sum = 0;
10601        for (var i = 0; i < n; i++) sum += (Number(reviews[i].rating) || 0);
10602        var avg = sum / n;
10603        if (avg >= 4.6) return 'Customers love the results, especially freshness and overall mouth feel.';
10604        if (avg >= 4.0) return 'Most customers are happy overall, with a few mixed experiences.';
10605        return 'Reviews are mixed\u2014some customers love it, while others had issues.';
10606      }
10607
10608      async function initialLoad() {
10609        if (!apiToken) {
10610          showError('Missing Judge.me API token. Add your public token in this section’s Liquid (jm_token).');
10611          return;
10612        }
10613
10614        renderSkeleton(true);
10615        els.loadMore.style.display = 'none';
10616
10617        try {
10618          var data = await fetchReviewsPage(1);
10619          var reviews = Array.isArray(data && data.reviews) ? data.reviews : [];
10620
10621          state.currentPage = Number(data && data.current_page) || 1;
10622          var tp = Number(data && data.total_pages) || 0;
10623          var tc = Number(data && data.total_count) || 0;
10624          // Widget endpoints often provide total_count but not total_pages → derive pages from FETCH_BATCH_SIZE.
10625          if (!tp && tc > 0) tp = Math.ceil(tc / FETCH_BATCH_SIZE);
10626          // If totals are unknown, assume "maybe more" if we received a full page.
10627          if (!tp && reviews.length >= FETCH_BATCH_SIZE) tp = state.currentPage + 1;
10628          state.totalPages = tp || 1;
10629          state.reviews = reviews;
10630          // Only reveal `perPage` reviews at a time in the UI, even though we
10631          // may have fetched up to FETCH_BATCH_SIZE of them in one call.
10632          state.displayCount = Math.min(perPage, reviews.length);
10633          state.allLoaded = state.currentPage >= state.totalPages;
10634          state.hasLoadedOnce = true;
10635
10636          renderSkeleton(false);
10637
10638          if (!reviews.length) {
10639            showEmpty();
10640            els.summary.textContent = defaultSummaryText || 'No reviews yet.';
10641            renderTop({
10642              average: null,
10643              totalCount: Number(data && data.total_count) || 0,
10644              histogram: {1:0,2:0,3:0,4:0,5:0}
10645            });
10646            updateLoadMoreVisibility();
10647            return;
10648          }
10649
10650          var totalCount = Number(data.total_count) || Number(data.total_reviews) || reviews.length;
10651          var avg = typeof data.rating_average === 'number'
10652            ? data.rating_average
10653            : (reviews.reduce(function (a, r) { return a + (Number(r.rating) || 0); }, 0) / reviews.length);
10654
10655          var histogram = data.rating_distribution
10656            ? {
10657                1: Number(data.rating_distribution['1'] || 0),
10658                2: Number(data.rating_distribution['2'] || 0),
10659                3: Number(data.rating_distribution['3'] || 0),
10660                4: Number(data.rating_distribution['4'] || 0),
10661                5: Number(data.rating_distribution['5'] || 0),
10662              }
10663            : computeHistogram(reviews);
10664
10665          // Remember these as the authoritative store-wide totals. Later
10666          // paginated responses only give us partial data and must NOT
10667          // overwrite these values.
10668          state.totalCount = totalCount;
10669          state.rawHistogram = histogram;
10670          state.ratingAverage = avg;
10671
10672          renderTop({ average: avg, totalCount: totalCount, histogram: histogram });
10673          els.summary.textContent = (data && data.reviews_summary) || defaultSummaryText || extractSummaryText(reviews);
10674          renderGrid();
10675          updateLoadMoreVisibility();
10676
10677          // Kick off background prefetch of remaining pages so that sorting
10678          // eventually covers the full dataset.
10679          if (!state.allLoaded) prefetchAllPages();
10680        } catch (e) {
10681          renderSkeleton(false);
10682          showError('Could not load reviews.');
10683        }
10684      }
10685
10686      async function loadMore() {
10687        // "Load More" just reveals more of the already-sorted local dataset.
10688        // If we haven't finished prefetching every page yet, we wait for enough
10689        // data to be available before revealing the next batch.
10690        var targetCount = state.displayCount + perPage;
10691
10692        if (state.reviews.length < targetCount && !state.allLoaded) {
10693          els.loadMore.disabled = true;
10694          els.loadMore.textContent = 'Loading\u2026';
10695          try { await prefetchAllPages(); } catch (e) {}
10696          els.loadMore.disabled = false;
10697          els.loadMore.textContent = 'Load More';
10698        }
10699
10700        state.displayCount = Math.min(targetCount, state.reviews.length);
10701        renderGrid();
10702        updateLoadMoreVisibility();
10703      }
10704
10705      /* ── Write-a-review dropdown form ── */
10706      var formRating = 0;
10707      var formFiles = [];
10708      var formOpenedAt = 0;
10709
10710      function toggleForm() {
10711        if (!els.formWrap) return;
10712        var isOpen = els.formWrap.classList.contains('is-open');
10713        if (isOpen) {
10714          els.formWrap.classList.remove('is-open');
10715        } else {
10716          els.formWrap.classList.add('is-open');
10717          formOpenedAt = Date.now();
10718          els.formWrap.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
10719        }
10720      }
10721
10722      function resetForm() {
10723        formRating = 0;
10724        formFiles = [];
10725        updateStarDisplay(0);
10726        if (els.form) els.form.reset();
10727        if (els.formPreviews) els.formPreviews.innerHTML = '';
10728        if (els.formMsg) { els.formMsg.textContent = ''; els.formMsg.className = 'jm-form-msg'; }
10729        if (els.formSubmit) els.formSubmit.disabled = false;
10730      }
10731
10732      function updateStarDisplay(rating) {
10733        if (!els.formStars) return;
10734        var stars = els.formStars.querySelectorAll('.jm-form-star');
10735        for (var i = 0; i < stars.length; i++) {
10736          if (i < rating) { stars[i].classList.add('active'); }
10737          else { stars[i].classList.remove('active'); }
10738        }
10739      }
10740
10741      if (els.formStars) {
10742        // Click to set rating, hover to preview rating.
10743        els.formStars.addEventListener('click', function (e) {
10744          var star = e.target.closest('.jm-form-star');
10745          if (!star) return;
10746          formRating = parseInt(star.getAttribute('data-star'), 10) || 0;
10747          updateStarDisplay(formRating);
10748        });
10749        els.formStars.addEventListener('mouseover', function (e) {
10750          var star = e.target.closest('.jm-form-star');
10751          if (!star) return;
10752          updateStarDisplay(parseInt(star.getAttribute('data-star'), 10) || 0);
10753        });
10754        els.formStars.addEventListener('mouseleave', function () {
10755          updateStarDisplay(formRating);
10756        });
10757      }
10758
10759      if (els.formFileInput) {
10760        // Optional media selection (we currently only show previews; actual upload support depends on Judge.me endpoint).
10761        els.formFileInput.addEventListener('change', function () {
10762          var files = els.formFileInput.files;
10763          if (!files || !files.length) return;
10764          for (var i = 0; i < files.length; i++) {
10765            if (formFiles.length >= 5) break;
10766            formFiles.push(files[i]);
10767          }
10768          renderPreviews();
10769        });
10770      }
10771
10772      function renderPreviews() {
10773        if (!els.formPreviews) return;
10774        els.formPreviews.innerHTML = '';
10775        for (var i = 0; i < formFiles.length; i++) {
10776          var img = document.createElement('img');
10777          img.src = URL.createObjectURL(formFiles[i]);
10778          img.alt = 'Preview';
10779          els.formPreviews.appendChild(img);
10780        }
10781      }
10782
10783      function showFormMsg(text, type) {
10784        if (!els.formMsg) return;
10785        els.formMsg.textContent = text;
10786        els.formMsg.className = 'jm-form-msg ' + (type || '');
10787      }
10788
10789      async function submitReview(e) {
10790        e.preventDefault();
10791        // Basic client-side validation.
10792        var honeypot = root.querySelector('[data-jm-honeypot]');
10793        if (honeypot && honeypot.value) return;
10794        if (formOpenedAt && (Date.now() - formOpenedAt) < 3000) { showFormMsg('Please take a moment before submitting.', 'error'); return; }
10795        if (!formRating) { showFormMsg('Please select a star rating.', 'error'); return; }
10796        var body = (els.formBody && els.formBody.value || '').trim();
10797        if (!body) { showFormMsg('Please write your review.', 'error'); return; }
10798        var name = (els.formName && els.formName.value || '').trim();
10799        if (!name) { showFormMsg('Please enter your display name.', 'error'); return; }
10800        var email = (els.formEmail && els.formEmail.value || '').trim();
10801        if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { showFormMsg('Please enter a valid email address.', 'error'); return; }
10802
10803        els.formSubmit.disabled = true;
10804        els.formSubmit.classList.add('is-loading');
10805        showFormMsg('', '');
10806
10807        var payload = {
10808          shop_domain: shopDomain,
10809          platform: 'shopify',
10810          name: name,
10811          email: email,
10812          rating: formRating,
10813          title: (els.formTitle && els.formTitle.value || '').trim(),
10814          body: body,
10815        };
10816
10817        // Submit via a hidden iframe form POST (bypasses CORS; judge.me/reviews always returns 200).
10818        try {
10819          var iframeName = 'jm-submit-' + Date.now();
10820          var iframe = document.createElement('iframe');
10821          iframe.name = iframeName;
10822          iframe.style.cssText = 'position:absolute;left:-9999px;top:-9999px;width:0;height:0;border:0;';
10823          document.body.appendChild(iframe);
10824
10825          var hiddenForm = document.createElement('form');
10826          hiddenForm.method = 'POST';
10827          hiddenForm.action = 'https://judge.me/reviews';
10828          hiddenForm.target = iframeName;
10829          hiddenForm.style.display = 'none';
10830
10831          var fields = {
10832            shop_domain: payload.shop_domain,
10833            platform: payload.platform,
10834            name: payload.name,
10835            email: payload.email,
10836            rating: String(payload.rating),
10837            title: payload.title,
10838            body: payload.body,
10839          };
10840          var fieldKeys = Object.keys(fields);
10841          for (var fi = 0; fi < fieldKeys.length; fi++) {
10842            var inp = document.createElement('input');
10843            inp.type = 'hidden';
10844            inp.name = fieldKeys[fi];
10845            inp.value = fields[fieldKeys[fi]] || '';
10846            hiddenForm.appendChild(inp);
10847          }
10848
10849          document.body.appendChild(hiddenForm);
10850          hiddenForm.submit();
10851
10852          // Show spinner for at least 1 second before closing.
10853          setTimeout(function () {
10854            els.formSubmit.classList.remove('is-loading');
10855            resetForm();
10856            els.formWrap.classList.remove('is-open');
10857
10858            // Scroll to top of section after form closes.
10859            root.scrollIntoView({ behavior: 'smooth', block: 'start' });
10860
10861            // Show toast after form is visually closed (allow 400ms for collapse animation).
10862            setTimeout(function () {
10863              var toast = root.querySelector('[data-jm-toast]') || document.querySelector('[data-jm-toast]');
10864              if (toast) {
10865                toast.textContent = 'Review has been submitted';
10866                toast.classList.add('is-visible');
10867                setTimeout(function () { toast.classList.remove('is-visible'); }, 2000);
10868              }
10869            }, 400);
10870
10871            // Clean up hidden iframe/form.
10872            setTimeout(function () {
10873              try { document.body.removeChild(iframe); } catch (x) {}
10874              try { document.body.removeChild(hiddenForm); } catch (x) {}
10875            }, 3000);
10876          }, 1000);
10877        } catch (err) {
10878          els.formSubmit.classList.remove('is-loading');
10879          showFormMsg('Could not submit review. Please try again.', 'error');
10880          els.formSubmit.disabled = false;
10881        }
10882      }
10883
10884      var allToggleBtns = root.querySelectorAll('[data-jm-toggle-form]');
10885      for (var i = 0; i < allToggleBtns.length; i++) allToggleBtns[i].addEventListener('click', toggleForm);
10886      if (els.formCancel) els.formCancel.addEventListener('click', function () { resetForm(); els.formWrap.classList.remove('is-open'); });
10887      if (els.form) els.form.addEventListener('submit', submitReview);
10888
10889      if (els.sort) {
10890        // Custom dropdown open/close.
10891        function closeSort() {
10892          if (!els.sort || !els.sortBtn) return;
10893          els.sort.classList.remove('is-open');
10894          els.sortBtn.setAttribute('aria-expanded', 'false');
10895        }
10896
10897        function openSort() {
10898          if (!els.sort || !els.sortBtn) return;
10899          els.sort.classList.add('is-open');
10900          els.sortBtn.setAttribute('aria-expanded', 'true');
10901        }
10902
10903        function setSort(value, label) {
10904          var previousSort = state.sort;
10905          state.sort = value;
10906          if (els.sortLabel) els.sortLabel.textContent = label;
10907          if (els.sortList) {
10908            var opts = els.sortList.querySelectorAll('[role="option"]');
10909            for (var i = 0; i < opts.length; i++) {
10910              var isSelected = (opts[i].getAttribute('data-value') === value);
10911              opts[i].setAttribute('aria-selected', isSelected ? 'true' : 'false');
10912              opts[i].tabIndex = isSelected ? 0 : -1;
10913            }
10914          }
10915
10916          if (!state.hasLoadedOnce || previousSort === value) return;
10917
10918          // Re-render immediately with whatever reviews we have so far. If the
10919          // background prefetch is still running, the sorted view will update
10920          // again as more pages arrive (prefetchAllPages calls renderGrid on
10921          // each appended page).
10922          renderGrid();
10923          updateLoadMoreVisibility();
10924        }
10925
10926        if (els.sortBtn) {
10927          els.sortBtn.addEventListener('click', function () {
10928            var isOpen = els.sort.classList.contains('is-open');
10929            if (isOpen) closeSort(); else openSort();
10930          });
10931        }
10932
10933        if (els.sortList) {
10934          els.sortList.addEventListener('click', function (e) {
10935            var opt = e.target.closest('[role="option"]');
10936            if (!opt) return;
10937            setSort(opt.getAttribute('data-value'), opt.textContent.trim());
10938            closeSort();
10939          });
10940
10941          els.sortList.addEventListener('keydown', function (e) {
10942            var opts = els.sortList.querySelectorAll('[role="option"]');
10943            if (!opts.length) return;
10944            var current = document.activeElement && document.activeElement.getAttribute('role') === 'option'
10945              ? document.activeElement
10946              : (els.sortList.querySelector('[role="option"][aria-selected="true"]') || opts[0]);
10947            var idx = 0;
10948            for (var i = 0; i < opts.length; i++) if (opts[i] === current) idx = i;
10949
10950            if (e.key === 'Enter' || e.key === ' ') {
10951              e.preventDefault();
10952              setSort(current.getAttribute('data-value'), current.textContent.trim());
10953              closeSort();
10954              if (els.sortBtn) els.sortBtn.focus();
10955            } else if (e.key === 'Escape') {
10956              e.preventDefault();
10957              closeSort();
10958              if (els.sortBtn) els.sortBtn.focus();
10959            } else if (e.key === 'ArrowDown') {
10960              e.preventDefault();
10961              opts[Math.min(opts.length - 1, idx + 1)].focus();
10962            } else if (e.key === 'ArrowUp') {
10963              e.preventDefault();
10964              opts[Math.max(0, idx - 1)].focus();
10965            }
10966          });
10967        }
10968
10969        document.addEventListener('click', function (e) {
10970          if (!els.sort) return;
10971          if (!els.sort.contains(e.target)) closeSort();
10972        });
10973
10974        document.addEventListener('keydown', function (e) {
10975          if (e.key !== 'Escape') return;
10976          if (els.sort && els.sort.classList.contains('is-open')) closeSort();
10977        });
10978
10979        // Default sort.
10980        setSort('highest', 'Highest Rating');
10981      }
10982
10983      if (els.loadMore) els.loadMore.addEventListener('click', loadMore);
10984
10985      initialLoad();
10986    })();
10987  </script>
10987
10988</section>
10989
10990
10991</div></div>
10992  <div id='easylockdown404' style='display:none;'><div class="easylockdown404-content-container"><div class="easylockdown404-content-wrapper"><div class="easylockdown404-title-holder"><span class="easylockdown-title-404"></span></div><div class="easylockdown404-content-holder rte"><div class="easylockdown-message-404"></div></div></div></div></div>
10993  
10994<div id="easylockdown-password-form" style="display: none;">
10995  <div id="easylockdown-wrapper">
10996    
10997
10998    <div class="easylockdown-form-holder">
10999      <div id="easylockdown-password-error">Invalid password</div>
11000      <input type="password" placeholder="" id="easylockdown-password"
11001             onkeypress="if( event.keyCode == 13 && typeof easylockdown == 'object' && typeof easylockdown.checkUnlockPassword == 'function' ) { event.preventDefault(); easylockdown.checkUnlockPassword(this); }" />
11002      <a href="javascript:void(0);" id="easylockdown-password-form-button" onclick="if( typeof easylockdown == 'object' && typeof easylockdown.checkUnlockPassword == 'function' ) easylockdown.checkUnlockPassword(this);">Enter</a>
11003    </div>
11004  </div>
11005</div>
11006
11007  
11007<script type="text/javascript" id='easylockdown-helper'>
11008    var easylockdownLoaded = false;
11009    document.addEventListener('easylockdown_loaded', function() {
11010      easylockdownLoaded = true;
11011      easylockdown.clientContentToggle(true);
11012    }, {once: true});
11013    document.addEventListener('DOMContentLoaded', function() {
11014      setTimeout(function() {
11015        if(!easylockdownLoaded) { for(var blocks=document.querySelectorAll("#easylockdown-password-form, #easylockdown-hpbtn-style, .easylockdown-auto-hl-styles, .easylockdown-custom-hl-styles, #easylockdown404"),_easylockdownElementIndex=0;_easylockdownElementIndex<blocks.length;_easylockdownElementIndex++)blocks[_easylockdownElementIndex].remove();
11016        var elContent = document.querySelector('.easylockdown-content')
11017        if(elContent) {
11018          elContent.removeAttribute('style');
11019        }
11020        var elStyle = document.getElementById('easylockdown-plugin-style');
11021        if(elStyle) {
11022          elStyle.remove();
11023        }
11024        console.info("EasyLockdown is not loaded");
11025        }
11026      }, 350);
11027    });
11028  </script>
11028
11029
11030
11031
11032
11033        <div id="shopify-section-footer" class="shopify-section"><footer class="bg-light-tan mt-8 lg:mt-12">
11034  <div class="bg-sand rounded-3xl py-14 lg:py-24 middle-footer">
11035    <div class="site-container">
11036      <div class="grid lg:grid-cols-[1fr_2fr] lg:gap-6">
11037        <h3 class="hidden lg:block text-[1.5rem] lg:text-[1.75rem] text-brown body-regular !leading-tight max-w-sm">The world’s first prebiotic toothpaste. Try it today!</h3>
11038        <div class="grid lg:grid-cols-2 lg:gap-6 lg:justify-between lg:items-start">
11039          <div class="grid grid-cols-2 order-2 mt-8 lg:order-1 lg:mt-0">
11040            
11041              
11042              <div class="grid content-start">
11043                <p class="tag mt-5 mb-2 lg:mb-5 lg:mt-0">Shop </p>
11044                
11045                  
11046                    <a href="https://revitin.com/products/revitin-natural-toothpaste" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Revitin Toothpaste</a>
11047                  
11048                  
11049                
11050                  
11051                    <a href="/pages/about" class="text-brown my-1 lg:hover:underline transition-all max-w-max">About Us</a>
11052                  
11053                  
11054                
11055                  
11056                    <a href="/pages/ingredients" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Ingredients</a>
11057                  
11058                  
11059                
11060                  
11061                    <a href="/pages/about/#meet-dr-gerry" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Meet Dr. Gerry</a>
11062                  
11063                  
11064                
11065                  
11066                    <a href="/blogs/all" class="text-brown my-1 lg:hover:underline transition-all max-w-max">The Science</a>
11067                  
11068                  
11069                
11070                  
11071                    <a href="/pages/ingredients" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Made in the USA</a>
11072                  
11073                  
11074                
11075                  
11076                    <a href="/pages/press" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Press</a>
11077                  
11078                  
11079                
11080                <a href="/pages/review" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Reviews</a>
11081                <a href="/pages/faqs" class="text-brown my-1 lg:hover:underline transition-all max-w-max">FAQ</a>
11082              </div>
11083            
11084              
11085              <div class="grid content-start">
11086                <p class="tag mt-5 mb-2 lg:mb-5 lg:mt-0">Orders</p>
11087                
11088                  
11089                    <a href="https://ui.awin.com/merchant-profile/89339" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Affiliates</a>
11090                  
11091                  
11092                
11093                  
11094                    <a href="/pages/shipping-policy" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Shipping Policy</a>
11095                  
11096                  
11097                
11098                  
11099                    <a href="/pages/return-and-refund-policy" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Return & Refund Policy</a>
11100                  
11101                  
11102                
11103                  
11104                    <a href="/pages/contact-us" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Contact Us</a>
11105                  
11106                  
11107                
11108                  
11109                    <a href="/pages/wholesale" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Wholesale</a>
11110                  
11111                  
11112                    <a href="/pages/partner-with-us-professionally" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Professional Partnerships</a>
11113                  
11114                
11115                  
11116                    <a href="https://revitin.com/account" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Account</a>
11117                  
11118                  
11119                
11120                <a href="/pages/review" class="text-brown my-1 lg:hover:underline transition-all max-w-max">Reviews</a>
11121                <a href="/pages/faqs" class="text-brown my-1 lg:hover:underline transition-all max-w-max">FAQ</a>
11122              </div>
11123            
11124          </div>
11125          
11126          <div class="flex flex-col order-1 lg:order-2">
11127            <newsletter-form
11128              data-list-id="RCUMMs"
11129              data-loading-text="Submitting..."
11130              data-success-text="">
11131              <div class="grid content-start order-1 lg:order-2">
11132                <span class="tag mb-2 lg:mb-5">Newsletter</span>
11133                <p class="text-brown">Receive special offers and first look at new products!</p>
11134                <div class="klaviyo-form-UR9w6e"></div>
11135                
11136                <p class="success hidden text-sm mt-2">Successfully subscribed.</p>
11137                <p class="error hidden text-sm mt-2">Oops! There was an error submitting. Please try again.</p>
11138              </div>
11139            </newsletter-form>
11140          </div>
11141        </div>
11142      </div>
11143    </div>
11144  </div>
11145  <div class="bg-light-tan site-container w-full py-6 lg:py-2 lg:grid lg:grid-cols-4 lg:gap-6 footer-wrapper">
11146    <div class="grid items-center lg:grid-flow-col lg:gap-8 lg:justify-start lg:col-span-2">
11147      <a href="/">
11148        <div class="w-[120px] lg:w-[140px] -ml-3.5 lg:-ml-4">
11149          <svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 504 232.3" style="enable-background:new 0 0 504 232.3" xml:space="preserve" fill="currentColor">
11150            <path d="M132.33 157.14c0 1.5-1.12 2.24-3.24 2.24h-10.72c-3.86 0-5.85-1.62-8.35-4.61l-30.78-36.14v30.28c0 5.36 6.23 4.36 6.23 8.47 0 1-.87 1.99-2.49 1.99H60.79c-1.62 0-2.49-1-2.49-1.99 0-3.61 6.36-2.99 6.36-8.47V82.36c0-5.36-6.36-4.36-6.36-8.47 0-1 1-1.99 2.49-1.99h29.79c24.42 0 35.89 9.22 35.89 23.68 0 11.84-8.35 21.44-32.28 22.93 3.12.87 5.24 2.37 7.23 4.49l20.81 23.93c5.74 6.47 10.1 6.47 10.1 10.21zm-53.09-44.37c2.37.37 5.11.5 7.6.5 16.07 0 23.68-5.86 23.68-17.07 0-11.46-6.6-18.32-23.43-18.32h-3.86c-2.62 0-3.99 1.37-3.99 3.61v31.28zM131.8 129.35c0-18.57 11.96-31.53 29.17-31.53 15.58 0 24.8 10.59 24.8 21.56 0 5.24-1.99 6.98-5.86 6.98h-35.64c.38 15.08 8.85 23.43 21.56 23.43 12.09 0 16.07-7.85 19.32-7.85 1.24 0 1.87 1.25.99 3.49-3.37 9.1-12.34 15.45-24.67 15.45-16.7 0-29.67-11.97-29.67-31.53zm37.02-8.85c2.37 0 3.62-1.12 3.62-3.37 0-6.98-3.37-13.58-12.46-13.58-8.6 0-14.83 5.86-15.57 16.95h24.41zM250.55 100.81c0 2.37-4.86 4.48-7.1 10.09l-19.19 46.36c-1.12 2.49-3.12 3.62-5.23 3.62-2.12 0-4.12-1.12-5.11-3.62l-19.07-46.23c-2.49-5.74-7.23-7.85-7.23-10.09 0-1 .75-1.62 2.12-1.62h22.56c1.24 0 1.87.63 1.87 1.5 0 2.37-5.36 3.74-5.36 7.98 0 1 .25 1.99.74 3.24l12.71 33.4 13.34-33.28c.5-1.37.74-2.37.74-3.49 0-3.99-4.86-5.86-4.86-7.98 0-.87.63-1.37 1.87-1.37h15.45c1.13-.01 1.75.62 1.75 1.49zM255.02 157.26c0-3.24 5.73-2.99 5.73-6.35v-36.27c0-4.49-6.85-3.24-6.85-6.85 0-1 .74-1.87 1.99-2.49l13.71-6.85c2.74-1.37 4.49-.38 4.49 2.24v50.22c0 3.36 5.6 3.11 5.6 6.35 0 1.12-1.12 2.12-2.62 2.12H257.5c-1.48 0-2.48-1-2.48-2.12zm1.37-77.51c0-5.11 4.24-9.35 9.48-9.35 5.11 0 9.34 4.24 9.34 9.35 0 5.24-4.23 9.47-9.34 9.47-5.24 0-9.48-4.24-9.48-9.47zM295.13 145.42v-37.39c0-2.24-1.24-3.49-3.49-3.49h-4.24c-3.24 0-4.24-2.74-1.62-4.86l18.44-15.08c2.12-1.87 4.24-1 4.24 1.87v12.84h18.7c1.49 0 2.24.75 2.24 2.12v1.74c0 1.37-.75 2.12-2.24 2.12h-18.7v40c0 5.49 2.37 7.6 7.98 7.6 5.11 0 7.85-1.37 9.47-1.37 1.12 0 1.62.62 1.62 1.49 0 3.49-8.6 7.85-17.57 7.85-9.34.02-14.83-4.6-14.83-15.44zM334.38 157.26c0-3.24 5.73-2.99 5.73-6.35v-36.27c0-4.49-6.85-3.24-6.85-6.85 0-1 .75-1.87 1.99-2.49l13.71-6.85c2.74-1.37 4.49-.38 4.49 2.24v50.22c0 3.36 5.61 3.11 5.61 6.35 0 1.12-1.12 2.12-2.62 2.12h-19.57c-1.49 0-2.49-1-2.49-2.12zm1.37-77.51c0-5.11 4.24-9.35 9.47-9.35 5.11 0 9.35 4.24 9.35 9.35 0 5.24-4.24 9.47-9.35 9.47a9.47 9.47 0 0 1-9.47-9.47zM432.44 157.26c0 1.12-.87 2.12-2.49 2.12h-19.57c-1.62 0-2.49-1-2.49-2.12 0-3.12 5.6-2.99 5.6-5.98v-30.91c0-9.59-2.99-12.96-10.71-12.96-4.49 0-9.6 1-15.58 3.74v40.13c0 2.74 5.61 2.87 5.61 5.98 0 1.12-.87 2.12-2.49 2.12h-19.69c-1.62 0-2.49-1-2.49-2.12 0-2.99 5.61-3.12 5.61-5.98v-36.51c0-4.61-6.73-3.62-6.73-6.85 0-.87.75-1.75 1.99-2.49l13.71-6.98c2.12-1.25 4.49-.62 4.49 2.24v5.36c7.85-4.98 17.45-8.22 24.93-8.22 9.97 0 14.7 5.73 14.7 16.08v37.39c-.01 2.72 5.6 2.97 5.6 5.96z"/>
11151            <path d="M447.66 76.53c.75.08 1.52.07 2.26.26.42.11.85.15 1.26.28.63.2 1.26.44 1.88.7.48.2.95.42 1.39.69.6.36 1.19.74 1.74 1.18.58.46 1.12.96 1.64 1.48.63.64 1.2 1.34 1.65 2.12.35.6.72 1.19 1.01 1.82.48 1.01.84 2.06 1.05 3.16.12.61.23 1.21.26 1.83.01.2.02.39.04.59.01.01.02.03.02.04v1.08c-.01.01-.02.03-.03.04-.02.88-.13 
111511.75-.32 2.61-.22.98-.53 1.92-.93 2.84-.45 1.03-1.01 1.99-1.71 2.87-.41.52-.84 1.04-1.3 1.51-.69.7-1.44 1.35-2.29 1.87-.6.37-1.21.74-1.84 1.05-.52.26-1.08.45-1.63.65-.45.16-.91.29-1.37.4-.4.1-.8.14-1.2.22-1.01.19-2.03.16-3.05.14-.42-.01-.84-.08-1.26-.15-.56-.09-1.12-.18-1.66-.34-.73-.22-1.45-.47-2.15-.77-.49-.21-.96-.49-1.42-.75-.39-.23-.78-.47-1.15-.72-.32-.22-.62-.46-.91-.72-.32-.28-.65-.56-.94-.87-.68-.7-1.31-1.44-1.84-2.26-.41-.63-.78-1.27-1.1-1.96-.34-.75-.66-1.51-.84-2.32-.16-.72-.31-1.43-.44-2.15-.04-.22-.03-.46-.05-.68l-.03-.48c0-.08 0-.15.01-.23v-.97c.06-.58.08-1.17.19-1.74.15-.78.33-1.55.57-2.31.2-.64.49-1.25.78-1.85.43-.9.98-1.72 1.59-2.51.5-.65 1.05-1.25 1.66-1.8.55-.49 1.15-.95 1.76-1.37.48-.33.99-.6 1.5-.89.63-.35 1.3-.63 1.99-.84.45-.14.9-.27 1.36-.37.57-.12 1.15-.22 1.73-.3.35-.05.7-.06 1.05-.08.08-.01.15-.01.23-.02h.63c.06.01.13.01.21.02zm12.37 14.07c-.01-.03-.02-.05-.02-.08 0-.16.01-.33-.01-.49-.06-.45-.13-.89-.23-1.33-.12-.53-.23-1.07-.41-1.58-.23-.63-.51-1.24-.8-1.84-.2-.42-.43-.83-.69-1.21-.35-.5-.75-.96-1.13-1.44-.48-.6-1.07-1.1-1.67-1.57-.67-.53-1.37-.99-2.15-1.34-.58-.27-1.17-.54-1.77-.74a12.57 12.57 0 0 0-3.44-.62c-.04-.01-.08-.02-.11-.03-.04 0-.08 0-.11.01h-.78c-.06.01-.13.01-.19.02-.18.01-.36.02-.53.04-.61.08-1.23.12-1.83.28-.76.2-1.5.46-2.23.75-.72.29-1.4.69-2.04 1.13-.88.61-1.68 1.31-2.39 2.11-.55.61-1.03 1.27-1.45 1.97-.5.82-.9 1.7-1.19 2.61-.33 1.01-.55 2.05-.59 3.1-.04.83-.01 1.66.07 2.49.06.64.23 1.28.39 1.91.32 1.21.85 2.33 1.51 3.38.42.67.89 1.3 1.45 1.87.46.46.93.93 1.43 1.34.71.58 1.48 1.09 2.32 1.47.58.26 1.17.53 1.78.73.65.21 1.32.35 2 .48.4.08.81.08 1.22.11.01 0 .03 0 .04-.01h1.38c.01 0 .03 0 .04.01.21-.01.43 0 .64-.04.62-.11 1.24-.24 1.85-.37.7-.15 1.36-.42 2.01-.71.72-.32 1.41-.7 2.06-1.15.76-.52 1.47-1.11 2.08-1.81.46-.53.93-1.07 1.33-1.66.36-.53.65-1.11.95-1.69.36-.7.61-1.44.8-2.19.21-.83.37-1.68.4-2.54.01-.03.01-.05.02-.08v-1.27c-.01 0-.01-.01-.01-.02zM432.4 90.6v.34c.01-.12 0-.23 0-.34z"/><path class="st0" d="M432.41 91.57c0 .08 0 .15-.01.23 0-.08.01-.16.01-.23zM446.8 76.51c-.08.01-.15.01-.23.02.08-.01.15-.01.23-.02zM447.66 76.53c-.08-.01-.15-.02-.23-.02.08.01.15.01.23.02zM461.86 90.67a.076.076 0 0 1-.02-.04c0 .02.01.03.02.04zM461.84 91.8c.01-.01.02-.03.03-.04-.02.01-.02.03-.03.04zM447.7 78.36h-.11v-.03c.03.01.07.02.11.03zM446.69 78.35c-.06.01-.13.01-.19.02.06-.01.12-.02.19-.02zM460.01 91.98v-.08h.02c-.01.03-.02.06-.02.08zM460 90.6c0-.03 0-.05.01-.08.01.03.02.05.02.08H460zM447.58 78.33v.03c-.04-.01-.08-.02-.12-.02.05 0 .08 0 .12-.01zM446.84 78.34h-.08.08zM460 90.6h.03v.04c-.01-.02-.02-.03-.03-.04z"/><path class="st0" d="M460.03 91.91h-.02c.01-.01.02-.03.03-.04-.01.01-.01.02-.01.04zM446.42 104.13c.01 0 .03 0 .04-.01-.01.01-.02.01-.04.01zM447.84 104.13c.01 0 .03 0 .04.01-.01-.01-.02-.01-.04-.01zM447.73 83.5c.03.01.07.03.1.03.8 0 1.57.12 2.31.41.85.33 1.59.82 2.09 1.62.35.56.56 1.16.62 1.81.04.45.07.91.03 1.35-.06.71-.25 1.39-.68 1.99-.53.77-1.24 1.29-2.09 1.66-.01 0-.02.02-.04.04.12.24.25.49.38.73l1.17 2.16c.52.97 1.05 1.94 1.57 2.91.12.21.23.43.34.65.01.03.01.07.01.11l-.03.03c-.95 0-1.89 0-2.84-.01-.01-.01-.02-.02-.03-.02-.19-.36-.38-.73-.58-1.09-.16-.31-.33-.61-.49-.91-.3-.57-.6-1.15-.89-1.72-.29-.55-.58-1.1-.86-1.65-.09-.17-.18-.35-.26-.52-.01-.01-.02-.02-.03-.02-.58 0-1.17-.01-1.75-.01-.4 0-.8.01-1.19.01l-.03.03v.14c0 .04-.01.
1115109-.01.13v5.36c0 .04.01.09.01.13 0 .05-.01.1-.01.15-.01.01-.02.02-.04.03h-2.61l-.03-.03c0-.06-.01-.12-.01-.19V83.72c0-.08-.07-.22.11-.22.06.01.11.02.17.02h5.34c.04 0 .07-.01.11-.01h.1c.01-.02.02-.02.04-.01zm-3.16 7.32.03.03h2.99c.16-.01.34.01.49-.04.35-.11.69-.24 1.02-.4.49-.23.78-.65.95-1.14.18-.5.19-1.02.12-1.54-.07-.5-.24-.95-.6-1.3-.53-.51-1.18-.7-1.9-.72-.01-.01-.03-.01-.04-.02-1.01 0-2.02 0-3.03-.01l-.03.03v.37c0 .07-.01.14-.01.2v4.12c0 .07.01.14.01.2v.22zM447.59 83.48c-.04 0-.07.01-.11.01h-5.34c-.06 0-.11-.01-.17-.02.06-.01.12-.02.18-.02h5.24c.07 0 .13.02.2.03z"/><path class="st0" d="M444.56 98.83c0-.04-.01-.09-.01-.13v-5.36c0-.04.01-.09.01-.13.01.06.03.12.03.18v5.26c0 .06-.02.12-.03.18zM444.57 93.07l.03-.03-.03.03zM447.54 93.05c.01.01.02.02.03.02-.01-.01-.02-.02-.03-.02zM447.73 83.5c-.01 0-.02-.01-.03-.01 0 0 .01 0 .03.01zM441.87 98.98l.03.03c-.01-.02-.02-.03-.03-.03zM444.51 99c.01-.01.02-.02.04-.03-.01.02-.02.03-.04.03zM450.66 98.97c.01.01.02.02.03.02-.01 0-.02-.01-.03-.02zM453.53 99l.03-.03-.03.03zM444.56 86.07c.01.05.03.11.03.16v4.21c0 .05-.02.11-.03.16 0-.07-.01-.14-.01-.2v-4.12c0-.07.01-.14.01-.21zM444.57 90.82l.03.03-.03-.03zM447.54 90.85h.04-.04zM447.66 85.7c-.01-.01-.03-.01-.04-.02.01 0 .03.01.04.02zM444.59 85.67l-.03.03c.02-.01.02-.02.03-.03z"/>
11152          </svg>
11153        </div>
11154      </a>
11155      
11156      <p class="text-brown opacity-50 text-sm">&copy; 2026, Revitin</p>
11157    </div>
11158    <div class="flex justify-start gap-6 mt-5 lg:mt-0 lg:items-center lg:col-span-2">
11159      <a data-acsb-custom-trigger="true" href="" class="text-brown lg:hover:underline">
11160        Accessibility
11161      </a>
11162      <a href="/pages/privacy-policy" class="text-brown lg:hover:underline">Privacy Policy</a>
11163      <a href="/pages/terms-of-use" class="text-brown lg:hover:underline">Terms of Service</a>
11164    </div>
11165  </div>
11166  <div class="w-full h-1.5 bg-olive rounded-lg"></div>
11167</footer>
11168
11169
11170<style>
11171  .grid.grid-cols-2 > div:nth-child(2) a:nth-last-child(-n+2) {
11172      display: none;
11173    }
11174
11175  .klaviyo-form-UR9w6e > div > form {
11176    max-width: none !important;
11177  }
11178
11179  .klaviyo-form-UR9w6e > div > form > div {
11180    min-height: 68px !important;
11181  }
11182
11183  .klaviyo-form-UR9w6e input[name="email"]{
11184    background-color: transparent !important;
11185    outline: none !important;
11186    border: none !important;
11187    font-size: 14px !important;
11188    color: #5f471d !important;
11189    height: 45px !important;
11190  }
11191
11192  .klaviyo-form-UR9w6e button[type="button"]{
11193    font-size: 14px !important;
11194    height: 45px !important;
11195    color: #5f471d !important;
11196    font-weight: 500;
11197    padding: 0px 26px !important;
11198    background: rgb(250, 223, 170) !important;
11199  }
11200
11201  .klaviyo-form-UR9w6e div[data-testid="form-row"] {
11202    border: 1px solid #5f471d;
11203    border-radius: 6px;
11204    position: relative;
11205    background: transparent !important;
11206    transition: border-color 0.2s ease-out;
11207  }
11208
11209  /* Hide the default placeholder */
11210  .klaviyo-form-UR9w6e input[name="email"]::placeholder {
11211    color: transparent !important;
11212  }
11213
11214  /* Style the label for floating effect */
11215  .klaviyo-form-UR9w6e .klaviyo-sr-only {
11216    position: absolute !important;
11217    left: 16px !important;
11218    top: 50% !important;
11219    transform: translateY(-50%) !important;
11220    width: auto !important;
11221    height: auto !important;
11222    clip: auto !important;
11223    white-space: nowrap !important;
11224    background: transparent !important;
11225    padding: 0 4px !important;
11226    font-size: 14px !important;
11227    color: #5f471d !important;
11228    opacity: 0.7 !important;
11229    transition: all 0.2s ease-out !important;
11230    pointer-events: none !important;
11231    z-index: 1 !important;
11232    line-height: 1 !important;
11233    margin: 0 !important;
11234    font-weight: normal !important;
11235  }
11236
11237  /* Move the label up on focus or when input has content */
11238  .klaviyo-form-UR9w6e div[data-testid="form-row"]:focus-within .klaviyo-sr-only,
11239  .klaviyo-form-UR9w6e input[name="email"]:not(:placeholder-shown) ~ .klaviyo-sr-only {
11240    top: 0 !important;
11241    transform: translateY(-50%) !important;
11242    font-size: 10px !important;
11243    opacity: 1 !important;
11244    background: #f7eede !important;
11245  }
11246
11247  /* Alternative approach using has-content detection */
11248  .klaviyo-form-UR9w6e input[name="email"]:focus + .klaviyo-sr-only,
11249  .klaviyo-form-UR9w6e input[name="email"]:not(:placeholder-shown) + .klaviyo-sr-only {
11250    top: 0 !important;
11251    transform: translateY(-50%) !important;
11252    font-size: 10px !important;
11253    opacity: 1 !important;
11254  }
11255
11256  .klaviyo-form-UR9w6e div[data-testid="form-row"]:focus-within {
11257    border-color: #8b6b3c;
11258  }
11259
11260  .klaviyo-form-UR9w6e div[data-testid="form-row"] > div[data-testid="form-component"] {
11261    margin: 0 !important;
11262    padding: 0  !important;
11263    background: transparent !important;
11264  }
11265
11266  .klaviyo-form-UR9w6e div[data-testid="form-row"] > :nth-child(2) {
11267    border-radius: 6px;
11268  }
11269
11270  /* Make sure the input container is transparent */
11271  .klaviyo-form-UR9w6e div[data-testid="form-component"] {
11272    background: transparent !important;
11273  }
11274
11275  /* Ensure the label stays transparent */
11276  .klaviyo-form-UR9w6e label {
11277    background: #f7eede !important;
11278  }
11279
11280  /* THANK YOU MESSAGE STYLES */
11281  
11282  /* Remove borders from form rows when they contain the thank you message */
11283  .klaviyo-form-UR9w6e div[data-testid="form-row"]:has(div[id*="rich-text"]) {
11284    border: none !important;
11285    padding: 0 !important;
11286    margin: 0 !important;
11287  }
11288
11289  /* Style the thank you heading */
11290  .klaviyo-form-UR9w6e div[id*="rich-text"] h1 {
11291    font-size: 28px !important;
11292    color: #8b6b3c !important;
11293    font-family: Nunito-Sans-Klaviyo-Hosted, Arial, 'Helvetica Neue', Helvetica, sans-serif !important;
11294    font-weight: bold !important;
11295    margin: 0 0 10px 0 !important;
11296    line-height: 1.2 !important;
11297    text-align: center !important;
11298  }
11299
11300  /* Style the thank you paragraph */
11301  .klaviyo-form-UR9w6e div[id*="rich-text"] p {
11302    font-size: 20px !important;
11303    color: #8b6b3c !important;
11304    font-family: Nunito-Sans-Klaviyo-Hosted, Arial, 'Helvetica Neue', Helvetica, sans-serif !important;
11305    font-weight: 400 !important;
11306    margin: 0 !important;
11307    line-height: 1.4 !important;
11308    text-align: center !important;
11309  }
11310
11311  /* Remove borders from the entire form when thank you message is present */
11312  .klaviyo-form-UR9w6e:has(div[id*="rich-text"]) div[data-testid="form-row"] {
11313    border: none !important;
11314  }
11315
11316  /* Target specific rich text containers */
11317  .klaviyo-form-UR9w6e div[id="rich-text-01KJ4FNR00PK140PYQ20F5ZABH"],
11318  .klaviyo-form-UR9w6e div[id="rich-text-01KJ4FNR07P6Q6AMF9BGB48XH8"] {
11319    padding: 0 !important;
11320    margin: 0 !important;
11321  }
11322
11323  /* Remove any background colors from thank you message */
11324  .klaviyo-form-UR9w6e div[id*="rich-text"] * {
11325    background: transparent !important;
11326    color: #8b6b3c !important;
11327  }
11328
11329  /* Adjust spacing for thank you message */
11330  .klaviyo-form-UR9w6e:has(div[id*="rich-text"]) {
11331    padding: 20px !important;
11332  }
11333
11334  /* Remove borders from form rows containing rich text */
11335  .klaviyo-form-UR9w6e div[data-testid="form-row"]:has(.go3176171171) {
11336    border: none !important;
11337  }
11338  @media (max-width: 1024px) {
11339    .footer-wrapper{
11340      padding-bottom: 100px;
11341    }
11342  }
11343</style>
11344
11345<script>
11346(function(){
11347  var s = document.createElement('script');
11348  var h = document.querySelector('head') || document.body;
11349  s.src = 'https://acsbapp.com/apps/app/dist/js/app.js';
11350  s.async = true;
11351  s.onload = function(){
11352    acsbJS.init({
11353      hideWidget: true 
11354    });
11355  };
11356  h.appendChild(s);
11357})();
11358</script>
11358
11359              
11360              
11361
11362
11363
11364</div>
11365      
11366    </main><site-cart>
11367  <div class="site-cart fixed w-full top-0 right-0 bottom-0 opacity-0 invisible z-[100] transition-all">
11368    <div class="bg-light-tan flyout__content absolute overflow-hidden w-full right-0 top-[6px] bottom-0 z-20 translate-x-[100%] transition-all duration-300 max-w-[500px] lg:shadow-md lg:rounded-l-xl">
11369      <div class="cart__container h-full grid grid-rows-[auto_1fr_auto]"><div id="shopify-section-main-cart-header" class="shopify-section"><div class="site-container">
11370  <div
11371    id="main-cart-header"
11372    class="relative flex justify-between items-center w-full bg-light-tan text-primary main-cart-header mt-5"
11373  >
11374    <div class="flex justify-between gap-3 items-center text-primary heading">
11375      <h3 class="text-xl lg:text-xl font-heading tracking-tight">Your Cart</h3>
11376    </div>
11377    <cart-toggle>
11378      <button
11379        id="close-menu"
11380        class="w-6 h-6 flex items-center justify-end bg-transparent border-0 cursor-pointer text-white lg:w-8 lg:h-8"
11381      ><svg
11382  class="w-4"
11383  width="20"
11384  height="20"
11385  viewBox="0 0 20 20"
11386  fill="none"
11387  xmlns="http://www.w3.org/2000/svg">
11388  <rect
11389    x="1.51471"
11390    y="0.100586"
11391    width="26"
11392    height="2"
11393    rx="1"
11394    transform="rotate(45 1.51471 0.100586)"
11395    fill="#5F471D" />
11396  <rect
11397    x="0.100525"
11398    y="18.4854"
11399    width="26"
11400    height="2"
11401    rx="1"
11402    transform="rotate(-45 0.100525 18.4854)"
11403    fill="#5F471D" />
11404</svg></button>
11405    </cart-toggle>
11406  </div>
11407</div>
11408
11409<style>
11410   .main-cart-header {
11411     padding: 12px 0 12px 0;
11412     border-bottom: 1px solid rgb(95 71 29 / 30%);
11413   }
11414  .max-w-\[500px\] {
11415      max-width: 500px;
11416  }
11417  .shipping-text {
11418    font-weight: bold;
11419    letter-spacing: 1.4px;
11420    margin-bottom: 7px;
11421    display: inline-block;
11422  }
11423
11424    .free-shipping-banner {
11425    background-color: #F7EEDE;
11426    padding: 16px 16px 2px 16px;
11427    border-radius: 4.66px;
11428    margin-top: 1rem;
11429    font-family: sans-serif;
11430    color: #5c4521;
11431    display: flex;
11432    gap: 1rem;
11433    justify-content: space-between;
11434  }
11435
11436  .icon-and-text {
11437    display: flex;
11438    align-items: center;
11439    gap: 10px;
11440    font-weight: 600;
11441    font-size: 15px;
11442    margin-bottom: 10px;
11443    width: max-content;
11444  }
11445
11446  .truck-icon {
11447    font-size: 20px;
11448  }
11449
11450  .progress-bar {
11451    position: relative;
11452    background-color: #f4e2bb;
11453    height: 6px;
11454    border-radius: 999px;
11455    margin-bottom: 8px;
11456  }
11457
11458  .progress-fill {
11459    background-color: #f6b439;
11460    height: 100%;
11461    width: 60%; /* Adjust this width based on cart amount */
11462  }
11463
11464  .progress-dot {
11465    position: absolute;
11466    top: 50%;
11467    left: 60%;
11468    transform: translate(-50%, -50%);
11469    width: 14px;
11470    height: 14px;
11471    background-color: #f6b439;
11472    border-radius: 50%;
11473  }
11474
11475  .shipping-status {
11476    text-align: right;
11477    font-size: 13px;
11478    color: #8c6f4e;
11479  }
11480
11481  @media screen and (max-width: 324px) {
11482    .subscription-options {
11483        padding: 0px 6px 0px 5px !important;
11484    }
11485  }
11486  
11487</style>
11488
11489
11490</div><div id="shopify-section-main-cart-items" class="shopify-section"><div id="main-cart-items" class="cart__items site-container"><div class="grid content-center justify-items-center mx-auto gap-6 py-14 bg-light-tan">
11491      <span class="heading-3">Your cart is empty</span>
11492      <a href="/products/revitin-natural-toothpaste" class="button button--gold"> Shop Revitin </a>
11493    </div><div style="display: none;" class="free_tote_loader">
11494    <div class="free_tote_spinner"></div>
11495  </div>
11496</div>
11497
11498<script>
11499  document.addEventListener('DOMContentLoaded', function () {
11500    // Use event delegation for better Shopify compatibility
11501    document.body.addEventListener('click', function (e) {
11502      // Check if click originated from subscription title or its children
11503      const titleElement = e.target.closest('.subscription-title');
11504      if (!titleElement) return;
11505
11506      e.preventDefault();
11507      e.stopPropagation();
11508
11509      const subscriptionBox = titleElement.closest('.cart-subscription-box');
11510      const options = subscriptionBox.querySelector('.subscription-options');
11511      const arrow = titleElement.querySelector('svg path');
11512      const subscribeSmallTitle = subscriptionBox.querySelector('.subscribe-save-header');
11513
11514      // Toggle the dropdown
11515      const isOpening = !options.classList.contains('active');
11516      options.classList.toggle('active');
11517
11518      // Update UI based on state
11519      if (isOpening) {
11520        arrow.setAttribute('transform', 'rotate(180 7.5 4)');
11521        subscribeSmallTitle.style.display = 'block';
11522        subscribeSmallTitle.style.marginTop = '10px';
11523        options.style.padding = '2px 12px 12px 19px';
11524      } else {
11525        arrow.removeAttribute('transform');
11526        subscribeSmallTitle.style.display = 'none';
11527        subscribeSmallTitle.style.marginTop = '0px';
11528        options.style.padding = '0px';
11529      }
11530    });
11531  });
11532
11533  const siteCart = document.querySelector('.site-cart');
11534
11535  const CART_SUBSCRIPTION_UPSELL_PROPERTY = '_cart_subscription_upsell';
11536  const CART_SUBSCRIPTION_UPSELL_ORIGINAL_VARIANT = '_cart_subscription_upsell_original_variant';
11537  const TUBE_PLAN_UPGRADED_PROPERTY = '_tube_plan_upgraded';
11538  const TUBE_PLAN_ORIGINAL_SELLING_PLAN = '_tube_plan_original_selling_plan';
11539  const TRAVEL_PLAN_UPGRADED_PROPERTY = '_travel_plan_upgraded';
11540
11541  function handleSubscriptionChange(e) {
11542    const button = e.target;
11543    if (!button) return;
11544    if (button.name !== 'selling_plan') return;
11545
11546    // Get the subscription container
11547    const subscriptionContainer = button.closest('.subscription-container');
11548    if (!subscriptionContainer) return;
11549
11550    // Disable all inputs in the container
11551    const allInputs = subscriptionContainer.querySelectorAll('input');
11552    allInputs.forEach((input) => (input.disabled = true));
11553
11554    // Add skeleton loading class
11555    subscriptionContainer.classList.add('loading');
11556
11557    const radio = button;
11558    const itemKey = radio.dataset.key;
11559    const variantId = radio.dataset.variantId;
11560    const quantity = radio.dataset.quantity;
11561    const sellingPlanId = radio.dataset.sellingPlanId;
11562
11563    // Preserve GWP marker (and related props) across selling-plan swaps
11564    fetch('/cart.js')
11565      .then((r) => r.json())
11566      .then((cart) => {
11567        const existing = (cart.items || []).find((item) => item.key === itemKey);
11568        const nextProperties = {
11569          [CART_SUBSCRIPTION_UPSELL_PROPERTY]: 'true',
11570        };
11571        if (existing && existing.properties) {
11572          if (existing.properties._gwp === 'back_to_school_minis') {
11573            nextProperties._gwp = existing.properties._gwp;
11574            nextProperties._gwp_source = existing.properties._gwp_source || 'pdp';
11575          }
11576          if (existing.properties[CART_SUBSCRIPTION_UPSELL_ORIGINAL_VARIANT]) {
11577            nextProperties[CART_SUBSCRIPTION_UPSELL_ORIGINAL_VARIANT] =
11578              existing.properties[CART_SUBSCRIPTION_UPSELL_ORIGINAL_VARIANT];
11579          }
11580        }
11581        // Cart → subscription: stamp GWP if cart has no marker yet (blocked templates / wholesale skipped)
11582        const gwpAllowed =
11583          window.RevitinGWP &&
11584          window.RevitinGWP.enabled !== false &&
11585          typeof window.RevitinGWP.getPdpGwpProperties === 'function';
11586        if (gwpAllowed && !nextProperties._gwp) {
11587          const gwpProps = window.RevitinGWP.getPdpGwpProperties(cart);
11588          if (gwpProps) {
11589            Object.assign(nextProperties, gwpProps, { _gwp_source: 'cart' });
11590          }
11591        }
11592
11593        return fetch('/cart/update.js', {
11594          method: 'POST',
11595          headers: {
11596            'Content-Type': 'application/json',
11597          },
11598          body: JSON.stringify({
11599            updates: {
11600              [itemKey]: 0,
11601            },
11602          }),
11603        }).then(() => nextProperties);
11604      })
11605      .then((nextProperties) => {
11606        // Then add the new item with updated subscription
11607        return fetch('/cart/add.js', {
11608          method: 'POST',
11609          headers: {
11610            'Content-Type': 'application/json',
11611          },
11612          body: JSON.stringify({
11613            items: [
11614              {
11615                id: variantId,
11616                quantity: quantity,
11617                selling_plan: sellingPlanId,
11618                properties: nextProperties,
11619              },
11620            ],
11621          }),
11622        });
11623      })
11624      .then((response) => response.json())
11625      .then((cart) => {
11626        updateCartUI(cart);
11627        showToast('Subscription updated successfully!');
11628      })
11629      .catch((error) => {
11630        console.error('Error:', error);
11631        showToast('Error updating subscription', true);
11632      })
11633      .finally(() => {
11634        // Re-enable inputs and remove loading state
11635        allInputs.forEach((input) => (input.disabled = false));
11636        subscriptionContainer.classList.remove('loading');
11637      });
11638  }
11639
11640  function handleSwitchToOneTime(e) {
11641    const radio = e.target.closest('.switch-one-time-label').querySelector('.switch-one-time-input');
11642    if (!radio) return;
11643
11644    const subscriptionContainer = radio.closest('.subscription-container');
11645    const allInputs = subscriptionContainer ? subscriptionContainer.querySelectorAll('input') : [];
11646    allInputs.forEach((input) => (input.disabled = true));
11647    if (subscriptionContainer) subscriptionContainer.classList.add('loading');
11648
11649    const itemKey = radio.dataset.key;
11650    const variantId = radio.dataset.variantId;
11651    const quantity = radio.dataset.quantity;
11652    const sellingPlanId = radio.dataset.sellingPlanId;
11653
11654    if (sellingPlanId) {
11655      fetch('/cart/add.js', {
11656        method: 'POST',
11657        headers: {
11658          'Content-Type': 'application/json',
11659          Accept: 'application/json',
11660        },
11661        body: JSON.stringify({
11662          items: [
11663            {
11664              id: parseInt(variantId, 10),
11665              quantity: parseInt(quantity, 10) || 1,
11666              selling_plan: parseInt(sellingPlanId, 10),
11667            },
11668          ],
11669        }),
11670      })
11671        .then(async (response) => {
11672          const addResult = await response.json();
11673          if (response.status === 422) {
11674            throw new Error(addResult.description);
11675          }
11676          return fetch('/cart/update.js', {
11677            method: 'POST',
11678            headers: {
11679              'Content-Type': 'application/json',
11680            },
11681            body: JSON.stringify({
11682              updates: {
11683                [itemKey]: 0,
11684              },
11685            }),
11686          });
11687        })
11688        .then((response) => response.json())
11689        .then((cart) => {
11690          updateCartUI(cart);
11691          showToast('Subscription updated successfully!');
11692        })
11693        .catch((error) => {
11694          console.error('Error:', error);
11695          showToast('Error updating subscription', true);
11696        })
11697        .finally(() => {
11698          allInputs.forEach((input) => (input.disabled = false));
11699          if (subscriptionContainer) subscriptionContainer.classList.remove('loading');
11700        });
11701      return;
11702    }
11703
11704    // Remove the existing subscription item, then re-add it as a one-time purchase (no selling_plan)
11705    fetch('/cart/update.js', {
11706      method: 'POST',
11707      headers: {
11708        'Content-Type': 'application/json',
11709      },
11710      body: JSON.stringify({
11711        updates: {
11712          [itemKey]: 0,
11713        },
11714      }),
11715    })
11716      .then(() => {
11717        return fetch('/cart/add.js', {
11718          method: 'POST',
11719          headers: {
11720            'Content-Type': 'application/json',
11721          },
11722          body: JSON.stringify({
11723            items: [
11724              {
11725                id: variantId,
11726                quantity: quantity,
11727              },
11728            ],
11729          }),
11730        });
11731      })
11732      .then((response) => response.json())
11733      .then((cart) => {
11734        updateCartUI(cart);
11735        showToast('Switched to one time purchase!');
11736      })
11737      .catch((error) => {
11738        console.error('Error:', error);
11739        showToast('Error switching to one time purchase', true);
11740      })
11741      .finally(() => {
11742        allInputs.forEach((input) => (input.disabled = false));
11743        if (subscriptionContainer) subscriptionContainer.classList.remove('loading');
11744      });
11745  }
11746 function syncCartFlyoutLayout() {
11747    const footer = document.querySelector('#shopify-section-main-cart-footer');
11748    const cartContainer = document.querySelector('.cart__container');
11749    if (!footer || !cartContainer) return;
11750
11751    const height = footer.offsetHeight + 10;
11752    cartContainer.style.paddingBottom = `${height}px`;
11753
11754    // Ensure the items column can shrink inside the grid so overflow scrolls
11755    const itemsSection = document.querySelector('#shopify-section-main-cart-items');
11756    if (itemsSection) {
11757      itemsSection.style.minHeight = '0';
11758    }
11759  }
11760  function updateCartUI(cart) {
11761    // Update cart count in header
11762    const cartCountElements = document.querySelectorAll('.cart-count, .js-cart-count');
11763    if (cartCountElements) {
11764      cartCountElements.forEach((el) => {
11765        el.textContent = cart.item_count;
11766        el.classList.remove('hidden');
11767      });
11768    }
11769
11770    // Update both cart items AND cart footer sections
11771    Promise.all([
11772      fetch('/?section_id=main-cart-items').then((r) => r.text()),
11773      fetch('/?section_id=main-cart-footer').then((r) => r.text()),
11774    ]).then(([itemsHtml, footerHtml]) => {
11775      // Parse responses
11776      const itemsDoc = new DOMParser().parseFromString(itemsHtml, 'text/html');
11777      const footerDoc = new DOMParser().parseFromString(footerHtml, 'text/html');
11778
11779      // Update cart items
11780      const newItemsContent = itemsDoc.getElementById('main-cart-items');
11781      if (newItemsContent) {
11782        document.getElementById('main-cart-items').innerHTML = newItemsContent.innerHTML;
11783      }
11784
11785      // Update cart footer (including subtotal)
11786      const newFooterContent = footerDoc.getElementById('main-cart-footer');
11787      if (newFooterContent) {
11788        document.getElementById('main-cart-footer').innerHTML = newFooterContent.innerHTML;
11789      }
11790      // Recalc space above absolute footer so upsells aren't clipped after first add
11791      requestAnimationFrame(() => {
11792        syncCartFlyoutLayout();
11793        requestAnimationFrame(syncCartFlyoutLayout);
11794      });
11795    });
11796  }
11797  window.updateCartUI = updateCartUI;
11798  window.syncCartFlyoutLayout = syncCartFlyoutLayout;
11799
11800  function updateCartSummary() {
11801    fetch('/?section_id=cart-drawer')
11802      .then((response) => response.text())
11803      .then((text) => {
11804        const html = new DOMParser().parseFromString(text, 'text/html');
11805        const cartDrawer = document.getElementById('cart-drawer');
11806
11807        if (cartDrawer) {
11808          cartDrawer.innerHTML = html.getElementById('cart-drawer').innerHTML;
11809        }
11810      });
11811  }
11812
11813  function showToast(message, isError = false) {
11814    const toast = document.createElement('div');
11815    toast.className = `fixed bottom-4 right-4 px-4 py-2 rounded shadow-lg ${
11816      isError ? 'bg-red-500' : 'bg-sea-green'
11817    } text-white`;
11818    toast.textContent = message;
11819    document.body.appendChild(toast);
11820
11821    setTimeout(() => {
11822      toast.style.opacity = '0';
11823      setTimeout(() => toast.remove(), 300);
11824    }, 3000);
11825  }
11826
11827  function formatShopifyPrice(priceInCents) {
11828    const price = priceInCents / 100;
11829    const formatted = price.toFixed(2);
11830    return formatted.endsWith('.00') ? price.toFixed(0) : formatted;
11831  }
11832
11833  // Event delegation for subscribe buttons
11834  document.getElementById('main-cart-items').addEventListener('click', async (e) => {
11835    const button = e.target.closest('.subscribe-btn-js');
11836    if (!button) return;
11837
11838    const originalText = button.textContent;
11839    button.disabled = true;
11840    button.textContent = 'Subscribing...';
11841
11842    const variantId = button.dataset.variantId;
11843    const quantity = button.dataset.quantity;
11844    const sellingPlanId = button.dataset.sellingPlan;
11845    const originalItemKey = button.dataset.key;
11846    const originalVariantId = button.dataset.originalVariantId;
11847    const originalSellingPlanId = button.dataset.originalSellingPlan;
11848    const isTubePlanSwitch = button.dataset.tubePlanSwitch === 'true';
11849    const isTravelPlanSwitch = button.dataset.travelPlanSwitch === 'true';
11850
11851    if (!variantId || !sellingPlanId) {
11852      console.error('Missing variant or selling plan for subscription upsell');
11853      button.disabled = false;
11854      button.textContent = originalText;
11855      return;
11856    }
11857
11858    try {
11859      // First add the subscription item
11860      const addItem = {
11861        id: parseInt(variantId, 10),
11862        quantity: parseInt(quantity, 10) || 1,
11863        selling_plan: parseInt(sellingPlanId, 10),
11864      };
11865      if (isTubePlanSwitch) {
11866        addItem.properties = {
11867          [TUBE_PLAN_UPGRADED_PROPERTY]: 'true',
11868        };
11869        // Remember original 3-tube plan so Switch to 3-tubes restores that interval
11870        if (originalSellingPlanId) {
11871          addItem.properties[TUBE_PLAN_ORIGINAL_SELLING_PLAN] = String(originalSellingPlanId);
11872        }
11873      } else if (isTravelPlanSwitch) {
11874        addItem.properties = {
11875          [TRAVEL_PLAN_UPGRADED_PROPERTY]: 'true',
11876        };
11877      } else {
11878        addItem.properties = {
11879          [CART_SUBSCRIPTION_UPSELL_PROPERTY]: 'true',
11880        };
11881        // Single Tube upsells to 3 Tubes — remember original so OTP can revert
11882        if (originalVariantId) {
11883          addItem.properties[CART_SUBSCRIPTION_UPSELL_ORIGINAL_VARIANT] = String(originalVariantId);
11884        }
11885      }
11886
11887      // Stamp GWP on cart subscription upsell when allowed and not already marked
11888      try {
11889        if (
11890          window.RevitinGWP &&
11891          window.RevitinGWP.enabled !== false &&
11892          typeof window.RevitinGWP.getPdpGwpProperties === 'function'
11893        ) {
11894          const cartBefore = await fetch('/cart.js').then((r) => r.json());
11895          const gwpProps = window.RevitinGWP.getPdpGwpProperties(cartBefore);
11896          if (gwpProps) {
11897            addItem.properties = Object.assign({}, addItem.properties || {}, gwpProps, {
11898              _gwp_source: 'cart',
11899            });
11900          }
11901        }
11902      } catch (_) {}
11903
11904      const addResponse = await fetch('/cart/add.js', {
11905        method: 'POST',
11906        headers: {
11907          'Content-Type': 'application/json',
11908          Accept: 'application/json',
11909        },
11910        body: JSON.stringify({
11911          items: [addItem],
11912        }),
11913      });
11914
11915      const addResult = await addResponse.json();
11916      if (addResponse.status === 422) {
11917        throw new Error(addResult.description);
11918      }
11919
11920      // Then remove the original non-subscription item
11921      const updateResponse = await fetch('/cart/update.js', {
11922        method: 'POST',
11923        headers: {
11924          'Content-Type': 'application/json',
11925          Accept: 'application/json',
11926        },
11927        body: JSON.stringify({
11928          updates: {
11929            [originalItemKey]: 0,
11930          },
11931        }),
11932      });
11933
11934      const updateResult = await updateResponse.json();
11935      updateCartUI(updateResult);
11936      showToast('Subscription updated successfully!');
11937    } catch (error) {
11938      console.error('Error:', error);
11939      const errorElement = document.createElement('div');
11940      errorElement.className = 'text-red-500 text-xs mt-1';
11941      errorElement.textContent = 'Error adding subscription. Please try again.';
11942      button.parentNode.appendChild(errorElement);
11943      setTimeout(() => errorElement.remove(), 3000);
11944    } finally {
11945      button.disabled = false;
11946      button.textContent = originalText;
11947    }
11948  });
11949
11950  function addToCartHandler(e) {
11951    e.preventDefault();
11952    e.stopPropagation();
11953    e.stopImmediatePropagation();
11954
11955    const button = e.target.closest('.add-to-cart-btn') || e.target;
11956    const variantId = button.dataset.variantId;
11957    const sellingPlanId = button.dataset.sellingPlan;
11958    const isUpsell = button.dataset.upsell === 'true' || !!button.closest('.you-may-also-like');
11959
11960    button.disabled = true;
11961    const originalText = button.textContent;
11962    button.textContent = 'Adding...';
11963
11964    const itemData = {
11965      id: variantId,
11966      quantity: 1,
11967    };
11968
11969    if (sellingPlanId) {
11970      itemData.selling_plan = sellingPlanId;
11971    }
11972
11973    if (isUpsell) {
11974      itemData.properties = {
11975        '_upsell-product': 'true',
11976      };
11977      if (button.dataset.subscriptionUpsell === 'true') {
11978        itemData.properties[CART_SUBSCRIPTION_UPSELL_PROPERTY] = 'true';
11979      }
11980    }
11981
11982    fetch('/cart/add.js', {
11983      method: 'POST',
11984      headers: {
11985        'Content-Type': 'application/json',
11986      },
11987      body: JSON.stringify({
11988        items: [itemData],
11989      }),
11990    })
11991      .then((response) => response.json())
11992      .then((data) => {
11993        if (data.description) throw new Error(data.description);
11994        showToast('Item added to cart!');
11995        updateCartUI(data);
11996      })
11997      .catch((error) => {
11998        console.error('Error:', error);
11999        showToast('Error adding item to cart', true);
12000      })
12001      .finally(() => {
12002        button.disabled = false;
12003        button.textContent = originalText;
12004      });
12005  }
12006
12007  // Initialize on DOM load
12008  document.addEventListener('DOMContentLoaded', function () {
12009    syncCartFlyoutLayout();
12010    // Set up event delegation for any dynamically added add-to-cart buttons
12011    document.body.addEventListener('click', function (e) {
12012      if (e.target.closest('.add-to-cart-btn')) {
12013        addToCartHandler(e);
12014      }
12015
12016      if (e.target.closest('.option-label')) {
12017        handleSubscriptionChange(e);
12018      }
12019
12020      if (e.target.closest('.switch-one-time-label')) {
12021        handleSwitchToOneTime(e);
12022      }
12023    });
12024  });
12025  // Keep layout in sync when cart opens (empty → first item is the common failure case)
12026  document.addEventListener('click', function (e) {
12027    if (e.target.closest('cart-toggle') || e.target.closest('.site-cart')) {
12028      requestAnimationFrame(syncCartFlyoutLayout);
12029    }
12030  });
12031</script>
12031
12032
12033<script>
12034  const TOTE_HANDLE = 'free-tote';
12035  const freeProductLoader = document.querySelector(`.free_tote_loader`);
12036
12037  // --- CORE HELPERS (unchanged for stability) ---
12038  const fetchJSON = (url, options = {}) =>
12039    fetch(url, {
12040      credentials: 'same-origin',
12041      headers: { 'Content-Type': 'application/json' },
12042      ...options,
12043    }).then((res) => res.json());
12044  const getCart = () => fetchJSON('/cart.js');
12045  const isSubscriptionItem = (item) => item.selling_plan_allocation != null;
12046  const isToteItem = (item) => item.handle === TOTE_HANDLE || item.product_handle === TOTE_HANDLE;
12047
12048  let toteVariantId = null;
12049  async function getToteVariantId() {
12050    if (toteVariantId) return toteVariantId;
12051    const product = await fetchJSON(`/products/${TOTE_HANDLE}.js`);
12052    toteVariantId = product?.variants?.[0]?.id || null;
12053    return toteVariantId;
12054  }
12055
12056  // --- OPTIMIZED CART LOGIC ---
12057  let isProcessing = false;
12058  let lastCartState = null;
12059
12060  function updateUi(count, handle, action) {
12061    const cartCount = document.querySelector('.variety-cart-count');
12062    const freeCartItem = document.querySelector(`.cart-item[data-handle=${handle}]`);
12063
12064    if (freeCartItem && action) {
12065      if (action === 'add') {
12066        freeCartItem.style.display = 'block';
12067      }
12068
12069      if (action === 'remove') {
12070        freeCartItem.style.display = 'none';
12071      }
12072    }
12073    cartCount.textContent = count ? count : 0;
12074  }
12075
12076  async function enforceToteRule() {
12077    // Prevent multiple simultaneous runs
12078    if (isProcessing) return;
12079    isProcessing = true;
12080
12081    console.log('EnforeRule Start');
12082
12083    try {
12084      const cart = await getCart();
12085      const cartStateKey = JSON.stringify(cart.items.map((i) => ({ id: i.id, q: i.quantity })));
12086
12087      // Skip if cart state hasn't changed
12088      if (lastCartState === cartStateKey) {
12089        isProcessing = false;
12090        return;
12091      }
12092      lastCartState = cartStateKey;
12093
12094      const hasSubscription = cart.items.some(isSubscriptionItem);
12095      const toteItems = cart.items.filter(isToteItem);
12096      const hasTote = toteItems.length > 0;
12097      const toteNeedsNormalize = hasTote && (toteItems.length > 1 || toteItems[0].quantity > 1);
12098
12099      let action = null;
12100      if (hasSubscription && !hasTote) action = 'add';
12101      else if (hasSubscription && toteNeedsNormalize) action = 'normalize';
12102      else if (!hasSubscription && hasTote) action = 'remove';
12103
12104      function whenElementReady(selector, callback, timeout = 5000) {
12105        const start = Date.now();
12106
12107        (function check() {
12108          const el = document.querySelector(selector);
12109          if (el) {
12110            callback(el);
12111            return;
12112          }
12113          if (Date.now() - start < timeout) {
12114            requestAnimationFrame(check);
12115          }
12116        })();
12117      }
12118
12119      function applyFreeProductStyle(action) {
12120        if (action !== 'add') return;
12121
12122        whenElementReady('.free_tote_loader', function (loader) {
12123          loader.setAttribute(
12124            'style',
12125            'display: flex; align-items: center; justify-content: center; margin-top: 12px;'
12126          );
12127        });
12128      }
12129
12130      if (action === 'add' && freeProductLoader) {
12131        applyFreeProductStyle('add');
12132      }
12133
12134      updateUi(cart.item_count, TOTE_HANDLE, action);
12135
12136      if (action) {
12137        switch (action) {
12138          case 'add':
12139            const variantId = await getToteVariantId();
12140            if (variantId)
12141              await fetchJSON('/cart/add.js', {
12142                method: 'POST',
12143                body: JSON.stringify({ items: [{ id: variantId, quantity: 1 }] }),
12144              });
12145            break;
12146          case 'remove':
12147            const toteItem = toteItems[0];
12148            await fetchJSON('/cart/update.js', {
12149              method: 'POST',
12150              body: JSON.stringify({ updates: { [toteItem.key]: 0 } }),
12151            });
12152            break;
12153          case 'normalize':
12154            const normItem = toteItems[0];
12155            await fetchJSON('/cart/update.js', {
12156              method: 'POST',
12157              body: JSON.stringify({ updates: { [normItem.key]: 1 } }),
12158            });
12159            break;
12160        }
12161        // Update UI immediately after cart change
12162        freeProductLoader.style.display = 'none';
12163        triggerCartRefresh();
12164      }
12165    } catch (error) {
12166      console.error('Tote rule error:', error);
12167    } finally {
12168      isProcessing = false;
12169    }
12170  }
12171
12172  function triggerCartRefresh() {
12173    getCart().then((cart) => {
12174      if (window.updateCartUI) window.updateCartUI(cart);
12175      if (window.updateCartSummary) window.updateCartSummary();
12176    });
12177  }
12178
12179  // --- OPTIMIZED EVENT MONITORING ---
12180  
12181</script>
12181
12182
12183<style>
12184  /* .cart__items:has(.subscription-container:not(.hidden)) .you-may-also-like {
12185        display: none;
12186      } */
12187
12188  .free_tote_badge {
12189    padding: 3px 10px;
12190    font-size: 14px;
12191    background: #fadfaa;
12192    border-radius: 5px;
12193    height: max-content;
12194  }
12195
12196  .delete-icon {
12197    max-width: 18cm;
12198  }
12199
12200  .subscription-container.loading {
12201    position: relative;
12202    pointer-events: none;
12203    opacity: 0.7;
12204  }
12205
12206  .subscription-container.loading::after {
12207    content: '';
12208    position: absolute;
12209    top: 0;
12210    left: 0;
12211    right: 0;
12212    bottom: 0;
12213    background: linear-gradient(90deg, #f6e8cf 25%, #f7eede 50%, #f7eede 75%);
12214    background-size: 200% 100%;
12215    animation: shimmer 1.5s infinite;
12216    border-radius: 4px;
12217    z-index: 10;
12218  }
12219
12220  @keyframes shimmer {
12221    0% {
12222      background-position: 200% 0;
12223    }
12224    100% {
12225      background-position: -200% 0;
12226    }
12227  }
12228
12229  .rc-form {
12230    width: 100%;
12231    display: flex;
12232    justify-content: end;
12233    align-items: end;
12234  }
12235
12236  .rc-form .rc-container-wrapper {
12237    display: none;
12238  }
12239
12240  .alt-product-container {
12241    border-radius: 4px;
12242  }
12243
12244  .you-may-also-like {
12245    padding-top: 12px;
12246    background: #fffbef;
12247  }
12248
12249  .you-may-also-like__heading {
12250    font-size: 14px;
12251    margin-bottom: 8px;
12252    color: #5f471d;
12253  }
12254
12255  .you-may-also-like__cards {
12256    display: flex;
12257    flex-direction: column;
12258    gap: 12px;
12259  }
12260
12261  .cart-upsell-card {
12262    position: relative;
12263    border-radius: 8px;
12264    padding: 15px 14px 14px;
12265    overflow: hidden;
12266  }
12267
12268  .cart-upsell-badge {
12269    
12270    
12271    
12272    z-index: 2;
12273    display: inline-flex;
12274    align-items: center;
12275    gap: 4px;
12276    padding: 6px 10px;
12277    border-radius: 999px;
12278    font-size: 11px;
12279    line-height: 1;
12280    font-weight: 500;
12281    color: #fff;
12282    margin-bottom: 10px;
12283  }
12284
12285  .cart-upsell-badge--citrus {
12286    background: #fbaa4a;
12287  }
12288
12289  .cart-upsell-badge--mint {
12290    background: #7e8f72;
12291  }
12292
12293  .cart-upsell-badge--variety {
12294    background: linear-gradient(to right, #ffdea3, #ffdea3, #e6ecd3, #e6ecd3);
12295    color: #5f471d !important;
12296  }
12297
12298  .cart-upsell-badge--variety .cart-upsell-badge__icon {
12299    color: #5f471d;
12300  }
12301  .cart-upsell-badge__icon {
12302    flex-shrink: 0;
12303    color: #fff;
12304  }
12305
12306  .cart-upsell-card__body {
12307    display: grid;
12308    grid-template-columns: 72px 1fr;
12309    gap: 12px;
12310    align-items: start;
12311  }
12312
12313  .cart-upsell-card__image {
12314    display: flex;
12315    align-items: center;
12316    justify-content: center;
12317    min-height: 72px;
12318  }
12319
12320  .cart-upsell-card__image img {
12321    width: 100%;
12322    max-height: 72px;
12323    object-fit: contain;
12324  }
12325
12326  .cart-upsell-card__content {
12327    display: flex;
12328    flex-direction: column;
12329    gap: 4px;
12330    min-width: 0;
12331  }
12332
12333  .cart-upsell-card__header {
12334    display: flex;
12335    justify-content: space-between;
12336    align-items: flex-start;
12337    gap: 10px;
12338  }
12339
12340  .cart-upsell-card__title {
12341    font-size: 15px;
12342    line-height: 1.25;
12343    margin: 0;
12344    color: #5f471d;
12345  }
12346
12347  .cart-upsell-card__title a {
12348    color: inherit;
12349    text-decoration: none;
12350  }
12351
12352  .cart-upsell-card__price {
12353    display: flex;
12354    align-items: center;
12355    gap: 6px;
12356    flex-shrink: 0;
12357    font-size: 15px;
12358    color: #5f471d;
12359    white-space: nowrap;
12360  }
12361
12362  .cart-upsell-card__compare {
12363    font-size: 14px;
12364  }
12365
12366  .cart-upsell-card__flavor {
12367    margin: 0;
12368    font-size: 13px;
12369    line-height: 1.35;
12370    color: #5f471d;
12371  }
12372
12373  .cart-upsell-card__description {
12374    margin: 2px 0 0;
12375    font-size: 12px;
12376    line-height: 1.4;
12377    color: #5f471d;
12378    opacity: 0.85;
12379  }
12380
12381  .cart-upsell-card__footer {
12382    display: flex;
12383    justify-content: flex-end;
12384    margin-top: 6px;
12385  }
12386  .cart-upsell-card__footer button {
12387    width: 180px;
12388    transition: all ease 0.2s;
12389    background: rgba(244, 220, 179, 0);
12390    border: 1px solid rgb(95 71 29);
12391  }
12392  .cart-upsell-card__footer button:hover {
12393    background: #ffdea3;
12394    border: 1px solid #ffdea3;
12395  }
12396  .cart-upsell-card__add {
12397    padding: 7px 28px;
12398    border-radius: 10px;
12399    width: 180px;
12400  }
12401
12402  .you-may-also-like h3 {
12403    font-size: 14px;
12404    margin-bottom: 6px;
12405  }
12406
12407  .add-to-cart-btn {
12408    padding: 7px 34px;
12409    border-radius: 0.5em;
12410    margin-left: auto;
12411  }
12412
12413  .product_ad_flavour {
12414    font-size: 14px;
12415  }
12416
12417  .subscribe_save {
12418    margin-top: 1.3rem;
12419    border-radius: 0.5em;
12420    text-align: center;
12421    padding: 12px 0px;
12422    cursor: pointer;
12423    width: 100%;
12424    background: rgba(244, 220, 179, 0);
12425    border: 1px solid rgb(95 71 29);
12426    transition: all ease 0.2s;
12427  }
12428
12429  .subscribe_save:hover {
12430    border: none;
12431    background: #ffdea3;
12432    border: 1px solid #ffdea3;
12433    transition: all ease 0.2s;
12434  }
12435
12436  .cart-item {
12437    padding: 11px 0px 20px 0px;
12438  }
12439
12440  .product-card {
12441    display: flex;
12442    gap: 4px;
12443    width: 100%;
12444    border-radius: 5px;
12445  }
12446
12447  .product-image {
12448    width: 6rem;
12449    display: flex;
12450    justify-content: center;
12451    align-items: center;
12452    max-height: 5.5rem;
12453  }
12454
12455  .product-details-main {
12456    display: flex;
12457    justify-content: space-between;
12458  }
12459
12460  .product-details {
12461    width: 100%;
12462  }
12463
12464  div#shopify-section-main-cart-items {
12465    height: 100%;
12466    min-height: 0;
12467    overflow: auto;
12468    -webkit-overflow-scrolling: touch;
12469  }
12470  .cart__container {
12471    min-height: 0;
12472  }
12473
12474  .cart__container > #shopify-section-main-cart-items,
12475  .cart__container .cart__items-wrapper {
12476    min-height: 0;
12477  }
12478
12479  /* Let the section be the single scroll container so first-add height is reliable */
12480  #main-cart-items > .cart__items.overflow-y-scroll {
12481    overflow-y: visible;
12482  }
12483
12484  .free_tote_spinner {
12485    width: 40px;
12486    height: 40px;
12487    border: 4px solid rgba(255, 222, 163, 0.35); /* light ring */
12488    border-top-color: #ffdea3; /* theme color */
12489    border-radius: 50%;
12490    animation: spin 0.9s linear infinite;
12491  }
12492  .subscribe-upsell-card {
12493    padding: 12px;
12494    background: #f7eede;
12495    border-radius: 5px;
12496    margin-top: 20px;
12497  }
12498  .subscribe-upsell-title {
12499    font-weight: 500;
12500    font-size: 14px;
12501    line-height: 20px;
12502    letter-spacing: 0;
12503  }
12504  .subscribe-upsell-list {
12505    margin-top: 10px;
12506  }
12507  .subscribe-upsell-list li {
12508    list-style: disc;
12509    margin-left: 25px;
12510    font-weight: 400;
12511    font-size: 14px;
12512    line-height: 19.25px;
12513    letter-spacing: 0;
12514  }
12515  .subscription-delivery-text {
12516    font-weight: 400;
12517    font-size: 12px;
12518    line-height: 16.5px;
12519    letter-spacing: 0;
12520    margin-bottom: 5px;
12521  }
12522  .switch-one-time-label {
12523    font-weight: 400;
12524    font-size: 12px;
12525    line-height: 16.5px;
12526    letter-spacing: 0;
12527    text-decoration: underline;
12528    text-decoration-style: solid;
12529    text-decoration-offset: 0%;
12530    text-decoration-thickness: 0%;
12531  }
12532  @keyframes spin {
12533    to {
12534      transform: rotate(360deg);
12535    }
12536  }
12537
12538  @media (max-width: 768px) {
12539    .subscription-title {
12540      font-size: 14px;
12541      padding: 12px;
12542    }
12543
12544    .shipping-text {
12545      font-size: 13px;
12546      letter-spacing: 0px;
12547    }
12548
12549    .current-plan {
12550      font-size: 14px;
12551    }
12552
12553    .truck-icon {
12554      max-width: 2rem;
12555    }
12556
12557    .free-shipping-banner {
12558      padding: 16px 14px 2px 14px;
12559    }
12560  }
12561
12562  .cart-item[data-handle='free-tote'],
12563  .cart-item[data-handle='variety-travel-2-pack-of-1-oz'],
12564  .cart-item--gwp,
12565  .cart-item[data-gwp-visual='true'] {
12566    pointer-events: none;
12567  }
12568
12569  @media (max-height: 700px) {
12570    .cart-upsell-card {
12571      padding: 24px 10px 10px;
12572    }
12573
12574    .cart-upsell-card__body {
12575      grid-template-columns: 60px 1fr;
12576      gap: 10px;
12577    }
12578
12579    .cart-upsell-card__title {
12580      font-size: 13px;
12581    }
12582
12583    .cart-upsell-card__image img {
12584      max-height: 60px;
12585    }
12586
12587    .cart-upsell-card__add {
12588      font-size: 12px;
12589      padding: 7px 18px;
12590    }
12591
12592    .product-card {
12593      padding: 8px 6px 5px 6px;
12594    }
12595
12596    .product-details-main h4 {
12597      font-size: 13px !important;
12598    }
12599
12600    .product-image {
12601      width: 5rem;
12602    }
12603
12604    .product-image a img {
12605      max-height: 5rem !important;
12606    }
12607
12608    .product-details-main .price span:first-child {
12609      display: none;
12610    }
12611
12612    .add-to-cart-btn {
12613      font-size: 12px;
12614      padding: 7px 18px;
12615    }
12616
12617    .subscription-title {
12618      padding: 9px;
12619    }
12620
12621    .current-plan {
12622      font-size: 13px;
12623    }
12624  }
12625</style>
12626
12627
12628</div><div id="shopify-section-main-cart-footer" class="shopify-section cart__footer-wrapper"><div data-id="main-cart-footer" class="bg-sand py-5 lg:py-8 rounded-t-3xl" id="cart__footer">
12629  <div id="main-cart-footer" class="site-container">
12630    <div>
12631      <div>
12632        <div class="totals flex justify-between mb-6">
12633          <h3>Subtotal</h3>
12634          <p class="font-body-medium">$0</p>
12635          
12636        </div>
12637
12638      </div>
12639    <div>
12640      <a href="/checkout" class="button button--gold !w-full">Checkout</a>
12641    </div>
12642      <small class="block text-center mt-3.5 text-primary text-sm">Taxes and <a href="/policies/shipping-policy">shipping</a> calculated at checkout
12643</small>
12644    </div>
12645  </div>
12646</div>
12647<style>
12648div#shopify-section-main-cart-footer {
12649  bottom: 0;
12650  position: absolute;
12651  left: 0;
12652  right: 0;
12653}
12654</style>
12655
12656</div></div>
12657    </div>
12658    <cart-toggle>
12659      <button class="flyout__veil absolute opacity-0 invisible top-0 bottom-0 left-0 w-full h-full z-10 cursor-pointer bg-transparent border-0 outline-none transition-all duration-500 ease-in-out"></button>
12660    </cart-toggle>
12661  </div>
12662</site-cart>
12662<script>
12663      setTimeout(function () {
12664        var script = document.createElement('script');
12665        script.src = 'https://connect.podium.com/widget.js#ORG_TOKEN=26e5de10-54f2-4772-b419-ec6a202d561a';
12666        script.async = true;
12667        document.body.appendChild(script);
12668      }, 6000); // 8-second delay
12669
12670      document.addEventListener('DOMContentLoaded', () => {
12671        const filterButtons = document.querySelectorAll('.filter-button');
12672        const allItems = Array.from(document.querySelectorAll('.js-blog-item'));
12673        const pagerContainer = document.querySelector('.blog-pagination');
12674        const pageSize = 4;
12675        let filteredItems = [...allItems];
12676        let currentPage = 1;
12677
12678        // Show a slice of filteredItems, rebuild pager
12679        function showPage(page) {
12680          currentPage = page;
12681          const start = (page - 1) * pageSize;
12682          const end = start + pageSize;
12683
12684          // hide everything, then show just this page’s slice
12685          allItems.forEach((i) => (i.style.display = 'none'));
12686          filteredItems.slice(start, end).forEach((i) => (i.style.display = ''));
12687
12688          renderPager();
12689          window.scrollTo({ top: 0, behavior: 'smooth' });
12690        }
12691
12692        // Build the “Previous 1 2 3 Next” buttons
12693        function renderPager() {
12694          const totalPages = Math.ceil(filteredItems.length / pageSize);
12695          if (pagerContainer) pagerContainer.innerHTML = '';
12696
12697          // Previous btn
12698          const prev = document.createElement('button');
12699          prev.textContent = 'Previous';
12700          prev.className = 'page-btn';
12701          prev.disabled = currentPage === 1;
12702          prev.addEventListener('click', () => showPage(currentPage - 1));
12703          if (pagerContainer) pagerContainer.appendChild(prev);
12704
12705          // Page numbers
12706          for (let i = 1; i <= totalPages; i++) {
12707            const btn = document.createElement('button');
12708            btn.textContent = i;
12709            btn.className = 'page-btn' + (i === currentPage ? ' active' : '');
12710            btn.addEventListener('click', () => showPage(i));
12711            if (pagerContainer) pagerContainer.appendChild(btn);
12712          }
12713
12714          // Next btn
12715          const next = document.createElement('button');
12716          next.textContent = 'Next';
12717          next.className = 'page-btn';
12718          next.disabled = currentPage === totalPages;
12719          next.addEventListener('click', () => showPage(currentPage + 1));
12720          if (pagerContainer) pagerContainer.appendChild(next);
12721        }
12722
12723        // Filter handler—updates filteredItems and resets to page 1
12724        filterButtons.forEach((btn) => {
12725          btn.addEventListener('click', () => {
12726            // highlight the pill
12727            filterButtons.forEach((b) => b.classList.remove('active'));
12728            btn.classList.add('active');
12729
12730            const filter = btn.dataset.filter;
12731            filteredItems = allItems.filter((item) => filter === 'all' || item.dataset.filter === filter);
12732
12733            showPage(1);
12734          });
12735        });
12736
12737        // kick it off
12738        showPage(1);
12739      });
12740    </script>
vendor: 88 bytes, lines 12740-12744
12740
12741
12742    <noscript
12743      ><iframe
12744        src="https://www.googletagmanager.com/ns.html?id=
12744GTM-MX86RPVR
vendor: 124 bytes, lines 12744-12751
12744"
12745        height="0"
12746        width="0"
12747        style="display:none;visibility:hidden"
12748      ></iframe
12749    ></noscript>
12750
12751    
12751<script>
12752      document.addEventListener('DOMContentLoaded', function () {
12753        let path = window.location.pathname;
12754
12755        if (path === '/cart') {
12756          sessionStorage.setItem('openCartOnHome', 'true');
12757
12758          window.location.href = '/';
12759        }
12760
12761        if (path === '/') {
12762          if (sessionStorage.getItem('openCartOnHome') === 'true') {
12763            sessionStorage.removeItem('openCartOnHome');
12764
12765            let siteCart = document.querySelector('.site-cart');
12766            if (siteCart) {
12767              siteCart.classList.add('active');
12768            }
12769          }
12770        }
12771      });
12772    </script>
12772
12773
12774    
12775    
12776  <div id="shopify-block-AVElYbHJnemxjbVVrN__10840395464443086010" class="shopify-block shopify-app-block">
12777
12778
12779<script>
12780  console.log("[Alia app extension] v1.0.5");
12781
12782  const BACKEND_URL = "https://backend.alia-prod.com";
12783
12784  window.ALIA_SHOPIFY_EXTENSION_INFO = {
12785    customerID: "",
12786    country: "US",
12787    market: "us",
12788    language: "en"
12789  }
12790
12791  if (document.readyState !== "loading") {
12792    initAlia();
12793  } else {
12794    document.addEventListener("DOMContentLoaded", () => initAlia(), { once: true });
12795  }
12796
12797  async function initAlia() {
12798    const url = BACKEND_URL + "/public/launcher.js?shopifyUrl=revitin.myshopify.com";
12799    const script = document.createElement("script");
12800    script.src = url;
12801    script.async = true;
12802    document.head.appendChild(script);
12803  }
12804</script>
12804
12805
12806</div>
12806<script src="https://cdn.shopify.com/storefront/standard-actions.js" type="module" data-source-attribution="shopify.standard_actions"></script>
12806
12807</body>
12808</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.