style: replace emoji glyphs in the UI with plain text labels

Buttons read Play/Hide, Cut, Delete, Download, Highlights, Prev/Next,
Open in file, Refresh, Clear; the clip-bar close button uses a
typographic multiplication sign. Day disclosure arrows switch to the
text-presentation triangles (U+25B8/U+25BE) so they can never render as
colored emoji. The red REC dot stays: U+25CF is text-presentation and
takes the badge's CSS color.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 09:03:32 +02:00
parent f3716d3ff1
commit 2caf23f17d
2 changed files with 26 additions and 26 deletions
+21 -21
View File
@@ -140,7 +140,7 @@ body.clip-open{padding-bottom:70px}
<h1>ISR Archive</h1>
<span id="subtitle" aria-live="polite" aria-atomic="true">Loading…</span>
<span id="storage-info" aria-live="polite"></span>
<button id="refresh-btn" aria-label="Refresh file list">&#8635; Refresh</button>
<button id="refresh-btn" aria-label="Refresh file list">Refresh</button>
</header>
<div class="controls-bar">
<label for="margin-input">Loudness margin:</label>
@@ -167,20 +167,20 @@ body.clip-open{padding-bottom:70px}
<input type="date" id="filter-from" aria-label="From date">
<label for="filter-to">To:</label>
<input type="date" id="filter-to" aria-label="To date">
<button id="filter-clear" aria-label="Clear all filters">Clear</button>
<button id="filter-clear" aria-label="Clear all filters">Clear</button>
</div>
<div class="wrap" id="main">
<div id="tbody" role="region" aria-label="Recordings archive"></div>
<div id="empty" class="empty" style="display:none" role="status">No recordings found.</div>
</div>
<div id="clip-bar" hidden role="region" aria-label="Section clip player">
<button id="clip-prev" aria-label="Previous section (J)"></button>
<button id="clip-next" aria-label="Next section (K)"></button>
<button id="clip-prev" aria-label="Previous section (J)">Prev</button>
<button id="clip-next" aria-label="Next section (K)">Next</button>
<span id="clip-label"></span>
<audio id="clip-audio" controls preload="auto" aria-label="Section clip playback"></audio>
<label id="clip-auto-label"><input type="checkbox" id="clip-auto" checked> Auto-advance</label>
<button id="clip-context" title="Open the full recording at this position">Open in file</button>
<button id="clip-close" aria-label="Close clip player"></button>
<button id="clip-context" title="Open the full recording at this position">Open in file</button>
<button id="clip-close" aria-label="Close clip player">&times;</button>
</div>
<script>
const esc = s => String(s)
@@ -226,7 +226,7 @@ let activePlayerIdx = null;
let allFiles = [];
// dayId -> boolean, persists expanded state across re-renders
const dayExpanded = new Map();
// cross-file day section list (populated by Highlights)
// cross-file day section list (populated by the day Highlights button)
let dayActiveSections = [];
let dayActiveId = null;
@@ -248,7 +248,7 @@ function closePlayer(idx) {
const btn = document.getElementById('pbtn-'+idx);
if (btn) {
btn.setAttribute('aria-expanded','false');
btn.textContent = 'Play';
btn.textContent = 'Play';
btn.setAttribute('aria-label','Play '+(recMap.get(idx) || ''));
}
}
@@ -276,7 +276,7 @@ function togglePlayer(idx, filename) {
activePlayerIdx = idx;
prow.hidden = false;
btn.setAttribute('aria-expanded','true');
btn.textContent = 'Hide';
btn.textContent = 'Hide';
btn.setAttribute('aria-label','Hide player for '+filename);
audio.focus();
}
@@ -347,7 +347,7 @@ function seekToSection(idx, filename, startSec, endSec, sectionIdx) {
// Sections play as small server-rendered WAV clips (/api/clip) in the bottom
// bar instead of seeking the full recording, which is slow for big FLACs.
// clipQueue holds the active review list (one file's sections, or a whole
// day's); J/K and ⏮/⏭ step through it.
// day's); J/K and the Prev/Next buttons step through it.
let clipQueue = [];
let clipCursor = -1;
@@ -557,11 +557,11 @@ async function deleteFile(idx, filename) {
} else {
const d = await r.json().catch(()=>({}));
alert('Delete failed: '+(d.error||r.statusText));
if (btn) { btn.disabled = false; btn.textContent = 'Delete'; }
if (btn) { btn.disabled = false; btn.textContent = 'Delete'; }
}
} catch(e) {
alert('Delete failed: '+e.message);
if (btn) { btn.disabled = false; btn.textContent = 'Delete'; }
if (btn) { btn.disabled = false; btn.textContent = 'Delete'; }
}
}
@@ -701,13 +701,13 @@ function renderFiles(files) {
<button class="day-toggle" id="daytgl-${dayId}"
aria-expanded="${expanded}"
aria-controls="daytbl-${dayId}">
<span class="day-arrow" aria-hidden="true">${expanded ? '' : ''}</span>
<span class="day-arrow" aria-hidden="true">${expanded ? '' : ''}</span>
${esc(day)}
<span class="day-meta">${fileStr}${durStr}${sizeStr}</span>
</button>
</h2>
${canHl ? `<button class="day-hl" id="dayhln-${dayId}"
aria-label="Show day highlights for ${esc(day)}">Highlights</button>` : ''}`;
aria-label="Show day highlights for ${esc(day)}">Highlights</button>` : ''}`;
section.appendChild(headBar);
// Highlights panel (hidden until button clicked)
@@ -766,15 +766,15 @@ function renderFiles(files) {
<button id="pbtn-${i}"
aria-expanded="false"
aria-controls="prow-${i}"
aria-label="Play ${esc(f.name)}">Play</button>
aria-label="Play ${esc(f.name)}">Play</button>
<a class="dl" href="/download/${encodeURIComponent(f.name)}"
aria-label="Download ${esc(f.name)}">Download</a>
aria-label="Download ${esc(f.name)}">Download</a>
<button id="cutbtn-${i}" class="cut"
aria-label="Cut ${esc(f.name)}"
${isRec ? 'disabled title="Cannot cut while recording"' : ''}>Cut</button>
${isRec ? 'disabled title="Cannot cut while recording"' : ''}>Cut</button>
<button id="delbtn-${i}" class="del"
aria-label="Delete ${esc(f.name)}"
${isRec ? 'disabled title="Cannot delete while recording"' : ''}>Delete</button>
${isRec ? 'disabled title="Cannot delete while recording"' : ''}>Delete</button>
</div>
</td>`;
dayTbody.appendChild(tr);
@@ -790,7 +790,7 @@ function renderFiles(files) {
<audio id="aud-${i}" controls preload="none"
aria-label="Playback: ${esc(f.name)}"></audio>${durLabel}
<div class="cut-panel">
<span class="cut-label">Cut:</span>
<span class="cut-label">Cut:</span>
<label class="cut-field">Start
<input type="text" id="cut-start-${i}" class="cut-time" placeholder="m:ss or h:mm:ss">
</label>
@@ -799,7 +799,7 @@ function renderFiles(files) {
</label>
<button id="cut-dl-${i}" class="cut"
${isRec ? 'disabled title="Cannot cut while recording"' : ''}
aria-label="Download cut of ${esc(f.name)}">Download cut</button>
aria-label="Download cut of ${esc(f.name)}">Download cut</button>
</div>
</td>`;
dayTbody.appendChild(prow);
@@ -813,7 +813,7 @@ function renderFiles(files) {
dayExpanded.set(dayId, nowExp);
const tgl = document.getElementById('daytgl-' + dayId);
tgl.setAttribute('aria-expanded', nowExp);
tgl.querySelector('.day-arrow').textContent = nowExp ? '' : '';
tgl.querySelector('.day-arrow').textContent = nowExp ? '' : '';
headBar.classList.toggle('open', nowExp);
document.getElementById('daytbl-' + dayId).hidden = !nowExp;
if (nowExp) autoloadDayAnalyses(dayId);