12 / 20
All 20 in 20 Tailwind SVG Stroke Buttons
- 01Tailwind SVG Stroke Draw Button Border on Hover
- 02Tailwind Stroke Dashoffset Button Outline Animation
- 03Tailwind Corner Start Perimeter Draw Button
- 04Tailwind Two Path Split Border Draw Button
- 05Tailwind Rounded Rect Stroke Button with rx Radius
- 06Tailwind Dashed Marching Ants Button Border
- 07Tailwind Gradient Stroke Button with SVG linearGradient
- 08Tailwind Stroke Draw Button That Reverses on Mouse Leave
- 09Tailwind Focus Visible Stroke Outline for Keyboard Users
- 10Tailwind Non Scaling Stroke Button That Resizes with Text
- 11Tailwind Stroke Draw Button with pathLength Normalization
- 12Tailwind Dual Layer Stroke Button with Offset Trailing Path
- 13Tailwind Sequential Stroke and Label Fade Button
- 14Tailwind Icon Plus Border Stroke Draw Together
- 15Tailwind Stroke Draw Submit Button Loading State
- 16Tailwind Stroke Draw Button Disabled and Error States
- 17Tailwind Scroll Triggered Button Stroke with animation-timeline
- 18Tailwind Stroke Draw Button Group with Staggered Delay
- 19Tailwind Reduced Motion Fallback for Stroke Buttons
- 20Tailwind Variable Width Stroke Button with Text Length
Tailwind Dual Layer Stroke Button with Offset Trailing Path
A crisp leader and a blurred follower 90ms behind it, which the eye reads as speed rather than as two lines. The offset is two utilities — duration-[620ms] on the leader, duration-[800ms] delay-[90ms] on the trail — and the comet pair animates the offset negative, so a 4.5% fraction of pathLength="1" travels the path instead of a line being drawn.
Nucleo: 44,000+ SVG icons in five families · All Icons Bundle $149
Nucleo · Affiliate link
The code
<section class="svgb-12 relative block w-full min-h-svh overflow-hidden bg-svgb12-bg text-svgb12-fg font-svgb12-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-12-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded border border-current/22 bg-current/8 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-12-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="relative min-h-svh grid place-items-center p-[clamp(22px,5vw,70px)]">
<div class="flex flex-col items-start gap-[clamp(16px,3vw,26px)] w-full max-w-105">
<div class="grid grid-cols-2 gap-x-5 gap-y-2.5 w-full">
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Lap</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">14</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Delta</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums text-svgb12-good">-0.412</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Tyre</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">C3 · 62%</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">ERS</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">2.1 MJ</span></div>
</div>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:7] opacity-36 [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[800ms] delay-[90ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke [stroke-width:2] [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[620ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:transition-none motion-reduce:[stroke-dasharray:none] motion-reduce:[stroke-dashoffset:0] motion-reduce:opacity-0 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-visible:opacity-100" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Push lap</span>
</button>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:6] opacity-32 [stroke-dasharray:0.16_0.84] [stroke-dashoffset:0.16] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.84] group-focus-visible:[stroke-dashoffset:-0.84] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-fg [stroke-width:2.4] [stroke-dasharray:0.045_0.955] [stroke-dashoffset:0.045] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.955] group-focus-visible:[stroke-dashoffset:-0.955] motion-reduce:!transition-none motion-reduce:opacity-0" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Deploy overtake</span>
</button>
<p class="m-0 font-svgb12-mono text-[10.5px] tracking-[0.04em] text-svgb12-muted">leader 620ms · trail 800ms + 90ms · paint order: trail first</p>
</div>
</div>
</section><section class="svgb-12 relative block w-full min-h-svh overflow-hidden bg-svgb12-bg text-svgb12-fg font-svgb12-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-12-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded border border-current/22 bg-current/8 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-12-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="relative min-h-svh grid place-items-center p-[clamp(22px,5vw,70px)]">
<div class="flex flex-col items-start gap-[clamp(16px,3vw,26px)] w-full max-w-105">
<div class="grid grid-cols-2 gap-x-5 gap-y-2.5 w-full">
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Lap</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">14</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Delta</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums text-svgb12-good">-0.412</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Tyre</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">C3 · 62%</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">ERS</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">2.1 MJ</span></div>
</div>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:7] opacity-36 [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[800ms] delay-[90ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke [stroke-width:2] [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[620ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:transition-none motion-reduce:[stroke-dasharray:none] motion-reduce:[stroke-dashoffset:0] motion-reduce:opacity-0 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-visible:opacity-100" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Push lap</span>
</button>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:6] opacity-32 [stroke-dasharray:0.16_0.84] [stroke-dashoffset:0.16] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.84] group-focus-visible:[stroke-dashoffset:-0.84] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-fg [stroke-width:2.4] [stroke-dasharray:0.045_0.955] [stroke-dashoffset:0.045] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.955] group-focus-visible:[stroke-dashoffset:-0.955] motion-reduce:!transition-none motion-reduce:opacity-0" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Deploy overtake</span>
</button>
<p class="m-0 font-svgb12-mono text-[10.5px] tracking-[0.04em] text-svgb12-muted">leader 620ms · trail 800ms + 90ms · paint order: trail first</p>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-svgb12-bg: #08090a;
--color-svgb12-bg: oklch(0.145 0.002 250);
--color-svgb12-fg: #edeff1;
--color-svgb12-fg: oklch(0.95 0.003 250);
--color-svgb12-muted: #83878d;
--color-svgb12-muted: oklch(0.645 0.008 250);
--color-svgb12-rest: rgba(237, 239, 241, 0.14);
--color-svgb12-rest: oklch(0.95 0.003 250 / 0.14);
--color-svgb12-stroke: #00e5ff;
--color-svgb12-stroke: oklch(0.85 0.15 205);
--color-svgb12-good: #7cff8f;
--color-svgb12-good: oklch(0.89 0.18 145);
--font-svgb12-sans: 'Saira Condensed', system-ui, sans-serif;
--font-svgb12-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* screen over a dark rack, multiply over a light one: the blend mode itself is
scheme-dependent, which no utility can express as one class */
.svgb-12 {
--svgb-12-blend: screen;
}
.svgb-12::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: var(--svgb-12-weave), radial-gradient(70% 60% at 50% 40%, color-mix(in oklab, var(--color-svgb12-stroke) 8%, transparent), transparent 70%);
}
.svgb-12 {
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px);
}
.svgb-12:has(#svgb-12-theme:checked) {
--color-svgb12-bg: #f1f2f4;
--color-svgb12-bg: oklch(0.955 0.003 250);
--color-svgb12-fg: #101214;
--color-svgb12-fg: oklch(0.185 0.004 250);
--color-svgb12-muted: #555a60;
--color-svgb12-muted: oklch(0.49 0.008 250);
--color-svgb12-rest: rgba(16, 18, 20, 0.16);
--color-svgb12-rest: oklch(0.185 0.004 250 / 0.16);
--color-svgb12-stroke: #00647f;
--color-svgb12-stroke: oklch(0.45 0.11 215);
--color-svgb12-good: #0d6b2c;
--color-svgb12-good: oklch(0.46 0.14 148);
--svgb-12-blend: multiply;
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px);
}@import "tailwindcss";
@theme {
--color-svgb12-bg: #08090a;
--color-svgb12-bg: oklch(0.145 0.002 250);
--color-svgb12-fg: #edeff1;
--color-svgb12-fg: oklch(0.95 0.003 250);
--color-svgb12-muted: #83878d;
--color-svgb12-muted: oklch(0.645 0.008 250);
--color-svgb12-rest: rgba(237, 239, 241, 0.14);
--color-svgb12-rest: oklch(0.95 0.003 250 / 0.14);
--color-svgb12-stroke: #00e5ff;
--color-svgb12-stroke: oklch(0.85 0.15 205);
--color-svgb12-good: #7cff8f;
--color-svgb12-good: oklch(0.89 0.18 145);
--font-svgb12-sans: 'Saira Condensed', system-ui, sans-serif;
--font-svgb12-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* screen over a dark rack, multiply over a light one: the blend mode itself is
scheme-dependent, which no utility can express as one class */
.svgb-12 {
--svgb-12-blend: screen;
}
.svgb-12::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: var(--svgb-12-weave), radial-gradient(70% 60% at 50% 40%, color-mix(in oklab, var(--color-svgb12-stroke) 8%, transparent), transparent 70%);
}
.svgb-12 {
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px);
}
.svgb-12:has(#svgb-12-theme:checked) {
--color-svgb12-bg: #f1f2f4;
--color-svgb12-bg: oklch(0.955 0.003 250);
--color-svgb12-fg: #101214;
--color-svgb12-fg: oklch(0.185 0.004 250);
--color-svgb12-muted: #555a60;
--color-svgb12-muted: oklch(0.49 0.008 250);
--color-svgb12-rest: rgba(16, 18, 20, 0.16);
--color-svgb12-rest: oklch(0.185 0.004 250 / 0.16);
--color-svgb12-stroke: #00647f;
--color-svgb12-stroke: oklch(0.45 0.11 215);
--color-svgb12-good: #0d6b2c;
--color-svgb12-good: oklch(0.46 0.14 148);
--svgb-12-blend: multiply;
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px);
}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-svgb12-bg: #08090a;
--color-svgb12-bg: oklch(0.145 0.002 250);
--color-svgb12-fg: #edeff1;
--color-svgb12-fg: oklch(0.95 0.003 250);
--color-svgb12-muted: #83878d;
--color-svgb12-muted: oklch(0.645 0.008 250);
--color-svgb12-rest: rgba(237, 239, 241, 0.14);
--color-svgb12-rest: oklch(0.95 0.003 250 / 0.14);
--color-svgb12-stroke: #00e5ff;
--color-svgb12-stroke: oklch(0.85 0.15 205);
--color-svgb12-good: #7cff8f;
--color-svgb12-good: oklch(0.89 0.18 145);
--font-svgb12-sans: 'Saira Condensed', system-ui, sans-serif;
--font-svgb12-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* screen over a dark rack, multiply over a light one: the blend mode itself is
scheme-dependent, which no utility can express as one class */
.svgb-12 {
--svgb-12-blend: screen;
}
.svgb-12::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: var(--svgb-12-weave), radial-gradient(70% 60% at 50% 40%, color-mix(in oklab, var(--color-svgb12-stroke) 8%, transparent), transparent 70%);
}
.svgb-12 {
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px);
}
.svgb-12:has(#svgb-12-theme:checked) {
--color-svgb12-bg: #f1f2f4;
--color-svgb12-bg: oklch(0.955 0.003 250);
--color-svgb12-fg: #101214;
--color-svgb12-fg: oklch(0.185 0.004 250);
--color-svgb12-muted: #555a60;
--color-svgb12-muted: oklch(0.49 0.008 250);
--color-svgb12-rest: rgba(16, 18, 20, 0.16);
--color-svgb12-rest: oklch(0.185 0.004 250 / 0.16);
--color-svgb12-stroke: #00647f;
--color-svgb12-stroke: oklch(0.45 0.11 215);
--color-svgb12-good: #0d6b2c;
--color-svgb12-good: oklch(0.46 0.14 148);
--svgb-12-blend: multiply;
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px);
}@import "tailwindcss";
@theme {
--color-svgb12-bg: #08090a;
--color-svgb12-bg: oklch(0.145 0.002 250);
--color-svgb12-fg: #edeff1;
--color-svgb12-fg: oklch(0.95 0.003 250);
--color-svgb12-muted: #83878d;
--color-svgb12-muted: oklch(0.645 0.008 250);
--color-svgb12-rest: rgba(237, 239, 241, 0.14);
--color-svgb12-rest: oklch(0.95 0.003 250 / 0.14);
--color-svgb12-stroke: #00e5ff;
--color-svgb12-stroke: oklch(0.85 0.15 205);
--color-svgb12-good: #7cff8f;
--color-svgb12-good: oklch(0.89 0.18 145);
--font-svgb12-sans: 'Saira Condensed', system-ui, sans-serif;
--font-svgb12-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* screen over a dark rack, multiply over a light one: the blend mode itself is
scheme-dependent, which no utility can express as one class */
.svgb-12 {
--svgb-12-blend: screen;
}
.svgb-12::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: var(--svgb-12-weave), radial-gradient(70% 60% at 50% 40%, color-mix(in oklab, var(--color-svgb12-stroke) 8%, transparent), transparent 70%);
}
.svgb-12 {
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px);
}
.svgb-12:has(#svgb-12-theme:checked) {
--color-svgb12-bg: #f1f2f4;
--color-svgb12-bg: oklch(0.955 0.003 250);
--color-svgb12-fg: #101214;
--color-svgb12-fg: oklch(0.185 0.004 250);
--color-svgb12-muted: #555a60;
--color-svgb12-muted: oklch(0.49 0.008 250);
--color-svgb12-rest: rgba(16, 18, 20, 0.16);
--color-svgb12-rest: oklch(0.185 0.004 250 / 0.16);
--color-svgb12-stroke: #00647f;
--color-svgb12-stroke: oklch(0.45 0.11 215);
--color-svgb12-good: #0d6b2c;
--color-svgb12-good: oklch(0.46 0.14 148);
--svgb-12-blend: multiply;
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px);
}<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=Saira+Condensed:wght@400;600;700&family=JetBrains+Mono:wght@400;500&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=Saira+Condensed:wght@400;600;700&family=JetBrains+Mono:wght@400;500&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The webfonts load as
<link>tags insetup, not as an@importinside the stylesheet. Tailwind emits user@importrules after its own@layerblocks, and a late@importis invalid CSS — the browser drops it and the demo silently falls back to system fonts. - Paint order is document order in SVG —
z-indexdoes nothing here — so the soft trail is written before the crisp leader in the markup, and no utility can rescue a wrong order. - The offset between the two layers is two utilities: the leader gets
duration-[620ms], the trailduration-[800ms] delay-[90ms]. That 90ms is the whole sense of a wake. - The comet pair animates the offset negative —
group-hover:[stroke-dashoffset:-0.84]— so a fractional segment travels the path instead of a line being drawn. - Both segments are fractions of
pathLength="1":[stroke-dasharray:0.045_0.955]is a 4.5% spark on any perimeter. [mix-blend-mode:var(--svgb-12-blend)]reads a variable because the correct blend flips with the scheme — screen on the dark rack, multiply on the light one.- The glow uses
text-svgb12-strokeplusdrop-shadow(...currentColor), which is how you tint an SVG filter from a token without repeating the colour.
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 Dual Layer Stroke Button with Offset Trailing Path
Source: https://codefronts.com/components/tailwind-svg-stroke-buttons/tailwind-dual-layer-stroke-button-with-offset-trailing-path/
A crisp leader and a blurred follower 90ms behind it, which the eye reads as speed rather than as two lines. The offset is two utilities — duration-[620ms] on the leader, duration-[800ms] delay-[90ms] on the trail — and the comet pair animates the offset negative, so a 4.5% fraction of pathLength="1" travels the path instead of a line being drawn.
## HTML
```html
<section class="svgb-12 relative block w-full min-h-svh overflow-hidden bg-svgb12-bg text-svgb12-fg font-svgb12-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-12-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded border border-current/22 bg-current/8 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-12-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="relative min-h-svh grid place-items-center p-[clamp(22px,5vw,70px)]">
<div class="flex flex-col items-start gap-[clamp(16px,3vw,26px)] w-full max-w-105">
<div class="grid grid-cols-2 gap-x-5 gap-y-2.5 w-full">
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Lap</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">14</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Delta</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums text-svgb12-good">-0.412</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Tyre</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">C3 · 62%</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">ERS</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">2.1 MJ</span></div>
</div>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:7] opacity-36 [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[800ms] delay-[90ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke [stroke-width:2] [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[620ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:transition-none motion-reduce:[stroke-dasharray:none] motion-reduce:[stroke-dashoffset:0] motion-reduce:opacity-0 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-visible:opacity-100" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Push lap</span>
</button>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:6] opacity-32 [stroke-dasharray:0.16_0.84] [stroke-dashoffset:0.16] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.84] group-focus-visible:[stroke-dashoffset:-0.84] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-fg [stroke-width:2.4] [stroke-dasharray:0.045_0.955] [stroke-dashoffset:0.045] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.955] group-focus-visible:[stroke-dashoffset:-0.955] motion-reduce:!transition-none motion-reduce:opacity-0" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Deploy overtake</span>
</button>
<p class="m-0 font-svgb12-mono text-[10.5px] tracking-[0.04em] text-svgb12-muted">leader 620ms · trail 800ms + 90ms · paint order: trail first</p>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-svgb12-bg: #08090a;
--color-svgb12-bg: oklch(0.145 0.002 250);
--color-svgb12-fg: #edeff1;
--color-svgb12-fg: oklch(0.95 0.003 250);
--color-svgb12-muted: #83878d;
--color-svgb12-muted: oklch(0.645 0.008 250);
--color-svgb12-rest: rgba(237, 239, 241, 0.14);
--color-svgb12-rest: oklch(0.95 0.003 250 / 0.14);
--color-svgb12-stroke: #00e5ff;
--color-svgb12-stroke: oklch(0.85 0.15 205);
--color-svgb12-good: #7cff8f;
--color-svgb12-good: oklch(0.89 0.18 145);
--font-svgb12-sans: 'Saira Condensed', system-ui, sans-serif;
--font-svgb12-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* screen over a dark rack, multiply over a light one: the blend mode itself is
scheme-dependent, which no utility can express as one class */
.svgb-12 {
--svgb-12-blend: screen;
}
.svgb-12::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: var(--svgb-12-weave), radial-gradient(70% 60% at 50% 40%, color-mix(in oklab, var(--color-svgb12-stroke) 8%, transparent), transparent 70%);
}
.svgb-12 {
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px);
}
.svgb-12:has(#svgb-12-theme:checked) {
--color-svgb12-bg: #f1f2f4;
--color-svgb12-bg: oklch(0.955 0.003 250);
--color-svgb12-fg: #101214;
--color-svgb12-fg: oklch(0.185 0.004 250);
--color-svgb12-muted: #555a60;
--color-svgb12-muted: oklch(0.49 0.008 250);
--color-svgb12-rest: rgba(16, 18, 20, 0.16);
--color-svgb12-rest: oklch(0.185 0.004 250 / 0.16);
--color-svgb12-stroke: #00647f;
--color-svgb12-stroke: oklch(0.45 0.11 215);
--color-svgb12-good: #0d6b2c;
--color-svgb12-good: oklch(0.46 0.14 148);
--svgb-12-blend: multiply;
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px);
}
```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 Dual Layer Stroke Button with Offset Trailing Path
Source: https://codefronts.com/components/tailwind-svg-stroke-buttons/tailwind-dual-layer-stroke-button-with-offset-trailing-path/
A crisp leader and a blurred follower 90ms behind it, which the eye reads as speed rather than as two lines. The offset is two utilities — duration-[620ms] on the leader, duration-[800ms] delay-[90ms] on the trail — and the comet pair animates the offset negative, so a 4.5% fraction of pathLength="1" travels the path instead of a line being drawn.
## HTML
```html
<section class="svgb-12 relative block w-full min-h-svh overflow-hidden bg-svgb12-bg text-svgb12-fg font-svgb12-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-12-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded border border-current/22 bg-current/8 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-12-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="relative min-h-svh grid place-items-center p-[clamp(22px,5vw,70px)]">
<div class="flex flex-col items-start gap-[clamp(16px,3vw,26px)] w-full max-w-105">
<div class="grid grid-cols-2 gap-x-5 gap-y-2.5 w-full">
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Lap</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">14</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Delta</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums text-svgb12-good">-0.412</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">Tyre</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">C3 · 62%</span></div>
<div class="flex flex-col gap-0.5 pb-2 border-b border-svgb12-rest"><span class="font-svgb12-mono text-[9.5px] tracking-[0.22em] uppercase text-svgb12-muted">ERS</span><span class="text-[26px] font-bold italic tracking-[-0.01em] tabular-nums">2.1 MJ</span></div>
</div>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:7] opacity-36 [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[800ms] delay-[90ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke [stroke-width:2] [stroke-dasharray:1] [stroke-dashoffset:1] transition-[stroke-dashoffset] duration-[620ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[stroke-dashoffset:0] group-focus-visible:[stroke-dashoffset:0] motion-reduce:transition-none motion-reduce:[stroke-dasharray:none] motion-reduce:[stroke-dashoffset:0] motion-reduce:opacity-0 motion-reduce:group-hover:opacity-100 motion-reduce:group-focus-visible:opacity-100" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Push lap</span>
</button>
<button class="group relative w-[min(340px,92vw)] h-[78px] grid place-items-center border-0 p-0 bg-transparent isolate text-xl font-semibold italic tracking-[0.1em] uppercase cursor-pointer focus-visible:outline-none focus-visible:shadow-[0_0_0_3px_color-mix(in_oklab,var(--color-svgb12-stroke)_34%,transparent)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 340 78" aria-hidden="true">
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-rest [stroke-width:1.4]" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-stroke text-svgb12-stroke [filter:drop-shadow(0_0_10px_currentColor)] [mix-blend-mode:var(--svgb-12-blend)] motion-reduce:!filter-none motion-reduce:opacity-0 [stroke-width:6] opacity-32 [stroke-dasharray:0.16_0.84] [stroke-dashoffset:0.16] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.84] group-focus-visible:[stroke-dashoffset:-0.84] motion-reduce:!transition-none" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
<path class="fill-none [stroke-linejoin:miter] stroke-svgb12-fg [stroke-width:2.4] [stroke-dasharray:0.045_0.955] [stroke-dashoffset:0.045] transition-[stroke-dashoffset] duration-[900ms] ease-linear group-hover:[stroke-dashoffset:-0.955] group-focus-visible:[stroke-dashoffset:-0.955] motion-reduce:!transition-none motion-reduce:opacity-0" d="M26 3H337L314 75H3Z" pathLength="1" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative z-[2] transition-[color,letter-spacing] duration-[400ms] motion-reduce:transition-none group-hover:text-svgb12-stroke group-hover:tracking-[0.16em] group-focus-visible:text-svgb12-stroke group-focus-visible:tracking-[0.16em]">Deploy overtake</span>
</button>
<p class="m-0 font-svgb12-mono text-[10.5px] tracking-[0.04em] text-svgb12-muted">leader 620ms · trail 800ms + 90ms · paint order: trail first</p>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-svgb12-bg: #08090a;
--color-svgb12-bg: oklch(0.145 0.002 250);
--color-svgb12-fg: #edeff1;
--color-svgb12-fg: oklch(0.95 0.003 250);
--color-svgb12-muted: #83878d;
--color-svgb12-muted: oklch(0.645 0.008 250);
--color-svgb12-rest: rgba(237, 239, 241, 0.14);
--color-svgb12-rest: oklch(0.95 0.003 250 / 0.14);
--color-svgb12-stroke: #00e5ff;
--color-svgb12-stroke: oklch(0.85 0.15 205);
--color-svgb12-good: #7cff8f;
--color-svgb12-good: oklch(0.89 0.18 145);
--font-svgb12-sans: 'Saira Condensed', system-ui, sans-serif;
--font-svgb12-mono: 'JetBrains Mono', ui-monospace, monospace;
}
/* screen over a dark rack, multiply over a light one: the blend mode itself is
scheme-dependent, which no utility can express as one class */
.svgb-12 {
--svgb-12-blend: screen;
}
.svgb-12::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: var(--svgb-12-weave), radial-gradient(70% 60% at 50% 40%, color-mix(in oklab, var(--color-svgb12-stroke) 8%, transparent), transparent 70%);
}
.svgb-12 {
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(1 0 0 / 0.022) 0 2px, transparent 2px 5px);
}
.svgb-12:has(#svgb-12-theme:checked) {
--color-svgb12-bg: #f1f2f4;
--color-svgb12-bg: oklch(0.955 0.003 250);
--color-svgb12-fg: #101214;
--color-svgb12-fg: oklch(0.185 0.004 250);
--color-svgb12-muted: #555a60;
--color-svgb12-muted: oklch(0.49 0.008 250);
--color-svgb12-rest: rgba(16, 18, 20, 0.16);
--color-svgb12-rest: oklch(0.185 0.004 250 / 0.16);
--color-svgb12-stroke: #00647f;
--color-svgb12-stroke: oklch(0.45 0.11 215);
--color-svgb12-good: #0d6b2c;
--color-svgb12-good: oklch(0.46 0.14 148);
--svgb-12-blend: multiply;
--svgb-12-weave: repeating-linear-gradient(45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px), repeating-linear-gradient(-45deg, oklch(0 0 0 / 0.03) 0 2px, transparent 2px 5px);
}
```How this works
Two layers, one gap that opens and closes. The leader finishes first; the trail is both slower and later, so the distance between them grows through the middle of the draw and closes at the end:
<!-- written FIRST: the soft trail -->
class="[stroke-width:9] [filter:blur(6px)]
duration-[800ms] delay-[90ms]"
<!-- written SECOND: the crisp leader -->
class="[stroke-width:2] duration-[620ms]"Order is structural here. SVG paints in document order and ignores z-index entirely, so the trail must appear earlier in the markup. This is the one thing in the port that utilities cannot express — it is a decision about where an element lives, not what class it has.
Negative offsets travel; positive offsets draw. The comet spark is a short dash with a long gap. Animating its offset to a negative value slides that dash forward along the path forever, rather than revealing a line from a start point. Same two properties, completely different read.
class="[stroke-dasharray:0.045_0.955]
group-hover:[stroke-dashoffset:-0.84]"Fractions, because the path is normalised. With pathLength="1", 0.045 is 4.5% of the perimeter whatever the blade's actual size. The skew and the geometry can change without touching the spark.
The blend has to flip. A glow that screens beautifully on carbon black turns to mud on a light panel, where multiply is correct. Blend mode is therefore a variable rather than a utility, read inline with [mix-blend-mode:var(--svgb-12-blend)] — one of the few cases where the right value genuinely depends on the scheme.
Make it yours
- Tune the lag with
delay-[90ms]. Below about 50ms the two layers read as one thick line; past 150ms they read as two separate strokes. - Widen the wake by raising the trail's stroke width and blur together — blur alone just makes it faint.
- Lengthen the spark with the first number in
[stroke-dasharray:0.045_0.955]; keep the pair summing to 1. - Reverse the comet by flipping the sign on its target offset.
- Remove the blur layer entirely for a flat motorsport look; the skewed blade and the negative-offset spark carry it.
Gotchas — read before shipping
z-indexdoes nothing in SVG. If the trail paints over the leader, the fix is moving the element, not adding a class.- A blurred stroke needs room: without
overflow-visibleon the SVG the wake is clipped at the viewBox edge. - The trail must be both slower and delayed. Delay alone makes it arrive late rather than lag behind.
- Fractional dash values require the path to carry
pathLength="1"; without it, 0.045 is 4.5 hundredths of a user unit and effectively invisible. mix-blend-modeblends against whatever is behind it in the stacking context, so a blend inside a transformed or filtered ancestor can behave unexpectedly.- Blur filters are the most expensive thing in this collection to paint. One wake on one hero control is fine; a grid of them is not.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Blur filters, blend modes and dash animation are all long-standing. The floor is Tailwind v4's generated sheet. Note that mix-blend-mode on SVG children is correct everywhere current but historically inconsistent in older WebKit, which is why the value is a variable you can set to normal.