function initPhoneMask(selector = 'input[type="tel"]') {
  const format = (digits) => {
    // Пример маски: +7 (999) 123-45-67
    const d = digits.slice(0, 11); // ограничим 11 цифрами (под РФ)
    if (!d.length) return '';

    // если начали вводить с 8/7 — приведём к +7
    let rest = d;
    let prefix = '+7';
    if (d[0] === '8') rest = '7' + d.slice(1);
    if (rest[0] === '7') rest = rest.slice(1);
    else {
      // если первая цифра не 7, считаем что пользователь вводит локально, но всё равно показываем +7
      // (при желании можно тут менять логику)
    }

    const a = rest.slice(0, 3);
    const b = rest.slice(3, 6);
    const c = rest.slice(6, 8);
    const e = rest.slice(8, 10);

    let out = prefix;
    if (a) out += ` (${a}`;
    if (a && a.length === 3) out += `)`;
    if (b) out += ` ${b}`;
    if (c) out += `-${c}`;
    if (e) out += `-${e}`;
    return out;
  };

  const applyToInput = (input) => {
    if (input.dataset.phoneMasked === '1') return;
    input.dataset.phoneMasked = '1';

    // Подсказки браузеру: tel-поле и события input/change поддерживаются стандартно [web:2]
    input.autocomplete = input.autocomplete || 'tel';
    input.inputMode = input.inputMode || 'tel'; // подсказка клавиатуры, особенно на мобилках [web:12]

    const handler = () => {
      const digits = input.value.replace(/\D/g, '');
      input.value = format(digits);
    };

    input.addEventListener('input', handler);   // события input/change для tel описаны в MDN [web:2]
    input.addEventListener('change', handler);  // [web:2]
  };

  // 1) применяем ко всем уже существующим
  document.querySelectorAll(selector).forEach(applyToInput);

  // 2) применяем к добавляемым динамически
  const mo = new MutationObserver((mutations) => {
    for (const m of mutations) {
      for (const node of m.addedNodes) {
        if (!(node instanceof Element)) continue;
        if (node.matches?.(selector)) applyToInput(node);
        node.querySelectorAll?.(selector).forEach(applyToInput);
      }
    }
  });

  mo.observe(document.documentElement, { childList: true, subtree: true });
  return () => mo.disconnect();
}
// запуск
initPhoneMask();

function runOnDomUpdate(fn, root = document.documentElement) {
  const observer = new MutationObserver((mutations) => {
    // если важно “не дергать” лишний раз — фильтруем
    if (mutations.some(m => m.type === 'childList' && (m.addedNodes.length || m.removedNodes.length))) {
      fn();
    }
  });

  observer.observe(root, { childList: true, subtree: true }); // childList/subtree — ключевые опции [web:16]
  return () => observer.disconnect();
}

// пример: заново применить маску к новым инпутам
const stop = runOnDomUpdate(() => initPhoneMask());