<!-- Прогресс сборов T1291 V2: суммы из цен, завершение по метке и скрытие цен в попапе. -->
<style>
.t1291 {
  --fund-color: #2585d8;
  --fund-track: #dfe9f2;
  --fund-label-color: #ffffff;
}
.t1291 .fund-ready { position: relative; }
.t1291 .fund-ready .t-catalog__card__price-wrapper { display: none !important; }
.t1291 .t-catalog__prod-popup__price-wrapper,
.t1291 .t-catalog__prod-popup__price,
.t1291 .t-catalog__prod-popup__price_old,
.t1291 .fund-complete-tag { display: none !important; }
.t1291 .fund-progress {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  margin-top: auto;
  padding-top: 24px;
  font-family: var(--t-text-font, Arial, sans-serif);
  font-size: 12px;
  line-height: 1.5;
  text-align: left;
  color: inherit;
}
.t1291 .fund-track {
  height: 5px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--fund-track);
}
.t1291 .fund-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--fund-color);
  transition: width .45s ease;
}
.t1291 .fund-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  margin-top: 8px;
}
.t1291 .fund-percent {
  flex: 0 0 auto;
  color: var(--fund-color);
  font-weight: 600;
}
.t1291 .fund-summary {
  flex: 1 1 160px;
  min-width: 0;
  text-align: right;
  overflow-wrap: anywhere;
}
.t1291 .fund-badge {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 10;
  box-sizing: border-box;
  max-width: calc(100% - 28px);
  padding: 7px 12px;
  border-radius: 6px;
  background: var(--fund-color);
  color: var(--fund-label-color);
  font-family: var(--t-text-font, Arial, sans-serif);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  text-align: center;
  pointer-events: none;
}
.t1291 .fund-badge[hidden] { display: none !important; }
@media (prefers-reduced-motion: reduce) {
  .t1291 .fund-fill { transition: none; }
}
</style>
<script>
(function () {
  'use strict';
  if (window.TildaFundraisingST340) {
    window.TildaFundraisingST340.refresh();
    return;
  }

  var ROOT = '.t1291';
  var CARD = '.t-catalog__card';
  var queued = false;
  var number = new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 2 });
  var percent = new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 1 });

  function amount(value) {
    var text = String(value == null ? '' : value).trim();
    if (!text) return NaN;
    text = text.replace(/[\s\u00a0\u202f]/g, '').replace(',', '.');
    return /^\d+(?:\.\d+)?$/.test(text) ? Number(text) : NaN;
  }

  function make(tag, className, text) {
    var node = document.createElement(tag);
    node.className = className;
    if (text != null) node.textContent = text;
    return node;
  }

  function setText(node, text) {
    if (node.textContent !== text) node.textContent = text;
  }

  function reset(card) {
    card.classList.remove('fund-ready');
    card.querySelectorAll('.fund-progress, .fund-badge').forEach(function (node) {
      node.remove();
    });
  }

  function update(card) {
    var price = card.querySelector('.t-catalog__card__price .t-catalog__card__price-value');
    var old = card.querySelector('.t-catalog__card__price_old .t-catalog__card__price-value');
    var host = card.querySelector('.t-catalog__card__wrap_txt-and-btns');
    if (!price || !host) { reset(card); return; }

    // При равенстве цен Тильда может удалить старую цену даже из ответа каталога.
    // В таком случае явная метка «Сбор завершён» отличает 100% от пустого сбора.
    var goal = amount(price.getAttribute('data-product-price-def'));
    if (!Number.isFinite(goal)) goal = amount(price.textContent);
    var collected = old && old.textContent.trim() ? amount(old.textContent) : 0;
    var markedComplete = false;
    card.querySelectorAll('.t-catalog__card__mark').forEach(function (mark) {
      var isComplete = /^сбор\s+заверш[её]н[.!]?$/i.test(mark.textContent.trim());
      mark.classList.toggle('fund-complete-tag', isComplete);
      if (isComplete) markedComplete = true;
    });
    if (markedComplete && goal > 0) {
      collected = Number.isFinite(collected) ? Math.max(goal, collected) : goal;
    }
    if (!(goal > 0) || !Number.isFinite(collected) || collected < 0) {
      reset(card);
      return;
    }

    var ratio = collected / goal * 100;
    var fill = Math.min(100, ratio);
    var complete = collected >= goal;
    // Не показываем округлённые 100% до фактического достижения цели.
    var shown = !complete && ratio >= 99.95 ? 99.9 : ratio;
    var currencyNode = card.querySelector('.t-catalog__card__price .t-catalog__card__price-currency');
    var currency = currencyNode ? currencyNode.textContent.trim() : '₽';
    if (/^(?:р\.?|руб\.?)$/i.test(currency)) currency = '₽';
    var unit = currency ? ' ' + currency : '';
    var summary = 'Собрано ' + number.format(collected) + unit + ' из ' + number.format(goal) + unit;

    var progress = card.querySelector('.fund-progress');
    if (!progress) {
      progress = make('div', 'fund-progress');
      var track = make('div', 'fund-track');
      track.setAttribute('role', 'progressbar');
      track.setAttribute('aria-label', 'Прогресс сбора');
      track.setAttribute('aria-valuemin', '0');
      track.setAttribute('aria-valuemax', '100');
      track.appendChild(make('span', 'fund-fill'));
      var meta = make('div', 'fund-meta');
      meta.appendChild(make('span', 'fund-percent'));
      meta.appendChild(make('span', 'fund-summary'));
      progress.appendChild(track);
      progress.appendChild(meta);
      host.appendChild(progress);
    }
    var trackNode = progress.querySelector('.fund-track');
    trackNode.setAttribute('aria-valuenow', String(fill));
    trackNode.setAttribute('aria-valuetext', summary);
    progress.querySelector('.fund-fill').style.width = fill + '%';
    setText(progress.querySelector('.fund-percent'), percent.format(shown) + '%');
    setText(progress.querySelector('.fund-summary'), summary);

    var badge = card.querySelector('.fund-badge');
    if (!badge) {
      badge = make('div', 'fund-badge', 'Сбор завершён');
      card.appendChild(badge);
    }
    badge.hidden = !complete;
    card.classList.add('fund-ready');
  }

  function refresh() {
    document.querySelectorAll(ROOT + ' ' + CARD).forEach(update);
  }

  function schedule() {
    if (queued) return;
    queued = true;
    requestAnimationFrame(function () { queued = false; refresh(); });
  }

  function start() {
    refresh();
    // Фильтрация, «Показать ещё» и обновление сумм без повторного запуска кода.
    new MutationObserver(function (records) {
      var changed = records.some(function (record) {
        var target = record.target.nodeType === 1 ? record.target : record.target.parentElement;
        if (!target || target.closest('.fund-progress, .fund-badge')) return false;
        if (target.closest(ROOT)) return true;
        return Array.from(record.addedNodes).some(function (node) {
          return node.nodeType === 1 && (node.matches(ROOT) || node.querySelector(ROOT));
        });
      });
      if (changed) schedule();
    }).observe(document.body, {
      childList: true,
      subtree: true,
      characterData: true,
      attributes: true,
      attributeFilter: ['data-product-price-def']
    });
  }

  window.TildaFundraisingST340 = { version: '2', refresh: refresh };
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', start, { once: true });
  } else start();
})();
</script>


<!-- Мобильные карточки сборов T1291: внутренние отступы 10 px и выравнивание текстов по левому краю. -->
<style>
@media screen and (max-width: 640px) {
  .t1291 .fund-ready .t-catalog__card__contentwrapper {
    padding: 10px !important;
  }
  .t1291 .fund-ready .t-catalog__card__wrap_txt-and-btns,
  .t1291 .fund-ready .t-catalog__card__textwrapper {
    padding: 0 !important;
  }
  .t1291 .fund-ready .t-catalog__card__title,
  .t1291 .fund-ready .t-catalog__card__descr {
    margin-left: 0 !important;
    margin-right: 0 !important;
    text-align: left !important;
  }
  .t1291 .fund-progress {
    padding-top: 10px;
    text-align: left;
  }
  .t1291 .fund-meta {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }
  .t1291 .fund-summary {
    flex: none;
    width: 100%;
    text-align: left;
  }
}
</style>
Made on
Tilda