/** * Page Header Component * * Универсальная шапка для страниц списков с: * - Полупрозрачным фоном (sticky positioning) * - Иконкой и заголовком * - Счётчиком элементов * - Переключателем области (Мои/Все) * - Кнопкой фильтров * - Кнопкой создания (вытянутая на десктопе, иконка на мобильных) * - Поиском iOS-стиль * * Использование: * {% include "includes/components/page_header.html" with ... %} * */ /* ===== ОСНОВНОЙ КОНТЕЙНЕР ШАПКИ ===== */ .page-header { position: sticky; top: var(--navbar-h, 60px); z-index: 10; padding: var(--space-2) 0; /* 8px сверху/снизу */ margin-bottom: var(--space-3); /* 12px отступ снизу */ /* Полупрозрачный фон с градиентом */ background: linear-gradient( to bottom, color-mix(in srgb, var(--bs-body-bg) 90%, transparent) 0%, color-mix(in srgb, var(--bs-body-bg) 85%, transparent) 30%, color-mix(in srgb, var(--bs-body-bg) 70%, transparent) 50%, color-mix(in srgb, var(--bs-body-bg) 40%, transparent) 70%, transparent 100% ); /* Убрана border-bottom - линия не нужна */ /* Анимация появления при скролле */ transition: background 0.2s ease, box-shadow 0.2s ease; } /* Псевдоэлемент для градиентного размытия */ .page-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; backdrop-filter: saturate(180%) blur(12px); -webkit-backdrop-filter: saturate(180%) blur(12px); mask-image: linear-gradient( to bottom, black 0%, black 30%, rgba(0, 0, 0, 0.7) 50%, rgba(0, 0, 0, 0.4) 70%, transparent 100% ); -webkit-mask-image: linear-gradient( to bottom, black 0%, black 30%, rgba(0, 0, 0, 0.7) 50%, rgba(0, 0, 0, 0.4) 70%, transparent 100% ); pointer-events: none; z-index: -1; } /* Контент должен быть выше псевдоэлемента */ .page-header > * { position: relative; z-index: 1; } /* При скролле - более выраженный фон */ .page-header.scrolled { background: linear-gradient( to bottom, color-mix(in srgb, var(--bs-body-bg) 95%, transparent) 0%, color-mix(in srgb, var(--bs-body-bg) 90%, transparent) 30%, color-mix(in srgb, var(--bs-body-bg) 75%, transparent) 50%, color-mix(in srgb, var(--bs-body-bg) 45%, transparent) 70%, transparent 100% ); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); } /* ===== ЗАГОЛОВОК ===== */ .page-title { font-weight: 800; font-size: 1.75rem; letter-spacing: -0.01em; line-height: 1.2; color: var(--bs-body-color); flex-shrink: 0; } /* ===== СЧЁТЧИК ===== */ .page-count { font-size: 0.875rem; color: var(--bs-secondary-color); white-space: nowrap; flex-shrink: 0; } .page-count .count-value { font-weight: 600; color: var(--bs-body-color); } /* ===== ПЕРЕКЛЮЧАТЕЛЬ ОБЛАСТИ (МОИ/ВСЕ) ===== */ .page-scope-switch { flex-shrink: 0; } .page-scope-switch .btn { min-width: 60px; font-size: 0.875rem; border-radius: 999px; padding: 0.375rem 0.75rem; transition: all 0.2s ease; } .page-scope-switch .btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; } .page-scope-switch .btn:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } .page-scope-switch .btn.active { background-color: var(--bs-primary); border-color: var(--bs-primary); color: white; font-weight: 600; } /* ===== КНОПКА ФИЛЬТРОВ ===== */ /* Использует класс .btn-circle из buttons.css */ .page-filter-toggle:hover { background-color: color-mix(in srgb, var(--bs-primary), transparent 85%); border-color: var(--bs-primary); color: var(--bs-primary); } .page-filter-toggle[aria-expanded="true"] { background-color: var(--bs-primary); border-color: var(--bs-primary); color: white; } /* ===== КНОПКА СОЗДАНИЯ ===== */ /* Использует классы .btn-pill и .btn-icon из buttons.css */ .page-create-btn { font-weight: 600; font-size: 0.875rem; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: all 0.2s ease; } .page-create-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } .page-create-btn:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } /* ===== ПОИСК ===== */ .page-search { flex-shrink: 1; min-width: 200px; max-width: 400px; flex-grow: 1; } /* На мобильных поиск на всю ширину */ @media (max-width: 991.98px) { .page-search { flex-basis: 100%; max-width: none; margin-top: var(--space-2); order: 10; } } /* ===== БЛОК ФИЛЬТРОВ ===== */ .page-filters-collapse { margin-top: var(--space-2); width: 100%; } .page-filters { border-radius: var(--radius-lg, 14px); border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 10%); background: var(--bs-body-bg); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); padding: var(--space-3); animation: slideDown 0.3s ease; } /* Адаптивность кнопок внутри фильтров */ .page-filters .btn { white-space: nowrap; min-width: fit-content; } .page-filters .d-flex.gap-2 { flex-wrap: wrap; } @keyframes slideDown { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } /* ===== АДАПТИВНОСТЬ ===== */ /* Планшеты */ @media (max-width: 991.98px) { .page-title { font-size: 1.5rem; } .page-header { padding: var(--space-2) 0; } } /* Мобильные */ @media (max-width: 575.98px) { .page-title { font-size: 1.25rem; } .page-count { font-size: 0.75rem; } .page-scope-switch .btn { min-width: 50px; font-size: 0.75rem; padding: 0.25rem 0.5rem; } } /* ===== ИНТЕГРАЦИЯ С IOS-SEARCH ===== */ /* ios-search уже определён в ios-search.css, здесь только позиционирование */ .page-search .ios-search { width: 100%; } /* ===== КНОПКА СОЗДАНИЯ В ВИДЕ КАРТОЧКИ (для модала) ===== */ /* Кнопка должна выглядеть как ссылка в feed-card */ .page-header .feed-card { margin-top: var(--space-2); width: 100%; } .page-header .feed-card button.dept-row, .page-header .feed-card a.dept-row { cursor: pointer; transition: background-color 0.2s ease; width: 100%; padding: var(--space-1) var(--space-2); text-align: center; } /* Текст кнопки должен быть как feed-author */ .page-header .feed-card button.dept-row .feed-author, .page-header .feed-card a.dept-row .feed-author { font-weight: 700; color: var(--bs-body-color); } /* Иконка должна быть синей как в оригинале */ .page-header .feed-card button.dept-row i, .page-header .feed-card a.dept-row i { color: var(--bs-primary); } .page-header .feed-card button.dept-row:hover, .page-header .feed-card a.dept-row:hover { background-color: var(--bs-light); } @media (prefers-color-scheme: dark) { .page-header .feed-card button.dept-row:hover, .page-header .feed-card a.dept-row:hover { background-color: color-mix(in srgb, var(--bs-body-bg) 95%, white); } } /* ===== ТЕМНАЯ ТЕМА ===== */ @media (prefers-color-scheme: dark) { .page-header { background: linear-gradient( to bottom, color-mix(in srgb, var(--bs-body-bg) 85%, transparent) 0%, color-mix(in srgb, var(--bs-body-bg) 80%, transparent) 45%, color-mix(in srgb, var(--bs-body-bg) 65%, transparent) 50%, color-mix(in srgb, var(--bs-body-bg) 35%, transparent) 70%, transparent 100% ); border-bottom-color: color-mix(in srgb, var(--bs-border-color), transparent 60%); } .page-header.scrolled { background: linear-gradient( to bottom, color-mix(in srgb, var(--bs-body-bg) 90%, transparent) 0%, color-mix(in srgb, var(--bs-body-bg) 80%, transparent) 30%, color-mix(in srgb, var(--bs-body-bg) 72%, transparent) 50%, color-mix(in srgb, var(--bs-body-bg) 40%, transparent) 70%, transparent 100% ); } .page-filters { box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3); } }