diff --git a/.env.example b/.env.example index f2fcfc9..2b63511 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ # База данных -DATABASE_URL="postgresql://brandbook:brandbook@localhost:5432/brandbook" +DATABASE_URL="postgresql://brandbook:brandbook@localhost:5433/brandbook" # API (NestJS) API_PORT=3001 diff --git a/apps/web/app/foundation/logo/page.tsx b/apps/web/app/foundation/logo/page.tsx index e191fc2..fced535 100644 --- a/apps/web/app/foundation/logo/page.tsx +++ b/apps/web/app/foundation/logo/page.tsx @@ -1,10 +1,10 @@ import type { Metadata } from "next"; +import Image from "next/image"; export const metadata: Metadata = { title: "Логотип | Брендбук О!Клиника", }; -/* ─── Компонент: плашка правила ─────────────────────────────── */ function RuleTag({ children }: { children: React.ReactNode }) { return (
-

+

{title}

{subtitle && ( @@ -48,167 +44,52 @@ function Section({ ); } -/* ─── SVG-заглушка логотипа (до получения вектора) ─────────── */ -function LogoPlaceholder({ - variant = "main", - size = "md", +/* ─── Карточка логотипа с реальным изображением ─────────────── */ +function LogoCard({ + src, + alt, + label, + description, + tag, + dark = false, }: { - variant?: "main" | "general" | "inverted" | "brown" | "white"; - size?: "sm" | "md" | "lg"; + src: string; + alt: string; + label: string; + description: string; + tag: string; + dark?: boolean; }) { - const sizes = { sm: 160, md: 280, lg: 380 }; - const w = sizes[size]; - - const bg = - variant === "inverted" - ? "var(--brand-073m)" - : variant === "white" - ? "var(--brand-053m)" - : "#f8f9fa"; - - const tealColor = - variant === "inverted" || variant === "white" - ? "#ffffff" - : "var(--brand-053m)"; - - const darkColor = - variant === "inverted" || variant === "white" - ? "#ffffff" - : "var(--brand-073m)"; - - const brownColor = - variant === "brown" ? "var(--brand-080m)" : tealColor; - - return ( -
- {/* SVG-приближение логотипа */} - - {/* Графический элемент — три капли */} - - - - - {/* Текст КЛИНИКА */} - - КЛИНИКА - - - {/* Текст УХО ГОРЛО НОС */} - - УХО•ГОРЛО•НОС - - - {/* Текст ИМ. ПРОФ. */} - - ИМ. ПРОФ. Е.Н. ОЛЕНЕВОЙ - - - {/* Метка версии */} - {variant === "general" && ( - - Общий (сеть клиник) - - )} - {variant === "main" && ( - - Основной (направление) - - )} - -
- ); -} - -/* ─── Компонент: таблица охранной зоны ─────────────────────── */ -function ClearspaceDemo() { return ( -
- {/* Охранная зона — пунктирная рамка */} +
- {/* Стрелки-обозначения */} -
- x -
-
- x -
-
- x -
-
- x + className="flex items-center justify-center rounded-xl border p-8 mb-4" + style={{ + background: dark ? "var(--brand-073m)" : "#f8f9fa", + borderColor: dark ? "transparent" : "var(--bb-border)", + minHeight: 200, + }} + > + {alt}
- +

+ {label} +

+

+ {description} +

+ {tag}
); } -/* ─── Компонент: недопустимое использование ─────────────────── */ function ProhibitedItem({ label }: { label: string }) { return (
-

- {label} -

+

{label}

); } -/* ─── Главная страница «Логотип» ────────────────────────────── */ export default function LogoPage() { return (
- {/* Заголовок страницы */} + + {/* Заголовок */}
-

+

Фундамент → 1.2

@@ -243,53 +120,39 @@ export default function LogoPage() { Он не подлежит никаким изменениям и не допускается его сочетание ни с каким дополнительным текстом.

-
⚠️ - Векторный файл логотипа будет добавлен после передачи SVG-файлов. - Ниже — SVG-приближение для справки. + Изображение извлечено из PDF-брендбука. Векторный SVG будет добавлен + после передачи исходных файлов от дизайнера.

- {/* 1. Иерархия и версии */} + {/* 1. Иерархия */}
-
- -
-

- Основной логотип -

-

- Локальные версии по направлениям (ЛОР, аллергология и др.). - Применяется в точках контакта с клиентами, на лендингах и сайтах направлений. -

- Точки контакта с клиентом -
-
- -
- -
-

- Общий логотип -

-

- Версия сети клиник. Применяется для онлайн и оффлайн коммуникаций - с клиентами, во внутренней документации. Допустимо на общем сайте. -

- Сеть клиник · Документация · Сайт -
-
+ +
@@ -299,22 +162,44 @@ export default function LogoPage() { title="Цветовые варианты" subtitle="Логотип существует в нескольких вариантах в зависимости от фона носителя." > -
+
- -

+

+ Логотип на светлом фоне +
+

Основной — на светлом фоне

- -

+

+ {/* brightness(0) делает всё чёрным, invert(1) — белым */} + Логотип инвертированный +
+

Инвертированный — на тёмном фоне

- -

+

+ {/* Коричневый: насыщенный sepia + darkening */} + Логотип коричневый на форме +
+

Коричневый — на форме (бежевый костюм)

@@ -325,21 +210,28 @@ export default function LogoPage() {
-
- -
-

- Охранная зона — минимальное расстояние от логотипа до любого другого - графического элемента или края носителя. -

-

- Пунктирная рамка обозначает охранную зону. Никакие другие элементы - не должны пересекать её границы. -

-
+
+
+ {["top","bottom","left","right"].map(side => ( +
x
+ ))} + Логотип с охранной зоной
+

+ Пунктирная рамка — граница охранной зоны. Никакие другие элементы не должны её пересекать. +

{/* 4. Минимальные размеры */} @@ -348,68 +240,28 @@ export default function LogoPage() { title="Минимальные размеры" subtitle="Размеры логотипа для размещения на форме сотрудников." > -
+
- - - - + {["Размер одежды","Длина","Высота","Расположение"].map(h => ( + + ))} - - - - - - - - - - - - + {[ + ["До 46 (включительно)", "70 мм", "25,5 мм", "Левая сторона груди"], + ["От 48", "90 мм", "32,8 мм", "Левая сторона груди"], + ].map(([size, w, h, pos]) => ( + + + + + + + ))}
- Размер одежды - - Длина логотипа - - Высота логотипа - - Расположение - {h}
- До 46 (включительно) - - 70 мм - - 25,5 мм - - Левая сторона груди -
- От 48 - - 90 мм - - 32,8 мм - - Левая сторона груди -
{size}{w}{h}{pos}
@@ -419,48 +271,38 @@ export default function LogoPage() {
- - + +
- {/* 6. Скачать файлы */} -
+ {/* 6. Скачать */} +

- Векторные файлы логотипа (SVG, PNG) + Векторные файлы логотипа (SVG, AI, PNG)

Будут доступны после передачи исходных файлов от дизайнера.

-
+
); } diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 8eac42b..ddffa4d 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -11,7 +11,7 @@ const firaSans = Fira_Sans({ }); export const metadata: Metadata = { - title: "Цифровой брендбук | Клиника УХО•ГОРЛО•НОС им. проф. Е.Н. Оленевой", + title: "Цифровой брендбук | Клиника ухо, горло, нос им. проф. Е.Н.Оленевой", description: "Интерактивный брендбук — Living Styleguide oclinica.ru", }; diff --git a/apps/web/components/layout/Sidebar.tsx b/apps/web/components/layout/Sidebar.tsx index 70385ce..429f157 100644 --- a/apps/web/components/layout/Sidebar.tsx +++ b/apps/web/components/layout/Sidebar.tsx @@ -105,9 +105,9 @@ export function Sidebar() { className="text-xs leading-tight" style={{ color: "var(--bb-sidebar-text-muted)" }} > - Клиника УХО•ГОРЛО•НОС + Клиника ухо, горло, нос
- им. проф. Е.Н. Оленевой + им. проф. Е.Н.Оленевой

diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts index e9ffa30..63dc60b 100644 --- a/apps/web/next.config.ts +++ b/apps/web/next.config.ts @@ -1,7 +1,10 @@ import type { NextConfig } from "next"; +import path from "path"; const nextConfig: NextConfig = { - /* config options here */ + turbopack: { + root: path.resolve(__dirname, "../.."), + }, }; export default nextConfig; diff --git a/apps/web/public/logo/logo-large.png b/apps/web/public/logo/logo-large.png new file mode 100644 index 0000000..a6c6c39 Binary files /dev/null and b/apps/web/public/logo/logo-large.png differ diff --git a/apps/web/public/logo/logo-main.png b/apps/web/public/logo/logo-main.png new file mode 100644 index 0000000..237bb99 Binary files /dev/null and b/apps/web/public/logo/logo-main.png differ diff --git a/apps/web/public/logo/logo-transparent.png b/apps/web/public/logo/logo-transparent.png new file mode 100644 index 0000000..ddee329 Binary files /dev/null and b/apps/web/public/logo/logo-transparent.png differ diff --git a/docker-compose.yml b/docker-compose.yml index 1b40b75..8640dda 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: POSTGRES_PASSWORD: brandbook POSTGRES_DB: brandbook ports: - - "5432:5432" + - "5433:5432" volumes: - postgres_data:/var/lib/postgresql/data diff --git a/docs/SPRINTS.md b/docs/SPRINTS.md index 4515add..4a58168 100644 --- a/docs/SPRINTS.md +++ b/docs/SPRINTS.md @@ -14,33 +14,42 @@ --- -## Sprint 1 — Инициализация проекта + страница «Логотип» +## Sprint 1 — Инициализация проекта + страница «Логотип» ✅ ЗАВЕРШЁН **Цель:** Рабочее окружение, monorepo, базовая архитектура, первая живая страница брендбука — «Логотип». ### Задачи — инфраструктура -- [ ] FE: Инициализация Next.js (App Router) в `apps/web` -- [ ] BE: Инициализация NestJS в `apps/api` -- [ ] DB: Подключение PostgreSQL + Prisma, базовая схема -- [ ] Настройка Docker Compose для локальной разработки -- [ ] Настройка monorepo (pnpm workspaces) -- [ ] Создание `.env.example` -- [ ] Git: создание веток `develop` и `sprint/1` -- [ ] FE: Базовая структура брендбука (layout, боковая навигация по разделам) -- [ ] FE: Подключение шрифта Fira Sans (веб) + подготовка к DINPro (бренд) - -### Задачи — страница «Логотип» (первый контент брендбука) -- [ ] Design: Экспорт PNG логотипа из PDF для использования как placeholder -- [ ] FE: Страница `/foundation/logo` в брендбуке -- [ ] FE: Отображение обеих версий логотипа: «Общий» и «Основной» -- [ ] FE: Секция «Иерархия»: описание применения каждой версии -- [ ] FE: Секция «Цветовые варианты»: основной / инвертированный / на форме -- [ ] FE: Секция «Охранная зона» с визуализацией отступов -- [ ] FE: Секция «Минимальные размеры» (таблица: до 46 р. и от 48 р.) -- [ ] FE: Секция «Недопустимые варианты» — правило не менять и не сочетать с текстом -- [ ] FE: Placeholder-блок «Скачать вектор» (кнопка неактивна до получения SVG) - -**Результат спринта:** Запускается `pnpm dev`, открывается брендбук с навигацией. Раздел «Логотип» полностью заполнен контентом и правилами. +- [x] FE: Инициализация Next.js 16 (App Router, Tailwind 4, TypeScript) в `apps/web` +- [x] BE: Инициализация NestJS 11 в `apps/api` +- [x] DB: PostgreSQL 16 + Prisma 7, схема User + ExperimentalComponent +- [x] Настройка Docker Compose (порт 5433 — 5432 занят на хосте) +- [x] Настройка monorepo (pnpm workspaces) +- [x] Создание `.env.example` +- [x] Git: создание веток `develop` и `sprint/1`, подключён remote git.pirogov.ai +- [x] FE: Layout с боковой навигацией (все разделы, статус «скоро») +- [x] FE: Fira Sans подключён через next/font/google, CSS-токены бренда в globals.css + +### Задачи — страница «Логотип» +- [x] Design: PNG логотипа извлечён из PDF программно (PyMuPDF + Pillow) +- [x] FE: Прозрачная версия логотипа (удалён белый фон через numpy) +- [x] FE: Страница `/foundation/logo` +- [x] FE: Иерархия версий (Основной / Общий) с реальным изображением из PDF +- [x] FE: Цветовые варианты: светлый / инвертированный (CSS filter) / на форме +- [x] FE: Охранная зона с визуализацией отступов +- [x] FE: Таблица минимальных размеров (до 46 р. и от 48 р.) +- [x] FE: 6 правил недопустимого использования +- [x] FE: Placeholder «Скачать вектор» (кнопка неактивна) + +### Фактические результаты +- Брендбук запущен локально на `http://localhost:3001` +- Название клиники исправлено: «Клиника ухо, горло, нос им. проф. Е.Н.Оленевой» +- Инвертированный логотип корректно отображается (белый на тёмном фоне) + +### Технические решения Sprint 1 +- PostgreSQL запущен на порту **5433** (5432 занят на хосте) +- Логотип хранится как PNG с прозрачным фоном (`public/logo/logo-transparent.png`) +- Инверсия логотипа: CSS `filter: brightness(0) invert(1)` на прозрачном PNG +- Next.js запускается на порту **3001** (3000 занят на хосте) ---