Adding Calculator to Squarespace

Some instructions to add Calculator to Squarespace with Code Block, they will sync with style from Site Styles.

You can also use Calculator Widget Tool (free) to add Calculator if you don’t want to use complex code.

Style 01. Shipping Rates Calculator

#1. Install Code

This is just a calculator using a sample formula, but you can easily send it to AI (ChatGPT or Claude. I recommend this AI chat bot, it is designed for Squarespace site) to customize it to your specific needs – and, notably, it can sync with style from Site Styles. You can also use this free calculator tool to create a calculator.

#1.1. You can edit Page where you want to place Calculator > Add a Code Block

#1.2. Add this code into Code Block

<!-- 09.26c01v1 Shipping Rates Calculator -->
<div class="tp-calc" data-tp-calc></div>

<script>
  window.ShippingCalcConfig = {
    text: {
      title: "Shipping Rates Calculator",
      weightLabel: "Weight",
      weightUnit: "lbs",
      weightHint: "Select the weight of the package.",
      distanceLabel: "Distance",
      distanceUnit: "miles",
      distanceHint: "Set the distance to the destination.",
      serviceLabel: "Service Type",
      serviceHint: "Choose a shipping service.",
      costHeading: "Shipping Cost",
      costHint: "Final Shipping Cost",
      etaLabel: "Estimated Delivery Time",
      etaHint: "Delivery Time Estimate",
      etaUnit: "days",
      ctaHeading: "Get Your Package Moving!",
      ctaHint: "Experience fast and reliable shipping with our service. Take the next step now!",
      ctaButton: "Ship Now",
      ctaHref: "#"
    },
    tags: {
      // HTML tag per text; style (size/color) inherits from the tag on the site
      title: "h2",
      weightLabel: "h3",
      distanceLabel: "h3",
      serviceLabel: "h3",
      costHeading: "h3",
      etaLabel: "h3",
      ctaHeading: "h3"
    },
    colors: {
      // "" = inherit from the tag/class; set a value to override
      title: "",
      label: "",
      smallText: "",
      cardBg: "#000000",
      cardHeading: "#ffffff",
      cardValue: "#ffffff",
      cardMuted: "rgba(255,255,255,0.7)"
    },
    slider: {
      trackFill: "#111111",
      trackEmpty: "#eaeaea",
      thumbBg: "#ffffff",
      thumbBorder: "#cccccc",
      trackHeight: "12px",
      thumbSize: "26px"
    },
    layout: {
      valueInputWidth: "72px" // width of the Weight/Distance number inputs
    },
    button: {
      // "" = inherit the native button classes; set a value to override
      text: "",
      bg: "",
      border: "",
      hoverText: "",
      hoverBg: "",
      hoverBorder: ""
    },
    ranges: {
      weight: { min: 1, max: 100, step: 1, value: 5 },
      distance: { min: 1, max: 3000, step: 1, value: 500 }
    },
    formula: {
      currencySymbol: "$",
      moneyDecimals: 2,
      baseFee: 0,
      rateByService: { 1: 0.05, 2: 0.10, 3: 0.20 },
      milesPerDayByService: { 1: 500, 2: 250, 3: 100 },
      // Optional. Return a number; leave null to use the built-in formula.
      // costFn(weight, distance, service, formula) -> cost
      // daysFn(weight, distance, service, formula) -> days
      costFn: null,
      daysFn: null
    },
    services: [
      { value: 1, label: "Standard" },
      { value: 2, label: "Express" },
      { value: 3, label: "Overnight" }
    ]
  };
</script>

