webdevpuneet.com

Lifetime Deal Pricing Card — Free HTML CSS JS Snippet, Real Payback Math

Lifetime Deal Pricing Card · Pricing · Plain HTML, CSS & JS · Live preview

CategoryPricing

Copy & paste

Source Code

<div class="ldc-wrap">
  <div class="ldc-card">
    <span class="ldc-badge">Limited-time lifetime deal</span>
    <h2 class="ldc-title">Pay once. Own it forever.</h2>

    <div class="ldc-compare">
      <div class="ldc-option">
        <p class="ldc-option-label">Lifetime access</p>
        <p class="ldc-option-price">$299<span>one-time</span></p>
      </div>
      <div class="ldc-vs">vs</div>
      <div class="ldc-option ldc-option-muted">
        <p class="ldc-option-label">Monthly subscription</p>
        <p class="ldc-option-price">$19<span>/month, forever</span></p>
      </div>
    </div>

    <div class="ldc-payback">
      <p class="ldc-payback-text">Lifetime access pays for itself after <strong id="ldcPaybackMonths">—</strong> months of subscription payments — everything after that is money the subscription would have kept charging you.</p>
    </div>

    <div class="ldc-availability">
      <div class="ldc-availability-row">
        <span id="ldcRemainingText">— licenses remaining</span>
        <span id="ldcClaimedPct">—</span>
      </div>
      <div class="ldc-bar"><div class="ldc-bar-fill" id="ldcBarFill"></div></div>
      <p class="ldc-availability-note">Once all 200 licenses are claimed, this deal is gone for good — the plan reverts to subscription-only.</p>
    </div>

    <button class="ldc-cta">Claim lifetime access — $299</button>
    <p class="ldc-fineprint">One payment. No renewals, no recurring charge, ever.</p>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real payback-period math
Math.ceil(lifetime / monthly), correctly rounded up.
Side-by-side price contrast
Lifetime and subscription prices shown together, not in isolation.
Genuinely computed scarcity
Bar width and remaining count derive from the same two numbers.
Animated bar fill
Fills to the real percentage on load via requestAnimationFrame.
Honest urgency copy
States a real, finite constraint, not vague pressure.
Clear one-time-payment framing
Fine print reinforces no renewals, ever.
Four-constant customization
Every number on the card derives from four editable values.
Zero dependencies
Pure HTML, CSS, and vanilla JS.

About this UI Snippet

Lifetime Deal Pricing Card — Computed Payback Period and a Real Licenses-Remaining Bar

Screenshot of the Lifetime Deal Pricing Card snippet rendered live

Lifetime deals live or die on one piece of arithmetic: how long does it take before paying once is actually cheaper than paying monthly forever? This snippet computes that number for real — Math.ceil(LIFETIME_PRICE / MONTHLY_PRICE) — rather than writing an arbitrary "pays for itself fast!" claim, and pairs it with a licenses-remaining progress bar built from real claimed/total counts instead of a fake, endlessly-refreshing urgency bar.

The payback period, computed and rounded correctly

At \$299 lifetime versus \$19/month, the raw division is \$299 ÷ \$19 = 15.7368… months. The snippet uses Math.ceil(), not a truncated or rounded-to-nearest value, because the question being answered is "after how many *whole* months of payments does cumulative subscription cost first exceed the lifetime price?" — and 15 months of \$19 payments totals only \$285 (still less than \$299), while 16 months totals \$304 (the first month that actually exceeds it). Rounding down or to-nearest would overstate the deal's value by claiming payback a month earlier than the math actually supports.

Why licenses-remaining needs to be a real fraction, not a decoration

The availability bar's fill width is computed as (CLAIMED_LICENSES / TOTAL_LICENSES) * 100 — at 153 of 200 claimed, that's exactly 76.5%, and the bar's visual width and the "47 of 200 remaining" text both derive from the same two constants. This matters because a scarcity bar with a number that doesn't match its own visual fill (or that resets on every page load regardless of actual claims) is a well-recognized dark pattern that erodes trust the moment a visitor notices the mismatch — this snippet's bar width and its stated numbers are structurally guaranteed to agree, because both come from the same division.

Contrast, not just a headline price

