Lab

Pricing Lab

Seven pricing page patterns — from classic three-tier cards to usage-based calculators and enterprise CTA panels.

1. Three-Tier Cards — classic pricing with featured middle tier

Starter

$9/mo

For personal projects

  • 1 user
  • 10 projects
  • Community support
Get started

Team

$99/mo

For organizations

  • Unlimited users
  • SSO / SAML
  • Dedicated CSM
Contact sales
<div class="cards">
  <div class="card">
    <h3>Starter</h3>
    <div class="price">$9<span>/mo</span></div>
    <p style="color:#888;font-size:14px;">For personal projects</p>
    <ul>
      <li class="check">1 user</li>
      <li class="check">10 projects</li>
      <li class="check">Community support</li>
    </ul>
    <a class="cta">Get started</a>
  </div>
  <div class="card featured">
    <div class="badge">Most Popular</div>
    <h3>Pro</h3>
    <div class="price">$29<span>/mo</span></div>
    <p style="color:#a0a0b0;font-size:14px;">For growing teams</p>
    <ul>
      <li class="check">10 users</li>
      <li class="check">Unlimited projects</li>
      <li class="check">Priority support</li>
      <li class="check">Advanced analytics</li>
    </ul>
    <a class="cta">Start free trial</a>
  </div>
  <div class="card">
    <h3>Team</h3>
    <div class="price">$99<span>/mo</span></div>
    <p style="color:#888;font-size:14px;">For organizations</p>
    <ul>
      <li class="check">Unlimited users</li>
      <li class="check">SSO / SAML</li>
      <li class="check">Dedicated CSM</li>
    </ul>
    <a class="cta">Contact sales</a>
  </div>
</div>
.card.featured {
  background: #111;
  color: #fff;
  transform: scale(1.03);
}