<script>
  (function () {
    var CFG = window.ShippingCalcConfig;

    var CSS =
      ".tp-calc,.tp-calc *{box-sizing:border-box}" +
      ".tp-calc{--tp-card-bg:#000;--tp-track-fill:#111;--tp-track-empty:#eaeaea;--tp-thumb-bg:#fff;--tp-thumb-border:#ccc;--tp-track-h:12px;--tp-thumb-size:26px;--tp-input-w:72px;--tp-pill-min-width:84px;--tp-card-radius:22px;color:inherit}" +
      ".tp-calc__wrap{max-width:1180px;margin:40px auto;padding:0 24px;display:grid;grid-template-columns:1.1fr 0.9fr;gap:48px;align-items:start}" +
      ".tp-calc__h{margin:0}" +
      ".tp-calc__title{margin:0 0 32px}" +
      ".tp-calc__field{padding:6px 0}" +
      ".tp-calc__labelRow{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:18px}" +
      ".tp-calc__sm{margin:14px 0 0}" +
      ".tp-calc__pill{min-width:var(--tp-pill-min-width);background:#fff;border:1px solid #dcdcdc;border-radius:12px;padding:12px 16px;display:inline-flex;gap:5px;align-items:center;justify-content:center;font-weight:600;font-size:17px;color:#111}" +
      ".tp-calc__num{width:var(--tp-input-w);border:0;background:transparent;padding:0;margin:0;font:inherit;color:inherit;text-align:right;-moz-appearance:textfield;appearance:textfield}" +
      ".tp-calc__num::-webkit-outer-spin-button,.tp-calc__num::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}" +
      ".tp-calc__range{width:100%;-webkit-appearance:none;appearance:none;height:var(--tp-track-h);border-radius:999px;margin:4px 0 0;cursor:pointer;background:linear-gradient(90deg,var(--tp-track-fill) 0%,var(--tp-track-fill) var(--tp-fill,0%),var(--tp-track-empty) var(--tp-fill,0%),var(--tp-track-empty) 100%)}" +
      ".tp-calc__range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:var(--tp-thumb-size);height:var(--tp-thumb-size);border-radius:50%;background:var(--tp-thumb-bg);border:1px solid var(--tp-thumb-border);box-shadow:0 1px 3px rgba(0,0,0,.2);cursor:pointer}" +
      ".tp-calc__range::-moz-range-thumb{width:var(--tp-thumb-size);height:var(--tp-thumb-size);border-radius:50%;background:var(--tp-thumb-bg);border:1px solid var(--tp-thumb-border);cursor:pointer}" +
      ".tp-calc__minmax{display:flex;justify-content:space-between;margin-top:12px}" +
      ".tp-calc__divider{height:1px;background:#ededed;margin:30px 0}" +
      ".tp-calc__dd{position:relative;margin-top:16px}" +
      ".tp-calc__ddBtn{width:100%;display:flex;align-items:center;justify-content:space-between;padding:18px 20px;border:1px solid #dcdcdc;border-radius:12px;background:#fff;font-family:inherit;font-size:17px;font-weight:500;color:#111;cursor:pointer;text-align:left}" +
      ".tp-calc__chev{width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:7px solid #222;transition:transform .18s ease;flex:none}" +
      ".tp-calc__dd.is-open .tp-calc__chev{transform:rotate(180deg)}" +
      ".tp-calc__ddList{list-style:none;margin:6px 0 0;padding:6px;position:absolute;left:0;right:0;top:100%;z-index:20;background:#fff;border:1px solid #dcdcdc;border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.12)}" +
      ".tp-calc__ddList[hidden]{display:none}" +
      ".tp-calc__ddOpt{padding:14px 16px;border-radius:8px;font-size:17px;color:#111;cursor:pointer}" +
      ".tp-calc__ddOpt:hover{background:#f4f4f4}" +
      ".tp-calc__ddOpt.is-selected{background:#f0f0f0;font-weight:600}" +
      ".tp-calc__card{width:100%;background:var(--tp-card-bg);border-radius:var(--tp-card-radius);padding:44px}" +
      ".tp-calc__card .tp-calc__h{margin:0 0 4px}" +
      ".tp-calc__total{font-weight:800;font-size:60px;line-height:1;margin:10px 0 6px}" +
      ".tp-calc__etaRow{display:flex;justify-content:space-between;align-items:flex-start;gap:16px}" +
      ".tp-calc__etaVal{font-size:20px;font-weight:700;white-space:nowrap}" +
      ".tp-calc__spacer{height:26px}" +
      ".tp-calc__spacer--lg{height:40px}" +
      ".tp-calc__btn{margin-top:20px}" +
      "@media (max-width:980px){.tp-calc__wrap{grid-template-columns:1fr;gap:28px}.tp-calc__card{padding:34px}}" +
      "@media (max-width:520px){.tp-calc__card{padding:28px}.tp-calc__total{font-size:52px}}";

    function decl(prop, val) { return val ? prop + ":" + val + " !important;" : ""; }

    function buttonCSS() {
      var B = CFG.button;
      var base = decl("color", B.text) + decl("background-color", B.bg) + decl("border-color", B.border);
      var hover = decl("color", B.hoverText) + decl("background-color", B.hoverBg) + decl("border-color", B.hoverBorder);
      var out = "";
      if (base) out += ".tp-calc a.tp-calc__btn{" + base + "}";
      if (hover) out += ".tp-calc a.tp-calc__btn:hover{" + hover + "}";
      return out;
    }

    function injectCSS() {
      if (window.__tpCalcStyled) return;
      window.__tpCalcStyled = true;
      var st = document.createElement("style");
      st.type = "text/css";
      st.textContent = CSS + buttonCSS();
      document.head.appendChild(st);
    }

    function el(tag, cls, txt) {
      var e = document.createElement(tag);
      if (cls) e.className = cls;
      if (txt != null) e.textContent = txt;
      return e;
    }

    function fmtNum(n) { return (+n).toLocaleString("en-US"); }

    function heading(tag, txt, color) {
      var e = el(tag, "tp-calc__h", txt);
      if (color) e.style.color = color;
      return e;
    }

    function smallP(txt, color) {
      var e = el("p", "sqsrte-small tp-calc__sm", txt);
      if (color) e.style.color = color;
      return e;
    }

    function round2(n) { return Math.round((+n + Number.EPSILON) * 100) / 100; }

    function formatMoney(n) {
      var F = CFG.formula;
      var v = round2(n);
      var d = Math.max(0, F.moneyDecimals | 0);
      var fixed = v.toFixed(d);
      var isInt = Math.abs(v - Math.round(v)) < 1e-9;
      if (d > 0 && isInt) return F.currencySymbol + Math.round(v);
      return F.currencySymbol + fixed;
    }

    function calcCost(w, d, s) {
      var F = CFG.formula;
      if (typeof F.costFn === "function") return round2(F.costFn(w, d, s, F));
      var rate = +F.rateByService[s] || 0;
      return round2((+F.baseFee || 0) + w * d * rate);
    }

    function calcDays(w, d, s) {
      var F = CFG.formula;
      if (typeof F.daysFn === "function") return F.daysFn(w, d, s, F);
      var mpd = +F.milesPerDayByService[s] || 1;
      return Math.ceil(d / mpd);
    }

    function clampInt(v, min, max) {
      v = Math.round(+v);
      if (!isFinite(v)) v = min;
      return Math.min(max, Math.max(min, v));
    }

    function numField(o) {
      var node = el("div", "tp-calc__field");
      var row = el("div", "tp-calc__labelRow");
      row.appendChild(heading(o.tag, o.label, CFG.colors.label));

      var pill = el("div", "tp-calc__pill");
      var input = el("input", "tp-calc__num");
      input.type = "number";
      input.min = o.r.min; input.max = o.r.max; input.step = o.r.step; input.value = o.r.value;
      input.setAttribute("aria-label", o.label);
      pill.appendChild(input);
      pill.appendChild(el("span", null, o.unit));
      row.appendChild(pill);
      node.appendChild(row);

      var range = el("input", "tp-calc__range");
      range.type = "range";
      range.min = o.r.min; range.max = o.r.max; range.step = o.r.step; range.value = o.r.value;
      range.setAttribute("aria-label", o.label);
      node.appendChild(range);

      var mm = el("div", "tp-calc__minmax");
      var s1 = el("span", "sqsrte-small", fmtNum(o.r.min) + " " + o.unit);
      var s2 = el("span", "sqsrte-small", fmtNum(o.r.max) + " " + o.unit);
      if (CFG.colors.smallText) { s1.style.color = CFG.colors.smallText; s2.style.color = CFG.colors.smallText; }
      mm.appendChild(s1); mm.appendChild(s2);
      node.appendChild(mm);

      node.appendChild(smallP(o.hint, CFG.colors.smallText));

      function get() {
        var raw = input.value === "" ? o.r.min : input.value;
        return clampInt(raw, o.r.min, o.r.max);
      }
      function fill() {
        var v = +range.value, min = +range.min, max = +range.max;
        range.style.setProperty("--tp-fill", ((v - min) / (max - min)) * 100 + "%");
      }
      function sync(v) { range.value = v; fill(); }

      var cb = function () {};
      input.addEventListener("input", function () { cb(); });
      input.addEventListener("change", function () { input.value = get(); cb(); });
      range.addEventListener("input", function () { input.value = range.value; cb(); });

      return { node: node, get: get, sync: sync, onChange: function (f) { cb = f; } };
    }

    function serviceField() {
      var node = el("div", "tp-calc__field");
      node.appendChild(heading(CFG.tags.serviceLabel, CFG.text.serviceLabel, CFG.colors.label));

      var dd = el("div", "tp-calc__dd");
      var ddBtn = el("button", "tp-calc__ddBtn");
      ddBtn.type = "button";
      ddBtn.setAttribute("aria-haspopup", "listbox");
      ddBtn.setAttribute("aria-expanded", "false");
      var lbl = el("span", null, CFG.services[0].label);
      var chev = el("span", "tp-calc__chev");
      chev.setAttribute("aria-hidden", "true");
      ddBtn.appendChild(lbl); ddBtn.appendChild(chev);

      var list = el("ul", "tp-calc__ddList");
      list.setAttribute("role", "listbox");
      list.hidden = true;

      var current = CFG.services[0].value;

      function open() { dd.classList.add("is-open"); list.hidden = false; ddBtn.setAttribute("aria-expanded", "true"); }
      function close() { dd.classList.remove("is-open"); list.hidden = true; ddBtn.setAttribute("aria-expanded", "false"); }

      var cb = function () {};

      CFG.services.forEach(function (s, i) {
        var li = el("li", "tp-calc__ddOpt" + (i === 0 ? " is-selected" : ""), s.label);
        li.setAttribute("role", "option");
        li.setAttribute("data-value", s.value);
        li.addEventListener("click", function () {
          current = s.value;
          lbl.textContent = s.label;
          var all = list.querySelectorAll(".tp-calc__ddOpt");
          for (var j = 0; j < all.length; j++) all[j].classList.remove("is-selected");
          li.classList.add("is-selected");
          close();
          cb();
        });
        list.appendChild(li);
      });

      dd.appendChild(ddBtn); dd.appendChild(list);
      node.appendChild(dd);
      node.appendChild(smallP(CFG.text.serviceHint, CFG.colors.smallText));

      ddBtn.addEventListener("click", function (e) {
        e.stopPropagation();
        if (dd.classList.contains("is-open")) close(); else open();
      });
      document.addEventListener("click", function (e) { if (!dd.contains(e.target)) close(); });
      ddBtn.addEventListener("keydown", function (e) { if (e.key === "Escape") close(); });

      return { node: node, get: function () { return current; }, onChange: function (f) { cb = f; } };
    }

    function mount(root) {
      if (!root || root.dataset.tpDone === "1") return;
      root.dataset.tpDone = "1";

      var T = CFG.text, G = CFG.tags, K = CFG.colors, S = CFG.slider, R = CFG.ranges;

      root.style.setProperty("--tp-card-bg", K.cardBg);
      root.style.setProperty("--tp-track-fill", S.trackFill);
      root.style.setProperty("--tp-track-empty", S.trackEmpty);
      root.style.setProperty("--tp-thumb-bg", S.thumbBg);
      root.style.setProperty("--tp-thumb-border", S.thumbBorder);
      root.style.setProperty("--tp-track-h", S.trackHeight);
      root.style.setProperty("--tp-thumb-size", S.thumbSize);
      root.style.setProperty("--tp-input-w", CFG.layout.valueInputWidth);

      var wrap = el("div", "tp-calc__wrap");
      var left = el("div", "tp-calc__left");
      var right = el("div", "tp-calc__right");

      var title = heading(G.title, T.title, K.title);
      title.classList.add("tp-calc__title");
      left.appendChild(title);

      var wField = numField({ label: T.weightLabel, tag: G.weightLabel, unit: T.weightUnit, hint: T.weightHint, r: R.weight });
      left.appendChild(wField.node);
      left.appendChild(el("div", "tp-calc__divider"));

      var dField = numField({ label: T.distanceLabel, tag: G.distanceLabel, unit: T.distanceUnit, hint: T.distanceHint, r: R.distance });
      left.appendChild(dField.node);
      left.appendChild(el("div", "tp-calc__divider"));

      var sField = serviceField();
      left.appendChild(sField.node);

      var card = el("div", "tp-calc__card");
      card.appendChild(heading(G.costHeading, T.costHeading, K.cardHeading));
      var total = el("div", "tp-calc__total");
      total.style.color = K.cardValue;
      card.appendChild(total);
      card.appendChild(smallP(T.costHint, K.cardMuted));
      card.appendChild(el("div", "tp-calc__spacer"));

      var etaRow = el("div", "tp-calc__etaRow");
      var etaLeft = el("div");
      etaLeft.appendChild(heading(G.etaLabel, T.etaLabel, K.cardHeading));
      etaLeft.appendChild(smallP(T.etaHint, K.cardMuted));
      var etaVal = el("div", "tp-calc__etaVal");
      etaVal.style.color = K.cardValue;
      etaRow.appendChild(etaLeft); etaRow.appendChild(etaVal);
      card.appendChild(etaRow);

      card.appendChild(el("div", "tp-calc__spacer tp-calc__spacer--lg"));
      card.appendChild(heading(G.ctaHeading, T.ctaHeading, K.cardHeading));
      card.appendChild(smallP(T.ctaHint, K.cardMuted));

      var btn = el("a", "btn btn--border theme-btn--primary-inverse sqs-button-element--primary tp-calc__btn", T.ctaButton);
      btn.setAttribute("href", T.ctaHref);
      btn.setAttribute("rel", "noopener");
      card.appendChild(btn);

      right.appendChild(card);
      wrap.appendChild(left); wrap.appendChild(right);
      root.appendChild(wrap);

      function recalc() {
        var w = wField.get(), d = dField.get(), s = +sField.get() || 1;
        wField.sync(w); dField.sync(d);
        total.textContent = formatMoney(calcCost(w, d, s));
        etaVal.textContent = calcDays(w, d, s) + " " + T.etaUnit;
      }

      wField.onChange(recalc);
      dField.onChange(recalc);
      sField.onChange(recalc);
      recalc();
    }

    function init() {
      var nodes = document.querySelectorAll("[data-tp-calc]");
      for (var i = 0; i < nodes.length; i++) mount(nodes[i]);
    }

    function ready(fn) {
      if (document.readyState !== "loading") fn();
      else document.addEventListener("DOMContentLoaded", fn);
    }

    injectCSS();
    ready(init);

    if (!window.__tpCalcBound) {
      window.__tpCalcBound = true;
      window.addEventListener("mercury:load", init);
    }
  })();
