/* ===== Данные клинических кейсов ===== */ const CASES = [ { id:"stemi", theme:"aks", themeLabel:"ОКС / инфаркт", badge:"b-aks", title:"Острый инфаркт миокарда с подъёмом ST", severity:3, patient:{avatar:"👨‍🦰", name:"Пациент А.", age:"58 лет, мужчина", ctx:"Поступил по скорой, ~2 ч от начала боли"}, complaint:"Доктор, часа два назад как прижало за грудиной — давит сильно, будто слон на грудь сел. Отдаёт в левую руку и в челюсть. Дышать тяжело, бросило в холодный пот, стало страшно. Таблетку нитроглицерина под язык клал — не отпускает.", anamnesis:[ "Боль возникла в покое, после эмоционального стресса на работе.", "Курит 30 лет по пачке в день. Артериальная гипертензия 8 лет.", "Отец умер от инфаркта миокарда в 60 лет.", "Ранее подобных приступов не было. Регулярно терапии не получает." ], objective:{ vitals:{hr:"102", bp:"150/95", rr:"22", spo2:"93%"}, general:"Кожа бледная, влажная, холодный пот. Пациент тревожен, ищет удобное положение.", heart:"Тоны сердца приглушены, тахикардия, ритм правильный.", lungs:"В нижних отделах с обеих сторон — мелкопузырчатые незвучные хрипы.", other:"Шумов на сонных артериях нет. Отёков нет." }, extra:{title:"ЭКГ и биомаркеры", text:"ЭКГ: подъём сегмента ST в отведениях I, aVL, V1–V4; реципрокная депрессия в II, III, aVF. Патологический зубец Q начинает формироваться. Тропонин I повышен."}, quiz:{ q:"Какой наиболее вероятный диагноз и тактика?", options:[ {t:"Острый перикардит — НПВС, наблюдение", c:false}, {t:"STEMI (передне-перегородочный) — экстренная реперфузия", c:true}, {t:"ТЭЛА — антикоагуляция, тромболизис", c:false}, {t:"Расслоение аорты — контроль АД, экстренная хирургия", c:false} ], feedback:{ ok:"Верно. Типичный болевой синдром, подъём ST в передних отведениях и реципрокные изменения — это STEMI. Время мышления = гибнущий миокард: показана экстренная реперфузия.", no:"Не совсем. Подъём ST в V1–V4 с реципрокной депрессией и типичной клиникой — это STEMI, требующий немедленной реперфузии." } }, diagnosis:"Острый инфаркт миокарда с подъёмом сегмента ST (STEMI), передне-перегородочная локализация. Острая левожелудочковая недостаточность (Killip II).", algorithm:[ {s:"Вызовите реанимационную бригаду, активируйте STEMI-маршрут (door-to-balloon ≤ 90 мин)."}, {s:"Мониторинг ЭКГ, пульсоксиметрия, 2 венозных доступа."}, {s:"Обезболивание (морфин), кислород при SpO₂ < 90%, нитраты при сохраняющемся болевом синдроме и АД > 100."}, {s:"Двойная антитромбоцитарная терапия: аспирин + ингибитор P2Y12 (тикагрелор/прасугрел). Антикоагулянт (эноксапарин/НФГ)."}, {s:"Реперфузия — первичное ЧКВ предпочтительно; при недоступности ≤ 120 мин — тромболизис с последующим переводом."}, {s:"Бета-блокатор, статин в высокой дозе, ингибитор АПФ — после стабилизации."} ], keypoints:[ {t:"good",x:"Время = миокард: чем раньше реперфузия, тем больше спасённой мышцы."}, {t:"bad",x:"Не откладывайте реперфузию, ожидая тропонин — ЭКГ и клиника достаточны для STEMI."}, {t:"bad",x:"Осторожно с нитратами при инфаркте ПЖ и гипотонии — оцените состояние."} ] }, { id:"nstemi", theme:"aks", themeLabel:"ОКС / инфаркт", badge:"b-aks", title:"Острый коронарный синдром без подъёма ST", severity:2, patient:{avatar:"👩‍🦳", name:"Пациентка Б.", age:"65 лет, женщина", ctx:"Поступила через сутки от начала симптомов"}, complaint:"Вчера ночью проснулась от боли за грудиной — давящая, минут двадцать держалась, отдала в спину. Сегодня повторилось дважды, уже при небольшой нагрузке — просто по квартире походила. Раньше такого никогда не было. Как-то страшно, думаю, это сердце.", anamnesis:[ "Сахарный диабет 2 типа 12 лет, ожирение, гиперхолестеринемия.", "Гипертония, принимает периодически.", "Боли провоцируются нагрузкой, купируются в покое за 10–15 мин (прогрессирующая стенокардия).", "За последний месяц снизилась толерантность к нагрузке." ], objective:{ vitals:{hr:"88", bp:"140/85", rr:"18", spo2:"96%"}, general:"Состояние средней тяжести. Кожные покровы обычной окраски. ИМТ 32.", heart:"Тоны ритмичные, приглушены. Шумов нет.", lungs:"Дыхание везикулярное, хрипов нет.", other:"Пульс на периферических артериях сохранён. Отёков нет." }, extra:{title:"ЭКГ и лаборатория", text:"ЭКГ: горизонтальная депрессия ST в V4–V6, инверсия зубца T. Тропонин I повышен (>99-го перцентиля), динамика нарастания. Оценка по шкале GRACE — высокий риск."}, quiz:{ q:"Какая тактика наиболее оправдана?", options:[ {t:"Стабильная стенокардия — амбулаторное наблюдение", c:false}, {t:"NSTEMI высокого риска — ранняя инвазивная стратегия ≤ 24 ч", c:true}, {t:"Костохондрит — НПВС и покой", c:false}, {t:"ГЭРБ — ингибиторы протонной помпы", c:false} ], feedback:{ ok:"Верно. Депрессия ST + подъём тропонина + высокий риск по GRACE = NSTEMI. Показана ранняя инвазивная стратегия.", no:"Не совсем. У пациентки депрессия ST, рост тропонина и высокий риск — это NSTEMI, требующий раннего ЧКВ." } }, diagnosis:"Острый коронарный синдром без подъёма ST (NSTEMI). Высокий риск по шкале GRACE.", algorithm:[ {s:"Госпитализация в ОРИТ/кардиологию, мониторинг ЭКГ и ритма."}, {s:"Двойная антиагрегантная терапия (аспирин + P2Y12-ингибитор) + антикоагулянт."}, {s:"Стратификация риска (GRACE/ESC). Высокий риск → ранняя инвазивная стратегия (ЧКВ ≤ 24 ч)."}, {s:"Симптоматически: нитраты при боли, бета-блокатор при отсутствии противопоказаний."}, {s:"Статины в высокой дозе, ингибитор АПФ, контроль гликемии."}, {s:"Вторичная профилактика и кардиореабилитация."} ], keypoints:[ {t:"good",x:"Женщины и диабетики часто имеют атипичную клинику — не сбрасывайте со счетов."}, {t:"bad",x:"Не ставьте «стабильную стенокардию» при недавнем изменении/прогрессии симптомов — это ОКС."}, {t:"good",x:"Решение о раннем ЧКВ принимает стратификация риска, а не один тропонин."} ] }, { id:"asthma", theme:"odn", themeLabel:"ОДН / астма / ХОБЛ", badge:"b-odn", title:"Острый тяжёлый приступ бронхиальной астмы", severity:3, patient:{avatar:"👩", name:"Пациентка В.", age:"24 года, женщина", ctx:"Доставлена СМП, одышка 1 час"}, complaint:"Не могу... выдохнуть... свистит вся грудь... началось час назад... ингалятор... уже третий раз пшикала — не помогает... тяжело... говорит по словам... страшно задохнуться.", anamnesis:[ "Бронхиальная астма с детства, базисную терапию (ИГКС) принимает нерегулярно.", "Неделю назад перенесла ОРВИ с кашлем.", "За последние дни ингалятор сальбутамола использовала всё чаще (более 10 раз в сутки).", "Аллергия на пыльцу, домашнюю пыль." ], objective:{ vitals:{hr:"120", bp:"135/85", rr:"30", spo2:"91%"}, general:"Положение ортопноэ, опирается на руки. Речь прерывистая, произносит отдельные фразы. Выраженная работа вспомогательной мускулатуры.", lungs:"Выдох резко удлинён, свистящие сухие хрипы по всем полям. Участие в акте дыхания всех групп мышц.", heart:"Тахикардия. Гиперзвуковой перкуторный звук над лёгкими.", other:"Втянутые межрёберные промежутки, парадоксальный пульс." }, extra:{title:"Дополнительные признаки", text:"Пиковая скорость выдоха (ПСВ) < 50% от должного. При угрожающем жизни статусе — «немое лёгкое» (исчезновение хрипов при нарастающей дыхательной недостаточности), брадикардия, нарушение сознания."}, quiz:{ q:"Что является приоритетом в неотложной помощи?", options:[ {t:"Дать седативное, уложить пациента — panic attack", c:false}, {t:"Кислород + повторные небулайзеры Сальбутамола + системные ГКС", c:true}, {t:"Антибиотики широкого спектра внутривенно", c:false}, {t:"Наркотический анальгетик от боли в груди", c:false} ], feedback:{ ok:"Верно. Тяжёлый приступ астмы: оксигенация, частые бронходилататоры через небулайзер, системные ГКС, при ухудшении — ИВЛ.", no:"Не совсем. Седация и наркотики угнетают дыхание и противопоказаны. Основа — бронходилататоры и ГКС." } }, diagnosis:"Острый тяжёлый приступ бронхиальной астмы. Угроза астматического статуса.", algorithm:[ {s:"Оценка ABCD. Мониторинг SpO₂, ЧДД, ЧСС. Кислород через маску, титровать до SpO₂ 94–98%."}, {s:"Сальбутамол 5 мг через небулайзер, при тяжёлом — повторно каждые 15–20 мин (или непрерывно). Добавить ипратропия бромид."}, {s:"Системные ГКС как можно раньше: преднизолон 40–60 мг внутрь или гидрокортизон в/в."}, {s:"Магния сульфат 2 г в/в при тяжёлом приступе, не отвечающем на терапию."}, {s:"Критерии жизнеугрожающего статуса: «немое лёгкое», SpO₂ < 92%, нарушение сознания, брадикардия → ИВЛ, перевод в ОРИТ."}, {s:"После стабилизации — пересмотр базисной терапии (ступенчатое лечение, ИГКС), обучение пациента."} ], keypoints:[ {t:"bad",x:"Никогда не давайте седативные/опиоиды при астме — это угнетает дыхание и ведёт к остановке."}, {t:"good",x:"Системные ГКС работают через 4–6 ч, поэтому вводите их сразу, не ждите ухудшения."}, {t:"bad",x:"«Немое лёгкое» = плохо, а не хорошо: хрипы исчезли из-за отсутствия дыхательного резерва — это предлетальное состояние."} ] }, { id:"copd", theme:"odn", themeLabel:"ОДН / астма / ХОБЛ", badge:"b-odn", title:"Обострение ХОБЛ с острой дыхательной недостаточностью", severity:2, patient:{avatar:"👴", name:"Пациент Г.", age:"68 лет, мужчина", ctx:"Направлен врачом общей практики"}, complaint:"Уже неделю кашель усилился, мокрота стала густая, жёлто-зелёная. Дышать совсем тяжело, особенно со вчера. Раньше хоть по дому ходил, а сейчас до туалета не дойти — задыхаюсь. Сплю полусидя, две подушки подкладываю. Лихорадит три дня.", anamnesis:[ "ХОБЛ диагностирована 10 лет назад. Курит 40 лет (40 пачко-лет).", "Последние 3 дня — лихорадка до 38.5 °C, гнойная мокрота.", "Базовая SpO₂ целевая 88–92% (компенсированная гиперкапния).", "Дома — ипратропия бромид/фенотерол, длительные оксигены не получал." ], objective:{ vitals:{hr:"110", bp:"160/90", rr:"28", spo2:"86%", temp:"38.3°C"}, general:"Состояние тяжёлое. Цианоз губ, акроцианоз. Разговорчив с трудом.", lungs:"Грудная клетка бочкообразная, перкуторно — коробочный звук. Сухие свистящие хрипы на выдохе, ослабленное дыхание.", heart:"Громкий II тон над лёгочной артерией. Тахикардия.", other:"Периферические отёки голеней — признаки cor pulmonale." }, extra:{title:"Газометрия артериальной крови", text:"PaO₂ 52 мм рт.ст. ↓, PaCO₂ 68 мм рт.ст. ↑, pH 7.31 (дыхательный ацидоз). Гиперкапническая ОДН 2 типа. Рентген: усиление лёгочного рисунка, без очаговой инфильтрации."}, quiz:{ q:"Какой подход к кислородотерапии правильный?", options:[ {t:"Максимальный O₂ через маску до SpO₂ 99–100%", c:false}, {t:"Титровать O₂ до целевого SpO₂ 88–92% + NIV при тяжёлой ОДН", c:true}, {t:"Кислород не давать вообще — опасно", c:false}, {t:"Только ингаляции эфирных масел", c:false} ], feedback:{ ok:"Верно. При ХОБЛ с гиперкапнией избыток кислорода снимает гипоксический драйв дыхания → рост PaCO₂ и кома. Титруйте до 88–92%.", no:"Не совсем. Неконтролируемый O₂ при ХОБЛ ведёт к нарастанию гиперкапнии и CO₂-наркозу. Нужен титрованный кислород и NIV." } }, diagnosis:"Обострение ХОБЛ. Острая дыхательная недостаточность 2 типа (гиперкапническая), декомпенсация cor pulmonale.", algorithm:[ {s:"Контролируемая оксигенотерапия: начать с 24–28% через Venturi-маску, титровать до SpO₂ 88–92%."}, {s:"Бронходилататоры через небулайзер (ипратропия бромид + фенотерол/сальбутамол)."}, {s:"Системные ГКС: преднизолон 30–40 мг/сут на 5–7 дней."}, {s:"Антибиотики при признаках инфекции (гнойная мокрота, лихорадка) — амоксициллин/клавуланат или макролид."}, {s:"При тяжёлой ОДН с гиперкапнией/ацидозом (pH < 7.35) — неинвазивная вентиляция (NIV/BiPAP)."}, {s:"Контроль газометрии, мониторинг. При отсутствии эффекта от NIV — интубация и ИВЛ."} ], keypoints:[ {t:"bad",x:"Не давайте 100% O₂ «на всякий случай» при ХОБЛ — это классическая ошибка, ведущая к CO₂-наркозу."}, {t:"good",x:"NIV снижает потребность в интубации и летальность при обострении ХОБЛ с гиперкапнией."}, {t:"good",x:"Целевой SpO₂ для пациента с ХОБЛ — 88–92%, а не 94–98% как у большинства."} ] }, { id:"hemoshock", theme:"shock", themeLabel:"Шок и травма", badge:"b-shock", title:"Травматический геморрагический шок", severity:3, patient:{avatar:"🧑", name:"Пациент Д.", age:"30 лет, мужчина", ctx:"ДТП, доставлен бригадой СМП"}, complaint:"Всё кружится... холодно почему-то... пить очень хочу... ногу не чувствую... где я... ничего не вижу ясно...", anamnesis:[ "ДТП: лобовое столкновение, пациент за рулём, не пристёгнут.", "Закрытый перелом бедра, подозрение на перелом таза.", "Видимое наружное кровотечение из раны бедра, обширная гематома.", "Время от травмы до поступления ~40 минут." ], objective:{ vitals:{hr:"130", bp:"80/40", rr:"28", spo2:"95%"}, general:"Сознание оглушение (GCS 13). Резкая бледность, кожа покрыта холодным липким потом. Акроцианоз.", heart:"Тоны глухие, выраженная тахикардия, нитевидный пульс.", lungs:"Дыхание проводится по всем полям, хрипов нет.", other:"Левое бедро деформировано, укорочено, обширная пульсирующая гематома. Кровь на одежде. Живот мягкий, без перитонеальных знаков." }, extra:{title:"Оценка шока", text:"Класс геморрагического шока III–IV (потеря > 30% ОЦК). Дефицит базы > −6 ммоль/л, лактат повышен. Шоковый индекс (ЧСС/САД) = 130/80 = 1.6 — тяжёлый шок."}, quiz:{ q:"Что является абсолютным приоритетом?", options:[ {t:"Полное рентген-обследование до любой терапии", c:false}, {t:"Остановка кровотечения + венозный доступ + инфузия/гемотрансфузия", c:true}, {t:"Введение обезболивающего и ожидание хирурга", c:false}, {t:"Только внутривенно коллоиды в большой дозе", c:false} ], feedback:{ ok:"Верно. Принцип damage control: немедленная остановка кровотечения, восстановление ОЦК, раннее переливание крови в соотношении 1:1:1.", no:"Не совсем. До полного обследования пациент может погибнуть от гиповолемии. Сначала — остановка кровотечения и инфузия." } }, diagnosis:"Травматический геморрагический шок III–IV степени. Закрытый перелом бедра, перелом таза. Массивная кровопотеря.", algorithm:[ {s:"ABCDE. Обеспечение проходимости дыхательных путей, оксигенация, иммобилизация шейного отдела."}, {s:"Немедленная остановка наружного кровотечения: прямое давление, тазовый бинт, жгут при артериальном кровотечении."}, {s:"Два крупных венозных доступа. Пробы на группу крови, кросс-матч, лактат."}, {s:"Согревание пациента, профилактика триады смерти: гипотермия — ацидоз — коагулопатия."}, {s:"Сбалансированная инфузия кристаллоидов + ранняя гемотрансфузия (эритроциты/плазма/тромбоциты ~1:1:1). Вазопрессоры временно, если инфузия неэффективна."}, {s:"Экстренный хирургический/ортопедический гемостаз (damage control surgery). Контроль внутреннего кровотечения."} ], keypoints:[ {t:"bad",x:"Не тратьте время на полное обследование при нестабильной гемодинамике — пациент гибнет от кровопотери."}, {t:"good",x:"Боритесь с триадой смерти (гипотермия + ацидоз + коагулопатия) — это определяет выживаемость."}, {t:"bad",x:"Избыток кристаллоидов до гемотрансфузии усугубляет коагулопатию и гипотермию — не «заливайте» пациента."} ] }, { id:"sepsis", theme:"shock", themeLabel:"Шок и травма", badge:"b-shock", title:"Септический шок", severity:3, patient:{avatar:"🧔", name:"Пациент Е.", age:"55 лет, мужчина", ctx:"Направлен из приёмного покоя"}, complaint:"Три дня назад начался озноб, температура под тридцать девять, кашель с мокротой. Со вчера стало хуже — давление упало, в себя прихожу с трудом. Раньше ноги никогда так не отекали, а сейчас задыхаюсь. Пить хочу, но тошнит.", anamnesis:[ "Сахарный диабет 2 типа, плохо компенсирован.", "Заболел как ОРВИ 5 дней назад, затем присоединился кашель с гнойной мокротой.", "Самостоятельно принимал парацетамол и «антибиотик из аптечки».", "Аллергия на пенициллин." ], objective:{ vitals:{hr:"125", bp:"85/50", rr:"26", spo2:"92%", temp:"38.9°C"}, general:"Состояние тяжёлое. Кожа горячая, пятнистая сыпь. Сознание спутано, вялый.", heart:"Тоны глухие, тахикардия. САД 85 после инфузии кристаллоидов.", lungs:"В правой нижней доле — ослабленное дыхание, влажные мелкопузырчатые хрипы, притупление перкуторно.", other:"Олигурия (< 0.5 мл/кг/ч). Капиллярное наполнение > 3 сек. Холодные на ощупь конечности на поздней стадии." }, extra:{title:"Лаборатория и визуализация", text:"Лактат 4.2 ммоль/л ↑. Лейкоциты 22×10⁹/л, сдвиг формулы. Креатинин повышен. Рентген ОГК: инфильтрация нижней доли справа, плевральный выпот. Гемокультуры взяты до антибиотиков."}, quiz:{ q:"Что должно быть выполнено в первый час (Sepsis 1-hour bundle)?", options:[ {t:"Только ждать результаты посевов 24 часа", c:false}, {t:"Лактат + гемокультуры + антибиотики + инфузия 30 мл/кг + вазопрессоры при гипотонии", c:true}, {t:"Только вазопрессоры без инфузии", c:false}, {t:"Только жаропонижающие и наблюдение", c:false} ], feedback:{ ok:"Верно. Hour-1 bundle: измерить лактат, взять культуры до антибиотиков, ввести широкопрофильные антибиотики, инфузия 30 мл/кг кристаллоидов, норадреналин при стойкой гипотонии.", no:"Не совсем. Задержка с антибиотиками и инфузией每小时 повышает летальность. Все компоненты выполняются в первый час." } }, diagnosis:"Септический шок. Внебольничная пневмония нижней доли справа — вероятный источник. Острое почечное повреждение.", algorithm:[ {s:"Sepsis hour-1 bundle: лактат, забор гемокультур до антибиотиков."}, {s:"Антибиотики широкого спектра в/в в первый час (учесть аллергию на пенициллин — например, цефалоспорин/карбапенем + макролид)."}, {s:"Инфузия кристаллоидов 30 мл/кг за 3 ч при гипотензии или лактате ≥ 4 ммоль/л."}, {s:"При стойкой гипотензии после инфузии — норадреналин титровать до САД ≥ 65 мм рт.ст. Вазопрессином добавить при необходимости."}, {s:"Контроль источника инфекции (дренирование выпота, лечение пневмонии). Мониторинг: лактат, диурез, АД."}, {s:"Поддерживающая терапия: оксигенация/ИВЛ по показаниям, контроль гликемии, профилактика тромбозов."} ], keypoints:[ {t:"bad",x:"Не ждите посевов, чтобы начать антибиотики — каждая час задержки повышает летальность."}, {t:"good",x:"Норадреналин — препарат первого ряда при септическом шоке после адекватной инфузии."}, {t:"good",x:"Контроль источника инфекции так же важен, как антибиотики — без него шок не купируется."} ] } ]; /* ===== Рендер карточек ===== */ const grid = document.getElementById("caseGrid"); function sevDots(n){ let s="";for(let i=0;i<3;i++) s+=``; return s; } function renderCards(filter="all"){ grid.innerHTML=""; CASES.filter(c=>filter==="all"||c.theme===filter).forEach(c=>{ const el=document.createElement("article"); el.className=`case-card t-${c.theme}`; el.innerHTML=`
${c.patient.avatar}

${c.title}

${c.patient.name}, ${c.patient.age.split(',')[0]}

«${c.complaint.length>130?c.complaint.slice(0,130)+'…':c.complaint}»

▶ Прослушать и разобрать ${sevDots(c.severity)}
`; el.addEventListener("click",()=>openCase(c)); grid.appendChild(el); }); } /* ===== Фильтры ===== */ document.getElementById("filters").addEventListener("click",e=>{ const b=e.target.closest(".filter");if(!b)return; document.querySelectorAll(".filter").forEach(f=>f.classList.remove("is-active")); b.classList.add("is-active"); renderCards(b.dataset.filter); }); /* ===== Модальное окно ===== */ const modal=document.getElementById("modal"); const modalBody=document.getElementById("modalBody"); function vitalsHTML(v){ let extras=""; if(v.temp) extras=`
${v.temp}Температура
`; return `
${v.hr}ЧСС
${v.bp}АД
${v.rr}ЧДД
${v.spo2}SpO₂
${extras}
`; } function examHTML(o){ return `

Жизненные показатели

${vitalsHTML(o.vitals)}

Общий осмотр

${o.general}

Сердечно-сосудистая система

${o.heart}

Дыхательная система

${o.lungs}

Прочее

${o.other}

`; } function algoHTML(a){ return `
    ${a.map(s=>`
  1. ${s.s}
  2. `).join("")}
`; } function kpHTML(k){ return `
${k.map(p=>`
${p.t==='good'?'✅':'⚠️'}${p.x}
`).join("")}
`; } function openCase(c){ const qOpts=c.quiz.options.map((o,i)=>``).join(""); modalBody.innerHTML=`
${c.patient.avatar}

${c.title}

${c.patient.name} · ${c.patient.age} · ${c.patient.ctx}
${c.themeLabel}
🔊 Жалобы пациентаНажмите, чтобы услышать голос
«${c.complaint}»
📋 Анамнез заболевания и жизни
    ${c.anamnesis.map(a=>`
  • ${a}
  • `).join("")}
🩺 Объективный осмотр
${examHTML(c.objective)}
🔬 Дополнительные данные

${c.extra.text}

🧠 Поставьте диагноз и выберите тактику

${c.quiz.q}

${qOpts}
✅ Правильный диагноз

${c.diagnosis}

🚑 Алгоритм неотложной помощи
${algoHTML(c.algorithm)}
💡 Ключевые моменты и типичные ошибки
${kpHTML(c.keypoints)}
`; // озвучка const speakBtn=document.getElementById("speakBtn"); const pAvatar=document.getElementById("pAvatar"); speakBtn.addEventListener("click",()=>toggleSpeak(c.complaint,speakBtn,pAvatar)); // квиз const opts=modalBody.querySelectorAll(".quiz-opt"); const fb=document.getElementById("quizFb"); opts.forEach(o=>{ o.addEventListener("click",()=>{ opts.forEach(x=>x.disabled=true); const correct=o.dataset.c==="true"; if(correct){o.classList.add("correct")}else{o.classList.add("wrong"); // подсветить верный opts.forEach(x=>{if(x.dataset.c==="true")x.classList.add("correct")}); } fb.className=`quiz-feedback show ${correct?'ok':'no'}`; fb.innerHTML=correct?`Верно!${c.quiz.feedback.ok}`:`Не совсем так${c.quiz.feedback.no}`; }); }); modal.hidden=false; document.body.style.overflow="hidden"; } function closeModal(){ window.speechSynthesis.cancel(); modal.hidden=true; document.body.style.overflow=""; } modal.addEventListener("click",e=>{if(e.target.hasAttribute("data-close"))closeModal()}); document.addEventListener("keydown",e=>{if(e.key==="Escape"&&!modal.hidden)closeModal()}); /* ===== Озвучка (Web Speech API) ===== */ let voicesReady=false; function loadVoices(){ voicesReady=window.speechSynthesis.getVoices().length>0; } if("speechSynthesis" in window){ loadVoices(); window.speechSynthesis.onvoiceschanged=loadVoices; } function toggleSpeak(text,btn,avatar){ const synth=window.speechSynthesis; if(!synth){alert("Озвучка не поддерживается этим браузером.");return} // если уже играет — остановить if(btn.classList.contains("is-playing")){ synth.cancel(); btn.classList.remove("is-playing"); btn.textContent="▶ Прослушать"; avatar.classList.remove("is-speaking"); return; } synth.cancel(); const u=new SpeechSynthesisUtterance(text); u.lang="ru-RU";u.rate=0.97;u.pitch=1; const voices=synth.getVoices(); const ru=voices.find(v=>v.lang&&v.lang.toLowerCase().startsWith("ru")); if(ru)u.voice=ru; u.onend=()=>{btn.classList.remove("is-playing");btn.textContent="▶ Прослушать";avatar.classList.remove("is-speaking")}; u.onerror=()=>{btn.classList.remove("is-playing");btn.textContent="▶ Прослушать";avatar.classList.remove("is-speaking")}; btn.classList.add("is-playing"); btn.textContent="⏹ Остановить"; avatar.classList.add("is-speaking"); synth.speak(u); } /* остановить речь при перерисовке */ window.addEventListener("beforeunload",()=>{if("speechSynthesis" in window)window.speechSynthesis.cancel()}); /* старт */ renderCards();