diff --git a/static/index.html b/static/index.html
index 9432818..b8fe9fe 100644
--- a/static/index.html
+++ b/static/index.html
@@ -373,6 +373,29 @@ function debounce(fn, ms){ let t; return (...a)=>{ clearTimeout(t); t=setTimeout
let analysis = null; // last server response
let backendOk = true;
+let focusGid = null; // spotlight: the family under the caret
+
+function caretGid(){
+ if(!analysis || editor.selectionStart !== editor.selectionEnd) return null;
+ const pos = editor.selectionStart;
+ const before = editor.value.slice(0, pos);
+ const ln = before.split('\n').length - 1;
+ const col = pos - (before.lastIndexOf('\n') + 1);
+ const line = editor.value.split('\n')[ln];
+ if(!analysis.lines || analysis.lines[ln] !== line) return null;
+ let best = null;
+ analysis.tokens.forEach(t=>{
+ if(t.l === ln && t.s <= col && col < t.e){
+ if(!best || (t.e - t.s) < (best.e - best.s)) best = t;
+ }
+ });
+ return best ? best.g : null;
+}
+
+function updateSpotlight(){
+ const g = caretGid();
+ if(g !== focusGid){ focusGid = g; render(); }
+}
let analyzeSeq = 0; // guards against out-of-order responses
const SAMPLE_TEXT =
@@ -573,11 +596,15 @@ function render(){
// gray = an ending still waiting for its answer
let style = '';
if(w || p){
- const alpha = w ? (w.end ? 34 : 19) : (p.end ? 24 : 14);
- const color = w ? colorOf(w) : colorOf(p);
- style += `background:color-mix(in srgb, ${color} ${alpha}%, transparent);`;
+ const t = (w && (focusGid === null || w.g === focusGid)) ? w
+ : (p && (focusGid === null || p.g === focusGid)) ? p
+ : (w || p);
+ let alpha = !t.ph ? (t.end ? 34 : 19) : (t.end ? 24 : 14);
+ if(focusGid !== null && t.g !== focusGid) alpha = Math.round(alpha * 0.22);
+ style += `background:color-mix(in srgb, ${colorOf(t)} ${alpha}%, transparent);`;
}else if(op){
- style += `background:color-mix(in srgb, var(--ink-dim) 13%, transparent);`;
+ const opAlpha = focusGid === null ? 13 : 3;
+ style += `background:color-mix(in srgb, var(--ink-dim) ${opAlpha}%, transparent);`;
}
if(al) style += `box-shadow:inset 0 -2px 0 0 color-mix(in srgb, var(--r${al.g % COLORS}) 75%, transparent);`;
h += `${text}`;
@@ -700,10 +727,10 @@ function buildReadout(){
schemeReadout.innerHTML = parts.join(' ');
}
-editor.addEventListener('input', ()=>{ render(); analyzeSoon(); });
+editor.addEventListener('input', ()=>{ focusGid = caretGid(); render(); analyzeSoon(); });
editor.addEventListener('scroll', ()=>{ highlight.scrollTop = stresslayer.scrollTop = editor.scrollTop; highlight.scrollLeft = stresslayer.scrollLeft = editor.scrollLeft; });
-editor.addEventListener('keyup', buildReadout);
-editor.addEventListener('click', buildReadout);
+editor.addEventListener('keyup', ()=>{ updateSpotlight(); buildReadout(); });
+editor.addEventListener('click', ()=>{ updateSpotlight(); buildReadout(); });
/* ---------- double-click (or touch-select) a word -> look it up ---------- */
function lookupSelection(){