/* Gotcha — токен-система, тёмная и светлая темы. Без фреймворка, без сборки. */

/* htmx-индикатор: обычно htmx вставляет эти правила инлайном, но CSP
   default-src 'self' без unsafe-inline это блокирует (см. htmx-config в
   layout.templ, includeIndicatorStyles:false), поэтому держим их здесь. */
.htmx-indicator { opacity: 0; transition: opacity 200ms ease-in; }
.htmx-request .htmx-indicator { opacity: 1; }
.htmx-request.htmx-indicator { opacity: 1; }

:root {
	--bg: #0f131b;
	--surface: #171c28;
	--surface-2: #1b2130;
	--border: #263041;
	--text: #e6ebf3;
	--text-dim: #8a93a6;
	--text-mute: #5c6473;
	--accent: #3d7bff;
	--accent-hover: #5a90ff;
	--accent-fg: #ffffff;
	--accent-soft: rgba(96, 132, 255, .12);
	--rail: #0c0f16;
	--rail-border: #1c2534;
	--good: #2ea043;
	--warn: #d9a521;
	--danger: #f0574a;
	--info: #3d7bff;
	--link: #79aaff;
	--radius: 6px;
	--radius-lg: 10px;
	--space: 4px;
	--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--font-mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
	/* Шкала кеглей одним местом: раньше размеры были захардкожены в двух
	   десятках правил, и подгонка «чуть крупнее» означала правку каждого.
	   --fs-base — обычный текст, --fs-sm — вторичный (ячейки таблиц, мета),
	   --fs-xs — мелкие подписи и бейджи, --fs-label — микро-лейблы капсом
	   (заголовки колонок, подписи стат-плиток, ярлыки рейла). */
	--fs-base: 15px;
	--fs-sm: 14px;
	--fs-xs: 12px;
	--fs-label: 11px;
}
:root[data-theme="light"] {
	--bg: #f6f8fb;
	--surface: #ffffff;
	--surface-2: #eef2f7;
	--border: #dde3ec;
	--text: #1a2130;
	--text-dim: #5a6472;
	--text-mute: #8a93a6;
	--accent: #2f6bff;
	--accent-hover: #1f5aff;
	--accent-fg: #ffffff;
	--accent-soft: rgba(47, 107, 255, .10);
	/* Рейл заметно глубже полотна и сайдбара: на светлой теме он иначе
	   сливается с сайдбаром в одну серую полосу и перестаёт читаться как
	   отдельная зона навигации. Тёмным (как в спеке §4.1) не делаем —
	   сплошная тёмная колонка на светлом фоне читается как артефакт. */
	--rail: #e4e9f2;
	--rail-border: #ccd5e2;
	--good: #1a7f37;
	--warn: #9a6700;
	--danger: #cf222e;
	--info: #2f6bff;
	--link: #2f6bff;
}
@media (prefers-color-scheme: light) {
	:root:not([data-theme="dark"]) {
		--bg: #f6f8fb;
		--surface: #ffffff;
		--surface-2: #eef2f7;
		--border: #dde3ec;
		--text: #1a2130;
		--text-dim: #5a6472;
		--text-mute: #8a93a6;
		--accent: #2f6bff;
		--accent-hover: #1f5aff;
		--accent-fg: #ffffff;
		--accent-soft: rgba(47, 107, 255, .10);
		--rail: #e4e9f2;
		--rail-border: #ccd5e2;
		--good: #1a7f37;
		--warn: #9a6700;
		--danger: #cf222e;
		--info: #2f6bff;
		--link: #2f6bff;
	}
}

* {
	box-sizing: border-box;
}

body {
	margin: 0;
	background: var(--bg);
	color: var(--text);
	font-family: var(--font-sans);
	font-size: var(--fs-base);
	line-height: 1.5;
}

/* Типографическая шкала (спека §4.2, компактная плотность). Без этих правил
   заголовки берут дефолт браузера (h1 = 2em), и шапка каждой страницы
   получается втрое крупнее строки таблицы — из компактной вёрстки это
   выбивается сильнее всего. */
h1 {
	font-size: 22px;
	font-weight: 650;
	line-height: 1.25;
	margin: 0 0 10px;
}
h2 {
	font-size: 18px;
	font-weight: 650;
	line-height: 1.3;
	margin: 18px 0 8px;
}
h3 {
	font-size: 15px;
	font-weight: 600;
	line-height: 1.3;
	margin: 14px 0 6px;
}

code, pre {
	font-family: var(--font-mono);
}
pre {
	overflow-x: auto;
	max-width: 100%;
}

a {
	color: var(--link);
	text-decoration: none;
}
a:hover {
	text-decoration: underline;
}

/* ============================================================
   App shell — icon rail + context sidebar + topbar (Task 4, §5 IA).
   Компактно, всё через токены (кроме фирменного градиента лого-
   типа рейла — фиксированная марка бренда, см. .rail-logo).
   ============================================================ */
.app-shell {
	display: grid;
	grid-template-columns: 96px 200px 1fr;
	min-height: 100vh;
}

/* -- Icon rail: логотип, области нав-структуры, аватар, логаут -- */
.rail {
	background: var(--rail);
	border-right: 1px solid var(--rail-border);
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 8px 0;
	gap: 2px;
}
.rail-logo {
	width: 30px;
	height: 30px;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 8px;
	text-decoration: none;
}
/* Фирменный знак: моно-«G» в уголковой рамке-прицеле (см. brandMark в
   icons.templ). Размер задаётся здесь, не атрибутами SVG. */
.brand-mark {
	display: block;
	width: 30px;
	height: 30px;
}
.rail-area {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 3px;
	width: 100%;
	padding: 7px 4px;
	color: var(--text-dim);
	text-decoration: none;
}
.rail-area:hover {
	color: var(--text);
}
/* Двутон: иконка на мягкой плитке, активная область — плитка акцентом */
.rail-area .rail-ic {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	border-radius: 8px;
	background: var(--accent-soft);
}
.rail-area .ic {
	width: 18px;
	height: 18px;
}
.rail-area.is-active {
	color: var(--text);
}
.rail-area.is-active .rail-ic {
	background: var(--accent);
}
.rail-area.is-active .ic {
	color: var(--accent-fg);
}
.rail-label {
	font-size: var(--fs-label);
	line-height: 1.1;
	letter-spacing: .2px;
	text-align: center;
	/* Перенос длинных ярлыков задаётся мягким переносом (U+00AD) прямо в
	   каталоге локалей: hyphens:auto работает только там, где у браузера есть
	   словарь переносов для языка страницы, а без него слово рвалось в
	   произвольном месте («Документаци/я»). Мягкий перенос не зависит от
	   словаря и не виден, пока перенос не понадобился. */
	hyphens: manual;
	overflow-wrap: break-word;
	max-width: 100%;
}
.rail-spacer {
	flex: 1;
}
.rail-logout,
.rail-logout .rail-logout-btn {
	background: none;
	border: none;
	color: var(--text-dim);
	cursor: pointer;
	padding: 6px;
	margin: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}
.rail-logout-btn:hover {
	background: none;
	color: var(--danger);
}
.rail-logout-btn .ic {
	width: 18px;
	height: 18px;
}
.avatar {
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: var(--accent-soft);
	color: var(--accent);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: var(--fs-xs);
	font-weight: 600;
	text-decoration: none;
	margin-top: 6px;
}

/* -- Context sidebar: переключатель проекта + подразделы области -- */
.ctx-sidebar {
	background: var(--surface);
	border-right: 1px solid var(--border);
	display: flex;
	flex-direction: column;
	padding: 8px;
	gap: 2px;
	overflow-y: auto;
}
.proj-switch {
	margin-bottom: 8px;
}
.proj-switch summary {
	list-style: none;
	cursor: pointer;
	padding: 7px 9px;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	font-weight: 600;
	color: var(--text);
	overflow-wrap: anywhere;
}
.proj-switch summary::-webkit-details-marker {
	display: none;
}
.proj-switch summary {
	display: flex;
	align-items: center;
	gap: 6px;
}
.proj-switch-name {
	flex: 1;
	min-width: 0;
	overflow-wrap: anywhere;
}
.proj-switch summary .ic {
	flex: none;
	color: var(--text-dim);
	transition: transform 120ms ease;
}
.proj-switch[open] summary .ic {
	transform: rotate(180deg);
}
.proj-switch ul {
	list-style: none;
	margin: 4px 0 0;
	padding: 4px;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
}
.proj-switch li a {
	display: block;
	padding: 5px 8px;
	border-radius: var(--radius);
	color: var(--text-dim);
	text-decoration: none;
}
.proj-switch li a:hover {
	background: var(--surface-2);
	color: var(--text);
}
.ctx-item {
	display: block;
	padding: 6px 10px;
	border-radius: var(--radius);
	color: var(--text-dim);
	text-decoration: none;
	font-size: var(--fs-sm);
	overflow-wrap: anywhere;
}
.ctx-item:hover {
	background: var(--surface-2);
	color: var(--text);
}
.ctx-item.is-active {
	background: var(--surface-2);
	color: var(--text);
	box-shadow: inset 2px 0 0 var(--accent);
}
.ctx-settings {
	margin-top: auto;
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 6px 10px;
	color: var(--text-dim);
	text-decoration: none;
	border-top: 1px solid var(--border);
}
.ctx-settings .ic {
	width: 15px;
	height: 15px;
}
.ctx-settings:hover {
	color: var(--text);
}

