Files
2026-etpgrf-site/etpgrf_site/typograph/templates/typograph/base.html

334 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% 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">
В&nbsp;соответствии с&nbsp;<abbr title="General Data Protection Regulation">GDPR</abbr>
и&nbsp;152-<abbr title="Федеральный закон">ФЗ</abbr>, уведомляем вас, что настоящий сайт использует файлы cookie
для&nbsp;сбора данных о&nbsp;поведении пользо&shy;вателей, с&nbsp;целью аналитики и&nbsp;улучшения своей работы.
Оставаясь на&nbsp;сайте, вы&nbsp;соглашаетесь с&nbsp;нашей
<a href="/privacy-policy">политикой конфи&shy;денциаль&shy;ности</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>