/* Эффекты интерфейса (Егор, 20.09.2026). Только transform и opacity,
   200–350 мс, всё гасится при «уменьшить движение». Классы здесь глобальные:
   стили компонентов собираются с хэшами, а эти правила должны доставать до
   разметки библиотек (bootstrap, react-dates, sonner). */

/* 6. Шапка сжимается при прокрутке: плавно, с тенью в сжатом виде */
.rentAllHeader {
	transition: min-height .3s ease, padding .3s ease, box-shadow .3s ease;
}
.rentAllHeader.headerCompact {
	box-shadow: 0 4px 14px rgba(0, 0, 0, .08);
}

/* 10. Подсветка диапазона дат: фон дня меняется плавно, а не рывком */
.CalendarDay {
	transition: background-color .15s ease, color .15s ease;
}

/* 11. Кнопка «утапливается» и волна от клика (сама волна — helpers/pressRipple) */
button.btn,
a.btn {
	position: relative;
	overflow: hidden;
	transition: transform .1s ease, background-color .15s ease, box-shadow .15s ease;
}
button.btn:active,
a.btn:active {
	transform: scale(.97);
}
.pressRipple {
	position: absolute;
	border-radius: 50%;
	background: rgba(255, 255, 255, .45);
	transform: scale(0);
	pointer-events: none;
	animation: pressRipple .6s ease-out forwards;
}
@keyframes pressRipple {
	to { transform: scale(4); opacity: 0; }
}

/* 9. Переход список → жильё: обложка «перелетает» на своё место */
::view-transition-old(root),
::view-transition-new(root) {
	animation-duration: .28s;
}
::view-transition-group(listing-cover) {
	animation-duration: .42s;
	animation-timing-function: cubic-bezier(.2, .8, .2, 1);
}

/* Переход между страницами (client.js): полоса загрузки сверху, пока
   роутер ходит за данными, и плавное проявление новой страницы */
html::before {
	content: '';
	position: fixed;
	top: 0;
	left: 0;
	height: 3px;
	width: 100%;
	background: #ff5a5f;
	transform: scaleX(0);
	transform-origin: left;
	opacity: 0;
	z-index: 100000;
	pointer-events: none;
}
html.routeLoading::before {
	opacity: 1;
	animation: routeLoading 1.6s cubic-bezier(.2, .8, .3, 1) forwards;
}
@keyframes routeLoading {
	0% { transform: scaleX(0); }
	60% { transform: scaleX(.7); }
	100% { transform: scaleX(.92); }
}
html.pageIn main,
html.pageIn > body > div:first-child > main {
	animation: pageIn .28s ease-out;
}
@keyframes pageIn {
	from { opacity: 0; transform: translateY(6px); }
	to { opacity: 1; transform: none; }
}

/* 1. Карточки всплывают при прокрутке — только там, где браузер умеет
   scroll-driven animations; остальные видят карточки сразу */
@supports (animation-timeline: view()) {
	.revealCard {
		animation: revealCard linear both;
		animation-timeline: view();
		animation-range: entry 0% entry 30%;
	}
}
@keyframes revealCard {
	from { opacity: 0; transform: translateY(22px); }
	to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: .001s !important;
		animation-iteration-count: 1 !important;
		transition-duration: .001s !important;
		scroll-behavior: auto !important;
	}
	.revealCard { animation: none; opacity: 1; transform: none; }
}


/* ===== Вторая партия эффектов (Егор, 20.09.2026) ===== */

/* A6, D10. Модалки появляются с лёгким увеличением; на телефоне — снизу */
.modal.fade .modal-dialog {
	transform: scale(.96);
	transition: transform .25s cubic-bezier(.2, .9, .3, 1.15), opacity .2s ease;
}
.modal.show .modal-dialog {
	transform: none;
}
@media (max-width: 767px) {
	.modal.fade .modal-dialog { transform: translateY(32px); }
	.modal.show .modal-dialog { transform: none; }
}

