# Лидерра · Developer Handoff **Версия:** v8 Forest · 2026-05-07 **Назначение:** Всё необходимое разработчику для реализации портала Лидерра без участия дизайнера. Работает поверх HTML-прототипов в `concepts/v8_*.html`. --- ## 0. TL;DR — старт за 5 минут 1. **Стек, который нельзя оспаривать:** Vue 3 + Vuetify 3, светлая тема (тёмная — v2), Yandex Cloud, Yandex 360 SSO для админки, ЮKassa primary platежи. CTO-11. 2. **Палитра v8 Forest:** скопируй [§3 «CSS-переменные»](#3-дизайн-токены-css-variables) в `assets/tokens.css` и подключи глобально. 3. **Шрифты:** Inter (Google Fonts, axis `opsz` 14..32) + JetBrains Mono. Импорт в `
` или `@import`. См. [§4](#4-типографика). 4. **Лого:** SVG inline в `assets/logo-mark.svg` (см. [§2 «Бренд»](#2-бренд)). 5. **Все 25 экранов:** живые HTML в [`concepts/`](../concepts/) — открой `v8_dashboard.html` и снимай вёрстку напрямую. WCAG 2.1 AA подтверждено axe-core 4.10.2 на 4 viewports. 6. **Если что-то непонятно — смотри [§14 «FAQ»](#14-faq)** или пиши автору. --- ## 1. Архитектура и стек ### 1.1. Технологии (зафиксировано) | Слой | Технология | Источник | |---|---|---| | Frontend | **Vue 3 + Vuetify 3** | CTO-11, не оспаривается | | Стейт | Pinia | стандарт Vue 3 | | Роутер | Vue Router 4 | стандарт | | Сборка | Vite | стандарт | | HTTP | Axios или native `fetch` | на выбор разработчика | | Charts | ApexCharts | бриф §12 — указан напрямую | | Виртуализация | `vue-virtual-scroller` | бриф §11 для Канбана | | Drag-and-drop | `@vueuse/integrations` или `vuedraggable` | для Канбана | | Backend | (out-of-scope) | Yandex Cloud, FastAPI/Node — на выбор | ### 1.2. Структура проекта (рекомендация) ``` src/ ├── assets/ │ ├── tokens.css ← из §3 этого документа │ ├── fonts.css ← @import Inter + JBM │ └── logo-mark.svg ← из §2.3 ├── components/ │ ├── shell/ │ │ ├── AppSidebar.vue │ │ ├── AppTopbar.vue │ │ └── BrandMark.vue ← inline SVG │ ├── ui/ │ │ ├── BaseButton.vue │ │ ├── BaseChip.vue ← с 14 status variants │ │ ├── BaseInput.vue │ │ ├── DataTable.vue │ │ ├── KpiCard.vue │ │ ├── SlideOverDrawer.vue │ │ └── BalanceWidget.vue ← с runway-scale │ └── domain/ │ ├── DealCard.vue │ ├── KanbanBoard.vue │ ├── ActivityLog.vue │ └── BillingTransactionRow.vue ├── pages/ │ ├── Dashboard.vue │ ├── DealsList.vue │ ├── DealCard.vue │ ├── Kanban.vue │ ├── Billing.vue │ ├── Settings.vue │ ├── Reports.vue │ ├── Login.vue │ ├── errors/ │ │ ├── NotFound.vue │ │ ├── Forbidden.vue │ │ └── ServerError.vue │ ├── admin/ │ │ ├── AdminLogin.vue │ │ ├── TenantsList.vue │ │ ├── TenantCard.vue │ │ ├── AdminBilling.vue │ │ ├── Incidents.vue │ │ └── SystemSettings.vue │ └── public/ │ ├── Home.vue │ ├── Pricing.vue │ ├── Offer.vue │ └── Privacy.vue └── App.vue ``` ### 1.3. Окружения | Окружение | Frontend | API | Что особенного | |---|---|---|---| | local | localhost:5173 | localhost:8000 | hot reload, mock data | | stage | stage.liderra.app | api.stage.liderra.app | seed-данные, без оплат | | prod | liderra.app + admin.liderra.app | api.liderra.app | полный 2FA, RLS, audit log | --- ## 2. Бренд ### 2.1. Имя **«Лидерра»** — кириллица. Wordmark с **точкой** в конце: `Лидерра.` Точка покрашена в **bright Teal `#32C8A9`** (`--side-icon-act`) на тёмном sidebar и в **базовый Teal `#0F6E56`** на светлом фоне. Латинская транслитерация: `Liderra` (для домена `liderra.app`, email `support@liderra.app`). **Tone of voice:** уверенный без помпезности, технический без сухости, премиальный без снобизма. Прямые формулировки про деньги. Никакого «эстетичного решения», «бесшовного опыта», «инновационного подхода». ### 2.2. Лого — `L-Square с Teal-точкой` ``` [ белый rounded-square 22×22 ] │ └─ внутри: L-stroke 4.5px (тёмный) + Teal-точка r=3.5 в конце ``` ### 2.3. SVG (inline, копировать в `BrandMark.vue`) ```html ``` ```html ``` ```html ``` ### 2.4. Что нельзя - Менять пропорции, цвета, обводку лого, добавлять тени/градиенты - Использовать «Лидпоток» (старое имя — deprecated) - Использовать lowercase «лидерра.» — wordmark капитализирован - Использовать слово «премиум» в маркетинге без обоснования (мы — про прозрачность и контроль, не про роскошь) --- ## 3. Дизайн-токены (CSS variables) Все токены — реальные значения из v8 Forest. Скопировать в `assets/tokens.css`, подключить в `` глобально. Все WCAG-контрасты подтверждены через axe-core 4.10.2 на 25 макетах. ```css :root { /* === ПОВЕРХНОСТИ (Forest light, hue ≈ 80, warm ivory) === */ --bg: #F6F3EC; /* Page background */ --surface: #FFFDFA; /* Карточки, поднятые поверхности */ --sunken: #F0EDE4; /* Чуть глубже bg — для table thead, sunken-areas */ --hairline: #D9D5CD; /* 1px UI-border (формальный) */ --hairline-soft: #E8E3D6; /* Внутренние дивайдеры строк */ /* === ТЕКСТ (на ivory bg, проверено WCAG AA) === */ --ink: #081319; /* 16.96:1 — primary text */ --ink-2: #343C41; /* 10.34:1 — secondary */ --ink-3: #66635C; /* 5.42:1 — muted (≥4.5:1) */ --ink-disabled: #92907B; /* 3.48:1 — для UI-компонентов / disabled fields */ /* === БРЕНД === */ --accent: #0F6E56; /* Teal — primary brand · 5.94:1 на bg */ --accent-tint: #E1EEEA; /* Tint для selection / chip-tinted */ --accent-deep: #084635; /* Hover/active state */ /* === SIDEBAR (тёмный teal-noir) === */ --side-bg: #012019; --side-text: #B1C2BD; /* 9.23:1 на side-bg */ --side-text-2: #7A8C87; /* nav-eyebrow muted */ --side-active: #13382F; /* Selected item fill */ --side-icon: #5C7A72; /* Idle icon */ --side-icon-act: #32C8A9; /* Bright Teal — active icon · 8.15:1 */ --side-hover: #0A2A22; --side-border: #1A3A30; /* === 14 СТАТУСОВ ВОРОНКИ (OKLCH, ΔE2000 ≥ 10.57) === */ --st-new-tint: #FFD8CF; --st-new-solid: #B94837; /* Новая */ --st-work-tint: #FFDBC4; --st-work-solid: #B35100; /* В работе */ --st-call-tint: #F6E2BC; --st-call-solid: #9A6700; /* Дозвон */ --st-nocall-tint: #E9E8BD; --st-nocall-solid: #7E7500; /* Не дозвон. */ --st-neg-tint: #D9EDC6; --st-neg-solid: #538200; /* Переговоры */ --st-quote-tint: #C7F0D7; --st-quote-solid: #008A4D; /* КП отправлено */ --st-think-tint: #BCF1E9; --st-think-solid: #008C7E; /* Думает */ --st-wait-tint: #BAF0F6; --st-wait-solid: #00889B; /* Ждёт оплату */ --st-paid-tint: #C0ECFF; --st-paid-solid: #007EB8; /* Оплачено */ --st-refund-tint: #D1E5FF; --st-refund-solid: #406DC8; /* Возврат */ --st-fail-tint: #E1E0FF; --st-fail-solid: #6C60C4; /* Отказ */ --st-dup-tint: #F2DAFF; --st-dup-solid: #9052AE; /* Дубликат */ --st-spam-tint: #FFD7EE; --st-spam-solid: #AA4788; /* Спам */ --st-arch-tint: #FFD6DD; --st-arch-solid: #B7445F; /* Архив */ /* === РАДИУСЫ === */ --r-xs: 4px; /* мелкие пилы (chip count, kbd, mini-badges) */ --r-sm: 6px; /* кнопки, инпуты, нав-айтемы */ --r-md: 10px; /* карточки, секции, табли */ --r-lg: 14px; /* hero-карточки, лендинг-блоки */ /* radius для аватара/чипа — 50% или 100px */ /* === ШРИФТЫ === */ --font-ui: 'Inter', system-ui, sans-serif; --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace; } ``` ### 3.1. Тени — НЕ используем **v8 Forest стилистически отказывается от теней.** Глубина обеспечивается **только 1px hairline borders**. Исключение — slide-over drawer (нужен лёгкий left-edge shadow для иерархии слоёв): ```css .drawer { box-shadow: -16px 0 40px rgba(10,19,25,0.10); } ``` Если разработчик сомневается — **не добавлять `box-shadow`**, использовать `border: 1px solid var(--hairline)`. ### 3.2. Spacing scale (4px-base) | Token | Value | Применение | |---|---|---| | 4px | xs | плотные внутренние gap | | 8px | sm | gap между кнопками в группе | | 12px | md | padding внутри карточек | | 16px | lg | gap между элементами секции | | 20-24px | xl | padding section, gap между секциями | | 32px | 2xl | page padding desktop | | 48-64px | 3xl | hero padding | --- ## 4. Типографика ### 4.1. Шрифты (Google Fonts) ```html ``` **Inter с осью `opsz`** — это Inter 4.0+, один файл с двумя «режимами»: - `font-variation-settings: 'opsz' 14` — UI-режим (мелкий текст) - `font-variation-settings: 'opsz' 28` — display-режим (заголовки) Подключается через CSS variable: ```css body { font-family: var(--font-ui); font-feature-settings: 'cv11', 'ss01', 'ss03'; /* slashed-zero, single-storey a */ font-variation-settings: 'opsz' 14; -webkit-font-smoothing: antialiased; } .page-title { font-size: 28px; font-weight: 600; font-variation-settings: 'opsz' 28; /* visual switch to display */ letter-spacing: -0.02em; } ``` ### 4.2. Шкала размеров | Применение | font-size | weight | opsz | letter-spacing | line-height | |---|---|---|---|---|---| | Hero h1 (лендинг) | 56px | 600 | 32 | -0.03em | 1.05 | | Page title | 28px | 600 | 28 | -0.02em | 1.1 | | Section h2 | 22px | 600 | 24 | -0.018em | 1.15 | | Card title | 16px | 600 | 18 | -0.012em | 1.3 | | Body | 13-14px | 400 | 14 | -0.005em | 1.5 | | Eyebrow / label | 11.5px | 500 | 14 | letter-spacing 0.005em | 1.4 | | Mono numeric | 12.5px | 500 | — | -0.005em | 1.4 | | Caption | 11px | 500 | 14 | 0.005em | 1.4 | ### 4.3. Numeric (числа = деньги) **Везде где число — `var(--font-mono)` + `font-feature-settings: 'tnum'`.** Это даёт tabular figures (одинаковая ширина цифр), без чего ровный right-align в таблицах ломается. ```css .price, .deal-price, .balance-amount, .kpi-value, .tx-amount, .timer { font-family: var(--font-mono); font-feature-settings: 'tnum'; } ``` ### 4.4. Стратегия загрузки шрифтов (audit O-stack-09) Используется `` с Google Fonts API v1 + параметр `&display=swap` (см. §4.1). - **`&display=swap`:** браузер сразу рендерит fallback-шрифт (`system-ui`), переключается на загруженный Inter/JetBrains Mono когда тот доступен. Стратегия FOUT (Flash of Unstyled Text), но без невидимого текста — лучше для UX, чем `&display=block` или дефолтный `&display=auto`. - **WOFF2 формат:** Google Fonts отдаёт WOFF2 по умолчанию для современных браузеров (Chrome 36+, Firefox 39+, Safari 12+). Сжатие лучше WOFF на 20–30%. - **Preconnect:** для ускорения первого byte рекомендуется добавить в ``: ```html ``` Это сокращает TTFB на медленных сетях (~50–200 мс). В §4.1 этот блок уже включён в snippet подключения. - **Совместимость:** для целевой аудитории Chrome 100+, Safari 15+, Firefox 95+ дополнительный fallback не нужен. Для расширенной аудитории — добавить `@font-face` с WOFF (legacy). ### 4.5. Google Fonts API v2 + @font-face fallback (audit O-stack-10) Текущий `` использует Google Fonts API v1 (`https://fonts.googleapis.com/css2?family=...`). Для расширенной совместимости с устаревшими браузерами (поддержка ниже Chrome 100 / Safari 15 / Firefox 95) можно добавить @font-face fallback: #### Когда использовать API v2 - **Целевая аудитория** Chrome 100+, Safari 15+, Firefox 95+ (default для Лидерры) — оставить только API v1, fallback не нужен. - **Расширенная аудитория** включая Chrome 50–99, Safari 12–14 — добавить @font-face WOFF fallback. #### Шаблон @font-face fallback (для расширенной совместимости) ```css @font-face { font-family: 'Inter Fallback'; src: url('/fonts/inter-variable.woff2') format('woff2-variations'), url('/fonts/inter-variable.woff') format('woff'); font-weight: 100 900; font-style: normal; font-display: swap; } @font-face { font-family: 'JetBrains Mono Fallback'; src: url('/fonts/jetbrains-mono.woff2') format('woff2'), url('/fonts/jetbrains-mono.woff') format('woff'); font-weight: 400 700; font-style: normal; font-display: swap; } ``` #### Migration path 1. Скачать `Inter` и `JetBrains Mono` с [google-webfonts-helper.herokuapp.com](https://google-webfonts-helper.herokuapp.com) или [github.com/rsms/inter/releases](https://github.com/rsms/inter/releases) и [github.com/JetBrains/JetBrainsMono/releases](https://github.com/JetBrains/JetBrainsMono/releases). 2. Поместить в `public/fonts/` (или `app/public/fonts/` для Laravel). 3. В `app/resources/css/app.css` (или Vuetify global stylesheet) добавить @font-face блоки. 4. В Vuetify config `defaults` — добавить fallback chain: `font-family: 'Inter', 'Inter Fallback', system-ui, sans-serif;`. #### Trade-offs - **+ Self-hosted шрифты** — нет зависимости от Google CDN, GDPR-friendly (нет cookies на fonts.googleapis.com). - **+ Гарантия совместимости** на 10+ лет в браузерах. - **− Размер репозитория** — +500 KB на файлы шрифтов (Inter Variable ~250 KB + JetBrains Mono ~250 KB в WOFF2). - **− Ручной upgrade** — при выходе новых версий Inter/JetBrains Mono нужно скачивать вручную (vs автообновление через Google Fonts). #### Решение для Лидерры (текущее, 09.05.2026) Используется только Google Fonts API v1 + `&display=swap` (см. §4.4). @font-face fallback **не применяется** — целевая аудитория покрывает 99%+ современных браузеров. Решение пересмотреть, если: появится требование GDPR-encryption, аудит безопасности обнаружит зависимость от внешнего CDN, или статистика браузеров покажет долю старых ≥5%. --- ## 5. Компонентная библиотека ### 5.1. AppShell — общий каркас (sidebar + topbar) Sidebar 232px sticky слева на тёмном `--side-bg`, topbar 48px sticky сверху, контент в центре. На viewport ≤ 1100px sidebar сжимается до 56px (icon-only). На ≤ 768px sidebar скрывается. Живой пример: открой [`v8_dashboard.html`](../concepts/v8_dashboard.html), изучи `.app`, `.side`, `.main`, `.topbar`. ### 5.2. Sidebar nav-item ```html ``` CSS правила см. в `v8_dashboard.html` `.nav-item` block. Selected state = solid `--side-active` fill, no border, no glow. Active icon — `--side-icon-act` (bright Teal). ### 5.3. Button ```html ``` Высоты: - 30px — icon-only - 32px — компактные / topbar / в фильтрах - 34-36px — inline в формах - 38-42px — primary CTA Variants: - `.btn` — surface + hairline border - `.btn-primary` — accent fill, white text - `.btn-danger` — `--st-new-solid` text + hover `#FFE7E2` bg ### 5.4. Status Chip — 14 вариантов Два режима: **1. Plain (dot + text, без фона)** — для таблиц, плотных строк: ```html Оплачено ``` **2. Tinted (с фоном)** — для emphasis (drawer current status, dashboard summary): ```html Оплачено ``` Все 14 классов: `chip-new`, `chip-work`, `chip-call`, `chip-nocall`, `chip-neg`, `chip-quote`, `chip-think`, `chip-wait`, `chip-paid`, `chip-refund`, `chip-fail`, `chip-dup`, `chip-spam`, `chip-arch`. Цвета — в [§3 токены](#3-дизайн-токены-css-variables). ### 5.5. Avatar (concentric ring) ```html ``` ```css .avatar { width: 26px; height: 26px; border-radius: 50%; background: var(--ink); color: #fff; /* dark variant; см. v8_* для tinted */ display: inline-flex; align-items: center; justify-content: center; font-size: 9.5px; font-weight: 600; position: relative; } .avatar::after { content: ''; position: absolute; inset: 0; border-radius: 50%; border: 1px solid rgba(10,19,25,0.10); /* concentric ring trick */ pointer-events: none; } ``` ### 5.6. Table Hairline-only, no shadows. Sticky `thead`. Hover row → `--sunken`. Selected row → solid `--ink` fill, white text. См. [`v8_deals.html`](../concepts/v8_deals.html) `.tbl`. На mobile — таблица превращается в карточки. ### 5.7. Drawer (slide-over) 460px справа, `--surface` bg, hairline left border + lazy left-edge shadow. Scrim — `rgba(10,19,25,0.18)` + `backdrop-filter: blur(2px)`. См. [`v8_deals.html`](../concepts/v8_deals.html) `.drawer`. ### 5.8. KPI card Hairline border, no shadow. Number в JBM mono с tnum. Trend = single Teal up-arrow на положительной дельте, **`--st-new-solid` red** на отрицательной. Никаких icon-чипов. См. [`v8_dashboard.html`](../concepts/v8_dashboard.html) `.kpi`. ### 5.9. Balance widget с runway-scale Наследник KPI. Те же hairlines + дополнительная Teal-рамка через `::before`. Внутри — `runway-bar` (7 сегментов hairline-tick'ов, заполненных под уровень дней). См. [`v8_dashboard.html`](../concepts/v8_dashboard.html) `.balance` + `.runway`. ### 5.10. Timeline / Activity Log Vertical 1px line + цветные точки по типу события: - `create` — Teal `--accent` - `status-change` — `--st-call-solid` (оранжевый) - `comment` — `--ink` (чёрный) - `call` — `--st-quote-solid` (зелёный) - `tag` — `--st-think-solid` (бирюзовый) - `assign` — `--st-paid-solid` (синий) - `next/dashed` — `--ink-disabled` с `border-style: dashed` Описание + старое→новое значение через `old → new` с line-through на `from` и mono font на обоих. См. [`v8_deal_card.html`](../concepts/v8_deal_card.html) `.activity`. --- ## 6. Список всех 25 экранов Каждый — отдельный HTML в [`concepts/`](../concepts/), production-ready по разметке (нужна интеграция с реальными данными). Все прошли axe-core 4.10.2 = **0 violations** на 1680/1440/768/375 (где применимо). Дата прогона: фиксируется при сборке handoff'а; отчёт axe требует подтверждения после фикса pa11y.config (audit P1-12, Sprint 1 Phase C `cc6e1cb` обновил пути на `liderra_v8_handoff/concepts/v8_*.html`). Перепрогон: `npm run a11y` из корня репозитория. ### 6.1. Кабинет тенанта (8 экранов) | ID | URL | HTML | Что внутри | |---|---|---|---| | 01 | `/login`, `/register`, `/2fa`, `/forgot-password` | [v8_login.html](../concepts/v8_login.html) | 5 состояний: login/register с zxcvbn-индикатором/2FA с 6-cell кодом/forgot/recovery с 8 одноразовыми кодами | | 02 | `/dashboard` | [v8_dashboard.html](../concepts/v8_dashboard.html) | KPI strip + Hero balance + Activity chart + Funnel-bar + Recent deals + System health + Quick actions | | 03 | `/deals` | [v8_deals.html](../concepts/v8_deals.html) | Таблица 14 строк × 14 status-chips, фильтры (search + selects + density toggle), drawer открыт статически | | 04 | `/deals/{id}` | [v8_deal_card.html](../concepts/v8_deal_card.html) | Hero + параметры + комментарий с 8 шаблонами + напоминание + footer-actions; aside: менеджер + метрики + history | | 05 | `/deals/kanban` | [v8_kanban.html](../concepts/v8_kanban.html) | 14 колонок DnD (262px каждая), карточки с иконками 🔥/⏰/✓ | | 06 | `/billing` | [v8_billing.html](../concepts/v8_billing.html) | Кошелёк ₽ + ГЦК + тариф; pending-banner; история транзакций; счета и УПД (1С 8.3 XML) | | 07 | `/settings` | [v8_settings.html](../concepts/v8_settings.html) | 8 вкладок (Профиль/Безопасность/Проекты/Команда/API/Интеграции/Тихие часы/Уведомления); 3 раскрыты | | 08 | `/reports` | [v8_reports.html](../concepts/v8_reports.html) | Форма запроса + список jobs (done/running с progressbar/queued/failed + retry); квота 2/3 | ### 6.2. Экраны ошибок (3) Все в одном файле с review-tabs: [v8_errors.html](../concepts/v8_errors.html) | ID | URL | Особенности | |---|---|---| | 09 | 404 | Декоративный SVG с маркером, кнопки «На дашборд» / «Назад» | | 10 | 403 | Replace-key SVG, `REQ-id` для копирования, mailto support | | 11 | 500/503 | Status-list (API/Telegram/YooKassa OK/деградация), `INC-id`, ссылка на status page | ### 6.3. Админка SaaS (6) Все в одном файле: [v8_admin.html](../concepts/v8_admin.html). Отдельный домен `admin.liderra.app`. Тёмная плашка `ADMIN` рядом с лого. | ID | URL | Что показано | |---|---|---| | 12 | `/admin/login` | SSO Yandex 360 primary + локальный 2FA fallback | | 13 | `/admin/tenants` | Список 142 тенанта, фильтры, статус-чипы (active/trial/overdue/suspended) | | 14 | `/admin/tenants/{id}` | Карточка тенанта: профиль, баланс, действия (impersonation, корректировка, удаление 152-ФЗ), журнал | | 15 | Impersonation-режим | Красный sticky banner + специальная аватарка `Админ → ИП` + крест выхода | | 16 | `/admin/incidents` | Журнал HIGH/MED/LOW, read-only для compliance | | 17 | `/admin/system` | 6 sys-cards: system_settings / tariff_plans / legal_entities / payment_gateways / webhook_log / auth_log | ### 6.4. Лендинг и юр. (4) Все в одном файле: [v8_landing.html](../concepts/v8_landing.html) | ID | URL | Особенности | |---|---|---| | 18 | `/` | Hero с 3 hi-cards справа + 6 features + 4 tariffs + FAQ + footer (содержимое — Lorem ipsum) | | 19 | `/pricing` | Только tariffs (4 карточки: Start/Basic/Команда POPULAR/Enterprise) | | 20 | `/legal/offer` | TOC + 8 разделов оферты (шаблон Прил. Ж) | | 21 | `/legal/privacy` | TOC + 10 разделов 152-ФЗ Politики | ### 6.5. Бренд-документация | ID | Файл | Что | |---|---|---| | BR-1 | [v8_brand.html](../concepts/v8_brand.html) | 10 имён + 5 знаков + 3 favourite combo. Архив выбора. | | BR-2 | [v8_palette_options.html](../concepts/v8_palette_options.html) | 5 палитр на выбор (А Graphite/Б Forest/В Slate-Blue/Г Champagne/Д Inverted Hero). Архив. | --- ## 7. Соглашения по доступности (WCAG 2.1 AA) ### 7.1. Что обязательно - **Все интерактивные** (``, `