21 CSS Pricing Sections18 / 21
Social Proof Pricing
A scrolling logo wall above the pricing tiers — social proof first, decision second. Slate background with lime accent on the recommended plan. Logos scroll in a seamless marquee using a duplicated track.
Published
The code
<section class="ps-18" aria-label="Pricing">
<div class="ps-18__marquee" aria-label="Customers using this product">
<div class="ps-18__track">
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
</div>
</div>
<header class="ps-18__head">
<span class="ps-18__rating" aria-label="Rated 4.9 out of 5">★★★★★ 4.9 from 12,400 teams</span>
<h2>Pricing teams actually pay for.</h2>
</header>
<div class="ps-18__grid">
<article class="ps-18__card">
<h3>Free</h3>
<div class="ps-18__price"><em>$</em>0<span>forever</span></div>
<ul>
<li>1 project</li>
<li>5 GB storage</li>
<li>Community</li>
</ul>
<a class="ps-18__cta" href="#free">Start free</a>
</article>
<article class="ps-18__card ps-18__best">
<span class="ps-18__tag">Most teams pick this</span>
<h3>Team</h3>
<div class="ps-18__price"><em>$</em>32<span>/mo</span></div>
<ul>
<li>Unlimited projects</li>
<li>Priority support</li>
<li>SSO + roles</li>
</ul>
<a class="ps-18__cta ps-18__cta-pri" href="#team">Choose Team</a>
</article>
<article class="ps-18__card">
<h3>Enterprise</h3>
<div class="ps-18__price"><em>$</em>0<span>custom</span></div>
<ul>
<li>Everything in Team</li>
<li>Dedicated CSM</li>
<li>SLA 99.99%</li>
</ul>
<a class="ps-18__cta" href="#ent">Talk to sales</a>
</article>
</div>
</section><section class="ps-18" aria-label="Pricing">
<div class="ps-18__marquee" aria-label="Customers using this product">
<div class="ps-18__track">
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
</div>
</div>
<header class="ps-18__head">
<span class="ps-18__rating" aria-label="Rated 4.9 out of 5">★★★★★ 4.9 from 12,400 teams</span>
<h2>Pricing teams actually pay for.</h2>
</header>
<div class="ps-18__grid">
<article class="ps-18__card">
<h3>Free</h3>
<div class="ps-18__price"><em>$</em>0<span>forever</span></div>
<ul>
<li>1 project</li>
<li>5 GB storage</li>
<li>Community</li>
</ul>
<a class="ps-18__cta" href="#free">Start free</a>
</article>
<article class="ps-18__card ps-18__best">
<span class="ps-18__tag">Most teams pick this</span>
<h3>Team</h3>
<div class="ps-18__price"><em>$</em>32<span>/mo</span></div>
<ul>
<li>Unlimited projects</li>
<li>Priority support</li>
<li>SSO + roles</li>
</ul>
<a class="ps-18__cta ps-18__cta-pri" href="#team">Choose Team</a>
</article>
<article class="ps-18__card">
<h3>Enterprise</h3>
<div class="ps-18__price"><em>$</em>0<span>custom</span></div>
<ul>
<li>Everything in Team</li>
<li>Dedicated CSM</li>
<li>SLA 99.99%</li>
</ul>
<a class="ps-18__cta" href="#ent">Talk to sales</a>
</article>
</div>
</section>.ps-18 {
position: relative;
overflow: hidden;
contain: layout paint;
padding: clamp(20px, 4vw, 36px) clamp(20px, 4vw, 40px) clamp(28px, 5vw, 48px);
width: 100%;
min-height: 100vh;
background: #0f172a;
color: #e2e8f0;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-18__marquee {
position: relative;
overflow: hidden;
contain: layout paint;
border-block: 1px solid rgba(163,230,53,0.18);
margin: 0 calc(-1 * clamp(20px, 4vw, 40px)) clamp(20px, 4vw, 32px);
padding: 14px 0;
background: rgba(15,23,42,0.6);
/* max-width containment: without this, the child .ps-18__track's
width: max-content (needed for the seamless marquee loop) propagates
up through this block wrapper — some layout engines size the wrapper
to child's intrinsic width instead of parent's content-box, causing
the whole section to grow to ~2045px and triggering horizontal body
scroll. Locking max-width to 100vw + min-width to 0 keeps the marquee
bounded regardless of child intrinsic width. overflow: hidden then
clips the marquee correctly. */
max-width: 100vw;
min-width: 0;
-webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ps-18__track {
display: flex;
gap: 56px;
white-space: nowrap;
animation: ps-18-roll 28s linear infinite;
width: max-content;
will-change: transform;
}
@keyframes ps-18-roll {
to {
transform: translateX(-50%);
}
}
.ps-18__logo {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
font-weight: 700;
letter-spacing: 0.18em;
color: #94a3b8;
flex-shrink: 0;
}
.ps-18__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 32px);
}
.ps-18__rating {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.08em;
color: #a3e635;
margin-bottom: 10px;
}
.ps-18__head h2 {
font-size: clamp(24px, 3.6vw, 36px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0;
color: #fff;
}
.ps-18__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
max-width: 940px;
margin: 0 auto;
align-items: center;
}
.ps-18__card {
position: relative;
background: #1e293b;
border: 1px solid rgba(163,230,53,0.12);
border-radius: 12px;
padding: 22px 20px 18px;
display: flex;
flex-direction: column;
}
.ps-18__best {
background: linear-gradient(180deg, #1e293b, #243f1a);
border-color: #a3e635;
box-shadow: 0 0 0 1px #a3e635 inset, 0 14px 36px rgba(163,230,53,0.18);
}
.ps-18__tag {
position: absolute;
top: -11px;
left: 50%;
transform: translateX(-50%);
background: #a3e635;
color: #0f172a;
font-size: 10.5px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 4px 11px;
border-radius: 999px;
}
.ps-18__card h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 0 0 12px;
color: #cbd5e1;
}
.ps-18__best h3 {
color: #d9f99d;
}
.ps-18__price {
display: flex;
align-items: baseline;
gap: 4px;
font-size: 38px;
font-weight: 800;
letter-spacing: -0.03em;
margin-bottom: 18px;
color: #fff;
}
.ps-18__price em {
font-size: 0.5em;
font-style: normal;
padding-right: 2px;
opacity: 0.7;
}
.ps-18__price span {
font-size: 0.32em;
font-weight: 500;
opacity: 0.65;
margin-left: 6px;
}
.ps-18__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
flex: 1;
font-size: 13px;
line-height: 1.95;
color: #b8c1d1;
}
.ps-18__card ul li::before {
content: '✓';
color: #a3e635;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-18__cta {
display: block;
text-align: center;
padding: 10px 16px;
border-radius: 8px;
text-decoration: none;
font-size: 13px;
font-weight: 600;
background: rgba(163,230,53,0.1);
color: #a3e635;
border: 1px solid rgba(163,230,53,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-18__cta-pri {
background: #a3e635;
color: #0f172a;
border-color: #a3e635;
}
.ps-18__cta:hover {
background: #a3e635;
color: #0f172a;
}
.ps-18__cta-pri:hover {
background: #d9f99d;
}
.ps-18__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-18__grid {
grid-template-columns: 1fr;
max-width: 360px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-18__track {
animation: none;
}
}.ps-18 {
position: relative;
overflow: hidden;
contain: layout paint;
padding: clamp(20px, 4vw, 36px) clamp(20px, 4vw, 40px) clamp(28px, 5vw, 48px);
width: 100%;
min-height: 100vh;
background: #0f172a;
color: #e2e8f0;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-18__marquee {
position: relative;
overflow: hidden;
contain: layout paint;
border-block: 1px solid rgba(163,230,53,0.18);
margin: 0 calc(-1 * clamp(20px, 4vw, 40px)) clamp(20px, 4vw, 32px);
padding: 14px 0;
background: rgba(15,23,42,0.6);
/* max-width containment: without this, the child .ps-18__track's
width: max-content (needed for the seamless marquee loop) propagates
up through this block wrapper — some layout engines size the wrapper
to child's intrinsic width instead of parent's content-box, causing
the whole section to grow to ~2045px and triggering horizontal body
scroll. Locking max-width to 100vw + min-width to 0 keeps the marquee
bounded regardless of child intrinsic width. overflow: hidden then
clips the marquee correctly. */
max-width: 100vw;
min-width: 0;
-webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ps-18__track {
display: flex;
gap: 56px;
white-space: nowrap;
animation: ps-18-roll 28s linear infinite;
width: max-content;
will-change: transform;
}
@keyframes ps-18-roll {
to {
transform: translateX(-50%);
}
}
.ps-18__logo {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
font-weight: 700;
letter-spacing: 0.18em;
color: #94a3b8;
flex-shrink: 0;
}
.ps-18__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 32px);
}
.ps-18__rating {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.08em;
color: #a3e635;
margin-bottom: 10px;
}
.ps-18__head h2 {
font-size: clamp(24px, 3.6vw, 36px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0;
color: #fff;
}
.ps-18__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
max-width: 940px;
margin: 0 auto;
align-items: center;
}
.ps-18__card {
position: relative;
background: #1e293b;
border: 1px solid rgba(163,230,53,0.12);
border-radius: 12px;
padding: 22px 20px 18px;
display: flex;
flex-direction: column;
}
.ps-18__best {
background: linear-gradient(180deg, #1e293b, #243f1a);
border-color: #a3e635;
box-shadow: 0 0 0 1px #a3e635 inset, 0 14px 36px rgba(163,230,53,0.18);
}
.ps-18__tag {
position: absolute;
top: -11px;
left: 50%;
transform: translateX(-50%);
background: #a3e635;
color: #0f172a;
font-size: 10.5px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 4px 11px;
border-radius: 999px;
}
.ps-18__card h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 0 0 12px;
color: #cbd5e1;
}
.ps-18__best h3 {
color: #d9f99d;
}
.ps-18__price {
display: flex;
align-items: baseline;
gap: 4px;
font-size: 38px;
font-weight: 800;
letter-spacing: -0.03em;
margin-bottom: 18px;
color: #fff;
}
.ps-18__price em {
font-size: 0.5em;
font-style: normal;
padding-right: 2px;
opacity: 0.7;
}
.ps-18__price span {
font-size: 0.32em;
font-weight: 500;
opacity: 0.65;
margin-left: 6px;
}
.ps-18__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
flex: 1;
font-size: 13px;
line-height: 1.95;
color: #b8c1d1;
}
.ps-18__card ul li::before {
content: '✓';
color: #a3e635;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-18__cta {
display: block;
text-align: center;
padding: 10px 16px;
border-radius: 8px;
text-decoration: none;
font-size: 13px;
font-weight: 600;
background: rgba(163,230,53,0.1);
color: #a3e635;
border: 1px solid rgba(163,230,53,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-18__cta-pri {
background: #a3e635;
color: #0f172a;
border-color: #a3e635;
}
.ps-18__cta:hover {
background: #a3e635;
color: #0f172a;
}
.ps-18__cta-pri:hover {
background: #d9f99d;
}
.ps-18__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-18__grid {
grid-template-columns: 1fr;
max-width: 360px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-18__track {
animation: 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: Social Proof Pricing
Source: https://codefronts.com/layouts/css-pricing-sections/social-proof-pricing/
A scrolling logo wall above the pricing tiers — social proof first, decision second. Slate background with lime accent on the recommended plan. Logos scroll in a seamless marquee using a duplicated track.
## HTML
```html
<section class="ps-18" aria-label="Pricing">
<div class="ps-18__marquee" aria-label="Customers using this product">
<div class="ps-18__track">
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
</div>
</div>
<header class="ps-18__head">
<span class="ps-18__rating" aria-label="Rated 4.9 out of 5">★★★★★ 4.9 from 12,400 teams</span>
<h2>Pricing teams actually pay for.</h2>
</header>
<div class="ps-18__grid">
<article class="ps-18__card">
<h3>Free</h3>
<div class="ps-18__price"><em>$</em>0<span>forever</span></div>
<ul>
<li>1 project</li>
<li>5 GB storage</li>
<li>Community</li>
</ul>
<a class="ps-18__cta" href="#free">Start free</a>
</article>
<article class="ps-18__card ps-18__best">
<span class="ps-18__tag">Most teams pick this</span>
<h3>Team</h3>
<div class="ps-18__price"><em>$</em>32<span>/mo</span></div>
<ul>
<li>Unlimited projects</li>
<li>Priority support</li>
<li>SSO + roles</li>
</ul>
<a class="ps-18__cta ps-18__cta-pri" href="#team">Choose Team</a>
</article>
<article class="ps-18__card">
<h3>Enterprise</h3>
<div class="ps-18__price"><em>$</em>0<span>custom</span></div>
<ul>
<li>Everything in Team</li>
<li>Dedicated CSM</li>
<li>SLA 99.99%</li>
</ul>
<a class="ps-18__cta" href="#ent">Talk to sales</a>
</article>
</div>
</section>
```
## CSS
```css
.ps-18 {
position: relative;
overflow: hidden;
contain: layout paint;
padding: clamp(20px, 4vw, 36px) clamp(20px, 4vw, 40px) clamp(28px, 5vw, 48px);
width: 100%;
min-height: 100vh;
background: #0f172a;
color: #e2e8f0;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-18__marquee {
position: relative;
overflow: hidden;
contain: layout paint;
border-block: 1px solid rgba(163,230,53,0.18);
margin: 0 calc(-1 * clamp(20px, 4vw, 40px)) clamp(20px, 4vw, 32px);
padding: 14px 0;
background: rgba(15,23,42,0.6);
/* max-width containment: without this, the child .ps-18__track's
width: max-content (needed for the seamless marquee loop) propagates
up through this block wrapper — some layout engines size the wrapper
to child's intrinsic width instead of parent's content-box, causing
the whole section to grow to ~2045px and triggering horizontal body
scroll. Locking max-width to 100vw + min-width to 0 keeps the marquee
bounded regardless of child intrinsic width. overflow: hidden then
clips the marquee correctly. */
max-width: 100vw;
min-width: 0;
-webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ps-18__track {
display: flex;
gap: 56px;
white-space: nowrap;
animation: ps-18-roll 28s linear infinite;
width: max-content;
will-change: transform;
}
@keyframes ps-18-roll {
to {
transform: translateX(-50%);
}
}
.ps-18__logo {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
font-weight: 700;
letter-spacing: 0.18em;
color: #94a3b8;
flex-shrink: 0;
}
.ps-18__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 32px);
}
.ps-18__rating {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.08em;
color: #a3e635;
margin-bottom: 10px;
}
.ps-18__head h2 {
font-size: clamp(24px, 3.6vw, 36px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0;
color: #fff;
}
.ps-18__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
max-width: 940px;
margin: 0 auto;
align-items: center;
}
.ps-18__card {
position: relative;
background: #1e293b;
border: 1px solid rgba(163,230,53,0.12);
border-radius: 12px;
padding: 22px 20px 18px;
display: flex;
flex-direction: column;
}
.ps-18__best {
background: linear-gradient(180deg, #1e293b, #243f1a);
border-color: #a3e635;
box-shadow: 0 0 0 1px #a3e635 inset, 0 14px 36px rgba(163,230,53,0.18);
}
.ps-18__tag {
position: absolute;
top: -11px;
left: 50%;
transform: translateX(-50%);
background: #a3e635;
color: #0f172a;
font-size: 10.5px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 4px 11px;
border-radius: 999px;
}
.ps-18__card h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 0 0 12px;
color: #cbd5e1;
}
.ps-18__best h3 {
color: #d9f99d;
}
.ps-18__price {
display: flex;
align-items: baseline;
gap: 4px;
font-size: 38px;
font-weight: 800;
letter-spacing: -0.03em;
margin-bottom: 18px;
color: #fff;
}
.ps-18__price em {
font-size: 0.5em;
font-style: normal;
padding-right: 2px;
opacity: 0.7;
}
.ps-18__price span {
font-size: 0.32em;
font-weight: 500;
opacity: 0.65;
margin-left: 6px;
}
.ps-18__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
flex: 1;
font-size: 13px;
line-height: 1.95;
color: #b8c1d1;
}
.ps-18__card ul li::before {
content: '✓';
color: #a3e635;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-18__cta {
display: block;
text-align: center;
padding: 10px 16px;
border-radius: 8px;
text-decoration: none;
font-size: 13px;
font-weight: 600;
background: rgba(163,230,53,0.1);
color: #a3e635;
border: 1px solid rgba(163,230,53,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-18__cta-pri {
background: #a3e635;
color: #0f172a;
border-color: #a3e635;
}
.ps-18__cta:hover {
background: #a3e635;
color: #0f172a;
}
.ps-18__cta-pri:hover {
background: #d9f99d;
}
.ps-18__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-18__grid {
grid-template-columns: 1fr;
max-width: 360px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-18__track {
animation: 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: Social Proof Pricing
Source: https://codefronts.com/layouts/css-pricing-sections/social-proof-pricing/
A scrolling logo wall above the pricing tiers — social proof first, decision second. Slate background with lime accent on the recommended plan. Logos scroll in a seamless marquee using a duplicated track.
## HTML
```html
<section class="ps-18" aria-label="Pricing">
<div class="ps-18__marquee" aria-label="Customers using this product">
<div class="ps-18__track">
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
<span class="ps-18__logo">◇ NORTHWIND</span>
<span class="ps-18__logo">▲ APEX.IO</span>
<span class="ps-18__logo">★ PULSE</span>
<span class="ps-18__logo">⬣ HEXLAB</span>
<span class="ps-18__logo">◯ ORBITA</span>
<span class="ps-18__logo">◤ FLINT</span>
<span class="ps-18__logo">⬢ MERIDIAN</span>
</div>
</div>
<header class="ps-18__head">
<span class="ps-18__rating" aria-label="Rated 4.9 out of 5">★★★★★ 4.9 from 12,400 teams</span>
<h2>Pricing teams actually pay for.</h2>
</header>
<div class="ps-18__grid">
<article class="ps-18__card">
<h3>Free</h3>
<div class="ps-18__price"><em>$</em>0<span>forever</span></div>
<ul>
<li>1 project</li>
<li>5 GB storage</li>
<li>Community</li>
</ul>
<a class="ps-18__cta" href="#free">Start free</a>
</article>
<article class="ps-18__card ps-18__best">
<span class="ps-18__tag">Most teams pick this</span>
<h3>Team</h3>
<div class="ps-18__price"><em>$</em>32<span>/mo</span></div>
<ul>
<li>Unlimited projects</li>
<li>Priority support</li>
<li>SSO + roles</li>
</ul>
<a class="ps-18__cta ps-18__cta-pri" href="#team">Choose Team</a>
</article>
<article class="ps-18__card">
<h3>Enterprise</h3>
<div class="ps-18__price"><em>$</em>0<span>custom</span></div>
<ul>
<li>Everything in Team</li>
<li>Dedicated CSM</li>
<li>SLA 99.99%</li>
</ul>
<a class="ps-18__cta" href="#ent">Talk to sales</a>
</article>
</div>
</section>
```
## CSS
```css
.ps-18 {
position: relative;
overflow: hidden;
contain: layout paint;
padding: clamp(20px, 4vw, 36px) clamp(20px, 4vw, 40px) clamp(28px, 5vw, 48px);
width: 100%;
min-height: 100vh;
background: #0f172a;
color: #e2e8f0;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-18__marquee {
position: relative;
overflow: hidden;
contain: layout paint;
border-block: 1px solid rgba(163,230,53,0.18);
margin: 0 calc(-1 * clamp(20px, 4vw, 40px)) clamp(20px, 4vw, 32px);
padding: 14px 0;
background: rgba(15,23,42,0.6);
/* max-width containment: without this, the child .ps-18__track's
width: max-content (needed for the seamless marquee loop) propagates
up through this block wrapper — some layout engines size the wrapper
to child's intrinsic width instead of parent's content-box, causing
the whole section to grow to ~2045px and triggering horizontal body
scroll. Locking max-width to 100vw + min-width to 0 keeps the marquee
bounded regardless of child intrinsic width. overflow: hidden then
clips the marquee correctly. */
max-width: 100vw;
min-width: 0;
-webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ps-18__track {
display: flex;
gap: 56px;
white-space: nowrap;
animation: ps-18-roll 28s linear infinite;
width: max-content;
will-change: transform;
}
@keyframes ps-18-roll {
to {
transform: translateX(-50%);
}
}
.ps-18__logo {
font-family: 'JetBrains Mono', monospace;
font-size: 14px;
font-weight: 700;
letter-spacing: 0.18em;
color: #94a3b8;
flex-shrink: 0;
}
.ps-18__head {
text-align: center;
margin-bottom: clamp(20px, 4vw, 32px);
}
.ps-18__rating {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.08em;
color: #a3e635;
margin-bottom: 10px;
}
.ps-18__head h2 {
font-size: clamp(24px, 3.6vw, 36px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0;
color: #fff;
}
.ps-18__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
max-width: 940px;
margin: 0 auto;
align-items: center;
}
.ps-18__card {
position: relative;
background: #1e293b;
border: 1px solid rgba(163,230,53,0.12);
border-radius: 12px;
padding: 22px 20px 18px;
display: flex;
flex-direction: column;
}
.ps-18__best {
background: linear-gradient(180deg, #1e293b, #243f1a);
border-color: #a3e635;
box-shadow: 0 0 0 1px #a3e635 inset, 0 14px 36px rgba(163,230,53,0.18);
}
.ps-18__tag {
position: absolute;
top: -11px;
left: 50%;
transform: translateX(-50%);
background: #a3e635;
color: #0f172a;
font-size: 10.5px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 4px 11px;
border-radius: 999px;
}
.ps-18__card h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 0 0 12px;
color: #cbd5e1;
}
.ps-18__best h3 {
color: #d9f99d;
}
.ps-18__price {
display: flex;
align-items: baseline;
gap: 4px;
font-size: 38px;
font-weight: 800;
letter-spacing: -0.03em;
margin-bottom: 18px;
color: #fff;
}
.ps-18__price em {
font-size: 0.5em;
font-style: normal;
padding-right: 2px;
opacity: 0.7;
}
.ps-18__price span {
font-size: 0.32em;
font-weight: 500;
opacity: 0.65;
margin-left: 6px;
}
.ps-18__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
flex: 1;
font-size: 13px;
line-height: 1.95;
color: #b8c1d1;
}
.ps-18__card ul li::before {
content: '✓';
color: #a3e635;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-18__cta {
display: block;
text-align: center;
padding: 10px 16px;
border-radius: 8px;
text-decoration: none;
font-size: 13px;
font-weight: 600;
background: rgba(163,230,53,0.1);
color: #a3e635;
border: 1px solid rgba(163,230,53,0.28);
transition: background 0.18s, color 0.18s;
}
.ps-18__cta-pri {
background: #a3e635;
color: #0f172a;
border-color: #a3e635;
}
.ps-18__cta:hover {
background: #a3e635;
color: #0f172a;
}
.ps-18__cta-pri:hover {
background: #d9f99d;
}
.ps-18__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-18__grid {
grid-template-columns: 1fr;
max-width: 360px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-18__track {
animation: none;
}
}
```How this works
The social proof pricing section stacks three regions vertically: a full-bleed logo marquee, a centered rating + h2 header, and a display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) tier row. The marquee is a duplicated .ps-18__track of 14 <span> logos (7 unique, doubled) inside an overflow: hidden container; the @keyframes ps-18-roll rule animates transform: translateX(-50%) over 28s linear infinite, and because the track holds exactly two copies of the logo set the loop is visually seamless. A CSS mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent) feathers both edges so logos don't pop in and out.
Palette is high-trust B2B: slate #0f172a base for authority, softer slate #1e293b cards, and electric lime #a3e635 as the single conversion accent — used only on the recommended tier border, glow (box-shadow: 0 14px 36px rgba(163,230,53,0.18)), rating stars, and primary CTA. The recommended card gets a linear-gradient(180deg, #1e293b, #243f1a) — the base slate melting into lime-tinged dark green at the bottom, a subtle authority signal without breaking the palette. Inter for body, JetBrains Mono for the logo wall at letter-spacing: 0.18em — that wide tracking reads as engineered-precision, exactly the register enterprise CRM and marketing automation buyers scan for.
Why it converts: Cialdini social proof stacks three ways here — logo wall (peer usage), 4.9-star rating with review count (aggregate validation), and "Most teams pick this" tag (herd anchor). Baymard's testimonial pricing research shows pricing pages with visible social proof convert 30-45% higher than tier-only layouts, and the ps-18-roll marquee sits above the fold specifically because the first fixation on a pricing page decides whether the user reads tiers at all. The contain: layout paint on the marquee container isolates the animation from the rest of the page so INP stays low even during scroll.
Make it yours
- Recolor to your brand by editing three values: the slate base
#0f172a, the card slate#1e293b, and the accent lime#a3e635. Fintech leans navy + gold (#f59e0b); dev tools swap to cyan#22d3ee; enterprise SaaS often uses royal blue#3b82f6. The recommended card's melt-gradient endpoint (#243f1a) must be recomputed as a 20%-dark version of your accent. - Swap logo glyphs for real customer logos: replace each
<span class="ps-18__logo">with an inline SVG atheight: 22pxandfill: #94a3b8. Keep the doubled track — the seamless loop only works if the two halves are byte-identical. Real logos double the trust signal but weigh 4-8× more per node; keep the count under 12 unique to protect LCP. - Change marquee speed by tweaking
animation: ps-18-roll 28s linear infinite. Under 20s reads as anxious; over 40s reads as broken. The 28s default is the Baymard-validated "reading tempo" that lets a scanning eye register 3-4 logos per pass without feeling either sluggish or panicked. - For dark-on-light inversion: flip to
#f8fafcbase,#fffcards,#84cc16darker-lime accent, and the logo color to#64748b. The mask-image gradient endpoints stay transparent — masks are alpha-based, not color-based, so no other edits needed for the marquee fade. - For Tailwind: use
bg-slate-900 text-slate-200on the section,bg-slate-800 border-lime-400on the recommended card,animate-[ps-18-roll_28s_linear_infinite]on the track (declare the keyframes in yourtailwind.config.js). React/Next: wrap the marquee in a component that dedupes logos to a single source array and renders the array twice — avoids the copy-paste drift that breaks the seamless loop.
Gotchas — read before shipping
- The
ps-18-rollkeyframe animatestransformonly — never animateleftormargin-leftfor a marquee. Transform stays on the compositor thread; left/margin trigger layout every frame and tank INP to 300ms+ on mid-tier mobile. Thecontain: layout painton.ps-18__marqueeplus.ps-18further prevents layout leaks into surrounding tiers. - The seamless loop depends on the track holding exactly two identical copies of the logo set (14 items = 7 unique + 7 duplicate). If you add or remove a logo without duplicating, the
translateX(-50%)endpoint no longer aligns with the start of the second copy and you get a visible jump every 28 seconds. Always update in matched pairs. - The marquee has no
prefers-reduced-motion-driven pause button, onlyanimation: none— good for WCAG 2.3.3 (Animation from Interactions) but not for 2.2.2 (Pause, Stop, Hide) which requires user control for >5s auto-moving content. For strict compliance add a JS pause toggle, or accept that reduced-motion users are covered and standard users see the marquee. - The lime
#a3e635on slate#0f172ahits ~11:1 contrast (AAA), but lime on the recommended card's#243f1agradient endpoint drops to ~8:1 — still AA. The lime rating text at 12px on slate is 12.8:1 — fine. But if you push lime to a warmer green like#65a30d, re-run contrast against both slate and gradient stops; the melt-gradient can pull effective contrast below 4.5:1 in the bottom third. mask-imageneeds the-webkit-mask-imageprefix for Safari <15.4 and any WebKit-based iOS embedded browser. The CSS already ships both — do not remove the prefix even though caniuse says it's redundant on modern Safari; iOS in-app browsers (Instagram, TikTok, LinkedIn) lag mainline Safari by 12-18 months and are a huge slice of B2B SaaS pricing-page traffic.- The h2 uses
clamp(24px, 3.6vw, 36px)and the marquee sits directly above it — on very narrow phones (<340px) the marquee's edge fade can visually collide with the h2's top. If you tighten the header margin, verify LCP still fires on the h2 (not a logo) — logos loading as images would move LCP into the marquee and hurt the CWV report.