/* B1. Календарь раскрывается из поля, а не появляется рывком */
.DayPicker,
.DateRangePicker_picker,
.SingleDatePicker_picker {
	animation: dpIn .2s ease-out;
	transform-origin: top left;
}
@keyframes dpIn {
	from { opacity: 0; transform: translateY(-8px) scale(.98); }
}

/* B9. Занятые дни — штриховкой, без картинок */
.CalendarDay__blocked_calendar,
.CalendarDay__blocked_calendar:hover {
	background: repeating-linear-gradient(135deg, #f3f3f3 0 4px, #e3e3e3 4px 8px) !important;
	color: #a8a8a8 !important;
	text-decoration: line-through;
}

/* D1. Фото в лайтбоксе вырастает, а не появляется */
.yarl__slide_image {
	animation: lbIn .3s cubic-bezier(.2, .8, .2, 1);
}
@keyframes lbIn {
	from { opacity: 0; transform: scale(.92); }
}

/* D5. Звёзды рейтинга проявляются слева направо */
.dv-star-rating {
	display: inline-block;
	animation: starsIn .6s ease-out both;
	clip-path: inset(0 0 0 0);
}
@keyframes starsIn {
	from { clip-path: inset(0 100% 0 0); }
	to { clip-path: inset(0 0 0 0); }
}

/* E3. Кольца фокуса — только с клавиатуры */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid #ff5a5f;
	outline-offset: 2px;
}
a:focus:not(:focus-visible),
button:focus:not(:focus-visible) {
	outline: none;
}

/* E4. Якоря не прячутся под липкой шапкой */
[id] {
	scroll-margin-top: 90px;
}

/* E6. Подсказки всплывают, а не включаются */
[role="tooltip"] {
	transition: opacity .18s ease, transform .18s ease, visibility .18s;
}

/* E7. Выпадающие меню — с пружиной */
.dropdown-menu.show,
.userMenuSpring {
	animation: menuIn .2s cubic-bezier(.2, .9, .3, 1.2);
	transform-origin: top right;
}
@keyframes menuIn {
	from { opacity: 0; transform: scale(.95); }
}

/* A10. Автозаполнение без жёлтой заливки Chrome */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
	-webkit-box-shadow: 0 0 0 1000px #ffffff inset;
	-webkit-text-fill-color: #222222;
	transition: background-color 9999s ease-in-out 0s;
}

/* A3. Тряска формы при неверном пароле (LoginForm) */
.shakeOnce {
	animation: shakeOnce .4s ease;
}
@keyframes shakeOnce {
	20%, 60% { transform: translateX(-6px); }
	40%, 80% { transform: translateX(6px); }
}

/* C10. Конфетти при публикации (helpers/confetti) */
.confettiPiece {
	position: fixed;
	top: -14px;
	width: 8px;
	height: 12px;
	z-index: 100001;
	pointer-events: none;
	animation: confettiFall 1.9s ease-in forwards;
}
@keyframes confettiFall {
	to { transform: translateY(105vh) rotate(540deg); opacity: 0; }
}

/* D9. Кнопка «Наверх» (components/BackToTop) */
.backToTop {
	position: fixed;
	right: 20px;
	bottom: 88px;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: 0;
	background: #222222;
	color: #ffffff;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	z-index: 900;
	opacity: 0;
	transform: scale(.6);
	pointer-events: none;
	transition: opacity .25s ease, transform .25s ease;
	box-shadow: 0 6px 18px rgba(0, 0, 0, .25);
}
.backToTop.on {
	opacity: 1;
	transform: none;
	pointer-events: auto;
}
@media (max-width: 767px) {
	.backToTop { right: 14px; bottom: 96px; width: 40px; height: 40px; }
}

@media (prefers-reduced-motion: reduce) {
	.confettiPiece { display: none; }
}