The lifetime price sits directly beside the ongoing subscription price in a two-column comparison, rather than showing the lifetime price in isolation and leaving the "instead of what?" question to the visitor's imagination. Seeing "\$299 once" next to "\$19/month, forever" is what makes the payback-period math feel concrete rather than abstract — the visitor can see exactly what they're comparing before reading the computed months figure.

Urgency that's honest about its own mechanics

The fine print states plainly that once all 200 licenses are claimed, the deal reverts to subscription-only — a real, finite constraint rather than vague "act now" pressure with no actual limit behind it. Pairing a genuinely limited quantity with a genuinely computed payback period is what separates a legitimate lifetime-deal launch from a manufactured-scarcity dark pattern.

Customizing it

Change LIFETIME_PRICE, MONTHLY_PRICE, TOTAL_LICENSES, and CLAIMED_LICENSES — the payback months, the remaining count, the claimed percentage, and the bar's fill width all recalculate from those four constants. Wire CLAIMED_LICENSES to your real database count in production so the bar reflects actual, live claims rather than a static demo number.

Step by step

How to Use

  1. 1
    Compare the two pricesLifetime and monthly sit side by side so the trade-off is concrete.
  2. 2
    Read the computed payback lineThe month count is Math.ceil(lifetime price / monthly price), not a guess.
  3. 3
    Watch the availability bar animate inIts fill width is the real claimed/total percentage.
  4. 4
    Check the remaining countThe text and the bar width are guaranteed to agree — both derive from the same numbers.
  5. 5
    Change the pricesEdit LIFETIME_PRICE or MONTHLY_PRICE — the payback month recalculates.
  6. 6
    Wire claimed count to real dataReplace CLAIMED_LICENSES with a live count from your backend.

Real-world uses

Common Use Cases

Indie SaaS launches
Run the classic lifetime deal with a computed payback period, Math.ceil(lifetime / monthly), so buyers see when paying once becomes cheaper.
Deal site listings
Model the payback pitch honestly on AppSumo-style pages, showing lifetime and subscription prices side by side rather than in separate boxes.
Subscription alongside lifetime
Pair with a pricing card for the ongoing plan, so the contrast is visible in one view.
Founder-led product launches
Justify a one-time price with a real licences-remaining bar whose width and count both derive from the same two numbers.
Scarcity bar reuse and teaching
Reuse the animated fill, driven by requestAnimationFrame, for limited-run unlocks, and learn honest scarcity UI where the number is computed and never invented.
Related: Limited-Time Discount Banner
See the Limited-Time Discount Banner for a related pricing pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Because the question is "after how many whole months does the subscription cost actually exceed the lifetime price," not "roughly how many months." At $299 lifetime versus $19/month, 15 months of payments totals $285 — still less than $299 — while 16 months totals $304, the first month that genuinely exceeds it. Rounding to nearest (which would give 16 anyway here, but wouldn't in every case) or truncating down would misstate the real crossover point.

Yes — the bar's fill width is computed as (CLAIMED_LICENSES / TOTAL_LICENSES) * 100, and the "47 of 200 remaining" text is computed from the same two constants (TOTAL_LICENSES minus CLAIMED_LICENSES). Both numbers are structurally guaranteed to agree because they derive from the same source, unlike a decorative scarcity bar whose displayed count and visual fill could silently drift apart.

The payback-period claim is meaningless without a comparison point — "pays for itself after 16 months" only means something next to the $19/month figure it is being compared against. Showing both prices side by side lets a skeptical visitor verify the payback math themselves rather than taking a bare "great value!" claim on faith.

The scarcity messaging here is deliberately built to be honest: the remaining-license count and bar fill are real computed values tied to an actual finite quantity (200 total licenses), and the copy states plainly what happens when they run out. The distinction from a dark pattern is whether the constraint is real and consistently represented — a bar that resets on every visit or a count that does not match its own visual fill would cross that line; this one is structured not to.

Replace the hardcoded CLAIMED_LICENSES constant with a value fetched from your backend (e.g. a count query against your licenses table) before the calculation runs, ideally cached briefly rather than queried on every single page view. Every other computed value on the card — remaining count, claimed percentage, and bar width — will then reflect the real live count automatically.