</script>

#2. Customize

#2.1. To change text, change line 06 – 25

text: {
      title: "Shipping Rates Calculator",
      weightLabel: "Weight",
      weightUnit: "lbs",
      weightHint: "Select the weight of the package.",
      distanceLabel: "Distance",
      distanceUnit: "miles",
      distanceHint: "Set the distance to the destination.",
      serviceLabel: "Service Type",
      serviceHint: "Choose a shipping service.",
      costHeading: "Shipping Cost",
      costHint: "Final Shipping Cost",
      etaLabel: "Estimated Delivery Time",
      etaHint: "Delivery Time Estimate",
      etaUnit: "days",
      ctaHeading: "Get Your Package Moving!",
      ctaHint: "Experience fast and reliable shipping with our service. Take the next step now!",
      ctaButton: "Ship Now",
      ctaHref: "#"
    },

#2.2. Style will inherit from Tags. You can set tags for all elements here (line 26 – 35)

tags: {
  // HTML tag per text; style (size/color) inherits from the tag on the site
  title: "h2",
  weightLabel: "h3",
  distanceLabel: "h3",
  serviceLabel: "h3",
  costHeading: "h3",
  etaLabel: "h3",
  ctaHeading: "h3"
},

#2.3. To change color, change line 36 – 45

colors: {
  // "" = inherit from the tag/class; set a value to override
  title: "",
  label: "",
  smallText: "",
  cardBg: "#000000",
  cardHeading: "#ffffff",
  cardValue: "#ffffff",
  cardMuted: "rgba(255,255,255,0.7)"
},

#2.4. To change scroll/track bar style, change line 46 – 53

slider: {
      trackFill: "#111111",
      trackEmpty: "#eaeaea",
      thumbBg: "#ffffff",
      thumbBorder: "#cccccc",
      trackHeight: "12px",
      thumbSize: "26px"
    },

#2.5. To change input width, change line 54 – 56

layout: {
      valueInputWidth: "72px" // width of the Weight/Distance number inputs
    },

#2.6. To change button style (it will inherit from Primary Button Style), you can change line 57 to line 65

button: {
      // "" = inherit the native button classes; set a value to override
      text: "",
      bg: "",
      border: "",
      hoverText: "",
      hoverBg: "",
      hoverBorder: ""
    },

#2.7. To set Weight, Distance, change line 67 – 69

ranges: {
     weight: { min: 1, max: 100, step: 1, value: 5 },
     distance: { min: 1, max: 3000, step: 1, value: 500 }
   },

#2.8. To change Services dropdown value, change line 82 – 86

services: [
     { value: 1, label: "Standard" },
     { value: 2, label: "Express" },
     { value: 3, label: "Overnight" }
   ]

#2.9. To change formula, change line 70 – 81

formula: {
     currencySymbol: "$",
     moneyDecimals: 2,
     baseFee: 0,
     rateByService: { 1: 0.05, 2: 0.10, 3: 0.20 },
     milesPerDayByService: { 1: 500, 2: 250, 3: 100 },
     // Optional. Return a number; leave null to use the built-in formula.
     // costFn(weight, distance, service, formula) -> cost
     // daysFn(weight, distance, service, formula) -> days
     costFn: null,
     daysFn: null
   },

For example, if you want to change Cost formula, change line 79

costFn: null,

to something like this

costFn: function (weight, distance, service, formula) {
  return 5 + weight * 1.2 + distance * 0.03;
},

or similar with Days, we will change

daysFn: null

to

daysFn: function (weight, distance, service, formula) {
  return Math.ceil(distance / 400) + 1;
}

You can ask AI adjust formula for you!

Style 02. Mortgage Caculator

You can use a Code Block with this code

<!-- 09.26c14v1(v2) Mortgage Caculator -->
<div class="tp-calc" data-tp-calc></div>

<script>
  window.MortgageCalcConfig = {
    text: {
      title: "",
      amountLabel: "Loan Amount",
      amountHint: "Enter the total loan amount you want to borrow",
      rateLabel: "Interest Rate",
      rateUnit: "%",
      rateHint: "",
      periodLabel: "Loan Period",
      periodUnit: "years",
      periodHint: "",
      paymentHeading: "Monthly Payment",
      paymentHint: "This is an approximate monthly repayment amount for your mortgage based on the given inputs.",
      interestLabel: "Total Interest Paid",
      interestHint: "This is the total interest you would pay over the entire loan period.",
      ctaHeading: "Ready to get started?",
      ctaHint: "Get in touch with our mortgage advisors for personalized advice!",
      ctaButton: "Book a Meeting",
      ctaHref: "/contact-us"
    },
    tags: {
      title: "h2",
      amountLabel: "h3",
      rateLabel: "h3",
      periodLabel: "h3",
      paymentHeading: "h3",
      interestLabel: "h3",
      ctaHeading: "h2"
    },
    colors: {
      title: "",
      label: "",
      smallText: "",
      cardBg: "#f0f6fd",
      cardHeading: "",
      cardValue: "",
      cardMuted: "rgba(17,17,17,0.6)"
    },
    slider: {
      trackFill: "#197bff",
      trackEmpty: "rgba(17,17,17,0.05)",
      thumbBg: "#ffffff",
      thumbBorder: "rgba(17,17,17,0.1)",
      trackHeight: "6px",
      thumbSize: "24px"
    },
    layout: {
      inputBorder: "1px solid rgba(17,17,17,0.2)"
    },
    button: {
      text: "#ffffff",
      bg: "#197bff",
      border: "#197bff",
      hoverText: "#ffffff",
      hoverBg: "#1569e0",
      hoverBorder: "#1569e0"
    },
    ranges: {
      amount: { min: 100000, max: 5000000, step: 10000, value: 1000000 },
      rate: { min: 1, max: 15, step: 0.1, value: 5 },
      period: { min: 5, max: 40, step: 1, value: 30 }
    },
    formula: {
      currencySymbol: "$",
      moneyDecimals: 0,
      // paymentFn(amount, annualRatePct, years, formula) -> monthly payment
      // interestFn(amount, annualRatePct, years, formula) -> total interest
      paymentFn: null,
      interestFn: null
    }
  };
</script>

