Pure TailwindMIT licensed

Tailwind Classic Three Tier Pricing Section

The conversion-tested baseline — three equal tiers (Starter / Team / Business) on a forest ground with one emerald accent — ported to utilities. The whole stylesheet reduces to @theme tokens plus the masked check-mark URL, because minmax(0,1fr), the flex-1 CTA push and the reduced-motion fallback all have utility forms that live on the elements that need them.

Live Demo
Plain CSSTailwind v4
Try it

Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49

Cruip · Affiliate link

Browse Cruip templates

The code

<section class="tps-01 w-full min-h-svh bg-tps01-bg font-tps01-sans text-tps01-ink px-[clamp(20px,4vw,40px)] py-[clamp(28px,5vw,56px)]" aria-label="Pricing">
  <header class="text-center mb-[clamp(20px,4vw,40px)]">
    <span class="inline-block mb-3 text-xs font-semibold tracking-[0.18em] uppercase text-tps01-acc">Pricing</span>
    <h2 class="m-0 mb-2 text-[clamp(22px,3.4vw,34px)] font-bold tracking-[-0.01em] text-pretty">Pick the plan that fits today.</h2>
    <p class="m-0 text-sm text-tps01-mut">Upgrade, downgrade, or cancel any time. No fine print.</p>
  </header>
  <div class="grid grid-cols-1 md:grid-cols-[repeat(3,minmax(0,1fr))] gap-4 max-w-[460px] md:max-w-[980px] mx-auto">
    <article class="flex flex-col p-5 pt-5.5 rounded-2xl bg-tps01-card border border-tps01-edge transition-[border-color,translate] duration-200 hover:border-tps01-acc hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h3 class="m-0 mb-1 text-[15px] font-bold uppercase tracking-[0.04em] text-tps01-acc">Starter</h3>
      <p class="m-0 mb-4.5 min-h-0 md:min-h-9.5 text-[13px] leading-normal text-tps01-mut">For solo builders shipping their first thing.</p>
      <div class="flex items-baseline gap-1.5 mb-4.5 pb-4.5 border-b border-dashed border-tps01-edge2">
        <span class="text-[38px] font-extrabold tracking-[-0.02em] text-tps01-price">$9</span><span class="text-[13px] text-tps01-mut">/ month</span>
      </div>
      <ul class="flex-1 list-none p-0 m-0 mb-5.5 flex flex-col">
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>1 project</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>2 GB storage</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Community support</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Basic analytics</li>
      </ul>
      <a href="#starter" class="block text-center px-4 py-2.75 rounded-lg text-[13.5px] font-semibold no-underline text-tps01-acc bg-tps01-ctabg border border-tps01-ctaedge transition-[background-color,color] duration-200 hover:bg-tps01-acc hover:text-tps01-bg focus-visible:outline-2 focus-visible:outline-tps01-acc focus-visible:outline-offset-3 motion-reduce:transition-none">Start free &rarr;</a>
    </article>
    <article class="flex flex-col p-5 pt-5.5 rounded-2xl bg-tps01-card border border-tps01-edge transition-[border-color,translate] duration-200 hover:border-tps01-acc hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h3 class="m-0 mb-1 text-[15px] font-bold uppercase tracking-[0.04em] text-tps01-acc">Team</h3>
      <p class="m-0 mb-4.5 min-h-0 md:min-h-9.5 text-[13px] leading-normal text-tps01-mut">For small teams who need to ship together.</p>
      <div class="flex items-baseline gap-1.5 mb-4.5 pb-4.5 border-b border-dashed border-tps01-edge2">
        <span class="text-[38px] font-extrabold tracking-[-0.02em] text-tps01-price">$29</span><span class="text-[13px] text-tps01-mut">/ month</span>
      </div>
      <ul class="flex-1 list-none p-0 m-0 mb-5.5 flex flex-col">
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>10 projects</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>50 GB storage</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Email support</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Team analytics</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Role-based access</li>
      </ul>
      <a href="#team" class="block text-center px-4 py-2.75 rounded-lg text-[13.5px] font-semibold no-underline text-tps01-acc bg-tps01-ctabg border border-tps01-ctaedge transition-[background-color,color] duration-200 hover:bg-tps01-acc hover:text-tps01-bg focus-visible:outline-2 focus-visible:outline-tps01-acc focus-visible:outline-offset-3 motion-reduce:transition-none">Start 14-day trial &rarr;</a>
    </article>
    <article class="flex flex-col p-5 pt-5.5 rounded-2xl bg-tps01-card border border-tps01-edge transition-[border-color,translate] duration-200 hover:border-tps01-acc hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h3 class="m-0 mb-1 text-[15px] font-bold uppercase tracking-[0.04em] text-tps01-acc">Business</h3>
      <p class="m-0 mb-4.5 min-h-0 md:min-h-9.5 text-[13px] leading-normal text-tps01-mut">For growing companies that need governance.</p>
      <div class="flex items-baseline gap-1.5 mb-4.5 pb-4.5 border-b border-dashed border-tps01-edge2">
        <span class="text-[38px] font-extrabold tracking-[-0.02em] text-tps01-price">$79</span><span class="text-[13px] text-tps01-mut">/ month</span>
      </div>
      <ul class="flex-1 list-none p-0 m-0 mb-5.5 flex flex-col">
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Unlimited projects</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>500 GB storage</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Priority support</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Advanced analytics</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>SSO + audit logs</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>SOC 2 ready</li>
      </ul>
      <a href="#business" class="block text-center px-4 py-2.75 rounded-lg text-[13.5px] font-semibold no-underline text-tps01-acc bg-tps01-ctabg border border-tps01-ctaedge transition-[background-color,color] duration-200 hover:bg-tps01-acc hover:text-tps01-bg focus-visible:outline-2 focus-visible:outline-tps01-acc focus-visible:outline-offset-3 motion-reduce:transition-none">Talk to sales &rarr;</a>
    </article>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tps01-bg: #07120e;
  --color-tps01-bg: oklch(0.16 0.02 160);
  --color-tps01-card: #0d1f18;
  --color-tps01-card: oklch(0.22 0.03 163);
  --color-tps01-edge: #1f4536;
  --color-tps01-edge: oklch(0.36 0.05 163);
  --color-tps01-edge2: #2a5a46;
  --color-tps01-edge2: oklch(0.43 0.06 163);
  --color-tps01-ctabg: #123326;
  --color-tps01-ctabg: oklch(0.27 0.05 163);
  --color-tps01-ctaedge: #276b4f;
  --color-tps01-ctaedge: oklch(0.47 0.08 163);
  --color-tps01-ink: #e7f5ee;
  --color-tps01-ink: oklch(0.95 0.02 163);
  --color-tps01-body: #d2e9dc;
  --color-tps01-body: oklch(0.9 0.03 163);
  --color-tps01-price: #f0fff7;
  --color-tps01-price: oklch(0.98 0.02 163);
  --color-tps01-mut: #9bb5a8;
  --color-tps01-mut: oklch(0.73 0.03 163);
  --color-tps01-acc: #34d399;
  --color-tps01-acc: oklch(0.79 0.16 163);
  --font-tps01-sans: 'Inter', system-ui, -apple-system, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh, so the section is correctly sized in the moment before the
   browser build has compiled its utilities. It also carries the check-mark mask
   source: a data URI cannot survive an arbitrary value's quote and space rules,
   and a mask source is not a design-scale value. */

