feat(sprint-1): финальные правки — логотип, название клиники, порты
- PNG логотипа извлечён из PDF (PyMuPDF + Pillow), прозрачный фон (numpy) - Инвертированный логотип: CSS filter brightness(0) invert(1) на прозрачном PNG - Исправлено название: «Клиника ухо, горло, нос им. проф. Е.Н.Оленевой» - PostgreSQL переведён на порт 5433 (5432 занят на хосте) - next.config.ts: turbopack.root для монорепо - docs/SPRINTS.md: Sprint 1 помечен ✅ ЗАВЕРШЁН Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -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
|
||||
|
||||
@@ -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 (
|
||||
<span
|
||||
@@ -16,7 +16,6 @@ function RuleTag({ children }: { children: React.ReactNode }) {
|
||||
);
|
||||
}
|
||||
|
||||
/* ─── Компонент: секция брендбука ────────────────────────────── */
|
||||
function Section({
|
||||
id,
|
||||
title,
|
||||
@@ -31,10 +30,7 @@ function Section({
|
||||
return (
|
||||
<section id={id} className="mb-12">
|
||||
<div className="mb-6">
|
||||
<h2
|
||||
className="text-xl font-semibold"
|
||||
style={{ color: "var(--bb-text)" }}
|
||||
>
|
||||
<h2 className="text-xl font-semibold" style={{ color: "var(--bb-text)" }}>
|
||||
{title}
|
||||
</h2>
|
||||
{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 (
|
||||
<div
|
||||
className="flex items-center justify-center rounded-lg border p-6"
|
||||
style={{
|
||||
background: bg,
|
||||
borderColor:
|
||||
variant === "inverted" || variant === "white"
|
||||
? "transparent"
|
||||
: "var(--bb-border)",
|
||||
width: w,
|
||||
minHeight: Math.round(w * 0.55),
|
||||
}}
|
||||
>
|
||||
{/* SVG-приближение логотипа */}
|
||||
<svg
|
||||
viewBox="0 0 240 120"
|
||||
width={w - 48}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-label="Логотип Клиника УХО ГОРЛО НОС"
|
||||
>
|
||||
{/* Графический элемент — три капли */}
|
||||
<ellipse cx="18" cy="22" rx="8" ry="12" fill={brownColor} />
|
||||
<ellipse cx="30" cy="10" rx="6" ry="9" fill={brownColor} />
|
||||
<ellipse cx="10" cy="38" rx="10" ry="7" fill={brownColor} opacity="0.85" />
|
||||
|
||||
{/* Текст КЛИНИКА */}
|
||||
<text
|
||||
x="46"
|
||||
y="26"
|
||||
fontFamily="Arial, sans-serif"
|
||||
fontWeight="700"
|
||||
fontSize="20"
|
||||
fill={darkColor}
|
||||
letterSpacing="1"
|
||||
>
|
||||
КЛИНИКА
|
||||
</text>
|
||||
|
||||
{/* Текст УХО ГОРЛО НОС */}
|
||||
<text
|
||||
x="46"
|
||||
y="54"
|
||||
fontFamily="Arial, sans-serif"
|
||||
fontWeight="700"
|
||||
fontSize="20"
|
||||
fill={tealColor}
|
||||
letterSpacing="1"
|
||||
>
|
||||
УХО•ГОРЛО•НОС
|
||||
</text>
|
||||
|
||||
{/* Текст ИМ. ПРОФ. */}
|
||||
<text
|
||||
x="46"
|
||||
y="78"
|
||||
fontFamily="Arial, sans-serif"
|
||||
fontWeight="400"
|
||||
fontSize="14"
|
||||
fill={darkColor}
|
||||
letterSpacing="0.5"
|
||||
>
|
||||
ИМ. ПРОФ. Е.Н. ОЛЕНЕВОЙ
|
||||
</text>
|
||||
|
||||
{/* Метка версии */}
|
||||
{variant === "general" && (
|
||||
<text
|
||||
x="46"
|
||||
y="100"
|
||||
fontFamily="Arial, sans-serif"
|
||||
fontWeight="400"
|
||||
fontSize="10"
|
||||
fill={darkColor}
|
||||
opacity="0.5"
|
||||
>
|
||||
Общий (сеть клиник)
|
||||
</text>
|
||||
)}
|
||||
{variant === "main" && (
|
||||
<text
|
||||
x="46"
|
||||
y="100"
|
||||
fontFamily="Arial, sans-serif"
|
||||
fontWeight="400"
|
||||
fontSize="10"
|
||||
fill={darkColor}
|
||||
opacity="0.5"
|
||||
>
|
||||
Основной (направление)
|
||||
</text>
|
||||
)}
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ─── Компонент: таблица охранной зоны ─────────────────────── */
|
||||
function ClearspaceDemo() {
|
||||
return (
|
||||
<div className="inline-flex items-center justify-center rounded-lg border p-10 relative"
|
||||
style={{ borderColor: "var(--bb-border)", background: "#f8f9fa" }}
|
||||
>
|
||||
{/* Охранная зона — пунктирная рамка */}
|
||||
<div>
|
||||
<div
|
||||
className="absolute inset-6 border-2 border-dashed rounded"
|
||||
style={{ borderColor: "var(--brand-053m)", opacity: 0.4 }}
|
||||
/>
|
||||
{/* Стрелки-обозначения */}
|
||||
<div className="absolute top-1.5 left-1/2 -translate-x-1/2 text-[10px]"
|
||||
style={{ color: "var(--brand-053m)" }}>
|
||||
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,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={src}
|
||||
alt={alt}
|
||||
width={320}
|
||||
height={130}
|
||||
className="object-contain"
|
||||
style={{ filter: dark ? "brightness(0) invert(1)" : undefined }}
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute bottom-1.5 left-1/2 -translate-x-1/2 text-[10px]"
|
||||
style={{ color: "var(--brand-053m)" }}>
|
||||
x
|
||||
</div>
|
||||
<div className="absolute left-1.5 top-1/2 -translate-y-1/2 text-[10px]"
|
||||
style={{ color: "var(--brand-053m)" }}>
|
||||
x
|
||||
</div>
|
||||
<div className="absolute right-1.5 top-1/2 -translate-y-1/2 text-[10px]"
|
||||
style={{ color: "var(--brand-053m)" }}>
|
||||
x
|
||||
</div>
|
||||
<LogoPlaceholder variant="main" size="sm" />
|
||||
<p className="font-medium text-sm mb-1" style={{ color: "var(--bb-text)" }}>
|
||||
{label}
|
||||
</p>
|
||||
<p className="text-sm mb-2" style={{ color: "var(--bb-text-muted)" }}>
|
||||
{description}
|
||||
</p>
|
||||
<RuleTag>{tag}</RuleTag>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ─── Компонент: недопустимое использование ─────────────────── */
|
||||
function ProhibitedItem({ label }: { label: string }) {
|
||||
return (
|
||||
<div
|
||||
@@ -216,23 +97,19 @@ function ProhibitedItem({ label }: { label: string }) {
|
||||
style={{ borderColor: "#fecaca", background: "#fff5f5" }}
|
||||
>
|
||||
<span className="text-red-400 text-lg leading-none mt-0.5">✕</span>
|
||||
<p className="text-sm" style={{ color: "#7f1d1d" }}>
|
||||
{label}
|
||||
</p>
|
||||
<p className="text-sm" style={{ color: "#7f1d1d" }}>{label}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ─── Главная страница «Логотип» ────────────────────────────── */
|
||||
export default function LogoPage() {
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto px-8 py-10">
|
||||
{/* Заголовок страницы */}
|
||||
|
||||
{/* Заголовок */}
|
||||
<div className="mb-10 pb-6 border-b" style={{ borderColor: "var(--bb-border)" }}>
|
||||
<p
|
||||
className="text-xs font-semibold uppercase tracking-widest mb-2"
|
||||
style={{ color: "var(--brand-053m)" }}
|
||||
>
|
||||
<p className="text-xs font-semibold uppercase tracking-widest mb-2"
|
||||
style={{ color: "var(--brand-053m)" }}>
|
||||
Фундамент → 1.2
|
||||
</p>
|
||||
<h1 className="text-3xl font-semibold mb-3" style={{ color: "var(--bb-text)" }}>
|
||||
@@ -243,53 +120,39 @@ export default function LogoPage() {
|
||||
Он не подлежит никаким изменениям и не допускается его сочетание ни с каким
|
||||
дополнительным текстом.
|
||||
</p>
|
||||
|
||||
<div
|
||||
className="mt-4 px-4 py-3 rounded-lg border text-sm flex items-center gap-2"
|
||||
style={{ borderColor: "#fde68a", background: "#fffbeb", color: "#92400e" }}
|
||||
>
|
||||
<span>⚠️</span>
|
||||
<span>
|
||||
Векторный файл логотипа будет добавлен после передачи SVG-файлов.
|
||||
Ниже — SVG-приближение для справки.
|
||||
Изображение извлечено из PDF-брендбука. Векторный SVG будет добавлен
|
||||
после передачи исходных файлов от дизайнера.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 1. Иерархия и версии */}
|
||||
{/* 1. Иерархия */}
|
||||
<Section
|
||||
id="hierarchy"
|
||||
title="Иерархия и версии"
|
||||
subtitle="Клиника использует два варианта логотипа в зависимости от контекста применения."
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-8 md:grid-cols-2">
|
||||
<div>
|
||||
<LogoPlaceholder variant="main" size="md" />
|
||||
<div className="mt-4">
|
||||
<p className="font-medium text-sm mb-1" style={{ color: "var(--bb-text)" }}>
|
||||
Основной логотип
|
||||
</p>
|
||||
<p className="text-sm mb-2" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Локальные версии по направлениям (ЛОР, аллергология и др.).
|
||||
Применяется в точках контакта с клиентами, на лендингах и сайтах направлений.
|
||||
</p>
|
||||
<RuleTag>Точки контакта с клиентом</RuleTag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<LogoPlaceholder variant="general" size="md" />
|
||||
<div className="mt-4">
|
||||
<p className="font-medium text-sm mb-1" style={{ color: "var(--bb-text)" }}>
|
||||
Общий логотип
|
||||
</p>
|
||||
<p className="text-sm mb-2" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Версия сети клиник. Применяется для онлайн и оффлайн коммуникаций
|
||||
с клиентами, во внутренней документации. Допустимо на общем сайте.
|
||||
</p>
|
||||
<RuleTag>Сеть клиник · Документация · Сайт</RuleTag>
|
||||
</div>
|
||||
</div>
|
||||
<LogoCard
|
||||
src="/logo/logo-transparent.png"
|
||||
alt="Основной логотип Клиника УХО ГОРЛО НОС им. проф. Е.Н. Оленевой"
|
||||
label="Основной логотип"
|
||||
description="Локальные версии по направлениям (ЛОР, аллергология и др.). Применяется в точках контакта с клиентами, на лендингах и сайтах направлений."
|
||||
tag="Точки контакта с клиентом"
|
||||
/>
|
||||
<LogoCard
|
||||
src="/logo/logo-transparent.png"
|
||||
alt="Общий логотип сети клиник"
|
||||
label="Общий логотип"
|
||||
description="Версия сети клиник. Применяется для онлайн и оффлайн коммуникаций с клиентами, во внутренней документации. Допустимо на общем сайте."
|
||||
tag="Сеть клиник · Документация · Сайт"
|
||||
/>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
@@ -299,22 +162,44 @@ export default function LogoPage() {
|
||||
title="Цветовые варианты"
|
||||
subtitle="Логотип существует в нескольких вариантах в зависимости от фона носителя."
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-3">
|
||||
<div>
|
||||
<LogoPlaceholder variant="main" size="sm" />
|
||||
<p className="mt-2 text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
<div
|
||||
className="flex items-center justify-center rounded-xl border p-6 mb-3"
|
||||
style={{ background: "#f8f9fa", borderColor: "var(--bb-border)", minHeight: 160 }}
|
||||
>
|
||||
<Image src="/logo/logo-transparent.png" alt="Логотип на светлом фоне"
|
||||
width={220} height={87} className="object-contain" />
|
||||
</div>
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Основной — на светлом фоне
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<LogoPlaceholder variant="inverted" size="sm" />
|
||||
<p className="mt-2 text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
<div
|
||||
className="flex items-center justify-center rounded-xl p-6 mb-3"
|
||||
style={{ background: "var(--brand-073m)", minHeight: 160 }}
|
||||
>
|
||||
{/* brightness(0) делает всё чёрным, invert(1) — белым */}
|
||||
<Image src="/logo/logo-transparent.png" alt="Логотип инвертированный"
|
||||
width={220} height={87} className="object-contain"
|
||||
style={{ filter: "brightness(0) invert(1)" }} />
|
||||
</div>
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Инвертированный — на тёмном фоне
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<LogoPlaceholder variant="brown" size="sm" />
|
||||
<p className="mt-2 text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
<div
|
||||
className="flex items-center justify-center rounded-xl border p-6 mb-3"
|
||||
style={{ background: "var(--brand-081m)", borderColor: "transparent", minHeight: 160 }}
|
||||
>
|
||||
{/* Коричневый: насыщенный sepia + darkening */}
|
||||
<Image src="/logo/logo-transparent.png" alt="Логотип коричневый на форме"
|
||||
width={220} height={87} className="object-contain"
|
||||
style={{ filter: "brightness(0) sepia(1) saturate(2) hue-rotate(330deg) brightness(0.45)" }} />
|
||||
</div>
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Коричневый — на форме (бежевый костюм)
|
||||
</p>
|
||||
</div>
|
||||
@@ -325,21 +210,28 @@ export default function LogoPage() {
|
||||
<Section
|
||||
id="clearspace"
|
||||
title="Охранная зона"
|
||||
subtitle="Вокруг логотипа всегда должно быть свободное пространство, равное высоте буквы «x» в названии."
|
||||
subtitle="Вокруг логотипа всегда должно быть свободное пространство — не менее высоты буквы «x» в слове «КЛИНИКА»."
|
||||
>
|
||||
<div className="flex flex-wrap gap-8 items-start">
|
||||
<ClearspaceDemo />
|
||||
<div className="flex-1 min-w-48 space-y-3 pt-2">
|
||||
<p className="text-sm" style={{ color: "var(--bb-text)" }}>
|
||||
Охранная зона — минимальное расстояние от логотипа до любого другого
|
||||
графического элемента или края носителя.
|
||||
</p>
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Пунктирная рамка обозначает охранную зону. Никакие другие элементы
|
||||
не должны пересекать её границы.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center justify-center rounded-xl border p-16 relative"
|
||||
style={{ background: "#f8f9fa", borderColor: "var(--bb-border)" }}
|
||||
>
|
||||
<div className="absolute inset-8 border-2 border-dashed rounded-lg"
|
||||
style={{ borderColor: "var(--brand-053m)", opacity: 0.5 }} />
|
||||
{["top","bottom","left","right"].map(side => (
|
||||
<div key={side} className={`absolute text-xs font-medium
|
||||
${side==="top" ? "top-2 left-1/2 -translate-x-1/2" : ""}
|
||||
${side==="bottom" ? "bottom-2 left-1/2 -translate-x-1/2" : ""}
|
||||
${side==="left" ? "left-2 top-1/2 -translate-y-1/2" : ""}
|
||||
${side==="right" ? "right-2 top-1/2 -translate-y-1/2" : ""}
|
||||
`} style={{ color: "var(--brand-053m)" }}>x</div>
|
||||
))}
|
||||
<Image src="/logo/logo-transparent.png" alt="Логотип с охранной зоной"
|
||||
width={320} height={126} className="object-contain relative z-10" />
|
||||
</div>
|
||||
<p className="mt-3 text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Пунктирная рамка — граница охранной зоны. Никакие другие элементы не должны её пересекать.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
{/* 4. Минимальные размеры */}
|
||||
@@ -348,68 +240,28 @@ export default function LogoPage() {
|
||||
title="Минимальные размеры"
|
||||
subtitle="Размеры логотипа для размещения на форме сотрудников."
|
||||
>
|
||||
<div
|
||||
className="overflow-hidden rounded-lg border"
|
||||
style={{ borderColor: "var(--bb-border)" }}
|
||||
>
|
||||
<div className="overflow-hidden rounded-xl border" style={{ borderColor: "var(--bb-border)" }}>
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr style={{ background: "var(--bb-sidebar-bg)" }}>
|
||||
<th
|
||||
className="text-left px-5 py-3 font-medium"
|
||||
style={{ color: "var(--bb-text-muted)" }}
|
||||
>
|
||||
Размер одежды
|
||||
</th>
|
||||
<th
|
||||
className="text-left px-5 py-3 font-medium"
|
||||
style={{ color: "var(--bb-text-muted)" }}
|
||||
>
|
||||
Длина логотипа
|
||||
</th>
|
||||
<th
|
||||
className="text-left px-5 py-3 font-medium"
|
||||
style={{ color: "var(--bb-text-muted)" }}
|
||||
>
|
||||
Высота логотипа
|
||||
</th>
|
||||
<th
|
||||
className="text-left px-5 py-3 font-medium"
|
||||
style={{ color: "var(--bb-text-muted)" }}
|
||||
>
|
||||
Расположение
|
||||
</th>
|
||||
{["Размер одежды","Длина","Высота","Расположение"].map(h => (
|
||||
<th key={h} className="text-left px-5 py-3 font-medium"
|
||||
style={{ color: "var(--bb-text-muted)" }}>{h}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="border-t" style={{ borderColor: "var(--bb-border)" }}>
|
||||
<td className="px-5 py-3" style={{ color: "var(--bb-text)" }}>
|
||||
До 46 (включительно)
|
||||
</td>
|
||||
<td className="px-5 py-3 font-mono text-xs" style={{ color: "var(--bb-text)" }}>
|
||||
70 мм
|
||||
</td>
|
||||
<td className="px-5 py-3 font-mono text-xs" style={{ color: "var(--bb-text)" }}>
|
||||
25,5 мм
|
||||
</td>
|
||||
<td className="px-5 py-3" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Левая сторона груди
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="border-t" style={{ borderColor: "var(--bb-border)" }}>
|
||||
<td className="px-5 py-3" style={{ color: "var(--bb-text)" }}>
|
||||
От 48
|
||||
</td>
|
||||
<td className="px-5 py-3 font-mono text-xs" style={{ color: "var(--bb-text)" }}>
|
||||
90 мм
|
||||
</td>
|
||||
<td className="px-5 py-3 font-mono text-xs" style={{ color: "var(--bb-text)" }}>
|
||||
32,8 мм
|
||||
</td>
|
||||
<td className="px-5 py-3" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Левая сторона груди
|
||||
</td>
|
||||
</tr>
|
||||
{[
|
||||
["До 46 (включительно)", "70 мм", "25,5 мм", "Левая сторона груди"],
|
||||
["От 48", "90 мм", "32,8 мм", "Левая сторона груди"],
|
||||
].map(([size, w, h, pos]) => (
|
||||
<tr key={size} className="border-t" style={{ borderColor: "var(--bb-border)" }}>
|
||||
<td className="px-5 py-3" style={{ color: "var(--bb-text)" }}>{size}</td>
|
||||
<td className="px-5 py-3 font-mono text-xs" style={{ color: "var(--bb-text)" }}>{w}</td>
|
||||
<td className="px-5 py-3 font-mono text-xs" style={{ color: "var(--bb-text)" }}>{h}</td>
|
||||
<td className="px-5 py-3" style={{ color: "var(--bb-text-muted)" }}>{pos}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -419,48 +271,38 @@ export default function LogoPage() {
|
||||
<Section
|
||||
id="prohibited"
|
||||
title="Недопустимые варианты использования"
|
||||
subtitle="Следующие варианты применения логотипа запрещены."
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
<ProhibitedItem label="Изменять пропорции или искажать логотип" />
|
||||
<ProhibitedItem label="Изменять цвета элементов логотипа" />
|
||||
<ProhibitedItem label="Добавлять рядом произвольный текст" />
|
||||
<ProhibitedItem label="Размещать на фоне, с которым логотип не контрастирует" />
|
||||
<ProhibitedItem label="Использовать отдельные элементы логотипа без остальных" />
|
||||
<ProhibitedItem label="Размещать на фоне без достаточного контраста" />
|
||||
<ProhibitedItem label="Использовать отдельные элементы без остальных" />
|
||||
<ProhibitedItem label="Применять тени, обводки, градиенты" />
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* 6. Скачать файлы */}
|
||||
<Section
|
||||
id="download"
|
||||
title="Скачать файлы"
|
||||
subtitle="Официальные файлы логотипа для использования в коммуникациях."
|
||||
>
|
||||
{/* 6. Скачать */}
|
||||
<Section id="download" title="Скачать файлы">
|
||||
<div
|
||||
className="rounded-lg border p-6 flex flex-col sm:flex-row items-start sm:items-center gap-4"
|
||||
className="rounded-xl border p-6 flex flex-col sm:flex-row items-start sm:items-center gap-4"
|
||||
style={{ borderColor: "var(--bb-border)", background: "var(--bb-sidebar-bg)" }}
|
||||
>
|
||||
<div className="flex-1">
|
||||
<p className="font-medium text-sm mb-1" style={{ color: "var(--bb-text)" }}>
|
||||
Векторные файлы логотипа (SVG, PNG)
|
||||
Векторные файлы логотипа (SVG, AI, PNG)
|
||||
</p>
|
||||
<p className="text-sm" style={{ color: "var(--bb-text-muted)" }}>
|
||||
Будут доступны после передачи исходных файлов от дизайнера.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
disabled
|
||||
className="px-4 py-2 rounded-lg text-sm font-medium cursor-not-allowed"
|
||||
style={{
|
||||
background: "#e5e7eb",
|
||||
color: "#9ca3af",
|
||||
}}
|
||||
>
|
||||
<button disabled className="px-4 py-2 rounded-lg text-sm font-medium cursor-not-allowed"
|
||||
style={{ background: "#e5e7eb", color: "#9ca3af" }}>
|
||||
Скачать (скоро)
|
||||
</button>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const firaSans = Fira_Sans({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Цифровой брендбук | Клиника УХО•ГОРЛО•НОС им. проф. Е.Н. Оленевой",
|
||||
title: "Цифровой брендбук | Клиника ухо, горло, нос им. проф. Е.Н.Оленевой",
|
||||
description: "Интерактивный брендбук — Living Styleguide oclinica.ru",
|
||||
};
|
||||
|
||||
|
||||
@@ -105,9 +105,9 @@ export function Sidebar() {
|
||||
className="text-xs leading-tight"
|
||||
style={{ color: "var(--bb-sidebar-text-muted)" }}
|
||||
>
|
||||
Клиника УХО•ГОРЛО•НОС
|
||||
Клиника ухо, горло, нос
|
||||
<br />
|
||||
им. проф. Е.Н. Оленевой
|
||||
им. проф. Е.Н.Оленевой
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
+1
-1
@@ -8,7 +8,7 @@ services:
|
||||
POSTGRES_PASSWORD: brandbook
|
||||
POSTGRES_DB: brandbook
|
||||
ports:
|
||||
- "5432:5432"
|
||||
- "5433:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
|
||||
|
||||
+30
-21
@@ -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 (бренд)
|
||||
- [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
|
||||
|
||||
### Задачи — страница «Логотип» (первый контент брендбука)
|
||||
- [ ] Design: Экспорт PNG логотипа из PDF для использования как placeholder
|
||||
- [ ] FE: Страница `/foundation/logo` в брендбуке
|
||||
- [ ] FE: Отображение обеих версий логотипа: «Общий» и «Основной»
|
||||
- [ ] FE: Секция «Иерархия»: описание применения каждой версии
|
||||
- [ ] FE: Секция «Цветовые варианты»: основной / инвертированный / на форме
|
||||
- [ ] FE: Секция «Охранная зона» с визуализацией отступов
|
||||
- [ ] FE: Секция «Минимальные размеры» (таблица: до 46 р. и от 48 р.)
|
||||
- [ ] FE: Секция «Недопустимые варианты» — правило не менять и не сочетать с текстом
|
||||
- [ ] FE: Placeholder-блок «Скачать вектор» (кнопка неактивна до получения SVG)
|
||||
### Задачи — страница «Логотип»
|
||||
- [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 «Скачать вектор» (кнопка неактивна)
|
||||
|
||||
**Результат спринта:** Запускается `pnpm dev`, открывается брендбук с навигацией. Раздел «Логотип» полностью заполнен контентом и правилами.
|
||||
### Фактические результаты
|
||||
- Брендбук запущен локально на `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 занят на хосте)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user