<script>
  (function () {
    var CFG = window.MortgageCalcConfig;

    var CSS =
      ".tp-calc,.tp-calc *{box-sizing:border-box}" +
      ".tp-calc{--tp-card-bg:#f0f6fd;--tp-track-fill:#197bff;--tp-track-empty:rgba(17,17,17,0.05);--tp-thumb-bg:#fff;--tp-thumb-border:rgba(17,17,17,0.1);--tp-track-h:6px;--tp-thumb-size:24px;--tp-input-border:1px solid rgba(17,17,17,0.2);--tp-pill-min-width:84px;--tp-card-radius:22px;color:inherit}" +
      ".tp-calc__wrap{max-width:1180px;margin:40px auto;padding:0 24px;display:grid;grid-template-columns:1.1fr 0.9fr;gap:48px;align-items:start}" +
      ".tp-calc__h{margin:0}" +
      ".tp-calc__title{margin:0 0 32px}" +
      ".tp-calc__field{padding:6px 0}" +
      ".tp-calc__labelRow{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:18px}" +
      ".tp-calc__sm{margin:14px 0 0}" +
      ".tp-calc__pill{min-width:var(--tp-pill-min-width);background:#fff;border:var(--tp-input-border);border-radius:12px;padding:12px 16px;display:inline-flex;gap:0;align-items:center;justify-content:center;font-size:17px;color:#111}" +
      ".tp-calc__num{width:auto;min-width:1ch;border:0;background:transparent;padding:0;margin:0;color:inherit}" +
      ".tp-calc__unit{margin-left:6px}" +
      ".tp-calc__unit--tight{margin-left:2px}" +
      ".tp-calc__range{width:100%;-webkit-appearance:none;appearance:none;height:var(--tp-track-h);border-radius:999px;margin:4px 0 0;cursor:pointer;background:linear-gradient(90deg,var(--tp-track-fill) 0%,var(--tp-track-fill) var(--tp-fill,0%),var(--tp-track-empty) var(--tp-fill,0%),var(--tp-track-empty) 100%)}" +
      ".tp-calc__range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:var(--tp-thumb-size);height:var(--tp-thumb-size);border-radius:50%;background:var(--tp-thumb-bg);border:1px solid var(--tp-thumb-border);box-shadow:0 2px 6px rgba(0,0,0,.15);cursor:pointer}" +
      ".tp-calc__range::-moz-range-thumb{width:var(--tp-thumb-size);height:var(--tp-thumb-size);border-radius:50%;background:var(--tp-thumb-bg);border:1px solid var(--tp-thumb-border);box-shadow:0 2px 6px rgba(0,0,0,.15);cursor:pointer}" +
      ".tp-calc__minmax{display:flex;justify-content:space-between;margin-top:12px}" +
      ".tp-calc__divider{height:1px;background:rgba(17,17,17,0.08);margin:30px 0}" +
      ".tp-calc__card{width:100%;background:var(--tp-card-bg);border-radius:var(--tp-card-radius);padding:44px}" +
      ".tp-calc__card .tp-calc__h{margin:0 0 4px}" +
      ".tp-calc__total{font-weight:800;font-size:60px;line-height:1;margin:10px 0 6px}" +
      ".tp-calc__cardDivider{height:1px;background:rgba(17,17,17,0.1);margin:28px 0}" +
      ".tp-calc__etaRow{display:flex;justify-content:space-between;align-items:flex-start;gap:16px}" +
      ".tp-calc__etaVal{font-size:20px;font-weight:700;white-space:nowrap}" +
      ".tp-calc__spacer{height:26px}" +
      ".tp-calc__spacer--lg{height:40px}" +
      ".tp-calc a.tp-calc__btn{display:block !important;width:100% !important;text-align:center !important;border-radius:10px !important;margin-top:20px}" +
      "@media (max-width:980px){.tp-calc__wrap{grid-template-columns:1fr;gap:28px}.tp-calc__card{padding:34px}}" +
      "@media (max-width:520px){.tp-calc__card{padding:28px}.tp-calc__total{font-size:52px}}";

    function decl(prop, val) { return val ? prop + ":" + val + " !important;" : ""; }

    function buttonCSS() {
      var B = CFG.button;
      var base = decl("color", B.text) + decl("background-color", B.bg) + decl("border-color", B.border);
      var hover = decl("color", B.hoverText) + decl("background-color", B.hoverBg) + decl("border-color", B.hoverBorder);
      var out = "";
      if (base) out += ".tp-calc a.tp-calc__btn{" + base + "}";
      if (hover) out += ".tp-calc a.tp-calc__btn:hover{" + hover + "}";
      return out;
    }

    function injectCSS() {
      if (window.__mortCalcStyled) return;
      window.__mortCalcStyled = true;
      var st = document.createElement("style");
      st.type = "text/css";
      st.textContent = CSS + buttonCSS();
      document.head.appendChild(st);
    }

    function el(tag, cls, txt) {
      var e = document.createElement(tag);
      if (cls) e.className = cls;
      if (txt != null) e.textContent = txt;
      return e;
    }

    function heading(tag, txt, color) {
      var e = el(tag, "tp-calc__h", txt);
      if (color) e.style.color = color;
      return e;
    }

    function smallP(txt, color) {
      var e = el("p", "sqsrte-small tp-calc__sm", txt);
      if (color) e.style.color = color;
      return e;
    }

    function stepDecimals(step) {
      var s = String(step);
      var i = s.indexOf(".");
      return i < 0 ? 0 : (s.length - i - 1);
    }

    function fmtNumber(v, decimals) {
      return (+v).toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits: decimals });
    }

    function formatMoney(n) {
      var F = CFG.formula;
      var d = Math.max(0, F.moneyDecimals | 0);
      return F.currencySymbol + (+n).toLocaleString("en-US", { minimumFractionDigits: d, maximumFractionDigits: d });
    }

    function calcMonthly(P, ratePct, years) {
      var F = CFG.formula;
      if (typeof F.paymentFn === "function") return F.paymentFn(P, ratePct, years, F);
      var r = (ratePct / 100) / 12;
      var n = years * 12;
      if (!n) return 0;
      if (r === 0) return P / n;
      var pow = Math.pow(1 + r, n);
      return P * (r * pow) / (pow - 1);
    }

    function calcInterest(P, ratePct, years) {
      var F = CFG.formula;
      if (typeof F.interestFn === "function") return F.interestFn(P, ratePct, years, F);
      return calcMonthly(P, ratePct, years) * years * 12 - P;
    }

    function clampNum(v, min, max, decimals) {
      v = +v;
      if (!isFinite(v)) v = min;
      v = Math.min(max, Math.max(min, v));
      var f = Math.pow(10, decimals || 0);
      return Math.round(v * f) / f;
    }

    var measureSpan;
    function autosize(input) {
      if (!measureSpan) {
        measureSpan = document.createElement("span");
        measureSpan.style.cssText = "position:absolute;visibility:hidden;white-space:pre;left:-9999px;top:0";
        document.body.appendChild(measureSpan);
      }
      var cs = window.getComputedStyle(input);
      measureSpan.style.fontFamily = cs.fontFamily;
      measureSpan.style.fontSize = cs.fontSize;
      measureSpan.style.fontWeight = cs.fontWeight;
      measureSpan.style.fontStyle = cs.fontStyle;
      measureSpan.style.letterSpacing = cs.letterSpacing;
      measureSpan.textContent = input.value || "0";
      input.style.width = (measureSpan.offsetWidth + 2) + "px";
    }

    function numField(o) {
      var decimals = stepDecimals(o.r.step);
      var node = el("div", "tp-calc__field");
      var row = el("div", "tp-calc__labelRow");
      row.appendChild(heading(o.tag, o.label, CFG.colors.label));

      var pill = el("div", "tp-calc__pill");
      var input = el("input", "tp-calc__num");
      input.type = "text";
      input.setAttribute("inputmode", decimals ? "decimal" : "numeric");
      input.setAttribute("aria-label", o.label);
      pill.appendChild(input);
      if (o.suffix) {
        pill.appendChild(el("span", "tp-calc__unit" + (o.suffixTight ? " tp-calc__unit--tight" : ""), o.suffix));
      }
      row.appendChild(pill);
      node.appendChild(row);

      var range = el("input", "tp-calc__range");
      range.type = "range";
      range.min = o.r.min; range.max = o.r.max; range.step = o.r.step; range.value = o.r.value;
      range.setAttribute("aria-label", o.label);
      node.appendChild(range);

      var mm = el("div", "tp-calc__minmax");
      var s1 = el("span", "sqsrte-small", labelText(o.r.min));
      var s2 = el("span", "sqsrte-small", labelText(o.r.max));
      if (CFG.colors.smallText) { s1.style.color = CFG.colors.smallText; s2.style.color = CFG.colors.smallText; }
      mm.appendChild(s1); mm.appendChild(s2);
      node.appendChild(mm);

      if (o.hint) node.appendChild(smallP(o.hint, CFG.colors.smallText));

      function labelText(v) {
        var s = (o.prefix || "") + fmtNumber(v, decimals);
        if (o.suffix) s += (o.suffixTight ? "" : " ") + o.suffix;
        return s;
      }
      function disp(v) { return (o.prefix || "") + fmtNumber(v, decimals); }
      function get() {
        var cleaned = (input.value || "").replace(/[^0-9.]/g, "");
        var v = cleaned === "" ? o.r.min : parseFloat(cleaned);
        return clampNum(v, o.r.min, o.r.max, decimals);
      }
      function fill() {
        var v = +range.value, min = +range.min, max = +range.max;
        range.style.setProperty("--tp-fill", ((v - min) / (max - min)) * 100 + "%");
      }
      function sync(v) { range.value = v; fill(); autosize(input); }

      var cb = function () {};
      input.addEventListener("input", function () { autosize(input); cb(); });
      input.addEventListener("change", function () { input.value = disp(get()); autosize(input); cb(); });
      range.addEventListener("input", function () { input.value = disp(+range.value); autosize(input); cb(); });

      input.value = disp(o.r.value);
      fill();

      return { node: node, get: get, sync: sync, onChange: function (f) { cb = f; } };
    }

    function mount(root) {
      if (!root || root.dataset.tpDone === "1") return;
      root.dataset.tpDone = "1";

      var T = CFG.text, G = CFG.tags, K = CFG.colors, S = CFG.slider, R = CFG.ranges, F = CFG.formula;

      root.style.setProperty("--tp-card-bg", K.cardBg);
      root.style.setProperty("--tp-track-fill", S.trackFill);
      root.style.setProperty("--tp-track-empty", S.trackEmpty);
      root.style.setProperty("--tp-thumb-bg", S.thumbBg);
      root.style.setProperty("--tp-thumb-border", S.thumbBorder);
      root.style.setProperty("--tp-track-h", S.trackHeight);
      root.style.setProperty("--tp-thumb-size", S.thumbSize);
      root.style.setProperty("--tp-input-border", CFG.layout.inputBorder);

      var wrap = el("div", "tp-calc__wrap");
      var left = el("div", "tp-calc__left");
      var right = el("div", "tp-calc__right");

      if (T.title) {
        var title = heading(G.title, T.title, K.title);
        title.classList.add("tp-calc__title");
        left.appendChild(title);
      }

      var aField = numField({ label: T.amountLabel, tag: G.amountLabel, prefix: F.currencySymbol, hint: T.amountHint, r: R.amount });
      left.appendChild(aField.node);
      left.appendChild(el("div", "tp-calc__divider"));

      var rField = numField({ label: T.rateLabel, tag: G.rateLabel, suffix: T.rateUnit, suffixTight: true, hint: T.rateHint, r: R.rate });
      left.appendChild(rField.node);
      left.appendChild(el("div", "tp-calc__divider"));

      var pField = numField({ label: T.periodLabel, tag: G.periodLabel, suffix: T.periodUnit, hint: T.periodHint, r: R.period });
      left.appendChild(pField.node);

      var card = el("div", "tp-calc__card");
      card.appendChild(heading(G.paymentHeading, T.paymentHeading, K.cardHeading));
      var total = el("div", "tp-calc__total");
      if (K.cardValue) total.style.color = K.cardValue;
      card.appendChild(total);
      card.appendChild(smallP(T.paymentHint, K.cardMuted));

      card.appendChild(el("div", "tp-calc__cardDivider"));

      var intRow = el("div", "tp-calc__etaRow");
      var intLeft = el("div");
      intLeft.appendChild(heading(G.interestLabel, T.interestLabel, K.cardHeading));
      intLeft.appendChild(smallP(T.interestHint, K.cardMuted));
      var intVal = el("div", "tp-calc__etaVal");
      if (K.cardValue) intVal.style.color = K.cardValue;
      intRow.appendChild(intLeft); intRow.appendChild(intVal);
      card.appendChild(intRow);

      card.appendChild(el("div", "tp-calc__spacer tp-calc__spacer--lg"));
      card.appendChild(heading(G.ctaHeading, T.ctaHeading, K.cardHeading));
      card.appendChild(smallP(T.ctaHint, K.cardMuted));

      var btn = el("a", "btn btn--border theme-btn--primary-inverse sqs-button-element--primary tp-calc__btn", T.ctaButton);
      btn.setAttribute("href", T.ctaHref);
      btn.setAttribute("rel", "noopener");
      card.appendChild(btn);

      right.appendChild(card);
      wrap.appendChild(left); wrap.appendChild(right);
      root.appendChild(wrap);

      function recalc() {
        var P = aField.get(), rate = rField.get(), years = pField.get();
        aField.sync(P); rField.sync(rate); pField.sync(years);
        total.textContent = formatMoney(calcMonthly(P, rate, years));
        intVal.textContent = formatMoney(calcInterest(P, rate, years));
      }

      aField.onChange(recalc);
      rField.onChange(recalc);
      pField.onChange(recalc);
      recalc();
    }

    function init() {
      var nodes = document.querySelectorAll("[data-tp-calc]");
      for (var i = 0; i < nodes.length; i++) mount(nodes[i]);
    }

    function ready(fn) {
      if (document.readyState !== "loading") fn();
      else document.addEventListener("DOMContentLoaded", fn);
    }

    injectCSS();
    ready(init);

    if (!window.__mortCalcBound) {
      window.__mortCalcBound = true;
      window.addEventListener("mercury:load", init);
    }
  })();
