From d5286ab980e1dc508723ee537cce860ecdebd71a Mon Sep 17 00:00:00 2001 From: Web-serfer Date: Thu, 2 Apr 2026 20:38:33 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BA=D0=BE=C3=90=D0=B4=D0=B0=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B1=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/home/Hero.astro | 299 +++--------- .../src/components/layout/header/Header.astro | 308 ++++++------ .../layout/header/LoginButton.astro | 7 + .../components/layout/header/MobileMenu.astro | 455 +++++++++++++----- .../src/components/layout/header/Navbar.astro | 219 ++++++++- frontend/src/constants.ts | 23 + frontend/src/constants/index.ts | 22 - frontend/src/layouts/Layout.astro | 4 +- frontend/src/styles/global.css | 43 +- 9 files changed, 800 insertions(+), 580 deletions(-) delete mode 100644 frontend/src/constants/index.ts diff --git a/frontend/src/components/home/Hero.astro b/frontend/src/components/home/Hero.astro index e17bf30..2774849 100644 --- a/frontend/src/components/home/Hero.astro +++ b/frontend/src/components/home/Hero.astro @@ -1,48 +1,35 @@ --- import Button from '@components/base/Button.astro'; -// Текстовые константы для удобного редактирования const badgeText = "ЗАЩИТА ПРАВ ВОДИТЕЛЕЙ В СУРГУТЕ"; const titleWhite = "Защитите свои права"; const titleGold = "и водительское удостоверение"; const description = "Профессиональная юридическая помощь при ДТП, спорах с ГИБДД и страховыми компаниями. Работаем на результат в судах ХМАО-Югры."; - const btnPrimary = "Бесплатная консультация"; const btnSecondary = "Наши услуги"; -// Пути к изображениям (замените на свои локальные файлы в папке public/ или src/assets/) -// Для демо я использую плейсхолдеры const bgImageUrl = "/images/home/bg_hero.png"; const lawyerImageUrl = "/images/home/heroImg.jpg"; ---
-
- -
-
- - - + {badgeText}
-

{titleWhite}
{titleGold}

-

{description}

