Pricing
Base plan with add-ons
Core price plus optional modules
Core price plus optional modules
Create an à-la-carte pricing block with Tailwind CSS. A dark rounded-2xl base plan card on the left showing the plan name, price, and what is included. On the right, a stacked list of optional add-on rows, each a label wrapping a checkbox carrying a data-price attribute, with a name, a one-line description, and a price on the far right; one row is pre-checked and highlighted with a ring. Below the list show a running total row and a checkout button. Then add JavaScript that recalculates the total from the base fee plus every checked add-on, moves the selected ring styling onto the rows that are actually checked, and updates the checkout button to name how many add-ons are included. <section class="mx-auto grid max-w-5xl gap-6 px-6 py-16 lg:grid-cols-5">
<div class="rounded-2xl bg-neutral-900 p-8 lg:col-span-2">
<h3 class="font-medium text-white">Core platform</h3>
<p class="mt-4"><span class="text-4xl font-semibold text-white">$99</span><span class="text-neutral-400">/mo</span></p>
<p class="mt-2 text-sm text-neutral-400">Everything a small team needs to run day to day.</p>
<ul class="mt-6 space-y-2.5 text-sm text-neutral-300">
<li class="flex gap-2"><span class="text-white"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m5 12.5 4.25 4.25L19 7"/></svg></span> 25 seats included</li>
<li class="flex gap-2"><span class="text-white"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m5 12.5 4.25 4.25L19 7"/></svg></span> Unlimited workspaces</li>
<li class="flex gap-2"><span class="text-white"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m5 12.5 4.25 4.25L19 7"/></svg></span> Standard support</li>
</ul>
</div>
<div class="lg:col-span-3">
<h3 class="text-sm font-medium text-neutral-900">Add what you need</h3>
<div id="addons" class="mt-3 space-y-2">
<label class="flex cursor-pointer items-center gap-4 rounded-xl border border-neutral-900 bg-white p-4 ring-4 ring-neutral-900/10">
<input type="checkbox" checked data-price="40" class="rounded border-neutral-300 accent-neutral-900" />
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">Advanced analytics</span>
<span class="block text-xs text-neutral-500">Cohorts, funnels, and retention reports.</span>
</span>
<span class="text-sm font-medium text-neutral-900">+$40</span>
</label>
<label class="flex cursor-pointer items-center gap-4 rounded-xl border border-neutral-200 bg-white p-4 hover:bg-neutral-50">
<input type="checkbox" data-price="60" class="rounded border-neutral-300 accent-neutral-900" />
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">SSO & SCIM</span>
<span class="block text-xs text-neutral-500">Okta, Entra ID, and automated provisioning.</span>
</span>
<span class="text-sm font-medium text-neutral-900">+$60</span>
</label>
<label class="flex cursor-pointer items-center gap-4 rounded-xl border border-neutral-200 bg-white p-4 hover:bg-neutral-50">
<input type="checkbox" data-price="85" class="rounded border-neutral-300 accent-neutral-900" />
<span class="flex-1">
<span class="block text-sm font-medium text-neutral-900">Priority support</span>
<span class="block text-xs text-neutral-500">One-hour response, 24/7, with a named engineer.</span>
</span>
<span class="text-sm font-medium text-neutral-900">+$85</span>
</label>
</div>
<div class="mt-4 flex items-center justify-between rounded-xl bg-neutral-100 px-4 py-3">
<span class="text-sm text-neutral-600">Total per month</span>
<span id="total" class="text-lg font-semibold text-neutral-900">$139</span>
</div>
<button id="checkout" class="mt-3 w-full rounded-xl bg-neutral-900 py-3 text-sm font-medium text-white hover:bg-neutral-800">Continue to checkout</button>
</div>
</section> var BASE = 99;
var boxes = [].slice.call(document.querySelectorAll("#addons input[type=checkbox]"));
var total = document.getElementById("total");
var checkout = document.getElementById("checkout");
var SELECTED = "flex cursor-pointer items-center gap-4 rounded-xl border border-neutral-900 bg-white p-4 ring-4 ring-neutral-900/10";
var IDLE = "flex cursor-pointer items-center gap-4 rounded-xl border border-neutral-200 bg-white p-4 hover:bg-neutral-50";
function render() {
var sum = BASE;
var picked = 0;
boxes.forEach(function (box) {
var row = box.closest("label");
if (box.checked) {
sum += Number(box.getAttribute("data-price"));
picked += 1;
}
row.className = box.checked ? SELECTED : IDLE;
});
total.textContent = "$" + sum;
checkout.textContent =
picked === 0
? "Continue to checkout"
: "Continue with " + picked + " add-" + (picked === 1 ? "on" : "ons");
}
boxes.forEach(function (box) {
box.addEventListener("change", render);
});
render();