Compare commits
4 Commits
d974bbd740
...
70077ed279
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70077ed279 | ||
|
|
9eed6b578b | ||
|
|
506ec6e2f9 | ||
|
|
53d97f674e |
@ -24,23 +24,41 @@ class MenuContextMixin(ContextMixin):
|
||||
|
||||
# Основное меню (всегда)
|
||||
main_menu = [
|
||||
{'title': "Главная", 'url_name': 'home'},
|
||||
{'title': "Проекты", 'url_name': 'solution'},
|
||||
{'title': "Статьи", 'url_name': 'blog'},
|
||||
# {'title': "Главная", 'url_name': 'home'},
|
||||
{
|
||||
'title': "Разработки",
|
||||
'url_name': None,
|
||||
'children': [
|
||||
{'title': "Кейсы", 'url_name': 'solution'},
|
||||
{'title': "Статьи", 'url_name': 'blog'},
|
||||
]
|
||||
},
|
||||
{'title': "Отзывы", 'url_name': 'recall'},
|
||||
{'title': "Обо мне", 'url_name': 'about'},
|
||||
{'title': "О нас", 'url_name': 'about'},
|
||||
]
|
||||
|
||||
# Пользовательское меню (зависит от статуса)
|
||||
if self.request.user.is_authenticated:
|
||||
user_menu = [
|
||||
{'title': "Профиль", 'url_name': 'profile'},
|
||||
{'title': "Выйти", 'url_name': 'logout'}, # будет обработан как форма
|
||||
{
|
||||
'title': "Профиль",
|
||||
'url_name': None,
|
||||
'children': [
|
||||
{'title': "Профиль", 'url_name': 'profile'},
|
||||
{'title': "Выйти", 'url_name': 'logout'},
|
||||
]
|
||||
}
|
||||
]
|
||||
else:
|
||||
user_menu = [
|
||||
{'title': "Войти", 'url_name': 'login'},
|
||||
{'title': "Регистрация", 'url_name': 'register'},
|
||||
{
|
||||
'title': "Войти",
|
||||
'url_name': None,
|
||||
'children': [
|
||||
{'title': "Войти", 'url_name': 'login'},
|
||||
{'title': "Регистрация", 'url_name': 'register'},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
context['main_menu'] = main_menu
|
||||
|
||||
@ -125,7 +125,7 @@ body {
|
||||
.nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-start;
|
||||
padding: 1rem 0;
|
||||
gap: 2rem;
|
||||
}
|
||||
@ -160,16 +160,190 @@ body {
|
||||
|
||||
.nav-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
gap: 2.5rem;
|
||||
margin: 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ===== DROPDOWN MENU (DESKTOP) ===== */
|
||||
.nav-menu .has-dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Родительский пункт (span или ссылка) */
|
||||
.nav-menu .has-dropdown > a,
|
||||
.nav-menu .has-dropdown > span {
|
||||
text-decoration: none;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 600;
|
||||
padding: 0.75rem 0;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
display: inline-block;
|
||||
cursor: default;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
/* Выпадающий список */
|
||||
.nav-menu .dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
min-width: 200px;
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-xl);
|
||||
border: 1px solid var(--border-light);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-10px);
|
||||
transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease;
|
||||
list-style: none;
|
||||
padding: 0.5rem 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* Показываем dropdown при наведении на родительский li */
|
||||
.nav-menu .has-dropdown:hover .dropdown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Элементы dropdown */
|
||||
.nav-menu .dropdown li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-menu .dropdown a {
|
||||
display: block;
|
||||
padding: 0.6rem 1.2rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-menu .dropdown a:hover {
|
||||
background: var(--bg-secondary);
|
||||
color: var(--primary);
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
/* Небольшой треугольник (опционально) */
|
||||
.nav-menu .has-dropdown > span::after,
|
||||
.nav-menu .has-dropdown > a::after {
|
||||
/* content: '▼'; */
|
||||
font-size: 0.75em;
|
||||
margin-left: 6px;
|
||||
opacity: 0.7;
|
||||
vertical-align: middle;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.nav-menu .has-dropdown:hover > span::after,
|
||||
.nav-menu .has-dropdown:hover > a::after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* ===== USER MENU DROPDOWN (DESKTOP) ===== */
|
||||
.user-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.user-menu-item {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.user-menu-parent {
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1rem; /* соответствие .nav-link */
|
||||
}
|
||||
|
||||
.user-menu .has-dropdown > a,
|
||||
.user-menu .has-dropdown > span {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.user-menu .dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0; /* выравнивание по правому краю */
|
||||
min-width: 180px;
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-xl);
|
||||
border: 1px solid var(--border-light);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-10px);
|
||||
transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease;
|
||||
list-style: none;
|
||||
padding: 0.5rem 0;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.user-menu .has-dropdown:hover .dropdown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.user-menu .dropdown li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.user-menu .dropdown-link,
|
||||
.user-menu .dropdown-link-btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.6rem 1.2rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
background: none;
|
||||
border: none;
|
||||
text-align: left;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-menu .dropdown-link:hover,
|
||||
.user-menu .dropdown-link-btn:hover {
|
||||
background: var(--bg-secondary);
|
||||
color: var(--primary);
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
/* Стрелка для родительского пункта (опционально) */
|
||||
.user-menu .has-dropdown > span::after,
|
||||
.user-menu .has-dropdown > a::after {
|
||||
/* content: '▼'; */
|
||||
font-size: 0.75em;
|
||||
margin-left: 6px;
|
||||
opacity: 0.7;
|
||||
vertical-align: middle;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.user-menu .has-dropdown:hover > span::after,
|
||||
.user-menu .has-dropdown:hover > a::after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
@ -1346,6 +1520,53 @@ body {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* ===== MOBILE SUBMENU ===== */
|
||||
.mobile-nav-item.has-submenu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Родительский пункт в мобильном меню (может быть span или ссылка) */
|
||||
.mobile-nav-parent {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Стрелочка для родительского пункта */
|
||||
.mobile-nav-parent::after {
|
||||
content: '▼';
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.has-submenu.submenu-open .mobile-nav-parent::after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* Вложенный список */
|
||||
.mobile-submenu {
|
||||
list-style: none;
|
||||
margin-left: 1rem;
|
||||
padding-left: 0.5rem;
|
||||
border-left: 2px solid var(--primary);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.has-submenu.submenu-open .mobile-submenu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-submenu .mobile-nav-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mobile-submenu .mobile-nav-link {
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.mobile-nav-link {
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
@ -1753,3 +1974,38 @@ body {
|
||||
animation: pulse 1.5s infinite;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
/* Стили для <details> / <summary> */
|
||||
details {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--bg-primary);
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: var(--radius-md);
|
||||
transition: var(--transition);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
summary:hover {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
details[open] summary {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
details[open] {
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1rem;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
@ -49,9 +49,14 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
// Закрытие меню при клике на ссылку
|
||||
const mobileNavLinks = document.querySelectorAll('.mobile-nav-link');
|
||||
mobileNavLinks.forEach(link => {
|
||||
link.addEventListener('click', closeMobileMenu);
|
||||
document.querySelectorAll('.mobile-nav-item.has-submenu > .mobile-nav-link, .mobile-nav-item.has-submenu > .mobile-nav-parent').forEach(item => {
|
||||
item.addEventListener('click', function(e) {
|
||||
if (window.innerWidth <= 768) { // или ваш брейкпоинт
|
||||
e.preventDefault();
|
||||
const parent = this.closest('.has-submenu');
|
||||
parent.classList.toggle('submenu-open');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Синхронизация переключателей темы
|
||||
|
||||
@ -4,88 +4,133 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">{{title}}</h1>
|
||||
<p class="page-subtitle">Профессиональный программист 1С с более чем 10-летним опытом</p>
|
||||
<h1 class="page-title">{{ title }}</h1>
|
||||
<p class="page-subtitle">Команда экспертов по автоматизации бизнеса на платформе 1С</p>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="about-header">
|
||||
<h2>Николай Сердюк</h2>
|
||||
<p class="subtitle">Разработчик 1С</p>
|
||||
<!-- <div class="about-header">
|
||||
<h2>С.Н.А. Технологии</h2>
|
||||
<p class="subtitle">Профессиональная разработка и сопровождение 1С</p>
|
||||
</div> -->
|
||||
|
||||
<div class="about-section">
|
||||
<h3>🚀 О компании</h3>
|
||||
<p class="card-subtitle">
|
||||
Мы помогаем компаниям расти за счёт прозрачной и эффективной автоматизации
|
||||
на платформе 1С. Более 10 лет опыта, десятки успешных проектов и
|
||||
собственная методология внедрения.
|
||||
</p>
|
||||
<p>
|
||||
В основе нашей работы — глубокое понимание бизнес-процессов заказчика,
|
||||
техническая экспертиза и ответственность за результат. Каждый проект
|
||||
ведёт выделенная команда под личным управлением ведущего архитектора.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="about-section">
|
||||
<h3>🚀 Опыт работы</h3>
|
||||
<p class="card-subtitle">Более 10 лет успешной работы в разработке и сопровождении систем на платформе 1С</p>
|
||||
|
||||
<div class="experience-item mt-3">
|
||||
<h4>Основные направления:</h4>
|
||||
<div class="skills-grid">
|
||||
<div class="skill-category">
|
||||
<h4>💻 Разработка</h4>
|
||||
<ul>
|
||||
<li>Разработка и доработка конфигураций 1С</li>
|
||||
<li>Создание внешних обработок и отчетов</li>
|
||||
<li>Кастомизация под бизнес-процессы</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>🔗 Интеграция</h4>
|
||||
<ul>
|
||||
<li>Интеграция 1С с веб-сервисами</li>
|
||||
<li>Связь с сайтами и мобильными приложениями</li>
|
||||
<li>API и веб-сервисы</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>⚡ Оптимизация</h4>
|
||||
<ul>
|
||||
<li>Оптимизация бизнес-процессов</li>
|
||||
<li>Ускорение работы баз данных</li>
|
||||
<li>Автоматизация рутинных операций</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="about-section">
|
||||
<h3>🛠 Технологии и навыки</h3>
|
||||
<h3>👥 Наша команда</h3>
|
||||
<div class="skills-grid">
|
||||
<div class="skill-category">
|
||||
<h4>🎯 1С Разработка</h4>
|
||||
<ul>
|
||||
<li>1С:Предприятие 8.3</li>
|
||||
<li>Управление торговлей</li>
|
||||
<li>Бухгалтерия предприятия</li>
|
||||
<li>Зарплата и управление персоналом</li>
|
||||
<li>Внешние обработки и отчеты</li>
|
||||
<h4>Николай Сердюк</h4>
|
||||
<p style="margin-bottom: 0.5rem;">Руководитель проектов, ведущий архитектор 1С</p>
|
||||
<ul style="margin-top: 0;">
|
||||
<li>10+ лет в разработке 1С</li>
|
||||
<li>Архитектура сложных интеграций</li>
|
||||
<li>Управление командой и контроль качества</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>🔧 Дополнительные технологии</h4>
|
||||
<h4>Привлекаемые эксперты</h4>
|
||||
<ul>
|
||||
<li>SQL и оптимизация запросов</li>
|
||||
<li>Веб-сервисы и API</li>
|
||||
<li>XML, JSON, REST</li>
|
||||
<li>Системное администрирование</li>
|
||||
<li>Аналитики бизнес-процессов</li>
|
||||
<li>Специалисты по интеграции с внешними системами</li>
|
||||
<!-- <li>Инженеры технической поддержки 24/7</li> -->
|
||||
<!-- <li>Консультанты по бухгалтерскому и налоговому учёту</li> -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-2">
|
||||
Такой подход позволяет нам гибко масштабировать ресурсы под задачи любой
|
||||
сложности, сохраняя при этом персональную ответственность и высокое качество.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="about-section">
|
||||
<h3>⚙️ Ключевые компетенции</h3>
|
||||
<div class="skills-grid">
|
||||
<div class="skill-category">
|
||||
<h4>💻 Разработка 1С</h4>
|
||||
<ul>
|
||||
<li>Доработка типовых и создание уникальных конфигураций</li>
|
||||
<li>Внешние обработки, отчёты, печатные формы</li>
|
||||
<li>Адаптация интерфейсов под бизнес-процессы</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>🔗 Интеграции</h4>
|
||||
<ul>
|
||||
<li>Связь 1С с сайтами, маркетплейсами, CRM</li>
|
||||
<li>Обмен данными через API, веб-сервисы, HTTP-сервисы</li>
|
||||
<li>Интеграция с банками, платёжными системами, ЕГАИС</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>⚡ Оптимизация</h4>
|
||||
<ul>
|
||||
<li>Ускорение работы баз данных и запросов</li>
|
||||
<li>Автоматизация рутинных операций</li>
|
||||
<li>Настройка производительности серверов 1С</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="about-section">
|
||||
<h3>📈 Проекты и достижения</h3>
|
||||
<p class="card-subtitle">Успешно реализовал более 50 проектов различной сложности</p>
|
||||
<h3>🛠 Технологический стек</h3>
|
||||
<div class="skills-grid">
|
||||
<div class="skill-category">
|
||||
<h4>🎯 Платформа 1С</h4>
|
||||
<ul>
|
||||
<li>1С:Предприятие 8.3</li>
|
||||
<li>Управление торговлей (УТ)</li>
|
||||
<li>Бухгалтерия предприятия (БП)</li>
|
||||
<li>Зарплата и управление персоналом (ЗУП)</li>
|
||||
<li>Управление небольшой фирмой (УНФ)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>🔧 Смежные технологии</h4>
|
||||
<ul>
|
||||
<li>MS SQL, PostgreSQL – администрирование и оптимизация</li>
|
||||
<li>REST API, SOAP, JSON, XML</li>
|
||||
<li>Git, системы контроля версий</li>
|
||||
<li>Linux, Windows Server</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="about-section">
|
||||
<h3>📈 Опыт и проекты</h3>
|
||||
<p class="card-subtitle">Более 50 успешно реализованных проектов для компаний из разных отраслей</p>
|
||||
<div class="skills-grid mt-3">
|
||||
<div class="skill-category">
|
||||
<h4>🏆 Ключевые проекты</h4>
|
||||
<h4>🏭 Отраслевой опыт</h4>
|
||||
<ul>
|
||||
<li>Автоматизация учетных систем для предприятий</li>
|
||||
<li>Интеграция 1С с сайтами и мобильными приложениями</li>
|
||||
<li>Разработка кастомизированных отчетов и дашбордов</li>
|
||||
<li>Оптимизация производительности баз данных</li>
|
||||
<li>Оптовая и розничная торговля</li>
|
||||
<li>Производственные предприятия</li>
|
||||
<li>Логистика и складские комплексы</li>
|
||||
<li>Сфера услуг</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>📊 Типовые задачи</h4>
|
||||
<ul>
|
||||
<li>Автоматизация складского учёта и логистики</li>
|
||||
<li>Интеграция интернет-магазинов с 1С</li>
|
||||
<li>Построение управленческой отчётности и дашбордов</li>
|
||||
<li>Переход с устаревших версий 1С на актуальные</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -93,58 +138,87 @@
|
||||
|
||||
<div class="about-section">
|
||||
<h3>📞 Контакты</h3>
|
||||
<div class="contacts">
|
||||
<div class="skills-grid">
|
||||
<div class="skill-category">
|
||||
<h4>📧 Электронная почта</h4>
|
||||
<p><strong>{{ CONTACT_EMAIL }}</strong></p>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>📱 Телефон</h4>
|
||||
<p><strong>{{ CONTACT_PHONE }}</strong></p>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>💬 Telegram</h4>
|
||||
<p><strong><a href="https://t.me/odinesina_prog" target="_blank" class="btn btn-primary" style="display: inline-flex; padding: 0.5rem 1rem;">@odinesina_prog</a></strong></p>
|
||||
</div>
|
||||
<div class="skills-grid">
|
||||
<div class="skill-category">
|
||||
<h4>📧 Электронная почта</h4>
|
||||
<p><strong>{{ CONTACT_EMAIL }}</strong></p>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>📱 Телефон</h4>
|
||||
<p><strong>{{ CONTACT_PHONE }}</strong></p>
|
||||
</div>
|
||||
<div class="skill-category">
|
||||
<h4>💬 Telegram</h4>
|
||||
<p>
|
||||
<a href="https://t.me/odinesina_prog" target="_blank" class="btn btn-primary" style="display: inline-flex; padding: 0.5rem 1rem;">
|
||||
@odinesina_prog
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-3">
|
||||
Работаем официально по договору.
|
||||
<a href="{% url 'requisites' %}" style="color: var(--primary); text-decoration: underline;">
|
||||
ИП Сердюк Николай Александрович
|
||||
</a> |
|
||||
<a href="{% url 'requisites' %}" style="color: var(--primary); text-decoration: underline;">
|
||||
Реквизиты
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<div class="card-actions">
|
||||
<a href="{% url 'solution' %}" class="btn btn-primary">📂 Посмотреть мои проекты</a>
|
||||
<a href="{% url 'solution' %}" class="btn btn-primary">📂 Наши проекты</a>
|
||||
<a href="{% url 'recall' %}" class="btn btn-secondary">⭐ Отзывы клиентов</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Обновлённая микроразметка Schema.org для организации #}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Service",
|
||||
"serviceType": "1С программирование",
|
||||
"provider": {
|
||||
"@type": "ProfessionalService",
|
||||
"name": "С.Н.А. Технологии",
|
||||
"description": "Профессиональная разработка и сопровождение систем на платформе 1С. Команда экспертов с более чем 10-летним опытом.",
|
||||
"url": "{{ request.build_absolute_uri }}",
|
||||
"logo": "{% static 'programmer/images/black_logo.ico' %}",
|
||||
"telephone": "{{ CONTACT_PHONE }}",
|
||||
"email": "{{ CONTACT_EMAIL }}",
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"addressCountry": "RU"
|
||||
},
|
||||
"founder": {
|
||||
"@type": "Person",
|
||||
"name": "Николай Сердюк"
|
||||
"name": "Николай Сердюк",
|
||||
"jobTitle": "Руководитель проектов"
|
||||
},
|
||||
"areaServed": "Россия",
|
||||
"hasOfferCatalog": {
|
||||
"@type": "OfferCatalog",
|
||||
"name": "Услуги программиста 1С",
|
||||
"name": "Услуги по разработке и сопровождению 1С",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "Offer",
|
||||
"itemOffered": {
|
||||
"@type": "Service",
|
||||
"name": "Разработка конфигураций 1С"
|
||||
"name": "Разработка и доработка конфигураций 1С"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Offer",
|
||||
"itemOffered": {
|
||||
"@type": "Service",
|
||||
"name": "Интеграция 1С с веб-сервисами"
|
||||
"name": "Интеграция 1С с внешними системами"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Offer",
|
||||
"itemOffered": {
|
||||
"@type": "Service",
|
||||
"name": "Техническая поддержка и сопровождение 1С"
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -155,4 +229,3 @@
|
||||
<script src="{% static 'programmer/js/floating-button.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
<head>
|
||||
<title>{{title}}</title>
|
||||
<!-- Основные мета-теги -->
|
||||
<meta name="description" content="{% block meta_description %}{{ meta_description|default:'Профессиональный программист 1С с более чем 10-летним опытом. Разработка, интеграция и оптимизация систем 1С.' }}{% endblock %}">
|
||||
<meta name="description" content="{% block meta_description %}{{ meta_description|default:'Профессиональная разработка и поддержка 1С с более чем 10-летним опытом. Разработка, интеграция и оптимизация систем 1С.' }}{% endblock %}">
|
||||
<meta name="keywords" content="{% block meta_keywords %}{{ meta_keywords|default:'программист 1С, разработка 1С, интеграция 1С, оптимизация 1С, 1С предприятие' }}{% endblock %}">
|
||||
<meta name="author" content="Николай Сердюк">
|
||||
|
||||
<!-- Open Graph для соцсетей -->
|
||||
<meta property="og:title" content="{{title}}">
|
||||
<meta property="og:description" content="{% block og_description %}{{ meta_description|default:'Профессиональный программист 1С с более чем 10-летним опытом' }}{% endblock %}">
|
||||
<meta property="og:description" content="{% block og_description %}{{ meta_description|default:'Профессиональная разработка и поддержка 1С с более чем 10-летним опытом' }}{% endblock %}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="{{ request.build_absolute_uri }}">
|
||||
<!-- <meta property="og:image" content="{% static 'programmer/images/og-image.jpg' %}">-->
|
||||
@ -21,7 +21,7 @@
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="{{title}}">
|
||||
<meta name="twitter:description" content="{% block twitter_description %}{{ meta_description|default:'Профессиональный программист 1С с более чем 10-летним опытом' }}{% endblock %}">
|
||||
<meta name="twitter:description" content="{% block twitter_description %}{{ meta_description|default:'Профессиональная разработка и поддержка 1С с более чем 10-летним опытом' }}{% endblock %}">
|
||||
<!-- <meta name="twitter:image" content="{% static 'programmer/images/og-image.jpg' %}">-->
|
||||
|
||||
<!-- Дополнительные SEO-теги -->
|
||||
@ -90,8 +90,8 @@
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Person",
|
||||
"name": "Николай Сердюк",
|
||||
"jobTitle": "Программист 1С",
|
||||
"description": "Профессиональный программист 1С с более чем 10-летним опытом",
|
||||
"jobTitle": "Компания-разработчик 1С",
|
||||
"description": "Профессиональная разработка и поддержка 1С с более чем 10-летним опытом",
|
||||
"url": "https://nikdizell.ru",
|
||||
"email": "{{ CONTACT_EMAIL }}",
|
||||
"telephone": "{{ CONTACT_PHONE }}",
|
||||
@ -122,18 +122,27 @@
|
||||
<nav class="nav">
|
||||
<a href="{% url 'home' %}" class="logo">
|
||||
<img src="{% static 'programmer/images/black_logo.ico' %}" alt="Logo" class="logo-img">
|
||||
<span class="logo-text">СНА Технологии</span>
|
||||
<span class="logo-text">С.Н.А. Технологии</span>
|
||||
</a>
|
||||
|
||||
<!-- Десктопное меню -->
|
||||
<ul class="nav-menu">
|
||||
{% for item in main_menu %}
|
||||
<li class="nav-item">
|
||||
<a href="{% url item.url_name %}" class="nav-link {% if request.resolver_match.url_name == item.url_name %}active{% endif %}">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
{% for item in main_menu %}
|
||||
<li class="{% if item.children %}has-dropdown{% endif %}">
|
||||
{% if item.url_name %}
|
||||
<a href="{% url item.url_name %}" class="nav-link">{{ item.title }}</a>
|
||||
{% else %}
|
||||
<span>{{ item.title }}</span>
|
||||
{% endif %}
|
||||
{% if item.children %}
|
||||
<ul class="dropdown">
|
||||
{% for child in item.children %}
|
||||
<li><a href="{% url child.url_name %}">{{ child.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div class="nav-actions">
|
||||
@ -155,28 +164,46 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="user-menu">
|
||||
<div class="user-menu">
|
||||
{% for item in user_menu %}
|
||||
{% if item.url_name == 'logout' %}
|
||||
<form method="post" action="{% url 'logout' %}" style="display: inline;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="nav-link btn btn-link" style="border: none; background: none; padding: 0.5rem 1rem; font: inherit; cursor: pointer; color: inherit;">
|
||||
<div class="user-menu-item {% if item.children %}has-dropdown{% endif %}">
|
||||
{% if item.url_name %}
|
||||
<a href="{% url item.url_name %}" class="nav-link {% if request.resolver_match.url_name == item.url_name %}active{% endif %}">
|
||||
{{ item.title }}
|
||||
</button>
|
||||
</form>
|
||||
{% elif item.url_name == 'login' %}
|
||||
<a href="{% url 'login' %}?next={{ request.path|urlencode }}" class="nav-link {% if request.resolver_match.url_name == item.url_name %}active{% endif %}" style="display: inline-block; padding: 0.5rem 1rem;">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
{% elif item.url_name == 'register' %}
|
||||
<a href="{% url 'register' %}?next={{ request.path|urlencode }}" class="nav-link {% if request.resolver_match.url_name == item.url_name %}active{% endif %}" style="display: inline-block; padding: 0.5rem 1rem;">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url item.url_name %}" class="nav-link {% if request.resolver_match.url_name == item.url_name %}active{% endif %}" style="display: inline-block; padding: 0.5rem 1rem;">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="nav-link user-menu-parent">{{ item.title }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if item.children %}
|
||||
<ul class="dropdown user-dropdown">
|
||||
{% for child in item.children %}
|
||||
<li>
|
||||
{% if child.url_name == 'logout' %}
|
||||
<form method="post" action="{% url 'logout' %}" style="display: block;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="dropdown-link-btn">
|
||||
{{ child.title }}
|
||||
</button>
|
||||
</form>
|
||||
{% elif child.url_name == 'login' %}
|
||||
<a href="{% url 'login' %}?next={{ request.path|urlencode }}" class="dropdown-link">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
{% elif child.url_name == 'register' %}
|
||||
<a href="{% url 'register' %}?next={{ request.path|urlencode }}" class="dropdown-link">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url child.url_name %}" class="dropdown-link">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
@ -201,37 +228,70 @@
|
||||
|
||||
<ul class="mobile-nav-menu">
|
||||
{% for m in main_menu %}
|
||||
<li class="mobile-nav-item">
|
||||
{% if m.url_name == 'logout' %}
|
||||
<form method="post" action="{% url 'logout' %}" style="display: block;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="mobile-nav-link btn btn-link" style="border: none; background: none; width: 100%; text-align: left; padding: 1rem; font: inherit; cursor: pointer; color: inherit;">
|
||||
<li class="mobile-nav-item {% if m.children %}has-submenu{% endif %}">
|
||||
{% if m.url_name %}
|
||||
<a href="{% url m.url_name %}" class="mobile-nav-link {% if request.resolver_match.url_name == m.url_name %}active{% endif %}">
|
||||
{{ m.title }}
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<a href="{% url m.url_name %}" class="mobile-nav-link {% if request.resolver_match.url_name == m.url_name %}active{% endif %}">
|
||||
{{ m.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="mobile-nav-link mobile-nav-parent">{{ m.title }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if m.children %}
|
||||
<ul class="mobile-submenu">
|
||||
{% for child in m.children %}
|
||||
<li class="mobile-nav-item">
|
||||
<a href="{% url child.url_name %}" class="mobile-nav-link {% if request.resolver_match.url_name == child.url_name %}active{% endif %}">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
{% for item in user_menu %}
|
||||
{% if item.url_name == 'logout' %}
|
||||
<form method="post" action="{% url 'logout' %}" style="display: inline;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="nav-link btn btn-link" style="border: none; background: none; padding: 0.5rem 1rem; font: inherit; cursor: pointer; color: inherit;">
|
||||
<li class="mobile-nav-item {% if item.children %}has-submenu{% endif %}">
|
||||
{% if item.url_name %}
|
||||
<a href="{% url item.url_name %}" class="mobile-nav-link {% if request.resolver_match.url_name == item.url_name %}active{% endif %}">
|
||||
{{ item.title }}
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<a href="{% url item.url_name %}" class="nav-link {% if request.resolver_match.url_name == item.url_name %}active{% endif %}" style="display: inline-block; padding: 0.5rem 1rem;">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="mobile-nav-link mobile-nav-parent">{{ item.title }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if item.children %}
|
||||
<ul class="mobile-submenu">
|
||||
{% for child in item.children %}
|
||||
<li class="mobile-nav-item">
|
||||
{% if child.url_name == 'logout' %}
|
||||
<form method="post" action="{% url 'logout' %}" style="display: block;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="mobile-nav-link" style="border: none; background: none; width: 100%; text-align: left;">
|
||||
{{ child.title }}
|
||||
</button>
|
||||
</form>
|
||||
{% elif child.url_name == 'login' %}
|
||||
<a href="{% url 'login' %}?next={{ request.path|urlencode }}" class="mobile-nav-link">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
{% elif child.url_name == 'register' %}
|
||||
<a href="{% url 'register' %}?next={{ request.path|urlencode }}" class="mobile-nav-link">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url child.url_name %}" class="mobile-nav-link">
|
||||
{{ child.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<div class="mobile-nav-actions">
|
||||
<!-- <a href="https://t.me/odinesina_prog" target="_blank" class="btn btn-primary" style="width: 100%; text-align: center;">-->
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
{% block content %}
|
||||
<div class="hero-section fade-in">
|
||||
<h1 class="hero-title">🚀 Добро пожаловать!</h1>
|
||||
<p class="hero-subtitle">Я профессиональный программист 1С с опытом создания эффективных бизнес-решений</p>
|
||||
<p class="hero-subtitle">Профессиональная разработка на платформе 1С с опытом создания эффективных бизнес-решений</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-2">
|
||||
|
||||
50
programmer/templates/programmer/requisites.html
Normal file
50
programmer/templates/programmer/requisites.html
Normal file
@ -0,0 +1,50 @@
|
||||
{% extends 'programmer/base.html' %}
|
||||
{% load static %}
|
||||
{% load django_bootstrap5 %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">{{ title }}</h1>
|
||||
<p class="page-subtitle">Официальная информация о компании</p>
|
||||
</div>
|
||||
|
||||
<div class="content-card">
|
||||
<div class="about-section">
|
||||
<h3>📄 Реквизиты</h3>
|
||||
|
||||
<div style="background: var(--bg-secondary); padding: 2rem; border-radius: var(--radius-lg);">
|
||||
<p><strong>Индивидуальный предприниматель</strong><br>
|
||||
Сердюк Николай Александрович</p>
|
||||
|
||||
<p><strong>ИНН:</strong> {{ RQ_INN }}</p>
|
||||
<p><strong>ОГРНИП:</strong> {{ RQ_OGRNIP }}</p>
|
||||
|
||||
<p><strong>Юридический адрес:</strong><br>
|
||||
{{ RQ_ADRES }}</p>
|
||||
|
||||
<p><strong>Почтовый адрес:</strong><br>
|
||||
{{ RQ_ADRES }}</p>
|
||||
|
||||
<!-- Спойлер с банковскими реквизитами -->
|
||||
<details style="margin-top: 1.5rem;">
|
||||
<summary style="cursor: pointer; font-weight: bold; color: var(--primary);">
|
||||
🔒 Банковские реквизиты (нажмите, чтобы показать)
|
||||
</summary>
|
||||
<div style="margin-top: 1rem; padding-top: 1rem; border-top: 1px dashed var(--border-light);">
|
||||
<p><strong>Расчётный счёт:</strong> {{ RQ_ECENT }}</p>
|
||||
<p><strong>Банк:</strong> {{ RQ_BANK }}</p>
|
||||
<p><strong>БИК:</strong> {{ RQ_BIK }}</p>
|
||||
<p><strong>Корреспондентский счёт:</strong> {{ RQ_KOR_ECENT }}</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<p style="margin-top: 1rem;"><strong>Контактный телефон:</strong> {{ CONTACT_PHONE }}</p>
|
||||
<p><strong>Электронная почта:</strong> {{ CONTACT_EMAIL }}</p>
|
||||
</div>
|
||||
|
||||
<p class="mt-3 text-muted" style="color: var(--text-light);">
|
||||
Актуально на {% now "d.m.Y" %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -34,6 +34,7 @@ urlpatterns = [
|
||||
path('profile/edit/', views.ProfileEditView.as_view(), name='profile_edit'),
|
||||
path('privacy/', PrivacyPolicyView.as_view(), name='privacy'),
|
||||
path('yandex_cdc16c33291495b9.html/', yandex_html, name='yandex_cdc16c33291495b9'),
|
||||
path('requisites/', RequisitesPageView.as_view(), name='requisites'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ from .mixins import PageViewTrackingMixin, MenuContextMixin, BreadcrumbMixin
|
||||
from .services import get_published_queryset, track_page_view
|
||||
from typing import Any, Dict, Type
|
||||
from django.template.loader import render_to_string
|
||||
import os
|
||||
|
||||
|
||||
class BasePageView(PageViewTrackingMixin, MenuContextMixin, TemplateView):
|
||||
@ -98,7 +99,7 @@ class AboutPageView(BasePageView, BreadcrumbMixin):
|
||||
template_name = 'programmer/about.html'
|
||||
|
||||
def get_breadcrumbs(self):
|
||||
return [{'title': 'Обо мне', 'url_name': None}]
|
||||
return [{'title': 'Обо нас', 'url_name': None}]
|
||||
|
||||
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
||||
context = super().get_context_data(**kwargs)
|
||||
@ -106,14 +107,15 @@ class AboutPageView(BasePageView, BreadcrumbMixin):
|
||||
|
||||
context.update({
|
||||
'form': form,
|
||||
'title': "Программист 1С Николай Сердюк - 10+ лет опыта | Услуги 1С",
|
||||
'title': "С.Н.А. Технологии — Профессиональная разработка и сопровождение 1С",
|
||||
'meta_description': (
|
||||
"Николай Сердюк - сертифицированный программист 1С с 10+ лет опыта. "
|
||||
"Специализация: обновление 1С, разработка под ключ, интеграция, миграция с 1С 7.7."
|
||||
"Команда экспертов по автоматизации бизнеса на платформе 1С. "
|
||||
"Разработка, доработка, интеграция и поддержка 1С для компаний любого масштаба. "
|
||||
"Официальный договор, опыт более 10 лет."
|
||||
),
|
||||
'meta_keywords': (
|
||||
"программист 1С Николай Сердюк, обновление 1С, разработка 1С под ключ, "
|
||||
"интеграция 1С, сертифицированный 1С, миграция 1С 7.7"
|
||||
"разработка 1С, сопровождение 1С, автоматизация бизнеса 1С, "
|
||||
"интеграция 1С, программист 1С компания, СНА Технологии, обновление 1С, 1С под ключ"
|
||||
),
|
||||
})
|
||||
return context
|
||||
@ -285,7 +287,7 @@ class PrivacyPolicyView(TemplateView, MenuContextMixin, BreadcrumbMixin):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({
|
||||
'title': "Политика конфиденциальности | СНА Технологии",
|
||||
'title': "Политика конфиденциальности | С.Н.А. Технологии",
|
||||
})
|
||||
|
||||
return context
|
||||
@ -347,6 +349,37 @@ class CompetenceDetailView(MenuContextMixin, BreadcrumbMixin, DetailView):
|
||||
return context
|
||||
|
||||
|
||||
|
||||
class RequisitesPageView(BasePageView, BreadcrumbMixin):
|
||||
"""Страница с реквизитами компании."""
|
||||
template_name = 'programmer/requisites.html'
|
||||
|
||||
def get_breadcrumbs(self):
|
||||
return [
|
||||
{'title': 'О компании', 'url_name': 'about'},
|
||||
{'title': 'Реквизиты', 'url_name': None}
|
||||
]
|
||||
|
||||
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({
|
||||
'title': "Реквизиты ИП Сердюк Н.А. | С.Н.А. Технологии",
|
||||
'meta_description': (
|
||||
"Официальные реквизиты ИП Сердюк Николай Александрович. "
|
||||
"ИНН, ОГРНИП, банковские реквизиты для выставления счетов и заключения договоров."
|
||||
),
|
||||
'meta_keywords': "реквизиты ИП, Сердюк Николай Александрович, СНА Технологии, ИНН, ОГРНИП",
|
||||
'RQ_INN': os.getenv('RQ_INN', 'не указан'),
|
||||
'RQ_OGRNIP': os.getenv('RQ_OGRNIP', 'не указан'),
|
||||
'RQ_ADRES': os.getenv('RQ_ADRES', 'не указан'),
|
||||
'RQ_ECENT': os.getenv('RQ_ECENT', 'не указан'),
|
||||
'RQ_BANK': os.getenv('RQ_BANK', 'не указан'),
|
||||
'RQ_BIK': os.getenv('RQ_BIK', 'не указан'),
|
||||
'RQ_KOR_ECENT': os.getenv('RQ_KOR_ECENT', 'не указан'),
|
||||
})
|
||||
return context
|
||||
|
||||
|
||||
@require_POST
|
||||
def callback_request(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
|
||||
194
static/programmer/css/solution-cards.css
Normal file
194
static/programmer/css/solution-cards.css
Normal file
@ -0,0 +1,194 @@
|
||||
/* ===== PROJECTS GRID ===== */
|
||||
.projects-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* ===== PROJECT CARD ===== */
|
||||
.project-card {
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--radius-lg);
|
||||
border: 1px solid var(--border-light);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
|
||||
}
|
||||
|
||||
.project-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
border-color: var(--primary-light);
|
||||
}
|
||||
|
||||
/* Оранжевая полоска сверху — единственный декоративный слой */
|
||||
.project-card__accent {
|
||||
height: 3px;
|
||||
background: var(--gradient-primary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.project-card__body {
|
||||
padding: 1.5rem 1.5rem 1rem;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.project-card__title {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.project-card__desc {
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.65;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.project-card__footer {
|
||||
padding: 1rem 1.5rem 1.25rem;
|
||||
border-top: 1px solid var(--border-light);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.project-card__link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
color: var(--primary);
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
text-decoration: none;
|
||||
transition: gap 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.project-card__link:hover {
|
||||
color: var(--primary-dark);
|
||||
gap: 0.65rem;
|
||||
}
|
||||
|
||||
/* ===== MOBILE ===== */
|
||||
@media (max-width: 768px) {
|
||||
.projects-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
/* На мобиле убираем hover-подъём — он не работает на touch */
|
||||
.project-card:hover {
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Вместо этого — активное состояние при нажатии */
|
||||
.project-card:active {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.project-card__body {
|
||||
padding: 1.25rem 1.25rem 0.75rem;
|
||||
}
|
||||
|
||||
.project-card__footer {
|
||||
padding: 0.75rem 1.25rem 1rem;
|
||||
}
|
||||
|
||||
.project-card__title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.projects-grid {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== СТИЛИ ДЛЯ СТРАНИЦЫ ДЕТАЛЬНОГО РЕШЕНИЯ ===== */
|
||||
|
||||
.solution-section {
|
||||
margin-bottom: 2.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
}
|
||||
|
||||
.solution-section:last-of-type {
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-left: 5px solid var(--primary);
|
||||
padding-left: 1.25rem;
|
||||
}
|
||||
|
||||
.section-content {
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.7;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* Вложенные заголовки */
|
||||
.section-content h2,
|
||||
.section-content h3 {
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.75em;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.section-content h2 {
|
||||
font-size: 1.4rem;
|
||||
border-bottom: 1px dashed var(--border-light);
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.section-content h3 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.section-content ul,
|
||||
.section-content ol {
|
||||
margin: 1rem 0 1rem 1.5rem;
|
||||
}
|
||||
|
||||
.section-content li {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Адаптация для мобильных */
|
||||
@media (max-width: 768px) {
|
||||
.solution-section {
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 1.5rem;
|
||||
padding-left: 1rem;
|
||||
border-left-width: 4px;
|
||||
}
|
||||
.section-content {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.section-title {
|
||||
font-size: 1.35rem;
|
||||
}
|
||||
}
|
||||
@ -125,7 +125,7 @@ body {
|
||||
.nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-start;
|
||||
padding: 1rem 0;
|
||||
gap: 2rem;
|
||||
}
|
||||
@ -160,16 +160,190 @@ body {
|
||||
|
||||
.nav-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
gap: 2.5rem;
|
||||
margin: 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ===== DROPDOWN MENU (DESKTOP) ===== */
|
||||
.nav-menu .has-dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Родительский пункт (span или ссылка) */
|
||||
.nav-menu .has-dropdown > a,
|
||||
.nav-menu .has-dropdown > span {
|
||||
text-decoration: none;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 600;
|
||||
padding: 0.75rem 0;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
display: inline-block;
|
||||
cursor: default;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
/* Выпадающий список */
|
||||
.nav-menu .dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
min-width: 200px;
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-xl);
|
||||
border: 1px solid var(--border-light);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-10px);
|
||||
transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease;
|
||||
list-style: none;
|
||||
padding: 0.5rem 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* Показываем dropdown при наведении на родительский li */
|
||||
.nav-menu .has-dropdown:hover .dropdown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Элементы dropdown */
|
||||
.nav-menu .dropdown li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-menu .dropdown a {
|
||||
display: block;
|
||||
padding: 0.6rem 1.2rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-menu .dropdown a:hover {
|
||||
background: var(--bg-secondary);
|
||||
color: var(--primary);
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
/* Небольшой треугольник (опционально) */
|
||||
.nav-menu .has-dropdown > span::after,
|
||||
.nav-menu .has-dropdown > a::after {
|
||||
/* content: '▼'; */
|
||||
font-size: 0.75em;
|
||||
margin-left: 6px;
|
||||
opacity: 0.7;
|
||||
vertical-align: middle;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.nav-menu .has-dropdown:hover > span::after,
|
||||
.nav-menu .has-dropdown:hover > a::after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* ===== USER MENU DROPDOWN (DESKTOP) ===== */
|
||||
.user-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.user-menu-item {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.user-menu-parent {
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1rem; /* соответствие .nav-link */
|
||||
}
|
||||
|
||||
.user-menu .has-dropdown > a,
|
||||
.user-menu .has-dropdown > span {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.user-menu .dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0; /* выравнивание по правому краю */
|
||||
min-width: 180px;
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-xl);
|
||||
border: 1px solid var(--border-light);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-10px);
|
||||
transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease;
|
||||
list-style: none;
|
||||
padding: 0.5rem 0;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.user-menu .has-dropdown:hover .dropdown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.user-menu .dropdown li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.user-menu .dropdown-link,
|
||||
.user-menu .dropdown-link-btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.6rem 1.2rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
background: none;
|
||||
border: none;
|
||||
text-align: left;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-menu .dropdown-link:hover,
|
||||
.user-menu .dropdown-link-btn:hover {
|
||||
background: var(--bg-secondary);
|
||||
color: var(--primary);
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
/* Стрелка для родительского пункта (опционально) */
|
||||
.user-menu .has-dropdown > span::after,
|
||||
.user-menu .has-dropdown > a::after {
|
||||
/* content: '▼'; */
|
||||
font-size: 0.75em;
|
||||
margin-left: 6px;
|
||||
opacity: 0.7;
|
||||
vertical-align: middle;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.user-menu .has-dropdown:hover > span::after,
|
||||
.user-menu .has-dropdown:hover > a::after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
@ -1346,6 +1520,53 @@ body {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* ===== MOBILE SUBMENU ===== */
|
||||
.mobile-nav-item.has-submenu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Родительский пункт в мобильном меню (может быть span или ссылка) */
|
||||
.mobile-nav-parent {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Стрелочка для родительского пункта */
|
||||
.mobile-nav-parent::after {
|
||||
content: '▼';
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.has-submenu.submenu-open .mobile-nav-parent::after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* Вложенный список */
|
||||
.mobile-submenu {
|
||||
list-style: none;
|
||||
margin-left: 1rem;
|
||||
padding-left: 0.5rem;
|
||||
border-left: 2px solid var(--primary);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.has-submenu.submenu-open .mobile-submenu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-submenu .mobile-nav-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mobile-submenu .mobile-nav-link {
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.mobile-nav-link {
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
@ -1753,3 +1974,38 @@ body {
|
||||
animation: pulse 1.5s infinite;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
/* Стили для <details> / <summary> */
|
||||
details {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--bg-primary);
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: var(--radius-md);
|
||||
transition: var(--transition);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
summary:hover {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
details[open] summary {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
details[open] {
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 1rem;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
@ -49,9 +49,14 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
// Закрытие меню при клике на ссылку
|
||||
const mobileNavLinks = document.querySelectorAll('.mobile-nav-link');
|
||||
mobileNavLinks.forEach(link => {
|
||||
link.addEventListener('click', closeMobileMenu);
|
||||
document.querySelectorAll('.mobile-nav-item.has-submenu > .mobile-nav-link, .mobile-nav-item.has-submenu > .mobile-nav-parent').forEach(item => {
|
||||
item.addEventListener('click', function(e) {
|
||||
if (window.innerWidth <= 768) { // или ваш брейкпоинт
|
||||
e.preventDefault();
|
||||
const parent = this.closest('.has-submenu');
|
||||
parent.classList.toggle('submenu-open');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Синхронизация переключателей темы
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user