/* -- Main column: topbar (breadcrumb + переключатели) + контент -- */
.app-main {
	display: flex;
	flex-direction: column;
	min-width: 0;
}
.topbar {
	height: 44px;
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 0 16px;
	border-bottom: 1px solid var(--border);
	background: var(--surface);
}
.topbar-spacer {
	flex: 1;
}
/* Сегмент-контролы: кнопки склеены в одну пилюлю (общие границы, без
   зазора), поэтому читаются как один переключатель с выбранным значением, а
   не как три самостоятельные кнопки. */
.lang-switcher,
.theme-toggle {
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
}
/* Компактные сегментированные переключатели — переопределяем громкую
   акцентную кнопку по умолчанию (см. правило `button` ниже), чтобы в 44px
   topbar они не спорили с основными действиями. */
.lang-switcher button,
.theme-toggle button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: none;
	border-left: 1px solid var(--border);
	color: var(--text-dim);
	padding: 4px 8px;
	font-size: var(--fs-xs);
	font-weight: 600;
	cursor: pointer;
	border-radius: 0;
}
.lang-switcher button:first-child,
.theme-toggle button:first-child {
	border-left: none;
}
.theme-toggle .ic {
	width: 14px;
	height: 14px;
}
.lang-switcher button:hover:not(.is-active),
.theme-toggle button:hover:not(.is-active) {
	color: var(--text);
	border-color: var(--text-dim);
}
.lang-btn.is-active,
.theme-btn.is-active {
	background: var(--accent-soft);
	color: var(--accent);
}
.app-content {
	flex: 1;
	padding: 16px 24px;
	min-width: 0;
	overflow-x: auto;
	/* Контент прижат влево, а не центрирован: оболочка выстроена слева
	   направо (рейл → сайдбар → контент), и центрирование разрывало эту
	   цепочку — левый край контента переставал совпадать с краем сайдбара,
	   и слева появлялось сиротское поле.
	   Потолок ширины сохраняем: без него таблица из восьми колонок на
	   ультравайде растягивается на 2400px, и связать первую колонку с
	   последней глазом уже трудно. На 1920-мониторе потолок не срабатывает. */
	max-width: 1920px;
	width: 100%;
	margin: 0;
}
.app-footer {
	padding: 8px 16px;
	font-size: 12px;
	text-align: right;
	color: var(--text-dim);
}
.app-footer a {
	color: var(--link);
	text-decoration: none;
}
.app-footer a:hover {
	text-decoration: underline;
}

/* Скролл-контейнер для длинных списков (участники и т.п.): ограничивает
   высоту блока и включает вертикальный скролл, чтобы 100 строк не растягивали
   страницу. */
/* Формы внутри ячеек таблицы выкладываются в строку. Без этого .select с его
   width:100% распирает ячейку и выталкивает кнопку на вторую строку, хотя
   места в карточке вдоволь. */
.member-role-form {
	display: flex;
	align-items: center;
	gap: 6px;
}
/* Формы добавления в команде: у select есть подпись сверху, поэтому кнопку
   выравниваем по НИЖНЕМУ краю поля (= низ select), иначе она центрируется
   относительно «подпись + select» и висит выше самого поля. */
.team-member-add-form,
.team-project-attach-form {
	display: flex;
	align-items: end;
	gap: 6px;
}
/* .field тянет нижний margin — в этой inline-форме он не нужен, иначе кнопка
   встаёт ниже select на величину этого отступа. */
.team-member-add-form .field,
.team-project-attach-form .field {
	margin-bottom: 0;
}
.member-role-form .select,
.team-member-add-form .select,
.team-project-attach-form .select {
	width: auto;
	min-width: 140px;
}

/* Прокручиваемый список: нижний край растворяется, чтобы обрезанная строка
   читалась как «список продолжается», а не как сломанная вёрстка. */
.scroll-list {
	max-height: 340px;
	overflow-y: auto;
	mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent 100%);
}

/* No-JS модальное окно через :target (CSP запрещает инлайн-JS). Триггер —
   ссылка на #id; оверлей скрыт, показывается при совпадении :target; закрытие
   — ссылка-фон и крестик ведут на "#" (пустой фрагмент снимает :target). */
.modal {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 100;
	background: rgba(0, 0, 0, .55);
	align-items: flex-start;
	justify-content: center;
	padding: 56px 16px;
	overflow-y: auto;
}
.modal:target {
	display: flex;
}
.modal-backdrop {
	position: absolute;
	inset: 0;
}
.modal-card {
	position: relative;
	z-index: 1;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: 20px 24px;
	width: 100%;
	max-width: 460px;
	box-shadow: 0 12px 40px rgba(0, 0, 0, .35);
}
/* Широкая модалка — для форм, где узкая колонка рвёт вёрстку (длинные подписи
   полей). */
.modal-card--wide {
	max-width: 560px;
}
.modal-close {
	position: absolute;
	top: 12px;
	right: 14px;
	color: var(--text-dim);
	font-size: 22px;
	line-height: 1;
	text-decoration: none;
}
.modal-close:hover {
	color: var(--text);
}
/* Кнопка-триггер создания сущности (в шапке раздела). */
.create-trigger {
	margin-bottom: 16px;
}
/* Две подформы «Данные субъекта (ПДн)» рядом (экспорт | удаление). */
.gdpr-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 16px 24px;
}
@media (min-width: 900px) {
	.gdpr-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Карточки правил алертинга (new_issue/regression/spike) рядами — было
   вертикальным стеком трёх fieldset'ов, слишком высоко/разреженно. */
/* Правила алертов: на узком экране — колонкой. */
.rule-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 16px;
	margin-bottom: 16px;
}
/* На широком экране — две колонки: слева «Новый issue» и под ним «Регрессия»
   (равны между собой — одинаковое содержимое, по одному полю), справа
   «Всплеск» на всю высоту левой пары (grid-row 1/span 2, растянут). Порядок
   в DOM: new_issue(1), regression(2), spike(3). */
@media (min-width: 900px) {
	.rule-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-auto-rows: 1fr;
		align-items: stretch;
	}
	.rule-grid > :nth-child(1) { grid-column: 1; grid-row: 1; }
	.rule-grid > :nth-child(2) { grid-column: 1; grid-row: 2; }
	.rule-grid > :nth-child(3) { grid-column: 2; grid-row: 1 / span 2; }
}

/* -- Chromeless: анонимные/setup-страницы (логин, регистрация, онбординг,
   ошибки) — без рейла и сайдбара, тонкая верхняя полоса + центр-форма -- */
.chromeless-top {
	height: 48px;
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 0 16px;
	border-bottom: 1px solid var(--border);
	background: var(--surface);
}
.chromeless-main {
	max-width: 520px;
	margin: 40px auto;
	padding: 0 16px;
}
/* Бренд-лок-ап (знак + вордмарк) в тонкой верхней полосе chromeless-страниц. */
.brand-lockup {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	text-decoration: none;
}
.brand-lockup .brand-mark {
	width: 26px;
	height: 26px;
}
.brand-word {
	font-weight: 700;
	font-size: 16px;
	letter-spacing: -.01em;
	color: var(--text);
}

/* Бренд-момент на логине: крупный знак + вордмарк + слоган голосом продукта. */
.auth-brand {
	max-width: 360px;
	margin: 40px auto 0;
	text-align: center;
}
.auth-brand .brand-mark {
	width: 52px;
	height: 52px;
	margin: 0 auto 8px;
}
.auth-brand-word {
	display: block;
	font-weight: 700;
	font-size: 26px;
	letter-spacing: -.02em;
	color: var(--text);
}
.auth-tagline {
	margin: 6px 0 0;
	color: var(--text-dim);
	font-size: var(--fs-base);
}
.auth-brand + .auth-form {
	margin-top: 16px;
}

/* -- Мобильное disclosure-меню в topbar: дублирует содержимое .ctx-sidebar
   (переключатель проекта, подразделы, настройки проекта) без JS — работает
   через нативные <details>/<summary>. На десктопе скрыто, т.к. тот же
   контент уже доступен в .ctx-sidebar (см. адаптив ниже). -- */
