/* Rentoplan UI — components. Все интерактивные элементы — пилюли; одна primary-кнопка на экран. */

/* ---------- Icons ---------- */
.rp-i { width: 20px; height: 20px; flex: none; fill: currentColor; }
.rp-i-16 { width: 16px; height: 16px; }
.rp-i-24 { width: 24px; height: 24px; }

/* ---------- Buttons ---------- */
.rp-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--rp-s2);
  height: var(--rp-h-md); padding: 0 var(--rp-s5); border-radius: var(--rp-r-pill);
  font-size: var(--rp-fs-14); font-weight: 700; white-space: nowrap; line-height: 1;
  border: 1px solid transparent; transition: background var(--rp-t-fast) var(--rp-ease), border-color var(--rp-t-fast), color var(--rp-t-fast), transform var(--rp-t-fast);
  user-select: none;
}
.rp-btn:active { transform: scale(.98); }
.rp-btn-primary { background: var(--rp-accent); color: #fff; }
.rp-btn-primary:hover { background: var(--rp-accent-hover); color: #fff; }
.rp-btn-ink { background: var(--rp-ink); color: var(--rp-on-ink); }
.rp-btn-ink:hover { background: var(--rp-n700); color: #fff; }
.rp-btn-secondary { background: var(--rp-bg); color: var(--rp-text); border-color: var(--rp-border); }
.rp-btn-secondary:hover { background: var(--rp-surface); color: var(--rp-text); }
.rp-btn-tonal { background: var(--rp-surface); color: var(--rp-text); }
.rp-btn-tonal:hover { background: var(--rp-border); color: var(--rp-text); }
.rp-btn-ghost { background: transparent; color: var(--rp-text); }
.rp-btn-ghost:hover { background: var(--rp-surface); color: var(--rp-text); }
.rp-btn-sm { height: var(--rp-h-sm); padding: 0 var(--rp-s4); font-size: var(--rp-fs-13); }
.rp-btn-lg { height: var(--rp-h-lg); padding: 0 var(--rp-s6); font-size: var(--rp-fs-15); }
.rp-btn-block { width: 100%; }
.rp-btn-icon { width: var(--rp-h-md); padding: 0; border-radius: 50%; }
.rp-btn-icon.rp-btn-sm { width: var(--rp-h-sm); }
.rp-btn-white { background: var(--rp-bg); color: var(--rp-text); box-shadow: var(--rp-sh-pin); }
.rp-btn-white:hover { background: var(--rp-surface); color: var(--rp-text); }

/* ---------- Chips / tags ---------- */
.rp-chip {
  display: inline-flex; align-items: center; gap: var(--rp-s2); height: 40px; padding: 0 var(--rp-s4);
  border-radius: var(--rp-r-pill); border: 1px solid var(--rp-border); background: var(--rp-bg);
  font-size: var(--rp-fs-14); font-weight: 600; white-space: nowrap; color: var(--rp-text);
  transition: border-color var(--rp-t-fast), background var(--rp-t-fast);
}
.rp-chip:hover { border-color: var(--rp-ink); color: var(--rp-text); }
.rp-chip.is-active, .rp-chip[aria-pressed="true"] { background: var(--rp-ink); border-color: var(--rp-ink); color: var(--rp-on-ink); }
/* [2026-09-09] «Filters» when filters are actually on. Not the ink fill above — that one means «this
   is the chosen tab», and a filter chip is not a tab. The accent outline says «something is
   narrowing this list» and the number says how much, which is the part that lets somebody notice a
   filter they forgot. Readable when the caption is hidden on a phone: the number stays. */
.rp-chip.is-on { border-color: var(--rp-accent); color: var(--rp-accent-text, var(--rp-accent)); }
.rp-chip.is-on .rp-i { color: var(--rp-accent); }
.rp-chip-n { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px;
  margin-left: 6px; padding: 0 5px; border-radius: var(--rp-r-pill); background: var(--rp-accent); color: #fff;
  font-size: 11px; font-weight: 800; }
.rp-tools .rp-chip.is-on .rp-chip-n { margin-left: 4px; }
.rp-chip-sm { height: var(--rp-h-sm); padding: 0 var(--rp-s3); font-size: var(--rp-fs-13); }
.rp-chip .rp-muted { color: inherit; opacity: .6; }
.rp-tag {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: var(--rp-r-pill);
  font-size: var(--rp-fs-12); font-weight: 700; white-space: nowrap; line-height: 1;
  background: rgba(255,255,255,.95); color: var(--rp-text);
}
.rp-tag-ink { background: var(--rp-ink); color: var(--rp-on-ink); }
.rp-tag-accent { background: var(--rp-accent-soft); color: var(--rp-accent-text); }
.rp-tag-success { background: var(--rp-success-soft); color: var(--rp-success-text); }
.rp-tag-warning { background: var(--rp-warning-soft); color: var(--rp-warning-text); }
.rp-tag-danger { background: var(--rp-danger-soft); color: var(--rp-danger-text); }
.rp-tag-outline { background: var(--rp-bg); border: 1px solid var(--rp-border); }

/* ---------- Forms ---------- */
.rp-field { min-width: 0; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.rp-field > label, .rp-field-label { font-size: var(--rp-fs-13); font-weight: 600; }
.rp-field-hint { font-size: var(--rp-fs-12); color: var(--rp-text-2); }
.rp-field.is-error .rp-input, .rp-field.is-error .rp-select { border-color: var(--rp-danger); }
.rp-field.is-error .rp-field-hint { color: var(--rp-danger-text); font-weight: 600; }
.rp-input, .rp-select, .rp-textarea {
  width: 100%; min-width: 0; max-width: 100%; /* [2026-09-07] never wider than the grid track (date/number inputs) */ height: 48px; padding: 0 var(--rp-s4); border: 1px solid var(--rp-border); border-radius: var(--rp-r-md);
  background: var(--rp-bg); font-size: var(--rp-fs-15); color: var(--rp-text); -webkit-appearance: none; appearance: none;
  transition: border-color var(--rp-t-fast), box-shadow var(--rp-t-fast);
}
.rp-input::placeholder, .rp-textarea::placeholder { color: var(--rp-text-3); }
.rp-input:hover, .rp-select:hover, .rp-textarea:hover { border-color: var(--rp-n300); }
.rp-input:focus, .rp-select:focus, .rp-textarea:focus { border-color: var(--rp-accent); box-shadow: 0 0 0 1px var(--rp-accent); outline: none; }
.rp-select { padding-right: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%236B7280'%3E%3Cpath d='M213.66 101.66l-80 80a8 8 0 0 1-11.32 0l-80-80a8 8 0 0 1 11.32-11.32L128 164.69l74.34-74.35a8 8 0 0 1 11.32 11.32z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; background-size: 14px; }
.rp-textarea { height: auto; min-height: 96px; padding: var(--rp-s3) var(--rp-s4); resize: vertical; }
.rp-input-wrap { position: relative; display: flex; align-items: center; }
.rp-input-wrap .rp-i { position: absolute; left: 14px; color: var(--rp-text-2); pointer-events: none; }
.rp-input-wrap .rp-input { padding-left: 42px; }
.rp-input-suffix { position: absolute; right: 14px; color: var(--rp-text-2); font-size: var(--rp-fs-14); pointer-events: none; }
.rp-seg { display: inline-flex; background: var(--rp-surface); border-radius: var(--rp-r-pill); padding: 4px; width: fit-content; max-width: 100%; }
.rp-seg-opt { height: 40px; padding: 0 var(--rp-s5); border-radius: var(--rp-r-pill); font-size: var(--rp-fs-14); font-weight: 600; color: var(--rp-text-2); display: inline-flex; align-items: center; white-space: nowrap; }
.rp-seg-opt.is-active, .rp-seg-opt[aria-pressed="true"] { background: var(--rp-bg); color: var(--rp-text); font-weight: 700; box-shadow: var(--rp-sh-sm); }
.rp-toggle { position: relative; width: 48px; height: 28px; border-radius: var(--rp-r-pill); background: var(--rp-n300); transition: background var(--rp-t-fast); flex: none; }
.rp-toggle::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; transition: transform var(--rp-t) var(--rp-ease); box-shadow: var(--rp-sh-sm); }
.rp-toggle.is-on, .rp-toggle[aria-checked="true"] { background: var(--rp-accent); }
.rp-toggle.is-on::after, .rp-toggle[aria-checked="true"]::after { transform: translateX(20px); }
.rp-stepper { display: flex; align-items: center; justify-content: space-between; height: 48px; padding: 0 6px; border: 1px solid var(--rp-border); border-radius: var(--rp-r-md); }
.rp-stepper button { width: 36px; height: 36px; border-radius: 50%; background: var(--rp-surface); font-size: 18px; display: inline-flex; align-items: center; justify-content: center; }
.rp-stepper output { font-weight: 700; }

/* ---------- Search bar ---------- */
.rp-search {
  display: flex; align-items: center; height: 48px; padding: 0 6px 0 var(--rp-s5);
  border: 1px solid var(--rp-border); border-radius: var(--rp-r-pill); background: var(--rp-bg); box-shadow: var(--rp-sh-md);
  font-size: var(--rp-fs-14); font-weight: 600; min-width: 0;
}
/* Quick-select pill: each segment is a button inside its own dropdown wrapper; the
   wrapper carries the flex share and the divider the bare segments used to have. */
.rp-qs-wrap { flex: 1 1 0; min-width: 0; display: flex; border-left: 1px solid var(--rp-border); }
.rp-qs-wrap.is-first { border-left: 0; flex: 1.4 1 0; }
/* [2026-09-07] Each segment carries its label («Where / Type / Budget») above the value, the way
   every large travel search pill does — a first-time visitor could not tell the three values
   were three separate steps. */
.rp-search-seg { flex: 1 1 auto; min-width: 0; padding: 0 var(--rp-s4); text-align: left; font: inherit; height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 2px; }
.rp-search-seg-label { font-size: 11px; line-height: 1; font-weight: 600; color: var(--rp-text-2); letter-spacing: .01em; }
.rp-search-seg-val { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.2; }
.rp-header .rp-search { height: 56px; }
.rp-qs-wrap.is-first .rp-search-seg { padding-left: 0; }
.rp-qs-wrap:last-of-type .rp-search-seg { color: var(--rp-text-2); font-weight: 500; }
.rp-qs-menu { left: 0; right: auto; max-height: 60vh; overflow-y: auto; min-width: max-content; }
.rp-qs-menu [role="menuitem"] { white-space: nowrap; }
/* [2026-09-10] Group headings inside the «Where» menu — cities of the chosen country, then every
   country. Sticky, because the list scrolls and a heading that scrolls away answers the question
   only for whoever was already looking. Not a menuitem: it is a label, so the keyboard walks past
   it and a screen reader does not offer it as a choice. */
.rp-menu-group { position: sticky; top: 0; z-index: 1; padding: 10px var(--rp-s3) 6px; background: var(--rp-bg);
  font-size: var(--rp-fs-12); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--rp-text-2); }
.rp-menu-group + [role="menuitem"] { margin-top: 0; }
/* [2026-09-10] Three weights in one menu, each earning its own. The city rows sit lighter than
   the countries: they are the inner list, and a reader scanning for a country should not have to
   read past them at equal strength. «Все города» and «Все страны» are the reset of their group —
   the one row that undoes a choice — so they lead it in bold. Countries keep the default. */
.rp-qs-menu-where [role="menuitem"].is-city { font-weight: 400; color: var(--rp-text-2); }
.rp-qs-menu-where [role="menuitem"].is-city .rp-menu-name { font-weight: 400; }
.rp-qs-menu-where [role="menuitem"].is-all { font-weight: 700; }
.rp-qs-menu-where { min-width: 320px; }
.rp-places { display: block; }
.rp-places-field { display: flex; align-items: center; gap: var(--rp-s2); height: 44px; padding: 0 var(--rp-s3); border: 1px solid var(--rp-border); border-radius: var(--rp-r-lg); background: var(--rp-bg); color: var(--rp-text-2); }
.rp-places-field:focus-within { border-color: var(--rp-text); }
.rp-places-input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font: inherit; font-size: 16px; color: var(--rp-text); }
.rp-places-input::-webkit-search-cancel-button { -webkit-appearance: none; }
.rp-qs-menu .rp-places { padding: 0 0 var(--rp-s2); }
.rp-places-list { display: grid; margin-top: var(--rp-s2); }
.rp-dropdown-menu .rp-places-item, .rp-places-item { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px; width: 100%; height: auto; min-height: 44px; padding: 8px var(--rp-s3); border-radius: var(--rp-r-md); text-align: left; font: inherit; font-size: var(--rp-fs-14); line-height: 1.25; }
.rp-dropdown-menu .rp-places-item:hover, .rp-places-item:hover, .rp-places-item.is-active { background: var(--rp-surface); }
.rp-places-name { font-weight: 600; }
.rp-places-item-search .rp-places-name { font-weight: 500; }
.rp-places-sub { font-size: var(--rp-fs-12); color: var(--rp-text-2); font-weight: 400; }
.rp-places-item-search { border-top: 1px solid var(--rp-border); border-radius: 0; margin-top: var(--rp-s1); }
.rp-places-item-search:first-child { border-top: 0; border-bottom: 1px solid var(--rp-border); margin: 0 0 var(--rp-s1); }
.rp-places-sheet .rp-places-list { max-height: 50vh; overflow-y: auto; }
.rp-search-close { display: none; }
.rp-search-go { width: 36px; height: 36px; margin-left: var(--rp-s2); border-radius: 50%; background: var(--rp-accent); color: #fff; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.rp-search-go:hover { background: var(--rp-accent-hover); }
.rp-search-m { display: flex; align-items: center; gap: var(--rp-s3); height: 52px; padding: 0 6px 0 var(--rp-s4); border: 1px solid var(--rp-border); border-radius: var(--rp-r-pill); box-shadow: var(--rp-sh-md); background: var(--rp-bg); width: 100%; text-align: left; }
.rp-search-m-text { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.rp-search-m-text strong { font-size: var(--rp-fs-14); font-weight: 700; }
.rp-search-m-text span { font-size: var(--rp-fs-12); color: var(--rp-text-2); }

/* ---------- Header ---------- */
.rp-header { position: sticky; top: 0; z-index: var(--rp-z-header); background: rgba(255,255,255,.92); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.rp-header-in { height: var(--rp-header-h); display: flex; align-items: center; justify-content: space-between; gap: var(--rp-s6); }
.rp-logo { display: flex; align-items: center; flex: none; }
.rp-logo img, .rp-logo svg { height: 24px; width: auto; }
.rp-header .rp-search { flex: 1 1 auto; max-width: 560px; }
.rp-header-actions { display: flex; align-items: center; gap: var(--rp-s2); flex: none; }
.rp-nav { display: flex; gap: var(--rp-s1); font-size: var(--rp-fs-14); font-weight: 600; }
.rp-nav a { height: 40px; padding: 0 var(--rp-s3); border-radius: var(--rp-r-pill); display: inline-flex; align-items: center; white-space: nowrap; }
.rp-nav a:hover { background: var(--rp-surface); color: var(--rp-text); }
.rp-nav a.is-active { background: var(--rp-surface); font-weight: 700; }
/* [2026-09-08] signed in → accent, signed out → ink. The colour is the state, not a decoration. */
.rp-avatar.is-in { background: var(--rp-accent); }
.rp-avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--rp-ink); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: var(--rp-fs-12); font-weight: 800; }
.rp-menu-btn { height: 40px; padding: 0 6px 0 var(--rp-s4); border: 1px solid var(--rp-border); border-radius: var(--rp-r-pill); display: inline-flex; align-items: center; gap: 10px; background: var(--rp-bg); }
.rp-menu-btn:hover { box-shadow: var(--rp-sh-md); }
.rp-badge-count { position: absolute; top: -2px; right: -2px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--rp-r-pill); background: var(--rp-accent); color: #fff; font-size: 11px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; }

/* Dropdown */
.rp-dropdown { position: relative; }
.rp-dropdown-menu { position: absolute; top: calc(100% + 8px); right: 0; min-width: 200px; max-width: min(360px, calc(100vw - var(--rp-s8))); padding: 6px; background: var(--rp-bg); border: 1px solid var(--rp-border); border-radius: var(--rp-r-lg); box-shadow: var(--rp-sh-lg); z-index: var(--rp-z-dropdown); display: none; }
.rp-dropdown-menu.show, .rp-dropdown.is-open .rp-dropdown-menu { display: block; }
/* [2026-09-08] :not(.rp-btn) — a real design-system button placed inside a menu keeps its own
   look. Without it this rule (two classes) beat .rp-btn-primary (one) and the Save-search
   button came out with menu-item text colour on the accent fill. */
.rp-dropdown-menu a:not(.rp-btn), .rp-dropdown-menu button:not(.rp-btn) { display: flex; align-items: center; gap: var(--rp-s3); width: 100%; height: 40px; padding: 0 var(--rp-s3); border-radius: var(--rp-r-sm); font-size: var(--rp-fs-14); font-weight: 600; color: var(--rp-text); text-align: left; }
.rp-dropdown-menu a:not(.rp-btn):hover, .rp-dropdown-menu button:not(.rp-btn):hover { background: var(--rp-surface); color: var(--rp-text); }
/* [2026-09-08] A long place name («Puerto del Carmen Lanzarote») ran past the menu's edge and took
   its count with it: the row is a flex line with no minimum, so nothing could shrink and nothing
   was allowed to be cut. The NAME gives way — one line, an ellipsis where it does not fit — and the
   count keeps its own width, because a row that shows a place without its number is the one thing
   this menu must never do. */
.rp-dropdown-menu button:not(.rp-btn) { min-width: 0; gap: var(--rp-s2); }
.rp-dropdown-menu button:not(.rp-btn) > .rp-muted { margin-left: auto; flex: 0 0 auto; }
/* text-overflow cannot clip a flex CONTAINER — the name needs an element of its own to be cut in */
.rp-dropdown-menu .rp-menu-name { min-width: 0; flex: 1 1 auto; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.rp-dropdown-menu a.is-active { color: var(--rp-accent-text); }
.rp-menu-2l { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; } .rp-menu-2l small { font-size: var(--rp-fs-12); overflow: hidden; text-overflow: ellipsis; }
.rp-dropdown-menu hr { border: 0; border-top: 1px solid var(--rp-n100); margin: 6px 0; }
.rp-dropdown-cols { grid-template-columns: 1fr 1fr; }
.rp-dropdown.is-open .rp-dropdown-menu.rp-dropdown-cols, .rp-dropdown-menu.rp-dropdown-cols.show { display: grid; }

/* Mobile tab bar */
.rp-tabbar { display: none; }
.rp-fab { display: none; }

/* ---------- Property card ---------- */
.rp-card { display: flex; flex-direction: column; gap: var(--rp-s3); position: relative; min-width: 0; }
.rp-card-media { position: relative; aspect-ratio: 4 / 3; border-radius: var(--rp-r-xl); overflow: hidden; background: var(--rp-surface); isolation: isolate; }
/* [2026-09-07] a photo still loading shimmers; a bare grey square used to read as «no photo, site is broken» */
.rp-card-media { background-image: linear-gradient(100deg, var(--rp-surface) 35%, var(--rp-n100, #EEF0F4) 50%, var(--rp-surface) 65%); background-size: 240% 100%; animation: rp-shimmer 1.4s linear infinite; }
@keyframes rp-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@media (prefers-reduced-motion: reduce) { .rp-card-media { animation: none; } }
.rp-card-media img, .rp-card-media video, .rp-card-media picture { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--rp-ease); }
.rp-card:hover .rp-card-media img { transform: scale(1.03); }
.rp-card-link { display: block; width: 100%; height: 100%; color: inherit; }
.rp-card-tags { position: absolute; top: var(--rp-s3); left: var(--rp-s3); display: flex; gap: 6px; z-index: 2; pointer-events: none; }
.rp-card-body { display: flex; flex-direction: column; gap: 2px; }
.rp-card-title { font-size: var(--rp-fs-15); font-weight: 700; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-card-title a:hover { color: var(--rp-accent-text); }
.rp-card-meta { font-size: var(--rp-fs-14); color: var(--rp-text-2); }
/* [2026-09-04] On the listing this line is a link (city/country search), so it is a touch
   target and 21px was under the 24px minimum. The padding grows the hit box only; the
   matching negative margin keeps the card laid out exactly as before. */
a.rp-card-meta { display: block; padding-block: 2px; margin-block: -2px; }
.rp-card-price { font-size: var(--rp-fs-15); margin-top: var(--rp-s1); white-space: normal; }
.rp-nowrap { white-space: nowrap; }
/* [2026-09-08] not bold: 400 by the owner's call — the price reads as a fact, not a shout */
.rp-card-price strong { font-weight: 400; font-size: var(--rp-fs-17); letter-spacing: -0.02em; color: var(--rp-text); }
.rp-card-price span:not(.rp-nowrap) { color: var(--rp-text-2); }
.rp-card-price a { color: inherit; }
/* [2026-09-07] the price as published, in the listing's own currency, under the converted one */
.rp-card-price-orig { display: inline; white-space: nowrap; font-size: var(--rp-fs-13); font-weight: 500; color: var(--rp-text-2); letter-spacing: 0; }
.rp-card-cta { margin-top: var(--rp-s2); }

/* Favorite */
.rp-fav { position: absolute; top: var(--rp-s2); right: var(--rp-s2); width: 40px; height: 40px; z-index: 3; display: inline-flex; align-items: center; justify-content: center; color: #fff; border-radius: 50%; }
.rp-fav svg { width: 26px; height: 26px; transition: transform var(--rp-t-fast) var(--rp-ease); }
/* Two-path heart from the design (screens/ui.js): tinted fill under a white outline. */
.rp-fav .rp-fav-fill { fill: rgba(22,24,29,.45); transition: fill var(--rp-t-fast); }
.rp-fav .rp-fav-outline { fill: #fff; }
.rp-fav:hover svg { transform: scale(1.08); }
.rp-fav:active svg { transform: scale(.9); }
.rp-fav.is-active .rp-fav-fill, .rp-fav.favorite-active .rp-fav-fill { fill: var(--rp-accent); }

/* Card slider (hooks .rp-slider*, plus legacy .slider-* for existing JS) */
.rp-slider { position: relative; width: 100%; height: 100%; }
.rp-slider-track { width: 100%; height: 100%; }
.rp-slide { width: 100%; height: 100%; display: none; }
.rp-slide.is-active, .rp-slide.active { display: block; }
.rp-slider-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; border-radius: 50%; background: rgba(255,255,255,.92); color: var(--rp-text); display: inline-flex; align-items: center; justify-content: center; opacity: 0; transition: opacity var(--rp-t-fast); z-index: 2; box-shadow: var(--rp-sh-pin); }
.rp-slider-nav.is-prev { left: var(--rp-s2); } .rp-slider-nav.is-next { right: var(--rp-s2); }
.rp-card-media:hover .rp-slider-nav { opacity: 1; }
.rp-slider-nav:hover { background: #fff; }
/* padding gives the 24px tap areas room inside the clipped strip: without it `overflow: hidden`
   would cut the top and bottom of every dot's hit box back to 6px */
.rp-slider-dots { position: absolute; bottom: calc(var(--rp-s3) - 9px); left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 5px; z-index: 2; max-width: 98px; padding: 9px; overflow: hidden; }
/* Active dot per the design source: same 6px circle, opaque white — no scale. The
   scale(1.2) also hit a WebKit bug (tiny layer rasterized before the transform loses
   its border-radius: the active dot rendered as a rounded square on iPhones). */
/* [2026-09-04] The dot stays 6px to the eye, but its tap area is 24px — Lighthouse flagged 159
   of these as too small to hit, and they are the control people use most on a card. The dot is
   drawn by ::before so the button itself can be the larger target without growing the visual. */
/* Horizontally the hit box may only grow to the 11px pitch (6px dot + 5px gap) — going wider
   makes neighbouring targets overlap, which the audit counts as "obscured" rather than an
   improvement. Vertically there is free space, so it takes the full 24px. */
.rp-slider-dot { -webkit-appearance: none; appearance: none; width: 11px; height: 24px; padding: 0; margin: -9px -2.5px; border: 0; background: none; flex: none; position: relative; pointer-events: none; }
.rp-slider-dot::before { content: ''; position: absolute; inset: 9px 2.5px; border-radius: 50%; background: rgba(255,255,255,.55); transition: background var(--rp-t-fast); }
.rp-slider-dot.is-active::before, .rp-slider-dot.active::before { background: #fff; }
.rp-lazy, .rp-lazy .rp-placeholder { width: 100%; height: 100%; background: var(--rp-surface); }
.rp-no-photo { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--rp-s2); color: var(--rp-text-2); font-size: var(--rp-fs-13); font-weight: 600; background: var(--rp-surface); }
@media (hover: none) { .rp-slider-nav { display: none; } }

/* Horizontal card (map list, favorites) */
.rp-card-h { display: grid; grid-template-columns: 168px minmax(0, 1fr); gap: var(--rp-s4); padding: var(--rp-s3); border: 1px solid var(--rp-border); border-radius: var(--rp-r-2xl); background: var(--rp-bg); transition: border-color var(--rp-t-fast); }
.rp-card-h:hover { border-color: var(--rp-ink); }
.rp-card-h .rp-card-media { border-radius: var(--rp-r-lg); }
.rp-card-h .rp-card-body { justify-content: space-between; padding: var(--rp-s1) var(--rp-s1) var(--rp-s1) 0; }
@media (max-width: 480px) { .rp-card-h { grid-template-columns: 120px minmax(0, 1fr); gap: var(--rp-s3); padding: var(--rp-s2); border-radius: var(--rp-r-xl); } }

/* ---------- Page header / results bar ---------- */
.rp-page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--rp-s6); flex-wrap: wrap; padding-top: var(--rp-s10); }
.rp-page-head .rp-h1 { max-width: 20ch; }
.rp-results-bar { display: flex; align-items: center; gap: var(--rp-s2); padding-top: var(--rp-s6); }
/* [2026-09-09] sort / save / map / filters. Was a style attribute on the div, which is why the
   phone rule below could not override its flex-wrap. */
.rp-tools { display: flex; align-items: center; gap: var(--rp-s2); flex-wrap: wrap; }
/* [2026-09-09] NOT nowrap. This line used to read «Offers: 1 234» and the ban on wrapping was
   harmless; it now carries the filter description too — «Долгосрочная аренда, с мебелью ·
   Объявлений: 36 676» — and at 378px inside a 343px column it pushed the whole page sideways on a
   phone: every screen scrolled horizontally by 19px. The count itself keeps its own spaces
   unbreakable (formatLocalizedNumber), so the line may wrap anywhere but never inside a number. */
.rp-results-count { font-size: var(--rp-fs-14); color: var(--rp-text-2); font-weight: 600; }
/* a flex/grid child is min-content wide by default and a long word can push its parent wider than
   the screen; this is the one line that stops it doing so */
.rp-page-head > .rp-stack, .rp-page-head .rp-stack { min-width: 0; }

/* Breadcrumbs */
.rp-crumbs { display: flex; align-items: center; gap: var(--rp-s2); font-size: var(--rp-fs-13); font-weight: 600; color: var(--rp-text-2); flex-wrap: wrap; padding-top: var(--rp-s6); }
.rp-crumbs a { color: var(--rp-text-2); } .rp-crumbs a:hover { color: var(--rp-text); }
.rp-crumbs li { display: inline-flex; align-items: center; gap: var(--rp-s2); }
.rp-crumbs li + li::before { content: "›"; color: var(--rp-text-3); }
.rp-crumbs li:last-child { color: var(--rp-text); }

/* ---------- Filters panel ---------- */
.rp-filters { display: none; margin-top: var(--rp-s5); padding: var(--rp-s5); border: 1px solid var(--rp-border); border-radius: var(--rp-r-2xl); background: var(--rp-bg); box-shadow: var(--rp-sh-md); }
.rp-filters.is-open, .rp-filters.filters-visible { display: block; }
/* [2026-09-04] auto-fit, not auto-fill: with four fields auto-fill kept the empty tracks it
   could fit and left a wide hole on the right; auto-fit collapses them so the fields share the row. */
.rp-filters-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--rp-s4); align-items: end; }
.rp-filters-actions { display: flex; gap: var(--rp-s2); justify-content: flex-end; margin-top: var(--rp-s4); }
/* Desktop: a dropdown under the «Filters» chip, not a full-bleed strip across the page.
   The chips section is the positioning context (the home page). */
@media (min-width: 768px) {
  .rp-home-chips, .rp-listing-chips { position: relative; }
  .rp-filters.is-open, .rp-filters.filters-visible {
    position: absolute; top: calc(100% + var(--rp-s2)); right: var(--rp-gutter); left: auto;
    width: min(560px, calc(100% - 2 * var(--rp-gutter))); margin-top: 0; z-index: var(--rp-z-dropdown);
    box-shadow: var(--rp-sh-lg);
  }
  .rp-filters-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .rp-filters [data-rp-sheet-close] { display: none; }
}
@media (max-width: 767px) {
  /* [2026-09-09] The action bar is sticky at the bottom of this sheet, so it floats over whatever is
     scrolled under it — and the sheet reserved only 20px below, which meant the last two amenity
     chips («Стиральная машина», «Wi-Fi») could never be scrolled out from under it. The reserve is
     now the bar's own height, so the list always ends above it. */
  .rp-filters.is-open, .rp-filters.filters-visible { position: fixed; inset: auto 0 0 0; max-height: 88dvh; overflow-y: auto; margin: 0; border-radius: var(--rp-r-2xl) var(--rp-r-2xl) 0 0; box-shadow: var(--rp-sh-lg); z-index: var(--rp-z-sheet); padding-bottom: 0; }
  .rp-filters-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  /* it must read as a bar over the list, not as two buttons floating in the middle of it: an opaque
     ground, a hairline above, and it reaches the sheet's edges */
  /* [2026-09-09] The bar is the LAST element in the form, so a plain sticky bottom: 0 is all it
     needs: while scrolling it floats over the chips, and at the end of the scroll it settles below
     the last of them. Everything I added around that — a negative offset, a 76px reserve, a negative
     margin cancelling the reserve — only moved it up into the middle of the list, where the last
     three chips ended up under it and could not be reached at all. */
  .rp-filters-actions { position: sticky; bottom: 0; z-index: 2;
    background: var(--rp-bg); border-top: 1px solid var(--rp-border);
    margin: var(--rp-s4) calc(-1 * var(--rp-s5)) 0;
    padding: var(--rp-s3) var(--rp-s5) calc(var(--rp-s3) + var(--rp-safe-b)); }
  .rp-filters-actions .rp-btn { flex: 1; }
  /* reset is a cross here; «Apply» takes everything that is left */
  .rp-filters-clear { flex: none !important; width: var(--rp-h-lg, 52px); padding: 0; }
  .rp-filters-clear .rp-btn-lbl { display: none; }
  /* [2026-09-09] An open sheet is a modal and must be above everything, including the chat bubble
     that was sitting on top of «Apply». Its own layer only — the widget itself is untouched. */
  .rp-filters.is-open, .rp-filters.filters-visible { z-index: 2147483000; }
}
.rp-scrim { position: fixed; inset: 0; background: rgba(22,24,29,.45); z-index: calc(var(--rp-z-sheet) - 1); display: none; }
.rp-scrim.is-open { display: block; }

/* ---------- Pagination ---------- */
.rp-pagination { display: flex; justify-content: center; gap: 6px; padding-top: var(--rp-s10); }
.rp-pagination a, .rp-pagination span { min-width: 40px; height: 40px; padding: 0 var(--rp-s3); border-radius: var(--rp-r-pill); display: inline-flex; align-items: center; justify-content: center; font-size: var(--rp-fs-14); font-weight: 700; border: 1px solid var(--rp-border); }
.rp-pagination a:hover { border-color: var(--rp-ink); color: var(--rp-text); }
.rp-pagination .is-current { background: var(--rp-ink); border-color: var(--rp-ink); color: var(--rp-on-ink); }

/* ---------- Panels / CTA ---------- */
.rp-panel { border-radius: var(--rp-r-2xl); background: var(--rp-surface); padding: var(--rp-s10); }
.rp-panel-ink { border-radius: var(--rp-r-2xl); background: var(--rp-ink); color: var(--rp-on-ink); padding: var(--rp-s10); position: relative; overflow: hidden; }
.rp-panel-ink .rp-muted { color: rgba(255,255,255,.7); }
.rp-panel-ink::before { content: ""; position: absolute; right: -80px; top: -80px; width: 280px; height: 280px; border-radius: 50%; background: var(--rp-accent); opacity: .9; }
.rp-panel-ink > * { position: relative; }
.rp-outline-box { border: 1px solid var(--rp-border); border-radius: var(--rp-r-2xl); padding: var(--rp-s6); }
.rp-stat { display: flex; flex-direction: column; }
.rp-stat strong { font-size: var(--rp-fs-20); font-weight: 800; letter-spacing: -0.02em; }
.rp-stat span { font-size: var(--rp-fs-12); color: var(--rp-text-2); font-weight: 600; }
@media (max-width: 767px) { .rp-panel, .rp-panel-ink { padding: var(--rp-s6); border-radius: var(--rp-r-xl); } }

/* SEO link grids */
.rp-links-block { padding-top: var(--rp-s12); display: flex; flex-direction: column; gap: var(--rp-s8); }
.rp-links-block .rp-stack { gap: var(--rp-s8); }
.rp-links-block .rp-label { margin-bottom: calc(-1 * var(--rp-s4)); }
/* Equal-width responsive columns: auto-fill keeps rows aligned instead of the ragged
   4-column float the old block produced. */
.rp-links-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--rp-s1) var(--rp-s6); }
/* Hierarchy per the design system: the eyebrow label stays small/uppercase/muted,
   the links themselves carry the main ink — grey-on-grey gave the two rows the same
   visual weight. */
.rp-links-grid a { display: block; padding: 6px 0; font-size: var(--rp-fs-14); font-weight: 500; color: var(--rp-text); }
.rp-links-grid a:hover { color: var(--rp-accent); }
/* [2026-09-04] --rp-text-3 (#9AA1AD) is 2.6:1 on white — fine for icons and separators,
   too pale for text. Real copy takes --rp-text-2 (#6B7180, 4.9:1). */
.rp-links-count { color: var(--rp-text-2); font-weight: 500; }
.rp-chips-wrap { display: flex; flex-wrap: wrap; gap: var(--rp-s2); }

/* ---------- Footer ---------- */
/* Footer v2 (the site footer): brand + four link columns, bottom bar. */
.rp-footer { margin-top: var(--rp-s10); padding: var(--rp-s10) 0 var(--rp-s8); font-size: var(--rp-fs-14); color: var(--rp-text-2); background: var(--rp-bg); }
.rp-footer-grid { display: grid; grid-template-columns: 1.6fr repeat(4, 1fr); gap: var(--rp-s8); }
.rp-footer h4 { font-size: var(--rp-fs-12); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--rp-text-2); margin: 0 0 var(--rp-s3); }
.rp-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.rp-footer a { color: var(--rp-text); font-weight: 600; text-decoration: none; }
.rp-footer a:hover { color: var(--rp-accent-text); }
.rp-footer-brand { display: flex; flex-direction: column; gap: var(--rp-s3); padding-right: var(--rp-s6); }
.rp-footer-logo { display: inline-flex; width: 139px; }
.rp-footer-logo img { display: block; width: 139px; height: 24px; }
.rp-footer-tagline { margin: 0; max-width: 300px; line-height: 1.5; }
.rp-footer-contacts { margin-top: var(--rp-s2); }
.rp-footer-contacts a { display: inline-flex; align-items: center; gap: 8px; font-variant-numeric: tabular-nums; }
.rp-footer-contacts .rp-i { color: var(--rp-text-2); flex-shrink: 0; }
/* [2026-09-09] no margin of its own: the brand column is a flex stack with a 12px gap, and the
   extra 12 here made «About us» sit twice as far from the contacts as everything else. */
.rp-footer-about { margin: 0; }   /* under the contacts, in the brand column */
.rp-footer-bottom { display: flex; justify-content: space-between; align-items: center; gap: var(--rp-s4); flex-wrap: wrap; margin-top: var(--rp-s8); padding-top: var(--rp-s5); font-size: var(--rp-fs-13); }
.rp-footer-bottom a { color: var(--rp-text-2); font-weight: 600; }
.rp-footer-bottom-links { display: flex; gap: var(--rp-s5); flex-wrap: wrap; }
/* [2026-09-12] The pasted links (admin /links). Quiet by design: smaller than the bottom bar and
   in the secondary colour, because they are a reference at the end of the page, not navigation. */
.rp-footer-extra { display: flex; flex-wrap: wrap; gap: var(--rp-s2) var(--rp-s4); margin-top: var(--rp-s4); font-size: var(--rp-fs-12); line-height: 1.6; }
.rp-footer-extra a { color: var(--rp-text-2); font-weight: 500; }
@media (max-width: 1023px) {
	.rp-footer-grid { grid-template-columns: repeat(2, 1fr); gap: var(--rp-s6) var(--rp-s6); }
	.rp-footer-brand { grid-column: 1 / -1; padding-right: 0; }
}
@media (max-width: 767px) {
	/* two link columns above the mobile tab bar; every link is a 40px tap row */
	.rp-footer { padding: var(--rp-s8) 0 calc(var(--rp-s6) + var(--rp-tabbar-h) + var(--rp-safe-b)); }
	/* [2026-09-09] 168px OF NOTHING BEFORE THE FOOTER, measured on a phone: .rp-main reserves 96px so
	   the tab bar cannot cover the last line, and then the footer adds 40 of margin and 32 of padding
	   on top of it. But the footer reserves for that tab bar ITSELF, at its own bottom — so main's
	   reserve was not protecting anything, it was a hole in the middle of the page. Where a footer
	   follows, main gives the reserve up; where none does, it keeps it. */
	.rp-main:has(+ .rp-footer) { padding-bottom: var(--rp-s6); }
	.rp-footer { margin-top: var(--rp-s6); }
	/* [2026-09-09] and the section headings need to read as a new block: at the old 24px they sat
	   exactly as far from the brand column as the lines inside it, so nothing said «this is a new
	   list». The columns stay 20px apart, the rows go to 32. */
	.rp-footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--rp-s8) var(--rp-s5); }
	.rp-footer-brand { grid-column: 1 / -1; }
	.rp-footer ul { gap: 0; }
	/* [2026-09-09] The spacing was min-height and nothing else, so a one-line link got 40px of box
	   around ~20px of text and looked airy, while «Разместить недвижимость» wrapping to two lines
	   filled its box edge to edge and touched the link under it. Real padding spaces both alike;
	   min-height still guarantees the 40px tap target for the short ones. */
	.rp-footer ul li a { display: flex; align-items: center; min-height: 32px; padding: 6px 0; box-sizing: border-box; line-height: 1.35; }
	.rp-footer-contacts a { min-height: 32px; }
	.rp-footer-bottom { flex-direction: column; align-items: flex-start; gap: var(--rp-s3); }
	.rp-footer-bottom-links a { display: inline-flex; align-items: center; min-height: 44px; }
}
.rp-social { display: flex; gap: var(--rp-s1); }
.rp-social a { width: 36px; height: 36px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: var(--rp-text-2); }
.rp-social a:hover { background: var(--rp-surface); color: var(--rp-text); }
.rp-social svg { width: 18px; height: 18px; fill: currentColor; }

