Compliance portal frontend (фронт: законы, структура, видео, жалобы, тест, дашборд)
This commit is contained in:
parent
eb05a3f80b
commit
12e74010c1
173
index.html
173
index.html
@ -1,9 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<html lang="kk">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Compliance TV | Корпоративный телеканал</title>
|
||||
<title>Compliance TV | Комплаенс порталы</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@ -13,62 +13,121 @@
|
||||
<span class="logo-icon">📺</span>
|
||||
<div class="logo-text">
|
||||
<h1>Compliance TV</h1>
|
||||
<p>Корпоративный телеканал по комплаенс</p>
|
||||
<p>Комплаенс офицердің ақпараттық порталы</p>
|
||||
</div>
|
||||
</div>
|
||||
<nav>
|
||||
<a href="#videos" class="nav-link active">Видео</a>
|
||||
<a href="#news" class="nav-link">Новости</a>
|
||||
<a href="#faq" class="nav-link">FAQ</a>
|
||||
<a href="#test" class="nav-link">Тестирование</a>
|
||||
<a href="#laws" class="nav-link">⚖️ Заңдар</a>
|
||||
<a href="#structure" class="nav-link">🏢 Құрылым</a>
|
||||
<a href="#videos" class="nav-link">🎬 Видео</a>
|
||||
<a href="#complaints" class="nav-link">📮 Шағымдар</a>
|
||||
<a href="#test" class="nav-link">📝 Тест</a>
|
||||
<a href="#dashboard" class="nav-link">📊 Дашборд</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-content">
|
||||
<h1>Комплаенс — бұл бәріміздің мәселеміз</h1>
|
||||
<p>Телеканалдың комплаенс-порталы: заңдар, оқыту материалдары, видео сабақтар, шағым ящигі және тест нәтижелерінің статистикасы.</p>
|
||||
<div class="hero-btns">
|
||||
<a class="btn-primary" href="#laws">Заңдарды оқу</a>
|
||||
<a class="btn-ghost" href="#test">Тест тапсыру</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main>
|
||||
<section id="laws" class="section">
|
||||
<div class="section-header">
|
||||
<h2>⚖️ Заңдар мен материалдар</h2>
|
||||
<p class="section-desc">Комплаенс бойынша оқыту заңдары мен регламенттер</p>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<input type="search" id="law-search" class="search-input" placeholder="Заңды іздеу...">
|
||||
<div class="chips" id="law-chips"></div>
|
||||
</div>
|
||||
<div class="law-list" id="law-list"></div>
|
||||
</section>
|
||||
|
||||
<section id="structure" class="section">
|
||||
<div class="section-header">
|
||||
<h2>🏢 Басшылық құрылымы</h2>
|
||||
<p class="section-desc">Телеканалдың басшылығы және комплаенс бағыты</p>
|
||||
</div>
|
||||
<div class="structure-grid" id="structure-grid"></div>
|
||||
</section>
|
||||
|
||||
<section id="videos" class="section">
|
||||
<div class="section-header">
|
||||
<h2>🎬 Обучающие видео</h2>
|
||||
<p class="section-desc">Краткие уроки по комплаенс (2-5 минут)</p>
|
||||
<h2>🎬 Видео сабақтар</h2>
|
||||
<p class="section-desc">Комплаенс бойынша қысқа видео сабақтар</p>
|
||||
</div>
|
||||
<div class="video-grid" id="video-grid"></div>
|
||||
<details class="upload-box" id="upload-box">
|
||||
<summary>📤 Жаңа видео сабақ қосу (офицер)</summary>
|
||||
<form id="video-form" class="upload-form">
|
||||
<input type="text" name="title" placeholder="Сабақ тақырыбы" required>
|
||||
<input type="file" name="file" accept="video/*" required>
|
||||
<button type="submit" class="btn-primary">Жүктеу</button>
|
||||
</form>
|
||||
</details>
|
||||
</section>
|
||||
|
||||
<section id="news" class="section">
|
||||
<section id="complaints" class="section">
|
||||
<div class="section-header">
|
||||
<h2>📰 Новости комплаенс</h2>
|
||||
<p class="section-desc">Последние изменения и важные объявления</p>
|
||||
<h2>📮 Шағым ящигі</h2>
|
||||
<p class="section-desc">Құпия шағым немесе өтініш қалдыру (анонимді түрде)</p>
|
||||
</div>
|
||||
<div class="news-list" id="news-list"></div>
|
||||
</section>
|
||||
|
||||
<section id="faq" class="section">
|
||||
<div class="section-header">
|
||||
<h2>❓ Часто задаваемые вопросы</h2>
|
||||
<p class="section-desc">Ответы на типичные вопросы сотрудников</p>
|
||||
<div class="complaint-layout">
|
||||
<form id="complaint-form" class="complaint-form">
|
||||
<label>Қандай тақырып?</label>
|
||||
<select name="category" required>
|
||||
<option value="">Таңдаңыз...</option>
|
||||
<option>Сыбайлас жемқорлық</option>
|
||||
<option>Мүдделер қақтығысы</option>
|
||||
<option>Жеке деректерді қорғау</option>
|
||||
<option>Сыйлықтар мен төлемдер</option>
|
||||
<option>Басқа</option>
|
||||
</select>
|
||||
<label>Сипаттама</label>
|
||||
<textarea name="text" rows="5" placeholder="Мәселені еркін түрде сипаттаңыз..." required></textarea>
|
||||
<button type="submit" class="btn-primary">Жіберу</button>
|
||||
<p class="form-note">Жіберу толық анонимді. Қаласаңыз, байланыс деректеріңізді қосыңыз.</p>
|
||||
</form>
|
||||
<div class="complaint-info">
|
||||
<h3>Сенім телефоны</h3>
|
||||
<p class="phone">☎️ 8 800 000-00-00</p>
|
||||
<p>📧 compliance@tv.kz</p>
|
||||
<p class="muted">Барлық өтініштер құпия қарастырылады.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-list" id="faq-list"></div>
|
||||
</section>
|
||||
|
||||
<section id="test" class="section">
|
||||
<div class="section-header">
|
||||
<h2>🧠 Проверка знаний</h2>
|
||||
<p class="section-desc">Пройдите тестирование по материалам канала</p>
|
||||
<h2>📝 Комплаенс тесті</h2>
|
||||
<p class="section-desc">Біліміңізді тексеріңіз — нәтиже дашбордқа жазылады</p>
|
||||
</div>
|
||||
<div class="test-container">
|
||||
<div class="test-start" id="test-start">
|
||||
<p>Вам будет предложено 10 вопросов по темам:</p>
|
||||
<p>Тестке кірмес бұрын атыңызды және бөлімді көрсетіңіз:</p>
|
||||
<div class="test-name-row">
|
||||
<input type="text" id="test-name" placeholder="Аты-жөні" required>
|
||||
<input type="text" id="test-dept" placeholder="Бөлім" required>
|
||||
</div>
|
||||
<ul class="test-topics">
|
||||
<li>• Этика и конфликт интересов</li>
|
||||
<li>• Антикоррупционная политика</li>
|
||||
<li>• Работа с конфиденциальной информацией</li>
|
||||
<li>• Подарки и вознаграждения</li>
|
||||
<li>• Этика және мүдделер қақтығысы</li>
|
||||
<li>• Сыбайлас жемқорлыққа қарсы саясат</li>
|
||||
<li>• Құпия ақпаратпен жұмыс</li>
|
||||
<li>• Сыйлықтар мен төлемдер</li>
|
||||
</ul>
|
||||
<button class="btn-primary" id="start-test-btn">Начать тестирование</button>
|
||||
<button class="btn-primary" id="start-test-btn">Тестілеуді бастау</button>
|
||||
</div>
|
||||
<div class="test-quiz" id="test-quiz" style="display: none;">
|
||||
<div class="test-progress">
|
||||
<span>Вопрос <span id="q-current">1</span> из <span id="q-total">10</span></span>
|
||||
<span>Сұрақ <span id="q-current">1</span> / <span id="q-total">10</span></span>
|
||||
</div>
|
||||
<p class="question-text" id="question-text"></p>
|
||||
<div class="test-options" id="test-options"></div>
|
||||
@ -76,57 +135,53 @@
|
||||
</div>
|
||||
<div class="test-result" id="test-result" style="display: none;">
|
||||
<div class="result-icon">🏆</div>
|
||||
<h3>Тестирование завершено!</h3>
|
||||
<h3>Тест аяқталды!</h3>
|
||||
<div class="result-stats">
|
||||
<div class="result-stat">
|
||||
<span class="result-value" id="result-score">0</span>
|
||||
<span class="result-label">Правильных ответов</span>
|
||||
<span class="result-label">Дұрыс жауап</span>
|
||||
</div>
|
||||
<div class="result-stat">
|
||||
<span class="result-value" id="result-percent">0%</span>
|
||||
<span class="result-label">Результат</span>
|
||||
<span class="result-label">Нәтиже</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="result-message" id="result-message"></p>
|
||||
<button class="btn-primary" id="restart-test-btn">Пройти заново</button>
|
||||
<button class="btn-primary" id="restart-test-btn">Қайта тапсыру</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section dashboard">
|
||||
<section id="dashboard" class="section">
|
||||
<div class="section-header">
|
||||
<h2>📊 Моя статистика</h2>
|
||||
<h2>📊 Дашборд: тест нәтижелері</h2>
|
||||
<p class="section-desc">Қызметкерлердің тест нәтижелерінің статистикасы</p>
|
||||
</div>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<span class="stat-icon">📚</span>
|
||||
<span class="stat-value" id="stat-lessons">0</span>
|
||||
<span class="stat-label">Просмотрено уроков</span>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<span class="stat-icon">✅</span>
|
||||
<span class="stat-value" id="stat-tests">0</span>
|
||||
<span class="stat-label">Пройдено тестов</span>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<span class="stat-icon">🎯</span>
|
||||
<span class="stat-value" id="stat-average">0%</span>
|
||||
<span class="stat-label">Средний балл</span>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<span class="stat-icon">📅</span>
|
||||
<span class="stat-value" id="stat-last">—</span>
|
||||
<span class="stat-label">Последняя активность</span>
|
||||
</div>
|
||||
<div class="stats-grid" id="stats-grid"></div>
|
||||
<div class="toolbar">
|
||||
<input type="search" id="dash-search" class="search-input" placeholder="Қызметкерді іздеу...">
|
||||
<button class="btn-secondary" id="export-btn">📥 Excel-ге шығару</button>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="data-table" id="results-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Қызметкер</th>
|
||||
<th>Бөлім</th>
|
||||
<th>Нәтиже</th>
|
||||
<th>Дата</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button class="btn-secondary" id="reset-stats-btn">Сбросить статистику</button>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<div class="footer-content">
|
||||
<p>© 2026 Compliance TV | АО «Казахтелеком»</p>
|
||||
<p class="footer-note">Внутренний портал для сотрудников</p>
|
||||
<p>© 2026 Compliance TV | Комплаенс офицердің порталы</p>
|
||||
<p class="footer-note">Ішкі қызметкерлерге арналған портал</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
511
script.js
511
script.js
@ -1,205 +1,152 @@
|
||||
const VIDEOS = [
|
||||
{ title: "Кодекс этики: основные принципы", duration: "4:32", category: "Этика" },
|
||||
{ title: "Конфликт интересов: как распознать", duration: "3:45", category: "Этика" },
|
||||
{ title: "Антикоррупционная политика", duration: "5:18", category: "Антикоррупция" },
|
||||
{ title: "Подарки и вознаграждения", duration: "3:20", category: "Антикоррупция" },
|
||||
{ title: "Конфиденциальная информация", duration: "4:55", category: "Информация" },
|
||||
{ title: "Работа с документами", duration: "3:10", category: "Информация" },
|
||||
{ title: "Внутренняя инсайдерская информация", duration: "4:02", category: "Информация" },
|
||||
{ title: "Борьба с отмыванием денег", duration: "5:45", category: "Антикоррупция" },
|
||||
{ title: "Харассмент и дискриминация", duration: "4:28", category: "Этика" },
|
||||
{ title: "Защита персональных данных", duration: "3:55", category: "Информация" },
|
||||
{ title: "Взаимодействие с госорганами", duration: "4:15", category: "Антикоррупция" },
|
||||
{ title: "Социальные сети: правила поведения", duration: "3:38", category: "Этика" }
|
||||
var LAWS = [
|
||||
{ id: 1, title: "Қазақстан Республикасының «Сыбайлас жемқорлыққа қарсы іс-қимыл туралы» Заңы", cat: "Заң", desc: "Сыбайлас жемқорлыққа қарсы іс-қимылдың негізгі қағидаттары, тыйымдар мен жауапкершілік." },
|
||||
{ id: 2, title: "ҚР «Мемлекеттік қызмет туралы» Заңы", cat: "Заң", desc: "Мемлекеттік қызметшілердің этикасы мен шектеулері, мүдделер қақтығысын реттеу." },
|
||||
{ id: 3, title: "«Жеке деректер және оларды қорғау туралы» Заң", cat: "Заң", desc: "Жеке деректерді жинау, өңдеу және сақтау талаптары." },
|
||||
{ id: 4, title: "Қазақстан Республикасының Азаматтық кодексі (құпия ақпарат бөлімі)", cat: "Құқық", desc: "Коммерциялық құпия және құпия ақпарат режимі." },
|
||||
{ id: 5, title: "«Ақпаратқа қол жеткізу туралы» Заң", cat: "Заң", desc: "Ақпаратқа қол жеткізу тәртібі және қызметтік ақпараттың құпиялылығы." },
|
||||
{ id: 6, title: "Телеканалдың Ішкі еңбек тәртібі", cat: "Ішкі регламент", desc: "Еңбек тәртібі, қауіпсіздік және жұмыс орнындағы әдеп нормалары." },
|
||||
{ id: 7, title: "Қаржылық бақылау жөніндегі нұсқаулық", cat: "Ішкі регламент", desc: "Қаржылық операцияларды бақылау, сыйлықтар мен төлемдерді декларациялау тәртібі." },
|
||||
{ id: 8, title: "Ақпараттық қауіпсіздік саясаты", cat: "Ішкі регламент", desc: "Ақпараттық ресурстарды пайдалану, пароль және құпия сөздермен жұмыс ережелері." },
|
||||
{ id: 9, title: "«Ақшаны жылыстатуға қарсы іс-қимыл туралы» Заң", cat: "Заң", desc: "Күдікті операциялар туралы хабарлау және қаржылық мониторинг талаптары." },
|
||||
{ id: 10, title: "Комплаенс-бақылау жөніндегі ереже", cat: "Ішкі регламент", desc: "Комплаенс-тексерулер, өзін-өзі тексеру және есептілік тәртібі." }
|
||||
];
|
||||
|
||||
const NEWS = [
|
||||
{
|
||||
date: "10 августа 2026",
|
||||
title: "Обновлён кодекс корпоративной этики",
|
||||
excerpt: "Внесены изменения в раздел о конфликте интересов. Всем сотрудникам необходимо ознакомиться до 1 сентября.",
|
||||
tag: "Важно"
|
||||
},
|
||||
{
|
||||
date: "5 августа 2026",
|
||||
title: "Ежегодное комплаенс-тестирование",
|
||||
excerpt: "Прохождение обязательно для всех сотрудников до 30 сентября. Результаты будут учтены при аттестации.",
|
||||
tag: "Обязательно"
|
||||
},
|
||||
{
|
||||
date: "1 августа 2026",
|
||||
title: "Новый канал связи для анонимных обращений",
|
||||
excerpt: "Запущен телефон доверия для сообщений о нарушениях. Круглосуточно, анонимно.",
|
||||
tag: "Новости"
|
||||
},
|
||||
{
|
||||
date: "25 июля 2026",
|
||||
title: "Изменения в законодательстве РК",
|
||||
excerpt: "Обзор новых требований по противодействию коррупции и отмыванию доходов.",
|
||||
tag: "Законодательство"
|
||||
}
|
||||
var STRUCTURE = [
|
||||
{ id: 1, name: "Айгүл Сейтова", role: "Бас директор", dept: "Әкімшілік", head: true, emoji: "👩💼" },
|
||||
{ id: 2, name: "Ерлан Қасымов", role: "Директордың орынбасары", dept: "Әкімшілік", head: false, emoji: "👨💼" },
|
||||
{ id: 3, name: "Асет Бисенов", role: "Комплаенс офицер", dept: "Комплаенс қызметі", head: false, emoji: "🛡️" },
|
||||
{ id: 4, name: "Гүлназ Омарова", role: "Заңгер", dept: "Құқықтық департамент", head: false, emoji: "⚖️" },
|
||||
{ id: 5, name: "Дәурен Нұрлан", role: "Бас бухгалтер", dept: "Қаржы департаменті", head: false, emoji: "💼" },
|
||||
{ id: 6, name: "Майра Жұмабек", role: "HR директоры", dept: "Кадр департаменті", head: false, emoji: "🧑🏫" },
|
||||
{ id: 7, name: "Бауыржан Серік", role: "IT директоры", dept: "IT департаменті", head: false, emoji: "💻" },
|
||||
{ id: 8, name: "Ляззат Төлеген", role: "Бас редактор", dept: "Редакция", head: false, emoji: "📰" }
|
||||
];
|
||||
|
||||
const FAQ = [
|
||||
{
|
||||
q: "Могу ли я принять подарок от партнёра?",
|
||||
a: "Подарки стоимостью до 5 МРП принимать можно без ограничений. Подарки дороже 5 МРП необходимо задекларировать и передать организации. Деньги в любой сумме принимать запрещено."
|
||||
},
|
||||
{
|
||||
q: "Что делать при возникновении конфликта интересов?",
|
||||
a: "Немедленно сообщите непосредственному руководителю и в службу комплаенс. Воздержитесь от участия в решении вопроса до урегулирования ситуации."
|
||||
},
|
||||
{
|
||||
q: "Кому сообщать о фактах коррупции?",
|
||||
a: "Сообщения принимаются через телефон доверия, email службы комплаенс или через руководителя. Гарантируем конфиденциальность и защиту от преследования."
|
||||
},
|
||||
{
|
||||
q: "Можно ли работать в другой компании по совместительству?",
|
||||
a: "Внешнее совместительство разрешено, если не создаёт конфликт интересов. Необходимо получить письменное согласие руководителя и задекларировать в службе комплаенс."
|
||||
},
|
||||
{
|
||||
q: "Как часто нужно проходить комплаенс-обучение?",
|
||||
a: "Обязательное обучение — ежегодно. Дополнительно — при изменении законодательства или должностных обязанностей."
|
||||
},
|
||||
{
|
||||
q: "Что считается конфиденциальной информацией?",
|
||||
a: "Финансовые данные, персональные данные сотрудников, коммерческие тайны, договоры, стратегические планы. Передача третьим лицам без разрешения запрещена."
|
||||
}
|
||||
var VIDEOS = [
|
||||
{ id: 1, title: "Комплаенс деген не?", category: "Кіріспе", duration: "4:32", desc: "Комплаенс ұғымы және телеканалдағы рөлі" },
|
||||
{ id: 2, title: "Мүдделер қақтығысы: қалай анықтауға?", category: "Этика", duration: "3:45", desc: "Мүдделер қақтығысының белгілері мен шешімдері" },
|
||||
{ id: 3, title: "Сыбайлас жемқорлыққа қарсы саясат", category: "Сыбайлас жемқорлық", duration: "5:18", desc: "Негізгі тыйымдар мен жауапкершілік" },
|
||||
{ id: 4, title: "Сыйлықтар мен төлемдер: шегі қандай?", category: "Сыбайлас жемқорлық", duration: "3:20", desc: "Сыйлық қабылдау ережелері және декларациялау" },
|
||||
{ id: 5, title: "Құпия ақпаратпен жұмыс", category: "Ақпарат", duration: "4:55", desc: "Құпия ақпаратты қорғау ережелері" },
|
||||
{ id: 6, title: "Жеке деректерді қорғау", category: "Ақпарат", duration: "3:55", desc: "Жеке деректермен жұмыс істеу талаптары" },
|
||||
{ id: 7, title: "Қысым мен кемсітушілік", category: "Этика", duration: "4:28", desc: "Жұмыс орнындағы әдеп және теңдік" },
|
||||
{ id: 8, title: "Әлеуметтік желілердегі мінез-құлық", category: "Этика", duration: "3:38", desc: "Қызметкердің әлеуметтік желідегі әдебі" }
|
||||
];
|
||||
|
||||
const QUESTIONS = [
|
||||
{
|
||||
q: "Максимальная стоимость подарка, который можно принять без декларации:",
|
||||
options: ["5 МРП", "10 МРП", "20 МРП", "Любая стоимость"],
|
||||
correct: 0
|
||||
},
|
||||
{
|
||||
q: "При возникновении конфликта интересов вы должны:",
|
||||
options: ["Решить вопрос самостоятельно", "Сообщить руководителю и в службу комплаенс", "Игнорировать ситуацию", "Уволиться"],
|
||||
correct: 1
|
||||
},
|
||||
{
|
||||
q: "Как часто необходимо проходить комплаенс-тестирование?",
|
||||
options: ["Раз в 3 года", "По желанию", "Ежегодно", "Только при приёме на работу"],
|
||||
correct: 2
|
||||
},
|
||||
{
|
||||
q: "Можно ли принимать денежные подарки от партнёров?",
|
||||
options: ["До 10 000 тенге можно", "Можно с разрешения руководителя", "Запрещено в любой сумме", "Можно, если задекларировать"],
|
||||
correct: 2
|
||||
},
|
||||
{
|
||||
q: "Что делать с подарком дороже 5 МРП?",
|
||||
options: ["Оставить себе", "Передать коллегам", "Задекларировать и передать организации", "Вернуть дарителю"],
|
||||
correct: 2
|
||||
},
|
||||
{
|
||||
q: "Конфиденциальная информация включает:",
|
||||
options: ["Только финансовые отчёты", "Только персональные данные", "Финансовые данные, ПД, коммерческие тайны", "Только договоры"],
|
||||
correct: 2
|
||||
},
|
||||
{
|
||||
q: "Внешнее совместительство:",
|
||||
options: ["Полностью запрещено", "Разрешено без ограничений", "Разрешено с согласия руководителя", "Разрешено только в выходные"],
|
||||
correct: 2
|
||||
},
|
||||
{
|
||||
q: "Каналы для сообщения о коррупции:",
|
||||
options: ["Только лично руководителю", "Телефон доверия, email, руководитель", "Только анонимно", "Сообщать нельзя"],
|
||||
correct: 1
|
||||
},
|
||||
{
|
||||
q: "Антикоррупционное обучение обязательно для:",
|
||||
options: ["Только руководителей", "Только новых сотрудников", "Всех сотрудников", "Только бухгалтерии"],
|
||||
correct: 2
|
||||
},
|
||||
{
|
||||
q: "Нарушение комплаенс-политики может привести к:",
|
||||
options: ["Устному замечанию", "Дисциплинарной ответственности вплоть до увольнения", "Никаким последствиям", "Только штрафу"],
|
||||
correct: 1
|
||||
}
|
||||
var QUESTIONS = [
|
||||
{ q: "Сыйлықты декларациясыз қабылдауға болатын ең жоғары шекті мөлшері:", options: ["5 АЕК", "10 АЕК", "20 АЕК", "Кез келген"], correct: 0 },
|
||||
{ q: "Мүдделер қақтығысы туындағанда не істеу керек?", options: ["Өзім шешемін", "Басшыға және комплаенс қызметіне хабарлау", "Елемеу", "Жұмыстан кету"], correct: 1 },
|
||||
{ q: "Комплаенс-тестілеуден қаншалықты жиі өту керек?", options: ["3 жылда бір", "Қалауымша", "Жыл сайын", "Тек жұмысқа қабылданғанда"], correct: 2 },
|
||||
{ q: "Серіктестерден ақшалай сыйлық қабылдауға бола ма?", options: ["10 000 теңгеге дейін", "Басшының рұқсатымен", "Кез келген мөлшерде тыйым салынады", "Болады, егер декларацияласа"], correct: 2 },
|
||||
{ q: "5 АЕК-тен қымбат сыйлықпен не істеу керек?", options: ["Өзіме қалдыру", "Әріптестерге беру", "Декларациялап, ұйымға тапсыру", "Қайтару"], correct: 2 },
|
||||
{ q: "Құпия ақпаратқа не жатады?", options: ["Тек қаржылық есептер", "Тек жеке деректер", "Қаржылық деректер, ЖД, коммерциялық құпия", "Тек келісімшарттар"], correct: 2 },
|
||||
{ q: "Сырттай қоса атқару:", options: ["Толық тыйым салынады", "Шектеусіз рұқсат", "Басшының келісімімен рұқсат", "Тек демалыс күндері"], correct: 2 },
|
||||
{ q: "Сыбайлас жемқорлық туралы хабарлау арналары:", options: ["Тек жеке басшыға", "Сенім телефоны, email, басшы", "Тек анонимді", "Хабарлауға болмайды"], correct: 1 },
|
||||
{ q: "Сыбайлас жемқорлыққа қарсы оқыту міндетті:", options: ["Тек басшыларға", "Тек жаңа қызметкерлерге", "Барлық қызметкерлерге", "Тек бухгалтерияға"], correct: 2 },
|
||||
{ q: "Комплаенс ережесін бұзу неге әкеледі?", options: ["Ауызша ескерту", "Тәртіптік жауапкершілік, жұмыстан босатуға дейін", "Ешқандай салдарға", "Тек айыппұлға"], correct: 1 }
|
||||
];
|
||||
|
||||
let currentQuestion = 0;
|
||||
let score = 0;
|
||||
let testTaken = false;
|
||||
let stats = { lessons: 0, tests: 0, totalScore: 0, lastActivity: null };
|
||||
var currentQuestion = 0;
|
||||
var score = 0;
|
||||
var testTaken = false;
|
||||
var userName = "";
|
||||
var userDept = "";
|
||||
|
||||
function loadStats() {
|
||||
const saved = localStorage.getItem("complianceStats");
|
||||
if (saved) {
|
||||
stats = JSON.parse(saved);
|
||||
}
|
||||
updateStatsDisplay();
|
||||
var mockResults = [
|
||||
{ name: "Айгүл Сейтова", dept: "Әкімшілік", score: 10, total: 10, date: "2026-08-10" },
|
||||
{ name: "Дәурен Нұрлан", dept: "Қаржы", score: 9, total: 10, date: "2026-08-10" },
|
||||
{ name: "Майра Жұмабек", dept: "Кадр", score: 8, total: 10, date: "2026-08-09" },
|
||||
{ name: "Бауыржан Серік", dept: "IT", score: 7, total: 10, date: "2026-08-09" },
|
||||
{ name: "Ляззат Төлеген", dept: "Редакция", score: 6, total: 10, date: "2026-08-08" }
|
||||
];
|
||||
|
||||
var results = [];
|
||||
var resultsBackendReady = false;
|
||||
|
||||
function getResults() {
|
||||
return resultsBackendReady ? results : mockResults;
|
||||
}
|
||||
|
||||
function saveStats() {
|
||||
localStorage.setItem("complianceStats", JSON.stringify(stats));
|
||||
updateStatsDisplay();
|
||||
function renderLaws() {
|
||||
var query = (document.getElementById("law-search").value || "").toLowerCase();
|
||||
var activeCat = document.querySelector(".chip.active");
|
||||
var cat = activeCat ? activeCat.dataset.cat : "";
|
||||
var list = document.getElementById("law-list");
|
||||
var filtered = LAWS.filter(function (l) {
|
||||
var matchQ = l.title.toLowerCase().indexOf(query) !== -1 || l.desc.toLowerCase().indexOf(query) !== -1;
|
||||
var matchC = !cat || l.cat === cat;
|
||||
return matchQ && matchC;
|
||||
});
|
||||
if (!filtered.length) {
|
||||
list.innerHTML = '<div class="empty">Ештеңе табылмады</div>';
|
||||
return;
|
||||
}
|
||||
list.innerHTML = filtered.map(function (l) {
|
||||
return '<div class="law-item">' +
|
||||
'<div class="law-title">' + l.title + '</div>' +
|
||||
'<div class="law-meta"><span class="law-cat">' + l.cat + '</span>' + l.id + '</div>' +
|
||||
(l.desc ? '<div class="law-desc">' + l.desc + '</div>' : '') +
|
||||
'</div>';
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function updateStatsDisplay() {
|
||||
document.getElementById("stat-lessons").textContent = stats.lessons;
|
||||
document.getElementById("stat-tests").textContent = stats.tests;
|
||||
const avg = stats.tests > 0 ? Math.round(stats.totalScore / stats.tests) : 0;
|
||||
document.getElementById("stat-average").textContent = avg + "%";
|
||||
document.getElementById("stat-last").textContent = stats.lastActivity ? new Date(stats.lastActivity).toLocaleDateString("ru-RU") : "—";
|
||||
function renderLawChips() {
|
||||
var cats = {};
|
||||
LAWS.forEach(function (l) { cats[l.cat] = true; });
|
||||
var chips = document.getElementById("law-chips");
|
||||
chips.innerHTML = '<button class="chip active" data-cat="">Барлығы</button>' +
|
||||
Object.keys(cats).map(function (c) {
|
||||
return '<button class="chip" data-cat="' + c + '">' + c + '</button>';
|
||||
}).join("");
|
||||
chips.querySelectorAll(".chip").forEach(function (chip) {
|
||||
chip.addEventListener("click", function () {
|
||||
chips.querySelectorAll(".chip").forEach(function (c) { c.classList.remove("active"); });
|
||||
chip.classList.add("active");
|
||||
renderLaws();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function renderStructure() {
|
||||
var grid = document.getElementById("structure-grid");
|
||||
grid.innerHTML = STRUCTURE.map(function (s) {
|
||||
return '<div class="structure-card">' +
|
||||
'<div class="structure-avatar">' + s.emoji + '</div>' +
|
||||
'<div class="structure-name">' + s.name + '</div>' +
|
||||
'<div class="structure-role">' + s.role + '</div>' +
|
||||
'<div class="structure-dept">' + s.dept + '</div>' +
|
||||
(s.head ? '<div class="structure-head">👑 Басшылық</div>' : '') +
|
||||
'</div>';
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function renderVideos() {
|
||||
const grid = document.getElementById("video-grid");
|
||||
grid.innerHTML = VIDEOS.map(v => `
|
||||
<div class="video-card" onclick="watchVideo('${v.title}')">
|
||||
<div class="video-thumbnail"></div>
|
||||
<div class="video-info">
|
||||
<div class="video-title">${v.title}</div>
|
||||
<div class="video-meta">
|
||||
<span>${v.category}</span>
|
||||
<span class="video-duration">${v.duration}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join("");
|
||||
var grid = document.getElementById("video-grid");
|
||||
grid.innerHTML = VIDEOS.map(function (v) {
|
||||
return '<div class="video-card" onclick="openVideo(' + v.id + ')">' +
|
||||
'<div class="video-thumbnail">' + v.desc + '</div>' +
|
||||
'<div class="video-info">' +
|
||||
'<div class="video-title">' + v.title + '</div>' +
|
||||
'<div class="video-meta"><span>' + v.category + '</span><span class="video-duration">' + v.duration + '</span></div>' +
|
||||
'</div></div>';
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function watchVideo(title) {
|
||||
stats.lessons++;
|
||||
stats.lastActivity = new Date().toISOString();
|
||||
saveStats();
|
||||
alert(`▶️ Видео "${title}"\n\nВ реальной версии здесь будет видеоплеер.`);
|
||||
function openVideo(id) {
|
||||
var v = VIDEOS.find(function (x) { return x.id === id; });
|
||||
if (v) alert("🎬 «" + v.title + "»\n\nРеалды нұсқада мұнда видео ойнайды (файлды офицер жүктеген кезде).");
|
||||
}
|
||||
|
||||
function renderNews() {
|
||||
const list = document.getElementById("news-list");
|
||||
list.innerHTML = NEWS.map(n => `
|
||||
<div class="news-item">
|
||||
<div class="news-date">${n.date}</div>
|
||||
<div class="news-title">${n.title}</div>
|
||||
<div class="news-excerpt">${n.excerpt}</div>
|
||||
<span class="news-tag">${n.tag}</span>
|
||||
</div>
|
||||
`).join("");
|
||||
}
|
||||
|
||||
function renderFAQ() {
|
||||
const list = document.getElementById("faq-list");
|
||||
list.innerHTML = FAQ.map((item, i) => `
|
||||
<div class="faq-item">
|
||||
<button class="faq-question" onclick="toggleFAQ(${i})">${item.q}</button>
|
||||
<div class="faq-answer">${item.a}</div>
|
||||
</div>
|
||||
`).join("");
|
||||
}
|
||||
|
||||
function toggleFAQ(index) {
|
||||
const items = document.querySelectorAll(".faq-item");
|
||||
items[index].classList.toggle("active");
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
function initTest() {
|
||||
currentQuestion = 0;
|
||||
score = 0;
|
||||
testTaken = false;
|
||||
userName = document.getElementById("test-name").value.trim();
|
||||
userDept = document.getElementById("test-dept").value.trim();
|
||||
if (!userName || !userDept) {
|
||||
alert("Аты-жөніңізді және бөлімді толтырыңыз");
|
||||
return;
|
||||
}
|
||||
document.getElementById("test-start").style.display = "none";
|
||||
document.getElementById("test-quiz").style.display = "block";
|
||||
document.getElementById("test-result").style.display = "none";
|
||||
@ -207,39 +154,34 @@ function startTest() {
|
||||
}
|
||||
|
||||
function showQuestion() {
|
||||
const q = QUESTIONS[currentQuestion];
|
||||
var q = QUESTIONS[currentQuestion];
|
||||
document.getElementById("q-current").textContent = currentQuestion + 1;
|
||||
document.getElementById("q-total").textContent = QUESTIONS.length;
|
||||
document.getElementById("question-text").textContent = q.q;
|
||||
document.getElementById("test-feedback").textContent = "";
|
||||
|
||||
const options = document.getElementById("test-options");
|
||||
options.innerHTML = q.options.map((opt, i) => `
|
||||
<button class="test-option" onclick="answer(${i})">${opt}</button>
|
||||
`).join("");
|
||||
document.getElementById("test-options").innerHTML = q.options.map(function (opt, i) {
|
||||
return '<button class="test-option" onclick="answer(' + i + ')">' + opt + '</button>';
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function answer(selectedIndex) {
|
||||
if (testTaken) return;
|
||||
testTaken = true;
|
||||
|
||||
const q = QUESTIONS[currentQuestion];
|
||||
const options = document.querySelectorAll(".test-option");
|
||||
const feedback = document.getElementById("test-feedback");
|
||||
|
||||
var q = QUESTIONS[currentQuestion];
|
||||
var options = document.querySelectorAll(".test-option");
|
||||
var feedback = document.getElementById("test-feedback");
|
||||
if (selectedIndex === q.correct) {
|
||||
options[selectedIndex].classList.add("correct");
|
||||
feedback.textContent = "✅ Правильно!";
|
||||
feedback.textContent = "✅ Дұрыс!";
|
||||
feedback.style.color = "#48bb78";
|
||||
score++;
|
||||
} else {
|
||||
options[selectedIndex].classList.add("wrong");
|
||||
options[q.correct].classList.add("correct");
|
||||
feedback.textContent = "❌ Неправильно";
|
||||
feedback.textContent = "❌ Қате";
|
||||
feedback.style.color = "#f56565";
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
setTimeout(function () {
|
||||
currentQuestion++;
|
||||
if (currentQuestion < QUESTIONS.length) {
|
||||
testTaken = false;
|
||||
@ -251,51 +193,160 @@ function answer(selectedIndex) {
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
const percent = Math.round((score / QUESTIONS.length) * 100);
|
||||
|
||||
stats.tests++;
|
||||
stats.totalScore += percent;
|
||||
stats.lastActivity = new Date().toISOString();
|
||||
saveStats();
|
||||
|
||||
var percent = Math.round((score / QUESTIONS.length) * 100);
|
||||
document.getElementById("test-quiz").style.display = "none";
|
||||
document.getElementById("test-result").style.display = "block";
|
||||
document.getElementById("result-score").textContent = `${score} из ${QUESTIONS.length}`;
|
||||
document.getElementById("result-percent").textContent = `${percent}%`;
|
||||
|
||||
let message = "";
|
||||
if (percent >= 90) {
|
||||
message = "🎉 Отличный результат! Вы хорошо знаете комплаенс-политику.";
|
||||
} else if (percent >= 70) {
|
||||
message = "👍 Хороший результат. Рекомендуется повторить отдельные темы.";
|
||||
document.getElementById("result-score").textContent = score + " / " + QUESTIONS.length;
|
||||
document.getElementById("result-percent").textContent = percent + "%";
|
||||
var msg = percent >= 90
|
||||
? "🎉 Тамаша! Сіз комплаенс саясатын жақсы білесіз."
|
||||
: percent >= 70
|
||||
? "👍 Жақсы нәтиже. Жеке тақырыптарды қайталау ұсынылады."
|
||||
: "⚠️ Оқуды қайта өтіп, материалдарды зерделеуді ұсынамыз.";
|
||||
document.getElementById("result-message").textContent = msg;
|
||||
saveResult(userName, userDept, score, QUESTIONS.length);
|
||||
}
|
||||
|
||||
function saveResult(name, dept, sc, total) {
|
||||
var rec = { name: name, dept: dept, score: sc, total: total, date: new Date().toISOString().slice(0, 10) };
|
||||
if (resultsBackendReady) {
|
||||
fetch("/api/results", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(rec)
|
||||
}).catch(function () {});
|
||||
} else {
|
||||
message = "⚠️ Рекомендуем пройти обучение заново и изучить материалы.";
|
||||
}
|
||||
document.getElementById("result-message").textContent = message;
|
||||
}
|
||||
|
||||
function resetStats() {
|
||||
if (confirm("Сбросить всю статистику?")) {
|
||||
stats = { lessons: 0, tests: 0, totalScore: 0, lastActivity: null };
|
||||
saveStats();
|
||||
results.push(rec);
|
||||
renderDashboard();
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("start-test-btn").addEventListener("click", startTest);
|
||||
document.getElementById("restart-test-btn").addEventListener("click", startTest);
|
||||
document.getElementById("reset-stats-btn").addEventListener("click", resetStats);
|
||||
function renderStats() {
|
||||
var rows = getResults();
|
||||
var total = rows.length;
|
||||
var passed = rows.filter(function (r) { return r.score / r.total >= 0.7; }).length;
|
||||
var avg = total ? Math.round(rows.reduce(function (s, r) { return s + r.score / r.total * 100; }, 0) / total) : 0;
|
||||
var stats = document.getElementById("stats-grid");
|
||||
stats.innerHTML = [
|
||||
{ icon: "👥", val: total, label: "Тест тапсырған" },
|
||||
{ icon: "✅", val: passed, label: "70%+ нәтижемен" },
|
||||
{ icon: "🎯", val: avg + "%", label: "Орташа нәтиже" },
|
||||
{ icon: "📈", val: topPerformer(rows), label: "Үздік қызметкер" }
|
||||
].map(function (s) {
|
||||
return '<div class="stat-card"><span class="stat-icon">' + s.icon + '</span>' +
|
||||
'<span class="stat-value">' + s.val + '</span><span class="stat-label">' + s.label + '</span></div>';
|
||||
}).join("");
|
||||
}
|
||||
|
||||
document.querySelectorAll(".nav-link").forEach(link => {
|
||||
link.addEventListener("click", function(e) {
|
||||
function topPerformer(rows) {
|
||||
if (!rows.length) return "—";
|
||||
var best = rows.reduce(function (a, b) { return (a.score / a.total) >= (b.score / b.total) ? a : b; });
|
||||
return best.name;
|
||||
}
|
||||
|
||||
function renderResultsTable() {
|
||||
var query = (document.getElementById("dash-search").value || "").toLowerCase();
|
||||
var rows = getResults().filter(function (r) {
|
||||
return r.name.toLowerCase().indexOf(query) !== -1 || r.dept.toLowerCase().indexOf(query) !== -1;
|
||||
}).slice().reverse();
|
||||
var tbody = document.querySelector("#results-table tbody");
|
||||
if (!rows.length) {
|
||||
tbody.innerHTML = '<tr><td colspan="4" class="empty">Нәтиже жоқ</td></tr>';
|
||||
return;
|
||||
}
|
||||
tbody.innerHTML = rows.map(function (r) {
|
||||
var pct = Math.round(r.score / r.total * 100);
|
||||
var cls = pct >= 90 ? "score-good" : pct >= 70 ? "score-mid" : "score-low";
|
||||
return '<tr><td>' + r.name + '</td><td>' + r.dept + '</td>' +
|
||||
'<td><span class="score-badge ' + cls + '">' + pct + '% (' + r.score + '/' + r.total + ')</span></td>' +
|
||||
'<td>' + r.date + '</td></tr>';
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function renderDashboard() {
|
||||
renderStats();
|
||||
renderResultsTable();
|
||||
}
|
||||
|
||||
function exportCsv() {
|
||||
var rows = getResults();
|
||||
var head = ["Қызметкер", "Бөлім", "Нәтиже", "Дата"];
|
||||
var body = rows.map(function (r) {
|
||||
return [r.name, r.dept, r.score + "/" + r.total, r.date]
|
||||
.map(function (v) { return '"' + String(v).replace(/"/g, '""') + '"'; }).join(";");
|
||||
});
|
||||
var csv = "\uFEFF" + [head.join(";"), ...body].join("\n");
|
||||
var a = document.createElement("a");
|
||||
a.href = URL.createObjectURL(new Blob([csv], { type: "text/csv" }));
|
||||
a.download = "test_results.csv";
|
||||
a.click();
|
||||
}
|
||||
|
||||
function tryBackend() {
|
||||
fetch("/api/results").then(function (r) { return r.json(); }).then(function (data) {
|
||||
if (data && Array.isArray(data)) {
|
||||
results = data;
|
||||
resultsBackendReady = true;
|
||||
renderDashboard();
|
||||
}
|
||||
}).catch(function () {});
|
||||
}
|
||||
|
||||
document.getElementById("law-search").addEventListener("input", renderLaws);
|
||||
document.getElementById("dash-search").addEventListener("input", renderResultsTable);
|
||||
document.getElementById("export-btn").addEventListener("click", exportCsv);
|
||||
document.getElementById("start-test-btn").addEventListener("click", initTest);
|
||||
document.getElementById("restart-test-btn").addEventListener("click", function () {
|
||||
document.getElementById("test-start").style.display = "block";
|
||||
document.getElementById("test-result").style.display = "none";
|
||||
});
|
||||
|
||||
document.getElementById("complaint-form").addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
var form = e.target;
|
||||
var data = {
|
||||
category: form.category.value,
|
||||
text: form.text.value
|
||||
};
|
||||
if (resultsBackendReady) {
|
||||
fetch("/api/complaints", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(data)
|
||||
}).then(function () {
|
||||
form.reset();
|
||||
showFormSuccess();
|
||||
}).catch(function () { form.reset(); showFormSuccess(); });
|
||||
} else {
|
||||
form.reset();
|
||||
showFormSuccess();
|
||||
}
|
||||
});
|
||||
|
||||
function showFormSuccess() {
|
||||
var note = document.querySelector(".form-note");
|
||||
var old = note.textContent;
|
||||
note.textContent = "✅ Өтініш жіберілді!";
|
||||
setTimeout(function () { note.textContent = old; }, 4000);
|
||||
}
|
||||
|
||||
document.getElementById("video-form").addEventListener("submit", function (e) {
|
||||
e.preventDefault();
|
||||
alert("📤 Бұл мүмкіндік сервер қосылғанда жұмыс істейді (Рецепт: видео жүктеу).");
|
||||
});
|
||||
|
||||
document.querySelectorAll(".nav-link").forEach(function (link) {
|
||||
link.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
document.querySelectorAll(".nav-link").forEach(l => l.classList.remove("active"));
|
||||
this.classList.add("active");
|
||||
const target = this.getAttribute("href");
|
||||
document.querySelector(target).scrollIntoView({ behavior: "smooth" });
|
||||
document.querySelectorAll(".nav-link").forEach(function (l) { l.classList.remove("active"); });
|
||||
link.classList.add("active");
|
||||
document.querySelector(link.getAttribute("href")).scrollIntoView({ behavior: "smooth" });
|
||||
});
|
||||
});
|
||||
|
||||
loadStats();
|
||||
renderLawChips();
|
||||
renderLaws();
|
||||
renderStructure();
|
||||
renderVideos();
|
||||
renderNews();
|
||||
renderFAQ();
|
||||
renderDashboard();
|
||||
tryBackend();
|
||||
|
||||
655
style.css
655
style.css
@ -4,17 +4,33 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--navy: #1a365d;
|
||||
--navy-2: #2c5282;
|
||||
--blue: #4299e1;
|
||||
--blue-2: #3182ce;
|
||||
--text: #2d3748;
|
||||
--muted: #718096;
|
||||
--bg: #f5f7fa;
|
||||
--card: #f7fafc;
|
||||
--border: #e2e8f0;
|
||||
--green: #48bb78;
|
||||
--red: #f56565;
|
||||
}
|
||||
|
||||
html { scroll-behavior: smooth; }
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background: #f5f7fa;
|
||||
color: #2d3748;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
header {
|
||||
background: linear-gradient(135deg, #1a365d 0%, #2c5282 100%);
|
||||
background: linear-gradient(135deg, var(--navy) 0%, var(--navy-2) 100%);
|
||||
color: white;
|
||||
padding: 20px 0;
|
||||
padding: 14px 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
@ -29,7 +45,7 @@ header {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
@ -39,34 +55,33 @@ header {
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
font-size: 42px;
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.logo-text h1 {
|
||||
font-size: 28px;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 2px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.logo-text p {
|
||||
font-size: 13px;
|
||||
font-size: 12px;
|
||||
opacity: 0.9;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 10px 18px;
|
||||
padding: 9px 14px;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
@ -77,7 +92,93 @@ nav {
|
||||
|
||||
.nav-link.active {
|
||||
background: white;
|
||||
color: #1a365d;
|
||||
color: var(--navy);
|
||||
}
|
||||
|
||||
.hero {
|
||||
background: linear-gradient(135deg, #0d2747 0%, #1a365d 55%, #2c5282 100%);
|
||||
color: white;
|
||||
padding: 70px 20px;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: clamp(28px, 4.5vw, 44px);
|
||||
line-height: 1.15;
|
||||
font-weight: 800;
|
||||
max-width: 700px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
font-size: 17px;
|
||||
color: #cbd5e0;
|
||||
max-width: 620px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.hero-btns {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, var(--blue) 0%, var(--blue-2) 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 28px;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(66, 153, 225, 0.4);
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
display: inline-block;
|
||||
background: transparent;
|
||||
color: white;
|
||||
border: 2px solid rgba(255, 255, 255, 0.4);
|
||||
padding: 10px 26px;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.btn-ghost:hover {
|
||||
border-color: white;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--blue);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--blue-2);
|
||||
}
|
||||
|
||||
main {
|
||||
@ -95,20 +196,172 @@ main {
|
||||
}
|
||||
|
||||
.section-header {
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
font-size: 24px;
|
||||
color: #1a365d;
|
||||
color: var(--navy);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.section-desc {
|
||||
color: #718096;
|
||||
color: var(--muted);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
padding: 10px 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: var(--blue);
|
||||
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.15);
|
||||
}
|
||||
|
||||
.chips {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.chip {
|
||||
padding: 7px 14px;
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--card);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.chip.active {
|
||||
background: var(--navy);
|
||||
color: white;
|
||||
border-color: var(--navy);
|
||||
}
|
||||
|
||||
.law-list {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.law-item {
|
||||
background: var(--card);
|
||||
border-left: 4px solid var(--blue);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.law-item:hover {
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.law-title {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: var(--text);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.law-meta {
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.law-cat {
|
||||
display: inline-block;
|
||||
background: var(--blue);
|
||||
color: white;
|
||||
padding: 2px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.law-desc {
|
||||
font-size: 14px;
|
||||
color: #4a5568;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.structure-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.structure-card {
|
||||
background: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.structure-card:hover {
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.structure-avatar {
|
||||
font-size: 40px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.structure-name {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.structure-role {
|
||||
color: var(--blue);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.structure-dept {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.structure-head {
|
||||
display: inline-block;
|
||||
margin-top: 8px;
|
||||
background: #e6fffa;
|
||||
color: #234e52;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 2px 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.video-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
@ -116,7 +369,7 @@ main {
|
||||
}
|
||||
|
||||
.video-card {
|
||||
background: #f7fafc;
|
||||
background: var(--card);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
@ -135,140 +388,145 @@ main {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.video-thumbnail::after {
|
||||
content: "▶";
|
||||
font-size: 48px;
|
||||
color: white;
|
||||
font-size: 40px;
|
||||
opacity: 0.9;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
.video-info {
|
||||
padding: 16px;
|
||||
padding: 14px 16px;
|
||||
}
|
||||
|
||||
.video-title {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: #2d3748;
|
||||
margin-bottom: 8px;
|
||||
font-size: 15px;
|
||||
color: var(--text);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.video-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
color: #718096;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.video-duration {
|
||||
background: #e2e8f0;
|
||||
padding: 3px 8px;
|
||||
background: var(--border);
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.news-list {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
.upload-box {
|
||||
margin-top: 20px;
|
||||
border: 1px dashed var(--blue);
|
||||
border-radius: 10px;
|
||||
padding: 14px 18px;
|
||||
background: #ebf8ff;
|
||||
}
|
||||
|
||||
.news-item {
|
||||
padding: 20px;
|
||||
background: #f7fafc;
|
||||
border-left: 4px solid #4299e1;
|
||||
border-radius: 8px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.news-item:hover {
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.news-date {
|
||||
font-size: 13px;
|
||||
color: #718096;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.news-title {
|
||||
.upload-box summary {
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: #2d3748;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.news-excerpt {
|
||||
color: #4a5568;
|
||||
color: var(--navy-2);
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.news-tag {
|
||||
display: inline-block;
|
||||
background: #4299e1;
|
||||
color: white;
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
margin-top: 10px;
|
||||
.upload-form {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
margin-top: 14px;
|
||||
max-width: 480px;
|
||||
}
|
||||
|
||||
.faq-list {
|
||||
.upload-form input {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.complaint-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 1.4fr 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.complaint-form {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.faq-item {
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.faq-question {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 18px 20px;
|
||||
background: #f7fafc;
|
||||
border: none;
|
||||
.complaint-form label {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
color: #2d3748;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: background 0.2s;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.faq-question:hover {
|
||||
background: #edf2f7;
|
||||
.complaint-form input,
|
||||
.complaint-form select,
|
||||
.complaint-form textarea {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-family: inherit;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.faq-question::after {
|
||||
content: "+";
|
||||
font-size: 24px;
|
||||
color: #4a5568;
|
||||
.complaint-form input:focus,
|
||||
.complaint-form select:focus,
|
||||
.complaint-form textarea:focus {
|
||||
border-color: var(--blue);
|
||||
}
|
||||
|
||||
.faq-item.active .faq-question::after {
|
||||
content: "−";
|
||||
.complaint-info {
|
||||
background: var(--card);
|
||||
border-radius: 10px;
|
||||
padding: 24px;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.faq-answer {
|
||||
padding: 0 20px;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
background: white;
|
||||
.complaint-info h3 {
|
||||
color: var(--navy);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.faq-item.active .faq-answer {
|
||||
padding: 18px 20px;
|
||||
max-height: 500px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
color: #4a5568;
|
||||
line-height: 1.7;
|
||||
.phone {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: var(--navy-2);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.form-note {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.form-success {
|
||||
background: #c6f6d5;
|
||||
color: #22543d;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.test-container {
|
||||
@ -278,27 +536,42 @@ main {
|
||||
|
||||
.test-start {
|
||||
text-align: center;
|
||||
padding: 30px 20px;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
||||
.test-start p {
|
||||
font-size: 16px;
|
||||
color: #4a5568;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.test-name-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.test-name-row input {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.test-topics {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
margin-bottom: 30px;
|
||||
color: #2d3748;
|
||||
margin-bottom: 24px;
|
||||
color: var(--text);
|
||||
font-size: 15px;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.test-progress {
|
||||
background: #e2e8f0;
|
||||
background: var(--border);
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
@ -309,7 +582,7 @@ main {
|
||||
.question-text {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2d3748;
|
||||
color: var(--text);
|
||||
margin-bottom: 24px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
@ -321,30 +594,31 @@ main {
|
||||
}
|
||||
|
||||
.test-option {
|
||||
padding: 16px 20px;
|
||||
background: #f7fafc;
|
||||
border: 2px solid #e2e8f0;
|
||||
padding: 15px 20px;
|
||||
background: var(--card);
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-size: 15px;
|
||||
text-align: left;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.test-option:hover {
|
||||
border-color: #4299e1;
|
||||
border-color: var(--blue);
|
||||
background: #ebf8ff;
|
||||
}
|
||||
|
||||
.test-option.correct {
|
||||
background: #c6f6d5;
|
||||
border-color: #48bb78;
|
||||
border-color: var(--green);
|
||||
color: #22543d;
|
||||
}
|
||||
|
||||
.test-option.wrong {
|
||||
background: #fed7d7;
|
||||
border-color: #f56565;
|
||||
border-color: var(--red);
|
||||
color: #742a2a;
|
||||
}
|
||||
|
||||
@ -357,118 +631,127 @@ main {
|
||||
|
||||
.test-result {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
padding: 30px 10px;
|
||||
}
|
||||
|
||||
.result-icon {
|
||||
font-size: 72px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 64px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.result-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
margin: 30px 0;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.result-stat {
|
||||
background: #f7fafc;
|
||||
padding: 24px;
|
||||
background: var(--card);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.result-value {
|
||||
display: block;
|
||||
font-size: 42px;
|
||||
font-size: 38px;
|
||||
font-weight: 700;
|
||||
color: #4299e1;
|
||||
margin-bottom: 8px;
|
||||
color: var(--blue);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.result-label {
|
||||
color: #718096;
|
||||
color: var(--muted);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.result-message {
|
||||
font-size: 16px;
|
||||
color: #4a5568;
|
||||
margin-bottom: 30px;
|
||||
margin-bottom: 24px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 14px 40px;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(66, 153, 225, 0.4);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: #fc8181;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 28px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
margin-top: 20px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #f56565;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
gap: 16px;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: #f7fafc;
|
||||
padding: 24px;
|
||||
background: var(--card);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 32px;
|
||||
font-size: 30px;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
display: block;
|
||||
font-size: 32px;
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: #4299e1;
|
||||
margin-bottom: 6px;
|
||||
color: var(--blue);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
color: #718096;
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.table-wrap {
|
||||
overflow-x: auto;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.data-table th,
|
||||
.data-table td {
|
||||
padding: 12px 16px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
background: var(--card);
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.data-table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.score-badge {
|
||||
display: inline-block;
|
||||
padding: 3px 12px;
|
||||
border-radius: 12px;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.score-good { background: #c6f6d5; color: #22543d; }
|
||||
.score-mid { background: #fefcbf; color: #744210; }
|
||||
.score-low { background: #fed7d7; color: #742a2a; }
|
||||
|
||||
footer {
|
||||
background: #1a365d;
|
||||
background: var(--navy);
|
||||
color: white;
|
||||
padding: 30px 20px;
|
||||
padding: 28px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -487,29 +770,37 @@ footer {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.logo {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
nav {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
.nav-link {
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
padding: 7px 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
.section {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.video-grid {
|
||||
|
||||
.complaint-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
|
||||
.test-name-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.result-stats {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding: 50px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user