-
-
- -
Юрист - -
20+ ЛЕТ ОПЫТА В ХМАО
-
-
diff --git a/frontend/src/components/layout/header/Header.astro b/frontend/src/components/layout/header/Header.astro index 6887a78..9d329f6 100644 --- a/frontend/src/components/layout/header/Header.astro +++ b/frontend/src/components/layout/header/Header.astro @@ -1,21 +1,33 @@ --- import Logo from './Logo.astro'; -import LoginButton from './LoginButton.astro'; import Navbar from './Navbar.astro'; import MobileMenu from './MobileMenu.astro'; +import { COMPANY } from '@constants'; --- @@ -31,88 +48,30 @@ import MobileMenu from './MobileMenu.astro'; document.addEventListener('DOMContentLoaded', () => { const burgerBtn = document.getElementById('burger-btn'); const mobileMenuOverlay = document.getElementById('mobile-menu-overlay'); - const mobileMenuClose = document.getElementById('mobile-menu-close'); - const mobileNavLinks = mobileMenuOverlay?.querySelectorAll('.mobile-nav-link'); const progressBar = document.getElementById('progress-bar'); const header = document.getElementById('header'); - // Обработка прогресса скролла - function updateProgressBar() { - if (!progressBar) return; - - // Получаем высоту документа и окна + function updateScroll() { const scrollTop = window.scrollY || document.documentElement.scrollTop; const docHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; - // Избегаем деления на ноль - if (docHeight <= 0) { - progressBar.style.width = '0%'; - return; + if (progressBar && docHeight > 0) { + const scrollPercent = (scrollTop / docHeight) * 100; + progressBar.style.width = `${Math.min(100, Math.max(0, scrollPercent))}%`; } - // Вычисляем процент прокрутки (0-100) - const scrollPercent = (scrollTop / docHeight) * 100; - - // Ограничиваем значения от 0 до 100 - const clampedPercent = Math.min(100, Math.max(0, scrollPercent)); - - // Применяем ширину - progressBar.style.width = `${clampedPercent}%`; - - // Добавляем/убираем класс visible для дополнительных эффектов - if (scrollTop > 5) { - header?.classList.add('scrolled'); - } else { - header?.classList.remove('scrolled'); - } + if (scrollTop > 10) header?.classList.add('scrolled'); + else header?.classList.remove('scrolled'); } - // Оптимизация через requestAnimationFrame - let ticking = false; - function handleScroll() { - if (!ticking) { - window.requestAnimationFrame(() => { - updateProgressBar(); - ticking = false; - }); - ticking = true; - } - } + window.addEventListener('scroll', updateScroll, { passive: true }); - // Инициализация и слушатели - updateProgressBar(); - window.addEventListener('scroll', handleScroll, { passive: true }); - window.addEventListener('resize', updateProgressBar); - - // Мобильное меню - function openMenu() { - mobileMenuOverlay?.classList.add('active'); - document.body.style.overflow = 'hidden'; - burgerBtn?.classList.add('active'); - } - - function closeMenu() { - mobileMenuOverlay?.classList.remove('active'); - document.body.style.overflow = ''; - burgerBtn?.classList.remove('active'); - } - - burgerBtn?.addEventListener('click', openMenu); - mobileMenuClose?.addEventListener('click', closeMenu); - - mobileMenuOverlay?.addEventListener('click', (e) => { - if (e.target === mobileMenuOverlay) closeMenu(); - }); - - mobileNavLinks?.forEach(link => { - link.addEventListener('click', closeMenu); - }); - - document.addEventListener('keydown', (e) => { - if (e.key === 'Escape' && mobileMenuOverlay?.classList.contains('active')) { - closeMenu(); - } + burgerBtn?.addEventListener('click', () => { + mobileMenuOverlay?.classList.toggle('active'); + burgerBtn?.classList.toggle('active'); + document.body.style.overflow = mobileMenuOverlay?.classList.contains('active') ? 'hidden' : ''; }); + updateScroll(); }); @@ -121,119 +80,152 @@ import MobileMenu from './MobileMenu.astro'; position: fixed; top: 0; left: 0; - right: 0; - background-color: #d1d9e4; - font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + width: 100%; + background-color: var(--color-light); z-index: 1000; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease, box-shadow 0.3s ease; + margin: 0 !important; /* Убираем любые отступы */ + padding: 0 !important; + border-bottom: 1px solid rgba(30, 48, 80, 0.05); } - /* Контейнер прогресс-бара */ + .header-wrapper.scrolled { + background-color: rgba(209, 217, 228, 0.98); + backdrop-filter: blur(10px); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + } + + .header-container { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + /* ФИКСИРОВАННЫЕ ВЫСОТЫ (важно для Hero) */ + height: 80px; + transition: height 0.3s ease; + } + + .header-wrapper.scrolled .header-container { + height: 70px; + } + + .header-column { display: flex; align-items: center; } + .header-left { justify-content: flex-start; } + .header-center { justify-content: center; } + .header-right { justify-content: flex-end; gap: 1.5rem; } + + /* НОМЕР ТЕЛЕФОНА В ШАПКЕ */ + .header-phone { + display: flex; + align-items: center; + gap: 0.5rem; + color: #1e3050; + text-decoration: none; + font-weight: 600; + font-size: 0.95rem; + white-space: nowrap; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + padding: 0.6rem 1.2rem; + border-radius: 10px; + overflow: hidden; + letter-spacing: 0.3px; + cursor: pointer; + background: transparent; + position: relative; + } + + .header-phone:hover { + color: #0a1a2e; + background: rgba(30, 48, 80, 0.05); + transform: translateY(-2px); + } + + /* Эффект перелива при наведении */ + .header-phone::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(234, 194, 110, 0.1), transparent); + transition: left 0.5s ease; + pointer-events: none; + } + + .header-phone:hover::after { + left: 100%; + } + + .phone-icon { + flex-shrink: 0; + transition: transform 0.3s ease; + } + + .header-phone:hover .phone-icon { + transform: scale(1.1); + } + + .phone-number { + font-weight: 700; + } + + /* ПОЛОСА ПРОГРЕССА */ .header-progress-container { position: absolute; bottom: 0; left: 0; width: 100%; height: 3px; - background: rgba(212, 175, 55, 0.1); + background: rgba(234, 194, 110, 0.1); + z-index: 1001; /* Выше фона шапки */ overflow: hidden; } - /* Сама линия прогресса */ .header-progress-bar { height: 100%; width: 0%; - background: linear-gradient(90deg, #d4af37 0%, #e8c547 50%, #d4af37 100%); - background-size: 200% 100%; - transition: width 0.1s linear; - box-shadow: 0 0 10px rgba(212, 175, 55, 0.5); - animation: shimmer 2s infinite linear; + background: linear-gradient(90deg, var(--color-gold) 0%, #f0d68a 50%, var(--color-gold) 100%); + box-shadow: 0 0 10px rgba(234, 194, 110, 0.5); } - /* Эффект мерцания градиента */ - @keyframes shimmer { - 0% { background-position: 200% 0; } - 100% { background-position: -200% 0; } - } - - /* Состояние при скролле */ - .header-wrapper.scrolled { - background-color: rgba(209, 217, 228, 0.95); - backdrop-filter: blur(10px); - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); - } - - .header-container { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1.2rem 0; - position: relative; - } - - .contact-block { - display: flex; - align-items: center; - gap: 1rem; - } - - /* Кнопка гамбургера */ + /* БУРГЕР */ .burger-btn { display: none; flex-direction: column; justify-content: space-between; - width: 30px; - height: 21px; + width: 28px; + height: 18px; background: transparent; border: none; cursor: pointer; - padding: 0; - z-index: 1001; - margin-left: 1rem; } - .burger-line { - width: 100%; - height: 3px; - background: linear-gradient(90deg, #1e3050 0%, #2a4266 100%); - border-radius: 2px; - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - transform-origin: center; + width: 100%; height: 2.5px; + background-color: var(--color-primary); + border-radius: 4px; transition: 0.3s; } - .burger-btn.active .burger-line:nth-child(1) { - transform: rotate(45deg) translate(5px, 5px); - } - - .burger-btn.active .burger-line:nth-child(2) { - opacity: 0; - transform: scaleX(0); - } - - .burger-btn.active .burger-line:nth-child(3) { - transform: rotate(-45deg) translate(5px, -5px); - } + .burger-btn.active .burger-line:nth-child(1) { transform: translateY(8px) rotate(45deg); } + .burger-btn.active .burger-line:nth-child(2) { opacity: 0; } + .burger-btn.active .burger-line:nth-child(3) { transform: translateY(-8px) rotate(-45deg); } @media (max-width: 992px) { - .burger-btn { - display: flex; - } - - .login-btn { + .header-container { display: flex; justify-content: space-between; height: 70px; } + .header-center { display: none; } + .header-right { gap: 0.75rem; } + .header-phone { display: none; } + .burger-btn { display: flex; } } - @media (max-width: 576px) { - .contact-block { - flex-direction: column; - align-items: flex-end; - gap: 0.5rem; - } - - .header-container { - padding: 0 1rem; + @media (min-width: 993px) { + .header-phone { + display: flex; } } - + + @media (max-width: 767px) { + .header-container { height: 64px; padding: 0 1rem; } + } + \ No newline at end of file diff --git a/frontend/src/components/layout/header/LoginButton.astro b/frontend/src/components/layout/header/LoginButton.astro index 786ff4e..e78a9a6 100644 --- a/frontend/src/components/layout/header/LoginButton.astro +++ b/frontend/src/components/layout/header/LoginButton.astro @@ -95,4 +95,11 @@ const classes = `${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} .login-text { white-space: nowrap; } + + /* Скрываем на мобильных разрешениях */ + @media (max-width: 992px) { + .login-btn { + display: none; + } + } diff --git a/frontend/src/components/layout/header/MobileMenu.astro b/frontend/src/components/layout/header/MobileMenu.astro index bf32b9c..895447e 100644 --- a/frontend/src/components/layout/header/MobileMenu.astro +++ b/frontend/src/components/layout/header/MobileMenu.astro @@ -1,82 +1,102 @@ --- -import { NAV_LINKS } from '../../../constants/index.ts'; +import { NAV_LINKS } from '@constants'; ---
- +
+ Автоюрист + 086 +
+
+ - - + + + + + +
+
+
📞
+ +7 (3462) 00-00-00 + Ежедневно 9:00–21:00 +
+ + + +
+ +// Внутри MobileMenu.astro + \ No newline at end of file diff --git a/frontend/src/components/layout/header/Navbar.astro b/frontend/src/components/layout/header/Navbar.astro index 15e2afc..b2354ad 100644 --- a/frontend/src/components/layout/header/Navbar.astro +++ b/frontend/src/components/layout/header/Navbar.astro @@ -1,10 +1,11 @@ --- export interface Props { - links?: Array<{ name: string; url: string }>; - class?: string; + links?: Array<{ name: string; url: string }>; + class?: string; } const defaultLinks = [ + { name: 'Главная', url: '/' }, { name: 'Услуги', url: '/services' }, { name: 'Кейсы', url: '/cases' }, { name: 'Блог', url: '/blog' }, @@ -12,53 +13,229 @@ const defaultLinks = [ { name: 'Контакты', url: '/contacts' }, ]; -const { - links = defaultLinks, - class: className = '', +const { + links = defaultLinks, + class: className = '', }: Props = Astro.props; + +// Определяем текущую страницу +const currentPath = Astro.url.pathname; +const isHomePage = currentPath === '/' || currentPath === ''; + +// Фильтруем ссылки: убираем "Главная" если мы на главной странице +const filteredLinks = isHomePage + ? links.filter(link => link.url !== '/') + : links; --- + + \ No newline at end of file diff --git a/frontend/src/constants.ts b/frontend/src/constants.ts index 53f2dbe..a007445 100644 --- a/frontend/src/constants.ts +++ b/frontend/src/constants.ts @@ -1,2 +1,25 @@ export const SITE_URL = 'https://avtourist-surgut.ru/'; export const SITE_TITLE_SUFFIX = ' | Автоюрист Сургут'; + +// ============================================ +// КОНСТАНТЫ САЙТА "Автоюрист 086" +// ============================================ + +// Основная информация о компании +export const COMPANY = { + name: 'Автоюрист 086', + fullName: 'Центр защиты прав водителей "Автоюрист 086"', + phone: '+7 (922) 253-83-75', + email: 'info@avtourist086.ru', + address: 'г. Сургут, ул. Примерная, д. 1', + workHours: 'Пн-Пт: 9:00 - 18:00', +} as const; + +// Навигация +export const NAV_LINKS = [ + { name: 'Услуги', url: '/services' }, + { name: 'Кейсы', url: '/cases' }, + { name: 'Блог', url: '/blog' }, + { name: 'Отзывы', url: '/reviews' }, + { name: 'Контакты', url: '/contacts' }, +] as const; diff --git a/frontend/src/constants/index.ts b/frontend/src/constants/index.ts deleted file mode 100644 index f951d86..0000000 --- a/frontend/src/constants/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -// ============================================ -// КОНСТАНТЫ САЙТА "Автоюрист 086" -// ============================================ - -// Основная информация о компании -export const COMPANY = { - name: 'Автоюрист 086', - fullName: 'Центр защиты прав водителей "Автоюрист 086"', - phone: '+7 (999) 999-99-99', - email: 'info@avtourist086.ru', - address: 'г. Сургут, ул. Примерная, д. 1', - workHours: 'Пн-Пт: 9:00 - 18:00', -} as const; - -// Навигация -export const NAV_LINKS = [ - { name: 'Услуги', url: '/services' }, - { name: 'Кейсы', url: '/cases' }, - { name: 'Блог', url: '/blog' }, - { name: 'Отзывы', url: '/reviews' }, - { name: 'Контакты', url: '/contacts' }, -] as const; diff --git a/frontend/src/layouts/Layout.astro b/frontend/src/layouts/Layout.astro index 577c480..c770938 100644 --- a/frontend/src/layouts/Layout.astro +++ b/frontend/src/layouts/Layout.astro @@ -39,9 +39,9 @@ const { title, description, canonicalLink } = Astro.props; diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index e2b371f..55914f6 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -1,35 +1,28 @@ @import "tailwindcss"; -/* ============================================ - ЦВЕТОВЫЕ ПЕРЕМЕННЫЕ САЙТА "Автоюрист 086" - ============================================ */ :root { - /* Основные цвета */ - --color-primary: #1e3050; /* Тёмно-синий */ - --color-secondary: #535e6c; /* Серый */ - --color-gold: #eac26e; /* Золотой */ - --color-gold-dark: #ce9f40; /* Тёмно-золотой */ - --color-light: #d1d9e4; /* Серо-голубой фон */ - --color-white: #ffffff; /* Белый */ - - /* Дополнительные оттенки */ - --color-primary-dark: #152238; /* Тёмно-синий тёмный */ - --color-gray-light: #f0f2f5; /* Светло-серый фон */ - --color-gray-border: #e0e4e8; /* Цвет границ */ - --color-text-muted: #9ca3af; /* Приглушённый текст */ - - /* Функциональные цвета */ - --color-success: #10b981; /* Успех */ - --color-error: #ef4444; /* Ошибка */ - --color-warning: #f59e0b; /* Предупреждение */ - - /* Ширина контейнера сайта */ --site-max-width: 1400px; } -/* Единый контейнер для всех компонентов */ +html, body { + margin: 0; + padding: 0; + width: 100%; + overflow-x: hidden; + background-color: var(--color-white); /* Цвет фона страницы */ +} + +/* 2. Исправленный контейнер */ .site-container { + width: 100%; max-width: var(--site-max-width); margin: 0 auto; - padding: 0 2rem; + padding: 0 1rem; + box-sizing: border-box; +} + +@media (min-width: 768px) { + .site-container { + padding: 0 2rem; + } } \ No newline at end of file