privet-menya-zovut-madina-mn/index.html

1384 lines
58 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Мои тренировки — Мадина</title>
<style>
* { margin: 0; box-sizing: border-box; }
body {
font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #333;
}
.container { max-width: 1200px; margin: 0 auto; padding: 20px; }
header {
text-align: center;
padding: 40px 20px;
color: white;
}
header h1 { font-size: clamp(28px, 5vw, 42px); margin-bottom: 10px; }
header p { font-size: 18px; opacity: 0.9; }
.nav {
display: flex;
gap: 10px;
justify-content: center;
flex-wrap: wrap;
margin-bottom: 30px;
}
.nav button {
padding: 12px 24px;
border: none;
border-radius: 25px;
background: rgba(255,255,255,0.2);
color: white;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
}
.nav button.active, .nav button:hover {
background: white;
color: #667eea;
}
.section {
background: white;
border-radius: 20px;
padding: 30px;
margin-bottom: 30px;
box-shadow: 0 10px 40px rgba(0,0,0,0.1);
display: none;
}
.section.active { display: block; }
h2 { color: #667eea; margin-bottom: 20px; font-size: 26px; }
h3 { color: #764ba2; margin: 20px 0 15px; font-size: 20px; }
/* Workout of the day */
.workout-card {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
border-radius: 15px;
padding: 25px;
margin-bottom: 20px;
}
.workout-card h3 { margin-top: 0; color: #333; }
.exercise {
background: white;
border-radius: 12px;
padding: 20px;
margin: 15px 0;
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
}
.exercise h4 { color: #667eea; margin-bottom: 10px; }
.exercise-meta {
display: flex;
gap: 15px;
flex-wrap: wrap;
margin: 10px 0;
font-size: 14px;
color: #666;
}
.exercise-meta span {
background: #f0f0f5;
padding: 5px 12px;
border-radius: 15px;
}
.video-placeholder {
width: 100%;
aspect-ratio: 16/9;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 18px;
margin: 15px 0;
cursor: pointer;
transition: transform 0.3s;
}
.video-placeholder:hover { transform: scale(1.02); }
.video-placeholder::before {
content: "▶";
font-size: 48px;
margin-right: 15px;
}
/* Exercise catalog */
.exercise-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.exercise-card {
background: white;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
transition: transform 0.3s;
}
.exercise-card:hover { transform: translateY(-5px); }
.exercise-card .video {
width: 100%;
aspect-ratio: 16/9;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 36px;
cursor: pointer;
}
.exercise-card .info { padding: 20px; }
.exercise-card .info h4 { color: #667eea; margin-bottom: 10px; }
.exercise-card .info p { color: #666; font-size: 14px; line-height: 1.6; }
.exercise-card .meta {
display: flex;
gap: 10px;
margin-top: 15px;
flex-wrap: wrap;
}
.exercise-card .meta span {
background: #f0f0f5;
padding: 5px 12px;
border-radius: 15px;
font-size: 12px;
color: #666;
}
/* Calendar */
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 10px;
}
.calendar-day {
background: #f8f9fc;
border-radius: 10px;
padding: 15px 10px;
text-align: center;
min-height: 100px;
cursor: pointer;
transition: 0.3s;
border: 2px solid transparent;
}
.calendar-day:hover { border-color: #667eea; }
.calendar-day.today {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.calendar-day.done {
background: #d4edda;
border-color: #28a745;
}
.calendar-day .day-num {
font-size: 20px;
font-weight: bold;
margin-bottom: 5px;
}
.calendar-day .workout-type {
font-size: 11px;
line-height: 1.4;
}
.calendar-header {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 10px;
margin-bottom: 10px;
}
.calendar-header div {
text-align: center;
font-weight: bold;
color: #667eea;
padding: 10px;
}
/* Tracker */
.tracker-form {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.tracker-form input {
padding: 15px;
border: 2px solid #e0e0e5;
border-radius: 12px;
font-size: 16px;
}
.tracker-form input:focus {
border-color: #667eea;
outline: none;
}
.btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px 30px;
border-radius: 12px;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(102,126,234,0.4); }
.btn-block { width: 100%; }
.progress-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 20px;
margin-top: 30px;
}
.stat-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 25px;
border-radius: 15px;
text-align: center;
}
.stat-card .value { font-size: 36px; font-weight: bold; }
.stat-card .label { opacity: 0.9; margin-top: 5px; }
.week-selector {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.week-selector button {
background: #667eea;
color: white;
border: none;
padding: 10px 20px;
border-radius: 8px;
cursor: pointer;
}
.category-filter {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 20px;
}
.category-filter button {
padding: 8px 16px;
border: 2px solid #667eea;
background: white;
color: #667eea;
border-radius: 20px;
cursor: pointer;
}
.category-filter button.active {
background: #667eea;
color: white;
}
.modal {
display: none;
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.8);
z-index: 1000;
align-items: center;
justify-content: center;
}
.modal.active { display: flex; }
.modal-content {
background: white;
border-radius: 20px;
padding: 30px;
max-width: 800px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
}
.modal-close {
float: right;
font-size: 28px;
cursor: pointer;
color: #666;
}
.goal-info {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
}
.goal-info p { margin: 5px 0; }
/* Музыкальный плеер */
.music-player {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
color: white;
}
.music-player h3 { margin: 0 0 15px; font-size: 18px; }
.player-controls {
display: flex;
align-items: center;
gap: 15px;
flex-wrap: wrap;
}
.player-btn {
width: 50px;
height: 50px;
border-radius: 50%;
border: none;
background: white;
color: #667eea;
font-size: 20px;
cursor: pointer;
transition: 0.3s;
}
.player-btn:hover { transform: scale(1.1); }
.player-btn.big {
width: 60px;
height: 60px;
font-size: 28px;
}
.playlist-select {
flex: 1;
min-width: 200px;
padding: 12px;
border-radius: 10px;
border: none;
font-size: 14px;
background: rgba(255,255,255,0.9);
color: #333;
}
.now-playing {
margin-top: 15px;
font-size: 14px;
opacity: 0.9;
}
.volume-control {
display: flex;
align-items: center;
gap: 10px;
margin-top: 10px;
}
.volume-control input {
flex: 1;
height: 6px;
-webkit-appearance: none;
background: rgba(255,255,255,0.3);
border-radius: 3px;
}
.volume-control input::-webkit-slider-thumb {
-webkit-appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
background: white;
cursor: pointer;
}
.equalizer {
display: flex;
gap: 3px;
align-items: flex-end;
height: 20px;
margin-left: auto;
}
.equalizer span {
width: 4px;
background: rgba(255,255,255,0.7);
border-radius: 2px;
animation: equalize 0.5s ease-in-out infinite alternate;
}
.equalizer span:nth-child(2) { animation-delay: 0.1s; }
.equalizer span:nth-child(3) { animation-delay: 0.2s; }
.equalizer span:nth-child(4) { animation-delay: 0.3s; }
@keyframes equalize {
from { height: 5px; }
to { height: 20px; }
}
.equalizer.off span { animation: none; height: 5px; }
</style>
</head>
<body>
<div class="container">
<header>
<h1>💪 Мои тренировки</h1>
<p>Персональная программа на 8 недель</p>
</header>
<nav class="nav">
<button class="active" onclick="showSection('today')">📅 Сегодня</button>
<button onclick="showSection('catalog')">🎬 Каталог упражнений</button>
<button onclick="showSection('calendar')">📆 Календарь</button>
<button onclick="showSection('tracker')">📊 Трекер прогресса</button>
<button onclick="showSection('nutrition')">🥗 Питание</button>
<button onclick="showSection('habits')">✨ Привычки</button>
</nav>
<!-- СЕКЦИЯ: СЕГОДНЯ -->
<div id="today" class="section active">
<h2>Тренировка на сегодня</h2>
<!-- Музыкальный плеер -->
<div class="music-player">
<h3>🎵 Мотивационная музыка</h3>
<div class="player-controls">
<button class="player-btn" onclick="prevTrack()">⏮</button>
<button class="player-btn big" onclick="togglePlay()" id="play-btn">▶</button>
<button class="player-btn" onclick="nextTrack()">⏭</button>
<select class="playlist-select" id="playlist-select" onchange="changePlaylist()">
<option value="workout">💪 Для тренировки (энергичная)</option>
<option value="cardio">🏃 Для кардио (быстрая)</option>
<option value="yoga">🧘 Для растяжки (спокойная)</option>
<option value="motivation">🔥 Мотивация (речь + музыка)</option>
</select>
<div class="equalizer off" id="equalizer">
<span></span><span></span><span></span><span></span>
</div>
</div>
<div class="volume-control">
<span>🔈</span>
<input type="range" min="0" max="100" value="70" oninput="setVolume(this.value)">
<span>🔊</span>
</div>
<div class="now-playing" id="now-playing">Выберите плейлист и нажмите ▶</div>
</div>
<div class="goal-info">
<p><strong>Цель:</strong> Похудение, осанка, укрепление рук</p>
<p><strong>Длительность:</strong> 45-60 минут</p>
<p><strong>Фокус:</strong> <span id="today-focus">Пресс и осанка</span></p>
</div>
<div id="today-workout"></div>
<button class="btn btn-block" onclick="markTodayDone()">✅ Отметить тренировку выполненной</button>
</div>
<!-- СЕКЦИЯ: КАТАЛОГ -->
<div id="catalog" class="section">
<h2>Каталог упражнений с видео</h2>
<div class="category-filter">
<button class="active" onclick="filterCatalog('all')">Все</button>
<button onclick="filterCatalog('posture')">Осанка и спина</button>
<button onclick="filterCatalog('abs')">Живот и бока</button>
<button onclick="filterCatalog('arms')">Руки</button>
<button onclick="filterCatalog('legs')">Ноги и ягодицы</button>
<button onclick="filterCatalog('cardio')">Кардио</button>
</div>
<div class="exercise-grid" id="exercise-grid"></div>
</div>
<!-- СЕКЦИЯ: КАЛЕНДАРЬ -->
<div id="calendar" class="section">
<h2>Календарь тренировок на 8 недель</h2>
<div class="week-selector">
<button onclick="changeWeek(-1)">← Назад</button>
<span id="week-label">Неделя 1</span>
<button onclick="changeWeek(1)">Вперёд →</button>
</div>
<div class="calendar-header">
<div>Пн</div><div>Вт</div><div>Ср</div><div>Чт</div><div>Пт</div><div>Сб</div><div>Вс</div>
</div>
<div class="calendar-grid" id="calendar-grid"></div>
</div>
<!-- СЕКЦИЯ: ТРЕКЕР -->
<div id="tracker" class="section">
<h2>Трекер прогресса</h2>
<div class="tracker-form">
<input type="number" id="weight" placeholder="Вес (кг)" step="0.1">
<input type="number" id="waist" placeholder="Талия (см)">
<input type="number" id="hips" placeholder="Бёдра (см)">
<input type="number" id="arms" placeholder="Руки (см)">
<button class="btn" onclick="addProgress()">Записать</button>
</div>
<div class="progress-stats" id="progress-stats"></div>
<!-- График веса -->
<div style="margin-top: 30px; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); border-radius: 15px; padding: 25px;">
<h3>📈 График веса</h3>
<p style="margin-bottom: 15px; color: #666;">Цель: <strong>58 кг</strong> через 8 недель</p>
<canvas id="weight-chart" height="80" style="width: 100%; background: white; border-radius: 10px;"></canvas>
<div style="display: flex; justify-content: space-between; margin-top: 10px; font-size: 12px; color: #666;">
<span>Неделя 1</span>
<span>Неделя 4</span>
<span>Неделя 8</span>
</div>
</div>
<div id="progress-history" style="margin-top: 30px;"></div>
</div>
<!-- СЕКЦИЯ: ПРИВЫЧКИ -->
<div id="habits" class="section">
<h2>✨ Полезные привычки для похудения</h2>
<p style="margin-bottom: 20px; color: #666;">Отмечай галочкой каждый день, когда выполнил привычку. Цель — 21 день подряд!</p>
<div id="habits-list"></div>
<div class="progress-stats" style="margin-top: 30px;">
<div class="stat-card" style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);">
<div class="value" id="habits-streak">0</div>
<div class="label">Дней подряд</div>
</div>
<div class="stat-card" style="background: linear-gradient(135deg, #30cfd0 0%, #330867 100%);">
<div class="value" id="habits-total">0</div>
<div class="label">Всего выполнено</div>
</div>
<div class="stat-card" style="background: linear-gradient(135deg, #a8ff78 0%, #78ffd6 100%);">
<div class="value" id="habits-percent">0%</div>
<div class="label">Успех сегодня</div>
</div>
</div>
</div>
<!-- СЕКЦИЯ: ПИТАНИЕ -->
<div id="nutrition" class="section">
<h2>🥗 Питание для похудения</h2>
<div class="goal-info" style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);">
<h3 style="margin-top: 0; color: #333;">Твоя цель</h3>
<p><strong>Стартовый вес:</strong> 65 кг</p>
<p><strong>Цель за 2 месяца:</strong> 58-59 кг (-6-7 кг)</p>
<p><strong>Калорий в день:</strong> 1400-1500 ккал</p>
<p><strong>Воды в день:</strong> 2-2.5 литра</p>
</div>
<h3>📋 Рекомендации по питанию</h3>
<div class="exercise-grid" style="grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));">
<div class="exercise-card">
<div class="info">
<h4>🍳 Завтрак (7:00-9:00)</h4>
<p>Омлет из 2 яиц с овощами + кусочек цельнозернового хлеба</p>
<p>Или: овсянка на воде с ягодами + 1 яйцо</p>
<div class="meta"><span>~350 ккал</span></div>
</div>
</div>
<div class="exercise-card">
<div class="info">
<h4>🥗 Перекус (11:00)</h4>
<p>Яблоко/груша + 10 орешков (миндаль/грецкий)</p>
<p>Или: натуральный йогурт без сахара</p>
<div class="meta"><span>~150 ккал</span></div>
</div>
</div>
<div class="exercise-card">
<div class="info">
<h4>🍲 Обед (13:00-14:00)</h4>
<p>Куриная грудка/рыба (150г) + гречка/рис (100г) + салат</p>
<p>Или: суп на овощном бульоне + кусочек мяса</p>
<div class="meta"><span>~450 ккал</span></div>
</div>
</div>
<div class="exercise-card">
<div class="info">
<h4>🥛 Перекус (16:00)</h4>
<p>Творог (100г) + ложка мёда</p>
<p>Или: кефир + 1 хлебец</p>
<div class="meta"><span>~150 ккал</span></div>
</div>
</div>
<div class="exercise-card">
<div class="info">
<h4>🐟 Ужин (18:00-19:00)</h4>
<p>Рыба/курица (120г) + тушёные овощи</p>
<p>Или: салат с тунцом и яйцом</p>
<div class="meta"><span>~300 ккал</span></div>
</div>
</div>
<div class="exercise-card">
<div class="info">
<h4>⚠️ Что исключить</h4>
<p>❌ Сахар и сладости</p>
<p>❌ Белый хлеб и выпечку</p>
<p>❌ Газировку и пакетированные соки</p>
<p>❌ Фастфуд и майонез</p>
<div class="meta"><span>Экономия ~500 ккал/день</span></div>
</div>
</div>
</div>
<h3 style="margin-top: 30px;">💧 Трекер воды</h3>
<div style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); border-radius: 15px; padding: 25px; margin-top: 20px;">
<p style="margin-bottom: 15px;">Выпито сегодня: <strong id="water-count">0</strong> из 8 стаканов</p>
<div style="display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 15px;" id="water-glasses"></div>
<button class="btn" onclick="addWater()">💧 Выпить стакан</button>
<button class="btn" onclick="resetWater()" style="background: #999; margin-left: 10px;">Сбросить</button>
</div>
<h3 style="margin-top: 30px;">📊 Калькулятор калорий</h3>
<div style="background: #f8f9fc; border-radius: 15px; padding: 25px; margin-top: 20px;">
<p>Рассчитай калорийность продуктов, которые ешь:</p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-top: 15px;">
<input type="text" id="product-name" placeholder="Продукт (например: яблоко)" style="padding: 12px; border: 2px solid #e0e0e5; border-radius: 10px;">
<input type="number" id="product-grams" placeholder="Вес (грамм)" style="padding: 12px; border: 2px solid #e0e0e5; border-radius: 10px;">
</div>
<button class="btn" onclick="calculateCalories()" style="margin-top: 15px;">Рассчитать</button>
<div id="calories-result" style="margin-top: 15px; font-size: 18px; font-weight: bold; color: #667eea;"></div>
</div>
<div class="progress-stats" style="margin-top: 30px;">
<div class="stat-card" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">
<div class="value" id="total-water">0</div>
<div class="label">Стаканов всего</div>
</div>
<div class="stat-card" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);">
<div class="value" id="days-tracked">0</div>
<div class="label">Дней отслеживания</div>
</div>
<div class="stat-card" style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);">
<div class="value" id="avg-weight">65</div>
<div class="label">Средний вес</div>
</div>
</div>
</div>
</div>
<!-- Модальное окно для видео -->
<div class="modal" id="video-modal">
<div class="modal-content">
<span class="modal-close" onclick="closeModal()">&times;</span>
<h3 id="modal-title"></h3>
<div id="modal-video"></div>
<p id="modal-desc" style="margin-top: 20px; line-height: 1.6;"></p>
</div>
</div>
<script>
// === МУЗЫКАЛЬНЫЙ ПЛЕЕР ===
const playlists = {
workout: [
{ name: "Eye of the Tiger - Survivor", url: "https://www.youtube.com/embed/btPJPFnesV4?autoplay=1&loop=1&playlist=btPJPFnesV4" },
{ name: "Stronger - Kanye West", url: "https://www.youtube.com/embed/PsO6ZnU8G6g?autoplay=1&loop=1&playlist=PsO6ZnU8G6g" },
{ name: "Lose Yourself - Eminem", url: "https://www.youtube.com/embed/_Yhyp-_hX2s?autoplay=1&loop=1&playlist=_Yhyp-_hX2s" },
{ name: "Titanium - David Guetta", url: "https://www.youtube.com/embed/JRfuAukYTKg?autoplay=1&loop=1&playlist=JRfuAukYTKg" },
{ name: "Can't Hold Us - Macklemore", url: "https://www.youtube.com/embed/2zNSgSzhBfM?autoplay=1&loop=1&playlist=2zNSgSzhBfM" }
],
cardio: [
{ name: "Uptown Funk - Mark Ronson", url: "https://www.youtube.com/embed/OPf0YbXqDm0?autoplay=1&loop=1&playlist=OPf0YbXqDm0" },
{ name: "Shake It Off - Taylor Swift", url: "https://www.youtube.com/embed/nfWlot6h_JM?autoplay=1&loop=1&playlist=nfWlot6h_JM" },
{ name: "Happy - Pharrell Williams", url: "https://www.youtube.com/embed/ZbZSe6N_BXs?autoplay=1&loop=1&playlist=ZbZSe6N_BXs" },
{ name: "24K Magic - Bruno Mars", url: "https://www.youtube.com/embed/UqyT8IEBkvY?autoplay=1&loop=1&playlist=UqyT8IEBkvY" }
],
yoga: [
{ name: "Weightless - Marconi Union", url: "https://www.youtube.com/embed/UfcAV6ZK8hE?autoplay=1&loop=1&playlist=UfcAV6ZK8hE" },
{ name: "River Flows in You - Yiruma", url: "https://www.youtube.com/embed/7maJOI3QMu0?autoplay=1&loop=1&playlist=7maJOI3QMu0" },
{ name: "Meditation Music - Relaxing Piano", url: "https://www.youtube.com/embed/1ZYbU82GVz4?autoplay=1&loop=1&playlist=1ZYbU82GVz4" },
{ name: "Tibetan Bowls - Healing", url: "https://www.youtube.com/embed/47G2BgXSC74?autoplay=1&loop=1&playlist=47G2BgXSC74" }
],
motivation: [
{ name: "Motivational Speech - Believe", url: "https://www.youtube.com/embed/rHY3HCxJF20?autoplay=1&loop=1&playlist=rHY3HCxJF20" },
{ name: "Never Give Up - Motivation", url: "https://www.youtube.com/embed/tvnxMyrWb1E?autoplay=1&loop=1&playlist=tvnxMyrWb1E" },
{ name: "Warrior Mindset - Motivation", url: "https://www.youtube.com/embed/hp3j8c9pKxU?autoplay=1&loop=1&playlist=hp3j8c9pKxU" }
]
};
let currentPlaylist = 'workout';
let currentTrackIndex = 0;
let isPlaying = false;
let player = null;
// Загрузка YouTube IFrame API
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubeIframeAPIReady() {
console.log('YouTube Player API готов');
}
function initPlayer() {
if (!player && window.YT && YT.Player) {
player = new YT.Player('music-player-frame', {
height: '0',
width: '0',
playerVars: { 'autoplay': 0, 'controls': 0 },
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
}
function onPlayerReady(event) {
console.log('Плеер готов');
}
function onPlayerStateChange(event) {
if (event.data === YT.PlayerState.ENDED) {
nextTrack();
}
updatePlayButton();
}
function changePlaylist() {
currentPlaylist = document.getElementById('playlist-select').value;
currentTrackIndex = 0;
loadTrack(currentTrackIndex);
}
function loadTrack(index) {
const playlist = playlists[currentPlaylist];
if (!playlist || playlist.length === 0) return;
const track = playlist[index];
document.getElementById('now-playing').textContent = '🎵 ' + track.name;
if (player && player.loadVideoById) {
const videoId = track.url.split('v=')[1].split('&')[0];
player.loadVideoById(videoId);
player.setVolume(70);
}
updatePlayButton();
}
function togglePlay() {
if (!player) {
initPlayer();
setTimeout(() => {
loadTrack(currentTrackIndex);
isPlaying = true;
updatePlayButton();
document.getElementById('equalizer').classList.remove('off');
}, 500);
return;
}
if (isPlaying) {
player.pauseVideo();
document.getElementById('equalizer').classList.add('off');
} else {
player.playVideo();
document.getElementById('equalizer').classList.remove('off');
}
isPlaying = !isPlaying;
updatePlayButton();
}
function nextTrack() {
const playlist = playlists[currentPlaylist];
currentTrackIndex = (currentTrackIndex + 1) % playlist.length;
loadTrack(currentTrackIndex);
isPlaying = true;
document.getElementById('equalizer').classList.remove('off');
}
function prevTrack() {
const playlist = playlists[currentPlaylist];
currentTrackIndex = (currentTrackIndex - 1 + playlist.length) % playlist.length;
loadTrack(currentTrackIndex);
isPlaying = true;
document.getElementById('equalizer').classList.remove('off');
}
function setVolume(value) {
if (player && player.setVolume) {
player.setVolume(value);
}
}
function updatePlayButton() {
document.getElementById('play-btn').textContent = isPlaying ? '⏸' : '▶';
}
// === ДАННЫЕ: УПРАЖНЕНИЯ С ВИДЕО ===
const exercises = [
// Осанка и спина
{ id: 1, name: "Кошка-корова", category: "posture", focus: "Гиперлордоз, гибкость спины", time: "2 мин", reps: "10-12 повторений", video: "https://www.youtube.com/embed/2qhJb8SvHjM", desc: "Медленно прогибай спину вверх, затем вниз. Дыхание ровное." },
{ id: 2, name: "Стена у стены", category: "posture", focus: "Осанка", time: "1 мин", reps: "3 подхода", video: "https://www.youtube.com/embed/k_FZCvsL53w", desc: "Встань спиной к стене, прижми затылок, лопатки, ягодицы и пятки." },
{ id: 3, name: "Лодочка", category: "posture", focus: "Спина, осанка", time: "1 мин", reps: "10 повторений", video: "https://www.youtube.com/embed/4K0e1EjwRnM", desc: "Лёжа на животе, одновременно поднимай руки и ноги." },
{ id: 4, name: "Тяга к стене", category: "posture", focus: "Осанка, плечи", time: "2 мин", reps: "15 повторений", video: "https://www.youtube.com/embed/aS5C2nQa3vM", desc: "Стоя у стены, своди лопатки и тянись руками вверх." },
{ id: 5, name: "Планка на предплечьях", category: "posture", focus: "Кор, осанка", time: "30-60 сек", reps: "3 подхода", video: "https://www.youtube.com/embed/pSHjTRCQxIw", desc: "Держи тело ровно, не прогибай поясницу." },
// Живот и бока
{ id: 6, name: "Вакуум", category: "abs", focus: "Плоский живот", time: "2 мин", reps: "5 подходов по 15 сек", video: "https://www.youtube.com/embed/8QcXlB6kXhE", desc: "Выдохни весь воздух, втяни живот под рёбра, держи." },
{ id: 7, name: "Велосипед", category: "abs", focus: "Косые мышцы, бока", time: "2 мин", reps: "20 повторений", video: "https://www.youtube.com/embed/1obhK7pOwEw", desc: "Лёжа на спине, крути педали, касайся локтем противоположного колена." },
{ id: 8, name: "Скручивания", category: "abs", focus: "Пресс", time: "2 мин", reps: "15-20 повторений", video: "https://www.youtube.com/embed/Xyd_fa5zoEU", desc: "Поднимай только лопатки, поясница прижата." },
{ id: 9, name: "Боковая планка", category: "abs", focus: "Бока, косые", time: "30 сек", reps: "3 подхода на сторону", video: "https://www.youtube.com/embed/3wVknM4sLgM", desc: "Держи тело в линию, не опускай таз." },
{ id: 10, name: "Ножницы", category: "abs", focus: "Нижний пресс", time: "1 мин", reps: "3 подхода", video: "https://www.youtube.com/embed/02eKNa3NOOo", desc: "Лёжа на спине, скрещивай ноги в воздухе." },
// Руки
{ id: 11, name: "Отжимания от стены", category: "arms", focus: "Трицепс, грудь", time: "2 мин", reps: "15 повторений", video: "https://www.youtube.com/embed/IODxDxX7oi4", desc: "Чем дальше ноги от стены, тем сложнее." },
{ id: 12, name: "Обратные отжимания", category: "arms", focus: "Трицепс", time: "2 мин", reps: "12 повторений", video: "https://www.youtube.com/embed/6pS5E1y5_7E", desc: "Сидя на полу, руки сзади на стуле, опускай таз." },
{ id: 13, name: "Круговые вращения", category: "arms", focus: "Плечи", time: "1 мин", reps: "20 вперёд, 20 назад", video: "https://www.youtube.com/embed/qX9YfKzIwHs", desc: "Руки в стороны, делай маленькие круги." },
{ id: 14, name: "Боксирование", category: "arms", focus: "Руки, кардио", time: "2 мин", reps: "50 ударов", video: "https://www.youtube.com/embed/hP2uH4XnJdM", desc: "Быстро боксируй в воздухе, держи темп." },
// Ноги и ягодицы
{ id: 15, name: "Приседания", category: "legs", focus: "Ноги, ягодицы", time: "3 мин", reps: "20 повторений", video: "https://www.youtube.com/embed/U0t2KK8vLzU", desc: "Спина ровная, колени не выходят за носки." },
{ id: 16, name: "Выпады", category: "legs", focus: "Ноги, ягодицы", time: "3 мин", reps: "12 на ногу", video: "https://www.youtube.com/embed/QOVaTkbz9fA", desc: "Шагай вперёд, опускай колено почти до пола." },
{ id: 17, name: "Ягодичный мост", category: "legs", focus: "Ягодицы", time: "2 мин", reps: "20 повторений", video: "https://www.youtube.com/embed/7iI4oVXQkXQ", desc: "Лёжа на спине, поднимай таз, сжимай ягодицы." },
{ id: 18, name: "Махи ногой", category: "legs", focus: "Ягодицы, бока", time: "2 мин", reps: "15 на ногу", video: "https://www.youtube.com/embed/4vA8R0eXzQY", desc: "Стоя на четвереньках, поднимай ногу в сторону." },
// Кардио
{ id: 19, name: "Джампинг Джек", category: "cardio", focus: "Сжигание жира", time: "2 мин", reps: "40 повторений", video: "https://www.youtube.com/embed/c4DAnljDykF", desc: "Прыжки с хлопком над головой." },
{ id: 20, name: "Бег на месте", category: "cardio", focus: "Кардио", time: "3 мин", reps: "Высоко поднимай колени", video: "https://www.youtube.com/embed/2qTF3S1Qh8M", desc: "Быстрый темп, руки работают." },
{ id: 21, name: "Бёрпи (облегчённый)", category: "cardio", focus: "Всё тело", time: "2 мин", reps: "10 повторений", video: "https://www.youtube.com/embed/auBL5Jk54gw", desc: "Присядь, шаг назад в планку, шаг вперёд, прыжок." }
];
// === ПЛАН НА 8 НЕДЕЛЬ ===
const workoutPlan = [
// Неделя 1-2: Адаптация
{ week: 1, days: [
{ type: "Осанка + Пресс", exercises: [1, 2, 5, 6, 7, 8] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19, 20] },
{ type: "Ноги + Ягодицы", exercises: [15, 16, 17, 18] },
{ type: "Осанка + Пресс", exercises: [1, 3, 4, 6, 9, 10] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19] },
{ type: "Полная тренировка", exercises: [2, 5, 7, 15, 17, 20] },
{ type: "Отдых / Растяжка", exercises: [] }
]},
// Неделя 3-4: Увеличение интенсивности
{ week: 2, days: [
{ type: "Осанка + Пресс", exercises: [1, 2, 3, 6, 7, 8, 9] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19, 20] },
{ type: "Ноги + Ягодицы", exercises: [15, 16, 17, 18] },
{ type: "Осанка + Пресс", exercises: [1, 4, 5, 6, 8, 10] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19, 20] },
{ type: "Полная тренировка", exercises: [2, 3, 7, 15, 17, 21] },
{ type: "Отдых / Растяжка", exercises: [] }
]},
// Неделя 5-6: Интенсив
{ week: 3, days: [
{ type: "Осанка + Пресс", exercises: [1, 2, 3, 4, 6, 7, 8, 9] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19, 20, 21] },
{ type: "Ноги + Ягодицы", exercises: [15, 16, 17, 18] },
{ type: "Осанка + Пресс", exercises: [1, 3, 5, 6, 8, 9, 10] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19, 20] },
{ type: "Полная тренировка", exercises: [2, 4, 7, 15, 16, 17, 21] },
{ type: "Отдых / Растяжка", exercises: [] }
]},
// Неделя 7-8: Финал
{ week: 4, days: [
{ type: "Осанка + Пресс", exercises: [1, 2, 3, 4, 5, 6, 7, 8, 9] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19, 20, 21] },
{ type: "Ноги + Ягодицы", exercises: [15, 16, 17, 18] },
{ type: "Осанка + Пресс", exercises: [1, 3, 4, 5, 6, 8, 9, 10] },
{ type: "Руки + Кардио", exercises: [11, 12, 13, 14, 19, 20, 21] },
{ type: "Полная тренировка", exercises: [2, 3, 4, 7, 15, 16, 17, 18, 21] },
{ type: "Отдых / Растяжка", exercises: [] }
]}
];
// Повторить недели 5-8 как 3-4
for (let i = 4; i < 8; i++) {
workoutPlan[i] = workoutPlan[i - 2];
}
// === СОСТОЯНИЕ ===
let currentWeek = 0;
let progressData = JSON.parse(localStorage.getItem('madinaProgress') || '{"entries":[],"completedDays":[],"water":[],"waterToday":0,"habits":{}}');
// === ПРИВЫЧКИ ===
const habitsList = [
{ id: 'water', icon: '💧', name: 'Выпить 8 стаканов воды' },
{ id: 'workout', icon: '💪', name: 'Тренировка по плану' },
{ id: 'breakfast', icon: '🍳', name: 'Здоровый завтрак' },
{ id: 'no_sugar', icon: '🚫', name: 'Без сахара и сладкого' },
{ id: 'sleep', icon: '😴', name: 'Сон 7-8 часов' },
{ id: 'no_late', icon: '🕖', name: 'Ужин до 19:00' },
{ id: 'walk', icon: '🚶', name: 'Прогулка 30 мин' },
{ id: 'stretch', icon: '🧘', name: 'Растяжка утром' }
];
// === ИНИЦИАЛИЗАЦИЯ ===
function init() {
renderTodayWorkout();
renderCatalog('all');
renderCalendar();
renderProgress();
}
// === СЕКЦИИ ===
function showSection(id) {
document.querySelectorAll('.section').forEach(s => s.classList.remove('active'));
document.querySelectorAll('.nav button').forEach(b => b.classList.remove('active'));
document.getElementById(id).classList.add('active');
event.target.classList.add('active');
}
// === СЕГОДНЯ ===
function getTodayWorkout() {
const startDate = new Date('2026-08-10');
const today = new Date();
const diffDays = Math.floor((today - startDate) / (1000 * 60 * 60 * 24));
const weekNum = Math.floor(diffDays / 7);
const dayNum = diffDays % 7;
if (weekNum >= 8) return workoutPlan[7].days[dayNum];
if (weekNum < 0) return workoutPlan[0].days[dayNum];
return workoutPlan[weekNum].days[dayNum];
}
function renderTodayWorkout() {
const today = getTodayWorkout();
const focusMap = {
'Осанка': 'Осанка и спина',
'Пресс': 'Живот и бока',
'Руки': 'Руки',
'Кардио': 'Кардио',
'Ноги': 'Ноги и ягодицы'
};
let focusText = today.type.split('+').map(s => focusMap[s.trim()] || s).join(', ');
document.getElementById('today-focus').textContent = focusText || today.type;
const container = document.getElementById('today-workout');
if (today.exercises.length === 0) {
container.innerHTML = '<div class="workout-card"><h3>🧘 Сегодня день отдыха!</h3><p>Сделай лёгкую растяжку или прогулку.</p></div>';
return;
}
container.innerHTML = '<div class="workout-card"><h3>📋 Программа на сегодня: ' + today.type + '</h3>' +
today.exercises.map(exId => {
const ex = exercises.find(e => e.id === exId);
return '<div class="exercise">' +
'<h4>' + ex.name + '</h4>' +
'<div class="video-placeholder" onclick="openVideo(' + ex.id + ')">Смотреть видео</div>' +
'<div class="exercise-meta">' +
'<span>⏱ ' + (ex.time || ex.reps) + '</span>' +
'<span>🎯 ' + ex.focus + '</span>' +
'</div>' +
'<p>' + ex.desc + '</p>' +
'</div>';
}).join('') +
'</div>';
}
function markTodayDone() {
const todayStr = new Date().toDateString();
if (!progressData.completedDays.includes(todayStr)) {
progressData.completedDays.push(todayStr);
localStorage.setItem('madinaProgress', JSON.stringify(progressData));
alert('🎉 Молодец! Тренировка отмечена!');
renderCalendar();
renderProgress();
} else {
alert('✅ Уже отмечено!');
}
}
// === КАТАЛОГ ===
function filterCatalog(category) {
document.querySelectorAll('.category-filter button').forEach(b => b.classList.remove('active'));
event.target.classList.add('active');
renderCatalog(category);
}
function renderCatalog(category) {
const filtered = category === 'all' ? exercises : exercises.filter(e => e.category === category);
document.getElementById('exercise-grid').innerHTML = filtered.map(ex =>
'<div class="exercise-card">' +
'<div class="video" onclick="openVideo(' + ex.id + ')">▶</div>' +
'<div class="info">' +
'<h4>' + ex.name + '</h4>' +
'<p>' + ex.desc + '</p>' +
'<div class="meta">' +
'<span>🎯 ' + ex.focus + '</span>' +
'<span>⏱ ' + (ex.time || ex.reps) + '</span>' +
'</div>' +
'</div>' +
'</div>'
).join('');
}
// === КАЛЕНДАРЬ ===
function changeWeek(delta) {
currentWeek = Math.max(0, Math.min(7, currentWeek + delta));
document.getElementById('week-label').textContent = 'Неделя ' + (currentWeek + 1);
renderCalendar();
}
function renderCalendar() {
const grid = document.getElementById('calendar-grid');
const plan = workoutPlan[currentWeek];
const today = new Date();
const startDate = new Date('2026-08-10');
const currentDay = Math.floor((today - startDate) / (1000 * 60 * 60 * 24));
grid.innerHTML = plan.days.map((day, i) => {
const absDay = currentWeek * 7 + i;
const isToday = absDay === currentDay && currentWeek <= 7;
const isDone = progressData.completedDays.some(d => {
const completedDate = new Date(d);
const completedDay = Math.floor((completedDate - startDate) / (1000 * 60 * 60 * 24));
return completedDay === absDay;
});
return '<div class="calendar-day' + (isToday ? ' today' : '') + (isDone ? ' done' : '') + '">' +
'<div class="day-num">' + (i + 1) + '</div>' +
'<div class="workout-type">' + day.type + '</div>' +
(isDone ? '<div style="margin-top:5px; font-size:20px;">✅</div>' : '') +
'</div>';
}).join('');
}
// === ТРЕКЕР ===
function addProgress() {
const weight = document.getElementById('weight').value;
const waist = document.getElementById('waist').value;
const hips = document.getElementById('hips').value;
const arms = document.getElementById('arms').value;
if (!weight && !waist && !hips && !arms) {
alert('Введи хотя бы одно значение');
return;
}
progressData.entries.push({
date: new Date().toISOString(),
weight, waist, hips, arms
});
localStorage.setItem('madinaProgress', JSON.stringify(progressData));
document.getElementById('weight').value = '';
document.getElementById('waist').value = '';
document.getElementById('hips').value = '';
document.getElementById('arms').value = '';
renderProgress();
alert('✅ Прогресс записан!');
}
function renderProgress() {
const entries = progressData.entries.sort((a, b) => new Date(b.date) - new Date(a.date));
const completed = progressData.completedDays.length;
const startWeight = entries[entries.length - 1]?.weight || 65;
const currentWeight = entries[0]?.weight || 65;
const lost = (startWeight - currentWeight).toFixed(1);
document.getElementById('progress-stats').innerHTML =
'<div class="stat-card"><div class="value">' + completed + '</div><div class="label">Тренировок выполнено</div></div>' +
'<div class="stat-card"><div class="value">' + startWeight + '</div><div class="label">Начальный вес</div></div>' +
'<div class="stat-card"><div class="value">' + currentWeight + '</div><div class="label">Текущий вес</div></div>' +
'<div class="stat-card"><div class="value">' + lost + '</div><div class="label">Сброшено (кг)</div></div>';
document.getElementById('progress-history').innerHTML = entries.length > 0 ?
'<h3>История замеров</h3>' + entries.map(e =>
'<div style="background:#f8f9fc; padding:15px; border-radius:10px; margin:10px 0;">' +
'<strong>' + new Date(e.date).toLocaleDateString('ru') + '</strong>: ' +
(e.weight ? e.weight + ' кг, ' : '') +
(e.waist ? 'талия ' + e.waist + ' см, ' : '') +
(e.hips ? 'бёдра ' + e.hips + ' см, ' : '') +
(e.arms ? 'руки ' + e.arms + ' см' : '') +
'</div>'
).join('') : '<p>Пока нет записей. Заполни данные выше!</p>';
renderNutrition();
renderWeightChart();
}
function renderWeightChart() {
const canvas = document.getElementById('weight-chart');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const rect = canvas.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
const entries = progressData.entries.sort((a, b) => new Date(a.date) - new Date(b.date));
const startDate = new Date('2026-08-10');
const totalWeeks = 8;
const startWeight = 65;
const targetWeight = 58;
// Данные для графика
const weights = [];
const weeks = [];
for (let w = 0; w <= totalWeeks; w++) {
weeks.push(w);
// Целевая линия: 65 - (w * 7/8)
weights.push({
week: w,
target: startWeight - (w * (startWeight - targetWeight) / totalWeeks),
actual: null
});
}
// Добавляем фактические замеры
entries.forEach(e => {
const date = new Date(e.date);
const daysFromStart = (date - startDate) / (1000 * 60 * 60 * 24);
const week = Math.min(8, Math.max(0, daysFromStart / 7));
if (e.weight) {
const weekIndex = Math.round(week);
if (weekIndex >= 0 && weekIndex <= 8) {
weights[weekIndex].actual = parseFloat(e.weight);
}
}
});
// Очистка
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Настройки
const padding = 40;
const chartWidth = canvas.width - padding * 2;
const chartHeight = canvas.height - padding * 2;
const weightRange = 10; // 55-75 кг
const minWeight = 55;
function x(w) { return padding + (w / totalWeeks) * chartWidth; }
function y(weight) { return padding + chartHeight - ((weight - minWeight) / weightRange) * chartHeight; }
// Сетка
ctx.strokeStyle = '#e0e0e5';
ctx.lineWidth = 1;
for (let w = 0; w <= totalWeeks; w += 2) {
ctx.beginPath();
ctx.moveTo(x(w), padding);
ctx.lineTo(x(w), canvas.height - padding);
ctx.stroke();
}
for (let wt = 56; wt <= 74; wt += 2) {
ctx.beginPath();
ctx.moveTo(padding, y(wt));
ctx.lineTo(canvas.width - padding, y(wt));
ctx.stroke();
}
// Целевая линия (красная пунктирная)
ctx.strokeStyle = '#f5576c';
ctx.lineWidth = 3;
ctx.setLineDash([10, 5]);
ctx.beginPath();
ctx.moveTo(x(0), y(startWeight));
ctx.lineTo(x(8), y(targetWeight));
ctx.stroke();
ctx.setLineDash([]);
// Фактические замеры (синяя линия)
ctx.strokeStyle = '#667eea';
ctx.lineWidth = 3;
ctx.beginPath();
let started = false;
for (let w = 0; w <= 8; w++) {
if (weights[w].actual !== null) {
if (!started) {
ctx.moveTo(x(w), y(weights[w].actual));
started = true;
} else {
ctx.lineTo(x(w), y(weights[w].actual));
}
}
}
ctx.stroke();
// Точки замеров
for (let w = 0; w <= 8; w++) {
if (weights[w].actual !== null) {
ctx.fillStyle = '#667eea';
ctx.beginPath();
ctx.arc(x(w), y(weights[w].actual), 6, 0, Math.PI * 2);
ctx.fill();
}
}
// Подписи
ctx.fillStyle = '#667eea';
ctx.font = 'bold 14px sans-serif';
ctx.fillText('Цель: 58 кг', canvas.width - padding - 100, y(targetWeight) - 10);
ctx.fillStyle = '#667eea';
ctx.font = 'bold 14px sans-serif';
ctx.fillText('Старт: 65 кг', padding, y(startWeight) - 10);
}
// === ПИТАНИЕ ===
const productsCalories = {
'яблоко': 52, 'груша': 57, 'банан': 89, 'апельсин': 47, 'виноград': 67,
'курица': 165, 'куриная грудка': 110, 'рыба': 206, 'тунец': 132, 'лосось': 208,
'яйцо': 155, 'овсянка': 389, 'гречка': 343, 'рис': 130, 'картофель': 77,
'творог': 98, 'йогурт': 59, 'кефир': 41, 'молоко': 42, 'сыр': 402,
'хлеб': 265, 'хлебец': 310, 'орехи': 607, 'миндаль': 579, 'мёд': 304,
'помидор': 18, 'огурец': 16, 'капуста': 25, 'морковь': 41, 'брокколи': 34
};
function renderNutrition() {
// Вода
const todayStr = new Date().toDateString();
const waterToday = progressData.waterToday || 0;
const totalWater = progressData.water ? progressData.water.length : 0;
document.getElementById('water-count').textContent = waterToday;
document.getElementById('total-water').textContent = totalWater;
const glassesContainer = document.getElementById('water-glasses');
glassesContainer.innerHTML = '';
for (let i = 0; i < 8; i++) {
const glass = document.createElement('span');
glass.textContent = i < waterToday ? '💧' : '🥛';
glass.style.fontSize = '24px';
glassesContainer.appendChild(glass);
}
// Дни отслеживания
const uniqueDates = [...new Set(progressData.entries.map(e => new Date(e.date).toDateString()))];
document.getElementById('days-tracked').textContent = uniqueDates.length;
// Средний вес
if (progressData.entries.length > 0) {
const avg = progressData.entries.reduce((sum, e) => sum + (parseFloat(e.weight) || 0), 0) / progressData.entries.length;
document.getElementById('avg-weight').textContent = avg.toFixed(1);
}
renderHabits();
}
function renderHabits() {
const todayStr = new Date().toDateString();
const container = document.getElementById('habits-list');
if (!container) return;
// Инициализация сегодняшних привычек
if (!progressData.habits[todayStr]) {
progressData.habits[todayStr] = {};
}
// Чек-лист привычек
container.innerHTML = habitsList.map(h => {
const done = progressData.habits[todayStr][h.id] ? 'checked' : '';
return '<div style="background: ' + (done ? 'linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%)' : '#f8f9fc') + '; padding: 15px; border-radius: 12px; margin: 10px 0; display: flex; align-items: center; gap: 15px; cursor: pointer; transition: 0.3s;" onclick="toggleHabit(\'' + h.id + '\')">' +
'<input type="checkbox" ' + done + ' style="width: 24px; height: 24px; cursor: pointer;">' +
'<span style="font-size: 28px;">' + h.icon + '</span>' +
'<span style="font-size: 16px; flex: 1;">' + h.name + '</span>' +
(done ? '<span style="color: #28a745; font-weight: bold;">✓ Выполнено!</span>' : '') +
'</div>';
}).join('');
// Статистика
const todayHabits = progressData.habits[todayStr] || {};
const doneCount = Object.values(todayHabits).filter(v => v).length;
const percent = Math.round((doneCount / habitsList.length) * 100);
// Серия подряд
let streak = 0;
const dates = Object.keys(progressData.habits).sort((a, b) => new Date(b) - new Date(a));
for (const date of dates) {
const dayHabits = progressData.habits[date];
const allDone = habitsList.every(h => dayHabits[h.id]);
if (allDone) streak++;
else break;
}
// Всего выполнено
let total = 0;
for (const date in progressData.habits) {
total += Object.values(progressData.habits[date]).filter(v => v).length;
}
document.getElementById('habits-streak').textContent = streak;
document.getElementById('habits-total').textContent = total;
document.getElementById('habits-percent').textContent = percent + '%';
}
function toggleHabit(id) {
const todayStr = new Date().toDateString();
if (!progressData.habits[todayStr]) {
progressData.habits[todayStr] = {};
}
progressData.habits[todayStr][id] = !progressData.habits[todayStr][id];
localStorage.setItem('madinaProgress', JSON.stringify(progressData));
renderHabits();
}
function addWater() {
if (progressData.waterToday >= 8) {
alert('💧 8 стаканов уже выпито! Отличный результат!');
return;
}
progressData.waterToday++;
if (!progressData.water) progressData.water = [];
progressData.water.push(new Date().toISOString());
localStorage.setItem('madinaProgress', JSON.stringify(progressData));
renderNutrition();
}
function resetWater() {
progressData.waterToday = 0;
localStorage.setItem('madinaProgress', JSON.stringify(progressData));
renderNutrition();
}
function calculateCalories() {
const name = document.getElementById('product-name').value.toLowerCase().trim();
const grams = parseInt(document.getElementById('product-grams').value);
if (!name || !grams) {
document.getElementById('calories-result').textContent = '⚠️ Введи продукт и вес';
return;
}
// Поиск продукта в базе
let caloriesPer100 = 0;
let found = false;
for (const key in productsCalories) {
if (name.includes(key)) {
caloriesPer100 = productsCalories[key];
found = true;
break;
}
}
if (!found) {
document.getElementById('calories-result').textContent = '❓ Продукт не найден в базе. Пример: яблоко 100г = ~52 ккал';
return;
}
const result = Math.round((caloriesPer100 * grams) / 100);
document.getElementById('calories-result').textContent =
'🍎 ' + name + ' (' + grams + 'г) = ' + result + ' ккал';
}
// === МОДАЛЬНОЕ ОКНО ===
function openVideo(id) {
const ex = exercises.find(e => e.id === id);
document.getElementById('modal-title').textContent = ex.name;
document.getElementById('modal-video').innerHTML =
'<iframe width="100%" height="400" src="' + ex.video + '" frameborder="0" allowfullscreen style="border-radius:12px;"></iframe>';
document.getElementById('modal-desc').textContent = ex.desc + ' (' + (ex.time || ex.reps) + ')';
document.getElementById('video-modal').classList.add('active');
}
function closeModal() {
document.getElementById('video-modal').classList.remove('active');
document.getElementById('modal-video').innerHTML = '';
}
// Закрытие по клику вне
document.getElementById('video-modal').addEventListener('click', function(e) {
if (e.target === this) closeModal();
});
// Инициализация плеера при загрузке
setTimeout(() => initPlayer(), 1000);
init();
// Сброс воды каждый день
setInterval(() => {
const lastWaterDate = localStorage.getItem('lastWaterDate');
const todayStr = new Date().toDateString();
if (lastWaterDate !== todayStr) {
progressData.waterToday = 0;
localStorage.setItem('lastWaterDate', todayStr);
localStorage.setItem('madinaProgress', JSON.stringify(progressData));
renderNutrition();
}
}, 60000); // Проверка каждую минуту
</script>
<!-- Скрытый iframe для музыкального плеера -->
<div id="music-player-frame" style="display:none;"></div>
</body>
</html>
</body>
</html>