02 / 25
All 25 in 25 Tailwind CSS Button Groups
- 01Tailwind Split Button with Anchor-Positioned Popover Dropdown (No JS)
- 02Tailwind Segmented Control with Motion-Path Comet Indicator
- 03Tailwind Toggle Button Group with View Transitions Morphing Highlight
- 04Tailwind Pricing Toggle — Monthly / Yearly Billing Switch (No JS)
- 05Tailwind Segmented Control with Sliding Thumb (iOS Style)
- 06Tailwind Split Button Dropdown with Native Details Menu (Save Options)
- 07Tailwind Icon Button Group Toolbar with Tooltips (Rich Text Editor)
- 08Tailwind Pill Filter Button Group with Sliding Indicator (Anchor Positioning)
- 09Tailwind Toggle Button Group for Text Alignment (Radio Inputs, Live Preview)
- 10Tailwind Web3 Connect Wallet Button Grid (Wallet Sign-In Modal)
- 11Tailwind AI Model Selector Button Group (LLM Model Picker with Badges)
- 12Tailwind Liquid Metal Segmented Control (Animated Chrome Thumb)
- 13Tailwind Tab Button Group with Subgrid Underline Indicator
- 14Tailwind Multi-Select Chip Buttons (Tag Filter Checkboxes with Count)
- 15Tailwind Animated Split Button Deploy Menu (Staggered Dropdown Reveal)
- 16Tailwind Radio Button Group with Conic Fill Animation (Export Format Picker)
- 17Tailwind Retro LED Pixel Button Group (Dot-Matrix Display Buttons)
- 18Tailwind Hold-to-Confirm Button Group with Gradient Progress (Press and Hold)
- 19Tailwind Holographic Icon Segmented Control (Grid / List View Switcher)
- 20Tailwind 3D Vertical Button Group with Hover Depth (Perspective Stack)
- 21Tailwind Floating Action Button with Radial Speed Dial Menu (No JS)
- 22Tailwind Glitch Effect Button Group (Cyberpunk RGB-Split Audio Filter)
- 23Tailwind Animated Gradient Border Pill Buttons (Rotating Conic Ring)
- 24Tailwind Button Group with Ripple Click Effect (Radar Shockwave Feedback)
- 25Tailwind Button Group with Cursor-Following Spotlight Glow (Date Range Presets)
Tailwind Segmented Control with Motion-Path Comet Indicator
A four-way mode switch whose thumb travels an arc instead of a straight line, trailed by a blurred comet tail that lags behind on a slower curve. The motion path is an arbitrary property — [offset-path:path('M43,28C123,6,203,6,283,28')] — and each radio moves it with group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%]. A live status line under the control reports the active mode, still with no JavaScript.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tbg-02 w-full min-h-svh grid place-items-center bg-tbg02-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg02-glow),transparent_70%)] px-5 py-14 font-tbg02-sans text-tbg02-ink" aria-label="Motion-path comet segmented control demo">
<div class="group/wrap grid gap-4">
<p id="tbg02-label" class="ml-1 text-xs font-bold uppercase tracking-[0.16em] text-tbg02-acc">Signal mode</p>
<div role="radiogroup" aria-labelledby="tbg02-label" class="group/seg relative grid w-fit max-w-full grid-cols-[repeat(4,80px)] rounded-2xl border border-tbg02-line bg-tbg02-well p-1.5 shadow-[inset_0_2px_8px_rgb(0_0_0/0.5)]">
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-1" class="sr-only" checked>Live</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-2" class="sr-only">Pulse</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-3" class="sr-only">Wave</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-4" class="sr-only">Idle</label>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-0 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc3 opacity-60 blur-[9px] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-800 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-1 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc2 shadow-[0_4px_18px_-4px_var(--color-tbg02-acc)] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-500 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
</div>
<p class="ml-1 flex items-center gap-2.5 font-tbg02-mono text-xs text-tbg02-mut">
<span aria-hidden="true" class="size-2 rounded-full bg-tbg02-acc shadow-[0_0_10px_var(--color-tbg02-acc)] group-has-[#tbg02-4:checked]/wrap:bg-tbg02-mut group-has-[#tbg02-4:checked]/wrap:shadow-none"></span>
<span class="group-has-[#tbg02-1:checked]/wrap:inline hidden">Streaming · 60 Hz refresh</span>
<span class="group-has-[#tbg02-2:checked]/wrap:inline hidden">Heartbeat · every 5 s</span>
<span class="group-has-[#tbg02-3:checked]/wrap:inline hidden">Batched · rolling 1 min</span>
<span class="group-has-[#tbg02-4:checked]/wrap:inline hidden">Paused · no data sent</span>
</p>
</div>
</section><section class="tbg-02 w-full min-h-svh grid place-items-center bg-tbg02-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg02-glow),transparent_70%)] px-5 py-14 font-tbg02-sans text-tbg02-ink" aria-label="Motion-path comet segmented control demo">
<div class="group/wrap grid gap-4">
<p id="tbg02-label" class="ml-1 text-xs font-bold uppercase tracking-[0.16em] text-tbg02-acc">Signal mode</p>
<div role="radiogroup" aria-labelledby="tbg02-label" class="group/seg relative grid w-fit max-w-full grid-cols-[repeat(4,80px)] rounded-2xl border border-tbg02-line bg-tbg02-well p-1.5 shadow-[inset_0_2px_8px_rgb(0_0_0/0.5)]">
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-1" class="sr-only" checked>Live</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-2" class="sr-only">Pulse</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-3" class="sr-only">Wave</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-4" class="sr-only">Idle</label>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-0 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc3 opacity-60 blur-[9px] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-800 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-1 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc2 shadow-[0_4px_18px_-4px_var(--color-tbg02-acc)] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-500 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
</div>
<p class="ml-1 flex items-center gap-2.5 font-tbg02-mono text-xs text-tbg02-mut">
<span aria-hidden="true" class="size-2 rounded-full bg-tbg02-acc shadow-[0_0_10px_var(--color-tbg02-acc)] group-has-[#tbg02-4:checked]/wrap:bg-tbg02-mut group-has-[#tbg02-4:checked]/wrap:shadow-none"></span>
<span class="group-has-[#tbg02-1:checked]/wrap:inline hidden">Streaming · 60 Hz refresh</span>
<span class="group-has-[#tbg02-2:checked]/wrap:inline hidden">Heartbeat · every 5 s</span>
<span class="group-has-[#tbg02-3:checked]/wrap:inline hidden">Batched · rolling 1 min</span>
<span class="group-has-[#tbg02-4:checked]/wrap:inline hidden">Paused · no data sent</span>
</p>
</div>
</section>@import "tailwindcss";
@theme {
--color-tbg02-bg: #06070f;
--color-tbg02-glow: #12163a;
--color-tbg02-well: #12142a;
--color-tbg02-line: #222647;
--color-tbg02-ink: #e6e9ff;
--color-tbg02-mut: #9aa2cc;
--color-tbg02-mut: oklch(0.72 0.05 275);
--color-tbg02-on: #04121c;
--color-tbg02-acc: #38f2c0;
--color-tbg02-acc: oklch(0.86 0.16 170);
--color-tbg02-acc2: #3aa0ff;
--color-tbg02-acc2: oklch(0.69 0.17 250);
--color-tbg02-acc3: #8a5bff;
--color-tbg02-acc3: oklch(0.6 0.23 290);
--font-tbg02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tbg02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-02 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tbg02-bg: #06070f;
--color-tbg02-glow: #12163a;
--color-tbg02-well: #12142a;
--color-tbg02-line: #222647;
--color-tbg02-ink: #e6e9ff;
--color-tbg02-mut: #9aa2cc;
--color-tbg02-mut: oklch(0.72 0.05 275);
--color-tbg02-on: #04121c;
--color-tbg02-acc: #38f2c0;
--color-tbg02-acc: oklch(0.86 0.16 170);
--color-tbg02-acc2: #3aa0ff;
--color-tbg02-acc2: oklch(0.69 0.17 250);
--color-tbg02-acc3: #8a5bff;
--color-tbg02-acc3: oklch(0.6 0.23 290);
--font-tbg02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tbg02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-02 {
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-tbg02-bg: #06070f;
--color-tbg02-glow: #12163a;
--color-tbg02-well: #12142a;
--color-tbg02-line: #222647;
--color-tbg02-ink: #e6e9ff;
--color-tbg02-mut: #9aa2cc;
--color-tbg02-mut: oklch(0.72 0.05 275);
--color-tbg02-on: #04121c;
--color-tbg02-acc: #38f2c0;
--color-tbg02-acc: oklch(0.86 0.16 170);
--color-tbg02-acc2: #3aa0ff;
--color-tbg02-acc2: oklch(0.69 0.17 250);
--color-tbg02-acc3: #8a5bff;
--color-tbg02-acc3: oklch(0.6 0.23 290);
--font-tbg02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tbg02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-02 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tbg02-bg: #06070f;
--color-tbg02-glow: #12163a;
--color-tbg02-well: #12142a;
--color-tbg02-line: #222647;
--color-tbg02-ink: #e6e9ff;
--color-tbg02-mut: #9aa2cc;
--color-tbg02-mut: oklch(0.72 0.05 275);
--color-tbg02-on: #04121c;
--color-tbg02-acc: #38f2c0;
--color-tbg02-acc: oklch(0.86 0.16 170);
--color-tbg02-acc2: #3aa0ff;
--color-tbg02-acc2: oklch(0.69 0.17 250);
--color-tbg02-acc3: #8a5bff;
--color-tbg02-acc3: oklch(0.6 0.23 290);
--font-tbg02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tbg02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-02 {
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=Space+Grotesk:wght@400..700&family=JetBrains+Mono:wght@400..600&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=Space+Grotesk:wght@400..700&family=JetBrains+Mono:wght@400..600&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The four
.btn-02__seg:has(#…:checked){--d:…}rules becamegroup-has-[#tbg02-N:checked]/seg:variants directly on the thumb and tail. - Inputs moved inside their labels, so
has-checked:replaces theinput:checked + labelsibling chain. - UI upgrade: a live status line (pure CSS) now explains what each mode actually does, and the indicator dot goes dark on Idle.
- UI upgrade: muted labels rose to
oklch(0.72)for 4.5:1+ on the dark well, and the label is wired to the group witharia-labelledby.
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 Segmented Control with Motion-Path Comet Indicator
Source: https://codefronts.com/components/tailwind-css-button-groups/tailwind-segmented-control-motion-path-indicator/
A four-way mode switch whose thumb travels an arc instead of a straight line, trailed by a blurred comet tail that lags behind on a slower curve. The motion path is an arbitrary property — [offset-path:path('M43,28C123,6,203,6,283,28')] — and each radio moves it with group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%]. A live status line under the control reports the active mode, still with no JavaScript.
## HTML
```html
<section class="tbg-02 w-full min-h-svh grid place-items-center bg-tbg02-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg02-glow),transparent_70%)] px-5 py-14 font-tbg02-sans text-tbg02-ink" aria-label="Motion-path comet segmented control demo">
<div class="group/wrap grid gap-4">
<p id="tbg02-label" class="ml-1 text-xs font-bold uppercase tracking-[0.16em] text-tbg02-acc">Signal mode</p>
<div role="radiogroup" aria-labelledby="tbg02-label" class="group/seg relative grid w-fit max-w-full grid-cols-[repeat(4,80px)] rounded-2xl border border-tbg02-line bg-tbg02-well p-1.5 shadow-[inset_0_2px_8px_rgb(0_0_0/0.5)]">
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-1" class="sr-only" checked>Live</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-2" class="sr-only">Pulse</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-3" class="sr-only">Wave</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-4" class="sr-only">Idle</label>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-0 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc3 opacity-60 blur-[9px] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-800 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-1 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc2 shadow-[0_4px_18px_-4px_var(--color-tbg02-acc)] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-500 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
</div>
<p class="ml-1 flex items-center gap-2.5 font-tbg02-mono text-xs text-tbg02-mut">
<span aria-hidden="true" class="size-2 rounded-full bg-tbg02-acc shadow-[0_0_10px_var(--color-tbg02-acc)] group-has-[#tbg02-4:checked]/wrap:bg-tbg02-mut group-has-[#tbg02-4:checked]/wrap:shadow-none"></span>
<span class="group-has-[#tbg02-1:checked]/wrap:inline hidden">Streaming · 60 Hz refresh</span>
<span class="group-has-[#tbg02-2:checked]/wrap:inline hidden">Heartbeat · every 5 s</span>
<span class="group-has-[#tbg02-3:checked]/wrap:inline hidden">Batched · rolling 1 min</span>
<span class="group-has-[#tbg02-4:checked]/wrap:inline hidden">Paused · no data sent</span>
</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbg02-bg: #06070f;
--color-tbg02-glow: #12163a;
--color-tbg02-well: #12142a;
--color-tbg02-line: #222647;
--color-tbg02-ink: #e6e9ff;
--color-tbg02-mut: #9aa2cc;
--color-tbg02-mut: oklch(0.72 0.05 275);
--color-tbg02-on: #04121c;
--color-tbg02-acc: #38f2c0;
--color-tbg02-acc: oklch(0.86 0.16 170);
--color-tbg02-acc2: #3aa0ff;
--color-tbg02-acc2: oklch(0.69 0.17 250);
--color-tbg02-acc3: #8a5bff;
--color-tbg02-acc3: oklch(0.6 0.23 290);
--font-tbg02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tbg02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-02 {
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 Segmented Control with Motion-Path Comet Indicator
Source: https://codefronts.com/components/tailwind-css-button-groups/tailwind-segmented-control-motion-path-indicator/
A four-way mode switch whose thumb travels an arc instead of a straight line, trailed by a blurred comet tail that lags behind on a slower curve. The motion path is an arbitrary property — [offset-path:path('M43,28C123,6,203,6,283,28')] — and each radio moves it with group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%]. A live status line under the control reports the active mode, still with no JavaScript.
## HTML
```html
<section class="tbg-02 w-full min-h-svh grid place-items-center bg-tbg02-bg bg-[radial-gradient(120%_120%_at_50%_0%,var(--color-tbg02-glow),transparent_70%)] px-5 py-14 font-tbg02-sans text-tbg02-ink" aria-label="Motion-path comet segmented control demo">
<div class="group/wrap grid gap-4">
<p id="tbg02-label" class="ml-1 text-xs font-bold uppercase tracking-[0.16em] text-tbg02-acc">Signal mode</p>
<div role="radiogroup" aria-labelledby="tbg02-label" class="group/seg relative grid w-fit max-w-full grid-cols-[repeat(4,80px)] rounded-2xl border border-tbg02-line bg-tbg02-well p-1.5 shadow-[inset_0_2px_8px_rgb(0_0_0/0.5)]">
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-1" class="sr-only" checked>Live</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-2" class="sr-only">Pulse</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-3" class="sr-only">Wave</label>
<label class="relative z-2 grid min-h-11 cursor-pointer place-items-center rounded-lg text-[14.5px] font-semibold text-tbg02-mut transition-colors duration-300 hover:text-tbg02-ink has-checked:text-tbg02-on has-focus-visible:outline-3 has-focus-visible:outline-offset-3 has-focus-visible:outline-tbg02-acc"><input type="radio" name="tbg02" id="tbg02-4" class="sr-only">Idle</label>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-0 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc3 opacity-60 blur-[9px] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-800 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
<span aria-hidden="true" class="pointer-events-none absolute top-0 left-0 z-1 h-11 w-[74px] rounded-[11px] bg-linear-120 from-tbg02-acc to-tbg02-acc2 shadow-[0_4px_18px_-4px_var(--color-tbg02-acc)] [offset-path:path('M43,28C123,6,203,6,283,28')] [offset-rotate:0deg] [offset-distance:0%] transition-[offset-distance] duration-500 ease-[cubic-bezier(.5,0,.2,1)] group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%] group-has-[#tbg02-3:checked]/seg:[offset-distance:66.666%] group-has-[#tbg02-4:checked]/seg:[offset-distance:100%] motion-reduce:duration-200 motion-reduce:[offset-path:path('M43,28L283,28')]"></span>
</div>
<p class="ml-1 flex items-center gap-2.5 font-tbg02-mono text-xs text-tbg02-mut">
<span aria-hidden="true" class="size-2 rounded-full bg-tbg02-acc shadow-[0_0_10px_var(--color-tbg02-acc)] group-has-[#tbg02-4:checked]/wrap:bg-tbg02-mut group-has-[#tbg02-4:checked]/wrap:shadow-none"></span>
<span class="group-has-[#tbg02-1:checked]/wrap:inline hidden">Streaming · 60 Hz refresh</span>
<span class="group-has-[#tbg02-2:checked]/wrap:inline hidden">Heartbeat · every 5 s</span>
<span class="group-has-[#tbg02-3:checked]/wrap:inline hidden">Batched · rolling 1 min</span>
<span class="group-has-[#tbg02-4:checked]/wrap:inline hidden">Paused · no data sent</span>
</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbg02-bg: #06070f;
--color-tbg02-glow: #12163a;
--color-tbg02-well: #12142a;
--color-tbg02-line: #222647;
--color-tbg02-ink: #e6e9ff;
--color-tbg02-mut: #9aa2cc;
--color-tbg02-mut: oklch(0.72 0.05 275);
--color-tbg02-on: #04121c;
--color-tbg02-acc: #38f2c0;
--color-tbg02-acc: oklch(0.86 0.16 170);
--color-tbg02-acc2: #3aa0ff;
--color-tbg02-acc2: oklch(0.69 0.17 250);
--color-tbg02-acc3: #8a5bff;
--color-tbg02-acc3: oklch(0.6 0.23 290);
--font-tbg02-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tbg02-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* Root rule: the full-bleed contract, restated so the stage is sized before the browser build compiles. */
.tbg-02 {
width: 100%;
min-height: 100svh;
}
```How this works
Path coordinates without spaces. Tailwind turns underscores into spaces, but path data does not need either — commas are enough, so the arc reads cleanly in a class list:
<span class="[offset-path:path('M43,28C123,6,203,6,283,28')]
[offset-distance:0%] transition-[offset-distance] duration-500
group-has-[#tbg02-2:checked]/seg:[offset-distance:33.333%]">Why the geometry is fixed. The four columns are exactly 80px, so the path's endpoints land on each segment's centre. If you change the column width, recompute the x values (first centre, last centre) and keep the control at w-fit.
Reduced motion swaps the arc for a straight line and shortens the move to 200ms.
Make it yours
- Flatter arc: raise the control points' y from
6towards28. - Three segments:
grid-cols-[repeat(3,80px)], path end203,28, distances 0 / 50 / 100%. - Swap the gradient in
--color-tbg02-acc/-acc2for a single brand colour if the comet feels too playful.
Gotchas — read before shipping
- Motion-path coordinates are relative to the control's padding box — keep
relativeon the group. - Arbitrary values can't contain spaces; write path data with commas, not underscores.
- Keep the visible text on the labels: the thumb is decorative and
aria-hidden.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 116+ | 16+ | 72+ | 116+ |
offset-path: path() is widely supported; the floor is Tailwind v4's generated sheet (Chrome 111 / Safari 16.4 / Firefox 128) and :has() (Firefox 121).