/
Jenison4ik
/
SeaSearch_Alt
Обзор
Документация
Войти
/
Jenison4ik
/
SeaSearch_Alt
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
styles.css
501 строка
12 KB
Jenison4ik
first_commit
04 мар 2026, 05:34
04 мар 2026, 05:34
d740bbc
Код
Авторство
О чём код?
/* ============================================= ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ (CSS Custom Properties) Центральное место для хранения цветов, шрифтов, отступов — легко менять тему целиком ============================================= */ :root { /* Основные цвета */ --color-bg: #f0f4f8; /* фон страницы — мягкий сине-серый */ --color-surface: #ffffff; /* фон карточек и модалки */ --color-text: #1a2332; /* основной текст */ --color-text-secondary: #5a6a7e;/* вторичный текст (адрес, подпись) */ --color-accent: #0070f3; /* акцентный синий (кнопки, ссылки) */ --color-accent-hover: #005bb5; /* акцент при наведении */ --color-border: #e2e8f0; /* рамки и разделители */ /* Цвета бейджей по типу места */ --badge-beach-bg: #dbeafe; /* Пляж — голубой фон */ --badge-beach-text: #1d4ed8; /* Пляж — синий текст */ --badge-bay-bg: #dcfce7; /* Бухта — зелёный фон */ --badge-bay-text: #15803d; /* Бухта — зелёный текст */ --badge-harbor-bg: #fef3c7; /* Гавань — жёлтый фон */ --badge-harbor-text: #92400e; /* Гавань — коричневый текст */ /* Типографика */ --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; /* Скругления */ --radius-sm: 8px; --radius-md: 12px; --radius-lg: 16px; /* Тени */ --shadow-card: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06); --shadow-card-hover: 0 4px 12px rgba(0,0,0,0.12); } /* ============================================= СБРОС И БАЗОВЫЕ СТИЛИ Убираем дефолтные отступы браузера, задаём шрифт и цвет по умолчанию ============================================= */ *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } html { /* Плавная прокрутка при клике на якоря */ scroll-behavior: smooth; } body { font-family: var(--font-family); background-color: var(--color-bg); color: var(--color-text); line-height: 1.6; min-height: 100vh; /* Запрещаем горизонтальный скролл */ overflow-x: hidden; } /* ============================================= ХЕДЕР Фиксированная шапка с названием проекта ============================================= */ .header { background: var(--color-surface); border-bottom: 1px solid var(--color-border); padding: 16px 20px; } /* Внутренний контейнер — ограничиваем ширину */ .header__inner { max-width: 600px; margin: 0 auto; display: flex; align-items: center; gap: 12px; } /* SVG иконка волны */ .header__icon { width: 32px; height: 32px; color: var(--color-accent); flex-shrink: 0; /* не сжимается при нехватке места */ } /* Заголовок «SeaSearch» */ .header__title { font-size: 22px; font-weight: 700; letter-spacing: -0.3px; } /* Подзаголовок «Владивосток» */ .header__subtitle { font-size: 13px; color: var(--color-text-secondary); margin-top: -2px; } /* ============================================= ФИЛЬТРЫ Горизонтальный ряд кнопок для выбора типа ============================================= */ .filters { max-width: 600px; margin: 16px auto 0; padding: 0 20px; display: flex; gap: 8px; /* Если не помещается — горизонтальный скролл */ overflow-x: auto; } /* Каждая кнопка фильтра */ .filters__btn { padding: 8px 18px; border: 1px solid var(--color-border); border-radius: 50px; /* таблетка */ background: var(--color-surface); color: var(--color-text-secondary); font-size: 14px; font-weight: 500; cursor: pointer; white-space: nowrap; /* не переносим текст */ /* Убираем дефолтные стили кнопки */ font-family: inherit; transition: background 0.15s, color 0.15s, border-color 0.15s; } /* Наведение на неактивный фильтр */ .filters__btn:hover { border-color: var(--color-accent); color: var(--color-accent); } /* Активный (выбранный) фильтр */ .filters__btn--active { background: var(--color-accent); color: #fff; border-color: var(--color-accent); } /* ============================================= ОСНОВНАЯ ОБЛАСТЬ ============================================= */ .main { max-width: 600px; margin: 0 auto; padding: 16px 20px 40px; } /* ============================================= ЗАГРУЗЧИК (СПИННЕР) Отображается пока данные не пришли с сервера ============================================= */ .loader { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 60px 0; } /* Крутящийся кружок */ .loader__spinner { width: 36px; height: 36px; border: 3px solid var(--color-border); border-top-color: var(--color-accent); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .loader__text { color: var(--color-text-secondary); font-size: 14px; } /* ============================================= СООБЩЕНИЕ ОБ ОШИБКЕ ============================================= */ .error { text-align: center; padding: 40px 0; } .error__text { color: var(--color-text-secondary); margin-bottom: 16px; } /* Кнопка «Повторить» / «Вернуться к списку» */ .error__btn { display: inline-block; padding: 10px 24px; background: var(--color-accent); color: #fff; border: none; border-radius: var(--radius-sm); font-size: 14px; font-family: inherit; text-decoration: none; cursor: pointer; } .error__btn:hover { background: var(--color-accent-hover); } /* ============================================= КАРТОЧКИ МЕСТ Сетка карточек — одна колонка на мобилке, две на более широких экранах ============================================= */ .cards { display: grid; grid-template-columns: 1fr; gap: 16px; } /* Одна карточка */ .card { background: var(--color-surface); border-radius: var(--radius-md); box-shadow: var(--shadow-card); overflow: hidden; /* обрезаем углы картинки */ cursor: pointer; transition: box-shadow 0.15s, transform 0.15s; } /* Подъём карточки при наведении */ .card:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); } /* Обёртка для изображения — фиксированные пропорции */ .card__image-wrap { width: 100%; aspect-ratio: 16 / 10; overflow: hidden; background: var(--color-border); /* плейсхолдер пока грузится фото */ } /* Само изображение — заполняет контейнер */ .card__image { width: 100%; height: 100%; object-fit: cover; display: block; } /* Текстовая часть карточки */ .card__body { padding: 14px 16px 16px; } /* Название места */ .card__title { font-size: 16px; font-weight: 600; margin-bottom: 6px; } /* Адрес под названием */ .card__address { font-size: 13px; color: var(--color-text-secondary); margin-bottom: 8px; } /* ============================================= БЕЙДЖ (ТЭЙП) ТИПА МЕСТА Цветная метка: Пляж / Бухта / Гавань ============================================= */ .badge { display: inline-block; padding: 3px 10px; border-radius: 50px; font-size: 12px; font-weight: 600; line-height: 1.4; } /* Цвета бейджей — каждому типу свой */ .badge--beach { background: var(--badge-beach-bg); color: var(--badge-beach-text); } .badge--bay { background: var(--badge-bay-bg); color: var(--badge-bay-text); } .badge--harbor { background: var(--badge-harbor-bg); color: var(--badge-harbor-text); } /* ============================================= ПУСТОЕ СОСТОЯНИЕ Когда фильтр не вернул ни одного результата ============================================= */ .empty { text-align: center; padding: 60px 0; } .empty__text { color: var(--color-text-secondary); font-size: 15px; } /* ============================================= МОДАЛЬНОЕ ОКНО (ДЕТАЛЬНЫЙ ПРОСМОТР МЕСТА) ============================================= */ /* Контейнер модалки — растянут на весь экран */ .modal { position: fixed; inset: 0; /* top:0, right:0, bottom:0, left:0 */ z-index: 1000; display: flex; align-items: flex-end; /* модалка появляется снизу */ justify-content: center; } /* hidden-атрибут должен скрывать модалку, несмотря на display:flex */ .modal[hidden] { display: none; } /* Полупрозрачный затемнённый фон */ .modal__overlay { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.5); } /* Само содержимое модалки */ .modal__content { position: relative; background: var(--color-surface); border-radius: var(--radius-lg) var(--radius-lg) 0 0; max-width: 600px; width: 100%; max-height: 90vh; overflow-y: auto; box-shadow: 0 -4px 30px rgba(0, 0, 0, 0.2); } /* Кнопка закрытия (крестик) */ .modal__close { position: absolute; top: 12px; right: 12px; width: 36px; height: 36px; border: none; border-radius: 50%; background: rgba(0, 0, 0, 0.4); color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 10; } .modal__close svg { width: 20px; height: 20px; } .modal__close:hover { background: rgba(0, 0, 0, 0.6); } /* Изображение в модалке */ .modal__image-wrap { width: 100%; aspect-ratio: 16 / 10; overflow: hidden; background: var(--color-border); } .modal__image { width: 100%; height: 100%; object-fit: cover; display: block; } /* Текстовый блок модалки */ .modal__body { padding: 20px; } /* Название места */ .modal__title { font-size: 22px; font-weight: 700; margin: 10px 0 6px; } /* Адрес */ .modal__address { font-size: 14px; color: var(--color-text-secondary); margin-bottom: 16px; } /* Описание — рендерится из Markdown через Showdown.js, стилизуем вложенные элементы */ .modal__description { font-size: 15px; line-height: 1.7; color: var(--color-text); } .modal__description h2 { font-size: 18px; font-weight: 700; margin: 20px 0 8px; } .modal__description h3 { font-size: 16px; font-weight: 600; margin: 16px 0 6px; } .modal__description p { margin-bottom: 10px; } .modal__description strong { font-weight: 600; } .modal__description ul, .modal__description ol { margin: 8px 0 12px 20px; } .modal__description li { margin-bottom: 4px; } .modal__description hr { border: none; border-top: 1px solid var(--color-border); margin: 16px 0; } /* ============================================= ПОДВАЛ (ФУТЕР) ============================================= */ .footer { text-align: center; padding: 20px; color: var(--color-text-secondary); font-size: 13px; border-top: 1px solid var(--color-border); max-width: 600px; margin: 0 auto; } /* ============================================= АДАПТИВНОСТЬ На экранах шире 480px показываем 2 колонки ============================================= */ @media (min-width: 480px) { .cards { grid-template-columns: repeat(2, 1fr); } }