.mobile-nav {
	display: none;
}
.mobile-nav-summary {
	list-style: none;
	cursor: pointer;
	padding: 6px;
	display: inline-flex;
	align-items: center;
	border-radius: var(--radius);
	color: var(--text-dim);
}
.mobile-nav-summary::-webkit-details-marker {
	display: none;
}
.mobile-nav-summary:hover {
	background: var(--surface-2);
	color: var(--text);
}
.mobile-nav-panel {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 20;
	min-width: 220px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 8px;
	display: flex;
	flex-direction: column;
	gap: 2px;
	box-shadow: 0 8px 24px rgba(0, 0, 0, .3);
}

/* -- Адаптив: на узких экранах сайдбар подразделов скрывается, рейл
   остаётся всегда доступным; вместо сайдбара — мобильное disclosure-меню
   в topbar (см. .mobile-nav выше) -- */
@media (max-width: 900px) {
	.app-shell {
		grid-template-columns: 96px 1fr;
	}
	.ctx-sidebar {
		display: none;
	}
	.mobile-nav {
		display: block;
		position: relative;
	}
}

main {
	max-width: 960px;
	margin: 0 auto;
	padding: 24px;
}

.auth-form {
	max-width: 360px;
	margin: 40px auto;
	display: flex;
	flex-direction: column;
	gap: 12px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 24px;
}
.auth-form h1 {
	margin: 0 0 4px;
	font-size: 20px;
}
.auth-switch {
	margin: 0;
	font-size: var(--fs-base);
	color: var(--text-dim);
}

label {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: var(--fs-base);
	color: var(--text-dim);
}

input {
	background: var(--bg);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	color: var(--text);
	padding: 6px 10px;
	font-size: var(--fs-base);
}
input:focus {
	outline: 2px solid var(--accent);
	outline-offset: -1px;
}

button {
	background: var(--accent);
	color: var(--accent-fg);
	border: none;
	border-radius: var(--radius);
	padding: 6px 12px;
	font-size: var(--fs-base);
	font-weight: 600;
	cursor: pointer;
}
button:hover {
	background: var(--accent-hover);
}

.error {
	background: color-mix(in srgb, var(--danger) 16%, transparent);
	border: 1px solid var(--danger);
	color: var(--danger);
	border-radius: var(--radius);
	padding: 6px 10px;
	font-size: var(--fs-base);
	margin: 0;
}

.quota-banner {
	display: flex;
	align-items: center;
	gap: 10px;
	background: color-mix(in srgb, var(--warn) 16%, transparent);
	border: 1px solid var(--warn);
	border-radius: var(--radius);
	padding: 8px 12px;
	font-size: var(--fs-base);
	margin: 0 0 12px;
}
.quota-banner a {
	white-space: nowrap;
}

.notice {
	background: color-mix(in srgb, var(--info) 16%, transparent);
	border: 1px solid var(--info);
	color: var(--info);
	border-radius: var(--radius);
	padding: 6px 10px;
	font-size: var(--fs-base);
	margin: 0;
}

.warning {
	background: color-mix(in srgb, var(--warn) 14%, transparent);
	color: var(--warn);
	border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
	border-radius: var(--radius);
	padding: 8px 12px;
}

/* Приглушённые пояснительные абзацы (подсказки полей, заметки о лимитах). */
.hint, .apdex-note, .perf-cap-note, .trace-cap-note, .retention-notice {
	color: var(--text-dim);
	font-size: var(--fs-sm);
	margin: 4px 0;
}

table {
	width: 100%;
	border-collapse: collapse;
	font-variant-numeric: tabular-nums;
}
th, td {
	text-align: left;
	padding: 6px 10px;
	border-bottom: 1px solid var(--border);
	font-size: var(--fs-base);
}
th {
	color: var(--text-dim);
	font-weight: 600;
	font-size: var(--fs-sm);
	text-transform: uppercase;
}

.badge {
	display: inline-block;
	border-radius: 999px;
	padding: 2px 8px;
	font-size: var(--fs-xs);
	font-weight: 700;
	text-transform: uppercase;
	white-space: nowrap;
}
/* Inline checkbox + подпись (используется формами алертов/мониторов/обслуживания
   и др.): чекбокс и текст на одной строке, кликабельная подпись целиком. */
.checkbox-inline {
	display: inline-flex;
	flex-direction: row;
	align-items: center;
	gap: 8px;
	color: var(--text);
	font-size: var(--fs-base);
	cursor: pointer;
}
.checkbox-inline input[type="checkbox"] {
	margin: 0;
	width: auto;
	padding: 0;
	flex: none;
}
/* Флеймграф-SVG (viewBox без width/height) — растянуть на ширину карточки. */
.flamegraph {
	width: 100%;
	height: auto;
	display: block;
}
/* SVG-графики (viewBox без width/height) — растянуть на ширину карточки. */
.metric-chart, .waterfall {
	width: 100%;
	height: auto;
	display: block;
}
.waterfall-label {
	font-family: var(--font-mono);
	font-size: var(--fs-label);
}
.badge-info { background: color-mix(in srgb, var(--info) 16%, transparent); color: var(--info); }

.vital-value { margin-right: 6px; }
.vital-chart {
	display: inline-block;
	width: 240px;
	height: 48px;
	vertical-align: middle;
	color: var(--accent);
}
.vital-chart-cell {
	white-space: nowrap;
}

.sparkline {
	display: inline-block;
	width: 96px;
	height: 24px;
	vertical-align: middle;
	color: var(--accent);
}

/* -- Фильтр-панели разделов: единый компактный горизонтальный тулбар.
   Общий для Issues / Performance / Web Vitals / Metrics. Тулбар намеренно
   визуально тихий — герой страницы это таблица/график под ним. Контролы
   по содержимому (а не во всю ширину), поиск слегка растягивается, кнопка
   «Применить» замыкает ряд справа. На узких экранах ряд переносится. -- */
.issues-filters,
.performance-filters,
.metric-filters {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 8px;
	margin-bottom: 16px;
}
/* Контролы тулбара — по содержимому. Базовое .input/.select задаёт
   width:100% (для вертикальных форм), здесь его переопределяем. */
.issues-filters .select,
.issues-filters .input,
.performance-filters .select,
.performance-filters .input,
.metric-filters .select {
	width: auto;
	min-width: 128px;
}
/* Текстовый поиск может умеренно растянуться, заполняя ряд. */
.issues-filters .input[type="text"] {
	flex: 1 1 200px;
	min-width: 180px;
	max-width: 380px;
}
/* Metric-фильтр: подпись над контролом (label-обёртка) — пары стоят в ряд. */
.metric-filters > label {
	width: auto;
	gap: 4px;
	font-size: var(--fs-sm);
}
.issues-filters select,
.issues-filters input {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	color: var(--text);
	padding: 6px 8px;
	font-size: var(--fs-base);
}

/* Metric-фильтр по лейблам (страница метрики). */
.metric-labels {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
}
.metric-label-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	margin-bottom: 4px;
}
.metric-label-key {
	color: var(--text-dim);
	font-size: var(--fs-sm);
	font-weight: 600;
}

.culprit {
	color: var(--text-dim);
	font-size: var(--fs-sm);
}

.bulk-actions {
	display: flex;
	gap: 8px;
	margin-top: 8px;
}
.bulk-actions button:not(.btn) {
	background: var(--surface);
	color: var(--text);
	border: 1px solid var(--border);
	font-weight: 600;
}
.bulk-actions button:not(.btn):hover {
	background: var(--surface);
	border-color: var(--accent);
}

.pagination {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 12px;
	color: var(--text-dim);
	font-size: var(--fs-base);
	font-variant-numeric: tabular-nums;
}

.issue-meta {
	display: flex;
	gap: 12px;
	margin: 6px 0 12px;
	color: var(--text-dim);
	font-size: var(--fs-base);
}

.issue-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 8px;
	margin-bottom: 16px;
}
.issue-actions form {
	display: flex;
	gap: 8px;
	margin: 0;
}
.assign-form select {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	color: var(--text);
	padding: 6px 8px;
	font-size: var(--fs-base);
}

.chart {
	display: block;
	width: 100%;
	max-width: 480px;
	height: 96px;
	color: var(--accent);
	margin-bottom: 16px;
}

/* Выбор типа проверки в форме монитора: радиокнопки-вкладки + прогрессивное
   раскрытие полей выбранного типа без JS (см. kindPicker в monitorform.templ).
   Радио скрыты визуально, но фокусируемы; клик по .kind-tab переключает. */