/* ---------- Toast (JS: .notification) ---------- */
.rp-toast, .notification { position: fixed; left: 50%; bottom: calc(var(--rp-s6) + var(--rp-safe-b)); transform: translateX(-50%); z-index: var(--rp-z-toast); max-width: min(92vw, 480px); padding: var(--rp-s3) var(--rp-s4); border-radius: var(--rp-r-lg); background: var(--rp-ink); color: #fff; font-size: var(--rp-fs-14); font-weight: 600; box-shadow: var(--rp-sh-lg); animation: rp-toast-in var(--rp-t) var(--rp-ease); }
.rp-toast-content, .notification-content { display: flex; align-items: center; gap: var(--rp-s3); }
.rp-toast .rp-btn-close, .notification-close { color: rgba(255,255,255,.7); font-size: 16px; line-height: 1; padding: 4px; }
.notification-error { background: var(--rp-danger); }
.notification-success { background: var(--rp-ink); }
@keyframes rp-toast-in { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }
@media (max-width: 767px) { .rp-toast, .notification { bottom: calc(var(--rp-tabbar-h) + var(--rp-s3) + var(--rp-safe-b)); } }

/* ---------- Modal ---------- */
.rp-modal-backdrop { position: fixed; inset: 0; background: rgba(22,24,29,.5); z-index: var(--rp-z-modal); display: none; align-items: center; justify-content: center; padding: var(--rp-s4); }
.rp-modal-backdrop.is-open { display: flex; }
.rp-modal { width: 100%; max-width: 480px; max-height: 92dvh; overflow-y: auto; background: var(--rp-bg); border-radius: var(--rp-r-2xl); padding: var(--rp-s6); box-shadow: var(--rp-sh-lg); position: relative; }
.rp-modal-close { position: absolute; top: var(--rp-s3); right: var(--rp-s3); }
.rp-modal-title { font-size: var(--rp-fs-24); font-weight: 800; letter-spacing: -0.03em; margin-bottom: var(--rp-s2); padding-right: var(--rp-s10); }
.rp-modal-actions { display: flex; gap: var(--rp-s2); margin-top: var(--rp-s5); }
@media (max-width: 767px) { .rp-modal-backdrop { align-items: flex-end; padding: 0; } .rp-modal { border-radius: var(--rp-r-2xl) var(--rp-r-2xl) 0 0; padding-bottom: calc(var(--rp-s6) + var(--rp-safe-b)); } }

/* ---------- Map bits ---------- */
.rp-pin { height: 32px; padding: 0 var(--rp-s3); border-radius: var(--rp-r-pill); background: var(--rp-bg); border: 1px solid var(--rp-border); font-size: var(--rp-fs-13); font-weight: 800; display: inline-flex; align-items: center; box-shadow: var(--rp-sh-pin); white-space: nowrap; }
.rp-pin.is-active { background: var(--rp-ink); border-color: var(--rp-ink); color: #fff; }
.rp-pin.is-cluster { background: var(--rp-accent); border-color: var(--rp-accent); color: #fff; }
.rp-pin.is-visited { color: var(--rp-text-2); }

/* ---------- Mobile ---------- */
/* [2026-09-04] hidden below 1024px as before — keyed to the button itself now, not to the
   variant it happens to wear, so restyling it never changes where it shows. */
@media (max-width: 1023px) { .rp-header-actions > .rp-header-post { display: none; } }
@media (max-width: 767px) {
  .rp-header-in { height: var(--rp-header-h-m); gap: var(--rp-s3); }
  .rp-header .rp-search, .rp-nav { display: none; }
  /* [2026-09-09] THE SEARCH SHEET. The «Search» tab used to link to the home page: on the home page
     that is the address you are already at, so the tap did nothing, and from a listing it discarded
     the search to show the front door. The row it opens is the header's own search — three pickers
     and a go button, present on every page and hidden here only because it does not fit a phone as
     a row. Opened, it becomes a sheet from the top, where a search bar belongs, and each picker is
     a full-width control rather than a third of 375px.
     Two rules matter beyond the shape: the pickers lose their own positioning so their menus open
     in the flow of the sheet instead of hanging off its edge (the same off-screen menu bug the
     tools row had), and the sheet scrolls, because the «where» menu carries a country list. */
  /* [2026-09-09] AND THE HEADER HAS TO RISE WITH IT. The header is position: sticky with z-index
     100, which makes it a stacking context — so the sheet's own z-index only ever competes INSIDE
     it, and the scrim (299, appended to the body) covered the sheet: the whole thing looked dimmed
     and, worse, every tap landed on the scrim instead of the list. Measured with elementFromPoint
     over the open sheet: it returned .rp-scrim. While the sheet is open the header leads; closed,
     it drops back to 100 and nothing else changes. */
  .rp-header:has(.rp-search.is-open) { z-index: 2147483000; }
  .rp-header .rp-search.is-open {
    display: flex; flex-direction: column; align-items: stretch; gap: var(--rp-s2);
    position: fixed; top: 0; left: 0; right: 0; z-index: 2147483000;
    height: auto; max-height: 100dvh; overflow-y: auto;
    /* the top strip is left clear for the close control, which floats in the corner */
    padding: calc(52px + env(safe-area-inset-top)) var(--rp-s4) var(--rp-s5);
    border: 0; border-radius: 0 0 var(--rp-r-2xl) var(--rp-r-2xl);
    background: var(--rp-bg); box-shadow: var(--rp-sh-lg);
  }
  /* [2026-09-09] display: block, and this is the whole bug. The wrapper is a flex ROW in the
     desktop bar, so inside the sheet the picker and its menu sat SIDE BY SIDE: the button took the
     left half, the menu opened as a 166px column against the right edge, and the halves of the
     controls behind it showed as stripes down the left. Stacked, the menu opens under its own
     field across the full width, which is what a picker in a sheet has to do. */
  /* [2026-09-09] border-left: 0 — the two stray lines. In the desktop bar the pickers sit in a ROW
     and a hairline on the left of each is the divider between «where | type | budget»; the first
     one has none, which is why only «type» and «budget» showed them. Stacked in the sheet, each
     field is already a box with its own outline, so that divider becomes a line hanging in the
     margin beside it — read, correctly, as a rendering fault. */
  .rp-header .rp-search.is-open .rp-qs-wrap { position: static; display: block; width: 100%; border-left: 0; }
  .rp-header .rp-search.is-open .rp-search-seg {
    width: 100%; height: 56px; padding: 0 var(--rp-s4);
    border: 1px solid var(--rp-border); border-radius: var(--rp-r-lg);
  }
  .rp-header .rp-search.is-open .rp-qs-wrap.is-first .rp-search-seg { padding-left: var(--rp-s4); }
  .rp-header .rp-search.is-open .rp-search-seg-val { white-space: normal; }
  .rp-header .rp-search.is-open .rp-dropdown-menu {
    position: static; width: 100%; min-width: 0; max-width: none;
    margin-top: var(--rp-s2); border-radius: var(--rp-r-lg); box-shadow: none;
  }
  /* [2026-09-09] NO GO BUTTON HERE. Picking is searching in this widget — every pick navigates
     immediately (RP.quickSearch: «Picking IS searching», and the click handler calls run() on each
     one). The button is a fallback nobody presses, and in a sheet it reads as a required last step
     that does not exist: you would tap a city, the page would already be loading, and a big red
     bar would still be sitting there asking to be pressed. The desktop row keeps it — there it is
     a 36px circle at the end of the line, not an instruction. */
  .rp-header .rp-search.is-open .rp-search-go { display: none; }
  /* the way out of the sheet: a 44px target in the corner, not a guess at the dimmed area */
  .rp-search-close {
    position: absolute; top: calc(var(--rp-s2) + env(safe-area-inset-top)); right: var(--rp-s2);
    width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
    border: 0; background: transparent; color: var(--rp-text-2); border-radius: 50%;
  }
  .rp-header .rp-search:not(.is-open) .rp-search-close { display: none; }
  .rp-logo img, .rp-logo svg { height: 20px; }
  .rp-tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--rp-z-header); display: grid; grid-template-columns: repeat(4, 1fr); height: calc(var(--rp-tabbar-h) + var(--rp-safe-b)); padding: 6px var(--rp-s2) var(--rp-safe-b); background: rgba(255,255,255,.96); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
  .rp-tabbar a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; color: var(--rp-text-2); font-size: 10px; font-weight: 700; position: relative; }
  .rp-tabbar a.is-active { color: var(--rp-accent); }
  .rp-tabbar .rp-badge-count { top: 0; right: calc(50% - 22px); }
  .rp-fab { display: inline-flex; position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(var(--rp-tabbar-h) + var(--rp-safe-b) + var(--rp-s4)); z-index: var(--rp-z-header); box-shadow: var(--rp-sh-lg); }
  .rp-page-head { padding-top: var(--rp-s5); }
  /* [2026-09-09] A two-line heading at 22px with line-height 1.2 leaves 4px between the lines and
     the words look glued; the tighter the letter-spacing of a bold face, the more the lines need.
     1.28 here, and a little air before the line that follows it. */
  .rp-page-head .rp-h1, .rp-page-head .rp-h2 { line-height: 1.28; }
  .rp-page-head .rp-results-count { margin-top: 2px; line-height: 1.4; }
  /* [2026-09-09] FOUR CONTROLS, THREE LINES. Sort, save, map and filters wrapped onto three rows on
     a phone and pushed the first listing below the fold. They scroll sideways instead — the same
     pattern the category chips above them already use — and the sort pill drops the word «Sort:»,
     because the value beside it («Recommended») already says what it is. */
  /* [2026-09-09] NO SCROLLING CONTAINER HERE, and this is not a style preference. Two of these four
     controls are dropdowns, and `overflow-x: auto` makes the row a clipping context: the menus
     opened and were cut off at its edge, so sort and «save search» silently stopped working while
     filters — a bottom sheet, not a dropdown — kept working. That is a worse bug than three rows.
     The row wraps instead, and it fits on one line because map and filters are icons here. */
  .rp-page-head .rp-row.rp-tools, .rp-tools { flex-wrap: wrap; overflow: visible; }
  .rp-sort-lbl { display: none; }
  /* [2026-09-09] Map and filters keep only their icon here — a funnel and a map are read without a
     caption. The sort chip does NOT: its text is the current sorting («Recommended»), a state and
     not a label, and an icon alone would hide the one thing it exists to show. «Save search» keeps
     its words too: a bell on its own reads as «notifications», not «remember this search». */
  /* [2026-09-09] A dropdown here is anchored right:0 to its chip. The sort chip sits at the left of
     the row and its menu is 220px wide, so the menu's left edge landed at -33px — it opened, it was
     «visible» to the code, and half of it was off the screen. On a phone these menus align to the
     row's left edge and never exceed the screen. */
  /* [2026-09-09] AND THE ANCHOR IS THE ROW, NOT THE CHIP. `.rp-tools .rp-dropdown-menu {left:0}`
     lost to `.rp-sort .rp-dropdown-menu {right:0}` further down this file — same specificity, later
     wins — so both menus stayed pinned to their chip's right edge and opened at x = -33 (sort) and
     x = -83 (save search) on a 375px screen. Measured, not guessed. Anchoring them to the tools row
     instead of the chip removes the arithmetic entirely: the row is exactly as wide as the content
     column, so a menu that fills it cannot leave the screen wherever its chip happens to sit. */
  .rp-tools { position: relative; }
  .rp-tools .rp-dropdown { position: static; }
  .rp-tools .rp-sort .rp-dropdown-menu,
  .rp-tools .rp-save-search .rp-dropdown-menu,
  .rp-tools .rp-dropdown-menu { left: 0; right: auto; top: calc(100% + 8px);
    width: auto; min-width: 0; max-width: 100%; }
  /* [2026-09-09] the map chip goes: the tab bar below now leads to the same search on the map, and
     two map icons on one screen pointing at different maps is one too many */
  .rp-tools .rp-chip[href*="/map"] { display: none; }
  .rp-tools .rp-chip-lbl { display: none; }
  .rp-tools .rp-chip:has(.rp-chip-lbl) { padding-left: var(--rp-s3); padding-right: var(--rp-s3); }
  /* [2026-09-09] TWO COLUMNS FOR THE PLACE LINKS. minmax(240px, 1fr) fits exactly one column in a
     343px phone column, so «popular cities» became a twenty-screen ladder of one name per line. Two
     columns halve it; a name too long for its half is cut with an ellipsis rather than allowed to
     wrap into a second line, because a ragged two-line entry in a list of links reads as two links.
     The full name stays in the title attribute and in the link itself — nothing is lost, only the
     rendering is trimmed. */
  .rp-grid-links, .rp-links-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--rp-s4); }
  .rp-links-grid a { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .rp-card-media { border-radius: var(--rp-r-xl); }
  .rp-fav { width: 44px; height: 44px; }
  /* [2026-09-09] NO ZOOM WHEN A FIELD IS TAPPED. Safari on iOS magnifies the whole page whenever a
     focused field's text is smaller than 16px — our scale puts inputs at 15 — and the page then
     stays magnified, so the form somebody is filling runs off the side of the screen and the
     buttons under it become unreachable. The fix is the type size, not «user-scalable=no»: turning
     pinch-zoom off would take the page away from anybody who needs to enlarge it, and iOS ignores
     that instruction anyway. 16px on phones, unchanged everywhere else. */
  .rp-input, .rp-select, .rp-textarea, input, select, textarea { font-size: 16px; }
}

