diff --git a/apps/web/app/foundation/colors/page.tsx b/apps/web/app/foundation/colors/page.tsx index 6415516..327a2ff 100644 --- a/apps/web/app/foundation/colors/page.tsx +++ b/apps/web/app/foundation/colors/page.tsx @@ -1,6 +1,7 @@ "use client"; import { useState, useCallback } from "react"; +import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock"; import type { Metadata } from "next"; /* ─── Утилиты конвертации ──────────────────────────────────────────── */ @@ -149,6 +150,21 @@ const COLOR_MAPPING = [ web: { name: "Кремовый фон", hex: "#e9e4d4", count: 1 }, note: "Только на сайте — нет Oracal-аналога", }, + { + brand: null, + web: { name: "Коралловый", hex: "#ffa39c", count: 2 }, + note: "Только на сайте — CTA-кнопки, нет в оффлайн-палитре", + }, + { + brand: null, + web: { name: "Светло-жёлтый фон", hex: "#eef4d1", count: 1 }, + note: "Только на сайте — фон карточек отзывов", + }, + { + brand: null, + web: { name: "Светло-зелёный фон", hex: "#f2fee6", count: 1 }, + note: "Только на сайте — фон секции новостей", + }, ]; /* ─── Цвета с сайта ────────────────────────────────────────────────── */ @@ -163,6 +179,9 @@ const WEB_COLORS = [ { name: "Второстепенный текст", hex: "#949290", usage: "Подписи, второстепенный контент", count: 4, group: "Текст" }, { name: "Светло-бирюзовый фон", hex: "#b8e6ed", usage: "Фоны светлых секций с акцентом", count: 1, group: "Фоны" }, { name: "Кремовый фон", hex: "#e9e4d4", usage: "Тёплые фоны секций", count: 1, group: "Фоны" }, + { name: "Коралловый", hex: "#ffa39c", usage: "CTA-кнопки («Запишите меня!»), акцентные призывы к действию", count: 2, group: "Акценты" }, + { name: "Светло-жёлтый фон", hex: "#eef4d1", usage: "Фон карточек отзывов (секция «Отзывы о нас»)", count: 1, group: "Фоны" }, + { name: "Светло-зелёный фон", hex: "#f2fee6", usage: "Фон секции новостей", count: 1, group: "Фоны" }, ]; const CONTRAST_PAIRS = [ @@ -381,6 +400,62 @@ function exportTokens() { URL.revokeObjectURL(url); } +/* ─── LLM spec text ────────────────────────────────────────────────── */ +const LLM_COLORS_TEXT = `# ЦВЕТА — LLM-СПЕЦИФИКАЦИЯ +# Клиника ухо, горло, нос им. проф. Е.Н.Оленевой +# docs/LLM_CONTEXT.md · /foundation/colors · v2.1 · 2026-03-22 + +ФИРМЕННЫЕ ЦВЕТА (Oracal) +Oracal | Название | HEX | RGB | CSS-переменная | Применение +053M | Основной бирюзовый | #7ECFCA | rgb(126,207,202) | --brand-053m | Акцент, CTA-кнопки, иконки, активные состояния +073M | Тёмный серо-голубой | #5B7B87 | rgb(91,123,135) | --brand-073m | Тёмный фон, хедер, заголовки навигации +066M | Средний бирюзовый | #5BB5AD | rgb(91,181,173) | --brand-066m | Вторичные акценты, фоны секций +050M | Тёмно-синий | #1B4C72 | rgb(27,76,114) | --brand-050m | Наружная реклама, полиграфия, заголовки +081M | Бежевый | #C4A882 | rgb(196,168,130) | --brand-081m | Форма сотрудников, тёплые акценты +080M | Тёмно-коричневый | #5C2E0E | rgb(92,46,14) | --brand-080m | Текст на бежевом, логотип на форме +— | Белый | #FFFFFF | rgb(255,255,255) | --brand-white | Фон, инвертированный текст, логотип на тёмных + +ЦВЕТА САЙТА oclinica.ru (CSS: clinic_bootstrap_mobile/css/style.css) +Название | HEX | Группа | × | Применение +Бежевый | #BF9975 | Акценты | 12| Тёплый акцент, фоны, рамки, текст +Серо-бирюзовый | #60959C | Акценты | 7 | Холодный акцент, ссылки +Бирюзовый | #63BAC3 | Акценты | 4 | Фоны акцентных блоков, иконки +Бирюзовый средний | #52B4BD | Акценты | 4 | Вторичные цветовые акценты +Коралловый | #FFA39C | Акценты | 2 | CTA-кнопки («Запишите меня!») +Основной текст | #464646 | Текст | 3 | Цвет основного текста сайта +Второстепенный текст | #949290 | Текст | 4 | Подписи, второстепенный контент +Светло-бирюзовый фон | #B8E6ED | Фоны | 1 | Фоны светлых секций +Кремовый фон | #E9E4D4 | Фоны | 1 | Тёплые фоны секций +Светло-жёлтый фон | #EEF4D1 | Фоны | 1 | Фон карточек отзывов +Светло-зелёный фон | #F2FEE6 | Фоны | 1 | Фон секции новостей + +СООТВЕТСТВИЕ ORACAL → САЙТ +053M #7ECFCA → #63BAC3 (темнее, насыщеннее) +073M #5B7B87 → #60959C (светлее) +066M #5BB5AD → #52B4BD (смещён в синеву) +081M #C4A882 → #BF9975 (темнее, насыщеннее) +050M #1B4C72 → не найден в CSS сайта +080M #5C2E0E → не найден в CSS сайта + +КОНТРАСТНОСТЬ WCAG 2.1 +#FFFFFF / #5B7B87 | 4.6:1 | AA PASS | AAA FAIL +#FFFFFF / #1B4C72 | 9.3:1 | AA PASS | AAA PASS +#FFFFFF / #5C2E0E | 11.2:1 | AA PASS | AAA PASS +#FFFFFF / #5BB5AD | 3.0:1 | AA FAIL | AAA FAIL | только крупный текст ≥18pt +#111827 / #7ECFCA | 5.8:1 | AA PASS | AAA FAIL +#111827 / #C4A882 | 4.8:1 | AA PASS | AAA FAIL +#5C2E0E / #C4A882 | 6.7:1 | AA PASS | AAA FAIL + +ПРАВИЛА +✓ Только цвета из фирменной палитры +✓ Digital → цвета сайта; оффлайн → коды Oracal +✓ Текст на цветном фоне: минимум WCAG AA (4.5:1) +✓ Белый текст на: 073M (#5B7B87), 050M (#1B4C72), 080M (#5C2E0E) +✓ Тёмный текст на: 053M (#7ECFCA), 081M (#C4A882) +✕ Произвольные цвета вне фирменной палитры +✕ Изменение насыщенности / оттенка фирменных цветов +✕ Тёплые и холодные акценты рядом без нейтрального разделителя`.trim(); + /* ─── Страница ─────────────────────────────────────────────────────── */ export default function ColorsPage() { return ( @@ -574,7 +649,7 @@ export default function ColorsPage() { {/* 5. Применение */} -
+

