/* Каркас админки immohunter. Палитра взята из static/css/style.css (тема Saasytech) — */
/* чтобы лендинг и админка визуально совпадали. TODO: заменить блоки на готовые из шаблона, выбранного утром. */

:root {
	--dh-accent: #D4F772;
	--dh-accent-2: #00DEE1;
	--dh-dark: #13140E;
	--dh-bg: #F4F4F4;
	--dh-muted: #616161;
	--dh-border: #E7E7E7;
	--dh-warn: #FF9F31;
}

.admin-body {
	background: var(--dh-bg);
	color: var(--dh-dark);
	font-family: "Inter", Arial, sans-serif;
	margin: 0;
}

.admin-topbar {
	height: 64px;
	background: var(--dh-dark);
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0 24px;
	position: sticky;
	top: 0;
	z-index: 10;
}

.admin-topbar .admin-logo {
	display: inline-flex;
	align-items: center;
	text-decoration: none;
}

/* Was bare text "IMMOHUNTER" (no icon) - inconsistent with the icon+wordmark logo used
   everywhere else on the site (marketing header, auth pages). admin.css doesn't load
   style.css (separate stylesheet), so .site-logo's height:40px rule doesn't reach here -
   duplicated the same constraint locally. 2026-08-25. */
.admin-topbar .admin-logo img {
	display: block;
	height: 32px;
	width: auto;
}

.admin-topbar .admin-search input {
	border: none;
	border-radius: 8px;
	padding: 8px 14px;
	width: 320px;
	height: 40px;
	box-sizing: border-box;
}

.admin-topbar .admin-user {
	display: flex;
	align-items: center;
	gap: 12px;
}

.admin-lang-switcher {
	position: relative;
	display: inline-flex;
}

.admin-lang-switcher__trigger {
	appearance: none;
	border: none;
	border-radius: 8px;
	width: 56px;
	height: 40px;
	box-sizing: border-box;
	padding: 8px 22px 8px 12px;
	text-align: center;
	font-size: 0.85rem;
	font-weight: 600;
	background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23616161'/%3E%3C/svg%3E") no-repeat right 8px center;
	color: var(--dh-dark);
	cursor: pointer;
}

.admin-lang-switcher__list {
	position: absolute;
	top: calc(100% + 6px);
	left: 0;
	z-index: 50;
	display: flex;
	flex-direction: column;
	min-width: 56px;
	margin: 0;
	padding: 4px;
	background: #fff;
	border: 1px solid var(--dh-border);
	border-radius: 8px;
	box-shadow: 0 12px 28px rgba(0, 0, 0, .15);
}

.admin-lang-switcher__list [role="option"] {
	padding: 8px 10px;
	border-radius: 6px;
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--dh-dark);
	text-align: center;
	cursor: pointer;
}

.admin-lang-switcher__list [role="option"]:hover {
	background: var(--dh-bg);
}

.admin-lang-switcher__list [aria-selected="true"] {
	background: var(--dh-accent);
}

.admin-orig-lang-badge {
	display: inline-block;
	font-size: 0.7rem;
	font-weight: 600;
	color: var(--dh-muted);
	border: 1px solid var(--dh-border);
	border-radius: 6px;
	padding: 1px 6px;
	margin-left: 4px;
	white-space: nowrap;
	flex-shrink: 0;
}

.admin-avatar-identicon {
	display: inline-flex;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	overflow: hidden;
	flex-shrink: 0;
}

.admin-avatar-identicon svg {
	width: 100%;
	height: 100%;
}

.admin-avatar-menu {
	position: relative;
}

/* .admin-avatar-identicon is now a <summary> (inside <details>) - drop the native
   disclosure triangle, it should look exactly like the plain avatar it replaced. */
.admin-avatar-identicon {
	cursor: pointer;
	list-style: none;
}

.admin-avatar-identicon::-webkit-details-marker {
	display: none;
}

.admin-avatar-dropdown {
	position: absolute;
	top: calc(100% + 8px);
	right: 0;
	background: #fff;
	border: 1px solid var(--dh-border);
	border-radius: 10px;
	box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
	min-width: 140px;
	overflow: hidden;
	z-index: 20;
}

