diff --git a/pygitweb/static/board.js b/pygitweb/static/board.js
index 600dade..8712b5f 100644
--- a/pygitweb/static/board.js
+++ b/pygitweb/static/board.js
@@ -2,6 +2,33 @@
   var template = document.getElementById('board-card-template');
   var addCardButtons = document.querySelectorAll('.board-column-add-card');
 
+  var ICONS_BASE = '/static/icons/';
+  var ICON_LIST = ['cloud.svg', 'cloud-filled.svg', 'cloud-storm.svg', 'cloud-down.svg', 'cloud-up.svg'];
+  var CLOUD_ICON_URL = ICONS_BASE + 'cloud.svg';
+
+  function preloadIcons() {
+    ICON_LIST.forEach(function(name) {
+      var img = new Image();
+      img.src = ICONS_BASE + name;
+    });
+  }
+
+  function assignCloudIconToCard(card) {
+    var icon = card && card.querySelector && card.querySelector('.board-card-icon');
+    if (icon) icon.setAttribute('data-icon', 'cloud');
+  }
+
+  function assignCloudIconToAllCards() {
+    document.querySelectorAll('.board-card').forEach(assignCloudIconToCard);
+  }
+
+  preloadIcons();
+  if (document.readyState === 'loading') {
+    document.addEventListener('DOMContentLoaded', assignCloudIconToAllCards);
+  } else {
+    assignCloudIconToAllCards();
+  }
+
   function addDefaultCard(ev) {
     if (!template || !template.content) return;
     var column = ev.currentTarget.closest('.board-column');
@@ -12,6 +39,7 @@
     if (card) {
       var titleEl = card.querySelector('.board-card-title');
       if (titleEl) titleEl.textContent = 'New task';
+      assignCloudIconToCard(card);
     }
     cardsContainer.appendChild(clone);
     var badge = column.querySelector('.board-column-add-card');
@@ -28,6 +56,7 @@
   var boardColumns = document.querySelector('.board-columns');
   var dropzones = document.querySelectorAll('.board-column.dropzone');
   var draggedCard = null;
+  var didDrag = false;
 
   function updateColumnBadge(column) {
     var cardsContainer = column && column.querySelector('.board-column-cards');
@@ -40,6 +69,7 @@
   function handleDragStart(e) {
     var card = e.target.closest && e.target.closest('.board-card');
     if (!card) return;
+    didDrag = true;
     draggedCard = card;
     e.dataTransfer.effectAllowed = 'move';
     e.dataTransfer.setData('text/plain', card.dataset.taskRef || '');
@@ -49,6 +79,192 @@
     var card = e.target.closest && e.target.closest('.board-card');
     if (card) card.classList.remove('opacity-50');
     draggedCard = null;
+    setTimeout(function() { didDrag = false; }, 0);
+  }
+
+  /** Parse display date text to YYYY-MM-DD for input[type=date]. Returns '' if none. */
+  function parseDateForInput(text) {
+    if (!text || text.trim() === 'None') return '';
+    var s = text.trim();
+    var m = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
+    return m ? m[0] : '';
+  }
+
+  function setupPopoutEditables(popoutCard) {
+    var titleEl = popoutCard.querySelector('.board-card-title');
+    var descEl = popoutCard.querySelector('.board-card-description-full');
+    var dueEl = popoutCard.querySelector('.board-card-due-date');
+    var statusEl = popoutCard.querySelector('.board-card-status');
+    var priorityEl = popoutCard.querySelector('.board-card-priority');
+
+    if (titleEl) titleEl.classList.add('board-card-editable');
+    function commitTitle() {
+      var input = popoutCard.querySelector('.board-card-title-edit');
+      if (!input) return;
+      var val = (input.value || '').trim() || 'Untitled';
+      titleEl.textContent = val;
+      titleEl.classList.remove('d-none');
+      input.remove();
+    }
+    if (titleEl) {
+      titleEl.addEventListener('click', function () {
+        if (popoutCard.querySelector('.board-card-title-edit')) return;
+        var val = (titleEl.textContent || '').trim();
+        var input = document.createElement('input');
+        input.type = 'text';
+        input.className = 'form-control form-control-sm board-card-title-edit';
+        input.value = val;
+        titleEl.classList.add('d-none');
+        titleEl.parentNode.insertBefore(input, titleEl);
+        input.focus();
+        input.addEventListener('blur', commitTitle);
+        input.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); input.blur(); } });
+      });
+    }
+
+    function commitDescription() {
+      var textarea = popoutCard.querySelector('.board-card-description-edit');
+      if (!textarea) return;
+      var val = (textarea.value || '').trim();
+      descEl.textContent = val || '';
+      descEl.classList.remove('d-none');
+      textarea.remove();
+    }
+    if (descEl) {
+      descEl.addEventListener('click', function () {
+        if (popoutCard.querySelector('.board-card-description-edit')) return;
+        var val = (descEl.textContent || '').trim();
+        var textarea = document.createElement('textarea');
+        textarea.className = 'form-control form-control-sm board-card-description-edit mt-1';
+        textarea.rows = 3;
+        textarea.value = val;
+        descEl.classList.add('d-none');
+        descEl.parentNode.insertBefore(textarea, descEl);
+        textarea.focus();
+        textarea.addEventListener('blur', commitDescription);
+      });
+    }
+
+    function commitDueDate() {
+      var input = popoutCard.querySelector('.board-card-due-date-edit');
+      if (!input) return;
+      var val = (input.value || '').trim();
+      dueEl.textContent = val || 'None';
+      dueEl.classList.remove('d-none');
+      input.remove();
+    }
+    if (dueEl) {
+      dueEl.addEventListener('click', function () {
+        if (popoutCard.querySelector('.board-card-due-date-edit')) return;
+        var val = parseDateForInput(dueEl.textContent);
+        var input = document.createElement('input');
+        input.type = 'date';
+        input.className = 'form-control form-control-sm board-card-due-date-edit mt-1';
+        input.value = val;
+        dueEl.classList.add('d-none');
+        dueEl.parentNode.insertBefore(input, dueEl);
+        input.focus();
+        input.addEventListener('blur', commitDueDate);
+      });
+    }
+
+    function commitStatus() {
+      var sel = popoutCard.querySelector('.board-card-status-edit');
+      if (!sel) return;
+      var display = (sel.options[sel.selectedIndex] && sel.options[sel.selectedIndex].text) ? sel.options[sel.selectedIndex].text : (sel.value || 'TODO');
+      statusEl.textContent = display || 'TODO';
+      statusEl.classList.remove('d-none');
+      sel.remove();
+    }
+    if (statusEl) {
+      statusEl.addEventListener('click', function () {
+        if (popoutCard.querySelector('.board-card-status-edit')) return;
+        var current = (statusEl.textContent || '').trim() || 'TODO';
+        var sel = document.createElement('select');
+        sel.className = 'form-select form-select-sm board-card-status-edit mt-1';
+        sel.innerHTML = '';
+        var opt = document.createElement('option');
+        opt.value = current;
+        opt.textContent = current;
+        opt.selected = true;
+        sel.appendChild(opt);
+        statusEl.classList.add('d-none');
+        statusEl.parentNode.insertBefore(sel, statusEl);
+        sel.focus();
+        sel.addEventListener('blur', commitStatus);
+        sel.addEventListener('change', commitStatus);
+      });
+    }
+
+    function commitPriority() {
+      var sel = popoutCard.querySelector('.board-card-priority-edit');
+      if (!sel) return;
+      var display = (sel.options[sel.selectedIndex] && sel.options[sel.selectedIndex].text) ? sel.options[sel.selectedIndex].text : (sel.value || 'LOW');
+      priorityEl.textContent = display || 'LOW';
+      priorityEl.classList.remove('d-none');
+      sel.remove();
+    }
+    if (priorityEl) {
+      priorityEl.addEventListener('click', function () {
+        if (popoutCard.querySelector('.board-card-priority-edit')) return;
+        var current = (priorityEl.textContent || '').trim() || 'LOW';
+        var sel = document.createElement('select');
+        sel.className = 'form-select form-select-sm board-card-priority-edit mt-1';
+        sel.innerHTML = '';
+        var opt = document.createElement('option');
+        opt.value = current;
+        opt.textContent = current;
+        opt.selected = true;
+        sel.appendChild(opt);
+        priorityEl.classList.add('d-none');
+        priorityEl.parentNode.insertBefore(sel, priorityEl);
+        sel.focus();
+        sel.addEventListener('blur', commitPriority);
+        sel.addEventListener('change', commitPriority);
+      });
+    }
+  }
+
+  function showCardPopout(card) {
+    var cardsContainer = card.parentNode;
+    var nextSibling = card.nextSibling;
+    card.classList.add('board-card-popout');
+    card.draggable = false;
+    card.removeAttribute('draggable');
+    var details = card.querySelector('.board-card-details');
+    if (details) details.classList.remove('d-none');
+    setupPopoutEditables(card);
+    var overlay = document.createElement('div');
+    overlay.className = 'board-card-popout-overlay';
+    overlay.appendChild(card);
+    function close() {
+      overlay.removeEventListener('click', closeOnBackdrop);
+      document.body.removeChild(overlay);
+      card.classList.remove('board-card-popout');
+      card.setAttribute('draggable', 'true');
+      card.draggable = true;
+      if (details) details.classList.add('d-none');
+      if (nextSibling) {
+        cardsContainer.insertBefore(card, nextSibling);
+      } else {
+        cardsContainer.appendChild(card);
+      }
+      updateColumnBadge(cardsContainer.closest('.board-column'));
+    }
+    function closeOnBackdrop(e) {
+      if (e.target === overlay) close();
+    }
+    overlay.addEventListener('click', closeOnBackdrop);
+    document.body.appendChild(overlay);
+    updateColumnBadge(cardsContainer.closest('.board-column'));
+  }
+
+  function handleCardClick(e) {
+    if (didDrag) return;
+    var card = e.target.closest && e.target.closest('.board-card');
+    if (!card || card.classList.contains('board-card-popout')) return;
+    e.preventDefault();
+    showCardPopout(card);
   }
 
   function handleDragOver(e) {
@@ -78,6 +294,7 @@
   if (boardColumns) {
     boardColumns.addEventListener('dragstart', handleDragStart);
     boardColumns.addEventListener('dragend', handleDragEnd);
+    boardColumns.addEventListener('click', handleCardClick);
   }
   dropzones.forEach(function(el) {
     el.addEventListener('dragover', handleDragOver);
diff --git a/pygitweb/static/icons/cloud-down.svg b/pygitweb/static/icons/cloud-down.svg
new file mode 100644
index 0000000..4af025f
--- /dev/null
+++ b/pygitweb/static/icons/cloud-down.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-cloud-down"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.573 .813 3.13 1.99" /><path d="M19 16v6" /><path d="M22 19l-3 3l-3 -3" /></svg>
\ No newline at end of file
diff --git a/pygitweb/static/icons/cloud-filled.svg b/pygitweb/static/icons/cloud-filled.svg
new file mode 100644
index 0000000..72d35f9
--- /dev/null
+++ b/pygitweb/static/icons/cloud-filled.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-cloud"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M10.04 4.305c2.195 -.667 4.615 -.224 6.36 1.176c1.386 1.108 2.188 2.686 2.252 4.34l.003 .212l.091 .003c2.3 .107 4.143 1.961 4.25 4.27l.004 .211c0 2.407 -1.885 4.372 -4.255 4.482l-.21 .005h-11.878l-.222 -.008c-2.94 -.11 -5.317 -2.399 -5.43 -5.263l-.005 -.216c0 -2.747 2.08 -5.01 4.784 -5.417l.114 -.016l.07 -.181c.663 -1.62 2.056 -2.906 3.829 -3.518l.244 -.08z" /></svg>
\ No newline at end of file
diff --git a/pygitweb/static/icons/cloud-storm.svg b/pygitweb/static/icons/cloud-storm.svg
new file mode 100644
index 0000000..87ed0c9
--- /dev/null
+++ b/pygitweb/static/icons/cloud-storm.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-cloud-storm"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 18a4.6 4.4 0 0 1 0 -9a5 4.5 0 0 1 11 2h1a3.5 3.5 0 0 1 0 7h-1" /><path d="M13 14l-2 4l3 0l-2 4" /></svg>
\ No newline at end of file
diff --git a/pygitweb/static/icons/cloud-up.svg b/pygitweb/static/icons/cloud-up.svg
new file mode 100644
index 0000000..1016ddd
--- /dev/null
+++ b/pygitweb/static/icons/cloud-up.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-cloud-up"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.57 .811 3.128 1.986" /><path d="M19 22v-6" /><path d="M22 19l-3 -3l-3 3" /></svg>
\ No newline at end of file
diff --git a/pygitweb/static/icons/cloud.svg b/pygitweb/static/icons/cloud.svg
new file mode 100644
index 0000000..44b8086
--- /dev/null
+++ b/pygitweb/static/icons/cloud.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-cloud"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M6.657 18c-2.572 0 -4.657 -2.007 -4.657 -4.483c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.913 0 3.464 1.56 3.464 3.486c0 1.927 -1.551 3.487 -3.465 3.487h-11.878" /></svg>
\ No newline at end of file
diff --git a/pygitweb/static/main.css b/pygitweb/static/main.css
index 961e7bd..d3864b3 100644
--- a/pygitweb/static/main.css
+++ b/pygitweb/static/main.css
@@ -623,3 +623,71 @@ tbody tr:hover {
 .board-column .text-muted {
 	color: var(--pgw-text-muted) !important;
 }
+
+/* Board: Sync status icons (mask so currentColor is respected when loaded) */
+.board-card-icon-wrap {
+	opacity: 0.7;
+	color: var(--pgw-text-muted);
+}
+.board-card-icon {
+	display: inline-block;
+	width: 20px;
+	height: 20px;
+	background-color: currentColor;
+	-webkit-mask-image: url(/static/icons/cloud.svg);
+	mask-image: url(/static/icons/cloud.svg);
+	-webkit-mask-size: contain;
+	mask-size: contain;
+	-webkit-mask-repeat: no-repeat;
+	mask-repeat: no-repeat;
+	-webkit-mask-position: center;
+	mask-position: center;
+}
+.board-card .board-card-title {
+	padding-right: 1.75rem;
+}
+
+/* Board card popout: overlay and card on top of the board (above navbar and Bootstrap modals) */
+.board-card-popout-overlay {
+	position: fixed;
+	inset: 0;
+	z-index: 1060;
+	background-color: rgba(0, 0, 0, 0.35);
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	padding: 1.5rem;
+	box-sizing: border-box;
+}
+.board-card-popout-overlay .board-card-popout {
+	position: relative;
+	z-index: 1061;
+	max-width: 40rem;
+	width: 100%;
+	pointer-events: auto;
+	box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2);
+}
+
+/* Popout card: editable fields (click to edit) */
+.board-card-popout .board-card-editable,
+.board-card-popout .board-card-title.board-card-editable {
+	cursor: pointer;
+	border-radius: 0.25rem;
+	min-height: 1.5em;
+}
+.board-card-popout .board-card-editable:hover,
+.board-card-popout .board-card-title.board-card-editable:hover {
+	background-color: var(--pgw-bg-muted);
+}
+.board-card-popout .board-card-title-edit,
+.board-card-popout .board-card-description-edit,
+.board-card-popout .board-card-due-date-edit,
+.board-card-popout .board-card-status-edit,
+.board-card-popout .board-card-priority-edit {
+	min-width: 10rem;
+	width: 100%;
+}
+.board-card-popout .board-card-description-edit {
+	min-height: 4rem;
+	resize: vertical;
+}
diff --git a/pygitweb/templates/board_card.html b/pygitweb/templates/board_card.html
index 7154ce6..10faa43 100644
--- a/pygitweb/templates/board_card.html
+++ b/pygitweb/templates/board_card.html
@@ -1,6 +1,7 @@
-{# Static card structure. When `task` is provided and truthy, title and meta are filled (server); otherwise empty for template clone / JS fill. #}
+{# Static card structure. When `task` is provided and truthy, title and meta are filled (server); otherwise empty for template clone / JS fill. .board-card-details is hidden on the small card and shown in the popout. #}
 <div class="card board-card mb-2 draggable" data-task-ref="{{ task.ref if task else '' }}" data-task-status="{{ (task.status or 'TODO') if task else 'TODO' }}" draggable="true">
-  <div class="card-body py-2 px-3">
+  <div class="card-body py-2 px-3 position-relative">
+    <span class="board-card-icon-wrap position-absolute top-0 end-0 mt-1 me-1" aria-hidden="true"><span class="board-card-icon" data-icon="cloud"></span></span>
     <div class="board-card-title fw-medium text-truncate"{% if task %} title="{{ task.title }}"{% endif %}>{% if task %}{{ task.title or 'Untitled' }}{% endif %}</div>
     <div class="board-card-description small text-muted mt-1 text-truncate">{% if task and task.description %}{{ task.description }}{% else %}{% endif %}</div>
     <div class="board-card-meta d-flex align-items-center gap-1 mt-1 small text-muted">
@@ -26,5 +27,14 @@
         <span class="ms-auto">0 comments</span>
       {% endif %}
     </div>
+    <div class="board-card-details d-none mt-2 pt-2 border-top small">
+      <div class="mb-2"><strong class="text-muted">Description</strong><div class="board-card-description-full board-card-editable text-muted mt-1">{% if task and task.description %}{{ task.description }}{% else %}{% endif %}</div></div>
+      <div class="mb-2"><strong class="text-muted">Due date</strong><div class="board-card-due-date board-card-editable text-muted mt-1">{% if task and task.due_date %}{{ task.due_date }}{% else %}None{% endif %}</div></div>
+      <div class="mb-2"><strong class="text-muted">Last modified</strong><div class="board-card-updated-at text-muted mt-1">{% if task and task.updated_at %}{{ task.updated_at }}{% else %}None{% endif %}</div></div>
+      <div class="mb-2"><strong class="text-muted">Status</strong><div class="board-card-status board-card-editable text-muted mt-1">{% if task %}{{ task.status or 'TODO' }}{% else %}TODO{% endif %}</div></div>
+      <div class="mb-2"><strong class="text-muted">Priority</strong><div class="board-card-priority board-card-editable text-muted mt-1">{% if task and task.priority %}{{ task.priority }}{% else %}LOW{% endif %}</div></div>
+      <div class="mb-2"><strong class="text-muted">Assignee</strong><div class="board-card-assignee text-muted mt-1">{% if task and task.assignee %}{{ task.assignee }}{% else %}None{% endif %}</div></div>
+      <div class="mb-0"><strong class="text-muted">Comments</strong><div class="board-card-comments-count text-muted mt-1">{% if task and task.comments_count %}{{ task.comments_count }} comment{{ 's' if task.comments_count != 1 else '' }}{% else %}0 comments{% endif %}</div></div>
+    </div>
   </div>
 </div>
