diff --git a/public/css/styles.css b/public/css/styles.css
index cf0672f..99b3fdb 100644
--- a/public/css/styles.css
+++ b/public/css/styles.css
@@ -439,7 +439,7 @@ body{font-family:'Inter',system-ui,sans-serif;background:var(--g50);color:var(--
.shadess-flag-btn{font-size:11px;padding:2px 6px;}
/* Settings page */
-.settings-page{display:flex;flex-direction:column;gap:0;max-width:800px;}
+.settings-page{display:flex;flex-direction:column;gap:0;}
.settings-page .settings-section{padding:20px;margin-bottom:12px;border-radius:var(--radius);}
.settings-page .settings-section h3{font-size:16px;font-weight:700;color:var(--g800);margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid var(--g100);display:flex;align-items:center;gap:8px;}
.settings-page .settings-section p{font-size:13px;color:var(--g600);margin-bottom:12px;line-height:1.6;}
@@ -548,10 +548,7 @@ body{font-family:'Inter',system-ui,sans-serif;background:var(--g50);color:var(--
.lh-quiz-option input[type="radio"]{accent-color:var(--blue);width:18px;height:18px;flex-shrink:0;}
.lh-quiz-option span{flex:1;}
.lh-opt-correct{border-color:var(--green) !important;background:var(--green-light) !important;box-shadow:0 0 0 2px rgba(16,185,129,0.2) !important;}
-.lh-opt-correct::after{content:'\\2713';position:absolute;right:14px;color:var(--green);font-weight:700;font-size:18px;}
-.lh-quiz-option.lh-opt-correct,.lh-quiz-option.lh-opt-wrong{position:relative;}
.lh-opt-wrong{border-color:var(--red) !important;background:var(--red-light) !important;box-shadow:0 0 0 2px rgba(239,68,68,0.2) !important;}
-.lh-opt-wrong::after{content:'\\2717';position:absolute;right:14px;color:var(--red);font-weight:700;font-size:18px;}
/* Quiz results */
.lh-result-item{margin-bottom:14px;padding-bottom:14px;border-bottom:1px solid var(--g100);}
diff --git a/public/js/app.js b/public/js/app.js
index 9265564..9a49c47 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -223,6 +223,18 @@ document.addEventListener('DOMContentLoaded', function() {
// GLOBAL FUNCTIONS (must be outside DOMContentLoaded)
// ============================================================
+// ── Set formatted text on output/contenteditable elements ──
+// Converts \n to
so line breaks survive in contenteditable divs
+// and are preserved when copying with innerText
+function setOutputText(el, text) {
+ if (!el) return;
+ if (typeof el === 'string') el = document.getElementById(el);
+ if (!el) return;
+ // Escape HTML, then convert newlines to
+ var safe = String(text || '').replace(/&/g, '&').replace(//g, '>');
+ el.innerHTML = safe.replace(/\n/g, '
');
+}
+
// ── Announcement banner ────────────────────────────────────
function loadAnnouncement() {
fetch('/api/admin/config/announcement', { headers: getAuthHeaders() })
@@ -457,7 +469,7 @@ function refineDocument(outputElementId, inputElementId) {
.then(function(r) { return r.json(); })
.then(function(data) {
hideLoading();
- if (data.success) { doc.textContent = data.refined; input.value = ''; showToast('Refined!', 'success'); }
+ if (data.success) { setOutputText(doc, data.refined); input.value = ''; showToast('Refined!', 'success'); }
else showToast(data.error || 'Failed', 'error');
})
.catch(function(err) { hideLoading(); showToast(err.message, 'error'); });
@@ -476,7 +488,7 @@ function shortenDocument(outputElementId) {
.then(function(r) { return r.json(); })
.then(function(data) {
hideLoading();
- if (data.success) { doc.textContent = data.shortened; showToast('Shortened!', 'success'); }
+ if (data.success) { setOutputText(doc, data.shortened); showToast('Shortened!', 'success'); }
else showToast(data.error || 'Failed', 'error');
})
.catch(function(err) { hideLoading(); showToast(err.message, 'error'); });
diff --git a/public/js/chartReview.js b/public/js/chartReview.js
index 21b0f8d..bbaab75 100644
--- a/public/js/chartReview.js
+++ b/public/js/chartReview.js
@@ -141,7 +141,7 @@
.then(function(data) {
hideLoading();
if (data.success) {
- reviewText.textContent = data.review;
+ setOutputText(reviewText, data.review);
modelTag.textContent = (data.model || '').split('/').pop();
outputCard.classList.remove('hidden');
outputCard.scrollIntoView({ behavior: 'smooth' });
diff --git a/public/js/hospitalCourse.js b/public/js/hospitalCourse.js
index 1eaf8ec..5e8bee9 100644
--- a/public/js/hospitalCourse.js
+++ b/public/js/hospitalCourse.js
@@ -152,7 +152,7 @@
.then(function(data) {
hideLoading();
if (data.success) {
- courseText.textContent = data.hospitalCourse;
+ setOutputText(courseText, data.hospitalCourse);
formatTag.textContent = data.format || '';
modelTag.textContent = (data.model || '').split('/').pop();
outputCard.classList.remove('hidden');
@@ -183,7 +183,7 @@
.then(function(data) {
hideLoading();
if (data.success) {
- clarifyOutput.textContent = data.questions;
+ setOutputText(clarifyOutput, data.questions);
clarifyOutput.classList.remove('hidden');
showToast('Review missing information below', 'info');
}
diff --git a/public/js/liveEncounter.js b/public/js/liveEncounter.js
index ce0a1bc..1d21875 100644
--- a/public/js/liveEncounter.js
+++ b/public/js/liveEncounter.js
@@ -125,7 +125,7 @@
.then(function(data) {
hideLoading();
if (data.success) {
- hpiText.textContent = data.hpi;
+ setOutputText(hpiText, data.hpi);
modelTag.textContent = (data.model || '').split('/').pop();
outputCard.classList.remove('hidden');
outputCard.scrollIntoView({ behavior: 'smooth' });
diff --git a/public/js/milestones.js b/public/js/milestones.js
index 7ba5f50..274c8ae 100644
--- a/public/js/milestones.js
+++ b/public/js/milestones.js
@@ -130,7 +130,7 @@
.then(function(data) {
hideLoading();
if (data.success) {
- narrativeText.textContent = data.narrative;
+ setOutputText(narrativeText, data.narrative);
modelTag.textContent = (data.model || '').split('/').pop();
if (data.summary) {
summaryBar.innerHTML = '