# DESIGN.md Портфолио-сайт продуктового дизайнера. Лонгриды кейсов, резюме, блог. Визуал — минимализм с акцентом на типографику и контент. --- ## Продукт Одностраничный сайт-портфолио с внутренними страницами (кейсы, резюме, блог). Основной контент — лонгриды с описанием проектов. Навигация через главную страницу с секциями: навыки, портфолио, контакты. **Характер:** Сдержанный, профессиональный. Без визуального шума. Контент — главный элемент интерфейса. --- ## Цвета ### Токены темы | Токен | Назначение | |---|---| | `--theme-h` | Оттенок акцента (0–360°) | | `--theme-s` | Насыщенность акцента | | `--theme-l` | Светлота акцента | | `--accent` | Основной акцентный цвет | | `--accent-text` | Цвет текста на акцентном фоне | | `--accent-soft` | Мягкий акцент для фона | | `--bg` | Фон страницы | | `--bg-elevated` | Поверхность второго уровня | | `--surface` | Фон карточек и секций | | `--text` | Основной текст | | `--text-muted` | Приглушённый текст | | `--line` | Рамки и разделители | ### Правила - Акцент меняется через `--theme-h/s/l` на ``. Все производные пересчитываются автоматически. - Светлая/тёмная тема — `data-theme="light|dark"` на ``. - Нейтральные фоны (`--bg`, `--surface`) слегка подмешивают оттенок акцента через `--neutral-accent-tint`. - Не используйте хардкод hex-значений. Всегда обращайтесь к токенам. --- ## Типографика ### Семейства | `data-font` | Стек | Назначение | |---|---|---| | `merriweather` | Merriweather + Alice | По умолчанию. Alice — проза, Merriweather — заголовки | | `geologica` | Geologica + PT Sans | Гротеск + нейтральная проза | | `mono` | Source Code Pro + PT Mono | Моноширинный | ### Шкала | Класс | Размер | Вес | Назначение | |---|---|---|---| | `.hero__eyebrow` | `0.78rem` | 700 | Подзаголовок секции, ввод кейса. Uppercase, letter-spacing 0.14em | | `.hero__title` | `clamp(3.1rem, 7.2vw, 4.85rem)` | 700 | H1 главной страницы | | `.case-page__h1` | `clamp(2rem, 3.9vw, 2.9rem)` | 700 | H1 кейса / внутренней страницы | | `.case-page__sub` | `clamp(1.5rem, 2vw, 1.65rem)` | 500 | Подзаголовок под H1 | | `.section__title` | `clamp(0.95rem, 1.35vw, 1.1rem)` | 600 | Заголовки секций («Навыки», «Портфолио») | | `.section__prose` | наследует | — | Основной текст абзацев | | `h2` в `.case-article` | `clamp(1.5rem, 2vw, 1.65rem)` | 500 | Разделы лонгрида | | `h3` в `.case-article` | наследует | — | Подразделы внутри H2 | ### Правила - Заголовки используют `clamp()` — размер масштабируется от вьюпорта. - Не задавайте `font-size` в пикселях. Используйте `rem` или `clamp()`. - `line-height` для прозы: `1.55` (базовый), для заголовков: `1.2`. - `max-width` текстовой колонки: `42rem` (`.section__prose`). --- ## Отступы и сетка ### Токены | Токен | Значение | Назначение | |---|---|---| | `--space` | `clamp(1rem, 4vw, 2.75rem)` | Горизонтальные поля + safe-area | | `--max` | `none` | Ширина контента = вьюпорт минус padding | | `--radius-sm` | Зависит от `data-radius` | Малые скругления | | `--radius-md` | Зависит от `data-radius` | Средние скругления | | `--radius-card` | Зависит от `data-radius` | Карточки | ### Секции | Класс | Назначение | |---|---| | `.section` | Вертикальные отступы через `clamp()` | | `.section--tight` | Компактные отступы (кейсы, внутренние страницы) | | `.section--surface` | Прозрачный фон (для mesh на главной) | | `.section__inner` | Центрированная обёртка с `max-width: var(--max)` | | `.case-article` | Контентная колонка лонгрида: `max-width: 48rem` | ### Брейкпоинты | Ширина | Что меняется | |---|---| | `860px` | Hero → 2 колонки (`1.15fr 0.85fr`) | | `760px` / `1180px` | Карусель портфолио: 1 → 2 → 3 карточки | | `720px` | Сетка навыков → 2 колонки | | `1024px` | Навыки: 6-колоночная мозаика | | `560px` / `1024px` | Контакты → 2 → 4 колонки | | `640px` | Wide-блоки схлопываются в ширину колонки | ### Правила - Отдельной 12-колоночной сетки нет. Используйте CSS Grid внутри секций. - Горизонтальные отступы — `--space` + `safe-area-inset`. - Wide-блоки (`.case-media--wide`, `.case-callout`) шире колонки: `min(100vw - 2*padding, content + 8rem)`. --- ## Компоненты ### Кнопки | Класс | Назначение | |---|---| | `.btn` | Базовый класс кнопки | | `.btn--primary` | Основная кнопка (акцентный фон, стекло) | | `.btn--secondary` | Вторичная кнопка (нейтральное стекло) | | `.btn--ghost` | Текстовая кнопка без фона | | `.btn--flat` | Плоский вариант (без «объёма») | | `.btn--raised` | Приподнятый вариант (с тенью) | | `.btn__icon` | Иконка внутри кнопки | ### FAB-кнопки | Класс | Назначение | |---|---| | `.fab` | Базовый класс плавающей кнопки (круглая, `position: fixed`) | | `.fab--primary` | Акцентная FAB (градиент, стекло, `--on-accent` для текста/иконки) | | `.fab--secondary` | Вторичная FAB (нейтральная, для настроек) | | `.fab--label` | Модификатор: снимает фиксированную ширину, добавляет текст рядом с иконкой | | `.fab-primary__ico` | Иконка внутри primary FAB (маска через `mask-image`) | | `.fab__label` | Текстовая подпись внутри FAB | Правило: `--on-accent` вычисляется в синхронном `theme-init-script` (в `
`) по luminance акцента. Не задавайте `color` вручную — наследуется от `.fab--primary`. ### Теги | Класс | Назначение | |---|---| | `.hero__tags` | Контейнер тегов в Hero | | `.hero__tag` | Тег (пилл с рамкой). Используйте для ключевых слов | | `.portfolio-card__tag` | Тег внутри карточки портфолио | ### Карточки | Класс | Назначение | |---|---| | `.portfolio-card` | Карточка проекта в портфолио | | `.portfolio-card__body` | Текстовая часть | | `.portfolio-card__cover` | Обложка | | `.skill-task-card` | Карточка навыка (задача + решения) | | `.contact-card` | Контактная карточка (ссылка или действие) | ### Блоки лонгрида | Класс | Назначение | |---|---| | `.hero__eyebrow` | Подзаголовок перед H1 | | `.case-page__h1` | Заголовок страницы | | `.case-page__sub` | Подзаголовок | | `.section__prose` | Абзац текста | | `.section__title` | Заголовок секции | | `.case-callout` | Акцентный блок (важная мысль) | | `.case-media` | Обёртка для изображения/видео | | `.case-media--natural` | Изображение в натуральном масштабе | | `.case-media--content` | По ширине текстовой колонки | | `.case-media--wide` | Шире колонки статьи | --- ## Поведение ### Изображения - Формат: **WebP** для всех изображений. - Видео: **WebM** (MP4 как fallback). - Lazy loading: `loading="lazy"`, `decoding="async"`. - Просмотр по клику: `data-image-viewer` на `