2118 lines
131 KiB
HTML
2118 lines
131 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru" data-theme="dark">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||
<title>Notes — Персональный тренажер и словарь английского языка</title>
|
||
<meta name="description" content="Защищённый персональный тренажёр и словарь английского языка с интервальными повторениями SRS SM-2, контекстным поиском и озвучкой">
|
||
<link rel="stylesheet" href="/static/css/style.css?v=6.9">
|
||
|
||
<!-- PWA meta and icons -->
|
||
<link rel="manifest" href="/manifest.json">
|
||
<meta name="theme-color" content="#0f172a">
|
||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||
<meta name="apple-mobile-web-app-title" content="Notes English">
|
||
<link rel="icon" type="image/png" href="/static/icons/icon-192.png">
|
||
<link rel="apple-touch-icon" href="/static/icons/icon-192.png">
|
||
</head>
|
||
<body>
|
||
<!-- Login Overlay / Page -->
|
||
<div id="login-overlay" class="login-overlay">
|
||
<div class="login-card">
|
||
<div class="login-header">
|
||
<div class="login-logo">📖</div>
|
||
<h1>Notes</h1>
|
||
<p>Персональный словарь и тренажёр английского языка</p>
|
||
</div>
|
||
|
||
<form id="login-form" class="login-form">
|
||
<div class="form-group">
|
||
<label for="login-username">Имя пользователя</label>
|
||
<input type="text" id="login-username" class="input-styled" autocomplete="username" required autofocus placeholder="kopri">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="login-password">Пароль</label>
|
||
<input type="password" id="login-password" class="input-styled" autocomplete="current-password" required placeholder="••••••••">
|
||
</div>
|
||
|
||
<div id="login-error" class="login-error hidden"></div>
|
||
|
||
<button type="submit" id="login-submit-btn" class="btn btn-primary btn-block">
|
||
Войти в словарь
|
||
</button>
|
||
</form>
|
||
<div class="login-footer">
|
||
<small>Безопасное хранилище словаря • study.qpid.pro</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Main Application Shell -->
|
||
<div id="app-shell" class="app-shell hidden">
|
||
<!-- Top Navigation Bar -->
|
||
<header class="navbar" id="main-navbar">
|
||
<div class="nav-left">
|
||
<button id="drawer-toggle-btn" class="icon-btn drawer-toggle-btn" title="Меню навигации (☰)" aria-label="Открыть меню">
|
||
<span class="hamburger-icon">☰</span>
|
||
</button>
|
||
<div class="nav-brand" id="nav-brand-home" title="На главную (Словарь)">
|
||
<span class="brand-icon">📖</span>
|
||
<span class="brand-title">Notes</span>
|
||
<span class="brand-sub">English Lexicon</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nav-center">
|
||
<button id="srs-trainer-btn" class="btn btn-trainer" title="Интервальный тренажер SRS (повторение слов)">
|
||
<span class="trainer-icon">🎓</span>
|
||
<span class="trainer-text">Тренажёр SRS</span>
|
||
<span id="srs-badge" class="srs-due-badge">0</span>
|
||
</button>
|
||
<div class="nav-stats" id="nav-stats">
|
||
<span class="stat-badge" title="Всего слов в словаре">Всего: <strong id="stat-total">0</strong></span>
|
||
<span class="stat-badge stat-today" title="Добавлено сегодня">Сегодня: <strong id="stat-today">+0</strong></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nav-actions nav-right">
|
||
<button id="theme-toggle" class="icon-btn" title="Переключить тему">🌓</button>
|
||
<button id="nav-user-profile-btn" class="user-profile-btn" title="Меню профиля и настройки">
|
||
<span class="user-avatar-icon">👤</span>
|
||
<span id="user-display-name" class="user-badge">user</span>
|
||
</button>
|
||
<button id="logout-btn" class="hidden" style="display: none;" title="Выйти из аккаунта"></button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- VIEW 1: Main Dictionary & Capture View -->
|
||
<main class="main-content" id="dictionary-view">
|
||
<!-- Search & Translation Section -->
|
||
<section class="search-section">
|
||
<div class="search-box-wrapper">
|
||
<div class="search-input-box">
|
||
<span class="search-icon">🔍</span>
|
||
<input type="text" id="term-input" placeholder="Введите слово, фразовый глагол или предложение..." autocomplete="off" autofocus>
|
||
<button id="clear-search-btn" class="clear-btn hidden" title="Очистить (Esc)">✕</button>
|
||
<button id="translate-btn" class="btn btn-primary translate-action-btn">Перевести</button>
|
||
</div>
|
||
|
||
<!-- Duplicate Warning Notification -->
|
||
<div id="duplicate-warning-box" class="duplicate-warning-box hidden">
|
||
<div class="dup-left">
|
||
<span class="dup-icon">⚠️</span>
|
||
<span class="dup-text">Это слово уже есть в вашем словаре: <strong id="dup-term-label"></strong> (<em id="dup-trans-label"></em>)</span>
|
||
</div>
|
||
<button id="dup-open-btn" class="btn btn-xs btn-outline">Посмотреть / Дополнить</button>
|
||
</div>
|
||
|
||
<div class="hotkey-hints">
|
||
<span class="hint-item"><kbd>Enter</kbd> перевод</span>
|
||
<span class="hint-item"><kbd>Ctrl</kbd>+<kbd>Enter</kbd> сохранить</span>
|
||
<span class="hint-item"><kbd>Esc</kbd> сброс</span>
|
||
<span class="hint-item"><kbd>Space</kbd> / <kbd>🔊</kbd> озвучить</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Live Translation & Dictionary Lookup Result Card -->
|
||
<div id="lookup-card" class="lookup-card hidden">
|
||
<div class="lookup-header">
|
||
<div class="lookup-term-group">
|
||
<h2 id="res-term" class="res-term">Word</h2>
|
||
<span id="res-phonetic" class="res-phonetic">/wɜːd/</span>
|
||
<span id="res-in-library" class="badge-library-star hidden" title="Это слово уже есть в вашей библиотеке">⭐ В библиотеке</span>
|
||
<button id="audio-play-btn" class="icon-btn audio-btn hidden" style="display: none;" title="Прослушать произношение">🔊</button>
|
||
</div>
|
||
<span id="res-pos" class="badge-pos">Noun</span>
|
||
</div>
|
||
|
||
<!-- English Definition if available -->
|
||
<div id="res-definition-wrap" class="definition-wrap hidden">
|
||
<div class="def-label">Толкование (EN):</div>
|
||
<div id="res-definition" class="res-definition"></div>
|
||
</div>
|
||
|
||
<!-- Primary Translation Field (Editable before saving) -->
|
||
<div class="form-group edit-translation-group">
|
||
<label for="edit-translation">Перевод на русский язык:</label>
|
||
<div class="input-with-button">
|
||
<input type="text" id="edit-translation" class="input-styled" placeholder="Русский перевод...">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Context & Extra Details Box -->
|
||
<div class="context-group">
|
||
<label for="edit-context">Контекстное предложение (где встретилось выражение):</label>
|
||
<textarea id="edit-context" class="input-styled textarea-context" rows="2" placeholder="He was reluctant to admit his mistake during the team retrospective..."></textarea>
|
||
</div>
|
||
|
||
<!-- Organization: Collection & Tags Row -->
|
||
<div class="meta-inputs-grid">
|
||
<div class="field-row">
|
||
<div class="form-group flex-1">
|
||
<label for="edit-collection">📁 Коллекция (папка):</label>
|
||
<input type="text" id="edit-collection" list="collections-datalist" class="input-styled" value="General" placeholder="General, IT, Work...">
|
||
<datalist id="collections-datalist"></datalist>
|
||
</div>
|
||
<div class="form-group flex-1">
|
||
<label for="edit-tags">🏷️ Теги (через запятую):</label>
|
||
<input type="text" id="edit-tags" class="input-styled" placeholder="#phrasal-verb, #work, #daily" value="general">
|
||
</div>
|
||
<div class="form-group flex-1">
|
||
<label for="edit-notes">💡 Заметка / Ассоциация:</label>
|
||
<input type="text" id="edit-notes" class="input-styled" placeholder="Ассоциация...">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="result-actions">
|
||
<button id="save-card-btn" class="btn btn-success btn-lg">
|
||
💾 Сохранить в словарь <span class="btn-subtext">(Ctrl + Enter)</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Vocabulary Notebook & History -->
|
||
<section class="vocabulary-section">
|
||
<div class="section-header">
|
||
<div class="section-title-wrap">
|
||
<h3>📚 Мой словарь</h3>
|
||
<span id="cards-count-label" class="cards-count-label">(0 записей)</span>
|
||
</div>
|
||
|
||
<div class="list-controls">
|
||
<button id="batch-toggle-btn" class="btn btn-sm btn-outline batch-mode-btn" title="Режим множественного выбора">
|
||
☑️ Выбрать
|
||
</button>
|
||
<div class="search-mini-box">
|
||
<input type="text" id="filter-input" placeholder="Фильтр по слову, переводу, контексту...">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Collections Filter Bar -->
|
||
<div class="collections-filter-wrap">
|
||
<div class="filter-header-bar">
|
||
<span class="filter-title">📁 Коллекции:</span>
|
||
<button id="new-collection-btn" class="btn btn-xs btn-ghost">+ Новая папка</button>
|
||
</div>
|
||
<div id="collections-filter-bar" class="filter-chips-row">
|
||
<button class="col-chip active" data-col="">Все коллекции</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Active Tags Filter -->
|
||
<div class="tags-filter-wrap">
|
||
<span class="filter-title">🏷️ Теги:</span>
|
||
<div id="tags-filter-bar" class="filter-chips-row">
|
||
<button class="filter-chip active" data-tag="">Все теги</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Cards Grid/List -->
|
||
<div id="cards-list" class="cards-list">
|
||
<div class="empty-state" id="empty-state">
|
||
<div class="empty-icon">🌱</div>
|
||
<h4>Ваш словарь пока пуст</h4>
|
||
<p>Введите первое слово или фразу в поле поиска выше и сохраните её!</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- VIEW 2: SRS Trainer Interactive View -->
|
||
<section id="srs-view" class="srs-view hidden">
|
||
<!-- SRS Top Bar -->
|
||
<header class="srs-topbar">
|
||
<div class="srs-topbar-left">
|
||
<button id="srs-exit-btn" class="btn btn-sm btn-outline">← В словарь</button>
|
||
<div class="srs-mode-switch">
|
||
<button class="srs-tab active" data-mode="flashcards">📇 Карточки</button>
|
||
<button class="srs-tab" data-mode="quiz">🎯 4 Варианта</button>
|
||
<button class="srs-tab" data-mode="typing">✍️ Набор слова</button>
|
||
<button class="srs-tab" data-mode="cloze">🧩 Пропуски</button>
|
||
<button class="srs-tab" data-mode="dictation">🎧 Диктант</button>
|
||
<button class="srs-tab" data-mode="listening">📻 Аудирование</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="srs-topbar-center">
|
||
<div class="srs-progress-container">
|
||
<div id="srs-progress-fill" class="srs-progress-fill" style="width: 0%;"></div>
|
||
</div>
|
||
<span id="srs-counter" class="srs-counter">Карточка 0 из 0</span>
|
||
</div>
|
||
|
||
<div class="srs-topbar-right">
|
||
<button id="srs-jump-cefr-btn" class="btn btn-sm btn-outline" title="Пройти уровневый тест CEFR (A1–B2)">
|
||
<span>🎯 Тесты CEFR</span>
|
||
</button>
|
||
<button id="srs-mix-btn" class="btn btn-sm btn-ghost" title="Умный микс дня: 10 новых + 10 повторов + 5 трудных слов">
|
||
<span id="srs-mix-label">🎲 Микс дня: ВКЛ</span>
|
||
</button>
|
||
<button id="srs-dir-btn" class="btn btn-sm btn-secondary" title="Сменить направление">
|
||
<span id="srs-dir-label">EN ➔ RU</span> ⇄
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- SRS Main Interactive Arena -->
|
||
<div class="srs-arena">
|
||
<!-- Loading State -->
|
||
<div id="srs-loading" class="srs-state-box hidden">
|
||
<div class="spinner"></div>
|
||
<p>Загрузка карточек для тренировки...</p>
|
||
</div>
|
||
|
||
<!-- Empty State -->
|
||
<div id="srs-empty" class="srs-state-box hidden">
|
||
<div class="srs-big-icon">🎉</div>
|
||
<h3>На сегодня всё повторено!</h3>
|
||
<p>В очереди нет слов, требующих интервального повторения.</p>
|
||
<div class="srs-empty-buttons">
|
||
<button id="srs-train-all-btn" class="btn btn-primary btn-lg">Тренировать все слова вне очереди</button>
|
||
<button id="srs-empty-back-btn" class="btn btn-outline btn-lg">Вернуться в словарь</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODE 1: Flashcards -->
|
||
<div id="srs-mode-flashcards" class="srs-mode-container hidden">
|
||
<div class="flashcard-wrapper" id="flashcard-flip-wrap">
|
||
<div class="flashcard-inner" id="flashcard-inner">
|
||
<!-- Card Front -->
|
||
<div class="flashcard-face flashcard-front" id="flashcard-front">
|
||
<div class="fc-badge-row">
|
||
<span class="fc-dir-badge" id="fc-front-dir-badge">EN ➔ RU</span>
|
||
<span class="fc-pos-badge" id="fc-front-pos">Adjective</span>
|
||
</div>
|
||
<div class="fc-center">
|
||
<h1 class="fc-main-term" id="fc-front-main">reluctant</h1>
|
||
<div class="fc-phonetic-row" id="fc-front-phonetic-wrap">
|
||
<span class="res-phonetic" id="fc-front-phonetic">/rɪˈlʌktənt/</span>
|
||
<button id="fc-front-audio-btn" class="icon-btn audio-round-btn" style="display: none;" title="Озвучить (Ctrl+P / 🔊)">🔊</button>
|
||
</div>
|
||
<div class="fc-hint-wrapper">
|
||
<button id="fc-hint-btn" class="btn btn-xs btn-ghost">💡 Показать контекст</button>
|
||
<div id="fc-hint-box" class="fc-hint-content hidden"></div>
|
||
</div>
|
||
</div>
|
||
<div class="fc-footer-hint">
|
||
<kbd>Space</kbd> или клик по карточке — перевернуть
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Card Back -->
|
||
<div class="flashcard-face flashcard-back" id="flashcard-back">
|
||
<div class="fc-badge-row">
|
||
<span class="fc-dir-badge">ОТВЕТ</span>
|
||
<span class="fc-pos-badge" id="fc-back-pos">Adjective</span>
|
||
</div>
|
||
<div class="fc-back-content">
|
||
<div class="fc-back-top">
|
||
<h2 class="fc-back-term" id="fc-back-term">reluctant</h2>
|
||
<button id="fc-back-audio-btn" class="icon-btn audio-round-btn" style="display: none;" title="Озвучить">🔊</button>
|
||
</div>
|
||
<div class="fc-back-translation" id="fc-back-translation">неохотный, нежелающий</div>
|
||
<div class="fc-back-detail-box" id="fc-back-def-box">
|
||
<span class="detail-label">Толкование:</span>
|
||
<p id="fc-back-def" class="detail-text"></p>
|
||
</div>
|
||
<div class="fc-back-detail-box" id="fc-back-context-box">
|
||
<div class="fc-detail-header-row" style="display: flex; align-items: center; justify-content: space-between;">
|
||
<span class="detail-label">Контекст:</span>
|
||
<button type="button" id="fc-back-context-audio-btn" class="icon-btn audio-xs-btn" title="Озвучить предложение контекста">🔊</button>
|
||
</div>
|
||
<p id="fc-back-context" class="detail-text"></p>
|
||
</div>
|
||
<div class="fc-back-detail-box" id="fc-back-notes-box">
|
||
<span class="detail-label">Заметка:</span>
|
||
<p id="fc-back-notes" class="detail-text"></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Flip button (mobile accessible) -->
|
||
<div id="fc-flip-btn-wrap" class="fc-flip-btn-wrap">
|
||
<button id="fc-flip-btn" class="btn btn-primary btn-block btn-lg">Показать ответ (Space)</button>
|
||
</div>
|
||
|
||
<!-- Rating Buttons -->
|
||
<div id="fc-rating-bar" class="srs-rating-bar hidden">
|
||
<button class="btn-rate btn-rate-1" data-rating="1" title="Горячая клавиша: 1">
|
||
<span class="rate-key">[1]</span>
|
||
<span class="rate-name">Снова</span>
|
||
<span class="rate-time">< 1 мин</span>
|
||
</button>
|
||
<button class="btn-rate btn-rate-2" data-rating="2" title="Горячая клавиша: 2">
|
||
<span class="rate-key">[2]</span>
|
||
<span class="rate-name">Трудно</span>
|
||
<span class="rate-time">1 день</span>
|
||
</button>
|
||
<button class="btn-rate btn-rate-3" data-rating="3" title="Горячая клавиша: 3">
|
||
<span class="rate-key">[3]</span>
|
||
<span class="rate-name">Хорошо</span>
|
||
<span class="rate-time">3 дня</span>
|
||
</button>
|
||
<button class="btn-rate btn-rate-4" data-rating="4" title="Горячая клавиша: 4">
|
||
<span class="rate-key">[4]</span>
|
||
<span class="rate-name">Легко</span>
|
||
<span class="rate-time">7 дней</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODE 2: Multiple Choice Quiz (4 options) -->
|
||
<div id="srs-mode-quiz" class="srs-mode-container hidden">
|
||
<div class="trainer-card quiz-card">
|
||
<div class="trainer-header">
|
||
<span class="mode-tag">🎯 Выбор из 4 вариантов</span>
|
||
<span class="trainer-pos" id="quiz-pos"></span>
|
||
</div>
|
||
|
||
<div class="quiz-hero">
|
||
<div class="quiz-prompt-row">
|
||
<h2 id="quiz-term-display" class="quiz-term-display">word</h2>
|
||
<button id="quiz-audio-btn" class="icon-btn audio-round-btn" style="display: none;" title="Озвучить">🔊</button>
|
||
</div>
|
||
<div id="quiz-phonetic-display" class="res-phonetic"></div>
|
||
<div id="quiz-context-hint" class="quiz-context-hint hidden"></div>
|
||
</div>
|
||
|
||
<div class="quiz-options-grid" id="quiz-options-grid">
|
||
<!-- 4 option buttons generated dynamically -->
|
||
</div>
|
||
|
||
<div id="quiz-feedback-box" class="trainer-feedback-box hidden"></div>
|
||
<div id="quiz-details-box" class="trainer-revealed-details hidden"></div>
|
||
|
||
<div id="quiz-next-bar" class="quiz-next-bar hidden">
|
||
<button id="quiz-next-btn" class="btn btn-primary btn-lg btn-block">Следующее слово (Enter / Space)</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODE 3: Active Typing Mode (Ru -> En) -->
|
||
<div id="srs-mode-typing" class="srs-mode-container hidden">
|
||
<div class="trainer-card">
|
||
<div class="trainer-header">
|
||
<span class="mode-tag">✍️ Набор слова на английском</span>
|
||
<span class="trainer-pos" id="typing-pos"></span>
|
||
</div>
|
||
|
||
<div class="typing-hero">
|
||
<span class="hint-label">Переведите на английский язык:</span>
|
||
<h2 id="typing-prompt-ru" class="typing-prompt-ru">слово</h2>
|
||
<div id="typing-context-hint" class="typing-context-hint hidden"></div>
|
||
</div>
|
||
|
||
<form id="typing-form" class="trainer-form">
|
||
<div class="input-action-row">
|
||
<input type="text" id="typing-input" class="input-styled input-hero" placeholder="Напечатайте английское слово или связку..." autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus>
|
||
<button type="submit" id="typing-submit-btn" class="btn btn-primary">Проверить</button>
|
||
</div>
|
||
</form>
|
||
|
||
<div id="typing-feedback-box" class="trainer-feedback-box hidden"></div>
|
||
<div id="typing-details-box" class="trainer-revealed-details hidden"></div>
|
||
|
||
<!-- Rating bar for typing -->
|
||
<div id="typing-rating-bar" class="srs-rating-bar hidden"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODE 4: Cloze Deletion -->
|
||
<div id="srs-mode-cloze" class="srs-mode-container hidden">
|
||
<div class="trainer-card">
|
||
<div class="trainer-header">
|
||
<span class="mode-tag">🧩 Пропуски в контексте</span>
|
||
<span class="trainer-pos" id="cloze-pos"></span>
|
||
</div>
|
||
|
||
<div class="cloze-sentence-display" id="cloze-sentence-display">
|
||
The switch <span class="gap-placeholder">_____</span> the frame if invalid.
|
||
</div>
|
||
|
||
<div class="cloze-translation-hint">
|
||
<span class="hint-label">Перевод целевого слова:</span>
|
||
<strong id="cloze-target-translation">неохотный</strong>
|
||
</div>
|
||
|
||
<form id="cloze-form" class="trainer-form">
|
||
<div class="input-action-row">
|
||
<input type="text" id="cloze-input" class="input-styled input-hero" placeholder="Введите пропущенное слово..." autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus>
|
||
<button type="submit" id="cloze-submit-btn" class="btn btn-primary">Проверить</button>
|
||
</div>
|
||
</form>
|
||
|
||
<div id="cloze-feedback-box" class="trainer-feedback-box hidden"></div>
|
||
<div id="cloze-details-box" class="trainer-revealed-details hidden"></div>
|
||
|
||
<!-- Rating bar for cloze -->
|
||
<div id="cloze-rating-bar" class="srs-rating-bar hidden"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODE 5: Audio Dictation -->
|
||
<div id="srs-mode-dictation" class="srs-mode-container hidden">
|
||
<div class="trainer-card">
|
||
<div class="trainer-header">
|
||
<span class="mode-tag">🎧 Аудио-диктант</span>
|
||
<button id="dictation-replay-btn" class="btn btn-sm btn-ghost audio-replay-btn">
|
||
🔊 Повторить звук <span class="kbd-sub"><kbd>Space</kbd></span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="dictation-hero">
|
||
<button id="dictation-big-play-btn" class="dictation-pulse-btn" title="Слушать произношение">
|
||
🔊
|
||
</button>
|
||
<p class="dictation-instructions">Слушайте произношение нативного диктора и напечатайте слово</p>
|
||
</div>
|
||
|
||
<div class="dictation-hint-wrap">
|
||
<button id="dictation-toggle-hint-btn" class="btn btn-xs btn-ghost">💡 Показать перевод-подсказку</button>
|
||
<span id="dictation-hint-text" class="dictation-hint-text hidden"></span>
|
||
</div>
|
||
|
||
<form id="dictation-form" class="trainer-form">
|
||
<div class="input-action-row">
|
||
<input type="text" id="dictation-input" class="input-styled input-hero" placeholder="Напечатайте услышанное слово на английском..." autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus>
|
||
<button type="submit" id="dictation-submit-btn" class="btn btn-primary">Проверить</button>
|
||
</div>
|
||
</form>
|
||
|
||
<div id="dictation-feedback-box" class="trainer-feedback-box hidden"></div>
|
||
<div id="dictation-details-box" class="trainer-revealed-details hidden"></div>
|
||
|
||
<!-- Rating bar for dictation -->
|
||
<div id="dictation-rating-bar" class="srs-rating-bar hidden"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODE 6: Listening Comprehension Q&A -->
|
||
<div id="srs-mode-listening" class="srs-mode-container hidden">
|
||
<div class="trainer-card listening-card">
|
||
<div class="trainer-header listening-header-row">
|
||
<div class="listening-tag-wrap">
|
||
<span class="mode-tag">📻 Аудирование & Вопросы</span>
|
||
<span id="listening-level-badge" class="level-badge badge-b1">B1</span>
|
||
<span id="listening-topic-badge" class="topic-badge">Tech</span>
|
||
</div>
|
||
<div class="listening-filters">
|
||
<select id="listening-topic-select" class="select-styled select-xs" title="Выбрать тему">
|
||
<option value="all">🌐 Все темы</option>
|
||
<option value="tech">💻 Технологии & IT</option>
|
||
<option value="daily">☕ Повседневная жизнь</option>
|
||
<option value="travel">✈️ Путешествия</option>
|
||
<option value="science">🔬 Наука</option>
|
||
<option value="business">💼 Работа & Бизнес</option>
|
||
<option value="cards">📚 Мои слова из словаря</option>
|
||
</select>
|
||
<select id="listening-voice-select" class="select-styled select-xs" title="Голос английского диктора">
|
||
<option value="en_US-lessac">👩 Paula (US)</option>
|
||
<option value="en_US-ryan">👨 Ryan (US)</option>
|
||
<option value="en_GB-alan">👨 Alan (UK)</option>
|
||
</select>
|
||
<select id="listening-speed-select" class="select-styled select-xs" title="Скорость речи">
|
||
<option value="1.0">⚡ 1.0x</option>
|
||
<option value="0.75">🐢 0.75x</option>
|
||
<option value="1.25">🚀 1.25x</option>
|
||
</select>
|
||
<button type="button" id="listening-new-scenario-btn" class="btn btn-xs btn-outline" title="Загрузить другую ситуацию">
|
||
🔄 Другая история
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="listening-hero">
|
||
<div class="listening-title-box">
|
||
<h3 id="listening-title" class="listening-scenario-title">Загрузка аудио-ситуации...</h3>
|
||
<p class="listening-subtitle">Прослушайте аудио на английском и ответьте на вопрос диктора</p>
|
||
</div>
|
||
|
||
<div class="listening-audio-controls">
|
||
<div class="audio-control-card">
|
||
<div class="audio-control-label">1. Аудио-история (контекст):</div>
|
||
<button type="button" id="listening-play-story-btn" class="btn btn-primary btn-md listening-play-btn">
|
||
🔊 Слушать историю <span class="kbd-sub"><kbd>Space</kbd></span>
|
||
</button>
|
||
</div>
|
||
<div class="audio-control-card">
|
||
<div class="audio-control-label">2. Вопрос от диктора:</div>
|
||
<button type="button" id="listening-play-question-btn" class="btn btn-outline btn-md listening-play-btn">
|
||
❓ Слушать вопрос
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="listening-hint-bar">
|
||
<button type="button" id="listening-toggle-hint-btn" class="btn btn-xs btn-ghost">💡 Подсказка к вопросу</button>
|
||
<span id="listening-hint-text" class="listening-hint-text hidden"></span>
|
||
</div>
|
||
|
||
<form id="listening-form" class="trainer-form listening-form">
|
||
<div class="input-action-row">
|
||
<input type="text" id="listening-input" class="input-styled input-hero" placeholder="Напишите ответ на английском по услышанному..." autocomplete="off" spellcheck="false" autofocus>
|
||
<button type="submit" id="listening-submit-btn" class="btn btn-primary">Проверить ответ</button>
|
||
</div>
|
||
</form>
|
||
|
||
<div id="listening-feedback-box" class="trainer-feedback-box hidden"></div>
|
||
|
||
<div id="listening-revealed-box" class="listening-revealed-card hidden">
|
||
<div class="revealed-section">
|
||
<span class="revealed-label">🎯 Образцовый ответ:</span>
|
||
<strong id="listening-ideal-answer" class="revealed-val text-success"></strong>
|
||
</div>
|
||
<div class="revealed-section">
|
||
<span class="revealed-label">📖 Вопрос (текст):</span>
|
||
<p id="listening-revealed-question" class="revealed-text"></p>
|
||
<small id="listening-revealed-question-ru" class="text-muted"></small>
|
||
</div>
|
||
<div class="revealed-section">
|
||
<span class="revealed-label">📜 Полный текст истории:</span>
|
||
<p id="listening-revealed-story" class="revealed-text"></p>
|
||
<small id="listening-revealed-story-ru" class="text-muted"></small>
|
||
</div>
|
||
<div class="listening-next-bar">
|
||
<button type="button" id="listening-next-btn" class="btn btn-primary btn-md">
|
||
Следующая ситуация ➔ <span class="kbd-sub"><kbd>Enter</kbd></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Session Complete Summary Screen -->
|
||
<div id="srs-summary" class="srs-summary-card hidden">
|
||
<div class="summary-trophy">🏆</div>
|
||
<h2>Сессия завершена!</h2>
|
||
<p class="summary-lead">Вы успешно закрепили знания и освежили долговременную память.</p>
|
||
|
||
<div class="summary-metrics">
|
||
<div class="metric-card">
|
||
<span class="metric-val" id="sum-count">0</span>
|
||
<span class="metric-desc">Повторено слов</span>
|
||
</div>
|
||
<div class="metric-card">
|
||
<span class="metric-val text-success" id="sum-retention">100%</span>
|
||
<span class="metric-desc">Успешность (Хорошо/Легко)</span>
|
||
</div>
|
||
<div class="metric-card">
|
||
<span class="metric-val text-primary" id="sum-streak">🔥 1</span>
|
||
<span class="metric-desc">Серия дней</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="summary-rates-bar" id="sum-rates-breakdown"></div>
|
||
|
||
<div class="summary-buttons">
|
||
<button id="sum-repeat-btn" class="btn btn-primary btn-lg">🔄 Повторить ещё сессию</button>
|
||
<button id="sum-return-btn" class="btn btn-outline btn-lg">📚 Вернуться в словарь</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VIEW 3: Interactive Reader & Bookshelf View -->
|
||
<section id="reader-view" class="reader-view hidden">
|
||
<!-- Bookshelf View -->
|
||
<div id="bookshelf-container" class="bookshelf-container">
|
||
<div class="bookshelf-header">
|
||
<div class="bookshelf-title-wrap">
|
||
<h2>📚 Библиотека & Интерактивная Читалка</h2>
|
||
<p class="subtitle">Читайте тексты и книги с мгновенным клик-переводом, озвучкой и авто-захватом контекста</p>
|
||
</div>
|
||
<div class="bookshelf-actions">
|
||
<button id="add-text-btn" class="btn btn-outline">✏️ Вставить текст</button>
|
||
<label for="book-file-input" class="btn btn-primary file-upload-label">
|
||
📁 Загрузить EPUB / PDF / TXT
|
||
<input type="file" id="book-file-input" accept=".epub,.pdf,.txt,.md" style="display: none;">
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Bookshelf Grid / Empty -->
|
||
<div id="bookshelf-empty" class="empty-state hidden">
|
||
<div class="empty-icon">📖</div>
|
||
<h3>Ваша библиотека пуста</h3>
|
||
<p>Загрузите книгу в формате EPUB или PDF, текстовый файл TXT/MD или вставьте текст статьи, чтобы начать интерактивное чтение.</p>
|
||
</div>
|
||
<div id="bookshelf-grid" class="bookshelf-grid"></div>
|
||
|
||
<!-- Divider between General Books & Wikipedia Section -->
|
||
<hr class="bookshelf-divider">
|
||
|
||
<!-- Wikipedia Articles Section -->
|
||
<div id="wiki-section" class="wiki-section">
|
||
<div class="wiki-header">
|
||
<div class="wiki-title-wrap">
|
||
<div class="wiki-title-row">
|
||
<span class="wiki-icon-badge">🌐</span>
|
||
<div>
|
||
<h3 class="wiki-heading">Статьи Википедии (Wikipedia Reader)</h3>
|
||
<p class="subtitle">Автономное чтение статей Simple и Standard Wikipedia с иллюстрациями, таблицами и клик-переводом</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Wikipedia Action Bar & Current Settings Badges -->
|
||
<div class="wiki-action-box">
|
||
<div class="wiki-primary-actions">
|
||
<button type="button" id="wiki-read-btn" class="btn btn-primary wiki-read-btn">
|
||
<span>📖 Читать статью</span>
|
||
</button>
|
||
<button type="button" id="wiki-settings-btn" class="btn btn-outline wiki-settings-btn" title="Настроить сложность, объем и тематику статьи">
|
||
<span>⚙️ Настройки</span>
|
||
</button>
|
||
</div>
|
||
<div class="wiki-badges-row">
|
||
<span class="wiki-badges-label">Текущие фильтры:</span>
|
||
<span id="wiki-active-lang-badge" class="badge-chip wiki-badge-chip">Simple English (A2–B1)</span>
|
||
<span id="wiki-active-time-badge" class="badge-chip wiki-badge-chip">⏱️ ~10-15 мин</span>
|
||
<span id="wiki-active-topic-badge" class="badge-chip wiki-badge-chip">🎲 Любая тема</span>
|
||
</div>
|
||
<div id="wiki-fetch-status" class="wiki-fetch-status hidden"></div>
|
||
</div>
|
||
|
||
<!-- Wikipedia Articles Grid / Empty State -->
|
||
<div id="wiki-empty-state" class="empty-state wiki-empty-state hidden">
|
||
<div class="empty-icon">🌐</div>
|
||
<h4>Нет сохраненных статей из Википедии</h4>
|
||
<p>Нажмите «Читать статью» выше, чтобы подобрать случайную познавательную статью по вашим настройкам, или настройте тему и объем через шестерёнку ⚙️.</p>
|
||
</div>
|
||
<div id="wiki-grid" class="bookshelf-grid wiki-grid"></div>
|
||
</div>
|
||
|
||
<!-- Divider between Wikipedia & RFC Specifications -->
|
||
<hr class="bookshelf-divider">
|
||
|
||
<!-- RFC Specifications Section -->
|
||
<div id="rfc-section" class="rfc-section">
|
||
<div class="rfc-header">
|
||
<div class="rfc-title-wrap">
|
||
<div class="rfc-title-row">
|
||
<span class="rfc-icon-badge">🌐</span>
|
||
<div>
|
||
<h3 class="rfc-heading">Спецификации IETF & RFC Editor</h3>
|
||
<p class="subtitle">Интерактивное чтение официальных стандартов интернета на английском с клик-переводом и авто-словарем</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- RFC Fetch Form & Preset Chips -->
|
||
<div class="rfc-fetch-box">
|
||
<form id="rfc-fetch-form" class="rfc-fetch-form">
|
||
<div class="rfc-input-wrap">
|
||
<span class="rfc-input-prefix">RFC</span>
|
||
<input type="text" id="rfc-input" class="input-styled rfc-input" placeholder="Номер (напр. 9110, 7540, 8446, 6749) или URL rfc-editor.org" autocomplete="off" spellcheck="false">
|
||
<button type="submit" id="rfc-fetch-btn" class="btn btn-primary rfc-fetch-btn">
|
||
<span>⚡ Загрузить RFC</span>
|
||
</button>
|
||
</div>
|
||
<div id="rfc-fetch-status" class="rfc-fetch-status hidden"></div>
|
||
</form>
|
||
|
||
<div class="rfc-presets-wrap">
|
||
<span class="rfc-presets-label">Популярные стандарты:</span>
|
||
<div class="rfc-presets-list">
|
||
<button type="button" class="rfc-preset-chip" data-rfc="9110" title="HTTP Semantics (RFC 9110)">🌐 HTTP/1.1 (9110)</button>
|
||
<button type="button" class="rfc-preset-chip" data-rfc="7540" title="HTTP/2 (RFC 7540)">⚡ HTTP/2 (7540)</button>
|
||
<button type="button" class="rfc-preset-chip" data-rfc="9000" title="QUIC Transport Protocol (RFC 9000)">🚀 QUIC (9000)</button>
|
||
<button type="button" class="rfc-preset-chip" data-rfc="8446" title="TLS Protocol 1.3 (RFC 8446)">🔒 TLS 1.3 (8446)</button>
|
||
<button type="button" class="rfc-preset-chip" data-rfc="6749" title="OAuth 2.0 Authorization Framework (RFC 6749)">🔑 OAuth 2.0 (6749)</button>
|
||
<button type="button" class="rfc-preset-chip" data-rfc="6455" title="The WebSocket Protocol (RFC 6455)">🔌 WebSocket (6455)</button>
|
||
<button type="button" class="rfc-preset-chip" data-rfc="793" title="Transmission Control Protocol (RFC 793)">📡 TCP (793)</button>
|
||
<button type="button" class="rfc-preset-chip" data-rfc="1035" title="Domain Names Implementation (RFC 1035)">🧭 DNS (1035)</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- RFC Books Grid / Empty State -->
|
||
<div id="rfc-empty-state" class="empty-state rfc-empty-state hidden">
|
||
<div class="empty-icon">📜</div>
|
||
<h4>Нет сохраненных RFC спецификаций</h4>
|
||
<p>Введите номер стандарта выше или нажмите на одну из быстрых кнопок, чтобы разобрать спецификацию на главы и читать в интерактивном режиме.</p>
|
||
</div>
|
||
<div id="rfc-grid" class="bookshelf-grid rfc-grid"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Reading Interface (Active when a book is open) -->
|
||
<div id="reader-interface" class="reader-interface hidden">
|
||
<header class="reader-toolbar">
|
||
<div class="reader-toolbar-left">
|
||
<button id="reader-back-btn" class="btn btn-sm btn-outline">← Библиотека</button>
|
||
<div class="reader-meta">
|
||
<h3 id="reader-book-title" class="reader-title">Книга</h3>
|
||
<span id="reader-book-author" class="reader-author">Автор</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="reader-toolbar-center">
|
||
<button id="reader-prev-ch-btn" class="btn btn-xs btn-outline" title="Предыдущая глава">◀</button>
|
||
<select id="reader-chapter-select" class="reader-select"></select>
|
||
<button id="reader-next-ch-btn" class="btn btn-xs btn-outline" title="Следующая глава">▶</button>
|
||
<span id="reader-scroll-pct-badge" class="reader-progress-badge" title="Прогресс чтения главы">0%</span>
|
||
</div>
|
||
|
||
<div class="reader-toolbar-right">
|
||
<button id="reader-settings-btn" class="btn btn-xs btn-outline reader-settings-btn" title="Настройки оформления текста (шрифт, поля, тема)">
|
||
<span style="font-weight: 700; font-family: serif; font-size: 13px;">Aa</span>
|
||
<span class="btn-subtext-inline">Шрифт</span>
|
||
</button>
|
||
<button id="reader-zen-btn" class="btn btn-xs btn-outline reader-zen-btn" title="Фокус-режим чтения (Zen Mode, клавиша F)">
|
||
<span>🧘</span>
|
||
<span class="btn-subtext-inline">Фокус</span>
|
||
</button>
|
||
<button id="reader-toggle-highlight-btn" class="btn btn-xs btn-outline" title="Вкл/Выкл подсветку изучаемых слов">✨ Подсветка</button>
|
||
<button id="reader-train-btn" class="btn btn-xs btn-trainer" title="Тренировать слова из этой книги">🎓 Слова книги</button>
|
||
</div>
|
||
|
||
<div id="reader-chapter-progress-bar" class="reader-chapter-progress-bar">
|
||
<div id="reader-chapter-progress-fill" class="reader-chapter-progress-fill" style="width: 0%;"></div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Floating Zen HUD (Discreet, auto-fading, fixed in top-right) -->
|
||
<div id="reader-zen-hud" class="reader-zen-hud hidden">
|
||
<div class="zen-hud-content">
|
||
<span id="zen-hud-title" class="zen-hud-title">Книга</span>
|
||
<span class="zen-hud-sep">•</span>
|
||
<span id="zen-hud-chapter" class="zen-hud-chapter">Глава 1</span>
|
||
<span class="zen-hud-sep">•</span>
|
||
<span id="zen-hud-progress" class="zen-hud-progress">0%</span>
|
||
<button type="button" id="zen-hud-exit-btn" class="zen-hud-exit-btn" title="Выйти из фокус-режима (Esc или F)">✕</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Reading Container -->
|
||
<div class="reader-scroll-area" id="reader-scroll-area">
|
||
<div class="reader-content-body" id="reader-content-body">
|
||
<!-- Interactive paragraphs dynamically rendered here -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VIEW 4: CEFR Level Tests View -->
|
||
<section id="cefr-view" class="cefr-view hidden">
|
||
<!-- Screen 1: Level Overview & Selection -->
|
||
<div id="cefr-overview-screen" class="cefr-overview-container">
|
||
<div class="cefr-header">
|
||
<div class="cefr-title-wrap">
|
||
<h2>🎯 Уровневые тесты CEFR (A1 – B2)</h2>
|
||
<p class="subtitle">Эталонные тесты по международной шкале Oxford 3000/5000. Ошибки автоматически добавляются в ваш личный тренажёр SRS со статусом «В процессе»!</p>
|
||
</div>
|
||
<div class="cefr-header-actions">
|
||
<button type="button" id="cefr-mine-books-btn" class="btn btn-secondary">
|
||
⚡ Собрать тесты из книг
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Active Background Task Banner -->
|
||
<div id="cefr-task-banner" class="cefr-task-banner hidden"></div>
|
||
|
||
<div id="cefr-levels-grid" class="cefr-levels-grid">
|
||
<!-- Dynamic level cards rendered by cefr.js -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Screen 2: Active Cloze Tap Quiz -->
|
||
<div id="cefr-quiz-screen" class="cefr-quiz-container hidden">
|
||
<header class="cefr-quiz-topbar">
|
||
<div class="cefr-quiz-topbar-left">
|
||
<button id="cefr-back-btn" class="btn btn-sm btn-outline">← К уровням</button>
|
||
<span id="cefr-quiz-level-badge" class="level-pill">Уровень A1</span>
|
||
</div>
|
||
<div class="cefr-quiz-topbar-center">
|
||
<div class="srs-progress-container">
|
||
<div id="cefr-quiz-progress-bar" class="srs-progress-fill" style="width: 0%;"></div>
|
||
</div>
|
||
<span id="cefr-quiz-counter" class="srs-counter">1 / 10</span>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="cefr-quiz-card-wrapper">
|
||
<div id="cefr-cloze-card" class="cefr-cloze-card">
|
||
<!-- Dynamic question content rendered by cefr.js -->
|
||
</div>
|
||
|
||
<div id="cefr-next-bar" class="cefr-next-bar hidden">
|
||
<button id="cefr-next-btn" class="btn btn-primary btn-lg btn-block">Следующий вопрос → (Space)</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Screen 3: Quiz Session Summary -->
|
||
<div id="cefr-summary-screen" class="cefr-summary-container hidden">
|
||
<div class="cefr-summary-card">
|
||
<div class="summary-trophy">🏆</div>
|
||
<h2>Тест завершён!</h2>
|
||
<p id="cefr-sum-lead" class="summary-lead">Отличная работа по проверке словарного запаса.</p>
|
||
|
||
<div class="summary-metrics">
|
||
<div class="metric-card">
|
||
<span class="metric-val text-primary" id="cefr-sum-score">0%</span>
|
||
<span class="metric-desc">Точность</span>
|
||
</div>
|
||
<div class="metric-card">
|
||
<span class="metric-val text-success" id="cefr-sum-correct">0 / 0</span>
|
||
<span class="metric-desc">Правильно</span>
|
||
</div>
|
||
<div class="metric-card">
|
||
<span class="metric-val text-warning" id="cefr-sum-mistakes">0</span>
|
||
<span class="metric-desc">Ошибок</span>
|
||
</div>
|
||
<div class="metric-card">
|
||
<span class="metric-val text-danger" id="cefr-sum-ingested">0</span>
|
||
<span class="metric-desc">Добавлено в SRS</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="summary-buttons">
|
||
<button id="cefr-sum-repeat-btn" class="btn btn-primary btn-lg">🔄 Ещё 10 вопросов</button>
|
||
<button id="cefr-sum-srs-btn" class="btn btn-outline btn-lg hidden">🎓 Закрепить ошибки в SRS</button>
|
||
<button id="cefr-sum-levels-btn" class="btn btn-ghost btn-lg">← К списку уровней</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VIEW 5: Murphy Grammar Engine & Handwritten Journaling View -->
|
||
<section id="grammar-view" class="grammar-view hidden">
|
||
<!-- Screen 1: Units Directory -->
|
||
<div id="grammar-directory-screen" class="grammar-directory-container">
|
||
<div class="grammar-header">
|
||
<div class="grammar-title-wrap">
|
||
<h2>📖 Грамматика Мерфи (Essential & English Grammar)</h2>
|
||
<p class="subtitle">Вечерний режим глубокой фокусировки: 5–7 минутные микро-уроки, метод контрастов, золотые формулы для бумажной тетради и мгновенное закрепление в SRS при ошибках.</p>
|
||
</div>
|
||
<div class="grammar-top-stats">
|
||
<div class="grammar-stat-chip">
|
||
<span class="stat-num" id="grammar-stat-total">0</span>
|
||
<span class="stat-lbl">Юнитов</span>
|
||
</div>
|
||
<div class="grammar-stat-chip">
|
||
<span class="stat-num" id="grammar-stat-completed">0</span>
|
||
<span class="stat-lbl">Освоено</span>
|
||
</div>
|
||
<div class="grammar-stat-chip">
|
||
<span class="stat-num" id="grammar-stat-handwritten">0</span>
|
||
<span class="stat-lbl">✍️ В тетради</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Filter Pills -->
|
||
<div class="grammar-filter-bar">
|
||
<button class="grammar-filter-pill active" data-filter="all">Все юниты</button>
|
||
<button class="grammar-filter-pill" data-filter="A1-A2">A1–A2 (Красный Мерфи)</button>
|
||
<button class="grammar-filter-pill" data-filter="B1-B2">B1–B2 (Синий Мерфи)</button>
|
||
<button class="grammar-filter-pill" data-filter="Present">Present Tenses</button>
|
||
<button class="grammar-filter-pill" data-filter="Past">Past Tenses</button>
|
||
<button class="grammar-filter-pill" data-filter="Future">Future Forms</button>
|
||
<button class="grammar-filter-pill" data-filter="Modals">Modals</button>
|
||
<button class="grammar-filter-pill" data-filter="Conditionals">Conditionals</button>
|
||
<button class="grammar-filter-pill" data-filter="Passive">Passive</button>
|
||
<button class="grammar-filter-pill" data-filter="Gerund">Gerund & Inf</button>
|
||
<button class="grammar-filter-pill" data-filter="handwritten">✍️ Записано в тетрадь</button>
|
||
</div>
|
||
|
||
<!-- Units Grid -->
|
||
<div id="grammar-units-grid" class="grammar-units-grid">
|
||
<!-- Dynamic unit cards rendered by grammar.js -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Screen 2: Active Lesson & Practice -->
|
||
<div id="grammar-lesson-screen" class="grammar-lesson-container hidden">
|
||
<header class="grammar-lesson-topbar">
|
||
<div class="grammar-topbar-left">
|
||
<button id="grammar-back-btn" class="btn btn-sm btn-outline">← К юнитам</button>
|
||
<div class="grammar-lesson-badges">
|
||
<span id="grammar-lesson-num" class="grammar-unit-pill">Юнит 1</span>
|
||
<span id="grammar-lesson-level" class="grammar-level-pill badge-a1">A1-A2</span>
|
||
</div>
|
||
</div>
|
||
<div class="grammar-topbar-center">
|
||
<div class="grammar-tab-switch">
|
||
<button id="grammar-tab-theory-btn" class="tab-btn active">1. Теория и Тетрадь</button>
|
||
<button id="grammar-tab-practice-btn" class="tab-btn">2. Микро-практика (5 тап-заданий)</button>
|
||
</div>
|
||
</div>
|
||
<div class="grammar-topbar-right">
|
||
<span id="grammar-lesson-cat" class="grammar-cat-label">Present Tenses</span>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="grammar-lesson-content-wrap">
|
||
<!-- Tab 1 Content: Theory & Handwritten Journaling -->
|
||
<div id="grammar-tab-theory-content" class="grammar-tab-content">
|
||
<div class="grammar-theory-header">
|
||
<h2 id="grammar-lesson-title" class="lesson-main-title">Unit Title</h2>
|
||
<p id="grammar-lesson-sub" class="lesson-sub-title">Unit Subtitle</p>
|
||
</div>
|
||
|
||
<!-- Cheatsheet Markdown Table -->
|
||
<div id="grammar-cheatsheet-section" class="grammar-section-block">
|
||
<h3 class="section-title"><span class="title-icon">📊</span> Наглядная шпаргалка и правила (Таблица)</h3>
|
||
<div id="grammar-cheatsheet-content"></div>
|
||
</div>
|
||
|
||
<!-- Detailed Murphy Notes -->
|
||
<div id="grammar-detailed-notes-section" class="grammar-section-block">
|
||
<h3 class="section-title"><span class="title-icon">📖</span> Подробный конспект темы (Raymond Murphy)</h3>
|
||
<div id="grammar-detailed-notes-content"></div>
|
||
</div>
|
||
|
||
<!-- Contrast Explanation Cards -->
|
||
<div class="grammar-section-block">
|
||
<h3 class="section-title"><span class="title-icon">⚖️</span> Метод контрастов (В чём суть и когда применять)</h3>
|
||
<div id="grammar-contrasts-list" class="grammar-contrasts-list">
|
||
<!-- Rendered dynamically -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Golden Formula Card (Designed for Physical Paper Notebook) -->
|
||
<div class="grammar-section-block">
|
||
<h3 class="section-title"><span class="title-icon">✍️</span> Золотая формула для вашей бумажной тетради</h3>
|
||
<div class="grammar-golden-formula-card">
|
||
<div class="notebook-pen-icon">✒️</div>
|
||
<div class="formula-instructions">Выделите ярким маркером или цветной ручкой в конспекте:</div>
|
||
<div id="grammar-golden-formula-text" class="golden-formula-code"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Handwritten Journaling Prompt & Sync Checkbox -->
|
||
<div class="grammar-section-block">
|
||
<h3 class="section-title"><span class="title-icon">📓</span> Персональный дневник от руки (Motor Memory)</h3>
|
||
<div class="grammar-journaling-card">
|
||
<div class="journaling-prompt-box">
|
||
<p id="grammar-journaling-prompt-text" class="journaling-prompt-text"></p>
|
||
</div>
|
||
<div class="journaling-action-box">
|
||
<label class="handwritten-checkbox-label">
|
||
<input type="checkbox" id="grammar-handwritten-toggle" class="handwritten-checkbox">
|
||
<span class="custom-chk"></span>
|
||
<span class="handwritten-label-text">
|
||
<strong>Записал от руки в бумажную тетрадь</strong>
|
||
<small>Моторная память усиливает долгосрочную фиксацию грамматической конструкции на 65%</small>
|
||
</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grammar-theory-footer">
|
||
<button id="grammar-to-practice-btn" class="btn btn-primary btn-lg">
|
||
Перейти к микро-практике (5 заданий) →
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 2 Content: 5 Cloze Tap micro-exercises -->
|
||
<div id="grammar-tab-practice-content" class="grammar-tab-content hidden">
|
||
<div class="grammar-practice-card-wrap">
|
||
<div class="practice-header-bar">
|
||
<span id="grammar-practice-progress" class="practice-step-text">Задание 1 из 5</span>
|
||
<div id="grammar-practice-dots" class="practice-dots"></div>
|
||
</div>
|
||
|
||
<!-- Practice Mode Cheatsheet Toggle & Drawer -->
|
||
<div class="practice-cheatsheet-toggle-wrap">
|
||
<button type="button" id="grammar-practice-cheatsheet-toggle" class="btn btn-sm btn-ghost practice-cheatsheet-btn">
|
||
<span>📋 Шпаргалка по теме</span>
|
||
<i class="ph-caret-down"></i>
|
||
</button>
|
||
<div id="grammar-practice-cheatsheet-drawer" class="practice-cheatsheet-drawer hidden"></div>
|
||
</div>
|
||
|
||
<div class="grammar-cloze-box">
|
||
<div id="grammar-cloze-sentence" class="cloze-sentence-display"></div>
|
||
<div id="grammar-cloze-clue" class="cloze-clue-display"></div>
|
||
</div>
|
||
|
||
<div id="grammar-options-container" class="grammar-tap-options">
|
||
<!-- 4 Tap buttons rendered dynamically -->
|
||
</div>
|
||
|
||
<div id="grammar-exercise-feedback" class="grammar-feedback-box hidden">
|
||
<!-- Correct / Incorrect explanation -->
|
||
</div>
|
||
|
||
<div class="practice-nav-bar">
|
||
<button id="grammar-ex-next-btn" class="btn btn-primary btn-lg btn-block hidden">
|
||
Следующее задание → (Space)
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Lesson Summary Card -->
|
||
<div id="grammar-summary-card" class="grammar-summary-card hidden">
|
||
<div class="summary-trophy">✨</div>
|
||
<h2>Юнит освоен!</h2>
|
||
<div class="summary-score-large" id="grammar-sum-score-val">100%</div>
|
||
<p id="grammar-sum-score-text" class="summary-lead">Отличный результат!</p>
|
||
|
||
<div id="grammar-sum-hw-reminder" class="summary-reminder-box hidden">
|
||
<span class="reminder-icon">📝</span>
|
||
<div class="reminder-text">
|
||
<strong>Не забудьте записать от руки!</strong>
|
||
<span>Зафиксируйте формулу и 2 личных предложения в тетради для надежного моторного закрепления.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="summary-metrics">
|
||
<div class="metric-card">
|
||
<span class="metric-val text-info" id="grammar-sum-ingested-count">0</span>
|
||
<span class="metric-desc">Ошибок добавлено в SRS</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="summary-buttons">
|
||
<button id="grammar-sum-repeat-btn" class="btn btn-primary btn-lg">🔄 Повторить задания</button>
|
||
<button id="grammar-sum-srs-btn" class="btn btn-outline btn-lg hidden">🎓 Закрепить ошибки в SRS</button>
|
||
<button id="grammar-sum-units-btn" class="btn btn-ghost btn-lg">← К каталогу юнитов</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VIEW 6: Comprehensive Lesson Configurator (Beta) -->
|
||
<section id="lesson-view" class="lesson-view hidden">
|
||
<div class="lesson-configurator-container">
|
||
<!-- Header with Title & Action -->
|
||
<div class="lesson-header-bar">
|
||
<div class="lesson-title-wrap">
|
||
<h2>🚀 Конструктор комплексного урока <span class="badge badge-beta">Beta</span></h2>
|
||
<p class="lesson-subtitle text-muted">Соберите персональный ежедневный воркфлоу или запустите готовый шаблон</p>
|
||
</div>
|
||
<div class="lesson-header-actions">
|
||
<button id="lesson-history-btn" class="btn btn-outline" title="История пройденных уроков">
|
||
📜 История уроков
|
||
</button>
|
||
<button id="lesson-save-preset-btn" class="btn btn-secondary" title="Сохранить текущую настройку в мои шаблоны">
|
||
💾 Сохранить шаблон
|
||
</button>
|
||
<button id="lesson-start-btn" class="btn btn-primary btn-lg pulse-btn">
|
||
🚀 Начать урок (<span id="lesson-preset-duration">~15 мин</span>)
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Presets Carousel / Bar -->
|
||
<div class="lesson-presets-section mt-3">
|
||
<div class="presets-section-title">
|
||
<span>🎯 Готовые шаблоны уроков:</span>
|
||
</div>
|
||
<div id="lesson-presets-bar" class="lesson-presets-chips-row">
|
||
<!-- Loaded dynamically -->
|
||
</div>
|
||
<p id="lesson-preset-desc" class="preset-description-text text-muted mt-2"></p>
|
||
</div>
|
||
|
||
<!-- Steps List (Configurable Blocks) -->
|
||
<div class="lesson-blocks-section mt-4">
|
||
<div class="blocks-section-header">
|
||
<h3>🧩 Блоки вашего урока:</h3>
|
||
<span class="blocks-tip text-muted">Тасуйте порядок стрелками ▲/▼, меняйте объём и включайте нужные блоки</span>
|
||
</div>
|
||
<div id="lesson-steps-list" class="lesson-steps-list mt-3">
|
||
<!-- Rendered by lesson.js -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Bottom Floating Start CTA -->
|
||
<div class="lesson-bottom-cta mt-4">
|
||
<button id="lesson-start-btn-bottom" class="btn btn-primary btn-xl w-100" onclick="document.getElementById('lesson-start-btn').click()">
|
||
🚀 Начать комплексный урок сейчас
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VIEW 7: Active Lesson Session Runner -->
|
||
<section id="lesson-runner-view" class="lesson-runner-view hidden">
|
||
<!-- Top Sticky Control Bar -->
|
||
<header class="lesson-runner-header">
|
||
<div class="runner-nav-left">
|
||
<button id="lesson-runner-exit-btn" class="btn btn-sm btn-outline">✕ Выйти из урока</button>
|
||
<div class="runner-timer-wrap">
|
||
⏱️ <span id="lesson-runner-timer" class="runner-timer-val">00:00</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="runner-nav-center">
|
||
<div id="lesson-runner-breadcrumbs" class="runner-breadcrumbs-row">
|
||
<!-- Filled by lesson.js -->
|
||
</div>
|
||
</div>
|
||
|
||
<div class="runner-nav-right">
|
||
<button id="lesson-next-step-btn" class="btn btn-sm btn-ghost">
|
||
Пропустить этап ⏭️
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Runner Progress Bar -->
|
||
<div class="lesson-runner-progress-track">
|
||
<div id="lesson-runner-progress-fill" class="lesson-runner-progress-fill" style="width: 0%;"></div>
|
||
</div>
|
||
|
||
<!-- Dynamic Step Content Stage -->
|
||
<main class="lesson-runner-main">
|
||
<div id="lesson-step-content" class="lesson-step-content-container">
|
||
<!-- Injected dynamically by step runners -->
|
||
</div>
|
||
</main>
|
||
</section>
|
||
|
||
|
||
<!-- Sticky Bulk Action Bar for Batch Selection Mode -->
|
||
<div id="batch-action-bar" class="batch-action-bar hidden">
|
||
<div class="batch-left">
|
||
<label class="batch-check-label">
|
||
<input type="checkbox" id="batch-select-all" class="batch-master-checkbox">
|
||
<span id="batch-count-label">Выбрано: 0</span>
|
||
</label>
|
||
</div>
|
||
<div class="batch-actions">
|
||
<button id="batch-move-btn" class="btn btn-sm btn-outline">📁 В коллекцию</button>
|
||
<button id="batch-tag-btn" class="btn btn-sm btn-outline">🏷️ Добавить тег</button>
|
||
<button id="batch-delete-btn" class="btn btn-sm btn-danger">🗑️ Удалить</button>
|
||
<button id="batch-cancel-btn" class="btn btn-sm btn-ghost">✕ Отмена</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Mobile Bottom Navigation Tab Bar (iOS style, 4 core tabs) -->
|
||
<nav class="mobile-tab-bar" id="mobile-tab-bar">
|
||
<button class="tab-item active" data-view="dictionary-view" id="tab-nav-dict">
|
||
<span class="tab-icon">📖</span>
|
||
<span class="tab-label">Словарь</span>
|
||
</button>
|
||
<button class="tab-item" data-view="srs-view" id="tab-nav-srs">
|
||
<span class="tab-icon">🎓</span>
|
||
<span class="tab-label">Тренажёр</span>
|
||
<span id="tab-srs-badge" class="tab-badge hidden">0</span>
|
||
</button>
|
||
<button class="tab-item" data-view="reader-view" id="tab-nav-reader">
|
||
<span class="tab-icon">📚</span>
|
||
<span class="tab-label">Читалка</span>
|
||
</button>
|
||
<button class="tab-item" id="tab-nav-menu">
|
||
<span class="tab-icon">☰</span>
|
||
<span class="tab-label">Меню</span>
|
||
</button>
|
||
</nav>
|
||
</div>
|
||
|
||
<!-- Navigation Drawer (Unified Side Drawer for Desktop & Mobile) -->
|
||
<div id="app-drawer-backdrop" class="drawer-backdrop hidden" aria-hidden="true"></div>
|
||
<aside id="app-drawer" class="app-drawer" aria-label="Боковое меню навигации">
|
||
<div class="drawer-header">
|
||
<div class="drawer-user-card" id="drawer-user-card">
|
||
<div class="drawer-user-avatar">👤</div>
|
||
<div class="drawer-user-info">
|
||
<strong id="drawer-user-name" class="drawer-user-name">user</strong>
|
||
<span class="drawer-user-desc">Личный словарь English Lexicon</span>
|
||
</div>
|
||
</div>
|
||
<button id="app-drawer-close-btn" class="icon-btn drawer-close-btn" title="Закрыть меню (Esc)" aria-label="Закрыть">✕</button>
|
||
</div>
|
||
|
||
<!-- Quick Stats in Drawer -->
|
||
<div class="drawer-stats-summary" id="drawer-stats-summary">
|
||
<div class="drawer-stat-item">
|
||
<span class="drawer-stat-val" id="drawer-stat-total">0</span>
|
||
<span class="drawer-stat-lbl">Слов в базе</span>
|
||
</div>
|
||
<div class="drawer-stat-item">
|
||
<span class="drawer-stat-val text-success" id="drawer-stat-today">+0</span>
|
||
<span class="drawer-stat-lbl">Сегодня</span>
|
||
</div>
|
||
<div class="drawer-stat-item">
|
||
<span class="drawer-stat-val text-warning" id="drawer-stat-due">0</span>
|
||
<span class="drawer-stat-lbl">Повторение</span>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="drawer-nav">
|
||
<!-- Section 1: Study & Reading -->
|
||
<div class="drawer-section-title">Обучение & Чтение</div>
|
||
<ul class="drawer-nav-list">
|
||
<li>
|
||
<button class="drawer-nav-item active" data-hash="#dictionary" id="drawer-nav-dict">
|
||
<span class="drawer-item-icon">📖</span>
|
||
<span class="drawer-item-label">Словарь & Поиск</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" data-hash="#srs" id="drawer-nav-srs">
|
||
<span class="drawer-item-icon">🎓</span>
|
||
<span class="drawer-item-label">Тренажёр SRS</span>
|
||
<span id="drawer-srs-badge" class="drawer-badge hidden">0</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" data-hash="#reader" id="drawer-nav-reader">
|
||
<span class="drawer-item-icon">📚</span>
|
||
<span class="drawer-item-label">Интерактивная читалка & Книги</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" data-hash="#cefr" id="drawer-nav-cefr">
|
||
<span class="drawer-item-icon">🎯</span>
|
||
<span class="drawer-item-label">Уровневые тесты CEFR (A1–B2)</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" data-hash="#grammar" id="drawer-nav-grammar">
|
||
<span class="drawer-item-icon">📘</span>
|
||
<span class="drawer-item-label">Грамматика Мерфи & Тетрадь</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" data-hash="#lesson" id="drawer-nav-lesson">
|
||
<span class="drawer-item-icon">🚀</span>
|
||
<span class="drawer-item-label">Комплексный урок</span>
|
||
<span class="drawer-badge badge-beta">Beta</span>
|
||
</button>
|
||
</li>
|
||
</ul>
|
||
|
||
<!-- Section 2: Analytics & Progress -->
|
||
<div class="drawer-section-title">Аналитика</div>
|
||
<ul class="drawer-nav-list">
|
||
<li>
|
||
<button class="drawer-nav-item" id="drawer-nav-stats">
|
||
<span class="drawer-item-icon">📊</span>
|
||
<span class="drawer-item-label">Календарь активности & Статистика</span>
|
||
</button>
|
||
</li>
|
||
</ul>
|
||
|
||
<!-- Section 3: Profile & Settings -->
|
||
<div class="drawer-section-title">Настройки & Профиль</div>
|
||
<ul class="drawer-nav-list">
|
||
<li>
|
||
<button class="drawer-nav-item" id="drawer-nav-export">
|
||
<span class="drawer-item-icon">📤</span>
|
||
<span class="drawer-item-label">Экспорт словаря (JSON / CSV / TXT)</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" id="drawer-nav-pwd">
|
||
<span class="drawer-item-icon">🔑</span>
|
||
<span class="drawer-item-label">Сменить пароль</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" id="drawer-nav-theme">
|
||
<span class="drawer-item-icon">🌓</span>
|
||
<span class="drawer-item-label">Переключить тему оформления</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item" id="drawer-nav-voice-settings">
|
||
<span class="drawer-item-icon">🎙️</span>
|
||
<span class="drawer-item-label">Голоса озвучки (TTS)</span>
|
||
</button>
|
||
</li>
|
||
<li>
|
||
<button class="drawer-nav-item text-danger" id="drawer-nav-logout">
|
||
<span class="drawer-item-icon">🚪</span>
|
||
<span class="drawer-item-label">Выйти из аккаунта</span>
|
||
</button>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
|
||
<div class="drawer-footer">
|
||
<span class="drawer-footer-text">study.qpid.pro • v5.7 PWA</span>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- Analytics & Activity Heatmap Modal -->
|
||
<div id="stats-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window stats-modal-window">
|
||
<div class="modal-header">
|
||
<h3>📊 Аналитика обучения & Активность</h3>
|
||
<button id="close-stats-modal-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<!-- Streak & Core Stats Hero -->
|
||
<div class="stats-hero-grid">
|
||
<div class="stat-kpi-card streak-kpi">
|
||
<div class="kpi-icon">🔥</div>
|
||
<div class="kpi-value" id="kpi-current-streak">0</div>
|
||
<div class="kpi-label">Текущая серия дней</div>
|
||
<div class="kpi-sub" id="kpi-longest-streak">Рекорд: 0 дней</div>
|
||
</div>
|
||
<div class="stat-kpi-card">
|
||
<div class="kpi-icon">🎯</div>
|
||
<div class="kpi-value text-success" id="kpi-retention-rate">100%</div>
|
||
<div class="kpi-label">Точность запоминания</div>
|
||
<div class="kpi-sub" id="kpi-total-reviews">Всего повторений: 0</div>
|
||
</div>
|
||
<div class="stat-kpi-card">
|
||
<div class="kpi-icon">📚</div>
|
||
<div class="kpi-value" id="kpi-total-words">0</div>
|
||
<div class="kpi-label">Слов в словаре</div>
|
||
<div class="kpi-sub" id="kpi-today-added">Сегодня добавлено: +0</div>
|
||
</div>
|
||
<div class="stat-kpi-card">
|
||
<div class="kpi-icon">🎓</div>
|
||
<div class="kpi-value text-accent" id="kpi-cefr-level">A1</div>
|
||
<div class="kpi-label">Оценка уровня</div>
|
||
<div class="kpi-sub" id="kpi-cefr-desc">Начальный словарный запас</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Contribution Activity Heatmap -->
|
||
<div class="heatmap-section">
|
||
<div class="heatmap-header">
|
||
<h4>🟩 Календарь активности</h4>
|
||
<div class="heatmap-legend">
|
||
<span>Меньше</span>
|
||
<span class="legend-cell lvl-0" title="0 повторений"></span>
|
||
<span class="legend-cell lvl-1" title="1 повторение"></span>
|
||
<span class="legend-cell lvl-2" title="2-3 повторения"></span>
|
||
<span class="legend-cell lvl-3" title="4+ повторений"></span>
|
||
<span>Больше</span>
|
||
</div>
|
||
</div>
|
||
<div class="heatmap-container-wrap">
|
||
<div id="heatmap-grid" class="heatmap-grid">
|
||
<!-- Heatmap cells generated dynamically -->
|
||
</div>
|
||
</div>
|
||
<div class="heatmap-footer-note">
|
||
<small>Цвет ячейки показывает количество пройденных тестов и интервальных повторений за день.</small>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Mastery Distribution Progress -->
|
||
<div class="mastery-section">
|
||
<h4>📈 Стадии освоения слов (SM-2 SRS)</h4>
|
||
<div class="segmented-progress-bar">
|
||
<div id="prog-mastered" class="prog-segment seg-mastered" style="width: 0%;" title="Выучено (интервал > 21 дня)"></div>
|
||
<div id="prog-review" class="prog-segment seg-review" style="width: 0%;" title="Повторение"></div>
|
||
<div id="prog-learning" class="prog-segment seg-learning" style="width: 0%;" title="В процессе (1-3 повтора)"></div>
|
||
<div id="prog-new" class="prog-segment seg-new" style="width: 100%;" title="Новые слова"></div>
|
||
</div>
|
||
<div class="mastery-legend-row">
|
||
<div class="m-legend-item"><span class="dot dot-mastered"></span> Выучено: <strong id="cnt-mastered">0</strong></div>
|
||
<div class="m-legend-item"><span class="dot dot-review"></span> Закрепление: <strong id="cnt-review">0</strong></div>
|
||
<div class="m-legend-item"><span class="dot dot-learning"></span> В процессе: <strong id="cnt-learning">0</strong></div>
|
||
<div class="m-legend-item"><span class="dot dot-new"></span> Новые: <strong id="cnt-new">0</strong></div>
|
||
<div class="m-legend-item text-danger"><span class="dot dot-leech"></span> Трудные слова: <strong id="cnt-leeches">0</strong></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button id="close-stats-btn" class="btn btn-primary">Закрыть</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Edit Card Modal -->
|
||
<div id="edit-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window">
|
||
<div class="modal-header">
|
||
<h3>✏️ Редактировать карточку</h3>
|
||
<button id="close-modal-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<input type="hidden" id="modal-card-id">
|
||
<div class="form-group">
|
||
<label>Слово / Выражение (EN)</label>
|
||
<input type="text" id="modal-term" class="input-styled" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Перевод (RU)</label>
|
||
<input type="text" id="modal-translation" class="input-styled" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Контекстное предложение</label>
|
||
<textarea id="modal-context" class="input-styled" rows="2"></textarea>
|
||
</div>
|
||
<div class="field-row">
|
||
<div class="form-group flex-1">
|
||
<label>Транскрипция (IPA)</label>
|
||
<input type="text" id="modal-phonetic" class="input-styled">
|
||
</div>
|
||
<div class="form-group flex-1">
|
||
<label>Часть речи</label>
|
||
<input type="text" id="modal-pos" class="input-styled">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Английское толкование</label>
|
||
<textarea id="modal-def" class="input-styled" rows="2"></textarea>
|
||
</div>
|
||
<div class="field-row">
|
||
<div class="form-group flex-1">
|
||
<label>Коллекция (Папка)</label>
|
||
<input type="text" id="modal-collection" class="input-styled">
|
||
</div>
|
||
<div class="form-group flex-1">
|
||
<label>Теги</label>
|
||
<input type="text" id="modal-tags" class="input-styled">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Заметки / Мнемоника</label>
|
||
<input type="text" id="modal-notes" class="input-styled">
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button id="modal-cancel-btn" class="btn btn-outline">Отмена</button>
|
||
<button id="modal-save-btn" class="btn btn-primary">Сохранить изменения</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Export Modal -->
|
||
<div id="export-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window export-modal-window">
|
||
<div class="modal-header">
|
||
<h3>📤 Экспорт словаря</h3>
|
||
<button id="close-export-modal-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p class="modal-lead" id="export-modal-desc">Выберите удобный формат для выгрузки карточек:</p>
|
||
<div class="export-grid">
|
||
<div class="export-tile" data-format="csv">
|
||
<div class="export-tile-icon">📊</div>
|
||
<div class="export-tile-info">
|
||
<h4>CSV (Excel / Sheets)</h4>
|
||
<p>Таблица со всеми полями, переводами и примерами (UTF-8 BOM для русского языка).</p>
|
||
</div>
|
||
<button class="btn btn-sm btn-primary">Скачать</button>
|
||
</div>
|
||
|
||
<div class="export-tile" data-format="anki">
|
||
<div class="export-tile-icon">🗃️</div>
|
||
<div class="export-tile-info">
|
||
<h4>Колода для Anki (.tsv)</h4>
|
||
<p>Готовый файл для импорта в Anki с транскрипцией, озвучкой и контекстом.</p>
|
||
</div>
|
||
<button class="btn btn-sm btn-primary">Скачать</button>
|
||
</div>
|
||
|
||
<div class="export-tile" data-format="json">
|
||
<div class="export-tile-icon">📋</div>
|
||
<div class="export-tile-info">
|
||
<h4>JSON (Полный архив)</h4>
|
||
<p>Полная структурированная резервная копия данных словаря.</p>
|
||
</div>
|
||
<button class="btn btn-sm btn-primary">Скачать</button>
|
||
</div>
|
||
|
||
<div class="export-tile" data-format="md">
|
||
<div class="export-tile-icon">📝</div>
|
||
<div class="export-tile-info">
|
||
<h4>Markdown (.md)</h4>
|
||
<p>Красивый структурированный конспект для Obsidian, Notion или чтения.</p>
|
||
</div>
|
||
<button class="btn btn-sm btn-primary">Скачать</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<span id="export-scope-label" class="text-dim">Объём экспорта: все карточки</span>
|
||
<button id="export-cancel-btn" class="btn btn-outline">Закрыть</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Voice Settings Modal -->
|
||
<div id="voice-settings-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window voice-modal-window">
|
||
<div class="modal-header">
|
||
<h3>🎙️ Настройка дикторов (TTS)</h3>
|
||
<button id="voice-settings-close-btn" class="icon-btn" title="Закрыть">✕</button>
|
||
</div>
|
||
<div class="modal-body voice-modal-body">
|
||
<p class="modal-desc-sub">Выберите голос для озвучки английских и русских текстов. Нейросеть работает полностью автономно.</p>
|
||
|
||
<div class="voice-config-group">
|
||
<label class="voice-group-title">🇷🇺 Русский диктор (перевод и контекст):</label>
|
||
<div class="voice-options-grid">
|
||
<label class="voice-card-label">
|
||
<input type="radio" name="tts_voice_ru" value="ru_RU-irina" checked>
|
||
<div class="voice-card">
|
||
<div class="voice-card-head">
|
||
<strong>👩 Ирина</strong>
|
||
<span class="badge-recommended">Рекомендуется</span>
|
||
</div>
|
||
<small class="voice-card-desc">Плавный студийный голос, естественные паузы на тире и запятых, спокойный темп.</small>
|
||
<button type="button" class="btn btn-xs btn-outline voice-test-btn" data-lang="ru" data-voice="ru_RU-irina" data-text="Это важный проект — он требует внимания, концентрации и времени.">▶ Тест звука</button>
|
||
</div>
|
||
</label>
|
||
<label class="voice-card-label">
|
||
<input type="radio" name="tts_voice_ru" value="ru_RU-denis">
|
||
<div class="voice-card">
|
||
<div class="voice-card-head">
|
||
<strong>👨 Денис</strong>
|
||
</div>
|
||
<small class="voice-card-desc">Спокойный мужской тембр, ровная дикция.</small>
|
||
<button type="button" class="btn btn-xs btn-outline voice-test-btn" data-lang="ru" data-voice="ru_RU-denis" data-text="Это важный проект — он требует внимания, концентрации и времени.">▶ Тест звука</button>
|
||
</div>
|
||
</label>
|
||
<label class="voice-card-label">
|
||
<input type="radio" name="tts_voice_ru" value="ru_RU-dmitri">
|
||
<div class="voice-card">
|
||
<div class="voice-card-head">
|
||
<strong>👨 Дмитрий</strong>
|
||
</div>
|
||
<small class="voice-card-desc">Энергичный мужской голос с оптимизированным размеренным темпом.</small>
|
||
<button type="button" class="btn btn-xs btn-outline voice-test-btn" data-lang="ru" data-voice="ru_RU-dmitri" data-text="Это важный проект — он требует внимания, концентрации и времени.">▶ Тест звука</button>
|
||
</div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="voice-config-group" style="margin-top: 20px;">
|
||
<label class="voice-group-title">🇬🇧 / 🇺🇸 Английский диктор (слова, аудирование, книги):</label>
|
||
<div class="voice-options-grid">
|
||
<label class="voice-card-label">
|
||
<input type="radio" name="tts_voice_en" value="en_US-lessac" checked>
|
||
<div class="voice-card">
|
||
<div class="voice-card-head">
|
||
<strong>👩 Paula (US)</strong>
|
||
<span class="badge-recommended">По умолчанию</span>
|
||
</div>
|
||
<small class="voice-card-desc">Американский английский. Четкий академический женский голос.</small>
|
||
<button type="button" class="btn btn-xs btn-outline voice-test-btn" data-lang="en" data-voice="en_US-lessac" data-text="The quick brown fox jumps over the lazy dog.">▶ Test Voice</button>
|
||
</div>
|
||
</label>
|
||
<label class="voice-card-label">
|
||
<input type="radio" name="tts_voice_en" value="en_US-ryan">
|
||
<div class="voice-card">
|
||
<div class="voice-card-head">
|
||
<strong>👨 Ryan (US)</strong>
|
||
</div>
|
||
<small class="voice-card-desc">Американский английский. Естественный, выразительный мужской голос.</small>
|
||
<button type="button" class="btn btn-xs btn-outline voice-test-btn" data-lang="en" data-voice="en_US-ryan" data-text="The quick brown fox jumps over the lazy dog.">▶ Test Voice</button>
|
||
</div>
|
||
</label>
|
||
<label class="voice-card-label">
|
||
<input type="radio" name="tts_voice_en" value="en_GB-alan">
|
||
<div class="voice-card">
|
||
<div class="voice-card-head">
|
||
<strong>👨 Alan (UK)</strong>
|
||
<span class="badge-uk">British</span>
|
||
</div>
|
||
<small class="voice-card-desc">Британский английский (Received Pronunciation), классический мужской тембр.</small>
|
||
<button type="button" class="btn btn-xs btn-outline voice-test-btn" data-lang="en" data-voice="en_GB-alan" data-text="Good afternoon! The train to Oxford departs from platform four.">▶ Test Voice</button>
|
||
</div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" id="voice-settings-save-btn" class="btn btn-primary">Сохранить выбор</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Wikipedia Settings Modal -->
|
||
<div id="wiki-settings-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window wiki-modal-window">
|
||
<div class="modal-header">
|
||
<h3>⚙️ Настройки статей Википедии</h3>
|
||
<button id="wiki-settings-close-btn" class="icon-btn" title="Закрыть">✕</button>
|
||
</div>
|
||
<div class="modal-body wiki-modal-body">
|
||
<!-- Setting 1: Language / Complexity -->
|
||
<div class="wiki-setting-group">
|
||
<label class="wiki-group-label">Сложность языка (Wikipedia Edition):</label>
|
||
<div class="wiki-radio-cards">
|
||
<label class="wiki-radio-card">
|
||
<input type="radio" name="wiki-lang" value="simple" checked>
|
||
<div class="wiki-radio-card-content">
|
||
<div class="wiki-card-title-row">
|
||
<strong>Simple English</strong>
|
||
<span class="badge-level-pill badge-level-a2">A2–B1</span>
|
||
</div>
|
||
<p class="wiki-card-desc">Простая грамматика и базовая лексика (simple.wikipedia.org). Рекомендуется для уверенного чтения без перегрузки редкими терминами.</p>
|
||
</div>
|
||
</label>
|
||
<label class="wiki-radio-card">
|
||
<input type="radio" name="wiki-lang" value="en">
|
||
<div class="wiki-radio-card-content">
|
||
<div class="wiki-card-title-row">
|
||
<strong>Standard English</strong>
|
||
<span class="badge-level-pill badge-level-b2">B2–C1</span>
|
||
</div>
|
||
<p class="wiki-card-desc">Полный оригинальный текст (en.wikipedia.org). Академическая лексика, развернутые описания и глубокая научная терминология.</p>
|
||
</div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Setting 2: Reading Volume / Duration -->
|
||
<div class="wiki-setting-group">
|
||
<label class="wiki-group-label">Объем статьи / Время чтения:</label>
|
||
<div class="wiki-time-grid">
|
||
<label class="wiki-time-pill">
|
||
<input type="radio" name="wiki-time" value="5">
|
||
<span class="wiki-pill-text">⚡ ~5 мин <small class="text-dim">(800–1200 слов)</small></span>
|
||
</label>
|
||
<label class="wiki-time-pill">
|
||
<input type="radio" name="wiki-time" value="10-15" checked>
|
||
<span class="wiki-pill-text">⏱️ ~10–15 мин <small class="text-dim">(1500–2500 слов)</small></span>
|
||
</label>
|
||
<label class="wiki-time-pill">
|
||
<input type="radio" name="wiki-time" value="20+">
|
||
<span class="wiki-pill-text">📚 20+ мин <small class="text-dim">(лонгрид от 3000 слов)</small></span>
|
||
</label>
|
||
<label class="wiki-time-pill">
|
||
<input type="radio" name="wiki-time" value="any">
|
||
<span class="wiki-pill-text">🎲 Любой объем</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Setting 3: Topic Presets -->
|
||
<div class="wiki-setting-group">
|
||
<label class="wiki-group-label">Тематика статьи:</label>
|
||
<select id="wiki-topic-select" class="input-styled wiki-select">
|
||
<option value="random">🎲 Любая / Случайная тема</option>
|
||
<option value="science">🚀 Наука, космос и астрономия</option>
|
||
<option value="tech">💻 Технологии, IT и интернет</option>
|
||
<option value="history">🏛️ История и великие цивилизации</option>
|
||
<option value="nature">🌿 Природа, животные и экология</option>
|
||
<option value="psychology">🧠 Психология, мозг и память</option>
|
||
<option value="featured">⭐ Статья дня (Featured Article)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<!-- Setting 4: Direct Article URL or Title -->
|
||
<div class="wiki-setting-group wiki-direct-import-group">
|
||
<label class="wiki-group-label">Или загрузить конкретную статью по ссылке/названию:</label>
|
||
<form id="wiki-custom-form" class="wiki-custom-form">
|
||
<div class="wiki-custom-input-wrap">
|
||
<input type="text" id="wiki-custom-input" class="input-styled wiki-custom-input" placeholder="Название (напр. Black hole, Solar System) или URL статьи" autocomplete="off" spellcheck="false">
|
||
<button type="submit" id="wiki-custom-fetch-btn" class="btn btn-primary wiki-custom-fetch-btn">
|
||
<span>📥 Загрузить</span>
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" id="wiki-settings-save-btn" class="btn btn-primary">Применить настройки</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Lesson History Modal -->
|
||
<div id="lesson-history-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window modal-lg lesson-history-modal-window">
|
||
<div class="modal-header">
|
||
<h3>📜 История комплексных уроков</h3>
|
||
<button id="lesson-history-close-btn" class="icon-btn" title="Закрыть">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div id="lesson-history-list" class="lesson-history-list">
|
||
<!-- Populated dynamically by lesson.js -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Move Collection Modal -->
|
||
<div id="move-col-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window modal-sm">
|
||
<div class="modal-header">
|
||
<h3>📁 Переместить в коллекцию</h3>
|
||
<button id="close-move-modal-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p class="modal-lead" id="move-modal-count-label">Выберите коллекцию для выбранных карточек:</p>
|
||
<div class="form-group">
|
||
<label for="move-col-input">Название коллекции</label>
|
||
<input type="text" id="move-col-input" list="move-collections-datalist" class="input-styled" placeholder="Например: Разговорный">
|
||
<datalist id="move-collections-datalist"></datalist>
|
||
</div>
|
||
<div class="quick-tags" id="move-col-quick-list"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button id="move-col-cancel-btn" class="btn btn-outline">Отмена</button>
|
||
<button id="move-col-confirm-btn" class="btn btn-primary">Переместить</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- New Collection Modal -->
|
||
<div id="new-col-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window modal-sm">
|
||
<div class="modal-header">
|
||
<h3>📁 Новая коллекция</h3>
|
||
<button id="close-new-col-modal-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label for="new-col-name-input">Название новой коллекции</label>
|
||
<input type="text" id="new-col-name-input" class="input-styled" placeholder="Например: Сериалы / Netflix">
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button id="new-col-cancel-btn" class="btn btn-outline">Отмена</button>
|
||
<button id="new-col-save-btn" class="btn btn-primary">Создать</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Change Password Modal -->
|
||
<div id="change-password-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window modal-sm">
|
||
<div class="modal-header">
|
||
<h3>🔑 Смена пароля</h3>
|
||
<button id="close-change-pwd-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<form id="change-password-form">
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label for="current-password-input">Текущий пароль</label>
|
||
<input type="password" id="current-password-input" class="input-styled" autocomplete="current-password" required placeholder="••••••••">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="new-password-input">Новый пароль</label>
|
||
<input type="password" id="new-password-input" class="input-styled" autocomplete="new-password" required minlength="6" placeholder="Минимум 6 символов">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="confirm-password-input">Подтвердите новый пароль</label>
|
||
<input type="password" id="confirm-password-input" class="input-styled" autocomplete="new-password" required minlength="6" placeholder="Повторите новый пароль">
|
||
</div>
|
||
<div id="change-pwd-error" class="error-banner hidden"></div>
|
||
<div id="change-pwd-success" class="success-banner hidden"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" id="change-pwd-cancel-btn" class="btn btn-outline">Отмена</button>
|
||
<button type="submit" id="change-pwd-save-btn" class="btn btn-primary">Сохранить</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Add Book Modal (Paste Text) -->
|
||
<div id="add-book-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window">
|
||
<div class="modal-header">
|
||
<h3>✏️ Добавить текст или статью</h3>
|
||
<button id="close-add-book-modal-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<form id="add-book-form">
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label for="book-title-input">Название книги / статьи *</label>
|
||
<input type="text" id="book-title-input" class="input-styled" required placeholder="Например: Clean Code Principles">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="book-author-input">Автор / Источник</label>
|
||
<input type="text" id="book-author-input" class="input-styled" placeholder="Например: Robert C. Martin">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="book-content-input">Текст материала (English) *</label>
|
||
<textarea id="book-content-input" class="input-styled" rows="10" required placeholder="Вставьте английский текст книги, статьи или документации..."></textarea>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" id="cancel-add-book-btn" class="btn btn-outline">Отмена</button>
|
||
<button type="submit" id="submit-add-book-btn" class="btn btn-primary">📚 Сохранить в библиотеку</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Mine CEFR Questions from Books Modal -->
|
||
<div id="mine-books-modal" class="modal-backdrop hidden">
|
||
<div class="modal-window">
|
||
<div class="modal-header">
|
||
<h3>⚡ Сборка тестов из библиотеки книг</h3>
|
||
<button type="button" id="close-mine-books-modal-btn" class="icon-btn">✕</button>
|
||
</div>
|
||
<form id="mine-books-form">
|
||
<div class="modal-body">
|
||
<p class="modal-desc" style="margin-bottom: 1rem; color: var(--text-muted); font-size: 0.9rem;">
|
||
Сканирует ваши книги, находит аутентичные предложения с лексикой CEFR и создает тесты с выбором вариантов. Фоновая задача работает без задержек.
|
||
</p>
|
||
<div class="form-group">
|
||
<label for="mine-books-select">Книга для анализа:</label>
|
||
<select id="mine-books-select" class="input-styled">
|
||
<option value="">📚 Все книги библиотеки</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="mine-level-select">Целевой уровень CEFR:</label>
|
||
<select id="mine-level-select" class="input-styled">
|
||
<option value="ALL">Все уровни (A1 – B2)</option>
|
||
<option value="A1">A1 – Начальный</option>
|
||
<option value="A2">A2 – Элементарный</option>
|
||
<option value="B1">B1 – Средний</option>
|
||
<option value="B2">B2 – Выше среднего</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="mine-count-input">Количество вопросов для сборки:</label>
|
||
<select id="mine-count-input" class="input-styled">
|
||
<option value="15" selected>15 вопросов</option>
|
||
<option value="25">25 вопросов</option>
|
||
<option value="35">35 вопросов</option>
|
||
<option value="50">50 вопросов</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" id="cancel-mine-books-btn" class="btn btn-outline">Отмена</button>
|
||
<button type="submit" id="submit-mine-books-btn" class="btn btn-primary">⚡ Запустить сборку</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Reader Appearance Settings Popover / Bottom Sheet -->
|
||
<div id="reader-settings-panel" class="reader-settings-panel hidden">
|
||
<div class="sheet-drag-handle mobile-only"></div>
|
||
<div class="reader-settings-header">
|
||
<h4>🔤 Настройки текста</h4>
|
||
<button id="reader-settings-close-btn" class="popup-close-btn">✕</button>
|
||
</div>
|
||
<div class="reader-settings-body">
|
||
<!-- Reading Flow Mode -->
|
||
<div class="setting-row">
|
||
<span class="setting-label">Режим чтения</span>
|
||
<div class="setting-segmented-control" id="reader-mode-group">
|
||
<button type="button" class="seg-btn active" data-flow="chapters">📖 По главам</button>
|
||
<button type="button" class="seg-btn" data-flow="continuous">📜 Вся книга</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Autoload next chapter toggle (active in chapters mode) -->
|
||
<div class="setting-row" id="setting-autoload-row">
|
||
<span class="setting-label">Переход между главами</span>
|
||
<div class="setting-segmented-control" id="reader-autoload-group">
|
||
<button type="button" class="seg-btn active" data-autoload="true">⚡ Автоподгрузка</button>
|
||
<button type="button" class="seg-btn" data-autoload="false">🔘 По кнопке</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Font Family -->
|
||
<div class="setting-row">
|
||
<span class="setting-label">Шрифт</span>
|
||
<div class="setting-segmented-control" id="reader-font-family-group">
|
||
<button class="seg-btn" data-font="sans" style="font-family: var(--font-family);">Sans</button>
|
||
<button class="seg-btn active" data-font="serif" style="font-family: Georgia, serif;">Serif</button>
|
||
<button class="seg-btn" data-font="mono" style="font-family: monospace;">Mono</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Font Size & Text Alignment (Compact 2-col Grid) -->
|
||
<div class="setting-row-grid">
|
||
<div class="setting-row">
|
||
<span class="setting-label">Размер</span>
|
||
<div class="setting-stepper">
|
||
<button id="setting-font-dec-btn" class="step-btn">A−</button>
|
||
<span id="setting-font-size-val" class="step-val">18 px</span>
|
||
<button id="setting-font-inc-btn" class="step-btn">A+</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="setting-row">
|
||
<span class="setting-label">Выравнивание</span>
|
||
<div class="setting-segmented-control" id="reader-align-group">
|
||
<button class="seg-btn active" data-align="left" title="По левому краю">По краю</button>
|
||
<button class="seg-btn" data-align="justify" title="По ширине (Justified)">По ширине</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Line Height -->
|
||
<div class="setting-row">
|
||
<span class="setting-label">Межстрочный интервал</span>
|
||
<div class="setting-segmented-control" id="reader-line-height-group">
|
||
<button class="seg-btn" data-lh="1.35">Компакт</button>
|
||
<button class="seg-btn active" data-lh="1.65">Оптимум</button>
|
||
<button class="seg-btn" data-lh="1.95">Широкий</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Margins / Width -->
|
||
<div class="setting-row">
|
||
<span class="setting-label">Ширина и поля страницы</span>
|
||
<div class="setting-segmented-control" id="reader-margins-group">
|
||
<button class="seg-btn" data-margin="narrow">Узкие</button>
|
||
<button class="seg-btn active" data-margin="normal">Стандарт</button>
|
||
<button class="seg-btn" data-margin="wide">Книга</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Reading Theme -->
|
||
<div class="setting-row">
|
||
<span class="setting-label">Цветовая тема читалки</span>
|
||
<div class="theme-palette" id="reader-theme-group">
|
||
<button class="theme-chip theme-chip-dark active" data-theme="dark" title="Тёмная (Dark Slate)">🌙 Тёмная</button>
|
||
<button class="theme-chip theme-chip-sepia" data-theme="sepia" title="Сепия (Тёплый пергамент)">📜 Сепия</button>
|
||
<button class="theme-chip theme-chip-light" data-theme="light" title="Светлая (Чистый лист)">☀️ Светлая</button>
|
||
<button class="theme-chip theme-chip-oled" data-theme="oled" title="OLED (Абсолютный чёрный)">🖤 OLED</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Interactive Click-to-Translate Popup (Mounted at body root to prevent scroll clipping) -->
|
||
<div id="reader-word-popup" class="reader-word-popup hidden">
|
||
<div class="sheet-drag-handle mobile-only"></div>
|
||
<div class="popup-header">
|
||
<div class="popup-term-wrap">
|
||
<strong id="popup-term" class="popup-term">word</strong>
|
||
<span id="popup-phonetic" class="popup-phonetic">/wɜːd/</span>
|
||
<span id="popup-in-library" class="popup-in-library-badge hidden" title="Это слово уже есть в вашей библиотеке">⭐ В библиотеке</span>
|
||
<button id="popup-audio-btn" class="icon-btn audio-btn" style="display: none;" title="Слушать произношение">🔊</button>
|
||
</div>
|
||
<button id="popup-close-btn" class="popup-close-btn">✕</button>
|
||
</div>
|
||
<div class="popup-body">
|
||
<div id="popup-loading" class="popup-loading hidden">Переводим...</div>
|
||
<div id="popup-content" class="popup-content">
|
||
<!-- Phrasal Verb & Idiom Detector Card -->
|
||
<div id="popup-phrasal-card" class="popup-phrasal-card hidden">
|
||
<div class="phrasal-card-header">
|
||
<span class="phrasal-tag">🔗 Фразовый глагол</span>
|
||
<span id="popup-phrasal-library-badge" class="popup-in-library-badge hidden">⭐ В библиотеке</span>
|
||
</div>
|
||
<div class="phrasal-card-body">
|
||
<div class="phrasal-term-row">
|
||
<strong id="popup-phrasal-term" class="phrasal-term">take off</strong>
|
||
<span id="popup-phrasal-raw" class="phrasal-raw">(в тексте: «took off»)</span>
|
||
</div>
|
||
<div id="popup-phrasal-translation" class="phrasal-translation">взлетать, снимать</div>
|
||
</div>
|
||
<div class="phrasal-card-actions">
|
||
<button type="button" id="popup-switch-phrasal-btn" class="btn btn-xs btn-primary phrasal-action-btn">
|
||
🔗 Переключить на фразовый глагол
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="popup-translation" id="popup-translation">перевод</div>
|
||
<div class="popup-context-box">
|
||
<div class="popup-context" id="popup-context">“Контекст из книги...”</div>
|
||
<div class="popup-sentence-ai-bar">
|
||
<button type="button" id="popup-translate-sentence-btn" class="btn btn-xs btn-outline popup-sentence-btn" title="Перевести всё предложение через локальный ИИ">
|
||
🌐 Перевести предложение
|
||
</button>
|
||
<button type="button" id="popup-audio-sentence-btn" class="btn btn-xs btn-outline popup-sentence-audio-btn" title="Озвучить всё предложение нейросетью">
|
||
🔊 Озвучить
|
||
</button>
|
||
<span id="popup-ai-source-badge" class="popup-ai-source-badge hidden">⚡ Local AI</span>
|
||
</div>
|
||
<div id="popup-sentence-loading" class="popup-sentence-loading hidden">
|
||
<span class="spinner-sm"></span> Локальный ИИ переводит...
|
||
</div>
|
||
<div id="popup-sentence-translation-wrap" class="popup-sentence-translation-wrap hidden">
|
||
<div class="popup-sentence-ru-row" style="display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;">
|
||
<div class="popup-sentence-ru" id="popup-sentence-ru"></div>
|
||
<button type="button" id="popup-audio-ru-btn" class="icon-btn audio-xs-btn" style="flex-shrink: 0;" title="Озвучить русский перевод">🔊 RU</button>
|
||
</div>
|
||
<div id="popup-context-meaning-wrap" class="popup-context-meaning-wrap hidden">
|
||
<span class="context-meaning-label">🎯 В контексте:</span>
|
||
<strong id="popup-context-meaning-val" class="context-meaning-val"></strong>
|
||
<button type="button" id="popup-use-context-meaning-btn" class="btn btn-xs btn-ghost use-meaning-btn" title="Использовать этот перевод для карточки">Вставить в карточку</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="popup-footer">
|
||
<button id="popup-save-btn" class="btn btn-primary btn-sm btn-block">💾 Добавить в словарь</button>
|
||
<div id="popup-saved-badge" class="popup-saved-badge hidden">⭐ Слово уже в библиотеке</div>
|
||
<button id="popup-add-context-btn" class="btn btn-xs btn-outline btn-block hidden" style="margin-top: 6px;">+ Добавить эту цитату к карточке</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ChipDip-style Floating Feedback & Bug Report Widget -->
|
||
<div id="feedback-container" class="feedback-container">
|
||
<!-- Floating Launcher Button -->
|
||
<button id="feedback-trigger-btn" class="feedback-trigger-btn" title="Сообщить о баге или предложить идею (Dev Chat)" aria-label="Обратная связь">
|
||
<span class="feedback-trigger-icon">💬</span>
|
||
<span id="feedback-badge" class="feedback-badge hidden">0</span>
|
||
</button>
|
||
|
||
<!-- Floating Chat Window -->
|
||
<div id="feedback-widget" class="feedback-widget hidden" role="dialog" aria-labelledby="feedback-widget-title">
|
||
<div class="feedback-widget-header">
|
||
<div class="feedback-header-left">
|
||
<span class="feedback-header-icon">💬</span>
|
||
<div>
|
||
<div id="feedback-widget-title" class="feedback-header-title">Dev Feedback & Баги</div>
|
||
<div class="feedback-header-sub">Синхронизируется с AI-ассистентом</div>
|
||
</div>
|
||
</div>
|
||
<button type="button" id="feedback-close-btn" class="feedback-close-btn" title="Закрыть (Esc)">✕</button>
|
||
</div>
|
||
|
||
<!-- Category Selector Tabs -->
|
||
<div class="feedback-category-bar">
|
||
<button type="button" class="feedback-cat-chip active" data-category="bug">🐛 Баг</button>
|
||
<button type="button" class="feedback-cat-chip" data-category="feature">💡 Фича</button>
|
||
<button type="button" class="feedback-cat-chip" data-category="note">📝 Заметка</button>
|
||
</div>
|
||
|
||
<!-- Auto Context Indicator -->
|
||
<div class="feedback-context-indicator" id="feedback-context-indicator">
|
||
<span class="context-icon">📍</span>
|
||
<span id="feedback-context-text" class="context-text">Определение контекста...</span>
|
||
</div>
|
||
|
||
<!-- Chat / Reports Feed -->
|
||
<div id="feedback-messages-list" class="feedback-messages-list">
|
||
<div class="feedback-empty-state" id="feedback-empty-state">
|
||
<span class="empty-icon">📝</span>
|
||
<p>Нашли баг или есть идея для фичи?</p>
|
||
<small>Напишите сообщение ниже — оно сразу попадет в систему задач AI-разработчика.</small>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Input Area -->
|
||
<form id="feedback-form" class="feedback-input-form">
|
||
<textarea
|
||
id="feedback-input"
|
||
class="feedback-textarea"
|
||
placeholder="Опишите баг или идею... (Enter для отправки, Shift+Enter для новой строки)"
|
||
rows="2"
|
||
required
|
||
></textarea>
|
||
<div class="feedback-form-bottom">
|
||
<span class="feedback-hint">Enter — отправить</span>
|
||
<button type="submit" id="feedback-send-btn" class="feedback-send-btn" title="Отправить репорт">
|
||
<span class="send-icon">➤</span>
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Audio Element for native streaming -->
|
||
<audio id="global-audio-player" preload="none"></audio>
|
||
|
||
<script type="module" src="/static/js/app.js?v=6.6"></script>
|
||
</body>
|
||
</html>
|
||
|