    /* ── what a screen reader would be handed ────────────────────────────
       'exposed' is the tree TalkBack actually walks: nothing under
       aria-hidden or inert, nothing display:none or zero-boxed. 'aname' is
       the name it would announce — aria-label, aria-labelledby, then the
       visible text with the aria-hidden subtrees left out (an Icon is
       aria-hidden, so an icon-only control computes to nothing at all). A
       PLACEHOLDER is deliberately not a name here: it goes away the moment
       the field has text in it. Every backslash in this block is doubled —
       it lives inside a template literal. */
    var A11Y_SEL = 'button, [role=button], a, input, select, textarea, [role=tab], [role=switch], [role=slider], [role=checkbox]';
    function exposed(el) {
        if (el.closest('[aria-hidden="true"], [inert]')) return false;
        if (!el.getClientRects().length) return false;
        var st = getComputedStyle(el);
        return st.visibility !== 'hidden' && st.display !== 'none';
    }
    function vistext(el) {
        var out = '';
        for (var i = 0; i < el.childNodes.length; i++) {
            var n = el.childNodes[i];
            if (n.nodeType === 3) { out += n.nodeValue; continue; }
            if (n.nodeType !== 1) continue;
            if (n.getAttribute('aria-hidden') === 'true') continue;
            if (n.tagName === 'IMG') { out += ' ' + (n.getAttribute('alt') || ''); continue; }
            out += ' ' + vistext(n);
        }
        return out;
    }
    function aname(el) {
        var l = el.getAttribute('aria-label');
        if (l && l.trim()) return l.trim();
        var by = el.getAttribute('aria-labelledby');
        if (by) {
            var s = '';
            by.split(' ').forEach(function (id) { var n = document.getElementById(id); if (n) s += ' ' + vistext(n); });
            if (s.trim()) return s.replace(/\\s+/g, ' ').trim();
        }
        var t = el.tagName;
        if (t === 'INPUT' || t === 'TEXTAREA' || t === 'SELECT') {
            if (el.id) { var lab = document.querySelector('label[for="' + el.id + '"]'); if (lab && lab.textContent.trim()) return lab.textContent.replace(/\\s+/g, ' ').trim(); }
            return (el.getAttribute('title') || '').trim();
        }
        return vistext(el).replace(/\\s+/g, ' ').trim() || (el.getAttribute('title') || '').trim();
    }
    function whatis(el) { return (el.tagName.toLowerCase() + '.' + String(el.className || '').split(' ').slice(0, 2).join('.')).slice(0, 36); }
    function junk(el, nm) {
        if (/^[0-9 .,:;+·—–-]+$/.test(nm)) return 'digits';
        if (/\\.(png|jpe?g|webp|gif|svg|mp3|flac|m4a|ogg|wav)$/i.test(nm)) return 'file';
        if (/^[⋯…×✕✓→←]$/.test(nm)) return 'glyph';
        if (nm.length > 200 && !el.hasAttribute('aria-expanded')) return 'essay';
        return '';
    }
    var a11yAll = [].filter.call(document.querySelectorAll(A11Y_SEL), exposed);
    var a11yNone = a11yAll.filter(function (el) { return !aname(el); });