/* ============================================================================
   [2026-09-02] Home v2 blocks — from the design source screens/01 Home.dc.html.
   Hero (ink panel + photo tile with stats), section head, CTA panel, minimal
   footer. Values mirror the source; colors via tokens (same palette).
   ========================================================================== */

.rp-home-chips { padding-top: var(--rp-s10); }
.rp-home-chips .rp-scroll-x { align-items: center; }

/* Hero: two equal tiles ([2026-09-05] was 1.1fr / 1fr per the source; Max asked for equal), gap 24, radius 24, min-height 300 */
.rp-hero { padding-top: var(--rp-s6); display: grid; grid-template-columns: 1fr 1fr; gap: var(--rp-s6); }
.rp-hero-ink { border-radius: var(--rp-r-2xl); background: var(--rp-ink); color: var(--rp-on-ink); padding: var(--rp-s10); display: flex; flex-direction: column; justify-content: space-between; gap: var(--rp-s8); min-height: 300px; position: relative; overflow: hidden; }
.rp-hero-map { position: absolute; inset: 0; -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,.5) 0%, #000 45%); mask-image: linear-gradient(90deg, rgba(0,0,0,.5) 0%, #000 45%); pointer-events: none; }
.rp-hero-map svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.rp-hero-pin { fill: var(--rp-accent); }
.rp-hero-pin-ring { fill: none; stroke: var(--rp-accent); stroke-width: 0.6; transform-box: fill-box; transform-origin: center; animation: rp-hero-ring 2.4s ease-out infinite; }
@keyframes rp-hero-ring { 0% { transform: scale(1); opacity: 0.9; } 100% { transform: scale(3.2); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .rp-hero-pin-ring { animation: none; opacity: 0.5; } }
.rp-hero-title, .rp-hero-foot { position: relative; }
.rp-hero-title { margin: 0; font-size: var(--rp-fs-44); line-height: 1.05; letter-spacing: -0.03em; font-weight: 800; max-width: 460px; text-wrap: balance; position: relative; }
.rp-hero-foot { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--rp-s6); position: relative; flex-wrap: wrap; }
.rp-hero-sub { margin: 0; font-size: 16px; line-height: 1.5; color: rgba(255, 255, 255, 0.7); max-width: 380px; min-width: 0; }
.rp-hero-btn { height: 48px; padding: 0 22px; background: #fff; color: var(--rp-ink); border-radius: var(--rp-r-pill); font-size: var(--rp-fs-15); font-weight: 700; white-space: nowrap; }
.rp-hero-btn:hover { background: var(--rp-surface); color: var(--rp-ink); }
/* [2026-09-04] hero got a second action (the map); the pair stays on one line and wraps on phones */
.rp-hero-actions { display: flex; align-items: center; gap: var(--rp-s3); flex-shrink: 0; }
/* [2026-09-07] secondary on ink: full-strength on-ink outline + on-ink text next to the filled
   primary. The earlier 55 % outline read as «black on black»; a grey tonal fill read as disabled. */
.rp-hero-btn-ghost { background: transparent; color: var(--rp-on-ink); box-shadow: inset 0 0 0 1.5px var(--rp-on-ink); }
.rp-hero-btn-ghost:hover { background: rgba(255,255,255,.14); color: var(--rp-on-ink); }
.rp-hero-photo { border-radius: var(--rp-r-2xl); overflow: hidden; position: relative; min-height: 300px; background: var(--rp-surface); }
.rp-hero-photo img { width: 100%; height: 100%; object-fit: cover; display: block; position: absolute; inset: 0; }
/* Place tile: whole tile is a link; slides crossfade with a slow zoom; a pill names the place. */
.rp-hero-photo-link { position: absolute; inset: 0; display: block; color: inherit; }
.rp-hero-slide { opacity: 0; transition: opacity 1.2s ease; will-change: opacity, transform; }
.rp-hero-slide.is-on { opacity: 1; animation: rp-hero-zoom 12s ease-in-out both; }
@keyframes rp-hero-zoom { from { transform: scale(1); } to { transform: scale(1.06); } }
.rp-hero-place { position: absolute; left: var(--rp-s5); top: var(--rp-s5); height: 40px; padding: 0 14px 0 12px; display: inline-flex; align-items: center; gap: 8px; background: rgba(255, 255, 255, 0.94); backdrop-filter: blur(8px); border-radius: var(--rp-r-pill); font-size: var(--rp-fs-14); font-weight: 700; color: var(--rp-ink); transition: background var(--rp-t); }
.rp-hero-place .rp-i:first-child { color: var(--rp-accent); }
.rp-hero-place .rp-i:last-child { transition: transform var(--rp-t); }
.rp-hero-photo-link:hover .rp-hero-place { background: #fff; }
.rp-hero-photo-link:hover .rp-hero-place .rp-i:last-child { transform: translateX(3px); }
.rp-hero-photo-link:focus-visible { outline: 3px solid var(--rp-accent); outline-offset: -3px; border-radius: var(--rp-r-2xl); }
@media (prefers-reduced-motion: reduce) { .rp-hero-slide { transition: none; } .rp-hero-slide.is-on { animation: none; } }
.rp-hero-stats { position: absolute; left: var(--rp-s5); bottom: var(--rp-s5); background: rgba(255, 255, 255, 0.94); backdrop-filter: blur(8px); border-radius: var(--rp-r-lg); padding: 14px 18px; display: flex; gap: var(--rp-s6); }
.rp-hero-stats > div { display: flex; flex-direction: column; }
.rp-hero-stat-v { font-size: var(--rp-fs-20); font-weight: 800; letter-spacing: -0.02em; }
.rp-hero-stat-l { font-size: var(--rp-fs-12); color: var(--rp-text-2); font-weight: 600; }

/* Section head: h2 28/800 + accent "view all" link */
.rp-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--rp-s4); margin-bottom: var(--rp-s6); }
/* [2026-09-09] The hotels of a country or a city, under a listing of homes. The heading names them,
   the line beneath says how they are sold — a nightly price under a «long-term, furnished» page
   heading reads as an error until something tells the reader it is a different section. */