.kind-picker {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin-bottom: 16px;
}
.kind-picker-label {
	flex-basis: 100%;
	font-size: var(--fs-base);
	color: var(--text-dim);
	margin-bottom: 2px;
}
.kind-radio {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}
.kind-tab {
	padding: 6px 16px;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	cursor: pointer;
	font-size: 14px;
	user-select: none;
}
.kind-radio:checked + .kind-tab {
	background: var(--accent);
	color: #fff;
	border-color: var(--accent);
}
.kind-radio:focus-visible + .kind-tab {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}
.kind-fields {
	flex-basis: 100%;
	display: none;
}
#kf-http:checked ~ .kind-fields--http,
#kf-tcp:checked ~ .kind-fields--tcp,
#kf-dns:checked ~ .kind-fields--dns,
#kf-heartbeat:checked ~ .kind-fields--heartbeat {
	display: block;
}

/* График частоты событий на странице issue — с осями (viewBox 360×140,
   пропорции сохраняются, поэтому height:auto, а не фикс). */
.chart-freq {
	display: block;
	width: 100%;
	max-width: 480px;
	height: auto;
	color: var(--accent);
	margin-bottom: 16px;
}

/* Оси/сетка и подписи графиков (metric-chart, chart-freq): приглушённый цвет,
   моноширинный мелкий шрифт. Пороговые линии — цвет опасности. */
.metric-chart text, .chart-freq text { font-size: var(--fs-xs); font-family: var(--font-mono); }
.chart-axis { color: var(--text-dim); }
.chart-threshold { color: var(--danger); }

/* .issue-detail — вертикальный ритм страницы issue: заголовок, мета, действия,
   график и лента событий идут одной колонкой. Ширину не ограничиваем: потолок
   стоит на самой контентной колонке (.app-content), а второй уровень
   ограничения давал ступеньку — список issues шире, чем таблица событий на
   детали того же issue. */
.issue-detail {
	min-width: 0;
}

/* .issue-chart парен с .card (фон/рамка/радиус/внутренний отступ оттуда) —
   здесь только горизонтальная прокрутка: SVG за 7 дней шире узкого экрана,
   и обрезать его нельзя. */
.issue-chart {
	margin-bottom: 16px;
	overflow-x: auto;
}
/* График событий тянем на всю карточку: .chart/.chart-freq ограничены
   max-width 480px (разумно для узкой врезки в списке), но в карточке детали
   это давало график на половину ширины и пустое поле справа. Высоту не
   задаём — она считается из пропорций холста, иначе браузер вписал бы рисунок
   по высоте и отцентрировал, оставив поля по бокам. */
.issue-chart .chart,
.issue-chart .chart-freq {
	max-width: none;
	height: auto;
}

.issue-events-heading {
	margin: 20px 0 8px;
}

.event-trace-link {
	margin: 6px 0 12px;
	font-size: var(--fs-base);
}

/* .tags парен с .data-table: таблица тегов — это узкий список ключ/значение,
   и растягивать её на всю ширину незачем. Значение моноширинное, как и
   остальные машинные строки (id, стектрейсы). */
.tags {
	width: auto;
	min-width: min(420px, 100%);
	margin-bottom: 12px;
}
.tags td:first-child {
	color: var(--text-dim);
	white-space: nowrap;
}
.tags td:last-child {
	font-family: var(--font-mono);
	word-break: break-all;
}

.issue-events {
	margin-bottom: 16px;
}
.event-row {
	cursor: default;
}
.event-row-selected {
	background: var(--accent-soft);
}

