Section
Kanban Board — Neo-Brutalism
Brutalist project kanban board with hard black borders, offset drop shadows, and flat bright column headers. Draggable task cards move between Backlog, In Progress, Review, and Done via the HTML5 Drag and Drop API, count badges update live, and an add-card affordance creates new tasks per column. Press-down hover states and monospace labels keep the raw, editorial feel.
- Section
- Tailwind
- HTML
- MIT
What it does
Capabilities
- Hard offset shadows on cards and panel
- Flat bright accent column headers
- Press-down hover states
- HTML5 drag-and-drop between columns
- Live-updating count badges
- Add-card affordance per column
- Placeholder drop indicator
- Keyboard-focusable draggable cards
Preview
Live section
devsnips.site/library/tailwind/sections/app-ui/kanban-board/neo-brutalism/ Install
Add to your project
npx devsnips add Tailwind/Sections/App-UI/kanban-board/neo-brutalism Tailwind/Sections/App-UI/kanban-board/neo-brutalism <!--
Snippet Name: Kanban Board — Neo-Brutalism
Description: Hard-bordered kanban board with offset shadows, count badges, draggable task cards (HTML5 DnD), and an add-card affordance per column.
Author: DevSnips Contributors
Usage Example: Drop into any app shell as a project board widget. Drag cards between columns and click "+ ADD CARD" to create new tasks. Fully wired in preview.html.
-->
<div class="relative w-full" data-board="nb">
<!-- Board -->
<div class="border-2 border-black bg-white p-4 shadow-[8px_8px_0_0_#000] sm:p-5">
<div class="board-cols flex gap-4 overflow-x-auto pb-2" data-board-cols>
<!-- Column -->
<section class="nb-col w-[280px] shrink-0 border-2 border-black bg-[#FFFDF5]" aria-label="Backlog">
<header class="flex items-center justify-between border-b-2 border-black bg-[#FFE600] px-3 py-2">
<h3 class="font-archivo text-sm font-extrabold uppercase tracking-tight">Backlog</h3>
<span class="nb-count border-2 border-black bg-white px-2 font-mono text-[11px] font-bold shadow-[2px_2px_0_0_#000]" data-count>3</span>
</header>
<div class="nb-list space-y-3 p-3" data-list>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#FF4FA3] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase text-white">P1</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-104</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug">Wire dark-mode toggle to root class</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Persist choice in localStorage and reflect on first paint.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-[#00C2FF] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">css</span>
<span class="border border-black bg-[#00E676] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">a11y</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-[#FFE600] font-archivo text-[11px] font-extrabold">RM</div>
</div>
</article>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#00C2FF] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase text-black">P3</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-118</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug">Sketch onboarding empty state</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Three steps with inline illustrations and a CTA.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-white px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">design</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-[#FF4FA3] font-archivo text-[11px] font-extrabold text-white">JL</div>
</div>
</article>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#FF4FA3] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase text-white">P2</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-121</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug">Research drag-drop a11y patterns</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Compare native DnD vs roving tabindex keyboards.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-[#00E676] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">a11y</span>
<span class="border border-black bg-white px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">research</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-black font-archivo text-[11px] font-extrabold text-white">SK</div>
</div>
</article>
</div>
<button type="button" class="nb-add m-3 mt-0 flex w-[calc(100%-1.5rem)] items-center justify-center gap-1.5 border-2 border-black bg-white py-2 font-mono text-[11px] font-bold uppercase shadow-[2px_2px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
Add card
</button>
</section>
<!-- Column -->
<section class="nb-col w-[280px] shrink-0 border-2 border-black bg-[#FFFDF5]" aria-label="In Progress">
<header class="flex items-center justify-between border-b-2 border-black bg-[#00C2FF] px-3 py-2">
<h3 class="font-archivo text-sm font-extrabold uppercase tracking-tight">In Progress</h3>
<span class="nb-count border-2 border-black bg-white px-2 font-mono text-[11px] font-bold shadow-[2px_2px_0_0_#000]" data-count>2</span>
</header>
<div class="nb-list space-y-3 p-3" data-list>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#FF4FA3] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase text-white">P1</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-098</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug">Ship kanban drag-and-drop widget</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">HTML5 DnD, move cards across columns, update counts live.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-[#FFE600] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">js</span>
<span class="border border-black bg-white px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">widget</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-[#00E676] font-archivo text-[11px] font-extrabold">AB</div>
</div>
</article>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#FFE600] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">P2</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-110</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug">Tokenize the 3-style palette</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Extract shared tokens so variants stay cohesive.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-[#FF4FA3] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase text-white">tokens</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-[#00C2FF] font-archivo text-[11px] font-extrabold">DT</div>
</div>
</article>
</div>
<button type="button" class="nb-add m-3 mt-0 flex w-[calc(100%-1.5rem)] items-center justify-center gap-1.5 border-2 border-black bg-white py-2 font-mono text-[11px] font-bold uppercase shadow-[2px_2px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
Add card
</button>
</section>
<!-- Column -->
<section class="nb-col w-[280px] shrink-0 border-2 border-black bg-[#FFFDF5]" aria-label="Review">
<header class="flex items-center justify-between border-b-2 border-black bg-[#FF4FA3] px-3 py-2">
<h3 class="font-archivo text-sm font-extrabold uppercase tracking-tight text-white">Review</h3>
<span class="nb-count border-2 border-black bg-white px-2 font-mono text-[11px] font-bold shadow-[2px_2px_0_0_#000]" data-count>1</span>
</header>
<div class="nb-list space-y-3 p-3" data-list>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#00E676] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">P3</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-091</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug">Audit focus rings across sections</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Ensure every interactive element has a visible focus-visible ring.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-[#00E676] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">a11y</span>
<span class="border border-black bg-white px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">audit</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-[#FFE600] font-archivo text-[11px] font-extrabold">RM</div>
</div>
</article>
</div>
<button type="button" class="nb-add m-3 mt-0 flex w-[calc(100%-1.5rem)] items-center justify-center gap-1.5 border-2 border-black bg-white py-2 font-mono text-[11px] font-bold uppercase shadow-[2px_2px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
Add card
</button>
</section>
<!-- Column -->
<section class="nb-col w-[280px] shrink-0 border-2 border-black bg-[#FFFDF5]" aria-label="Done">
<header class="flex items-center justify-between border-b-2 border-black bg-[#00E676] px-3 py-2">
<h3 class="font-archivo text-sm font-extrabold uppercase tracking-tight">Done</h3>
<span class="nb-count border-2 border-black bg-white px-2 font-mono text-[11px] font-bold shadow-[2px_2px_0_0_#000]" data-count>2</span>
</header>
<div class="nb-list space-y-3 p-3" data-list>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#00C2FF] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">P3</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-087</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug line-through decoration-black decoration-2">Set up CDN + fonts scaffold</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Tailwind play CDN + Google Fonts across variants.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-[#FFE600] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">infra</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-[#FF4FA3] font-archivo text-[11px] font-extrabold text-white">JL</div>
</div>
</article>
<article class="nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing" draggable="true" tabindex="0">
<div class="mb-2 flex items-center justify-between gap-2">
<span class="border-2 border-black bg-[#00E676] px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">P3</span>
<span class="font-mono text-[10px] font-bold uppercase text-black/50">SNIP-074</span>
</div>
<h4 class="font-archivo text-[14px] font-bold leading-snug line-through decoration-black decoration-2">Write STYLE_TOKENS reference</h4>
<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Canonical token doc for all three design styles.</p>
<div class="mt-2.5 flex items-center justify-between">
<div class="flex items-center gap-1.5">
<span class="border border-black bg-white px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">docs</span>
</div>
<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-black font-archivo text-[11px] font-extrabold text-white">SK</div>
</div>
</article>
</div>
<button type="button" class="nb-add m-3 mt-0 flex w-[calc(100%-1.5rem)] items-center justify-center gap-1.5 border-2 border-black bg-white py-2 font-mono text-[11px] font-bold uppercase shadow-[2px_2px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-none focus:outline-none focus-visible:ring-2 focus-visible:ring-black focus-visible:ring-offset-2">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
Add card
</button>
</section>
</div>
</div>
<style>
[data-board="nb"] .nb-list { min-height: 56px; transition: background-color .12s ease; }
[data-board="nb"] .nb-list.nb-over { background-color: rgba(255, 230, 0, 0.35); outline: 2px dashed #000; outline-offset: -2px; }
[data-board="nb"] .nb-card.nb-drag { opacity: .4; }
[data-board="nb"] .nb-card.nb-focus:focus { outline: 2px solid #000; outline-offset: 2px; }
[data-board="nb"] .nb-placeholder { border: 2px dashed #000; background: rgba(0,0,0,0.04); height: 84px; }
[data-board="nb"] .board-cols { scrollbar-width: thin; scrollbar-color: #000 transparent; }
[data-board="nb"] .board-cols::-webkit-scrollbar { height: 10px; }
[data-board="nb"] .board-cols::-webkit-scrollbar-track { background: #FFFDF5; border-top: 2px solid #000; }
[data-board="nb"] .board-cols::-webkit-scrollbar-thumb { background: #000; }
[data-board="nb"] .nb-list::-webkit-scrollbar { width: 8px; }
[data-board="nb"] .nb-list::-webkit-scrollbar-thumb { background: #000; }
</style>
<script>
(function () {
var root = document.currentScript.closest('[data-board="nb"]');
if (!root) return;
var cols = root.querySelectorAll('[data-list]');
var dragged = null;
var placeholder = null;
var uid = 0;
function updateCounts() {
root.querySelectorAll('.nb-col').forEach(function (col) {
var count = col.querySelector('[data-list]').children.length;
var badge = col.querySelector('[data-count]');
if (badge) badge.textContent = count;
});
}
function findCard(node) {
return node && (node.closest ? node.closest('.nb-card') : null);
}
function makePlaceholder() {
var p = document.createElement('div');
p.className = 'nb-placeholder';
return p;
}
function clearOver() {
cols.forEach(function (l) { l.classList.remove('nb-over'); });
}
function attachCard(card) {
card.addEventListener('dragstart', function (e) {
dragged = card;
card.classList.add('nb-drag');
if (e.dataTransfer) {
e.dataTransfer.effectAllowed = 'move';
try { e.dataTransfer.setData('text/plain', card.dataset.id || ''); } catch (err) {}
}
placeholder = makePlaceholder();
if (card.parentNode) card.parentNode.insertBefore(placeholder, card.nextSibling);
});
card.addEventListener('dragend', function () {
card.classList.remove('nb-drag');
if (placeholder && placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
placeholder = null;
dragged = null;
clearOver();
updateCounts();
});
}
root.querySelectorAll('.nb-card').forEach(attachCard);
cols.forEach(function (list) {
list.addEventListener('dragover', function (e) {
e.preventDefault();
if (e.dataTransfer) e.dataTransfer.dropEffect = 'move';
list.classList.add('nb-over');
if (!dragged || !placeholder) return;
var after = null;
var cards = list.querySelectorAll('.nb-card:not(.nb-drag)');
Array.prototype.forEach.call(cards, function (c) {
var r = c.getBoundingClientRect();
if (e.clientY < r.top + r.height / 2) { after = c; }
});
if (after) { list.insertBefore(placeholder, after); }
else if (list !== dragged.parentNode || list.lastElementChild !== placeholder) { list.appendChild(placeholder); }
});
list.addEventListener('dragleave', function (e) {
if (!list.contains(e.relatedTarget)) list.classList.remove('nb-over');
});
list.addEventListener('drop', function (e) {
e.preventDefault();
if (dragged && placeholder && placeholder.parentNode === list) {
list.insertBefore(dragged, placeholder);
if (placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
} else if (dragged) {
list.appendChild(dragged);
}
placeholder = null;
dragged = null;
clearOver();
updateCounts();
});
});
// Add-card affordance
var palettes = ['#FF4FA3', '#FFE600', '#00C2FF', '#00E676'];
var avatars = ['AB', 'CD', 'EF', 'GH', 'JK', 'MN'];
root.querySelectorAll('.nb-add').forEach(function (btn) {
btn.addEventListener('click', function () {
var col = btn.closest('.nb-col');
var list = col.querySelector('[data-list]');
uid += 1;
var id = 'SNIP-' + (200 + uid);
var pri = palettes[uid % palettes.length];
var dark = pri === '#FFE600' || pri === '#00C2FF' || pri === '#00E676';
var card = document.createElement('article');
card.className = 'nb-card cursor-grab border-2 border-black bg-white p-3 shadow-[3px_3px_0_0_#000] transition-transform duration-100 hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[1px_1px_0_0_#000] active:cursor-grabbing';
card.setAttribute('draggable', 'true');
card.setAttribute('tabindex', '0');
card.dataset.id = id;
card.innerHTML =
'<div class="mb-2 flex items-center justify-between gap-2">' +
'<span class="border-2 border-black px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase ' + (dark ? 'text-black' : 'text-white') + '" style="background:' + pri + '">P2</span>' +
'<span class="font-mono text-[10px] font-bold uppercase text-black/50">' + id + '</span>' +
'</div>' +
'<h4 class="font-archivo text-[14px] font-bold leading-snug">New task — define the next step</h4>' +
'<p class="mt-1 font-mono text-[11px] leading-snug text-black/60">Click to flesh out details, owners, and tags.</p>' +
'<div class="mt-2.5 flex items-center justify-between">' +
'<div class="flex items-center gap-1.5"><span class="border border-black bg-white px-1.5 py-0.5 font-mono text-[10px] font-bold uppercase">new</span></div>' +
'<div class="flex h-7 w-7 items-center justify-center border-2 border-black bg-[#FFE600] font-archivo text-[11px] font-extrabold">' + avatars[uid % avatars.length] + '</div>' +
'</div>';
list.appendChild(card);
attachCard(card);
updateCounts();
card.focus();
});
});
// Keyboard reordering: ArrowUp/Down moves within a column,
// ArrowLeft/Right moves the card to the previous/next column.
// Reuses the same DOM-move + updateCounts() logic as drag-and-drop.
root.querySelectorAll('.nb-card').forEach(function (card) {
card.addEventListener('keydown', function (e) {
var list = card.parentNode;
if (!list || !list.hasAttribute('data-list')) return;
var colsArr = Array.prototype.slice.call(cols);
var colIdx = colsArr.indexOf(list);
var cards = Array.prototype.slice.call(list.querySelectorAll('.nb-card'));
var idx = cards.indexOf(card);
function moveTo(targetList) {
targetList.appendChild(card); updateCounts(); card.focus();
}
switch (e.key) {
case 'ArrowUp':
e.preventDefault();
if (idx > 0) { list.insertBefore(card, cards[idx - 1]); updateCounts(); card.focus(); }
break;
case 'ArrowDown':
e.preventDefault();
if (idx < cards.length - 1) { list.insertBefore(card, cards[idx + 1].nextSibling); updateCounts(); card.focus(); }
break;
case 'ArrowLeft':
e.preventDefault();
if (colIdx > 0) { moveTo(colsArr[colIdx - 1]); }
break;
case 'ArrowRight':
e.preventDefault();
if (colIdx < colsArr.length - 1) { moveTo(colsArr[colIdx + 1]); }
break;
}
});
});
updateCounts();
})();
</script>
</div> Agent skill & Model Context Protocol
Pass this section straight into your AI workflow. DevSnips exposes each resource as a structured, addressable registry entry, so your agent installs the real files instead of approximating them.
devsnips://sections/app-ui/kanban-board/neo-brutalism I want to use this DevSnips resource in production: Page: https://devsnips.site/library/tailwind/sections/app-ui/kanban-board/neo-brutalism/ Install: npx devsnips add Tailwind/Sections/App-UI/kanban-board/neo-brutalism This is the Kanban Board — Neo-Brutalism — Brutalist project kanban board with hard black borders, offset drop shadows, and flat bright column headers. Draggable task cards move between Backlog, In Progress, Review, and Done via the HTML5 Drag and Drop API, count badges update live, and an add-card affordance creates new tasks per column. Press-down hover states and monospace labels keep the raw, editorial feel. Use this DevSnips resource as the starting point for my project. Adapt it to my project's stack and conventions, fix any issues, and make it production-ready while preserving its intended design and behavior.
Paste into ChatGPT, Claude or your agent — it already carries the page URL and the exact install path.
devsnips://sections/app-ui/kanban-board/neo-brutalism