Blocks / Pricing
Pricing beta
Three plans and a billing switch. The middle plan carries the decision; the rest is context.
Pricing
Start small. Upgrade when the team does.
Starter
$9 / month
For one project and a quiet launch.
- 3 projects
- 1 GB storage
- Community support
Most popular
Pro
$29 / month
For teams shipping every week.
- Unlimited projects
- 100 GB storage
- Custom domain
- Priority support
Team
$79 / month
For organizations with many hands.
- Everything in Pro
- SSO and roles
- Audit log
- A named contact
Built from: Button, Badge, Switch, Separator — include their CSS alongside this block.
<div class="pricing">
<div class="pricing-head">
<div>
<h3 class="pricing-h">Pricing</h3>
<p class="pricing-sub">Start small. Upgrade when the team does.</p>
</div>
<span class="switchrow"><span>Monthly</span><label class="switch"><input type="checkbox" data-billing><span class="tr"></span></label><span>Yearly</span><span class="badge teal">−20%</span></span>
</div>
<div class="pricing-grid">
<div class="plan">
<div class="plan-name">Starter</div>
<div class="plan-price"><span data-m="$9" data-y="$7">$9</span> <span class="plan-per">/ month</span></div>
<p class="plan-desc">For one project and a quiet launch.</p>
<button class="btn btn-sec btn-lg plan-cta">Start free</button>
<hr class="k-sep">
<ul class="plan-feats">
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> 3 projects</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> 1 GB storage</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> Community support</li>
</ul>
</div>
<div class="plan plan-hot">
<span class="plan-badge"><span class="badge dark">Most popular</span></span>
<div class="plan-name">Pro</div>
<div class="plan-price"><span data-m="$29" data-y="$23">$29</span> <span class="plan-per">/ month</span></div>
<p class="plan-desc">For teams shipping every week.</p>
<button class="btn btn-pri btn-lg plan-cta">Start 14-day trial</button>
<hr class="k-sep">
<ul class="plan-feats">
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> Unlimited projects</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> 100 GB storage</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> Custom domain</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> Priority support</li>
</ul>
</div>
<div class="plan">
<div class="plan-name">Team</div>
<div class="plan-price"><span data-m="$79" data-y="$63">$79</span> <span class="plan-per">/ month</span></div>
<p class="plan-desc">For organizations with many hands.</p>
<button class="btn btn-sec btn-lg plan-cta">Talk to us</button>
<hr class="k-sep">
<ul class="plan-feats">
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> Everything in Pro</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> SSO and roles</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> Audit log</li>
<li><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m4.5 12.5 5 5L19.5 6.5"/></svg> A named contact</li>
</ul>
</div>
</div>
</div>.pricing{font-family:var(--k-font);color:var(--k-ink);text-align:left;width:100%}
.pricing-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.pricing-h{font-size:21px;font-weight:600;letter-spacing:-.02em}
.pricing-sub{margin-top:5px;font-size:13.5px;color:var(--k-ink-2)}
.pricing-grid{margin-top:20px;display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media (max-width:760px){.pricing-grid{grid-template-columns:1fr}}
.plan{position:relative;border:1px solid var(--k-line);border-radius:14px;background:var(--k-bg);padding:22px 20px}
.plan-hot{border-color:var(--k-ink)}
.plan-badge{position:absolute;top:-11px;left:20px}
.plan-name{font-size:13px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--k-ink-2)}
.plan-price{margin-top:10px;font-size:32px;font-weight:600;letter-spacing:-.03em}
.plan-per{font-size:13px;font-weight:500;color:var(--k-ink-3);letter-spacing:0}
.plan-desc{margin-top:7px;font-size:13px;line-height:1.7;color:var(--k-ink-2)}
.plan-cta{width:100%;justify-content:center;margin-top:16px}
.plan .k-sep{margin:18px 0 14px}
.plan-feats{list-style:none;margin:0;padding:0;display:grid;gap:9px;font-size:13px}
.plan-feats li{display:flex;gap:9px;align-items:center}
.plan-feats svg{color:var(--k-accent-ink);flex:none}
const billSwitch = document.querySelector('[data-billing]');
billSwitch.addEventListener('change', () => {
document.querySelectorAll('[data-m]').forEach(el => {
el.textContent = billSwitch.checked ? el.dataset.y : el.dataset.m;
});
});
Usage
Prices live in data-m (monthly) and data-y (yearly) on each amount; the switch swaps them. Rewire the amounts, keep the rhythm.