01
Для каждого концерта мы укладываем мягкий пол из мозаики и пледов, чтобы дети могли расположиться там, где им удобно. Поэтому все концерты у нас проводятся БЕЗ ОБУВИ! (берите носочки или сменку)
02
В процессе концертов для детей, мы рассказываем про музыкальные инструменты и показываем их разные варианты звучания. Так знакомство с музыкой получается очень весёлым!
03
Когда заканчивается концерт, все музыканты приглашают малышей к себе, чтобы юные слушатели могли потрогать музыкальные инструменты и попробовали на них поиграть

Как проходят концерты

«Прямая обязанность каждого родителя — заложить в детстве в своего ребенка все самое прекрасное. Миссия команды „Юный Эстет“ быть верным помощником родителям, на пути воспитания порядочных и интеллигентных людей»
Евгения Чухрова, основательница студии «Юный Эстет»

Видео о нас

Фото с концертов

На каждом концерте у нас работает фотограф, и в ближайшее время после праздника вы получите фотографии

Ближайшие концерты

}, }, window.PFS_SYNC_CONFIG || {}); // 3-letter prefixes cover both nominative (Март) and genitive (Марта) forms const MONTH_INDEX = { 'янв': 0, 'фев': 1, 'мар': 2, 'апр': 3, 'май': 4, 'мая': 4, 'июн': 5, 'июл': 6, 'авг': 7, 'сен': 8, 'окт': 9, 'ноя': 10, 'дек': 11, }; function isPast(record) { const dayNum = parseInt(record['Число'], 10); const monthRaw = (record['Месяц'] || '').trim().toLowerCase(); if (!dayNum || !monthRaw) return false; const monthNum = MONTH_INDEX[monthRaw.slice(0, 3)]; if (monthNum === undefined) return false; const now = new Date(); const year = now.getFullYear(); // Parse last (latest) time slot from "19:00" or "18:00 / 21:00" etc. let hour = 23, minute = 59; const timeRaw = record['Варианты времени'] || ''; const slots = timeRaw.match(/\d{1,2}:\d{2}/g); if (slots && slots.length) { const [h, m] = slots[slots.length - 1].split(':'); hour = parseInt(h, 10); minute = parseInt(m, 10); } // Check last year, current year, and next year — pick the candidate // closest to now. This resolves year ambiguity: a January concert viewed // in December is 1 month away as next year vs. 11 months back as this year, // so it stays. A concert from yesterday is closest as this year and gets filtered. const candidates = [-1, 0, 1].map(offset => new Date(year + offset, monthNum, dayNum, hour, minute, 0) ); const closest = candidates.reduce((best, d) => Math.abs(d - now) < Math.abs(best - now) ? d : best ); return closest < now; } function populateCard(card, record) { for (const [cls, field] of Object.entries(CONFIG.mapping.text || {})) { const elem = card.querySelector('.' + cls); if (!elem || !record[field]) continue; const atom = elem.querySelector('.tn-atom__button-text') || elem.querySelector('.tn-atom'); if (atom) atom.textContent = field === 'Цена' ? 'Купить билет от ' + record[field] + ' ₽' : record[field]; } for (const [cls, field] of Object.entries(CONFIG.mapping.image || {})) { if (!record[field]) continue; const elem = card.querySelector('.' + cls); if (!elem) continue; const img = elem.querySelector('img'); if (img) { img.src = record[field]; img.setAttribute('data-original', record[field]); } else { const t = elem.querySelector('.tn-atom') || elem; t.style.backgroundImage = 'url(' + record[field] + ')'; } } for (const [cls, field] of Object.entries(CONFIG.mapping.link || {})) { if (!record[field]) continue; const root = card.querySelector('.' + cls); if (!root) continue; const link = (root.tagName === 'A' ? root : null) || root.querySelector('a.tn-atom') || root.querySelector('a'); if (link) link.href = cls.includes('btn') ? record[field] + '#buy' : record[field]; } } // Tilda's own stylesheet forces `.t396__artboard { height: 0px !important }` // for this block (it expects to manage record heights itself via its internal // recalculation, which only knows about the ORIGINAL template card — not our // clones). Our window.dispatchEvent(new Event('resize')) below actually // triggers that Tilda recalculation, which re-zeroes every clone's height. // Fix: after Tilda's pass runs, measure each card's real content height // (furthest descendant bottom edge) and force it back via an inline // !important — which beats a stylesheet !important rule of equal specificity. function fixCardHeights(container) { container.querySelectorAll('.t396__artboard').forEach(card => { if (card.style.display === 'none') return; // skip the hidden template let maxBottom = 0; card.querySelectorAll('*').forEach(el => { const bottom = el.offsetTop + el.offsetHeight; if (bottom > maxBottom) maxBottom = bottom; }); if (maxBottom > 0) card.style.setProperty('height', maxBottom + 'px', 'important'); }); } function injectContainerStyles(blockId) { const styleId = 'pfs-responsive-' + blockId; if (document.getElementById(styleId)) return; const style = document.createElement('style'); style.id = styleId; // Only override height so N cards can stack — Tilda's own CSS handles all // artboard widths, positions, and scale transforms. style.textContent = ` #${blockId} .t396 { height: auto !important; overflow: hidden !important; } #${blockId} .t396__artboard { margin-bottom: 16px; } `; document.head.appendChild(style); } function init() { const records = window.PFS_STATIC_DATA; if (!records || !records.length) { console.warn('[PfS] PFS_STATIC_DATA не найден или пустой'); return; } const block = document.getElementById(CONFIG.blockId); if (!block) return; const artboard = block.querySelector('.t396__artboard'); if (!artboard) return; // Keep only the first artboard as the card template block.querySelectorAll('.t396__artboard').forEach((el, i) => { if (i > 0) el.remove(); }); injectContainerStyles(CONFIG.blockId); const upcoming = records.filter(r => !isPast(r)); console.log(`[PfS] Отфильтровано ${records.length - upcoming.length} прошедших концертов`); const fragment = document.createDocumentFragment(); upcoming.forEach(record => { const card = artboard.cloneNode(true); card.style.display = ''; populateCard(card, record); fragment.appendChild(card); }); artboard.style.display = 'none'; artboard.parentNode.appendChild(fragment); // Tell Tilda to re-apply its scale transform to all artboards now that // clones are in the DOM. This also re-zeroes every card's height (see // fixCardHeights above) — so we correct that right after, on the next frame. window.dispatchEvent(new Event('resize')); requestAnimationFrame(() => fixCardHeights(block)); // Required content height per card changes with breakpoint (Tilda scales // internal padding/gaps via --zoom), so recompute on real window resizes too. let resizeTimer = null; window.addEventListener('resize', () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(() => fixCardHeights(block), 200); }); console.log(`[PfS] Отрендерено ${upcoming.length} карточек`); } // We need Tilda's scale/positioning JS to run before we clone the artboard. // window.load guarantees this but can be slow (waits for Vimeo/images). // So we run on window.load OR after 500ms from DOMContentLoaded — whichever // comes first. 500ms is enough for Tilda to finish its own init on any device. let initiated = false; function runInit() { if (initiated) return; initiated = true; init(); } window.addEventListener('load', runInit); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => setTimeout(runInit, 500)); } else { setTimeout(runInit, 500); } })();
День недели
20
Месяц
Время

