fix: description unreadable in dark mode / OLED — swap disabled textarea for lt-markdown div

Root cause: disabled textarea gets opacity:0.45 + color:var(--text-muted) from
base.css, making it near-invisible on OLED (true-black background).

Fix:
- TicketView: add #ticketDescriptionView (div.lt-markdown) alongside the textarea;
  textarea is now hidden by default (style="display:none"), view div is shown
- ticket.js: renderDescriptionView() renders raw text via parseMarkdown() or nl2br;
  showDescriptionView() / showDescriptionEdit() swap between them;
  toggleEditMode() calls showDescriptionEdit() when entering edit, and
  renderDescriptionView() + showDescriptionView() when returning to read mode
- ticket.css: .ticket-description-view sets full-contrast text-primary/secondary
  colors, min-height, and line-height for comfortable reading

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-31 18:10:39 -04:00
parent cfb88d9c88
commit 1d721eecb4
3 changed files with 63 additions and 3 deletions
+15
View File
@@ -269,3 +269,18 @@ kbd {
.thread-depth-2 { margin-left: 1.5rem; }
.thread-depth-3 { margin-left: 2.25rem; }
}
/* ── Description read view ───────────────────────────────────── */
/* Shown in read mode instead of a disabled (faded) textarea. */
/* Uses lt-markdown typography for full contrast on dark/OLED. */
.ticket-description-view {
min-height: 8rem;
padding: 0.5rem 0.25rem;
line-height: 1.75;
color: var(--text-primary);
}
.ticket-description-view p {
color: var(--text-secondary);
margin-bottom: 0.6rem;
}
.ticket-description-view p:last-child { margin-bottom: 0; }
+41 -2
View File
@@ -77,6 +77,38 @@ function saveTicket() {
});
}
// ── Description read/edit helpers ────────────────────────────────────────────
// Read mode: styled lt-markdown div (full contrast, even on OLED).
// Edit mode: raw textarea (enabled for editing).
function renderDescriptionView() {
var viewDiv = document.getElementById('ticketDescriptionView');
var textarea = document.querySelector('textarea[data-field="description"]');
if (!viewDiv || !textarea) return;
var raw = textarea.value || '';
if (!raw.trim()) {
viewDiv.innerHTML = '<p class="lt-text-muted lt-text-sm"><em>No description provided.</em></p>';
} else if (typeof parseMarkdown === 'function') {
viewDiv.innerHTML = parseMarkdown(raw);
} else {
viewDiv.innerHTML = lt.escHtml(raw).replace(/\n/g, '<br>');
}
}
function showDescriptionView() {
var v = document.getElementById('ticketDescriptionView');
var t = document.querySelector('textarea[data-field="description"]');
if (v) v.style.display = '';
if (t) t.style.display = 'none';
}
function showDescriptionEdit() {
var v = document.getElementById('ticketDescriptionView');
var t = document.querySelector('textarea[data-field="description"]');
if (v) v.style.display = 'none';
if (t) t.style.display = '';
}
function toggleEditMode() {
const editButton = document.getElementById('editButton');
const titleField = document.querySelector('.title-input');
@@ -94,8 +126,9 @@ function toggleEditMode() {
titleField.focus();
}
// Enable description (textarea)
// Enable description (swap to textarea)
if (descriptionField) {
showDescriptionEdit();
descriptionField.disabled = false;
descriptionField.style.height = 'auto';
descriptionField.style.height = descriptionField.scrollHeight + 'px';
@@ -115,9 +148,11 @@ function toggleEditMode() {
titleField.setAttribute('contenteditable', 'false');
}
// Disable description
// Disable description — re-render view div with latest content
if (descriptionField) {
descriptionField.disabled = true;
renderDescriptionView();
showDescriptionView();
}
// Disable metadata fields
@@ -259,6 +294,10 @@ document.addEventListener('DOMContentLoaded', function() {
// Show description tab by default
showTab('description');
// Populate and show description view div on page load
renderDescriptionView();
showDescriptionView();
// Auto-resize function for textareas
function autoResizeTextarea(textarea) {
// Reset height to auto to get the correct scrollHeight
+7 -1
View File
@@ -320,12 +320,18 @@ include __DIR__ . '/layout_header.php';
<div class="lt-section-body">
<div class="lt-form-group">
<label class="lt-sr-only lt-label" for="ticketDescription">Description</label>
<!-- Read view: shown when not editing — uses lt-markdown for readable typography -->
<div id="ticketDescriptionView"
class="lt-markdown ticket-description-view"
aria-label="Ticket description"></div>
<!-- Edit view: shown only when editing -->
<textarea id="ticketDescription"
class="lt-input lt-textarea editable"
data-field="description"
disabled
rows="18"
aria-label="Ticket description"><?= htmlspecialchars($ticket['description'] ?? '') ?></textarea>
style="display:none"
aria-label="Ticket description (edit)"><?= htmlspecialchars($ticket['description'] ?? '') ?></textarea>
</div>
</div>
</div>