.event-detail {
	border-top: 1px solid var(--border);
	padding-top: 12px;
}
.event-detail h3 {
	font-size: var(--fs-base);
	text-transform: uppercase;
	color: var(--text-dim);
	margin: 12px 0 6px;
}
.event-detail pre {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 8px;
	overflow-x: auto;
	font-size: var(--fs-base);
}
.event-meta {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0 24px;
}
@media (min-width: 700px) {
	.event-meta { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.frames {
	display: flex;
	flex-direction: column;
	gap: 6px;
}
.frame {
	border: 1px solid var(--border);
	border-radius: var(--radius);
	padding: 6px 10px;
	font-size: var(--fs-base);
}
.frame.in-app {
	border-color: var(--accent);
	background: var(--accent-soft);
}
.frame-location {
	color: var(--text-dim);
	font-size: var(--fs-sm);
	overflow-wrap: anywhere;
}
.frame-function {
	font-weight: 600;
	overflow-wrap: anywhere;
}
.error-page {
	max-width: 460px;
	margin: 72px auto;
	padding: 0 16px;
	text-align: center;
}
/* Код статуса — герой: моноширинный, в акценте, обрамлён скобками-рамкой
   [код] (тот же «пойман в рамку» мотив, что и у фирменного знака). */
.error-code {
	font-family: var(--font-mono);
	font-size: 66px;
	font-weight: 700;
	line-height: 1;
	color: var(--accent);
	margin: 0 0 10px;
}
.error-code::before {
	content: "[";
	color: var(--text-mute);
	margin-right: 10px;
}
.error-code::after {
	content: "]";
	color: var(--text-mute);
	margin-left: 10px;
}
.error-title {
	font-size: 22px;
	font-weight: 700;
	margin: 0 0 6px;
	color: var(--text);
}
.error-body {
	max-width: 380px;
	margin: 0 auto 20px;
	color: var(--text-dim);
	font-size: 14px;
	line-height: 1.6;
}

.frame-module {
	color: var(--text-dim);
	font-size: var(--fs-sm);
}
/* Стектрейс — это код: фреймы моноширинным. Свёрнутые system-фреймы
   (<details>) кликабельны; длинный id события переносится. */
.frame {
	font-family: var(--font-mono);
}
.frame-system > summary {
	cursor: pointer;
	overflow-wrap: anywhere;
}
/* Исходный код кадра: строки с номерами, строка ошибки подсвечена акцентом. */
.frame-source {
	margin-top: 6px;
	padding-top: 6px;
	border-top: 1px solid var(--border);
	overflow-x: auto;
	font-size: var(--fs-sm);
	line-height: 1.55;
}
.src-line {
	display: flex;
}
.src-line-current {
	background: var(--accent-soft);
}
.src-lineno {
	flex: 0 0 auto;
	width: 44px;
	padding-right: 12px;
	text-align: right;
	color: var(--text-mute);
	user-select: none;
}
.src-line-current .src-lineno {
	color: var(--accent);
	font-weight: 700;
}
.src-code {
	flex: 1 1 auto;
	white-space: pre;
}
/* Контексты — читаемый отформатированный JSON (json.Indent), а не одна строка. */
.contexts-json {
	white-space: pre;
	overflow-x: auto;
}
.event-id {
	overflow-wrap: anywhere;
	margin-bottom: 8px;
}

.monitors table, .monitor-detail table {
	margin-bottom: 16px;
}
.availability-bars {
	display: inline-block;
	width: 192px;
	height: 24px;
	vertical-align: middle;
}
.monitor-meta {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin: 6px 0 12px;
	color: var(--text-dim);
	font-size: var(--fs-base);
}
.monitor-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-bottom: 16px;
}
.monitor-actions form {
	display: flex;
	gap: 8px;
	margin: 0;
}
.monitor-actions button:not(.btn) {
	background: var(--surface);
	color: var(--text);
	border: 1px solid var(--border);
	font-weight: 600;
}
.monitor-actions button:not(.btn):hover {
	background: var(--surface);
	border-color: var(--accent);
}
.monitor-chart {
	margin-bottom: 16px;
}
.latency-chart {
	display: block;
	width: 100%;
	max-width: 480px;
	height: 120px;
}

/* Публичная статус-страница (/status/{slug}): свой layout, без шапки
   приложения — отсюда собственные отступы у main. */
.status-page {
	max-width: 720px;
	margin: 0 auto;
	padding: 24px 20px;
}
.status-overall {
	display: inline-block;
	padding: 8px 16px;
	border-radius: var(--radius-lg);
	font-weight: 600;
	margin: 6px 0 20px;
}
.status-overall-ok { background: color-mix(in srgb, var(--good) 16%, transparent); color: var(--good); }
.status-overall-partial { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
.status-overall-major { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.status-description {
	color: var(--text-dim);
}
.status-tiles {
	list-style: none;
	padding: 0;
	margin: 0 0 20px;
}
/* .status-tile pairs with the shared .card component (background/border/
   radius/padding) in the template; only the tile-specific spacing lives
   here. */
.status-tile {
	margin-bottom: 8px;
}
.status-tile-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 6px;
}
.status-tile-name {
	font-weight: 600;
}
.status-tile-uptime {
	color: var(--text-dim);
	font-size: var(--fs-base);
	margin-top: 6px;
	font-variant-numeric: tabular-nums;
}
.status-tile-bars .availability-bars {
	width: 100%;
	height: 24px;
}

/* Настройки статус-страниц проекта: заголовок страницы и группа карточек
   (настройки, сервисы, публикация). Раньше поля шли сплошным потоком, а
   список сервисов был набором строк с повторяющейся подписью «Публичное имя»
   и полями, начинавшимися с разного отступа, — теперь это таблица. */
.status-page-item {
	margin-bottom: 16px;
}
/* Три блока одной карточки статус-страницы — друг под другом: настройки,
   сервисы, публикация. Разделены горизонтальными линиями, чтобы группы
   читались как части одной формы, а не как отдельные карточки. */
.status-page-editor {
	display: flex;
	flex-direction: column;
}
.status-page-block {
	min-width: 0;
	padding: 12px 0;
}
.status-page-block:first-child {
	padding-top: 0;
}
.status-page-block:last-child {
	padding-bottom: 0;
}
.status-page-block + .status-page-block {
	border-top: 1px solid var(--border);
}
.status-page-block > h3 {
	margin-top: 0;
	color: var(--text-dim);
	text-transform: uppercase;
	font-size: var(--fs-label);
	letter-spacing: .4px;
}
/* Поля настроек и публичных имён не растягиваем на всю карточку: slug,
   заголовок и публичное имя — короткие значения, поле во всю ширину под них
   выглядит несоразмерно. */
/* Внутри узкой карточки (сетка 3/2/1) фиксированные ширины полей больше не
   нужны — поля занимают ширину своего блока. Таблица сервисов тоже на всю
   ширину карточки. */
.status-page-editor .data-table {
	width: 100%;
}

/* OAuth / social login: кнопки на /login, /register и в профиле. */
.oauth-buttons {
	margin-top: 12px;
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.oauth-sep {
	text-align: center;
	color: var(--text-dim);
	margin: 6px 0;
}
.oauth-btn {
	display: block;
	text-align: center;
	padding: 6px;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	text-decoration: none;
	color: var(--text);
}
.oauth-btn:hover {
	background: var(--surface-2);
}
/* Профиль: список связанных аккаунтов. */
.linked-email {
	color: var(--text-dim);
	font-size: var(--fs-base);
}
.linked-note {
	color: var(--text-dim);
	font-size: var(--fs-base);
}
form.inline {
	display: inline;
}

/* ===== Design-system components (sub-project ②) ===== */
/* Общие переиспользуемые классы для app-shell (③) и разделов (④).
   Все цвета/отступы — через токены из :root выше; работает в обеих темах. */

/* -- Buttons -- */
.btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 12px;
	border: none;
	border-radius: var(--radius);
	font-family: inherit;
	font-size: var(--fs-base);
	font-weight: 600;
	line-height: 1.4;
	cursor: pointer;
	text-decoration: none;
}
.btn-primary {
	background: var(--accent);
	color: var(--accent-fg);
}
.btn-primary:hover {
	background: var(--accent-hover);
}
.btn-ghost {
	background: transparent;
	color: var(--text);
	border: 1px solid var(--border);
}
.btn-ghost:hover {
	background: var(--surface-2);
}
.btn-danger {
	background: var(--danger);
	color: var(--accent-fg);
}
.btn-danger:hover {
	filter: brightness(0.92);
}
/* .btn-danger-ghost — опасное действие В СТРОКЕ таблицы (удалить участника,
   канал, ключ, пробу). Сплошная заливка тут не годится: строк много, и
   столбик красных прямоугольников перетягивает на себя всё внимание, хотя
   удаление — не то действие, к которому надо вести взгляд. Заливку
   оставляем одиночным кнопкам в «опасной зоне». */
.btn-danger-ghost {
	background: none;
	color: var(--danger);
	border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}
.btn-danger-ghost:hover {
	background: color-mix(in srgb, var(--danger) 12%, transparent);
	color: var(--danger);
}
.btn:disabled {
	opacity: .5;
	cursor: not-allowed;
	filter: none;
}

/* -- Badges --
   Базовый .badge (display/radius/padding/uppercase) уже определён выше;
   здесь только семантические модификаторы новой палитры + служебные варианты.
   .badge-info уже существует выше и совпадает по стилю — переиспользуется как есть. */
.badge-good { background: color-mix(in srgb, var(--good) 16%, transparent); color: var(--good); }
.badge-warn { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
.badge-danger { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.badge-neutral {
	background: var(--surface-2);
	color: var(--text-dim);
}

/* -- Data table --
   Отдельный класс поверх глобальных table/th/td: компактнее, с hover-строками
   и колонкой .num для чисел. Не конфликтует с существующими table/th/td —
   выше по специфичности при использовании внутри .data-table. */
/* По умолчанию таблица занимает ширину своего контейнера: у таблиц с гибкой
   основной колонкой (issue, эндпойнт, монитор) слабину забирает эта колонка.
   Раньше умолчанием было width:auto — таблица льнула к содержимому и
   оставляла справа пустое поле внутри и без того ограниченной колонки. */
.data-table {
	width: 100%;
	max-width: 100%;
	border-collapse: collapse;
	font-variant-numeric: tabular-nums;
}
/* Обратный модификатор — для узких таблиц «ключ → значение» (теги события и
   т.п.), которые растягивать через всю страницу незачем. */
.data-table--auto {
	width: auto;
}
.data-table th {
	text-align: left;
	padding: 0 8px 8px 0;
	border-bottom: 1px solid var(--border);
	color: var(--text-dim);
	font-size: var(--fs-label);
	font-weight: 600;
	text-transform: uppercase;
}
.data-table td {
	padding: 8px 8px 8px 0;
	border-bottom: 1px solid var(--border);
	font-size: var(--fs-sm);
	font-variant-numeric: tabular-nums;
}
.data-table tbody tr:hover {
	background: var(--surface-2);
}
.data-table .num {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/* -- Stat tile -- */
.stat-tile {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: 10px 12px;
}
.stat-label {
	color: var(--text-dim);
	font-size: var(--fs-label);
	font-weight: 600;
	letter-spacing: .3px;
	text-transform: uppercase;
}
.stat-value {
	margin-top: 2px;
	font-size: 20px;
	font-weight: 680;
	letter-spacing: -.5px;
	font-variant-numeric: tabular-nums;
	overflow-wrap: anywhere;
}

/* -- Cards / panels -- */
.card,
.panel {
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: 14px 16px;
}
.card-header,
.panel-header {
	margin-bottom: 10px;
	font-weight: 650;
}

/* -- Адаптивная сетка блоков настроек (settings/profile/teams/org) --
   1 колонка → 2 (≥1024px) → 3 (≥1440px). minmax(0,1fr) не даёт широкому
   содержимому (таблицы, <pre>) распирать колонку. Карточки с широкими
   таблицами занимают всю ширину строки через .card--wide. */
.settings-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 16px;
	align-items: start;
	margin-bottom: 16px;
}
@media (min-width: 1024px) {
	.settings-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1440px) {
	.settings-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.settings-grid > .card { margin: 0; }
.settings-grid > .card--wide { grid-column: 1 / -1; }

/* Настройки проекта: карточки одной строки — равной высоты (ровные низа
   вместо «лесенки», которую давал общий align-items:start). */
.project-settings .settings-grid { align-items: stretch; }
/* Вертикальная пара карточек в одной колонке (Хранение данных + Опасная зона).
   Занимает одну ячейку сетки и НЕ растягивается под высокую соседнюю карточку
   (Регрессии) — align-self:start прижимает пару к верху строки. */
.settings-stack {
	display: flex;
	flex-direction: column;
	gap: 16px;
	align-self: start;
}
.settings-stack > .card { margin: 0; }
/* «Новый ключ» не должен прилипать к таблице DSN-ключей сверху. */
.key-create-form { margin-top: 12px; }

/* Разлипание вертикально составленных действий в карточке: несколько форм/
   кнопок подряд (напр. Опасная зона — «Покинуть» и «Удалить» шли впритык). */
.card-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 4px;
}
.card-actions > form {
	margin: 0;
}

/* -- About page (/about): build-info list + outbound links -- */
.about-list {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 6px 16px;
	margin: 0;
}
.about-list dt { color: var(--text-dim); }
.about-list dd {
	margin: 0;
	color: var(--text);
	font-variant-numeric: tabular-nums;
}
.about-links {
	margin-top: 16px;
	color: var(--text-dim);
}
.about-links a {
	color: var(--link);
	text-decoration: none;
}
.about-links a:hover { text-decoration: underline; }

/* -- Tabs -- */
.tabs {
	display: flex;
	gap: 4px;
	border-bottom: 1px solid var(--border);
}
.tab {
	padding: 8px 10px;
	background: none;
	border: none;
	color: var(--text-dim);
	font-size: var(--fs-base);
	font-weight: 600;
	cursor: pointer;
}
.tab:hover {
	color: var(--text);
}
.tab.is-active {
	color: var(--text);
	box-shadow: inset 0 -2px 0 var(--accent);
}

/* -- Filter chips / pills -- */
.chip {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: 999px;
	padding: 3px 10px;
	color: var(--text-dim);
	font-size: var(--fs-sm);
	cursor: pointer;
}
.chip.is-active {
	background: var(--accent-soft);
	border-color: var(--accent);
	color: var(--accent);
}

/* -- Breadcrumb -- */
.breadcrumb {
	display: flex;
	align-items: center;
	gap: 6px;
	color: var(--text);
	font-size: var(--fs-base);
	font-weight: 600;
}
/* Ссылка «назад» несёт иконку из спрайта (см. breadcrumbBack), поэтому сама
   выкладывается флексом: иконка и подпись должны стоять на одной базовой
   линии с одинаковым зазором на всех страницах-деталях. */
.breadcrumb a {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	color: var(--text-dim);
}
.breadcrumb a:hover {
	color: var(--text);
}

/* -- Empty state -- */
.empty-state {
	padding: 40px 20px;
	color: var(--text-dim);
	text-align: center;
}
.empty-state .ic {
	display: block;
	width: 28px;
	height: 28px;
	margin: 0 auto 10px;
	color: var(--text-mute);
}
.empty-state h3,
.empty-state .empty-title {
	margin: 0 0 4px;
	color: var(--text);
	font-size: 14px;
	font-weight: 650;
}
.empty-state p {
	margin: 0 auto;
	max-width: 380px;
	font-size: var(--fs-base);
	line-height: 1.5;
}
.empty-state .empty-cta {
	margin-top: 14px;
}
.no-projects {
	text-align: center;
	color: var(--text-dim);
}

/* -- Compact forms -- */
.field {
	display: block;
	margin-bottom: 12px;
}
.field label {
	display: flex;
	flex-direction: column;
	gap: 4px;
	color: var(--text-dim);
	font-size: var(--fs-sm);
}

/* -- Двухколоночная сетка полей внутри форм создания/редактирования
   (монитор, metric-алерт, обслуживание, статус-страница). 1 колонка →
   2 при ≥720px. Поля-исключения (textarea, длинные URL) занимают всю
   ширину через .field--wide. Внутри узких карточек-настроек НЕ
   используется — там формы остаются одноколоночными. -- */
.form-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0 16px;
	align-items: start;
}
@media (min-width: 720px) {
	.form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.form-grid > .field--wide { grid-column: 1 / -1; }
.input,
.select {
	display: block;
	width: 100%;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	color: var(--text);
	padding: 6px 10px;
	font-family: inherit;
	font-size: var(--fs-base);
}
.input:focus,
.select:focus {
	outline: 2px solid var(--accent);
	outline-offset: -1px;
}
textarea.input {
	resize: vertical;
	min-height: 64px;
}

/* -- Icon sprite (CSP: default-src 'self' без unsafe-inline запрещает
   style="", поэтому скрываем классом, не инлайн-стилем) -- */
.icon-sprite {
	display: none;
}

/* -- Icon base -- */
.ic {
	width: 1em;
	height: 1em;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.75;
	stroke-linecap: round;
	stroke-linejoin: round;
	vertical-align: -0.125em;
}

/* -- Keyboard focus ring (shared across interactive components) -- */
a:focus-visible, button:focus-visible, .btn:focus-visible, summary:focus-visible,
.rail-area:focus-visible, .rail-logout-btn:focus-visible, .ctx-item:focus-visible,
.tab:focus-visible, .chip:focus-visible, .lang-switcher button:focus-visible,
.theme-toggle button:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* -- Help panel (helpPanel, help.templ) -- контекстная справка под <h1>
   страниц-хабов (issues/performance/metrics/uptime/alerts). Нативный
   <details>/<summary> (CSP: default-src 'self' без unsafe-inline не
   допускает JS-раскрытие), свёрнут по умолчанию (нет open) -- тот же приём,
   что .proj-switch/.mobile-nav-summary выше. */
.help-panel {
	margin: 10px 0 16px;
}
.help-panel summary {
	list-style: none;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 0;
	color: var(--text-dim);
	font-size: var(--fs-base);
	font-weight: 600;
}
.help-panel summary::-webkit-details-marker {
	display: none;
}
.help-panel summary:hover {
	color: var(--text);
}
.help-panel-body {
	margin-top: 6px;
	padding: 10px 12px;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	font-size: var(--fs-base);
	color: var(--text-dim);
	max-width: 640px;
}
.help-panel-body p {
	margin: 0 0 8px;
}
.help-panel-body a {
	color: var(--link);
	text-decoration: none;
}
.help-panel-body a:hover {
	text-decoration: underline;
}

/* -- Getting started checklist (gettingStartedChecklist, help.templ) --
   компактная карточка над списком issues (задача 5, docs-onboarding),
   пока не закрыты все 4 шага онбординга. Список без маркеров: done-шаги
   приглушены (текстом ✓, без зачёркивания -- это не «отменено», а
   «выполнено»), todo-шаги ведут акцентной ссылкой на соответствующую
   страницу (SDK/оповещения/участники). */
.getting-started {
	max-width: 640px;
	margin: 0 0 16px;
}
.getting-started .card-header {
	font-size: 14px;
	font-weight: 650;
}
.gs-steps {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: var(--fs-base);
}
.gs-steps li {
	padding: 2px 0;
}
.gs-done {
	color: var(--text-dim);
}
.gs-todo {
	color: var(--text);
}
.gs-todo a {
	color: var(--link);
	font-weight: 600;
	text-decoration: none;
}
.gs-todo a:hover {
	text-decoration: underline;
}

/* -- Docs index (/docs) -- переиспользует .card/.settings-grid: одна
   секция (Начало/Разделы/Интеграции) на карточку. */
.docs-index {
	max-width: 760px;
	display: flex;
	flex-direction: column;
	gap: 16px;
}
.docs-index-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}
.docs-index-list a {
	color: var(--link);
	text-decoration: none;
	font-size: var(--fs-base);
}
.docs-index-list a:hover {
	text-decoration: underline;
}

/* -- Doc content (/docs/{slug}) -- типографика для отрендеренного markdown
   (goldmark + GFM, см. internal/docs). max-width держит строку читабельной,
   line-height ~1.6 — то же, что и остальной текстовый контент кабинета. */
.doc-content {
	max-width: 820px;
	font-size: 14px;
	line-height: 1.6;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	padding: 24px 32px;
}
.doc-content h1 {
	margin: 0 0 16px;
	font-size: 24px;
	font-weight: 700;
	letter-spacing: -.3px;
}
.doc-content h2 {
	margin: 28px 0 10px;
	font-size: 18px;
	font-weight: 650;
	border-bottom: 1px solid var(--border);
	padding-bottom: 6px;
}
.doc-content h3 {
	margin: 20px 0 8px;
	font-size: 15px;
	font-weight: 650;
}
.doc-content p {
	margin: 0 0 12px;
	line-height: 1.6;
}
.doc-content ul,
.doc-content ol {
	margin: 0 0 12px;
	padding-left: 22px;
	line-height: 1.6;
}
.doc-content li + li {
	margin-top: 2px;
}
.doc-content a {
	color: var(--accent);
}
.doc-content code {
	font-family: var(--font-mono);
	font-size: var(--fs-sm);
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: 4px;
	padding: 1px 5px;
}
.doc-content pre {
	margin: 0 0 14px;
	padding: 12px 14px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	overflow-x: auto;
}
.doc-content pre code {
	background: none;
	border: none;
	padding: 0;
	font-size: var(--fs-sm);
}
.doc-content table {
	width: 100%;
	margin: 0 0 14px;
	border-collapse: collapse;
	font-size: var(--fs-base);
}
.doc-content th {
	text-align: left;
	padding: 6px 8px;
	border-bottom: 1px solid var(--border);
	color: var(--text-dim);
	font-size: var(--fs-xs);
	font-weight: 600;
	text-transform: uppercase;
}
.doc-content td {
	padding: 6px 8px;
	border-bottom: 1px solid var(--border);
}
.doc-content blockquote {
	margin: 0 0 12px;
	padding: 6px 12px;
	border-left: 3px solid var(--border);
	color: var(--text-dim);
}
.doc-content hr {
	margin: 20px 0;
	border: none;
	border-top: 1px solid var(--border);
}

/* ===== Многоцветные графики: цвет из токенов (под-проект ④) =====
   Одноцветные графики наследуют currentColor от своего класса, но там, где
   в одном SVG нужно несколько цветов (полоска доступности, waterfall,
   перцентили, стек задержек), цвет назначается здесь по классу элемента.
   Раньше эти значения были впечатаны в SVG hex-литералами из тёмной палитры
   и не менялись в светлой теме. */
.availability-bars .bar-up    { fill: var(--good); }
.availability-bars .bar-down  { fill: var(--danger); }
.availability-bars .bar-empty { fill: var(--border); }

.waterfall .wf-ok  { fill: var(--accent); }
.waterfall .wf-err { fill: var(--danger); }

.latency-chart .series-p50 { stroke: var(--accent); }
.latency-chart .series-p95 { stroke: var(--warn); }

.latency-chart .seg-dns     { fill: var(--accent); }
.latency-chart .seg-connect { fill: var(--accent); opacity: .65; }
.latency-chart .seg-tls     { fill: var(--warn); }
.latency-chart .seg-ttfb    { fill: var(--good); }

/* ===== Performance / Trace / Profiles: секционные классы (под-проект ④) =====
   Эти классы стояли в разметке без определений, из-за чего блоки на страницах
   endpoint detail, perf issue detail, trace и profiles рендерились без
   отступов и без прокрутки широких SVG.

   Классы вида *-form (alert-rules-form, member-remove-form, key-create-form
   и т.д.) сюда сознательно НЕ добавлены: это семантические маркеры форм для
   чтения разметки, а не стилевые хуки, и пустые правила под них были бы
   мусором. */

/* Ширину не ограничиваем — см. комментарий у .issue-detail: потолок задаёт
   контентная колонка. */
.endpoint-detail,
.trace-detail {
	display: grid;
	gap: 12px;
	min-width: 0;
}

/* Обёртки широких SVG: график шире узкого экрана, и обрезать его нельзя.
   Все, кроме .trace-flame, стоят в паре с .card — фон, рамка, радиус и
   внутренний отступ приходят оттуда, поэтому здесь только прокрутка. */
.endpoint-chart,
.metric-chart-wrap,
.flamegraph-wrap,
.trace-waterfall,
.trace-flame {
	overflow-x: auto;
}
/* .trace-flame — единственная из них без .card: отступ задаём сами. */
.trace-flame {
	padding: 12px;
}

/* .web-vitals-panel — это <table class="data-table web-vitals-panel">, а не
   блок-панель. Здесь был display:grid, из-за чего thead и tbody становились
   ячейками сетки и таблицу «рвало»: шапка уезжала влево, тело вправо.
   Раскладку задаёт .data-table, здесь только отступ. */
.web-vitals-panel {
	margin-bottom: 12px;
}

.trace-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
}

.perf-evidence {
	display: grid;
	gap: 8px;
	margin-bottom: 12px;
}
/* .perf-evidence-list — это <dl> с парами dt/dd, а не маркированный список:
   без сетки браузер отбивает <dd> отступом и пары уезжают лесенкой. */
.perf-evidence-list {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 4px 16px;
	margin: 0;
	align-items: baseline;
}
.perf-evidence-list dt {
	color: var(--text-dim);
}
.perf-evidence-list dd {
	margin: 0;
	font-variant-numeric: tabular-nums;
}
/* URL — машинная строка: моноширинная и переносится по любому символу, иначе
   длинный путь распирает карточку по горизонтали. */
.perf-urls {
	font-family: var(--font-mono);
	font-size: var(--fs-sm);
	overflow-wrap: anywhere;
}
/* .perf-sample-trace — абзац-обёртка вокруг кнопки «пример трейса». Моно
   здесь ставить нельзя: шрифт наследовала бы сама кнопка (и наследовала —
   правка после визуального обхода). */
.perf-sample-trace {
	margin: 12px 0 0;
}

/* Публичная status-страница: фон задаётся на <body>, потому что у неё свой
   layout без app-shell. */
.status-body {
	padding: 24px 16px;
}
.status-incidents,
.status-maintenance {
	margin-bottom: 16px;
}

.inline {
	display: inline;
}

/* .visually-hidden — текст только для скринридера. Нужен там, где состояние
   несёт иконка: @icon печатает aria-hidden, и без дублирующего текста
   «сделано»/«не сделано» пункты чек-листа звучат одинаково. */
.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Disclosure «Что это за раздел?»: стрелка — иконка спрайта (раньше здесь
   стоял текстовый глиф ▸/▾ через ::before, он был другой толщины и не
   следовал иконографике). Поворот на раскрытии — чистый CSS, без JS. */
.help-panel summary .ic {
	color: var(--text-dim);
	transition: transform 120ms ease;
}
.help-panel[open] summary .ic {
	transform: rotate(90deg);
}

/* Кнопка «+ …»: иконка и подпись на одной линии. */
.create-trigger {
	gap: 6px;
}

/* Поля под небольшие числа (throttle, порог, окно) не растягиваем на всю
   карточку: поле шириной 500px под двузначное число выглядит как ошибка
   вёрстки и сбивает ожидание от вводимого значения. */
.input[type="number"] {
	max-width: 160px;
}

/* Таблицы, живущие внутри карточки во всю ширину, тянем на всю её ширину:
   иначе получается широкая карточка с узкой таблицей у левого края и
   большим пустым полем справа. */
.card .data-table,
.panel .data-table,
.scroll-list .data-table,
.issue-events {
	width: 100%;
}
/* Ширину таблицы тегов задаёт модификатор .data-table--auto в разметке
   (см. issuedetail.templ): она вне карточки, поэтому селектор с .card её не
   доставал, а общее умолчание width:100% растягивало список ключ/значение
   через всю страницу. */

/* ===== Правки после визуального обхода 2026-07-20 ===== */

/* min-width:0 нужен, чтобы карточка-грид-элемент могла быть уже своего
   содержимого; без него длинные машинные строки распирают колонку сетки. */
.card,
.panel {
	min-width: 0;
}

/* Машинные строки внутри карточки переносятся, а не уезжают за край. Раньше
   DSN обрывался на полуслове, а кнопка «Отозвать» в таблице ключей была
   срезана правой границей. Горизонтальная прокрутка тут не годится: она
   прячет содержимое ровно так же, просто с полосой. */
.card pre,
.panel pre {
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}
.card .data-table td,
.panel .data-table td {
	overflow-wrap: anywhere;
}
/* Числовые колонки не переносим: разрыв числа посреди разряда нечитаем. */
.card .data-table td.num,
.panel .data-table td.num {
	overflow-wrap: normal;
	white-space: nowrap;
}
/* Подписи кнопок и бейджей тоже не рвём: «Отозвать» переносилось как
   «Отозва/ть». Перенос по любому символу нужен только машинным строкам
   (ключам, DSN, URL), а не элементам управления. */
.card .data-table td .btn,
.card .data-table td .badge,
.panel .data-table td .btn,
.panel .data-table td .badge {
	overflow-wrap: normal;
	white-space: nowrap;
}

/* Соседние чекбоксы не слипаются: у .checkbox-inline свой внутренний gap, но
   между двумя такими блоками зазора не было — получалось «eu-west☑local». */
.checkbox-inline {
	margin: 2px 14px 2px 0;
}

/* Сортируемые заголовки таблиц: ссылка в <th> наследует цвет заголовка, а не
   акцент. Синие заголовки колонок спорили с данными и читались как обычные
   ссылки. */
.data-table th a {
	color: inherit;
	text-decoration: none;
}
.data-table th a:hover {
	color: var(--text);
	text-decoration: underline;
}

/* Широкие графики внутри карточки занимают её целиком (стек задержек на
   детали монитора упирался в собственную max-width и оставлял полкарточки
   пустой). */
.card > .latency-chart,
.card > .availability-bars {
	width: 100%;
	max-width: none;
}

/* Бейдж внутри таблицы чуть у́же по горизонтали, чтобы три бейджа в строке
   (web-vitals) не превращали её в гирлянду. Кегль общий со всеми бейджами —
   отдельно ужимать его больше не нужно. */
.data-table .badge {
	padding: 2px 6px;
}

/* Стат-плитка с текстовым значением (например «39 дн. до истечения»): крупный
   кегль числа для фразы не годится — рядом с «100.00%» она выглядела
   инородно. */
.stat-tile--text .stat-value {
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
}

/* Fieldset формы монитора выглядит как карточка дизайн-системы: собственная
   рамка с «вырезом» под legend — единственное место в продукте, где группа
   полей оформлена иначе, чем везде. Семантику fieldset/legend сохраняем: она
   нужна скринридеру для группировки полей. */
.monitor-form fieldset {
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background: var(--surface);
	padding: 14px 16px;
	margin: 0 0 16px;
	min-width: 0;
}
.monitor-form legend {
	padding: 0 6px;
	color: var(--text-dim);
	font-size: var(--fs-xs);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .4px;
}
/* Группы чекбоксов (регионы, каналы) — сетка, а не строка вплотную. */
.monitor-form fieldset > .checkbox-inline {
	margin-right: 18px;
}

/* Пояснение к Apdex над таблицей — служебная сноска, а не заголовок: без
   стиля она читалась как отладочная строка. */
.apdex-note,
.perf-cap-note {
	margin: 0 0 8px;
	color: var(--text-dim);
	font-size: var(--fs-sm);
}

/* Формы порогов (регрессии, производительность) раскладываются в несколько
   колонок: десять полей в один столбец растягивали карточку на всю высоту
   экрана, оставляя соседние колонки сетки пустыми. Кнопка и чекбокс
   «Включено» занимают всю ширину последней строкой. */
.project-regression-form,
.project-perf-form {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 8px 12px;
	align-items: end;
}
.project-regression-form > .checkbox-inline,
.project-regression-form > button,
.project-perf-form > button {
	grid-column: 1 / -1;
	justify-self: start;
}

/* Подсветка столбика графика частоты при наведении: нативная подсказка
   <title> всплывает с задержкой, и без визуального отклика непонятно, на
   каком именно столбике стоит курсор. Оформленной подсказки нет сознательно —
   она потребовала бы JS, а график должен работать и без него. */
.chart-freq rect {
	transition: opacity 100ms ease;
}
.chart-freq:hover rect {
	opacity: .45;
}
.chart-freq rect:hover {
	opacity: 1;
}

/* ===== Человек в интерфейсе: цветной аватар + чип ===== */

/* Цвет аватара выводится из хеша адреса (см. avatarColorClass в
   userchip.templ) и задаётся классом, а не inline-style: CSP запрещает
   style="". Хранится только тон, светлота подбирается под тему. */
.avatar--c0 { --avatar-h: 210; }
.avatar--c1 { --avatar-h: 265; }
.avatar--c2 { --avatar-h: 330; }
.avatar--c3 { --avatar-h: 10; }
.avatar--c4 { --avatar-h: 35; }
.avatar--c5 { --avatar-h: 145; }
.avatar--c6 { --avatar-h: 175; }
.avatar--c7 { --avatar-h: 80; }

.avatar[class*="avatar--c"] {
	background: hsl(var(--avatar-h) 45% 24%);
	color: hsl(var(--avatar-h) 75% 78%);
}
:root[data-theme="light"] .avatar[class*="avatar--c"] {
	background: hsl(var(--avatar-h) 72% 90%);
	color: hsl(var(--avatar-h) 55% 30%);
}
@media (prefers-color-scheme: light) {
	:root:not([data-theme="dark"]) .avatar[class*="avatar--c"] {
		background: hsl(var(--avatar-h) 72% 90%);
		color: hsl(var(--avatar-h) 55% 30%);
	}
}

/* Размер для таблиц и шапки: базовый .avatar рассчитан на рейл. */
.avatar--sm {
	width: 22px;
	height: 22px;
	font-size: var(--fs-label);
	margin-top: 0;
	flex: none;
}

.user-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-width: 0;
	vertical-align: middle;
}
.user-chip-name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
/* «не назначено» — приглушённо: это отсутствие состояния, а не значение. */
.user-chip--empty {
	color: var(--text-mute);
	font-style: italic;
}

/* Смена ответственного свёрнута: в шапке показан факт назначения, здесь —
   только действие. */
.assign-control > summary {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	list-style: none;
	cursor: pointer;
	padding: 6px 10px;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	color: var(--text-dim);
	font-weight: 500;
}
.assign-control > summary::-webkit-details-marker {
	display: none;
}
.assign-control > summary:hover {
	color: var(--text);
	border-color: var(--text-dim);
}
.assign-control[open] > summary {
	color: var(--text);
}
.assign-control .assign-form {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 8px;
}
.assign-control .assign-form .select {
	width: auto;
	min-width: 200px;
}

/* Ответственный — отдельной строкой под бейджами уровня и статуса: в одной
   строке с ними он читался как ещё один бейдж, а это другого рода факт. */
.issue-assignee {
	margin: 8px 0 0;
}

/* ===== Оси, легенда и подсказки графиков (доработка 2026-07-20) ===== */

/* Графики на детали эндпойнта занимают карточку целиком — как график частоты
   на детали issue. Собственный max-width у .chart/.chart-freq рассчитан на
   узкую врезку в списке. */
.endpoint-chart .chart,
.endpoint-chart .chart-freq,
.endpoint-chart .latency-chart {
	max-width: none;
	width: 100%;
	height: auto;
}

/* Полоса наведения над интервалом линейного графика: прозрачная, потому что
   наводиться на саму линию нечем — она в полтора пикселя. При наведении
   подсвечивается, чтобы было видно, к какому интервалу относится подсказка. */
.hover-band {
	fill: transparent;
}
.hover-band:hover {
	fill: var(--accent-soft);
}

/* Подпись под заголовком графика: что измеряется и с каким шагом агрегации. */
.chart-caption {
	margin: -4px 0 6px;
	color: var(--text-dim);
	font-size: var(--fs-sm);
}

/* Легенда перцентилей: цвет линии сам по себе ничего не сообщает — две линии
   разного цвета без подписи неразличимы по смыслу. */
.chart-legend {
	display: flex;
	gap: 16px;
	margin: 0 0 8px;
	font-size: var(--fs-sm);
	color: var(--text-dim);
}
.legend-item {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}
.legend-item::before {
	content: "";
	width: 14px;
	height: 2px;
	border-radius: 1px;
	background: currentColor;
}
.legend-p50::before { background: var(--accent); }
.legend-p95::before { background: var(--warn); }

/* ===== Форма окна обслуживания ===== */

/* Тип окна взаимоисключающий, поэтому в форме виден только выбранный блок.
   Скрытие — чистый CSS через :has() по radio, без JS: галка «Разовое»
   прячет еженедельный блок и наоборот. Скрытые поля всё равно уходят в
   POST, но хендлер читает только выбранную ветку, так что это безопасно. */
.maintenance-form:has(input[name="kind"][value="oneoff"]:checked) .mw-weekly,
.maintenance-form:has(input[name="kind"][value="weekly"]:checked) .mw-oneoff {
	display: none;
}

/* Поле «Свой IANA часовой пояс» видно только при выборе «Другой» (пустая
   option в select). Пока выбран любой готовый пояс, поле не нужно и только
   загромождает форму. :has по выбранной option, без JS. */
.maintenance-form:not(:has(select[name="timezone"] option[value=""]:checked)) .mw-custom-tz {
	display: none;
}

/* Сегмент-контрол «Разовое / Еженедельное» — две склеенные кнопки, как у
   переключателя языка/темы: сразу читается как выбор одного из двух, а не
   как флажок-опция. Радио скрыты, подсвечивается активная подпись. */
.segmented {
	display: inline-flex;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
	width: fit-content;
}
.segmented label {
	display: inline-flex;
	align-items: center;
	padding: 6px 14px;
	cursor: pointer;
	color: var(--text-dim);
	font-size: var(--fs-sm);
	border-left: 1px solid var(--border);
}
.segmented label:first-child {
	border-left: none;
}
.segmented input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}
.segmented label:has(input:checked) {
	background: var(--accent-soft);
	color: var(--accent);
}
.segmented label:has(input:focus-visible) {
	outline: 2px solid var(--accent);
	outline-offset: -2px;
}
/* Подпись сегмента набирается как обычная подпись поля. */
.field > .field-label {
	display: block;
	margin-bottom: 4px;
	color: var(--text-dim);
	font-size: var(--fs-sm);
}

/* Нижний ряд (часовой пояс + свой IANA): подписи разной длины, поэтому
   прижимаем контролы к низу ячейки — иначе поле с однострочной подписью
   стоит выше поля с двухстрочной. */
.maintenance-form .form-grid .field label {
	height: 100%;
}
.maintenance-form .form-grid .field .input,
.maintenance-form .form-grid .field .select {
	margin-top: auto;
}

/* Списки участников и проектов в карточке команды — фиксированной высоты со
   внутренним скроллом, чтобы соседние карточки не отличались по высоте из-за
   разного числа строк. Высота ~ три строки плюс заголовок столбца. */
.team-scroll {
	height: 240px;
	overflow-y: auto;
	margin-bottom: 4px;
}
/* Заголовок столбца остаётся на месте при прокрутке. */
.team-scroll .data-table thead th {
	position: sticky;
	top: 0;
	background: var(--surface);
	z-index: 1;
}