</script>

Again, if you don’t want to use complex code, try Elfsight Calculator Widget (free)

To change text + button url, change line 06 – 24

text: {
     title: "",
     amountLabel: "Loan Amount",
     amountHint: "Enter the total loan amount you want to borrow",
     rateLabel: "Interest Rate",
     rateUnit: "%",
     rateHint: "",
     periodLabel: "Loan Period",
     periodUnit: "years",
     periodHint: "",
     paymentHeading: "Monthly Payment",
     paymentHint: "This is an approximate monthly repayment amount for your mortgage based on the given inputs.",
     interestLabel: "Total Interest Paid",
     interestHint: "This is the total interest you would pay over the entire loan period.",
     ctaHeading: "Ready to get started?",
     ctaHint: "Get in touch with our mortgage advisors for personalized advice!",
     ctaButton: "Book a Meeting",
     ctaHref: "/contact-us"
   },

To change color, change line 34 – 42

colors: {
      title: "",
      label: "",
      smallText: "",
      cardBg: "#f0f6fd",
      cardHeading: "",
      cardValue: "",
      cardMuted: "rgba(17,17,17,0.6)"
    },

To change scroll/track bar style, change line 43 – 50

slider: {
      trackFill: "#197bff",
      trackEmpty: "rgba(17,17,17,0.05)",
      thumbBg: "#ffffff",
      thumbBorder: "rgba(17,17,17,0.1)",
      trackHeight: "6px",
      thumbSize: "24px"
    },

To change button style (it will inherit from Primary Button Style), you can change line 54 to line 61

button: {
      text: "#ffffff",
      bg: "#197bff",
      border: "#197bff",
      hoverText: "#ffffff",
      hoverBg: "#1569e0",
      hoverBorder: "#1569e0"
    },

To set Amount, Rate, Period, change line 62 – 66

ranges: {
     amount: { min: 100000, max: 5000000, step: 10000, value: 1000000 },
     rate: { min: 1, max: 15, step: 0.1, value: 5 },
     period: { min: 5, max: 40, step: 1, value: 30 }
   },

To change formula, change line 67 – 74

formula: {
     currencySymbol: "$",
     moneyDecimals: 0,
     // paymentFn(amount, annualRatePct, years, formula) -> monthly payment
     // interestFn(amount, annualRatePct, years, formula) -> total interest
     paymentFn: null,
     interestFn: null
   }

An example (If you don’t understand it, describe formula then send it to AI, AI will build it for you)

formula: {
  currencySymbol: "$",
  moneyDecimals: 0,
  paymentFn: function (amount, rate, years, F) {
    var totalInterest = amount * (rate / 100) * years;
    return (amount + totalInterest) / (years * 12);
  },
  interestFn: function (amount, rate, years, F) {
    return amount * (rate / 100) * years;
  }
},

Style 03. Car Rental Cost Calculator

If you need to tweak code, send all code to AI (ChatGPT, Claude or this AI chat bot for Squarespace). You can also use this free calculator tool to create a calculator with more layout/styles.

#1.1. You can edit Page where you want to place Calculator > Add a Code Block

#1.2. Add this code into Code Block

<!-- 09.26c14v1(v3) Car Rental Cost Calculator -->
<div class="tp-calc" data-tp-carcalc></div>

