Compare commits

...

11 Commits

Author SHA1 Message Date
5e80185cf7 Consolidate to Eleventy as single source of truth
Remove root HTML pages and the parallel client-side scheme
(components/head.js, components/*.html, assets/js/components.js)
along with duplicated assets/, css/, fonts/ at the root. Eleventy
partials in src/_includes/ already cover head (with Plausible),
header (with mega menu and full nav), and footer. Add .claude/ to
.gitignore to keep local worktrees out of commits.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 00:25:12 +03:00
ab4689bd2b current status 2026-04-21 23:27:50 +03:00
13c1cf9575 local fonts 2026-04-20 11:06:19 +03:00
372b910492 Restore UI-kit mega menu in header partial and fix nav links
- Restore UI-kit dropdown (mega menu) lost during 11ty migration:
  the block existed in index.html but not in components/menu.html,
  sourced from commit 08bd969
- Fix absolute nav links (/catalog.html, /about.html, etc.) to
  relative in header.njk and footer.njk for static file serving

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 23:45:48 +03:00
a2fd9a5483 Fix CSS/JS paths to relative for static file serving
Absolute paths (/css/site.css) break when opening _site/ directly
via file://. Relative paths work with both the dev server and static hosting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 23:26:40 +03:00
9e9cd69ce5 Migrate to 11ty and add prototype inspector
- Set up 11ty with Nunjucks templates (src/ → _site/)
- Extract shared header and footer into partials — single source of truth
- Convert all 11 pages to .njk with front matter (layout, title, permalink)
- Add base/default/ui-kit layout chain
- Add custom JS element inspector (Alt+I) with Typography, Tokens and Styles panels
- Add CLAUDE.md with architecture overview and dev commands
- Add .claude/launch.json with dev server configs
- Add docs/elementor-token-handoff.md
- Add _site/ to .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 23:13:13 +03:00
08bd969b19
Merge pull request #1 from 42point/codex/dp-trade-card
Codex/dp trade card
2026-04-18 16:52:15 +03:00
02a2782cb7 Refine footer layout and replace social icons 2026-04-17 23:55:09 +03:00
02193a0f66 Add editorial guidelines and refresh UI kit 2026-04-17 21:10:49 +03:00
18750fef24 Add demo pages for news, about, and contacts 2026-04-17 18:35:38 +03:00
4dd01aeb29 Add UI-kit demo pages and bottle card variants 2026-04-17 18:28:01 +03:00
62 changed files with 9548 additions and 2052 deletions

17
.claude/launch.json Normal file
View File

@ -0,0 +1,17 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "11ty dev server (live reload)",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"port": 8080
},
{
"name": "Python HTTP Server (_site)",
"runtimeExecutable": "python3",
"runtimeArgs": ["-m", "http.server", "8081", "--directory", "/Users/lexx/Projects/2026/dp-trade-UI-kit/_site"],
"port": 8081
}
]
}

16
.eleventy.js Normal file
View File

@ -0,0 +1,16 @@
export default function (eleventyConfig) {
eleventyConfig.addPassthroughCopy("src/css");
eleventyConfig.addPassthroughCopy("src/assets");
eleventyConfig.addPassthroughCopy("src/js");
eleventyConfig.addPassthroughCopy("src/fonts");
return {
dir: {
input: "src",
output: "_site",
includes: "_includes",
},
templateFormats: ["njk", "html"],
htmlTemplateEngine: "njk",
};
}

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
.DS_Store
node_modules/
dist/
_site/
.env
.claude/

View File

@ -0,0 +1,8 @@
{
"identifier" : "39856AD9-BD44-4500-B03F-EDFAE2A870CB",
"localPath" : "_site",
"remotePath" : "\/www\/vodkainmyblood.com\/wine-proto",
"remoteURL" : "wine-proto.vodkainmyblood.com",
"server" : "REG.RU hosting",
"usesPublishing" : true
}

100
CLAUDE.md Normal file
View File

@ -0,0 +1,100 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Перед началом работы над любой задачей сложнее одного шага
составь todo-список и показывай его прогресс по ходу выполнения.
Для задач с неочевидным подходом сначала предложи план и дождись подтверждения.
## Project
Static HTML/CSS UI-kit and page prototypes for **DP Trade** — a B2B wine wholesale catalog (wine-dp-trade.ru). The output of this project is handed off to **WordPress/Elementor** for production deployment. See `docs/elementor-token-handoff.md` for the full Elementor migration guide.
## Commands
```bash
# Dev server (11ty with live reload)
npm run dev # http://localhost:8080
# Production build → _site/
npm run build
```
Dev server config is also saved in `.claude/launch.json` for use with `preview_start`.
## Architecture
### CSS layer (single dependency direction)
```
css/tokens.css ← design tokens only (colors, fonts, spacing, radius, shadows)
css/site.css ← all page styles, imports tokens.css
css/ui-kit.css ← design system showcase styles, standalone
```
Never put visual styles in `tokens.css`. Never import `site.css` into `ui-kit.css`.
### 11ty template structure (`src/`)
```
src/
_includes/
layouts/
base.njk ← HTML shell: <head>, fonts, CSS link, <body class="{{ bodyClass }}">
default.njk ← base + header partial + footer partial (used by all site pages)
ui-kit.njk ← base only, no header/footer (used by ui-kit page)
partials/
header.njk ← full site header with mega-menu nav
footer.njk ← full site footer
css/ ← passthrough copy → _site/css/
assets/ ← passthrough copy → _site/assets/
*.njk ← one file per page
```
### Page front matter
Every page declares layout, title, optional bodyClass, and permalink:
```yaml
---
title: "DP Trade — Catalog"
layout: default # or "ui-kit" for the design system page
bodyClass: compact-type # omit if not needed
permalink: /catalog.html # keeps flat output, preserves relative CSS paths
---
```
Pages with `bodyClass: compact-type`: catalog, about, contacts, article-guidelines.
The `ui-kit` page uses `layout: ui-kit` and `css: ui-kit` (links `ui-kit.css` instead of `site.css`).
### CSS paths
All CSS and JS paths in `base.njk` are **relative** (`css/site.css`, `js/inspector.js`). This works both with the 11ty dev server and when opening `_site/` files directly via `file://`.
### Design tokens
Key CSS custom properties defined in `css/tokens.css`:
- Colors: `--color-primary-wine-100` (#4b0f24), `--color-accent-gold` (#b9965b), `--color-accent-blue` (#1f3476)
- Fonts: `--font-heading` (Montserrat 800), `--font-body` (Inter), `--font-heading-classic` (Playfair Display)
- Container: `--container: 1240px`
When adding new tokens, add to `tokens.css` and mirror to the Elementor CSS layer in `docs/elementor-token-handoff.md` (Section 6).
### Responsive breakpoints
Defined at the bottom of `css/site.css`:
- `@media (max-width: 1080px)` — tablet
- `@media (max-width: 720px)` — mobile
## Key files
| File | Purpose |
| ----------------------------------- | ------------------------------------------------------------ |
| `css/tokens.css` | Single source of truth for all design values |
| `docs/elementor-token-handoff.md` | Guide for migrating tokens/components to WordPress Elementor |
| `.claude/launch.json` | Dev server configurations |
| `src/_includes/partials/header.njk` | Mega-menu navigation — edit here, propagates to all pages |
| `src/_includes/partials/footer.njk` | Footer — edit here, propagates to all pages |

View File

@ -1,50 +0,0 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DP Trade — Catalog</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Montserrat:wght@500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/site.css" />
</head>
<body class="compact-type">
<main class="section catalog-section">
<div class="container">
<div class="section-heading">
<p class="eyebrow">Catalog</p>
<h2>Каталог вина</h2>
</div>
<div class="catalog-layout">
<aside class="filters-panel">
<h3>Фильтры</h3>
<label class="checkbox"><input type="checkbox" checked /> Bordeaux</label>
<label class="checkbox"><input type="checkbox" /> Tuscany</label>
<label class="checkbox"><input type="checkbox" /> Rioja</label>
<label class="checkbox"><input type="checkbox" /> Mosel</label>
<a class="button button--primary" href="#">Применить</a>
<a class="button button--secondary" href="index.html">На главную</a>
</aside>
<section class="product-grid product-grid--compact">
<article class="product-card">
<div class="product-media"><span class="bottle"></span></div>
<div><span class="muted-caps">Bordeaux</span><h3>Chateau Laroque Grand Cru</h3><p>France · Red dry · 2019</p></div>
<div class="product-footer"><strong>3 890 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
<article class="product-card">
<div class="product-media product-media--amber"><span class="bottle"></span></div>
<div><span class="muted-caps">Tuscany</span><h3>Brunello di Montalcino</h3><p>Italy · Red dry · 2018</p></div>
<div class="product-footer"><strong>4 240 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
<article class="product-card">
<div class="product-media product-media--green"><span class="bottle"></span></div>
<div><span class="muted-caps">Mosel</span><h3>Riesling Kabinett</h3><p>Germany · White · 2021</p></div>
<div class="product-footer"><strong>2 150 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
</section>
</div>
</div>
</main>
</body>
</html>

View File

@ -1,69 +0,0 @@
<footer class="site-footer">
<div class="container footer-container">
<section class="footer-main">
<div class="footer-left">
<div>
<a class="footer-brand" href="index.html" aria-label="DP Trade"><span>DP</span>.Trade</a>
<p class="footer-brand-subtitle">Территория качественного вина</p>
</div>
<div>
<span class="section-title">Мы в соцсетях</span>
<div class="social-links">
<a href="#" aria-label="Telegram">TG</a>
<a href="#" aria-label="VK">VK</a>
</div>
</div>
<article class="contacts-card">
<h2>Контакты</h2>
<a class="contact-link contact-phone" href="tel:+74959379460">+7 (495) 937-94-60</a>
<a class="contact-link" href="mailto:dptr@dp-trade.ru">dptr@dp-trade.ru</a>
<a class="button button--primary button--sm" href="#">Связаться с менеджером</a>
</article>
</div>
<section class="footer-nav" aria-label="Навигация по разделам">
<article class="nav-group">
<h2>Каталог</h2>
<ul>
<li><a href="catalog.html">Вина по регионам</a></li>
<li><a href="#">Франция</a></li>
<li><a href="#">Италия</a></li>
<li><a href="#">Испания</a></li>
<li><a href="#">Новинки</a></li>
</ul>
</article>
<article class="nav-group">
<h2>Клиентам</h2>
<ul>
<li><a href="#">Доставка</a></li>
<li><a href="#">Оплата</a></li>
<li><a href="#">Как купить</a></li>
<li><a href="#">Скачать каталог</a></li>
</ul>
</article>
<article class="nav-group">
<h2>Компания</h2>
<ul>
<li><a href="#">О компании</a></li>
<li><a href="#">Контакты</a></li>
<li><a href="#">Склады</a></li>
<li><a href="#">Реквизиты</a></li>
</ul>
</article>
<section class="footer-legal" aria-label="Правовая информация">
<p>
Интернет-витрина размещает информацию об алкогольной продукции исключительно в целях ознакомления.
Дистанционная продажа алкогольной продукции не осуществляется.
<a href="#">Подробнее о правовой информации</a>
</p>
<p>© 2026 DP-Trade</p>
</section>
</section>
</section>
</div>
</footer>

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
:root {
--color-primary-wine-100: #4b0f24;
--color-primary-wine-80: #6d1c36;
--color-neutral-black: #161616;
--color-neutral-gray-700: #30343a;
--color-neutral-gray-600: #66605f;
--color-neutral-gray-300: #d9dee6;
--color-background-base: #f4f6f9;
--color-surface: #ffffff;
--color-accent-gold: #b9965b;
--color-accent-blue: #1f3476;
--font-heading: "Montserrat", "Inter", Arial, sans-serif;
--font-body: "Inter", Arial, sans-serif;
--font-heading-classic: "Playfair Display", Georgia, serif;
--font-body-classic: "Inter", Arial, sans-serif;
--font-heading-retail: "Montserrat", "Inter", Arial, sans-serif;
--spacing-4: 4px;
--spacing-8: 8px;
--spacing-16: 16px;
--spacing-24: 24px;
--spacing-32: 32px;
--spacing-48: 48px;
--spacing-64: 64px;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 24px;
--shadow-soft: 0 12px 32px rgba(22, 22, 22, 0.08);
--shadow-lift: 0 20px 52px rgba(75, 15, 36, 0.14);
--container: 1240px;
}

View File

@ -0,0 +1,131 @@
# DP Trade - разбор предложений дизайнера
Источник: `/Users/lexx/Downloads/Аудит сайт дп-трейд.pdf`
Дата разбора: 2026-04-21
## Короткий вывод
Предложения дизайнера в основном подтверждаются текущей версткой. Главная системная проблема - сайт все еще построен на retail/B2B-визуальном языке: Montserrat/Inter, жирные uppercase-заголовки, холодный серо-голубой фон, конкурирующие синий и бордовый акценты, тяжелые CTA и градиентные карточки товара. Для премиального винного каталога нужно сместить систему к более спокойной editorial-подаче: Cormorant Garamond для заголовков и названий вин, Manrope для текста, теплый белый/кремовый фон, один основной бордовый акцент.
Часть аудита уже не полностью совпадает с текущей реализацией: на главной CTA в hero присутствуют (`Смотреть каталог`, `Открыть UI-kit`), а заголовки в исходных HTML не набраны капсом руками. Но CSS принудительно включает uppercase и тяжелый вес, поэтому визуально замечание дизайнера остается актуальным.
## Ключевые замечания
### 1. Типографика
- В `tokens.css` основными токенами стоят `Montserrat` для заголовков и `Inter` для body. Дизайнер предлагает заменить на `Cormorant Garamond` + `Manrope`, оба шрифта уже подключены.
- В CSS много `font-weight: 800` и `text-transform: uppercase` для hero, H2, карточек, меню, контактов и карточек преимуществ. Это создает ощущение "крика" и снижает премиальность.
- Важное уточнение: проблема не в текстах шаблонов, а в стилях. Например, `src/about.njk` содержит нормальный регистр, но `.page-hero h1` принудительно делает uppercase.
- Минимальный размер текста должен быть не ниже 12px. Текущий 8px встречается в `.brand-logo small`; если этот элемент реально используется или вернется, его надо поднять до 12px.
### 2. Цвет и палитра
- Сейчас системные цвета: бордовый `#4b0f24`, фон `#f4f6f9`, синий акцент `#1f3476`. Дизайнер предлагает: основной бордовый `#7D021D`, теплый белый `#FFFDFA`, теплый карточный фон `#F5F0E8`, синий оставить только в логотипе.
- Синий телефон в шапке конкурирует с бордовым CTA.
- Холодные фоны `#f4f6f9`, `#eef2f6`, `#f8fafc` встречаются во многих секциях и выглядят чужими для винной темы.
- Градиенты в карточках товара выглядят случайными и конкурируют с этикетками бутылок. Нужен единый нейтральный фон под товар.
### 3. Карточка товара
- На главной карточки рекомендаций используют разноцветные градиенты под бутылками.
- Название товара в карточке визуально становится жирным uppercase через CSS. Рекомендация: normal case, Cormorant Garamond, 16-18px.
- Цена и кнопка стоят в одной строке как равнозначные элементы. Лучше выстроить вертикальную иерархию: регион, название, мета, разделитель, цена, full-width outlined CTA.
- Основной CTA сейчас темный залитый. Для карточек дизайнер предлагает более легкую outlined-кнопку на всю ширину.
### 4. Mega-menu
- Заголовки mega-menu слишком крупные и тяжелые: 26px, 800, uppercase.
- Фото занимает целую колонку и перетягивает внимание с навигации. Лучше уменьшить изображение до декоративного акцента или вынести в промо-блок в конце меню.
- В апелласьонах страна и регионы недостаточно различаются по иерархии. Страна должна быть золотой, 11px, caps; апелласьоны - 14px normal case с отступом.
- Чипы популярных регионов имеют разную ширину. Лучше задать единый min-width или вытянуть в ровную горизонтальную строку.
### 5. Главная
- Hero сейчас уже содержит явные CTA, поэтому замечание из аудита про отсутствие CTA неактуально.
- Остается актуальным: hero H1 слишком тяжелый из-за Montserrat, 800 и uppercase. Нужно перевести в Cormorant Garamond, normal case, более спокойный вес.
- H2 в секциях тоже надо убрать из uppercase и снизить визуальный вес.
### 6. Страница продукта
- Нет хлебных крошек. Для каталога это важно для ориентации и SEO.
- Описание продукта пока короткое, но для будущего длинного описания нужен текстовый блок с `max-width: 65-72ch`.
- Есть большой разрыв между метаданными и кнопками из-за сетки и отступов. Нужно проверить вертикальную композицию после добавления breadcrumbs и описания.
- H1 товара также наследует тяжелый uppercase.
### 7. "О нас"
- Hero-паттерн похож на остальные внутренние страницы: темная фотография, большой H1, белая карточка справа. Это снижает ощущение перехода между разделами.
- H1 спокойнее сделать serif, 48-56px, normal case, без давления.
- Правая карточка в hero сейчас работает как приклеенный светлый прямоугольник. Ее стоит смягчить: меньше кегль, обычный текст, меньше uppercase.
- Основной текст ограничен `max-width: 860px`, дизайнер предлагает 600-640px или около 66ch.
- Подзаголовки внутри статьи слишком крупные и uppercase.
- Карточки 01-04 имеют жесткую высоту 210px и `align-content: space-between`, из-за чего контент искусственно растянут.
- Цитата в CSS оформлена цветной левой границей и холодным фоном. Если блокquote используется в контенте, его лучше сделать через italic serif и тонкую нейтральную линию.
- Финальный muted-section на холодном фоне надо перевести в теплый кремовый.
### 8. "Контакты"
- Для контактов полноэкранный/крупный hero с темной фотографией слишком тяжелый. Контакты должны быстрее показывать телефон, email и форму.
- Телефон в карточке слишком крупный и тяжелый, выбивается из общей иерархии.
- Юридическая информация стоит рядом с телефоном и email как равнозначная карточка. Ее лучше перенести ниже формы или в конец страницы мелким справочным блоком.
- Заголовок формы крупный и uppercase, labels слишком жирные.
- Поле "Телефон или email" неоднозначно. Лучше разделить на два поля или дать понятную подсказку.
- Нет видимого success-state после отправки формы.
## Расхождения с аудитом
- CTA в hero главной уже есть: `src/index.njk` содержит две кнопки в первом экране. Значит пункт "отсутствует явный CTA" стоит закрыть как неактуальный или переформулировать в "сделать CTA визуально легче/элегантнее".
- В исходных шаблонах многие заголовки набраны нормальным регистром. Капс появляется из CSS. Исправлять надо в основном CSS-токены и правила `text-transform`, а не тексты.
- В аудите упоминается Playfair Display как почти неиспользуемый шрифт, но итоговая рекомендация дизайнера - Cormorant Garamond + Manrope. Лучше не распыляться на Playfair и зафиксировать одну пару.
- В карточках каталога (`product-card--list`) названия уже без uppercase, но слишком тяжелые и крупные. Замечание про uppercase точнее относится к карточкам рекомендаций/общим `.product-card h3`.
- Страница продукта пока очень короткая. Замечание про ширину описания надо учесть как требование к будущему расширенному описанию, а не как текущий критический баг.
## План доработок
### Этап 1. Системные токены и базовая типографика
1. Обновить `src/css/tokens.css`: `--font-heading` на Cormorant Garamond, `--font-body` на Manrope, основной бордовый на `#7D021D`, фон на теплый `#FFFDFA`, surface/card background на теплую белую/кремовую шкалу.
2. Синхронизировать те же токены в `src/css/ui-kit.css`, чтобы витрина UI-kit не расходилась с сайтом.
3. Убрать uppercase с H2-H4, product titles, news titles, page hero titles, form titles. Caps оставить только для eyebrow/meta labels.
4. Пересобрать шкалу весов: H1 может быть крупным, но не обязательно 800; H2-H4 сделать 500-600 или доступный локальный эквивалент с текущими файлами шрифтов.
5. Проверить минимальные размеры: не использовать текст ниже 12px.
### Этап 2. Карточки и CTA
1. Заменить градиентные product media на единый теплый нейтральный фон `#F5F0E8`.
2. Перестроить карточку рекомендаций: region label, serif title 16-18px, gray meta 13px, разделитель, цена 22-24px, outlined full-width CTA.
3. Смягчить primary/secondary buttons: новый бордовый, меньше "B2B-тяжести", четкие hover/focus states.
4. Проверить карточки каталога отдельно: сохранить плотность B2B-списка, но снизить вес заголовков и цены.
### Этап 3. Header и mega-menu
1. Убрать синий цвет телефона в шапке, оставить синий только внутри логотипа.
2. Уменьшить и облегчить заголовки mega-menu: 16-18px, normal case, semibold.
3. Переделать визуальную колонку mega-menu: уменьшить изображение или вынести его в небольшой промо-блок.
4. Настроить иерархию апелласьонов: страна как meta label, регионы с отступом и normal case.
5. Выровнять popular chips: единый min-width или одна строка с равномерным ритмом.
### Этап 4. Страницы
1. Главная: обновить hero-типографику, H2 секций, карточки рекомендаций и холодные фоны новостей.
2. Продукт: добавить breadcrumbs, расширенный description-блок с `max-width: 65-72ch`, пересобрать вертикальную иерархию metadata/price/CTA.
3. О нас: сделать hero спокойнее, смягчить правую карточку, сузить основной текст до 66ch, облегчить подзаголовки, убрать жесткую высоту feature-card, заменить холодный muted-section.
4. Контакты: сделать компактный hero без тяжелой фотографии, вывести телефон/email в первый экран, юридический текст перенести ниже, облегчить форму, разделить контактные поля или добавить подсказку, добавить success-state.
### Этап 5. Проверка
1. Прогнать `npm run build`.
2. Проверить страницы минимум на desktop и mobile: `index.html`, `catalog.html`, `product.html`, `about.html`, `contacts.html`, `ui-kit.html`.
3. Отдельно проверить, что длинные русские заголовки и телефоны не ломают сетку.
4. Сверить UI-kit с сайтом: токены, кнопки, карточки, hero, формы.
## Приоритет
P0: токены, шрифты, uppercase, фон, основной бордовый. Без этого остальные правки будут точечными и визуально не соберутся.
P1: карточки товара, CTA, header/mega-menu. Это самые заметные пользовательские интерфейсы и они прямо влияют на восприятие каталога.
P2: страницы "О нас", "Контакты", "Продукт". Здесь много композиционных улучшений, но они лучше лягут после системной смены визуального языка.
P3: финальная полировка UI-kit, состояния формы, hover/focus, адаптивные проверки.

File diff suppressed because it is too large Load Diff

View File

@ -1,351 +0,0 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DP Trade — Home</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@600;700&family=Inter:wght@400;500;600;700;800&family=Manrope:wght@400;500;600;700;800&family=Montserrat:wght@500;600;700;800&family=Playfair+Display:wght@600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/site.css" />
</head>
<body>
<div class="site-shell">
<header class="site-header">
<div class="container header-top">
<a class="brand-logo" href="index.html" aria-label="DP Trade">
<img src="https://wine-dp-trade.ru/wp-content/uploads/2024/11/logo-500x107.png" alt="DP Trade" width="156" height="33" />
</a>
<form class="search-bar" action="#" role="search">
<button type="submit" aria-label="Поиск"></button>
<input type="search" placeholder="Поиск по вину, региону, производителю" aria-label="Поиск" />
</form>
<div class="header-actions">
<a class="phone-link" href="tel:+74959379460">+7 (495) 937-94-60</a>
<a class="header-icon header-icon--air" href="#" aria-label="Аккаунт">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 12.2a4.1 4.1 0 1 0 0-8.2 4.1 4.1 0 0 0 0 8.2Z" />
<path d="M4.8 20.2c1.1-3.3 3.6-5 7.2-5s6.1 1.7 7.2 5" />
</svg>
</a>
<a class="header-icon header-icon--air" href="#" aria-label="Корзина">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M5 6h2l1.4 9.2h8.5L19 8H8" />
<path d="M9.4 19.2h.1M16.8 19.2h.1" />
</svg>
</a>
</div>
</div>
<nav class="container main-nav" aria-label="Основная навигация">
<a href="catalog.html">Каталог</a>
<div class="nav-item">
<button class="nav-trigger" type="button" aria-expanded="false">Регион <span class="nav-chevron" aria-hidden="true"><svg viewBox="0 0 10 6"><path d="M1 1l4 4 4-4" /></svg></span></button>
<section class="mega-menu" aria-label="Регион">
<div class="mega-intro">
<div>
<p class="eyebrow">Регион</p>
<h2>Вина по географии</h2>
</div>
<p>Быстрый вход в каталог через страну, апелласьон или популярный регион.</p>
</div>
<div class="menu-grid">
<article class="menu-column visual-column">
<img src="https://images.unsplash.com/photo-1506377247377-2a5b3b417ebb?auto=format&fit=crop&w=900&q=80" alt="Виноградник на холмах" />
<p>Выбирайте через знакомую страну или сразу через регион, если точно знаете, что ищете.</p>
</article>
<article class="menu-column">
<p class="section-title">Страны</p>
<a href="#">Старый Свет</a><a href="#">Франция</a><a href="#">Италия</a><a href="#">Испания</a><a href="#">Германия</a><a href="#">Новый Свет</a><a href="#">Чили</a><a href="#">Аргентина</a>
</article>
<article class="menu-column appellations">
<p class="section-title">Апелласьоны</p>
<div class="appellation-group"><a class="country-link" href="#">Франция</a><a href="#">Bordeaux</a><a href="#">Medoc</a><a href="#">Margaux</a><a href="#">Pauillac</a><a href="#">Saint-Emilion</a></div>
<div class="appellation-group"><a class="country-link" href="#">Италия</a><a href="#">Toscana</a><a href="#">Chianti</a><a href="#">Brunello di Montalcino</a><a href="#">Piemonte</a></div>
</article>
<article class="menu-column">
<p class="section-title">Популярные регионы</p>
<div class="popular-list"><a href="#">Бордо</a><a href="#">Тоскана</a><a href="#">Пьемонт</a><a href="#">Риоха</a><a href="#">Напа Вэлли</a></div>
</article>
</div>
</section>
</div>
<div class="nav-item">
<button class="nav-trigger" type="button" aria-expanded="false">Вино <span class="nav-chevron" aria-hidden="true"><svg viewBox="0 0 10 6"><path d="M1 1l4 4 4-4" /></svg></span></button>
<section class="mega-menu" aria-label="Вино">
<div class="mega-intro">
<div>
<p class="eyebrow">Вино</p>
<h2>Каталог по типу и стилю</h2>
</div>
<p>Быстрый выбор вина по цвету, категории и уровню сладости.</p>
</div>
<div class="menu-grid">
<article class="menu-column visual-column">
<img src="https://images.unsplash.com/photo-1510812431401-41d2bd2722f3?auto=format&fit=crop&w=900&q=80" alt="Бокалы вина" />
<p>Начните с типа вина или сразу переходите к стилю, если знаете нужный профиль.</p>
</article>
<article class="menu-column">
<p class="section-title">По типу</p>
<a href="#">Красное</a><a href="#">Белое</a><a href="#">Розовое</a><a href="#">Игристое</a><a href="#">Шампанское</a>
</article>
<article class="menu-column">
<p class="section-title">По стилю</p>
<a href="#">Сухие</a><a href="#">Полусухие</a><a href="#">Полусладкие</a><a href="#">Сладкие</a><a href="#">Брют</a><a href="#">Экстра брют</a>
</article>
<article class="menu-column">
<p class="section-title">Популярное</p>
<div class="popular-list"><a href="#">Новинки</a><a href="#">Хиты продаж</a><a href="#">Для ресторанов</a><a href="#">Премиум подборка</a></div>
</article>
</div>
</section>
</div>
<div class="nav-item">
<button class="nav-trigger" type="button" aria-expanded="false">Крепкий алкоголь <span class="nav-chevron" aria-hidden="true"><svg viewBox="0 0 10 6"><path d="M1 1l4 4 4-4" /></svg></span></button>
<section class="mega-menu" aria-label="Крепкий алкоголь">
<div class="mega-intro">
<div>
<p class="eyebrow">Spirits</p>
<h2>Крепкий алкоголь</h2>
</div>
<p>Подборка крепких напитков для баров, ресторанов и специализированной розницы.</p>
</div>
<div class="menu-grid">
<article class="menu-column visual-column">
<img src="https://images.unsplash.com/photo-1527281400683-1aae777175f8?auto=format&fit=crop&w=900&q=80" alt="Крепкий алкоголь в бокале" />
<p>Категории, выдержка и происхождение для быстрой навигации по ассортименту.</p>
</article>
<article class="menu-column">
<p class="section-title">Категории</p>
<a href="#">Виски</a><a href="#">Коньяк</a><a href="#">Арманьяк</a><a href="#">Ром</a><a href="#">Джин</a><a href="#">Водка</a><a href="#">Текила</a><a href="#">Ликеры</a>
</article>
<article class="menu-column">
<p class="section-title">По стилю</p>
<a href="#">Односолодовый</a><a href="#">Купажированный</a><a href="#">Выдержанный</a><a href="#">Пряный</a><a href="#">Дижестив</a><a href="#">Для коктейлей</a>
</article>
<article class="menu-column">
<p class="section-title">Популярное</p>
<div class="popular-list"><a href="#">Single Malt</a><a href="#">Cognac VSOP</a><a href="#">Premium Gin</a><a href="#">Bar Selection</a></div>
</article>
</div>
</section>
</div>
<div class="nav-item">
<button class="nav-trigger" type="button" aria-expanded="false">Производители <span class="nav-chevron" aria-hidden="true"><svg viewBox="0 0 10 6"><path d="M1 1l4 4 4-4" /></svg></span></button>
<section class="mega-menu" aria-label="Производители">
<div class="mega-intro">
<div>
<p class="eyebrow">Производители</p>
<h2>Дома, хозяйства и бренды</h2>
</div>
<p>Навигация по ключевым производителям, регионам и партнерским брендам DP Trade.</p>
</div>
<div class="menu-grid">
<article class="menu-column visual-column">
<img src="https://images.unsplash.com/photo-1568213816046-0ee1c42bd559?auto=format&fit=crop&w=900&q=80" alt="Винодельня и бочки" />
<p>Откройте ассортимент через знакомые хозяйства, винные дома и регионы производства.</p>
</article>
<article class="menu-column">
<p class="section-title">По странам</p>
<a href="#">Франция</a><a href="#">Италия</a><a href="#">Испания</a><a href="#">Германия</a><a href="#">Португалия</a><a href="#">Чили</a><a href="#">Аргентина</a>
</article>
<article class="menu-column">
<p class="section-title">Избранные</p>
<a href="#">Chateau Laroque</a><a href="#">Marchesi Antinori</a><a href="#">Torres</a><a href="#">Dr. Loosen</a><a href="#">Catena Zapata</a><a href="#">Penfolds</a>
</article>
<article class="menu-column">
<p class="section-title">Форматы</p>
<div class="popular-list"><a href="#">Семейные хозяйства</a><a href="#">Grand Cru</a><a href="#">Органика</a><a href="#">Эксклюзив DP Trade</a></div>
</article>
</div>
</section>
</div>
<a href="#">Поставки</a>
<a href="#">Новости</a>
<a href="ui-kit.html">UI-kit</a>
</nav>
</header>
<main>
<section class="hero">
<div class="container hero-copy">
<p class="eyebrow">DP Trade</p>
<h1>Премиальный каталог вина для торговли</h1>
<p>Регионы, производители, партии и коммерческие условия собраны в одном интерфейсе для быстрых закупочных решений.</p>
<div class="hero-actions">
<a class="button button--primary" href="catalog.html">Смотреть каталог</a>
<a class="button button--secondary" href="ui-kit.html">Открыть UI-kit</a>
</div>
</div>
</section>
<section class="section type-lab-section">
<div class="container">
<div class="section-heading section-heading--split">
<div>
<p class="eyebrow">Typography direction</p>
<h2>5 вариантов типографики</h2>
</div>
<p>
Выбранное направление — Premium Retail: сильная витрина, крупные уверенные заголовки
и читаемый интерфейс для каталога.
</p>
</div>
<div class="type-options type-options--five">
<article class="type-card type-card--editorial">
<div class="type-card__meta">
<span>Option 01</span>
<strong>Editorial Wine</strong>
</div>
<h3>Редкие вина для профессиональной торговли</h3>
<p>
Cormorant Garamond для крупных заголовков и Manrope для интерфейса. Больше премиальности,
культурного контекста и ощущения curated selection.
</p>
<div class="type-usage">
<strong>Где использовать</strong>
<span>Имиджевые hero, истории производителей, региональные editorial-блоки.</span>
</div>
<div class="type-scale">
<span>H1 72/78</span>
<span>Body 16/25</span>
<span>Label 12/16</span>
</div>
</article>
<article class="type-card type-card--neo">
<div class="type-card__meta">
<span>Option 02</span>
<strong>Neo Trade</strong>
</div>
<h3>Каталог, который работает как торговый инструмент</h3>
<p>
Manrope везде: современно, ровно, технологично. Хорошо подойдет, если сайт должен читаться
как быстрый B2B-продукт.
</p>
<div class="type-usage">
<strong>Где использовать</strong>
<span>Личный кабинет, таблицы, фильтры, B2B-операции и плотные интерфейсы.</span>
</div>
<div class="type-scale">
<span>H1 64/70</span>
<span>Body 16/24</span>
<span>Label 12/16</span>
</div>
</article>
<article class="type-card type-card--classic">
<div class="type-card__meta">
<span>Option 03</span>
<strong>Modern Classic</strong>
</div>
<h3>Вино, регионы и производители в ясной системе</h3>
<p>
Playfair Display + Inter. Более классический premium retail, но с аккуратной цифровой
читаемостью в карточках, фильтрах и таблицах.
</p>
<div class="type-usage">
<strong>Где использовать</strong>
<span>Промо-разделы, подборки, страницы брендов и спокойные premium-лендинги.</span>
</div>
<div class="type-scale">
<span>H1 68/74</span>
<span>Body 16/24</span>
<span>Label 12/16</span>
</div>
</article>
<article class="type-card type-card--retail is-selected">
<div class="type-card__meta">
<span>Option 04</span>
<strong>Выбрано</strong>
</div>
<h3>Сильная витрина с акцентом на выбор</h3>
<p>
Montserrat для заголовков и Inter для текста. Более собранный, коммерческий, уверенный
вариант для каталога с большим количеством позиций.
</p>
<div class="type-usage">
<strong>Где использовать</strong>
<span>Главная, навигация, карточки, шаблоны страниц и основные marketing-блоки.</span>
</div>
<div class="type-scale">
<span>H1 60/66</span>
<span>Body 16/24</span>
<span>Label 12/16</span>
</div>
</article>
<article class="type-card type-card--compact is-selected-soft">
<div class="type-card__meta">
<span>Option 05</span>
<strong>Compact Retail</strong>
</div>
<h3>Компактный каталог для быстрого выбора</h3>
<p>
Montserrat + Inter, но с меньшим scale: заголовки спокойнее, карточки плотнее,
больше товаров помещается в первый экран.
</p>
<div class="type-usage">
<strong>Где использовать</strong>
<span>Каталог, выдача поиска, фильтрованные списки и страницы с высокой плотностью товаров.</span>
</div>
<div class="type-scale">
<span>H1 48/54</span>
<span>Body 15/22</span>
<span>Label 11/14</span>
</div>
</article>
</div>
</div>
</section>
<section class="section">
<div class="container">
<div class="section-heading">
<p class="eyebrow">Recommendations</p>
<h2>Рекомендации недели</h2>
</div>
<div class="product-grid">
<article class="product-card">
<div class="product-media"><span class="bottle"></span></div>
<div><span class="muted-caps">Bordeaux</span><h3>Chateau Laroque Grand Cru</h3><p>France · Red dry · 2019 · 0.75 L</p></div>
<div class="product-footer"><strong>3 890 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
<article class="product-card">
<div class="product-media product-media--amber"><span class="bottle"></span></div>
<div><span class="muted-caps">Tuscany</span><h3>Brunello di Montalcino</h3><p>Italy · Red dry · 2018 · 0.75 L</p></div>
<div class="product-footer"><strong>4 240 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
<article class="product-card">
<div class="product-media product-media--green"><span class="bottle"></span></div>
<div><span class="muted-caps">Mosel</span><h3>Riesling Kabinett</h3><p>Germany · White · 2021 · 0.75 L</p></div>
<div class="product-footer"><strong>2 150 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container footer-container">
<section class="footer-main">
<div class="footer-left">
<div><a class="footer-brand" href="index.html" aria-label="DP Trade"><span>DP</span>.Trade</a><p class="footer-brand-subtitle">Территория качественного вина</p></div>
<div><span class="section-title">Мы в соцсетях</span><div class="social-links"><a href="#" aria-label="Telegram">TG</a><a href="#" aria-label="VK">VK</a></div></div>
<article class="contacts-card"><h2>Контакты</h2><a class="contact-link contact-phone" href="tel:+74959379460">+7 (495) 937-94-60</a><a class="contact-link" href="mailto:dptr@dp-trade.ru">dptr@dp-trade.ru</a><a class="button button--primary button--sm" href="#">Связаться с менеджером</a></article>
</div>
<section class="footer-nav" aria-label="Навигация по разделам">
<article class="nav-group"><h2>Каталог</h2><ul><li><a href="catalog.html">Вина по регионам</a></li><li><a href="#">Франция</a></li><li><a href="#">Италия</a></li><li><a href="#">Испания</a></li><li><a href="#">Новинки</a></li></ul></article>
<article class="nav-group"><h2>Клиентам</h2><ul><li><a href="#">Доставка</a></li><li><a href="#">Оплата</a></li><li><a href="#">Как купить</a></li><li><a href="#">Скачать каталог</a></li></ul></article>
<article class="nav-group"><h2>Компания</h2><ul><li><a href="#">О компании</a></li><li><a href="#">Контакты</a></li><li><a href="#">Склады</a></li><li><a href="#">Реквизиты</a></li></ul></article>
<section class="footer-legal" aria-label="Правовая информация"><p>Интернет-витрина размещает информацию об алкогольной продукции исключительно в целях ознакомления. Дистанционная продажа алкогольной продукции не осуществляется. <a href="#">Подробнее о правовой информации</a></p><p>© 2026 DP-Trade</p></section>
</section>
</section>
</div>
</footer>
</div>
</body>
</html>

1652
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

13
package.json Normal file
View File

@ -0,0 +1,13 @@
{
"name": "dp-trade-ui-kit",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "eleventy --serve",
"build": "eleventy"
},
"devDependencies": {
"@11ty/eleventy": "^3.0.0"
},
"type": "module"
}

View File

@ -0,0 +1,19 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ title }}</title>
<link rel="stylesheet" href="css/{{ css | default('site') }}.css" />
<!-- Privacy-friendly analytics by Plausible -->
<script async src="https://metrika.in20.ru/js/pa-LKQHOT3En5k9NYpn80cYX.js"></script>
<script>
window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
plausible.init()
</script>
</head>
<body{% if bodyClass %} class="{{ bodyClass }}"{% endif %}>
{{ content | safe }}
<script src="js/inspector.js"></script>
</body>
</html>

View File

@ -0,0 +1,8 @@
---
layout: layouts/base
---
<div class="site-shell">
{% include "partials/header.njk" %}
{{ content | safe }}
{% include "partials/footer.njk" %}
</div>

View File

@ -0,0 +1,5 @@
---
layout: layouts/base
css: ui-kit
---
{{ content | safe }}

View File

@ -0,0 +1,73 @@
<footer class="site-footer">
<div class="container footer-container">
<section class="footer-main">
<div class="footer-brand-block">
<a class="footer-brand" href="index.html" aria-label="DP Trade">
<img src="https://wine-dp-trade.ru/wp-content/uploads/2024/11/logo-500x107.png" alt="DP Trade" width="156" height="33" />
</a>
<p class="footer-brand-subtitle">Территория качественного вина</p>
</div>
<section class="footer-nav" aria-label="Навигация по разделам">
<article class="nav-group">
<h2>Каталог</h2>
<ul>
<li><a href="catalog.html">Вина по регионам</a></li>
<li><a href="#">Франция</a></li>
<li><a href="#">Италия</a></li>
<li><a href="#">Испания</a></li>
<li><a href="#">Новинки</a></li>
</ul>
</article>
<article class="nav-group">
<h2>Клиентам</h2>
<ul>
<li><a href="#">Доставка</a></li>
<li><a href="#">Оплата</a></li>
<li><a href="#">Как купить</a></li>
<li><a href="#">Скачать каталог</a></li>
</ul>
</article>
<article class="nav-group">
<h2>Компания</h2>
<ul>
<li><a href="about.html">О компании</a></li>
<li><a href="contacts.html">Контакты</a></li>
<li><a href="contacts-auth.html">Контакты auth</a></li>
<li><a href="#">Склады</a></li>
<li><a href="#">Реквизиты</a></li>
</ul>
</article>
</section>
<article class="contacts-card">
<h2>Контакты</h2>
<a class="contact-link contact-phone" href="tel:+74959379460">+7 (495) 937-94-60</a>
<a class="contact-link" href="mailto:dptr@dp-trade.ru">dptr@dp-trade.ru</a>
<div class="social-links" aria-label="Социальные сети">
<a href="#" aria-label="Telegram">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M21 4 3 11.2l6.3 2.2L18 7.7l-6.8 7.1.2 5.2 3-3.3 4.7 3.5L21 4Z" />
</svg>
</a>
<a href="#" aria-label="VK">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 7h3l2 4.2c.5 1.1 1 1.6 1.3 1.6.2 0 .4-.3.4-1V7h3v3.7c0 .4.2.6.5.6.6 0 1.8-1.6 2.6-4.3H20c-.7 3-1.8 4.8-3 5.7 1.2.8 2.4 2.2 3.2 4.3h-3.4c-.8-1.5-1.8-2.7-2.5-2.7-.4 0-.6.3-.6.8V17h-1.5C8.8 17 6.2 13.9 4 7Z" />
</svg>
</a>
</div>
</article>
<section class="footer-legal" aria-label="Правовая информация">
<p>
Интернет-витрина размещает информацию об алкогольной продукции исключительно в целях ознакомления.
Дистанционная продажа алкогольной продукции не осуществляется.
<a href="#">Подробнее о правовой информации</a>
</p>
<p>© 2026 DP-Trade</p>
</section>
</section>
</div>
</footer>

View File

@ -248,6 +248,53 @@
</div>
<a href="#">Поставки</a>
<a href="#">Новости</a>
<a href="ui-kit.html">UI-kit</a>
<div class="nav-item">
<button class="nav-trigger" type="button" aria-expanded="false">UI-kit <span class="nav-chevron" aria-hidden="true"><svg viewBox="0 0 10 6"><path d="M1 1l4 4 4-4" /></svg></span></button>
<section class="mega-menu" aria-label="UI-kit">
<div class="mega-intro">
<div>
<p class="eyebrow">Design system</p>
<h2>UI-kit и демо-страницы</h2>
</div>
<p>Быстрый доступ к живым страницам, компонентам, паттернам и токенам для разработки.</p>
</div>
<div class="menu-grid">
<article class="menu-column visual-column">
<img src="https://images.unsplash.com/photo-1510812431401-41d2bd2722f3?auto=format&fit=crop&w=900&q=80" alt="Демонстрация винного каталога" />
<p>Все демо-страницы собраны в одном месте для проверки header, footer, карточек и каталожных сценариев.</p>
</article>
<article class="menu-column">
<p class="section-title">Demo pages</p>
<a href="index.html">Главная</a>
<a href="catalog.html">Каталог</a>
<a href="product.html">Карточка товара</a>
<a href="bottle-cards.html">Варианты карточек</a>
<a href="news-villa-raiano.html">Новость</a>
<a href="news-villa-raiano-v2.html">Новость v2</a>
<a href="article-guidelines.html">Ред. гайд</a>
<a href="about.html">О компании</a>
<a href="contacts.html">Контакты</a>
<a href="contacts-auth.html">Контакты auth</a>
</article>
<article class="menu-column">
<p class="section-title">UI-kit sections</p>
<a href="ui-kit.html#foundations">Foundations</a>
<a href="ui-kit.html#components">Components</a>
<a href="ui-kit.html#patterns">Patterns</a>
<a href="ui-kit.html#templates">Templates</a>
<a href="ui-kit.html#screens">Screens</a>
</article>
<article class="menu-column">
<p class="section-title">Dev handoff</p>
<div class="popular-list">
<a href="ui-kit.html#tokens">Tokens</a>
<a href="ui-kit.html#components">States</a>
<a href="ui-kit.html#patterns">Layouts</a>
<a href="ui-kit.html">Full UI-kit</a>
</div>
</article>
</div>
</section>
</div>
</nav>
</header>

46
src/about.njk Normal file
View File

@ -0,0 +1,46 @@
---
title: "DP Trade — О компании"
layout: layouts/default
permalink: /about.html
bodyClass: compact-type
---
<main class="content-page">
<section class="page-hero page-hero--about">
<div class="container page-hero__inner">
<div>
<p class="eyebrow">О компании</p>
<h1>DP Trade — территория качественного вина</h1>
<p>Импорт, каталог, персональная работа с клиентами, собственные склады в регионах и доставка собственным транспортом.</p>
</div>
<aside class="page-hero__meta" aria-label="Кратко о компании">
<span>Since 1991</span>
<strong>Premium wine trade</strong>
<p>Портфель винных домов для ресторанов, розницы и профессиональных закупок.</p>
</aside>
</div>
</section>
<section class="section">
<div class="container about-grid">
<article class="article-body">
<p class="lead">DP Trade развивает профессиональный винный каталог, где регионы, производители, партии и коммерческие условия собраны в едином интерфейсе для быстрых закупочных решений.</p>
<p>Главная ценность сервиса — соединить сильный ассортимент с понятной навигацией: от страны и апелласьона до конкретного производителя, винтажа и карточки товара.</p>
<h2>Как устроен подход</h2>
<p>Компания делает акцент на удобном каталоге, персональном отношении, собственных складских возможностях и доставке собственным транспортом. Для B2B-клиентов это значит меньше ручных уточнений и быстрее путь от выбора до заказа.</p>
</article>
<div class="feature-grid feature-grid--about">
<article class="feature-card"><span>01</span><h3>Удобный каталог</h3><p>Фильтры по типу, региону, производителю, сорту, году, объему и стилю.</p></article>
<article class="feature-card"><span>02</span><h3>Персональный подход</h3><p>Быстрая коммуникация с менеджером и подборки под формат клиента.</p></article>
<article class="feature-card"><span>03</span><h3>Склады в регионах</h3><p>Инфраструктура для регулярных поставок и управления доступностью.</p></article>
<article class="feature-card"><span>04</span><h3>Собственная доставка</h3><p>Контроль логистики и аккуратная работа с профессиональными заказами.</p></article>
</div>
</div>
</section>
<section class="section muted-section">
<div class="container section-heading section-heading--split">
<div><p class="eyebrow">Portfolio</p><h2>Винные дома и регионы</h2></div>
<p>Страница показывает, как может выглядеть корпоративный раздел: спокойная подача, крупные тезисы и блок преимуществ без перегруза.</p>
</div>
</section>
</main>

112
src/article-guidelines.njk Normal file
View File

@ -0,0 +1,112 @@
---
title: "DP Trade — Article Guidelines"
layout: layouts/default
permalink: /article-guidelines.html
bodyClass: compact-type
---
<main class="content-page guidelines-page">
<section class="page-hero page-hero--guidelines">
<div class="container page-hero__inner">
<div>
<p class="eyebrow">Editorial guidelines</p>
<h1>Рекомендации по статьям DP Trade</h1>
<p>Требования к структуре материала, заголовкам, тексту и фотографиям для новостей, историй производителей и экспертных заметок.</p>
</div>
<aside class="page-hero__meta">
<span>Для редакции</span>
<strong>Article system</strong>
<p>Единые правила помогают статьям выглядеть как часть продукта, а не как случайные публикации.</p>
</aside>
</div>
</section>
<section class="section">
<div class="container guideline-grid">
<article class="guideline-card guideline-card--lead">
<span>01</span>
<h2>Структура статьи</h2>
<p>Каждый материал должен быстро отвечать на три вопроса: о ком/о чём статья, почему это важно для аудитории DP Trade и какое действие читатель может сделать дальше.</p>
<ul>
<li>Заголовок: конкретный, с именем производителя, региона или события.</li>
<li>Лид: 1-2 предложения, раскрывает главный повод.</li>
<li>Основной текст: 3-5 смысловых блоков с подзаголовками или визуальными паузами.</li>
<li>Финал: вывод, рекомендация, ссылка в каталог или повод обратиться к менеджеру.</li>
</ul>
</article>
<article class="guideline-card">
<span>02</span>
<h2>Заголовки</h2>
<p>Заголовок должен быть редакционным, но полезным: не только красивым, а ещё и объясняющим тему.</p>
<ul>
<li>Оптимально: 55-90 символов.</li>
<li>Использовать имена: Villa Raiano, Gaja, Bordeaux, Fiano.</li>
<li>Избегать пустых формул: «уникальная история», «легендарное событие» без факта.</li>
<li>Подзаголовки должны вести читателя по смыслу, а не повторять заголовок.</li>
</ul>
</article>
<article class="guideline-card">
<span>03</span>
<h2>Текст</h2>
<p>Стиль: профессиональный, спокойный, без рекламного нажима. Пишем для закупщиков, сомелье, ресторанов и розницы.</p>
<ul>
<li>Абзац: 350-650 знаков.</li>
<li>Лид: до 280 знаков.</li>
<li>Новость: 3 000-5 500 знаков.</li>
<li>История производителя: 5 000-8 000 знаков.</li>
<li>Цифры, годы, награды и сорта проверять отдельно.</li>
</ul>
</article>
<article class="guideline-card">
<span>04</span>
<h2>Фотографии</h2>
<p>Фотографии должны показывать реальный продукт, место, людей или процесс. Лучше меньше декоративности и больше конкретики.</p>
<ul>
<li>Hero: горизонтальное фото от 1600px по ширине.</li>
<li>Внутренние фото: от 1200px, без сильной компрессии.</li>
<li>Для карточек: предмет или бутылка должны быть читаемы на мобильном.</li>
<li>Не использовать тёмные, размытые, случайно обрезанные изображения.</li>
<li>Обязательно писать alt: кто/что изображено и где.</li>
</ul>
</article>
<article class="guideline-card">
<span>05</span>
<h2>Композиция</h2>
<p>Для длинной статьи нужны визуальные паузы: крупное фото после лида, цитата или факт-блок в середине и финальный акцент.</p>
<ul>
<li>Не ставить подряд больше 4 текстовых абзацев без паузы.</li>
<li>Цитаты использовать только если они усиливают материал.</li>
<li>Сайдбар может содержать факты: страна, регион, сорт, год, награда.</li>
<li>Финальный CTA должен быть связан с каталогом или менеджером.</li>
</ul>
</article>
<article class="guideline-card">
<span>06</span>
<h2>SEO и handoff</h2>
<p>Материал должен быть понятен поиску и разработке: один H1, последовательные H2, корректные alt и прозрачная структура блоков.</p>
<ul>
<li>Title: до 60 символов, включает бренд или тему.</li>
<li>Description: 140-160 символов.</li>
<li>URL: латиница, короткий slug.</li>
<li>Изображения называть по смыслу, а не `photo-final-2`.</li>
<li>В CMS хранить дату, автора/раздел, теги и связанные товары.</li>
</ul>
</article>
</div>
</section>
<section class="section muted-section">
<div class="container guideline-checklist">
<div>
<p class="eyebrow">Pre-publish checklist</p>
<h2>Проверка перед публикацией</h2>
</div>
<ul>
<li>Заголовок отражает конкретный повод и не звучит как реклама.</li>
<li>В лиде понятна ценность материала для профессиональной аудитории.</li>
<li>Все годы, имена, апелласьоны и награды проверены.</li>
<li>Есть минимум 2-4 качественные фотографии с alt-текстами.</li>
<li>Финал ведёт к каталогу, производителю, товару или контакту с менеджером.</li>
</ul>
</div>
</section>
</main>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

232
src/bottle-cards.njk Normal file
View File

@ -0,0 +1,232 @@
---
title: "DP Trade — Bottle Card Variants"
layout: layouts/default
permalink: /bottle-cards.html
bodyClass: compact-type
---
<main class="section card-lab-section">
<div class="container">
<div class="card-lab-head">
<div>
<p class="eyebrow">UI-kit / Product cards</p>
<h1>Варианты карточек бутылок</h1>
</div>
<p>Отдельная витрина для выбора направления карточки: крупные плитки, компактные версии и горизонтальный формат для B2B-каталога.</p>
</div>
<section class="card-variant-block" aria-labelledby="cards-grid-title">
<div class="card-variant-title">
<p class="eyebrow">Variant 01</p>
<h2 id="cards-grid-title">Акцентные карточки каталога</h2>
</div>
<div class="bottle-card-grid">
<article class="bottle-card bottle-card--bordeaux">
<div class="bottle-card__media">
<img class="bottle-card__photo" src="assets/images/00081538_1.png" alt="Chateau Laroque Grand Cru" />
</div>
<div class="bottle-card__body">
<p class="bottle-card__region">Bordeaux</p>
<h3>Chateau Laroque Grand Cru</h3>
<p>France · Red dry · 2019 · 0.75 L</p>
</div>
<div class="bottle-card__footer">
<strong>3 890 ₽</strong>
<a class="button button--primary button--sm" href="product.html">Подробнее</a>
</div>
</article>
<article class="bottle-card bottle-card--tuscany">
<div class="bottle-card__media">
<img class="bottle-card__photo" src="assets/images/00080768_1.png" alt="Brunello di Montalcino" />
</div>
<div class="bottle-card__body">
<p class="bottle-card__region">Tuscany</p>
<h3>Brunello di Montalcino</h3>
<p>Italy · Red dry · 2018 · 0.75 L</p>
</div>
<div class="bottle-card__footer">
<strong>4 240 ₽</strong>
<a class="button button--primary button--sm" href="product.html">Подробнее</a>
</div>
</article>
<article class="bottle-card bottle-card--mosel">
<div class="bottle-card__media">
<img class="bottle-card__photo" src="assets/images/00081726_1.png" alt="Riesling Kabinett" />
</div>
<div class="bottle-card__body">
<p class="bottle-card__region">Mosel</p>
<h3>Riesling Kabinett</h3>
<p>Germany · White · 2021 · 0.75 L</p>
</div>
<div class="bottle-card__footer">
<strong>2 150 ₽</strong>
<a class="button button--primary button--sm" href="product.html">Подробнее</a>
</div>
</article>
</div>
</section>
<section class="card-variant-block" aria-labelledby="cards-alt-title">
<div class="card-variant-title">
<p class="eyebrow">Variant 02-04</p>
<h2 id="cards-alt-title">Альтернативные форматы</h2>
</div>
<div class="bottle-card-mix">
<article class="bottle-card bottle-card--clean">
<div class="bottle-card__media">
<img class="bottle-card__photo" src="assets/images/00081538_1.png" alt="Oremus Case of Aszu" />
</div>
<div class="bottle-card__body">
<p class="bottle-card__region">Clean retail</p>
<h3>Oremus Case of Aszu 5 Puttonyos</h3>
<p>Hungary · White sweet · 2000 · 0.5 L</p>
</div>
<div class="bottle-card__footer">
<strong>19 240 ₽</strong>
<a class="button button--secondary button--sm" href="product.html">В избранное</a>
</div>
</article>
<article class="bottle-card bottle-card--compact">
<div class="bottle-card__media">
<img class="bottle-card__photo" src="assets/images/00080768_1.png" alt="Oremus Tokaji Aszu" />
</div>
<div class="bottle-card__body">
<p class="bottle-card__region">Compact</p>
<h3>Tokaji Aszu 5 Puttonyos</h3>
<p>Hungary · 12% · Furmint, Harslevelu</p>
</div>
<div class="bottle-card__footer">
<strong>19 240 ₽</strong>
<a class="button button--primary button--sm" href="product.html">Подробнее</a>
</div>
</article>
<article class="bottle-card bottle-card--horizontal">
<div class="bottle-card__media">
<img class="bottle-card__photo" src="assets/images/00081726_1.png" alt="Oremus Tokaji Late Harvest" />
</div>
<div class="bottle-card__content">
<div class="bottle-card__body">
<p class="bottle-card__region">B2B row card</p>
<h3>Oremus Tokaji Late Harvest</h3>
<p>Вино белое полусладкое · Венгрия · 11.5%</p>
<p class="bottle-card__details">Сорт: Фурминт, Зета, Харшлевелю</p>
</div>
<div class="bottle-card__footer">
<strong>4 980 ₽</strong>
<a class="button button--secondary button--sm" href="product.html">В избранное</a>
</div>
</div>
</article>
</div>
</section>
<section class="card-variant-block" aria-labelledby="catalog-card-title">
<div class="card-variant-title">
<p class="eyebrow">Catalog current</p>
<h2 id="catalog-card-title">Варианты текущей карточки каталога</h2>
</div>
<div class="catalog-card-variants">
<article class="catalog-card-sample">
<p class="catalog-card-sample__label">Default / как в каталоге</p>
<div class="product-card product-card--list">
<a class="product-image" href="product.html" aria-label="Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000">
<img src="assets/images/00081538_1.png" alt="Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000</h3>
<p class="product-origin">Вино белое, Oremus, Венгрия</p>
<p>Вино Белое Сладкое<br />12 %</p>
<p>Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)</p>
</div>
<div class="product-buy">
<strong>19 240 ₽</strong>
<a class="button button--secondary" href="#">В избранное</a>
</div>
</div>
</article>
<article class="catalog-card-sample">
<p class="catalog-card-sample__label">Compact / меньше высота</p>
<div class="product-card product-card--list product-card--list-compact">
<a class="product-image" href="product.html" aria-label="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000">
<img src="assets/images/00080768_1.png" alt="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000</h3>
<p class="product-origin">Вино белое, Oremus, Венгрия</p>
<p>Сладкое · 12% · Фурминт, Харшлевелю, Мускат</p>
</div>
<div class="product-buy">
<strong>19 240 ₽</strong>
<a class="button button--secondary" href="#">В избранное</a>
</div>
</div>
</article>
<article class="catalog-card-sample">
<p class="catalog-card-sample__label">Hover / активная строка</p>
<div class="product-card product-card--list product-card--list-hover">
<a class="product-image" href="product.html" aria-label="Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021">
<img src="assets/images/00081726_1.png" alt="Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021</h3>
<p class="product-origin">Вино белое, Oremus, Венгрия</p>
<p>Вино Белое Полусладкое<br />11.5 %</p>
<p>Сорт: Фурминт, Зета, Харшлевелю</p>
</div>
<div class="product-buy">
<strong>4 980 ₽</strong>
<a class="button button--primary" href="#">Подробнее</a>
</div>
</div>
</article>
<article class="catalog-card-sample">
<p class="catalog-card-sample__label">Color image / цветной фон фото</p>
<div class="product-card product-card--list product-card--list-color">
<a class="product-image product-image--gold" href="product.html" aria-label="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000">
<img src="assets/images/00080768_1.png" alt="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000</h3>
<p class="product-origin">Вино белое, Oremus, Венгрия</p>
<p>Вино Белое Сладкое<br />12 %</p>
<p>Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)</p>
</div>
<div class="product-buy">
<strong>19 240 ₽</strong>
<a class="button button--secondary" href="#">В избранное</a>
</div>
</div>
</article>
<article class="catalog-card-sample">
<p class="catalog-card-sample__label">B2B dense / больше данных</p>
<div class="product-card product-card--list product-card--list-b2b">
<a class="product-image" href="product.html" aria-label="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000">
<img src="assets/images/00081538_1.png" alt="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000</h3>
<p class="product-origin">Венгрия · Tokaj · Oremus · 0.5 л · 12%</p>
<div class="product-params">
<span>Тип: белое сладкое</span>
<span>Сорт: Фурминт 70%</span>
<span>Упаковка: 6 шт.</span>
<span>Артикул: 00073820</span>
</div>
</div>
<div class="product-buy">
<strong>19 240 ₽</strong>
<a class="button button--secondary" href="#">В избранное</a>
</div>
</div>
</article>
</div>
</section>
</div>
</main>

80
src/catalog.njk Normal file
View File

@ -0,0 +1,80 @@
---
title: "DP Trade — Catalog"
layout: layouts/default
permalink: /catalog.html
bodyClass: compact-type
---
<main class="section catalog-section">
<div class="container">
<div class="catalog-head">
<div>
<p class="eyebrow">Catalog / Country</p>
<h1>Венгрия</h1>
</div>
<div class="catalog-actions" aria-label="Действия каталога">
<span>Всего найдено: 22</span>
<a class="button button--secondary" href="#">Все в избранное</a>
<a class="button button--secondary" href="#">Очистить избранное</a>
</div>
</div>
<div class="catalog-toolbar">
<span>Всего найдено: 22</span>
<select class="input catalog-sort" aria-label="Сортировка">
<option>Исходная сортировка</option>
<option>По цене</option>
<option>По названию</option>
</select>
</div>
<section class="product-list" aria-label="Список товаров">
<article class="product-card product-card--list">
<a class="product-image" href="product.html" aria-label="Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000">
<img src="assets/images/00081538_1.png" alt="Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000</h3>
<p class="product-origin">Вино белое, Oremus, Венгрия</p>
<p>Вино Белое Сладкое<br />12 %</p>
<p>Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)</p>
</div>
<div class="product-buy">
<strong>19 240 ₽</strong>
<a class="button button--secondary" href="#">В избранное</a>
</div>
</article>
<article class="product-card product-card--list">
<a class="product-image" href="product.html" aria-label="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000">
<img src="assets/images/00080768_1.png" alt="Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000</h3>
<p class="product-origin">Вино белое, Oremus, Венгрия</p>
<p>Вино Белое Сладкое<br />12 %</p>
<p>Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)</p>
</div>
<div class="product-buy">
<strong>19 240 ₽</strong>
<a class="button button--secondary" href="#">В избранное</a>
</div>
</article>
<article class="product-card product-card--list">
<a class="product-image" href="product.html" aria-label="Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021">
<img src="assets/images/00081726_1.png" alt="Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021" />
</a>
<div class="product-info">
<h3>Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021</h3>
<p class="product-origin">Вино белое, Oremus, Венгрия</p>
<p>Вино Белое Полусладкое<br />11.5 %</p>
<p>Сорт: Фурминт, Зета, Харшлевелю</p>
</div>
<div class="product-buy">
<strong>4 980 ₽</strong>
<a class="button button--secondary" href="#">В избранное</a>
</div>
</article>
</section>
</div>
</main>

61
src/contacts-auth.njk Normal file
View File

@ -0,0 +1,61 @@
---
title: "DP Trade — Контакты / Auth Gate"
layout: layouts/default
permalink: /contacts-auth.html
bodyClass: compact-type
---
<main class="content-page contacts-auth-page">
<section class="page-hero page-hero--contacts">
<div class="container page-hero__inner">
<div>
<p class="eyebrow">Контакты</p>
<h1>Связаться с DP Trade</h1>
<p>Контакты открыты для всех, но заявка менеджеру доступна только зарегистрированным или залогиненным пользователям.</p>
</div>
<aside class="page-hero__meta" aria-label="Основные контакты">
<span>Sales office</span>
<strong>+7 (495) 937-94-60</strong>
<p>dptr@dp-trade.ru</p>
</aside>
</div>
</section>
<section class="section">
<div class="container contacts-layout">
<div class="contact-stack">
<article class="contact-panel">
<span>Телефон</span>
<a href="tel:+74959379460">+7 (495) 937-94-60</a>
<p>Для консультаций по ассортименту, поставкам и условиям сотрудничества.</p>
</article>
<article class="contact-panel">
<span>Email</span>
<a href="mailto:dptr@dp-trade.ru">dptr@dp-trade.ru</a>
<p>Удобно для запросов прайса, карточек производителей и B2B-документов.</p>
</article>
<article class="contact-panel">
<span>Юридическая информация</span>
<p>Интернет-витрина размещает информацию об алкогольной продукции исключительно в ознакомительных целях. Дистанционная продажа алкогольной продукции не осуществляется.</p>
</article>
</div>
<section class="contact-form contact-auth-gate" aria-labelledby="auth-gate-title">
<div class="auth-gate__badge">Требуется аккаунт</div>
<h2 id="auth-gate-title">Заявка доступна после входа</h2>
<p>Мы показываем телефон и email открыто, но форму заявки менеджеру оставляем внутри личного кабинета: так менеджер сразу видит компанию, историю запросов и коммерческий статус клиента.</p>
<div class="auth-gate__actions">
<a class="button button--primary" href="#">Войти</a>
<a class="button button--secondary" href="#">Зарегистрироваться</a>
</div>
<div class="auth-gate__note">
<strong>После входа откроется:</strong>
<span>форма заявки, автозаполнение контактов, привязка к компании и история обращений.</span>
</div>
<div class="locked-form-preview" aria-label="Предпросмотр заблокированной формы">
<label>Имя<input class="input" type="text" placeholder="Как к вам обращаться" disabled /></label>
<label>Телефон или email<input class="input" type="text" placeholder="Контакт для ответа" disabled /></label>
<label>Сообщение<textarea class="input" rows="4" placeholder="Напишите, что нужно подобрать" disabled></textarea></label>
</div>
</section>
</div>
</section>
</main>

50
src/contacts.njk Normal file
View File

@ -0,0 +1,50 @@
---
title: "DP Trade — Контакты"
layout: layouts/default
permalink: /contacts.html
bodyClass: compact-type
---
<main class="content-page">
<section class="page-hero page-hero--contacts">
<div class="container page-hero__inner">
<div>
<p class="eyebrow">Контакты</p>
<h1>Связаться с DP Trade</h1>
<p>Для вопросов по каталогу, ассортименту, поставкам и работе с менеджером используйте телефон, почту или форму заявки.</p>
</div>
<aside class="page-hero__meta" aria-label="Основные контакты">
<span>Sales office</span>
<strong>+7 (495) 937-94-60</strong>
<p>dptr@dp-trade.ru</p>
</aside>
</div>
</section>
<section class="section">
<div class="container contacts-layout">
<div class="contact-stack">
<article class="contact-panel">
<span>Телефон</span>
<a href="tel:+74959379460">+7 (495) 937-94-60</a>
<p>Для консультаций по ассортименту, поставкам и условиям сотрудничества.</p>
</article>
<article class="contact-panel">
<span>Email</span>
<a href="mailto:dptr@dp-trade.ru">dptr@dp-trade.ru</a>
<p>Удобно для запросов прайса, карточек производителей и B2B-документов.</p>
</article>
<article class="contact-panel">
<span>Юридическая информация</span>
<p>Интернет-витрина размещает информацию об алкогольной продукции исключительно в ознакомительных целях. Дистанционная продажа алкогольной продукции не осуществляется.</p>
</article>
</div>
<form class="contact-form" action="#">
<h2>Заявка менеджеру</h2>
<label>Имя<input class="input" type="text" placeholder="Как к вам обращаться" /></label>
<label>Телефон или email<input class="input" type="text" placeholder="Контакт для ответа" /></label>
<label>Сообщение<textarea class="input" rows="5" placeholder="Напишите, что нужно подобрать"></textarea></label>
<button class="button button--primary" type="submit">Отправить заявку</button>
</form>
</div>
</section>
</main>

2541
src/css/site.css Normal file

File diff suppressed because it is too large Load Diff

665
src/css/tokens.css Normal file
View File

@ -0,0 +1,665 @@
/* cyrillic-ext */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* latin-ext */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/cormorant-garamond-600-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/inter-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/inter-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/inter-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/inter-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/inter-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/inter-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/inter-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/inter-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/inter-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/inter-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* latin-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/inter-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/inter-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/inter-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/inter-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/inter-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/inter-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/inter-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2213, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/inter-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/inter-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/inter-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/manrope-400-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* latin-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/manrope-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/manrope-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/manrope-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/manrope-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/manrope-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/manrope-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/manrope-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/manrope-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/manrope-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Manrope';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/manrope-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic-ext.woff2') format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/montserrat-500-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/montserrat-500-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/montserrat-500-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/montserrat-500-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/montserrat-500-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/montserrat-500-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/montserrat-500-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/montserrat-500-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url('../fonts/montserrat-500-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic */
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/playfair-display-600-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* cyrillic */
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/playfair-display-600-cyrillic.woff2') format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* latin-ext */
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/playfair-display-600-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin-ext */
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/playfair-display-600-latin-ext.woff2') format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/playfair-display-600-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Playfair Display';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('../fonts/playfair-display-600-latin.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
:root {
--color-primary-wine-100: #4b0f24;
--color-primary-wine-80: #6d1c36;
--color-neutral-black: #161616;
--color-neutral-gray-700: #30343a;
--color-neutral-gray-600: #66605f;
--color-neutral-gray-300: #d9dee6;
--color-background-base: #f4f6f9;
--color-surface: #ffffff;
--color-accent-gold: #b9965b;
--color-accent-blue: #1f3476;
--font-heading: "Montserrat", "Inter", Arial, sans-serif;
--font-body: "Inter", Arial, sans-serif;
--font-heading-classic: "Playfair Display", Georgia, serif;
--font-body-classic: "Inter", Arial, sans-serif;
--font-heading-retail: "Montserrat", "Inter", Arial, sans-serif;
--spacing-4: 4px;
--spacing-8: 8px;
--spacing-16: 16px;
--spacing-24: 24px;
--spacing-32: 32px;
--spacing-48: 48px;
--spacing-64: 64px;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 24px;
--shadow-soft: 0 12px 32px rgba(22, 22, 22, 0.08);
--shadow-lift: 0 20px 52px rgba(75, 15, 36, 0.14);
--container: 1240px;
}

View File

@ -1,3 +1,5 @@
@import url("tokens.css");
:root {
--color-primary-wine-100: #4b0f24;
--color-primary-wine-80: #6d1c36;
@ -58,6 +60,7 @@ select {
position: fixed;
inset: 0 auto 0 0;
width: 280px;
max-height: 100vh;
padding: 24px;
background: #f8fafc;
border-right: 1px solid rgba(102, 96, 95, 0.18);
@ -101,10 +104,39 @@ select {
}
.side-nav {
min-height: 0;
overflow-y: auto;
padding-right: 4px;
display: grid;
gap: 22px;
overscroll-behavior: contain;
scrollbar-width: thin;
scrollbar-color: rgba(75, 15, 36, 0.34) transparent;
}
.side-nav::-webkit-scrollbar {
width: 6px;
}
.side-nav::-webkit-scrollbar-thumb {
border-radius: 999px;
background: rgba(75, 15, 36, 0.28);
}
.side-nav__group {
display: grid;
gap: 8px;
}
.side-nav__group span {
padding: 0 12px;
color: var(--color-accent-gold);
font-size: 11px;
font-weight: 800;
letter-spacing: 0;
text-transform: uppercase;
}
.side-nav a {
padding: 10px 12px;
border-radius: var(--radius-sm);
@ -254,6 +286,105 @@ h3 {
font-size: 14px;
}
.icon-style-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 16px;
}
.icon-style-card {
min-width: 0;
padding: 18px;
border: 1px solid rgba(102, 96, 95, 0.16);
border-radius: var(--radius-sm);
background: var(--color-white);
box-shadow: var(--shadow-soft);
display: grid;
gap: 14px;
}
.icon-demo-row {
min-height: 86px;
padding: 14px;
border-radius: var(--radius-sm);
background: #eef2f6;
display: flex;
align-items: center;
gap: 12px;
}
.kit-icon {
color: var(--color-primary-wine-100);
display: inline-grid;
place-items: center;
flex: 0 0 auto;
}
.kit-icon svg {
width: 22px;
height: 22px;
fill: none;
stroke: currentColor;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.75;
}
.kit-icon--line {
width: 44px;
height: 44px;
}
.kit-icon--soft,
.kit-icon--filled {
width: 46px;
height: 46px;
border-radius: var(--radius-sm);
}
.kit-icon--soft {
border: 1px solid rgba(75, 15, 36, 0.14);
background: var(--color-white);
}
.kit-icon--filled {
background: var(--color-primary-wine-100);
color: var(--color-white);
box-shadow: 0 10px 22px rgba(75, 15, 36, 0.16);
}
.kit-icon--tiny {
width: 28px;
height: 28px;
}
.kit-icon--tiny svg {
width: 16px;
height: 16px;
stroke-width: 1.6;
}
.icon-style-card > span {
color: var(--color-accent-gold);
font-size: 12px;
font-weight: 800;
text-transform: uppercase;
}
.icon-style-card p {
margin: 0;
color: var(--color-gray-600);
font-size: 14px;
line-height: 1.45;
}
.icon-style-card code {
padding: 10px;
border-radius: var(--radius-sm);
background: #eef2f6;
white-space: normal;
}
.section {
padding: 72px clamp(24px, 5vw, 72px);
border-top: 1px solid rgba(102, 96, 95, 0.16);
@ -269,10 +400,145 @@ h3 {
margin-bottom: 40px;
}
.section-heading--split {
grid-template-columns: minmax(0, 0.58fr) minmax(280px, 0.42fr);
gap: 32px;
align-items: end;
}
.section-heading--split > p {
margin: 0;
color: var(--color-gray-600);
line-height: 1.6;
}
.subsection {
margin-top: 40px;
}
.spec-grid {
margin-top: 18px;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
}
.spec-card {
min-width: 0;
padding: 16px;
border: 1px solid rgba(102, 96, 95, 0.16);
border-radius: var(--radius-sm);
background: rgba(255, 255, 255, 0.72);
}
.spec-card span {
display: block;
margin-bottom: 8px;
color: var(--color-accent-gold);
font-size: 12px;
font-weight: 800;
text-transform: uppercase;
}
.spec-card p {
margin: 0;
color: var(--color-gray-600);
font-size: 14px;
line-height: 1.45;
}
.status-grid,
.checklist-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
}
.status-card,
.production-rules article,
.checklist-card {
min-width: 0;
padding: 20px;
border: 1px solid rgba(102, 96, 95, 0.16);
border-radius: var(--radius-sm);
background: var(--color-white);
box-shadow: var(--shadow-soft);
}
.status-card {
min-height: 190px;
display: grid;
align-content: space-between;
gap: 14px;
}
.status-card span,
.production-rules span,
.checklist-card span {
width: fit-content;
padding: 6px 9px;
border-radius: var(--radius-sm);
font-size: 11px;
font-weight: 800;
text-transform: uppercase;
}
.status-card--ready span {
background: rgba(31, 77, 58, 0.12);
color: #1f4d3a;
}
.status-card--review span {
background: rgba(185, 150, 91, 0.18);
color: #7c5f26;
}
.status-card--draft span {
background: rgba(102, 96, 95, 0.12);
color: var(--color-gray-600);
}
.status-card strong {
color: var(--color-neutral-black);
font-family: var(--font-heading);
font-size: 22px;
line-height: 1.12;
text-transform: uppercase;
}
.status-card p,
.production-rules p {
margin: 0;
color: var(--color-gray-600);
line-height: 1.5;
}
.production-rules {
margin-top: 18px;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
}
.production-rules span,
.checklist-card span {
margin-bottom: 14px;
display: inline-block;
background: rgba(75, 15, 36, 0.08);
color: var(--color-primary-wine-100);
}
.checklist-card ul {
margin: 0;
padding-left: 18px;
color: var(--color-gray-600);
line-height: 1.58;
}
.checklist-card li + li {
margin-top: 8px;
}
.swatch-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
@ -417,6 +683,88 @@ code {
background: #fff;
}
.shadow-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 16px;
}
.shadow-card {
min-height: 220px;
padding: 18px;
border: 1px solid rgba(102, 96, 95, 0.14);
border-radius: var(--radius-sm);
background: var(--color-white);
display: grid;
align-content: space-between;
gap: 12px;
}
.shadow-card span {
color: var(--color-accent-gold);
font-size: 11px;
font-weight: 800;
text-transform: uppercase;
}
.shadow-card strong {
color: var(--color-neutral-black);
font-family: var(--font-heading);
font-size: 20px;
line-height: 1.1;
text-transform: uppercase;
}
.shadow-card p {
margin: 0;
color: var(--color-gray-600);
font-size: 14px;
line-height: 1.45;
}
.shadow-card code {
width: fit-content;
max-width: 100%;
padding: 7px 9px;
border-radius: var(--radius-sm);
background: #eef2f6;
color: var(--color-primary-wine-100);
font-size: 12px;
white-space: normal;
}
.shadow-card--none {
box-shadow: none;
}
.shadow-card--header {
box-shadow: 0 10px 28px rgba(22, 22, 22, 0.05);
}
.shadow-card--soft {
box-shadow: var(--shadow-soft);
}
.shadow-card--card {
box-shadow: 0 18px 46px rgba(18, 25, 38, 0.08);
}
.shadow-card--hover {
box-shadow: 0 22px 54px rgba(25, 37, 62, 0.13);
}
.shadow-card--lift {
box-shadow: var(--shadow-lift);
}
.shadow-card--editorial {
box-shadow: 0 22px 58px rgba(25, 37, 62, 0.12);
}
.shadow-card--focus {
box-shadow: 0 0 0 4px rgba(75, 15, 36, 0.08);
}
.product-grid {
display: grid;
gap: 20px;
@ -466,6 +814,16 @@ code {
var(--media-bg, #dde4ec);
}
.product-photo {
width: auto;
max-width: 132px;
height: 190px;
object-fit: contain;
object-position: center;
border: 0;
box-shadow: none;
}
.product-card--compact .product-media {
min-height: 130px;
}
@ -539,6 +897,80 @@ code {
font-size: 18px;
}
.image-bg-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 16px;
}
.image-bg-card {
min-width: 0;
padding: 16px;
border: 1px solid rgba(102, 96, 95, 0.16);
border-radius: var(--radius-sm);
background: var(--color-white);
box-shadow: var(--shadow-soft);
display: grid;
gap: 12px;
}
.image-bg-preview {
min-height: 190px;
border-radius: var(--radius-sm);
overflow: hidden;
display: grid;
place-items: center;
}
.image-bg-preview img {
width: auto;
max-width: 120px;
height: 164px;
object-fit: contain;
border: 0;
box-shadow: none;
}
.product-image--gold {
background: linear-gradient(135deg, #b9965b 0%, #d7c18b 48%, #eef2f6 100%);
}
.product-image--wine {
background: linear-gradient(135deg, #6d1c36 0%, #9b5366 46%, #e6dce1 100%);
}
.product-image--green {
background: linear-gradient(135deg, #1f4d3a 0%, #88a28e 48%, #eef2e5 100%);
}
.image-bg-preview--neutral {
background: linear-gradient(135deg, #eef2f6 0%, #dde6ef 100%);
}
.image-bg-card span {
color: var(--color-accent-gold);
font-size: 12px;
font-weight: 800;
text-transform: uppercase;
}
.image-bg-card p {
margin: 0;
color: var(--color-gray-600);
font-size: 14px;
line-height: 1.45;
}
.image-bg-card code {
padding: 10px;
border-radius: var(--radius-sm);
background: #eef2f6;
color: var(--color-primary-wine-100);
font-size: 12px;
line-height: 1.45;
white-space: normal;
}
.header-demo {
padding: 16px;
border-radius: var(--radius-sm);
@ -728,49 +1160,134 @@ tbody tr:hover {
text-transform: uppercase;
}
.screen-preview {
overflow: hidden;
border: 1px solid rgba(102, 96, 95, 0.18);
border-radius: var(--radius-sm);
background: var(--color-white);
box-shadow: var(--shadow-soft);
}
.screen-preview__bar {
height: 48px;
background: var(--color-primary-wine-100);
}
.screen-preview__hero {
min-height: 300px;
padding: 48px;
background:
linear-gradient(90deg, rgba(75, 15, 36, 0.84), rgba(75, 15, 36, 0.24)),
linear-gradient(135deg, #4b0f24, #b9965b);
color: var(--color-white);
display: grid;
align-content: center;
justify-items: start;
}
.screen-preview__hero h3 {
max-width: 520px;
margin: 8px 0 20px;
font-size: 48px;
text-transform: uppercase;
}
.screen-preview__content {
padding: 24px;
.template-spec-grid {
margin-top: 24px;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
}
.screen-preview__content span {
min-height: 110px;
.template-spec {
min-width: 0;
padding: 20px;
border: 1px solid rgba(102, 96, 95, 0.16);
border-radius: var(--radius-sm);
background: #e8edf3;
background: var(--color-white);
box-shadow: var(--shadow-soft);
display: grid;
gap: 10px;
}
.template-spec span {
color: var(--color-accent-gold);
font-size: 12px;
font-weight: 800;
text-transform: uppercase;
}
.template-spec h3 {
margin: 0;
font-size: 22px;
line-height: 1.12;
text-transform: uppercase;
}
.template-spec p {
margin: 0;
color: var(--color-gray-600);
font-size: 14px;
line-height: 1.48;
}
.template-spec a {
color: var(--color-primary-wine-100);
font-weight: 800;
text-decoration: underline;
text-underline-offset: 3px;
}
.template-spec em {
margin-top: 4px;
color: var(--color-primary-wine-100);
font-size: 13px;
font-style: normal;
font-weight: 800;
}
.screen-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 18px;
}
.screen-card {
min-height: 230px;
padding: 20px;
border: 1px solid rgba(102, 96, 95, 0.16);
border-radius: var(--radius-sm);
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.98)),
var(--screen-accent, #eef2f6);
box-shadow: var(--shadow-soft);
display: grid;
align-content: space-between;
gap: 18px;
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.screen-card:hover {
border-color: rgba(75, 15, 36, 0.28);
box-shadow: 0 22px 54px rgba(25, 37, 62, 0.13);
transform: translateY(-2px);
}
.screen-card span {
color: var(--color-accent-gold);
font-size: 12px;
font-weight: 800;
text-transform: uppercase;
}
.screen-card strong {
color: var(--color-neutral-black);
font-family: var(--font-heading);
font-size: 24px;
line-height: 1.1;
text-transform: uppercase;
}
.screen-card p {
margin: 0;
color: var(--color-gray-600);
line-height: 1.5;
}
.screen-card--home {
--screen-accent: linear-gradient(135deg, #4b0f24, #b9965b);
}
.screen-card--catalog {
--screen-accent: linear-gradient(135deg, #eef2f6, #d9dee6);
}
.screen-card--product,
.screen-card--cards {
--screen-accent: linear-gradient(135deg, #6d1c36, #e6dce1);
}
.screen-card--news,
.screen-card--guidelines {
--screen-accent: linear-gradient(135deg, #1f4d3a, #e8eadb);
}
.screen-card--about,
.screen-card--contacts,
.screen-card--auth {
--screen-accent: linear-gradient(135deg, #1f3476, #dde4ec);
}
.screen-qa-grid {
margin-top: 24px;
}
@media (max-width: 1100px) {
@ -796,7 +1313,15 @@ tbody tr:hover {
}
.swatch-grid,
.template-grid {
.shadow-grid,
.image-bg-grid,
.icon-style-grid,
.status-grid,
.production-rules,
.checklist-grid,
.template-grid,
.template-spec-grid,
.screen-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@ -828,10 +1353,18 @@ tbody tr:hover {
}
.swatch-grid,
.shadow-grid,
.image-bg-grid,
.icon-style-grid,
.status-grid,
.production-rules,
.checklist-grid,
.product-grid--3,
.template-grid,
.screen-preview__content,
.token-grid {
.template-spec-grid,
.screen-grid,
.token-grid,
.spec-grid {
grid-template-columns: 1fr;
}
@ -853,11 +1386,7 @@ tbody tr:hover {
grid-column: auto;
}
.screen-preview__hero {
padding: 28px;
}
.screen-preview__hero h3 {
font-size: 36px;
.screen-card {
min-height: 190px;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

90
src/index.njk Normal file
View File

@ -0,0 +1,90 @@
---
title: "DP Trade — Home"
layout: layouts/default
permalink: /
---
<main>
<section class="hero">
<div class="container hero-copy">
<p class="eyebrow">DP Trade</p>
<h1>Премиальный каталог вина для торговли</h1>
<p>Регионы, производители, партии и коммерческие условия собраны в одном интерфейсе для быстрых закупочных решений.</p>
<div class="hero-actions">
<a class="button button--primary" href="catalog.html">Смотреть каталог</a>
<a class="button button--secondary" href="ui-kit.html">Открыть UI-kit</a>
</div>
</div>
</section>
<section class="section producers-section">
<div class="container">
<div class="section-heading section-heading--split">
<div>
<p class="eyebrow">Producers</p>
<h2>Производители</h2>
</div>
<p>Ключевые винные дома и хозяйства из портфеля DP Trade: от классических брендов до эксклюзивных партнеров.</p>
</div>
<div class="producer-grid">
<a class="producer-card" href="#"><span>Argentina</span><strong>Catena Zapata</strong></a>
<a class="producer-card" href="#"><span>Champagne</span><strong>Bollinger</strong></a>
<a class="producer-card" href="#"><span>Burgundy</span><strong>Domaine De Villaine</strong></a>
<a class="producer-card" href="#"><span>Italy</span><strong>Gaja</strong></a>
<a class="producer-card" href="#"><span>France</span><strong>Pascal Jolivet</strong></a>
<a class="producer-card" href="#"><span>Rhone</span><strong>Paul Jaboulet Aine</strong></a>
</div>
</div>
</section>
<section class="section news-section">
<div class="container">
<div class="section-heading section-heading--split">
<div>
<p class="eyebrow">Latest news</p>
<h2>Последние новости</h2>
</div>
<a class="button button--secondary" href="#">Все новости</a>
</div>
<div class="news-grid">
<article class="news-card">
<div class="news-card__image news-card__image--catena"></div>
<div><span>Интервью</span><h3>Интервью с Лаурой Катеной</h3></div>
</article>
<article class="news-card">
<div class="news-card__image news-card__image--brand"></div>
<div><span>Бренды</span><h3>Catena Zapata вновь признана самым почитаемым винным брендом мира</h3></div>
</article>
<article class="news-card">
<div class="news-card__image news-card__image--italy"></div>
<div><span>Италия</span><h3>Villa Raiano: от оливкового масла к одному из лучших фиано Италии</h3></div>
</article>
</div>
</div>
</section>
<section class="section">
<div class="container">
<div class="section-heading">
<p class="eyebrow">Recommendations</p>
<h2>Рекомендации недели</h2>
</div>
<div class="product-grid">
<article class="product-card">
<div class="product-media"><img class="product-photo" src="assets/images/00081538_1.png" alt="Chateau Laroque Grand Cru" /></div>
<div><span class="muted-caps">Bordeaux</span><h3>Chateau Laroque Grand Cru</h3><p>France · Red dry · 2019 · 0.75 L</p></div>
<div class="product-footer"><strong>3 890 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
<article class="product-card">
<div class="product-media product-media--amber"><img class="product-photo" src="assets/images/00080768_1.png" alt="Brunello di Montalcino" /></div>
<div><span class="muted-caps">Tuscany</span><h3>Brunello di Montalcino</h3><p>Italy · Red dry · 2018 · 0.75 L</p></div>
<div class="product-footer"><strong>4 240 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
<article class="product-card">
<div class="product-media product-media--green"><img class="product-photo" src="assets/images/00081726_1.png" alt="Riesling Kabinett" /></div>
<div><span class="muted-caps">Mosel</span><h3>Riesling Kabinett</h3><p>Germany · White · 2021 · 0.75 L</p></div>
<div class="product-footer"><strong>2 150 ₽</strong><a class="button button--primary button--sm" href="product.html">Подробнее</a></div>
</article>
</div>
</div>
</section>
</main>

624
src/js/inspector.js Normal file
View File

@ -0,0 +1,624 @@
(function () {
'use strict';
// ── Конфиг ─────────────────────────────────────────────────────────────────
const TOKEN_PREFIXES = ['--color-', '--font-', '--spacing-', '--radius-', '--shadow-', '--container'];
// layout-свойства для секции «Стили» (типографика — отдельная секция)
const LAYOUT_PROPS = [
'display', 'position', 'flexDirection', 'flexWrap',
'gridTemplateColumns', 'gridTemplateRows', 'gap', 'alignItems', 'justifyContent',
'width', 'maxWidth', 'minHeight', 'height',
'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',
'margin', 'marginTop', 'marginBottom',
'backgroundColor', 'borderRadius', 'boxShadow', 'opacity',
];
const SKIP_VALUES = new Set([
'none', 'normal', 'auto', '0px', 'rgba(0, 0, 0, 0)', 'transparent',
'start', 'static', 'visible', 'nowrap', 'row', 'inline',
'0px 0px 0px 0px rgba(0, 0, 0, 0)',
]);
const TOKEN_PROP_MAP = {
'--color-': ['color', 'background-color', 'border-top-color',
'border-bottom-color', 'border-left-color', 'border-right-color'],
'--font-': ['font-family'],
'--spacing-': ['padding-top', 'padding-right', 'padding-bottom', 'padding-left',
'margin-top', 'margin-right', 'margin-bottom', 'margin-left',
'row-gap', 'column-gap'],
'--radius-': ['border-top-left-radius'],
'--shadow-': ['box-shadow'],
'--container': ['max-width'],
};
// ── Состояние ───────────────────────────────────────────────────────────────
let enabled = false;
let pinned = null;
// ── Утилиты: цвет ───────────────────────────────────────────────────────────
function rgbToHex(rgb) {
const m = rgb.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
if (!m) return null;
return '#' + [m[1], m[2], m[3]]
.map(n => parseInt(n).toString(16).padStart(2, '0'))
.join('').toUpperCase();
}
function hexToRgb(hex) {
hex = hex.replace(/^#/, '');
if (hex.length === 3) hex = hex.split('').map(c => c + c).join('');
const r = parseInt(hex.slice(0, 2), 16);
const g = parseInt(hex.slice(2, 4), 16);
const b = parseInt(hex.slice(4, 6), 16);
return `rgb(${r}, ${g}, ${b})`;
}
function normalizeColor(val) {
val = val.trim().toLowerCase();
if (/^#[0-9a-f]{3,8}$/.test(val)) return hexToRgb(val);
return val.replace(/\s+/g, '');
}
function firstFont(val) {
return val.split(',')[0].trim().replace(/["']/g, '').toLowerCase();
}
function formatColor(val) {
if (/^#/.test(val.trim())) return val.trim().toUpperCase();
if (/^rgba?\(/.test(val.trim())) return rgbToHex(val) || val;
return val;
}
// ── Токены из :root ──────────────────────────────────────────────────────────
let _rootTokens = null;
function getRootTokens() {
if (_rootTokens) return _rootTokens;
_rootTokens = {};
for (const sheet of document.styleSheets) {
try {
for (const rule of sheet.cssRules) {
if (rule.selectorText === ':root') {
for (const prop of rule.style) {
if (TOKEN_PREFIXES.some(p => prop.startsWith(p))) {
_rootTokens[prop] = rule.style.getPropertyValue(prop).trim();
}
}
}
}
} catch (_) {}
}
return _rootTokens;
}
// ── Обратный маппинг: значение → имя токена ─────────────────────────────────
// Используется в секции Типографика, чтобы показать
// «Inter → --font-body» и «#30343A → --color-neutral-gray-700».
let _colorMap = null;
let _fontMap = null;
function getColorTokenMap() {
if (_colorMap) return _colorMap;
_colorMap = {};
for (const [name, val] of Object.entries(getRootTokens())) {
if (!name.startsWith('--color-')) continue;
try { _colorMap[normalizeColor(val)] = name; } catch (_) {}
}
return _colorMap;
}
function getFontTokenMap() {
if (_fontMap) return _fontMap;
_fontMap = {};
for (const [name, val] of Object.entries(getRootTokens())) {
if (!name.startsWith('--font-')) continue;
const key = firstFont(val);
// Приоритет: --font-heading > --font-heading-* > --font-body > etc.
// Первый встреченный побеждает, поэтому не перезаписываем.
if (!_fontMap[key]) _fontMap[key] = { name, fullValue: val };
}
return _fontMap;
}
// ── Токены, активные на элементе (для секции «Токены») ──────────────────────
function getElementTokens(el) {
const tokens = getRootTokens();
const cs = getComputedStyle(el);
const found = new Map();
for (const [tokenName, tokenRaw] of Object.entries(tokens)) {
const prefix = TOKEN_PREFIXES.find(p => tokenName.startsWith(p));
if (!prefix) continue;
const propsToCheck = TOKEN_PROP_MAP[prefix] || [];
for (const cssProp of propsToCheck) {
const computed = cs.getPropertyValue(cssProp).trim();
if (!computed) continue;
let match = false;
if (prefix === '--color-') {
try { match = normalizeColor(computed) === normalizeColor(tokenRaw); } catch (_) {}
} else if (prefix === '--font-') {
match = firstFont(computed) === firstFont(tokenRaw);
} else if (prefix === '--spacing-' || prefix === '--radius-' || prefix === '--container') {
match = computed === tokenRaw.trim();
} else if (prefix === '--shadow-') {
match = computed.includes(tokenRaw.split(' ').slice(0, 3).join(' '));
}
if (match) {
if (!found.has(tokenName)) {
found.set(tokenName, { raw: tokenRaw, usedIn: [] });
}
found.get(tokenName).usedIn.push(cssProp);
break;
}
}
}
return found;
}
// ── Типографика элемента ─────────────────────────────────────────────────────
function getTypography(el) {
const cs = getComputedStyle(el);
const colorMap = getColorTokenMap();
const fontMap = getFontTokenMap();
const rawFont = cs.fontFamily;
const rawColor = cs.color;
const fontKey = firstFont(rawFont);
const fontEntry = fontMap[fontKey];
// Название шрифта — первый, без кавычек
const fontName = fontKey.charAt(0).toUpperCase() + fontKey.slice(1);
// Токен шрифта — ищем точное совпадение первого шрифта
const fontToken = fontEntry ? fontEntry.name : null;
// Цвет текста
const colorHex = formatColor(rawColor);
const colorToken = colorMap[normalizeColor(rawColor)] || null;
// Линейная высота — упрощаем до числа если возможно
const lhRaw = cs.lineHeight;
const lhNum = parseFloat(lhRaw);
const fsNum = parseFloat(cs.fontSize);
const lh = (fsNum && lhNum)
? (lhNum / fsNum).toFixed(2).replace(/\.?0+$/, '')
: lhRaw;
// Letter-spacing
const ls = cs.letterSpacing !== '0px' ? cs.letterSpacing : null;
// Text-transform
const tt = cs.textTransform !== 'none' ? cs.textTransform : null;
return {
fontName,
fontToken,
fontFull: rawFont,
fontSize: cs.fontSize,
fontWeight: cs.fontWeight,
lineHeight: lh,
letterSpacing: ls,
textTransform: tt,
colorHex,
colorToken,
};
}
// ── Layout-стили (без типографики) ──────────────────────────────────────────
function getLayoutStyles(el) {
const cs = getComputedStyle(el);
const result = [];
for (const prop of LAYOUT_PROPS) {
let val = cs[prop];
if (!val || SKIP_VALUES.has(val)) continue;
if (/^rgba?\(/.test(val)) val = formatColor(val);
result.push({ prop: camelToKebab(prop), value: val });
}
return result;
}
function camelToKebab(s) {
return s.replace(/[A-Z]/g, c => '-' + c.toLowerCase());
}
function formatTokenValue(raw) {
const t = raw.trim();
if (/^#[0-9a-fA-F]{3,6}$/.test(t)) return t.toUpperCase();
if (/^rgba?\(/.test(t)) return rgbToHex(t) || t;
return t;
}
// ── DOM ─────────────────────────────────────────────────────────────────────
const panel = document.createElement('div');
panel.id = 'dp-inspector-panel';
panel.innerHTML = `
<div class="dpi-header">
<span class="dpi-title">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
</svg>
Инспектор
</span>
<button class="dpi-close" aria-label="Закрыть"></button>
</div>
<div class="dpi-body">
<p class="dpi-empty">Кликните на элемент</p>
</div>
`;
document.body.appendChild(panel);
const toggle = document.createElement('button');
toggle.id = 'dp-inspector-toggle';
toggle.title = 'Инспектор элементов (Alt+I)';
toggle.innerHTML = `
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
</svg>`;
document.body.appendChild(toggle);
const highlight = document.createElement('div');
highlight.id = 'dp-inspector-highlight';
document.body.appendChild(highlight);
const tooltip = document.createElement('div');
tooltip.id = 'dp-inspector-tooltip';
document.body.appendChild(tooltip);
// ── Стили ───────────────────────────────────────────────────────────────────
const style = document.createElement('style');
style.textContent = `
#dp-inspector-toggle {
position: fixed; bottom: 24px; right: 24px; z-index: 99998;
width: 44px; height: 44px; border-radius: 50%; border: none;
background: #4b0f24; color: #fff; cursor: pointer;
display: flex; align-items: center; justify-content: center;
box-shadow: 0 4px 16px rgba(75,15,36,.35);
transition: background .15s, transform .15s;
}
#dp-inspector-toggle:hover { background: #6d1c36; transform: scale(1.08); }
#dp-inspector-toggle.active { background: #b9965b; }
#dp-inspector-panel {
position: fixed; top: 0; right: -360px; width: 340px; height: 100vh;
z-index: 99999; background: #fff;
border-left: 1px solid rgba(102,96,95,.18);
box-shadow: -12px 0 40px rgba(22,22,22,.10);
display: flex; flex-direction: column;
font-family: 'Inter', system-ui, sans-serif; font-size: 13px;
transition: right .25s cubic-bezier(.4,0,.2,1); overflow: hidden;
}
#dp-inspector-panel.open { right: 0; }
.dpi-header {
display: flex; align-items: center; justify-content: space-between;
padding: 14px 16px; background: #4b0f24; color: #fff; flex-shrink: 0;
}
.dpi-title {
display: flex; align-items: center; gap: 7px;
font-weight: 700; font-size: 13px;
letter-spacing: .04em; text-transform: uppercase;
}
.dpi-close {
background: none; border: none; color: rgba(255,255,255,.7);
cursor: pointer; font-size: 15px; padding: 2px 4px; line-height: 1;
}
.dpi-close:hover { color: #fff; }
.dpi-body { flex: 1; overflow-y: auto; padding: 0 0 80px; }
.dpi-empty { color: #66605f; text-align: center; padding: 40px 16px; margin: 0; }
.dpi-section { padding: 12px 16px; border-bottom: 1px solid rgba(102,96,95,.12); }
.dpi-section:last-child { border-bottom: none; }
.dpi-section-title {
font-size: 10px; font-weight: 800; letter-spacing: .08em;
text-transform: uppercase; color: #b9965b; margin: 0 0 8px;
}
/* Элемент */
.dpi-element-tag {
font-family: 'Menlo','Monaco',monospace; font-size: 12px;
color: #4b0f24; font-weight: 600; margin: 0 0 6px; word-break: break-all;
}
.dpi-classes { display: flex; flex-wrap: wrap; gap: 5px; }
.dpi-class {
padding: 2px 8px; border-radius: 4px;
background: rgba(75,15,36,.08); color: #4b0f24;
font-family: 'Menlo','Monaco',monospace; font-size: 11px;
font-weight: 600; cursor: pointer; user-select: all;
}
.dpi-class:hover { background: rgba(75,15,36,.16); }
/* Типографика */
.dpi-type-row {
display: grid; grid-template-columns: 76px 1fr;
align-items: baseline; gap: 6px;
padding: 3px 0; border-bottom: 1px solid rgba(102,96,95,.07);
}
.dpi-type-row:last-child { border-bottom: none; }
.dpi-type-label {
font-size: 10px; font-weight: 700; text-transform: uppercase;
letter-spacing: .06em; color: #66605f;
}
.dpi-type-val {
font-family: 'Menlo','Monaco',monospace; font-size: 11px;
color: #161616; font-weight: 600;
}
.dpi-type-token {
font-family: 'Menlo','Monaco',monospace; font-size: 10px;
color: #b9965b; margin-left: 6px; font-weight: 400;
}
.dpi-color-dot {
display: inline-block; width: 10px; height: 10px;
border-radius: 2px; border: 1px solid rgba(0,0,0,.12);
margin-right: 5px; vertical-align: middle; flex-shrink: 0;
}
/* Токены */
.dpi-token {
display: grid; grid-template-columns: 16px 1fr auto;
align-items: start; gap: 7px;
padding: 5px 0; border-bottom: 1px solid rgba(102,96,95,.07);
}
.dpi-token:last-child { border-bottom: none; }
.dpi-token-swatch {
width: 14px; height: 14px; border-radius: 3px;
border: 1px solid rgba(0,0,0,.12); margin-top: 1px;
}
.dpi-token-swatch.no-color {
background: repeating-linear-gradient(45deg,#ddd 0 3px,#fff 3px 6px);
}
.dpi-token-info { min-width: 0; }
.dpi-token-name {
font-family: 'Menlo','Monaco',monospace; font-size: 11px;
color: #30343a; display: block;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dpi-token-uses {
font-size: 10px; color: #b9965b; margin-top: 1px;
display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dpi-token-value {
font-family: 'Menlo','Monaco',monospace; font-size: 11px;
color: #4b0f24; font-weight: 600; white-space: nowrap; margin-top: 1px;
}
/* Стили */
.dpi-style {
display: flex; justify-content: space-between; gap: 8px;
padding: 3px 0; border-bottom: 1px solid rgba(102,96,95,.07);
}
.dpi-style:last-child { border-bottom: none; }
.dpi-style-prop {
font-family: 'Menlo','Monaco',monospace; font-size: 11px;
color: #30343a; flex-shrink: 0;
}
.dpi-style-val {
font-family: 'Menlo','Monaco',monospace; font-size: 11px;
color: #4b0f24; font-weight: 600;
text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Highlight */
#dp-inspector-highlight {
position: fixed; pointer-events: none; z-index: 99990;
border: 2px solid #4b0f24; background: rgba(75,15,36,.06);
border-radius: 3px; display: none;
transition: top .05s, left .05s, width .05s, height .05s;
}
body.dp-inspect-mode #dp-inspector-highlight { display: block; }
#dp-inspector-tooltip {
position: fixed; pointer-events: none; z-index: 99995;
background: #4b0f24; color: #fff;
font-family: 'Menlo','Monaco',monospace; font-size: 11px;
padding: 3px 8px; border-radius: 4px; white-space: nowrap;
display: none; max-width: 300px;
overflow: hidden; text-overflow: ellipsis;
}
body.dp-inspect-mode #dp-inspector-tooltip { display: block; }
body.dp-inspect-mode * { cursor: crosshair !important; }
body.dp-inspect-mode #dp-inspector-toggle,
body.dp-inspect-mode #dp-inspector-panel,
body.dp-inspect-mode #dp-inspector-panel * { cursor: default !important; }
`;
document.head.appendChild(style);
// ── Рендер панели ───────────────────────────────────────────────────────────
function buildPanel(el) {
const tag = el.tagName.toLowerCase();
const id = el.id ? `#${el.id}` : '';
const classes = [...el.classList];
const typo = getTypography(el);
const tokens = getElementTokens(el);
const layout = getLayoutStyles(el);
let html = '';
// ── Элемент ──────────────────────────────────────────────────────────────
html += `<div class="dpi-section">
<p class="dpi-section-title">Элемент</p>
<p class="dpi-element-tag">&lt;${tag}${id}&gt;</p>`;
html += classes.length
? `<div class="dpi-classes">${classes.map(c => `<span class="dpi-class">.${c}</span>`).join('')}</div>`
: `<p style="color:#66605f;margin:0;font-size:12px">Нет классов</p>`;
html += `</div>`;
// ── Типографика ──────────────────────────────────────────────────────────
html += `<div class="dpi-section">
<p class="dpi-section-title">Типографика</p>`;
// Шрифт
const fontToken = typo.fontToken
? `<span class="dpi-type-token">${typo.fontToken}</span>` : '';
html += `<div class="dpi-type-row" title="${typo.fontFull}">
<span class="dpi-type-label">Шрифт</span>
<span class="dpi-type-val">${typo.fontName}${fontToken}</span>
</div>`;
// Размер
html += `<div class="dpi-type-row">
<span class="dpi-type-label">Размер</span>
<span class="dpi-type-val">${typo.fontSize}</span>
</div>`;
// Насыщенность
html += `<div class="dpi-type-row">
<span class="dpi-type-label">Насыщ.</span>
<span class="dpi-type-val">${typo.fontWeight}</span>
</div>`;
// Межстрочный
html += `<div class="dpi-type-row">
<span class="dpi-type-label">Line-height</span>
<span class="dpi-type-val">${typo.lineHeight}</span>
</div>`;
// Letter-spacing
if (typo.letterSpacing) {
html += `<div class="dpi-type-row">
<span class="dpi-type-label">Tracking</span>
<span class="dpi-type-val">${typo.letterSpacing}</span>
</div>`;
}
// Text-transform
if (typo.textTransform) {
html += `<div class="dpi-type-row">
<span class="dpi-type-label">Transform</span>
<span class="dpi-type-val">${typo.textTransform}</span>
</div>`;
}
// Цвет текста
const colorDot = `<span class="dpi-color-dot" style="background:${typo.colorHex}"></span>`;
const colorToken = typo.colorToken
? `<span class="dpi-type-token">${typo.colorToken}</span>` : '';
html += `<div class="dpi-type-row">
<span class="dpi-type-label">Цвет</span>
<span class="dpi-type-val">${colorDot}${typo.colorHex}${colorToken}</span>
</div>`;
html += `</div>`;
// ── Токены ───────────────────────────────────────────────────────────────
html += `<div class="dpi-section">
<p class="dpi-section-title">Токены${tokens.size ? ` (${tokens.size})` : ''}</p>`;
if (tokens.size) {
for (const [name, { raw, usedIn }] of tokens) {
const display = formatTokenValue(raw);
const isColor = name.startsWith('--color-');
const swatch = isColor
? `<span class="dpi-token-swatch" style="background:${raw}"></span>`
: `<span class="dpi-token-swatch no-color"></span>`;
html += `<div class="dpi-token">
${swatch}
<span class="dpi-token-info">
<span class="dpi-token-name" title="${name}">${name}</span>
<span class="dpi-token-uses">${usedIn.join(', ')}</span>
</span>
<span class="dpi-token-value">${display}</span>
</div>`;
}
} else {
html += `<p style="color:#66605f;margin:0;font-size:12px">Нет прямых совпадений с tokens.css</p>`;
}
html += `</div>`;
// ── Стили (layout) ───────────────────────────────────────────────────────
if (layout.length) {
html += `<div class="dpi-section">
<p class="dpi-section-title">Стили</p>`;
for (const { prop, value } of layout) {
html += `<div class="dpi-style">
<span class="dpi-style-prop">${prop}</span>
<span class="dpi-style-val" title="${value}">${value}</span>
</div>`;
}
html += `</div>`;
}
panel.querySelector('.dpi-body').innerHTML = html;
}
// ── Управление ──────────────────────────────────────────────────────────────
function enable() {
enabled = true;
document.body.classList.add('dp-inspect-mode');
toggle.classList.add('active');
panel.classList.add('open');
panel.querySelector('.dpi-body').innerHTML = '<p class="dpi-empty">Кликните на элемент</p>';
}
function disable() {
enabled = false; pinned = null;
document.body.classList.remove('dp-inspect-mode');
toggle.classList.remove('active');
panel.classList.remove('open');
highlight.style.display = 'none';
tooltip.style.display = 'none';
}
function isInspectable(el) {
if (!el || el === document.body || el === document.documentElement) return false;
if (['dp-inspector-panel','dp-inspector-toggle',
'dp-inspector-highlight','dp-inspector-tooltip'].includes(el.id)) return false;
if (el.closest('#dp-inspector-panel, #dp-inspector-toggle')) return false;
return true;
}
// ── События ─────────────────────────────────────────────────────────────────
toggle.addEventListener('click', () => enabled ? disable() : enable());
panel.querySelector('.dpi-close').addEventListener('click', disable);
document.addEventListener('keydown', e => {
if (e.altKey && e.key === 'i') { e.preventDefault(); enabled ? disable() : enable(); }
if (e.key === 'Escape' && enabled) disable();
});
document.addEventListener('mousemove', e => {
if (!enabled) return;
const el = document.elementFromPoint(e.clientX, e.clientY);
if (!isInspectable(el) || el === pinned) return;
const r = el.getBoundingClientRect();
Object.assign(highlight.style, {
display: 'block', top: r.top + 'px', left: r.left + 'px',
width: r.width + 'px', height: r.height + 'px',
});
const cls = [...el.classList].map(c => '.' + c).join('');
tooltip.textContent = el.tagName.toLowerCase() + (el.id ? '#' + el.id : '') + cls;
tooltip.style.display = 'block';
tooltip.style.left = Math.min(e.clientX + 12, window.innerWidth - tooltip.offsetWidth - 8) + 'px';
tooltip.style.top = (e.clientY + 20) + 'px';
});
document.addEventListener('click', e => {
if (!enabled) return;
const el = document.elementFromPoint(e.clientX, e.clientY);
if (!isInspectable(el)) return;
e.preventDefault(); e.stopPropagation();
pinned = el;
buildPanel(el);
}, true);
})();

View File

@ -0,0 +1,78 @@
---
title: "DP Trade — Villa Raiano editorial"
layout: layouts/default
permalink: /news-villa-raiano-v2.html
bodyClass: compact-type
---
<main class="news-editorial">
<article>
<header class="editorial-hero">
<div class="container editorial-hero__inner">
<div class="editorial-hero__copy">
<p class="eyebrow">Новости / Villa Raiano</p>
<h1>Villa Raiano: от оливкового масла к одному из лучших фиано Италии</h1>
<div class="editorial-meta"><span>6 апреля, 2026</span><span>Ирпиния, Кампания</span></div>
</div>
<figure class="editorial-hero__image">
<img src="assets/images/photo_2026-04-06_16-53-26.jpg" alt="Винодельня Villa Raiano среди холмов Ирпинии" />
</figure>
</div>
</header>
<section class="section editorial-section">
<div class="container editorial-layout">
<aside class="editorial-side">
<span>Article focus</span>
<p>Семья Бассо, новая винодельня, ставка на белые вина и признание Fiano di Avellino.</p>
</aside>
<div class="editorial-body">
<p class="lead">Рассказываем о семье Бассо и винодельне Villa Raiano, совершившей небольшую революцию в Ирпинии, сменив курс с красных вин на белые. Судя по нашим последним дегустациям, у них это получилось.</p>
<p>На холмах Сан-Микеле-ди-Серино, в провинции Авеллино, расположена винодельня семьи Бассо. Название связано с корнями: Villa Raiano — историческая местность коммуны Серино, где находилась старая оливковая плантация семьи.</p>
</div>
</div>
</section>
<figure class="container editorial-image editorial-image--wide">
<img src="assets/images/photo_2026-04-06_16-53-24.jpg" alt="Сбор белого винограда Villa Raiano" />
</figure>
<section class="section editorial-section">
<div class="container editorial-layout">
<aside class="editorial-side editorial-side--timeline">
<span>Timeline</span>
<ol>
<li><strong>1990-е</strong><small>семейная маслобойня</small></li>
<li><strong>2008</strong><small>новое оборудование и команда</small></li>
<li><strong>2009</strong><small>винодельня на холме</small></li>
<li><strong>2024</strong><small>подземная винодельня</small></li>
</ol>
</aside>
<div class="editorial-body">
<p>В середине 1990-х с основанием винодельни в Ирпинии начался винодельческий бум. Первые годы для семьи Бассо были скорее хобби: они делали и разливали вино на семейной маслобойне. С 1999 по 2008 год они стали сотрудничать с энологом Луиджи Мойо, который учился вместе с Сабино Бассо в аграрном институте Авеллино.</p>
<blockquote>«В 2008 году мы купили новое оборудование, начали сотрудничество с Фортунато Себастьяно и построили винодельню на вершине холма в Сан-Микеле-ди-Серино», — рассказывает сын Сабино Бассо, Федерико.</blockquote>
<p>Открытие в 2009 году совпало с новым курсом: появились четыре белых вина с отдельных виноградников — три Fiano di Avellino и один Greco di Tufo. Через десять лет к работе подключилось новое поколение: «В компанию пришли я, мой брат Фабрицио и наша кузина Брунелла, дочь Симоне».</p>
</div>
</div>
</section>
<section class="container editorial-photo-grid" aria-label="Фото Villa Raiano">
<figure><img src="assets/images/photo_2026-04-06_16-53-23.jpg" alt="Ящики с белым виноградом Villa Raiano" /></figure>
<figure><img src="assets/images/photo_2026-04-06_16-53-23-2.jpg" alt="Работа в погребе Villa Raiano" /></figure>
</section>
<section class="section editorial-section editorial-section--final">
<div class="container editorial-layout">
<aside class="editorial-side">
<span>Recognition</span>
<p>Gambero Rosso отметил Fiano di Avellino 2024 за лучшее соотношение цены и качества в регионе.</p>
</aside>
<div class="editorial-body">
<p>В 2024 году открылась новая подземная винодельня, полностью интегрированная в ландшафт. Сегодня Villa Raiano владеет 30 гектарами виноградников: хозяйство работает по биологическим принципам и сертифицировано с 2011 года.</p>
<blockquote>«Мы уверены, что наш регион — земля великих белых вин», — говорит Федерико. «Сила наших DOC — в огромных различиях, которые один и тот же сорт может проявлять в разных условиях».</blockquote>
<p>Континентальный климат позволяет ягодам созревать медленно, что делает вина особенными — как красные, так и белые. На последних дегустациях Gambero Rosso Fiano di Avellino 2024 года особенно впечатлил итальянских экспертов, получив премию Miglior Qualità Prezzo Regionale гида BereBene 2026.</p>
<p class="editorial-outro">Чем не повод самому проверить мнение Gambero Rosso?</p>
</div>
</div>
</section>
</article>
</main>

53
src/news-villa-raiano.njk Normal file
View File

@ -0,0 +1,53 @@
---
title: "DP Trade — Villa Raiano"
layout: layouts/default
permalink: /news-villa-raiano.html
bodyClass: compact-type
---
<main class="content-page">
<section class="page-hero page-hero--news">
<div class="container page-hero__inner">
<div>
<p class="eyebrow">Новости / Италия</p>
<h1>Villa Raiano: от оливкового масла к одному из лучших Fiano Италии</h1>
<p>История семейного хозяйства из Кампании, где любовь к Ирпинии выросла из маслобойного производства в современную винодельню.</p>
</div>
<aside class="page-hero__meta" aria-label="Параметры новости">
<span>Producer spotlight</span>
<strong>Villa Raiano</strong>
<p>Campania · Irpinia · Fiano di Avellino</p>
</aside>
</div>
</section>
<section class="section">
<div class="container article-layout">
<article class="article-body">
<p class="lead">Villa Raiano появилась в 1996 году по инициативе семьи Бассо, известной производством оливкового масла. Первые вина делались в помещениях старого маслобойного завода, а в 2009 году хозяйство переехало в новую винодельню в Ирпинии.</p>
<p>Для DP Trade эта история важна не только как биография производителя. Villa Raiano показывает, как локальная ремесленная культура Кампании может стать точной, современной и очень узнаваемой винной стилистикой.</p>
<h2>Почему Fiano di Avellino</h2>
<p>Фьяно из Авеллино ценят за минеральность, плотную фактуру и способность к развитию в бутылке. В молодых винах часто появляются цитрусовые, груша, персик, травы и медовые оттенки; с возрастом они становятся глубже, прянее и сложнее.</p>
<p>Villa Raiano работает с традиционными сортами региона: Fiano, Greco, Falanghina и Aglianico. Такой фокус помогает хозяйству говорить не универсальным языком международного вина, а языком конкретного места.</p>
<blockquote>Фокус карточки новости: семейная история, локальный сорт и ценность производителя для профессионального каталога.</blockquote>
<h2>Что показать в каталоге</h2>
<p>Для товарной страницы и подборок можно вынести происхождение, сорт, стиль, потенциал выдержки и гастрономические пары. В B2B-сценарии особенно полезны быстрые маркеры: регион, апелласьон, тип вина, крепость, объем и доступность партии.</p>
</article>
<aside class="article-aside">
<div class="info-card">
<span>Ключевые факты</span>
<dl>
<div><dt>Страна</dt><dd>Италия</dd></div>
<div><dt>Регион</dt><dd>Кампания, Ирпиния</dd></div>
<div><dt>Основание</dt><dd>1996</dd></div>
<div><dt>Сорта</dt><dd>Fiano, Greco, Aglianico</dd></div>
</dl>
</div>
<div class="info-card info-card--accent">
<span>Для UI-kit</span>
<p>Эта страница проверяет длинный заголовок новости, текстовую статью, боковую карточку фактов и CTA обратно в каталог.</p>
<a class="button button--primary button--sm" href="catalog.html">В каталог</a>
</div>
</aside>
</div>
</section>
</main>

View File

@ -1,18 +1,11 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DP Trade — Product</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Montserrat:wght@500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="css/site.css" />
</head>
<body>
---
title: "DP Trade — Product"
layout: layouts/default
permalink: /product.html
---
<main class="section">
<div class="container product-detail">
<div class="product-media"><span class="bottle"></span></div>
<div class="product-media"><img class="product-photo" src="assets/images/00081538_1.png" alt="Chateau Laroque Grand Cru" /></div>
<section class="detail-copy">
<p class="eyebrow">Product / Default</p>
<h1>Chateau Laroque Grand Cru</h1>
@ -31,5 +24,3 @@
</section>
</div>
</main>
</body>
</html>

1168
src/ui-kit.njk Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,374 +0,0 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DP Trade — Design System</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Montserrat:wght@500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="css/ui-kit.css" />
</head>
<body>
<aside class="sidebar">
<a class="brand" href="#top" aria-label="DP Trade Design System">
<span class="brand__mark">DP</span>
<span>
<strong>DP Trade</strong>
<small>Design System</small>
</span>
</a>
<nav class="side-nav" aria-label="Разделы UI-kit">
<a href="index.html">Site Preview</a>
<a href="#foundations">01 Foundations</a>
<a href="#components">02 Components</a>
<a href="#patterns">03 Patterns</a>
<a href="#templates">04 Templates</a>
<a href="#screens">05 Screens</a>
</nav>
</aside>
<main id="top" class="page-shell">
<header class="kit-hero">
<div class="kit-hero__content">
<p class="eyebrow">DP Trade — Design System</p>
<h1>UI-kit для премиального торгового каталога</h1>
<p>
Живая HTML/CSS витрина компонентов, токенов, паттернов и экранов для сайта DP Trade.
Структура повторяет Figma-файл и использует критичный naming format.
</p>
<div class="hero-actions">
<a class="button button--primary" href="#components">Компоненты</a>
<a class="button button--secondary" href="#tokens">Dev tokens</a>
</div>
</div>
<div class="kit-hero__visual" aria-label="Пример карточки продукта">
<article class="product-card product-card--featured">
<div class="product-media product-media--wine">
<span class="bottle"></span>
</div>
<div class="product-meta">
<span class="tag tag--filled">Bordeaux</span>
<h3>Chateau Laroque Grand Cru</h3>
<p>France · Red dry · 2019 · 0.75 L</p>
</div>
<div class="product-footer">
<strong>от 3 890 ₽</strong>
<button class="button button--primary button--sm">В каталог</button>
</div>
</article>
</div>
</header>
<section id="foundations" class="section">
<div class="section-heading">
<p class="eyebrow">01 Foundations</p>
<h2>База системы</h2>
</div>
<div class="subsection">
<h3>Colors</h3>
<div class="swatch-grid">
<article class="swatch">
<span style="--swatch: var(--color-primary-wine-100)"></span>
<strong>Color / Primary / Wine / 100</strong>
<code>#4B0F24</code>
</article>
<article class="swatch">
<span style="--swatch: var(--color-primary-wine-80)"></span>
<strong>Color / Primary / Wine / 80</strong>
<code>#6D1C36</code>
</article>
<article class="swatch">
<span style="--swatch: var(--color-neutral-black)"></span>
<strong>Color / Neutral / Black</strong>
<code>#161616</code>
</article>
<article class="swatch">
<span style="--swatch: var(--color-gray-600)"></span>
<strong>Color / Neutral / Gray / 600</strong>
<code>#66605F</code>
</article>
<article class="swatch">
<span style="--swatch: var(--color-gray-300)"></span>
<strong>Color / Neutral / Gray / 300</strong>
<code>#D8D3CF</code>
</article>
<article class="swatch">
<span style="--swatch: var(--color-background-base)"></span>
<strong>Color / Background / Base</strong>
<code>#FAF8F5</code>
</article>
<article class="swatch">
<span style="--swatch: var(--color-accent-gold)"></span>
<strong>Color / Accent / Gold</strong>
<code>#B9965B</code>
</article>
</div>
</div>
<div class="subsection typography-specimen">
<h3>Typography</h3>
<div class="type-row">
<span>Text / Heading / H1 / Montserrat / 48 / 56</span>
<p class="text-h1">Rare wines for trade</p>
</div>
<div class="type-row">
<span>Text / Heading / H2 / Montserrat / 36 / 44</span>
<p class="text-h2">Catalog collections</p>
</div>
<div class="type-row">
<span>Text / Heading / H3 / Montserrat / 28 / 36</span>
<p class="text-h3">Producer selection</p>
</div>
<div class="type-row">
<span>Text / Body / Regular / Inter / 16 / 24</span>
<p class="text-body">Вина, регионы, партии и коммерческие условия в единой системе.</p>
</div>
<div class="type-row">
<span>Text / Label / Caps / Inter / 12 / 16</span>
<p class="text-label">FEATURED REGION</p>
</div>
</div>
<div class="subsection">
<h3>Grid & Spacing</h3>
<div class="grid-demo" aria-label="Desktop grid 12 columns">
<span></span><span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span><span></span>
</div>
<div class="spacing-scale">
<span style="--space: 4px">4</span>
<span style="--space: 8px">8</span>
<span style="--space: 16px">16</span>
<span style="--space: 24px">24</span>
<span style="--space: 32px">32</span>
<span style="--space: 48px">48</span>
<span style="--space: 64px">64</span>
</div>
</div>
<div id="tokens" class="subsection">
<h3>Tokens</h3>
<div class="token-grid">
<code>color.primary = #4B0F24</code>
<code>color.text = #161616</code>
<code>spacing.md = 16px</code>
<code>radius.sm = 8px</code>
<code>shadow.soft = 0 12px 32px rgba(22,22,22,.08)</code>
</div>
</div>
</section>
<section id="components" class="section">
<div class="section-heading">
<p class="eyebrow">02 Components</p>
<h2>Компоненты</h2>
</div>
<div class="subsection">
<h3>Buttons</h3>
<div class="component-row">
<button class="button button--primary">Button / Primary / Default</button>
<button class="button button--primary is-hover">Button / Primary / Hover</button>
<button class="button button--secondary">Button / Secondary / Default</button>
<button class="button button--ghost">Button / Ghost / Default</button>
</div>
</div>
<div class="subsection">
<h3>Product Card</h3>
<div class="product-grid product-grid--3">
<article class="product-card">
<div class="product-media product-media--amber"><span class="bottle"></span></div>
<div class="product-meta">
<span class="muted-caps">Tuscany</span>
<h3>Brunello di Montalcino</h3>
<p>Italy · Red dry · 2018 · 0.75 L</p>
</div>
<div class="product-footer">
<strong>4 240 ₽</strong>
<button class="button button--primary button--sm">Подробнее</button>
</div>
</article>
<article class="product-card product-card--hover">
<div class="product-media product-media--wine"><span class="bottle"></span></div>
<div class="product-meta">
<span class="muted-caps">Rioja</span>
<h3>Reserva Seleccion Especial</h3>
<p>Spain · Red dry · 2017 · 0.75 L</p>
</div>
<div class="product-footer">
<strong>2 980 ₽</strong>
<button class="button button--primary button--sm">Подробнее</button>
</div>
</article>
<article class="product-card product-card--compact">
<div class="product-media product-media--green"><span class="bottle"></span></div>
<div class="product-meta">
<span class="muted-caps">Mosel</span>
<h3>Riesling Kabinett</h3>
<p>Germany · White · 2021</p>
</div>
<div class="product-footer">
<strong>2 150 ₽</strong>
</div>
</article>
</div>
</div>
<div class="subsection">
<h3>Navigation</h3>
<div class="header-demo">
<a class="brand brand--compact" href="#"><span class="brand__mark">DP</span><strong>Trade</strong></a>
<nav>
<a href="#">Каталог</a>
<a href="#">Регионы</a>
<a href="#">Производители</a>
<a href="#">B2B</a>
</nav>
<button class="button button--secondary button--sm">Запросить прайс</button>
</div>
</div>
<div class="subsection component-columns">
<div>
<h3>Filters</h3>
<div class="control-stack">
<label class="checkbox"><input type="checkbox" /> France</label>
<label class="checkbox"><input type="checkbox" checked /> Italy</label>
<div class="chip-row">
<button class="chip">Red</button>
<button class="chip chip--active">White</button>
<button class="chip">Sparkling</button>
</div>
<label class="range">
<span>Price range</span>
<input type="range" min="0" max="100" value="64" />
</label>
</div>
</div>
<div>
<h3>Tags & Inputs</h3>
<div class="control-stack">
<div class="chip-row">
<span class="tag">Tag / Default</span>
<span class="tag tag--filled">Tag / Filled</span>
<span class="tag tag--outline">Tag / Outline</span>
</div>
<input class="input" placeholder="Input / Default" />
<input class="input input--focus" value="Input / Focus" />
<input class="input input--error" value="Input / Error" />
<select class="input">
<option>Select / Default</option>
</select>
</div>
</div>
</div>
<div class="subsection">
<h3>Tables / B2B</h3>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>SKU</th>
<th>Name</th>
<th>Region</th>
<th>Stock</th>
<th>Trade price</th>
</tr>
</thead>
<tbody>
<tr>
<td>DP-1042</td>
<td>Chateau Laroque Grand Cru</td>
<td>Bordeaux</td>
<td>48 cases</td>
<td>3 890 ₽</td>
</tr>
<tr>
<td>DP-1188</td>
<td>Riesling Kabinett</td>
<td>Mosel</td>
<td>32 cases</td>
<td>2 150 ₽</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section id="patterns" class="section">
<div class="section-heading">
<p class="eyebrow">03 Patterns</p>
<h2>Паттерны</h2>
</div>
<div class="catalog-pattern">
<aside class="filters-panel">
<h3>Filters / Sidebar</h3>
<label class="checkbox"><input type="checkbox" checked /> Bordeaux</label>
<label class="checkbox"><input type="checkbox" /> Tuscany</label>
<label class="checkbox"><input type="checkbox" /> Rioja</label>
<button class="button button--primary">Применить</button>
</aside>
<div>
<h3>Pattern / Product Grid / 3 col</h3>
<div class="product-grid product-grid--3">
<article class="mini-card">Bordeaux Grand Cru</article>
<article class="mini-card">Tuscany Reserve</article>
<article class="mini-card">Mosel Riesling</article>
</div>
</div>
</div>
</section>
<section id="templates" class="section">
<div class="section-heading">
<p class="eyebrow">04 Templates</p>
<h2>Шаблоны</h2>
</div>
<div class="template-grid">
<article class="template-card">
<span>Template / Home</span>
<strong>Hero + regions + recommendations</strong>
</article>
<article class="template-card">
<span>Template / Catalog</span>
<strong>Filters + product grid + table mode</strong>
</article>
<article class="template-card">
<span>Template / Product Page</span>
<strong>Gallery + meta + CTA + availability</strong>
</article>
<article class="template-card">
<span>Template / Producer Page</span>
<strong>Story + region + producer catalog</strong>
</article>
</div>
</section>
<section id="screens" class="section section--last">
<div class="section-heading">
<p class="eyebrow">05 Screens</p>
<h2>Реальные экраны</h2>
</div>
<div class="screen-preview">
<div class="screen-preview__bar"></div>
<div class="screen-preview__hero">
<p class="eyebrow">Screen / Home / v1</p>
<h3>Curated trade catalog</h3>
<button class="button button--primary">Смотреть каталог</button>
</div>
<div class="screen-preview__content">
<span></span><span></span><span></span>
</div>
</div>
</section>
</main>
</body>
</html>