[object Object]

← back to Ventura Corridor

iter 149: per-feature editor margin notes — collapsible "add note" textarea on /magazine.html w/ blur-save

f050969932537685e7907f2c425c9bc667057355 · 2026-05-06 19:16:07 -0700 · SteveStudio2

Files touched

Diff

commit f050969932537685e7907f2c425c9bc667057355
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 6 19:16:07 2026 -0700

    iter 149: per-feature editor margin notes — collapsible "add note" textarea on /magazine.html w/ blur-save
---
 public/magazine.html | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/public/magazine.html b/public/magazine.html
index 226e3e4..26e4c1d 100644
--- a/public/magazine.html
+++ b/public/magazine.html
@@ -388,6 +388,10 @@ async function load() {
           ${r.editorial ? `<span title="Editorial length">${r.editorial.length}c</span>` : ''}
           <span style="color:var(--ink-mute)">${escHtml(r.model || '')}</span>
         </div>
+        <details class="margin-note" ${r.notes ? 'open' : ''} style="margin-top:10px;font-family:'Cormorant Garamond',serif;font-style:italic;font-size:13px;color:var(--ink-mute);border-top:1px dotted var(--rule);padding-top:8px">
+          <summary style="cursor:pointer;font-family:'Inter',sans-serif;font-style:normal;font-size:9px;letter-spacing:.32em;text-transform:uppercase;color:${r.notes ? 'var(--metal)' : 'var(--ink-mute)'};font-weight:500;outline:none">${r.notes ? '✎ note' : '✎ add note'}</summary>
+          <textarea data-feature-id="${r.id}" oninput="this.dataset.dirty='1'" onblur="saveNote(this)" placeholder="margin note (private editor's note)" rows="2" style="width:100%;margin-top:6px;background:transparent;color:var(--ink);border:1px solid var(--rule);padding:6px 8px;font-family:'Cormorant Garamond',serif;font-style:italic;font-size:13px;resize:vertical">${escHtml(r.notes || '')}</textarea>
+        </details>
         <footer>
           <div>
             <div class="biz">${escHtml(r.name)}</div>
@@ -419,6 +423,24 @@ async function advance(id, status) {
   } catch (e) { alert('failed: ' + e.message); }
 }
 
+async function saveNote(el) {
+  if (el.dataset.dirty !== '1') return;
+  const id = Number(el.dataset.featureId);
+  try {
+    const r = await fetch('/api/magazine/' + id, {
+      method: 'PATCH', headers: { 'Content-Type': 'application/json' },
+      body: JSON.stringify({ notes: el.value || '' })
+    });
+    if (!r.ok) throw new Error(await r.text());
+    el.dataset.dirty = '0';
+    const summary = el.parentElement.querySelector('summary');
+    if (summary) {
+      summary.style.color = el.value ? 'var(--metal)' : 'var(--ink-mute)';
+      summary.textContent = el.value ? '✎ note' : '✎ add note';
+    }
+  } catch (e) { console.error('saveNote', e); }
+}
+
 async function setCover(id) {
   try {
     const month = new Date().toISOString().slice(0, 7);

← a9953cd iter 148: /api/magazine/lottery?n=N&cat= — random N features  ·  back to Ventura Corridor  ·  iter 150: /magazine.html 🆕 since-last filter — localStorage 6dc50d0 →