Browse Source

feat(colors): раздел «Цвета с сайта» + документация источника CSS

- Добавлен массив WEB_COLORS (8 цветов из CSS темы oclinica.ru)
- Добавлен компонент WebColorCard с группой, счётчиком применений, HEX/RGB/HSL
- Новый раздел «Цвета с сайта» со ссылкой на CSS-источник в интерфейсе
- TZ.md: ОВ-07 — зафиксирован URL темы clinic_bootstrap_mobile и метод извлечения

Источник CSS: perm.oclinica.ru/sites/all/themes/clinic_bootstrap_mobile/css/style.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sprint/3
AR 15 M4 1 week ago
parent
commit
761347ed85
  1. 91
      apps/web/app/foundation/colors/page.tsx
  2. 3
      docs/TZ.md

91
apps/web/app/foundation/colors/page.tsx

@ -102,6 +102,20 @@ const BRAND_COLORS = [
}, },
]; ];
/* ─── Цвета с сайта ────────────────────────────────────────────────── */
// Источник: https://perm.oclinica.ru/sites/all/themes/clinic_bootstrap_mobile/css/style.css
// Извлечены парсингом CSS: grep + python Counter по property/value, 2026-03-22
const WEB_COLORS = [
{ name: "Бежевый", hex: "#bf9975", usage: "Основной тёплый акцент, фоны, рамки, текст", count: 12, group: "Акценты" },
{ name: "Серо-бирюзовый", hex: "#60959c", usage: "Основной холодный акцент, ссылки", count: 7, group: "Акценты" },
{ name: "Бирюзовый", hex: "#63bac3", usage: "Фоны акцентных блоков, иконки", count: 4, group: "Акценты" },
{ name: "Бирюзовый средний", hex: "#52b4bd", usage: "Вторичные цветовые акценты", count: 4, group: "Акценты" },
{ name: "Основной текст", hex: "#464646", usage: "Цвет основного текста на сайте", count: 3, group: "Текст" },
{ name: "Второстепенный текст", hex: "#949290", usage: "Подписи, второстепенный контент", count: 4, group: "Текст" },
{ name: "Светло-бирюзовый фон", hex: "#b8e6ed", usage: "Фоны светлых секций с акцентом", count: 1, group: "Фоны" },
{ name: "Кремовый фон", hex: "#e9e4d4", usage: "Тёплые фоны секций", count: 1, group: "Фоны" },
];
const CONTRAST_PAIRS = [ const CONTRAST_PAIRS = [
{ fg: "#ffffff", bg: "#5b7b87", label: "Белый на тёмном серо-голубом" }, { fg: "#ffffff", bg: "#5b7b87", label: "Белый на тёмном серо-голубом" },
{ fg: "#ffffff", bg: "#1b4c72", label: "Белый на тёмно-синем" }, { fg: "#ffffff", bg: "#1b4c72", label: "Белый на тёмно-синем" },
@ -245,6 +259,56 @@ function ContrastRow({ pair }: { pair: typeof CONTRAST_PAIRS[0] }) {
); );
} }
function WebColorCard({ color }: { color: typeof WEB_COLORS[0] }) {
const { r, g, b } = hexToRgb(color.hex);
const { h, s, l } = rgbToHsl(r, g, b);
const isLight = l > 60;
return (
<div
className="rounded-xl overflow-hidden border"
style={{ borderColor: "var(--bb-border)" }}
>
<div
className="h-24 flex items-end justify-between px-4 pb-3"
style={{ background: color.hex }}
>
<span
className="text-xs font-semibold px-2 py-0.5 rounded"
style={{
background: isLight ? "rgba(0,0,0,0.12)" : "rgba(255,255,255,0.18)",
color: isLight ? "rgba(0,0,0,0.75)" : "rgba(255,255,255,0.9)",
}}
>
{color.group}
</span>
<span
className="text-xs px-2 py-0.5 rounded font-mono"
style={{
background: isLight ? "rgba(0,0,0,0.12)" : "rgba(255,255,255,0.18)",
color: isLight ? "rgba(0,0,0,0.75)" : "rgba(255,255,255,0.9)",
}}
>
×{color.count}
</span>
</div>
<div className="p-4" style={{ background: "var(--bb-content-bg)" }}>
<p className="font-medium text-sm mb-1" style={{ color: "var(--bb-text)" }}>
{color.name}
</p>
<p className="text-xs mb-3" style={{ color: "var(--bb-text-muted)" }}>
{color.usage}
</p>
<div className="flex flex-wrap gap-1.5">
<CopyBadge value={color.hex.toUpperCase()} label="HEX" />
<CopyBadge value={`rgb(${r}, ${g}, ${b})`} label="RGB" />
<CopyBadge value={`hsl(${h}, ${s}%, ${l}%)`} label="HSL" />
</div>
</div>
</div>
);
}
/* ─── Экспорт токенов ──────────────────────────────────────────────── */ /* ─── Экспорт токенов ──────────────────────────────────────────────── */
function exportTokens() { function exportTokens() {
const tokens: Record<string, Record<string, unknown>> = { colors: {} }; const tokens: Record<string, Record<string, unknown>> = { colors: {} };
@ -348,7 +412,32 @@ export default function ColorsPage() {
</div> </div>
</section> </section>
{/* 3. Применение */} {/* 3. Цвета с сайта */}
<section className="mb-12">
<div className="mb-6">
<h2 className="text-xl font-semibold" style={{ color: "var(--bb-text)" }}>
Цвета с сайта
</h2>
<p className="mt-1 text-sm" style={{ color: "var(--bb-text-muted)" }}>
Реальные цвета, используемые на сайте oclinica.ru. Извлечены из CSS темы сайта.
Число применений показано в правом углу карточки.
</p>
<div
className="mt-3 flex items-center gap-2 px-3 py-2 rounded-lg text-xs w-fit font-mono"
style={{ background: "var(--bb-sidebar-bg)", color: "var(--bb-text-muted)", border: "1px solid var(--bb-border)" }}
>
<span style={{ color: "var(--brand-053m)" }}>CSS</span>
perm.oclinica.ru/sites/all/themes/clinic_bootstrap_mobile/css/style.css
</div>
</div>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
{WEB_COLORS.map(c => (
<WebColorCard key={c.hex} color={c} />
))}
</div>
</section>
{/* 4. Применение */}
<section className="mb-12"> <section className="mb-12">
<div className="mb-6"> <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)" }}>

3
docs/TZ.md

@ -530,7 +530,8 @@ vercel --prod --yes
| ОВ-03 | Нужна ли страница «Заболевание» как отдельный тип, или это подвид страницы «Услуга»? | Клиника | Sprint 9 | | ОВ-03 | Нужна ли страница «Заболевание» как отдельный тип, или это подвид страницы «Услуга»? | Клиника | Sprint 9 |
| ОВ-04 | Список иконок — какую стороннюю библиотеку утвердить? (Lucide, Heroicons, и др.) | Совместно | Sprint 2 | | ОВ-04 | Список иконок — какую стороннюю библиотеку утвердить? (Lucide, Heroicons, и др.) | Совместно | Sprint 2 |
| ОВ-05 | ~~Нужен ли раздел «Логотип» в v1.0 или ждём вектор?~~ **Закрыт:** страница логотипа реализуется в Sprint 1 с PNG-версией; вектор будет добавлен позже | — | Закрыт | | ОВ-05 | ~~Нужен ли раздел «Логотип» в v1.0 или ждём вектор?~~ **Закрыт:** страница логотипа реализуется в Sprint 1 с PNG-версией; вектор будет добавлен позже | — | Закрыт |
| ОВ-06 | ~~HEX-эквиваленты цветов Oracal~~ **Закрыт:** приблизительные HEX зафиксированы в Sprint 2 и подтверждены как рабочие (053M=#7ecfca, 073M=#5b7b87, 066M=#5bb5ad, 050M=#1b4c72, 081M=#c4a882, 080M=#5c2e0e). Точная калибровка — при получении физических образцов. | — | Закрыт | | ОВ-06 | ~~HEX-эквиваленты цветов Oracal~~ **Закрыт:** приблизительные HEX зафиксированы в Sprint 2 (053M=#7ecfca, 073M=#5b7b87, 066M=#5bb5ad, 050M=#1b4c72, 081M=#c4a882, 080M=#5c2e0e). Дополнительно — реальные цвета сайта извлечены из CSS (см. ОВ-07). Точная калибровка Oracal — при получении физических образцов. | — | Закрыт |
| ОВ-07 | **Цвета сайта oclinica.ru** — CSS тема Drupal доступна по адресу: `https://perm.oclinica.ru/sites/all/themes/clinic_bootstrap_mobile/css/style.css`. Тема: `clinic_bootstrap_mobile`. Ключевые цвета извлечены парсингом (python + regex + Counter), 2026-03-22. Добавлены в раздел «Цвета с сайта» в брендбуке (`/foundation/colors`). Расхождение с Oracal-палитрой ожидаемо — цифровые адаптации под экран. | — | Закрыт |
--- ---

Loading…
Cancel
Save