.admin-avatar-dropdown a,
.admin-avatar-dropdown button {
	display: block;
	width: 100%;
	padding: 10px 16px;
	color: var(--dh-dark);
	font-size: 14px;
	text-decoration: none;
	background: none;
	border: none;
	text-align: left;
	cursor: pointer;
	font-family: inherit;
}

.admin-avatar-dropdown a:hover,
.admin-avatar-dropdown button:hover {
	background: var(--dh-bg);
}

.admin-layout {
	display: flex;
	align-items: flex-start;
	min-height: calc(100vh - 64px);
}

/* Dashboard оборачивает левый сайдбар в <form id="filters-form"> (фильтры сабмитятся вместе
 с навигацией) - без этого правила форма сама становится flex-элементом ВМЕСТО aside, её
 короткая высота (по размеру контента) обрезает диапазон, в котором может "прилипать" сайдбар
 внутри неё. display:contents убирает бокс самой формы из раскладки - aside становится
 фактически прямым потомком .admin-layout, как и правый сайдбар. */
.admin-layout > form {
	display: contents;
}

/* Оба сайдбара статичны ("приклеены") при скролле центральной колонки - top совпадает
 с высотой топбара (64px, .admin-topbar), свой overflow-y на случай длинного меню/фильтров. */
.admin-sidebar,
.admin-side-right {
	position: sticky;
	top: 64px;
	max-height: calc(100vh - 64px);
	overflow-y: auto;
}

.admin-sidebar {
	width: 260px;
	background: #fff;
	border-right: 1px solid var(--dh-border);
	padding: 24px 16px;
	flex-shrink: 0;
}

.admin-nav {
	list-style: none;
	padding: 0;
	margin: 0 0 28px 0;
}

.admin-nav li a {
	display: block;
	padding: 10px 12px;
	border-radius: 8px;
	color: var(--dh-dark);
	text-decoration: none;
	font-weight: 500;
	margin-bottom: 4px;
}

.admin-nav li a.active {
	background: var(--dh-accent);
	color: var(--dh-dark);
}

.admin-nav li a:hover {
	background: var(--dh-bg);
}

/* Тумблер "Filters" и обёртка вокруг фильтров - на десктопе (>992px) невидим/неактивен,
 фильтры всегда развёрнуты как раньше; реальное сворачивание включается только внутри
 @media (max-width: 992px) ниже. 2026-08-23, по прямому запросу - десктоп не трогать. */
.admin-filter-toggle {
	display: none;
}

.admin-filter-body[hidden] {
	display: block;
}

.admin-filter-group {
	margin-bottom: 20px;
}

.admin-filter-group h6 {
	font-size: 12px;
	text-transform: uppercase;
	color: var(--dh-muted);
	letter-spacing: 0.04em;
	margin-bottom: 10px;
}

.admin-filter-cat-toggle {
	display: flex;
	align-items: center;
	gap: 4px;
}

.admin-filter-expand {
	border: none;
	background: none;
	color: var(--dh-muted);
	padding: 0 4px;
	margin-left: auto;
}

.admin-filter-sub {
	margin-left: 22px;
	margin-bottom: 6px;
}

.admin-request-chip {
	display: block;
	text-align: center;
	border: 1px dashed var(--dh-border);
	border-radius: 8px;
	padding: 6px;
	font-size: 13px;
	color: var(--dh-muted);
	margin-top: 8px;
	cursor: pointer;
}

.admin-request-chip:hover {
	border-color: var(--dh-dark);
	color: var(--dh-dark);
}

.admin-filter-group .form-check {
	margin-bottom: 6px;
}

.admin-content {
	flex: 1;
	padding: 24px 32px;
}

.admin-content h1 {
	font-size: 24px;
	margin-bottom: 20px;
}

.admin-tabs {
	display: flex;
	gap: 8px;
	margin-bottom: 12px;
}

.admin-tab {
	border: 1px solid var(--dh-border);
	background: #fff;
	color: var(--dh-muted);
	border-radius: 20px;
	padding: 6px 18px;
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
}

.admin-tab.active {
	background: var(--dh-accent);
	border-color: var(--dh-accent);
	color: var(--dh-dark);
}

.admin-locked {
	padding: 32px;
	text-align: center;
	color: var(--dh-muted);
}

