Models 44

North Mini Code (free)

by CohereReasoningClean
Open in new window

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

How it went

Total time
1 min 13 s
Cost
$0
Output tokens
17,603
Spent thinking
14,851 tokens
Speed
241.8 tok/s
Console errors
0
First token after
275 ms
First visible text after
1 min 4 s
Prompt tokens
482
Code size
11.9 KB
Finish reason
stop
Served by
Cohere
Model id
cohere/north-mini-code:free
Reasoning sent
model default
Max output
32,000 tokens
Generated
Nov 9, 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 · 464 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Kanban Board</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* Reset some basics */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Theme variables */
:root {
  --bg-color: #f9f9f9;
  --text-color: #333;
  --column-bg: #fff;
  --header-bg: #e0e0e0;
  --border-color: #ddd;
  --badge-low: #28a745;
  --badge-medium: #ffc107;
  --badge-high: #dc3545;
}

/* Dark theme overrides */
body.dark {
  --bg-color: #1e1e1e;
  --text-color: #ddd;
  --column-bg: #2d2d2d;
  --header-bg: #3a3a3a;
  --border-color: #555;
}

/* Body & layout */
body {
  font-family: -apple-system, BlinkMacSystemUI, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background-color: var(--bg-color);
  color: var(--text-color);
  padding: 1rem;
  transition: background-color 0.3s, color 0.3s;
}

/* Header */
.app-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}
.app-header h1 {
  margin: 0;
  font-size: 1.5rem;
}
.controls {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
#search {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--column-bg);
  color: var(--text-color);
}
#add-card-btn {
  padding: 0.4rem 0.8rem;
  background: #007bff;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
#theme-toggle {
  background: none;
  border: none;
  font-size: 1.2rem;
  cursor: pointer;
  color: var(--text-color);
}

/* Kanban board */
.kanban-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
}

/* Column */
.column {
  background: var(--column-bg);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.column-header {
  background: var(--header-bg);
  padding: 0.75rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border-color);
}
.column-header .title {
  font-weight: 600;
}
.column-header .count {
  font-size: 0.9rem;
  opacity: 0.7;
}

/* Column body (drop zone) */
.column-body {
  flex: 1;
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 40px; /* give drop visual when empty */
}
.column-body.highlight {
  background-color: rgba(0,123,255,0.05);
  outline: 2px dashed #007bff;
}

/* Card */
.card {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: grab;
  position: relative;
}
.card:active {
  cursor: grabbing;
}
.card .info {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card .title-text {
  font-weight: 500;
  margin-right: 0.5rem;
}
.card .priority-badge {
  display: inline-block;
  padding: 0.2em 0.5em;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
}
.priority-low { background: var(--badge-low); color: #fff; }
.priority-medium { background: var(--badge-medium); color: #212529; }
.priority-high { background: var(--badge-high); color: #fff; }
.card .delete-btn {
  background: none;
  border: none;
  color: var(--text-color);
  font-weight: bold;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  opacity: 0.6;
}
.card .delete-btn:hover { opacity: 1; }

/* Modal overlay */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.modal-overlay[hidden] {
  display: none;
}
.modal {
  background: var(--column-bg);
  color: var(--text-color);
  padding: 1.5rem;
  border-radius: 8px;
  width: 90%;
  max-width: 400px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.modal h2 {
  margin-top: 0;
  font-size: 1.3rem;
}
.form-group {
  margin-bottom: 1rem;
}
.form-group label {
  display: block;
  margin-bottom: 0.3rem;
  font-weight: 600;
}
.form-group input,
.form-group select {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-color);
  color: var(--text-color);
}
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}
.modal-actions button {
  padding: 0.4rem 0.8rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.modal-actions button[type="submit"] {
  background: #007bff;
  color: #fff;
}
.modal-actions button[type="button"] {
  background: #6c757d;
  color: #fff;
}
</style>
</head>
<body>
<header class="app-header">
  <h1>Kanban Board</h1>
  <div class="controls">
    <input type="search" id="search" placeholder="Search cards...">
    <button id="add-card-btn">Add Card</button>
    <button id="theme-toggle" aria-label="Toggle theme">🌗</button>
  </div>
</header>

<div class="kanban-board"></div>

<div class="modal-overlay" hidden>
  <div class="modal">
    <h2>Add New Card</h2>
    <form id="add-card-form">
      <div class="form-group">
        <label for="card-title">Title</label>
        <input type="text" id="card-title" name="title" required>
      </div>
      <div class="form-group">
        <label for="card-priority">Priority</label>
        <select id="card-priority" name="priority">
          <option value="low">Low</option>
          <option value="medium">Medium</option>
          <option value="high">High</option>
        </select>
      </div>
      <div class="modal-actions">
        <button type="button" id="cancel-btn">Cancel</button>
        <button type="submit">Add</button>
      </div>
    </form>
  </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', () => {
  // Elements
  const searchInput = document.getElementById('search');
  const addCardBtn = document.getElementById('add-card-btn');
  const themeToggleBtn = document.getElementById('theme-toggle');
  const modalOverlay = document.querySelector('.modal-overlay');
  const modalForm = document.getElementById('add-card-form');
  const cancelBtn = document.getElementById('cancel-btn');
  const boardContainer = document.querySelector('.kanban-board');

  // Column definitions
  const columnDefs = [
    { id: 'todo', title: 'To do' },
    { id: 'inprogress', title: 'In progress' },
    { id: 'done', title: 'Done' }
  ];

  // Create column structure
  columnDefs.forEach(col => {
    const colEl = document.createElement('div');
    colEl.className = 'column';
    colEl.setAttribute('aria-label', col.title);
    colEl.innerHTML = `
      <div class="column-header">
        <span class="title">${col.title}</span>
        <span class="count">(0)</span>
      </div>
      <div class="column-body" data-col="${col.id}"></div>
    `;
    boardContainer.appendChild(colEl);
  });

  // Helper: create a card element
  function createCardEl({ title, priority }) {
    const card = document.createElement('div');
    card.className = 'card';
    card.draggable = true;
    card.innerHTML = `
      <div class="info">
        <span class="title-text">${title}</span>
        <span class="priority-badge ${priority === 'low' ? 'priority-low' : priority === 'medium' ? 'priority-medium' : 'priority-high'}">${priority}</span>
      </div>
      <button class="delete-btn" aria-label="Delete">×</button>
    `;
    return card;
  }

  // Initial cards data (6 cards)
  const initialCards = [
    { title: 'Design homepage mockups', priority: 'high', column: 'todo' },
    { title: 'Write API documentation', priority: 'medium', column: 'todo' },
    { title: 'Implement login feature', priority: 'high', column: 'inprogress' },
    { title: 'Fix responsive layout bug', priority: 'medium', column: 'inprogress' },
    { title: 'Update README', priority: 'low', column: 'done' },
    { title: 'Deploy to staging', priority: 'high', column: 'done' }
  ];

  // Render initial cards
  initialCards.forEach(data => {
    const cardEl = createCardEl(data);
    const targetColumn = document.querySelector(`.column-body[data-col="${data.column}"]`);
    targetColumn.appendChild(cardEl);

    // Delete button
    const delBtn = cardEl.querySelector('.delete-btn');
    delBtn.addEventListener('click', () => {
      cardEl.remove();
      updateAllCounts();
      filterCards(searchInput.value);
    });

    // Drag start
    cardEl.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', '');
      cardEl.classList.add('dragging');
    });
    // Drag end – clear highlight on all columns
    cardEl.addEventListener('dragend', () => {
      cardEl.classList.remove('dragging');
      document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
    });
  });

  // Update card counts in each column (visible only)
  function updateAllCounts() {
    document.querySelectorAll('.column-body').forEach(col => {
      const visibleCards = col.querySelectorAll('.card:not([style*="display: none"])');
      const countSpan = col.previousElementSibling.querySelector('.count');
      countSpan.textContent = `(${visibleCards.length})`;
    });
  }

  // Modal helpers
  function openModal() {
    modalOverlay.removeAttribute('hidden');
    document.getElementById('card-title').focus();
  }
  function closeModal() {
    modalOverlay.setAttribute('hidden', '');
    modalForm.reset();
  }

  addCardBtn.addEventListener('click', openModal);
  cancelBtn.addEventListener('click', closeModal);
  modalOverlay.addEventListener('click', e => {
    if (e.target === modalOverlay) closeModal();
  });

  // Add new card from modal
  modalForm.addEventListener('submit', e => {
    e.preventDefault();
    const title = document.getElementById('card-title').value.trim();
    if (!title) return;
    const priority = document.getElementById('card-priority').value;
    const cardEl = createCardEl({ title, priority });
    const targetColumn = document.querySelector('.column-body[data-col="todo"]');
    targetColumn.appendChild(cardEl);

    // Attach delete & drag listeners for the new card
    const delBtn = cardEl.querySelector('.delete-btn');
    delBtn.addEventListener('click', () => {
      cardEl.remove();
      updateAllCounts();
      filterCards(searchInput.value);
    });
    cardEl.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', '');
      cardEl.classList.add('dragging');
    });
    cardEl.addEventListener('dragend', () => {
      cardEl.classList.remove('dragging');
      document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
    });

    closeModal();
    updateAllCounts();
    filterCards(searchInput.value);
  });

  // Drag & drop handling
  document.querySelectorAll('.column-body').forEach(col => {
    col.addEventListener('dragover', e => {
      e.preventDefault();
      col.classList.add('highlight');
    });
    col.addEventListener('dragleave', () => {
      col.classList.remove('highlight');
    });
    col.addEventListener('drop', e => {
      e.preventDefault();
      const draggingCard = document.querySelector('.card.dragging');
      if (!draggingCard) return;
      col.classList.remove('highlight');
      const previousParent = draggingCard.parentElement;
      if (previousParent !== col) {
        col.appendChild(draggingCard);
        updateAllCounts();
        filterCards(searchInput.value);
      }
    });
  });

  // Search filter
  function filterCards(query) {
    const lower = query.toLowerCase();
    document.querySelectorAll('.card').forEach(card => {
      const title = card.querySelector('.title-text').textContent;
      const match = title.toLowerCase().includes(lower);
      card.style.display = match ? '' : 'none';
    });
    updateAllCounts();
  }
  searchInput.addEventListener('input', e => filterCards(e.target.value));

  // Theme toggle
  themeToggleBtn.addEventListener('click', () => {
    document.body.classList.toggle('dark');
  });

  // Initial counts
  updateAllCounts();
});
</script>
</body>
</html>
Reasoning trace (14,851 tokens)
We need to generate a self-contained HTML page that includes everything inline. It should meet the requirements:

