gendesign/frontend/src/app/globals.css
Light1YT f4b54671d9
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 57s
CI / openapi-codegen-check (pull_request) Successful in 1m56s
fix(ptica): load Inter, surface map legend, drop flag, honest product chart, home link
Root causes behind the cockpit looking «криво/косо»:

- Inter was never loaded — app referenced literal "Inter" but only IBM Plex
  Mono went through next/font, so the whole cockpit rendered in -apple-system
  (wider metrics → rail labels overflow, tabular numbers misalign). Load Inter
  via next/font/google (latin+cyrillic) and wire --font-ui/body to it.
- Map legend overlay (z-index 4) was buried under Leaflet panes (200-700):
  give .leaflet-container its own stacking context (position:absolute; z-index:1)
  like the prototype, so the overlay + tools surface.
- Drop the Leaflet attribution flag/"Leaflet" prefix (prefix={false}) while
  keeping the © Esri/Maxar/CARTO data credits.
- RECOMMENDED PRODUCT rendered 15 degenerate full-red −1.00 bars: filter mix to
  the recommended class, show an honest empty state on degenerate signal, cap
  rows, and stop labels wrapping (nowrap+ellipsis).
- ПТИЦА wordmark is now a Link → /site-finder (home), with a focus ring.
2026-06-21 01:41:13 +05:00

202 lines
6.9 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* GenDesign — global CSS design tokens (UI Brief May 17)
* All CSS vars used across site-finder and analytics components.
* Spacing scale: 4/8/12/16/24/32px only.
* Tabular-nums applied globally for numeric readability.
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
:root {
/* ── Surface ─────────────────────────────────────────────────────────── */
--bg-app: #f6f7f9;
--bg-card: #ffffff;
--bg-card-alt: #fafbfc;
--bg-headline: #0f172a; /* slate-900 — dark verdict bar */
/* ── Borders ─────────────────────────────────────────────────────────── */
--border-soft: #eef0f3;
--border-card: #e6e8ec;
--border-strong: #d1d5db;
/* ── Text ────────────────────────────────────────────────────────────── */
--fg-primary: #111111;
--fg-secondary: #5b6066;
--fg-tertiary: #73767e;
--fg-on-dark: #e2e8f0; /* text on --bg-headline */
--fg-on-dark-muted: #94a3b8; /* caveat text on dark */
/* ── Brand / CTA ─────────────────────────────────────────────────────── */
--accent: #1d4ed8; /* primary blue CTA */
--accent-hover: #1e40af;
--accent-soft: #dbeafe; /* badge bg, active tab bg */
--accent-2: #f2994a; /* secondary orange CTA (Export, Share) */
/* ── Semantic ────────────────────────────────────────────────────────── */
--success: #0a7a3a;
--success-soft: #dcfce7;
--warn: #9a6700;
--warn-soft: #fef3c7;
--danger: #b3261e;
--danger-soft: #fee2e2;
/* ── Data-viz (use in order, no skip) ───────────────────────────────── */
--viz-1: #1d4ed8;
--viz-2: #0ea5e9;
--viz-3: #14b8a6;
--viz-4: #f59e0b;
--viz-5: #8b5cf6;
--prediction-line: #0ea5e9;
--prediction-band: rgba(14, 165, 233, 0.18);
}
html,
body {
margin: 0;
padding: 0;
background: var(--bg-app);
color: var(--fg-primary);
font-family:
var(--font-inter),
"Inter",
-apple-system,
"Segoe UI",
system-ui,
sans-serif;
font-size: 14px;
line-height: 1.5;
/* Tabular nums globally for numeric legibility (Bloomberg lesson) */
font-variant-numeric: tabular-nums;
font-feature-settings: "tnum";
-webkit-font-smoothing: antialiased;
}
/* Focus-visible ring — accessible, not outline:none */
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* Remove default outline for mouse users */
:focus:not(:focus-visible) {
outline: none;
}
a {
color: inherit;
}
/*
* ── Responsive (issue #66) ───────────────────────────────────────────────────
* 3 контекста (НЕ Tailwind sm/md/lg): phone <768, tablet 7681280, desktop >1280.
* Утилиты ниже — единственный источник правды для брейкпоинтов. Компоненты
* подключаются через className; инлайн-стили остаются desktop-видом по умолчанию.
*/
/* Никакого горизонтального скролла на узких экранах (acceptance #66). */
html,
body {
max-width: 100%;
overflow-x: hidden;
}
/* Sidebar-grid (напр. "240px 1fr" / "minmax(300px,360px) 1fr"): на планшете
* и ниже схлопывается в одну колонку, сайдбар уезжает над контентом. */
@media (max-width: 1024px) {
.gd-grid-sidebar {
grid-template-columns: 1fr !important;
}
/* sticky-сайдбар внутри схлопнутого грида не должен «прилипать». */
.gd-grid-sidebar > .gd-sidebar {
position: static !important;
top: auto !important;
height: auto !important;
}
}
/* Карта/контент рядом с фиксированным сайдбаром: на планшете в колонку. */
@media (max-width: 1024px) {
.gd-split {
flex-direction: column !important;
overflow: visible !important;
}
.gd-split > .gd-split-aside {
width: 100% !important;
flex-shrink: 1 !important;
/* в desktop у сайдбара не было левого паддинга (он стоял справа от карты);
* в колонке возвращаем симметрию. */
padding-left: 16px !important;
padding-top: 0 !important;
}
}
/* Nav-tabs: на телефоне — горизонтальный скролл со снапом, НЕ hamburger. */
@media (max-width: 767px) {
.gd-nav-scroll {
overflow-x: auto;
flex-wrap: nowrap;
scroll-snap-type: x proximity;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
.gd-nav-scroll::-webkit-scrollbar {
display: none;
}
.gd-nav-scroll > * {
flex: 0 0 auto;
scroll-snap-align: start;
}
}
/* Таблицы с фиксированной шириной колонок — оборачивать в .gd-table-scroll. */
.gd-table-scroll {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
/* KPI-grid: на телефоне одна колонка во всю ширину (ui-conventions). */
@media (max-width: 767px) {
.gd-kpi-grid {
grid-template-columns: 1fr !important;
}
}
/* Карта Leaflet на узких экранах — гарантированная высота, чтобы не
* схлопнулась в 0 когда flex-родитель встаёт в колонку. */
@media (max-width: 1024px) {
.gd-map-shell {
min-height: 420px;
}
}
/* Section-nav сайдбара анализа: на планшете/телефоне (когда грид схлопнут)
* вертикальный список превращается в горизонтальную скролл-полоску со снапом —
* чтобы не съедать пол-экрана высоты над контентом (issue #66). */
@media (max-width: 1024px) {
.gd-section-nav {
flex-direction: row !important;
overflow-x: auto;
padding: 8px 4px !important;
scroll-snap-type: x proximity;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
.gd-section-nav::-webkit-scrollbar {
display: none;
}
.gd-section-nav > * {
display: flex;
flex: 0 0 auto;
scroll-snap-align: start;
}
.gd-section-nav button {
width: auto !important;
white-space: nowrap;
padding-left: 12px !important;
padding-right: 12px !important;
}
}