21 CSS Pricing Sections01 / 21
Classic Three Tier
The canonical SaaS pricing layout — three equal tier cards (Starter / Team / Business) with emerald accent. Real <ul> feature lists, dashed dividers, and full-width CTAs at the bottom. The conversion-tested baseline every team starts from.
Published
The code
<section class="ps-01" aria-label="Pricing">
<header class="ps-01__head">
<span class="ps-01__eye">Pricing</span>
<h2>Pick the plan that fits today.</h2>
<p>Upgrade, downgrade, or cancel any time. No fine print.</p>
</header>
<div class="ps-01__grid">
<article class="ps-01__card">
<h3>Starter</h3>
<p class="ps-01__sub">For solo builders shipping their first thing.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$9</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>1 project</li>
<li>2 GB storage</li>
<li>Community support</li>
<li>Basic analytics</li>
</ul>
<a class="ps-01__cta" href="#starter">Start free →</a>
</article>
<article class="ps-01__card">
<h3>Team</h3>
<p class="ps-01__sub">For small teams who need to ship together.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$29</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>10 projects</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Team analytics</li>
<li>Role-based access</li>
</ul>
<a class="ps-01__cta" href="#team">Start 14-day trial →</a>
</article>
<article class="ps-01__card">
<h3>Business</h3>
<p class="ps-01__sub">For growing companies that need governance.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$79</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>Unlimited projects</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>Advanced analytics</li>
<li>SSO + audit logs</li>
<li>SOC 2 ready</li>
</ul>
<a class="ps-01__cta" href="#business">Talk to sales →</a>
</article>
</div>
</section><section class="ps-01" aria-label="Pricing">
<header class="ps-01__head">
<span class="ps-01__eye">Pricing</span>
<h2>Pick the plan that fits today.</h2>
<p>Upgrade, downgrade, or cancel any time. No fine print.</p>
</header>
<div class="ps-01__grid">
<article class="ps-01__card">
<h3>Starter</h3>
<p class="ps-01__sub">For solo builders shipping their first thing.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$9</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>1 project</li>
<li>2 GB storage</li>
<li>Community support</li>
<li>Basic analytics</li>
</ul>
<a class="ps-01__cta" href="#starter">Start free →</a>
</article>
<article class="ps-01__card">
<h3>Team</h3>
<p class="ps-01__sub">For small teams who need to ship together.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$29</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>10 projects</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Team analytics</li>
<li>Role-based access</li>
</ul>
<a class="ps-01__cta" href="#team">Start 14-day trial →</a>
</article>
<article class="ps-01__card">
<h3>Business</h3>
<p class="ps-01__sub">For growing companies that need governance.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$79</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>Unlimited projects</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>Advanced analytics</li>
<li>SSO + audit logs</li>
<li>SOC 2 ready</li>
</ul>
<a class="ps-01__cta" href="#business">Talk to sales →</a>
</article>
</div>
</section>.ps-01 {
display: block;
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #07120e;
color: #e7f5ee;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
}
.ps-01__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 40px);
}
.ps-01__eye {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: #34d399;
margin-bottom: 12px;
}
.ps-01__head h2 {
font-size: clamp(22px, 3.4vw, 34px);
font-weight: 700;
letter-spacing: -0.01em;
margin: 0 0 8px;
}
.ps-01__head p {
color: #9bb5a8;
margin: 0;
font-size: 14px;
}
.ps-01__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
max-width: 980px;
margin: 0 auto;
}
.ps-01__card {
background: #0d1f18;
border: 1px solid rgba(52,211,153,0.2);
border-radius: 14px;
padding: 22px 20px 20px;
display: flex;
flex-direction: column;
transition: border-color 0.2s, transform 0.2s;
}
.ps-01__card:hover {
border-color: #34d399;
transform: translateY(-2px);
}
.ps-01__card h3 {
font-size: 15px;
font-weight: 700;
margin: 0 0 4px;
color: #34d399;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.ps-01__sub {
font-size: 13px;
color: #9bb5a8;
margin: 0 0 18px;
line-height: 1.5;
min-height: 38px;
}
.ps-01__price {
display: flex;
align-items: baseline;
gap: 6px;
margin-bottom: 18px;
padding-bottom: 18px;
border-bottom: 1px dashed rgba(52,211,153,0.25);
}
.ps-01__amt {
font-size: 38px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f0fff7;
}
.ps-01__per {
font-size: 13px;
color: #9bb5a8;
}
.ps-01__feats {
list-style: none;
padding: 0;
margin: 0 0 22px;
flex: 1;
}
.ps-01__feats li {
position: relative;
padding: 6px 0 6px 22px;
font-size: 13.5px;
color: #d2e9dc;
}
.ps-01__feats li::before {
content: '';
position: absolute;
left: 0;
top: 50%;
width: 14px;
height: 14px;
transform: translateY(-50%);
background: linear-gradient(135deg, transparent 50%, #34d399 50%) center/100% 100% no-repeat;
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
background: #34d399;
}
.ps-01__cta {
display: block;
text-align: center;
padding: 11px 16px;
border-radius: 8px;
background: rgba(52,211,153,0.12);
color: #34d399;
text-decoration: none;
font-size: 13.5px;
font-weight: 600;
border: 1px solid rgba(52,211,153,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-01__cta:hover {
background: #34d399;
color: #07120e;
}
.ps-01__cta:focus-visible {
outline: 2px solid #34d399;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-01__grid {
grid-template-columns: 1fr;
max-width: 460px;
}
.ps-01__sub {
min-height: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-01__card {
transition: none;
}
.ps-01__card:hover {
transform: none;
}
}.ps-01 {
display: block;
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #07120e;
color: #e7f5ee;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
}
.ps-01__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 40px);
}
.ps-01__eye {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: #34d399;
margin-bottom: 12px;
}
.ps-01__head h2 {
font-size: clamp(22px, 3.4vw, 34px);
font-weight: 700;
letter-spacing: -0.01em;
margin: 0 0 8px;
}
.ps-01__head p {
color: #9bb5a8;
margin: 0;
font-size: 14px;
}
.ps-01__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
max-width: 980px;
margin: 0 auto;
}
.ps-01__card {
background: #0d1f18;
border: 1px solid rgba(52,211,153,0.2);
border-radius: 14px;
padding: 22px 20px 20px;
display: flex;
flex-direction: column;
transition: border-color 0.2s, transform 0.2s;
}
.ps-01__card:hover {
border-color: #34d399;
transform: translateY(-2px);
}
.ps-01__card h3 {
font-size: 15px;
font-weight: 700;
margin: 0 0 4px;
color: #34d399;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.ps-01__sub {
font-size: 13px;
color: #9bb5a8;
margin: 0 0 18px;
line-height: 1.5;
min-height: 38px;
}
.ps-01__price {
display: flex;
align-items: baseline;
gap: 6px;
margin-bottom: 18px;
padding-bottom: 18px;
border-bottom: 1px dashed rgba(52,211,153,0.25);
}
.ps-01__amt {
font-size: 38px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f0fff7;
}
.ps-01__per {
font-size: 13px;
color: #9bb5a8;
}
.ps-01__feats {
list-style: none;
padding: 0;
margin: 0 0 22px;
flex: 1;
}
.ps-01__feats li {
position: relative;
padding: 6px 0 6px 22px;
font-size: 13.5px;
color: #d2e9dc;
}
.ps-01__feats li::before {
content: '';
position: absolute;
left: 0;
top: 50%;
width: 14px;
height: 14px;
transform: translateY(-50%);
background: linear-gradient(135deg, transparent 50%, #34d399 50%) center/100% 100% no-repeat;
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
background: #34d399;
}
.ps-01__cta {
display: block;
text-align: center;
padding: 11px 16px;
border-radius: 8px;
background: rgba(52,211,153,0.12);
color: #34d399;
text-decoration: none;
font-size: 13.5px;
font-weight: 600;
border: 1px solid rgba(52,211,153,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-01__cta:hover {
background: #34d399;
color: #07120e;
}
.ps-01__cta:focus-visible {
outline: 2px solid #34d399;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-01__grid {
grid-template-columns: 1fr;
max-width: 460px;
}
.ps-01__sub {
min-height: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-01__card {
transition: none;
}
.ps-01__card:hover {
transform: none;
}
}Here's a working CSS Pricing Section from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Classic Three Tier
Source: https://codefronts.com/layouts/css-pricing-sections/classic-three-tier/
The canonical SaaS pricing layout — three equal tier cards (Starter / Team / Business) with emerald accent. Real <ul> feature lists, dashed dividers, and full-width CTAs at the bottom. The conversion-tested baseline every team starts from.
## HTML
```html
<section class="ps-01" aria-label="Pricing">
<header class="ps-01__head">
<span class="ps-01__eye">Pricing</span>
<h2>Pick the plan that fits today.</h2>
<p>Upgrade, downgrade, or cancel any time. No fine print.</p>
</header>
<div class="ps-01__grid">
<article class="ps-01__card">
<h3>Starter</h3>
<p class="ps-01__sub">For solo builders shipping their first thing.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$9</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>1 project</li>
<li>2 GB storage</li>
<li>Community support</li>
<li>Basic analytics</li>
</ul>
<a class="ps-01__cta" href="#starter">Start free →</a>
</article>
<article class="ps-01__card">
<h3>Team</h3>
<p class="ps-01__sub">For small teams who need to ship together.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$29</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>10 projects</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Team analytics</li>
<li>Role-based access</li>
</ul>
<a class="ps-01__cta" href="#team">Start 14-day trial →</a>
</article>
<article class="ps-01__card">
<h3>Business</h3>
<p class="ps-01__sub">For growing companies that need governance.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$79</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>Unlimited projects</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>Advanced analytics</li>
<li>SSO + audit logs</li>
<li>SOC 2 ready</li>
</ul>
<a class="ps-01__cta" href="#business">Talk to sales →</a>
</article>
</div>
</section>
```
## CSS
```css
.ps-01 {
display: block;
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #07120e;
color: #e7f5ee;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
}
.ps-01__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 40px);
}
.ps-01__eye {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: #34d399;
margin-bottom: 12px;
}
.ps-01__head h2 {
font-size: clamp(22px, 3.4vw, 34px);
font-weight: 700;
letter-spacing: -0.01em;
margin: 0 0 8px;
}
.ps-01__head p {
color: #9bb5a8;
margin: 0;
font-size: 14px;
}
.ps-01__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
max-width: 980px;
margin: 0 auto;
}
.ps-01__card {
background: #0d1f18;
border: 1px solid rgba(52,211,153,0.2);
border-radius: 14px;
padding: 22px 20px 20px;
display: flex;
flex-direction: column;
transition: border-color 0.2s, transform 0.2s;
}
.ps-01__card:hover {
border-color: #34d399;
transform: translateY(-2px);
}
.ps-01__card h3 {
font-size: 15px;
font-weight: 700;
margin: 0 0 4px;
color: #34d399;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.ps-01__sub {
font-size: 13px;
color: #9bb5a8;
margin: 0 0 18px;
line-height: 1.5;
min-height: 38px;
}
.ps-01__price {
display: flex;
align-items: baseline;
gap: 6px;
margin-bottom: 18px;
padding-bottom: 18px;
border-bottom: 1px dashed rgba(52,211,153,0.25);
}
.ps-01__amt {
font-size: 38px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f0fff7;
}
.ps-01__per {
font-size: 13px;
color: #9bb5a8;
}
.ps-01__feats {
list-style: none;
padding: 0;
margin: 0 0 22px;
flex: 1;
}
.ps-01__feats li {
position: relative;
padding: 6px 0 6px 22px;
font-size: 13.5px;
color: #d2e9dc;
}
.ps-01__feats li::before {
content: '';
position: absolute;
left: 0;
top: 50%;
width: 14px;
height: 14px;
transform: translateY(-50%);
background: linear-gradient(135deg, transparent 50%, #34d399 50%) center/100% 100% no-repeat;
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
background: #34d399;
}
.ps-01__cta {
display: block;
text-align: center;
padding: 11px 16px;
border-radius: 8px;
background: rgba(52,211,153,0.12);
color: #34d399;
text-decoration: none;
font-size: 13.5px;
font-weight: 600;
border: 1px solid rgba(52,211,153,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-01__cta:hover {
background: #34d399;
color: #07120e;
}
.ps-01__cta:focus-visible {
outline: 2px solid #34d399;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-01__grid {
grid-template-columns: 1fr;
max-width: 460px;
}
.ps-01__sub {
min-height: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-01__card {
transition: none;
}
.ps-01__card:hover {
transform: none;
}
}
```Here's a working CSS Pricing Section from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Classic Three Tier
Source: https://codefronts.com/layouts/css-pricing-sections/classic-three-tier/
The canonical SaaS pricing layout — three equal tier cards (Starter / Team / Business) with emerald accent. Real <ul> feature lists, dashed dividers, and full-width CTAs at the bottom. The conversion-tested baseline every team starts from.
## HTML
```html
<section class="ps-01" aria-label="Pricing">
<header class="ps-01__head">
<span class="ps-01__eye">Pricing</span>
<h2>Pick the plan that fits today.</h2>
<p>Upgrade, downgrade, or cancel any time. No fine print.</p>
</header>
<div class="ps-01__grid">
<article class="ps-01__card">
<h3>Starter</h3>
<p class="ps-01__sub">For solo builders shipping their first thing.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$9</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>1 project</li>
<li>2 GB storage</li>
<li>Community support</li>
<li>Basic analytics</li>
</ul>
<a class="ps-01__cta" href="#starter">Start free →</a>
</article>
<article class="ps-01__card">
<h3>Team</h3>
<p class="ps-01__sub">For small teams who need to ship together.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$29</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>10 projects</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Team analytics</li>
<li>Role-based access</li>
</ul>
<a class="ps-01__cta" href="#team">Start 14-day trial →</a>
</article>
<article class="ps-01__card">
<h3>Business</h3>
<p class="ps-01__sub">For growing companies that need governance.</p>
<div class="ps-01__price">
<span class="ps-01__amt">$79</span><span class="ps-01__per">/ month</span>
</div>
<ul class="ps-01__feats">
<li>Unlimited projects</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>Advanced analytics</li>
<li>SSO + audit logs</li>
<li>SOC 2 ready</li>
</ul>
<a class="ps-01__cta" href="#business">Talk to sales →</a>
</article>
</div>
</section>
```
## CSS
```css
.ps-01 {
display: block;
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #07120e;
color: #e7f5ee;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
}
.ps-01__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 40px);
}
.ps-01__eye {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: #34d399;
margin-bottom: 12px;
}
.ps-01__head h2 {
font-size: clamp(22px, 3.4vw, 34px);
font-weight: 700;
letter-spacing: -0.01em;
margin: 0 0 8px;
}
.ps-01__head p {
color: #9bb5a8;
margin: 0;
font-size: 14px;
}
.ps-01__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
max-width: 980px;
margin: 0 auto;
}
.ps-01__card {
background: #0d1f18;
border: 1px solid rgba(52,211,153,0.2);
border-radius: 14px;
padding: 22px 20px 20px;
display: flex;
flex-direction: column;
transition: border-color 0.2s, transform 0.2s;
}
.ps-01__card:hover {
border-color: #34d399;
transform: translateY(-2px);
}
.ps-01__card h3 {
font-size: 15px;
font-weight: 700;
margin: 0 0 4px;
color: #34d399;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.ps-01__sub {
font-size: 13px;
color: #9bb5a8;
margin: 0 0 18px;
line-height: 1.5;
min-height: 38px;
}
.ps-01__price {
display: flex;
align-items: baseline;
gap: 6px;
margin-bottom: 18px;
padding-bottom: 18px;
border-bottom: 1px dashed rgba(52,211,153,0.25);
}
.ps-01__amt {
font-size: 38px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f0fff7;
}
.ps-01__per {
font-size: 13px;
color: #9bb5a8;
}
.ps-01__feats {
list-style: none;
padding: 0;
margin: 0 0 22px;
flex: 1;
}
.ps-01__feats li {
position: relative;
padding: 6px 0 6px 22px;
font-size: 13.5px;
color: #d2e9dc;
}
.ps-01__feats li::before {
content: '';
position: absolute;
left: 0;
top: 50%;
width: 14px;
height: 14px;
transform: translateY(-50%);
background: linear-gradient(135deg, transparent 50%, #34d399 50%) center/100% 100% no-repeat;
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
background: #34d399;
}
.ps-01__cta {
display: block;
text-align: center;
padding: 11px 16px;
border-radius: 8px;
background: rgba(52,211,153,0.12);
color: #34d399;
text-decoration: none;
font-size: 13.5px;
font-weight: 600;
border: 1px solid rgba(52,211,153,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-01__cta:hover {
background: #34d399;
color: #07120e;
}
.ps-01__cta:focus-visible {
outline: 2px solid #34d399;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-01__grid {
grid-template-columns: 1fr;
max-width: 460px;
}
.ps-01__sub {
min-height: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-01__card {
transition: none;
}
.ps-01__card:hover {
transform: none;
}
}
```How this works
The layout is a semantic <section> wrapping a centered .ps-01__head plus .ps-01__grid using display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) with gap: 16px — the canonical anchor-and-recommend layout for any SaaS pricing page. The minmax(0, 1fr) is load-bearing: without the 0 minimum, long feature strings force intrinsic column widths and one tier bulges wider than the other two, breaking the visual parity that the three-column tier design depends on. Each .ps-01__card is display: flex; flex-direction: column so flex: 1 on the feature list glues every CTA to the card bottom regardless of feature-count skew (4 items in Starter, 6 in Business).
The palette is a deep forest #07120e base with body text #e7f5ee and a single emerald accent #34d399 that carries eyebrow, tier titles, price emphasis, and the check-mark icon painted via a masked SVG — one color, four jobs, zero paint cost. The Inter typeface with letter-spacing: -0.01em on the h2 and letter-spacing: 0.18em; text-transform: uppercase on the eyebrow is the standard fintech / developer-tools trust signal. The dashed border-bottom: 1px dashed rgba(52,211,153,0.25) under each price separates commitment (the number) from proof (the feature list) — a subtle Baymard-validated grouping cue.
Why it converts: the three-tier pricing card layout is the anchor-effect execution — Starter at $9 sets the floor, Business at $79 sets the ceiling, and the eye lands on Team at $29 as the mid-anchor. Iyengar & Lepper's jam-shelf work shows three options maximize conversion versus one or six; three tiers hits that sweet spot exactly. Every CTA gets :focus-visible with a 2px emerald ring at outline-offset: 3px, and the hover only shifts transform: translateY(-2px) + border-color — compositor-only, so INP on the card interaction stays well under 200ms even on mid-tier Android.
Make it yours
- Recolor the emerald: change
#34d399(accent) and#e7f5ee(body) to your brand. Keep the accent above 4.5:1 against#07120efor WCAG 1.4.3 AA on the CTA text — Tailwind'semerald-400,sky-400, andviolet-400all clear that bar against a near-black surface. - Swap Inter for the register you want:
'IBM Plex Sans'for developer tools,'Söhne'or'General Sans'for premium B2B SaaS,'Manrope'for startup pricing card energy. Keepletter-spacing: -0.01emon the h2 — every geometric sans needs it to avoid feeling airy at display sizes. - Change the CTA shape from
border-radius: 8pxtoborder-radius: 999pxfor a pill CTA (fintech default) orborder-radius: 0for a brutalist / developer-tools look. Thergba(52,211,153,0.12)ghost fill can drop totransparentif you want the CTA to read as a link on the two side tiers and reserved solid emerald for a highlighted Team card. - For a light-mode inversion: swap
#07120e→#f5faf7,#e7f5ee→#0d1f18, keep#34d399as accent, but bump the card border torgba(15,118,72,0.28)and the dashed divider torgba(15,118,72,0.35)— the original 0.2–0.25 alphas disappear on cream. - Tailwind mapping: section
bg-[#07120e] text-[#e7f5ee] font-sans, gridgrid grid-cols-1 md:grid-cols-3 gap-4 max-w-[980px] mx-auto, cardbg-[#0d1f18] border border-emerald-400/20 rounded-2xl p-6 flex flex-col hover:border-emerald-400 hover:-translate-y-0.5 transition, CTAbg-emerald-400/10 text-emerald-400 border border-emerald-400/25 hover:bg-emerald-400 hover:text-[#07120e].
Gotchas — read before shipping
- The
grid-template-columns: repeat(3, minmax(0, 1fr))usesminmax(0, ...)deliberately — the default1frresolves tominmax(auto, 1fr)and a long unbreakable string (like a coupon code or a URL in a feature name) forces the column wider than 1/3, breaking the three-tier design. Never drop the0. - The
.ps-01__subhasmin-height: 38pxso all three subheads align vertically even when the copy is one line vs two. If you translate this to a language where the subhead is longer (German averages ~30% more characters than English), bump tomin-height: 56pxand remove the mobile override to avoid a CLS pop. - The CTA
rgba(52,211,153,0.12)fill against dark text at rest measures ~2.1:1 contrast for the border pattern — the emerald text against#0d1f18is what carries the ~7:1 contrast for WCAG 1.4.3. Do not lower the text color's alpha thinking it's decorative; it's the primary readable state. - The check-mark icon uses
-webkit-maskandmaskwith a data-URI SVG. Older Safari (< 15.4) requires the-webkit-prefix or the check disappears entirely; keep both lines. Do not switch tobackground-imageunless you also recolor per-tier — the mask lets one hex value repaint every check via thebackgroundshorthand. - The
:hoverusestransform: translateY(-2px)+border-color— both compositor-only in modern engines. Never addbox-shadowto the hover transition; box-shadow forces a paint on every frame and drops the interactive card off the compositor thread, spiking INP past 200ms on the 75th percentile mobile. - In React / Next.js, do not render this list from a
tiersarray without a stablekeyprop bound to tier slug (not index). If you A/B test tier order via GrowthBook or LaunchDarkly, an index key remounts the card on flip, firing a full paint mid-experiment and destroying the CLS reading for the exposure cohort.