/* Same visual treatment as the .analytics-locked/.alerts-limit-banner "Choose a plan"
   buttons (admin-analytics.css/admin-alerts.css) - .admin-btn itself carries no base style,
   every locked-banner variant scopes it to its own parent class, this is dashboard.html's. */
.admin-locked .admin-btn {
	display: inline-block;
	margin-top: 16px;
	background: var(--dh-accent);
	color: var(--dh-dark);
	font-weight: 700;
	padding: 12px 24px;
	border-radius: 999px;
	text-decoration: none;
}

/* Третья колонка + лента лидов — структура подсмотрена в референсе (3 колонки, табы, скролл-лист), */
/* контент свой: лиды вместо твитов, заявки на ресурсы вместо профиля в соцсети. */

.admin-side-right {
	width: 300px;
	border-left: 1px solid var(--dh-border);
	padding: 24px 16px;
	flex-shrink: 0;
	background: #fff;
}

.admin-stats-card {
	background: var(--dh-dark);
	border-radius: 12px;
	padding: 18px;
	margin-bottom: 24px;
}

.admin-stats-row {
	display: flex;
	justify-content: space-between;
	text-align: center;
}

.admin-stats-value {
	font-size: 22px;
	font-weight: 700;
	color: var(--dh-accent);
	display: block;
}

.admin-stats-row .text-muted {
	color: #cfcfcf !important;
}

.admin-panel h6 {
	font-size: 12px;
	text-transform: uppercase;
	color: var(--dh-muted);
	letter-spacing: 0.04em;
	margin-bottom: 12px;
}

.admin-request-list {
	list-style: none;
	padding: 0;
	margin: 0;
}

.admin-request-list li {
	border: 1px solid var(--dh-border);
	border-radius: 10px;
	padding: 12px;
	margin-bottom: 10px;
}

.admin-request-actions {
	margin-top: 8px;
	display: flex;
	gap: 8px;
}

.btn-dh-accent {
	background: var(--dh-accent);
	border: none;
	color: var(--dh-dark);
	font-weight: 600;
}

.admin-feed-card {
	background: #fff;
	border: 1px solid var(--dh-border);
	border-radius: 12px;
}

.admin-feed {
	list-style: none;
	padding: 0;
	margin: 0;
}

.admin-feed-item {
	display: flex;
	align-items: flex-start;
	gap: 14px;
	padding: 14px 16px;
	border-bottom: 1px solid var(--dh-border);
}

.admin-feed-item:last-child {
	border-bottom: none;
}

/* Промо-баннер alert-подписок внутри ленты - см. .claude/reports/2026-07-25_alerts-banner-tz.html.
 Padding/gap/иконка - как у .admin-feed-item/.admin-avatar (14px 16px, 36px), чтобы не было
 лишнего "воздуха" вокруг текста. НО у баннера всего 1 строка текста, а у карточек лида часто
 3-4 строки (длинные посты) - при одинаковом padding баннер на однострочном тексте схлопывается
 заметно МЕНЬШЕ соседних карточек. min-height держит его вровень с типичной многострочной
 карточкой (замерено на реальной ленте - карточки с длинным текстом ~140px). */
.admin-feed-banner {
	align-items: center;
	gap: 14px;
	padding: 14px 16px;
	min-height: 140px;
	box-sizing: border-box;
	background: linear-gradient(90deg, rgba(212, 247, 114, 0.18), rgba(0, 222, 225, 0.12));
}