.rp-hotels-block { margin-top: var(--rp-s8); }
.rp-hotels-block .rp-section-head { margin-bottom: var(--rp-s2); flex-wrap: wrap; row-gap: var(--rp-s2); }
.rp-hotels-note { margin: 0 0 var(--rp-s5); font-size: var(--rp-fs-14); }
/* [2026-09-06] «Viewing now» (the home page): a pulsing accent dot marks the live window only */
.rp-nv { padding-bottom: 64px; }
.rp-nv-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--rp-accent); margin: 0 10px 4px 0; vertical-align: middle; animation: rp-nv-pulse 1.8s ease-in-out infinite; }
@keyframes rp-nv-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(200, 16, 46, .45); } 50% { box-shadow: 0 0 0 6px rgba(200, 16, 46, 0); } }
@media (prefers-reduced-motion: reduce) { .rp-nv-dot { animation: none; } }
.rp-h1-sm { margin: 0; font-size: var(--rp-fs-28); font-weight: 800; letter-spacing: -0.03em; }
.rp-link-accent { font-size: var(--rp-fs-14); font-weight: 700; color: var(--rp-accent); display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }

/* CTA panel: surface, radius 24, padding 40, two columns */
/* [2026-09-09] minmax(320px, 1fr) is a FLOOR, not a wish: on a 375px phone the panel has 263px of
   room inside its padding and the column still claimed 320, so «Размещение бесплатно, продвижение —
   по желанию.» ran 17px past the panel and off the screen. Measured, not guessed. min(320px, 100%)
   keeps the 320px column wherever it fits and lets it shrink where it does not — the desktop layout
   is unchanged. */