- Kanban board with three columns: To do, In progress, Done, each showing its card count.
- Prepopulate with 6 realistic cards across columns.
- Each card has title and priority shown as a colored badge (low, medium, high).
- Add a card via a small modal form (title required). Probably a form with title input and maybe priority selection? It says only title required; could have optional priority default to low? It might be optional. But we could let the user pick priority as a select (low/medium/high) to provide more info.
- Delete a card with a button on it.
- Drag and drop cards between columns with mouse, with clear visual drop indicator.
- Search field that filters cards live by title.
- Light/dark theme toggle.
- State lives in memory only (no storage APIs). So on page reload the data will be lost.

Constraints: Output must be exactly ONE fenced code block (```html). No extra text.

We need to write HTML, CSS, JS inlined.

The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. Must have meaningful content on first paint. The board should be visible instantly.

The demo must be self-playing behind a "Click or press a	protected"? Actually it's not a game; it's UI. So no requirement for game start message. But "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." There's no keyboard usage except maybe focus on search. So it's okay.

But we need to ensure that if there is any focus on input, we need to display that message. Might just not use keyboard focus but we could show message if keyboard events are used for moving cards? Not needed.

Anyway, we can implement.

Let's design:

- At the top: search field and theme toggle. Maybe a header with search input and theme button.

- Board container: three columns as flex containers or CSS grid.

- Each column is a section with a header: column title and count (like "To do (2)"). Use a badge for count maybe.

- Cards: div with class card. Show title text, and a small badge for priority. Badges: low = green, medium = orange, high = red.

- Card includes a delete button (maybe an 'x' icon) that removes the card.

- Modal: small overlay with a form. Title input required, maybe priority select optional. Buttons: Cancel and Add. Clicking Add will create a new card in the "To do" column (or maybe default column). Then close modal.

- Drag and drop: Use HTML5 drag and drop. We'll need to add draggable attributes to cards, handle dragstart, dragover, drop events on columns. Provide visual drop indicator (e.g., a highlighted area on the column when dragging over). Show card count updates.

- Filtering: search field filters cards across all columns. The cards that don't match title are hidden (display: none) while preserving layout? Usually show only matching cards. To keep layout simple, we can hide them via class "filtered-out". Should also update counts to show only visible cards per column? It says each column shows its card count. Might show total cards in column (including filtered?). Typically filtered count only visible cards. We'll implement counts based on visible cards.

- Light/dark theme: CSS variables for colors, toggle via button to swap class on body or root. We'll store theme preference in local memory? But requirement says state lives in memory only, but we can still toggle visually without persistent storage. However, typical theme toggles can just toggle a class, not using storage. That's fine. But the state is memory only; not persistent across reloads is okay.

- The page must be self-contained and run with zero errors.

- Prepopulate: six cards with realistic titles. For example:

To do: "Design homepage mockups", "Write API documentation", "Plan sprint" (maybe 3). Each with different priority.

In progress: "Implement login feature", "Fix responsive layout bug". Done: "Update README", "Deploy to staging". That makes 6.

- We need to ensure cards have distinct priority: low, medium, high.

Implementation details:

HTML skeleton:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Kanban Board</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
 ... CSS ...
</style>
</head>
<body>
... HTML ...
<script>
 ... JS ...
</script>
</body>
</html>
```

Add a container for UI controls: <header class="controls"> with search input and theme toggle button.

Add modal overlay: <div class="modal-overlay" hidden> containing <form> with input for title and select for priority, and buttons.

Add board: <div class="kanban-board"> with three columns: .column (To do, In progress, Done). In each column, <div class="column-header"> title and count. Inside <div class="column-body"> contains cards in order (maybe using flex column). Use CSS to handle drop zones: .column-body.highlight when dragging over.

Drag and drop implementation:

- On dragstart: set dataTransfer.setData("text/plain", card.id) or index? We'll store card element reference and maybe column.

- On dragover: prevent default, add highlight class to column body.

- On drop: get card; remove from its current column; append to target column's column-body; after drop, update counts; also update filtered list if needed.

Make sure we handle that dropping into a column updates order; maybe we can just move card.

Search filter:

- Search input: on input, get value; for each card element, check if title includes filter (case-insensitive). If matches, set card.style.display = ''; else card.style.display = 'none'.

- When filter changes, also update counts per column: maybe the count includes only visible cards. So each column's count should be dynamic: update when filter changes or when cards added/removed.

- Modal: when form submitted, prevent default, get title and priority (optional). If title empty, show error (maybe inline). If ok, create new card element, add to To do column (by default). Then close modal.

- Delete: each card has a delete button (maybe <button class="delete-btn" aria-label="Delete">×</button>) that removes card on click.

- Theme toggle: button toggles class 'dark' on body (or root). Use CSS variables for background, text, column backgrounds, etc.

- Ensure adaptiveness: use CSS variables for spacing; flex-wrap; columns on small screens maybe stack? It says adapt gracefully down to 375px; we can make columns flex column with width: 100% at small breakpoints; but we can just make them horizontal with min-width, and if not enough space, they may wrap. But the board container could become scrollable horizontally? Avoid horizontal scrollbar: on small screens, maybe columns stack vertically to fit. Let's design using CSS Grid: at desktop, three columns; on medium, two columns; on mobile, one column. Use media queries. Use container: .kanban-board { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; } This will adapt.

But we also need visual drop indicator: highlight column-body when dragging over. Use .column-body.highlight { background-color: rgba(0,0,0,0.05); border: 2px dashed #007bff; } maybe.

Let's write the CSS.

We'll also include a reset (simple). Use CSS custom properties for theme.

Light theme defaults: background #f9f9f9, text #333, column background #fff, header background #e0e0e0, badge colors: low green (#28a745), medium orange (#ffc107), high red (#dc3545). For dark theme: background #1e1e1e, text #ddd, column background #2d2d2d, header background #3a3a3a, badge colors same but maybe slightly lighter.

Add a transition for background and color.

Add scrollbar styling? Not needed.

Focus: hide default outline for draggable? Use user-select? We'll just let default.

Implement JS logic:

- Data model: we could store cards in a simple array of objects, but we can also derive from DOM. However, we need to update counts and filter. We'll just use DOM.

Define functions:

- createCardElement({title, priority}) returns HTMLDivElement.

- updateColumnCounts(): for each column-body, count visible cards (display != 'none'), set column-header text accordingly.

- filterCards(query): set each card's display accordingly, then update counts.

- handleModalOpen(): show modal, focus title input.

- handleModalClose(): hide modal.

- handleAddCard(e): prevent default, get title and priority, validate title not empty, create card, add to To do column (maybe first column), close modal.

- handleDeleteButton(e): remove card element, update counts.

- drag events: attach to cards.

Implement.

Also, implement a "Click or press a key to start" message if keyboard usage? Not needed. But the requirement states: "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." Our board may not use keyboard (maybe search input uses keyboard). So we might need to enforce that before using search, we need to click board. But that is more complicated. Actually the requirement: "The iframe only receives keyboard events after the user clicks it". In a sandbox, clicking the iframe is required to send keyboard events. Since we are in a code block, not actual iframe. But we just need to ensure the page doesn't try to capture keyboard before click. Usually you can add an event listener for keydown to move cards via keyboard? But not needed. However, we have a search input that will receive keyboard events. That might be considered as using keyboard before clicking. The requirement says if the demo uses the keyboard, display a clear "Click or press a key to start" message. So to be safe, we can add a global message overlay that says "Click to start" and when user clicks anywhere, we hide it and allow keyboard interaction (focus). But the requirement also says "Click or press a key to start". So we could show a message overlay initially that says "Click or press any key to start". When user clicks or presses any key, we hide it. Then we can allow keyboard events. But the page should look alive on first paint, so that overlay should be visible initially, then after click, it's removed. However, the requirement: "Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction." If we have an overlay blocking interaction, the board may not be visible on first paint, which may be problematic. So maybe we need to show the board on first paint, and also show a "Click or press a key to start" message for keyboard features. But we aren't using keyboard features. So maybe we can ignore it. The requirement is conditional: "if the demo uses the keyboard, display a clear "Click or press a key to start" message". Our demo does not use keyboard for any core functionality; only search input can be focused with mouse. So we can skip this.

Thus we can not include any global start message.

Now ensure the code runs without errors.

Now generate the final code block.

We'll write HTML:

```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Kanban Board</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* CSS */
</style>
</head>
<body>
<header class="app-header">
  <h1>Kanban Board</h1>
  <div class="controls">
    <input type="search" id="search" placeholder="Search cards...">
    <button id="theme-toggle" aria-label="Toggle theme">🌗</button>
  </div>
</header>

<div class="kanban-board" role="main">
  <!-- columns will be generated by JS? Or static? We can write static columns and then add cards via JS -->
</div>

<div class="modal-overlay" hidden>
  <div class="modal">
    <h2>Add New Card</h2>
    <form id="add-card-form">
      <div class="form-group">
        <label for="card-title">Title</label>
        <input type="text" id="card-title" name="title" required>
      </div>
      <div class="form-group">
        <label for="card-priority">Priority</label>
        <select id="card-priority" name="priority">
          <option value="low">Low</option>
          <option value="medium">Medium</option>
          <option value="high">High</option>
        </select>
      </div>
      <div class="modal-actions">
        <button type="button" id="cancel-btn">Cancel</button>
        <button type="submit">Add</button>
      </div>
    </form>
  </div>
</div>

<button class="add-column-btn" id="add-card-btn">+ Add Card</button>

<script>
/* JS */
</script>
</body>
</html>
```

Now static columns:

We can have three column divs like:

```
<div class="column">
  <div class="column-header">
    <span class="title">To do</span>
    <span class="count">(0)</span>
  </div>
  <div class="column-body" data-col="todo"></div>
</div>
...
```

But we also need to prepopulate with cards. Instead of creating them via JS initially, we can create them in JS after DOM loaded, so they are present from load. Or we can embed them in HTML but better to generate via JS to show initial state. However, static HTML is fine.

But the requirement: "Pre-populate the board with 6 realistic cards spread across the columns so the first screenshot looks alive." We need the cards present initially, not via modal. So we can create them in JS on page load, after DOM ready.

Thus we can create the board structure in JS, not in static HTML. That simplifies.

So we can have <div class="kanban-board"></div> empty. Then in JS we create columns and cards. That ensures initial state.

Let's structure JS:

On DOMContentLoaded:

- createBoard() function.

- Create columns array: ["To do","In progress","Done"].

- For each column, create column div with header and column-body.

- Append to .kanban-board.

- Then create initial cards: define array of card objects with title, priority, column.

- For each, create card element and append to appropriate column-body.

- Update counts.

- Attach event listeners for delete, drag, etc.

- Also attach search input listener.

- Attach theme toggle.

- Attach modal open and close.

Focus: The modal should be triggered by a button "Add Card". We can add a button outside board, maybe at top. There's also requirement: "Add a card through a small modal form (title required)". So we need a button to open the modal. Could be a global "Add Card" button at top.

Thus in HTML we need a button with id="add-card-btn". But we also have modal overlay.

Thus implement:

- The "Add Card" button opens modal (click event) and hides overlay.

- Modal form has title required input, optional priority.

- On form submit, create new card with title and priority, add to "To do" column (or maybe whichever column? Typically new cards go to "To do").

- Delete button: within card, small '×' button.

- Drag and drop: add draggable attribute to cards, and set dataTransfer setData to something like "text/plain", maybe card id.

- Use column-body as drop zones. Add dragover and drop listeners.

- Provide drop indicator: add class "highlight" to column-body when dragging over.

- Use CSS to style highlight.

- Search: input with id "search". On input event, filter cards based on title.

- Count updates for each column reflect visible cards.

- Theme toggle: a button with id "theme-toggle". On click, toggle class 'dark' on body (or <html>).

- Ensure everything uses inline CSS.

Now we need to ensure the page looks good.

Let's write CSS.

We'll use CSS variables for colors:

:root {
  --bg-color: #f9f9f9;
  --text-color: #333;
  --column-bg: #fff;
  --header-bg: #e0e0e0;
  --border-color: #ddd;
  --badge-low: #28a745;
  --badge-medium: #ffc107;
  --badge-high: #dc3545;
}

body.dark {
  --bg-color: #1e1e1e;
  --text-color: #ddd;
  --column-bg: #2d2d2d;
  --header-bg: #3a3a3a;
  --border-color: #555;
}

body {
  font-family: -apple-system, BlinkMacSystemUI, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  background-color: var(--bg-color);
  color: var(--text-color);
  margin: 0;
  padding: 1rem;
  transition: background-color 0.3s, color 0.3s;
}

/* App header */
.app-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.app-header h1 {
  margin: 0;
  font-size: 1.5rem;
}

.controls {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

#search {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--column-bg);
  color: var(--text-color);
}

#theme-toggle {
  background: none;
  border: none;
  font-size: 1.2rem;
  cursor: pointer;
  color: var(--text-color);
}

/* Kanban board layout */
.kanban-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
}

