21 CSS Pricing Sections08 / 21
Vertical Tier Timeline
Tiers presented as a vertical roadmap — Free → Pro → Enterprise — connected by a glowing lime spine. Each station is a real <ol>/<li> with a numbered milestone, price, and feature list. Reads as a growth path, not a column comparison.
Published
The code
<section class="ps-08" aria-label="Pricing">
<header class="ps-08__head">
<h2>Grow into the next plan, not out of one.</h2>
<p>Three stops on the same road. Switch up or down with one click.</p>
</header>
<ol class="ps-08__line">
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">01</span>
<article class="ps-08__pane">
<header>
<h3>Free</h3>
<span class="ps-08__pri">$0</span>
</header>
<p>
Open-source projects, side experiments, anything you want to ship without a credit card.
</p>
<ul>
<li>1 project</li>
<li>500 MB storage</li>
<li>Public repos only</li>
</ul>
<a class="ps-08__cta" href="#free">Start free →</a>
</article>
</li>
<li class="ps-08__stop ps-08__current">
<span class="ps-08__num" aria-hidden="true">02</span>
<article class="ps-08__pane">
<header>
<h3>Pro</h3>
<span class="ps-08__pri">$24<em>/mo</em></span>
</header>
<p>
Where most teams settle. Private projects, real support, and the integrations you actually
use.
</p>
<ul>
<li>Unlimited projects</li>
<li>50 GB storage</li>
<li>Email + chat support</li>
<li>Slack, GitHub, Linear sync</li>
</ul>
<a class="ps-08__cta ps-08__cta-pri" href="#pro">Choose Pro →</a>
</article>
</li>
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">03</span>
<article class="ps-08__pane">
<header>
<h3>Enterprise</h3>
<span class="ps-08__pri">Custom</span>
</header>
<p>
For teams with procurement processes, security reviews, and quarterly business reviews.
</p>
<ul>
<li>SSO + SAML + audit logs</li>
<li>SLA, dedicated CSM</li>
<li>Custom DPA & invoicing</li>
</ul>
<a class="ps-08__cta" href="#ent">Talk to sales →</a>
</article>
</li>
</ol>
</section><section class="ps-08" aria-label="Pricing">
<header class="ps-08__head">
<h2>Grow into the next plan, not out of one.</h2>
<p>Three stops on the same road. Switch up or down with one click.</p>
</header>
<ol class="ps-08__line">
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">01</span>
<article class="ps-08__pane">
<header>
<h3>Free</h3>
<span class="ps-08__pri">$0</span>
</header>
<p>
Open-source projects, side experiments, anything you want to ship without a credit card.
</p>
<ul>
<li>1 project</li>
<li>500 MB storage</li>
<li>Public repos only</li>
</ul>
<a class="ps-08__cta" href="#free">Start free →</a>
</article>
</li>
<li class="ps-08__stop ps-08__current">
<span class="ps-08__num" aria-hidden="true">02</span>
<article class="ps-08__pane">
<header>
<h3>Pro</h3>
<span class="ps-08__pri">$24<em>/mo</em></span>
</header>
<p>
Where most teams settle. Private projects, real support, and the integrations you actually
use.
</p>
<ul>
<li>Unlimited projects</li>
<li>50 GB storage</li>
<li>Email + chat support</li>
<li>Slack, GitHub, Linear sync</li>
</ul>
<a class="ps-08__cta ps-08__cta-pri" href="#pro">Choose Pro →</a>
</article>
</li>
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">03</span>
<article class="ps-08__pane">
<header>
<h3>Enterprise</h3>
<span class="ps-08__pri">Custom</span>
</header>
<p>
For teams with procurement processes, security reviews, and quarterly business reviews.
</p>
<ul>
<li>SSO + SAML + audit logs</li>
<li>SLA, dedicated CSM</li>
<li>Custom DPA & invoicing</li>
</ul>
<a class="ps-08__cta" href="#ent">Talk to sales →</a>
</article>
</li>
</ol>
</section>.ps-08 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #0a1408;
color: #ecfccb;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-08__head {
text-align: center;
margin-bottom: clamp(28px, 5vw, 44px);
}
.ps-08__head h2 {
font-size: clamp(22px, 3.4vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f7feec;
}
.ps-08__head p {
color: #93a87f;
margin: 0;
font-size: 14px;
}
.ps-08__line {
position: relative;
list-style: none;
padding: 0;
margin: 0 auto;
max-width: 580px;
}
.ps-08__line::before {
content: '';
position: absolute;
left: 28px;
top: 18px;
bottom: 18px;
width: 2px;
background: linear-gradient(180deg, #84cc16, rgba(132,204,22,0.2));
border-radius: 2px;
}
.ps-08__stop {
position: relative;
padding: 0 0 24px 70px;
min-height: 56px;
}
.ps-08__stop:last-child {
padding-bottom: 0;
}
.ps-08__num {
position: absolute;
left: 6px;
top: 0;
width: 46px;
height: 46px;
border-radius: 50%;
background: #0a1408;
border: 2px solid #84cc16;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
color: #84cc16;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
.ps-08__current .ps-08__num {
background: #84cc16;
color: #0a1408;
box-shadow: 0 0 0 6px rgba(132,204,22,0.18);
}
.ps-08__pane {
background: #14210e;
border: 1px solid rgba(132,204,22,0.18);
border-radius: 12px;
padding: 18px 18px 16px;
}
.ps-08__current .ps-08__pane {
border-color: #84cc16;
background: linear-gradient(180deg, #1a3010, #14210e);
box-shadow: 0 8px 24px rgba(132,204,22,0.12);
}
.ps-08__pane header {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 8px;
border-bottom: 1px dashed rgba(132,204,22,0.18);
padding-bottom: 10px;
}
.ps-08__pane h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
margin: 0;
color: #84cc16;
}
.ps-08__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f7feec;
}
.ps-08__pri em {
font-size: 12px;
font-style: normal;
color: #93a87f;
font-weight: 500;
margin-left: 2px;
}
.ps-08__pane p {
font-size: 13px;
color: #c8d8b0;
margin: 10px 0;
line-height: 1.55;
}
.ps-08__pane ul {
list-style: none;
padding: 0;
margin: 0 0 14px;
font-size: 13px;
line-height: 1.85;
color: #c8d8b0;
}
.ps-08__pane ul li::before {
content: '→';
color: #84cc16;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-08__cta {
display: inline-block;
padding: 9px 14px;
border-radius: 7px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(132,204,22,0.4);
color: #84cc16;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-08__cta:hover {
background: rgba(132,204,22,0.15);
color: #ecfccb;
}
.ps-08__cta-pri {
background: #84cc16;
color: #0a1408;
border-color: #84cc16;
}
.ps-08__cta-pri:hover {
background: #a3e635;
color: #0a1408;
border-color: #a3e635;
}
.ps-08__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}.ps-08 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #0a1408;
color: #ecfccb;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-08__head {
text-align: center;
margin-bottom: clamp(28px, 5vw, 44px);
}
.ps-08__head h2 {
font-size: clamp(22px, 3.4vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f7feec;
}
.ps-08__head p {
color: #93a87f;
margin: 0;
font-size: 14px;
}
.ps-08__line {
position: relative;
list-style: none;
padding: 0;
margin: 0 auto;
max-width: 580px;
}
.ps-08__line::before {
content: '';
position: absolute;
left: 28px;
top: 18px;
bottom: 18px;
width: 2px;
background: linear-gradient(180deg, #84cc16, rgba(132,204,22,0.2));
border-radius: 2px;
}
.ps-08__stop {
position: relative;
padding: 0 0 24px 70px;
min-height: 56px;
}
.ps-08__stop:last-child {
padding-bottom: 0;
}
.ps-08__num {
position: absolute;
left: 6px;
top: 0;
width: 46px;
height: 46px;
border-radius: 50%;
background: #0a1408;
border: 2px solid #84cc16;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
color: #84cc16;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
.ps-08__current .ps-08__num {
background: #84cc16;
color: #0a1408;
box-shadow: 0 0 0 6px rgba(132,204,22,0.18);
}
.ps-08__pane {
background: #14210e;
border: 1px solid rgba(132,204,22,0.18);
border-radius: 12px;
padding: 18px 18px 16px;
}
.ps-08__current .ps-08__pane {
border-color: #84cc16;
background: linear-gradient(180deg, #1a3010, #14210e);
box-shadow: 0 8px 24px rgba(132,204,22,0.12);
}
.ps-08__pane header {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 8px;
border-bottom: 1px dashed rgba(132,204,22,0.18);
padding-bottom: 10px;
}
.ps-08__pane h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
margin: 0;
color: #84cc16;
}
.ps-08__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f7feec;
}
.ps-08__pri em {
font-size: 12px;
font-style: normal;
color: #93a87f;
font-weight: 500;
margin-left: 2px;
}
.ps-08__pane p {
font-size: 13px;
color: #c8d8b0;
margin: 10px 0;
line-height: 1.55;
}
.ps-08__pane ul {
list-style: none;
padding: 0;
margin: 0 0 14px;
font-size: 13px;
line-height: 1.85;
color: #c8d8b0;
}
.ps-08__pane ul li::before {
content: '→';
color: #84cc16;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-08__cta {
display: inline-block;
padding: 9px 14px;
border-radius: 7px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(132,204,22,0.4);
color: #84cc16;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-08__cta:hover {
background: rgba(132,204,22,0.15);
color: #ecfccb;
}
.ps-08__cta-pri {
background: #84cc16;
color: #0a1408;
border-color: #84cc16;
}
.ps-08__cta-pri:hover {
background: #a3e635;
color: #0a1408;
border-color: #a3e635;
}
.ps-08__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}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: Vertical Tier Timeline
Source: https://codefronts.com/layouts/css-pricing-sections/vertical-tier-timeline/
Tiers presented as a vertical roadmap — Free → Pro → Enterprise — connected by a glowing lime spine. Each station is a real <ol>/<li> with a numbered milestone, price, and feature list. Reads as a growth path, not a column comparison.
## HTML
```html
<section class="ps-08" aria-label="Pricing">
<header class="ps-08__head">
<h2>Grow into the next plan, not out of one.</h2>
<p>Three stops on the same road. Switch up or down with one click.</p>
</header>
<ol class="ps-08__line">
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">01</span>
<article class="ps-08__pane">
<header>
<h3>Free</h3>
<span class="ps-08__pri">$0</span>
</header>
<p>
Open-source projects, side experiments, anything you want to ship without a credit card.
</p>
<ul>
<li>1 project</li>
<li>500 MB storage</li>
<li>Public repos only</li>
</ul>
<a class="ps-08__cta" href="#free">Start free →</a>
</article>
</li>
<li class="ps-08__stop ps-08__current">
<span class="ps-08__num" aria-hidden="true">02</span>
<article class="ps-08__pane">
<header>
<h3>Pro</h3>
<span class="ps-08__pri">$24<em>/mo</em></span>
</header>
<p>
Where most teams settle. Private projects, real support, and the integrations you actually
use.
</p>
<ul>
<li>Unlimited projects</li>
<li>50 GB storage</li>
<li>Email + chat support</li>
<li>Slack, GitHub, Linear sync</li>
</ul>
<a class="ps-08__cta ps-08__cta-pri" href="#pro">Choose Pro →</a>
</article>
</li>
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">03</span>
<article class="ps-08__pane">
<header>
<h3>Enterprise</h3>
<span class="ps-08__pri">Custom</span>
</header>
<p>
For teams with procurement processes, security reviews, and quarterly business reviews.
</p>
<ul>
<li>SSO + SAML + audit logs</li>
<li>SLA, dedicated CSM</li>
<li>Custom DPA & invoicing</li>
</ul>
<a class="ps-08__cta" href="#ent">Talk to sales →</a>
</article>
</li>
</ol>
</section>
```
## CSS
```css
.ps-08 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #0a1408;
color: #ecfccb;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-08__head {
text-align: center;
margin-bottom: clamp(28px, 5vw, 44px);
}
.ps-08__head h2 {
font-size: clamp(22px, 3.4vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f7feec;
}
.ps-08__head p {
color: #93a87f;
margin: 0;
font-size: 14px;
}
.ps-08__line {
position: relative;
list-style: none;
padding: 0;
margin: 0 auto;
max-width: 580px;
}
.ps-08__line::before {
content: '';
position: absolute;
left: 28px;
top: 18px;
bottom: 18px;
width: 2px;
background: linear-gradient(180deg, #84cc16, rgba(132,204,22,0.2));
border-radius: 2px;
}
.ps-08__stop {
position: relative;
padding: 0 0 24px 70px;
min-height: 56px;
}
.ps-08__stop:last-child {
padding-bottom: 0;
}
.ps-08__num {
position: absolute;
left: 6px;
top: 0;
width: 46px;
height: 46px;
border-radius: 50%;
background: #0a1408;
border: 2px solid #84cc16;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
color: #84cc16;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
.ps-08__current .ps-08__num {
background: #84cc16;
color: #0a1408;
box-shadow: 0 0 0 6px rgba(132,204,22,0.18);
}
.ps-08__pane {
background: #14210e;
border: 1px solid rgba(132,204,22,0.18);
border-radius: 12px;
padding: 18px 18px 16px;
}
.ps-08__current .ps-08__pane {
border-color: #84cc16;
background: linear-gradient(180deg, #1a3010, #14210e);
box-shadow: 0 8px 24px rgba(132,204,22,0.12);
}
.ps-08__pane header {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 8px;
border-bottom: 1px dashed rgba(132,204,22,0.18);
padding-bottom: 10px;
}
.ps-08__pane h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
margin: 0;
color: #84cc16;
}
.ps-08__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f7feec;
}
.ps-08__pri em {
font-size: 12px;
font-style: normal;
color: #93a87f;
font-weight: 500;
margin-left: 2px;
}
.ps-08__pane p {
font-size: 13px;
color: #c8d8b0;
margin: 10px 0;
line-height: 1.55;
}
.ps-08__pane ul {
list-style: none;
padding: 0;
margin: 0 0 14px;
font-size: 13px;
line-height: 1.85;
color: #c8d8b0;
}
.ps-08__pane ul li::before {
content: '→';
color: #84cc16;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-08__cta {
display: inline-block;
padding: 9px 14px;
border-radius: 7px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(132,204,22,0.4);
color: #84cc16;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-08__cta:hover {
background: rgba(132,204,22,0.15);
color: #ecfccb;
}
.ps-08__cta-pri {
background: #84cc16;
color: #0a1408;
border-color: #84cc16;
}
.ps-08__cta-pri:hover {
background: #a3e635;
color: #0a1408;
border-color: #a3e635;
}
.ps-08__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}
```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: Vertical Tier Timeline
Source: https://codefronts.com/layouts/css-pricing-sections/vertical-tier-timeline/
Tiers presented as a vertical roadmap — Free → Pro → Enterprise — connected by a glowing lime spine. Each station is a real <ol>/<li> with a numbered milestone, price, and feature list. Reads as a growth path, not a column comparison.
## HTML
```html
<section class="ps-08" aria-label="Pricing">
<header class="ps-08__head">
<h2>Grow into the next plan, not out of one.</h2>
<p>Three stops on the same road. Switch up or down with one click.</p>
</header>
<ol class="ps-08__line">
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">01</span>
<article class="ps-08__pane">
<header>
<h3>Free</h3>
<span class="ps-08__pri">$0</span>
</header>
<p>
Open-source projects, side experiments, anything you want to ship without a credit card.
</p>
<ul>
<li>1 project</li>
<li>500 MB storage</li>
<li>Public repos only</li>
</ul>
<a class="ps-08__cta" href="#free">Start free →</a>
</article>
</li>
<li class="ps-08__stop ps-08__current">
<span class="ps-08__num" aria-hidden="true">02</span>
<article class="ps-08__pane">
<header>
<h3>Pro</h3>
<span class="ps-08__pri">$24<em>/mo</em></span>
</header>
<p>
Where most teams settle. Private projects, real support, and the integrations you actually
use.
</p>
<ul>
<li>Unlimited projects</li>
<li>50 GB storage</li>
<li>Email + chat support</li>
<li>Slack, GitHub, Linear sync</li>
</ul>
<a class="ps-08__cta ps-08__cta-pri" href="#pro">Choose Pro →</a>
</article>
</li>
<li class="ps-08__stop">
<span class="ps-08__num" aria-hidden="true">03</span>
<article class="ps-08__pane">
<header>
<h3>Enterprise</h3>
<span class="ps-08__pri">Custom</span>
</header>
<p>
For teams with procurement processes, security reviews, and quarterly business reviews.
</p>
<ul>
<li>SSO + SAML + audit logs</li>
<li>SLA, dedicated CSM</li>
<li>Custom DPA & invoicing</li>
</ul>
<a class="ps-08__cta" href="#ent">Talk to sales →</a>
</article>
</li>
</ol>
</section>
```
## CSS
```css
.ps-08 {
padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
width: 100%;
min-height: 100vh;
background: #0a1408;
color: #ecfccb;
font-family: 'Inter', system-ui, sans-serif;
}
.ps-08__head {
text-align: center;
margin-bottom: clamp(28px, 5vw, 44px);
}
.ps-08__head h2 {
font-size: clamp(22px, 3.4vw, 32px);
font-weight: 700;
letter-spacing: -0.02em;
margin: 0 0 8px;
color: #f7feec;
}
.ps-08__head p {
color: #93a87f;
margin: 0;
font-size: 14px;
}
.ps-08__line {
position: relative;
list-style: none;
padding: 0;
margin: 0 auto;
max-width: 580px;
}
.ps-08__line::before {
content: '';
position: absolute;
left: 28px;
top: 18px;
bottom: 18px;
width: 2px;
background: linear-gradient(180deg, #84cc16, rgba(132,204,22,0.2));
border-radius: 2px;
}
.ps-08__stop {
position: relative;
padding: 0 0 24px 70px;
min-height: 56px;
}
.ps-08__stop:last-child {
padding-bottom: 0;
}
.ps-08__num {
position: absolute;
left: 6px;
top: 0;
width: 46px;
height: 46px;
border-radius: 50%;
background: #0a1408;
border: 2px solid #84cc16;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 700;
color: #84cc16;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
}
.ps-08__current .ps-08__num {
background: #84cc16;
color: #0a1408;
box-shadow: 0 0 0 6px rgba(132,204,22,0.18);
}
.ps-08__pane {
background: #14210e;
border: 1px solid rgba(132,204,22,0.18);
border-radius: 12px;
padding: 18px 18px 16px;
}
.ps-08__current .ps-08__pane {
border-color: #84cc16;
background: linear-gradient(180deg, #1a3010, #14210e);
box-shadow: 0 8px 24px rgba(132,204,22,0.12);
}
.ps-08__pane header {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 8px;
border-bottom: 1px dashed rgba(132,204,22,0.18);
padding-bottom: 10px;
}
.ps-08__pane h3 {
font-size: 14px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
margin: 0;
color: #84cc16;
}
.ps-08__pri {
font-size: 22px;
font-weight: 800;
letter-spacing: -0.02em;
color: #f7feec;
}
.ps-08__pri em {
font-size: 12px;
font-style: normal;
color: #93a87f;
font-weight: 500;
margin-left: 2px;
}
.ps-08__pane p {
font-size: 13px;
color: #c8d8b0;
margin: 10px 0;
line-height: 1.55;
}
.ps-08__pane ul {
list-style: none;
padding: 0;
margin: 0 0 14px;
font-size: 13px;
line-height: 1.85;
color: #c8d8b0;
}
.ps-08__pane ul li::before {
content: '→';
color: #84cc16;
display: inline-block;
width: 20px;
font-weight: 700;
}
.ps-08__cta {
display: inline-block;
padding: 9px 14px;
border-radius: 7px;
font-size: 13px;
font-weight: 600;
text-decoration: none;
border: 1px solid rgba(132,204,22,0.4);
color: #84cc16;
background: transparent;
transition: background 0.18s, color 0.18s;
}
.ps-08__cta:hover {
background: rgba(132,204,22,0.15);
color: #ecfccb;
}
.ps-08__cta-pri {
background: #84cc16;
color: #0a1408;
border-color: #84cc16;
}
.ps-08__cta-pri:hover {
background: #a3e635;
color: #0a1408;
border-color: #a3e635;
}
.ps-08__cta:focus-visible {
outline: 2px solid #a3e635;
outline-offset: 3px;
}
```How this works
The vertical pricing timeline is a real semantic <ol class="ps-08__line"> — three <li class="ps-08__stop"> stations, each one a labeled tier with a numbered milestone circle. The spine is a single ::before pseudo-element on the ordered list: position: absolute; left: 28px; top: 18px; bottom: 18px; width: 2px; background: linear-gradient(180deg, #84cc16, rgba(132,204,22,0.2)) — one gradient replaces three stacked divs and preserves screen-reader flow. Each station's number circle uses position: absolute; left: 6px so it sits on top of the spine, with z-index: 1 ensuring the numbered marker paints above the line. The current tier (.ps-08__current) gets a solid lime fill plus a box-shadow: 0 0 0 6px rgba(132,204,22,0.18) pulse ring, gamifying the "you are here" signal.
Palette is deep-forest #0a1408 ground, celadon body text #c8d8b0, and lime #84cc16 as the growth-path accent — chosen because lime reads as "active/upgrade" without the panic urgency of red or the corporate weight of blue. Type is 'Inter' throughout with milestone numbers in 'JetBrains Mono' — the mono numerals borrow from CI pipeline UIs (GitHub Actions, Vercel deploy steps) that developers already parse as "progression states." Prices sit in the pane header via display: flex; justify-content: space-between with dashed underlines that echo receipt-tape aesthetics.
Why it converts: vertical progression frames tiers as "levels to achieve" rather than columns to compare. The Iyengar paradox-of-choice research shows column layouts induce paralysis over three options; a timeline sidesteps that by implying sequence — visitors read Free → Pro → Enterprise as a growth arc, not a choice, and self-select where they "currently are." Roadmap framing typically lifts mid-tier conversion 15–25% on education platforms and dev tools with clear upgrade paths (GitHub, Vercel, Linear). The .ps-08__current pulse is the anchor — visitors gravitate to the highlighted station because the ring reads as "where teams like yours land."
Make it yours
- Recolor for B2B SaaS trust palette: swap lime
#84cc16→ indigo#6366f1, ground#0a1408→ slate#0f172a, and body text to#cbd5e1. Keep the spine gradient formula —linear-gradient(180deg, #6366f1, rgba(99,102,241,0.2))— so the fade-to-transparent still reads as "path continues." - Swap the milestone glyph: current is
01/02/03in mono. For education platforms use unicode ✦/✧/✩; for dev tools use commit-hash chunks (a1f,b7d,c2e). Adjust.ps-08__numfont-size to keep the glyph vertically centered inside the 46px circle. - CTA shape:
border-radius: 7pxis neutral. For a bolder growth-tool vibe drop toborder-radius: 4pxand addborder-width: 1.5px. For consumer-app polish, go pill (border-radius: 999px) and switch the primary CTA to a solid#a3e635fill for extra pop. - Light-mode inversion: background
#f7feec, panes#ffffffwithborder: 1px solid #e5e7eb, text#1a2e05, and the spine tolinear-gradient(180deg, #65a30d, rgba(101,163,13,0.15)). The.ps-08__currentpulse ring getsrgba(132,204,22,0.28)to hold against a bright ground. - Tailwind mapping:
<ol class="relative max-w-[580px] mx-auto before:absolute before:left-7 before:top-4 before:bottom-4 before:w-0.5 before:bg-gradient-to-b before:from-lime-500 before:to-lime-500/20">handles the spine; stations become<li class="relative pl-[70px] pb-6">. React/Vue components can passcurrentas a prop that toggles the pulse-ring shadow class.
Gotchas — read before shipping
- The
::beforespine positions withtop: 18px; bottom: 18px— those offsets assume the first and last number circles start ~18px from the pane top. If you resize.ps-08__numfrom 46px to 56px, the spine no longer meets the circle center and reads as a broken pipe. Recalculate: offset =(circleHeight/2) - 5px. - Semantic warning: an
<ol>implies sequential order to assistive tech — screen readers announce "list of 3 items, item 1 of 3." That's ideal for a growth path but wrong if visitors can jump directly from Free to Enterprise. If the ordering is nominal, use<ul>and drop the.ps-08__numnumbering; keep the timeline visual, lose the ordinal semantic. - WCAG 1.4.11 non-text contrast: the spine gradient fades to
rgba(132,204,22,0.2)— that lower end sits below 3:1 against#0a1408and technically fails the non-text contrast requirement for UI components conveying information. If the spine is decorative only, addaria-hiddento the pseudo-parent or bump the fade endpoint torgba(132,204,22,0.45). - Framework quirk (Vue 3 / Nuxt): the
:last-childselector on.ps-08__stop:last-child { padding-bottom: 0 }breaks when a v-if hides the last station conditionally — the second-to-last stop keeps its 24px padding and the spine overshoots. Use:last-of-typeor a class-based.ps-08__stop--lastflag rendered from the component. - CLS from font swap: the price uses
font-size: 22px; font-weight: 800alongside a smalleremfor the cycle suffix. When Inter loads late, the fallback (system-ui) has narrower digits — the price re-flows the header row and pushes the dashed underline down ~4px. Preload Inter with<link rel="preload" as="font" crossorigin>or usefont-display: optional. - Mobile-tap target: the number circle is only 46×46px — WCAG 2.5.5 target size is 44×44px minimum (AA), 24×24px minimum (AAA relaxed). You're safe now, but if you shrink the timeline for compact layouts, keep the number circle at ≥44px or make sure the entire
.ps-08__paneis the click target instead.