.rp-cta-panel { border-radius: var(--rp-r-2xl); background: var(--rp-surface); padding: var(--rp-s10); display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--rp-s10); align-items: center; }
.rp-cta-text { display: flex; flex-direction: column; gap: var(--rp-s4); align-items: flex-start; }
.rp-cta-text h3 { margin: 0; font-size: var(--rp-fs-28); font-weight: 800; letter-spacing: -0.03em; }
.rp-cta-text p { margin: 0; color: var(--rp-text-2); font-size: var(--rp-fs-15); line-height: 1.5; }
.rp-cta-countries { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.rp-chip-onpanel { background: var(--rp-bg); border-color: transparent; }
/* [2026-09-07] toggle chip with a hidden checkbox (amenity filters); the chip itself is the control */
.rp-tag-verified { display: inline-flex; align-items: center; gap: 4px; }
.rp-chip.is-busy { opacity: .7; pointer-events: none; }
/* [2026-09-07] «Nearby»: the pin pulses in accent; the chip's own outline stays standard (user's call) */
.rp-tag-drop { color: var(--rp-success-text); }
/* [2026-09-07] mode picker (web_shared/stay_modes.php) + its stay window */
.rp-chip-sep { flex: none; align-self: center; width: 1px; height: 24px; margin: 0 var(--rp-s2); background: var(--rp-border); }
.rp-stay-dates { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--rp-s3); margin-top: var(--rp-s4); }
.rp-stay-dates .rp-field { flex: 0 1 190px; min-width: 0; }
.rp-stay-dates .rp-input { min-width: 0; }
@media (max-width: 767px) {
	.rp-stay-dates .rp-field { flex: 1 1 calc(50% - var(--rp-s3)); }
	.rp-stay-dates .rp-btn { flex: 1 1 100%; }
}
.rp-chip-near .rp-i { color: var(--rp-accent); animation: rp-near-pulse 2s ease-in-out infinite; }
.rp-chip-near.is-active .rp-i { color: inherit; animation: none; }
@keyframes rp-near-pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.25); opacity: .6; } }
@media (prefers-reduced-motion: reduce) { .rp-chip-near .rp-i { animation: none; } }
.rp-chip-check { cursor: pointer; position: relative; }
.rp-chip-check input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.rp-chip-check:has(input:checked) { background: var(--rp-ink); color: var(--rp-on-ink); border-color: var(--rp-ink); }
.rp-chip-check:has(input:focus-visible) { outline: 2px solid var(--rp-accent); outline-offset: 2px; }
.rp-amen { border: 0; padding: 0; margin: var(--rp-s4) 0 0; }
.rp-amen legend { padding: 0; margin-bottom: var(--rp-s2); }
.rp-sort .rp-dropdown-menu { left: auto; right: 0; min-width: 220px; }
/* [2026-09-07] «Save search» popover: hint, e-mail, one button, a status line */
.rp-save-search .rp-dropdown-menu { left: auto; right: 0; width: 320px; max-width: calc(100vw - 32px); padding: var(--rp-s4); display: none; flex-direction: column; gap: var(--rp-s3); }
.rp-save-search.is-open .rp-dropdown-menu { display: flex; }
.rp-save-hint { margin: 0; font-size: var(--rp-fs-14); color: var(--rp-text-2); }
.rp-save-form .rp-btn { width: 100%; }
.rp-save-state { margin: 0; font-size: var(--rp-fs-14); color: var(--rp-text); }
.rp-sort-lbl { color: var(--rp-text-2); font-weight: 500; }