Правила применения @@ -635,6 +710,105 @@ export default function ColorsPage() {

+ {/* 6. LLM-спецификация */} +
+
+

+ LLM-спецификация +

+

+ Машиночитаемые данные раздела для использования AI-ассистентами при разработке + дизайна, макетов и кода. Нажмите «Скопировать» чтобы получить полный текст. +

+
+ + {/* Фирменные цвета */} +
+ + { + const { r, g, b } = hexToRgb(c.hex); + return [ + + + {c.oracal} + , + {c.hex.toUpperCase()}, + `rgb(${r},${g},${b})`, + {c.cssVar}, + c.usage, + ]; + })} + /> +
+ + {/* Цвета сайта */} +
+ + [ + + + {c.name} + , + {c.hex.toUpperCase()}, + c.group, + String(c.count), + c.usage, + ])} + /> +
+ + {/* Контрастность */} +
+ + { + const ratio = contrastRatio(p.fg, p.bg); + const aa = ratio >= 4.5, aaa = ratio >= 7, aal = ratio >= 3; + const badge = (pass: boolean) => ( + + {pass ? "PASS" : "FAIL"} + + ); + return [ + + + {p.fg} / {p.bg} + , + `${ratio}:1`, + badge(aa), + badge(aaa), + badge(aal), + ]; + })} + /> +
+ + {/* Правила */} +
+ + +
+
+
+ ); } diff --git a/apps/web/app/foundation/typography/page.tsx b/apps/web/app/foundation/typography/page.tsx index f2a81ca..5c7afcc 100644 --- a/apps/web/app/foundation/typography/page.tsx +++ b/apps/web/app/foundation/typography/page.tsx @@ -1,4 +1,5 @@ import type { Metadata } from "next"; +import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock"; export const metadata: Metadata = { title: "Типографика. Цифровой брендбук Клиники ухо, горло, нос им. проф. Е.Н.Оленевой", @@ -28,6 +29,60 @@ const FIRA_SCALE = [ { token: "overline", size: "10px / 0.625rem",weight: "600", lh: "1.4", sample: "ФУНДАМЕНТ → 1.4" }, ]; +/* ─── LLM spec text ────────────────────────────────────────────────── */ +const LLM_TYPOGRAPHY_TEXT = `# ТИПОГРАФИКА — LLM-СПЕЦИФИКАЦИЯ +# Клиника ухо, горло, нос им. проф. Е.Н.Оленевой +# docs/LLM_CONTEXT.md · /foundation/typography · v2.0 · 2026-03-22 + +ШРИФТЫ БРЕНДА +Шрифт | Тип | Применение | CSS +DINPro | Бренд | Оффлайн, физические носители (бейджи, таблички, транспорт, форма) | font-family: 'DINPro', Arial, sans-serif +Fira Sans| Веб | Сайт, цифровые материалы, брендбук | font-family: 'Fira Sans', sans-serif; Google Fonts; weights: 300/400/500/600 + +ПРАВИЛО ВЫБОРА: носитель цифровой → Fira Sans; физический/печатный → DINPro + +DINPro — ШКАЛА (оффлайн) +Стиль | font-size | rem | weight | line-height +h1 | 40px | 2.5rem | 700 | 1.20 +h2 | 32px | 2rem | 700 | 1.25 +h3 | 24px | 1.5rem | 700 | 1.30 +h4 | 20px | 1.25rem | 700 | 1.35 +h5 | 16px | 1rem | 700 | 1.40 +h6 | 14px | 0.875rem | 700 | 1.40 + +Fira Sans — ШКАЛА (веб) +Стиль | font-size | rem | weight | line-height | letter-spacing +h1 | 40px | 2.5rem | 600 | 1.20 | -0.025em +h2 | 32px | 2rem | 600 | 1.25 | -0.020em +h3 | 24px | 1.5rem | 600 | 1.30 | -0.010em +h4 | 20px | 1.25rem | 500 | 1.35 | 0em +h5 | 16px | 1rem | 500 | 1.40 | 0em +h6 | 14px | 0.875rem | 500 | 1.40 | +0.010em +body | 16px | 1rem | 400 | 1.60 | 0em +body-sm | 14px | 0.875rem | 400 | 1.60 | 0em +caption | 12px | 0.75rem | 400 | 1.50 | +0.020em +label | 12px | 0.75rem | 500 | 1.40 | +0.030em +overline | 10px | 0.625rem | 600 | 1.40 | +0.100em (uppercase) + +ПРИМЕНЕНИЕ ПО НОСИТЕЛЮ +Носитель | Шрифт +Сайт, цифровые материалы, брендбук | Fira Sans +Форма сотрудников, бейджи | DINPro +Вывески, таблички, навигация | DINPro +Брендирование транспорта | DINPro +Визитки, листовки, полиграфия | DINPro +Telegram-бот, пуш-уведомления | Fira Sans (системный) + +ПРАВИЛА +✓ H1 — только один на странице +✓ Не пропускать уровни заголовков (h1 → h2 → h3) +✓ Минимальный размер текста на экране: 12px +✓ Кириллица → Fira Sans (не DINPro) +✓ Fira Sans: доступные веса 300 / 400 / 500 / 600 +✕ DINPro на сайте без явного согласования дизайнера +✕ Light (300) для текста < 14px +✕ Смешивать DINPro и Fira Sans на одном носителе`.trim(); + /* ─── Компоненты ───────────────────────────────────────────────────── */ function Section({ title, @@ -344,6 +399,110 @@ export default function TypographyPage() {
+ {/* LLM-спецификация */} +
+
+