Мамы делятся впечатлениями о нас

Ответы на часто задаваемые вопросы

Внимание!
По вопросам возвратов и переносов на новогодние представления читайте на странице концертов. Правила, описанные ниже, не относятся к ёлкам.

Если ваши планы поменялись, сообщите нам об этом любым способом не позднее, чем за 24 часа до концерта и мы перенесем билет на другое мероприятие

К сожалению, мы не сможем вернуть или перенести билет, если вы сообщите об этом позднее, чем за сутки до концерта

Мы сможем перенести ваш билет на другой концерт, куда это будет возможно. Вам скажут куда возможно сделать перенос.

Перенести билет мы можем только один раз

Обращаем Ваше внимание, что если Вы переносите посещение концерта, локации последующих концертов могут быть другими!

Возврат средств не осуществляется по причине того, что Вам не удобна та или иная локация.

Если вы хотите сделать возврат:
По закону вы можете получить гарантированную сумму возврата в зависимости от того, сколько дней осталось до мероприятия.
100% — при отмене мероприятия
100% — если покупатель заболел или потерял близкого родственника
100% — за 10 и более дней до мероприятия
50% — за 5−10 дней
30% — за 3−5 дней
0% — менее 3 дней

Заявление на возврат билетов вы можете прислать нам на почту support@playforsoul.ru

Наш max-канал

Анонсы
Наши подписчики в числе первых видят афишу предстоящих концертов
Новости
Все самые свежие новости студии публикуются на нашей страничке
Подарки
Мы часто разыгрываем билеты и другие призы среди наших подписчиков
Телеграм-канал (тгк) play.for.soul
Польза
Экспертные сторис, полезные посты и важные рилс мамы точно оценят!
Поддержка
Мы оперативно отвечаем на все Ваши запросы в Директ
Эстетика
Черпайте музыкальное и визуальное вдохновение внутри нашего сообщества

Сотрудничество

-
Подписка на анонсы концертов
Made on
Tilda