/* Minimal footer (design screens 01/02): one line, hairline on top */
/* The inner box mirrors .rp-container exactly (gutter INSIDE the max-width), so the
   footer line starts and ends flush with the cards and the CTA panel. Gutter on the
   outer element instead made the footer content 2 gutters wider than the page. */
.rp-footer-min { padding: 28px 0; font-size: var(--rp-fs-13); color: var(--rp-text-2); font-weight: 600; }
.rp-footer-min-in { max-width: var(--rp-container); margin: 0 auto; padding: 0 var(--rp-gutter); display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--rp-s4); }
.rp-footer-min-links { display: flex; gap: var(--rp-s5); flex-wrap: wrap; }
.rp-footer-min a { color: var(--rp-text-2); }
.rp-footer-min a:hover { color: var(--rp-accent); }

@media (max-width: 1023px) {
	.rp-hero { grid-template-columns: 1fr; }
	.rp-hero-title { font-size: var(--rp-fs-36); }
}
@media (max-width: 767px) {
	.rp-home-chips { padding-top: var(--rp-s4); }
	.rp-hero-ink { padding: var(--rp-s6); min-height: 240px; }
	.rp-hero-map { -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,.35) 0%, #000 55%); mask-image: linear-gradient(180deg, rgba(0,0,0,.35) 0%, #000 55%); }
	.rp-hero-title { font-size: var(--rp-fs-28); }
	.rp-hero-foot { flex-direction: column; align-items: flex-start; gap: var(--rp-s4); }
	.rp-hero-actions { flex-wrap: wrap; width: 100%; }
	.rp-hero-actions .rp-hero-btn { flex: 1 1 auto; padding: 0 16px; }
	.rp-hero-photo { min-height: 220px; }
	.rp-footer-min { padding-bottom: calc(28px + var(--rp-tabbar-h) + var(--rp-safe-b)); }
}

