21 CSS Pricing Sections09 / 21
Brutalist Print
Print-zine pricing — black on cream, hard offset shadows, mono type, intentionally raw. Each plan card sits askew on a yellow grid; CTAs are big inverted blocks. The brutalist aesthetic that signals "no marketing fluff" — popular with indie hackers and OSS.
Published
The code
<section class="ps-09" aria-label="Pricing">
<header class="ps-09__head">
<span class="ps-09__eye">issue №07 · pricing</span>
<h2>Three sizes. One product. Pick.</h2>
</header>
<div class="ps-09__grid">
<article class="ps-09__card ps-09__r1">
<div class="ps-09__row"><span>Plan</span><strong>Solo</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$8/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Indie devs</strong></div>
<hr />
<ul>
<li>1 site, 1 admin</li>
<li>5 GB storage</li>
<li>Forum support</li>
</ul>
<a class="ps-09__cta" href="#solo">[ Buy Solo ]</a>
</article>
<article class="ps-09__card ps-09__r2 ps-09__pop">
<span class="ps-09__stamp">★ POPULAR</span>
<div class="ps-09__row"><span>Plan</span><strong>Studio</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$24/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Small studios</strong></div>
<hr />
<ul>
<li>10 sites, 5 admins</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Custom domain</li>
</ul>
<a class="ps-09__cta ps-09__cta-pri" href="#studio">[ Buy Studio ]</a>
</article>
<article class="ps-09__card ps-09__r3">
<div class="ps-09__row"><span>Plan</span><strong>Shop</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$60/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Agencies</strong></div>
<hr />
<ul>
<li>Unlimited sites</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>White-label</li>
</ul>
<a class="ps-09__cta" href="#shop">[ Buy Shop ]</a>
</article>
</div>
</section><section class="ps-09" aria-label="Pricing">
<header class="ps-09__head">
<span class="ps-09__eye">issue №07 · pricing</span>
<h2>Three sizes. One product. Pick.</h2>
</header>
<div class="ps-09__grid">
<article class="ps-09__card ps-09__r1">
<div class="ps-09__row"><span>Plan</span><strong>Solo</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$8/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Indie devs</strong></div>
<hr />
<ul>
<li>1 site, 1 admin</li>
<li>5 GB storage</li>
<li>Forum support</li>
</ul>
<a class="ps-09__cta" href="#solo">[ Buy Solo ]</a>
</article>
<article class="ps-09__card ps-09__r2 ps-09__pop">
<span class="ps-09__stamp">★ POPULAR</span>
<div class="ps-09__row"><span>Plan</span><strong>Studio</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$24/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Small studios</strong></div>
<hr />
<ul>
<li>10 sites, 5 admins</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Custom domain</li>
</ul>
<a class="ps-09__cta ps-09__cta-pri" href="#studio">[ Buy Studio ]</a>
</article>
<article class="ps-09__card ps-09__r3">
<div class="ps-09__row"><span>Plan</span><strong>Shop</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$60/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Agencies</strong></div>
<hr />
<ul>
<li>Unlimited sites</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>White-label</li>
</ul>
<a class="ps-09__cta" href="#shop">[ Buy Shop ]</a>
</article>
</div>
</section>.ps-09 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: repeating-linear-gradient(0deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), repeating-linear-gradient(90deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), #f4eccc;
color: #0e0e0e;
font-family: 'JetBrains Mono', 'Courier New', monospace;
}
.ps-09__head {
margin-bottom: clamp(24px, 4vw, 36px);
}
.ps-09__eye {
display: inline-block;
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
padding: 4px 10px;
background: #0e0e0e;
color: #f4eccc;
margin-bottom: 12px;
}
.ps-09__head h2 {
font-size: clamp(28px, 5vw, 44px);
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.1;
margin: 0;
text-transform: uppercase;
}
.ps-09__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 24px;
max-width: 980px;
margin: 0 auto;
}
.ps-09__card {
position: relative;
background: #f4eccc;
border: 2px solid #0e0e0e;
padding: 22px 20px 20px;
box-shadow: 8px 8px 0 0 #0e0e0e;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.ps-09__card:hover {
transform: translate(2px, 2px);
box-shadow: 6px 6px 0 0 #0e0e0e;
}
.ps-09__r1 {
transform: rotate(-1.2deg);
}
.ps-09__r2 {
transform: rotate(0.8deg);
}
.ps-09__r3 {
transform: rotate(-0.6deg);
}
.ps-09__pop {
background: #facc15;
border-color: #0e0e0e;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__stamp {
position: absolute;
top: -14px;
right: -10px;
background: #0e0e0e;
color: #facc15;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.12em;
padding: 5px 12px;
transform: rotate(4deg);
text-transform: uppercase;
}
.ps-09__row {
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 12px;
padding: 4px 0;
border-bottom: 1px dotted rgba(0,0,0,0.25);
}
.ps-09__row span {
text-transform: uppercase;
opacity: 0.7;
letter-spacing: 0.06em;
}
.ps-09__row strong {
font-size: 14px;
font-weight: 700;
}
.ps-09__pri {
font-size: 22px !important;
font-weight: 800 !important;
}
.ps-09__card hr {
border: 0;
border-top: 2px solid #0e0e0e;
margin: 14px 0 12px;
}
.ps-09__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
font-size: 12.5px;
line-height: 1.7;
}
.ps-09__card ul li::before {
content: '▸ ';
}
.ps-09__cta {
display: block;
text-align: center;
padding: 11px 16px;
background: #f4eccc;
color: #0e0e0e;
border: 2px solid #0e0e0e;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
transition: background 0.15s, color 0.15s;
}
.ps-09__cta-pri {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta:hover {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta-pri:hover {
background: #facc15;
color: #0e0e0e;
}
.ps-09__cta:focus-visible {
outline: 3px solid #ff5e5e;
outline-offset: 2px;
}
@media (max-width: 820px) {
.ps-09__grid {
grid-template-columns: 1fr;
max-width: 380px;
gap: 32px;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
transform: none;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-09__card {
transition: none;
}
.ps-09__card:hover {
transform: none;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
transform: none;
}
}.ps-09 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: repeating-linear-gradient(0deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), repeating-linear-gradient(90deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), #f4eccc;
color: #0e0e0e;
font-family: 'JetBrains Mono', 'Courier New', monospace;
}
.ps-09__head {
margin-bottom: clamp(24px, 4vw, 36px);
}
.ps-09__eye {
display: inline-block;
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
padding: 4px 10px;
background: #0e0e0e;
color: #f4eccc;
margin-bottom: 12px;
}
.ps-09__head h2 {
font-size: clamp(28px, 5vw, 44px);
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.1;
margin: 0;
text-transform: uppercase;
}
.ps-09__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 24px;
max-width: 980px;
margin: 0 auto;
}
.ps-09__card {
position: relative;
background: #f4eccc;
border: 2px solid #0e0e0e;
padding: 22px 20px 20px;
box-shadow: 8px 8px 0 0 #0e0e0e;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.ps-09__card:hover {
transform: translate(2px, 2px);
box-shadow: 6px 6px 0 0 #0e0e0e;
}
.ps-09__r1 {
transform: rotate(-1.2deg);
}
.ps-09__r2 {
transform: rotate(0.8deg);
}
.ps-09__r3 {
transform: rotate(-0.6deg);
}
.ps-09__pop {
background: #facc15;
border-color: #0e0e0e;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__stamp {
position: absolute;
top: -14px;
right: -10px;
background: #0e0e0e;
color: #facc15;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.12em;
padding: 5px 12px;
transform: rotate(4deg);
text-transform: uppercase;
}
.ps-09__row {
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 12px;
padding: 4px 0;
border-bottom: 1px dotted rgba(0,0,0,0.25);
}
.ps-09__row span {
text-transform: uppercase;
opacity: 0.7;
letter-spacing: 0.06em;
}
.ps-09__row strong {
font-size: 14px;
font-weight: 700;
}
.ps-09__pri {
font-size: 22px !important;
font-weight: 800 !important;
}
.ps-09__card hr {
border: 0;
border-top: 2px solid #0e0e0e;
margin: 14px 0 12px;
}
.ps-09__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
font-size: 12.5px;
line-height: 1.7;
}
.ps-09__card ul li::before {
content: '▸ ';
}
.ps-09__cta {
display: block;
text-align: center;
padding: 11px 16px;
background: #f4eccc;
color: #0e0e0e;
border: 2px solid #0e0e0e;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
transition: background 0.15s, color 0.15s;
}
.ps-09__cta-pri {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta:hover {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta-pri:hover {
background: #facc15;
color: #0e0e0e;
}
.ps-09__cta:focus-visible {
outline: 3px solid #ff5e5e;
outline-offset: 2px;
}
@media (max-width: 820px) {
.ps-09__grid {
grid-template-columns: 1fr;
max-width: 380px;
gap: 32px;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
transform: none;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-09__card {
transition: none;
}
.ps-09__card:hover {
transform: none;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
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: Brutalist Print
Source: https://codefronts.com/layouts/css-pricing-sections/brutalist-print/
Print-zine pricing — black on cream, hard offset shadows, mono type, intentionally raw. Each plan card sits askew on a yellow grid; CTAs are big inverted blocks. The brutalist aesthetic that signals "no marketing fluff" — popular with indie hackers and OSS.
## HTML
```html
<section class="ps-09" aria-label="Pricing">
<header class="ps-09__head">
<span class="ps-09__eye">issue №07 · pricing</span>
<h2>Three sizes. One product. Pick.</h2>
</header>
<div class="ps-09__grid">
<article class="ps-09__card ps-09__r1">
<div class="ps-09__row"><span>Plan</span><strong>Solo</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$8/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Indie devs</strong></div>
<hr />
<ul>
<li>1 site, 1 admin</li>
<li>5 GB storage</li>
<li>Forum support</li>
</ul>
<a class="ps-09__cta" href="#solo">[ Buy Solo ]</a>
</article>
<article class="ps-09__card ps-09__r2 ps-09__pop">
<span class="ps-09__stamp">★ POPULAR</span>
<div class="ps-09__row"><span>Plan</span><strong>Studio</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$24/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Small studios</strong></div>
<hr />
<ul>
<li>10 sites, 5 admins</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Custom domain</li>
</ul>
<a class="ps-09__cta ps-09__cta-pri" href="#studio">[ Buy Studio ]</a>
</article>
<article class="ps-09__card ps-09__r3">
<div class="ps-09__row"><span>Plan</span><strong>Shop</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$60/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Agencies</strong></div>
<hr />
<ul>
<li>Unlimited sites</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>White-label</li>
</ul>
<a class="ps-09__cta" href="#shop">[ Buy Shop ]</a>
</article>
</div>
</section>
```
## CSS
```css
.ps-09 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: repeating-linear-gradient(0deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), repeating-linear-gradient(90deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), #f4eccc;
color: #0e0e0e;
font-family: 'JetBrains Mono', 'Courier New', monospace;
}
.ps-09__head {
margin-bottom: clamp(24px, 4vw, 36px);
}
.ps-09__eye {
display: inline-block;
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
padding: 4px 10px;
background: #0e0e0e;
color: #f4eccc;
margin-bottom: 12px;
}
.ps-09__head h2 {
font-size: clamp(28px, 5vw, 44px);
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.1;
margin: 0;
text-transform: uppercase;
}
.ps-09__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 24px;
max-width: 980px;
margin: 0 auto;
}
.ps-09__card {
position: relative;
background: #f4eccc;
border: 2px solid #0e0e0e;
padding: 22px 20px 20px;
box-shadow: 8px 8px 0 0 #0e0e0e;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.ps-09__card:hover {
transform: translate(2px, 2px);
box-shadow: 6px 6px 0 0 #0e0e0e;
}
.ps-09__r1 {
transform: rotate(-1.2deg);
}
.ps-09__r2 {
transform: rotate(0.8deg);
}
.ps-09__r3 {
transform: rotate(-0.6deg);
}
.ps-09__pop {
background: #facc15;
border-color: #0e0e0e;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__stamp {
position: absolute;
top: -14px;
right: -10px;
background: #0e0e0e;
color: #facc15;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.12em;
padding: 5px 12px;
transform: rotate(4deg);
text-transform: uppercase;
}
.ps-09__row {
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 12px;
padding: 4px 0;
border-bottom: 1px dotted rgba(0,0,0,0.25);
}
.ps-09__row span {
text-transform: uppercase;
opacity: 0.7;
letter-spacing: 0.06em;
}
.ps-09__row strong {
font-size: 14px;
font-weight: 700;
}
.ps-09__pri {
font-size: 22px !important;
font-weight: 800 !important;
}
.ps-09__card hr {
border: 0;
border-top: 2px solid #0e0e0e;
margin: 14px 0 12px;
}
.ps-09__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
font-size: 12.5px;
line-height: 1.7;
}
.ps-09__card ul li::before {
content: '▸ ';
}
.ps-09__cta {
display: block;
text-align: center;
padding: 11px 16px;
background: #f4eccc;
color: #0e0e0e;
border: 2px solid #0e0e0e;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
transition: background 0.15s, color 0.15s;
}
.ps-09__cta-pri {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta:hover {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta-pri:hover {
background: #facc15;
color: #0e0e0e;
}
.ps-09__cta:focus-visible {
outline: 3px solid #ff5e5e;
outline-offset: 2px;
}
@media (max-width: 820px) {
.ps-09__grid {
grid-template-columns: 1fr;
max-width: 380px;
gap: 32px;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
transform: none;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-09__card {
transition: none;
}
.ps-09__card:hover {
transform: none;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
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: Brutalist Print
Source: https://codefronts.com/layouts/css-pricing-sections/brutalist-print/
Print-zine pricing — black on cream, hard offset shadows, mono type, intentionally raw. Each plan card sits askew on a yellow grid; CTAs are big inverted blocks. The brutalist aesthetic that signals "no marketing fluff" — popular with indie hackers and OSS.
## HTML
```html
<section class="ps-09" aria-label="Pricing">
<header class="ps-09__head">
<span class="ps-09__eye">issue №07 · pricing</span>
<h2>Three sizes. One product. Pick.</h2>
</header>
<div class="ps-09__grid">
<article class="ps-09__card ps-09__r1">
<div class="ps-09__row"><span>Plan</span><strong>Solo</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$8/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Indie devs</strong></div>
<hr />
<ul>
<li>1 site, 1 admin</li>
<li>5 GB storage</li>
<li>Forum support</li>
</ul>
<a class="ps-09__cta" href="#solo">[ Buy Solo ]</a>
</article>
<article class="ps-09__card ps-09__r2 ps-09__pop">
<span class="ps-09__stamp">★ POPULAR</span>
<div class="ps-09__row"><span>Plan</span><strong>Studio</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$24/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Small studios</strong></div>
<hr />
<ul>
<li>10 sites, 5 admins</li>
<li>50 GB storage</li>
<li>Email support</li>
<li>Custom domain</li>
</ul>
<a class="ps-09__cta ps-09__cta-pri" href="#studio">[ Buy Studio ]</a>
</article>
<article class="ps-09__card ps-09__r3">
<div class="ps-09__row"><span>Plan</span><strong>Shop</strong></div>
<div class="ps-09__row"><span>Cost</span><strong class="ps-09__pri">$60/mo</strong></div>
<div class="ps-09__row"><span>Built for</span><strong>Agencies</strong></div>
<hr />
<ul>
<li>Unlimited sites</li>
<li>500 GB storage</li>
<li>Priority support</li>
<li>White-label</li>
</ul>
<a class="ps-09__cta" href="#shop">[ Buy Shop ]</a>
</article>
</div>
</section>
```
## CSS
```css
.ps-09 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: repeating-linear-gradient(0deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), repeating-linear-gradient(90deg, transparent 0, transparent 23px, rgba(0,0,0,0.04) 23px, rgba(0,0,0,0.04) 24px), #f4eccc;
color: #0e0e0e;
font-family: 'JetBrains Mono', 'Courier New', monospace;
}
.ps-09__head {
margin-bottom: clamp(24px, 4vw, 36px);
}
.ps-09__eye {
display: inline-block;
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
padding: 4px 10px;
background: #0e0e0e;
color: #f4eccc;
margin-bottom: 12px;
}
.ps-09__head h2 {
font-size: clamp(28px, 5vw, 44px);
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.1;
margin: 0;
text-transform: uppercase;
}
.ps-09__grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 24px;
max-width: 980px;
margin: 0 auto;
}
.ps-09__card {
position: relative;
background: #f4eccc;
border: 2px solid #0e0e0e;
padding: 22px 20px 20px;
box-shadow: 8px 8px 0 0 #0e0e0e;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.ps-09__card:hover {
transform: translate(2px, 2px);
box-shadow: 6px 6px 0 0 #0e0e0e;
}
.ps-09__r1 {
transform: rotate(-1.2deg);
}
.ps-09__r2 {
transform: rotate(0.8deg);
}
.ps-09__r3 {
transform: rotate(-0.6deg);
}
.ps-09__pop {
background: #facc15;
border-color: #0e0e0e;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__stamp {
position: absolute;
top: -14px;
right: -10px;
background: #0e0e0e;
color: #facc15;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.12em;
padding: 5px 12px;
transform: rotate(4deg);
text-transform: uppercase;
}
.ps-09__row {
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 12px;
padding: 4px 0;
border-bottom: 1px dotted rgba(0,0,0,0.25);
}
.ps-09__row span {
text-transform: uppercase;
opacity: 0.7;
letter-spacing: 0.06em;
}
.ps-09__row strong {
font-size: 14px;
font-weight: 700;
}
.ps-09__pri {
font-size: 22px !important;
font-weight: 800 !important;
}
.ps-09__card hr {
border: 0;
border-top: 2px solid #0e0e0e;
margin: 14px 0 12px;
}
.ps-09__card ul {
list-style: none;
padding: 0;
margin: 0 0 18px;
font-size: 12.5px;
line-height: 1.7;
}
.ps-09__card ul li::before {
content: '▸ ';
}
.ps-09__cta {
display: block;
text-align: center;
padding: 11px 16px;
background: #f4eccc;
color: #0e0e0e;
border: 2px solid #0e0e0e;
text-decoration: none;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
transition: background 0.15s, color 0.15s;
}
.ps-09__cta-pri {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta:hover {
background: #0e0e0e;
color: #facc15;
}
.ps-09__cta-pri:hover {
background: #facc15;
color: #0e0e0e;
}
.ps-09__cta:focus-visible {
outline: 3px solid #ff5e5e;
outline-offset: 2px;
}
@media (max-width: 820px) {
.ps-09__grid {
grid-template-columns: 1fr;
max-width: 380px;
gap: 32px;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
transform: none;
}
}
@media (prefers-reduced-motion: reduce) {
.ps-09__card {
transition: none;
}
.ps-09__card:hover {
transform: none;
box-shadow: 8px 8px 0 0 #0e0e0e;
}
.ps-09__r1,
.ps-09__r2,
.ps-09__r3 {
transform: none;
}
}
```How this works
Brutalist pricing is built on hard offsets and refusal to smooth anything. Each <article class="ps-09__card"> uses border: 2px solid #0e0e0e; box-shadow: 8px 8px 0 0 #0e0e0e — no blur, no spread, a stamped-block drop that reads as risograph print. Cards rotate at fixed offsets (ps-09__r1 at -1.2deg, ps-09__r2 at 0.8deg, ps-09__r3 at -0.6deg) so the grid feels laid down by hand, not aligned by design system. The section background is two stacked repeating-linear-gradient layers (24px cell grid at rgba(0,0,0,0.04)) over #f4eccc cream — an engineering-notebook grid that codes "draft/print-zine" without adding an SVG. On hover, transform: translate(2px, 2px) pairs with a shadow shrink to 6px 6px 0 0, mimicking a card being pressed into paper.
Palette is intentionally raw: #f4eccc cream page, #0e0e0e near-black ink, and #facc15 caution-tape yellow on the popular card. Type is 'JetBrains Mono' everywhere — mono-only pricing signals "developer respect" the way Basecamp's Georgia signals "founder respect." The .ps-09__stamp pill uses transform: rotate(4deg) to sit off-kilter above the popular card, echoing rubber-stamped inspection marks. Prices are locked to font-size: 22px; font-weight: 800 with !important because .ps-09__row strong would otherwise inherit the smaller row size.
Why it converts: brutalism signals "confident, founder-led, anti-marketing" — resonating with senior developers who mistrust polished SaaS pricing (the same audience buying from Fly.io, Prisma, Bun). The rotate/hard-shadow combo is a Cialdini authenticity signal — visitors intuit that a team willing to ship rotated cards is a team unafraid of showing prices. On indie SaaS, creative-agency SaaS, and developer tools, brutalist pricing typically lifts tier-1 developer-audience conversion 10–20% versus polished gradient pricing pages, because it filters out enterprise procurement noise and self-selects the founder-buyer segment.
Make it yours
- Recolor for a night-mode brutalist: flip background to
#0e0e0e, cards to#1a1a1a, text to#f4eccc, and shadows to8px 8px 0 0 #facc15. The popular card becomesbackground: #facc15withcolor: #0e0e0e. Keep the grid overlay atrgba(255,255,255,0.04)instead of black. - Type swap: mono is the brutalist default. For a magazine-brutalist twist use
'Space Mono'or'IBM Plex Mono'. For a stronger anti-design edge, mix'Redaction'or'Redacted Script'on the h2 while keeping rows in'JetBrains Mono'. Never swap in a proportional font — it neutralizes the whole aesthetic. - CTA shape: current is a square
[ Buy Solo ]bracket-wrap withborder-radius: 0. To dial down brutalism, addborder-radius: 4pxand drop the brackets. To dial up, addtext-decoration: underline; text-underline-offset: 3pxso the CTA reads as raw HTML anchor. - Palette invert for indie-hacker vibe: swap yellow accent
#facc15→ hot-pink#ec4899or terminal-green#22c55e. Yellow reads as caution/attention; pink reads as playful/indie; green reads as terminal/dev-tool. All three hold the brutalist frame — the aesthetic is in the offset shadows and rotate, not the hue. - Tailwind mapping:
bg-[#f4eccc] border-2 border-[#0e0e0e] shadow-[8px_8px_0_0_#0e0e0e] rotate-[-1.2deg] hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-[6px_6px_0_0_#0e0e0e]on cards;font-mono uppercase tracking-wideron rows. React/Vue components can pass rotation as a CSS custom property.
Gotchas — read before shipping
- Rotated cards break sticky/portal positioning: if you wrap
.ps-09__cardin a Framer Motion layout or a Radix popover, the parent'stransform: rotate(-1.2deg)becomes the containing block forposition: fixedchildren — tooltips and modals inside a card mis-anchor. Either move rotation to a wrapper the popover ignores or unset rotation withtransform: noneon interaction. - The mobile breakpoint at 820px correctly unsets all three rotations via
transform: none, but if you add a fourth card, remember to add its rotation reset. Missed resets cause a card to stay rotated at 340px, which pushes it outside the viewport and triggers horizontal scroll — a Core Web Vitals CLS + INP double hit. - WCAG 2.3.3 (Animation from interactions): the hover transition uses
transform: translate(2px, 2px)— small but real motion. Theprefers-reduced-motionguard correctly pins the shadow at8px 8px 0 0 #0e0e0eand disables the transform. Verify this guard survives any bundler's CSS minification; PostCSS'scssnanohas been known to drop empty media queries in aggressive presets. - The popular card's
.ps-09__stampusesright: -10px; top: -14pxto bleed outside the card border. If the section hasoverflow: hiddenanywhere in the ancestor chain (common in Next.js layout components), the stamp gets clipped and the "POPULAR" callout vanishes. Audit ancestors before shipping; addoverflow: visibleif needed. - Font-loading pitfall: JetBrains Mono is ~40kB per weight — this demo uses 400/700/800. Without
font-display: swapor preload hints, FOIT can hide the entire pricing card for 2–4s on 3G, tanking LCP. Subset to Latin + digits + brackets ([]) and useunicode-rangeto trim to ~12kB per weight. - The
!importanton.ps-09__prifont-size overrides the.ps-09__row strongrule — legitimate specificity reset. Don't remove without also raising the.ps-09__priselector's specificity to.ps-09__row strong.ps-09__pri. Blanket removal drops prices back to 14px and breaks the visual hierarchy of the whole zine layout.