.badge {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  background: linear-gradient(135deg, #ec4899, #8b5cf6);
}

.check::before {
  content: "✓";
  color: #10b981;
  font-weight: 700;
}

2. Monthly / Annual Toggle — save 20% with annual billing

Simple, transparent pricing

Pay monthly or save 20% with annual billing.

Starter

$79/mo

Billed annually

  • Unlimited projects
  • Basic support

Pro

$2329/mo

Billed annually

  • All Starter features
  • Priority support
  • API access

Team

$7999/mo

Billed annually

  • All Pro features
  • SSO
  • Dedicated CSM
<div class="top">
  <h2>Simple, transparent pricing</h2>
  <p>Pay monthly or save 20% with annual billing.</p>
</div>

<div class="toggle">
  <span class="indicator"></span>
  <button data-b="monthly">Monthly</button>
  <button class="active" data-b="yearly">Yearly<small>-20%</small></button>
</div>

<div class="cards">
  <div class="card">
    <h3>Starter</h3>
    <div class="price">$<span class="yearly">7</span><span class="monthly">9</span>/mo</div>
    <p>Billed annually</p>
    <ul>
      <li class="check">Unlimited projects</li>
      <li class="check">Basic support</li>
    </ul>
  </div>

  <div class="card">
    <h3>Pro</h3>
    <div class="price">$<span class="yearly">23</span><span class="monthly">29</span>/mo</div>
    <p>Billed annually</p>
    <ul>
      <li class="check">All Starter features</li>
      <li class="check">Priority support</li>
      <li class="check">API access</li>
    </ul>
  </div>

  <div class="card">
    <h3>Team</h3>
    <div class="price">$<span class="yearly">79</span><span class="monthly">99</span>/mo</div>
    <p>Billed annually</p>
    <ul>
      <li class="check">All Pro features</li>
      <li class="check">SSO</li>
      <li class="check">Dedicated CSM</li>
    </ul>
  </div>
</div>
/* Show/hide prices based on parent class */
.cards .monthly         { display: none; }
.cards.monthly .monthly { display: inline; }
.cards.monthly .yearly  { display: none; }
const toggle = document.getElementById('v2toggle');
const cards = document.getElementById('v2cards');
const indicator = toggle.querySelector('.indicator');

toggle.querySelectorAll('button').forEach(btn => {
  btn.addEventListener('click', () => {
    toggle.querySelectorAll('button').forEach(b => b.classList.remove('active'));
    btn.classList.add('active');
    cards.classList.toggle('monthly', btn.dataset.b === 'monthly');
    indicator.style.left = btn.offsetLeft + 'px';
    indicator.style.width = btn.offsetWidth + 'px';
  });
});

3. Comparison Table — side-by-side plan features

Starter
$9/mo
Pro
$29/mo
Team
$99/mo
Projects10UnlimitedUnlimited
Users110Unlimited
Storage5 GB100 GB1 TB
API access
Custom domain
SSO / SAML
Dedicated CSM
Priority support
<table>
  <thead><tr>
    <th></th>
    <th><div class="plan-name">Starter</div><div class="plan-price">$9<span>/mo</span></div></th>
    <th class="featured"><div class="plan-name">Pro</div><div class="plan-price">$29<span>/mo</span></div></th>
    <th><div class="plan-name">Team</div><div class="plan-price">$99<span>/mo</span></div></th>
  </tr></thead>
  <tbody>
    <tr><td>Projects</td><td>10</td><td>Unlimited</td><td>Unlimited</td></tr>
    <tr><td>Users</td><td>1</td><td>10</td><td>Unlimited</td></tr>
    <tr><td>Storage</td><td>5 GB</td><td>100 GB</td><td>1 TB</td></tr>
    <tr><td>API access</td><td class="x"></td><td class="check"></td><td class="check"></td></tr>
    <tr><td>Custom domain</td><td class="x"></td><td class="check"></td><td class="check"></td></tr>
    <tr><td>SSO / SAML</td><td class="x"></td><td class="x"></td><td class="check"></td></tr>
    <tr><td>Dedicated CSM</td><td class="x"></td><td class="x"></td><td class="check"></td></tr>
    <tr><td>Priority support</td><td class="x"></td><td class="check"></td><td class="check"></td></tr>
  </tbody>
</table>
/* Featured column gets a top border accent */
thead .featured {
  background: #fef7ed;
  border-top: 3px solid #ec4899;
}

td.check { color: #10b981; font-weight: 700; }
td.x     { color: #ccc; }

4. Usage-Based Calculator — drag sliders, see total update live

Calculate your price

Only pay for what you use. Adjust the sliders to see your monthly total.

Team members8
Storage (GB)120
API calls / month50k
Estimated monthly
$182
Billed monthly
Cancel anytime
Start 14-day trial
<div class="calc">
  <h3>Calculate your price</h3>
  <p class="sub">Only pay for what you use. Adjust the sliders to see your monthly total.</p>

<div class="slider-row">
  <div class="top">
    <span>Team members</span>
    <strong id="users">8</strong>
  </div>
  <input type="range" id="s1" value="8">
</div>

<div class="slider-row">
  <div class="top">
    <span>Storage (GB)</span>
    <strong id="storage">120</strong>
  </div>
  <input type="range" id="s2" value="120">
</div>

<div class="slider-row">
  <div class="top">
    <span>API calls / month</span>
    <strong id="api">50k</strong>
  </div>
  <input type="range" id="s3" value="50">
</div>

<div class="total">
  <div><small>Estimated monthly</small><br><strong>$<span id="total">182</span></strong></div>
  <div>Billed monthly<br>Cancel anytime</div>
</div>
<a href="#" class="cta">Start 14-day trial</a>
</div>
.calc {
  background: #fff;
  border: 1px solid #eee;
  border-radius: 16px;
  padding: 30px;
}

.slider-row .top {
  display: flex;
  justify-content: space-between;
  font-size: 14px;
}
.slider-row .top strong { color: #ec4899; font-weight: 800; }   /* the live value */

input[type=range] {
  -webkit-appearance: none;
  width: 100%; height: 6px;
  background: #e5e7eb; border-radius: 999px;
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 22px; height: 22px; border-radius: 50%;
  background: linear-gradient(135deg, #ec4899, #8b5cf6);
}

.total {
  display: flex;
  justify-content: space-between;
  padding: 20px; border-radius: 12px;
  background: linear-gradient(135deg, #fdf2f8, #eff6ff);
}
const calc = () => {
  const u = +document.getElementById('s1').value;
  const s = +document.getElementById('s2').value;
  const a = +document.getElementById('s3').value;

  // Simple pricing formula
  const total = u * 9 + s * 0.5 + a * 1;

  document.getElementById('users').textContent = u;
  document.getElementById('storage').textContent = s;
  document.getElementById('total').textContent = Math.round(total);
};

['s1', 's2', 's3'].forEach(id =>
  document.getElementById(id).addEventListener('input', calc)
);

5. Feature Matrix — grouped rows with section headers

Starter$9/mo
Pro$29/mo
Team$99/mo
Core
Projects
10
Unlimited
Unlimited
Users
1
10
Unlimited
Storage
5 GB
100 GB
1 TB
Integrations
API access
Webhooks
Zapier
Security
2FA
SSO / SAML
Audit log
<div class="matrix">
  <div class="head"></div>
  <div class="head"><strong>Starter</strong><small>$9/mo</small></div>
  <div class="head"><strong>Pro</strong><small>$29/mo</small></div>
  <div class="head"><strong>Team</strong><small>$99/mo</small></div>

  <!-- Section spans all columns -->
  <div class="section">Core</div>
  <div>Projects</div><div class="val">10</div><div class="val">Unlimited</div><div class="val">Unlimited</div>
  <div>Users</div><div class="val">1</div><div class="val">10</div><div class="val">Unlimited</div>
  <div>Storage</div><div class="val">5 GB</div><div class="val">100 GB</div><div class="val">1 TB</div>

  <div class="section">Integrations</div>
  <div>API access</div><div class="val x"></div><div class="val check"></div><div class="val check"></div>
  <div>Webhooks</div><div class="val x"></div><div class="val check"></div><div class="val check"></div>
  <div>Zapier</div><div class="val check"></div><div class="val check"></div><div class="val check"></div>

  <div class="section">Security</div>
  <div>2FA</div><div class="val check"></div><div class="val check"></div><div class="val check"></div>
  <div>SSO / SAML</div><div class="val x"></div><div class="val x"></div><div class="val check"></div>
  <div>Audit log</div><div class="val x"></div><div class="val x"></div><div class="val check"></div>
</div>
.matrix {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
}

/* Section headers span all 4 columns */
.matrix .section {
  grid-column: 1 / -1;
  background: #f4f4f5;
  text-transform: uppercase;
  letter-spacing: .08em;
  font-size: 11px;
}

6. Simple Cards — lightweight card per plan, no "featured" treatment

Launch

Perfect for side projects and solo builds.

$19/mo
Choose Launch →

Cruise

For growing teams shipping real products.

$49/mo
Choose Cruise →

Orbit

Enterprise-grade scale and security.

$199/mo
Choose Orbit →
<div class="cards">
  <div class="card">
    <div class="icon"><i class="ph-duotone ph-rocket-launch"></i></div>
    <h3>Launch</h3>
    <p>Perfect for side projects and solo builds.</p>
    <div class="price">$19<span>/mo</span></div>
    <a href="#" class="cta">Choose Launch →</a>
  </div>
  <div class="card">
    <div class="icon"><i class="ph-duotone ph-airplane-tilt"></i></div>
    <h3>Cruise</h3>
    <p>For growing teams shipping real products.</p>
    <div class="price">$49<span>/mo</span></div>
    <a href="#" class="cta">Choose Cruise →</a>
  </div>
  <div class="card">
    <div class="icon"><i class="ph-duotone ph-lightning"></i></div>
    <h3>Orbit</h3>
    <p>Enterprise-grade scale and security.</p>
    <div class="price">$199<span>/mo</span></div>
    <a href="#" class="cta">Choose Orbit →</a>
  </div>
</div>
.card {
  padding: 26px;
  border: 1px solid #eee;
  border-radius: 14px;
  transition: all .2s;
}

.card:hover {
  border-color: #111;
  transform: translateY(-3px);
  box-shadow: 0 8px 20px rgba(0,0,0,.06);
}

7. Enterprise CTA — dark gradient panel for "contact sales" plans

Need something bigger?

Our Enterprise plan is for teams with custom needs — volume discounts, dedicated infrastructure, and white-glove onboarding.

  • Unlimited everything, forever
  • Dedicated account manager
  • Custom SLAs + uptime guarantees
  • On-premise deployment options
  • Security reviews + SOC 2 reports
Enterprise
Let's talk
Book a call →

Avg. response in 2 hours

<div class="panel">
  <div class="left">
    <h2>Need something bigger?</h2>
    <p class="sub">Our Enterprise plan is for teams with custom needs — volume discounts, dedicated infrastructure, and white-glove onboarding.</p>
    <ul>
      <li>Unlimited everything, forever</li>
      <li>Dedicated account manager</li>
      <li>Custom SLAs + uptime guarantees</li>
      <li>On-premise deployment options</li>
      <li>Security reviews + SOC 2 reports</li>
    </ul>
  </div>
  <div class="right">
    <div class="tag">Enterprise</div>
    <div class="price">Let's talk</div>
    <a class="cta">Book a call →</a>
    <p>Avg. response in 2 hours</p>
  </div>
</div>
.panel {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  background: #0f172a;
  color: #fff;
  border-radius: 18px;
  padding: 50px 40px;
  overflow: hidden;
  position: relative;
}

/* Radial glow decoration */
.panel::before {
  content: "";
  position: absolute;
  top: -50%;
  right: -30%;
  width: 80%;
  height: 200%;
  background: radial-gradient(circle, rgba(236,72,153,.3), transparent 60%);
}

Full Page — a complete, copy-pasteable pricing page (3-tier cards + monthly/annual toggle)

Live preview

Complete HTML — copy this whole file

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Pricing — Simple, transparent plans</title>
  <style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      color: #111; background: linear-gradient(180deg, #fef7ff, #eff6ff);
      min-height: 100vh; padding: 60px 20px;
    }
    .wrap { max-width: 980px; margin: 0 auto; }

    /* ===== Heading + billing toggle ===== */
    .top { text-align: center; margin-bottom: 32px; }
    .top h1 { font-size: 2.6rem; font-weight: 800; letter-spacing: -0.02em; margin-bottom: 10px; }
    .top p { color: #64748b; font-size: 1.05rem; }

    .toggle {
      display: inline-flex; padding: 4px; gap: 4px;
      background: #f4f4f5; border-radius: 999px;
      margin: 24px auto 0; position: relative;
    }
    .toggle button {
      position: relative; z-index: 1;
      padding: 9px 22px; border-radius: 999px;
      background: transparent; border: none; font: inherit;
      font-size: 13px; font-weight: 600; cursor: pointer;
      color: #64748b; transition: color .2s;
    }
    .toggle button.active { color: #fff; }
    .toggle button small {
      background: #10b981; color: #fff; font-size: 10px;
      padding: 2px 8px; border-radius: 999px; margin-left: 6px;
    }
    .toggle .indicator {
      position: absolute; top: 4px; bottom: 4px;
      background: #111; border-radius: 999px; z-index: 0;
      transition: all .3s cubic-bezier(.2,.8,.3,1);
    }

    /* ===== Three-tier cards ===== */
    .cards {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 20px; align-items: start;
    }
    .card {
      background: #fff; border: 1px solid #e5e5e5;
      border-radius: 16px; padding: 32px 28px; position: relative;
    }
    .card.featured {
      background: linear-gradient(180deg, #111, #1a1a1a); color: #fff;
      border-color: transparent; transform: scale(1.03);
    }
    .badge {
      position: absolute; top: -12px; left: 50%;
      transform: translateX(-50%);
      background: linear-gradient(135deg, #ec4899, #8b5cf6);
      color: #fff; font-size: 11px; font-weight: 700;
      padding: 5px 14px; border-radius: 999px;
      text-transform: uppercase; letter-spacing: .1em;
    }
    .card h3 { font-size: 1.1rem; margin-bottom: 6px; }
    .card .price { font-size: 2.75rem; font-weight: 800; margin: 10px 0 4px; letter-spacing: -0.03em; }
    .card .price .per { font-size: 1rem; color: #888; font-weight: 500; }
    .card.featured .price .per { color: #a0a0b0; }
    /* Price swap: yearly shown by default, monthly hidden */
    .card .price .monthly { display: none; }
    .cards.monthly .price .monthly { display: inline; }
    .cards.monthly .price .yearly { display: none; }
    .card .desc { font-size: 14px; color: #888; }
    .card.featured .desc { color: #a0a0b0; }
    .card ul {
      list-style: none; margin: 20px 0;
      display: flex; flex-direction: column; gap: 8px; font-size: 14px;
    }
    .card li::before { content: "\2713"; color: #10b981; font-weight: 700; margin-right: 8px; }
    .cta {
      display: block; text-align: center; padding: 12px;
      border-radius: 10px; background: #111; color: #fff;
      text-decoration: none; font-weight: 600; font-size: 14px;
    }
    .card.featured .cta { background: linear-gradient(135deg, #ec4899, #8b5cf6); }

    @media (max-width: 720px) {
      .cards { grid-template-columns: 1fr; }
      .card.featured { transform: none; }
    }
  </style>
</head>
<body>

  <div class="wrap">
    <div class="top">
      <h1>Simple, transparent pricing</h1>
      <p>Pick a plan that grows with you. Pay monthly or save 20% annually.</p>
      <div class="toggle" id="toggle">
        <span class="indicator"></span>
        <button data-b="monthly">Monthly</button>
        <button class="active" data-b="yearly">Yearly<small>-20%</small></button>
      </div>
    </div>

    <div class="cards" id="cards">
      <div class="card">
        <h3>Starter</h3>
        <div class="price">$<span class="yearly">7</span><span class="monthly">9</span><span class="per">/mo</span></div>
        <p class="desc">For personal projects</p>
        <ul>
          <li>1 user</li>
          <li>10 projects</li>
          <li>Community support</li>
        </ul>
        <a href="#" class="cta">Get started</a>
      </div>

      <div class="card featured">
        <div class="badge">Most Popular</div>
        <h3>Pro</h3>
        <div class="price">$<span class="yearly">23</span><span class="monthly">29</span><span class="per">/mo</span></div>
        <p class="desc">For growing teams</p>
        <ul>
          <li>10 users</li>
          <li>Unlimited projects</li>
          <li>Priority support</li>
          <li>Advanced analytics</li>
        </ul>
        <a href="#" class="cta">Start free trial</a>
      </div>

      <div class="card">
        <h3>Team</h3>
        <div class="price">$<span class="yearly">79</span><span class="monthly">99</span><span class="per">/mo</span></div>
        <p class="desc">For organizations</p>
        <ul>
          <li>Unlimited users</li>
          <li>SSO / SAML</li>
          <li>Dedicated CSM</li>
        </ul>
        <a href="#" class="cta">Contact sales</a>
      </div>
    </div>
  </div>

  <script>
    const toggle = document.getElementById('toggle');
    const cards = document.getElementById('cards');
    const indicator = toggle.querySelector('.indicator');

    const setIndicator = (btn) => {
      indicator.style.left = btn.offsetLeft + 'px';
      indicator.style.width = btn.offsetWidth + 'px';
    };

    toggle.querySelectorAll('button').forEach(btn => {
      btn.addEventListener('click', () => {
        toggle.querySelectorAll('button').forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        cards.classList.toggle('monthly', btn.dataset.b === 'monthly');
        setIndicator(btn);
      });
    });

    requestAnimationFrame(() => setIndicator(toggle.querySelector('.active')));
  </script>
</body>
</html>