.column {
  background: var(--column-bg);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}

.column-header {
  background: var(--header-bg);
  padding: 0.75rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border-color);
}

.column-header .title {
  font-weight: 600;
}

.column-header .count {
  font-size: 0.9rem;
  opacity: 0.7;
}

/* Cards */
.column-body {
  flex: 1;
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 40px; /* allow drop indicator when empty */
}

.card {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: grab;
  position: relative;
}

.card:active {
  cursor: grabbing;
}

.card .info {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card .title-text {
  font-weight: 500;
  margin-right: 0.5rem;
}

.card .priority-badge {
  display: inline-block;
  padding: 0.2em 0.5em;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
}

.priority-low { background: var(--badge-low); color: #fff;}
.priority-medium { background: var(--badge-medium); color: #212529;}
.priority-high { background: var(--badge-high); color: #fff;}

.card .delete-btn {
  background: none;
  border: none;
  color: var(--text-color);
  font-weight: bold;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  opacity: 0.6;
}
.card .delete-btn:hover { opacity: 1; }

/* Drop indicator */
.column-body.highlight {
  background-color: rgba(0,123,255,0.05);
  outline: 2px dashed #007bff;
}

/* Modal overlay */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-overlay[hidden] {
  display: none;
}

.modal {
  background: var(--column-bg);
  color: var(--text-color);
  padding: 1.5rem;
  border-radius: 8px;
  width: 90%;
  max-width: 400px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}

.modal h2 {
  margin-top: 0;
  font-size: 1.3rem;
}

.form-group {
  margin-bottom: 1rem;
}

.form-group label {
  display: block;
  margin-bottom: 0.3rem;
  font-weight: 600;
}

.form-group input,
.form-group select {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-color);
  color: var(--text-color);
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

.modal-actions button {
  padding: 0.4rem 0.8rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.modal-actions button[type="submit"] {
  background: #007bff;
  color: #fff;
}

.modal-actions button[type="button"] {
  background: #6c757d;
  color: #fff;
}

/* Add card button */
.add-column-btn {
  margin-top: 1rem;
  padding: 0.5rem 1rem;
  background: #28a745;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  align-self: flex-start;
}
```

But we need to add button to open modal. We'll place the "Add Card" button before board or after.

Maybe place a button outside board: "Add Card". Since there is also a "add-column-btn"? Actually requirement says "Add a card through a small modal form (title required)". There's no requirement for an "Add Card" button but we need a way to open modal. So we add a button at top, maybe next to search.

Simplify: In header, we can have "Add Card" button as part of controls.

Let's modify HTML header: add <button id="add-card-btn" aria-label="Add card">Add Card</button>.

Thus header:

```
<header class="app-header">
  <h1>Kanban Board</h1>
  <div class="controls">
    <input type="search" id="search" placeholder="Search cards...">
    <button id="add-card-btn">Add Card</button>
    <button id="theme-toggle" aria-label="Toggle theme">🌗</button>
  </div>
</header>
```

So we remove the separate button at bottom.

Now we need to adjust CSS for .controls button style.

We'll keep simple.

Now implementation of JS.

We'll start:

```
document.addEventListener('DOMContentLoaded', () => {
  const searchInput = document.getElementById('search');
  const addCardBtn = document.getElementById('add-card-btn');
  const themeToggleBtn = document.getElementById('theme-toggle');
  const modalOverlay = document.querySelector('.modal-overlay');
  const modalForm = document.getElementById('add-card-form');
  const cancelBtn = document.getElementById('cancel-btn');
  const columnHeadersContainer = document.querySelector('.kanban-board');

  // Column definitions
  const columnDefs = [
    { id: 'todo', title: 'To do' },
    { id: 'inprogress', title: 'In progress' },
    { id: 'done', title: 'Done' }
  ];

  // Create columns
  columnDefs.forEach(col => {
    const colEl = document.createElement('div');
    colEl.className = 'column';
    colEl.setAttribute('aria-label', col.title);
    colEl.innerHTML = `
      <div class="column-header">
        <span class="title">${col.title}</span>
        <span class="count">(0)</span>
      </div>
      <div class="column-body" data-col="${col.id}"></div>
    `;
    columnHeadersContainer.appendChild(colEl);
  });

  // Initialize cards
  const initialCards = [
    { title: 'Design homepage mockups', priority: 'high', column: 'todo' },
    { title: 'Write API documentation', priority: 'medium', column: 'todo' },
    { title: 'Plan sprint', priority: 'low', column: 'todo' },
    { title: 'Implement login feature', priority: 'high', column: 'inprogress' },
    { title: 'Fix responsive layout bug', priority: 'medium', column: 'inprogress' },
    { title: 'Update README', priority: 'low', column: 'done' },
    { title: 'Deploy to staging', priority: 'high', column: 'done' }
  ];

  // Card creation function
  function createCardEl({title, priority}) {
    const card = document.createElement('div');
    card.className = 'card';
    card.draggable = true;
    card.innerHTML = `
      <div class="info">
        <span class="title-text">${title}</span>
        <span class="priority-badge ${priority === 'low' ? 'priority-low' : priority === 'medium' ? 'priority-medium' : 'priority-high'}">${priority}</span>
      </div>
      <button class="delete-btn" aria-label="Delete">×</button>
    `;
    return card;
  }

  // Render initial cards
  initialCards.forEach(data => {
    const cardEl = createCardEl(data);
    const targetColumn = document.querySelector(`.column-body[data-col="${data.column}"]`);
    targetColumn.appendChild(cardEl);
    // Attach delete
    const delBtn = cardEl.querySelector('.delete-btn');
    delBtn.addEventListener('click', () => {
      cardEl.remove();
      updateAllCounts();
      filterCards(searchInput.value);
    });
    // Attach drag start
    cardEl.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', '');
      cardEl.classList.add('dragging');
    });
    cardEl.addEventListener('dragend', () => {
      cardEl.classList.remove('dragging');
      // remove highlight from all column bodies
      document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
    });
  });

  // Update counts for all columns
  function updateAllCounts() {
    document.querySelectorAll('.column-body').forEach(col => {
      const visibleCards = col.querySelectorAll('.card:not([style*="display: none"])');
      const countSpan = col.previousElementSibling.querySelector('.count');
      countSpan.textContent = `(${visibleCards.length})`;
    });
  }

  // Modal handling
  function openModal() {
    modalOverlay.removeAttribute('hidden');
    document.getElementById('card-title').focus();
  }
  function closeModal() {
    modalOverlay.setAttribute('hidden', '');
    modalForm.reset();
  }
  addCardBtn.addEventListener('click', openModal);
  cancelBtn.addEventListener('click', closeModal);
  modalOverlay.addEventListener('click', (e) => {
    if (e.target === modalOverlay) closeModal();
  });

  modalForm.addEventListener('submit', (e) => {
    e.preventDefault();
    const title = document.getElementById('card-title').value.trim();
    if (!title) return;
    const priority = document.getElementById('card-priority').value;
    const cardEl = createCardEl({title, priority});
    const targetColumn = document.querySelector('.column-body[data-col="todo"]');
    targetColumn.appendChild(cardEl);
    // Attach delete and drag events
    const delBtn = cardEl.querySelector('.delete-btn');
    delBtn.addEventListener('click', () => {
      cardEl.remove();
      updateAllCounts();
      filterCards(searchInput.value);
    });
    cardEl.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', '');
      cardEl.classList.add('dragging');
    });
    cardEl.addEventListener('dragend', () => {
      cardEl.classList.remove('dragging');
      document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
    });
    closeModal();
    updateAllCounts();
    filterCards(searchInput.value);
  });

  // Drag and drop handling
  document.querySelectorAll('.column-body').forEach(col => {
    col.addEventListener('dragover', (e) => {
      e.preventDefault();
      col.classList.add('highlight');
    });
    col.addEventListener('dragleave', () => {
      col.classList.remove('highlight');
    });
    col.addEventListener('drop', (e) => {
      e.preventDefault();
      const draggingCard = document.querySelector('.card.dragging');
      if (!draggingCard) return;
      col.classList.remove('highlight');
      // Ensure the card is removed from its current parent
      const previousParent = draggingCard.parentElement;
      if (previousParent !== col) {
        col.appendChild(draggingCard);
        updateAllCounts();
        filterCards(searchInput.value);
      }
    });
  });

  // Search filtering
  function filterCards(query) {
    const lower = query.toLowerCase();
    document.querySelectorAll('.card').forEach(card => {
      const title = card.querySelector('.title-text').textContent;
      const match = title.toLowerCase().includes(lower);
      card.style.display = match ? '' : 'none';
    });
    updateAllCounts();
  }
  searchInput.addEventListener('input', (e) => filterCards(e.target.value));

  // Theme toggle
  themeToggleBtn.addEventListener('click', () => {
    document.body.classList.toggle('dark');
  });

  // Initial counts
  updateAllCounts();
});
```

But we have an issue: document.body is not defined (body is a property of document). So we should use document.body.

Also, we need to import the CSS variables for dark class. The toggle should apply 'dark' class to <body> or <html>. We'll do body.

The CSS includes `.dark` style definitions.

Need to ensure that CSS code for .dark defines correct variables? In my earlier CSS, I defined `--bg-color` etc, and set .dark to update variables. But we need to ensure .dark is defined. Actually I had:

```
body.dark {
  --bg-color: #1e1e1e;
  --text-color: #ddd;
  --column-bg: #2d2d2d;
  --header-bg: #3a3a3a;
  --border-color: #555;
}
```

But we also need to define .dark .priority-badge? Not needed.

Now need to adjust CSS for .add-column-btn? Actually we removed that button; we have addCardBtn. So we need to adjust CSS for addCardBtn accordingly.

Let's refine CSS for the "Add Card" button (same as .add-column-btn style). We'll rename CSS to .add-card-btn.

But we used `addCardBtn` in JS for opening modal. So we need consistent class.

In HTML we have `<button id="add-card-btn">Add Card</button>`.

We can style it similarly:

```
#add-card-btn {
  padding: 0.4rem 0.8rem;
  background: #007bff;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
```

But we also might want a separate style for the button. It's fine.

Now we must ensure no errors. Let's go through entire code and test logic.

### HTML

We need a proper DOCTYPE and `<html>` etc.

The CSS style block will have many rules.

Make sure we have appropriate selectors. Ensure that all elements used in JS exist: `#search`, `#add-card-btn`, `#theme-toggle`, `.modal-overlay`, `#add-card-form`, `#cancel-btn`, `.kanban-board`, etc.

We also used `.modal-overlay[hidden]` attribute; we set hidden attribute in JS via `setAttribute('hidden','')`. That is correct.

Now, we need to ensure that the modal overlay is initially hidden. Using `hidden` attribute in HTML is okay, but we need to define it in HTML. So we need `<div class="modal-overlay" hidden>`.

Now check code for errors:

- In CSS, there is `.add-column-btn` but we might not need that class. We can remove that CSS, but it's okay.

- The CSS for .add-column-btn uses background #28a745 etc. Not used.

But we have button `#add-card-btn` not targeted by CSS, so its style may be default (blue). We can add a style for it.

Better to include style for #add-card-btn.

Let's modify CSS to include:

```
#add-card-btn {
  padding: 0.4rem 0.8rem;
  background: #007bff;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
```

Thus no conflict.

Now let's finalize CSS.

Now check JS for errors.

In JS, we have `const columnHeadersContainer = document.querySelector('.kanban-board');` - but we used variable `columnHeadersContainer` but then we used `columnHeadersContainer.appendChild(colEl);` Actually variable name is `columnHeadersContainer`. In code we defined:

```
const columnHeadersContainer = document.querySelector('.kanban-board');
```

But then later:

```
columnHeadersContainer.appendChild(colEl);
```

That is fine.

But after that we also have some leftover variable: there is a variable `columnHeadersContainer` but we used `columnHeadersContainer` - it's correct.

Now I see an error: after creating columns, we also referenced `columnHeadersContainer` incorrectly in initial comment: maybe we had leftover comment.

Now let's check entire JS carefully.

We have:

```
document.addEventListener('DOMContentLoaded', () => {
  const searchInput = document.getElementById('search');
...
  const columnHeadersContainer = document.querySelector('.kanban-board');

  // Column definitions
...
  columnDefs.forEach(col => {
    const colEl = document.createElement('div');
    colEl.className = 'column';
    colEl.setAttribute('aria-label', col.title);
    colEl.innerHTML = `
      <div class="column-header">
        <span class="title">${col.title}</span>
        <span class="count">(0)</span>
      </div>
      <div class="column-body" data-col="${col.id}"></div>
    `;
    columnHeadersContainer.appendChild(colEl);
  });

  // Initialize cards
...
});
```

Everything seems okay.

Now we need to make sure that the function `createCardEl` uses backticks correctly; yes.

Now check that `cardEl.querySelector('.delete-btn')` is correct. In card element we have class `delete-btn`. Yes.

Now check that `cardEl.addEventListener('dragstart', (e) => { e.dataTransfer.setData('text/plain', ''); cardEl.classList.add('dragging'); });` is correct.

One issue: In dragstart we set data to empty string. Typically we set data to card id. It's fine.

Now check the "drop" event handling: we have:

```
col.addEventListener('drop', (e) => {
  e.preventDefault();
  const draggingCard = document.querySelector('.card.dragging');
  if (!draggingCard) return;
  col.classList.remove('highlight');
  const previousParent = draggingCard.parentElement;
  if (previousParent !== col) {
    col.appendChild(draggingCard);
    updateAllCounts();
    filterCards(searchInput.value);
  }
});
```

But the variable `previousParent` is defined but not used? Actually it's defined but not used; we may use it for something else, but it's okay.

We might also want to remove highlight after drop on the column where card came from? Actually we remove highlight from col only. Should also remove from other columns? We remove after drop. But the dragenter events might not be triggered; it's fine.

But the drop event for all columns is attached. We remove highlight from the target column. However, we might also want to remove highlight from all columns on dragend. We already have dragend handler that removes class "dragging" and also loops to remove highlight from all columns: we have:

```
cardEl.addEventListener('dragend', () => {
  cardEl.classList.remove('dragging');
  document.query নির্বাচন('.column-body').forEach(col => col.classList.remove('highlight');
});
```

But we wrote `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));`. That is correct.

Now we need to ensure that the variable name in that part is correct. In JS we wrote:

```
cardEl.addEventListener('dragend', () => {
  cardEl.classList.remove('dragging');
  document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
});
```

But we used a typo: "querySelectorAll" vs "querySelectorAll". We wrote `querySelectorAll` but we need `querySelectorAll`. In the code we wrote earlier: `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));` It seems we have a stray "検索"? Let's scroll up.

The code snippet we wrote for dragend is:

```
cardEl.addEventListener('dragend', () => {
  cardEl.classList.remove('dragging');
  document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
});
```

That is correct: `document.querySelectorAll` but it's `document.querySelectorAll`? It should be `document.querySelectorAll`. Actually we wrote `document.querySelectorAll`. That is correct.

But earlier we wrote `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));` with `querySelectorAll`. Yes, it's fine.

Now we need to ensure we used consistent naming. We have a stray part where we used `document.querySelectorAll`. That's fine.

Now check the `themeToggleBtn` event:

```
themeToggleBtn.addEventListener('click', () => {
  document.body.classList.toggle('dark');
});
```

But we used `document.body`. Actually `document.body` is correct. So that's fine.

Now check if there are any undefined variables. E.g., we used `updateAllCounts` inside functions. That's defined.

Now we need to consider the scenario when the board is empty after filter, the column-body still has min-height etc.

Also, we need to ensure that the column header and count display correctly. Count shows the count of visible cards.

One nuance: The column header count includes only visible cards (since we update after filter). Yes, `updateAllCounts` uses `.card:not([style*="display: none"])`. That's fine.

Now confirm that the "Add Card" button opens the modal. In modal, after adding a card, we call `filterCards(searchInput.value);` and `updateAllCounts();`. That works.

Now verify that the modal overlay is hidden after adding a card. The `closeModal` sets attribute hidden. Good.

Now verify that we attached event listeners for delete button after initial card creation and after new card addition. Yes.

Now verify that after dragging, we call `updateAllCounts()` and `filterCards(searchInput.value)`. Should be fine.

Now test if any missing imports: No external files.

Now check for any console errors: For vanilla JS, we have many querySelectorAll calls, but they should find elements.

Potential errors: In the CSS, there is a stray comment: we have `.add-column-btn` but we never used it. It's okay.

But there may be a syntax error: In CSS we used `.add-column-btn` and later we used `#add-card-btn`. There is no syntax error.

Now we need to ensure that the `<style>` block is correctly formatted. Use proper CSS syntax.

Now ensure that we have a proper `<title>` and viewport meta tag.

Now let's rewrite the full code in a single fenced block.

We need to ensure the code is all inline, no external dependencies.

Now produce the final answer.

We must output only ONE fenced code block starting with ```html and ending with ```.

Let's construct final code. We'll carefully put everything inside.

We'll include the CSS inside `<style>` tags. We'll do proper indentation.

Let's write the final code.

I will compose it.

---

After writing final code, I'll double-check for any missing semicolons, stray characters.

I'll re-write in a clean way.

Let's start with the HTML skeleton:

```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-()));

Oops, I typed an error: I'm not finished. Let's produce full code carefully.

Write step by step.

I will manually generate final code.

Here is the final code:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Kanban Board</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* Reset some basics */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Theme variables */
:root {
  --bg-color: #f9f9f9;
  --text-color: #333;
  --column-bg: #fff;
  --header-bg: #e0e0e0;
  --border-color: #ddd;
  --badge-low: #28a745;
  --badge-medium: #ffc107;
  --badge-high: #dc3545;
}

/* Dark theme overrides */
body.dark {
  --bg-color: #1e1e1e;
  --text-color: #ddd;
  --column-bg: #2d2d2d;
  --header-bg: #3a3a3a;
  --border-color: #555;
}

/* Body & layout */
body {
  font-family: -apple-system, BlinkMacSystemUI, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background-color: var(--bg-color);
  color: var(--text-color);
  padding: 1rem;
  transition: background-color 0.3s, color 0.3s;
}

/* Header */
.app-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}
.app-header h1 {
  margin: 0;
  font-size: 1.5rem;
}
.controls {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
#search {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--column-bg);
  color: var(--text-color);
}
#add-card-btn {
  padding: 0.4rem 0.8rem;
  background: #007bff;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
#theme-toggle {
  background: none;
  border: none;
  font-size: 1.2rem;
  cursor: pointer;
  color: var(--text-color);
}

/* Kanban board */
.kanban-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
}

/* Column */
.column {
  background: var(--column-bg);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.column-header {
  background: var(--header-bg);
  padding: 0.75rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border-color);
}
.column-header .title {
  font-weight: 600;
}
.column-header .count {
  font-size: 0.9rem;
  opacity: 0.7;
}

/* Column body (drop zone) */
.column-body {
  flex: 1;
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 40px; /* give drop visual when empty */
}
.column-body.highlight {
  background-color: rgba(0,123,255,0.05);
  outline: 2px dashed #007bff;
}

/* Card */
.card {
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: grab;
  position: relative;
}
.card:active {
  cursor: grabbing;
}
.card .info {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card .title-text {
  font-weight: 500;
  margin-right: 0.5rem;
}
.card .priority-badge {
  display: inline-block;
  padding: 0.2em 0.5em;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
}
.priority-low { background: var(--badge-low); color: #fff; }
.priority-medium { background: var(--badge-medium); color: #212529; }
.priority-high { background: var(--badge-high); color: #fff; }
.card .delete-btn {
  background: none;
  border: none;
  color: var(--text-color);
  font-weight: bold;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  opacity: 0.6;
}
.card .delete-btn:hover { opacity: 1; }

/* Modal overlay */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.modal-overlay[hidden] {
  display: none;
}
.modal {
  background: var(--column-bg);
  color: var(--text-color);
  padding: 1.5rem;
  border-radius: 8px;
  width: 90%;
  max-width: 400px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.modal h2 {
  margin-top: 0;
  font-size: 1.3rem;
}
.form-group {
  margin-bottom: 1rem;
}
.form-group label {
  display: block;
  margin-bottom: 0.3rem;
  font-weight: 600;
}
.form-group input,
.form-group select {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-color);
  color: var(--text-color);
}
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}
.modal-actions button {
  padding: 0.4rem 0.8rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.modal-actions button[type="submit"] {
  background: #007bff;
  color: #fff;
}
.modal-actions button[type="button"] {
  background: #6c757d;
  color: #fff;
}
</style>
</head>
<body>
<header class="app-header">
  <h1>Kanban Board</h1>
  <div class="controls">
    <input type="search" id="search" placeholder="Search cards...">
    <button id="add-card-btn">Add Card</button>
    <button id="theme-toggle" aria-label="Toggle theme">🌗</button>
  </div>
</header>

<div class="kanban-board"></div>

<div class="modal-overlay" hidden>
  <div class="modal">
    <h2>Add New Card</h2>
    <form id="add-card-form">
      <div class="form-group">
        <label for="card-title">Title</label>
        <input type="text" id="card-title" name="title" required>
      </div>
      <div class="form-group">
        <label for="card-priority">Priority</label>
        <select id="card-priority" name="priority">
          <option value="low">Low</option>
          <option value="medium">Medium</option>
          <option value="high">High</option>
        </select>
      </div>
      <div class="modal-actions">
        <button type="button" id="cancel-btn">Cancel</button>
        <button type="submit">Add</button>
      </div>
    </form>
  </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', () => {
  // Elements
  const searchInput = document.getElementById('search');
  const addCardBtn = document.getElementById('add-card-btn');
  const themeToggleBtn = document.getElementById('theme-toggle');
  const modalOverlay = document.querySelector('.modal-overlay');
  const modalForm = document.getElementById('add-card-form');
  const cancelBtn = document.getElementById('cancel-btn');
  const boardContainer = document.querySelector('.kanban-board');

  // Column definitions
  const columnDefs = [
    { id: 'todo', title: 'To do' },
    { id: 'inprogress', title: 'In progress' },
    { id: 'done', title: 'Done' }
  ];

  // Create column structure
  columnDefs.forEach(col => {
    const colEl = document.createElement('div');
    colEl.className = 'column';
    colEl.setAttribute('aria-label', col.title);
    colEl.innerHTML = `
      <div class="column-header">
        <span class="title">${col.title}</span>
        <span class="count">(0)</span>
      </div>
      <div class="column-body" data-col="${col.id}"></div>
    `;
    boardContainer.appendChild(colEl);
  });

  // Helper: create a card element
  function createCardEl({ title, priority }) {
    const card = document.createElement('div');
    card.className = 'card';
    card.draggable = true;
    card.innerHTML = `
      <div class="info">
        <span class="title-text">${title}</span>
        <span class="priority-badge ${priority === 'low' ? 'priority-low' : priority === 'medium' ? 'priority-medium' : 'priority-high'}">${priority}</span>
      </div>
      <button class="delete-btn" aria-label="Delete">×</button>
    `;
    return card;
  }

  // Initial cards data
  const initialCards = [
    { title: 'Design homepage mockups', priority: 'high', column: 'todo' },
    { title: 'Write API documentation', priority: 'medium', column: 'todo' },
    { title: 'Plan sprint', priority: 'low', column: 'todo' },
    { title: 'Implement login feature', priority: 'high', column: 'inprogress' },
    { title: 'Fix responsive layout bug', priority: 'medium', column: 'inprogress' },
    { title: 'Update README', priority: 'low', column: 'done' },
    { title: 'Deploy to staging', priority: 'high', column: 'done' }
  ];

  // Render initial cards
  initialCards.forEach(data => {
    const cardEl = createCardEl(data);
    const targetColumn = document.querySelector(`.column-body[data-col="${data.column}"]`);
    targetColumn.appendChild(cardEl);

    // Delete button
    const delBtn = cardEl.querySelector('.delete-btn');
    delBtn.addEventListener('click', () => {
      cardEl.remove();
      updateAllCounts();
      filterCards(searchInput.value);
    });

    // Drag start
    cardEl.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', '');
      cardEl.classList.add('dragging');
    });
    // Drag end – clear highlight on all columns
    cardEl.addEventListener('dragend', () => {
      cardEl.classList.remove('dragging');
      document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
    });
  });

  // Update card counts in each column (visible only)
  function updateAllCounts() {
    document.querySelectorAll('.column-body').forEach(col => {
      const visibleCards = col.querySelectorAll('.card:not([style*="display: none"])');
      const countSpan = col.previousElementSibling.querySelector('.count');
      countSpan.textContent = `(${visibleCards.length})`;
    });
  }

  // Modal helpers
  function openModal() {
    modalOverlay.removeAttribute('hidden');
    document.getElementById('card-title').focus();
  }
  function closeModal() {
    modalOverlay.setAttribute('hidden', '');
    modalForm.reset();
  }

  addCardBtn.addEventListener('click', openModal);
  cancelBtn.addEventListener('click', closeModal);
  modalOverlay.addEventListener('click', e => {
    if (e.target === modalOverlay) closeModal();
  });

  // Add new card from modal
  modalForm.addEventListener('submit', e => {
    e.preventDefault();
    const title = document.getElementById('card-title').value.trim();
    if (!title) return;
    const priority = document.getElementById('card-priority').value;
    const cardEl = createCardEl({ title, priority });
    const targetColumn = document.querySelector('.column-body[data-col="todo"]');
    targetColumn.appendChild(cardEl);

    // Attach delete & drag listeners for the new card
    const delBtn = cardEl.querySelector('.delete-btn');
    delBtn.addEventListener('click', () => {
      cardEl.remove();
      updateAllCounts();
      filterCards(searchInput.value);
    });
    cardEl.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', '');
      cardEl.classList.add('dragging');
    });
    cardEl.addEventListener('dragend', () => {
      cardEl.classList.remove('dragging');
      document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
    });

    closeModal();
    updateAllCounts();
    filterCards(searchInput.value);
  });

  // Drag & drop handling
  document.querySelectorAll('.column-body').forEach(col => {
    col.addEventListener('dragover', e => {
      e.preventDefault();
      col.classList.add('highlight');
    });
    col.addEventListener('dragleave', () => {
      col.classList.remove('highlight');
    });
    col.addEventListener('drop', e => {
      e.preventDefault();
      const draggingCard = document.querySelector('.card.dragging');
      if (!draggingCard) return;
      col.classList.remove('highlight');
      const previousParent = draggingCard.parentElement;
      if (previousParent !== col) {
        col.appendChild(draggingCard);
        updateAllCounts();
        filterCards(searchInput.value);
      }
    });
  });

  // Search filter
  function filterCards(query) {
    const lower = query.toLowerCase();
    document.querySelectorAll('.card').forEach(card => {
      const title = card.querySelector('.title-text').textContent;
      const match = title.toLowerCase().includes(lower);
      card.style.display = match ? '' : 'none';
    });
    updateAllCounts();
  }
  searchInput.addEventListener('input', e => filterCards(e.target.value));

  // Theme toggle
  themeToggleBtn.addEventListener('click', () => {
    document.body.classList.toggle('dark');
  });

  // Initial counts
  updateAllCounts();
});
</script>
</body>
</html>
```

Now check for any syntax errors: ensure backticks closed correctly.

In the code, after the initial column definitions, there is a stray "columns?" Actually we have a comment `// Column definitions`. It looks fine.

We need to ensure that the opening `<!DOCTYPE html>` and `<html>` tags are correct. There's a missing opening `<head>` after `<meta charset="UTF-8">`. The code seems fine.

Let's quickly scan for any syntax errors.

Search for stray backticks. In CSS we used backticks in property values? No.

Check for missing closing `>` after style closing. The code after the CSS style includes `</style>` then `<body>` etc. Looks fine.

But there is a stray `);` after `<meta charset="UTF-8">`? Let's re-open from start. It looks fine.

Now double-check HTML syntax:

```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Kanban Board</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
...
</style>
</head>
<body>
...
</body>
</html>
```

Looks fine.

Now ensure that any attributes with `aria-label` and `aria-described` are correct. It's fine.

One possible issue: In the code, we used `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));` inside the dragend event of each card. But the code has `cardEl.addEventListener('dragend', () => { ... });` and inside we have `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));`. That's fine.

But I need to check that the dragend event is defined correctly. The code snippet:

```
cardEl.addEventListener('dragend', () => {
  cardEl.classList.remove('dragging');
  document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));
});
```

Yes.

Now there is also a stray `.addEventListener('dragover'` in the drop handling for each column, but it's fine.

One more check: In the modal form, we have `<form id="add-card-form">`. In JS we reference `modalForm` variable: `const modalForm = document.getElementById('add-card-form');` That's correct.

Now check that the "Add Card" button has id "add-card-btn" and is referenced correctly in JS: `const addCardBtn = document.getElementById('add-card-btn');` Good.

Now check that the theme toggle button has id "theme-toggle": JS `const themeToggleBtn = document.getElementById('theme-toggle');` Good.

Now check the variable `boardContainer` is used to append columns: We use `boardContainer.appendChild(colEl);`. Yes.

Now check that the board container `.kanban-board` is empty initially, which is fine.

Now check that we are not using any library. All code is vanilla.

Now check that there are no external resources (no images). All good.

Now check for any potential console errors:

- Using `document.body.classList.toggle('dark')` - body exists.

- Using `.addEventListener('input', e => filterCards(e.target.value));` - Good.

- `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));` inside dragend is fine.

- `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));` inside dragend is fine.

- There may be a syntax error: After we defined `// Column definitions` we have `const columnDefs = [`. That is fine.

- The CSS includes `.add-column-btn` but we never defined an element with that id. Not used. That's fine, no error.

- In the CSS, there is a stray `);` after `<meta charset="UTF-8">`. Wait we need to check carefully.

Let's re-open from near the top of the HTML portion to ensure there is no stray characters.

The code snippet we pasted includes:

```
<head>
<meta charset="UTF-8">
<title>Kanban Board</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* Reset some basics */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
...
</style>
</head>
<body>
...
```

Seems fine.

Now, check that the CSS has no stray characters. The CSS looks fine.

Now we should check that we didn't accidentally include any stray characters like backticks inside HTML attributes. For instance, we used `${col.title}` inside innerHTML. That's fine inside JS template literal but inside HTML? Wait, we used colEl.innerHTML with backticks to embed col.title. That is fine as part of JavaScript. The HTML itself contains no backticks.

Now, let's check potential escaping issues: In CSS, we use `var(--badge-low)`, etc. Fine.

Now check for missing semicolons in CSS? Not necessary.

Now ensure that the theme toggle uses proper button text. It's an emoji; fine.

Now check that there is no stray `);` after `<meta charset="UTF-8">`. The snippet seems correct.

Now I notice there is a stray `);` after `<meta charset="UTF-8">`? Let's view the snippet:

```
<head>
<meta charset="UTF-8">
<title>Kanban Board</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
...
```

All good.

Now check that we didn't accidentally have a stray `document.querySelectorAll('.column-body').forEach(col => col.classList.remove('highlight'));` inside the drop event handling. That's fine.

Now check for potential duplication: In the drop handling we also remove highlight on drop. That's fine.

Now we need to ensure that `cardEl.remove()` is valid. Yes, it's a method to remove element from DOM.

Now ensure that after deletion, the column counts reflect visible cards. Yes, `updateAllCounts` runs after removal.

Now ensure that after filter, counts reflect visible cards. Yes.

Now ensure that the search input is case-insensitive: we use `.toLowerCase()`. Good.

Now test scenario: on page load, board should show columns and 7 cards (the initial 6 plus? Actually we had 7 initial cards? Wait, we listed 7 objects in initialCards: let's count:

1. Design homepage mockups (todo)
2. Write API documentation (todo)
3. Plan sprint (todo)
4. Implement login feature (inprogress)
5. Fix responsive layout bug (inprogress)
6. Update README (done)
7. Deploy to staging (done)

That's 7 cards, not 6. The requirement says pre-populate with 6 realistic cards spread across columns. We have 7. Need to correct to 6 cards.

We need to reduce one. Perhaps we can remove the "Plan sprint" card (or any one). Let's remove "Plan sprint" (low priority, todo). Then we have 6.

Thus modify initialCards to 6 items.

Let's adjust initialCards array:

- "Design homepage mockups" (high, todo)
- "Write API documentation" (medium, todo)
- "Implement login feature" (high, inprogress)
- "Fix responsive layout bug" (medium, inprogress)
- "Update README" (low, done)
- "Deploy to staging" (high, done)

That's 6 cards. Good.

So we need to edit code to have only those 6.

Thus initialCards array should be:

```
const initialCards = [
  { title: 'Design homepage mockups', priority: 'high', column: 'todo' },
  { title: 'Write API documentation', priority: 'medium', column: 'todo' },
  { title: 'Implement login feature', priority: 'high', column: 'inprogress' },
  { title: 'Fix responsive layout bug', priority: 'medium', column: 'inprogress' },
  { title: 'Update README', priority: 'low', column: 'done' },
  { title: 'Deploy to staging', priority: 'high', column: 'done' }
];
```

Now we also need to ensure that we didn't have any stray leftover references. We'll adjust the code accordingly.

Now we need to edit the code inside the final answer.

Given that we have to output a single fenced code block containing the entire file, we can just re-write the final code with the corrected initialCards.

Now let's rewrite the whole final answer with corrected initialCards.

We must ensure to escape any backticks in the code block properly.

The final answer will be a fenced code block containing the entire HTML.

We'll produce it now.

Let's re-compose final code.

We'll need to carefully include everything and correct the initialCards.

I'll write the final code now.