18 / 30
All 30 in 30 Tailwind CSS Grid Layouts
- 01Tailwind Full-Bleed Article Layout for Long-Form Editorial
- 02Tailwind Docs Layout with Sticky Table of Contents
- 03Tailwind Photo Gallery Grid with auto-fill and Real Images
- 04Tailwind Holy Grail Page Layout for a News Site
- 05Tailwind Data Table with Subgrid Rows and Status Pills
- 06Tailwind Overlapping Card Hero for a Case Study
- 07Tailwind Help Center Layout with Fixed Sidebars
- 08Tailwind 12 Column Grid System for Marketing Pages
- 09Tailwind Bento Grid for a Product Feature Section
- 10Tailwind Magazine Spread Layout with Overlapping Headline
- 11Tailwind Responsive Card Grid for an Integrations Directory
- 12Tailwind CMS Category Grid that Compacts Itself with has()
- 13Tailwind Masonry Layout for a Saved Ideas Board
- 14Tailwind Hexagon Team Grid with clip-path Avatars
- 15Tailwind Subgrid Cards with Perfectly Aligned Buttons
- 16Tailwind Analytics Dashboard Layout with Grid App Shell
- 17Tailwind Pricing Table with Subgrid and a Featured Plan
- 18Tailwind Kanban Board with Scroll Snap Columns
- 19Tailwind Video Thumbnail Grid with Zero Layout Shift
- 20Tailwind Container Query Card for Reusable Article Teasers
- 21Tailwind Diagonal Section Band with skewY Counter-Skew
- 22Tailwind Asymmetric Poster Hero with Layered Grid Regions
- 23Tailwind Mosaic Photo Wall with a Designed Span Sequence
- 24Tailwind Dense Grid Packing for a Mixed-Size Asset Library
- 25Tailwind Onboarding Stepper with CSS Counters
- 26Tailwind macOS Window Layout with Vibrancy Sidebar
- 27Tailwind Scroll Snap Carousel with Peeking Slides
- 28Tailwind Status Map UI with Grid Coordinate Pins
- 29Tailwind Logo Wall with 1px Gap Hairline Dividers
- 30Tailwind Periodic Table Layout with Grid Coordinates
Tailwind Kanban Board with Scroll Snap Columns
A sprint board with avatars, labels, estimate chips and WIP limits. Columns are implicit — append a <section> and you have a new list — and each stack scrolls under its own pinned header.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tgx-18 w-full min-h-svh bg-tgx18-bg font-tgx18-sans p-5">
<header class="flex items-end justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx18-dim">Sprint 42 · ends Friday</p>
<h2 class="text-[1.25rem] font-semibold text-tgx18-ink tracking-[-0.01em]">Platform board</h2>
</div>
<div class="flex -space-x-2" aria-label="4 assignees on this board">
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a1 text-tgx18-bg ring-2 ring-tgx18-bg">AR</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a2 text-tgx18-bg ring-2 ring-tgx18-bg">TK</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a3 text-tgx18-bg ring-2 ring-tgx18-bg">MC</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-card text-tgx18-dim ring-2 ring-tgx18-bg">+5</span>
</div>
</header>
<div role="list" aria-label="Board columns" class="grid grid-flow-col auto-cols-[clamp(240px,28vw,300px)] gap-3 h-[360px] overflow-x-auto overscroll-x-contain snap-x snap-proximity scroll-pl-1 pb-2">
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Backlog</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">4</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Refactor token refresh flow</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Empty states for the board view</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Rate-limit webhook retries</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
<article style="--p:oklch(0.84 0.13 85)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Quickstart rewrite</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Docs</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In progress</h3><span class="text-[0.66rem] tabular-nums text-tgx18-warn bg-tgx18-warntint rounded-full px-2 py-0.5">2 / 2 WIP</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.76 0.17 25)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Dunning emails firing twice</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Urgent</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Grid layout collection, v2</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">13pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In review</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">1</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Subgrid pricing table</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Done</h3><span class="text-[0.66rem] tabular-nums text-tgx18-ok bg-tgx18-oktint rounded-full px-2 py-0.5">3</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Dark mode tokens</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Design</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Onboarding checklist</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Growth</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">CDN migration</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Infra</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span></div></article>
</div>
</section>
</div>
</section><section class="tgx-18 w-full min-h-svh bg-tgx18-bg font-tgx18-sans p-5">
<header class="flex items-end justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx18-dim">Sprint 42 · ends Friday</p>
<h2 class="text-[1.25rem] font-semibold text-tgx18-ink tracking-[-0.01em]">Platform board</h2>
</div>
<div class="flex -space-x-2" aria-label="4 assignees on this board">
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a1 text-tgx18-bg ring-2 ring-tgx18-bg">AR</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a2 text-tgx18-bg ring-2 ring-tgx18-bg">TK</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a3 text-tgx18-bg ring-2 ring-tgx18-bg">MC</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-card text-tgx18-dim ring-2 ring-tgx18-bg">+5</span>
</div>
</header>
<div role="list" aria-label="Board columns" class="grid grid-flow-col auto-cols-[clamp(240px,28vw,300px)] gap-3 h-[360px] overflow-x-auto overscroll-x-contain snap-x snap-proximity scroll-pl-1 pb-2">
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Backlog</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">4</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Refactor token refresh flow</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Empty states for the board view</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Rate-limit webhook retries</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
<article style="--p:oklch(0.84 0.13 85)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Quickstart rewrite</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Docs</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In progress</h3><span class="text-[0.66rem] tabular-nums text-tgx18-warn bg-tgx18-warntint rounded-full px-2 py-0.5">2 / 2 WIP</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.76 0.17 25)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Dunning emails firing twice</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Urgent</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Grid layout collection, v2</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">13pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In review</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">1</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Subgrid pricing table</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Done</h3><span class="text-[0.66rem] tabular-nums text-tgx18-ok bg-tgx18-oktint rounded-full px-2 py-0.5">3</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Dark mode tokens</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Design</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Onboarding checklist</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Growth</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">CDN migration</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Infra</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span></div></article>
</div>
</section>
</div>
</section>@import "tailwindcss";
@theme {
--color-tgx18-bg: #1c1e2a;
--color-tgx18-bg: oklch(0.21 0.02 270);
--color-tgx18-col: #232634;
--color-tgx18-col: oklch(0.25 0.025 270);
--color-tgx18-card: #2b2f3f;
--color-tgx18-card: oklch(0.3 0.025 270);
--color-tgx18-line: #3a3f52;
--color-tgx18-line: oklch(0.38 0.03 270);
--color-tgx18-hover: #5b6280;
--color-tgx18-hover: oklch(0.55 0.05 270);
--color-tgx18-ink: #e9eaf1;
--color-tgx18-ink: oklch(0.93 0.01 270);
--color-tgx18-dim: #a8acbd;
--color-tgx18-dim: oklch(0.74 0.02 270);
--color-tgx18-done: #767b91;
--color-tgx18-done: oklch(0.6 0.02 270);
--color-tgx18-ok: #8ce0ae;
--color-tgx18-ok: oklch(0.85 0.14 150);
--color-tgx18-oktint: #29382f;
--color-tgx18-oktint: oklch(0.31 0.04 150);
--color-tgx18-warn: #f0cc72;
--color-tgx18-warn: oklch(0.86 0.14 85);
--color-tgx18-warntint: #3a3423;
--color-tgx18-warntint: oklch(0.32 0.04 85);
--color-tgx18-a1: #8ab4f8;
--color-tgx18-a1: oklch(0.78 0.11 250);
--color-tgx18-a2: #f0a68a;
--color-tgx18-a2: oklch(0.79 0.12 40);
--color-tgx18-a3: #9ee0c0;
--color-tgx18-a3: oklch(0.86 0.11 160);
--font-tgx18-sans: 'Inter Tight', system-ui, sans-serif;
}
.tgx-18 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tgx18-bg: #1c1e2a;
--color-tgx18-bg: oklch(0.21 0.02 270);
--color-tgx18-col: #232634;
--color-tgx18-col: oklch(0.25 0.025 270);
--color-tgx18-card: #2b2f3f;
--color-tgx18-card: oklch(0.3 0.025 270);
--color-tgx18-line: #3a3f52;
--color-tgx18-line: oklch(0.38 0.03 270);
--color-tgx18-hover: #5b6280;
--color-tgx18-hover: oklch(0.55 0.05 270);
--color-tgx18-ink: #e9eaf1;
--color-tgx18-ink: oklch(0.93 0.01 270);
--color-tgx18-dim: #a8acbd;
--color-tgx18-dim: oklch(0.74 0.02 270);
--color-tgx18-done: #767b91;
--color-tgx18-done: oklch(0.6 0.02 270);
--color-tgx18-ok: #8ce0ae;
--color-tgx18-ok: oklch(0.85 0.14 150);
--color-tgx18-oktint: #29382f;
--color-tgx18-oktint: oklch(0.31 0.04 150);
--color-tgx18-warn: #f0cc72;
--color-tgx18-warn: oklch(0.86 0.14 85);
--color-tgx18-warntint: #3a3423;
--color-tgx18-warntint: oklch(0.32 0.04 85);
--color-tgx18-a1: #8ab4f8;
--color-tgx18-a1: oklch(0.78 0.11 250);
--color-tgx18-a2: #f0a68a;
--color-tgx18-a2: oklch(0.79 0.12 40);
--color-tgx18-a3: #9ee0c0;
--color-tgx18-a3: oklch(0.86 0.11 160);
--font-tgx18-sans: 'Inter Tight', system-ui, sans-serif;
}
.tgx-18 {
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-tgx18-bg: #1c1e2a;
--color-tgx18-bg: oklch(0.21 0.02 270);
--color-tgx18-col: #232634;
--color-tgx18-col: oklch(0.25 0.025 270);
--color-tgx18-card: #2b2f3f;
--color-tgx18-card: oklch(0.3 0.025 270);
--color-tgx18-line: #3a3f52;
--color-tgx18-line: oklch(0.38 0.03 270);
--color-tgx18-hover: #5b6280;
--color-tgx18-hover: oklch(0.55 0.05 270);
--color-tgx18-ink: #e9eaf1;
--color-tgx18-ink: oklch(0.93 0.01 270);
--color-tgx18-dim: #a8acbd;
--color-tgx18-dim: oklch(0.74 0.02 270);
--color-tgx18-done: #767b91;
--color-tgx18-done: oklch(0.6 0.02 270);
--color-tgx18-ok: #8ce0ae;
--color-tgx18-ok: oklch(0.85 0.14 150);
--color-tgx18-oktint: #29382f;
--color-tgx18-oktint: oklch(0.31 0.04 150);
--color-tgx18-warn: #f0cc72;
--color-tgx18-warn: oklch(0.86 0.14 85);
--color-tgx18-warntint: #3a3423;
--color-tgx18-warntint: oklch(0.32 0.04 85);
--color-tgx18-a1: #8ab4f8;
--color-tgx18-a1: oklch(0.78 0.11 250);
--color-tgx18-a2: #f0a68a;
--color-tgx18-a2: oklch(0.79 0.12 40);
--color-tgx18-a3: #9ee0c0;
--color-tgx18-a3: oklch(0.86 0.11 160);
--font-tgx18-sans: 'Inter Tight', system-ui, sans-serif;
}
.tgx-18 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tgx18-bg: #1c1e2a;
--color-tgx18-bg: oklch(0.21 0.02 270);
--color-tgx18-col: #232634;
--color-tgx18-col: oklch(0.25 0.025 270);
--color-tgx18-card: #2b2f3f;
--color-tgx18-card: oklch(0.3 0.025 270);
--color-tgx18-line: #3a3f52;
--color-tgx18-line: oklch(0.38 0.03 270);
--color-tgx18-hover: #5b6280;
--color-tgx18-hover: oklch(0.55 0.05 270);
--color-tgx18-ink: #e9eaf1;
--color-tgx18-ink: oklch(0.93 0.01 270);
--color-tgx18-dim: #a8acbd;
--color-tgx18-dim: oklch(0.74 0.02 270);
--color-tgx18-done: #767b91;
--color-tgx18-done: oklch(0.6 0.02 270);
--color-tgx18-ok: #8ce0ae;
--color-tgx18-ok: oklch(0.85 0.14 150);
--color-tgx18-oktint: #29382f;
--color-tgx18-oktint: oklch(0.31 0.04 150);
--color-tgx18-warn: #f0cc72;
--color-tgx18-warn: oklch(0.86 0.14 85);
--color-tgx18-warntint: #3a3423;
--color-tgx18-warntint: oklch(0.32 0.04 85);
--color-tgx18-a1: #8ab4f8;
--color-tgx18-a1: oklch(0.78 0.11 250);
--color-tgx18-a2: #f0a68a;
--color-tgx18-a2: oklch(0.79 0.12 40);
--color-tgx18-a3: #9ee0c0;
--color-tgx18-a3: oklch(0.86 0.11 160);
--font-tgx18-sans: 'Inter Tight', system-ui, sans-serif;
}
.tgx-18 {
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=Inter+Tight:wght@400;500;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=Inter+Tight:wght@400;500;600&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The WIP-limit pill on the in-progress column is the detail that makes a board look real, and it costs one token swap on the existing count pill.
- Every card is a two-row flex: title, then a metadata row with label, estimate and assignee. Repeating that shape is what makes a board scannable at a glance.
- Product upgrade: bare task strings became sprint tickets with labels, point estimates and assignee avatars, the header gained a stacked avatar group, and done cards keep readable ink with a strike rather than fading to 55% opacity.
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 Kanban Board with Scroll Snap Columns
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-kanban-board-scroll-snap-columns/
A sprint board with avatars, labels, estimate chips and WIP limits. Columns are implicit — append a <section> and you have a new list — and each stack scrolls under its own pinned header.
## HTML
```html
<section class="tgx-18 w-full min-h-svh bg-tgx18-bg font-tgx18-sans p-5">
<header class="flex items-end justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx18-dim">Sprint 42 · ends Friday</p>
<h2 class="text-[1.25rem] font-semibold text-tgx18-ink tracking-[-0.01em]">Platform board</h2>
</div>
<div class="flex -space-x-2" aria-label="4 assignees on this board">
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a1 text-tgx18-bg ring-2 ring-tgx18-bg">AR</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a2 text-tgx18-bg ring-2 ring-tgx18-bg">TK</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a3 text-tgx18-bg ring-2 ring-tgx18-bg">MC</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-card text-tgx18-dim ring-2 ring-tgx18-bg">+5</span>
</div>
</header>
<div role="list" aria-label="Board columns" class="grid grid-flow-col auto-cols-[clamp(240px,28vw,300px)] gap-3 h-[360px] overflow-x-auto overscroll-x-contain snap-x snap-proximity scroll-pl-1 pb-2">
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Backlog</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">4</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Refactor token refresh flow</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Empty states for the board view</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Rate-limit webhook retries</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
<article style="--p:oklch(0.84 0.13 85)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Quickstart rewrite</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Docs</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In progress</h3><span class="text-[0.66rem] tabular-nums text-tgx18-warn bg-tgx18-warntint rounded-full px-2 py-0.5">2 / 2 WIP</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.76 0.17 25)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Dunning emails firing twice</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Urgent</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Grid layout collection, v2</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">13pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In review</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">1</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Subgrid pricing table</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Done</h3><span class="text-[0.66rem] tabular-nums text-tgx18-ok bg-tgx18-oktint rounded-full px-2 py-0.5">3</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Dark mode tokens</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Design</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Onboarding checklist</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Growth</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">CDN migration</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Infra</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span></div></article>
</div>
</section>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgx18-bg: #1c1e2a;
--color-tgx18-bg: oklch(0.21 0.02 270);
--color-tgx18-col: #232634;
--color-tgx18-col: oklch(0.25 0.025 270);
--color-tgx18-card: #2b2f3f;
--color-tgx18-card: oklch(0.3 0.025 270);
--color-tgx18-line: #3a3f52;
--color-tgx18-line: oklch(0.38 0.03 270);
--color-tgx18-hover: #5b6280;
--color-tgx18-hover: oklch(0.55 0.05 270);
--color-tgx18-ink: #e9eaf1;
--color-tgx18-ink: oklch(0.93 0.01 270);
--color-tgx18-dim: #a8acbd;
--color-tgx18-dim: oklch(0.74 0.02 270);
--color-tgx18-done: #767b91;
--color-tgx18-done: oklch(0.6 0.02 270);
--color-tgx18-ok: #8ce0ae;
--color-tgx18-ok: oklch(0.85 0.14 150);
--color-tgx18-oktint: #29382f;
--color-tgx18-oktint: oklch(0.31 0.04 150);
--color-tgx18-warn: #f0cc72;
--color-tgx18-warn: oklch(0.86 0.14 85);
--color-tgx18-warntint: #3a3423;
--color-tgx18-warntint: oklch(0.32 0.04 85);
--color-tgx18-a1: #8ab4f8;
--color-tgx18-a1: oklch(0.78 0.11 250);
--color-tgx18-a2: #f0a68a;
--color-tgx18-a2: oklch(0.79 0.12 40);
--color-tgx18-a3: #9ee0c0;
--color-tgx18-a3: oklch(0.86 0.11 160);
--font-tgx18-sans: 'Inter Tight', system-ui, sans-serif;
}
.tgx-18 {
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 Kanban Board with Scroll Snap Columns
Source: https://codefronts.com/layouts/tailwind-css-grid-layouts/tailwind-kanban-board-scroll-snap-columns/
A sprint board with avatars, labels, estimate chips and WIP limits. Columns are implicit — append a <section> and you have a new list — and each stack scrolls under its own pinned header.
## HTML
```html
<section class="tgx-18 w-full min-h-svh bg-tgx18-bg font-tgx18-sans p-5">
<header class="flex items-end justify-between gap-4 flex-wrap mb-4">
<div class="flex flex-col gap-1">
<p class="text-[0.66rem] tracking-[0.18em] uppercase text-tgx18-dim">Sprint 42 · ends Friday</p>
<h2 class="text-[1.25rem] font-semibold text-tgx18-ink tracking-[-0.01em]">Platform board</h2>
</div>
<div class="flex -space-x-2" aria-label="4 assignees on this board">
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a1 text-tgx18-bg ring-2 ring-tgx18-bg">AR</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a2 text-tgx18-bg ring-2 ring-tgx18-bg">TK</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-a3 text-tgx18-bg ring-2 ring-tgx18-bg">MC</span>
<span class="size-7 rounded-full grid place-items-center text-[0.62rem] font-semibold bg-tgx18-card text-tgx18-dim ring-2 ring-tgx18-bg">+5</span>
</div>
</header>
<div role="list" aria-label="Board columns" class="grid grid-flow-col auto-cols-[clamp(240px,28vw,300px)] gap-3 h-[360px] overflow-x-auto overscroll-x-contain snap-x snap-proximity scroll-pl-1 pb-2">
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Backlog</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">4</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Refactor token refresh flow</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Empty states for the board view</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Rate-limit webhook retries</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
<article style="--p:oklch(0.84 0.13 85)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Quickstart rewrite</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Docs</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In progress</h3><span class="text-[0.66rem] tabular-nums text-tgx18-warn bg-tgx18-warntint rounded-full px-2 py-0.5">2 / 2 WIP</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.76 0.17 25)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Dunning emails firing twice</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Urgent</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a1 text-tgx18-bg">AR</span></span></div></article>
<article style="--p:oklch(0.82 0.13 150)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Grid layout collection, v2</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">Design</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">13pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a3 text-tgx18-bg">MC</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">In review</h3><span class="text-[0.66rem] tabular-nums text-tgx18-dim bg-tgx18-bg rounded-full px-2 py-0.5">1</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article style="--p:oklch(0.78 0.12 250)" class="rounded-lg border border-tgx18-line border-l-[3px] border-l-[var(--p)] bg-tgx18-card p-3 flex flex-col gap-2 transition-colors hover:border-tgx18-hover"><p class="text-[0.8rem] leading-[1.4] text-tgx18-ink">Subgrid pricing table</p><div class="flex items-center justify-between gap-2"><em class="not-italic text-[0.62rem] tracking-[0.04em] text-[var(--p)] bg-[color-mix(in_oklab,var(--p)_18%,transparent)] rounded px-1.5 py-0.5">API</em><span class="flex items-center gap-1.5"><span class="text-[0.62rem] tabular-nums text-tgx18-dim">5pt</span><span class="size-5 rounded-full grid place-items-center text-[0.55rem] font-semibold bg-tgx18-a2 text-tgx18-bg">TK</span></span></div></article>
</div>
</section>
<section role="listitem" class="snap-start grid grid-rows-[auto_minmax(0,1fr)] rounded-2xl border border-tgx18-line bg-tgx18-col overflow-hidden">
<header class="flex justify-between items-center px-3.5 py-3 border-b border-tgx18-line"><h3 class="text-[0.82rem] font-semibold text-tgx18-ink">Done</h3><span class="text-[0.66rem] tabular-nums text-tgx18-ok bg-tgx18-oktint rounded-full px-2 py-0.5">3</span></header>
<div class="overflow-y-auto p-2.5 flex flex-col gap-2">
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Dark mode tokens</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Design</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">2pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">Onboarding checklist</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Growth</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">3pt</span></div></article>
<article class="rounded-lg border border-tgx18-line border-l-[3px] border-l-tgx18-done bg-tgx18-card p-3 flex flex-col gap-2"><p class="text-[0.8rem] leading-[1.4] text-tgx18-dim line-through">CDN migration</p><div class="flex items-center justify-between gap-2"><em class="not-italic no-underline text-[0.62rem] text-tgx18-dim bg-tgx18-bg rounded px-1.5 py-0.5">Infra</em><span class="text-[0.62rem] tabular-nums text-tgx18-dim">8pt</span></div></article>
</div>
</section>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tgx18-bg: #1c1e2a;
--color-tgx18-bg: oklch(0.21 0.02 270);
--color-tgx18-col: #232634;
--color-tgx18-col: oklch(0.25 0.025 270);
--color-tgx18-card: #2b2f3f;
--color-tgx18-card: oklch(0.3 0.025 270);
--color-tgx18-line: #3a3f52;
--color-tgx18-line: oklch(0.38 0.03 270);
--color-tgx18-hover: #5b6280;
--color-tgx18-hover: oklch(0.55 0.05 270);
--color-tgx18-ink: #e9eaf1;
--color-tgx18-ink: oklch(0.93 0.01 270);
--color-tgx18-dim: #a8acbd;
--color-tgx18-dim: oklch(0.74 0.02 270);
--color-tgx18-done: #767b91;
--color-tgx18-done: oklch(0.6 0.02 270);
--color-tgx18-ok: #8ce0ae;
--color-tgx18-ok: oklch(0.85 0.14 150);
--color-tgx18-oktint: #29382f;
--color-tgx18-oktint: oklch(0.31 0.04 150);
--color-tgx18-warn: #f0cc72;
--color-tgx18-warn: oklch(0.86 0.14 85);
--color-tgx18-warntint: #3a3423;
--color-tgx18-warntint: oklch(0.32 0.04 85);
--color-tgx18-a1: #8ab4f8;
--color-tgx18-a1: oklch(0.78 0.11 250);
--color-tgx18-a2: #f0a68a;
--color-tgx18-a2: oklch(0.79 0.12 40);
--color-tgx18-a3: #9ee0c0;
--color-tgx18-a3: oklch(0.86 0.11 160);
--font-tgx18-sans: 'Inter Tight', system-ui, sans-serif;
}
.tgx-18 {
width: 100%;
min-height: 100svh;
}
```How this works
Implicit columns are the trick. Auto-flow mints an identically sized column for every child, which is what makes a board with an unknown list count possible without JavaScript.
Proximity, not mandatory. Mandatory snapping fights a user who wants to rest between two columns; proximity settles when they are close and otherwise leaves them alone.
Make it yours
- Column width lives in one
clamp(). - Cap the board height anywhere; the stacks inherit and scroll internally.
- Add a ghost 'new list' column that is just a button — auto-flow places it like any other.
Gotchas — read before shipping
overscroll-x-containis load-bearing: without it a swipe past the last column triggers browser back-navigation.- The inner stack needs
minmax(0,1fr), not1fr. - Only use
cursor-grabif drag is actually wired; here the cards are links, so they use a pointer.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Scroll snap and auto-flow column are long universal; clamp() sizing needs 2020+.