334 lines
14 KiB
HTML
334 lines
14 KiB
HTML
{% load static %}<!doctype html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>{% block title %}ETPGRF — единая типографика для веба{% endblock %}</title>
|
||
{# Favicons #} <link rel="icon" type="image/png" href="{% static 'favicon-96x96.png' %}" sizes="96x96" />
|
||
<link rel="icon" href="{% static 'favicon-light.svg' %}" type="image/svg+xml" media="(prefers-color-scheme: light)">
|
||
<link rel="icon" href="{% static 'favicon-dark.svg' %}" type="image/svg+xml" media="(prefers-color-scheme: dark)">
|
||
<link rel="icon" type="image/svg+xml" href="{% static 'favicon.svg' %}" />
|
||
{# Fallback для старых браузеров #}<link rel="shortcut icon" href="{% static 'favicon.ico' %}" sizes="any" />
|
||
{# iOS Icon #}<link rel="apple-touch-icon" sizes="180x180" href="{% static 'apple-touch-icon.png' %}" />
|
||
<link rel="manifest" href="{% static 'site.webmanifest' %}" />
|
||
{# Bootstrap 5 CSS #}<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||
{# Bootstrap Icons #}<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" />
|
||
{# HTMX #}<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
||
{# Alpine.js #}<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||
{# Polyfill for Import Maps #}<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.0/dist/es-module-shims.js"></script>
|
||
|
||
|
||
|
||
<style>
|
||
/* === ЦВЕТОВАЯ СХЕМА === */
|
||
:root {
|
||
/* Светлая тема: Темно-серый с легкой желтизной (Warm Charcoal) */
|
||
--bs-body-bg: #f8f8f2;
|
||
--bs-body-color: #1f1f19;
|
||
--bs-primary: #4a4a44;
|
||
--bs-primary-rgb: 74, 74, 68;
|
||
--bs-link-color: #4a4a44;
|
||
--bs-link-hover-color: #2e2e2a;
|
||
--bs-focus-ring-color: rgba(74, 74, 68, 0.25);
|
||
|
||
/* Фон навбара в светлой теме */
|
||
--bs-navbar-bg: #b8b8d055; /* Тот же, что и body, или чуть темнее */
|
||
--bs-navbar-color: #1f1f19;
|
||
}
|
||
|
||
[data-bs-theme="dark"] {
|
||
/* Темная тема: Глубокий черный фон и Стальной акцент */
|
||
--bs-body-bg: #151111;
|
||
--bs-body-color: #eceff1;
|
||
|
||
/* Акцент: Светлый серо-голубой */
|
||
--bs-primary: #b0bec5;
|
||
--bs-primary-rgb: 176, 190, 197;
|
||
|
||
--bs-link-color: #90caf9;
|
||
--bs-link-hover-color: #bbdefb;
|
||
|
||
--bs-border-color: #37474f;
|
||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||
|
||
/* Цвет фокуса для полей ввода */
|
||
--bs-focus-ring-color: rgba(176, 190, 197, 0.25);
|
||
|
||
/* Фон навбара в темной теме */
|
||
--bs-navbar-bg: #55558555;
|
||
--bs-navbar-color: #b0bec5;
|
||
}
|
||
|
||
/* Небольшие стили для красоты */
|
||
body { background-color: var(--bs-body-bg); }
|
||
|
||
/* Навбар: используем переменную для фона */
|
||
.navbar {
|
||
background-color: var(--bs-navbar-bg) !important;
|
||
border-bottom: 1px solid var(--bs-border-color);
|
||
padding: 0; /* Убираем отступы у навбара */
|
||
position: sticky;
|
||
top: 0;
|
||
height: 105px;
|
||
z-index: 1000;
|
||
backdrop-filter: blur(4px); /* Эффект размытия */
|
||
box-shadow: 0 -25px 30px 15px var(--bs-border-color);
|
||
}
|
||
.navbar-brand {
|
||
padding: 0; /* Убираем отступы у бренда */
|
||
}
|
||
|
||
/* Стили для скролла */
|
||
.navbar-scrolled {
|
||
height: 55px;
|
||
}
|
||
|
||
/* Логотип */
|
||
.logo-img {
|
||
width: 70%;
|
||
margin-left: -3%; /* Немного сдвигаем влево, чтобы буквы ETPGRF логотипа выровнять */
|
||
height: 151px; /* Ограничиваем высоту */
|
||
object-fit: contain; /* Вписываем, сохраняя пропорции */
|
||
}
|
||
|
||
/* Уменьшаем логотип при скролле */
|
||
.navbar-scrolled .logo-img {
|
||
height: 78px; /* Компактная высота */
|
||
margin-left: -5%;
|
||
}
|
||
|
||
/* === ПЕРЕОПРЕДЕЛЕНИЕ КОМПОНЕНТОВ BOOTSTRAP === */
|
||
|
||
/* Кнопки Primary */
|
||
.btn-primary {
|
||
--bs-btn-bg: var(--bs-primary);
|
||
--bs-btn-border-color: var(--bs-primary);
|
||
--bs-btn-hover-bg: var(--bs-link-hover-color);
|
||
--bs-btn-hover-border-color: var(--bs-link-hover-color);
|
||
--bs-btn-active-bg: var(--bs-link-hover-color);
|
||
--bs-btn-active-border-color: var(--bs-link-hover-color);
|
||
}
|
||
/* В темной теме текст на кнопке должен быть темным */
|
||
[data-bs-theme="dark"] .btn-primary {
|
||
--bs-btn-color: #151111;
|
||
--bs-btn-hover-color: #151111;
|
||
--bs-btn-active-color: #151111;
|
||
}
|
||
|
||
/* Чекбоксы и Радио */
|
||
.form-check-input:checked {
|
||
background-color: var(--bs-primary);
|
||
border-color: var(--bs-primary);
|
||
}
|
||
/* В темной теме галочка должна быть темной */
|
||
[data-bs-theme="dark"] .form-check-input:checked {
|
||
/* SVG галочки черного цвета (закодирован в base64) */
|
||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23151111' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
|
||
}
|
||
|
||
/* Фокус на полях ввода */
|
||
.form-control:focus, .form-select:focus, .form-check-input:focus {
|
||
border-color: var(--bs-primary);
|
||
box-shadow: 0 0 0 0.25rem var(--bs-focus-ring-color);
|
||
}
|
||
|
||
.result-box {
|
||
background: var(--bs-body-bg);
|
||
color: var(--bs-body-color);
|
||
border: 1px solid var(--bs-border-color);
|
||
border-radius: 0.375rem;
|
||
padding: 1rem;
|
||
min-height: 300px;
|
||
padding-left: 1.5rem;
|
||
padding-right: 1.5rem;
|
||
white-space: pre-wrap;
|
||
font-family: inherit;
|
||
}
|
||
.cm-editor {
|
||
border: 1px solid var(--bs-border-color);
|
||
border-radius: 0.375rem;
|
||
height: 300px;
|
||
}
|
||
|
||
/* --- Висячая пунктуация (Hanging Punctuation) --- */
|
||
.result-box .etp-laquo { margin-left: -0.44em; }
|
||
.result-box .etp-ldquo { margin-left: -0.44em; }
|
||
.result-box .etp-lpar { margin-left: -0.3em; }
|
||
.result-box .etp-lsqb { margin-left: -0.3em; }
|
||
.result-box .etp-lcub { margin-left: -0.3em; }
|
||
.result-box .etp-raquo { margin-right: -0.44em; }
|
||
.result-box .etp-rdquo { margin-right: -0.44em; }
|
||
.result-box .etp-rpar { margin-right: -0.3em; }
|
||
.result-box .etp-rsqb { margin-right: -0.3em; }
|
||
.result-box .etp-rcub { margin-right: -0.3em; }
|
||
.result-box .etp-r-dot { margin-right: -0.2em; }
|
||
.result-box .etp-r-comma { margin-right: -0.2em; }
|
||
.result-box .etp-r-colon { margin-right: -0.2em; }
|
||
|
||
/* --- Стили для Cookie Banner --- */
|
||
#cookie-banner {
|
||
backdrop-filter: blur(10px);
|
||
border-top: 1px solid var(--bs-border-color);
|
||
z-index: 1050;
|
||
background-color: var(--bs-navbar-bg);
|
||
color: var(--bs-navbar-color); /* Используем цвет навбара для текста */
|
||
}
|
||
#cookie-banner a {
|
||
color: var(--bs-primary);
|
||
text-decoration: none;
|
||
border-bottom: 1px dotted var(--bs-primary);
|
||
}
|
||
#cookie-banner a:hover {
|
||
border-bottom-style: solid;
|
||
color: var(--bs-link-hover-color);
|
||
}
|
||
#cookie-accept {
|
||
color: var(--bs-primary);
|
||
border: 1px dashed var(--bs-primary);
|
||
background: transparent;
|
||
}
|
||
#cookie-accept:hover {
|
||
background: rgba(var(--bs-primary-rgb), 0.1);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
{# ШАПКА и главное меню #}
|
||
<nav id="main-navbar" class="navbar navbar-expand-lg mb-4">
|
||
<div class="container">
|
||
<a class="navbar-brand" href="/">
|
||
<img id="logo-img" class="logo-img" src=""
|
||
data-src-light="{% static 'svg/logo-etpgrf-site-light.svg' %}"
|
||
data-src-light-compact="{% static 'svg/logo-etpgrf-site-light-compact.svg' %}"
|
||
data-src-dark="{% static 'svg/logo-etpgrf-site-dark.svg' %}"
|
||
data-src-dark-compact="{% static 'svg/logo-etpgrf-site-dark-compact.svg' %}"
|
||
alt="ETPGRF — единая типографика для веба">
|
||
</a>
|
||
</div>
|
||
</nav>
|
||
|
||
<div id="content-container" class="container">
|
||
{% block content %}{% endblock %}
|
||
</div>
|
||
|
||
{# Плашка о куках #}
|
||
<div id="cookie-banner" class="fixed-bottom p-4 fs-5" style="display: none;">
|
||
<div class="container d-flex justify-content-between align-items-center">
|
||
<p class="mb-0 pe-5">
|
||
В соответствии с <abbr title="General Data Protection Regulation">GDPR</abbr>
|
||
и 152-<abbr title="Федеральный закон">ФЗ</abbr>, уведомляем вас, что настоящий сайт использует файлы cookie
|
||
для сбора данных о поведении пользо­вателей, с целью аналитики и улучшения своей работы.
|
||
Оставаясь на сайте, вы соглашаетесь с нашей
|
||
<a href="/privacy-policy">политикой конфи­денциаль­ности</a>.
|
||
</p>
|
||
<button id="cookie-accept" class="btn btn-lg ms-3">Принять</button>
|
||
</div>
|
||
</div>
|
||
|
||
{# Bootstrap JS #}
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||
|
||
{# Логика куки-баннера и счетчиков #}
|
||
<script>
|
||
(function () {
|
||
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||
const logoImg = document.getElementById('logo-img');
|
||
const navbar = document.getElementById('main-navbar');
|
||
|
||
// --- АВТОМАТИЧЕСКОЕ ПЕРЕКЛЮЧЕНИЕ ТЕМЫ (Dark/Light) ---
|
||
function updateTheme(e) {
|
||
const theme = e.matches ? 'dark' : 'light';
|
||
document.documentElement.setAttribute('data-bs-theme', theme);
|
||
}
|
||
|
||
// --- ОБНОВЛЕНИЕ ЛОГОТИПА ПРИ СКРОЛЛЕ И СМЕНЕ ТЕМЫ ---
|
||
function updateLogo() {
|
||
const isDark = darkModeMediaQuery.matches;
|
||
// Используем getBoundingClientRect для определения позиции контента
|
||
if (document.getElementById('content-container').getBoundingClientRect().top < 78) {
|
||
navbar.classList.add('navbar-scrolled');
|
||
logoImg.src = isDark ? logoImg.dataset.srcDarkCompact : logoImg.dataset.srcLightCompact;
|
||
} else {
|
||
navbar.classList.remove('navbar-scrolled');
|
||
logoImg.src = isDark ? logoImg.dataset.srcDark : logoImg.dataset.srcLight;
|
||
}
|
||
}
|
||
|
||
// Инициализация
|
||
updateTheme(darkModeMediaQuery);
|
||
updateLogo();
|
||
document.addEventListener('DOMContentLoaded', updateLogo);
|
||
|
||
// Слушаем скролл
|
||
window.addEventListener('scroll', updateLogo);
|
||
|
||
// Слушаем смену темы
|
||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateLogo);
|
||
|
||
// --- КУКИ ---
|
||
const COOKIE_KEY = 'cookie_consent';
|
||
const TTL_MS = 60 * 1000; // 1 минута для отладки (потом поставить 90 дней: 90 * 24 * 60 * 60 * 1000 = 7776000000)
|
||
|
||
const banner = document.getElementById('cookie-banner');
|
||
const acceptButton = document.getElementById('cookie-accept');
|
||
|
||
function loadCounters() {
|
||
console.log("Загрузка счетчиков (Яндекс, Google)...");
|
||
// Код Яндекс.Метрики
|
||
// (function(m,e,t,r,i,k,a){...})(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||
// ym(XXXXXX, "init", {...});
|
||
|
||
// Код Google Analytics
|
||
// window.dataLayer = window.dataLayer || [];
|
||
// function gtag(){dataLayer.push(arguments);}
|
||
// gtag('js', new Date());
|
||
// gtag('config', 'G-XXXXXXXXXX');
|
||
|
||
// Код Top.Mail.Ru
|
||
// (function(w, d, c) { ... })(window, document, "topmailru");
|
||
|
||
// и т.д.
|
||
|
||
// alert("Отладка. Счетчики загружены (здесь должен быть реальный код счетчиков).");
|
||
}
|
||
|
||
function checkConsent() {
|
||
const stored = localStorage.getItem(COOKIE_KEY);
|
||
if (!stored) return false;
|
||
|
||
try {
|
||
const data = JSON.parse(stored);
|
||
const now = Date.now();
|
||
// Проверяем, не истек ли срок
|
||
if (now - data.timestamp > TTL_MS) {
|
||
localStorage.removeItem(COOKIE_KEY);
|
||
return false;
|
||
}
|
||
return true;
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (checkConsent()) {
|
||
loadCounters();
|
||
} else {
|
||
banner.style.display = 'block';
|
||
}
|
||
|
||
acceptButton.addEventListener('click', function () {
|
||
const data = {
|
||
value: true,
|
||
timestamp: Date.now()
|
||
};
|
||
localStorage.setItem(COOKIE_KEY, JSON.stringify(data));
|
||
banner.style.display = 'none';
|
||
loadCounters();
|
||
});
|
||
})();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|