diff --git a/.claude/launch.json b/.claude/launch.json
new file mode 100644
index 0000000..068cf37
--- /dev/null
+++ b/.claude/launch.json
@@ -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
+ }
+ ]
+}
diff --git a/.eleventy.js b/.eleventy.js
new file mode 100644
index 0000000..820157b
--- /dev/null
+++ b/.eleventy.js
@@ -0,0 +1,15 @@
+export default function (eleventyConfig) {
+ eleventyConfig.addPassthroughCopy("src/css");
+ eleventyConfig.addPassthroughCopy("src/assets");
+ eleventyConfig.addPassthroughCopy("src/js");
+
+ return {
+ dir: {
+ input: "src",
+ output: "_site",
+ includes: "_includes",
+ },
+ templateFormats: ["njk", "html"],
+ htmlTemplateEngine: "njk",
+ };
+}
diff --git a/.gitignore b/.gitignore
index 6a73c02..5281e8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.DS_Store
node_modules/
dist/
+_site/
.env
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..818ebbc
--- /dev/null
+++ b/CLAUDE.md
@@ -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:
, fonts, CSS link,
+ 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 paths in `base.njk` are **absolute** (`/css/site.css`), which requires the 11ty dev server — they will not work when opening `_site/` files directly in a browser 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 |
diff --git a/docs/elementor-token-handoff.md b/docs/elementor-token-handoff.md
new file mode 100644
index 0000000..dc8d7ed
--- /dev/null
+++ b/docs/elementor-token-handoff.md
@@ -0,0 +1,666 @@
+# Перенос UI-kit токенов и элементов в Elementor
+
+Документ описывает безопасный перенос дизайн-токенов и базовых элементов DP Trade UI-kit в Elementor WordPress. Главная цель: внедрить новую дизайн-систему постепенно, не ломая текущие страницы и глобальные настройки сайта.
+
+## 1. Базовый принцип переноса
+
+Не заменяйте существующие настройки Elementor сразу. Сначала добавьте новые токены рядом со старыми, соберите тестовую страницу, проверьте визуально, затем постепенно переводите реальные шаблоны и страницы на новые значения.
+
+Рекомендуемый порядок:
+
+1. Сделать backup сайта и базы данных.
+2. Работать на staging-копии или тестовой странице.
+3. Добавить новые Global Colors.
+4. Добавить новые Global Fonts.
+5. Настроить базовые элементы: кнопки, поля, карточки, теги.
+6. Создать страницу `UI Kit Preview` в WordPress.
+7. Проверить desktop, tablet, mobile.
+8. Только после проверки применять к Header, Footer, каталогу и страницам.
+
+## 2. Источники токенов в проекте
+
+Основные файлы:
+
+- `css/tokens.css` — базовые дизайн-токены сайта.
+- `css/site.css` — стили реальных страниц, header, footer, карточек, каталога, форм.
+- `css/ui-kit.css` — витрина UI-kit, состояния и примеры компонентов.
+- `ui-kit.html` — живая HTML-витрина дизайн-системы.
+
+В Elementor переносите не весь CSS целиком, а роли и значения: цвета, шрифты, отступы, радиусы, тени и повторяемые компоненты.
+
+## 3. Карта цветов для Elementor Global Colors
+
+Перейдите в:
+
+`Elementor -> Site Settings -> Global Colors`
+
+Добавьте новые цвета. Старые цвета пока не удаляйте.
+
+| Elementor name | CSS token | Value | Role |
+|---|---:|---:|---|
+| DP Wine 100 | `--color-primary-wine-100` | `#4b0f24` | Основной брендовый цвет, primary buttons, hover menu, акценты |
+| DP Wine 80 | `--color-primary-wine-80` | `#6d1c36` | Hover для primary, вторичный винный оттенок |
+| DP Black | `--color-neutral-black` | `#161616` | Основной текст |
+| DP Gray 700 | `--color-neutral-gray-700` | `#30343a` | Навигация, плотный вторичный текст |
+| DP Gray 600 | `--color-neutral-gray-600` | `#66605f` | Описания, muted text, подписи |
+| DP Gray 300 | `--color-neutral-gray-300` | `#d9dee6` | Бордеры, разделители |
+| DP Background | `--color-background-base` | `#f4f6f9` | Основной фон страниц |
+| DP Surface | `--color-surface` | `#ffffff` | Карточки, поля, панели |
+| DP Gold | `--color-accent-gold` | `#b9965b` | Eyebrow, статусы, премиальные акценты |
+| DP Blue | `--color-accent-blue` | `#1f3476` | Логотип, телефон, информационные акценты |
+| DP Error | `--color-error` | `#a33a2f` | Ошибки форм |
+
+Важно: если в текущем Elementor уже есть цвета `Primary`, `Secondary`, `Text`, `Accent`, не заменяйте их сразу. Добавьте цвета с префиксом `DP`, затем перепривязывайте элементы вручную.
+
+## 4. Карта шрифтов для Elementor Global Fonts
+
+Перейдите в:
+
+`Elementor -> Site Settings -> Global Fonts`
+
+Подключение шрифтов:
+
+- Headings: `Montserrat`
+- Body: `Inter`
+- Classic heading, если понадобится для редакционных блоков: `Playfair Display`
+
+| Elementor style | Font family | Weight | Size desktop | Line height | Transform |
+|---|---|---:|---:|---:|---|
+| DP H1 | `Montserrat` | `800` | `48-72px` | `1.1` | Uppercase |
+| DP H2 | `Montserrat` | `800` | `36-40px` | `1.1-1.22` | Uppercase |
+| DP H3 | `Montserrat` | `800` | `24-28px` | `1.15-1.25` | Uppercase |
+| DP Body | `Inter` | `400` | `16px` | `1.5` | None |
+| DP Body Large | `Inter` | `400` | `18px` | `28px` | None |
+| DP Caption | `Inter` | `600-700` | `12-13px` | `16px` | Optional uppercase |
+| DP Button | `Inter` | `700` | `14-16px` | `1.2` | None |
+| DP Nav | `Inter` | `800` | `12px` | `1.2` | Uppercase |
+
+Рекомендация по responsive:
+
+| Style | Tablet | Mobile |
+|---|---:|---:|
+| DP H1 | `40-48px` | `34-40px` |
+| DP H2 | `32-36px` | `28-32px` |
+| DP H3 | `22-24px` | `20-22px` |
+| DP Body | `16px` | `16px` |
+| DP Button | `14-16px` | `14px` |
+
+Не используйте viewport-based font size в Elementor. Лучше задавать отдельные значения для desktop, tablet и mobile.
+
+## 5. Spacing, radius, shadows
+
+В Elementor нет полноценной системы design tokens для spacing, поэтому переносите значения как правила для секций, контейнеров и классов.
+
+### Spacing scale
+
+| Token | Value | Где использовать |
+|---|---:|---|
+| `--spacing-4` | `4px` | Мелкие зазоры, иконки |
+| `--spacing-8` | `8px` | Gap внутри кнопок, compact controls |
+| `--spacing-16` | `16px` | Карточки, поля, grid gap |
+| `--spacing-24` | `24px` | Padding карточек, блоки форм |
+| `--spacing-32` | `32px` | Gap между колонками |
+| `--spacing-48` | `48px` | Крупные отступы секций |
+| `--spacing-64` | `64px` | Hero, большие секции |
+
+### Layout
+
+| Token | Value | Elementor setting |
+|---|---:|---|
+| `--container` | `1240px` | Site Settings -> Layout -> Content Width |
+| Section desktop padding | `72px 24-72px` | Section/container padding |
+| Section mobile padding | `48px 20px` | Responsive padding |
+| Container side gap | `20px` each side | Container width: `min(100% - 40px, 1240px)` в CSS |
+
+### Radius
+
+| Token | Value | Где использовать |
+|---|---:|---|
+| `--radius-sm` | `8px` | Кнопки, поля, карточки, теги |
+| `--radius-md` | `12px` | Крупные панели, preview blocks |
+| `--radius-lg` | `24px` | Редкие крупные акцентные блоки |
+
+### Shadows
+
+Elementor поддерживает box-shadow в Advanced/Style, но удобнее завести CSS-классы.
+
+| Token | Value | Где использовать |
+|---|---|---|
+| `--shadow-soft` | `0 12px 32px rgba(22, 22, 22, 0.08)` | Обычные карточки, формы, footer panel |
+| `--shadow-lift` | `0 20px 52px rgba(75, 15, 36, 0.14)` | Hover карточек, mega menu, primary hover |
+| Header shadow | `0 10px 28px rgba(22, 22, 22, 0.05)` | Sticky header |
+| Focus shadow | `0 0 0 4px rgba(75, 15, 36, 0.08)` | Search/input focus |
+
+## 6. Безопасный CSS-слой для Elementor
+
+Добавляйте CSS не через глобальные теги `body`, `h1`, `button`, `input`, а через классы с префиксом `dp-`.
+
+Где добавлять:
+
+1. Сначала на тестовой странице: `Page Settings -> Advanced -> Custom CSS`.
+2. После проверки: `Elementor -> Site Settings -> Custom CSS`.
+3. Если есть child theme, финальную версию можно перенести в `style.css`.
+
+Базовый слой:
+
+```css
+:root {
+ --dp-wine-100: #4b0f24;
+ --dp-wine-80: #6d1c36;
+ --dp-black: #161616;
+ --dp-gray-700: #30343a;
+ --dp-gray-600: #66605f;
+ --dp-gray-300: #d9dee6;
+ --dp-bg: #f4f6f9;
+ --dp-surface: #ffffff;
+ --dp-gold: #b9965b;
+ --dp-blue: #1f3476;
+ --dp-error: #a33a2f;
+ --dp-radius-sm: 8px;
+ --dp-shadow-soft: 0 12px 32px rgba(22, 22, 22, 0.08);
+ --dp-shadow-lift: 0 20px 52px rgba(75, 15, 36, 0.14);
+}
+
+.dp-section {
+ padding-top: 72px;
+ padding-bottom: 72px;
+}
+
+.dp-surface {
+ background: var(--dp-surface);
+ border: 1px solid rgba(102, 96, 95, 0.16);
+ border-radius: var(--dp-radius-sm);
+ box-shadow: var(--dp-shadow-soft);
+}
+
+.dp-eyebrow {
+ color: var(--dp-gold);
+ font-family: Inter, Arial, sans-serif;
+ font-size: 12px;
+ line-height: 16px;
+ font-weight: 700;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+```
+
+Mobile override:
+
+```css
+@media (max-width: 767px) {
+ .dp-section {
+ padding-top: 48px;
+ padding-bottom: 48px;
+ }
+}
+```
+
+## 7. Перенос кнопок
+
+В Elementor настройте:
+
+`Site Settings -> Buttons`
+
+Базовая кнопка:
+
+| Property | Value |
+|---|---:|
+| Min height | `48px` |
+| Padding | `12px 22px` |
+| Border radius | `8px` |
+| Font | `Inter`, `700` |
+| Transition | `0.2s` |
+
+Primary:
+
+| State | Text | Background | Border | Shadow |
+|---|---:|---:|---:|---|
+| Default | `#ffffff` | `#4b0f24` | transparent | `0 10px 22px rgba(75, 15, 36, 0.16)` |
+| Hover | `#ffffff` | `#6d1c36` | transparent | `0 20px 52px rgba(75, 15, 36, 0.14)` |
+
+Secondary:
+
+| State | Text | Background | Border |
+|---|---:|---:|---:|
+| Default | `#4b0f24` | `rgba(255,255,255,0.55)` | `rgba(75,15,36,0.24)` |
+| Hover | `#4b0f24` | `rgba(75,15,36,0.06)` | `rgba(75,15,36,0.36)` |
+
+CSS-классы:
+
+```css
+.dp-btn-primary .elementor-button {
+ min-height: 48px;
+ padding: 12px 22px;
+ border-radius: 8px;
+ background: var(--dp-wine-100);
+ color: #ffffff;
+ font-weight: 700;
+ box-shadow: 0 10px 22px rgba(75, 15, 36, 0.16);
+ transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
+}
+
+.dp-btn-primary .elementor-button:hover {
+ background: var(--dp-wine-80);
+ box-shadow: var(--dp-shadow-lift);
+ transform: translateY(-1px);
+}
+
+.dp-btn-secondary .elementor-button {
+ min-height: 48px;
+ padding: 12px 22px;
+ border: 1px solid rgba(75, 15, 36, 0.24);
+ border-radius: 8px;
+ background: rgba(255, 255, 255, 0.55);
+ color: var(--dp-wine-100);
+ font-weight: 700;
+}
+
+.dp-btn-sm .elementor-button {
+ min-height: 38px;
+ padding: 8px 14px;
+ font-size: 14px;
+}
+```
+
+В Elementor у виджета Button добавляйте классы:
+
+- `dp-btn-primary`
+- `dp-btn-secondary`
+- `dp-btn-sm`
+
+## 8. Перенос форм и input fields
+
+Для Elementor Forms:
+
+`Site Settings -> Form Fields`
+
+| Property | Value |
+|---|---:|
+| Background | `#ffffff` |
+| Text | `#161616` |
+| Placeholder | `#66605f` |
+| Border | `1px solid rgba(102, 96, 95, 0.24)` |
+| Border radius | `8px` |
+| Padding | `12-14px` |
+| Focus border | `#4b0f24` |
+| Focus shadow | `0 0 0 3-4px rgba(75, 15, 36, 0.08-0.10)` |
+| Error color | `#a33a2f` |
+
+CSS-класс для формы:
+
+```css
+.dp-form .elementor-field {
+ border: 1px solid rgba(102, 96, 95, 0.24);
+ border-radius: 8px;
+ background: #ffffff;
+ color: var(--dp-black);
+ font-family: Inter, Arial, sans-serif;
+ font-size: 14px;
+}
+
+.dp-form .elementor-field:focus {
+ border-color: var(--dp-wine-100);
+ box-shadow: 0 0 0 4px rgba(75, 15, 36, 0.08);
+}
+
+.dp-form .elementor-field-label {
+ color: var(--dp-gray-700);
+ font-size: 13px;
+ font-weight: 700;
+}
+
+.dp-form .elementor-message-danger {
+ color: var(--dp-error);
+}
+```
+
+Проверить после переноса:
+
+- default state;
+- focus state;
+- required fields;
+- error message;
+- textarea;
+- disabled field;
+- submit button;
+- mobile keyboard behavior.
+
+## 9. Карточки товаров и контентные карточки
+
+Карточки UI-kit используют:
+
+- белую поверхность;
+- radius `8px`;
+- border `rgba(102, 96, 95, 0.16)`;
+- shadow soft;
+- hover lift;
+- внутренний padding `16-24px`;
+- muted text `#66605f`;
+- uppercase heading на `Montserrat 800`.
+
+CSS-класс:
+
+```css
+.dp-card {
+ min-width: 0;
+ border: 1px solid rgba(102, 96, 95, 0.16);
+ border-radius: 8px;
+ background: #ffffff;
+ box-shadow: var(--dp-shadow-soft);
+ overflow: hidden;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.dp-card:hover {
+ transform: translateY(-3px);
+ box-shadow: var(--dp-shadow-lift);
+}
+
+.dp-card-title {
+ color: var(--dp-black);
+ font-family: Montserrat, Inter, Arial, sans-serif;
+ font-size: 24px;
+ line-height: 1.15;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.dp-card-text {
+ color: var(--dp-gray-600);
+ font-size: 14px;
+ line-height: 1.45;
+}
+```
+
+Для Elementor:
+
+1. Создайте контейнер карточки.
+2. В Advanced -> CSS Classes добавьте `dp-card`.
+3. Заголовку добавьте `dp-card-title`.
+4. Описанию добавьте `dp-card-text`.
+5. Кнопке добавьте `dp-btn-primary` или `dp-btn-secondary`.
+
+## 10. Теги, chips, статусы
+
+Используются для стран, категорий, фильтров, статусов.
+
+```css
+.dp-tag,
+.dp-chip {
+ display: inline-flex;
+ align-items: center;
+ min-height: 30px;
+ padding: 6px 10px;
+ border-radius: 8px;
+ font-size: 12px;
+ font-weight: 800;
+ line-height: 1;
+ text-transform: uppercase;
+}
+
+.dp-tag-filled,
+.dp-chip-active {
+ background: var(--dp-wine-100);
+ color: #ffffff;
+}
+
+.dp-tag-outline {
+ border: 1px solid rgba(75, 15, 36, 0.24);
+ color: var(--dp-wine-100);
+ background: transparent;
+}
+
+.dp-tag-gold {
+ background: rgba(185, 150, 91, 0.18);
+ color: #7c5f26;
+}
+```
+
+В Elementor это можно делать через:
+
+- Heading widget с HTML tag `span`;
+- Text Editor;
+- Button widget без ссылки;
+- Loop item meta fields, если это каталог.
+
+## 11. Header и навигация
+
+Header в UI-kit использует:
+
+- sticky position;
+- background `rgba(248, 250, 252, 0.94)`;
+- border-bottom `rgba(102, 96, 95, 0.18)`;
+- shadow `0 10px 28px rgba(22, 22, 22, 0.05)`;
+- blur `backdrop-filter: blur(18px)`;
+- nav font `Inter 800 12px uppercase`;
+- active/hover color `#4b0f24`.
+
+Рекомендация:
+
+1. Не меняйте текущий Header template сразу.
+2. Дублируйте шаблон Header в Elementor.
+3. Назовите копию `Header DP UI Kit Draft`.
+4. Примените новые стили на копии.
+5. Проверьте меню, dropdown, search, phone, cart/favorites icons.
+6. Только после проверки назначайте новый шаблон на сайт.
+
+CSS-класс для контейнера:
+
+```css
+.dp-header {
+ background: rgba(248, 250, 252, 0.94);
+ border-bottom: 1px solid rgba(102, 96, 95, 0.18);
+ box-shadow: 0 10px 28px rgba(22, 22, 22, 0.05);
+ backdrop-filter: blur(18px);
+}
+
+.dp-nav a,
+.dp-nav .elementor-item {
+ color: var(--dp-gray-700);
+ font-family: Inter, Arial, sans-serif;
+ font-size: 12px;
+ font-weight: 800;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+
+.dp-nav a:hover,
+.dp-nav .elementor-item:hover,
+.dp-nav .elementor-item-active {
+ color: var(--dp-wine-100);
+}
+```
+
+## 12. Footer
+
+Footer использует карточную панель:
+
+- surface `#ffffff`;
+- radius `8px`;
+- shadow soft;
+- структурированную сетку ссылок;
+- muted legal text;
+- акцентные ссылки на hover.
+
+Безопасный перенос:
+
+1. Дублируйте текущий Footer template.
+2. Добавьте классы `dp-footer`, `dp-surface`, `dp-nav`.
+3. Проверьте desktop/mobile сетку.
+4. Не удаляйте старый footer до полной проверки.
+
+## 13. Каталог и product cards
+
+Для каталога важны следующие элементы:
+
+- toolbar;
+- sort select;
+- filters;
+- grid/list cards;
+- compact cards;
+- price block;
+- tags;
+- CTA button;
+- hover state.
+
+Порядок переноса:
+
+1. Сначала перенесите визуальный стиль карточки товара.
+2. Потом фильтры и chips.
+3. Потом toolbar/sort.
+4. Потом list/compact variants.
+5. Последним этапом подключайте hover и lift effects.
+
+Минимальный набор CSS-классов:
+
+```txt
+dp-card
+dp-product-card
+dp-card-title
+dp-card-text
+dp-tag
+dp-tag-filled
+dp-btn-primary
+dp-btn-sm
+```
+
+## 14. Страница UI Kit Preview в WordPress
+
+Создайте отдельную страницу:
+
+`UI Kit Preview`
+
+Разместите на ней:
+
+1. Цветовые swatches.
+2. H1, H2, H3, body, caption.
+3. Primary, secondary, small buttons.
+4. Form fields: default, focus, error.
+5. Product card.
+6. Tags/chips.
+7. Header preview.
+8. Footer preview.
+9. Catalog toolbar preview.
+10. Mobile preview section.
+
+Страница нужна как контрольная витрина. Любое изменение токенов сначала проверяйте на ней.
+
+## 15. Что нельзя делать при переносе
+
+Не добавляйте глобально такие правила без полной проверки:
+
+```css
+* {
+ margin: 0;
+ padding: 0;
+}
+
+button {
+ all: unset;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+h1,
+h2,
+h3 {
+ margin: 0;
+}
+```
+
+Они могут сломать тему, плагины, WooCommerce, формы, меню и старые страницы.
+
+Также не рекомендуется:
+
+- удалять старые Elementor Global Colors;
+- массово заменять цвета по всему сайту;
+- менять breakpoints без полного responsive QA;
+- вставлять весь `site.css` в Elementor;
+- переносить demo-стили UI-kit sidebar;
+- менять Header/Footer на production без дубликата и предпросмотра.
+
+## 16. QA checklist перед публикацией
+
+Проверьте:
+
+- Главная страница.
+- Каталог.
+- Карточка товара.
+- Страница контактов.
+- Страница статьи/новости.
+- Header desktop.
+- Header mobile.
+- Mega menu/dropdown.
+- Footer desktop.
+- Footer mobile.
+- Все формы.
+- Search.
+- Cart/favorites/account icons, если есть.
+- 404 page.
+- WooCommerce cart/checkout/account, если сайт использует WooCommerce.
+
+Для каждого экрана:
+
+- нет горизонтального скролла;
+- текст не обрезается;
+- кнопки не ломаются;
+- hover/focus состояния видны;
+- карточки не прыгают по высоте;
+- изображения не растягиваются;
+- меню открывается и закрывается корректно;
+- формы отправляются;
+- ошибки форм читаемы;
+- контраст текста достаточный.
+
+## 17. Публикация на production
+
+Финальный порядок:
+
+1. Сделать свежий backup production.
+2. Экспортировать Elementor templates.
+3. Перенести Global Colors.
+4. Перенести Global Fonts.
+5. Добавить проверенный CSS-слой.
+6. Импортировать или обновить шаблоны.
+7. Назначить Header/Footer только после проверки preview.
+8. Elementor -> Tools -> Regenerate CSS & Data.
+9. Очистить кэш плагина оптимизации.
+10. Очистить server/CDN cache, если есть.
+11. Проверить сайт в incognito.
+
+## 18. План отката
+
+Перед публикацией должны быть готовы:
+
+- backup production;
+- экспорт старых Elementor templates;
+- список измененных Global Colors/Fonts;
+- копия добавленного Custom CSS;
+- скриншоты ключевых страниц до переноса.
+
+Если что-то сломалось:
+
+1. Отключите новый Custom CSS.
+2. Верните старый Header/Footer template.
+3. Regenerate CSS & Data.
+4. Очистите кэш.
+5. Проверьте сайт.
+6. Если проблема осталась, восстановите backup.
+
+## 19. Минимальный набор для первого этапа
+
+Для первого безопасного внедрения достаточно перенести:
+
+1. Global Colors с префиксом `DP`.
+2. Global Fonts `DP H1`, `DP H2`, `DP H3`, `DP Body`, `DP Button`.
+3. CSS-переменные `--dp-*`.
+4. Классы кнопок `dp-btn-primary`, `dp-btn-secondary`, `dp-btn-sm`.
+5. Класс карточки `dp-card`.
+6. Класс формы `dp-form`.
+7. Классы тегов `dp-tag`, `dp-tag-filled`, `dp-tag-outline`.
+8. Тестовую страницу `UI Kit Preview`.
+
+После этого можно спокойно двигаться к Header, Footer, каталогу и product templates.
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..1715177
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1652 @@
+{
+ "name": "dp-trade-ui-kit",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "dp-trade-ui-kit",
+ "version": "1.0.0",
+ "devDependencies": {
+ "@11ty/eleventy": "^3.0.0"
+ }
+ },
+ "node_modules/@11ty/dependency-tree": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-4.0.2.tgz",
+ "integrity": "sha512-RTF6VTZHatYf7fSZBUN3RKwiUeJh5dhWV61gDPrHhQF2/gzruAkYz8yXuvGLx3w3ZBKreGrR+MfYpSVkdbdbLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@11ty/eleventy-utils": "^2.0.1"
+ }
+ },
+ "node_modules/@11ty/dependency-tree-esm": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@11ty/dependency-tree-esm/-/dependency-tree-esm-2.0.4.tgz",
+ "integrity": "sha512-MYKC0Ac77ILr1HnRJalzKDlb9Z8To3kXQCltx299pUXXUFtJ1RIONtULlknknqW8cLe19DLVgmxVCtjEFm7h0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@11ty/eleventy-utils": "^2.0.7",
+ "acorn": "^8.15.0",
+ "dependency-graph": "^1.0.0",
+ "normalize-path": "^3.0.0"
+ }
+ },
+ "node_modules/@11ty/eleventy": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.1.5.tgz",
+ "integrity": "sha512-hZ0g6MwZyRxCqXsPm82gIM304LraKbUz3ZmezOSjsqxttZG6cHTib3Qq8QkESJoKwnr+yX1eyfOkPC5/mEgZnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@11ty/dependency-tree": "^4.0.2",
+ "@11ty/dependency-tree-esm": "^2.0.4",
+ "@11ty/eleventy-dev-server": "^2.0.8",
+ "@11ty/eleventy-plugin-bundle": "^3.0.7",
+ "@11ty/eleventy-utils": "^2.0.7",
+ "@11ty/lodash-custom": "^4.17.21",
+ "@11ty/posthtml-urls": "^1.0.2",
+ "@11ty/recursive-copy": "^4.0.4",
+ "@sindresorhus/slugify": "^2.2.1",
+ "bcp-47-normalize": "^2.3.0",
+ "chokidar": "^3.6.0",
+ "debug": "^4.4.3",
+ "dependency-graph": "^1.0.0",
+ "entities": "^6.0.1",
+ "filesize": "^10.1.6",
+ "gray-matter": "^4.0.3",
+ "iso-639-1": "^3.1.5",
+ "js-yaml": "^4.1.1",
+ "kleur": "^4.1.5",
+ "liquidjs": "^10.25.0",
+ "luxon": "^3.7.2",
+ "markdown-it": "^14.1.1",
+ "minimist": "^1.2.8",
+ "moo": "0.5.2",
+ "node-retrieve-globals": "^6.0.1",
+ "nunjucks": "^3.2.4",
+ "picomatch": "^4.0.3",
+ "please-upgrade-node": "^3.2.0",
+ "posthtml": "^0.16.7",
+ "posthtml-match-helper": "^2.0.3",
+ "semver": "^7.7.4",
+ "slugify": "^1.6.8",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "eleventy": "cmd.cjs"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/11ty"
+ }
+ },
+ "node_modules/@11ty/eleventy-dev-server": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-2.0.8.tgz",
+ "integrity": "sha512-15oC5M1DQlCaOMUq4limKRYmWiGecDaGwryr7fTE/oM9Ix8siqMvWi+I8VjsfrGr+iViDvWcH/TVI6D12d93mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@11ty/eleventy-utils": "^2.0.1",
+ "chokidar": "^3.6.0",
+ "debug": "^4.4.0",
+ "finalhandler": "^1.3.1",
+ "mime": "^3.0.0",
+ "minimist": "^1.2.8",
+ "morphdom": "^2.7.4",
+ "please-upgrade-node": "^3.2.0",
+ "send": "^1.1.0",
+ "ssri": "^11.0.0",
+ "urlpattern-polyfill": "^10.0.0",
+ "ws": "^8.18.1"
+ },
+ "bin": {
+ "eleventy-dev-server": "cmd.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/11ty"
+ }
+ },
+ "node_modules/@11ty/eleventy-plugin-bundle": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.7.tgz",
+ "integrity": "sha512-QK1tRFBhQdZASnYU8GMzpTdsMMFLVAkuU0gVVILqNyp09xJJZb81kAS3AFrNrwBCsgLxTdWHJ8N64+OTTsoKkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@11ty/eleventy-utils": "^2.0.2",
+ "debug": "^4.4.0",
+ "posthtml-match-helper": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/11ty"
+ }
+ },
+ "node_modules/@11ty/eleventy-utils": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-2.0.7.tgz",
+ "integrity": "sha512-6QE+duqSQ0GY9rENXYb4iPR4AYGdrFpqnmi59tFp9VrleOl0QSh8VlBr2yd6dlhkdtj7904poZW5PvGr9cMiJQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/11ty"
+ }
+ },
+ "node_modules/@11ty/lodash-custom": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/@11ty/lodash-custom/-/lodash-custom-4.17.21.tgz",
+ "integrity": "sha512-Mqt6im1xpb1Ykn3nbcCovWXK3ggywRJa+IXIdoz4wIIK+cvozADH63lexcuPpGS/gJ6/m2JxyyXDyupkMr5DHw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/11ty"
+ }
+ },
+ "node_modules/@11ty/posthtml-urls": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@11ty/posthtml-urls/-/posthtml-urls-1.0.3.tgz",
+ "integrity": "sha512-1YvhnkaNlFnnJic1rBMWmTC2adbuy+JQiBfl1Hecr1Wjjik1pQZmGyk/eC9zKX/FQv52s2Nht1Gi/UwhYqrBeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "evaluate-value": "^2.0.0",
+ "http-equiv-refresh": "^2.0.1",
+ "list-to-array": "^1.1.0",
+ "parse-srcset": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@11ty/recursive-copy": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.4.tgz",
+ "integrity": "sha512-oI7m8pa7/IAU/3lqRU9vjBbs20iKFo7x+1K9kT3aVira6scc1X9MjBdgLCHzLJeJ7iB6wydioA+kr9/qPnvmlQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "errno": "^1.0.0",
+ "junk": "^3.1.0",
+ "minimatch": "^3.1.5",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sindresorhus/slugify": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz",
+ "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/transliterate": "^1.0.0",
+ "escape-string-regexp": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@sindresorhus/transliterate": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz",
+ "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/a-sync-waterfall": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
+ "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/acorn": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.5",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
+ "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/anymatch/node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bcp-47": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz",
+ "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/bcp-47-match": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz",
+ "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/bcp-47-normalize": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz",
+ "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bcp-47": "^2.0.0",
+ "bcp-47-match": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
+ "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/dependency-graph": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz",
+ "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/dom-serializer/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/errno": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-1.0.0.tgz",
+ "integrity": "sha512-3zV5mFS1E8/1bPxt/B0xxzI1snsg3uSCIh6Zo1qKg6iMw93hzPANk9oBFzSFBFrwuVoQuE3rLoouAUfwOAj1wQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prr": "~1.0.1"
+ },
+ "bin": {
+ "errno": "cli.js"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/esm-import-transformer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.5.tgz",
+ "integrity": "sha512-1GKLvfuMnnpI75l8c6sHoz0L3Z872xL5akGuBudgqTDPv4Vy6f2Ec7jEMKTxlqWl/3kSvNbHELeimJtnqgYniw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.15.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/evaluate-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/evaluate-value/-/evaluate-value-2.0.0.tgz",
+ "integrity": "sha512-VonfiuDJc0z4sOO7W0Pd130VLsXN6vmBWZlrog1mCb/o7o/Nl5Lr25+Kj/nkCCAhG+zqeeGjxhkK9oHpkgTHhQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/filesize": {
+ "version": "10.1.6",
+ "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz",
+ "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 10.4.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
+ "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "~2.0.2",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/gray-matter": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
+ "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-yaml": "^3.13.1",
+ "kind-of": "^6.0.2",
+ "section-matter": "^1.0.0",
+ "strip-bom-string": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/gray-matter/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/gray-matter/node_modules/js-yaml": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz",
+ "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.2",
+ "domutils": "^2.8.0",
+ "entities": "^3.0.1"
+ }
+ },
+ "node_modules/htmlparser2/node_modules/entities": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
+ "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/http-equiv-refresh": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-equiv-refresh/-/http-equiv-refresh-2.0.1.tgz",
+ "integrity": "sha512-XJpDL/MLkV3dKwLzHwr2dY05dYNfBNlyPu4STQ8WvKCFdc6vC5tPXuq28of663+gHVg03C+16pHHs/+FmmDjcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-json": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz",
+ "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/iso-639-1": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.5.tgz",
+ "integrity": "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/junk": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz",
+ "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
+ "node_modules/liquidjs": {
+ "version": "10.25.6",
+ "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.6.tgz",
+ "integrity": "sha512-h5ki5HS1PiL9/NmLw3iUcTF1jQswKJd8KLEXNrtSf8XHF0v3c5+d+8llz3N9I5IUdc5rsOuVLb9AVnqvqqscPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^10.0.0"
+ },
+ "bin": {
+ "liquid": "bin/liquid.js",
+ "liquidjs": "bin/liquid.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/liquidjs"
+ }
+ },
+ "node_modules/list-to-array": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/list-to-array/-/list-to-array-1.1.0.tgz",
+ "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/luxon": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
+ "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "14.1.1",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz",
+ "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.0",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/markdown-it/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mime": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
+ "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/moo": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
+ "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/morphdom": {
+ "version": "2.7.8",
+ "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz",
+ "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-retrieve-globals": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/node-retrieve-globals/-/node-retrieve-globals-6.0.1.tgz",
+ "integrity": "sha512-j0DeFuZ/Wg3VlklfbxUgZF/mdHMTEiEipBb3q0SpMMbHaV3AVfoUQF8UGxh1s/yjqO0TgRZd4Pi/x2yRqoQ4Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.14.1",
+ "acorn-walk": "^8.3.4",
+ "esm-import-transformer": "^3.0.3"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nunjucks": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz",
+ "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "a-sync-waterfall": "^1.0.0",
+ "asap": "^2.0.3",
+ "commander": "^5.1.0"
+ },
+ "bin": {
+ "nunjucks-precompile": "bin/precompile"
+ },
+ "engines": {
+ "node": ">= 6.9.0"
+ },
+ "peerDependencies": {
+ "chokidar": "^3.3.0"
+ },
+ "peerDependenciesMeta": {
+ "chokidar": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nunjucks/node_modules/commander": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/parse-srcset": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
+ "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/please-upgrade-node": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+ "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver-compare": "^1.0.0"
+ }
+ },
+ "node_modules/posthtml": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.7.tgz",
+ "integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "posthtml-parser": "^0.11.0",
+ "posthtml-render": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/posthtml-match-helper": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/posthtml-match-helper/-/posthtml-match-helper-2.0.3.tgz",
+ "integrity": "sha512-p9oJgTdMF2dyd7WE54QI1LvpBIkNkbSiiECKezNnDVYhGhD1AaOnAkw0Uh0y5TW+OHO8iBdSqnd8Wkpb6iUqmw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "posthtml": "^0.16.6"
+ }
+ },
+ "node_modules/posthtml-parser": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz",
+ "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "htmlparser2": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/posthtml-render": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz",
+ "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-json": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/picomatch": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/section-matter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
+ "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.1",
+ "mime-types": "^3.0.2",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slugify": {
+ "version": "1.6.9",
+ "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz",
+ "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ssri": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz",
+ "integrity": "sha512-aZpUoMN/Jj2MqA4vMCeiKGnc/8SuSyHbGSBdgFbZxP8OJGF/lFkIuElzPxsN0q8TQQ+prw3P4EDfB3TBHHgfXw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/strip-bom-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
+ "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.16",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
+ "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/urlpattern-polyfill": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz",
+ "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ws": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
+ "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..de1f2e5
--- /dev/null
+++ b/package.json
@@ -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"
+}
diff --git a/src/_includes/layouts/base.njk b/src/_includes/layouts/base.njk
new file mode 100644
index 0000000..5c07625
--- /dev/null
+++ b/src/_includes/layouts/base.njk
@@ -0,0 +1,16 @@
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+ {{ content | safe }}
+
+
+
diff --git a/src/_includes/layouts/default.njk b/src/_includes/layouts/default.njk
new file mode 100644
index 0000000..a7267ee
--- /dev/null
+++ b/src/_includes/layouts/default.njk
@@ -0,0 +1,8 @@
+---
+layout: layouts/base
+---
+
+ {% include "partials/header.njk" %}
+ {{ content | safe }}
+ {% include "partials/footer.njk" %}
+
diff --git a/src/_includes/layouts/ui-kit.njk b/src/_includes/layouts/ui-kit.njk
new file mode 100644
index 0000000..60a8207
--- /dev/null
+++ b/src/_includes/layouts/ui-kit.njk
@@ -0,0 +1,5 @@
+---
+layout: layouts/base
+css: ui-kit
+---
+{{ content | safe }}
diff --git a/src/_includes/partials/footer.njk b/src/_includes/partials/footer.njk
new file mode 100644
index 0000000..f993954
--- /dev/null
+++ b/src/_includes/partials/footer.njk
@@ -0,0 +1,73 @@
+
diff --git a/src/_includes/partials/header.njk b/src/_includes/partials/header.njk
new file mode 100644
index 0000000..c72a9cc
--- /dev/null
+++ b/src/_includes/partials/header.njk
@@ -0,0 +1,253 @@
+
diff --git a/src/about.njk b/src/about.njk
new file mode 100644
index 0000000..953242b
--- /dev/null
+++ b/src/about.njk
@@ -0,0 +1,46 @@
+---
+title: "DP Trade — О компании"
+layout: layouts/default
+permalink: /about.html
+bodyClass: compact-type
+---
+
+
+
+
+
О компании
+
DP Trade — территория качественного вина
+
Импорт, каталог, персональная работа с клиентами, собственные склады в регионах и доставка собственным транспортом.
+
+
+ Since 1991
+ Premium wine trade
+ Портфель винных домов для ресторанов, розницы и профессиональных закупок.
+
+
+
+
+
+
+
+ DP Trade развивает профессиональный винный каталог, где регионы, производители, партии и коммерческие условия собраны в едином интерфейсе для быстрых закупочных решений.
+ Главная ценность сервиса — соединить сильный ассортимент с понятной навигацией: от страны и апелласьона до конкретного производителя, винтажа и карточки товара.
+ Как устроен подход
+ Компания делает акцент на удобном каталоге, персональном отношении, собственных складских возможностях и доставке собственным транспортом. Для B2B-клиентов это значит меньше ручных уточнений и быстрее путь от выбора до заказа.
+
+
+
01 Удобный каталог Фильтры по типу, региону, производителю, сорту, году, объему и стилю.
+
02 Персональный подход Быстрая коммуникация с менеджером и подборки под формат клиента.
+
03 Склады в регионах Инфраструктура для регулярных поставок и управления доступностью.
+
04 Собственная доставка Контроль логистики и аккуратная работа с профессиональными заказами.
+
+
+
+
+
+
+
Portfolio
Винные дома и регионы
+
Страница показывает, как может выглядеть корпоративный раздел: спокойная подача, крупные тезисы и блок преимуществ без перегруза.
+
+
+
diff --git a/src/article-guidelines.njk b/src/article-guidelines.njk
new file mode 100644
index 0000000..fc3b260
--- /dev/null
+++ b/src/article-guidelines.njk
@@ -0,0 +1,112 @@
+---
+title: "DP Trade — Article Guidelines"
+layout: layouts/default
+permalink: /article-guidelines.html
+bodyClass: compact-type
+---
+
+
+
+
+
Editorial guidelines
+
Рекомендации по статьям DP Trade
+
Требования к структуре материала, заголовкам, тексту и фотографиям для новостей, историй производителей и экспертных заметок.
+
+
+ Для редакции
+ Article system
+ Единые правила помогают статьям выглядеть как часть продукта, а не как случайные публикации.
+
+
+
+
+
+
+
+ 01
+ Структура статьи
+ Каждый материал должен быстро отвечать на три вопроса: о ком/о чём статья, почему это важно для аудитории DP Trade и какое действие читатель может сделать дальше.
+
+ Заголовок: конкретный, с именем производителя, региона или события.
+ Лид: 1-2 предложения, раскрывает главный повод.
+ Основной текст: 3-5 смысловых блоков с подзаголовками или визуальными паузами.
+ Финал: вывод, рекомендация, ссылка в каталог или повод обратиться к менеджеру.
+
+
+
+ 02
+ Заголовки
+ Заголовок должен быть редакционным, но полезным: не только красивым, а ещё и объясняющим тему.
+
+ Оптимально: 55-90 символов.
+ Использовать имена: Villa Raiano, Gaja, Bordeaux, Fiano.
+ Избегать пустых формул: «уникальная история», «легендарное событие» без факта.
+ Подзаголовки должны вести читателя по смыслу, а не повторять заголовок.
+
+
+
+ 03
+ Текст
+ Стиль: профессиональный, спокойный, без рекламного нажима. Пишем для закупщиков, сомелье, ресторанов и розницы.
+
+ Абзац: 350-650 знаков.
+ Лид: до 280 знаков.
+ Новость: 3 000-5 500 знаков.
+ История производителя: 5 000-8 000 знаков.
+ Цифры, годы, награды и сорта проверять отдельно.
+
+
+
+ 04
+ Фотографии
+ Фотографии должны показывать реальный продукт, место, людей или процесс. Лучше меньше декоративности и больше конкретики.
+
+ Hero: горизонтальное фото от 1600px по ширине.
+ Внутренние фото: от 1200px, без сильной компрессии.
+ Для карточек: предмет или бутылка должны быть читаемы на мобильном.
+ Не использовать тёмные, размытые, случайно обрезанные изображения.
+ Обязательно писать alt: кто/что изображено и где.
+
+
+
+ 05
+ Композиция
+ Для длинной статьи нужны визуальные паузы: крупное фото после лида, цитата или факт-блок в середине и финальный акцент.
+
+ Не ставить подряд больше 4 текстовых абзацев без паузы.
+ Цитаты использовать только если они усиливают материал.
+ Сайдбар может содержать факты: страна, регион, сорт, год, награда.
+ Финальный CTA должен быть связан с каталогом или менеджером.
+
+
+
+ 06
+ SEO и handoff
+ Материал должен быть понятен поиску и разработке: один H1, последовательные H2, корректные alt и прозрачная структура блоков.
+
+ Title: до 60 символов, включает бренд или тему.
+ Description: 140-160 символов.
+ URL: латиница, короткий slug.
+ Изображения называть по смыслу, а не `photo-final-2`.
+ В CMS хранить дату, автора/раздел, теги и связанные товары.
+
+
+
+
+
+
+
+
+
Pre-publish checklist
+
Проверка перед публикацией
+
+
+ Заголовок отражает конкретный повод и не звучит как реклама.
+ В лиде понятна ценность материала для профессиональной аудитории.
+ Все годы, имена, апелласьоны и награды проверены.
+ Есть минимум 2-4 качественные фотографии с alt-текстами.
+ Финал ведёт к каталогу, производителю, товару или контакту с менеджером.
+
+
+
+
diff --git a/src/assets/images/00073820_1.png b/src/assets/images/00073820_1.png
new file mode 100644
index 0000000..9f82d3b
Binary files /dev/null and b/src/assets/images/00073820_1.png differ
diff --git a/src/assets/images/00080768_1.png b/src/assets/images/00080768_1.png
new file mode 100644
index 0000000..0bc9d72
Binary files /dev/null and b/src/assets/images/00080768_1.png differ
diff --git a/src/assets/images/00081538_1.png b/src/assets/images/00081538_1.png
new file mode 100644
index 0000000..24e149f
Binary files /dev/null and b/src/assets/images/00081538_1.png differ
diff --git a/src/assets/images/00081726_1.png b/src/assets/images/00081726_1.png
new file mode 100644
index 0000000..2c866d3
Binary files /dev/null and b/src/assets/images/00081726_1.png differ
diff --git a/src/assets/images/photo_2026-04-06_16-53-23-2.jpg b/src/assets/images/photo_2026-04-06_16-53-23-2.jpg
new file mode 100644
index 0000000..d540b6f
Binary files /dev/null and b/src/assets/images/photo_2026-04-06_16-53-23-2.jpg differ
diff --git a/src/assets/images/photo_2026-04-06_16-53-23.jpg b/src/assets/images/photo_2026-04-06_16-53-23.jpg
new file mode 100644
index 0000000..a474acc
Binary files /dev/null and b/src/assets/images/photo_2026-04-06_16-53-23.jpg differ
diff --git a/src/assets/images/photo_2026-04-06_16-53-24.jpg b/src/assets/images/photo_2026-04-06_16-53-24.jpg
new file mode 100644
index 0000000..c327af5
Binary files /dev/null and b/src/assets/images/photo_2026-04-06_16-53-24.jpg differ
diff --git a/src/assets/images/photo_2026-04-06_16-53-26.jpg b/src/assets/images/photo_2026-04-06_16-53-26.jpg
new file mode 100644
index 0000000..ab03f6b
Binary files /dev/null and b/src/assets/images/photo_2026-04-06_16-53-26.jpg differ
diff --git a/src/bottle-cards.njk b/src/bottle-cards.njk
new file mode 100644
index 0000000..c135734
--- /dev/null
+++ b/src/bottle-cards.njk
@@ -0,0 +1,232 @@
+---
+title: "DP Trade — Bottle Card Variants"
+layout: layouts/default
+permalink: /bottle-cards.html
+bodyClass: compact-type
+---
+
+
+
+
+
UI-kit / Product cards
+
Варианты карточек бутылок
+
+
Отдельная витрина для выбора направления карточки: крупные плитки, компактные версии и горизонтальный формат для B2B-каталога.
+
+
+
+
+
Variant 01
+
Акцентные карточки каталога
+
+
+
+
+
+
Bordeaux
+
Chateau Laroque Grand Cru
+
France · Red dry · 2019 · 0.75 L
+
+
+
+
+
+
+
+
Tuscany
+
Brunello di Montalcino
+
Italy · Red dry · 2018 · 0.75 L
+
+
+
+
+
+
+
+
Mosel
+
Riesling Kabinett
+
Germany · White · 2021 · 0.75 L
+
+
+
+
+
+
+
+
+
Variant 02-04
+
Альтернативные форматы
+
+
+
+
+
+
Clean retail
+
Oremus Case of Aszu 5 Puttonyos
+
Hungary · White sweet · 2000 · 0.5 L
+
+
+
+
+
+
+
+
Compact
+
Tokaji Aszu 5 Puttonyos
+
Hungary · 12% · Furmint, Harslevelu
+
+
+
+
+
+
+
+
+
B2B row card
+
Oremus Tokaji Late Harvest
+
Вино белое полусладкое · Венгрия · 11.5%
+
Сорт: Фурминт, Зета, Харшлевелю
+
+
+
+
+
+
+
+
+
+
Catalog current
+
Варианты текущей карточки каталога
+
+
+
+ Default / как в каталоге
+
+
+
+
+
+
Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000
+
Вино белое, Oremus, Венгрия
+
Вино Белое Сладкое 12 %
+
Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)
+
+
+
+
+
+
+ Compact / меньше высота
+
+
+
+
+
+
Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000
+
Вино белое, Oremus, Венгрия
+
Сладкое · 12% · Фурминт, Харшлевелю, Мускат
+
+
+
+
+
+
+ Hover / активная строка
+
+
+
+
+
+
Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021
+
Вино белое, Oremus, Венгрия
+
Вино Белое Полусладкое 11.5 %
+
Сорт: Фурминт, Зета, Харшлевелю
+
+
+
+
+
+
+ Color image / цветной фон фото
+
+
+
+
+
+
Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000
+
Вино белое, Oremus, Венгрия
+
Вино Белое Сладкое 12 %
+
Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)
+
+
+
+
+
+
+ B2B dense / больше данных
+
+
+
+
+
+
Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000
+
Венгрия · Tokaj · Oremus · 0.5 л · 12%
+
+ Тип: белое сладкое
+ Сорт: Фурминт 70%
+ Упаковка: 6 шт.
+ Артикул: 00073820
+
+
+
+
+
+
+
+
+
diff --git a/src/catalog.njk b/src/catalog.njk
new file mode 100644
index 0000000..a442a09
--- /dev/null
+++ b/src/catalog.njk
@@ -0,0 +1,80 @@
+---
+title: "DP Trade — Catalog"
+layout: layouts/default
+permalink: /catalog.html
+bodyClass: compact-type
+---
+
+
+
+
+
Catalog / Country
+
Венгрия
+
+
+
+
+
+ Всего найдено: 22
+
+ Исходная сортировка
+ По цене
+ По названию
+
+
+
+
+
+
+
+
+
+
Вино белое Oremus, Case of Aszu 5 Puttonyos, 0.5 л. 2000
+
Вино белое, Oremus, Венгрия
+
Вино Белое Сладкое 12 %
+
Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)
+
+
+
+
+
+
+
+
+
+
Вино белое Oremus, Tokaji Aszu 5 Puttonyos, 0.5 л. 2000
+
Вино белое, Oremus, Венгрия
+
Вино Белое Сладкое 12 %
+
Сорт: Фурминт (70%), Харшлевелю (28%), Мускат (2%)
+
+
+
+
+
+
+
+
+
+
Вино белое Oremus, Tokaji Late Harvest, 0.5 л. 2021
+
Вино белое, Oremus, Венгрия
+
Вино Белое Полусладкое 11.5 %
+
Сорт: Фурминт, Зета, Харшлевелю
+
+
+
+
+
+
diff --git a/src/contacts-auth.njk b/src/contacts-auth.njk
new file mode 100644
index 0000000..d0c3933
--- /dev/null
+++ b/src/contacts-auth.njk
@@ -0,0 +1,61 @@
+---
+title: "DP Trade — Контакты / Auth Gate"
+layout: layouts/default
+permalink: /contacts-auth.html
+bodyClass: compact-type
+---
+
+
+
+
+
Контакты
+
Связаться с DP Trade
+
Контакты открыты для всех, но заявка менеджеру доступна только зарегистрированным или залогиненным пользователям.
+
+
+ Sales office
+ +7 (495) 937-94-60
+ dptr@dp-trade.ru
+
+
+
+
+
+
diff --git a/src/contacts.njk b/src/contacts.njk
new file mode 100644
index 0000000..92f523e
--- /dev/null
+++ b/src/contacts.njk
@@ -0,0 +1,50 @@
+---
+title: "DP Trade — Контакты"
+layout: layouts/default
+permalink: /contacts.html
+bodyClass: compact-type
+---
+
+
+
+
+
Контакты
+
Связаться с DP Trade
+
Для вопросов по каталогу, ассортименту, поставкам и работе с менеджером используйте телефон, почту или форму заявки.
+
+
+ Sales office
+ +7 (495) 937-94-60
+ dptr@dp-trade.ru
+
+
+
+
+
+
diff --git a/src/css/site.css b/src/css/site.css
new file mode 100644
index 0000000..9e441e7
--- /dev/null
+++ b/src/css/site.css
@@ -0,0 +1,2541 @@
+@import url("tokens.css");
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ margin: 0;
+ background: var(--color-background-base);
+ color: var(--color-neutral-black);
+ font-family: var(--font-body);
+ font-size: 16px;
+ line-height: 1.5;
+}
+
+img {
+ display: block;
+ max-width: 100%;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+button,
+input,
+select {
+ font: inherit;
+}
+
+.site-shell {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.container {
+ width: min(100% - 40px, var(--container));
+ margin: 0 auto;
+}
+
+.site-header {
+ position: sticky;
+ top: 0;
+ z-index: 20;
+ background: rgba(248, 250, 252, 0.94);
+ border-bottom: 1px solid rgba(102, 96, 95, 0.18);
+ box-shadow: 0 10px 28px rgba(22, 22, 22, 0.05);
+ backdrop-filter: blur(18px);
+}
+
+.header-top {
+ display: grid;
+ grid-template-columns: 170px minmax(260px, 1fr) auto;
+ align-items: center;
+ gap: 20px;
+ min-height: 72px;
+}
+
+.brand-logo {
+ position: relative;
+ display: inline-block;
+ width: fit-content;
+ color: var(--color-accent-blue);
+ font-family: var(--font-heading-retail);
+ font-size: 26px;
+ font-weight: 800;
+ letter-spacing: 0;
+ line-height: 0.9;
+ text-transform: uppercase;
+}
+
+.brand-logo span:first-child {
+ color: var(--color-primary-wine-80);
+}
+
+.brand-logo small {
+ position: absolute;
+ left: 54px;
+ top: 24px;
+ color: var(--color-primary-wine-80);
+ font-size: 8px;
+ font-weight: 700;
+ white-space: nowrap;
+}
+
+.search-bar {
+ display: grid;
+ grid-template-columns: 44px minmax(0, 1fr);
+ align-items: center;
+ min-height: 44px;
+ border: 1px solid rgba(102, 96, 95, 0.24);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+}
+
+.search-bar:focus-within {
+ border-color: var(--color-primary-wine-100);
+ box-shadow: 0 0 0 4px rgba(75, 15, 36, 0.08);
+}
+
+.search-bar button {
+ width: 44px;
+ height: 42px;
+ border: 0;
+ background: transparent;
+ color: var(--color-primary-wine-100);
+ font-size: 18px;
+ cursor: pointer;
+}
+
+.search-bar input {
+ min-width: 0;
+ border: 0;
+ outline: 0;
+ color: var(--color-neutral-black);
+ font-size: 14px;
+}
+
+.header-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.phone-link {
+ color: var(--color-accent-blue);
+ font-size: 15px;
+ font-weight: 800;
+ white-space: nowrap;
+}
+
+.header-icon {
+ width: 38px;
+ height: 38px;
+ border: 1px solid rgba(75, 15, 36, 0.14);
+ border-radius: var(--radius-sm);
+ background: transparent;
+ color: var(--color-primary-wine-100);
+ display: inline-grid;
+ place-items: center;
+ transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
+}
+
+.header-icon:hover {
+ border-color: rgba(75, 15, 36, 0.36);
+ background: rgba(75, 15, 36, 0.06);
+ transform: translateY(-1px);
+}
+
+.header-icon svg {
+ width: 20px;
+ height: 20px;
+ fill: none;
+ stroke: currentColor;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ stroke-width: 1.45;
+}
+
+.header-icon--air {
+ border-color: rgba(75, 15, 36, 0.13);
+ background: transparent;
+}
+
+.main-nav {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 8px;
+ min-height: 52px;
+ overflow-x: auto;
+ border-top: 1px solid rgba(102, 96, 95, 0.12);
+}
+
+.main-nav > a,
+.nav-trigger {
+ display: inline-flex;
+ align-items: center;
+ gap: 7px;
+ min-height: 34px;
+ padding: 0 2px;
+ border: 0;
+ border-bottom: 2px solid transparent;
+ border-radius: 0;
+ background: transparent;
+ color: var(--color-neutral-gray-700);
+ font-size: 12px;
+ font-weight: 800;
+ letter-spacing: 0;
+ text-transform: uppercase;
+ cursor: pointer;
+ white-space: nowrap;
+}
+
+.main-nav > a:hover,
+.nav-item:hover .nav-trigger,
+.nav-item:focus-within .nav-trigger {
+ border-bottom-color: var(--color-primary-wine-100);
+ background: transparent;
+ color: var(--color-primary-wine-100);
+}
+
+.nav-chevron {
+ width: 10px;
+ height: 10px;
+ display: inline-grid;
+ place-items: center;
+ line-height: 0;
+}
+
+.nav-chevron svg {
+ width: 9px;
+ height: 6px;
+ fill: none;
+ stroke: currentColor;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ stroke-width: 1.6;
+}
+
+.nav-item {
+ position: static;
+}
+
+.nav-item::after {
+ content: "";
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 102px;
+ z-index: 19;
+ display: none;
+ height: 34px;
+}
+
+.mega-menu {
+ position: absolute;
+ left: 50%;
+ top: 118px;
+ width: min(var(--container), calc(100vw - 40px));
+ max-height: calc(100vh - 142px);
+ overflow: auto;
+ padding: 22px;
+ border: 1px solid rgba(102, 96, 95, 0.18);
+ background: #f8fafc;
+ box-shadow: var(--shadow-lift);
+ transform: translateX(-50%);
+ display: none;
+}
+
+.nav-item:hover::after,
+.nav-item:focus-within::after,
+.nav-item:hover .mega-menu,
+.nav-item:focus-within .mega-menu {
+ display: block;
+}
+
+.mega-intro {
+ display: grid;
+ grid-template-columns: minmax(220px, 0.7fr) minmax(320px, 1fr);
+ gap: 18px 28px;
+ align-items: end;
+ padding-bottom: 18px;
+ border-bottom: 1px solid rgba(102, 96, 95, 0.18);
+}
+
+.mega-intro h2 {
+ font-size: 26px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.eyebrow,
+.section-title,
+.muted-caps {
+ margin: 0;
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ font-weight: 800;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+
+.mega-intro h2,
+.section-heading h2,
+.hero h1,
+.product-card h3 {
+ margin: 0;
+ font-family: var(--font-heading);
+ line-height: 1.08;
+}
+
+.mega-intro p:last-child {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+}
+
+.menu-grid {
+ display: grid;
+ grid-template-columns: 1.05fr 0.82fr 1.25fr 0.88fr;
+ gap: 22px;
+ padding-top: 22px;
+}
+
+.menu-column {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ min-width: 0;
+}
+
+.menu-column a {
+ width: fit-content;
+ max-width: 100%;
+ color: var(--color-neutral-gray-700);
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.menu-column a:hover {
+ color: var(--color-primary-wine-80);
+}
+
+.visual-column {
+ gap: 12px;
+}
+
+.visual-column img {
+ width: 100%;
+ aspect-ratio: 4 / 3;
+ object-fit: cover;
+ border-radius: var(--radius-sm);
+}
+
+.visual-column p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+ font-size: 13px;
+ line-height: 1.42;
+}
+
+.appellations {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 9px 18px;
+ align-content: start;
+}
+
+.appellations .section-title {
+ grid-column: 1 / -1;
+ margin-bottom: 0;
+}
+
+.appellation-group {
+ display: flex;
+ flex-direction: column;
+ gap: 9px;
+}
+
+.country-link {
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.popular-list,
+.hero-actions,
+.product-footer {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 12px;
+}
+
+.popular-list a,
+.tag {
+ min-height: 34px;
+ padding: 7px 12px;
+ border: 1px solid rgba(75, 15, 36, 0.18);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ color: var(--color-primary-wine-100);
+ font-size: 13px;
+ font-weight: 700;
+}
+
+.tag--filled {
+ background: var(--color-primary-wine-100);
+ color: var(--color-surface);
+}
+
+.button {
+ min-height: 48px;
+ padding: 12px 22px;
+ border: 1px solid transparent;
+ border-radius: var(--radius-sm);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ font-weight: 800;
+ cursor: pointer;
+}
+
+.button--primary {
+ background: var(--color-primary-wine-100);
+ color: var(--color-surface);
+ box-shadow: 0 10px 22px rgba(75, 15, 36, 0.16);
+}
+
+.button--secondary {
+ border-color: rgba(75, 15, 36, 0.24);
+ color: var(--color-primary-wine-100);
+ background: rgba(248, 250, 252, 0.78);
+}
+
+.button--sm {
+ min-height: 38px;
+ padding: 8px 14px;
+ font-size: 14px;
+}
+
+.hero {
+ min-height: calc(100vh - 124px);
+ display: grid;
+ align-items: end;
+ padding: 104px 0 72px;
+ background:
+ linear-gradient(100deg, rgba(22, 20, 17, 0.84) 0%, rgba(22, 20, 17, 0.58) 38%, rgba(22, 20, 17, 0.12) 72%),
+ url("https://images.unsplash.com/photo-1560493676-04071c5f467b?auto=format&fit=crop&w=1800&q=80");
+ background-position: center right;
+ background-size: cover;
+ color: #f8fafc;
+}
+
+.hero-copy {
+ width: min(100% - 40px, var(--container));
+ max-width: none;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: minmax(0, 0.62fr) minmax(220px, 0.38fr);
+}
+
+.hero-copy > * {
+ grid-column: 1;
+}
+
+.hero h1 {
+ margin: 12px 0 20px;
+ max-width: 860px;
+ font-size: clamp(44px, 6vw, 78px);
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.hero p:not(.eyebrow) {
+ max-width: 610px;
+ color: rgba(255, 253, 250, 0.84);
+ font-size: 18px;
+}
+
+.section {
+ padding: 80px 0;
+}
+
+.section-heading {
+ display: grid;
+ gap: 8px;
+ margin-bottom: 32px;
+}
+
+.section-heading--split {
+ grid-template-columns: minmax(0, 0.9fr) minmax(280px, 0.7fr);
+ gap: 28px;
+ align-items: end;
+}
+
+.section-heading--split > p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+}
+
+.section-heading h2 {
+ font-size: clamp(32px, 4vw, 50px);
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.producer-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 16px;
+}
+
+.producer-card {
+ min-height: 148px;
+ padding: 20px;
+ border: 1px solid rgba(102, 96, 95, 0.14);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ display: grid;
+ align-content: space-between;
+ transition: border-color 0.18s ease, transform 0.18s ease;
+}
+
+.producer-card:hover {
+ border-color: rgba(75, 15, 36, 0.34);
+ transform: translateY(-2px);
+}
+
+.producer-card span,
+.news-card span {
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.producer-card strong {
+ color: var(--color-primary-wine-100);
+ font-family: var(--font-heading);
+ font-size: 24px;
+ line-height: 1.14;
+ text-transform: uppercase;
+}
+
+.news-section {
+ background: #eef2f6;
+}
+
+.news-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 18px;
+}
+
+.news-card {
+ min-width: 0;
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ overflow: hidden;
+ box-shadow: var(--shadow-soft);
+}
+
+.news-card > div:last-child {
+ padding: 18px;
+ display: grid;
+ gap: 8px;
+}
+
+.news-card h3 {
+ margin: 0;
+ color: var(--color-neutral-black);
+ font-family: var(--font-heading);
+ font-size: 20px;
+ line-height: 1.2;
+ text-transform: uppercase;
+}
+
+.news-card__image {
+ min-height: 190px;
+ background-position: center;
+ background-size: cover;
+}
+
+.news-card__image--catena {
+ background-image: linear-gradient(rgba(22, 22, 22, 0.1), rgba(22, 22, 22, 0.1)), url("https://images.unsplash.com/photo-1556760544-74068565f05c?auto=format&fit=crop&w=900&q=80");
+}
+
+.news-card__image--brand {
+ background-image: linear-gradient(rgba(22, 22, 22, 0.1), rgba(22, 22, 22, 0.1)), url("https://images.unsplash.com/photo-1506377247377-2a5b3b417ebb?auto=format&fit=crop&w=900&q=80");
+}
+
+.news-card__image--italy {
+ background-image: linear-gradient(rgba(22, 22, 22, 0.1), rgba(22, 22, 22, 0.1)), url("https://images.unsplash.com/photo-1528823872057-9c018a7a7553?auto=format&fit=crop&w=900&q=80");
+}
+
+.type-lab-section {
+ background: #eef2f6;
+}
+
+.type-options {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 18px;
+}
+
+.type-options--five {
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+}
+
+.type-card {
+ min-width: 0;
+ min-height: 390px;
+ padding: 24px;
+ border: 1px solid rgba(102, 96, 95, 0.16);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ box-shadow: var(--shadow-soft);
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 28px;
+}
+
+.type-card.is-selected {
+ border-color: rgba(75, 15, 36, 0.48);
+ background: linear-gradient(180deg, #ffffff 0%, #eef2f6 100%);
+ box-shadow: var(--shadow-lift);
+}
+
+.type-card.is-selected::before {
+ content: "Выбрано для системы";
+ width: fit-content;
+ padding: 7px 10px;
+ border-radius: var(--radius-sm);
+ background: var(--color-primary-wine-100);
+ color: var(--color-surface);
+ font-size: 12px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.type-card.is-selected-soft {
+ border-color: rgba(185, 150, 91, 0.62);
+ background: #f7f4ea;
+}
+
+.type-card.is-selected-soft::before {
+ content: "Новый компактный";
+ width: fit-content;
+ padding: 7px 10px;
+ border-radius: var(--radius-sm);
+ background: var(--color-accent-gold);
+ color: var(--color-neutral-black);
+ font-size: 12px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.type-card__meta {
+ display: flex;
+ justify-content: space-between;
+ gap: 14px;
+ color: var(--color-neutral-gray-600);
+ font-size: 12px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.type-card__meta strong {
+ color: var(--color-primary-wine-100);
+}
+
+.type-card h3 {
+ margin: 0;
+ color: var(--color-neutral-black);
+}
+
+.type-card p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+}
+
+.type-usage {
+ padding-top: 14px;
+ border-top: 1px solid rgba(102, 96, 95, 0.14);
+ display: grid;
+ gap: 6px;
+}
+
+.type-usage strong {
+ color: var(--color-primary-wine-100);
+ font-size: 11px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.type-usage span {
+ color: var(--color-neutral-gray-600);
+ font-size: 13px;
+ line-height: 1.42;
+}
+
+.type-scale {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.type-scale span {
+ padding: 6px 9px;
+ border: 1px solid rgba(75, 15, 36, 0.16);
+ border-radius: var(--radius-sm);
+ color: var(--color-primary-wine-100);
+ font-size: 12px;
+ font-weight: 800;
+}
+
+.type-card--editorial {
+ font-family: "Manrope", "Inter", Arial, sans-serif;
+}
+
+.type-card--editorial h3 {
+ font-family: "Cormorant Garamond", Georgia, serif;
+ font-size: 46px;
+ font-weight: 700;
+ line-height: 0.98;
+}
+
+.type-card--neo {
+ font-family: "Manrope", "Inter", Arial, sans-serif;
+}
+
+.type-card--neo h3 {
+ font-family: "Manrope", "Inter", Arial, sans-serif;
+ font-size: 34px;
+ font-weight: 800;
+ line-height: 1.08;
+}
+
+.type-card--classic {
+ font-family: "Inter", Arial, sans-serif;
+}
+
+.type-card--classic h3 {
+ font-family: "Playfair Display", Georgia, serif;
+ font-size: 38px;
+ font-weight: 700;
+ line-height: 1.04;
+}
+
+.type-card--retail {
+ font-family: "Inter", Arial, sans-serif;
+}
+
+.type-card--retail h3 {
+ font-family: "Montserrat", "Inter", Arial, sans-serif;
+ font-size: 31px;
+ font-weight: 800;
+ line-height: 1.14;
+ text-transform: uppercase;
+}
+
+.type-card--compact {
+ font-family: "Inter", Arial, sans-serif;
+}
+
+.type-card--compact h3 {
+ font-family: "Montserrat", "Inter", Arial, sans-serif;
+ font-size: 25px;
+ font-weight: 800;
+ line-height: 1.16;
+ text-transform: uppercase;
+}
+
+.compact-type {
+ font-size: 15px;
+ line-height: 1.46;
+}
+
+.compact-type .section {
+ padding: 56px 0;
+}
+
+.compact-type .section-heading {
+ margin-bottom: 24px;
+}
+
+.compact-type .section-heading h2 {
+ font-size: clamp(28px, 3.2vw, 40px);
+ line-height: 1.12;
+}
+
+.catalog-section .catalog-layout {
+ grid-template-columns: 250px minmax(0, 1fr);
+ gap: 22px;
+}
+
+.compact-type .filters-panel {
+ padding: 20px;
+ gap: 12px;
+}
+
+.compact-type .filters-panel h3 {
+ margin: 0 0 2px;
+ font-size: 18px;
+ line-height: 1.2;
+}
+
+.product-grid--compact {
+ gap: 16px;
+}
+
+.product-grid--compact .product-card {
+ padding: 14px;
+ gap: 12px;
+}
+
+.product-grid--compact .product-media {
+ min-height: 176px;
+}
+
+.product-grid--compact .bottle {
+ transform: scale(0.82);
+}
+
+.product-grid--compact .product-card h3 {
+ font-size: 17px;
+ line-height: 1.22;
+}
+
+.product-grid--compact .product-card p {
+ font-size: 13px;
+}
+
+.product-grid--compact .product-footer strong {
+ font-size: 16px;
+}
+
+.product-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 20px;
+}
+
+.product-card {
+ min-width: 0;
+ padding: 16px;
+ border: 1px solid rgba(102, 96, 95, 0.16);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ box-shadow: var(--shadow-soft);
+ display: grid;
+ gap: 16px;
+}
+
+.product-media {
+ min-height: 220px;
+ border-radius: var(--radius-sm);
+ overflow: hidden;
+ display: grid;
+ place-items: center;
+ background: linear-gradient(140deg, #5d1027, #c8a45d);
+}
+
+.product-photo {
+ width: auto;
+ max-width: 132px;
+ height: 190px;
+ object-fit: contain;
+ object-position: center;
+ border: 0;
+ box-shadow: none;
+}
+
+.product-media--amber {
+ background: linear-gradient(140deg, #a8632a, #dde4ec);
+}
+
+.product-media--green {
+ background: linear-gradient(140deg, #1f4d3a, #e8eadb);
+}
+
+.bottle {
+ width: 54px;
+ height: 152px;
+ border-radius: 16px 16px 10px 10px;
+ background: linear-gradient(90deg, #161616, #2f2a29 44%, #0c0c0c);
+ box-shadow: 18px 18px 44px rgba(22, 22, 22, 0.24);
+ position: relative;
+}
+
+.bottle::before {
+ content: "";
+ position: absolute;
+ top: -58px;
+ left: 17px;
+ width: 20px;
+ height: 72px;
+ border-radius: 8px 8px 2px 2px;
+ background: #171212;
+}
+
+.bottle::after {
+ content: "";
+ position: absolute;
+ inset: 54px 8px auto;
+ height: 42px;
+ border-radius: 4px;
+ background: #eef2f6;
+}
+
+.product-card h3 {
+ margin-top: 8px;
+ font-size: 21px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.product-card p {
+ margin: 6px 0 0;
+ color: var(--color-neutral-gray-600);
+}
+
+.product-footer {
+ justify-content: space-between;
+}
+
+.product-footer strong {
+ color: var(--color-primary-wine-100);
+ font-size: 18px;
+}
+
+.catalog-layout {
+ display: grid;
+ grid-template-columns: 280px minmax(0, 1fr);
+ gap: 28px;
+}
+
+.catalog-head {
+ margin-bottom: 28px;
+ display: grid;
+ grid-template-columns: minmax(0, 0.8fr) minmax(520px, 1fr);
+ gap: 24px;
+ align-items: end;
+}
+
+.catalog-head h1 {
+ margin: 6px 0 0;
+ color: var(--color-primary-wine-100);
+ font-family: var(--font-heading);
+ font-size: clamp(34px, 4vw, 52px);
+ font-weight: 800;
+ line-height: 1.12;
+}
+
+.catalog-actions {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ flex-wrap: wrap;
+ gap: 14px;
+}
+
+.catalog-actions > span,
+.catalog-toolbar > span {
+ color: var(--color-neutral-gray-700);
+ font-size: 17px;
+}
+
+.catalog-toolbar {
+ margin-bottom: 22px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 18px;
+}
+
+.catalog-sort {
+ width: min(100%, 320px);
+ min-height: 40px;
+ padding: 7px 12px;
+}
+
+.product-list {
+ display: grid;
+ gap: 18px;
+}
+
+.product-card--list {
+ min-height: 250px;
+ padding: 20px;
+ grid-template-columns: 210px minmax(0, 1fr) 220px;
+ gap: 28px;
+ align-items: center;
+ border-color: rgba(102, 96, 95, 0.08);
+}
+
+.product-image {
+ min-height: 214px;
+ max-height: 224px;
+ overflow: hidden;
+ display: grid;
+ place-items: center;
+}
+
+.product-image img {
+ width: auto;
+ max-width: 132px;
+ height: 208px;
+ object-fit: contain;
+ object-position: center;
+ border: 0;
+ box-shadow: none;
+}
+
+.product-info {
+ min-width: 0;
+ display: grid;
+ gap: 12px;
+}
+
+.product-info h3 {
+ margin: 0;
+ color: var(--color-neutral-black);
+ font-size: clamp(22px, 2.4vw, 32px);
+ font-weight: 800;
+ line-height: 1.18;
+ text-transform: none;
+}
+
+.product-info p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+ font-size: 16px;
+ line-height: 1.38;
+}
+
+.product-info .product-origin {
+ font-size: 15px;
+}
+
+.product-buy {
+ min-height: 170px;
+ display: grid;
+ align-content: end;
+ justify-items: end;
+ gap: 56px;
+}
+
+.product-buy strong {
+ color: var(--color-neutral-black);
+ font-size: 28px;
+ font-weight: 800;
+ line-height: 1;
+ white-space: nowrap;
+}
+
+.product-buy .button {
+ min-width: 180px;
+}
+
+.card-lab-section {
+ background:
+ linear-gradient(180deg, rgba(255, 255, 255, 0.7), rgba(244, 246, 249, 0.96)),
+ var(--color-background-base);
+}
+
+.card-lab-head {
+ margin-bottom: 42px;
+ display: grid;
+ grid-template-columns: minmax(0, 0.72fr) minmax(320px, 0.42fr);
+ gap: 32px;
+ align-items: end;
+}
+
+.card-lab-head h1 {
+ margin: 8px 0 0;
+ color: var(--color-neutral-black);
+ font-family: var(--font-heading);
+ font-size: clamp(38px, 5vw, 72px);
+ font-weight: 800;
+ line-height: 0.98;
+ text-transform: uppercase;
+}
+
+.card-lab-head > p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+ font-size: 18px;
+ line-height: 1.55;
+}
+
+.card-variant-block {
+ display: grid;
+ gap: 18px;
+}
+
+.card-variant-block + .card-variant-block {
+ margin-top: 48px;
+}
+
+.card-variant-title {
+ display: flex;
+ justify-content: space-between;
+ gap: 24px;
+ align-items: end;
+}
+
+.card-variant-title h2 {
+ margin: 2px 0 0;
+ color: var(--color-neutral-black);
+ font-family: var(--font-heading);
+ font-size: clamp(24px, 2.6vw, 34px);
+ font-weight: 800;
+}
+
+.bottle-card-grid,
+.bottle-card-mix {
+ display: grid;
+ gap: 20px;
+}
+
+.bottle-card-grid {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.bottle-card-mix {
+ grid-template-columns: minmax(0, 0.92fr) minmax(0, 0.78fr) minmax(320px, 1.3fr);
+ align-items: stretch;
+}
+
+.bottle-card {
+ min-width: 0;
+ padding: 16px;
+ border: 1px solid rgba(102, 96, 95, 0.12);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ box-shadow: 0 18px 46px rgba(18, 25, 38, 0.08);
+ display: grid;
+ gap: 16px;
+}
+
+.bottle-card__media {
+ min-height: 224px;
+ border-radius: var(--radius-sm);
+ overflow: hidden;
+ display: grid;
+ place-items: center;
+ background: linear-gradient(135deg, #6a1330 0%, #9e6a4e 48%, #d3b966 100%);
+}
+
+.bottle-card__photo {
+ width: auto;
+ max-width: 142px;
+ height: 198px;
+ object-fit: contain;
+ object-position: center;
+ border: 0;
+ box-shadow: none;
+}
+
+.bottle-card__body {
+ min-width: 0;
+}
+
+.bottle-card__region {
+ margin: 0 0 9px;
+ color: #b59a5a;
+ font-size: 13px;
+ font-weight: 800;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+}
+
+.bottle-card h3 {
+ margin: 0;
+ color: var(--color-neutral-black);
+ font-size: clamp(22px, 2.1vw, 28px);
+ font-weight: 800;
+ line-height: 1.08;
+ text-transform: uppercase;
+}
+
+.bottle-card p {
+ margin: 8px 0 0;
+ color: var(--color-neutral-gray-600);
+ font-size: 16px;
+ line-height: 1.42;
+}
+
+.bottle-card__details {
+ font-size: 15px;
+}
+
+.bottle-card__footer {
+ margin-top: 4px;
+ display: flex;
+ justify-content: space-between;
+ gap: 16px;
+ align-items: center;
+}
+
+.bottle-card__footer strong {
+ color: var(--color-primary-wine-100);
+ font-size: 22px;
+ font-weight: 800;
+ white-space: nowrap;
+}
+
+.bottle-card__footer .button {
+ min-width: 132px;
+}
+
+.bottle-card--tuscany .bottle-card__media {
+ background: linear-gradient(135deg, #b16d2c 0%, #c8ad94 52%, #dfe5eb 100%);
+}
+
+.bottle-card--mosel .bottle-card__media {
+ background: linear-gradient(135deg, #214f3d 0%, #8aa38e 48%, #e8ebdc 100%);
+}
+
+.bottle-card--clean .bottle-card__media {
+ background: linear-gradient(135deg, #edf1f5 0%, #d7dee7 100%);
+}
+
+.bottle-card--clean .bottle-card__photo {
+ height: 214px;
+}
+
+.bottle-card--compact {
+ align-content: start;
+}
+
+.bottle-card--compact .bottle-card__media {
+ min-height: 178px;
+ background: linear-gradient(135deg, #f3f5f8 0%, #dbe2ea 100%);
+}
+
+.bottle-card--compact .bottle-card__photo {
+ height: 154px;
+}
+
+.bottle-card--compact h3 {
+ font-size: 20px;
+}
+
+.bottle-card--compact p {
+ font-size: 15px;
+}
+
+.bottle-card--horizontal {
+ grid-template-columns: 180px minmax(0, 1fr);
+ gap: 20px;
+ align-items: center;
+}
+
+.bottle-card--horizontal .bottle-card__media {
+ min-height: 230px;
+ background: linear-gradient(135deg, #e9eef4 0%, #cfd8e3 100%);
+}
+
+.bottle-card--horizontal .bottle-card__photo {
+ height: 208px;
+}
+
+.bottle-card__content {
+ min-width: 0;
+ display: grid;
+ gap: 24px;
+}
+
+.catalog-card-variants {
+ display: grid;
+ gap: 18px;
+}
+
+.catalog-card-sample {
+ display: grid;
+ gap: 10px;
+}
+
+.catalog-card-sample__label {
+ margin: 0;
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ font-weight: 800;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+
+.product-card--list-compact {
+ min-height: 198px;
+ grid-template-columns: 160px minmax(0, 1fr) 190px;
+ gap: 22px;
+}
+
+.product-card--list-compact .product-image {
+ min-height: 164px;
+ max-height: 174px;
+}
+
+.product-card--list-compact .product-image img {
+ max-width: 104px;
+ height: 156px;
+}
+
+.product-card--list-compact .product-info {
+ gap: 8px;
+}
+
+.product-card--list-compact .product-info h3 {
+ font-size: clamp(19px, 2vw, 25px);
+}
+
+.product-card--list-compact .product-info p {
+ font-size: 14px;
+}
+
+.product-card--list-compact .product-buy {
+ min-height: 132px;
+ gap: 28px;
+}
+
+.product-card--list-hover {
+ border-color: rgba(75, 15, 36, 0.28);
+ box-shadow: 0 22px 54px rgba(25, 37, 62, 0.13);
+ transform: translateY(-2px);
+}
+
+.product-card--list-hover .product-image {
+ border-radius: var(--radius-sm);
+ background: linear-gradient(135deg, #eef2f6 0%, #dde6ef 100%);
+}
+
+.product-card--list-hover .button {
+ border-color: var(--color-primary-wine-100);
+}
+
+.product-card--list-color {
+ border-color: rgba(185, 150, 91, 0.24);
+}
+
+.product-card--list-color .product-image {
+ min-height: 214px;
+ border-radius: var(--radius-sm);
+}
+
+.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%);
+}
+
+.product-card--list-b2b {
+ min-height: 226px;
+ grid-template-columns: 176px minmax(0, 1fr) 190px;
+ gap: 24px;
+}
+
+.product-card--list-b2b .product-image {
+ min-height: 184px;
+ max-height: 194px;
+}
+
+.product-card--list-b2b .product-image img {
+ max-width: 108px;
+ height: 178px;
+}
+
+.product-params {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px 14px;
+}
+
+.product-params span {
+ min-width: 0;
+ color: var(--color-neutral-gray-600);
+ font-size: 14px;
+ line-height: 1.32;
+}
+
+.product-card--list-b2b .product-buy {
+ min-height: 148px;
+ gap: 34px;
+}
+
+.content-page {
+ background: var(--color-background-base);
+}
+
+.page-hero {
+ padding: 78px 0;
+ color: #f8fafc;
+ background:
+ linear-gradient(100deg, rgba(22, 20, 17, 0.86), rgba(22, 20, 17, 0.48) 54%, rgba(22, 20, 17, 0.22)),
+ url("https://images.unsplash.com/photo-1506377247377-2a5b3b417ebb?auto=format&fit=crop&w=1800&q=80");
+ background-position: center;
+ background-size: cover;
+}
+
+.page-hero--about {
+ background-image:
+ linear-gradient(100deg, rgba(22, 20, 17, 0.84), rgba(22, 20, 17, 0.46) 54%, rgba(22, 20, 17, 0.18)),
+ url("https://images.unsplash.com/photo-1568213816046-0ee1c42bd559?auto=format&fit=crop&w=1800&q=80");
+}
+
+.page-hero--contacts {
+ background-image:
+ linear-gradient(100deg, rgba(22, 20, 17, 0.86), rgba(22, 20, 17, 0.5) 54%, rgba(22, 20, 17, 0.2)),
+ url("https://images.unsplash.com/photo-1510812431401-41d2bd2722f3?auto=format&fit=crop&w=1800&q=80");
+}
+
+.page-hero--guidelines {
+ background-image:
+ linear-gradient(100deg, rgba(22, 20, 17, 0.86), rgba(22, 20, 17, 0.5) 54%, rgba(22, 20, 17, 0.22)),
+ url("https://images.unsplash.com/photo-1516594798947-e65505dbb29d?auto=format&fit=crop&w=1800&q=80");
+}
+
+.page-hero__inner {
+ display: grid;
+ grid-template-columns: minmax(0, 0.72fr) minmax(280px, 0.28fr);
+ gap: 36px;
+ align-items: end;
+}
+
+.page-hero h1 {
+ max-width: 980px;
+ margin: 10px 0 18px;
+ font-family: var(--font-heading);
+ font-size: clamp(40px, 5.6vw, 76px);
+ font-weight: 800;
+ line-height: 0.98;
+ text-transform: uppercase;
+}
+
+.page-hero p {
+ max-width: 740px;
+ margin: 0;
+ font-size: 19px;
+ line-height: 1.55;
+}
+
+.page-hero__meta,
+.info-card,
+.feature-card,
+.contact-panel,
+.contact-form {
+ border: 1px solid rgba(217, 222, 229, 0.9);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ box-shadow: var(--shadow-soft);
+}
+
+.page-hero__meta {
+ padding: 22px;
+ color: var(--color-neutral-black);
+}
+
+.page-hero__meta span,
+.info-card span,
+.feature-card span,
+.contact-panel span {
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.page-hero__meta strong {
+ display: block;
+ margin: 10px 0 8px;
+ color: var(--color-primary-wine-100);
+ font-family: var(--font-heading);
+ font-size: 26px;
+ line-height: 1.1;
+ text-transform: uppercase;
+}
+
+.page-hero__meta p {
+ color: var(--color-neutral-gray-600);
+ font-size: 15px;
+ line-height: 1.45;
+}
+
+.article-layout,
+.contacts-layout {
+ display: grid;
+ grid-template-columns: minmax(0, 0.68fr) minmax(300px, 0.32fr);
+ gap: 34px;
+ align-items: start;
+}
+
+.about-grid {
+ display: grid;
+ grid-template-columns: minmax(0, 0.58fr) minmax(360px, 0.42fr);
+ gap: 34px;
+ align-items: start;
+}
+
+.article-body {
+ max-width: 860px;
+}
+
+.article-body .lead {
+ color: var(--color-neutral-black);
+ font-size: 22px;
+ line-height: 1.48;
+}
+
+.article-body h2 {
+ margin: 34px 0 12px;
+ font-family: var(--font-heading);
+ font-size: clamp(28px, 3vw, 40px);
+ font-weight: 800;
+ line-height: 1.08;
+ text-transform: uppercase;
+}
+
+.article-body p {
+ color: var(--color-neutral-gray-600);
+ font-size: 17px;
+ line-height: 1.72;
+}
+
+.article-body blockquote {
+ margin: 30px 0;
+ padding: 22px 24px;
+ border-left: 4px solid var(--color-primary-wine-100);
+ background: #eef2f6;
+ color: var(--color-neutral-black);
+ font-size: 20px;
+ font-weight: 700;
+ line-height: 1.45;
+}
+
+.article-aside,
+.contact-stack {
+ display: grid;
+ gap: 16px;
+}
+
+.info-card {
+ padding: 22px;
+}
+
+.info-card dl {
+ margin: 18px 0 0;
+ display: grid;
+ gap: 12px;
+}
+
+.info-card dl div {
+ display: flex;
+ justify-content: space-between;
+ gap: 18px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid rgba(102, 96, 95, 0.14);
+}
+
+.info-card dt {
+ color: var(--color-neutral-gray-600);
+}
+
+.info-card dd {
+ margin: 0;
+ color: var(--color-neutral-black);
+ font-weight: 800;
+ text-align: right;
+}
+
+.info-card--accent {
+ background: #eef2f6;
+}
+
+.info-card--accent p {
+ color: var(--color-neutral-gray-600);
+ line-height: 1.55;
+}
+
+.feature-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 16px;
+}
+
+.feature-card {
+ min-height: 210px;
+ padding: 22px;
+ display: grid;
+ align-content: space-between;
+}
+
+.feature-card h3 {
+ margin: 18px 0 8px;
+ color: var(--color-neutral-black);
+ font-family: var(--font-heading);
+ font-size: 22px;
+ text-transform: uppercase;
+}
+
+.feature-card p,
+.contact-panel p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+ line-height: 1.55;
+}
+
+.muted-section {
+ background: #eef2f6;
+}
+
+.contact-panel,
+.contact-form {
+ padding: 24px;
+}
+
+.contact-panel a {
+ display: block;
+ margin: 8px 0 10px;
+ color: var(--color-primary-wine-100);
+ font-family: var(--font-heading);
+ font-size: clamp(24px, 3vw, 34px);
+ font-weight: 800;
+ line-height: 1.1;
+}
+
+.contact-form {
+ display: grid;
+ gap: 16px;
+}
+
+.contact-form h2 {
+ margin: 0;
+ font-family: var(--font-heading);
+ font-size: 30px;
+ text-transform: uppercase;
+}
+
+.contact-form label {
+ display: grid;
+ gap: 7px;
+ color: var(--color-neutral-gray-700);
+ font-weight: 800;
+}
+
+.contact-form textarea.input {
+ min-height: 132px;
+ resize: vertical;
+}
+
+.contact-auth-gate {
+ position: relative;
+ overflow: hidden;
+}
+
+.contact-auth-gate::before {
+ content: "";
+ position: absolute;
+ inset: 0 0 auto;
+ height: 6px;
+ background: linear-gradient(90deg, var(--color-primary-wine-100), var(--color-accent-gold));
+}
+
+.auth-gate__badge {
+ width: fit-content;
+ padding: 7px 10px;
+ border-radius: var(--radius-sm);
+ background: rgba(75, 15, 36, 0.08);
+ color: var(--color-primary-wine-100);
+ font-size: 12px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.contact-auth-gate > p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+ line-height: 1.62;
+}
+
+.auth-gate__actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+}
+
+.auth-gate__note {
+ padding: 16px;
+ border: 1px solid rgba(185, 150, 91, 0.28);
+ border-radius: var(--radius-sm);
+ background: #f8fafc;
+ display: grid;
+ gap: 6px;
+}
+
+.auth-gate__note strong {
+ color: var(--color-neutral-black);
+}
+
+.auth-gate__note span {
+ color: var(--color-neutral-gray-600);
+ line-height: 1.48;
+}
+
+.locked-form-preview {
+ padding-top: 16px;
+ border-top: 1px solid rgba(102, 96, 95, 0.14);
+ display: grid;
+ gap: 12px;
+ opacity: 0.62;
+}
+
+.locked-form-preview label {
+ display: grid;
+ gap: 7px;
+ color: var(--color-neutral-gray-600);
+ font-weight: 800;
+}
+
+.locked-form-preview .input:disabled {
+ cursor: not-allowed;
+ background: #eef2f6;
+ color: var(--color-neutral-gray-600);
+}
+
+.guideline-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 18px;
+}
+
+.guideline-card,
+.guideline-checklist {
+ border: 1px solid rgba(217, 222, 229, 0.9);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ box-shadow: var(--shadow-soft);
+}
+
+.guideline-card {
+ min-width: 0;
+ padding: 24px;
+ display: grid;
+ gap: 14px;
+ align-content: start;
+}
+
+.guideline-card--lead {
+ grid-column: span 2;
+ background: #eef2f6;
+}
+
+.guideline-card span {
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ font-weight: 800;
+}
+
+.guideline-card h2,
+.guideline-checklist h2 {
+ margin: 0;
+ color: var(--color-neutral-black);
+ font-family: var(--font-heading);
+ font-size: clamp(24px, 2.6vw, 34px);
+ font-weight: 800;
+ line-height: 1.08;
+ text-transform: uppercase;
+}
+
+.guideline-card p {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+ line-height: 1.55;
+}
+
+.guideline-card ul,
+.guideline-checklist ul {
+ margin: 0;
+ padding-left: 18px;
+ color: var(--color-neutral-gray-700);
+ line-height: 1.62;
+}
+
+.guideline-card li + li,
+.guideline-checklist li + li {
+ margin-top: 8px;
+}
+
+.guideline-checklist {
+ padding: 28px;
+ display: grid;
+ grid-template-columns: minmax(0, 0.42fr) minmax(0, 0.58fr);
+ gap: 28px;
+ align-items: start;
+}
+
+.news-editorial {
+ background: #f4f6f9;
+}
+
+.editorial-hero {
+ padding: 54px 0 34px;
+ background: #f8fafc;
+ border-bottom: 1px solid rgba(102, 96, 95, 0.14);
+}
+
+.editorial-hero__inner {
+ display: grid;
+ grid-template-columns: minmax(0, 0.55fr) minmax(360px, 0.45fr);
+ gap: 38px;
+ align-items: end;
+}
+
+.editorial-hero h1 {
+ margin: 10px 0 18px;
+ color: var(--color-neutral-black);
+ font-family: var(--font-heading);
+ font-size: clamp(42px, 5.6vw, 76px);
+ font-weight: 800;
+ line-height: 0.98;
+ text-transform: uppercase;
+}
+
+.editorial-meta {
+ display: flex;
+ gap: 12px;
+ flex-wrap: wrap;
+}
+
+.editorial-meta span {
+ padding: 8px 12px;
+ border: 1px solid rgba(75, 15, 36, 0.16);
+ border-radius: var(--radius-sm);
+ color: var(--color-primary-wine-100);
+ font-size: 13px;
+ font-weight: 800;
+}
+
+.editorial-hero__image {
+ margin: 0;
+ border-radius: var(--radius-sm);
+ overflow: hidden;
+ box-shadow: 0 22px 58px rgba(25, 37, 62, 0.12);
+}
+
+.editorial-hero__image img {
+ width: 100%;
+ aspect-ratio: 4 / 3;
+ object-fit: cover;
+}
+
+.editorial-section {
+ padding: 48px 0;
+}
+
+.editorial-layout {
+ display: grid;
+ grid-template-columns: 260px minmax(0, 780px);
+ gap: 56px;
+ align-items: start;
+ justify-content: center;
+}
+
+.editorial-side {
+ position: sticky;
+ top: 154px;
+ padding: 18px 0 0;
+ border-top: 2px solid var(--color-primary-wine-100);
+}
+
+.editorial-side span {
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.editorial-side p {
+ margin: 12px 0 0;
+ color: var(--color-neutral-gray-600);
+ line-height: 1.55;
+}
+
+.editorial-side ol {
+ margin: 16px 0 0;
+ padding: 0;
+ display: grid;
+ gap: 12px;
+ list-style: none;
+}
+
+.editorial-side li {
+ display: grid;
+ gap: 2px;
+}
+
+.editorial-side strong {
+ color: var(--color-primary-wine-100);
+ font-family: var(--font-heading);
+ font-size: 22px;
+}
+
+.editorial-side small {
+ color: var(--color-neutral-gray-600);
+ font-size: 13px;
+}
+
+.editorial-body .lead {
+ color: var(--color-neutral-black);
+ font-size: clamp(22px, 2.4vw, 30px);
+ line-height: 1.38;
+}
+
+.editorial-body p {
+ color: var(--color-neutral-gray-600);
+ font-size: 18px;
+ line-height: 1.74;
+}
+
+.editorial-body blockquote {
+ margin: 34px 0;
+ padding: 28px;
+ border-left: 4px solid var(--color-primary-wine-100);
+ background: #eef2f6;
+ color: var(--color-neutral-black);
+ font-family: var(--font-heading);
+ font-size: clamp(22px, 3vw, 34px);
+ font-weight: 800;
+ line-height: 1.2;
+}
+
+.editorial-image {
+ margin-top: 0;
+ margin-bottom: 0;
+ border-radius: var(--radius-sm);
+ overflow: hidden;
+}
+
+.editorial-image img {
+ width: 100%;
+ max-height: 540px;
+ object-fit: cover;
+}
+
+.editorial-photo-grid {
+ display: grid;
+ grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
+ gap: 18px;
+}
+
+.editorial-photo-grid figure {
+ margin: 0;
+ border-radius: var(--radius-sm);
+ overflow: hidden;
+}
+
+.editorial-photo-grid img {
+ width: 100%;
+ height: 100%;
+ min-height: 360px;
+ object-fit: cover;
+}
+
+.editorial-section--final {
+ padding-bottom: 82px;
+}
+
+.editorial-outro {
+ color: var(--color-primary-wine-100) !important;
+ font-family: var(--font-heading);
+ font-size: clamp(28px, 4vw, 46px) !important;
+ font-weight: 800;
+ line-height: 1.1 !important;
+ text-transform: uppercase;
+}
+
+.filters-panel,
+.info-panel {
+ padding: 24px;
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ box-shadow: var(--shadow-soft);
+}
+
+.filters-panel {
+ display: grid;
+ gap: 14px;
+ align-content: start;
+}
+
+.checkbox {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: var(--color-neutral-gray-600);
+ font-weight: 700;
+}
+
+.checkbox input {
+ width: 18px;
+ height: 18px;
+ accent-color: var(--color-primary-wine-100);
+}
+
+.product-detail {
+ display: grid;
+ grid-template-columns: minmax(320px, 0.9fr) minmax(0, 1.1fr);
+ gap: 40px;
+ align-items: start;
+}
+
+.product-detail .product-media {
+ min-height: 520px;
+}
+
+.product-detail .product-photo {
+ max-width: 220px;
+ height: 420px;
+}
+
+.detail-copy h1 {
+ margin: 10px 0 18px;
+ font-family: var(--font-heading);
+ font-size: clamp(38px, 5vw, 62px);
+ line-height: 1.08;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.meta-list {
+ display: grid;
+ gap: 12px;
+ margin: 28px 0;
+}
+
+.meta-list div {
+ display: flex;
+ justify-content: space-between;
+ gap: 18px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid rgba(102, 96, 95, 0.16);
+}
+
+.meta-list span {
+ color: var(--color-neutral-gray-600);
+}
+
+.site-footer {
+ margin-top: auto;
+ padding: 32px 0 40px;
+ border-top: 1px solid rgba(102, 96, 95, 0.12);
+ background: var(--color-background-base);
+}
+
+.footer-container {
+ padding: 24px 28px 20px;
+ border: 1px solid rgba(102, 96, 95, 0.16);
+ border-radius: var(--radius-sm);
+ background: var(--color-surface);
+ box-shadow: var(--shadow-soft);
+}
+
+.footer-main {
+ display: grid;
+ grid-template-columns: minmax(170px, 210px) minmax(0, 1fr) minmax(210px, 250px);
+ gap: 24px 32px;
+ align-items: start;
+}
+
+.footer-brand-block {
+ min-width: 0;
+ display: grid;
+ gap: 8px;
+}
+
+.footer-brand {
+ display: inline-flex;
+ width: fit-content;
+ line-height: 0;
+}
+
+.footer-brand img {
+ width: 156px;
+ height: auto;
+}
+
+.footer-brand-subtitle {
+ margin: 0;
+ color: var(--color-neutral-gray-600);
+ font-size: 13px;
+ line-height: 1.35;
+}
+
+.social-links {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 2px;
+}
+
+.social-links a {
+ display: inline-grid;
+ place-items: center;
+ width: 34px;
+ height: 34px;
+ border: 1px solid rgba(75, 15, 36, 0.14);
+ border-radius: var(--radius-sm);
+ background: transparent;
+ color: var(--color-primary-wine-100);
+ transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
+}
+
+.social-links svg {
+ width: 18px;
+ height: 18px;
+ fill: currentColor;
+}
+
+.social-links a:hover,
+.social-links a:focus-visible {
+ border-color: rgba(75, 15, 36, 0.36);
+ background: rgba(75, 15, 36, 0.06);
+ transform: translateY(-1px);
+}
+
+.contacts-card {
+ display: grid;
+ gap: 8px;
+ justify-items: start;
+ align-content: start;
+}
+
+.contacts-card h2,
+.nav-group h2 {
+ margin: 0 0 10px;
+ font-size: 13px;
+ font-weight: 800;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+
+.contact-link {
+ display: block;
+ width: fit-content;
+ color: var(--color-neutral-gray-700);
+ font-size: 14px;
+ line-height: 1.35;
+ transition: color 0.18s ease;
+}
+
+.contact-link:hover,
+.contact-link:focus-visible {
+ color: var(--color-primary-wine-100);
+}
+
+.contact-phone {
+ color: var(--color-accent-blue);
+ font-size: 18px;
+ font-weight: 800;
+}
+
+.footer-nav {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(140px, 1fr));
+ gap: 24px;
+ align-items: start;
+}
+
+.nav-group ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.nav-group li + li {
+ margin-top: 7px;
+}
+
+.nav-group a,
+.footer-legal {
+ color: var(--color-neutral-gray-600);
+}
+
+.nav-group a {
+ display: inline-flex;
+ padding: 2px 0;
+ font-size: 14px;
+ line-height: 1.35;
+ transition: color 0.18s ease;
+}
+
+.nav-group a:hover,
+.nav-group a:focus-visible {
+ color: var(--color-primary-wine-100);
+}
+
+.footer-legal {
+ grid-column: 1 / -1;
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 20px;
+ padding-top: 16px;
+ border-top: 1px solid rgba(102, 96, 95, 0.16);
+ font-size: 12px;
+ line-height: 1.45;
+}
+
+.footer-legal p {
+ margin: 0;
+}
+
+.footer-legal p:first-child {
+ max-width: 760px;
+}
+
+.footer-legal p:last-child {
+ flex: 0 0 auto;
+ color: var(--color-neutral-gray-700);
+ font-weight: 800;
+}
+
+.footer-legal a {
+ color: var(--color-primary-wine-80);
+ font-weight: 800;
+}
+
+.footer-legal a:hover,
+.footer-legal a:focus-visible {
+ color: var(--color-primary-wine-100);
+}
+
+@media (max-width: 1080px) {
+ .header-top,
+ .footer-main,
+ .catalog-layout,
+ .product-detail {
+ grid-template-columns: 1fr;
+ }
+
+ .header-top {
+ padding: 16px 0;
+ }
+
+ .footer-main {
+ grid-template-columns: minmax(180px, 0.7fr) minmax(220px, 1fr);
+ }
+
+ .footer-nav,
+ .footer-legal {
+ grid-column: 1 / -1;
+ }
+
+ .contacts-card {
+ justify-self: end;
+ }
+
+ .header-actions {
+ justify-content: space-between;
+ }
+
+ .phone-link {
+ font-size: 14px;
+ }
+
+ .main-nav {
+ justify-content: flex-start;
+ }
+
+ .menu-grid,
+ .product-grid,
+ .bottle-card-grid,
+ .producer-grid,
+ .news-grid,
+ .type-options--five {
+ grid-template-columns: 1fr 1fr;
+ }
+
+ .card-lab-head,
+ .bottle-card-mix,
+ .page-hero__inner,
+ .editorial-hero__inner,
+ .editorial-layout,
+ .article-layout,
+ .about-grid,
+ .contacts-layout,
+ .guideline-grid,
+ .guideline-checklist {
+ grid-template-columns: 1fr;
+ }
+
+ .type-options {
+ grid-template-columns: 1fr 1fr;
+ }
+
+ .catalog-head {
+ grid-template-columns: 1fr;
+ }
+
+ .catalog-actions {
+ justify-content: flex-start;
+ }
+
+ .product-card--list {
+ grid-template-columns: 150px minmax(0, 1fr);
+ }
+
+ .product-card--list-compact,
+ .product-card--list-b2b {
+ grid-template-columns: 140px minmax(0, 1fr);
+ }
+
+ .product-buy {
+ grid-column: 2;
+ min-height: auto;
+ align-content: start;
+ justify-items: start;
+ gap: 16px;
+ }
+
+ .mega-menu {
+ top: 172px;
+ }
+
+ .nav-item::after {
+ top: 150px;
+ height: 34px;
+ }
+}
+
+@media (max-width: 720px) {
+ .container {
+ width: min(100% - 28px, var(--container));
+ }
+
+ .header-top {
+ gap: 14px;
+ padding: 16px 0;
+ }
+
+ .header-actions {
+ align-items: center;
+ flex-direction: row;
+ gap: 10px;
+ }
+
+ .phone-link {
+ display: none;
+ }
+
+ .main-nav {
+ min-height: 54px;
+ }
+
+ .mega-menu {
+ top: 184px;
+ padding: 18px;
+ }
+
+ .nav-item::after {
+ top: 160px;
+ height: 34px;
+ }
+
+ .mega-intro,
+ .menu-grid,
+ .appellations,
+ .product-grid,
+ .bottle-card-grid,
+ .producer-grid,
+ .news-grid,
+ .type-options--five,
+ .type-options,
+ .section-heading--split,
+ .footer-nav {
+ grid-template-columns: 1fr;
+ }
+
+ .hero {
+ min-height: 620px;
+ padding: 56px 0;
+ }
+
+ .hero-copy {
+ width: min(100% - 28px, var(--container));
+ grid-template-columns: 1fr;
+ }
+
+ .section {
+ padding: 56px 0;
+ }
+
+ .card-lab-head {
+ gap: 18px;
+ margin-bottom: 32px;
+ }
+
+ .card-lab-head h1 {
+ font-size: 36px;
+ }
+
+ .card-variant-title {
+ align-items: flex-start;
+ flex-direction: column;
+ gap: 6px;
+ }
+
+ .page-hero {
+ padding: 56px 0;
+ }
+
+ .page-hero h1 {
+ font-size: 36px;
+ }
+
+ .page-hero p,
+ .article-body .lead {
+ font-size: 17px;
+ }
+
+ .editorial-side {
+ position: static;
+ }
+
+ .editorial-photo-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .feature-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .guideline-card--lead {
+ grid-column: auto;
+ }
+
+ .bottle-card {
+ padding: 14px;
+ }
+
+ .bottle-card__media {
+ min-height: 190px;
+ }
+
+ .bottle-card__photo {
+ height: 168px;
+ }
+
+ .bottle-card h3 {
+ font-size: 22px;
+ }
+
+ .bottle-card__footer {
+ align-items: stretch;
+ flex-direction: column;
+ }
+
+ .bottle-card__footer .button {
+ width: 100%;
+ }
+
+ .bottle-card--horizontal {
+ grid-template-columns: 1fr;
+ }
+
+ .catalog-toolbar,
+ .catalog-actions {
+ align-items: stretch;
+ flex-direction: column;
+ }
+
+ .catalog-sort {
+ width: 100%;
+ }
+
+ .product-card--list {
+ min-height: auto;
+ grid-template-columns: 108px minmax(0, 1fr);
+ gap: 16px;
+ padding: 16px;
+ }
+
+ .product-card--list-compact,
+ .product-card--list-b2b {
+ grid-template-columns: 96px minmax(0, 1fr);
+ }
+
+ .product-image {
+ min-height: 180px;
+ max-height: 186px;
+ }
+
+ .product-image img {
+ max-width: 98px;
+ height: 172px;
+ }
+
+ .product-info h3 {
+ font-size: 19px;
+ }
+
+ .product-info p {
+ font-size: 14px;
+ }
+
+ .product-params {
+ grid-template-columns: 1fr;
+ }
+
+ .product-photo {
+ max-width: 98px;
+ height: 164px;
+ }
+
+ .product-buy {
+ grid-column: 1 / -1;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .product-buy strong {
+ font-size: 22px;
+ }
+
+ .footer-container {
+ padding: 22px 18px;
+ }
+
+ .footer-main {
+ grid-template-columns: 1fr;
+ gap: 32px;
+ }
+
+ .footer-nav {
+ grid-template-columns: 1fr;
+ }
+
+ .contacts-card {
+ justify-self: start;
+ }
+
+ .footer-legal {
+ flex-direction: column;
+ gap: 12px;
+ }
+}
diff --git a/src/css/tokens.css b/src/css/tokens.css
new file mode 100644
index 0000000..3c27676
--- /dev/null
+++ b/src/css/tokens.css
@@ -0,0 +1,34 @@
+: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;
+}
diff --git a/src/css/ui-kit.css b/src/css/ui-kit.css
new file mode 100644
index 0000000..897d468
--- /dev/null
+++ b/src/css/ui-kit.css
@@ -0,0 +1,1390 @@
+:root {
+ --color-primary-wine-100: #4b0f24;
+ --color-primary-wine-80: #6d1c36;
+ --color-neutral-black: #161616;
+ --color-gray-600: #66605f;
+ --color-gray-300: #d9dee6;
+ --color-background-base: #f4f6f9;
+ --color-accent-gold: #b9965b;
+ --color-white: #ffffff;
+ --color-error: #a33a2f;
+
+ --font-heading: "Montserrat", "Inter", Arial, sans-serif;
+ --font-body: "Inter", Arial, sans-serif;
+
+ --spacing-1: 4px;
+ --spacing-2: 8px;
+ --spacing-3: 16px;
+ --spacing-4: 24px;
+ --spacing-5: 32px;
+ --spacing-6: 48px;
+ --spacing-7: 64px;
+
+ --radius-sm: 8px;
+ --radius-md: 12px;
+ --shadow-soft: 0 12px 32px rgba(22, 22, 22, 0.08);
+ --shadow-lift: 0 20px 52px rgba(75, 15, 36, 0.14);
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ margin: 0;
+ background: var(--color-background-base);
+ color: var(--color-neutral-black);
+ font-family: var(--font-body);
+ font-size: 16px;
+ line-height: 1.5;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+button,
+input,
+select {
+ font: inherit;
+}
+
+.sidebar {
+ 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);
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+ z-index: 5;
+}
+
+.brand {
+ display: inline-flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.brand__mark {
+ width: 44px;
+ height: 44px;
+ border-radius: var(--radius-sm);
+ background: var(--color-primary-wine-100);
+ color: var(--color-accent-gold);
+ display: inline-grid;
+ place-items: center;
+ font-family: var(--font-heading);
+ font-weight: 700;
+}
+
+.brand strong,
+.brand small {
+ display: block;
+}
+
+.brand small {
+ color: var(--color-gray-600);
+ font-size: 13px;
+}
+
+.brand--compact .brand__mark {
+ width: 36px;
+ height: 36px;
+}
+
+.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);
+ color: var(--color-gray-600);
+ font-weight: 600;
+}
+
+.side-nav a:hover {
+ background: rgba(75, 15, 36, 0.07);
+ color: var(--color-primary-wine-100);
+}
+
+.page-shell {
+ margin-left: 280px;
+ min-width: 0;
+}
+
+.kit-hero {
+ min-height: 92vh;
+ padding: 56px clamp(24px, 5vw, 72px);
+ display: grid;
+ grid-template-columns: minmax(0, 1.05fr) minmax(320px, 0.95fr);
+ align-items: center;
+ gap: 48px;
+ background:
+ radial-gradient(circle at 82% 28%, rgba(185, 150, 91, 0.25), transparent 24%),
+ linear-gradient(135deg, #ffffff 0%, #eef2f6 58%, #dde4ec 100%);
+}
+
+.kit-hero__content {
+ max-width: 720px;
+}
+
+.eyebrow,
+.muted-caps {
+ margin: 0;
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ line-height: 16px;
+ font-weight: 700;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+
+h1,
+h2,
+h3,
+p {
+ margin-top: 0;
+}
+
+h1,
+h2,
+h3 {
+ font-family: var(--font-heading);
+ line-height: 1.1;
+}
+
+h1 {
+ max-width: 780px;
+ margin-bottom: 20px;
+ font-size: clamp(40px, 5.5vw, 72px);
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+h2 {
+ margin-bottom: 0;
+ font-size: 40px;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+h3 {
+ margin-bottom: 16px;
+ font-size: 24px;
+ font-weight: 800;
+}
+
+.kit-hero p:not(.eyebrow) {
+ max-width: 640px;
+ color: var(--color-gray-600);
+ font-size: 18px;
+ line-height: 28px;
+}
+
+.hero-actions,
+.component-row,
+.chip-row {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 12px;
+}
+
+.kit-hero__visual {
+ justify-self: center;
+ width: min(100%, 420px);
+}
+
+.button {
+ min-height: 48px;
+ padding: 12px 22px;
+ border: 1px solid transparent;
+ border-radius: var(--radius-sm);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ color: var(--color-neutral-black);
+ background: transparent;
+ font-weight: 700;
+ cursor: pointer;
+ transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
+}
+
+.button:hover,
+.button.is-hover {
+ transform: translateY(-1px);
+}
+
+.button--primary {
+ background: var(--color-primary-wine-100);
+ color: var(--color-white);
+ box-shadow: 0 10px 22px rgba(75, 15, 36, 0.16);
+}
+
+.button--primary:hover,
+.button--primary.is-hover {
+ background: var(--color-primary-wine-80);
+ box-shadow: var(--shadow-lift);
+}
+
+.button--secondary {
+ border-color: rgba(75, 15, 36, 0.24);
+ background: rgba(255, 255, 255, 0.55);
+ color: var(--color-primary-wine-100);
+}
+
+.button--ghost {
+ color: var(--color-primary-wine-100);
+}
+
+.button--sm {
+ min-height: 38px;
+ padding: 8px 14px;
+ 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);
+}
+
+.section--last {
+ padding-bottom: 96px;
+}
+
+.section-heading {
+ display: grid;
+ gap: 8px;
+ 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));
+ gap: 16px;
+}
+
+.swatch,
+.template-card,
+.mini-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.74);
+}
+
+.swatch span {
+ display: block;
+ height: 88px;
+ margin-bottom: 14px;
+ border: 1px solid rgba(22, 22, 22, 0.08);
+ border-radius: var(--radius-sm);
+ background: var(--swatch);
+}
+
+.swatch strong,
+.swatch code,
+.template-card span,
+.template-card strong {
+ display: block;
+}
+
+code {
+ color: var(--color-primary-wine-80);
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 13px;
+}
+
+.typography-specimen {
+ display: grid;
+ gap: 18px;
+}
+
+.type-row {
+ padding-bottom: 18px;
+ border-bottom: 1px solid rgba(102, 96, 95, 0.16);
+ display: grid;
+ grid-template-columns: 280px minmax(0, 1fr);
+ gap: 24px;
+ align-items: baseline;
+}
+
+.type-row span {
+ color: var(--color-gray-600);
+ font-size: 13px;
+}
+
+.type-row p {
+ margin: 0;
+}
+
+.text-h1,
+.text-h2,
+.text-h3 {
+ font-family: var(--font-heading);
+ font-weight: 800;
+ text-transform: uppercase;
+}
+
+.text-h1 {
+ font-size: 48px;
+ line-height: 56px;
+}
+
+.text-h2 {
+ font-size: 36px;
+ line-height: 44px;
+}
+
+.text-h3 {
+ font-size: 28px;
+ line-height: 36px;
+}
+
+.text-body {
+ font-size: 16px;
+ line-height: 24px;
+}
+
+.text-label {
+ font-size: 12px;
+ line-height: 16px;
+ font-weight: 700;
+ text-transform: uppercase;
+}
+
+.grid-demo {
+ height: 120px;
+ padding: 16px;
+ border-radius: var(--radius-sm);
+ background: rgba(75, 15, 36, 0.06);
+ display: grid;
+ grid-template-columns: repeat(12, 1fr);
+ gap: 16px;
+}
+
+.grid-demo span {
+ border-radius: 4px;
+ background: rgba(75, 15, 36, 0.18);
+}
+
+.spacing-scale {
+ margin-top: 20px;
+ display: flex;
+ align-items: end;
+ flex-wrap: wrap;
+ gap: 18px;
+}
+
+.spacing-scale span {
+ width: var(--space);
+ height: var(--space);
+ min-width: 4px;
+ min-height: 4px;
+ background: var(--color-accent-gold);
+ color: var(--color-neutral-black);
+ font-size: 12px;
+ font-weight: 700;
+ display: grid;
+ place-items: center;
+}
+
+.token-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.token-grid code {
+ padding: 14px;
+ border-radius: var(--radius-sm);
+ 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;
+}
+
+.product-grid--3 {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.product-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: 16px;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.product-card:hover,
+.product-card--hover,
+.product-card--featured {
+ transform: translateY(-3px);
+ box-shadow: var(--shadow-lift);
+}
+
+.product-card--compact {
+ grid-template-columns: 90px minmax(0, 1fr);
+ align-items: center;
+}
+
+.product-card--compact .product-footer {
+ grid-column: 2;
+}
+
+.product-media {
+ position: relative;
+ min-height: 220px;
+ border-radius: var(--radius-sm);
+ overflow: hidden;
+ display: grid;
+ place-items: center;
+ background:
+ linear-gradient(135deg, rgba(255, 255, 255, 0.42), transparent 48%),
+ 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;
+}
+
+.product-media--wine {
+ --media-bg: linear-gradient(140deg, #5d1027, #c8a45d);
+}
+
+.product-media--amber {
+ --media-bg: linear-gradient(140deg, #a8632a, #dde4ec);
+}
+
+.product-media--green {
+ --media-bg: linear-gradient(140deg, #1f4d3a, #e8eadb);
+}
+
+.bottle {
+ width: 54px;
+ height: 152px;
+ border-radius: 16px 16px 10px 10px;
+ background: linear-gradient(90deg, #161616, #2f2a29 44%, #0c0c0c);
+ box-shadow: 18px 18px 44px rgba(22, 22, 22, 0.24);
+ position: relative;
+}
+
+.bottle::before {
+ content: "";
+ position: absolute;
+ top: -58px;
+ left: 17px;
+ width: 20px;
+ height: 72px;
+ border-radius: 8px 8px 2px 2px;
+ background: #171212;
+}
+
+.bottle::after {
+ content: "";
+ position: absolute;
+ inset: 54px 8px auto;
+ height: 42px;
+ border-radius: 4px;
+ background: #eef2f6;
+}
+
+.product-meta {
+ min-width: 0;
+}
+
+.product-meta h3 {
+ margin: 8px 0 6px;
+ font-size: 21px;
+ text-transform: uppercase;
+}
+
+.product-meta p {
+ margin: 0;
+ color: var(--color-gray-600);
+ font-size: 14px;
+}
+
+.product-footer {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+}
+
+.product-footer strong {
+ color: var(--color-primary-wine-100);
+ 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);
+ background: var(--color-white);
+ box-shadow: var(--shadow-soft);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 20px;
+}
+
+.header-demo nav {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 18px;
+ color: var(--color-gray-600);
+ font-weight: 600;
+}
+
+.component-columns,
+.catalog-pattern,
+.template-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 24px;
+}
+
+.control-stack {
+ padding: 20px;
+ border-radius: var(--radius-sm);
+ background: var(--color-white);
+ display: grid;
+ gap: 14px;
+ box-shadow: var(--shadow-soft);
+}
+
+.checkbox {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: var(--color-gray-600);
+ font-weight: 600;
+}
+
+.checkbox input {
+ width: 18px;
+ height: 18px;
+ accent-color: var(--color-primary-wine-100);
+}
+
+.chip,
+.tag {
+ min-height: 34px;
+ padding: 7px 12px;
+ border: 1px solid rgba(75, 15, 36, 0.18);
+ border-radius: var(--radius-sm);
+ background: var(--color-white);
+ color: var(--color-primary-wine-100);
+ font-size: 13px;
+ font-weight: 700;
+}
+
+.chip {
+ cursor: pointer;
+}
+
+.chip--active,
+.tag--filled {
+ background: var(--color-primary-wine-100);
+ color: var(--color-white);
+}
+
+.tag--outline {
+ background: transparent;
+ border-color: var(--color-accent-gold);
+ color: var(--color-primary-wine-100);
+}
+
+.range {
+ display: grid;
+ gap: 8px;
+ color: var(--color-gray-600);
+ font-weight: 600;
+}
+
+.range input {
+ accent-color: var(--color-primary-wine-100);
+}
+
+.input {
+ width: 100%;
+ min-height: 48px;
+ padding: 12px 14px;
+ border: 1px solid rgba(102, 96, 95, 0.24);
+ border-radius: var(--radius-sm);
+ background: var(--color-white);
+ color: var(--color-neutral-black);
+}
+
+.input--focus,
+.input:focus {
+ border-color: var(--color-primary-wine-100);
+ box-shadow: 0 0 0 3px rgba(75, 15, 36, 0.1);
+ outline: none;
+}
+
+.input--error {
+ border-color: var(--color-error);
+ color: var(--color-error);
+}
+
+.table-wrap {
+ overflow-x: auto;
+ border-radius: var(--radius-sm);
+ box-shadow: var(--shadow-soft);
+}
+
+table {
+ width: 100%;
+ min-width: 720px;
+ border-collapse: collapse;
+ background: var(--color-white);
+}
+
+th,
+td {
+ padding: 16px;
+ border-bottom: 1px solid rgba(102, 96, 95, 0.16);
+ text-align: left;
+}
+
+th {
+ background: #e8edf3;
+ color: var(--color-primary-wine-100);
+ font-size: 12px;
+ text-transform: uppercase;
+}
+
+tbody tr:hover {
+ background: rgba(75, 15, 36, 0.04);
+}
+
+.filters-panel {
+ padding: 24px;
+ border-radius: var(--radius-sm);
+ background: var(--color-white);
+ box-shadow: var(--shadow-soft);
+ display: grid;
+ gap: 14px;
+ align-content: start;
+}
+
+.mini-card {
+ min-height: 120px;
+ display: grid;
+ place-items: center;
+ color: var(--color-primary-wine-100);
+ font-family: var(--font-heading);
+ font-size: 20px;
+ font-weight: 800;
+ text-transform: uppercase;
+ text-align: center;
+}
+
+.template-grid {
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+}
+
+.template-card {
+ min-height: 148px;
+ display: grid;
+ align-content: space-between;
+}
+
+.template-card span {
+ color: var(--color-accent-gold);
+ font-size: 12px;
+ font-weight: 700;
+ text-transform: uppercase;
+}
+
+.template-card strong {
+ font-family: var(--font-heading);
+ font-size: 20px;
+ font-weight: 800;
+ line-height: 1.2;
+ text-transform: uppercase;
+}
+
+.template-spec-grid {
+ margin-top: 24px;
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 16px;
+}
+
+.template-spec {
+ 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);
+ 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) {
+ .sidebar {
+ position: static;
+ width: auto;
+ border-right: none;
+ border-bottom: 1px solid rgba(102, 96, 95, 0.18);
+ }
+
+ .side-nav {
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+ }
+
+ .page-shell {
+ margin-left: 0;
+ }
+
+ .kit-hero,
+ .component-columns,
+ .catalog-pattern {
+ grid-template-columns: 1fr;
+ }
+
+ .swatch-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));
+ }
+}
+
+@media (max-width: 760px) {
+ .sidebar {
+ padding: 18px;
+ }
+
+ .side-nav {
+ grid-template-columns: 1fr 1fr;
+ }
+
+ .kit-hero,
+ .section {
+ padding: 40px 18px;
+ }
+
+ .kit-hero {
+ min-height: auto;
+ }
+
+ h1 {
+ font-size: 42px;
+ }
+
+ h2 {
+ font-size: 34px;
+ }
+
+ .swatch-grid,
+ .shadow-grid,
+ .image-bg-grid,
+ .icon-style-grid,
+ .status-grid,
+ .production-rules,
+ .checklist-grid,
+ .product-grid--3,
+ .template-grid,
+ .template-spec-grid,
+ .screen-grid,
+ .token-grid,
+ .spec-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .type-row {
+ grid-template-columns: 1fr;
+ gap: 8px;
+ }
+
+ .header-demo {
+ align-items: flex-start;
+ flex-direction: column;
+ }
+
+ .product-card--compact {
+ grid-template-columns: 1fr;
+ }
+
+ .product-card--compact .product-footer {
+ grid-column: auto;
+ }
+
+ .screen-card {
+ min-height: 190px;
+ }
+}
diff --git a/src/index.njk b/src/index.njk
new file mode 100644
index 0000000..195234f
--- /dev/null
+++ b/src/index.njk
@@ -0,0 +1,90 @@
+---
+title: "DP Trade — Home"
+layout: layouts/default
+permalink: /
+---
+
+
+
+
DP Trade
+
Премиальный каталог вина для торговли
+
Регионы, производители, партии и коммерческие условия собраны в одном интерфейсе для быстрых закупочных решений.
+
+
+
+
+
+
+
+
+
Producers
+
Производители
+
+
Ключевые винные дома и хозяйства из портфеля DP Trade: от классических брендов до эксклюзивных партнеров.
+
+
+
+
+
+
+
+
+
+
+
+ Интервью
Интервью с Лаурой Катеной
+
+
+
+ Бренды
Catena Zapata вновь признана самым почитаемым винным брендом мира
+
+
+
+ Италия
Villa Raiano: от оливкового масла к одному из лучших фиано Италии
+
+
+
+
+
+
+
+
+
Recommendations
+
Рекомендации недели
+
+
+
+
+ Bordeaux Chateau Laroque Grand Cru France · Red dry · 2019 · 0.75 L
+
+
+
+
+ Tuscany Brunello di Montalcino Italy · Red dry · 2018 · 0.75 L
+
+
+
+
+ Mosel Riesling Kabinett Germany · White · 2021 · 0.75 L
+
+
+
+
+
+
diff --git a/src/js/inspector.js b/src/js/inspector.js
new file mode 100644
index 0000000..d5d9de8
--- /dev/null
+++ b/src/js/inspector.js
@@ -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 = `
+
+
+ `;
+ document.body.appendChild(panel);
+
+ const toggle = document.createElement('button');
+ toggle.id = 'dp-inspector-toggle';
+ toggle.title = 'Инспектор элементов (Alt+I)';
+ toggle.innerHTML = `
+
+
+ `;
+ 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 += `
+
Элемент
+
<${tag}${id}>
`;
+ html += classes.length
+ ? `
${classes.map(c => `.${c} `).join('')}
`
+ : `
Нет классов
`;
+ html += `
`;
+
+ // ── Типографика ──────────────────────────────────────────────────────────
+ html += `
+
Типографика
`;
+
+ // Шрифт
+ const fontToken = typo.fontToken
+ ? `
${typo.fontToken} ` : '';
+ html += `
+ Шрифт
+ ${typo.fontName}${fontToken}
+
`;
+
+ // Размер
+ html += `
+ Размер
+ ${typo.fontSize}
+
`;
+
+ // Насыщенность
+ html += `
+ Насыщ.
+ ${typo.fontWeight}
+
`;
+
+ // Межстрочный
+ html += `
+ Line-height
+ ${typo.lineHeight}
+
`;
+
+ // Letter-spacing
+ if (typo.letterSpacing) {
+ html += `
+ Tracking
+ ${typo.letterSpacing}
+
`;
+ }
+
+ // Text-transform
+ if (typo.textTransform) {
+ html += `
+ Transform
+ ${typo.textTransform}
+
`;
+ }
+
+ // Цвет текста
+ const colorDot = `
`;
+ const colorToken = typo.colorToken
+ ? `
${typo.colorToken} ` : '';
+ html += `
+ Цвет
+ ${colorDot}${typo.colorHex}${colorToken}
+
`;
+
+ html += `
`;
+
+ // ── Токены ───────────────────────────────────────────────────────────────
+ html += `
+
Токены${tokens.size ? ` (${tokens.size})` : ''}
`;
+
+ if (tokens.size) {
+ for (const [name, { raw, usedIn }] of tokens) {
+ const display = formatTokenValue(raw);
+ const isColor = name.startsWith('--color-');
+ const swatch = isColor
+ ? `
`
+ : `
`;
+ html += `
+ ${swatch}
+
+ ${name}
+ ${usedIn.join(', ')}
+
+ ${display}
+
`;
+ }
+ } else {
+ html += `
Нет прямых совпадений с tokens.css
`;
+ }
+ html += `
`;
+
+ // ── Стили (layout) ───────────────────────────────────────────────────────
+ if (layout.length) {
+ html += `
+
Стили
`;
+ for (const { prop, value } of layout) {
+ html += `
+ ${prop}
+ ${value}
+
`;
+ }
+ html += `
`;
+ }
+
+ 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 = 'Кликните на элемент
';
+ }
+
+ 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);
+
+})();
diff --git a/src/news-villa-raiano-v2.njk b/src/news-villa-raiano-v2.njk
new file mode 100644
index 0000000..d21e037
--- /dev/null
+++ b/src/news-villa-raiano-v2.njk
@@ -0,0 +1,78 @@
+---
+title: "DP Trade — Villa Raiano editorial"
+layout: layouts/default
+permalink: /news-villa-raiano-v2.html
+bodyClass: compact-type
+---
+
+
+
+
+
+
Новости / Villa Raiano
+
Villa Raiano: от оливкового масла к одному из лучших фиано Италии
+
6 апреля, 2026 Ирпиния, Кампания
+
+
+
+
+
+
+
+
+
+
+ Article focus
+ Семья Бассо, новая винодельня, ставка на белые вина и признание Fiano di Avellino.
+
+
+
Рассказываем о семье Бассо и винодельне Villa Raiano, совершившей небольшую революцию в Ирпинии, сменив курс с красных вин на белые. Судя по нашим последним дегустациям, у них это получилось.
+
На холмах Сан-Микеле-ди-Серино, в провинции Авеллино, расположена винодельня семьи Бассо. Название связано с корнями: Villa Raiano — историческая местность коммуны Серино, где находилась старая оливковая плантация семьи.
+
+
+
+
+
+
+
+
+
+
+
+ Timeline
+
+ 1990-е семейная маслобойня
+ 2008 новое оборудование и команда
+ 2009 винодельня на холме
+ 2024 подземная винодельня
+
+
+
+
В середине 1990-х с основанием винодельни в Ирпинии начался винодельческий бум. Первые годы для семьи Бассо были скорее хобби: они делали и разливали вино на семейной маслобойне. С 1999 по 2008 год они стали сотрудничать с энологом Луиджи Мойо, который учился вместе с Сабино Бассо в аграрном институте Авеллино.
+
«В 2008 году мы купили новое оборудование, начали сотрудничество с Фортунато Себастьяно и построили винодельню на вершине холма в Сан-Микеле-ди-Серино», — рассказывает сын Сабино Бассо, Федерико.
+
Открытие в 2009 году совпало с новым курсом: появились четыре белых вина с отдельных виноградников — три Fiano di Avellino и один Greco di Tufo. Через десять лет к работе подключилось новое поколение: «В компанию пришли я, мой брат Фабрицио и наша кузина Брунелла, дочь Симоне».
+
+
+
+
+
+
+
+
+
+
+
+
+
+
В 2024 году открылась новая подземная винодельня, полностью интегрированная в ландшафт. Сегодня Villa Raiano владеет 30 гектарами виноградников: хозяйство работает по биологическим принципам и сертифицировано с 2011 года.
+
«Мы уверены, что наш регион — земля великих белых вин», — говорит Федерико. «Сила наших DOC — в огромных различиях, которые один и тот же сорт может проявлять в разных условиях».
+
Континентальный климат позволяет ягодам созревать медленно, что делает вина особенными — как красные, так и белые. На последних дегустациях Gambero Rosso Fiano di Avellino 2024 года особенно впечатлил итальянских экспертов, получив премию Miglior Qualità Prezzo Regionale гида BereBene 2026.
+
Чем не повод самому проверить мнение Gambero Rosso?
+
+
+
+
+
diff --git a/src/news-villa-raiano.njk b/src/news-villa-raiano.njk
new file mode 100644
index 0000000..0c7cff1
--- /dev/null
+++ b/src/news-villa-raiano.njk
@@ -0,0 +1,53 @@
+---
+title: "DP Trade — Villa Raiano"
+layout: layouts/default
+permalink: /news-villa-raiano.html
+bodyClass: compact-type
+---
+
+
+
+
+
Новости / Италия
+
Villa Raiano: от оливкового масла к одному из лучших Fiano Италии
+
История семейного хозяйства из Кампании, где любовь к Ирпинии выросла из маслобойного производства в современную винодельню.
+
+
+
+
+
+
+
+
+ Villa Raiano появилась в 1996 году по инициативе семьи Бассо, известной производством оливкового масла. Первые вина делались в помещениях старого маслобойного завода, а в 2009 году хозяйство переехало в новую винодельню в Ирпинии.
+ Для DP Trade эта история важна не только как биография производителя. Villa Raiano показывает, как локальная ремесленная культура Кампании может стать точной, современной и очень узнаваемой винной стилистикой.
+ Почему Fiano di Avellino
+ Фьяно из Авеллино ценят за минеральность, плотную фактуру и способность к развитию в бутылке. В молодых винах часто появляются цитрусовые, груша, персик, травы и медовые оттенки; с возрастом они становятся глубже, прянее и сложнее.
+ Villa Raiano работает с традиционными сортами региона: Fiano, Greco, Falanghina и Aglianico. Такой фокус помогает хозяйству говорить не универсальным языком международного вина, а языком конкретного места.
+ Фокус карточки новости: семейная история, локальный сорт и ценность производителя для профессионального каталога.
+ Что показать в каталоге
+ Для товарной страницы и подборок можно вынести происхождение, сорт, стиль, потенциал выдержки и гастрономические пары. В B2B-сценарии особенно полезны быстрые маркеры: регион, апелласьон, тип вина, крепость, объем и доступность партии.
+
+
+
+
Ключевые факты
+
+
Страна Италия
+
Регион Кампания, Ирпиния
+
Основание 1996
+
Сорта Fiano, Greco, Aglianico
+
+
+
+
Для UI-kit
+
Эта страница проверяет длинный заголовок новости, текстовую статью, боковую карточку фактов и CTA обратно в каталог.
+
В каталог
+
+
+
+
+
diff --git a/src/product.njk b/src/product.njk
new file mode 100644
index 0000000..7f21620
--- /dev/null
+++ b/src/product.njk
@@ -0,0 +1,26 @@
+---
+title: "DP Trade — Product"
+layout: layouts/default
+permalink: /product.html
+---
+
+
+
+
+ Product / Default
+ Chateau Laroque Grand Cru
+ Премиальная позиция из Bordeaux для ресторанных карт и специализированной розницы.
+
+
+
+
+
diff --git a/src/ui-kit.njk b/src/ui-kit.njk
new file mode 100644
index 0000000..20e2b7e
--- /dev/null
+++ b/src/ui-kit.njk
@@ -0,0 +1,1168 @@
+---
+title: "DP Trade — Design System"
+layout: layouts/ui-kit
+permalink: /ui-kit.html
+---
+
+
+
+
+
+
+
+
+
00 Production Status
+
Статус дизайн-системы
+
+
Этот блок показывает, насколько UI-kit готов к production handoff: что можно использовать сразу, что требует детализации, и какие правила обязательны для новых экранов.
+
+
+
+ Ready
+ Catalog List Cards
+ Есть варианты, состояния, фоны изображений, shadows и реальная страница для проверки.
+
+
+ Ready
+ Navigation / Mega-menu
+ Header, dropdown, hover bridge, ширина контейнера и базовые состояния зафиксированы.
+
+
+ Ready
+ Foundations
+ Цветовые роли, типографика, сетка, spacing, tokens и shadows описаны для dev handoff.
+
+
+ Review
+ Forms / Inputs
+ Есть default/focus/error, но нужны helper text, required, disabled, textarea и validation patterns.
+
+
+ Ready
+ Templates
+ Шаблоны описывают обязательные блоки, компоненты, screen-ссылки и статус готовности.
+
+
+ Review
+ Responsive QA
+ Есть checklist и адаптивные правила, но перед релизом нужен визуальный проход по всем страницам.
+
+
+
+
+ Production rule
+ Новый компонент нельзя считать готовым без anatomy, variants, states, usage, CSS hook и responsive notes.
+
+
+ Screen rule
+ Новый экран должен быть связан с template, иметь статус, ссылку на HTML и список QA-проверок.
+
+
+ Content rule
+ Все изображения должны иметь понятный alt, стабильные размеры контейнера и не ломать layout на mobile.
+
+
+
+
Readiness Matrix
+
+
+
+
+ Раздел
+ Anatomy
+ States
+ Usage
+ Responsive
+ Status
+
+
+
+
+ Foundations
+ Да
+ Да
+ Да
+ Да
+ Ready
+
+
+ Buttons
+ Да
+ Partial
+ Да
+ Да
+ Review
+
+
+ Product Cards
+ Да
+ Да
+ Да
+ Да
+ Ready
+
+
+ Navigation
+ Да
+ Partial
+ Да
+ Partial
+ Review
+
+
+ Forms / Controls
+ Да
+ Partial
+ Да
+ Да
+ Review
+
+
+ Templates / Screens
+ Да
+ Да
+ Да
+ Да
+ Ready
+
+
+
+
+
+
+
+
+
+
01 Foundations
+
База системы
+
+
+
+
Colors
+
+
+
+ Color / Primary / Wine / 100
+ #4B0F24
+
+
+
+ Color / Primary / Wine / 80
+ #6D1C36
+
+
+
+ Color / Neutral / Black
+ #161616
+
+
+
+ Color / Neutral / Gray / 600
+ #66605F
+
+
+
+ Color / Neutral / Gray / 300
+ #D8D3CF
+
+
+
+ Color / Background / Base
+ #F4F6F9
+
+
+
+ Color / Accent / Gold
+ #B9965B
+
+
+
+
+ Text roles
+ `color.text.primary` = #161616 для заголовков и основного текста. `color.text.muted` = #66605F для meta, captions, описаний и вторичных ссылок.
+
+
+ Surface roles
+ `color.background.base` = #F4F6F9 для страницы. `color.surface.default` = #FFFFFF для карточек, форм, таблиц и dropdown.
+
+
+ Brand roles
+ `color.primary.wine.100` для CTA, активных состояний и важных ссылок. `color.accent.gold` для labels, eyebrow и editorial accents.
+
+
+ State roles
+ Error использует #A33A2F. Success/review/draft пока локальные в UI-kit; перед разработкой их нужно вынести в state tokens.
+
+
+
+
+
+
Typography
+
+
Text / Heading / H1 / Montserrat / 48 / 56
+
Rare wines for trade
+
+
+
Text / Heading / H2 / Montserrat / 36 / 44
+
Catalog collections
+
+
+
Text / Heading / H3 / Montserrat / 28 / 36
+
Producer selection
+
+
+
Text / Body / Regular / Inter / 16 / 24
+
Вина, регионы, партии и коммерческие условия в единой системе.
+
+
+
Text / Label / Caps / Inter / 12 / 16
+
FEATURED REGION
+
+
+
+ Hero / H1
+ Montserrat 700-800, uppercase, clamp 44-78px, line-height около 0.98-1.08. Используется на главной и крупных внутренних hero.
+
+
+ Catalog / Product title
+ Montserrat 800, 22-32px для list-card. Не использовать uppercase в текущем каталоге, чтобы длинные названия читались легче.
+
+
+ Article / Lead
+ Inter 22-30px, line-height 1.38-1.48. Используется как первый смысловой абзац в редакционных материалах.
+
+
+ Button / Label
+ Inter 700-800, 14-16px. Текст должен помещаться без переноса на desktop; на mobile кнопка может становиться full-width.
+
+
+
+
+
+
Grid & Spacing
+
+
+
+
+
+ 4
+ 8
+ 16
+ 24
+ 32
+ 48
+ 64
+
+
+
+ Container
+ `--container: 1240px`. Desktop width: `min(100% - 40px, var(--container))`; mobile width: `min(100% - 28px, var(--container))`.
+
+
+ Breakpoints
+ Desktop default. Tablet: max-width 1080/1100px. Mobile: max-width 720/760px depending on site vs UI-kit shell.
+
+
+ Spacing rule
+ Компоненты: 8-16px gap. Карточки/формы: 16-24px padding. Секции: 56-72px vertical padding.
+
+
+
+
+
+
Tokens
+
+ color.primary = #4B0F24
+ color.text = #161616
+ spacing.md = 16px
+ radius.sm = 8px
+ shadow.soft = 0 12px 32px rgba(22,22,22,.08)
+ shadow.lift = 0 20px 52px rgba(75,15,36,.14)
+
+
+
+ Color tokens
+ `color.primary.wine.100`, `color.primary.wine.80`, `color.accent.gold`, `color.accent.blue`, `color.background.base`, `color.surface.default`.
+
+
+ Layout tokens
+ `container.max = 1240px`, `spacing.4/8/16/24/32/48/64`, `radius.sm = 8px`, `radius.md = 12px`, `radius.lg = 24px`.
+
+
+ Typography tokens
+ `font.heading = Montserrat`, `font.body = Inter`. Размеры текста хранятся как semantic styles, а не только raw px.
+
+
+
+
+
+
Elevation & Shadows
+
+
+ Shadow / None
+ none
+ Изображения бутылок, прозрачные PNG/JPG внутри карточек, плоские служебные элементы.
+ box-shadow: none;
+
+
+ Shadow / Header / Sticky
+ Navigation depth
+ Только для sticky header: лёгкое отделение от контента при скролле.
+ 0 10px 28px rgba(22,22,22,.05)
+
+
+ Shadow / Soft
+ Base surface
+ Основной токен для карточек, footer-контейнера, форм, contact panels и info-card.
+ 0 12px 32px rgba(22,22,22,.08)
+
+
+ Shadow / Card / Product
+ Product card
+ Для bottle-card и визуальных карточек с изображением, когда нужно чуть больше воздуха.
+ 0 18px 46px rgba(18,25,38,.08)
+
+
+ Shadow / Card / Hover
+ Interactive lift
+ Hover/active состояние list-card. Используется вместе с border-color, без изменения размеров.
+ 0 22px 54px rgba(25,37,62,.13)
+
+
+ Shadow / Lift
+ Mega-menu
+ Высокий слой: dropdown, mega-menu, временно поднятые панели.
+ 0 20px 52px rgba(75,15,36,.14)
+
+
+ Shadow / Editorial / Image
+ Hero media
+ Крупные изображения в статье, где фото должно отделяться от фона страницы.
+ 0 22px 58px rgba(25,37,62,.12)
+
+
+ Shadow / Focus Ring
+ Input focus
+ Не декоративная тень, а доступное состояние focus для search/input.
+ 0 0 0 4px rgba(75,15,36,.08)
+
+
+
+
+
+
+
+
02 Components
+
Компоненты
+
+
+
+
Component Readiness
+
+
+ Required anatomy
+ Каждый production-компонент должен иметь anatomy, variants, states, sizes, usage, CSS hooks и responsive notes.
+
+
+ Required states
+ Default, Hover, Focus, Active, Disabled. Для data-heavy компонентов также Loading, Empty, Error, Selected.
+
+
+ CSS hooks
+ Использовать стабильные классы: `.button--primary`, `.product-card--list`, `.product-image--gold`, `.contact-auth-gate`.
+
+
+
+
+
+
+
+
Icon Styles
+
+
+
+ Icon / Line / Default
+ Основной стиль для header, account, cart, menu chevrons и вторичных действий. Stroke 1.75px, без заливки.
+ stroke-width: 1.75; width: 22px;
+
+
+
+ Icon / Soft Container
+ Для кликабельных icon buttons: header account/cart, toolbar actions, карточки избранного. Контейнер 44-48px.
+ background: #fff; border: rgba(75,15,36,.14);
+
+
+
+ Icon / Filled Action
+ Акцентный вариант для primary icon-only действий, selected states и важных быстрых команд. Использовать дозированно.
+ background: color.primary; color: #fff;
+
+
+
+ Icon / Utility / Small
+ Для chevron, accordion, table sorting и compact filters. Stroke 1.6px, размер 14-18px, без отдельного контейнера.
+ width: 16px; stroke-width: 1.6;
+
+
+
+
+ Size scale
+ Utility 16px, navigation 20-22px, icon button 44/48px container, primary action 48px container. SVG всегда квадратный.
+
+
+ Stroke rule
+ Базовый stroke 1.75px. Не использовать тяжёлые 2.5-3px иконки в header: они спорят с логотипом и типографикой.
+
+
+ States
+ Default, Hover, Focus, Active, Disabled, Selected. Hover меняет border/background, а не толщину линии.
+
+
+ CSS hooks
+ `.kit-icon--line`, `.kit-icon--soft`, `.kit-icon--filled`, `.kit-icon--tiny`. В рабочем header использовать тот же визуальный принцип.
+
+
+
+
+
+
Product Card
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Варианты
+ Card / Product / Default, Hover, Compact, List. List используется в каталоге и поисковой выдаче.
+
+
+ Анатомия
+ Image, Meta, Name, Details, Price, CTA. Для list-card добавляется Product info + Product buy.
+
+
+ Состояния
+ Default, Hover, Favorite, Out of stock. Hover усиливает border/shadow без изменения размеров.
+
+
+
+
+
+
Catalog List Cards
+
+
+ Card / Product / List / Default
+ Текущая карточка каталога: Image, Product info, Price, CTA. Используется для B2B-выдачи и страниц стран.
+
+
+ Card / Product / List / Compact
+ Сниженная высота, меньше изображение и короче details. Подходит для плотной выдачи и избранного.
+
+
+ Card / Product / List / Color Image
+ Цветной фон только в зоне изображения: Gold, Wine, Green. Бутылка остаётся реальной фотографией без shadow.
+
+
+ Card / Product / List / B2B Dense
+ Дополнительные параметры: тип, сорт, упаковка, артикул. Для профессионального сравнения SKU.
+
+
+ Shadow
+ Default использует Shadow / Soft. Hover использует Shadow / Card / Hover + border rgba(75,15,36,.28). Картинки бутылок всегда shadow none.
+
+
+
+
+
+
+
Image Backgrounds
+
+
+
+ Image Background / Gold
+ Для белых, сладких, премиальных и акцентных карточек. Хорошо работает с бутылками без прозрачного фона.
+ .product-image--gold { background: linear-gradient(135deg, #b9965b 0%, #d7c18b 48%, #eef2f6 100%); }
+
+
+
+ Image Background / Wine
+ Для красных вин, премиальных подборок и карточек, где нужен более сильный брендовый акцент.
+ .product-image--wine { background: linear-gradient(135deg, #6d1c36 0%, #9b5366 46%, #e6dce1 100%); }
+
+
+
+ Image Background / Green
+ Для белых, органики, свежих регионов и спокойных карточек с холодным фоном.
+ .product-image--green { background: linear-gradient(135deg, #1f4d3a 0%, #88a28e 48%, #eef2e5 100%); }
+
+
+
+ Image Background / Neutral
+ Для hover, B2B dense и ситуаций, где цвет не должен спорить с информацией.
+ background: linear-gradient(135deg, #eef2f6 0%, #dde6ef 100%);
+
+
+
+
+ Правило
+ Градиент применяется только к контейнеру изображения, не к карточке целиком. Так карточка остаётся читаемой и не превращается в баннер.
+
+
+ Изображение
+ Бутылка всегда `object-fit: contain`, `box-shadow: none`, без вылета за блок. Для JPG без прозрачности контейнер должен скрывать переполнение.
+
+
+ CSS hook
+ Для list-card использовать `.product-image product-image--gold|wine|green`. Для плиток использовать модификаторы media-контейнера.
+
+
+
+
+
+
Editorial Components
+
+
+ Article / Hero / Split
+ Заголовок, дата/мета, крупное фото. Для новостей производителей и экспертных материалов.
+
+
+ Article / Body
+ Lead, paragraph, blockquote, wide image, photo grid. Не больше 4 текстовых абзацев без визуальной паузы.
+
+
+ Article / Sidebar
+ Sticky fact block, timeline или recognition. На мобильном становится обычным блоком над текстом.
+
+
+ Guidelines
+ Отдельная страница с требованиями к заголовкам, тексту, фото, SEO и pre-publish checklist.
+
+
+ Shadow
+ Editorial hero image использует Shadow / Editorial / Image. Текстовые блоки и сайдбар остаются без декоративной тени, чтобы читать было спокойнее.
+
+
+ Production gap
+ Добавить компоненты: Article meta, Article quote, Article image caption, Related products, Related producer.
+
+
+
+
+
+
+
Navigation
+
+
+
+ Анатомия
+ Logo, Search, Phone, Account, Cart, Main nav, Mega-menu. Header sticky, две строки.
+
+
+ Состояния
+ Default, Sticky, Dropdown open, Focus. У nav hover только underline, без pill-background.
+
+
+ Dropdown
+ Mega-menu: visual image, intro, 3 content columns, popular links. Hover bridge удерживает меню.
+
+
+ Shadow
+ Header sticky использует Shadow / Header / Sticky. Mega-menu использует Shadow / Lift, потому что это слой поверх контента.
+
+
+ Production gap
+ Добавить mobile menu, active page state, account logged-in state, cart count, keyboard focus для dropdown.
+
+
+
+
+
+
+
Controls Specs
+
+
+ Filters
+ Checkbox Default/Active/Disabled, Chip Default/Active, Range Slider Default/Dragging.
+
+
+ Inputs
+ Input Default/Focus/Error/Disabled. Error меняет border и helper text, не меняет высоту поля.
+
+
+ Tags
+ Default для метаданных, Filled для выбранного статуса, Outline для мягких категорий.
+
+
+ Production gap
+ Нужны helper/error text, required label, disabled controls, textarea, select open state, clear all для фильтров.
+
+
+
+
+
+
Tables / B2B
+
+
+
+
+ SKU
+ Name
+ Region
+ Stock
+ Trade price
+
+
+
+
+ DP-1042
+ Chateau Laroque Grand Cru
+ Bordeaux
+ 48 cases
+ 3 890 ₽
+
+
+ DP-1188
+ Riesling Kabinett
+ Mosel
+ 32 cases
+ 2 150 ₽
+
+
+
+
+
+
+
Table Specs
+
+
+ Анатомия
+ Table Header, Row, Cell, Numeric cell, Actions. Горизонтальный scroll на мобильных.
+
+
+ Состояния
+ Row Default/Hover/Selected, Header, Empty, Loading. Hover используется для B2B-сканирования.
+
+
+ Использование
+ Прайс-листы, остатки, коммерческие условия и сравнение SKU.
+
+
+ Production gap
+ Добавить Empty, Loading, Selected, Actions column, numeric alignment, sticky header и mobile fallback.
+
+
+
+
+
+
+
+
03 Patterns
+
Паттерны
+
+
+
+
+
Pattern / Product Grid / 3 col
+
+
Bordeaux Grand Cru
+
Tuscany Reserve
+
Mosel Riesling
+
+
+
+
+
Content & Inner Pages
+
+
+ Pattern / News Article / Editorial
+ Split hero, date meta, lead, wide image, timeline sidebar, quote, photo grid, final CTA.
+
+
+ Pattern / About Page / Default
+ Hero + короткая история + сетка преимуществ. Подходит для корпоративной страницы без перегруза.
+
+
+ Pattern / Contacts / Form
+ Контактные панели + форма заявки менеджеру. На мобильном блоки идут одной колонкой.
+
+
+ Pattern / Contacts / Auth Gate
+ Контакты открыты, заявка заблокирована для гостя. Показываем CTA входа/регистрации и disabled-preview формы.
+
+
+ Pattern / Editorial Guidelines
+ Guideline cards + checklist. Используется как внутренняя документация для редакции и контент-менеджера.
+
+
+
+
+
+
+
+
+
04 Templates
+
Шаблоны
+
+
Templates описывают каркас страницы: обязательные блоки, опциональные зоны, компоненты и связь с реальным screen. Это не финальный экран, а правило сборки.
+
+
+
+ Template / Home
+ Hero + regions + recommendations
+
+
+ Template / Catalog
+ Filters + product grid + table mode
+
+
+ Template / Product Page
+ Gallery + meta + CTA + availability
+
+
+ Template / Producer Page
+ Story + region + producer catalog
+
+
+ Template / News Article
+ Editorial story + media + timeline
+
+
+ Template / About
+ Company story + advantages
+
+
+ Template / Contacts
+ Contact panels + manager request
+
+
+ Template / Contacts Auth
+ Open contacts + gated request form
+
+
+ Template / Article Guidelines
+ Rules + checklist + photo requirements
+
+
+
+
+ Template / Catalog
+ Product listing
+ Required: Header, catalog head, toolbar, product list, footer.
+ Components: Catalog List Card, Select, Button Secondary, Mega-menu.
+ Screen: catalog.html
+ Status: Review, needs mobile QA for dense list.
+
+
+ Template / News Article
+ Editorial story
+ Required: Article hero, date/meta, lead, body, image block, footer.
+ Optional: timeline, quote, photo grid, related products.
+ Screen: news-villa-raiano-v2.html
+ Status: Ready, content/photo rules documented.
+
+
+ Template / Contacts Auth
+ Gated request
+ Required: contacts hero, open contacts, auth gate, disabled preview, footer.
+ Components: Contact Panel, Contact Auth Gate, Button Primary/Secondary.
+ Screen: contacts-auth.html
+ Status: Review, needs real login/register routes.
+
+
+ Template / Home
+ Commercial landing
+ Required: asymmetrical hero, producer block, news block, footer.
+ Components: Header, Mega-menu, Button Primary, News Card, Producer Card.
+ Screen: index.html
+ Status: Ready, visual direction approved.
+
+
+ Template / Article Guidelines
+ Internal documentation
+ Required: page intro, rule cards, photo requirements, writing checklist.
+ Components: Guideline Card, Checklist Card, Editorial Specs.
+ Screen: article-guidelines.html
+ Status: Ready, supports content production.
+
+
+ Template / Product Page
+ Product detail
+ Required: product media, details, price/CTA, characteristics, recommendations.
+ Components: Product Media, Product Meta, Table, Product Card.
+ Screen: product.html
+ Status: Draft, needs final product content model.
+
+
+
+
+
+
+
+
05 Screens
+
Реальные экраны
+
+
Этот раздел ведёт на конкретные HTML-страницы проекта. В отличие от Templates, здесь фиксируются уже собранные экраны с реальным контентом, header/footer и состояниями.
+
+
+
+ Screen / Home / v1
+ Главная
+ Hero, производители, новости, рекомендации и общий визуальный тон сайта.
+
+
+ Screen / Catalog / v1
+ Каталог
+ Список товаров, toolbar, сортировка, текущая горизонтальная карточка каталога.
+
+
+ Screen / Product / v1
+ Карточка товара
+ Продуктовый detail layout: изображение, описание, метаданные и CTA.
+
+
+ Screen / Cards Lab / v1
+ Варианты карточек
+ Лаборатория карточек бутылок и текущих list-card состояний.
+
+
+ Screen / News / v2
+ Villa Raiano editorial
+ Журнальная статья с крупными фото, таймлайном, цитатами и финальным акцентом.
+
+
+ Screen / About / v1
+ О компании
+ Корпоративная страница: описание, преимущества, спокойная B2B-подача.
+
+
+ Screen / Contacts / v1
+ Контакты
+ Открытая форма заявки, контактные панели, юридический информационный блок.
+
+
+ Screen / Contacts / Auth
+ Контакты auth
+ Вариант, где заявка доступна только после входа или регистрации.
+
+
+ Screen / Guidelines / v1
+ Редакционный гайд
+ Требования к статьям, фотографиям, заголовкам, SEO и pre-publish checklist.
+
+
+
+
+ Screen status
+ Ready: Home, News v2, Guidelines, Cards Lab. Review: Catalog, Contacts Auth. Draft: Product, если не утверждена модель данных.
+
+
+ Screen QA
+ Каждый экран проверяется на desktop/tablet/mobile: header/footer, links, image loading, hover/focus states, overflow и читаемость текста.
+
+
+ Template link
+ Каждый screen должен соответствовать одному template. Если меняется template, связанные screens обновляются вместе с ним.
+
+
+
+
+
+
+
+
06 Handoff
+
Production checklist
+
+
Финальный список проверок перед передачей дизайна в разработку или публикацией новой страницы в UI-kit.
+
+
+
+ Design
+
+ Компонент использует существующие tokens: color, spacing, radius, shadow.
+ Есть все состояния: default, hover, focus, active, disabled, error/loading где нужно.
+ Размеры стабильны: hover, текст и динамический контент не двигают layout.
+ Компонент не дублирует уже существующий паттерн без причины.
+
+
+
+ Development
+
+ Есть CSS hook или class naming по схеме Category / Type / Variant / State.
+ В UI-kit указан usage: где компонент применяется и где не применяется.
+ Все ссылки в demo/screens ведут на реальные HTML-файлы.
+ Нет inline-логики, которая мешает переиспользовать компонент.
+
+
+
+ Responsive
+
+ Проверены desktop, tablet и mobile.
+ Карточки, таблицы и формы не переполняют контейнер.
+ Текст в кнопках и карточках не обрезается и не накладывается.
+ Таблицы имеют horizontal scroll или мобильную альтернативу.
+
+
+
+ Accessibility
+
+ Интерактивные элементы имеют видимый focus.
+ Изображения имеют осмысленный alt.
+ Кнопки и ссылки различимы по роли и тексту.
+ Цвет не является единственным способом передать состояние.
+
+
+
+ Content
+
+ Заголовки соответствуют иерархии H1/H2/H3.
+ Для статей есть лид, визуальные паузы, alt и финальный CTA.
+ Даты, имена, регионы, апелласьоны и награды проверены.
+ Изображения достаточно крупные и не выглядят случайно обрезанными.
+
+
+
+ Ready criteria
+
+ Раздел имеет описание назначения.
+ Есть пример, спецификация и ссылка на screen, если применимо.
+ Компонент или экран можно собрать без дополнительных устных пояснений.
+ Статус готовности понятен: Ready, Review или Draft.
+
+
+
+
+