/* ---------- empty state (favorites with nothing saved) ---------- */
.rp-empty { display: flex; flex-direction: column; align-items: flex-start; gap: var(--rp-s4); padding: var(--rp-s6) 0 var(--rp-s10); color: var(--rp-text-2); }
.rp-empty .rp-i { color: var(--rp-text-3, #9CA3AF); }
.rp-empty p { margin: 0; font-size: var(--rp-fs-15); }

@media (max-width: 767px) {
  /* phones (design 08): no breadcrumbs on screen (kept in the DOM for crawlers) and the
     chips row starts right under the header — no dead space on top */
  /* [2026-09-03] …except on the property page (.pd-crumbs): there the trail is real navigation
     (country › city), not a link to the page itself, so it stays as one compact line */
  nav[aria-label="Breadcrumb navigation"]:not(.pd-crumbs) { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); padding: 0 !important; }
  .rp-main > .rp-container > .rp-scroll-x { padding-top: 14px; }
  /* page-head actions wrap instead of running off screen */
  .rp-page-head .rp-row { flex-wrap: wrap; }
  /* Favorites on phones (design 08 «Mobile Favorites»): compact rows — 100x84 photo,
     title / meta / price beside it, on a surface tile */
  .rp-fav-list .rp-grid-cards { gap: var(--rp-s3); }
  .rp-fav-list .rp-card { display: grid; grid-template-columns: 100px minmax(0, 1fr); gap: var(--rp-s3); padding: 8px; border-radius: 18px; background: var(--rp-surface); align-items: center; }
  .rp-fav-list .rp-card-media { aspect-ratio: 100 / 84; border-radius: 12px; }
  .rp-fav-list .rp-card-media .rp-slider-nav, .rp-fav-list .rp-card-media .rp-slider-dots, .rp-fav-list .rp-card-tags { display: none; }
  .rp-fav-list .rp-fav { width: 28px; height: 28px; top: 4px; right: 4px; }
  .rp-fav-list .rp-card-body { gap: 2px; min-width: 0; }
  .rp-fav-list .rp-card-title { font-size: var(--rp-fs-14); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .rp-fav-list .rp-card-meta { font-size: var(--rp-fs-12); }
  .rp-fav-list .rp-card-price { font-size: var(--rp-fs-14); }
  .rp-fav-list .rp-card-cta { display: none; }
}

/* [2026-09-08] Stars, thumbs and review blocks. Half steps are drawn with a clipped overlay so a
   4.5 looks like 4.5 and not like «about four» — the scale we store is the scale we show. */
.rp-stars { display: inline-flex; gap: 2px; vertical-align: -2px; }
.rp-star { width: 14px; height: 14px; display: inline-block; background: var(--rp-n300);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1z'/%3E%3C/svg%3E") center/contain no-repeat; }
.rp-star-full { background: var(--rp-accent); }
.rp-star-half { background: linear-gradient(90deg, var(--rp-accent) 50%, var(--rp-n300) 50%); }
/* [2026-09-09] The rating shares the facts' line instead of taking a third one. The row wraps only
   when it truly has to, and the rating then goes below rather than squeezing the facts. */
.rp-card-metarow { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px var(--rp-s2); min-width: 0; }
.rp-card-metarow .rp-card-meta { min-width: 0; }
/* [2026-09-09] It is a link now (to the listing's reviews), so it must not inherit link colour and
   must show it is pressable. Same size and weight as before — nothing on the card moves.
   One star, not five: the digits carry the value, the star only says what they are about. It keeps
   the accent — the only social proof on a card should not be grey — while the number stays ordinary
   text and the count is muted. */
.rp-rating-inline { display: inline-flex; align-items: center; gap: 3px; font-size: var(--rp-fs-13); font-weight: 700; color: var(--rp-text); width: fit-content; white-space: nowrap; flex: none; }
/* .rp-star paints itself with a mask and `background`, so the accent already comes from
   .rp-star-full above — a `color` rule here would have done nothing at all. */
.rp-rating-inline:hover { color: var(--rp-text); }
.rp-rating-inline:hover .rp-muted { color: var(--rp-text); text-decoration: underline; text-underline-offset: 2px; }
.rp-rating-inline .rp-muted { font-weight: 500; }

/* [2026-09-13] The date range picker (web/ui/calendar.js). It exists because a native date input
   cannot be drawn into, and the one thing we want to draw is which nights are known to be free.
   Everything else here is an ordinary calendar, deliberately: the marks are a decoration on a
   control that behaves the same on every listing, with data or without. */
/* [2026-09-13] fixed, and above the booking sheet: the sheet is position: fixed with z-index
   1002, so a panel at 60 in document coordinates opened behind it and in the wrong place. */
.rp-cal { position: fixed; z-index: 1100; background: var(--rp-bg, #fff); border: 1px solid var(--rp-border); border-radius: var(--rp-r-lg); box-shadow: var(--rp-sh-lg, 0 12px 32px rgba(0,0,0,.16)); padding: var(--rp-s4); width: max-content; max-width: calc(100vw - 16px); }
.rp-cal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--rp-s3); margin-bottom: var(--rp-s3); }
/* [2026-09-13] NOT text-transform: capitalize. Intl gives «октябрь 2026 г.», and capitalize
   raises EVERY word — the panel said «Октябрь 2026 Г.», with the abbreviation for «year» shouting.
   Only the first letter is ours to change. */
.rp-cal-title { font-weight: 700; font-size: var(--rp-fs-14); }
.rp-cal-title::first-letter { text-transform: uppercase; }
.rp-cal-nav { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--rp-border); background: none; color: var(--rp-text); font-size: 18px; line-height: 1; cursor: pointer; }
.rp-cal-months { display: flex; gap: var(--rp-s5); }
.rp-cal-week, .rp-cal-grid { display: grid; grid-template-columns: repeat(7, 36px); }
.rp-cal-week { margin-bottom: 4px; }
.rp-cal-week span { text-align: center; font-size: var(--rp-fs-12); color: var(--rp-text-2); font-weight: 600; }
.rp-cal-day { height: 36px; border: 0; background: none; color: var(--rp-text); font-size: var(--rp-fs-13); font-weight: 600; cursor: pointer; position: relative; padding: 0; }
.rp-cal-day span { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; margin: 0 auto; border-radius: 50%; }
.rp-cal-day[disabled], .rp-cal-day.is-out { color: var(--rp-text-3, #9CA3AF); cursor: default; }
/* [2026-09-13] TWO THINGS WRONG WITH ONE LINE. First, a touch screen has no hover: iOS leaves the
   state stuck on whatever was last tapped, so the day you just chose kept a pale grey circle.
   Second, and worse, `:not([disabled]):hover` outweighs `.is-edge` by specificity — so that stuck
   grey was painted OVER the black circle of the selected day, and the date you picked looked
   disabled. Hover belongs only to devices that have one, and the selected day keeps its colour even
   under the pointer. */
@media (hover: hover) {
	.rp-cal-day:not([disabled]):hover span { background: var(--rp-surface); }
	.rp-cal-day.is-edge:hover span { background: var(--rp-ink, #16181D); color: #fff; }
}
/* known free: a quiet dot, never a filled cell — it is information, not a selection */
/* [2026-09-13] A 4px dot under a number is not a signal, it is a speck — «как-то не очень явно»,
   and correctly so. A free night now reads as a free night: the day itself sits on a soft green
   ground with a green number, which is visible at a glance and still quieter than the black circle
   of the day you have chosen. The dot stays under it for anyone who cannot separate the greens. */
.rp-cal-day.is-free span { background: var(--rp-ok-soft, #E7F6EC); color: var(--rp-ok-text, #14733A); }
.rp-cal-day.is-free::after { content: ''; position: absolute; left: 50%; bottom: 1px; transform: translateX(-50%); width: 5px; height: 5px; border-radius: 50%; background: var(--rp-ok, #16A34A); }
.rp-cal-day.is-edge.is-free span { background: var(--rp-ink, #16181D); color: #fff; }
/* [2026-09-13] The bar has to be continuous. The selected ends are 32px circles inside a 46px
   cell, so a strip drawn only on the middle days stopped 7px short of each circle and read as
   three separate marks. The ends paint their own half of the cell, and only when both ends exist:
   a half-bar leading nowhere while the second date is still being chosen is worse than none. */
/* [2026-09-13] The band was --rp-surface, the page's own faint panel tint, and against white it
   read as nothing at all — a chosen stay has to be visible at a glance, from arm's length, on a
   phone in daylight. --rp-n200 is the same neutral family two steps darker, so the band is plainly
   a band while the two ends stay the only strong marks on the grid. */
.rp-cal-day.is-between { background: var(--rp-n200, #E4E7EC); }
.rp-cal-day.is-between span { background: none; color: var(--rp-text); }
.rp-cal-grid.is-range .rp-cal-day.is-start { background: linear-gradient(to right, transparent 50%, var(--rp-n200, #E4E7EC) 50%); }
.rp-cal-grid.is-range .rp-cal-day.is-end { background: linear-gradient(to left, transparent 50%, var(--rp-n200, #E4E7EC) 50%); }
.rp-cal-day.is-edge span { background: var(--rp-ink, #16181D); color: #fff; }
/* an edge is a handle: the browser must not start a scroll or a text selection where a drag begins (calendar.js) */
.rp-cal-day.is-edge { touch-action: none; }
.rp-cal-grid { user-select: none; -webkit-user-select: none; }
.rp-cal-day.is-edge.is-free::after { background: #fff; }
/* [2026-09-13] The edge the next tap will move. Without it, «pick up the check-in and put it
   somewhere else» is a rule the guest has to be told rather than one they can see. A ring around
   the filled circle, drawn in the panel's own background so it reads as a halo and not a second
   selected day. */
.rp-cal-day.is-edge.is-active span { box-shadow: 0 0 0 2px var(--rp-bg, #fff), 0 0 0 4px var(--rp-ink, #16181D); }
/* [2026-09-13] How long the range is, said where the range is chosen. Two dates and a silent gap
   left the guest counting nights on their fingers at the moment of deciding. It takes the footer
   rule, and the legend below it then does not draw a second hairline two lines away. */
.rp-cal-nights { margin-top: var(--rp-s3); padding-top: var(--rp-s3); border-top: 1px solid var(--rp-border); font-size: var(--rp-fs-13); font-weight: 700; color: var(--rp-text); font-variant-numeric: tabular-nums; }
.rp-cal-nights + .rp-cal-legend { margin-top: 0; padding-top: 4px; border-top: 0; }
.rp-cal-legend { display: flex; align-items: center; gap: 6px; margin-top: var(--rp-s3); padding-top: var(--rp-s3); border-top: 1px solid var(--rp-border); font-size: var(--rp-fs-12); color: var(--rp-text-2); }
.rp-cal-legend i { width: 6px; height: 6px; border-radius: 50%; background: var(--rp-ok, #16A34A); flex: none; }
/* [2026-09-13] A field we have taken over keeps the browser's own calendar button otherwise, and a
   click on that button opens the OS panel over ours — no listener on the input can prevent it,
   because the button is inside the input's shadow tree. Removing it is the only way. The field is
   still a real <input type="date">; only its private button is gone. */
input[data-rp-cal]::-webkit-calendar-picker-indicator { display: none; -webkit-appearance: none; }
input[data-rp-cal] { cursor: pointer; }
@media (max-width: 719px) {
  .rp-cal { left: 8px !important; right: 8px; width: auto; }
  /* [2026-09-13] .rp-cal-months is a flex row and a month had no grow, so it sized to its content:
     measured on a 375px screen the panel stretched to 359px while the grid inside stayed 224px,
     leaving a third of the panel empty and the days crammed to one side. 1fr columns cannot fill a
     container that is itself sized to content — the month has to be told to take the room. */
  .rp-cal-month { flex: 1 1 auto; min-width: 0; }
  .rp-cal-week, .rp-cal-grid { grid-template-columns: repeat(7, 1fr); }
  .rp-cal-day { height: 40px; }
}