<script>
  window.CarRentalCalcConfig = {
    text: {
      title: "",
      daysLabel: "Rental Days",
      daysHint: "Select the number of days you want to rent the car for.",
      carLabel: "Car Type",
      carHint: "Choose the type of car you want to rent.",
      addonsLabel: "Add-ons",
      addonsHint: "Select additional options for your rental.",
      totalHeading: "Total Rental Cost",
      totalHint: "Overall cost of your rental",
      dailyRateLabel: "Daily Rate",
      dailyRateHint: "Cost per day",
      addonsSummaryLabel: "Add-ons",
      addonsSummaryHint: "",
      ctaHeading: "Book Your Rental Car Now",
      ctaHint: "Use our Car Rental Cost Calculator to get a quick estimate. Ready to secure your ride? Click below to proceed!",
      ctaButton: "Reserve Now",
      ctaHref: "/contact-us"
    },
    tags: {
      title: "h2",
      daysLabel: "h3",
      carLabel: "h3",
      addonsLabel: "h3",
      totalHeading: "h3",
      dailyRateLabel: "h4",
      addonsSummaryLabel: "h4",
      ctaHeading: "h2"
    },
    colors: {
      title: "",
      label: "",
      smallText: "",
      cardBg: "#c0392b",
      cardHeading: "#ffffff",
      cardValue: "#ffffff",
      cardMuted: "rgba(255,255,255,0.72)"
    },
    slider: {
      trackFill: "#c0392b",
      trackEmpty: "rgba(17,17,17,0.05)",
      thumbBg: "#ffffff",
      thumbBorder: "rgba(17,17,17,0.1)",
      trackHeight: "6px",
      thumbSize: "24px"
    },
    checkbox: {
      border: "rgba(17,17,17,0.25)",
      checkedBg: "#e74c3c",
      size: "26px",
      radius: "6px"
    },
    layout: {
      inputBorder: "1px solid rgba(17,17,17,0.2)"
    },
    button: {
      text: "#ffffff",
      bg: "#111111",
      border: "#111111",
      hoverText: "#ffffff",
      hoverBg: "#000000",
      hoverBorder: "#000000"
    },
    ranges: {
      days: { min: 1, max: 30, step: 1, value: 1 }
    },
    cars: [
      { label: "Compact", rate: 20 },
      { label: "Sedan", rate: 30 },
      { label: "SUV", rate: 45 },
      { label: "Luxury", rate: 80 }
    ],
    addons: [
      { label: "GPS", price: 5, checked: true },
      { label: "Child Seat", price: 8, checked: false },
      { label: "Insurance", price: 15, checked: false }
    ],
    formula: {
      currencySymbol: "$",
      moneyDecimals: 0,
      // totalFn(days, dailyRate, addonsTotal, formula) -> total rental cost
      totalFn: null
    }
  };
</script>

