Models 44

Muse Ember

Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
28.1 s
Cost
$0.0078
Output tokens
15,488
Spent thinking
6,937 tokens
Speed
592.4 tok/s
Console errors
0
First token after
1.9 s
First visible text after
18.0 s
Prompt tokens
511
Code size
27.9 KB
Finish reason
stop
Served by
Meta
Model id
meta/muse-ember
Reasoning sent
{"effort":"max"}
Max output
943,718 tokens
Generated
Nov 12, 2026

What it was asked

The prompt
Build an interactive Kanban board in vanilla HTML, CSS and JavaScript (no framework, no library). Requirements: - Three columns: "To do", "In progress", "Done", each showing its card count. - Pre-populate the board with 6 realistic cards spread across the columns so the first screenshot looks alive. - Each card has a title and a priority (low / medium / high) shown as a colored badge. - Add a card through a small modal form (title required), and delete a card with a button on it. - Drag and drop cards between columns with the mouse, with a clear visual drop indicator. - A search field that filters cards live by title. - A light / dark theme toggle. - State lives in memory only (no storage APIs).
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 563 lines

<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kanban Board</title>
<style>
  *{box-sizing:border-box;margin:0;padding:0}
  :root{
    --bg:#eef1f7;
    --surface:#ffffff;
    --surface-2:#f8fafc;
    --column-bg:#e9eef6;
    --card-bg:#ffffff;
    --text:#0f172a;
    --muted:#64748b;
    --border:#e2e8f0;
    --input-bg:#ffffff;
    --shadow:0 10px 25px rgba(15,23,42,.08);
    --shadow-sm:0 2px 8px rgba(15,23,42,.06);
    --primary:#6366f1;
    --primary-hover:#4f46e5;
  }
  [data-theme="dark"]{
    --bg:#0b0f1a;
    --surface:#151b2e;
    --surface-2:#1e293b;
    --column-bg:#131a2e;
    --card-bg:#1a2238;
    --text:#e8ecf5;
    --muted:#94a3b8;
    --border:#263052;
    --input-bg:#1a2238;
    --shadow:0 14px 30px rgba(0,0,0,.35);
    --shadow-sm:0 2px 10px rgba(0,0,0,.25);
  }
  html{overflow-x:hidden}
  body{
    font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Inter,Arial,sans-serif;
    background:var(--bg);
    color:var(--text);
    min-height:100vh;
    padding:0 22px 28px;
    transition:background .25s,color .25s;
    overflow-x:hidden;
  }
  body::before{content:"";display:block;height:5px;margin:0 -22px 0;background:linear-gradient(90deg,#6366f1,#a855f7,#ec4899,#f59e0b);border-radius:0 0 99px 99px}
  /* Topbar */
  .topbar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;padding:20px 0 16px;max-width:1240px;margin:0 auto}
  .brand{display:flex;align-items:center;gap:13px;min-width:0}
  .logo{width:46px;height:46px;border-radius:13px;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0;box-shadow:0 8px 20px rgba(99,102,241,.35)}
  .logo svg{width:26px;height:26px}
  .brand h1{font-size:22px;line-height:1.1;letter-spacing:-.02em}
  .brand p{font-size:13px;color:var(--muted);margin-top:3px}
  .controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .search-wrap{position:relative;width:280px;max-width:100%}
  .search-wrap svg.search-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);width:17px;height:17px;color:var(--muted);pointer-events:none}
  .search-wrap input{width:100%;height:42px;border:1.5px solid var(--border);background:var(--input-bg);color:var(--text);border-radius:99px;padding:0 36px 0 39px;font-size:14px;outline:none;transition:.2s;box-shadow:var(--shadow-sm)}
  .search-wrap input:focus{border-color:var(--primary);box-shadow:0 0 0 4px rgba(99,102,241,.15)}
  .search-wrap input::placeholder{color:var(--muted)}
  .clear-btn{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:26px;height:26px;border:none;border-radius:50%;background:var(--surface-2);color:var(--muted);cursor:pointer;font-size:16px;line-height:1;display:none}
  .clear-btn:hover{background:var(--border);color:var(--text)}
  .icon-btn{width:42px;height:42px;border-radius:50%;border:1.5px solid var(--border);background:var(--surface);color:var(--text);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.2s;box-shadow:var(--shadow-sm);flex-shrink:0}
  .icon-btn:hover{transform:translateY(-1px);border-color:var(--primary)}
  .icon-btn svg{width:19px;height:19px}
  [data-theme="light"] .icon-sun{display:none} [data-theme="dark"] .icon-moon{display:none}
  .add-btn{height:42px;border:none;border-radius:99px;background:linear-gradient(135deg,#6366f1,#7c3aed);color:#fff;font-size:14px;font-weight:700;padding:0 18px;cursor:pointer;display:inline-flex;align-items:center;gap:7px;box-shadow:0 8px 18px rgba(99,102,241,.32);transition:.2s;white-space:nowrap}
  .add-btn:hover{background:var(--primary-hover);transform:translateY(-1px)}
  .add-btn svg{width:16px;height:16px}
  /* Summary */
  .summary{max-width:1240px;margin:0 auto 18px;background:var(--surface);border:1px solid var(--border);border-radius:16px;padding:14px 18px;display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;box-shadow:var(--shadow-sm)}
  .summary strong{font-size:15px}
  .summary span.sub{display:block;font-size:13px;color:var(--muted);margin-top:2px}
  .progress-area{display:flex;align-items:center;gap:12px;min-width:260px;flex:1;max-width:420px}
  .track{flex:1;height:10px;border-radius:99px;background:var(--surface-2);border:1px solid var(--border);overflow:hidden}
  .fill{height:100%;width:0%;background:linear-gradient(90deg,#22c55e,#10b981);border-radius:99px;transition:width .35s ease}
  .pct{font-weight:800;font-size:14px;min-width:42px;text-align:right;color:#16a34a}
  /* Board */
  .board{max-width:1240px;margin:0 auto;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;align-items:start}
  .column{background:var(--column-bg);border:1px solid var(--border);border-radius:18px;padding:14px;min-width:0;transition:border-color .2s,box-shadow .2s}
  .column.drag-over{border:2px dashed var(--primary);box-shadow:0 0 0 5px rgba(99,102,241,.12)}
  .col-head{display:flex;align-items:center;gap:9px;padding:4px 4px 12px}
  .col-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
  .todo-dot{background:#3b82f6;box-shadow:0 0 0 4px rgba(59,130,246,.15)}
  .progress-dot{background:#f59e0b;box-shadow:0 0 0 4px rgba(245,158,11,.15)}
  .done-dot{background:#22c55e;box-shadow:0 0 0 4px rgba(34,197,94,.15)}
  .col-head h2{font-size:15px;letter-spacing:-.01em;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .count{font-size:12px;font-weight:800;background:var(--surface);border:1px solid var(--border);color:var(--muted);padding:3px 9px;border-radius:99px;min-width:28px;text-align:center}
  .col-label{font-size:12px;color:var(--muted);font-weight:600}
  .col-add{width:28px;height:28px;border-radius:50%;border:1px solid var(--border);background:var(--surface);color:var(--muted);cursor:pointer;font-size:18px;line-height:1;display:flex;align-items:center;justify-content:center;transition:.2s;flex-shrink:0}
  .col-add:hover{background:var(--primary);color:#fff;border-color:var(--primary)}
  .card-list{display:flex;flex-direction:column;gap:11px;min-height:200px}
  .card{background:var(--card-bg);border:1px solid var(--border);border-radius:14px;padding:13px 14px 12px;box-shadow:var(--shadow-sm);cursor:grab;transition:transform .15s,box-shadow .15s,border-color .15s;animation:fadeUp .35s ease both;position:relative}
  .card:hover{transform:translateY(-2px);box-shadow:var(--shadow);border-color:#c7d2fe}
  .card:active{cursor:grabbing}
  .card.dragging{opacity:.35;transform:rotate(1.5deg) scale(.98)}
  @keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
  .card-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:9px}
  .badge{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;padding:4px 9px;border-radius:99px}
  .badge .dot{width:6px;height:6px;border-radius:50%;background:currentColor}
  .badge-low{background:#dcfce7;color:#166534}.badge-medium{background:#fef3c7;color:#92400e}.badge-high{background:#fee2e2;color:#991b1b}
  [data-theme="dark"] .badge-low{background:rgba(34,197,94,.18);color:#86efac}
  [data-theme="dark"] .badge-medium{background:rgba(245,158,11,.18);color:#fcd34d}
  [data-theme="dark"] .badge-high{background:rgba(239,68,68,.18);color:#fca5a5}
  .delete-btn{width:26px;height:26px;border:none;border-radius:50%;background:transparent;color:var(--muted);font-size:18px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.15s;flex-shrink:0}
  .delete-btn:hover{background:#fee2e2;color:#dc2626;transform:scale(1.08)}
  .card-title{font-size:15px;line-height:1.35;letter-spacing:-.01em;font-weight:650;margin-bottom:12px;word-break:break-word}
  .card-meta{display:flex;align-items:center;justify-content:space-between;gap:8px}
  .tag{font-size:12px;color:var(--muted);background:var(--surface-2);border:1px solid var(--border);padding:3px 8px;border-radius:99px;font-weight:600}
  .avatar{width:27px;height:27px;border-radius:50%;background:linear-gradient(135deg,#6366f1,#a855f7);color:#fff;font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center;letter-spacing:.02em;flex-shrink:0}
  .empty{border:1.5px dashed var(--border);border-radius:12px;padding:22px 14px;text-align:center;color:var(--muted);font-size:13px;line-height:1.4;background:transparent}
  .drop-indicator{height:5px;border-radius:99px;background:var(--primary);box-shadow:0 0 0 4px rgba(99,102,241,.18),0 4px 10px rgba(99,102,241,.4);margin:2px 0;flex-shrink:0}
  .hint{max-width:1240px;margin:16px auto 0;text-align:center;font-size:12.5px;color:var(--muted)}
  kbd{background:var(--surface);border:1px solid var(--border);border-bottom-width:2px;border-radius:6px;padding:1px 6px;font-size:11px;font-family:inherit;font-weight:700;color:var(--text)}
  /* Modal */
  .overlay{position:fixed;inset:0;background:rgba(8,10,20,.55);backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;padding:18px;opacity:0;pointer-events:none;transition:opacity .2s;z-index:50}
  .overlay.open{opacity:1;pointer-events:auto}
  .modal{width:100%;max-width:440px;background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:20px;padding:22px;box-shadow:0 25px 60px rgba(0,0,0,.25);transform:translateY(14px) scale(.98);transition:.22s}
  .overlay.open .modal{transform:translateY(0) scale(1)}
  .modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:6px}
  .modal-head h3{font-size:19px;letter-spacing:-.02em}
  .modal-head p{font-size:13px;color:var(--muted);margin-top:4px}
  .close-x{width:34px;height:34px;border-radius:50%;border:1px solid var(--border);background:var(--surface-2);color:var(--muted);cursor:pointer;font-size:19px;line-height:1;flex-shrink:0}
  .close-x:hover{color:var(--text)}
  .field{margin-top:16px}
  .field label{display:block;font-size:13px;font-weight:700;margin-bottom:7px}
  .field label em{color:#dc2626;font-style:normal}
  .field input,.field select{width:100%;height:44px;border:1.5px solid var(--border);border-radius:11px;background:var(--input-bg);color:var(--text);padding:0 13px;font-size:14px;outline:none;transition:.2s;font-family:inherit}
  .field input:focus,.field select:focus{border-color:var(--primary);box-shadow:0 0 0 4px rgba(99,102,241,.13)}
  .field input.invalid{border-color:#ef4444;box-shadow:0 0 0 4px rgba(239,68,68,.12)}
  .error{display:none;color:#dc2626;font-size:12.5px;font-weight:600;margin-top:6px}
  .error.show{display:block}
  .prio-row{display:flex;gap:8px}
  .prio-btn{flex:1;height:40px;border-radius:11px;border:1.5px solid var(--border);background:var(--surface-2);color:var(--muted);font-weight:800;font-size:13px;cursor:pointer;text-transform:capitalize;transition:.15s;font-family:inherit}
  .prio-btn.selected[data-priority="low"]{background:#dcfce7;border-color:#86efac;color:#166534}
  .prio-btn.selected[data-priority="medium"]{background:#fef3c7;border-color:#fcd34d;color:#92400e}
  .prio-btn.selected[data-priority="high"]{background:#fee2e2;border-color:#fca5a5;color:#991b1b}
  .modal-actions{display:flex;gap:10px;margin-top:22px}
  .btn-cancel{flex:1;height:44px;border-radius:12px;border:1.5px solid var(--border);background:var(--surface);color:var(--text);font-weight:700;font-size:14px;cursor:pointer;font-family:inherit}
  .btn-cancel:hover{background:var(--surface-2)}
  .btn-submit{flex:1.4;height:44px;border:none;border-radius:12px;background:linear-gradient(135deg,#6366f1,#7c3aed);color:#fff;font-weight:800;font-size:14px;cursor:pointer;font-family:inherit;box-shadow:0 8px 18px rgba(99,102,241,.3)}
  .btn-submit:hover{filter:brightness(1.06)}
  /* Toast */
  .toast{position:fixed;left:50%;bottom:22px;transform:translate(-50%,20px);background:#0f172a;color:#fff;font-size:13.5px;font-weight:700;padding:11px 18px;border-radius:99px;box-shadow:0 12px 30px rgba(0,0,0,.25);opacity:0;pointer-events:none;transition:.25s;z-index:60;white-space:nowrap;max-width:calc(100vw - 32px);overflow:hidden;text-overflow:ellipsis}
  .toast.show{opacity:1;transform:translate(-50%,0)}
  @media (max-width:960px){
    .board{grid-template-columns:1fr}
    .card-list{min-height:90px}
    .search-wrap{flex:1;min-width:220px}
  }
  @media (max-width:520px){
    body{padding:0 14px 24px} body::before{margin:0 -14px 0}
    .topbar{padding-top:16px}.brand h1{font-size:19px}
    .controls{width:100%}.search-wrap{width:100%;flex-basis:100%}
    .add-btn{flex:1;justify-content:center}
    .progress-area{max-width:none;width:100%}
    .summary{padding:13px 14px}
    .prio-row{flex-direction:row}
  }
</style>
</head>
<body>

<header class="topbar">
  <div class="brand">
    <div class="logo" aria-hidden="true">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><rect x="3" y="4" width="5" height="13" rx="1.5"/><rect x="10" y="4" width="5" height="9" rx="1.5"/><rect x="17" y="4" width="4" height="16" rx="1.5"/></svg>
    </div>
    <div>
      <h1>Kanban Board</h1>
      <p>Plan &middot; Track &middot; Ship</p>
    </div>
  </div>
  <div class="controls">
    <div class="search-wrap">
      <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
      <input id="searchInput" type="search" placeholder="Search cards...  ( / )" aria-label="Search cards by title" autocomplete="off">
      <button class="clear-btn" id="clearSearch" type="button" aria-label="Clear search">&times;</button>
    </div>
    <button class="icon-btn" id="themeToggle" type="button" aria-label="Toggle light / dark theme" title="Toggle theme">
      <svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
      <svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>
    </button>
    <button class="add-btn" id="addCardBtn" type="button">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M12 5v14M5 12h14"/></svg>
      Add card
    </button>
  </div>
</header>

<div class="summary">
  <div>
    <strong id="summaryText">2 of 6 tasks done</strong>
    <span class="sub">Drag cards between columns to update progress</span>
  </div>
  <div class="progress-area">
    <div class="track"><div class="fill" id="progressFill"></div></div>
    <span class="pct" id="progressPct">33%</span>
  </div>
</div>

<main class="board" id="board">
  <section class="column" data-col="todo">
    <div class="col-head">
      <span class="col-dot todo-dot"></span>
      <h2>To do</h2>
      <span class="col-label" id="count-todo">2</span>
      <button class="col-add" data-col="todo" type="button" aria-label="Add card to To do" title="Add to To do">+</button>
    </div>
    <div class="card-list" data-col="todo"></div>
  </section>

  <section class="column" data-col="progress">
    <div class="col-head">
      <span class="col-dot progress-dot"></span>
      <h2>In progress</h2>
      <span class="col-label" id="count-progress">2</span>
      <button class="col-add" data-col="progress" type="button" aria-label="Add card to In progress" title="Add to In progress">+</button>
    </div>
    <div class="card-list" data-col="progress"></div>
  </section>

  <section class="column" data-col="done">
    <div class="col-head">
      <span class="col-dot done-dot"></span>
      <h2>Done</h2>
      <span class="col-label" id="count-done">2</span>
      <button class="col-add" data-col="done" type="button" aria-label="Add card to Done" title="Add to Done">+</button>
    </div>
    <div class="card-list" data-col="done"></div>
  </section>
</main>

<p class="hint">Tip: Drag cards between columns &middot; Press <kbd>/</kbd> to search &middot; <kbd>Esc</kbd> closes the form</p>

<!-- Modal -->
<div class="overlay" id="modalOverlay" role="dialog" aria-modal="true" aria-labelledby="modalTitle">
  <div class="modal">
    <div class="modal-head">
      <div>
        <h3 id="modalTitle">Add a new card</h3>
        <p>Give your task a clear title and set its priority.</p>
      </div>
      <button class="close-x" id="closeModal" type="button" aria-label="Close">&times;</button>
    </div>
    <form id="cardForm" novalidate>
      <div class="field">
        <label for="titleInput">Title <em>*</em></label>
        <input id="titleInput" type="text" placeholder="e.g. Fix login bug" maxlength="90" autocomplete="off">
        <p class="error" id="errorMsg">Please enter a title for this card.</p>
      </div>
      <div class="field">
        <label>Priority</label>
        <div class="prio-row">
          <button class="prio-btn" type="button" data-priority="low">Low</button>
          <button class="prio-btn selected" type="button" data-priority="medium">Medium</button>
          <button class="prio-btn" type="button" data-priority="high">High</button>
        </div>
      </div>
      <div class="field">
        <label for="columnSelect">Column</label>
        <select id="columnSelect">
          <option value="todo">To do</option>
          <option value="progress">In progress</option>
          <option value="done">Done</option>
        </select>
      </div>
      <div class="modal-actions">
        <button class="btn-cancel" id="cancelBtn" type="button">Cancel</button>
        <button class="btn-submit" type="submit">Add card</button>
      </div>
    </form>
  </div>
</div>

<div class="toast" id="toast"></div>

<script>
(function(){
  "use strict";
  var state = [
    {id:"1", title:"Design new landing page hero", priority:"high", column:"todo", tag:"Design", assignee:"AK"},
    {id:"2", title:"Prepare Q3 marketing report", priority:"medium", column:"todo", tag:"Marketing", assignee:"JM"},
    {id:"3", title:"Fix checkout payment bug", priority:"high", column:"progress", tag:"Engineering", assignee:"RS"},
    {id:"4", title:"Implement user onboarding flow", priority:"medium", column:"progress", tag:"Product", assignee:"AK"},
    {id:"5", title:"Update brand guidelines v2", priority:"low", column:"done", tag:"Design", assignee:"LT"},
    {id:"6", title:"Refactor API authentication", priority:"low", column:"done", tag:"Engineering", assignee:"RS"}
  ];
  var query = "";
  var draggingId = null;
  var selectedPriority = "medium";
  var columns = ["todo","progress","done"];

  var searchInput = document.getElementById("searchInput");
  var clearSearch = document.getElementById("clearSearch");
  var themeToggle = document.getElementById("themeToggle");
  var addCardBtn = document.getElementById("addCardBtn");
  var overlay = document.getElementById("modalOverlay");
  var closeModalBtn = document.getElementById("closeModal");
  var cancelBtn = document.getElementById("cancelBtn");
  var form = document.getElementById("cardForm");
  var titleInput = document.getElementById("titleInput");
  var columnSelect = document.getElementById("columnSelect");
  var errorMsg = document.getElementById("errorMsg");
  var toast = document.getElementById("toast");
  var toastTimer = null;

  var dropIndicator = document.createElement("div");
  dropIndicator.className = "drop-indicator";

  function showToast(msg){
    toast.textContent = msg;
    toast.classList.add("show");
    if(toastTimer) clearTimeout(toastTimer);
    toastTimer = setTimeout(function(){ toast.classList.remove("show"); }, 2200);
  }

  function createCard(card, idx){
    var el = document.createElement("article");
    el.className = "card";
    el.draggable = true;
    el.dataset.id = card.id;
    el.style.animationDelay = (idx * 50) + "ms";

    var top = document.createElement("div");
    top.className = "card-top";

    var badge = document.createElement("span");
    badge.className = "badge badge-" + card.priority;
    var dot = document.createElement("span");
    dot.className = "dot";
    badge.appendChild(dot);
    badge.appendChild(document.createTextNode(card.priority));

    var del = document.createElement("button");
    del.className = "delete-btn";
    del.type = "button";
    del.title = "Delete card";
    del.setAttribute("aria-label", "Delete card: " + card.title);
    del.textContent = "\u00D7";
    del.addEventListener("click", function(e){
      e.stopPropagation();
      state = state.filter(function(c){ return c.id !== card.id; });
      render();
      showToast("Card deleted");
    });

    top.appendChild(badge);
    top.appendChild(del);

    var title = document.createElement("h3");
    title.className = "card-title";
    title.textContent = card.title;

    var meta = document.createElement("div");
    meta.className = "card-meta";
    var tag = document.createElement("span");
    tag.className = "tag";
    tag.textContent = card.tag || "General";
    var avatar = document.createElement("span");
    avatar.className = "avatar";
    avatar.textContent = card.assignee || "YO";
    avatar.title = card.assignee || "";
    meta.appendChild(tag);
    meta.appendChild(avatar);

    el.appendChild(top);
    el.appendChild(title);
    el.appendChild(meta);
    return el;
  }

  function render(){
    columns.forEach(function(col){
      var list = document.querySelector('.card-list[data-col="'+col+'"]');
      var countEl = document.getElementById("count-" + col);
      if(!list) return;
      list.innerHTML = "";
      var inCol = state.filter(function(c){ return c.column === col; });
      var visible = inCol.filter(function(c){ return c.title.toLowerCase().indexOf(query) !== -1; });
      if(countEl) countEl.textContent = inCol.length;
      visible.forEach(function(card, i){ list.appendChild(createCard(card, i)); });
      if(visible.length === 0){
        var empty = document.createElement("div");
        empty.className = "empty";
        empty.textContent = query ? "No matching cards" : "No cards here \u2014 drag one in";
        list.appendChild(empty);
      }
    });
    var total = state.length;
    var done = state.filter(function(c){ return c.column === "done"; }).length;
    var pct = total ? Math.round((done / total) * 100) : 0;
    document.getElementById("summaryText").textContent = done + " of " + total + " tasks done";
    document.getElementById("progressFill").style.width = pct + "%";
    document.getElementById("progressPct").textContent = pct + "%";
  }

  /* Drag & drop */
  function cleanupDrag(){
    dropIndicator.remove();
    document.querySelectorAll(".column").forEach(function(c){ c.classList.remove("drag-over"); });
    document.querySelectorAll(".card.dragging").forEach(function(c){ c.classList.remove("dragging"); });
  }
  function getAfter(list, y){
    var cards = Array.prototype.slice.call(list.querySelectorAll(".card:not(.dragging)"));
    for(var i=0;i<cards.length;i++){
      var r = cards[i].getBoundingClientRect();
      if(y <= r.top + r.height / 2) return cards[i];
    }
    return null;
  }
  function moveCard(id, targetCol, beforeId){
    if(!id) return;
    var from = -1;
    for(var i=0;i<state.length;i++) if(state[i].id === id){ from = i; break; }
    if(from === -1) return;
    var moved = state.splice(from,1)[0];
    moved.column = targetCol;
    var insertAt;
    if(beforeId){
      insertAt = state.length;
      for(var j=0;j<state.length;j++) if(state[j].id === beforeId){ insertAt = j; break; }
    } else {
      var last = -1;
      for(var k=0;k<state.length;k++) if(state[k].column === targetCol) last = k;
      insertAt = (last === -1) ? state.length : last + 1;
    }
    state.splice(insertAt, 0, moved);
  }

  document.querySelectorAll(".card-list").forEach(function(list){
    list.addEventListener("dragstart", function(e){
      var card = e.target.closest(".card");
      if(!card) return;
      draggingId = card.dataset.id;
      card.classList.add("dragging");
      if(e.dataTransfer){
        e.dataTransfer.effectAllowed = "move";
        try{ e.dataTransfer.setData("text/plain", draggingId); }catch(err){}
      }
    });
    list.addEventListener("dragover", function(e){
      e.preventDefault();
      if(e.dataTransfer) e.dataTransfer.dropEffect = "move";
      var after = getAfter(list, e.clientY);
      if(after) list.insertBefore(dropIndicator, after);
      else list.appendChild(dropIndicator);
      var col = list.closest(".column");
      if(col) col.classList.add("drag-over");
    });
    list.addEventListener("dragleave", function(e){
      if(!list.contains(e.relatedTarget)){
        dropIndicator.remove();
        var col = list.closest(".column");
        if(col) col.classList.remove("drag-over");
      }
    });
    list.addEventListener("drop", function(e){
      e.preventDefault();
      var next = dropIndicator.nextElementSibling;
      var beforeId = (next && next.classList.contains("card")) ? next.dataset.id : null;
      var col = list.dataset.col;
      var id = draggingId;
      cleanupDrag();
      draggingId = null;
      moveCard(id, col, beforeId);
      render();
    });
    list.addEventListener("dragend", function(){
      cleanupDrag();
      draggingId = null;
    });
  });

  /* Search */
  searchInput.addEventListener("input", function(){
    query = searchInput.value.trim().toLowerCase();
    clearSearch.style.display = searchInput.value ? "block" : "none";
    render();
  });
  clearSearch.addEventListener("click", function(){
    searchInput.value = "";
    query = "";
    clearSearch.style.display = "none";
    render();
    searchInput.focus();
  });

  /* Theme */
  themeToggle.addEventListener("click", function(){
    var root = document.documentElement;
    var next = root.getAttribute("data-theme") === "dark" ? "light" : "dark";
    root.setAttribute("data-theme", next);
    showToast(next === "dark" ? "Dark theme on" : "Light theme on");
  });

  /* Modal */
  function setPriority(p){
    selectedPriority = p;
    document.querySelectorAll(".prio-btn").forEach(function(b){
      b.classList.toggle("selected", b.dataset.priority === p);
    });
  }
  document.querySelectorAll(".prio-btn").forEach(function(b){
    b.addEventListener("click", function(){ setPriority(b.dataset.priority); });
  });
  function openModal(col){
    columnSelect.value = col || "todo";
    titleInput.value = "";
    titleInput.classList.remove("invalid");
    errorMsg.classList.remove("show");
    setPriority("medium");
    overlay.classList.add("open");
    setTimeout(function(){ titleInput.focus(); }, 60);
  }
  function closeModal(){
    overlay.classList.remove("open");
  }
  addCardBtn.addEventListener("click", function(){ openModal("todo"); });
  document.querySelectorAll(".col-add").forEach(function(b){
    b.addEventListener("click", function(){ openModal(b.dataset.col); });
  });
  closeModalBtn.addEventListener("click", closeModal);
  cancelBtn.addEventListener("click", closeModal);
  overlay.addEventListener("click", function(e){ if(e.target === overlay) closeModal(); });
  titleInput.addEventListener("input", function(){
    if(titleInput.value.trim()){ titleInput.classList.remove("invalid"); errorMsg.classList.remove("show"); }
  });
  form.addEventListener("submit", function(e){
    e.preventDefault();
    var title = titleInput.value.trim();
    if(!title){
      titleInput.classList.add("invalid");
      errorMsg.classList.add("show");
      titleInput.focus();
      return;
    }
    state.push({
      id: "c" + Date.now(),
      title: title,
      priority: selectedPriority,
      column: columnSelect.value,
      tag: "General",
      assignee: "YO"
    });
    closeModal();
    render();
    showToast("Card added");
  });

  /* Keyboard */
  document.addEventListener("keydown", function(e){
    var tag = (e.target.tagName || "").toLowerCase();
    var typing = tag === "input" || tag === "textarea" || tag === "select";
    if(e.key === "Escape"){ closeModal(); return; }
    if(e.key === "/" && !typing){ e.preventDefault(); searchInput.focus(); }
  });

  render();
})();
</script>
</body>
</html>
Reasoning trace (6,937 tokens)
Implementing vanilla HTML, CSS, and JavaScript Kanban board with drag-drop, modal form, search, theme toggle, and in-memory state.Extending the implementation with sample data, styling, and drag-drop event handling.Adding DOM-based rendering, drag-drop indicators, modal form validation, and theme toggle with responsive CSS.Implementing drag-and-drop state updates with column highlighting and modal form validation.Reusing a single drop indicator to prevent flicker and adding render logic with search filtering and empty states.Extending rendering with tag chips, avatars, theme toggle, modal, and responsive CSS and JS.Adding drag-and-drop handlers with drop indicator logic and empty-state edge cases.Finalizing UI styling, SVG icons, layout, animations, and initial state rendering.