21 CSS Pricing Sections13 / 21
Editorial Two Column
A dense editorial pricing layout — left column carries the value-prop copy, right column stacks two compact tier rows like a printed price list. Neutral charcoal on cream, the Stripe / Basecamp documentation aesthetic.
Published
The code
<section class="ps-13" aria-label="Pricing">
<div class="ps-13__grid">
<div class="ps-13__copy">
<span class="ps-13__eye">— Pricing</span>
<h2>Two plans. <em>Pick one,</em> change later.</h2>
<p>
We don’t play games with feature gating, seat limits, or upsell pop-ups. Pick a plan, get
the whole product, and move on with your work.
</p>
<p class="ps-13__fine">
All plans include unlimited projects, every integration, and email support. Cancel any time,
money back inside 30 days.
</p>
<a class="ps-13__link" href="#compare">See the full feature list →</a>
</div>
<div class="ps-13__tiers">
<article class="ps-13__row">
<header>
<h3>Solo</h3>
<span class="ps-13__pri">$15<em>/ month</em></span>
</header>
<p>For freelancers and indie builders shipping client work.</p>
<ul>
<li>Single workspace</li>
<li>10 GB storage</li>
<li>Email support</li>
</ul>
<a class="ps-13__cta" href="#solo">Choose Solo →</a>
</article>
<article class="ps-13__row ps-13__rec">
<header>
<h3>Studio <span class="ps-13__tag">Recommended</span></h3>
<span class="ps-13__pri">$48<em>/ month</em></span>
</header>
<p>For small teams who run multiple client engagements.</p>
<ul>
<li>Unlimited workspaces</li>
<li>250 GB storage</li>
<li>Priority support & onboarding</li>
<li>Client billing & white-label</li>
</ul>
<a class="ps-13__cta ps-13__cta-pri" href="#studio">Choose Studio →</a>
</article>
</div>
</div>
</section><section class="ps-13" aria-label="Pricing">
<div class="ps-13__grid">
<div class="ps-13__copy">
<span class="ps-13__eye">— Pricing</span>
<h2>Two plans. <em>Pick one,</em> change later.</h2>
<p>
We don’t play games with feature gating, seat limits, or upsell pop-ups. Pick a plan, get
the whole product, and move on with your work.
</p>
<p class="ps-13__fine">
All plans include unlimited projects, every integration, and email support. Cancel any time,
money back inside 30 days.
</p>
<a class="ps-13__link" href="#compare">See the full feature list →</a>
</div>
<div class="ps-13__tiers">
<article class="ps-13__row">
<header>
<h3>Solo</h3>
<span class="ps-13__pri">$15<em>/ month</em></span>
</header>
<p>For freelancers and indie builders shipping client work.</p>
<ul>
<li>Single workspace</li>
<li>10 GB storage</li>
<li>Email support</li>
</ul>
<a class="ps-13__cta" href="#solo">Choose Solo →</a>
</article>
<article class="ps-13__row ps-13__rec">
<header>
<h3>Studio <span class="ps-13__tag">Recommended</span></h3>
<span class="ps-13__pri">$48<em>/ month</em></span>
</header>
<p>For small teams who run multiple client engagements.</p>
<ul>
<li>Unlimited workspaces</li>
<li>250 GB storage</li>
<li>Priority support & onboarding</li>
<li>Client billing & white-label</li>
</ul>
<a class="ps-13__cta ps-13__cta-pri" href="#studio">Choose Studio →</a>
</article>
</div>
</div>
</section>.ps-13 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #f5f1ea;
color: #1c1c1e;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-13__grid {
max-width: 1040px;
margin: 0 auto;
display: grid;
grid-template-columns: 1.1fr 1fr;
gap: 56px;
align-items: start;
}
.ps-13__copy {
padding-top: 6px;
}
.ps-13__eye {
display: block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
letter-spacing: 0.1em;
color: #6b6b6e;
margin-bottom: 14px;
}
.ps-13__copy h2 {
font-family: 'Playfair Display', Georgia, serif;
font-size: clamp(28px, 4.4vw, 44px);
font-weight: 700;
letter-spacing: -0.015em;
line-height: 1.1;
margin: 0 0 18px;
}
.ps-13__copy h2 em {
font-style: italic;
color: #6b6b6e;
}
.ps-13__copy p {
font-size: 15px;
line-height: 1.65;
color: #3d3d40;
margin: 0 0 12px;
max-width: 380px;
}
.ps-13__fine {
font-size: 13px !important;
color: #6b6b6e !important;
padding-top: 12px;
border-top: 1px solid #d8d2c5;
}
.ps-13__link {
display: inline-block;
margin-top: 12px;
font-size: 13px;
font-weight: 600;
color: #1c1c1e;
text-decoration: underline;
text-underline-offset: 4px;
text-decoration-thickness: 1.5px;
}
.ps-13__link:hover {
color: #6b6b6e;
}
.ps-13__tiers {
display: flex;
flex-direction: column;
gap: 14px;
}
.ps-13__row {
background: #fff;
border: 1px solid #d8d2c5;
border-radius: 6px;
padding: 22px 22px 18px;
transition: border-color 0.18s, box-shadow 0.18s;
}
.ps-13__row:hover {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__rec {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__row header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
padding-bottom: 12px;
margin-bottom: 12px;
border-bottom: 1px dashed #d8d2c5;
}
.ps-13__row h3 {
font-family: 'Playfair Display', Georgia, serif;
font-size: 22px;
font-weight: 700;
margin: 0;
display: flex;
align-items: center;
gap: 10px;
}
.ps-13__tag {
font-family: 'JetBrains Mono', monospace;
font-size: 9.5px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
background: #1c1c1e;
color: #f5f1ea;
padding: 3px 8px;
border-radius: 2px;
}
.ps-13__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
}
.ps-13__pri em {
font-size: 11px;
font-style: normal;
color: #6b6b6e;
font-weight: 500;
margin-left: 4px;
letter-spacing: 0;
}
.ps-13__row p {
font-size: 13.5px;
color: #3d3d40;
margin: 0 0 10px;
line-height: 1.5;
}
.ps-13__row ul {
list-style: none;
padding: 0;
margin: 0 0 16px;
font-size: 13px;
line-height: 1.85;
color: #3d3d40;
}
.ps-13__row ul li::before {
content: '·';
color: #1c1c1e;
font-weight: 800;
display: inline-block;
width: 18px;
font-size: 18px;
line-height: 0.5;
vertical-align: middle;
}
.ps-13__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 4px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1.5px solid #1c1c1e;
color: #1c1c1e;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-13__cta-pri {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta:hover {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta-pri:hover {
background: #f5f1ea;
color: #1c1c1e;
}
.ps-13__cta:focus-visible {
outline: 2px solid #1c1c1e;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-13__grid {
grid-template-columns: 1fr;
gap: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-13__row {
transition: none;
}
.ps-13__row:hover {
transform: none;
}
}.ps-13 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #f5f1ea;
color: #1c1c1e;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-13__grid {
max-width: 1040px;
margin: 0 auto;
display: grid;
grid-template-columns: 1.1fr 1fr;
gap: 56px;
align-items: start;
}
.ps-13__copy {
padding-top: 6px;
}
.ps-13__eye {
display: block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
letter-spacing: 0.1em;
color: #6b6b6e;
margin-bottom: 14px;
}
.ps-13__copy h2 {
font-family: 'Playfair Display', Georgia, serif;
font-size: clamp(28px, 4.4vw, 44px);
font-weight: 700;
letter-spacing: -0.015em;
line-height: 1.1;
margin: 0 0 18px;
}
.ps-13__copy h2 em {
font-style: italic;
color: #6b6b6e;
}
.ps-13__copy p {
font-size: 15px;
line-height: 1.65;
color: #3d3d40;
margin: 0 0 12px;
max-width: 380px;
}
.ps-13__fine {
font-size: 13px !important;
color: #6b6b6e !important;
padding-top: 12px;
border-top: 1px solid #d8d2c5;
}
.ps-13__link {
display: inline-block;
margin-top: 12px;
font-size: 13px;
font-weight: 600;
color: #1c1c1e;
text-decoration: underline;
text-underline-offset: 4px;
text-decoration-thickness: 1.5px;
}
.ps-13__link:hover {
color: #6b6b6e;
}
.ps-13__tiers {
display: flex;
flex-direction: column;
gap: 14px;
}
.ps-13__row {
background: #fff;
border: 1px solid #d8d2c5;
border-radius: 6px;
padding: 22px 22px 18px;
transition: border-color 0.18s, box-shadow 0.18s;
}
.ps-13__row:hover {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__rec {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__row header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
padding-bottom: 12px;
margin-bottom: 12px;
border-bottom: 1px dashed #d8d2c5;
}
.ps-13__row h3 {
font-family: 'Playfair Display', Georgia, serif;
font-size: 22px;
font-weight: 700;
margin: 0;
display: flex;
align-items: center;
gap: 10px;
}
.ps-13__tag {
font-family: 'JetBrains Mono', monospace;
font-size: 9.5px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
background: #1c1c1e;
color: #f5f1ea;
padding: 3px 8px;
border-radius: 2px;
}
.ps-13__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
}
.ps-13__pri em {
font-size: 11px;
font-style: normal;
color: #6b6b6e;
font-weight: 500;
margin-left: 4px;
letter-spacing: 0;
}
.ps-13__row p {
font-size: 13.5px;
color: #3d3d40;
margin: 0 0 10px;
line-height: 1.5;
}
.ps-13__row ul {
list-style: none;
padding: 0;
margin: 0 0 16px;
font-size: 13px;
line-height: 1.85;
color: #3d3d40;
}
.ps-13__row ul li::before {
content: '·';
color: #1c1c1e;
font-weight: 800;
display: inline-block;
width: 18px;
font-size: 18px;
line-height: 0.5;
vertical-align: middle;
}
.ps-13__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 4px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1.5px solid #1c1c1e;
color: #1c1c1e;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-13__cta-pri {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta:hover {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta-pri:hover {
background: #f5f1ea;
color: #1c1c1e;
}
.ps-13__cta:focus-visible {
outline: 2px solid #1c1c1e;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-13__grid {
grid-template-columns: 1fr;
gap: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-13__row {
transition: none;
}
.ps-13__row: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: Editorial Two Column
Source: https://codefronts.com/layouts/css-pricing-sections/editorial-two-column/
A dense editorial pricing layout — left column carries the value-prop copy, right column stacks two compact tier rows like a printed price list. Neutral charcoal on cream, the Stripe / Basecamp documentation aesthetic.
## HTML
```html
<section class="ps-13" aria-label="Pricing">
<div class="ps-13__grid">
<div class="ps-13__copy">
<span class="ps-13__eye">— Pricing</span>
<h2>Two plans. <em>Pick one,</em> change later.</h2>
<p>
We don’t play games with feature gating, seat limits, or upsell pop-ups. Pick a plan, get
the whole product, and move on with your work.
</p>
<p class="ps-13__fine">
All plans include unlimited projects, every integration, and email support. Cancel any time,
money back inside 30 days.
</p>
<a class="ps-13__link" href="#compare">See the full feature list →</a>
</div>
<div class="ps-13__tiers">
<article class="ps-13__row">
<header>
<h3>Solo</h3>
<span class="ps-13__pri">$15<em>/ month</em></span>
</header>
<p>For freelancers and indie builders shipping client work.</p>
<ul>
<li>Single workspace</li>
<li>10 GB storage</li>
<li>Email support</li>
</ul>
<a class="ps-13__cta" href="#solo">Choose Solo →</a>
</article>
<article class="ps-13__row ps-13__rec">
<header>
<h3>Studio <span class="ps-13__tag">Recommended</span></h3>
<span class="ps-13__pri">$48<em>/ month</em></span>
</header>
<p>For small teams who run multiple client engagements.</p>
<ul>
<li>Unlimited workspaces</li>
<li>250 GB storage</li>
<li>Priority support & onboarding</li>
<li>Client billing & white-label</li>
</ul>
<a class="ps-13__cta ps-13__cta-pri" href="#studio">Choose Studio →</a>
</article>
</div>
</div>
</section>
```
## CSS
```css
.ps-13 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #f5f1ea;
color: #1c1c1e;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-13__grid {
max-width: 1040px;
margin: 0 auto;
display: grid;
grid-template-columns: 1.1fr 1fr;
gap: 56px;
align-items: start;
}
.ps-13__copy {
padding-top: 6px;
}
.ps-13__eye {
display: block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
letter-spacing: 0.1em;
color: #6b6b6e;
margin-bottom: 14px;
}
.ps-13__copy h2 {
font-family: 'Playfair Display', Georgia, serif;
font-size: clamp(28px, 4.4vw, 44px);
font-weight: 700;
letter-spacing: -0.015em;
line-height: 1.1;
margin: 0 0 18px;
}
.ps-13__copy h2 em {
font-style: italic;
color: #6b6b6e;
}
.ps-13__copy p {
font-size: 15px;
line-height: 1.65;
color: #3d3d40;
margin: 0 0 12px;
max-width: 380px;
}
.ps-13__fine {
font-size: 13px !important;
color: #6b6b6e !important;
padding-top: 12px;
border-top: 1px solid #d8d2c5;
}
.ps-13__link {
display: inline-block;
margin-top: 12px;
font-size: 13px;
font-weight: 600;
color: #1c1c1e;
text-decoration: underline;
text-underline-offset: 4px;
text-decoration-thickness: 1.5px;
}
.ps-13__link:hover {
color: #6b6b6e;
}
.ps-13__tiers {
display: flex;
flex-direction: column;
gap: 14px;
}
.ps-13__row {
background: #fff;
border: 1px solid #d8d2c5;
border-radius: 6px;
padding: 22px 22px 18px;
transition: border-color 0.18s, box-shadow 0.18s;
}
.ps-13__row:hover {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__rec {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__row header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
padding-bottom: 12px;
margin-bottom: 12px;
border-bottom: 1px dashed #d8d2c5;
}
.ps-13__row h3 {
font-family: 'Playfair Display', Georgia, serif;
font-size: 22px;
font-weight: 700;
margin: 0;
display: flex;
align-items: center;
gap: 10px;
}
.ps-13__tag {
font-family: 'JetBrains Mono', monospace;
font-size: 9.5px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
background: #1c1c1e;
color: #f5f1ea;
padding: 3px 8px;
border-radius: 2px;
}
.ps-13__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
}
.ps-13__pri em {
font-size: 11px;
font-style: normal;
color: #6b6b6e;
font-weight: 500;
margin-left: 4px;
letter-spacing: 0;
}
.ps-13__row p {
font-size: 13.5px;
color: #3d3d40;
margin: 0 0 10px;
line-height: 1.5;
}
.ps-13__row ul {
list-style: none;
padding: 0;
margin: 0 0 16px;
font-size: 13px;
line-height: 1.85;
color: #3d3d40;
}
.ps-13__row ul li::before {
content: '·';
color: #1c1c1e;
font-weight: 800;
display: inline-block;
width: 18px;
font-size: 18px;
line-height: 0.5;
vertical-align: middle;
}
.ps-13__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 4px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1.5px solid #1c1c1e;
color: #1c1c1e;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-13__cta-pri {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta:hover {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta-pri:hover {
background: #f5f1ea;
color: #1c1c1e;
}
.ps-13__cta:focus-visible {
outline: 2px solid #1c1c1e;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-13__grid {
grid-template-columns: 1fr;
gap: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-13__row {
transition: none;
}
.ps-13__row: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: Editorial Two Column
Source: https://codefronts.com/layouts/css-pricing-sections/editorial-two-column/
A dense editorial pricing layout — left column carries the value-prop copy, right column stacks two compact tier rows like a printed price list. Neutral charcoal on cream, the Stripe / Basecamp documentation aesthetic.
## HTML
```html
<section class="ps-13" aria-label="Pricing">
<div class="ps-13__grid">
<div class="ps-13__copy">
<span class="ps-13__eye">— Pricing</span>
<h2>Two plans. <em>Pick one,</em> change later.</h2>
<p>
We don’t play games with feature gating, seat limits, or upsell pop-ups. Pick a plan, get
the whole product, and move on with your work.
</p>
<p class="ps-13__fine">
All plans include unlimited projects, every integration, and email support. Cancel any time,
money back inside 30 days.
</p>
<a class="ps-13__link" href="#compare">See the full feature list →</a>
</div>
<div class="ps-13__tiers">
<article class="ps-13__row">
<header>
<h3>Solo</h3>
<span class="ps-13__pri">$15<em>/ month</em></span>
</header>
<p>For freelancers and indie builders shipping client work.</p>
<ul>
<li>Single workspace</li>
<li>10 GB storage</li>
<li>Email support</li>
</ul>
<a class="ps-13__cta" href="#solo">Choose Solo →</a>
</article>
<article class="ps-13__row ps-13__rec">
<header>
<h3>Studio <span class="ps-13__tag">Recommended</span></h3>
<span class="ps-13__pri">$48<em>/ month</em></span>
</header>
<p>For small teams who run multiple client engagements.</p>
<ul>
<li>Unlimited workspaces</li>
<li>250 GB storage</li>
<li>Priority support & onboarding</li>
<li>Client billing & white-label</li>
</ul>
<a class="ps-13__cta ps-13__cta-pri" href="#studio">Choose Studio →</a>
</article>
</div>
</div>
</section>
```
## CSS
```css
.ps-13 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #f5f1ea;
color: #1c1c1e;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-13__grid {
max-width: 1040px;
margin: 0 auto;
display: grid;
grid-template-columns: 1.1fr 1fr;
gap: 56px;
align-items: start;
}
.ps-13__copy {
padding-top: 6px;
}
.ps-13__eye {
display: block;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
letter-spacing: 0.1em;
color: #6b6b6e;
margin-bottom: 14px;
}
.ps-13__copy h2 {
font-family: 'Playfair Display', Georgia, serif;
font-size: clamp(28px, 4.4vw, 44px);
font-weight: 700;
letter-spacing: -0.015em;
line-height: 1.1;
margin: 0 0 18px;
}
.ps-13__copy h2 em {
font-style: italic;
color: #6b6b6e;
}
.ps-13__copy p {
font-size: 15px;
line-height: 1.65;
color: #3d3d40;
margin: 0 0 12px;
max-width: 380px;
}
.ps-13__fine {
font-size: 13px !important;
color: #6b6b6e !important;
padding-top: 12px;
border-top: 1px solid #d8d2c5;
}
.ps-13__link {
display: inline-block;
margin-top: 12px;
font-size: 13px;
font-weight: 600;
color: #1c1c1e;
text-decoration: underline;
text-underline-offset: 4px;
text-decoration-thickness: 1.5px;
}
.ps-13__link:hover {
color: #6b6b6e;
}
.ps-13__tiers {
display: flex;
flex-direction: column;
gap: 14px;
}
.ps-13__row {
background: #fff;
border: 1px solid #d8d2c5;
border-radius: 6px;
padding: 22px 22px 18px;
transition: border-color 0.18s, box-shadow 0.18s;
}
.ps-13__row:hover {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__rec {
border-color: #1c1c1e;
box-shadow: 4px 4px 0 0 #1c1c1e;
}
.ps-13__row header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
padding-bottom: 12px;
margin-bottom: 12px;
border-bottom: 1px dashed #d8d2c5;
}
.ps-13__row h3 {
font-family: 'Playfair Display', Georgia, serif;
font-size: 22px;
font-weight: 700;
margin: 0;
display: flex;
align-items: center;
gap: 10px;
}
.ps-13__tag {
font-family: 'JetBrains Mono', monospace;
font-size: 9.5px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
background: #1c1c1e;
color: #f5f1ea;
padding: 3px 8px;
border-radius: 2px;
}
.ps-13__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
}
.ps-13__pri em {
font-size: 11px;
font-style: normal;
color: #6b6b6e;
font-weight: 500;
margin-left: 4px;
letter-spacing: 0;
}
.ps-13__row p {
font-size: 13.5px;
color: #3d3d40;
margin: 0 0 10px;
line-height: 1.5;
}
.ps-13__row ul {
list-style: none;
padding: 0;
margin: 0 0 16px;
font-size: 13px;
line-height: 1.85;
color: #3d3d40;
}
.ps-13__row ul li::before {
content: '·';
color: #1c1c1e;
font-weight: 800;
display: inline-block;
width: 18px;
font-size: 18px;
line-height: 0.5;
vertical-align: middle;
}
.ps-13__cta {
display: inline-block;
padding: 9px 16px;
border-radius: 4px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1.5px solid #1c1c1e;
color: #1c1c1e;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-13__cta-pri {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta:hover {
background: #1c1c1e;
color: #f5f1ea;
}
.ps-13__cta-pri:hover {
background: #f5f1ea;
color: #1c1c1e;
}
.ps-13__cta:focus-visible {
outline: 2px solid #1c1c1e;
outline-offset: 3px;
}
@media (max-width: 820px) {
.ps-13__grid {
grid-template-columns: 1fr;
gap: 32px;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-13__row {
transition: none;
}
.ps-13__row:hover {
transform: none;
}
}
```How this works
The layout is a two-column CSS grid, grid-template-columns: 1.1fr 1fr with a 56px gutter — the left column is deliberately heavier so the value-prop copy anchors the visitor's first read, and the right column stacks two .ps-13__row tier cards as if they were entries in a printed price list. align-items: start pins both columns to the top so the copy does not vertically center against the tiers — that would break the magazine-page rhythm. The tier stack uses display: flex; flex-direction: column; gap: 14px, and each row is a solid #fff card with a 4px 4px 0 0 #1c1c1e flat-stamp shadow on the recommended Studio tier — the same shadow the hover state applies to Solo, which telegraphs "hover-to-preview" without a tooltip.
The palette is deliberately editorial: cream body (#f5f1ea), near-black ink (#1c1c1e), and warm-gray secondary text (#6b6b6e) — the three-value stack that Stripe's docs, 37signals blog, and Basecamp pricing all use. Typography carries the register: Playfair Display serif for h2 and tier names (font-size: 22px; font-weight: 700), Inter for body copy at 15px/1.65, and JetBrains Mono for the .ps-13__eye eyebrow and the small .ps-13__tag "Recommended" chip. Serif headline + monospace metadata is the editorial pricing signature.
Why this converts on editorial pricing and B2B SaaS: prose-heavy pricing framing borrows trust from print journalism — visitors read the left column as "considered offer," not "hard sell," which is exactly the reciprocity signal Cialdini identifies. The two-tier constraint is deliberate Iyengar-jam-shelf choice reduction (two options beat five for conversion on considered purchases), and the .ps-13__fine risk-reversal line ("Cancel any time, money back inside 30 days") sits directly under the value prop where hesitant readers look — Baymard's checkout research shows visible refund copy lifts trust-motivated conversions 30-45%.
Make it yours
- Recolor to your brand by editing four values: cream background (
#f5f1ea), ink black (#1c1c1e), warm gray (#6b6b6e), and hairline border (#d8d2c5). For newsletter/media SaaS swap cream to#fefaf3; for fintech-editorial swap ink to#0b1220and cream to#f4f2ee. - Swap Playfair Display:
'Cormorant Garamond'for artisanal / handcrafted register,'Source Serif Pro'for tech-editorial,'GT Sectra'for luxury,'IBM Plex Serif'for brutalist. Keep JetBrains Mono for the eyebrow and tag — the serif+mono pairing is the whole editorial signal. - Change the CTA shape:
border-radius: 4pxreads as "editorial stamp." Drop to0for brutalist ticket-stub CTAs. The4px 4px 0 0 #1c1c1eflat shadow on.ps-13__recpairs with sharp corners only — bumping radius above 6px makes the offset shadow look like a mistake. - For dark-mode: invert to
#1a1815background,#f5f1eatext,#a8a29ewarm gray, keep white card bodies at#252220and the flat-stamp shadow becomes4px 4px 0 0 #f5f1ea. The Playfair italic emphasis stays untouched — cream-italic on ink is the strongest editorial pairing. - For Tailwind:
bg-[#f5f1ea] font-sanson section,font-serif text-[clamp(28px,4.4vw,44px)] leading-[1.1] tracking-tighton h2, tier rows asbg-white border border-[#d8d2c5] rounded-[6px] hover:shadow-[4px_4px_0_0_#1c1c1e]. Use@font-facefor Playfair — Google Fonts CDN blocks LCP by ~200ms.
Gotchas — read before shipping
- The
4px 4px 0 0 #1c1c1ehover shadow is a paint operation, not a transform — hovering triggers a paint on a 22×22px card region which is cheap, but if you replicate this pattern on 6+ tiers per row you will see INP spike above 200ms on mid-tier mobile. Cap total simultaneous hover paints at 3. - Playfair Display's italic
<em>inside the h2 works because Playfair ships true italics. If a browser fails to load Playfair and falls back to Georgia, Georgia's italics are acceptable butsystem-uion Android renders synthetic obliques that look janky. Shipfont-display: swapand preload the italic weight explicitly. - The
.ps-13__fineuses!importanton two properties because.ps-13__copy phas higher specificity than.ps-13__finealone. This is a legit specificity-reset use of !important — do not remove it unless you also raise.ps-13__fine's selector (e.g..ps-13__copy p.ps-13__fine). - The recommended-tier CTA uses
color: #f5f1eaonbackground: #1c1c1e— contrast ratio ~14.8:1, comfortably clears WCAG 2.1 SC 1.4.3 AAA. The muted eyebrow at#6b6b6eon#f5f1eahowever is only ~4.9:1, AA-only for the 12px size — do not drop it below 12px or you fail AA. - The dashed
border-bottom: 1px dashed #d8d2c5on the card header renders inconsistently across engines: Chrome draws 2px on/2px off, Safari draws 3px on/1px off, Firefox draws 2px on/3px off. If the dash pattern matters for brand consistency, replace withbackground-image: linear-gradient(90deg, #d8d2c5 50%, transparent 50%)atbackground-size: 6px 1px. - In Next.js App Router,
'Playfair Display'loaded vianext/font/googlededuplicates automatically, but Vue 3 + Vite with@fontsourceships one file per weight — importing italic + bold + regular triples the LCP font payload. Use@fontsource-variable/playfair-displayfor a single 40KB file instead.