.admin-feed-banner-icon {
	flex-shrink: 0;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--dh-dark, #13140E);
	color: var(--dh-accent, #D4F772);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 16px;
}

.admin-feed-banner-body {
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	gap: 16px;
	min-width: 0;
}

.admin-feed-banner-text {
	margin: 0;
	font-weight: 600;
	color: var(--dh-dark, #13140E);
	min-width: 0;
}

.admin-feed-banner-cta {
	/* margin-left:auto прижимает кнопку к правому краю независимо от длины текста слева -
	 раньше держалось на justify-content:space-between, которое ломалось при переносе строк
	 (кнопка падала на вторую строку и прилипала к левому краю вместо правого). */
	flex-shrink: 0;
	margin-left: auto;
	background: var(--dh-dark, #13140E);
	color: var(--dh-accent, #D4F772);
	padding: 8px 18px;
	border-radius: 30px;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}

.admin-feed-banner-cta:hover {
	opacity: 0.85;
}

@media (max-width: 576px) {
	.admin-feed-banner-body {
		flex-direction: column;
		align-items: center;
		text-align: center;
	}

	.admin-feed-banner-cta {
		margin-left: 0;
	}
}

/* Аватар — инициалы по умолчанию; img.admin-avatar — реальное фото автора (author_photo_url), когда есть */
.admin-avatar {
	width: 36px;
	height: 36px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	color: #fff;
	font-weight: 700;
	font-size: 13px;
}

img.admin-avatar {
	object-fit: cover;
}

.admin-feed-name-link,
.admin-feed-title-link {
	color: inherit;
	text-decoration: none;
}

.admin-feed-title-link:hover .admin-feed-title {
	text-decoration: underline;
}

.admin-feed-body {
	flex: 1;
	min-width: 0;
}

.admin-feed-name-row {
	display: flex;
	align-items: center;
	gap: 6px;
}

/* A long author name (nothing stops Facebook/Telegram from handing us one) used to eat all
   the row's width, forcing the category badge to wrap onto its own second line instead -
   inconsistent card height depending on name length (see screenshot QA, 2026-08-29). Name
   now truncates with an ellipsis at one line; badges get flex-shrink:0 so they're never the
   ones sacrificed for space. min-width:0 is required on a flex child for text-overflow to
   actually take effect - without it a flex item won't shrink below its content's natural
   width no matter what overflow/text-overflow say. */
.admin-feed-name-row strong {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	min-width: 0;
}

.admin-feed-title {
	font-size: 14px;
	color: var(--dh-dark);
	margin-top: 2px;
}

.admin-feed-location {
	font-size: 13px;
	font-weight: 700;
	color: var(--dh-dark);
	margin-top: 4px;
}

/* Бейдж "город не указан" — лид без города, показывается под любым городом страны (2026-07-09) */
.admin-city-unknown {
	display: inline-block;
	font-size: 11px;
	font-weight: 600;
	color: #8a8f98;
	background: #f0f1f3;
	border: 1px dashed #c9ccd2;
	border-radius: 6px;
	padding: 0 6px;
}

/* Усечение текста поста — TODO: обсудить финальный механизм (клэмп vs "показать полностью") */
.admin-feed-text-clamp {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.admin-pagination-wrap {
	display: flex;
	justify-content: center;
	margin-top: 20px;
}

.admin-pagination-wrap .page-link {
	color: var(--dh-dark);
	border-color: var(--dh-border);
}

.admin-pagination-wrap .page-item.active .page-link {
	background: var(--dh-accent);
	border-color: var(--dh-accent);
	color: var(--dh-dark);
}

.admin-pagination-wrap .page-item.disabled .page-link {
	color: var(--dh-muted);
	background: transparent;
	border-color: var(--dh-border);
}

.admin-source-icon {
	font-size: 12px;
	flex-shrink: 0;
}

.admin-source-icon.fb {
	color: #1877F2;
}

.admin-source-icon.tg {
	color: #26A5E4;
}

/* Third source "Forum" (Expat.com/kleinanzeigen.de etc., grouped under one generic
   icon) - backend/docs/FORUM_SOURCE_ICON_TOR.md. Purple - doesn't clash with the colors
   already in use (category lime #D4F772, cyan #00DEE1, orange #FF9F31, fb-blue,
   tg-cyan above). */
.admin-source-icon.forum {
	color: #8B5CF6;
}

/* Категория подкрашена цветом — недвижимость лайм, транспорт циан, авто оранж */
.admin-cat-badge {
	display: inline-block;
	padding: 2px 9px;
	border-radius: 999px;
	font-size: 11px;
	font-weight: 600;
	color: var(--dh-dark);
	white-space: nowrap;
	flex-shrink: 0;
}

.admin-cat-badge.re {
	background: var(--dh-accent);
}

.admin-cat-badge.transport {
	background: var(--dh-accent-2);
}

.admin-cat-badge.car {
	background: var(--dh-warn);
}

.admin-feed-time {
	color: var(--dh-muted);
	font-size: 12px;
	flex-shrink: 0;
	white-space: nowrap;
}

/* Адаптив: ниже планшетной ширины колонки складываются друг под друга. Порядок (2026-08-23,
 переработано по прямому запросу - десктоп(>992px) этот блок не видит вообще, там всё как
 было): статы (только счётчики Leads/Countries/Categories) сверху -> сворачиваемые фильтры ->
 лента лидов внизу. Раньше фильтры были ПОСЛЕДНИМИ (order:3, ниже всей ленты) - реальная
 причина жалобы "фильтры не работают/не видны на мобильном". */
@media (max-width: 992px) {
	.admin-layout {
		flex-direction: column;
	}

	.admin-content {
		order: 3;
		padding: 20px;
	}

	/* На узкой ширине колонки складываются в одну - sticky здесь только мешал бы (обе колонки
	 всё равно скроллятся вместе с центральной), сбрасываем на обычное позиционирование. */
	.admin-sidebar,
	.admin-side-right {
		position: static;
		max-height: none;
		overflow-y: visible;
	}

	.admin-sidebar {
		order: 2;
		width: 100%;
		border-right: none;
		border-bottom: 1px solid var(--dh-border);
	}

	.admin-side-right {
		order: 1;
		width: 100%;
		border-left: none;
		border-top: none;
		border-bottom: 1px solid var(--dh-border);
	}

	/* "Ожидающие запросы на ресурсы" - хардкоженная демо-панель, никогда не была подключена
	 к бэкенду (Approve/Reject никуда не отправляют - проверено в коде). Прячем только на
	 мобильном/планшетном по прямому запросу, десктоп её по-прежнему показывает. */
	.admin-panel {
		display: none;
	}

	/* "Filters" toggle - visible only here, opens/collapses the whole filter block with one tap.
	 Small bounce on page load (2 times, not looping) - to make it visible that the button is
	 actually clickable, not just a static label. Delayed start so it doesn't blend into the
	 rest of the page still loading. 2026-08-25, direct request. */
	.admin-filter-toggle {
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		background: none;
		border: none;
		border-top: 1px solid var(--dh-border);
		border-bottom: 1px solid var(--dh-border);
		padding: 12px 4px;
		margin: 4px 0;
		font-weight: 600;
		font-size: 14px;
		color: var(--dh-dark);
		cursor: pointer;
		animation: admin-filter-bounce .5s ease-in-out .6s 2;
	}

	@keyframes admin-filter-bounce {
		0%, 100% { transform: translateY(0); }
		50% { transform: translateY(-6px); }
	}

	.admin-filter-toggle i {
		color: var(--dh-muted);
		transition: transform .15s ease;
	}

	.admin-filter-toggle[aria-expanded="true"] i {
		transform: rotate(180deg);
	}

	.admin-filter-body[hidden] {
		display: none;
	}
}

@media (max-width: 576px) {
	.admin-topbar {
		padding: 0 14px;
	}

	.admin-topbar .admin-search {
		display: none;
	}

	.admin-topbar .admin-user span {
		display: none;
	}

	.admin-content {
		padding: 16px;
	}

	.admin-content h1 {
		font-size: 20px;
	}

	.admin-feed-item {
		padding: 12px;
		gap: 10px;
	}

	.admin-pagination-wrap {
		flex-wrap: wrap;
	}
}

/* Show/hide password toggle - shared by login/register/settings/reset-password (2026-08-25).
   code-review: first version stretched the button top:0/bottom:0/right:0, flush against the
   input's edge - looked fine on a square-cornered Bootstrap input, but auth.css's own
   .form-control is 16px border-radius/48px min-height (see .auth-card .form-control) - a
   flush square button corner poked past that rounded corner, an actual visible defect, not
   nitpicking. Centered on the field's own height (top:50%/translateY) and inset a few px from
   the edge instead of touching it at all - correct regardless of the input's own radius/height,
   works the same on auth.css's pill-shaped fields and admin.css/Bootstrap's default ones. */
.password-field {
	position: relative;
}
.password-field input {
	padding-right: 42px;
}
.password-field__toggle {
	position: absolute;
	top: 50%;
	right: 6px;
	transform: translateY(-50%);
	width: 30px;
	height: 30px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: none;
	padding: 0;
	line-height: 1;
	color: var(--paragraph-color, #616161);
	cursor: pointer;
}
.password-field__toggle:hover,
.password-field__toggle:focus-visible {
	color: var(--primary-color, #D4F772);
}