<script>
  (function () {
    var CFG = window.CarRentalCalcConfig;

    var CSS =
      ".tp-calc,.tp-calc *{box-sizing:border-box}" +
      ".tp-calc{--tp-card-bg:#c0392b;--tp-track-fill:#c0392b;--tp-track-empty:rgba(17,17,17,0.05);--tp-thumb-bg:#fff;--tp-thumb-border:rgba(17,17,17,0.1);--tp-track-h:6px;--tp-thumb-size:24px;--tp-input-border:1px solid rgba(17,17,17,0.2);--tp-check-border:rgba(17,17,17,0.25);--tp-check-bg:#e74c3c;--tp-check-size:26px;--tp-check-radius:6px;--tp-pill-min-width:64px;--tp-card-radius:22px;color:inherit}" +
      ".tp-calc__wrap{max-width:1180px;margin:40px auto;padding:0 24px;display:grid;grid-template-columns:1.1fr 0.9fr;gap:48px;align-items:start}" +
      ".tp-calc__h{margin:0}" +
      ".tp-calc__title{margin:0 0 32px}" +
      ".tp-calc__field{padding:14px 0}" +
      ".tp-calc__labelRow{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:18px}" +
      ".tp-calc__sm{margin:14px 0 0}" +
      ".tp-calc__pill{min-width:var(--tp-pill-min-width);background:#fff;border:var(--tp-input-border);border-radius:12px;padding:12px 16px;display:inline-flex;align-items:center;justify-content:center;font-size:17px;color:#111}" +
      ".tp-calc__num{width:auto;min-width:1ch;border:0;background:transparent;padding:0;margin:0;color:inherit;text-align:center}" +
      ".tp-calc__unit{margin-left:6px}" +
      ".tp-calc__unit--tight{margin-left:2px}" +
      ".tp-calc__range{width:100%;-webkit-appearance:none;appearance:none;height:var(--tp-track-h);border-radius:999px;margin:4px 0 0;cursor:pointer;background:linear-gradient(90deg,var(--tp-track-fill) 0%,var(--tp-track-fill) var(--tp-fill,0%),var(--tp-track-empty) var(--tp-fill,0%),var(--tp-track-empty) 100%)}" +
      ".tp-calc__range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:var(--tp-thumb-size);height:var(--tp-thumb-size);border-radius:50%;background:var(--tp-thumb-bg);border:1px solid var(--tp-thumb-border);box-shadow:0 2px 6px rgba(0,0,0,.15);cursor:pointer}" +
      ".tp-calc__range::-moz-range-thumb{width:var(--tp-thumb-size);height:var(--tp-thumb-size);border-radius:50%;background:var(--tp-thumb-bg);border:1px solid var(--tp-thumb-border);box-shadow:0 2px 6px rgba(0,0,0,.15);cursor:pointer}" +
      ".tp-calc__minmax{display:flex;justify-content:space-between;margin-top:12px}" +
      ".tp-calc__select{position:relative;margin-top:4px}" +
      ".tp-calc__selectTrigger{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;border:var(--tp-input-border);border-radius:12px;padding:16px 18px;font-size:18px;line-height:1.2;background:#fff;color:#111;cursor:pointer}" +
      ".tp-calc__selectValue{flex:1 1 auto}" +
      ".tp-calc__chevron{flex:0 0 auto;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:7px solid rgba(17,17,17,0.55);pointer-events:none;transition:transform .15s}" +
      ".tp-calc__select[data-open='true'] .tp-calc__chevron{transform:rotate(180deg)}" +
      ".tp-calc__options{list-style:none;margin:6px 0 0;padding:6px;position:absolute;left:0;right:0;top:100%;z-index:20;background:#fff;border:var(--tp-input-border);border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.12);display:none}" +
      ".tp-calc__select[data-open='true'] .tp-calc__options{display:block}" +
      ".tp-calc__option{padding:12px 14px;border-radius:8px;font-size:17px;line-height:1.2;cursor:pointer}" +
      ".tp-calc__option:hover{background:rgba(17,17,17,0.05)}" +
      ".tp-calc__option[aria-selected='true']{background:rgba(17,17,17,0.06)}" +
      ".tp-calc__checks{margin-top:6px}" +
      ".tp-calc__check{display:flex;align-items:center;gap:14px;padding:9px 0;cursor:pointer}" +
      ".tp-calc__check input{position:absolute;opacity:0;width:0;height:0}" +
      ".tp-calc__box{flex:0 0 auto;width:var(--tp-check-size);height:var(--tp-check-size);border-radius:var(--tp-check-radius);border:2px solid var(--tp-check-border);background:#fff;position:relative;transition:background .15s,border-color .15s}" +
      ".tp-calc__check input:checked+.tp-calc__box{background:var(--tp-check-bg);border-color:var(--tp-check-bg)}" +
      ".tp-calc__box::after{content:'';position:absolute;left:7px;top:3px;width:6px;height:11px;border:solid #fff;border-width:0 2.5px 2.5px 0;transform:rotate(45deg);opacity:0}" +
      ".tp-calc__check input:checked+.tp-calc__box::after{opacity:1}" +
      ".tp-calc__check input:focus-visible+.tp-calc__box{outline:2px solid var(--tp-check-bg);outline-offset:2px}" +
      ".tp-calc__checkLabel{font-size:18px;line-height:1.2}" +
      ".tp-calc__card{width:100%;background:var(--tp-card-bg);border-radius:var(--tp-card-radius);padding:44px}" +
      ".tp-calc__card .tp-calc__h{margin:0 0 4px}" +
      ".tp-calc__total{font-size:60px;line-height:1;margin:10px 0 6px}" +
      ".tp-calc__etaRow{display:flex;justify-content:space-between;align-items:flex-start;gap:16px}" +
      ".tp-calc__etaVal{font-size:22px;white-space:nowrap}" +
      ".tp-calc__spacer{height:26px}" +
      ".tp-calc__spacer--lg{height:40px}" +
      ".tp-calc a.tp-calc__btn{display:block !important;width:100% !important;text-align:center !important;border-radius:10px !important;margin-top:20px}" +
      "@media (max-width:980px){.tp-calc__wrap{grid-template-columns:1fr;gap:28px}.tp-calc__card{padding:34px}}" +
      "@media (max-width:520px){.tp-calc__card{padding:28px}.tp-calc__total{font-size:52px}}";

    function decl(prop, val) { return val ? prop + ":" + val + " !important;" : ""; }

    function buttonCSS() {
      var B = CFG.button;
      var base = decl("color", B.text) + decl("background-color", B.bg) + decl("border-color", B.border);
      var hover = decl("color", B.hoverText) + decl("background-color", B.hoverBg) + decl("border-color", B.hoverBorder);
      var out = "";
      if (base) out += ".tp-calc a.tp-calc__btn{" + base + "}";
      if (hover) out += ".tp-calc a.tp-calc__btn:hover{" + hover + "}";
      return out;
    }

    function injectCSS() {
      if (window.__carCalcStyled) return;
      window.__carCalcStyled = true;
      var st = document.createElement("style");
      st.type = "text/css";
      st.textContent = CSS + buttonCSS();
      document.head.appendChild(st);
    }

    function el(tag, cls, txt) {
      var e = document.createElement(tag);
      if (cls) e.className = cls;
      if (txt != null) e.textContent = txt;
      return e;
    }

    function heading(tag, txt, color) {
      var e = el(tag, "tp-calc__h", txt);
      if (color) e.style.color = color;
      return e;
    }

    function smallP(txt, color) {
      var e = el("p", "sqsrte-small tp-calc__sm", txt);
      if (color) e.style.color = color;
      return e;
    }

    function stepDecimals(step) {
      var s = String(step);
      var i = s.indexOf(".");
      return i < 0 ? 0 : (s.length - i - 1);
    }

    function fmtNumber(v, decimals) {
      return (+v).toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits: decimals });
    }

    function formatMoney(n) {
      var F = CFG.formula;
      var d = Math.max(0, F.moneyDecimals | 0);
      return F.currencySymbol + (+n).toLocaleString("en-US", { minimumFractionDigits: d, maximumFractionDigits: d });
    }

    function clampNum(v, min, max, decimals) {
      v = +v;
      if (!isFinite(v)) v = min;
      v = Math.min(max, Math.max(min, v));
      var f = Math.pow(10, decimals || 0);
      return Math.round(v * f) / f;
    }

    var measureSpan;
    function autosize(input) {
      if (!measureSpan) {
        measureSpan = document.createElement("span");
        measureSpan.style.cssText = "position:absolute;visibility:hidden;white-space:pre;left:-9999px;top:0";
        document.body.appendChild(measureSpan);
      }
      var cs = window.getComputedStyle(input);
      measureSpan.style.fontFamily = cs.fontFamily;
      measureSpan.style.fontSize = cs.fontSize;
      measureSpan.style.fontWeight = cs.fontWeight;
      measureSpan.style.fontStyle = cs.fontStyle;
      measureSpan.style.letterSpacing = cs.letterSpacing;
      measureSpan.textContent = input.value || "0";
      input.style.width = (measureSpan.offsetWidth + 2) + "px";
    }

    function numField(o) {
      var decimals = stepDecimals(o.r.step);
      var node = el("div", "tp-calc__field");
      var row = el("div", "tp-calc__labelRow");
      row.appendChild(heading(o.tag, o.label, CFG.colors.label));

      var pill = el("div", "tp-calc__pill");
      var input = el("input", "tp-calc__num");
      input.type = "text";
      input.setAttribute("inputmode", decimals ? "decimal" : "numeric");
      input.setAttribute("aria-label", o.label);
      pill.appendChild(input);
      if (o.suffix) {
        pill.appendChild(el("span", "tp-calc__unit" + (o.suffixTight ? " tp-calc__unit--tight" : ""), o.suffix));
      }
      row.appendChild(pill);
      node.appendChild(row);

      var range = el("input", "tp-calc__range");
      range.type = "range";
      range.min = o.r.min; range.max = o.r.max; range.step = o.r.step; range.value = o.r.value;
      range.setAttribute("aria-label", o.label);
      node.appendChild(range);

      var mm = el("div", "tp-calc__minmax");
      var s1 = el("span", "sqsrte-small", labelText(o.r.min));
      var s2 = el("span", "sqsrte-small", labelText(o.r.max));
      if (CFG.colors.smallText) { s1.style.color = CFG.colors.smallText; s2.style.color = CFG.colors.smallText; }
      mm.appendChild(s1); mm.appendChild(s2);
      node.appendChild(mm);

      if (o.hint) node.appendChild(smallP(o.hint, CFG.colors.smallText));

      function labelText(v) {
        var s = (o.prefix || "") + fmtNumber(v, decimals);
        if (o.suffix) s += (o.suffixTight ? "" : " ") + o.suffix;
        return s;
      }
      function disp(v) { return (o.prefix || "") + fmtNumber(v, decimals); }
      function get() {
        var cleaned = (input.value || "").replace(/[^0-9.]/g, "");
        var v = cleaned === "" ? o.r.min : parseFloat(cleaned);
        return clampNum(v, o.r.min, o.r.max, decimals);
      }
      function fill() {
        var v = +range.value, min = +range.min, max = +range.max;
        range.style.setProperty("--tp-fill", ((v - min) / (max - min)) * 100 + "%");
      }
      function sync(v) { range.value = v; fill(); autosize(input); }

      var cb = function () {};
      input.addEventListener("input", function () { autosize(input); cb(); });
      input.addEventListener("change", function () { input.value = disp(get()); autosize(input); cb(); });
      range.addEventListener("input", function () { input.value = disp(+range.value); autosize(input); cb(); });

      input.value = disp(o.r.value);
      fill();

      return { node: node, get: get, sync: sync, onChange: function (f) { cb = f; } };
    }

    function selectField(o) {
      var node = el("div", "tp-calc__field");
      node.appendChild(heading(o.tag, o.label, CFG.colors.label));

      var sel = el("div", "tp-calc__select");
      sel.setAttribute("data-open", "false");

      var trigger = el("div", "tp-calc__selectTrigger");
      trigger.setAttribute("role", "button");
      trigger.setAttribute("tabindex", "0");
      trigger.setAttribute("aria-haspopup", "listbox");
      trigger.setAttribute("aria-expanded", "false");
      trigger.setAttribute("aria-label", o.label);
      var valueEl = el("span", "tp-calc__selectValue", o.options[0].label);
      trigger.appendChild(valueEl);
      trigger.appendChild(el("span", "tp-calc__chevron"));
      sel.appendChild(trigger);

      var list = el("ul", "tp-calc__options");
      list.setAttribute("role", "listbox");
      var lis = [];
      for (var i = 0; i < o.options.length; i++) {
        var li = el("li", "tp-calc__option", o.options[i].label);
        li.setAttribute("role", "option");
        li.setAttribute("data-i", String(i));
        li.setAttribute("aria-selected", i === 0 ? "true" : "false");
        list.appendChild(li);
        lis.push(li);
      }
      sel.appendChild(list);
      node.appendChild(sel);
      if (o.hint) node.appendChild(smallP(o.hint, CFG.colors.smallText));

      var idx = 0;
      var cb = function () {};

      function open() { sel.setAttribute("data-open", "true"); trigger.setAttribute("aria-expanded", "true"); }
      function close() { sel.setAttribute("data-open", "false"); trigger.setAttribute("aria-expanded", "false"); }
      function toggle() { if (sel.getAttribute("data-open") === "true") close(); else open(); }
      function choose(i) {
        idx = i;
        valueEl.textContent = o.options[i].label;
        for (var k = 0; k < lis.length; k++) lis[k].setAttribute("aria-selected", k === i ? "true" : "false");
        close();
        cb();
      }

      trigger.addEventListener("click", toggle);
      trigger.addEventListener("keydown", function (e) {
        var k = e.keyCode || 0;
        if (e.key === "Enter" || e.key === " " || k === 13 || k === 32) { e.preventDefault(); toggle(); }
        else if (e.key === "Escape" || k === 27) close();
      });
      for (var j = 0; j < lis.length; j++) {
        (function (n) { lis[n].addEventListener("click", function () { choose(n); }); })(j);
      }
      document.addEventListener("click", function (e) { if (!sel.contains(e.target)) close(); });

      return { node: node, get: function () { return o.options[idx]; }, onChange: function (f) { cb = f; } };
    }

    function checkboxGroup(o) {
      var node = el("div", "tp-calc__field");
      node.appendChild(heading(o.tag, o.label, CFG.colors.label));
      if (o.hint) node.appendChild(smallP(o.hint, CFG.colors.smallText));
      var box = el("div", "tp-calc__checks");
      var inputs = [];
      for (var i = 0; i < o.items.length; i++) {
        var item = o.items[i];
        var lab = el("label", "tp-calc__check");
        var inp = el("input");
        inp.type = "checkbox";
        inp.checked = !!item.checked;
        lab.appendChild(inp);
        lab.appendChild(el("span", "tp-calc__box"));
        lab.appendChild(el("span", "tp-calc__checkLabel", item.label));
        box.appendChild(lab);
        inputs.push({ input: inp, price: +item.price });
      }
      node.appendChild(box);
      var cb = function () {};
      for (var j = 0; j < inputs.length; j++) inputs[j].input.addEventListener("change", function () { cb(); });
      return {
        node: node,
        total: function () {
          var t = 0;
          for (var k = 0; k < inputs.length; k++) if (inputs[k].input.checked) t += inputs[k].price;
          return t;
        },
        onChange: function (f) { cb = f; }
      };
    }

    function summaryRow(tag, label, hint) {
      var row = el("div", "tp-calc__etaRow");
      var lft = el("div");
      lft.appendChild(heading(tag, label, CFG.colors.cardHeading));
      if (hint) lft.appendChild(smallP(hint, CFG.colors.cardMuted));
      var val = el("div", "tp-calc__etaVal");
      if (CFG.colors.cardValue) val.style.color = CFG.colors.cardValue;
      row.appendChild(lft); row.appendChild(val);
      return { row: row, val: val };
    }

    function mount(root) {
      if (!root || root.dataset.tpDone === "1") return;
      root.dataset.tpDone = "1";

      var T = CFG.text, G = CFG.tags, K = CFG.colors, S = CFG.slider, C = CFG.checkbox, R = CFG.ranges, F = CFG.formula;

      root.style.setProperty("--tp-card-bg", K.cardBg);
      root.style.setProperty("--tp-track-fill", S.trackFill);
      root.style.setProperty("--tp-track-empty", S.trackEmpty);
      root.style.setProperty("--tp-thumb-bg", S.thumbBg);
      root.style.setProperty("--tp-thumb-border", S.thumbBorder);
      root.style.setProperty("--tp-track-h", S.trackHeight);
      root.style.setProperty("--tp-thumb-size", S.thumbSize);
      root.style.setProperty("--tp-check-border", C.border);
      root.style.setProperty("--tp-check-bg", C.checkedBg);
      root.style.setProperty("--tp-check-size", C.size);
      root.style.setProperty("--tp-check-radius", C.radius);
      root.style.setProperty("--tp-input-border", CFG.layout.inputBorder);

      var wrap = el("div", "tp-calc__wrap");
      var left = el("div", "tp-calc__left");
      var right = el("div", "tp-calc__right");

      if (T.title) {
        var title = heading(G.title, T.title, K.title);
        title.classList.add("tp-calc__title");
        left.appendChild(title);
      }

      var daysField = numField({ label: T.daysLabel, tag: G.daysLabel, hint: T.daysHint, r: R.days });
      left.appendChild(daysField.node);

      var carField = selectField({ label: T.carLabel, tag: G.carLabel, hint: T.carHint, options: CFG.cars });
      left.appendChild(carField.node);

      var addonsField = checkboxGroup({ label: T.addonsLabel, tag: G.addonsLabel, hint: T.addonsHint, items: CFG.addons });
      left.appendChild(addonsField.node);

      var card = el("div", "tp-calc__card");
      card.appendChild(heading(G.totalHeading, T.totalHeading, K.cardHeading));
      var total = el("div", "tp-calc__total");
      if (K.cardValue) total.style.color = K.cardValue;
      card.appendChild(total);
      card.appendChild(smallP(T.totalHint, K.cardMuted));

      card.appendChild(el("div", "tp-calc__spacer tp-calc__spacer--lg"));
      var daily = summaryRow(G.dailyRateLabel, T.dailyRateLabel, T.dailyRateHint);
      card.appendChild(daily.row);

      card.appendChild(el("div", "tp-calc__spacer"));
      var addonsRow = summaryRow(G.addonsSummaryLabel, T.addonsSummaryLabel, T.addonsSummaryHint);
      card.appendChild(addonsRow.row);

      card.appendChild(el("div", "tp-calc__spacer tp-calc__spacer--lg"));
      card.appendChild(heading(G.ctaHeading, T.ctaHeading, K.cardHeading));
      card.appendChild(smallP(T.ctaHint, K.cardMuted));

      var btn = el("a", "btn btn--border theme-btn--primary-inverse sqs-button-element--primary tp-calc__btn", T.ctaButton);
      btn.setAttribute("href", T.ctaHref);
      btn.setAttribute("rel", "noopener");
      card.appendChild(btn);

      right.appendChild(card);
      wrap.appendChild(left); wrap.appendChild(right);
      root.appendChild(wrap);

      function recalc() {
        var days = daysField.get();
        daysField.sync(days);
        var car = carField.get();
        var dailyRate = +car.rate;
        var addonsTotal = addonsField.total();
        var totalVal = (typeof F.totalFn === "function")
          ? F.totalFn(days, dailyRate, addonsTotal, F)
          : days * dailyRate + addonsTotal;
        total.textContent = formatMoney(totalVal);
        daily.val.textContent = formatMoney(dailyRate);
        addonsRow.val.textContent = formatMoney(addonsTotal);
      }

      daysField.onChange(recalc);
      carField.onChange(recalc);
      addonsField.onChange(recalc);
      recalc();
    }

    function init() {
      var nodes = document.querySelectorAll("[data-tp-carcalc]");
      for (var i = 0; i < nodes.length; i++) mount(nodes[i]);
    }

    function ready(fn) {
      if (document.readyState !== "loading") fn();
      else document.addEventListener("DOMContentLoaded", fn);
    }

    injectCSS();
    ready(init);

    if (!window.__carCalcBound) {
      window.__carCalcBound = true;
      window.addEventListener("mercury:load", init);
    }
  })();