+ LLM-спецификация +

+

+ Машиночитаемые данные раздела для использования AI-ассистентами при разработке + дизайна, макетов и кода. Нажмите «Скопировать» чтобы получить полный текст. +

+
+ + {/* Шрифты */} +
+ + DINPro, + "Бренд", + "Оффлайн, физические носители (бейджи, таблички, транспорт, форма)", + "'DINPro', Arial, sans-serif", + ], + [ + Fira Sans, + "Веб", + "Сайт, цифровые материалы, брендбук", + "'Fira Sans', sans-serif · Google Fonts · 300/400/500/600", + ], + ]} + /> +
+ + {/* DINPro шкала */} +
+ + { + const [px, rem] = r.size.split(" / "); + return [r.token, px, rem, r.weight, r.lh]; + })} + /> +
+ + {/* Fira Sans шкала */} +
+ + +
+ + {/* Применение */} +
+ + Fira Sans], + ["Форма сотрудников, бейджи", DINPro], + ["Вывески, таблички, навигация", DINPro], + ["Брендирование транспорта", DINPro], + ["Визитки, листовки, полиграфия", DINPro], + ["Telegram-бот, пуш-уведомления", Fira Sans (системный)], + ]} + /> +
+ + {/* Правила */} +
+ + +
+
+
+ ); } diff --git a/apps/web/components/llm/LlmBlock.tsx b/apps/web/components/llm/LlmBlock.tsx new file mode 100644 index 0000000..381904e --- /dev/null +++ b/apps/web/components/llm/LlmBlock.tsx @@ -0,0 +1,175 @@ +"use client"; + +import { useState } from "react"; + +interface LlmBlockProps { + /** Путь страницы, например "/foundation/colors" */ + path: string; + /** Версия данных, например "v2.1" */ + version: string; + /** Плоский текст для копирования */ + specText: string; + /** Содержимое блока — таблицы, правила */ + children: React.ReactNode; +} + +/** + * LlmBlock — переиспользуемый блок LLM-спецификации. + * Добавляется в конец каждой страницы брендбука, содержащей дизайн-стандарты. + * Требование: ФТ-03-LLM (TZ.md) · docs/LLM_CONTEXT.md + */ +export function LlmBlock({ path, version, specText, children }: LlmBlockProps) { + const [copied, setCopied] = useState(false); + + function handleCopy(e: React.MouseEvent) { + e.preventDefault(); + navigator.clipboard.writeText(specText); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + + return ( +
+ {/* Заголовок */} + +
+ + LLM + + + LLM-спецификация + + + · машиночитаемые данные · docs/LLM_CONTEXT.md + +
+ +
+ + {path} · {version} + + +
+
+ + {/* Содержимое */} +
+ {children} +
+
+ ); +} + +/* ─── Утилиты для содержимого блока ──────────────────────────── */ + +/** Заголовок подсекции внутри LLM-блока */ +export function LlmSection({ title }: { title: string }) { + return ( +

+ {title} +

+ ); +} + +/** Компактная таблица для LLM-блока */ +export function LlmTable({ + headers, + rows, +}: { + headers: string[]; + rows: (string | React.ReactNode)[][]; +}) { + return ( +
+ + + + {headers.map((h) => ( + + ))} + + + + {rows.map((row, ri) => ( + + {row.map((cell, ci) => ( + + ))} + + ))} + +
+ {h} +
+ {cell} +
+
+ ); +} + +/** Список правил ✓ / ✕ */ +export function LlmRules({ rules }: { rules: { ok: boolean; text: string }[] }) { + return ( +
+ {rules.map((r) => ( +
+ + {r.ok ? "✓" : "✕"} + + {r.text} +
+ ))} +
+ ); +} diff --git a/docs/LLM_CONTEXT.md b/docs/LLM_CONTEXT.md new file mode 100644 index 0000000..9bd4a28 --- /dev/null +++ b/docs/LLM_CONTEXT.md @@ -0,0 +1,376 @@ +# LLM Context — Цифровой брендбук Клиники + +## Клиника ухо, горло, нос им. проф. Е.Н.Оленевой + +**Версия контекста:** 2.1 +**Дата обновления:** 2026-03-22 +**Актуальный спринт:** Sprint 3 +**Сайт клиники:** https://oclinica.ru +**Брендбук (локально):** http://localhost:3001 +**Брендбук (production):** https://web-oclinica.vercel.app + +--- + +## Назначение файла + +Этот файл — единый источник дизайн-данных клиники в машиночитаемом формате. +Используется как контекст для LLM при: +- разработке страниц и компонентов сайта +- создании макетов и прототипов +- разработке мобильных приложений +- проектировании новых носителей бренда +- генерации CSS / Tailwind / Figma Tokens + +При работе с любым материалом клиники **всегда загружай этот файл первым**. + +--- + +## 1. О клинике + +**Полное название:** Клиника ухо, горло, нос им. проф. Е.Н.Оленевой +**Тип:** Медицинская клиника, отоларингология (ЛОР) +**Город:** Пермь +**Платформа сайта:** Drupal (тема `clinic_bootstrap_mobile`) +**Аудитория:** Пациенты, врачи клиники, подрядчики + +--- + +## 2. Цветовая палитра + +### 2.1 Фирменные цвета (Oracal — базовая палитра) + +Основаны на кодах самоклеящейся плёнки Oracal. HEX-значения — приближённые +цифровые эквиваленты. **Для печати и оффлайн-носителей используй коды Oracal, +не HEX.** + +| Oracal | Название | HEX | RGB | HSL | CSS-переменная | Применение | +|--------|-----------------------|-----------|-------------------|------------------|------------------|------------| +| 053M | Основной бирюзовый | `#7ecfca` | rgb(126,207,202) | hsl(177,47%,65%) | `--brand-053m` | Акцент, CTA-кнопки, иконки, активные состояния | +| 073M | Тёмный серо-голубой | `#5b7b87` | rgb(91,123,135) | hsl(197,20%,44%) | `--brand-073m` | Тёмный фон, хедер, заголовки навигации | +| 066M | Средний бирюзовый | `#5bb5ad` | rgb(91,181,173) | hsl(174,33%,53%) | `--brand-066m` | Вторичные акценты, фоны секций, иллюстрации | +| 050M | Тёмно-синий | `#1b4c72` | rgb(27,76,114) | hsl(208,61%,28%) | `--brand-050m` | Наружная реклама, полиграфия, заголовки на светлом | +| 081M | Бежевый | `#c4a882` | rgb(196,168,130) | hsl(33,35%,64%) | `--brand-081m` | Форма сотрудников, оффлайн носители, тёплые акценты | +| 080M | Тёмно-коричневый | `#5c2e0e` | rgb(92,46,14) | hsl(23,73%,21%) | `--brand-080m` | Текст на бежевых поверхностях, логотип на форме | +| — | Белый | `#ffffff` | rgb(255,255,255) | hsl(0,0%,100%) | `--brand-white` | Фон, инвертированный текст, логотип на тёмных фонах | + +### 2.2 Цвета сайта oclinica.ru (реальный CSS) + +Извлечены из CSS темы Drupal: +`https://perm.oclinica.ru/sites/all/themes/clinic_bootstrap_mobile/css/style.css` +Метод: python + regex + Counter, 2026-03-22 + +| Название | HEX | RGB | Группа | Вхождений | Применение на сайте | +|-----------------------|-----------|-------------------|----------|-----------|---------------------| +| Бежевый | `#bf9975` | rgb(191,153,117) | Акценты | 12 | Основной тёплый акцент, фоны, рамки, текст | +| Серо-бирюзовый | `#60959c` | rgb(96,149,156) | Акценты | 7 | Основной холодный акцент, ссылки | +| Бирюзовый | `#63bac3` | rgb(99,186,195) | Акценты | 4 | Фоны акцентных блоков, иконки | +| Бирюзовый средний | `#52b4bd` | rgb(82,180,189) | Акценты | 4 | Вторичные цветовые акценты | +| Коралловый | `#ffa39c` | rgb(255,163,156) | Акценты | 2 | CTA-кнопки («Запишите меня!») | +| Основной текст | `#464646` | rgb(70,70,70) | Текст | 3 | Цвет основного текста на сайте | +| Второстепенный текст | `#949290` | rgb(148,146,144) | Текст | 4 | Подписи, второстепенный контент | +| Светло-бирюзовый фон | `#b8e6ed` | rgb(184,230,237) | Фоны | 1 | Фоны светлых секций с акцентом | +| Кремовый фон | `#e9e4d4` | rgb(233,228,212) | Фоны | 1 | Тёплые фоны секций | +| Светло-жёлтый фон | `#eef4d1` | rgb(238,244,209) | Фоны | 1 | Фон карточек отзывов | +| Светло-зелёный фон | `#f2fee6` | rgb(242,254,230) | Фоны | 1 | Фон секции новостей | + +### 2.3 Соответствие Oracal → Сайт + +| Oracal (бренд) | HEX бренда | Сайт (цифровой) | HEX сайта | Отклонение | +|--------------------------|------------|-----------------------|-----------|------------| +| 053M Основной бирюзовый | `#7ecfca` | Бирюзовый | `#63bac3` | Темнее, насыщеннее | +| 073M Тёмный серо-голубой | `#5b7b87` | Серо-бирюзовый | `#60959c` | Светлее на сайте | +| 066M Средний бирюзовый | `#5bb5ad` | Бирюзовый средний | `#52b4bd` | Смещён в синеву | +| 081M Бежевый | `#c4a882` | Бежевый | `#bf9975` | Темнее, насыщеннее | +| 050M Тёмно-синий | `#1b4c72` | — | — | Не найден в CSS сайта | +| 080M Тёмно-коричневый | `#5c2e0e` | — | — | Не найден в CSS сайта | + +**Важно:** расхождения ожидаемы — это цифровая адаптация плёночных цветов под экран. +При разработке digital-материалов используй цвета сайта (раздел 2.2), не Oracal. + +### 2.4 Контрастность пар (WCAG 2.1) + +| Пара | Коэффициент | AA (4.5:1) | AAA (7:1) | AA large (3:1) | +|-------------------------------------------|-------------|------------|-----------|----------------| +| Белый на тёмном серо-голубом (#5b7b87) | 4.6:1 | ✓ | ✕ | ✓ | +| Белый на тёмно-синем (#1b4c72) | 9.3:1 | ✓ | ✓ | ✓ | +| Белый на тёмно-коричневом (#5c2e0e) | 11.2:1 | ✓ | ✓ | ✓ | +| Белый на среднем бирюзовом (#5bb5ad) | 3.0:1 | ✕ | ✕ | ✓ | +| Тёмный текст (#111827) на основном бирюзовом (#7ecfca) | 5.8:1 | ✓ | ✕ | ✓ | +| Тёмный текст (#111827) на бежевом (#c4a882) | 4.8:1 | ✓ | ✕ | ✓ | +| Тёмно-коричневый (#5c2e0e) на бежевом (#c4a882) | 6.7:1 | ✓ | ✕ | ✓ | + +--- + +## 3. Типографика + +### 3.1 DINPro — фирменный шрифт (оффлайн) + +**Применение:** логотип, оффлайн-носители (бейджи, навигационные таблички, транспорт, +форма сотрудников, полиграфия). +**Не использовать** на веб-сайте и в digital-материалах (лицензионный шрифт, +нет легального встраивания в веб). +**Веса:** Regular, Medium, Bold + +| Стиль | font-weight | font-size | line-height | letter-spacing | Применение | +|----------|-------------|-----------|-------------|----------------|------------| +| Display | 700 | 48px | 1.15 | -0.5px | Крупные заголовки носителей | +| H1 | 700 | 36px | 1.2 | -0.3px | Основной заголовок печатных материалов | +| H2 | 700 | 28px | 1.25 | -0.2px | Подзаголовки носителей | +| H3 | 500 | 22px | 1.3 | 0px | Подзаголовки третьего уровня | +| Body | 400 | 16px | 1.5 | 0px | Основной текст оффлайн | +| Small | 400 | 12px | 1.4 | 0.2px | Подписи, бейджи, таблички | +| Caption | 400 | 10px | 1.3 | 0.4px | Сноски, технические пометки | + +### 3.2 Fira Sans — веб-шрифт (digital) + +**Применение:** сайт oclinica.ru, цифровые коммуникации, digital-баннеры, email. +**Источник:** Google Fonts (`https://fonts.google.com/specimen/Fira+Sans`) +**Поддержка кириллицы:** да +**Используемые веса:** 300 (Light), 400 (Regular), 500 (Medium), 600 (SemiBold) +**CSS:** `font-family: 'Fira Sans', sans-serif;` + +| Стиль | font-weight | font-size | line-height | letter-spacing | Применение | +|----------------|-------------|---------------|-------------|----------------|------------| +| h1 | 600 | 2.25rem (36px)| 1.25 | -0.025em | Заголовок страницы | +| h2 | 600 | 1.875rem (30px)| 1.3 | -0.02em | Заголовок секции | +| h3 | 500 | 1.5rem (24px) | 1.375 | -0.01em | Подзаголовок | +| h4 | 500 | 1.25rem (20px)| 1.4 | 0em | Заголовок компонента | +| h5 | 500 | 1.125rem (18px)| 1.45 | 0em | Подзаголовок компонента | +| h6 | 500 | 1rem (16px) | 1.5 | 0.01em | Метка секции | +| body-large | 400 | 1.125rem (18px)| 1.6 | 0em | Лид-текст, вводный абзац | +| body | 400 | 1rem (16px) | 1.625 | 0em | Основной текст | +| body-small | 400 | 0.875rem (14px)| 1.5 | 0em | Дополнительный текст, подписи | +| caption | 300 | 0.75rem (12px)| 1.4 | 0.02em | Подписи к изображениям, сноски | +| label | 500 | 0.875rem (14px)| 1.2 | 0.03em | Метки форм | +| overline | 600 | 0.6875rem (11px)| 1.2 | 0.1em | Надписи над заголовками (uppercase) | + +**Принцип выбора шрифта:** +- Носитель цифровой → Fira Sans +- Носитель печатный / физический → DINPro + +--- + +## 4. Логотип + +### 4.1 Версии логотипа + +**Основной логотип** — включает название специализации («ухо, горло, нос»). +Используется на всех основных носителях: сайт, навигация, транспорт, форма. + +**Общий логотип** — без специализации, только название клиники или сеть. +Используется для обозначения сети клиник, в корпоративных материалах. + +### 4.2 Файлы + +| Файл | Описание | Путь в проекте | +|------|----------|----------------| +| `logo-transparent.png` | Логотип с прозрачным фоном | `apps/web/public/logo/logo-transparent.png` | + +SVG-версия ожидается (не получена от клиники). + +### 4.3 Цветовые варианты + +| Вариант | Фон | Логотип | Применение | +|---------|-----|---------|------------| +| Основной | Белый / светлый | Полноцветный | Сайт, полиграфия на белом | +| Инвертированный | Тёмный (#5b7b87, #1b4c72) | Белый (`filter: brightness(0) invert(1)`) | Хедер, тёмные секции | +| На форме (беж) | Бежевый (#c4a882 / Oracal 081M) | Коричневый (#5c2e0e / Oracal 080M) | Одежда персонала | +| На форме (синий) | Тёмно-синий (#1b4c72 / Oracal 050M) | Белый | Одежда персонала | + +### 4.4 Охранная зона + +Минимальный отступ вокруг логотипа = **высота буквы «К»** в названии. +Запрещено размещать другие элементы в охранной зоне. + +### 4.5 Минимальные размеры + +| Носитель | Размер логотипа | +|----------|----------------| +| Одежда до р.46 | 70 × 25,5 мм | +| Одежда от р.48 | 90 × 32,8 мм | + +### 4.6 Запрещено + +- Искажать пропорции +- Менять цвета на нефирменные +- Добавлять тени, обводки, эффекты +- Размещать на пёстром или плохо контрастном фоне +- Использовать низкое разрешение (< 150 dpi для печати) +- Переворачивать или отражать + +--- + +## 5. CSS-переменные брендбука + +Определены в `apps/web/app/globals.css`: + +```css +/* Цвета бренда */ +--brand-053m: #7ecfca; /* Основной бирюзовый */ +--brand-073m: #5b7b87; /* Тёмный серо-голубой */ +--brand-066m: #5bb5ad; /* Средний бирюзовый */ +--brand-050m: #1b4c72; /* Тёмно-синий */ +--brand-081m: #c4a882; /* Бежевый */ +--brand-080m: #5c2e0e; /* Тёмно-коричневый */ +--brand-white: #ffffff; /* Белый */ + +/* UI брендбука */ +--bb-sidebar-bg: ... /* Фон сайдбара */ +--bb-sidebar-border: ... /* Граница сайдбара */ +--bb-sidebar-text: ... /* Текст сайдбара */ +--bb-sidebar-text-muted: ... +--bb-sidebar-section: .../* Заголовки секций сайдбара */ +--bb-sidebar-active-bg: ... +--bb-text: ... /* Основной текст контента */ +--bb-text-muted: ... /* Приглушённый текст */ +--bb-border: ... /* Границы */ +--bb-content-bg: ... /* Фон карточек */ +``` + +--- + +## 6. Оффлайн носители + +### 6.1 Форма сотрудников + +**Варианты:** +- Бежевый: ткань цвета Oracal 081M, логотип Oracal 080M (коричневый), расположение — левая сторона груди +- Синий: ткань цвета Oracal 050M (тёмно-синий), логотип белый (Oracal 010), расположение — левая сторона груди + +**Размеры логотипа на форме:** +- Размеры до 46: 70 × 25,5 мм +- Размеры от 48: 90 × 32,8 мм + +### 6.2 Бейджи + +**Размер:** 70 × 30 мм +**Варианты:** серый (светлый) и белый +**Состав текста:** имя, должность, учёная степень (при наличии) +**Шрифт:** DINPro +**Логотип:** левый верхний угол или левая часть + +### 6.3 Внутренняя навигация + +**Материал:** оргстекло +**Плёнки:** Oracal 053M (бирюзовый) и 073M (тёмный серо-голубой) +**Типы табличек:** +- Таблички на дверях кабинетов: номер кабинета, профиль врача с фото и QR-кодом +- Указатели по этажам: стрелки направлений + номера кабинетов + +**Нумерация кабинетов:** +- Двузначное число, крупный шрифт (DINPro Bold) +- Фон: бирюзовый (053M), номер: белый +- Пример реализации: кабинеты 13, 31, «Кабинет 04» + +### 6.4 Брендирование транспорта (трамвай) + +**Зоны оклейки:** +- Борта: Oracal 053M (#7ecfca) + 073M (#5b7b87) +- Передняя часть: Oracal 066M (#5bb5ad) + 050M (#1b4c72) +- Акценты: Oracal 081M (#c4a882) + 080M (#5c2e0e) + +**Все 6 фирменных цветов присутствуют на транспорте.** + +--- + +## 7. Структура брендбука (страницы) + +| URL | Статус | Описание | +|-----|--------|----------| +| `/foundation/logo` | ✅ Готова | Логотип, варианты, охранная зона, правила | +| `/foundation/colors` | ✅ Готова | Палитра, контраст WCAG, цвета сайта, соответствие | +| `/foundation/typography` | ✅ Готова | DINPro + Fira Sans, шкала стилей | +| `/foundation/icons` | 🔜 Скоро | Иконография | +| `/offline/uniform` | ✅ Готова | Форма сотрудников | +| `/offline/badges` | ✅ Готова | Бейджи | +| `/offline/navigation` | ✅ Готова | Внутренняя навигация | +| `/offline/transport` | ✅ Готова | Брендирование транспорта | +| `/components/buttons` | 🔜 Sprint 3 | Кнопки | +| `/components/forms` | 🔜 Sprint 3 | Форм-контролы | +| `/components/*` | 🔜 Sprint 3–4 | Карточки, бейджи, алерты, модалки, таблицы | +| `/blocks/*` | 🔜 Sprint 5–8 | Hero, врачи, отзывы, новости, формы | +| `/pages/*` | 🔜 Sprint 9–11 | Главная, заболевание, врачи, цены, контакты | + +--- + +## 8. Правила применения цветов + +### Разрешено +- Использовать только цвета из фирменной палитры (раздел 2.1) +- Для digital: адаптировать к цветам сайта (раздел 2.2) +- Текст на цветном фоне — минимум WCAG AA (4.5:1) +- Белый логотип на тёмных фонах (073M, 050M, 080M) +- Коричневый логотип (080M) на бежевом фоне (081M) + +### Запрещено +- Использовать произвольные цвета вне палитры +- Осветлять, затемнять или менять оттенок фирменных цветов +- Текст с контрастом ниже 3:1 (даже для крупного текста) +- Размещать тёплые и холодные акценты рядом без разделителя + +### Иерархия цветов + +``` +Основной бирюзовый (053M / #7ecfca) ← главный идентификатор бренда + └── Средний бирюзовый (066M / #5bb5ad) ← вторичный акцент + └── Тёмный серо-голубой (073M / #5b7b87) ← фоны, хедер + +Тёмно-синий (050M / #1b4c72) ← авторитет, полиграфия +Бежевый (081M / #c4a882) ← тепло, форма + └── Тёмно-коричневый (080M / #5c2e0e) ← текст на бежевом +``` + +--- + +## 9. Правила применения типографики + +### Веб (Fira Sans) +- H1 только один на странице +- Заголовки не пропускать по уровням (h1→h2→h3) +- Основной текст: 16px / 400 / 1.625 +- Минимальный размер текста на экране: 12px +- Кириллица: только Fira Sans, не DINPro + +### Оффлайн (DINPro) +- Все физические носители: DINPro +- Логотип: DINPro Bold +- Таблички: DINPro Medium / Bold +- Не использовать light (300) для текста < 14pt + +--- + +## 10. Технический стек проекта + +| Слой | Технология | Версия | +|------|-----------|--------| +| Фронтенд | Next.js App Router | 16.x | +| Стилизация | Tailwind CSS | 4.x | +| Язык | TypeScript | 5.x | +| Шрифты | next/font/google | — | +| Бэкенд | NestJS | 11.x | +| БД | PostgreSQL + Prisma | 16.x / 7.x | +| Деплой | Vercel Hobby | — | +| Пакетный менеджер | pnpm | 10.x | + +--- + +## 11. История изменений контекста + +| Версия | Дата | Что добавлено | +|--------|------|---------------| +| 1.0 | 2026-03-22 | Sprint 1: логотип, базовые цвета | +| 2.0 | 2026-03-22 | Sprint 2: типографика, оффлайн носители, цвета сайта (8 цветов) | +| 2.1 | 2026-03-22 | Sprint 2 доп.: +3 цвета сайта (коралловый, светло-жёлтый, светло-зелёный) | + +--- + +## 12. Что обновлять в этом файле + +При каждом спринте добавляй: +- Новые компоненты и их спецификации (цвета, размеры, состояния) +- Новые правила применения, выявленные при разработке +- Изменения в палитре или типографике +- Новые паттерны и примеры кода + +**Соответствующий раздел в TZ.md:** ФТ-03-LLM +**Соответствующий раздел в SPRINTS.md:** задача «LLM-блок» в каждом спринте diff --git a/docs/SPRINTS.md b/docs/SPRINTS.md index fa1b050..2f24992 100644 --- a/docs/SPRINTS.md +++ b/docs/SPRINTS.md @@ -98,26 +98,38 @@ - Реальные фото и макеты из PDF: PyMuPDF (fitz) — извлечение растровых изображений и рендер векторных страниц - Рендер PDF страниц: 2.5–3.0x масштаб → JPEG, кроп до нужной области через Pillow +### Ретроспектива Sprint 2 — LLM-контекст +- [x] Docs: Создан `docs/LLM_CONTEXT.md` — сводный файл дизайн-данных для LLM (v2.1) +- [x] TZ: Добавлено требование ФТ-03-LLM — LLM-блок на каждой странице брендбука +- [ ] FE: Добавить LLM-блоки на страницы Sprint 1–2 (логотип, цвета, типографика, оффлайн) — перенесено в Sprint 3 + **Результат спринта:** Разделы «Цвета», «Типографика» и «Оффлайн элементы» полностью готовы с реальными материалами из брендбука. --- ## Sprint 3 — Базовые компоненты: кнопки и поля ввода -**Цель:** Все варианты кнопок и форм-контролов в брендбуке. +**Цель:** Все варианты кнопок и форм-контролов в брендбуке. LLM-блоки на страницах. -### Задачи +### Задачи — LLM-контекст +- [ ] FE: Добавить LLM-блок на страницу «Логотип» (`/foundation/logo`) +- [x] FE: Добавить LLM-блок на страницу «Цвета» (`/foundation/colors`) — v2.1 +- [x] FE: Добавить LLM-блок на страницу «Типографика» (`/foundation/typography`) — v2.0 +- [x] FE: Создать переиспользуемый компонент `components/llm/LlmBlock.tsx` (LlmBlock, LlmSection, LlmTable, LlmRules) +- [ ] Docs: Обновить `docs/LLM_CONTEXT.md` по итогам спринта (версия 3.x) + +### Задачи — компоненты - [ ] FE: Компонент Button (все варианты: primary/secondary/ghost/danger, размеры, состояния) - [ ] FE: Компонент Input (text, password, focus/error/disabled) - [ ] FE: Компонент Textarea - [ ] FE: Компонент Select - [ ] FE: Компонент Checkbox и Radio - [ ] FE: Компонент Toggle/Switch -- [ ] FE: Страница брендбука «Компоненты → Кнопки» с документацией -- [ ] FE: Страница брендбука «Компоненты → Форм-контролы» +- [ ] FE: Страница брендбука «Компоненты → Кнопки» с документацией + LLM-блок +- [ ] FE: Страница брендбука «Компоненты → Форм-контролы» + LLM-блок - [ ] FE: Копирование HTML/CSS кода компонента в один клик -**Результат спринта:** Раздел «Базовые компоненты — кнопки и ввод» готов. +**Результат спринта:** Раздел «Базовые компоненты — кнопки и ввод» готов. LLM-блоки добавлены на страницы Фундамента. --- @@ -126,6 +138,8 @@ **Цель:** Все типы карточек, используемых на сайте. ### Задачи +- [ ] Docs: Обновить `docs/LLM_CONTEXT.md` — добавить спецификации карточек +- [ ] FE: Добавить LLM-блок на страницу «Карточки» - [ ] FE: Карточка врача (DoctorCard) — фото, имя, специализация, кнопка записи - [ ] FE: Карточка услуги / заболевания - [ ] FE: Карточка новости — превью, дата, заголовок, анонс, читать далее @@ -143,6 +157,8 @@ **Цель:** Ключевые верхние блоки страниц. ### Задачи +- [ ] Docs: Обновить `docs/LLM_CONTEXT.md` — добавить спецификации Hero и CEO-блоков +- [ ] FE: Добавить LLM-блоки на страницы Hero и CEO-текст - [ ] FE: Hero-блок вариант 1 — фон + заголовок + CTA - [ ] FE: Hero-блок вариант 2 — иллюстрация сбоку - [ ] FE: Hero-блок вариант 3 — с встроенной формой записи @@ -160,6 +176,8 @@ **Цель:** Блоки и компоненты, связанные с врачами. ### Задачи +- [ ] Docs: Обновить `docs/LLM_CONTEXT.md` — добавить спецификации блоков врачей +- [ ] FE: Добавить LLM-блок на страницу «Блоки → Врачи» - [ ] FE: Блок «Наши врачи» — сетка карточек с фильтром по специализации - [ ] FE: Блок «Врач — профиль» (полная страница): фото, биография, специализации, расписание - [ ] FE: Компонент «Расписание / слоты записи» @@ -176,6 +194,8 @@ **Цель:** Контентные блоки сайта. ### Задачи +- [ ] Docs: Обновить `docs/LLM_CONTEXT.md` — добавить спецификации блоков отзывов и новостей +- [ ] FE: Добавить LLM-блок на страницу «Блоки → Отзывы и новости» - [ ] FE: Блок отзывов — карусель - [ ] FE: Блок отзывов — статичная сетка - [ ] FE: Блок рейтинга (звёзды + количество отзывов) @@ -194,6 +214,8 @@ **Цель:** Все формы и диалоги взаимодействия с пациентом. ### Задачи +- [ ] Docs: Обновить `docs/LLM_CONTEXT.md` — добавить спецификации форм и модальных окон +- [ ] FE: Добавить LLM-блок на страницу «Блоки → Формы и контакты» - [ ] FE: Форма записи — короткая (имя, телефон) - [ ] FE: Форма записи — расширенная (имя, телефон, специализация, врач, дата) - [ ] FE: Форма записи в модальном окне diff --git a/docs/TZ.md b/docs/TZ.md index cd1f26b..37e5358 100644 --- a/docs/TZ.md +++ b/docs/TZ.md @@ -153,6 +153,17 @@ - HTML-код компонента с кнопкой «Скопировать» - Краткое описание и правила применения +**ФТ-03-LLM.** На каждой странице брендбука, содержащей дизайн-стандарты (цвета, типографика, +компоненты, блоки, страницы), должен присутствовать **LLM-блок** — свёрнутая или отдельная +секция с машиночитаемым описанием стандарта для использования языковыми моделями при +разработке дизайна, макетов, сайта и приложений. LLM-блок содержит: +- Все токены и значения в табличном формате +- Правила применения в формате «разрешено / запрещено» +- Взаимосвязи с другими стандартами (ссылки на разделы) +- Примеры корректного и некорректного использования + +Сводный LLM-контекст всего брендбука хранится в файле: **`docs/LLM_CONTEXT.md`** + --- ### 5.2 Раздел «Цвета»