<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Подписатор PRO | Управление подписками</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="container">
<!-- Шапка с премиум статусом -->
<header class="app-header">
<div class="header-main">
<div class="logo-section">
<div class="logo">
<i class="fas fa-receipt"></i>
</div>
<div class="title-section">
<h1>Подписатор PRO</h1>
<p class="tagline">Умный контроль ваших подписок <i class="fas fa-bell premium-icon"></i></p>
</div>
</div>
<div class="premium-header" id="premiumHeader">
<div class="premium-status-badge" id="premiumBadge">
<i class="fas fa-crown"></i>
<span class="premium-text">Бесплатная версия</span>
<span class="premium-limit">(лимит: 3)</span>
</div>
<button id="upgradeBtn" class="btn-premium-small">
<i class="fas fa-rocket"></i> Премиум
</button>
</div>
</div>
<!-- Баннер напоминаний -->
<div class="reminder-banner" id="reminderBanner">
<i class="fas fa-bell"></i>
<span>Напоминаем о ваших подписках! Проверьте даты списаний.</span>
<button class="close-banner" id="closeBanner">×</button>
</div>
</header>
<main>
<!-- Панель управления -->
<section class="control-panel">
<div class="control-left">
<button id="addSubBtn" class="btn-primary-large">
<i class="fas fa-plus-circle"></i> Добавить подписку
</button>
<div class="quick-stats">
<div class="quick-stat">
<i class="fas fa-calendar-day"></i>
<span id="todaySubs">0 списаний сегодня</span>
</div>
<div class="quick-stat">
<i class="fas fa-exclamation-triangle"></i>
<span id="expiringSubs">0 скоро списывается</span>
</div>
</div>
</div>
<div class="stats-summary">
<div class="stat-box">
<span class="stat-label">
<i class="fas fa-wallet"></i> В месяц
</span>
<span class="stat-value" id="monthlyTotal">0 ₽</span>
</div>
<div class="stat-box">
<span class="stat-label">
<i class="fas fa-check-circle"></i> Активных
</span>
<span class="stat-value" id="activeCount">0</span>
</div>
<div class="stat-box limit-box" id="limitBox">
<span class="stat-label">
<i class="fas fa-chart-line"></i> Лимит
</span>
<span class="stat-value" id="limitCount">0/3</span>
</div>
</div>
</section>
<!-- Список подписок -->
<section class="subscriptions-section">
<div class="section-header">
<h2><i class="fas fa-list-alt"></i> Мои подписки</h2>
<div class="filter-buttons">
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Подписатор PRO | Управление подписками</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="container">
<!-- Шапка с премиум статусом -->
<header class="app-header">
<div class="header-main">
<div class="logo-section">
<div class="logo">
<i class="fas fa-receipt"></i>
</div>
<div class="title-section">
<h1>Подписатор PRO</h1>
<p class="tagline">Умный контроль ваших подписок <i class="fas fa-bell premium-icon"></i></p>
</div>
</div>
<div class="premium-header" id="premiumHeader">
<div class="premium-status-badge" id="premiumBadge">
<i class="fas fa-crown"></i>
<span class="premium-text">Бесплатная версия</span>
<span class="premium-limit">(лимит: 3)</span>
</div>
<button id="upgradeBtn" class="btn-premium-small">
<i class="fas fa-rocket"></i> Премиум
</button>
</div>
</div>
<!-- Баннер напоминаний -->
<div class="reminder-banner" id="reminderBanner">
<i class="fas fa-bell"></i>
<span>Напоминаем о ваших подписках! Проверьте даты списаний.</span>
<button class="close-banner" id="closeBanner">×</button>
</div>
</header>
<main>
<!-- Панель управления -->
<section class="control-panel">
<div class="control-left">
<button id="addSubBtn" class="btn-primary-large">
<i class="fas fa-plus-circle"></i> Добавить подписку
</button>
<div class="quick-stats">
<div class="quick-stat">
<i class="fas fa-calendar-day"></i>
<span id="todaySubs">0 списаний сегодня</span>
</div>
<div class="quick-stat">
<i class="fas fa-exclamation-triangle"></i>
<span id="expiringSubs">0 скоро списывается</span>
</div>
</div>
</div>
<div class="stats-summary">
<div class="stat-box">
<span class="stat-label">
<i class="fas fa-wallet"></i> В месяц
</span>
<span class="stat-value" id="monthlyTotal">0 ₽</span>
</div>
<div class="stat-box">
<span class="stat-label">
<i class="fas fa-check-circle"></i> Активных
</span>
<span class="stat-value" id="activeCount">0</span>
</div>
<div class="stat-box limit-box" id="limitBox">
<span class="stat-label">
<i class="fas fa-chart-line"></i> Лимит
</span>
<span class="stat-value" id="limitCount">0/3</span>
</div>
</div>
</section>
<!-- Список подписок -->
<section class="subscriptions-section">
<div class="section-header">
<h2><i class="fas fa-list-alt"></i> Мои подписки</h2>
<div class="filter-buttons">
Telegram
Удаление высолов
Instagram: 🪪chisto_ing
</select>
</div>
</div>
<div class="form-group">
<label for="subNextDate"><i class="far fa-calendar-alt"></i> Дата следующего списания</label>
<input type="date" id="subNextDate" required>
</div>
<div class="form-group">
<label><i class="fas fa-palette"></i> Цветовая метка</label>
<div class="color-picker-grid">
<div class="color-option" data-color="#4a6fa5" style="background-color: #4a6fa5;"></div>
<div class="color-option" data-color="#6a93cb" style="background-color: #6a93cb;"></div>
<div class="color-option" data-color="#ff6b6b" style="background-color: #ff6b6b;"></div>
<div class="color-option" data-color="#51cf66" style="background-color: #51cf66;"></div>
<div class="color-option" data-color="#ffd43b" style="background-color: #ffd43b;"></div>
<div class="color-option" data-color="#cc5de8" style="background-color: #cc5de8;"></div>
<input type="color" id="subColor" value="#4a6fa5" class="color-input">
</div>
</div>
<div class="form-group">
<label for="subNotes"><i class="far fa-sticky-note"></i> Примечание (необязательно)</label>
<textarea id="subNotes" placeholder="Логин, email, дополнительные детали..." rows="2"></textarea>
</div>
<div class="modal-actions">
<button type="button" class="btn-secondary" id="cancelBtn2">
<i class="fas fa-times"></i> Отмена
</button>
<button type="submit" class="btn-primary-large">
<i class="fas fa-save"></i> Сохранить подписку
</button>
</div>
</form>
</div>
</div>
<!-- Модальное окно премиума -->
<div id="premiumModalOverlay" class="modal-overlay" style="display: none;">
<div class="modal premium-modal">
<div class="premium-header">
<div class="crown-container">
<i class="fas fa-crown"></i>
</div>
<h2>Премиум Подписка</h2>
<p class="premium-subtitle">Откройте все возможности приложения</p>
</div>
<div class="premium-features">
<div class="feature-card">
<div class="feature-icon infinity">
<i class="fas fa-infinity"></i>
</div>
<div class="feature-content">
<h4>Неограниченное количество подписок</h4>
<p>Добавляйте столько сервисов, сколько вам нужно</p>
</div>
</div>
<div class="feature-card">
<div class="feature-icon chart">
<i class="fas fa-chart-pie"></i>
</div>
<div class="feature-content">
<h4>Расширенная статистика</h4>
<p>Детальные графики расходов и категоризация</p>
</div>
</div>
<div class="feature-card">
<div class="feature-icon bell">
<i class="fas fa-bell"></i>
</div>
<div class="feature-content">
</div>
</div>
<div class="form-group">
<label for="subNextDate"><i class="far fa-calendar-alt"></i> Дата следующего списания</label>
<input type="date" id="subNextDate" required>
</div>
<div class="form-group">
<label><i class="fas fa-palette"></i> Цветовая метка</label>
<div class="color-picker-grid">
<div class="color-option" data-color="#4a6fa5" style="background-color: #4a6fa5;"></div>
<div class="color-option" data-color="#6a93cb" style="background-color: #6a93cb;"></div>
<div class="color-option" data-color="#ff6b6b" style="background-color: #ff6b6b;"></div>
<div class="color-option" data-color="#51cf66" style="background-color: #51cf66;"></div>
<div class="color-option" data-color="#ffd43b" style="background-color: #ffd43b;"></div>
<div class="color-option" data-color="#cc5de8" style="background-color: #cc5de8;"></div>
<input type="color" id="subColor" value="#4a6fa5" class="color-input">
</div>
</div>
<div class="form-group">
<label for="subNotes"><i class="far fa-sticky-note"></i> Примечание (необязательно)</label>
<textarea id="subNotes" placeholder="Логин, email, дополнительные детали..." rows="2"></textarea>
</div>
<div class="modal-actions">
<button type="button" class="btn-secondary" id="cancelBtn2">
<i class="fas fa-times"></i> Отмена
</button>
<button type="submit" class="btn-primary-large">
<i class="fas fa-save"></i> Сохранить подписку
</button>
</div>
</form>
</div>
</div>
<!-- Модальное окно премиума -->
<div id="premiumModalOverlay" class="modal-overlay" style="display: none;">
<div class="modal premium-modal">
<div class="premium-header">
<div class="crown-container">
<i class="fas fa-crown"></i>
</div>
<h2>Премиум Подписка</h2>
<p class="premium-subtitle">Откройте все возможности приложения</p>
</div>
<div class="premium-features">
<div class="feature-card">
<div class="feature-icon infinity">
<i class="fas fa-infinity"></i>
</div>
<div class="feature-content">
<h4>Неограниченное количество подписок</h4>
<p>Добавляйте столько сервисов, сколько вам нужно</p>
</div>
</div>
<div class="feature-card">
<div class="feature-icon chart">
<i class="fas fa-chart-pie"></i>
</div>
<div class="feature-content">
<h4>Расширенная статистика</h4>
<p>Детальные графики расходов и категоризация</p>
</div>
</div>
<div class="feature-card">
<div class="feature-icon bell">
<i class="fas fa-bell"></i>
</div>
<div class="feature-content">
<h4>Умные напоминания</h4>
<p>Персональные уведомления о списаниях</p>
</div>
</div>
<div class="feature-card">
<div class="feature-icon cloud">
<i class="fas fa-cloud-upload-alt"></i>
</div>
<div class="feature-content">
<h4>Облачная синхронизация</h4>
<p>Доступ к вашим данным с любого устройства</p>
</div>
</div>
</div>
<div class="pricing-section">
<h3><i class="fas fa-credit-card"></i> Выберите тариф</h3>
<div class="pricing-cards">
<div class="pricing-card selected" data-plan="monthly">
<div class="pricing-header">
<i class="fas fa-calendar-alt"></i>
<h4>Ежемесячно</h4>
</div>
<div class="price">
<span class="amount">299 ₽</span>
<span class="period">/ месяц</span>
</div>
<div class="pricing-features">
<p><i class="fas fa-check"></i> Все премиум-функции</p>
<p><i class="fas fa-check"></i> Ежемесячная оплата</p>
<p><i class="fas fa-check"></i> Можно отменить в любой момент</p>
</div>
<button class="btn-select-plan" data-plan="monthly">Выбрать</button>
</div>
<div class="pricing-card popular" data-plan="yearly">
<div class="popular-badge">ВЫГОДА 20%</div>
<div class="pricing-header">
<i class="fas fa-calendar-star"></i>
<h4>Ежегодно</h4>
</div>
<div class="price">
<span class="amount">2 990 ₽</span>
<span class="period">/ год</span>
</div>
<div class="pricing-features">
<p><i class="fas fa-check"></i> Все премиум-функции</p>
<p><i class="fas fa-check"></i> Экономия 718₽ в год</p>
<p><i class="fas fa-check"></i> Лучшее предложение</p>
</div>
<button class="btn-select-plan" data-plan="yearly">Выбрать</button>
</div>
</div>
</div>
<div class="payment-section">
<h3><i class="fas fa-lock"></i> Безопасная оплата</h3>
<div class="payment-methods">
<div class="payment-method">
<i class="fab fa-cc-visa"></i>
<span>Visa</span>
</div>
<div class="payment-method">
<i class="fab fa-cc-mastercard"></i>
<span>Mastercard</span>
</div>
<div class="payment-method">
<i class="fab fa-cc-paypal"></i>
<span>PayPal</span>
</div>
<div class="payment-method">
<i class="fab fa-yandex"></i>
<span>ЮMoney</span>
</div>
<div class="payment-method">
<i class="fas fa-mobile-alt"></i>
<p>Персональные уведомления о списаниях</p>
</div>
</div>
<div class="feature-card">
<div class="feature-icon cloud">
<i class="fas fa-cloud-upload-alt"></i>
</div>
<div class="feature-content">
<h4>Облачная синхронизация</h4>
<p>Доступ к вашим данным с любого устройства</p>
</div>
</div>
</div>
<div class="pricing-section">
<h3><i class="fas fa-credit-card"></i> Выберите тариф</h3>
<div class="pricing-cards">
<div class="pricing-card selected" data-plan="monthly">
<div class="pricing-header">
<i class="fas fa-calendar-alt"></i>
<h4>Ежемесячно</h4>
</div>
<div class="price">
<span class="amount">299 ₽</span>
<span class="period">/ месяц</span>
</div>
<div class="pricing-features">
<p><i class="fas fa-check"></i> Все премиум-функции</p>
<p><i class="fas fa-check"></i> Ежемесячная оплата</p>
<p><i class="fas fa-check"></i> Можно отменить в любой момент</p>
</div>
<button class="btn-select-plan" data-plan="monthly">Выбрать</button>
</div>
<div class="pricing-card popular" data-plan="yearly">
<div class="popular-badge">ВЫГОДА 20%</div>
<div class="pricing-header">
<i class="fas fa-calendar-star"></i>
<h4>Ежегодно</h4>
</div>
<div class="price">
<span class="amount">2 990 ₽</span>
<span class="period">/ год</span>
</div>
<div class="pricing-features">
<p><i class="fas fa-check"></i> Все премиум-функции</p>
<p><i class="fas fa-check"></i> Экономия 718₽ в год</p>
<p><i class="fas fa-check"></i> Лучшее предложение</p>
</div>
<button class="btn-select-plan" data-plan="yearly">Выбрать</button>
</div>
</div>
</div>
<div class="payment-section">
<h3><i class="fas fa-lock"></i> Безопасная оплата</h3>
<div class="payment-methods">
<div class="payment-method">
<i class="fab fa-cc-visa"></i>
<span>Visa</span>
</div>
<div class="payment-method">
<i class="fab fa-cc-mastercard"></i>
<span>Mastercard</span>
</div>
<div class="payment-method">
<i class="fab fa-cc-paypal"></i>
<span>PayPal</span>
</div>
<div class="payment-method">
<i class="fab fa-yandex"></i>
<span>ЮMoney</span>
</div>
<div class="payment-method">
<i class="fas fa-mobile-alt"></i>
<span>Мобильная оплата</span>
</div>
</div>
<button id="buyPremiumBtn" class="btn-premium-purchase">
<i class="fas fa-lock"></i> Перейти к оплате 299 ₽
</button>
<div class="security-info">
<i class="fas fa-shield-alt"></i>
<span>Оплата защищена SSL-шифрованием</span>
</div>
</div>
<div class="premium-footer">
<button class="btn-close-premium" id="closePremiumBtn">
<i class="fas fa-times"></i> Закрыть
</button>
<p class="no-refund">
<i class="fas fa-info-circle"></i> Премиум подписка не предусматривает возврат средств
</p>
</div>
</div>
</div>
<!-- Модальное окно ограничения -->
<div id="limitModalOverlay" class="modal-overlay" style="display: none;">
<div class="modal limit-modal">
<div class="limit-icon">
<i class="fas fa-lock"></i>
</div>
<h2>Достигнут лимит бесплатной версии</h2>
<p class="limit-message">
Вы добавили максимальное количество подписок (3) в бесплатной версии.
</p>
<p class="upgrade-call">
Перейдите на <span class="premium-highlight">Премиум</span> чтобы добавлять неограниченное количество подписок и получить доступ ко всем функциям!
</p>
<div class="limit-benefits">
<div class="benefit">
<i class="fas fa-infinity"></i>
<span>Неограниченные подписки</span>
</div>
<div class="benefit">
<i class="fas fa-chart-pie"></i>
<span>Расширенная статистика</span>
</div>
<div class="benefit">
<i class="fas fa-bell"></i>
<span>Умные напоминания</span>
</div>
</div>
<div class="limit-actions">
<button class="btn-secondary" id="closeLimitBtn">
<i class="fas fa-times"></i> Остаться на бесплатном
</button>
<button class="btn-premium-large" id="upgradeFromLimitBtn">
<i class="fas fa-crown"></i> Перейти на Премиум
</button>
</div>
<p class="limit-footer">
Обновление займет менее минуты, и вы сразу получите доступ ко всем функциям
</p>
</div>
</div>
<!-- Модальное окно успешной оплаты -->
<div id="successModalOverlay" class="modal-overlay" style="display: none;">
<div class="modal success-modal">
<div class="success-icon">
<i class="fas fa-check-circle"></i>
</div>
<h2>Поздравляем!</h2>
<p class="success-message">
Вы успешно активировали <span class="premium-text">Премиум Подписку</span>
</p>
<div class="success-details">
<p><i class="fas fa-unlock"></i> Теперь доступны все функции</p>
<p><i class="fas fa-infinity"></i> Лимит подписок снят</p>
<p><i class="fas fa-rocket"></i> Премиум активирован на 30 дней</p>
</div>
<button class="btn-primary-large" id="closeSuccessBtn">
<i class="fas fa-check"></i> Продолжить
</button>
<p class="success-footer">
</div>
</div>
<button id="buyPremiumBtn" class="btn-premium-purchase">
<i class="fas fa-lock"></i> Перейти к оплате 299 ₽
</button>
<div class="security-info">
<i class="fas fa-shield-alt"></i>
<span>Оплата защищена SSL-шифрованием</span>
</div>
</div>
<div class="premium-footer">
<button class="btn-close-premium" id="closePremiumBtn">
<i class="fas fa-times"></i> Закрыть
</button>
<p class="no-refund">
<i class="fas fa-info-circle"></i> Премиум подписка не предусматривает возврат средств
</p>
</div>
</div>
</div>
<!-- Модальное окно ограничения -->
<div id="limitModalOverlay" class="modal-overlay" style="display: none;">
<div class="modal limit-modal">
<div class="limit-icon">
<i class="fas fa-lock"></i>
</div>
<h2>Достигнут лимит бесплатной версии</h2>
<p class="limit-message">
Вы добавили максимальное количество подписок (3) в бесплатной версии.
</p>
<p class="upgrade-call">
Перейдите на <span class="premium-highlight">Премиум</span> чтобы добавлять неограниченное количество подписок и получить доступ ко всем функциям!
</p>
<div class="limit-benefits">
<div class="benefit">
<i class="fas fa-infinity"></i>
<span>Неограниченные подписки</span>
</div>
<div class="benefit">
<i class="fas fa-chart-pie"></i>
<span>Расширенная статистика</span>
</div>
<div class="benefit">
<i class="fas fa-bell"></i>
<span>Умные напоминания</span>
</div>
</div>
<div class="limit-actions">
<button class="btn-secondary" id="closeLimitBtn">
<i class="fas fa-times"></i> Остаться на бесплатном
</button>
<button class="btn-premium-large" id="upgradeFromLimitBtn">
<i class="fas fa-crown"></i> Перейти на Премиум
</button>
</div>
<p class="limit-footer">
Обновление займет менее минуты, и вы сразу получите доступ ко всем функциям
</p>
</div>
</div>
<!-- Модальное окно успешной оплаты -->
<div id="successModalOverlay" class="modal-overlay" style="display: none;">
<div class="modal success-modal">
<div class="success-icon">
<i class="fas fa-check-circle"></i>
</div>
<h2>Поздравляем!</h2>
<p class="success-message">
Вы успешно активировали <span class="premium-text">Премиум Подписку</span>
</p>
<div class="success-details">
<p><i class="fas fa-unlock"></i> Теперь доступны все функции</p>
<p><i class="fas fa-infinity"></i> Лимит подписок снят</p>
<p><i class="fas fa-rocket"></i> Премиум активирован на 30 дней</p>
</div>
<button class="btn-primary-large" id="closeSuccessBtn">
<i class="fas fa-check"></i> Продолжить
</button>
<p class="success-footer">
Спасибо за выбор Подписатор PRO! 🎉
</p>
</div>
</div>
<!-- Контекстное меню для подписок -->
<div id="contextMenu" class="context-menu" style="display: none;">
<div class="context-item edit-item">
<i class="fas fa-edit"></i> Редактировать
</div>
<div class="context-item delete-item">
<i class="fas fa-trash-alt"></i> Удалить
</div>
<div class="context-item duplicate-item">
<i class="fas fa-copy"></i> Дублировать
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
</p>
</div>
</div>
<!-- Контекстное меню для подписок -->
<div id="contextMenu" class="context-menu" style="display: none;">
<div class="context-item edit-item">
<i class="fas fa-edit"></i> Редактировать
</div>
<div class="context-item delete-item">
<i class="fas fa-trash-alt"></i> Удалить
</div>
<div class="context-item duplicate-item">
<i class="fas fa-copy"></i> Дублировать
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
/* ===== ГЛОБАЛЬНЫЕ СТИЛИ ===== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
}
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #2d3748;
min-height: 100vh;
padding: 15px;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
.container {
max-width: 100%;
margin: 0 auto;
background: rgba(255, 255, 255, 0.98);
border-radius: 28px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
overflow: hidden;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
/* ===== ШАПКА ===== */
.app-header {
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
padding: 25px 30px 15px;
color: white;
position: relative;
overflow: hidden;
}
.app-header::before {
content: '';
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 200px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
border-radius: 50%;
transform: translate(30%, -30%);
}
.header-main {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
position: relative;
z-index: 1;
}
.logo-section {
display: flex;
align-items: center;
gap: 15px;
}
.logo {
width: 60px;
height: 60px;
background: rgba(255, 255, 255, 0.15);
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
backdrop-filter: blur(10px);
border: 2px solid rgba(255, 255, 255, 0.2);
}
.title-section h1 {
font-size: 2.2rem;
font-weight: 800;
margin-bottom: 5px;
background: linear-gradient(135deg, #ffffff 0%, #f0f4f9 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.tagline {
font-size: 0.95rem;
opacity: 0.9;
font-weight: 500;
}
.premium-icon {
color: #ffd700;
margin-left: 5px;
}
/* ===== ПРЕМИУМ ШАПКА ===== */
.premium-header {
display: flex;
align-items: center;
gap: 15px;
}
.premium-status-badge {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
padding: 10px 18px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 10px;
border: 2px solid rgba(255, 255, 255, 0.2);
font-weight: 600;
font-size: 0.9rem;
}
.premium-status-badge i {
color: #ffd700;
font-size: 1.1rem;
}
.btn-premium-small {
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
border: none;
padding: 12px 22px;
border-radius: 15px;
font-weight: 700;
font-size: 0.95rem;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
box-shadow: 0 6px 20px rgba(255, 193, 7, 0.3);
border: 2px solid rgba(255, 255, 255, 0.3);
}
.btn-premium-small:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(255, 193, 7, 0.4);
}
/* ===== БАННЕР НАПОМИНАНИЙ ===== */
.reminder-banner {
background: linear-gradient(135deg, #ff6b6b 0%, #ff8787 100%);
padding: 15px 20px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 15px;
margin-top: 15px;
animation: slideDown 0.5s ease;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.reminder-banner i {
font-size: 1.4rem;
color: white;
}
.reminder-banner span {
flex: 1;
color: white;
font-weight: 600;
font-size: 0.95rem;
}
.close-banner {
background: none;
border: none;
color: white;
font-size: 1.5rem;
cursor: pointer;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.3s;
}
.close-banner:hover {
background: rgba(255, 255, 255, 0.2);
}
/* ===== ПАНЕЛЬ УПРАВЛЕНИЯ ===== */
.control-panel {
display: flex;
justify-content: space-between;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
}
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #2d3748;
min-height: 100vh;
padding: 15px;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
.container {
max-width: 100%;
margin: 0 auto;
background: rgba(255, 255, 255, 0.98);
border-radius: 28px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
overflow: hidden;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
/* ===== ШАПКА ===== */
.app-header {
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
padding: 25px 30px 15px;
color: white;
position: relative;
overflow: hidden;
}
.app-header::before {
content: '';
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 200px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
border-radius: 50%;
transform: translate(30%, -30%);
}
.header-main {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
position: relative;
z-index: 1;
}
.logo-section {
display: flex;
align-items: center;
gap: 15px;
}
.logo {
width: 60px;
height: 60px;
background: rgba(255, 255, 255, 0.15);
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
backdrop-filter: blur(10px);
border: 2px solid rgba(255, 255, 255, 0.2);
}
.title-section h1 {
font-size: 2.2rem;
font-weight: 800;
margin-bottom: 5px;
background: linear-gradient(135deg, #ffffff 0%, #f0f4f9 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.tagline {
font-size: 0.95rem;
opacity: 0.9;
font-weight: 500;
}
.premium-icon {
color: #ffd700;
margin-left: 5px;
}
/* ===== ПРЕМИУМ ШАПКА ===== */
.premium-header {
display: flex;
align-items: center;
gap: 15px;
}
.premium-status-badge {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
padding: 10px 18px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 10px;
border: 2px solid rgba(255, 255, 255, 0.2);
font-weight: 600;
font-size: 0.9rem;
}
.premium-status-badge i {
color: #ffd700;
font-size: 1.1rem;
}
.btn-premium-small {
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
border: none;
padding: 12px 22px;
border-radius: 15px;
font-weight: 700;
font-size: 0.95rem;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
box-shadow: 0 6px 20px rgba(255, 193, 7, 0.3);
border: 2px solid rgba(255, 255, 255, 0.3);
}
.btn-premium-small:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(255, 193, 7, 0.4);
}
/* ===== БАННЕР НАПОМИНАНИЙ ===== */
.reminder-banner {
background: linear-gradient(135deg, #ff6b6b 0%, #ff8787 100%);
padding: 15px 20px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 15px;
margin-top: 15px;
animation: slideDown 0.5s ease;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.reminder-banner i {
font-size: 1.4rem;
color: white;
}
.reminder-banner span {
flex: 1;
color: white;
font-weight: 600;
font-size: 0.95rem;
}
.close-banner {
background: none;
border: none;
color: white;
font-size: 1.5rem;
cursor: pointer;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.3s;
}
.close-banner:hover {
background: rgba(255, 255, 255, 0.2);
}
/* ===== ПАНЕЛЬ УПРАВЛЕНИЯ ===== */
.control-panel {
display: flex;
justify-content: space-between;
align-items: stretch;
gap: 25px;
margin: 30px;
flex-wrap: wrap;
}
.control-left {
flex: 1;
min-width: 300px;
}
.btn-primary-large {
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
border: none;
padding: 18px 32px;
border-radius: 18px;
font-size: 1.1rem;
font-weight: 700;
cursor: pointer;
display: flex;
align-items: center;
gap: 12px;
transition: all 0.3s ease;
box-shadow: 0 8px 25px rgba(74, 111, 165, 0.3);
width: 100%;
justify-content: center;
margin-bottom: 20px;
}
.btn-primary-large:hover {
transform: translateY(-3px);
box-shadow: 0 12px 30px rgba(74, 111, 165, 0.4);
}
.quick-stats {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
}
.quick-stat {
background: #f8fafc;
padding: 15px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 12px;
border: 2px solid #e2e8f0;
transition: all 0.3s ease;
}
.quick-stat:hover {
border-color: #4a6fa5;
transform: translateY(-2px);
}
.quick-stat i {
font-size: 1.3rem;
color: #4a6fa5;
width: 35px;
height: 35px;
background: rgba(74, 111, 165, 0.1);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.quick-stat span {
font-weight: 600;
color: #2d3748;
font-size: 0.95rem;
}
/* ===== СТАТИСТИКА ===== */
.stats-summary {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.stat-box {
flex: 1;
min-width: 150px;
background: white;
padding: 22px;
border-radius: 20px;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
border: 2px solid #e2e8f0;
transition: all 0.3s ease;
}
.stat-box:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
}
.limit-box {
border-color: #ffd700;
background: linear-gradient(135deg, #fff9db 0%, #fff3bf 100%);
}
.stat-label {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
color: #64748b;
font-size: 0.95rem;
margin-bottom: 12px;
font-weight: 600;
}
.stat-label i {
font-size: 1.2rem;
}
.stat-value {
display: block;
font-size: 2.2rem;
font-weight: 800;
color: #2d3748;
}
.limit-box .stat-value {
color: #e67700;
}
/* ===== СПИСОК ПОДПИСОК ===== */
.subscriptions-section {
margin: 0 30px 40px;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
flex-wrap: wrap;
gap: 15px;
}
.section-header h2 {
font-size: 1.8rem;
color: #2d3748;
display: flex;
align-items: center;
gap: 12px;
}
.filter-buttons {
display: flex;
gap: 10px;
background: #f1f5f9;
padding: 8px;
border-radius: 15px;
}
.filter-btn {
padding: 10px 20px;
border: none;
background: none;
border-radius: 12px;
font-weight: 600;
cursor: pointer;
color: #64748b;
transition: all 0.3s ease;
}
.filter-btn.active {
background: white;
color: #4a6fa5;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.subscriptions-list {
display: flex;
flex-direction: column;
gap: 20px;
}
/* ===== ЭЛЕМЕНТ ПОДПИСКИ ===== */
.subscription-item {
background: white;
padding: 25px;
border-radius: 22px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.08);
border-left: 10px solid #4a6fa5;
transition: all 0.4s ease;
cursor: pointer;
position: relative;
overflow: hidden;
}
.subscription-item:hover {
transform: translateX(10px) translateY(-5px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.12);
}
.subscription-item::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, var(--item-color, #4a6fa5) 0%, rgba(74, 111, 165, 0.2) 100%);
}
.sub-info {
flex: 1;
}
.sub-info h4 {
font-size: 1.4rem;
gap: 25px;
margin: 30px;
flex-wrap: wrap;
}
.control-left {
flex: 1;
min-width: 300px;
}
.btn-primary-large {
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
border: none;
padding: 18px 32px;
border-radius: 18px;
font-size: 1.1rem;
font-weight: 700;
cursor: pointer;
display: flex;
align-items: center;
gap: 12px;
transition: all 0.3s ease;
box-shadow: 0 8px 25px rgba(74, 111, 165, 0.3);
width: 100%;
justify-content: center;
margin-bottom: 20px;
}
.btn-primary-large:hover {
transform: translateY(-3px);
box-shadow: 0 12px 30px rgba(74, 111, 165, 0.4);
}
.quick-stats {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
}
.quick-stat {
background: #f8fafc;
padding: 15px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 12px;
border: 2px solid #e2e8f0;
transition: all 0.3s ease;
}
.quick-stat:hover {
border-color: #4a6fa5;
transform: translateY(-2px);
}
.quick-stat i {
font-size: 1.3rem;
color: #4a6fa5;
width: 35px;
height: 35px;
background: rgba(74, 111, 165, 0.1);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.quick-stat span {
font-weight: 600;
color: #2d3748;
font-size: 0.95rem;
}
/* ===== СТАТИСТИКА ===== */
.stats-summary {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.stat-box {
flex: 1;
min-width: 150px;
background: white;
padding: 22px;
border-radius: 20px;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
border: 2px solid #e2e8f0;
transition: all 0.3s ease;
}
.stat-box:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
}
.limit-box {
border-color: #ffd700;
background: linear-gradient(135deg, #fff9db 0%, #fff3bf 100%);
}
.stat-label {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
color: #64748b;
font-size: 0.95rem;
margin-bottom: 12px;
font-weight: 600;
}
.stat-label i {
font-size: 1.2rem;
}
.stat-value {
display: block;
font-size: 2.2rem;
font-weight: 800;
color: #2d3748;
}
.limit-box .stat-value {
color: #e67700;
}
/* ===== СПИСОК ПОДПИСОК ===== */
.subscriptions-section {
margin: 0 30px 40px;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
flex-wrap: wrap;
gap: 15px;
}
.section-header h2 {
font-size: 1.8rem;
color: #2d3748;
display: flex;
align-items: center;
gap: 12px;
}
.filter-buttons {
display: flex;
gap: 10px;
background: #f1f5f9;
padding: 8px;
border-radius: 15px;
}
.filter-btn {
padding: 10px 20px;
border: none;
background: none;
border-radius: 12px;
font-weight: 600;
cursor: pointer;
color: #64748b;
transition: all 0.3s ease;
}
.filter-btn.active {
background: white;
color: #4a6fa5;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.subscriptions-list {
display: flex;
flex-direction: column;
gap: 20px;
}
/* ===== ЭЛЕМЕНТ ПОДПИСКИ ===== */
.subscription-item {
background: white;
padding: 25px;
border-radius: 22px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.08);
border-left: 10px solid #4a6fa5;
transition: all 0.4s ease;
cursor: pointer;
position: relative;
overflow: hidden;
}
.subscription-item:hover {
transform: translateX(10px) translateY(-5px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.12);
}
.subscription-item::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, var(--item-color, #4a6fa5) 0%, rgba(74, 111, 165, 0.2) 100%);
}
.sub-info {
flex: 1;
}
.sub-info h4 {
font-size: 1.4rem;
color: #2d3748;
margin-bottom: 12px;
font-weight: 700;
display: flex;
align-items: center;
gap: 10px;
}
.sub-meta {
display: flex;
gap: 25px;
flex-wrap: wrap;
}
.meta-item {
display: flex;
align-items: center;
gap: 8px;
color: #64748b;
font-size: 0.95rem;
font-weight: 500;
}
.meta-item i {
color: #4a6fa5;
font-size: 1.1rem;
}
.meta-item.price {
font-weight: 700;
color: #2d3748;
font-size: 1.1rem;
}
.sub-actions {
display: flex;
gap: 15px;
}
.action-btn {
width: 50px;
height: 50px;
border-radius: 14px;
border: none;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 1.2rem;
transition: all 0.3s ease;
}
.action-btn.edit {
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
}
.action-btn.delete {
background: linear-gradient(135deg, #ff6b6b 0%, #ff8787 100%);
color: white;
}
.action-btn:hover {
transform: scale(1.1);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
/* ===== ПУСТОЙ СОСТОЯНИЕ ===== */
.empty-state {
text-align: center;
padding: 60px 30px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
border-radius: 25px;
border: 3px dashed #cbd5e1;
margin: 20px 0;
}
.empty-icon {
font-size: 5rem;
color: #94a3b8;
margin-bottom: 25px;
opacity: 0.7;
}
.empty-state h3 {
font-size: 1.8rem;
color: #475569;
margin-bottom: 15px;
}
.empty-state p {
color: #64748b;
font-size: 1.1rem;
margin-bottom: 30px;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
/* ===== ФУТЕР ===== */
.app-footer {
background: #f8fafc;
padding: 40px 30px 25px;
border-top: 3px solid #e2e8f0;
}
.footer-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
margin-bottom: 30px;
}
.footer-section {
text-align: center;
}
.footer-section h4 {
font-size: 1.2rem;
color: #2d3748;
margin-bottom: 12px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.footer-section p {
color: #64748b;
font-size: 0.95rem;
margin-bottom: 15px;
}
.btn-premium-text {
background: none;
border: 2px solid #ffd700;
color: #e67700;
padding: 10px 20px;
border-radius: 12px;
font-weight: 700;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
}
.btn-premium-text:hover {
background: #ffd700;
color: #2d3748;
}
.footer-bottom {
text-align: center;
padding-top: 25px;
border-top: 2px solid #e2e8f0;
}
.footer-bottom p {
color: #64748b;
margin-bottom: 10px;
}
.footer-bottom a {
color: #4a6fa5;
font-weight: 700;
text-decoration: none;
}
.footer-bottom a:hover {
text-decoration: underline;
}
.copyright {
font-size: 0.9rem;
color: #94a3b8;
}
/* ===== МОДАЛЬНЫЕ ОКНА ===== */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
backdrop-filter: blur(8px);
animation: fadeIn 0.3s ease;
padding: 20px;
}
.modal {
background: white;
border-radius: 28px;
width: 100%;
max-width: 500px;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3);
animation: slideUp 0.4s ease;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25px 30px;
border-bottom: 2px solid #f1f5f9;
}
.modal-header h3 {
font-size: 1.6rem;
color: #2d3748;
margin: 0;
}
.modal-close {
background: none;
border: none;
font-size: 1.8rem;
color: #64748b;
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12px;
font-weight: 700;
display: flex;
align-items: center;
gap: 10px;
}
.sub-meta {
display: flex;
gap: 25px;
flex-wrap: wrap;
}
.meta-item {
display: flex;
align-items: center;
gap: 8px;
color: #64748b;
font-size: 0.95rem;
font-weight: 500;
}
.meta-item i {
color: #4a6fa5;
font-size: 1.1rem;
}
.meta-item.price {
font-weight: 700;
color: #2d3748;
font-size: 1.1rem;
}
.sub-actions {
display: flex;
gap: 15px;
}
.action-btn {
width: 50px;
height: 50px;
border-radius: 14px;
border: none;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 1.2rem;
transition: all 0.3s ease;
}
.action-btn.edit {
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
}
.action-btn.delete {
background: linear-gradient(135deg, #ff6b6b 0%, #ff8787 100%);
color: white;
}
.action-btn:hover {
transform: scale(1.1);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
/* ===== ПУСТОЙ СОСТОЯНИЕ ===== */
.empty-state {
text-align: center;
padding: 60px 30px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
border-radius: 25px;
border: 3px dashed #cbd5e1;
margin: 20px 0;
}
.empty-icon {
font-size: 5rem;
color: #94a3b8;
margin-bottom: 25px;
opacity: 0.7;
}
.empty-state h3 {
font-size: 1.8rem;
color: #475569;
margin-bottom: 15px;
}
.empty-state p {
color: #64748b;
font-size: 1.1rem;
margin-bottom: 30px;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
/* ===== ФУТЕР ===== */
.app-footer {
background: #f8fafc;
padding: 40px 30px 25px;
border-top: 3px solid #e2e8f0;
}
.footer-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
margin-bottom: 30px;
}
.footer-section {
text-align: center;
}
.footer-section h4 {
font-size: 1.2rem;
color: #2d3748;
margin-bottom: 12px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.footer-section p {
color: #64748b;
font-size: 0.95rem;
margin-bottom: 15px;
}
.btn-premium-text {
background: none;
border: 2px solid #ffd700;
color: #e67700;
padding: 10px 20px;
border-radius: 12px;
font-weight: 700;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
}
.btn-premium-text:hover {
background: #ffd700;
color: #2d3748;
}
.footer-bottom {
text-align: center;
padding-top: 25px;
border-top: 2px solid #e2e8f0;
}
.footer-bottom p {
color: #64748b;
margin-bottom: 10px;
}
.footer-bottom a {
color: #4a6fa5;
font-weight: 700;
text-decoration: none;
}
.footer-bottom a:hover {
text-decoration: underline;
}
.copyright {
font-size: 0.9rem;
color: #94a3b8;
}
/* ===== МОДАЛЬНЫЕ ОКНА ===== */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
backdrop-filter: blur(8px);
animation: fadeIn 0.3s ease;
padding: 20px;
}
.modal {
background: white;
border-radius: 28px;
width: 100%;
max-width: 500px;
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3);
animation: slideUp 0.4s ease;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25px 30px;
border-bottom: 2px solid #f1f5f9;
}
.modal-header h3 {
font-size: 1.6rem;
color: #2d3748;
margin: 0;
}
.modal-close {
background: none;
border: none;
font-size: 1.8rem;
color: #64748b;
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
}
.modal-close:hover {
background: #f1f5f9;
color: #2d3748;
}
/* ===== ФОРМА ПОДПИСКИ ===== */
.subscription-modal {
max-width: 550px;
}
#subForm {
padding: 30px;
}
.form-group {
margin-bottom: 25px;
}
.form-group label {
display: flex;
align-items: center;
gap: 10px;
font-weight: 600;
color: #2d3748;
margin-bottom: 10px;
font-size: 1rem;
}
.form-group label i {
color: #4a6fa5;
}
.form-row {
display: flex;
gap: 20px;
margin-bottom: 25px;
}
.form-group.half {
flex: 1;
}
input, select, textarea {
width: 100%;
padding: 18px 20px;
border: 2px solid #e2e8f0;
border-radius: 15px;
font-size: 1rem;
transition: all 0.3s;
background: white;
}
.input-with-icon {
position: relative;
}
.input-with-icon .input-icon {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
color: #64748b;
font-weight: 600;
}
input:focus, select:focus, textarea:focus {
border-color: #4a6fa5;
outline: none;
box-shadow: 0 0 0 3px rgba(74, 111, 165, 0.1);
}
textarea {
resize: vertical;
min-height: 80px;
}
/* ===== ПАЛИТРА ЦВЕТОВ ===== */
.color-picker-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 12px;
margin-top: 10px;
}
.color-option {
width: 45px;
height: 45px;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s;
border: 3px solid transparent;
}
.color-option:hover {
transform: scale(1.1);
}
.color-option.active {
border-color: #2d3748;
transform: scale(1.1);
}
.color-input {
grid-column: span 6;
height: 50px;
padding: 5px;
border-radius: 12px;
cursor: pointer;
}
/* ===== КНОПКИ ФОРМЫ ===== */
.modal-actions {
display: flex;
gap: 15px;
margin-top: 30px;
}
.btn-secondary {
flex: 1;
background: #f1f5f9;
color: #64748b;
border: none;
padding: 18px;
border-radius: 15px;
font-weight: 600;
font-size: 1rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
transition: all 0.3s;
}
.btn-secondary:hover {
background: #e2e8f0;
}
/* ===== ПРЕМИУМ МОДАЛКА ===== */
.premium-modal {
max-width: 650px;
}
.premium-header {
text-align: center;
padding: 40px 30px 30px;
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
border-radius: 28px 28px 0 0;
}
.crown-container {
width: 80px;
height: 80px;
background: rgba(255, 255, 255, 0.15);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 20px;
font-size: 2.5rem;
color: #ffd700;
border: 3px solid rgba(255, 255, 255, 0.2);
}
.premium-header h2 {
font-size: 2.2rem;
margin-bottom: 10px;
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.premium-subtitle {
font-size: 1.1rem;
opacity: 0.9;
font-weight: 500;
}
/* ===== ФИЧИ ПРЕМИУМА ===== */
.premium-features {
padding: 30px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.feature-card {
background: white;
padding: 25px;
border-radius: 20px;
display: flex;
gap: 20px;
align-items: flex-start;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
border: 2px solid #e2e8f0;
transition: all 0.3s;
}
.feature-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
border-color: #ffd700;
}
.feature-icon {
width: 60px;
height: 60px;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
flex-shrink: 0;
}
.feature-icon.infinity {
background: linear-gradient(135deg, #ffd700 0%, rgba(255, 215, 0, 0.3) 100%);
color: #e67700;
}
.feature-icon.chart {
}
.modal-close:hover {
background: #f1f5f9;
color: #2d3748;
}
/* ===== ФОРМА ПОДПИСКИ ===== */
.subscription-modal {
max-width: 550px;
}
#subForm {
padding: 30px;
}
.form-group {
margin-bottom: 25px;
}
.form-group label {
display: flex;
align-items: center;
gap: 10px;
font-weight: 600;
color: #2d3748;
margin-bottom: 10px;
font-size: 1rem;
}
.form-group label i {
color: #4a6fa5;
}
.form-row {
display: flex;
gap: 20px;
margin-bottom: 25px;
}
.form-group.half {
flex: 1;
}
input, select, textarea {
width: 100%;
padding: 18px 20px;
border: 2px solid #e2e8f0;
border-radius: 15px;
font-size: 1rem;
transition: all 0.3s;
background: white;
}
.input-with-icon {
position: relative;
}
.input-with-icon .input-icon {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
color: #64748b;
font-weight: 600;
}
input:focus, select:focus, textarea:focus {
border-color: #4a6fa5;
outline: none;
box-shadow: 0 0 0 3px rgba(74, 111, 165, 0.1);
}
textarea {
resize: vertical;
min-height: 80px;
}
/* ===== ПАЛИТРА ЦВЕТОВ ===== */
.color-picker-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 12px;
margin-top: 10px;
}
.color-option {
width: 45px;
height: 45px;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s;
border: 3px solid transparent;
}
.color-option:hover {
transform: scale(1.1);
}
.color-option.active {
border-color: #2d3748;
transform: scale(1.1);
}
.color-input {
grid-column: span 6;
height: 50px;
padding: 5px;
border-radius: 12px;
cursor: pointer;
}
/* ===== КНОПКИ ФОРМЫ ===== */
.modal-actions {
display: flex;
gap: 15px;
margin-top: 30px;
}
.btn-secondary {
flex: 1;
background: #f1f5f9;
color: #64748b;
border: none;
padding: 18px;
border-radius: 15px;
font-weight: 600;
font-size: 1rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
transition: all 0.3s;
}
.btn-secondary:hover {
background: #e2e8f0;
}
/* ===== ПРЕМИУМ МОДАЛКА ===== */
.premium-modal {
max-width: 650px;
}
.premium-header {
text-align: center;
padding: 40px 30px 30px;
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
border-radius: 28px 28px 0 0;
}
.crown-container {
width: 80px;
height: 80px;
background: rgba(255, 255, 255, 0.15);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 20px;
font-size: 2.5rem;
color: #ffd700;
border: 3px solid rgba(255, 255, 255, 0.2);
}
.premium-header h2 {
font-size: 2.2rem;
margin-bottom: 10px;
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.premium-subtitle {
font-size: 1.1rem;
opacity: 0.9;
font-weight: 500;
}
/* ===== ФИЧИ ПРЕМИУМА ===== */
.premium-features {
padding: 30px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.feature-card {
background: white;
padding: 25px;
border-radius: 20px;
display: flex;
gap: 20px;
align-items: flex-start;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
border: 2px solid #e2e8f0;
transition: all 0.3s;
}
.feature-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
border-color: #ffd700;
}
.feature-icon {
width: 60px;
height: 60px;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
flex-shrink: 0;
}
.feature-icon.infinity {
background: linear-gradient(135deg, #ffd700 0%, rgba(255, 215, 0, 0.3) 100%);
color: #e67700;
}
.feature-icon.chart {
background: linear-gradient(135deg, #4a6fa5 0%, rgba(74, 111, 165, 0.3) 100%);
color: #4a6fa5;
}
.feature-icon.bell {
background: linear-gradient(135deg, #51cf66 0%, rgba(81, 207, 102, 0.3) 100%);
color: #2b8a3e;
}
.feature-icon.cloud {
background: linear-gradient(135deg, #cc5de8 0%, rgba(204, 93, 232, 0.3) 100%);
color: #862e9c;
}
.feature-content h4 {
font-size: 1.2rem;
color: #2d3748;
margin-bottom: 8px;
font-weight: 700;
}
.feature-content p {
color: #64748b;
font-size: 0.95rem;
line-height: 1.5;
}
/* ===== ЦЕНООБРАЗОВАНИЕ ===== */
.pricing-section {
padding: 0 30px 30px;
}
.pricing-section h3 {
font-size: 1.4rem;
color: #2d3748;
margin-bottom: 25px;
display: flex;
align-items: center;
gap: 10px;
}
.pricing-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.pricing-card {
background: white;
padding: 30px;
border-radius: 22px;
border: 3px solid #e2e8f0;
position: relative;
transition: all 0.3s;
text-align: center;
}
.pricing-card.popular {
border-color: #ffd700;
transform: scale(1.05);
}
.popular-badge {
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
padding: 8px 20px;
border-radius: 20px;
font-weight: 700;
font-size: 0.85rem;
white-space: nowrap;
}
.pricing-header {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
margin-bottom: 25px;
}
.pricing-header i {
font-size: 2rem;
color: #4a6fa5;
}
.pricing-card.popular .pricing-header i {
color: #ffd700;
}
.pricing-header h4 {
font-size: 1.4rem;
color: #2d3748;
margin: 0;
}
.price {
margin-bottom: 25px;
}
.amount {
font-size: 3rem;
font-weight: 800;
color: #2d3748;
display: block;
line-height: 1;
}
.period {
font-size: 1rem;
color: #64748b;
font-weight: 500;
}
.pricing-features {
text-align: left;
margin-bottom: 25px;
}
.pricing-features p {
margin-bottom: 12px;
color: #64748b;
font-size: 0.95rem;
display: flex;
align-items: center;
gap: 10px;
}
.pricing-features i {
color: #51cf66;
font-size: 1rem;
}
.btn-select-plan {
width: 100%;
padding: 18px;
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
border: none;
border-radius: 15px;
font-weight: 700;
font-size: 1.1rem;
cursor: pointer;
transition: all 0.3s;
}
.pricing-card.popular .btn-select-plan {
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
}
.btn-select-plan:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
/* ===== ОПЛАТА ===== */
.payment-section {
padding: 30px;
background: #f8fafc;
border-radius: 25px;
margin: 0 30px 30px;
}
.payment-section h3 {
font-size: 1.4rem;
color: #2d3748;
margin-bottom: 25px;
display: flex;
align-items: center;
gap: 10px;
}
.payment-methods {
display: flex;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 30px;
}
.payment-method {
background: white;
padding: 15px;
border-radius: 15px;
min-width: 100px;
text-align: center;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
border: 2px solid #e2e8f0;
transition: all 0.3s;
}
.payment-method:hover {
transform: translateY(-5px);
border-color: #ffd700;
}
.payment-method i {
font-size: 2.5rem;
color: #4a5568;
margin-bottom: 10px;
display: block;
}
.payment-method span {
font-weight: 600;
color: #2d3748;
font-size: 0.9rem;
}
.btn-premium-purchase {
width: 100%;
padding: 22px;
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
border: none;
border-radius: 18px;
font-weight: 800;
font-size: 1.2rem;
cursor: pointer;
color: #4a6fa5;
}
.feature-icon.bell {
background: linear-gradient(135deg, #51cf66 0%, rgba(81, 207, 102, 0.3) 100%);
color: #2b8a3e;
}
.feature-icon.cloud {
background: linear-gradient(135deg, #cc5de8 0%, rgba(204, 93, 232, 0.3) 100%);
color: #862e9c;
}
.feature-content h4 {
font-size: 1.2rem;
color: #2d3748;
margin-bottom: 8px;
font-weight: 700;
}
.feature-content p {
color: #64748b;
font-size: 0.95rem;
line-height: 1.5;
}
/* ===== ЦЕНООБРАЗОВАНИЕ ===== */
.pricing-section {
padding: 0 30px 30px;
}
.pricing-section h3 {
font-size: 1.4rem;
color: #2d3748;
margin-bottom: 25px;
display: flex;
align-items: center;
gap: 10px;
}
.pricing-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.pricing-card {
background: white;
padding: 30px;
border-radius: 22px;
border: 3px solid #e2e8f0;
position: relative;
transition: all 0.3s;
text-align: center;
}
.pricing-card.popular {
border-color: #ffd700;
transform: scale(1.05);
}
.popular-badge {
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
padding: 8px 20px;
border-radius: 20px;
font-weight: 700;
font-size: 0.85rem;
white-space: nowrap;
}
.pricing-header {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
margin-bottom: 25px;
}
.pricing-header i {
font-size: 2rem;
color: #4a6fa5;
}
.pricing-card.popular .pricing-header i {
color: #ffd700;
}
.pricing-header h4 {
font-size: 1.4rem;
color: #2d3748;
margin: 0;
}
.price {
margin-bottom: 25px;
}
.amount {
font-size: 3rem;
font-weight: 800;
color: #2d3748;
display: block;
line-height: 1;
}
.period {
font-size: 1rem;
color: #64748b;
font-weight: 500;
}
.pricing-features {
text-align: left;
margin-bottom: 25px;
}
.pricing-features p {
margin-bottom: 12px;
color: #64748b;
font-size: 0.95rem;
display: flex;
align-items: center;
gap: 10px;
}
.pricing-features i {
color: #51cf66;
font-size: 1rem;
}
.btn-select-plan {
width: 100%;
padding: 18px;
background: linear-gradient(135deg, #4a6fa5 0%, #6a93cb 100%);
color: white;
border: none;
border-radius: 15px;
font-weight: 700;
font-size: 1.1rem;
cursor: pointer;
transition: all 0.3s;
}
.pricing-card.popular .btn-select-plan {
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
}
.btn-select-plan:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
/* ===== ОПЛАТА ===== */
.payment-section {
padding: 30px;
background: #f8fafc;
border-radius: 25px;
margin: 0 30px 30px;
}
.payment-section h3 {
font-size: 1.4rem;
color: #2d3748;
margin-bottom: 25px;
display: flex;
align-items: center;
gap: 10px;
}
.payment-methods {
display: flex;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 30px;
}
.payment-method {
background: white;
padding: 15px;
border-radius: 15px;
min-width: 100px;
text-align: center;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
border: 2px solid #e2e8f0;
transition: all 0.3s;
}
.payment-method:hover {
transform: translateY(-5px);
border-color: #ffd700;
}
.payment-method i {
font-size: 2.5rem;
color: #4a5568;
margin-bottom: 10px;
display: block;
}
.payment-method span {
font-weight: 600;
color: #2d3748;
font-size: 0.9rem;
}
.btn-premium-purchase {
width: 100%;
padding: 22px;
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
color: #2d3748;
border: none;
border-radius: 18px;
font-weight: 800;
font-size: 1.2rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
transition: all 0.3s;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(255, 193, 7, 0.3);
}
.btn-premium-purchase:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(255, 193, 7, 0.4);
}
.security-info {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
color: #51cf66;
font-weight: 600;
font-size: 0.95rem;
}
.premium-footer {
padding: 0 30px 30px;
text-align: center;
}
.btn-close-premium {
background: #f1f5f9;
color: #64748b;
border: none;
padding: 15px 30px;
border-radius: 15px;
font-weight: 600;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 10px;
transition: all 0.3s;
margin-bottom: 20px;
}
.btn-close-premium:hover {
background: #e2e8f0;
}
.no-refund {
color: #ff6b6b;
font-size: 0.9rem;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
/* ===== МОДАЛКА ОГРАНИЧЕНИЯ ===== */
.limit-modal {
max-width: 500px;
text-align: center;
padding: 40px 30px;
}
.limit-icon {
font-size: 5rem;
color: #ffd700;
margin-bottom: 25px;
}
.limit-modal h2 {
font-size: 1.8rem;
color: #2d3748;
margin-bottom: 15px;
}
.limit-message {
color: #64748b;
font-size: 1.1rem;
margin-bottom: 15px;
line-height: 1.5;
}
.upgrade-call {
font-size: 1.1rem;
color: #2d3748;
margin-bottom: 30px;
font-weight: 600;
}
.premium-highlight {
color: #ffd700;
font-weight: 800;
}
.limit-benefits {
display: flex;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin: 30px 0;
}
.benefit {
background: #f8fafc;
padding: 15px 25px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 12px;
border: 2px solid #e2e8f0;
}
.benefit i {
color: #ffd700;
font-size: 1.3rem;
}
.benefit span {
font-weight: 600;
color: #2d3748;
}
.limit-actions {
display: flex;
gap: 15px;
margin: 30px 0;
}
.limit-footer {
color: #94a3b8;
font-size: 0.9rem;
margin-top: 20px;
}
/* ===== МОДАЛКА УСПЕХА ===== */
.success-modal {
max-width: 500px;
text-align: center;
padding: 50px 30px;
}
.success-icon {
font-size: 6rem;
color: #51cf66;
margin-bottom: 25px;
}
.success-modal h2 {
font-size: 2.2rem;
color: #2d3748;
margin-bottom: 15px;
}
.success-message {
font-size: 1.2rem;
color: #64748b;
margin-bottom: 30px;
}
.premium-text {
color: #ffd700;
font-weight: 800;
}
.success-details {
background: #f8fafc;
padding: 25px;
border-radius: 20px;
margin: 30px 0;
text-align: left;
}
.success-details p {
margin-bottom: 15px;
color: #2d3748;
font-weight: 500;
display: flex;
align-items: center;
gap: 12px;
}
.success-details i {
color: #51cf66;
font-size: 1.2rem;
}
.success-footer {
color: #94a3b8;
font-size: 0.9rem;
margin-top: 25px;
}
/* ===== КОНТЕКСТНОЕ МЕНЮ ===== */
.context-menu {
position: fixed;
background: white;
border-radius: 15px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
z-index: 10001;
overflow: hidden;
min-width: 200px;
border: 2px solid #e2e8f0;
}
.context-item {
padding: 18px 25px;
display: flex;
align-items: center;
gap: 15px;
cursor: pointer;
transition: all 0.3s;
font-weight: 500;
}
.context-item:hover {
background: #f8fafc;
}
.edit-item {
color: #4a6fa5;
}
.delete-item {
color: #ff6b6b;
}
.duplicate-item {
color: #51cf66;
}
/* ===== АНИМАЦИИ ===== */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideDown {
from { transform: translateY(-20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes slideUp {
from { transform: translateY(30px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
align-items: center;
justify-content: center;
gap: 15px;
transition: all 0.3s;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(255, 193, 7, 0.3);
}
.btn-premium-purchase:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(255, 193, 7, 0.4);
}
.security-info {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
color: #51cf66;
font-weight: 600;
font-size: 0.95rem;
}
.premium-footer {
padding: 0 30px 30px;
text-align: center;
}
.btn-close-premium {
background: #f1f5f9;
color: #64748b;
border: none;
padding: 15px 30px;
border-radius: 15px;
font-weight: 600;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 10px;
transition: all 0.3s;
margin-bottom: 20px;
}
.btn-close-premium:hover {
background: #e2e8f0;
}
.no-refund {
color: #ff6b6b;
font-size: 0.9rem;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
/* ===== МОДАЛКА ОГРАНИЧЕНИЯ ===== */
.limit-modal {
max-width: 500px;
text-align: center;
padding: 40px 30px;
}
.limit-icon {
font-size: 5rem;
color: #ffd700;
margin-bottom: 25px;
}
.limit-modal h2 {
font-size: 1.8rem;
color: #2d3748;
margin-bottom: 15px;
}
.limit-message {
color: #64748b;
font-size: 1.1rem;
margin-bottom: 15px;
line-height: 1.5;
}
.upgrade-call {
font-size: 1.1rem;
color: #2d3748;
margin-bottom: 30px;
font-weight: 600;
}
.premium-highlight {
color: #ffd700;
font-weight: 800;
}
.limit-benefits {
display: flex;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin: 30px 0;
}
.benefit {
background: #f8fafc;
padding: 15px 25px;
border-radius: 15px;
display: flex;
align-items: center;
gap: 12px;
border: 2px solid #e2e8f0;
}
.benefit i {
color: #ffd700;
font-size: 1.3rem;
}
.benefit span {
font-weight: 600;
color: #2d3748;
}
.limit-actions {
display: flex;
gap: 15px;
margin: 30px 0;
}
.limit-footer {
color: #94a3b8;
font-size: 0.9rem;
margin-top: 20px;
}
/* ===== МОДАЛКА УСПЕХА ===== */
.success-modal {
max-width: 500px;
text-align: center;
padding: 50px 30px;
}
.success-icon {
font-size: 6rem;
color: #51cf66;
margin-bottom: 25px;
}
.success-modal h2 {
font-size: 2.2rem;
color: #2d3748;
margin-bottom: 15px;
}
.success-message {
font-size: 1.2rem;
color: #64748b;
margin-bottom: 30px;
}
.premium-text {
color: #ffd700;
font-weight: 800;
}
.success-details {
background: #f8fafc;
padding: 25px;
border-radius: 20px;
margin: 30px 0;
text-align: left;
}
.success-details p {
margin-bottom: 15px;
color: #2d3748;
font-weight: 500;
display: flex;
align-items: center;
gap: 12px;
}
.success-details i {
color: #51cf66;
font-size: 1.2rem;
}
.success-footer {
color: #94a3b8;
font-size: 0.9rem;
margin-top: 25px;
}
/* ===== КОНТЕКСТНОЕ МЕНЮ ===== */
.context-menu {
position: fixed;
background: white;
border-radius: 15px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
z-index: 10001;
overflow: hidden;
min-width: 200px;
border: 2px solid #e2e8f0;
}
.context-item {
padding: 18px 25px;
display: flex;
align-items: center;
gap: 15px;
cursor: pointer;
transition: all 0.3s;
font-weight: 500;
}
.context-item:hover {
background: #f8fafc;
}
.edit-item {
color: #4a6fa5;
}
.delete-item {
color: #ff6b6b;
}
.duplicate-item {
color: #51cf66;
}
/* ===== АНИМАЦИИ ===== */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideDown {
from { transform: translateY(-20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes slideUp {
from { transform: translateY(30px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
/* ===== АДАПТИВНОСТЬ ===== */
@media (max-width: 768px) {
.container {
border-radius: 20px;
padding: 0;
}
.app-header {
padding: 20px 25px 15px;
}
.header-main {
flex-direction: column;
gap: 20px;
text-align: center;
}
.logo-section {
flex-direction: column;
text-align: center;
}
.premium-header {
width: 100%;
justify-content: center;
}
.control-panel {
flex-direction: column;
margin: 25px 20px;
}
.stats-summary {
width: 100%;
}
.stat-box {
min-width: 0;
}
.section-header {
flex-direction: column;
text-align: center;
}
.filter-buttons {
width: 100%;
justify-content: center;
}
.subscription-item {
flex-direction: column;
align-items: flex-start;
gap: 20px;
}
.sub-actions {
align-self: stretch;
justify-content: space-between;
}
.footer-content {
grid-template-columns: 1fr;
}
.pricing-cards {
grid-template-columns: 1fr;
}
.pricing-card.popular {
transform: none;
}
.payment-methods {
gap: 15px;
}
.payment-method {
min-width: 80px;
padding: 12px;
}
.limit-actions {
flex-direction: column;
}
.modal {
max-height: 85vh;
}
}
@media (max-width: 480px) {
.app-header h1 {
font-size: 1.8rem;
}
.quick-stats {
grid-template-columns: 1fr;
}
.sub-meta {
flex-direction: column;
gap: 12px;
}
.color-picker-grid {
grid-template-columns: repeat(3, 1fr);
}
.color-input {
grid-column: span 3;
}
.feature-card {
flex-direction: column;
text-align: center;
align-items: center;
}
.limit-benefits {
flex-direction: column;
}
}
/* ===== ТЕМА ДЛЯ TELEGRAM MINI APP ===== */
.telegram-theme {
background: linear-gradient(135deg, #3390ec 0%, #2b6cb0 100%);
}
.telegram-theme .container {
background: rgba(255, 255, 255, 0.98);
}
.telegram-theme .btn-primary-large {
background: linear-gradient(135deg, #3390ec 0%, #2b6cb0 100%);
}
.telegram-theme .logo {
background: rgba(51, 144, 236, 0.15);
border-color: rgba(51, 144, 236, 0.2);
}
.telegram-theme .subscription-item {
border-left-color: #3390ec;
}
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
/* ===== АДАПТИВНОСТЬ ===== */
@media (max-width: 768px) {
.container {
border-radius: 20px;
padding: 0;
}
.app-header {
padding: 20px 25px 15px;
}
.header-main {
flex-direction: column;
gap: 20px;
text-align: center;
}
.logo-section {
flex-direction: column;
text-align: center;
}
.premium-header {
width: 100%;
justify-content: center;
}
.control-panel {
flex-direction: column;
margin: 25px 20px;
}
.stats-summary {
width: 100%;
}
.stat-box {
min-width: 0;
}
.section-header {
flex-direction: column;
text-align: center;
}
.filter-buttons {
width: 100%;
justify-content: center;
}
.subscription-item {
flex-direction: column;
align-items: flex-start;
gap: 20px;
}
.sub-actions {
align-self: stretch;
justify-content: space-between;
}
.footer-content {
grid-template-columns: 1fr;
}
.pricing-cards {
grid-template-columns: 1fr;
}
.pricing-card.popular {
transform: none;
}
.payment-methods {
gap: 15px;
}
.payment-method {
min-width: 80px;
padding: 12px;
}
.limit-actions {
flex-direction: column;
}
.modal {
max-height: 85vh;
}
}
@media (max-width: 480px) {
.app-header h1 {
font-size: 1.8rem;
}
.quick-stats {
grid-template-columns: 1fr;
}
.sub-meta {
flex-direction: column;
gap: 12px;
}
.color-picker-grid {
grid-template-columns: repeat(3, 1fr);
}
.color-input {
grid-column: span 3;
}
.feature-card {
flex-direction: column;
text-align: center;
align-items: center;
}
.limit-benefits {
flex-direction: column;
}
}
/* ===== ТЕМА ДЛЯ TELEGRAM MINI APP ===== */
.telegram-theme {
background: linear-gradient(135deg, #3390ec 0%, #2b6cb0 100%);
}
.telegram-theme .container {
background: rgba(255, 255, 255, 0.98);
}
.telegram-theme .btn-primary-large {
background: linear-gradient(135deg, #3390ec 0%, #2b6cb0 100%);
}
.telegram-theme .logo {
background: rgba(51, 144, 236, 0.15);
border-color: rgba(51, 144, 236, 0.2);
}
.telegram-theme .subscription-item {
border-left-color: #3390ec;
}
// ========== GLOBAL STATE ==========
let subscriptions = JSON.parse(localStorage.getItem('subscriptions')) || [];
let userData = JSON.parse(localStorage.getItem('userData')) || {
premium: false,
premiumUntil: null,
subscriptionId: null,
theme: 'default'
};
let editingId = null;
let currentContextMenuId = null;
const FREE_LIMIT = 3;
// ========== DOM ELEMENTS ==========
const dom = {
// Основные элементы
container: document.querySelector('.container'),
subsContainer: document.getElementById('subsContainer'),
// Кнопки
addSubBtn: document.getElementById('addSubBtn'),
addFirstSubBtn: document.getElementById('addFirstSubBtn'),
upgradeBtn: document.getElementById('upgradeBtn'),
footerUpgradeBtn: document.getElementById('footerUpgradeBtn'),
// Статистика
monthlyTotal: document.getElementById('monthlyTotal'),
activeCount: document.getElementById('activeCount'),
limitCount: document.getElementById('limitCount'),
limitBox: document.getElementById('limitBox'),
todaySubs: document.getElementById('todaySubs'),
expiringSubs: document.getElementById('expiringSubs'),
// Премиум статус
premiumBadge: document.getElementById('premiumBadge'),
premiumHeader: document.getElementById('premiumHeader'),
// Баннер
reminderBanner: document.getElementById('reminderBanner'),
closeBanner: document.getElementById('closeBanner'),
// Фильтры
filterButtons: document.querySelectorAll('.filter-btn'),
// Модальные окна
modalOverlay: document.getElementById('modalOverlay'),
premiumModalOverlay: document.getElementById('premiumModalOverlay'),
limitModalOverlay: document.getElementById('limitModalOverlay'),
successModalOverlay: document.getElementById('successModalOverlay'),
// Форма подписки
subForm: document.getElementById('subForm'),
modalTitle: document.getElementById('modalTitle'),
subName: document.getElementById('subName'),
subPrice: document.getElementById('subPrice'),
subCycle: document.getElementById('subCycle'),
subNextDate: document.getElementById('subNextDate'),
subColor: document.getElementById('subColor'),
subNotes: document.getElementById('subNotes'),
// Кнопки закрытия
cancelBtn: document.getElementById('cancelBtn'),
cancelBtn2: document.getElementById('cancelBtn2'),
closePremiumBtn: document.getElementById('closePremiumBtn'),
closeLimitBtn: document.getElementById('closeLimitBtn'),
closeSuccessBtn: document.getElementById('closeSuccessBtn'),
// Премиум покупка
buyPremiumBtn: document.getElementById('buyPremiumBtn'),
upgradeFromLimitBtn: document.getElementById('upgradeFromLimitBtn'),
// Контекстное меню
contextMenu: document.getElementById('contextMenu'),
// Цветовые опции
colorOptions: document.querySelectorAll('.color-option'),
// План премиума
planButtons: document.querySelectorAll('.btn-select-plan'),
pricingCards: document.querySelectorAll('.pricing-card')
};
// ========== INITIALIZATION ==========
document.addEventListener('DOMContentLoaded', function() {
initApp();
setupEventListeners();
renderSubscriptions();
updateUI();
});
function initApp() {
// Установка даты по умолчанию
const nextMonth = new Date();
nextMonth.setMonth(nextMonth.getMonth() + 1);
dom.subNextDate.value = nextMonth.toISOString().split('T')[0];
// Инициализация цветовых опций
initColorPicker();
// Проверка Telegram Mini App
if (window.Telegram && Telegram.WebApp) {
applyTelegramTheme();
}
}
// ========== EVENT LISTENERS ==========
function setupEventListeners() {
// Основные кнопки
dom.addSubBtn.addEventListener('click', () => openModal());
dom.addFirstSubBtn.addEventListener('click', () => openModal());
dom.upgradeBtn.addEventListener('click', showPremiumModal);
dom.footerUpgradeBtn.addEventListener('click', showPremiumModal);
dom.closeBanner.
let subscriptions = JSON.parse(localStorage.getItem('subscriptions')) || [];
let userData = JSON.parse(localStorage.getItem('userData')) || {
premium: false,
premiumUntil: null,
subscriptionId: null,
theme: 'default'
};
let editingId = null;
let currentContextMenuId = null;
const FREE_LIMIT = 3;
// ========== DOM ELEMENTS ==========
const dom = {
// Основные элементы
container: document.querySelector('.container'),
subsContainer: document.getElementById('subsContainer'),
// Кнопки
addSubBtn: document.getElementById('addSubBtn'),
addFirstSubBtn: document.getElementById('addFirstSubBtn'),
upgradeBtn: document.getElementById('upgradeBtn'),
footerUpgradeBtn: document.getElementById('footerUpgradeBtn'),
// Статистика
monthlyTotal: document.getElementById('monthlyTotal'),
activeCount: document.getElementById('activeCount'),
limitCount: document.getElementById('limitCount'),
limitBox: document.getElementById('limitBox'),
todaySubs: document.getElementById('todaySubs'),
expiringSubs: document.getElementById('expiringSubs'),
// Премиум статус
premiumBadge: document.getElementById('premiumBadge'),
premiumHeader: document.getElementById('premiumHeader'),
// Баннер
reminderBanner: document.getElementById('reminderBanner'),
closeBanner: document.getElementById('closeBanner'),
// Фильтры
filterButtons: document.querySelectorAll('.filter-btn'),
// Модальные окна
modalOverlay: document.getElementById('modalOverlay'),
premiumModalOverlay: document.getElementById('premiumModalOverlay'),
limitModalOverlay: document.getElementById('limitModalOverlay'),
successModalOverlay: document.getElementById('successModalOverlay'),
// Форма подписки
subForm: document.getElementById('subForm'),
modalTitle: document.getElementById('modalTitle'),
subName: document.getElementById('subName'),
subPrice: document.getElementById('subPrice'),
subCycle: document.getElementById('subCycle'),
subNextDate: document.getElementById('subNextDate'),
subColor: document.getElementById('subColor'),
subNotes: document.getElementById('subNotes'),
// Кнопки закрытия
cancelBtn: document.getElementById('cancelBtn'),
cancelBtn2: document.getElementById('cancelBtn2'),
closePremiumBtn: document.getElementById('closePremiumBtn'),
closeLimitBtn: document.getElementById('closeLimitBtn'),
closeSuccessBtn: document.getElementById('closeSuccessBtn'),
// Премиум покупка
buyPremiumBtn: document.getElementById('buyPremiumBtn'),
upgradeFromLimitBtn: document.getElementById('upgradeFromLimitBtn'),
// Контекстное меню
contextMenu: document.getElementById('contextMenu'),
// Цветовые опции
colorOptions: document.querySelectorAll('.color-option'),
// План премиума
planButtons: document.querySelectorAll('.btn-select-plan'),
pricingCards: document.querySelectorAll('.pricing-card')
};
// ========== INITIALIZATION ==========
document.addEventListener('DOMContentLoaded', function() {
initApp();
setupEventListeners();
renderSubscriptions();
updateUI();
});
function initApp() {
// Установка даты по умолчанию
const nextMonth = new Date();
nextMonth.setMonth(nextMonth.getMonth() + 1);
dom.subNextDate.value = nextMonth.toISOString().split('T')[0];
// Инициализация цветовых опций
initColorPicker();
// Проверка Telegram Mini App
if (window.Telegram && Telegram.WebApp) {
applyTelegramTheme();
}
}
// ========== EVENT LISTENERS ==========
function setupEventListeners() {
// Основные кнопки
dom.addSubBtn.addEventListener('click', () => openModal());
dom.addFirstSubBtn.addEventListener('click', () => openModal());
dom.upgradeBtn.addEventListener('click', showPremiumModal);
dom.footerUpgradeBtn.addEventListener('click', showPremiumModal);
dom.closeBanner.
addEventListener('click', hideReminderBanner);
// Закрытие модалок
dom.cancelBtn.addEventListener('click', closeModal);
dom.cancelBtn2.addEventListener('click', closeModal);
dom.closePremiumBtn.addEventListener('click', hidePremiumModal);
dom.closeLimitBtn.addEventListener('click', hideLimitModal);
dom.closeSuccessBtn.addEventListener('click', hideSuccessModal);
// Покупка премиума
dom.buyPremiumBtn.addEventListener('click', buyPremium);
dom.upgradeFromLimitBtn.addEventListener('click', showPremiumModal);
// Клики вне модалок
dom.modalOverlay.addEventListener('click', e => e.target === dom.modalOverlay && closeModal());
dom.premiumModalOverlay.addEventListener('click', e => e.target === dom.premiumModalOverlay && hidePremiumModal());
dom.limitModalOverlay.addEventListener('click', e => e.target === dom.limitModalOverlay && hideLimitModal());
dom.successModalOverlay.addEventListener('click', e => e.target === dom.successModalOverlay && hideSuccessModal());
// Форма подписки
dom.subForm.addEventListener('submit', handleFormSubmit);
// Фильтры
dom.filterButtons.forEach(btn => {
btn.addEventListener('click', () => {
dom.filterButtons.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
renderSubscriptions(btn.dataset.filter);
});
});
// Выбор плана премиума
dom.planButtons.forEach(btn => {
btn.addEventListener('click', () => {
const plan = btn.dataset.plan;
selectPremiumPlan(plan);
});
});
// Выбор карточки плана
dom.pricingCards.forEach(card => {
card.addEventListener('click', () => {
const plan = card.dataset.plan;
selectPremiumPlan(plan);
});
});
// Закрытие контекстного меню
document.addEventListener('click', () => {
dom.contextMenu.style.display = 'none';
});
}
// ========== COLOR PICKER ==========
function initColorPicker() {
dom.colorOptions.forEach(option => {
option.addEventListener('click', () => {
const color = option.dataset.color;
dom.subColor.value = color;
dom.colorOptions.forEach(o => o.classList.remove('active'));
option.classList.add('active');
});
});
dom.subColor.addEventListener('input', (e) => {
const color = e.target.value;
dom.colorOptions.forEach(o => o.classList.remove('active'));
});
}
// ========== SUBSCRIPTION MANAGEMENT ==========
function handleFormSubmit(e) {
e.preventDefault();
// Проверка лимита для новой подписки
if (!editingId && !checkSubscriptionLimit()) {
showLimitModal();
return;
}
const subData = {
id: editingId || Date.now(),
name: dom.subName.value.trim(),
price: parseFloat(dom.subPrice.value) || 0,
cycle: dom.subCycle.value,
nextDate: dom.subNextDate.value,
color: dom.subColor.value,
notes: dom.subNotes.value.trim(),
createdAt: editingId ? null : new Date().toISOString(),
updatedAt: new Date().toISOString(),
active: true
};
if (editingId) {
const index = subscriptions.findIndex(s => s.id == editingId);
subscriptions[index] = { ...subscriptions[index], ...subData };
} else {
subscriptions.push(subData);
}
saveToLocalStorage();
closeModal();
renderSubscriptions();
updateUI();
showNotification(editingId ? 'Подписка обновлена!' : 'Подписка добавлена!');
}
function deleteSubscription(id) {
if (!confirm('Удалить эту подписку?')) return;
subscriptions = subscriptions.filter(s => s.id != id);
saveToLocalStorage();
renderSubscriptions();
updateUI();
showNotification('Подписка удалена!');
}
function duplicateSubscription(id) {
const original = subscriptions.find(s => s.id == id);
if (!original) return;
if (!checkSubscriptionLimit()) {
// Закрытие модалок
dom.cancelBtn.addEventListener('click', closeModal);
dom.cancelBtn2.addEventListener('click', closeModal);
dom.closePremiumBtn.addEventListener('click', hidePremiumModal);
dom.closeLimitBtn.addEventListener('click', hideLimitModal);
dom.closeSuccessBtn.addEventListener('click', hideSuccessModal);
// Покупка премиума
dom.buyPremiumBtn.addEventListener('click', buyPremium);
dom.upgradeFromLimitBtn.addEventListener('click', showPremiumModal);
// Клики вне модалок
dom.modalOverlay.addEventListener('click', e => e.target === dom.modalOverlay && closeModal());
dom.premiumModalOverlay.addEventListener('click', e => e.target === dom.premiumModalOverlay && hidePremiumModal());
dom.limitModalOverlay.addEventListener('click', e => e.target === dom.limitModalOverlay && hideLimitModal());
dom.successModalOverlay.addEventListener('click', e => e.target === dom.successModalOverlay && hideSuccessModal());
// Форма подписки
dom.subForm.addEventListener('submit', handleFormSubmit);
// Фильтры
dom.filterButtons.forEach(btn => {
btn.addEventListener('click', () => {
dom.filterButtons.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
renderSubscriptions(btn.dataset.filter);
});
});
// Выбор плана премиума
dom.planButtons.forEach(btn => {
btn.addEventListener('click', () => {
const plan = btn.dataset.plan;
selectPremiumPlan(plan);
});
});
// Выбор карточки плана
dom.pricingCards.forEach(card => {
card.addEventListener('click', () => {
const plan = card.dataset.plan;
selectPremiumPlan(plan);
});
});
// Закрытие контекстного меню
document.addEventListener('click', () => {
dom.contextMenu.style.display = 'none';
});
}
// ========== COLOR PICKER ==========
function initColorPicker() {
dom.colorOptions.forEach(option => {
option.addEventListener('click', () => {
const color = option.dataset.color;
dom.subColor.value = color;
dom.colorOptions.forEach(o => o.classList.remove('active'));
option.classList.add('active');
});
});
dom.subColor.addEventListener('input', (e) => {
const color = e.target.value;
dom.colorOptions.forEach(o => o.classList.remove('active'));
});
}
// ========== SUBSCRIPTION MANAGEMENT ==========
function handleFormSubmit(e) {
e.preventDefault();
// Проверка лимита для новой подписки
if (!editingId && !checkSubscriptionLimit()) {
showLimitModal();
return;
}
const subData = {
id: editingId || Date.now(),
name: dom.subName.value.trim(),
price: parseFloat(dom.subPrice.value) || 0,
cycle: dom.subCycle.value,
nextDate: dom.subNextDate.value,
color: dom.subColor.value,
notes: dom.subNotes.value.trim(),
createdAt: editingId ? null : new Date().toISOString(),
updatedAt: new Date().toISOString(),
active: true
};
if (editingId) {
const index = subscriptions.findIndex(s => s.id == editingId);
subscriptions[index] = { ...subscriptions[index], ...subData };
} else {
subscriptions.push(subData);
}
saveToLocalStorage();
closeModal();
renderSubscriptions();
updateUI();
showNotification(editingId ? 'Подписка обновлена!' : 'Подписка добавлена!');
}
function deleteSubscription(id) {
if (!confirm('Удалить эту подписку?')) return;
subscriptions = subscriptions.filter(s => s.id != id);
saveToLocalStorage();
renderSubscriptions();
updateUI();
showNotification('Подписка удалена!');
}
function duplicateSubscription(id) {
const original = subscriptions.find(s => s.id == id);
if (!original) return;
if (!checkSubscriptionLimit()) {
showLimitModal();
return;
}
const duplicate = {
...original,
id: Date.now(),
name:
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
subscriptions.push(duplicate);
saveToLocalStorage();
renderSubscriptions();
updateUI();
showNotification('Подписка скопирована!');
}
// ========== RENDERING ==========
function renderSubscriptions(filter = 'all') {
if (!subscriptions.length) {
dom.subsContainer.innerHTML = `
<div class="empty-state">
<div class="empty-icon">
<i class="fas fa-box-open"></i>
</div>
<h3>Пока нет подписок</h3>
<p>Добавьте первую подписку, чтобы начать отслеживать расходы</p>
<button id="addFirstSubBtn" class="btn-primary">
<i class="fas fa-plus"></i> Добавить первую подписку
</button>
</div>
`;
document.getElementById('addFirstSubBtn').addEventListener('click', () => openModal());
return;
}
let filteredSubs = subscriptions;
if (filter === 'active') {
filteredSubs = subscriptions.filter(s => s.active);
} else if (filter === 'soon') {
const today = new Date();
const weekLater = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000);
filteredSubs = subscriptions.filter(s => {
const nextDate = new Date(s.nextDate);
return nextDate >= today && nextDate <= weekLater;
});
}
dom.subsContainer.innerHTML = filteredSubs.map(sub => renderSubscriptionItem(sub)).join('');
// Добавляем обработчики для элементов
document.querySelectorAll('.subscription-item').forEach(item => {
const id = item.dataset.id;
item.addEventListener('contextmenu', (e) => {
e.preventDefault();
showContextMenu(e.clientX, e.clientY, id);
});
item.addEventListener('click', (e) => {
if (!e.target.closest('.action-btn')) {
openModal(id);
}
});
});
document.querySelectorAll('.action-btn.edit').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
openModal(btn.dataset.id);
});
});
document.querySelectorAll('.action-btn.delete').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
deleteSubscription(btn.dataset.id);
});
});
}
function renderSubscriptionItem(sub) {
const nextDate = new Date(sub.nextDate);
const today = new Date();
const daysLeft = Math.ceil((nextDate - today) / (1000 * 60 * 60 * 24));
let dateClass = '';
let dateText = '';
if (daysLeft < 0) {
dateClass = 'expired';
dateText =
} else if (daysLeft === 0) {
dateClass = 'today';
dateText = 'Спишется сегодня';
} else if (daysLeft <= 3) {
dateClass = 'soon';
dateText =
} else {
dateText = formatDate(sub.nextDate);
}
const cycleIcons = {
monthly: '📅',
yearly: '📆',
weekly: '🗓️',
quarterly: '📊'
};
return `
<div class="subscription-item" data-id="${sub.id}" style="--item-color: ${sub.color}">
<div class="sub-info">
<h4>
<span class="color-dot" style="background-color: ${sub.color}"></span>
${sub.name}
${daysLeft <= 3 ? '<span class="urgent-badge">!</span>' : ''}
</h4>
<div class="sub-meta">
<div class="meta-item price">
<i class="fas fa-ruble-sign"></i>
${sub.price.toFixed(2)} ₽
</div>
<div class="meta-item">
return;
}
const duplicate = {
...original,
id: Date.now(),
name:
${original.name} (копия),createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
subscriptions.push(duplicate);
saveToLocalStorage();
renderSubscriptions();
updateUI();
showNotification('Подписка скопирована!');
}
// ========== RENDERING ==========
function renderSubscriptions(filter = 'all') {
if (!subscriptions.length) {
dom.subsContainer.innerHTML = `
<div class="empty-state">
<div class="empty-icon">
<i class="fas fa-box-open"></i>
</div>
<h3>Пока нет подписок</h3>
<p>Добавьте первую подписку, чтобы начать отслеживать расходы</p>
<button id="addFirstSubBtn" class="btn-primary">
<i class="fas fa-plus"></i> Добавить первую подписку
</button>
</div>
`;
document.getElementById('addFirstSubBtn').addEventListener('click', () => openModal());
return;
}
let filteredSubs = subscriptions;
if (filter === 'active') {
filteredSubs = subscriptions.filter(s => s.active);
} else if (filter === 'soon') {
const today = new Date();
const weekLater = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000);
filteredSubs = subscriptions.filter(s => {
const nextDate = new Date(s.nextDate);
return nextDate >= today && nextDate <= weekLater;
});
}
dom.subsContainer.innerHTML = filteredSubs.map(sub => renderSubscriptionItem(sub)).join('');
// Добавляем обработчики для элементов
document.querySelectorAll('.subscription-item').forEach(item => {
const id = item.dataset.id;
item.addEventListener('contextmenu', (e) => {
e.preventDefault();
showContextMenu(e.clientX, e.clientY, id);
});
item.addEventListener('click', (e) => {
if (!e.target.closest('.action-btn')) {
openModal(id);
}
});
});
document.querySelectorAll('.action-btn.edit').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
openModal(btn.dataset.id);
});
});
document.querySelectorAll('.action-btn.delete').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
deleteSubscription(btn.dataset.id);
});
});
}
function renderSubscriptionItem(sub) {
const nextDate = new Date(sub.nextDate);
const today = new Date();
const daysLeft = Math.ceil((nextDate - today) / (1000 * 60 * 60 * 24));
let dateClass = '';
let dateText = '';
if (daysLeft < 0) {
dateClass = 'expired';
dateText =
Просрочено на ${Math.abs(daysLeft)} дн.;} else if (daysLeft === 0) {
dateClass = 'today';
dateText = 'Спишется сегодня';
} else if (daysLeft <= 3) {
dateClass = 'soon';
dateText =
Через ${daysLeft} дн.;} else {
dateText = formatDate(sub.nextDate);
}
const cycleIcons = {
monthly: '📅',
yearly: '📆',
weekly: '🗓️',
quarterly: '📊'
};
return `
<div class="subscription-item" data-id="${sub.id}" style="--item-color: ${sub.color}">
<div class="sub-info">
<h4>
<span class="color-dot" style="background-color: ${sub.color}"></span>
${sub.name}
${daysLeft <= 3 ? '<span class="urgent-badge">!</span>' : ''}
</h4>
<div class="sub-meta">
<div class="meta-item price">
<i class="fas fa-ruble-sign"></i>
${sub.price.toFixed(2)} ₽
</div>
<div class="meta-item">
${cycleIcons[sub.cycle]}
${getCycleText(sub.cycle)}
</div>
<div class="meta-item ${dateClass}">
<i class="far fa-clock"></i>
${dateText}
</div>
${sub.notes ? `
<div class="meta-item">
<i class="far fa-sticky-note"></i>
${sub.notes.substring(0, 30)}${sub.notes.length > 30 ? '...' : ''}
</div>
` : ''}
</div>
</div>
<div class="sub-actions">
<button class="action-btn edit" data-id="${sub.id}">
<i class="fas fa-edit"></i>
</button>
<button class="action-btn delete" data-id="${sub.id}">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
`;
}
// ========== MODAL MANAGEMENT ==========
function openModal(id = null) {
if (id) {
const sub = subscriptions.find(s => s.id == id);
if (!sub) return;
editingId = id;
dom.modalTitle.textContent = 'Редактировать подписку';
dom.subName.value = sub.name;
dom.subPrice.value = sub.price;
dom.subCycle.value = sub.cycle;
dom.subNextDate.value = sub.nextDate;
dom.subColor.value = sub.color;
dom.subNotes.value = sub.notes || '';
// Активируем соответствующий цвет
dom.colorOptions.forEach(o => {
if (o.dataset.color === sub.color) {
o.classList.add('active');
} else {
o.classList.remove('active');
}
});
} else {
if (!checkSubscriptionLimit()) {
showLimitModal();
return;
}
editingId = null;
dom.modalTitle.textContent = 'Добавить новую подписку';
dom.subForm.reset();
// Устанавливаем дату на следующий месяц
const nextMonth = new Date();
nextMonth.setMonth(nextMonth.getMonth() + 1);
dom.subNextDate.value = nextMonth.toISOString().split('T')[0];
}
dom.modalOverlay.style.display = 'flex';
setTimeout(() => dom.subName.focus(), 100);
}
function closeModal() {
dom.modalOverlay.style.display = 'none';
editingId = null;
dom.subForm.reset();
}
// ========== PREMIUM MANAGEMENT ==========
function showPremiumModal() {
dom.premiumModalOverlay.style.display = 'flex';
selectPremiumPlan('monthly');
}
function hidePremiumModal() {
dom.premiumModalOverlay.style.display = 'none';
}
function showLimitModal() {
dom.limitModalOverlay.style.display = 'flex';
}
function hideLimitModal() {
dom.limitModalOverlay.style.display = 'none';
}
function showSuccessModal() {
dom.successModalOverlay.style.display = 'flex';
}
function hideSuccessModal() {
dom.successModalOverlay.style.display = 'none';
}
function selectPremiumPlan(plan) {
// Обновляем выбранную карточку
dom.pricingCards.forEach(card => {
card.classList.remove('selected');
if (card.dataset.plan === plan) {
card.classList.add('selected');
}
});
// Обновляем текст кнопки
const price = plan === 'monthly' ? '299 ₽' : '2 990 ₽';
dom.buyPremiumBtn.innerHTML =
dom.buyPremiumBtn.dataset.plan = plan;
}
function buyPremium() {
const plan = dom.buyPremiumBtn.dataset.plan || 'monthly';
// В реальном приложении здесь будет интеграция с платежной системой
// Для демо просто активируем премиум
userData = {
premium: true,
premiumUntil: new Date(Date.now() + (plan === 'monthly' ? 30 : 365) * 24 * 60 * 60 * 1000).toISOString(),
subscriptionId:
plan: plan
};
saveToLocalStorage();
hidePremiumModal();
showSuccessModal();
updateUI();
${getCycleText(sub.cycle)}
</div>
<div class="meta-item ${dateClass}">
<i class="far fa-clock"></i>
${dateText}
</div>
${sub.notes ? `
<div class="meta-item">
<i class="far fa-sticky-note"></i>
${sub.notes.substring(0, 30)}${sub.notes.length > 30 ? '...' : ''}
</div>
` : ''}
</div>
</div>
<div class="sub-actions">
<button class="action-btn edit" data-id="${sub.id}">
<i class="fas fa-edit"></i>
</button>
<button class="action-btn delete" data-id="${sub.id}">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
`;
}
// ========== MODAL MANAGEMENT ==========
function openModal(id = null) {
if (id) {
const sub = subscriptions.find(s => s.id == id);
if (!sub) return;
editingId = id;
dom.modalTitle.textContent = 'Редактировать подписку';
dom.subName.value = sub.name;
dom.subPrice.value = sub.price;
dom.subCycle.value = sub.cycle;
dom.subNextDate.value = sub.nextDate;
dom.subColor.value = sub.color;
dom.subNotes.value = sub.notes || '';
// Активируем соответствующий цвет
dom.colorOptions.forEach(o => {
if (o.dataset.color === sub.color) {
o.classList.add('active');
} else {
o.classList.remove('active');
}
});
} else {
if (!checkSubscriptionLimit()) {
showLimitModal();
return;
}
editingId = null;
dom.modalTitle.textContent = 'Добавить новую подписку';
dom.subForm.reset();
// Устанавливаем дату на следующий месяц
const nextMonth = new Date();
nextMonth.setMonth(nextMonth.getMonth() + 1);
dom.subNextDate.value = nextMonth.toISOString().split('T')[0];
}
dom.modalOverlay.style.display = 'flex';
setTimeout(() => dom.subName.focus(), 100);
}
function closeModal() {
dom.modalOverlay.style.display = 'none';
editingId = null;
dom.subForm.reset();
}
// ========== PREMIUM MANAGEMENT ==========
function showPremiumModal() {
dom.premiumModalOverlay.style.display = 'flex';
selectPremiumPlan('monthly');
}
function hidePremiumModal() {
dom.premiumModalOverlay.style.display = 'none';
}
function showLimitModal() {
dom.limitModalOverlay.style.display = 'flex';
}
function hideLimitModal() {
dom.limitModalOverlay.style.display = 'none';
}
function showSuccessModal() {
dom.successModalOverlay.style.display = 'flex';
}
function hideSuccessModal() {
dom.successModalOverlay.style.display = 'none';
}
function selectPremiumPlan(plan) {
// Обновляем выбранную карточку
dom.pricingCards.forEach(card => {
card.classList.remove('selected');
if (card.dataset.plan === plan) {
card.classList.add('selected');
}
});
// Обновляем текст кнопки
const price = plan === 'monthly' ? '299 ₽' : '2 990 ₽';
dom.buyPremiumBtn.innerHTML =
<i class="fas fa-lock"></i> Перейти к оплате ${price};dom.buyPremiumBtn.dataset.plan = plan;
}
function buyPremium() {
const plan = dom.buyPremiumBtn.dataset.plan || 'monthly';
// В реальном приложении здесь будет интеграция с платежной системой
// Для демо просто активируем премиум
userData = {
premium: true,
premiumUntil: new Date(Date.now() + (plan === 'monthly' ? 30 : 365) * 24 * 60 * 60 * 1000).toISOString(),
subscriptionId:
premium_${Date.now()},plan: plan
};
saveToLocalStorage();
hidePremiumModal();
showSuccessModal();
updateUI();
// Показываем уведомление об успешной оплате
setTimeout(() => {
showNotification('🎉 Премиум успешно активирован!');
}, 1000);
}
// ========== CONTEXT MENU ==========
function showContextMenu(x, y, id) {
currentContextMenuId = id;
dom.contextMenu.style.display = 'block';
dom.contextMenu.style.left =
dom.contextMenu.style.top =
// Добавляем обработчики для элементов меню
document.querySelector('.edit-item').onclick = () => {
dom.contextMenu.style.display = 'none';
openModal(id);
};
document.querySelector('.delete-item').onclick = () => {
dom.contextMenu.style.display = 'none';
deleteSubscription(id);
};
document.querySelector('.duplicate-item').onclick = () => {
dom.contextMenu.style.display = 'none';
duplicateSubscription(id);
};
}
// ========== UI UPDATES ==========
function updateUI() {
updateStats();
updatePremiumStatus();
updateReminders();
}
function updateStats() {
const monthlyTotal = subscriptions.reduce((sum, sub) => {
let price = sub.price;
if (sub.cycle === 'yearly') price /= 12;
if (sub.cycle === 'weekly') price *= 4.33;
if (sub.cycle === 'quarterly') price /= 3;
return sum + price;
}, 0);
dom.monthlyTotal.textContent =
dom.activeCount.textContent = subscriptions.length;
dom.limitCount.textContent = userData.premium ? '∞' :
if (userData.premium) {
dom.limitBox.style.background = 'linear-gradient(135deg, #fff9db 0%, #ffec99 100%)';
dom.limitBox.style.borderColor = '#ffd43b';
} else if (subscriptions.length >= FREE_LIMIT) {
dom.limitBox.style.background = 'linear-gradient(135deg, #ffe3e3 0%, #ffc9c9 100%)';
dom.limitBox.style.borderColor = '#ff6b6b';
} else {
dom.limitBox.style.background = 'white';
dom.limitBox.style.borderColor = '#e2e8f0';
}
}
function updatePremiumStatus() {
if (userData.premium) {
dom.premiumBadge.innerHTML = `
<i class="fas fa-crown"></i>
<span class="premium-text">Премиум активен</span>
${userData.premiumUntil ?
`;
dom.premiumBadge.style.background = 'linear-gradient(135deg, #ffd700 0%, #ffa500 100%)';
dom.upgradeBtn.style.display = 'none';
} else {
dom.premiumBadge.innerHTML = `
<i class="fas fa-crown"></i>
<span class="premium-text">Бесплатная версия</span>
<span class="premium-limit">(лимит: ${FREE_LIMIT})</span>
`;
dom.premiumBadge.style.background = 'rgba(255, 255, 255, 0.15)';
dom.upgradeBtn.style.display = 'flex';
}
}
function updateReminders() {
const today = new Date();
const todaySubs = subscriptions.filter(s => {
const nextDate = new Date(s.nextDate);
return nextDate.toDateString() === today.toDateString();
}).length;
const expiringSubs = subscriptions.filter(s => {
const nextDate = new Date(s.nextDate);
const daysLeft = Math.ceil((nextDate - today) / (1000 * 60 * 60 * 24));
return daysLeft > 0 && daysLeft <= 7;
}).length;
dom.todaySubs.textContent =
dom.expiringSubs.textContent =
if (todaySubs > 0 || expiringSubs > 0) {
dom.reminderBanner.style.display = 'flex';
}
}
function hideReminderBanner() {
dom.reminderBanner.style.display = 'none';
}
// ========== HELPER FUNCTIONS ==========
function checkSubscriptionLimit() {
return userData.premium || subscriptions.length < FREE_LIMIT;
}
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('ru-RU', {
day: 'numeric',
month: 'long',
year: 'numeric'
});
}
function getCycleText(cycle) {
setTimeout(() => {
showNotification('🎉 Премиум успешно активирован!');
}, 1000);
}
// ========== CONTEXT MENU ==========
function showContextMenu(x, y, id) {
currentContextMenuId = id;
dom.contextMenu.style.display = 'block';
dom.contextMenu.style.left =
${x}px;dom.contextMenu.style.top =
${y}px;// Добавляем обработчики для элементов меню
document.querySelector('.edit-item').onclick = () => {
dom.contextMenu.style.display = 'none';
openModal(id);
};
document.querySelector('.delete-item').onclick = () => {
dom.contextMenu.style.display = 'none';
deleteSubscription(id);
};
document.querySelector('.duplicate-item').onclick = () => {
dom.contextMenu.style.display = 'none';
duplicateSubscription(id);
};
}
// ========== UI UPDATES ==========
function updateUI() {
updateStats();
updatePremiumStatus();
updateReminders();
}
function updateStats() {
const monthlyTotal = subscriptions.reduce((sum, sub) => {
let price = sub.price;
if (sub.cycle === 'yearly') price /= 12;
if (sub.cycle === 'weekly') price *= 4.33;
if (sub.cycle === 'quarterly') price /= 3;
return sum + price;
}, 0);
dom.monthlyTotal.textContent =
${monthlyTotal.toFixed(2)} ₽;dom.activeCount.textContent = subscriptions.length;
dom.limitCount.textContent = userData.premium ? '∞' :
${subscriptions.length}/${FREE_LIMIT};if (userData.premium) {
dom.limitBox.style.background = 'linear-gradient(135deg, #fff9db 0%, #ffec99 100%)';
dom.limitBox.style.borderColor = '#ffd43b';
} else if (subscriptions.length >= FREE_LIMIT) {
dom.limitBox.style.background = 'linear-gradient(135deg, #ffe3e3 0%, #ffc9c9 100%)';
dom.limitBox.style.borderColor = '#ff6b6b';
} else {
dom.limitBox.style.background = 'white';
dom.limitBox.style.borderColor = '#e2e8f0';
}
}
function updatePremiumStatus() {
if (userData.premium) {
dom.premiumBadge.innerHTML = `
<i class="fas fa-crown"></i>
<span class="premium-text">Премиум активен</span>
${userData.premiumUntil ?
<span class="premium-limit">до ${formatDate(userData.premiumUntil)}</span> : ''}`;
dom.premiumBadge.style.background = 'linear-gradient(135deg, #ffd700 0%, #ffa500 100%)';
dom.upgradeBtn.style.display = 'none';
} else {
dom.premiumBadge.innerHTML = `
<i class="fas fa-crown"></i>
<span class="premium-text">Бесплатная версия</span>
<span class="premium-limit">(лимит: ${FREE_LIMIT})</span>
`;
dom.premiumBadge.style.background = 'rgba(255, 255, 255, 0.15)';
dom.upgradeBtn.style.display = 'flex';
}
}
function updateReminders() {
const today = new Date();
const todaySubs = subscriptions.filter(s => {
const nextDate = new Date(s.nextDate);
return nextDate.toDateString() === today.toDateString();
}).length;
const expiringSubs = subscriptions.filter(s => {
const nextDate = new Date(s.nextDate);
const daysLeft = Math.ceil((nextDate - today) / (1000 * 60 * 60 * 24));
return daysLeft > 0 && daysLeft <= 7;
}).length;
dom.todaySubs.textContent =
${todaySubs} списаний сегодня;dom.expiringSubs.textContent =
${expiringSubs} скоро списывается;if (todaySubs > 0 || expiringSubs > 0) {
dom.reminderBanner.style.display = 'flex';
}
}
function hideReminderBanner() {
dom.reminderBanner.style.display = 'none';
}
// ========== HELPER FUNCTIONS ==========
function checkSubscriptionLimit() {
return userData.premium || subscriptions.length < FREE_LIMIT;
}
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('ru-RU', {
day: 'numeric',
month: 'long',
year: 'numeric'
});
}
function getCycleText(cycle) {
const cycles = {
monthly: 'Ежемесячно',
yearly: 'Ежегодно',
weekly: 'Еженедельно',
quarterly: 'Ежеквартально'
};
return cycles[cycle] || cycle;
}
function saveToLocalStorage() {
localStorage.setItem('subscriptions', JSON.stringify(subscriptions));
localStorage.setItem('userData', JSON.stringify(userData));
}
function showNotification(message) {
// Создаем временное уведомление
const notification = document.createElement('div');
notification.className = 'notification';
notification.innerHTML = `
<i class="fas fa-check-circle"></i>
<span>${message}</span>
`;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #51cf66 0%, #2b8a3e 100%);
color: white;
padding: 15px 25px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(81, 207, 102, 0.3);
display: flex;
align-items: center;
gap: 12px;
z-index: 10000;
animation: slideInRight 0.3s ease;
font-weight: 600;
`;
document.body.appendChild(notification);
setTimeout(() => {
notification.style.animation = 'slideOutRight 0.3s ease';
setTimeout(() => notification.remove(), 300);
}, 3000);
}
// ========== TELEGRAM INTEGRATION ==========
function applyTelegramTheme() {
const theme = Telegram.WebApp.colorScheme;
if (theme === 'dark') {
document.body.classList.add('dark-mode');
}
// Используем Telegram тему
document.body.classList.add('telegram-theme');
// Отправляем данные о премиуме в Telegram
Telegram.WebApp.ready();
Telegram.WebApp.expand();
// Подписываемся на события
Telegram.WebApp.onEvent('themeChanged', () => {
const newTheme = Telegram.WebApp.colorScheme;
document.body.classList.toggle('dark-mode', newTheme === 'dark');
});
}
// Добавляем CSS анимации для уведомлений
const style = document.createElement('style');
style.textContent = `
@keyframes slideInRight {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideOutRight {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
.color-dot {
width: 12px;
height: 12px;
border-radius: 50%;
display: inline-block;
margin-right: 10px;
}
.urgent-badge {
background: #ff6b6b;
color: white;
font-size: 0.8rem;
padding: 2px 8px;
border-radius: 10px;
margin-left: 10px;
font-weight: 700;
}
.meta-item.expired {
color: #ff6b6b;
font-weight: 700;
}
.meta-item.today {
color: #e67700;
font-weight: 700;
}
.meta-item.soon {
color: #e67700;
font-weight: 600;
}
.dark-mode {
background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%);
color: #e2e8f0;
}
.dark-mode .container {
background: rgba(45, 55, 72, 0.95);
color: #e2e8f0;
}
.dark-mode .subscription-item {
background: #2d3748;
color: #e2e8f0;
}
.dark-mode .stat-box {
background: #2d3748;
color: #e2e8f0;
}
`;
document.head.appendChild(style);
// Инициализируем приложение
window.addEventListener('load', () => {
console.log('Подписатор PRO загружен!');
console.log('Премиум статус:', userData.premium ? 'Активен' : 'Не активен');
console.log('Количество подписок:', subscriptions.length);
// Показываем приветственное сообщение
if (subscriptions.length === 0) {
setTimeout(() => {
showNotification('👋 Добро пожаловать в Подписатор PRO!');
}, 1000);
}
});
monthly: 'Ежемесячно',
yearly: 'Ежегодно',
weekly: 'Еженедельно',
quarterly: 'Ежеквартально'
};
return cycles[cycle] || cycle;
}
function saveToLocalStorage() {
localStorage.setItem('subscriptions', JSON.stringify(subscriptions));
localStorage.setItem('userData', JSON.stringify(userData));
}
function showNotification(message) {
// Создаем временное уведомление
const notification = document.createElement('div');
notification.className = 'notification';
notification.innerHTML = `
<i class="fas fa-check-circle"></i>
<span>${message}</span>
`;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #51cf66 0%, #2b8a3e 100%);
color: white;
padding: 15px 25px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(81, 207, 102, 0.3);
display: flex;
align-items: center;
gap: 12px;
z-index: 10000;
animation: slideInRight 0.3s ease;
font-weight: 600;
`;
document.body.appendChild(notification);
setTimeout(() => {
notification.style.animation = 'slideOutRight 0.3s ease';
setTimeout(() => notification.remove(), 300);
}, 3000);
}
// ========== TELEGRAM INTEGRATION ==========
function applyTelegramTheme() {
const theme = Telegram.WebApp.colorScheme;
if (theme === 'dark') {
document.body.classList.add('dark-mode');
}
// Используем Telegram тему
document.body.classList.add('telegram-theme');
// Отправляем данные о премиуме в Telegram
Telegram.WebApp.ready();
Telegram.WebApp.expand();
// Подписываемся на события
Telegram.WebApp.onEvent('themeChanged', () => {
const newTheme = Telegram.WebApp.colorScheme;
document.body.classList.toggle('dark-mode', newTheme === 'dark');
});
}
// Добавляем CSS анимации для уведомлений
const style = document.createElement('style');
style.textContent = `
@keyframes slideInRight {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideOutRight {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
.color-dot {
width: 12px;
height: 12px;
border-radius: 50%;
display: inline-block;
margin-right: 10px;
}
.urgent-badge {
background: #ff6b6b;
color: white;
font-size: 0.8rem;
padding: 2px 8px;
border-radius: 10px;
margin-left: 10px;
font-weight: 700;
}
.meta-item.expired {
color: #ff6b6b;
font-weight: 700;
}
.meta-item.today {
color: #e67700;
font-weight: 700;
}
.meta-item.soon {
color: #e67700;
font-weight: 600;
}
.dark-mode {
background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%);
color: #e2e8f0;
}
.dark-mode .container {
background: rgba(45, 55, 72, 0.95);
color: #e2e8f0;
}
.dark-mode .subscription-item {
background: #2d3748;
color: #e2e8f0;
}
.dark-mode .stat-box {
background: #2d3748;
color: #e2e8f0;
}
`;
document.head.appendChild(style);
// Инициализируем приложение
window.addEventListener('load', () => {
console.log('Подписатор PRO загружен!');
console.log('Премиум статус:', userData.premium ? 'Активен' : 'Не активен');
console.log('Количество подписок:', subscriptions.length);
// Показываем приветственное сообщение
if (subscriptions.length === 0) {
setTimeout(() => {
showNotification('👋 Добро пожаловать в Подписатор PRO!');
}, 1000);
}
});