17 / 21
All 21 in 21 Tailwind CSS Pricing Sections
- 01Tailwind Classic Three Tier Pricing Section
- 02Tailwind Highlighted Popular Pricing Tier
- 03Tailwind Feature Comparison Pricing Table
- 04Tailwind Monthly Yearly Billing Toggle Pricing
- 05Tailwind Usage Slider Pricing Estimator
- 06Tailwind Single Premium Pricing Card
- 07Tailwind Bento Pricing Grid
- 08Tailwind Vertical Tier Timeline Pricing
- 09Tailwind Brutalist Print Pricing Zine
- 10Tailwind Glass Aurora Pricing Cards
- 11Tailwind Per-Seat Pricing Calculator
- 12Tailwind Animated Conic Border Pricing Cards
- 13Tailwind Editorial Two Column Pricing List
- 14Tailwind 3D Tilt Perspective Pricing Cards
- 15Tailwind Synthwave Neon Pricing Section
- 16Tailwind Pay What You Want Pricing Card
- 17Tailwind Currency Switcher Pricing Section
- 18Tailwind Social Proof Marquee Pricing
- 19Tailwind Feature Accordion Pricing Tiers
- 20Tailwind Cursor Spotlight Pricing Cards
- 21Tailwind Annual Savings Stripe Pricing
Tailwind Currency Switcher Pricing Section
Three currencies, nine prices, zero JavaScript: hidden radios plus group-has-[…]: swap every visible price across all three tiers at once. Burgundy on cream, with the featured tier inverted — and the port's clean-up is the inverted card, whose eight descendant override rules become ordinary utilities on the elements themselves.
Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49
Cruip · Affiliate link
The code
<section class="tps-17 group w-full min-h-svh bg-tps17-paper font-tps17-sans text-tps17-ink px-[clamp(20px,4vw,40px)] py-[clamp(28px,5vw,56px)]" aria-label="Pricing">
<header class="text-center mb-[clamp(24px,4vw,36px)]">
<h2 class="m-0 mb-2 font-tps17-serif text-[clamp(26px,4vw,38px)] font-bold italic tracking-[-0.015em] text-tps17-wine">Pricing in your currency.</h2>
<p class="m-0 mb-5 text-sm text-tps17-muted">Pay where you live, with the rate fixed at billing time.</p>
<fieldset class="relative inline-grid grid-cols-3 m-0 p-0.75 rounded-full bg-white border-[1.5px] border-tps17-wine">
<legend class="sr-only">Currency</legend>
<input type="radio" name="tps-17__c" id="tps-17-usd" class="peer/usd sr-only" checked>
<label for="tps-17-usd" class="col-start-1 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/usd:bg-tps17-wine peer-checked/usd:text-tps17-cream peer-focus-visible/usd:outline-2 peer-focus-visible/usd:outline-tps17-wine peer-focus-visible/usd:outline-offset-[3px] motion-reduce:transition-none">USD</label>
<input type="radio" name="tps-17__c" id="tps-17-eur" class="peer/eur sr-only">
<label for="tps-17-eur" class="col-start-2 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/eur:bg-tps17-wine peer-checked/eur:text-tps17-cream peer-focus-visible/eur:outline-2 peer-focus-visible/eur:outline-tps17-wine peer-focus-visible/eur:outline-offset-[3px] motion-reduce:transition-none">EUR</label>
<input type="radio" name="tps-17__c" id="tps-17-gbp" class="peer/gbp sr-only">
<label for="tps-17-gbp" class="col-start-3 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/gbp:bg-tps17-wine peer-checked/gbp:text-tps17-cream peer-focus-visible/gbp:outline-2 peer-focus-visible/gbp:outline-tps17-wine peer-focus-visible/gbp:outline-offset-[3px] motion-reduce:transition-none">GBP</label>
</fieldset>
</header>
<div class="grid grid-cols-1 md:grid-cols-[repeat(3,minmax(0,1fr))] items-center gap-[18px] max-w-[380px] md:max-w-[1000px] mx-auto">
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Petit</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$12</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€11</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£10</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Solo cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">3 bottles tracked</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Email reminders</li>
</ul>
<a href="#petit" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Petit</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-tps17-wine text-tps17-cream md:scale-[1.04] shadow-[0_18px_44px_--alpha(--color-tps17-wine/30)]">
<span class="absolute -top-3 left-1/2 -translate-x-1/2 whitespace-nowrap px-2.75 py-1 rounded-full bg-tps17-paper text-tps17-wine border-[1.5px] border-tps17-wine font-tps17-mono text-[10.5px] font-bold uppercase tracking-[0.12em]">Sommelier’s pick</span>
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-cream">Reserve</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-cream/25 text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$36</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€33</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£28</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-cream/70">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-cream">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Full cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Unlimited bottles</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Tasting notes</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Pairing engine</li>
</ul>
<a href="#reserve" class="block text-center px-4 py-2.75 rounded-[6px] bg-tps17-cream text-tps17-wine border-[1.5px] border-tps17-cream text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-transparent hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-tps17-cream focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Reserve</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Grand Cru</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$96</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€88</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£76</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Multi-cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Insurance valuation</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">White-glove setup</li>
</ul>
<a href="#grand" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Talk to us</a>
</article>
</div>
</section><section class="tps-17 group w-full min-h-svh bg-tps17-paper font-tps17-sans text-tps17-ink px-[clamp(20px,4vw,40px)] py-[clamp(28px,5vw,56px)]" aria-label="Pricing">
<header class="text-center mb-[clamp(24px,4vw,36px)]">
<h2 class="m-0 mb-2 font-tps17-serif text-[clamp(26px,4vw,38px)] font-bold italic tracking-[-0.015em] text-tps17-wine">Pricing in your currency.</h2>
<p class="m-0 mb-5 text-sm text-tps17-muted">Pay where you live, with the rate fixed at billing time.</p>
<fieldset class="relative inline-grid grid-cols-3 m-0 p-0.75 rounded-full bg-white border-[1.5px] border-tps17-wine">
<legend class="sr-only">Currency</legend>
<input type="radio" name="tps-17__c" id="tps-17-usd" class="peer/usd sr-only" checked>
<label for="tps-17-usd" class="col-start-1 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/usd:bg-tps17-wine peer-checked/usd:text-tps17-cream peer-focus-visible/usd:outline-2 peer-focus-visible/usd:outline-tps17-wine peer-focus-visible/usd:outline-offset-[3px] motion-reduce:transition-none">USD</label>
<input type="radio" name="tps-17__c" id="tps-17-eur" class="peer/eur sr-only">
<label for="tps-17-eur" class="col-start-2 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/eur:bg-tps17-wine peer-checked/eur:text-tps17-cream peer-focus-visible/eur:outline-2 peer-focus-visible/eur:outline-tps17-wine peer-focus-visible/eur:outline-offset-[3px] motion-reduce:transition-none">EUR</label>
<input type="radio" name="tps-17__c" id="tps-17-gbp" class="peer/gbp sr-only">
<label for="tps-17-gbp" class="col-start-3 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/gbp:bg-tps17-wine peer-checked/gbp:text-tps17-cream peer-focus-visible/gbp:outline-2 peer-focus-visible/gbp:outline-tps17-wine peer-focus-visible/gbp:outline-offset-[3px] motion-reduce:transition-none">GBP</label>
</fieldset>
</header>
<div class="grid grid-cols-1 md:grid-cols-[repeat(3,minmax(0,1fr))] items-center gap-[18px] max-w-[380px] md:max-w-[1000px] mx-auto">
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Petit</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$12</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€11</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£10</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Solo cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">3 bottles tracked</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Email reminders</li>
</ul>
<a href="#petit" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Petit</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-tps17-wine text-tps17-cream md:scale-[1.04] shadow-[0_18px_44px_--alpha(--color-tps17-wine/30)]">
<span class="absolute -top-3 left-1/2 -translate-x-1/2 whitespace-nowrap px-2.75 py-1 rounded-full bg-tps17-paper text-tps17-wine border-[1.5px] border-tps17-wine font-tps17-mono text-[10.5px] font-bold uppercase tracking-[0.12em]">Sommelier’s pick</span>
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-cream">Reserve</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-cream/25 text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$36</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€33</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£28</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-cream/70">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-cream">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Full cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Unlimited bottles</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Tasting notes</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Pairing engine</li>
</ul>
<a href="#reserve" class="block text-center px-4 py-2.75 rounded-[6px] bg-tps17-cream text-tps17-wine border-[1.5px] border-tps17-cream text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-transparent hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-tps17-cream focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Reserve</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Grand Cru</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$96</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€88</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£76</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Multi-cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Insurance valuation</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">White-glove setup</li>
</ul>
<a href="#grand" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Talk to us</a>
</article>
</div>
</section>@import "tailwindcss";
@theme {
--color-tps17-paper: #faf6ee;
--color-tps17-paper: oklch(0.97 0.012 85);
--color-tps17-cream: #faf6ee;
--color-tps17-cream: oklch(0.97 0.012 85);
--color-tps17-ink: #2a0a14;
--color-tps17-ink: oklch(0.21 0.06 10);
--color-tps17-wine: #6b1224;
--color-tps17-wine: oklch(0.34 0.13 15);
--color-tps17-body: #4a2030;
--color-tps17-body: oklch(0.32 0.07 8);
--color-tps17-muted: #8a4555;
--color-tps17-muted: oklch(0.48 0.09 10);
--color-tps17-line: #e7d8c8;
--color-tps17-line: oklch(0.89 0.025 75);
--font-tps17-serif: 'Playfair Display', Georgia, serif;
--font-tps17-mono: 'JetBrains Mono', monospace;
--font-tps17-sans: 'Public Sans', system-ui, 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 sized correctly in the moment before the
browser build has compiled its utilities. */
.tps-17 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tps17-paper: #faf6ee;
--color-tps17-paper: oklch(0.97 0.012 85);
--color-tps17-cream: #faf6ee;
--color-tps17-cream: oklch(0.97 0.012 85);
--color-tps17-ink: #2a0a14;
--color-tps17-ink: oklch(0.21 0.06 10);
--color-tps17-wine: #6b1224;
--color-tps17-wine: oklch(0.34 0.13 15);
--color-tps17-body: #4a2030;
--color-tps17-body: oklch(0.32 0.07 8);
--color-tps17-muted: #8a4555;
--color-tps17-muted: oklch(0.48 0.09 10);
--color-tps17-line: #e7d8c8;
--color-tps17-line: oklch(0.89 0.025 75);
--font-tps17-serif: 'Playfair Display', Georgia, serif;
--font-tps17-mono: 'JetBrains Mono', monospace;
--font-tps17-sans: 'Public Sans', system-ui, 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 sized correctly in the moment before the
browser build has compiled its utilities. */
.tps-17 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<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.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tps17-paper: #faf6ee;
--color-tps17-paper: oklch(0.97 0.012 85);
--color-tps17-cream: #faf6ee;
--color-tps17-cream: oklch(0.97 0.012 85);
--color-tps17-ink: #2a0a14;
--color-tps17-ink: oklch(0.21 0.06 10);
--color-tps17-wine: #6b1224;
--color-tps17-wine: oklch(0.34 0.13 15);
--color-tps17-body: #4a2030;
--color-tps17-body: oklch(0.32 0.07 8);
--color-tps17-muted: #8a4555;
--color-tps17-muted: oklch(0.48 0.09 10);
--color-tps17-line: #e7d8c8;
--color-tps17-line: oklch(0.89 0.025 75);
--font-tps17-serif: 'Playfair Display', Georgia, serif;
--font-tps17-mono: 'JetBrains Mono', monospace;
--font-tps17-sans: 'Public Sans', system-ui, 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 sized correctly in the moment before the
browser build has compiled its utilities. */
.tps-17 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tps17-paper: #faf6ee;
--color-tps17-paper: oklch(0.97 0.012 85);
--color-tps17-cream: #faf6ee;
--color-tps17-cream: oklch(0.97 0.012 85);
--color-tps17-ink: #2a0a14;
--color-tps17-ink: oklch(0.21 0.06 10);
--color-tps17-wine: #6b1224;
--color-tps17-wine: oklch(0.34 0.13 15);
--color-tps17-body: #4a2030;
--color-tps17-body: oklch(0.32 0.07 8);
--color-tps17-muted: #8a4555;
--color-tps17-muted: oklch(0.48 0.09 10);
--color-tps17-line: #e7d8c8;
--color-tps17-line: oklch(0.89 0.025 75);
--font-tps17-serif: 'Playfair Display', Georgia, serif;
--font-tps17-mono: 'JetBrains Mono', monospace;
--font-tps17-sans: 'Public Sans', system-ui, 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 sized correctly in the moment before the
browser build has compiled its utilities. */
.tps-17 {
width: 100%;
min-height: 100svh;
}<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=Playfair+Display:ital,wght@1,700&family=JetBrains+Mono:wght@700&family=Public+Sans:wght@400;500;600;800&display=swap">
<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=Playfair+Display:ital,wght@1,700&family=JetBrains+Mono:wght@700&family=Public+Sans:wght@400;500;600;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The three-selector
:has()rule plus itsdisplay: nonebase becomes nine independenthidden group-has-[#tps-17-eur:checked]:inlinespans. Each price says which currency it belongs to; there is no shared rule to keep in step. - Five
.ps-17__best …descendant overrides — heading, price border, suffix, list, bullets, CTA — disappear. The inverted card's children carry cream directly, and the CSS'scolor: #6b1224 !importantspecificity fight goes with them. border-currentreplacesborder: 1.5px solid currentColorplus two colour overrides: the outline CTA, the inverted CTA and the inverted-primary CTA all derive their border from their own text colour.- The tabs use named peers (
peer/usd,peer/eur,peer/gbp) with explicitcol-start-*, because three radios and three labels interleaved in one grid need both the naming and the placement stated. md:scale-[1.04]absorbs both the featured lift and the 820pxtransform: nonerule — the emphasis is a desktop enhancement by declaration.--alpha(--color-tps17-wine/30)ties the featured card's drop shadow to its own background token rather than repeating anrgba()literal.
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 Currency Switcher Pricing Section
Source: https://codefronts.com/layouts/tailwind-css-pricing-sections/tailwind-currency-switcher-pricing-section/
Three currencies, nine prices, zero JavaScript: hidden radios plus group-has-[…]: swap every visible price across all three tiers at once. Burgundy on cream, with the featured tier inverted — and the port's clean-up is the inverted card, whose eight descendant override rules become ordinary utilities on the elements themselves.
## HTML
```html
<section class="tps-17 group w-full min-h-svh bg-tps17-paper font-tps17-sans text-tps17-ink px-[clamp(20px,4vw,40px)] py-[clamp(28px,5vw,56px)]" aria-label="Pricing">
<header class="text-center mb-[clamp(24px,4vw,36px)]">
<h2 class="m-0 mb-2 font-tps17-serif text-[clamp(26px,4vw,38px)] font-bold italic tracking-[-0.015em] text-tps17-wine">Pricing in your currency.</h2>
<p class="m-0 mb-5 text-sm text-tps17-muted">Pay where you live, with the rate fixed at billing time.</p>
<fieldset class="relative inline-grid grid-cols-3 m-0 p-0.75 rounded-full bg-white border-[1.5px] border-tps17-wine">
<legend class="sr-only">Currency</legend>
<input type="radio" name="tps-17__c" id="tps-17-usd" class="peer/usd sr-only" checked>
<label for="tps-17-usd" class="col-start-1 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/usd:bg-tps17-wine peer-checked/usd:text-tps17-cream peer-focus-visible/usd:outline-2 peer-focus-visible/usd:outline-tps17-wine peer-focus-visible/usd:outline-offset-[3px] motion-reduce:transition-none">USD</label>
<input type="radio" name="tps-17__c" id="tps-17-eur" class="peer/eur sr-only">
<label for="tps-17-eur" class="col-start-2 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/eur:bg-tps17-wine peer-checked/eur:text-tps17-cream peer-focus-visible/eur:outline-2 peer-focus-visible/eur:outline-tps17-wine peer-focus-visible/eur:outline-offset-[3px] motion-reduce:transition-none">EUR</label>
<input type="radio" name="tps-17__c" id="tps-17-gbp" class="peer/gbp sr-only">
<label for="tps-17-gbp" class="col-start-3 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/gbp:bg-tps17-wine peer-checked/gbp:text-tps17-cream peer-focus-visible/gbp:outline-2 peer-focus-visible/gbp:outline-tps17-wine peer-focus-visible/gbp:outline-offset-[3px] motion-reduce:transition-none">GBP</label>
</fieldset>
</header>
<div class="grid grid-cols-1 md:grid-cols-[repeat(3,minmax(0,1fr))] items-center gap-[18px] max-w-[380px] md:max-w-[1000px] mx-auto">
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Petit</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$12</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€11</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£10</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Solo cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">3 bottles tracked</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Email reminders</li>
</ul>
<a href="#petit" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Petit</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-tps17-wine text-tps17-cream md:scale-[1.04] shadow-[0_18px_44px_--alpha(--color-tps17-wine/30)]">
<span class="absolute -top-3 left-1/2 -translate-x-1/2 whitespace-nowrap px-2.75 py-1 rounded-full bg-tps17-paper text-tps17-wine border-[1.5px] border-tps17-wine font-tps17-mono text-[10.5px] font-bold uppercase tracking-[0.12em]">Sommelier’s pick</span>
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-cream">Reserve</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-cream/25 text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$36</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€33</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£28</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-cream/70">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-cream">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Full cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Unlimited bottles</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Tasting notes</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Pairing engine</li>
</ul>
<a href="#reserve" class="block text-center px-4 py-2.75 rounded-[6px] bg-tps17-cream text-tps17-wine border-[1.5px] border-tps17-cream text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-transparent hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-tps17-cream focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Reserve</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Grand Cru</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$96</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€88</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£76</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Multi-cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Insurance valuation</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">White-glove setup</li>
</ul>
<a href="#grand" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Talk to us</a>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tps17-paper: #faf6ee;
--color-tps17-paper: oklch(0.97 0.012 85);
--color-tps17-cream: #faf6ee;
--color-tps17-cream: oklch(0.97 0.012 85);
--color-tps17-ink: #2a0a14;
--color-tps17-ink: oklch(0.21 0.06 10);
--color-tps17-wine: #6b1224;
--color-tps17-wine: oklch(0.34 0.13 15);
--color-tps17-body: #4a2030;
--color-tps17-body: oklch(0.32 0.07 8);
--color-tps17-muted: #8a4555;
--color-tps17-muted: oklch(0.48 0.09 10);
--color-tps17-line: #e7d8c8;
--color-tps17-line: oklch(0.89 0.025 75);
--font-tps17-serif: 'Playfair Display', Georgia, serif;
--font-tps17-mono: 'JetBrains Mono', monospace;
--font-tps17-sans: 'Public Sans', system-ui, 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 sized correctly in the moment before the
browser build has compiled its utilities. */
.tps-17 {
width: 100%;
min-height: 100svh;
}
```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 Currency Switcher Pricing Section
Source: https://codefronts.com/layouts/tailwind-css-pricing-sections/tailwind-currency-switcher-pricing-section/
Three currencies, nine prices, zero JavaScript: hidden radios plus group-has-[…]: swap every visible price across all three tiers at once. Burgundy on cream, with the featured tier inverted — and the port's clean-up is the inverted card, whose eight descendant override rules become ordinary utilities on the elements themselves.
## HTML
```html
<section class="tps-17 group w-full min-h-svh bg-tps17-paper font-tps17-sans text-tps17-ink px-[clamp(20px,4vw,40px)] py-[clamp(28px,5vw,56px)]" aria-label="Pricing">
<header class="text-center mb-[clamp(24px,4vw,36px)]">
<h2 class="m-0 mb-2 font-tps17-serif text-[clamp(26px,4vw,38px)] font-bold italic tracking-[-0.015em] text-tps17-wine">Pricing in your currency.</h2>
<p class="m-0 mb-5 text-sm text-tps17-muted">Pay where you live, with the rate fixed at billing time.</p>
<fieldset class="relative inline-grid grid-cols-3 m-0 p-0.75 rounded-full bg-white border-[1.5px] border-tps17-wine">
<legend class="sr-only">Currency</legend>
<input type="radio" name="tps-17__c" id="tps-17-usd" class="peer/usd sr-only" checked>
<label for="tps-17-usd" class="col-start-1 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/usd:bg-tps17-wine peer-checked/usd:text-tps17-cream peer-focus-visible/usd:outline-2 peer-focus-visible/usd:outline-tps17-wine peer-focus-visible/usd:outline-offset-[3px] motion-reduce:transition-none">USD</label>
<input type="radio" name="tps-17__c" id="tps-17-eur" class="peer/eur sr-only">
<label for="tps-17-eur" class="col-start-2 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/eur:bg-tps17-wine peer-checked/eur:text-tps17-cream peer-focus-visible/eur:outline-2 peer-focus-visible/eur:outline-tps17-wine peer-focus-visible/eur:outline-offset-[3px] motion-reduce:transition-none">EUR</label>
<input type="radio" name="tps-17__c" id="tps-17-gbp" class="peer/gbp sr-only">
<label for="tps-17-gbp" class="col-start-3 row-start-1 px-[22px] py-1.75 rounded-full font-tps17-mono text-xs font-bold tracking-[0.1em] text-tps17-muted cursor-pointer transition-[background-color,color] duration-[180ms] peer-checked/gbp:bg-tps17-wine peer-checked/gbp:text-tps17-cream peer-focus-visible/gbp:outline-2 peer-focus-visible/gbp:outline-tps17-wine peer-focus-visible/gbp:outline-offset-[3px] motion-reduce:transition-none">GBP</label>
</fieldset>
</header>
<div class="grid grid-cols-1 md:grid-cols-[repeat(3,minmax(0,1fr))] items-center gap-[18px] max-w-[380px] md:max-w-[1000px] mx-auto">
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Petit</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$12</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€11</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£10</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Solo cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">3 bottles tracked</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Email reminders</li>
</ul>
<a href="#petit" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Petit</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-tps17-wine text-tps17-cream md:scale-[1.04] shadow-[0_18px_44px_--alpha(--color-tps17-wine/30)]">
<span class="absolute -top-3 left-1/2 -translate-x-1/2 whitespace-nowrap px-2.75 py-1 rounded-full bg-tps17-paper text-tps17-wine border-[1.5px] border-tps17-wine font-tps17-mono text-[10.5px] font-bold uppercase tracking-[0.12em]">Sommelier’s pick</span>
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-cream">Reserve</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-cream/25 text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$36</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€33</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£28</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-cream/70">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-cream">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Full cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Unlimited bottles</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Tasting notes</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-cream">Pairing engine</li>
</ul>
<a href="#reserve" class="block text-center px-4 py-2.75 rounded-[6px] bg-tps17-cream text-tps17-wine border-[1.5px] border-tps17-cream text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-transparent hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-tps17-cream focus-visible:outline-offset-[3px] motion-reduce:transition-none">Choose Reserve</a>
</article>
<article class="relative flex flex-col px-[22px] pt-[26px] pb-[22px] rounded-[8px] bg-white border border-tps17-line">
<h3 class="m-0 mb-3 font-tps17-serif text-[22px] font-bold italic text-tps17-wine">Grand Cru</h3>
<div class="flex items-baseline gap-1 mb-[18px] pb-[18px] border-b border-dashed border-tps17-line text-[38px] font-extrabold tracking-[-0.03em]">
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$96</span><span class="hidden group-has-[#tps-17-eur:checked]:inline">€88</span><span class="hidden group-has-[#tps-17-gbp:checked]:inline">£76</span>
<em class="not-italic ml-1.5 text-[13px] font-medium text-tps17-muted">/month</em>
</div>
<ul class="list-none p-0 m-0 mb-5 flex-1 text-[13.5px]/[1.95] text-tps17-body">
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Multi-cellar</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">Insurance valuation</li>
<li class="before:content-['\25C6'] before:inline-block before:w-5 before:text-[9px] before:text-tps17-wine">White-glove setup</li>
</ul>
<a href="#grand" class="block text-center px-4 py-2.75 rounded-[6px] bg-transparent text-tps17-wine border-[1.5px] border-current text-[13px] font-semibold uppercase tracking-[0.04em] no-underline transition-[background-color,color] duration-[180ms] hover:bg-tps17-wine hover:text-tps17-cream focus-visible:outline-2 focus-visible:outline-current focus-visible:outline-offset-[3px] motion-reduce:transition-none">Talk to us</a>
</article>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tps17-paper: #faf6ee;
--color-tps17-paper: oklch(0.97 0.012 85);
--color-tps17-cream: #faf6ee;
--color-tps17-cream: oklch(0.97 0.012 85);
--color-tps17-ink: #2a0a14;
--color-tps17-ink: oklch(0.21 0.06 10);
--color-tps17-wine: #6b1224;
--color-tps17-wine: oklch(0.34 0.13 15);
--color-tps17-body: #4a2030;
--color-tps17-body: oklch(0.32 0.07 8);
--color-tps17-muted: #8a4555;
--color-tps17-muted: oklch(0.48 0.09 10);
--color-tps17-line: #e7d8c8;
--color-tps17-line: oklch(0.89 0.025 75);
--font-tps17-serif: 'Playfair Display', Georgia, serif;
--font-tps17-mono: 'JetBrains Mono', monospace;
--font-tps17-sans: 'Public Sans', system-ui, 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 sized correctly in the moment before the
browser build has compiled its utilities. */
.tps-17 {
width: 100%;
min-height: 100svh;
}
```How this works
One radio, nine prices. Every price cell carries all three currencies and lets a variant decide which one is inline:
<span class="hidden group-has-[#tps-17-usd:checked]:inline">$36</span>
<span class="hidden group-has-[#tps-17-eur:checked]:inline">€33</span>
<span class="hidden group-has-[#tps-17-gbp:checked]:inline">£28</span>The CSS does the same thing with a three-selector rule and a .ps-17__price > span { display: none } base. Ported, there is no base rule and no selector list — each span says what it is for.
The inverted card stops being a special case. .ps-17__best h3, .ps-17__best ul, .ps-17__best .ps-17__price, .ps-17__best ul li::before, .ps-17__best .ps-17__cta — five descendant overrides, plus a !important on the primary CTA to win the specificity fight. In utilities the featured card's children simply carry cream instead of wine, and nothing overrides anything.
border-current is the right abstraction here. The CTA's border should always match its text. Stating that once means the outline card, the inverted card and the inverted-primary card all work without a border colour of their own.
Real currency amounts, not a conversion. The prices are three separate round numbers, as a wine merchant would actually list them — which is the honest reason this can be a CSS swap at all rather than arithmetic.
Make it yours
- Currencies: three radios, and three spans per price. A fourth currency is four more spans — workable, but past that use JS.
- Rates: the nine price spans are independent numbers. Round them per market rather than converting; that is the point of the pattern.
- Palette:
--color-tps17-wine,--color-tps17-cream,--color-tps17-line. The featured card is just those first two swapped. - Lift:
md:scale-[1.04]. Drop it and the inverted palette alone still carries the emphasis. - Display face:
--font-tps17-seriffor the italic tier names,--font-tps17-monofor the tabs and the pill. The mono/serif tension is the whole boutique voice.
Gotchas — read before shipping
- The
checkedradio and the un-hidden default must agree — here USD ischeckedand its spans are the ones agroup-hasvariant reveals, so the card is correct before any interaction. - All nine prices are always in the DOM. A screen reader in USD mode will not read the hidden ones (
display: noneremoves them from the accessibility tree), but keep them in the same order so the visual and reading order match. sr-onlyon the radios, neverhidden: the tabs must stay keyboard-operable as a radio group.- Inside the inverted card, do not use alpha text for the list.
text-tps17-cream/85on wine is borderline; the port keeps the list cream at full opacity and drops opacity only on the/monthsuffix, which is not body copy. border-currentmeans the CTA border inherits its card's text colour — if you give a CTA a differenttext-*, the border follows. That is the feature, but it surprises people.- Prices sit in a
flex items-baselinerow. Withoutitems-baselinethe/monthsuffix aligns to the 38px number's box and floats.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
:has() is Baseline since Firefox 121 (December 2023); group-has-* compiles straight to it. Without :has() support the tabs still focus and check, but the displayed currency never changes — so USD, the checked default, is what everyone sees.