.tps-01 {
  width: 100%;
  min-height: 100svh;
  --tps01-check: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>");
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tps01-bg: #07120e;
  --color-tps01-bg: oklch(0.16 0.02 160);
  --color-tps01-card: #0d1f18;
  --color-tps01-card: oklch(0.22 0.03 163);
  --color-tps01-edge: #1f4536;
  --color-tps01-edge: oklch(0.36 0.05 163);
  --color-tps01-edge2: #2a5a46;
  --color-tps01-edge2: oklch(0.43 0.06 163);
  --color-tps01-ctabg: #123326;
  --color-tps01-ctabg: oklch(0.27 0.05 163);
  --color-tps01-ctaedge: #276b4f;
  --color-tps01-ctaedge: oklch(0.47 0.08 163);
  --color-tps01-ink: #e7f5ee;
  --color-tps01-ink: oklch(0.95 0.02 163);
  --color-tps01-body: #d2e9dc;
  --color-tps01-body: oklch(0.9 0.03 163);
  --color-tps01-price: #f0fff7;
  --color-tps01-price: oklch(0.98 0.02 163);
  --color-tps01-mut: #9bb5a8;
  --color-tps01-mut: oklch(0.73 0.03 163);
  --color-tps01-acc: #34d399;
  --color-tps01-acc: oklch(0.79 0.16 163);
  --font-tps01-sans: 'Inter', system-ui, -apple-system, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh, so the section is correctly sized in the moment before the
   browser build has compiled its utilities. It also carries the check-mark mask
   source: a data URI cannot survive an arbitrary value's quote and space rules,
   and a mask source is not a design-scale value. */

.tps-01 {
  width: 100%;
  min-height: 100svh;
  --tps01-check: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>");
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • A 60-line stylesheet becomes ten @theme colour entries and one root rule. Everything else — layout, spacing, type, hover, focus, the reduced-motion fallback — moved onto the elements.
  • The two media queries are gone: the 820px column collapse is grid-cols-1 md:grid-cols-[…] and the min-height reset is min-h-0 md:min-h-9.5, both read where they apply.
  • ::before has no variant form, so the check-mark pseudo-element becomes a real <i aria-hidden> and the list items become flex items-center gap-2. Honest trade: one extra node per row, no absolute positioning, and the icon is stylable.
  • The masked check keeps its data URI in CSS and reads it as [mask:var(--tps01-check)_center/contain_no-repeat] — the pattern for any non-token URL value in utilities.
  • motion-reduce: now sits next to the hover it cancels, which is the version of that media query least likely to rot.
  • The feature list repeats a 12-class string per row. That is the real cost of utilities on repeated items; in a codebase the answer is a component that renders the row, not @apply.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS demo 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: Tailwind Classic Three Tier Pricing Section
Source: https://codefronts.com/layouts/tailwind-css-pricing-sections/tailwind-classic-three-tier-pricing-section/

The conversion-tested baseline — three equal tiers (Starter / Team / Business) on a forest ground with one emerald accent — ported to utilities. The whole stylesheet reduces to @theme tokens plus the masked check-mark URL, because minmax(0,1fr), the flex-1 CTA push and the reduced-motion fallback all have utility forms that live on the elements that need them.
## HTML
```html
<section class="tps-01 w-full min-h-svh bg-tps01-bg font-tps01-sans text-tps01-ink px-[clamp(20px,4vw,40px)] py-[clamp(28px,5vw,56px)]" aria-label="Pricing">
  <header class="text-center mb-[clamp(20px,4vw,40px)]">
    <span class="inline-block mb-3 text-xs font-semibold tracking-[0.18em] uppercase text-tps01-acc">Pricing</span>
    <h2 class="m-0 mb-2 text-[clamp(22px,3.4vw,34px)] font-bold tracking-[-0.01em] text-pretty">Pick the plan that fits today.</h2>
    <p class="m-0 text-sm text-tps01-mut">Upgrade, downgrade, or cancel any time. No fine print.</p>
  </header>
  <div class="grid grid-cols-1 md:grid-cols-[repeat(3,minmax(0,1fr))] gap-4 max-w-[460px] md:max-w-[980px] mx-auto">
    <article class="flex flex-col p-5 pt-5.5 rounded-2xl bg-tps01-card border border-tps01-edge transition-[border-color,translate] duration-200 hover:border-tps01-acc hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h3 class="m-0 mb-1 text-[15px] font-bold uppercase tracking-[0.04em] text-tps01-acc">Starter</h3>
      <p class="m-0 mb-4.5 min-h-0 md:min-h-9.5 text-[13px] leading-normal text-tps01-mut">For solo builders shipping their first thing.</p>
      <div class="flex items-baseline gap-1.5 mb-4.5 pb-4.5 border-b border-dashed border-tps01-edge2">
        <span class="text-[38px] font-extrabold tracking-[-0.02em] text-tps01-price">$9</span><span class="text-[13px] text-tps01-mut">/ month</span>
      </div>
      <ul class="flex-1 list-none p-0 m-0 mb-5.5 flex flex-col">
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>1 project</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>2 GB storage</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Community support</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Basic analytics</li>
      </ul>
      <a href="#starter" class="block text-center px-4 py-2.75 rounded-lg text-[13.5px] font-semibold no-underline text-tps01-acc bg-tps01-ctabg border border-tps01-ctaedge transition-[background-color,color] duration-200 hover:bg-tps01-acc hover:text-tps01-bg focus-visible:outline-2 focus-visible:outline-tps01-acc focus-visible:outline-offset-3 motion-reduce:transition-none">Start free &rarr;</a>
    </article>
    <article class="flex flex-col p-5 pt-5.5 rounded-2xl bg-tps01-card border border-tps01-edge transition-[border-color,translate] duration-200 hover:border-tps01-acc hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h3 class="m-0 mb-1 text-[15px] font-bold uppercase tracking-[0.04em] text-tps01-acc">Team</h3>
      <p class="m-0 mb-4.5 min-h-0 md:min-h-9.5 text-[13px] leading-normal text-tps01-mut">For small teams who need to ship together.</p>
      <div class="flex items-baseline gap-1.5 mb-4.5 pb-4.5 border-b border-dashed border-tps01-edge2">
        <span class="text-[38px] font-extrabold tracking-[-0.02em] text-tps01-price">$29</span><span class="text-[13px] text-tps01-mut">/ month</span>
      </div>
      <ul class="flex-1 list-none p-0 m-0 mb-5.5 flex flex-col">
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>10 projects</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>50 GB storage</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Email support</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Team analytics</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Role-based access</li>
      </ul>
      <a href="#team" class="block text-center px-4 py-2.75 rounded-lg text-[13.5px] font-semibold no-underline text-tps01-acc bg-tps01-ctabg border border-tps01-ctaedge transition-[background-color,color] duration-200 hover:bg-tps01-acc hover:text-tps01-bg focus-visible:outline-2 focus-visible:outline-tps01-acc focus-visible:outline-offset-3 motion-reduce:transition-none">Start 14-day trial &rarr;</a>
    </article>
    <article class="flex flex-col p-5 pt-5.5 rounded-2xl bg-tps01-card border border-tps01-edge transition-[border-color,translate] duration-200 hover:border-tps01-acc hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
      <h3 class="m-0 mb-1 text-[15px] font-bold uppercase tracking-[0.04em] text-tps01-acc">Business</h3>
      <p class="m-0 mb-4.5 min-h-0 md:min-h-9.5 text-[13px] leading-normal text-tps01-mut">For growing companies that need governance.</p>
      <div class="flex items-baseline gap-1.5 mb-4.5 pb-4.5 border-b border-dashed border-tps01-edge2">
        <span class="text-[38px] font-extrabold tracking-[-0.02em] text-tps01-price">$79</span><span class="text-[13px] text-tps01-mut">/ month</span>
      </div>
      <ul class="flex-1 list-none p-0 m-0 mb-5.5 flex flex-col">
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Unlimited projects</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>500 GB storage</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Priority support</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>Advanced analytics</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>SSO + audit logs</li>
        <li class="flex items-center gap-2 py-1.5 text-[13.5px] text-tps01-body"><i class="w-3.5 h-3.5 shrink-0 bg-tps01-acc [mask:var(--tps01-check)_center/contain_no-repeat]" aria-hidden="true"></i>SOC 2 ready</li>
      </ul>
      <a href="#business" class="block text-center px-4 py-2.75 rounded-lg text-[13.5px] font-semibold no-underline text-tps01-acc bg-tps01-ctabg border border-tps01-ctaedge transition-[background-color,color] duration-200 hover:bg-tps01-acc hover:text-tps01-bg focus-visible:outline-2 focus-visible:outline-tps01-acc focus-visible:outline-offset-3 motion-reduce:transition-none">Talk to sales &rarr;</a>
    </article>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tps01-bg: #07120e;
  --color-tps01-bg: oklch(0.16 0.02 160);
  --color-tps01-card: #0d1f18;
  --color-tps01-card: oklch(0.22 0.03 163);
  --color-tps01-edge: #1f4536;
  --color-tps01-edge: oklch(0.36 0.05 163);
  --color-tps01-edge2: #2a5a46;
  --color-tps01-edge2: oklch(0.43 0.06 163);
  --color-tps01-ctabg: #123326;
  --color-tps01-ctabg: oklch(0.27 0.05 163);
  --color-tps01-ctaedge: #276b4f;
  --color-tps01-ctaedge: oklch(0.47 0.08 163);
  --color-tps01-ink: #e7f5ee;
  --color-tps01-ink: oklch(0.95 0.02 163);
  --color-tps01-body: #d2e9dc;
  --color-tps01-body: oklch(0.9 0.03 163);
  --color-tps01-price: #f0fff7;
  --color-tps01-price: oklch(0.98 0.02 163);
  --color-tps01-mut: #9bb5a8;
  --color-tps01-mut: oklch(0.73 0.03 163);
  --color-tps01-acc: #34d399;
  --color-tps01-acc: oklch(0.79 0.16 163);
  --font-tps01-sans: 'Inter', system-ui, -apple-system, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh, so the section is correctly sized in the moment before the
   browser build has compiled its utilities. It also carries the check-mark mask
   source: a data URI cannot survive an arbitrary value's quote and space rules,
   and a mask source is not a design-scale value. */

.tps-01 {
  width: 100%;
  min-height: 100svh;
  --tps01-check: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>");
}
```

How this works

The card is a column, and flex-1 does the alignment. Feature counts differ by tier, so nothing but a growing list can keep the CTAs level:

<article class="flex flex-col …">
  <h3>Starter</h3>
  <div class="… border-b border-dashed border-tps01-edge2">$9</div>
  <ul class="flex-1 …">…</ul>
  <a class="block text-center …">Start free</a>
</article>

Why the column template stays arbitrary. md:grid-cols-3 would emit the same minmax(0,1fr), but the 0 is the load-bearing part of this layout — a long unbreakable feature string bulges an auto-floored column and destroys tier parity. Writing it out means nobody “simplifies” it into something that breaks.

The check-mark is a mask, not a glyph. A masked span paints in whatever bg-* you give it, so re-theming the accent recolours nine checks with no new asset. The data URI lives in the .tps-01 root rule as --tps01-check: an arbitrary value cannot carry the SVG's spaces and quotes intact, and a mask source is not a design-scale value anyway.

Mobile is one variant, not a breakpoint block. The CSS version writes an 820px media query for the single column and the min-height reset. Here both are md: prefixes read at the element — the stacked state is the base, the three-up state is the enhancement.

Make it yours

  • Retheme through --color-tps01-acc in @theme: eyebrow, tier titles, checks, card borders, CTA fill and every focus ring read it. Keep it above 4.5:1 on --color-tps01-bg.
  • Tier count: the grid is md:grid-cols-[repeat(3,minmax(0,1fr))] — swap the 3 for a 4 and add an <article>; nothing else is arity-aware.
  • CTA shape: rounded-lg → rounded-full for the fintech pill, rounded-none for a developer-tools slab.
  • Emphasise one tier without a new component: add md:scale-105 border-tps01-acc to the middle <article> — demo 02 is that idea taken all the way.
  • Light mode: invert --color-tps01-bg/--color-tps01-ink and raise the two edge tokens' chroma; the 0.2-alpha borders vanish on cream.

Gotchas — read before shipping

  • Arbitrary values take no spaces: md:grid-cols-[repeat(3,minmax(0,1fr))] must be typed closed-up, and the mask shorthand uses the underscore escape (var(--tps01-check)_center/contain_no-repeat).
  • Keep the mask data URI in CSS. Inlined as an arbitrary value its xmlns='…' quotes collide with the class=&quot;…&quot; delimiter and the whole class list truncates silently.
  • flex-1 belongs on the feature list, not the card. On the card it fights the grid row and the CTAs drift apart again.
  • Do not add hover:shadow-* to the transition. border-color and translate composite; a shadow repaints every frame and shows up as INP on mid-range mobile.
  • The subhead's min-h-9.5 is English-sized. Longer locales need min-h-14 or the three cards' prices stop aligning.
  • The class strings must be statically visible to the compiler — a tier colour assembled at runtime from a template variable emits no CSS. Vary a custom property, not a class name.
  • The browser CDN build compiles in the page and is for prototyping; ship the CLI or a plugin build.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

CSS grid, mask (unprefixed since Safari 15.4) and compositor transforms all run far further back; the floor quoted here is Tailwind v4's own generated sheet (cascade layers, @property, color-mix()).

Techniques used in this demo

Theme tokensset in @theme, used by a utility

Search CodeFronts

Loading…