</script>

#2.1. To change text + button url, change line 06 – 24

text: {
     title: "",
     daysLabel: "Rental Days",
     daysHint: "Select the number of days you want to rent the car for.",
     carLabel: "Car Type",
     carHint: "Choose the type of car you want to rent.",
     addonsLabel: "Add-ons",
     addonsHint: "Select additional options for your rental.",
     totalHeading: "Total Rental Cost",
     totalHint: "Overall cost of your rental",
     dailyRateLabel: "Daily Rate",
     dailyRateHint: "Cost per day",
     addonsSummaryLabel: "Add-ons",
     addonsSummaryHint: "",
     ctaHeading: "Book Your Rental Car Now",
     ctaHint: "Use our Car Rental Cost Calculator to get a quick estimate. Ready to secure your ride? Click below to proceed!",
     ctaButton: "Reserve Now",
     ctaHref: "/contact-us"
   },

#2.2. Style will inherit from Tags. You can set tags for: title, description, paragraph, button. at line 25 – 34

tags: {
  title: "h2",
  daysLabel: "h3",
  carLabel: "h3",
  addonsLabel: "h3",
  totalHeading: "h3",
  dailyRateLabel: "h4",
  addonsSummaryLabel: "h4",
  ctaHeading: "h2"
},

#2.3. To change color, change line 35 – 43

  • Color will inherit from Tags. So if you use Heading 2 (h2), you can change Color in Site Styles
colors: {
  title: "",
  label: "",
  smallText: "",
  cardBg: "#c0392b",
  cardHeading: "#ffffff",
  cardValue: "#ffffff",
  cardMuted: "rgba(255,255,255,0.72)"
},

#2.4. To change slider + checkbox, change line 44 – 57

slider: {
     trackFill: "#c0392b",
     trackEmpty: "rgba(17,17,17,0.05)",
     thumbBg: "#ffffff",
     thumbBorder: "rgba(17,17,17,0.1)",
     trackHeight: "6px",
     thumbSize: "24px"
   },
   checkbox: {
     border: "rgba(17,17,17,0.25)",
     checkedBg: "#e74c3c",
     size: "26px",
     radius: "6px"
   },

#2.5. To change button style, change line 61 – 68

button: {
  text: "#ffffff",
  bg: "#111111",
  border: "#111111",
  hoverText: "#ffffff",
  hoverBg: "#000000",
  hoverBorder: "#000000"
},

#2.6. To set Rental Days, Cart Type, Addons, change line 69 – 82

ranges: {
     days: { min: 1, max: 30, step: 1, value: 1 }
   },
   cars: [
     { label: "Compact", rate: 20 },
     { label: "Sedan", rate: 30 },
     { label: "SUV", rate: 45 },
     { label: "Luxury", rate: 80 }
   ],
   addons: [
     { label: "GPS", price: 5, checked: true },
     { label: "Child Seat", price: 8, checked: false },
     { label: "Insurance", price: 15, checked: false }
   ],

#2.7. To change formula, change line 67 – 74

formula: {
      currencySymbol: "$",
      moneyDecimals: 0,
      // totalFn(days, dailyRate, addonsTotal, formula) -> total rental cost
      totalFn: null
    }

an example formula

formula: {
  currencySymbol: "$",
  moneyDecimals: 0,
  // totalFn(days, dailyRate, addonsTotal, formula) -> total rental cost
  totalFn: function (days, dailyRate, addonsTotal, formula) {
    var base = days * dailyRate;
    if (days >= 7) base = base * 0.9;
    return (base + addonsTotal) * 1.08;
  }
}

or

totalFn: function (days, dailyRate, addonsTotal) {
       return days * (dailyRate + addonsTotal);
     }

or

totalFn: function (days, dailyRate, addonsTotal) {
       return days * dailyRate + addonsTotal + 30;
     }