diff --git a/apps/web/app/components/cards/page.tsx b/apps/web/app/components/cards/page.tsx
new file mode 100644
index 0000000..26ca497
--- /dev/null
+++ b/apps/web/app/components/cards/page.tsx
@@ -0,0 +1,629 @@
+import type { Metadata } from "next";
+import { CodeCopy } from "@/components/ui/CodeCopy";
+import { LlmBlock, LlmSection, LlmTable, LlmRules } from "@/components/llm/LlmBlock";
+
+export const metadata: Metadata = {
+ title: "Карточки. Цифровой брендбук Клиники ухо, горло, нос им. проф. Е.Н.Оленевой",
+};
+
+function Section({
+ id, title, subtitle, children,
+}: {
+ id?: string; title: string; subtitle?: string; children: React.ReactNode;
+}) {
+ return (
+
+
+
{title}
+ {subtitle &&
{subtitle}
}
+
+ {children}
+
+ );
+}
+
+/* ─── Карточка врача ────────────────────────────────────────────────── */
+function DoctorCard({
+ name, specialty, experience, photo,
+}: {
+ name: string; specialty: string; experience: string; photo?: string;
+}) {
+ return (
+
+ {/* Фото */}
+
+ {photo ? (
+

+ ) : (
+
+ )}
+
+
+ {/* Информация */}
+
+
+
+ {name}
+
+
{specialty}
+
{experience}
+
+
+
+
+ );
+}
+
+/* ─── Карточка новости ──────────────────────────────────────────────── */
+function NewsCard({
+ date, title, snippet, category,
+}: {
+ date: string; title: string; snippet: string; category?: string;
+}) {
+ return (
+
+ {/* Превью */}
+
+ {category && (
+
+ {category}
+
+ )}
+
+
+ {/* Контент */}
+
+
{date}
+
+ {title}
+
+
+ {snippet}
+
+
+ Читать далее →
+
+
+
+ );
+}
+
+/* ─── Карточка отзыва ───────────────────────────────────────────────── */
+function ReviewCard({
+ author, date, text, rating, doctor,
+}: {
+ author: string; date: string; text: string; rating: number; doctor?: string;
+}) {
+ return (
+
+ {/* Звёзды */}
+
+ {Array.from({ length: 5 }, (_, i) => (
+
+ ))}
+
{rating}/5
+
+
+ {/* Текст */}
+
+ {text}
+
+
+ {/* Автор */}
+
+
+
{author}
+ {doctor &&
Врач: {doctor}
}
+
+
{date}
+
+
+ );
+}
+
+/* ─── Карточка цены ─────────────────────────────────────────────────── */
+function PriceCard({
+ service, price, description, highlighted,
+}: {
+ service: string; price: string; description?: string; highlighted?: boolean;
+}) {
+ return (
+
+
+
{service}
+
+ {price}
+
+
+ {description && (
+
{description}
+ )}
+
+
+ );
+}
+
+/* ─── Карточка услуги ───────────────────────────────────────────────── */
+function ServiceCard({
+ title, description, icon,
+}: {
+ title: string; description: string; icon: string;
+}) {
+ return (
+
+
+ {icon}
+
+
+
{title}
+
{description}
+
+
+ Подробнее →
+
+
+ );
+}
+
+/* ─── LLM текст ─────────────────────────────────────────────────────── */
+const LLM_CARDS_TEXT = `КАРТОЧКИ — LLM-спецификация
+Версия: v1.0 · /components/cards
+
+КАРТОЧКА ВРАЧА (DoctorCard)
+Структура: фото (110×160px) + имя + специализация + опыт + кнопка «Записаться»
+Фото: 110px × 160px, object-fit: cover, border-radius: 8px, фон-placeholder: #dff0fa
+Кнопка: .bb-btn-outline .bb-btn-sm
+Источник: .doctor на perm.oclinica.ru
+
+КАРТОЧКА НОВОСТИ (NewsCard)
+Структура: превью (h=144px) + дата + заголовок + анонс (4 строки) + «Читать далее →»
+Hover: background #eef4d1 + box-shadow 0 0 16px #9e9e9a
+Источник: #block-views-last-news-block-1 .views-column на сайте (200×200px)
+Без hover: background #fff, border 1px
+
+КАРТОЧКА ОТЗЫВА (ReviewCard)
+Структура: рейтинг (звёзды 1–5) + текст (4 строки, overflow hidden) + автор + дата + врач
+Фон: #eef4d1 (светло-жёлтый) — из реального CSS сайта
+Звёзды: SVG polygon, filled #f59e0b
+
+КАРТОЧКА ЦЕНЫ (PriceCard)
+Структура: услуга + цена (bold) + описание + кнопка
+highlighted-вариант: border var(--brand-053m), bg #f0f9ff, цена тоже --brand-053m
+
+КАРТОЧКА УСЛУГИ (ServiceCard)
+Структура: иконка (emoji, 48×48px, bg #dff0fa) + заголовок + описание + «Подробнее →»
+Hover: box-shadow (0.5rem smth)
+
+БЕЙДЖИ (Badge)
+Варианты: primary (#0089c3), success (#059669), warning (#d97706), danger (#dc2626), neutral (#6b7280)
+Размер: text-xs, px-2.5 py-0.5, border-radius: full
+CSS: inline-flex, font-weight: 600
+
+ТЕГИ (Tag)
+Варианты: default (border, text), filled (bg), removable (с кнопкой ×)
+Цвет: --brand-053m или нейтральный (#e5e7eb bg)
+Размер: text-xs, px-2 py-1, border-radius: 4px
+
+АЛЕРТЫ (Alert)
+Варианты: info (#dff0fa фон, #075985 текст), success (#d1fae5, #065f46), warning (#fef3c7, #92400e), error (#fee2e2, #991b1b)
+Структура: иконка (16×16px) + заголовок + описание
+Без кнопки закрыть в базовом варианте
+
+ПРАВИЛА
+✓ DoctorCard: всегда показывать фото-placeholder если нет фото (не ломать layout)
+✓ ReviewCard: обрезать текст после 4 строк (WebkitLineClamp)
+✓ PriceCard: highlighted = акционная или рекомендуемая позиция
+✓ NewsCard: hover-эффект обязателен (#eef4d1 + box-shadow)
+✓ Badge: не более 2–3 бейджей рядом
+✓ Alert: одновременно не более 1 alert одного типа на экране
+✕ Не смешивать типы карточек в одной сетке без заголовка секции
+✕ Не использовать ReviewCard без рейтинга`.trim();
+
+/* ─── Данные примеров ───────────────────────────────────────────────── */
+const DOCTORS = [
+ {
+ name: "Иванова Анна Сергеевна",
+ specialty: "Оториноларинголог (ЛОР), высшая категория",
+ experience: "Стаж 18 лет",
+ },
+ {
+ name: "Петров Дмитрий Александрович",
+ specialty: "Сурдолог, аудиолог",
+ experience: "Стаж 12 лет",
+ },
+ {
+ name: "Соколова Мария Ивановна",
+ specialty: "Детский ЛОР, ринолог",
+ experience: "Стаж 9 лет",
+ },
+];
+
+const REVIEWS = [
+ {
+ author: "Елена К.",
+ date: "15 марта 2026",
+ rating: 5,
+ doctor: "Иванова А.С.",
+ text: "Очень довольна визитом. Доктор внимательно выслушала все жалобы, провела осмотр и объяснила причину заболевания. Назначила лечение, которое помогло уже через 3 дня. Рекомендую!",
+ },
+ {
+ author: "Михаил Р.",
+ date: "10 марта 2026",
+ rating: 4,
+ doctor: "Петров Д.А.",
+ text: "Хороший специалист, всё объяснил понятно. Подождал немного дольше, чем ожидал, но качество приёма на высоте. Буду обращаться снова.",
+ },
+];
+
+const PRICES = [
+ { service: "Первичный приём ЛОР-врача", price: "1 500 ₽", description: "Включает осмотр и консультацию" },
+ { service: "Повторный приём", price: "1 000 ₽", description: "До 14 дней после первичного" },
+ { service: "Промывание миндалин", price: "800 ₽", highlighted: true, description: "Аппаратное — аккустический вакуум" },
+ { service: "Аудиометрия", price: "1 200 ₽", description: "Исследование слуха" },
+];
+
+const SERVICES = [
+ { title: "Лечение ангины и тонзиллита", description: "Консервативное и хирургическое лечение заболеваний миндалин", icon: "🦷" },
+ { title: "Аудиология и сурдология", description: "Диагностика нарушений слуха, подбор слуховых аппаратов", icon: "👂" },
+ { title: "Детский ЛОР", description: "Специализация на лечении ЛОР-заболеваний у детей от 0 лет", icon: "👶" },
+ { title: "Ринология", description: "Лечение заболеваний носа и придаточных пазух", icon: "👃" },
+];
+
+/* ─── Коды примеров ─────────────────────────────────────────────────── */
+const codeDoctorCard = `
+
+

+
+
Иванова Анна Сергеевна
+
Оториноларинголог, высшая категория
+
Стаж 18 лет
+
+
+
+
+/* CSS с сайта oclinica.ru */
+.doctor .image { float:left; margin-right:20px; width:110px; height:160px; }
+.doctor .item { float:left; width:170px; }
+.doctor h3 { margin-top:0; height:32px; }`;
+
+const codeNewsCard = `
+
+
...
+
+
+
Заголовок новости
+
Краткий анонс...
+
Читать далее →
+
+
+
+/* CSS с сайта */
+#block-views-last-news-block-1 .views-column {
+ background: #fff; width: 200px; height: 200px;
+ margin: 15px 8px; padding: 15px;
+}
+#block-views-last-news-block-1 .views-column:hover {
+ background: #eef4d1;
+ box-shadow: 0px 0px 16px 0px #9e9e9a;
+}`;
+
+const codeReviewCard = `
+
+
★★★★★
+
Текст отзыва (4 строки, overflow: hidden)...
+
+ Елена К.
+
+
+
+
+/* Стиль брендбука (фон из CSS сайта) */
+.review-card { background: #eef4d1; border-radius: 12px; padding: 20px; }`;
+
+const codePriceCard = `
+
+
+ Первичный приём ЛОР-врача
+ 1 500 ₽
+
+
Включает осмотр и консультацию
+
+
`;
+
+const codeBadges = `
+ЛОР
+Принимает
+Ожидает
+Не принимает
+Высшая категория
+
+
+
+
+
+
+
+
+
ℹ
+
+
Запись открыта
+
Вы можете записаться онлайн или по телефону.
+
+
`;
+
+export default function CardsPage() {
+ return (
+
+
+ {/* Заголовок */}
+
+
+ Компоненты → 3.3
+
+
+ Карточки
+
+
+ Карточки врача, новости, отзыва, цены и услуги — основные блоки контента сайта.
+ Бейджи, теги и алерты — вспомогательные элементы.
+
+
+
+ {/* 1. Карточки врачей */}
+
+
+ {DOCTORS.map(d => )}
+
+
+
+ {/* 2. Карточки новостей */}
+
+
+
+
+
+
+
+ * Наведите на карточку чтобы увидеть hover-эффект
+
+
+
+ {/* 3. Карточки отзывов */}
+
+
+ {REVIEWS.map(r => )}
+
+
+
+ {/* 4. Карточки цен */}
+
+
+ {/* 5. Карточки услуг */}
+
+
+ {SERVICES.map(s => )}
+
+
+
+ {/* 6. Бейджи и теги */}
+
+ {/* Бейджи */}
+
+
Бейджи (статус)
+
+ {[
+ { label: "Основной", bg: "var(--brand-053m)", color: "#fff" },
+ { label: "Принимает", bg: "#059669", color: "#fff" },
+ { label: "Высшая категория", bg: "#d97706", color: "#fff" },
+ { label: "Не принимает", bg: "#dc2626", color: "#fff" },
+ { label: "Нейтральный", bg: "#6b7280", color: "#fff" },
+ { label: "Новинка", bg: "#dff0fa", color: "var(--brand-053m)" },
+ ].map(b => (
+
+ {b.label}
+
+ ))}
+
+
+
+ {/* Теги */}
+
+
Теги (категории)
+
+ {["Ухо", "Горло", "Нос", "Аудиология", "Детский ЛОР", "Хирургия"].map((tag, i) => (
+
+ ))}
+
+
+
+ {/* Алерты */}
+
+
Алерты
+
+ {[
+ { type: "info", bg: "#dff0fa", color: "#075985", icon: "ℹ", title: "Информация", text: "Запись открыта. Вы можете записаться онлайн или по телефону." },
+ { type: "success", bg: "#d1fae5", color: "#065f46", icon: "✓", title: "Успешно", text: "Ваша запись подтверждена. Ждём вас 20 марта в 10:00." },
+ { type: "warning", bg: "#fef3c7", color: "#92400e", icon: "⚠", title: "Внимание", text: "Не забудьте взять паспорт и полис ОМС на приём." },
+ { type: "error", bg: "#fee2e2", color: "#991b1b", icon: "✕", title: "Ошибка", text: "К сожалению, это время уже занято. Выберите другое." },
+ ].map(a => (
+
+ ))}
+
+
+
+
+ {/* 7. Код */}
+
+
+ {/* LLM-блок */}
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css
index 7d46e0d..bc26fe4 100644
--- a/apps/web/app/globals.css
+++ b/apps/web/app/globals.css
@@ -162,6 +162,13 @@ body {
flex-shrink: 0;
}
+/* ─── Карточки (Sprint 4) ────────────────────────────────────── */
+.bb-news-card:hover {
+ background: #eef4d1 !important;
+ box-shadow: 0 0 16px 0 #9e9e9a;
+}
+.bb-service-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
+
/* ─── Тумблер (Sprint 3) ──────────────────────────────────────── */
.bb-toggle-track {
display: inline-flex;