/* MojeUbytko.cz — Airbnb-inspired design system
   built on Bootstrap 5.3 primitives (grid, dropdown, offcanvas,
   accordion). This file supplies brand tokens and the custom
   components Bootstrap doesn't provide out of the box: property
   cards, the pill AI search bar, the mega-menu panel, and badges. */

:root {
  --brand: #003580;
  --brand-dark: #00265c;
  --brand-rgb: 0,53,128;
  --ink: #222222;
  --muted: #6b7280;
  --border: #e5e7eb;
  --surface: #ffffff;
  --bg: #ffffff;
  /* Subtle hover/loading-placeholder background and the light "active/
     selected" tint (2026-09-22, dark-mode work) — consolidated from what
     were ~18 separate hardcoded near-duplicate grays/blues scattered
     across this file, so both light AND dark now stay in sync from one
     definition each instead of needing every call site hand-tuned. */
  --surface-alt: #f4f4f6;
  --surface-tint: #eef3fa;
  --radius: 8px;
  /* Fallback only — includes/header.php/adm/_header.php/adm/index.php
     all echo render_site_font_head() right after this stylesheet loads,
     which overrides this same variable per the admin's font choice
     (adm/settings.php's Systém tab). This value only ever applies if
     that render call is somehow skipped. */
  --bs-body-font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Booking.com/MegaBooking-style flat, business-like corners everywhere —
   overriding Bootstrap's .rounded-pill utility globally is far cheaper
   than touching every button/badge/input across ~20 PHP templates that
   use it inline, and keeps future markup consistent for free. */
.rounded-pill { border-radius: var(--radius) !important; }
.form-control, .form-select { border-radius: var(--radius); }

body {
  font-family: var(--bs-body-font-family);
  color: var(--ink);
  background: var(--bg);
}

a { color: inherit; }

/* Self-hosted flag SVGs (see h() sibling flag_icon() in functions.php) —
   Windows browsers render Unicode flag emoji as plain two-letter text,
   not an actual flag image, so an <img> is used instead everywhere a
   country/language/currency flag appears. */
.flag-icon {
  width: 1.15em;
  height: 0.86em;
  vertical-align: -0.1em;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.08);
  object-fit: cover;
}

/* ---------- Top bar ---------- */
.topbar {
  background: #1a1a1a;
  color: rgba(255,255,255,.85);
  font-size: 13px;
  min-height: 36px;
  display: flex;
  align-items: center;
  position: relative;
  z-index: 1031;
}
/* Bootstrap's .sticky-top (used by the main navbar below) sets
   z-index:1020, which otherwise renders on top of and hides the topbar's
   opened language-switcher dropdown. */
.topbar .dropdown-menu { z-index: 1035; }
.topbar__tagline { color: rgba(255,255,255,.7); }
.topbar__lang {
  background: transparent;
  border: none;
  color: rgba(255,255,255,.9);
  font-size: 13px;
  font-weight: 600;
  padding: .3rem .5rem;
}
.topbar__lang:hover, .topbar__lang:focus { color: #fff; }
.topbar__support {
  color: rgba(255,255,255,.85);
  text-decoration: none;
  font-weight: 500;
  transition: color .15s ease;
}
.topbar__support:hover { color: #fff; }

/* ---------- Header ---------- */
.site-header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding-block: 1rem;
  transition: box-shadow .25s ease;
}
.site-header.scrolled {
  box-shadow: 0 4px 20px rgba(0,0,0,.06);
}

.brand-logo {
  font-weight: 800;
  font-size: 1.35rem;
  color: var(--ink) !important;
  letter-spacing: -0.02em;
  transition: opacity .15s ease;
}
.navbar-brand.brand-logo:hover { opacity: .85; }

/* Menu text stays plain system Arial, regular weight — no custom font,
   no bold — independent of the site's branded Plus Jakarta Sans type. */
.navbar-nav .nav-link,
.dropdown-item,
.mega-list a,
.mega-panel h6,
.accordion-button,
.topbar__tagline,
.topbar__lang,
.topbar__support {
  font-family: Arial, Helvetica, sans-serif !important;
  font-weight: 400 !important;
}

.navbar-nav .nav-link {
  position: relative;
  color: var(--ink);
  padding: .5rem .9rem;
  border-radius: var(--radius);
  transition: background-color .18s ease, color .18s ease;
}
.navbar-nav .nav-link:hover,
.navbar-nav .nav-link:focus {
  background-color: var(--surface-alt);
}
.navbar-nav .dropdown-toggle::after {
  margin-left: .4rem;
  vertical-align: .1em;
  transition: transform .2s ease;
}
.navbar-nav .dropdown-toggle[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

/* ---------- Elegant buttons (site-wide) ----------
   Every Bootstrap .btn gets the same refined treatment: a full pill
   shape, medium weight, a soft lift + tinted shadow on hover instead of
   a flat color swap, and no visible focus ring flash. Individual
   variants (outline-*, success, warning, danger, dark, link) only
   override color where Bootstrap's default would clash with this. */
.btn {
  border-radius: var(--radius);
  font-weight: 600;
  letter-spacing: .01em;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease, transform .12s ease, box-shadow .18s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:focus, .btn:focus-visible { box-shadow: 0 0 0 .2rem rgba(34,34,34,.12); }
.btn.btn-sm { font-weight: 600; }
.btn-link { text-decoration: none; font-weight: 600; }
.btn-link:hover { text-decoration: underline; transform: none; }

.btn-outline-secondary,
.btn-outline-dark {
  background: var(--surface);
}
.btn-outline-secondary:hover,
.btn-outline-dark:hover {
  box-shadow: 0 6px 16px rgba(0,0,0,.1);
}

.btn-success:hover { box-shadow: 0 6px 16px rgba(25,135,84,.28); }
.btn-warning:hover { box-shadow: 0 6px 16px rgba(255,193,7,.35); }
.btn-danger:hover { box-shadow: 0 6px 16px rgba(220,53,69,.28); }
.btn-dark:hover { box-shadow: 0 6px 16px rgba(0,0,0,.3); }

.btn-brand {
  background: var(--brand);
  color: #fff;
  border: none;
}
.btn-brand:hover,
.btn-brand:focus {
  background: var(--brand-dark);
  color: #fff;
  box-shadow: 0 6px 16px rgba(var(--brand-rgb),.28);
}

.lang-switch-btn, .user-chip {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-weight: 600;
  font-size: .85rem;
  padding: .45rem .9rem;
  background: var(--surface);
  color: var(--ink);
  transition: background-color .18s ease, border-color .18s ease;
}
.lang-switch-btn:hover, .user-chip:hover { background: var(--surface-alt); border-color: #d1d5db; }

.dropdown-item {
  transition: background-color .15s ease, color .15s ease, padding-left .15s ease;
}
.dropdown-item:hover { padding-left: 1.1rem; }
.dropdown-item.active, .dropdown-item:active {
  background-color: var(--surface-tint);
  color: var(--brand);
}

.season-badge {
  background: var(--brand);
  border-radius: var(--radius);
  color: #fff;
  font-weight: 700;
  padding: .5rem .9rem;
  font-size: .8rem;
  display: inline-flex;
  align-items: center;
  animation: seasonPulse 2.6s ease-in-out infinite;
}
@keyframes seasonPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--brand-rgb),.35); }
  50% { box-shadow: 0 0 0 6px rgba(var(--brand-rgb),0); }
}

/* Animated dropdown / mega-menu panels (Bootstrap toggles .show; we
   keep the element always laid out but fade+slide it in/out so the
   menu feels alive instead of snapping open). */
.dropdown-menu {
  display: block !important;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px) scale(.98);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
  pointer-events: none;
  transform-origin: top center;
}
.dropdown-menu.show {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

/* Destination country-tab switcher inside the mega-panel — panel
   footprint stays constant as more countries get listings; only the
   active country's regions/districts/cities render visible. Wraps to
   a second row (not horizontal scroll) if enough countries exist that
   they don't fit one line, so it degrades gracefully either way. */
.dest-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
}
.dest-tab {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  border: 1px solid #e5e7eb;
  background: var(--surface);
  border-radius: 999px;
  padding: .35rem .85rem;
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.dest-tab:hover { border-color: var(--brand); color: var(--brand); }
.dest-tab.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.dest-panel { display: none; }
.dest-panel.active { display: block; }

/* "Filtre" mega-panel (2026-09-20) — reuses .dest-tabs/.dest-tab/
   .dest-panel wholesale (same JS click handler in main.js already
   works generically off those classes, no JS changes needed) but each
   panel holds a wrapping chip grid instead of destination columns,
   since a group can have 8-14 flat tags with no sub-hierarchy to
   column-split. Wider than the default .mega-panel so ~14 chips per
   row don't force an awkwardly tall, narrow panel. */
.mega-panel--filters { min-width: 720px; max-width: 820px; }
.filter-tag-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.filter-tag-chip {
  display: inline-block;
  border: 1px solid #e5e7eb;
  border-radius: 999px;
  padding: .4rem 1rem;
  font-size: .85rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.filter-tag-chip:hover { background: var(--brand); border-color: var(--brand); color: #fff; }

/* Mega-menu dropdown panel. Widened + nowrap so longer destination
   names (e.g. "Lednicko-valtický areál") never wrap onto a second
   line inside the col-6 country columns — found live: at the old
   480px min-width they did. */
.mega-panel {
  min-width: 640px;
}

/* Destination lists widened to show 16 per country (2026-09-21) — a
   single 16-row vertical list would make the panel oddly tall, so a
   section with more than 8 rows splits into 2 sub-columns (8+8) via
   CSS Grid with `max-content` column tracks: each sub-column sizes to
   its own widest row's real text width, so nothing ever wraps.
   Three approaches were tried and rejected live, in order: CSS
   multi-column (`column-count:2`) let a long row's own text overflow
   into the next column since its track width is an even split of the
   container, not sized to its own content; allowing `white-space:
   normal` to wrap instead avoided the overlap but produced visibly
   wrapped text; making the 3 sections themselves `flex-wrap`/auto-width
   (so the whole panel would grow to fit) instead made Chrome's
   shrink-to-fit sizing collapse the panel back to its bare min-width
   floor — a flex container with wrapping children doesn't reliably
   report its full preferred width to an ancestor computing shrink-to-
   fit — which then forced all 3 sections to stack vertically instead
   of sitting side by side, the opposite of what was asked for. Final
   fix: the panel is a normal fixed-width box again (like before this
   whole feature), sections never wrap (`flex-wrap: nowrap`), and if
   16-per-section content is ever wider than the panel, the sections
   row itself scrolls horizontally rather than wrapping or forcing the
   panel wider than the viewport. */
/* Centered horizontally on the page (2026-09-21, revised from an
   earlier flush-left-at-the-logo version) rather than anchored to its
   own toggle — still earns enough width to show 16 destinations per
   section without the horizontal scroll fallback kicking in, without
   needing to start right at the page's own left edge. `left: 50%` +
   `translateX(-50%)` centers it regardless of its own actual rendered
   width, so no JS measurement of the box itself is needed — only
   `top`/`max-width` still need computing against the real header
   height/viewport width (main.js), since those genuinely vary.
   `data-bs-display="static"` on the toggle (header.php) turns off
   Bootstrap's own Popper-driven positioning; `position`/`left`/
   `transform` are additionally set inline by main.js (not just here)
   since Bootstrap's `.dropdown-menu[data-bs-popper]` rule has higher
   specificity than a plain class and was silently overriding this
   class's own `position: fixed` — inline styles beat any CSS rule
   regardless of specificity, which is what actually makes it stick. */
.mega-panel--destinations {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  top: 90px;
  min-width: 920px;
  max-width: min(96vw, 1300px);
}
.mega-dest-sections {
  align-items: flex-start;
  flex-wrap: nowrap;
  overflow-x: auto;
}
.mega-dest-section { flex: 0 0 auto; }
/* A default overlay scrollbar is invisible until actively scrolling —
   made permanently visible (thin, subtle) so a visitor actually
   notices there's more to see, instead of discovering it by accident. */
.mega-dest-sections { scrollbar-width: thin; }
.mega-dest-sections::-webkit-scrollbar { height: 6px; }
.mega-dest-sections::-webkit-scrollbar-track { background: transparent; }
.mega-dest-sections::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 999px; }
.mega-list--cols {
  display: grid;
  grid-template-columns: repeat(2, max-content);
  grid-template-rows: repeat(var(--mega-rows, 1), auto);
  grid-auto-flow: column;
  column-gap: 1.75rem;
}
.mega-list li { margin-bottom: .55rem; }
.mega-list a {
  text-decoration: none;
  color: var(--ink);
  font-weight: 500;
  font-size: .92rem;
  transition: color .15s ease, padding-left .15s ease;
  display: inline-block;
  white-space: nowrap;
}
.mega-list a:hover { color: var(--brand); padding-left: .25rem; }

/* "Zobraziť všetky..." link under each mega-panel section (2026-09-20) —
   deliberately always present, not conditionally shown only once the
   real list actually exceeds what's displayed, so the menu never needs
   touching again as regions/districts/cities keep getting real listings. */
.mega-list__see-all {
  display: inline-block;
  font-size: .82rem;
  font-weight: 600;
  color: var(--brand);
  text-decoration: none;
}
.mega-list__see-all:hover { text-decoration: underline; }

/* Region hover flyout — shows which property-type categories have
   listings in that destination (e.g. "Liptov" -> "Chaty (3)"). Opens
   to the RIGHT of the link (not below it) — `width: max-content` on
   the `<li>` shrinks its box to the link's own text so `left: 100%`
   lands right next to the label instead of at the far edge of the
   (much wider) column. Shown via a JS-added `.show` class (main.js,
   same delayed mouseenter/mouseleave pattern as the top-level
   dropdowns) rather than plain CSS :hover alone — a pure-CSS flyout
   has a dead zone between the trigger and the flyout, and crossing
   that gap was enough to hide it before the cursor arrived. `:hover`
   stays too as a no-JS fallback. */
.mega-list__item { position: relative; width: max-content; max-width: 100%; }
.region-flyout {
  display: none;
  position: absolute;
  left: 100%;
  top: 50%;
  margin-left: .5rem;
  background: var(--surface);
  border-radius: .75rem;
  box-shadow: 0 10px 30px rgba(0,0,0,.14);
  padding: .5rem;
  min-width: 170px;
  opacity: 0;
  visibility: hidden;
  transform: translate(-4px, -50%);
  /* A snappier "ease-out" curve on the transform reads more like a real
     app's flyout/tooltip than a plain linear/ease slide (2026-09-21) —
     the JS-driven open (main.js) computes its own viewport-clamped
     top/left/transform inline, so this transition is what actually
     animates between the pre- and post-open values it sets. */
  transition: opacity .18s ease, transform .22s cubic-bezier(.16, 1, .3, 1), visibility .18s;
  pointer-events: none;
  z-index: 20;
}
/* `display: none` (not just opacity/visibility) when closed, added
   2026-09-21: a flyout for an item near the BOTTOM of its 8-row column
   extends well past `.mega-dest-sections`'s own bottom edge even while
   fully invisible — an opacity/visibility-hidden box still occupies
   its absolutely-positioned layout space and was silently inflating
   the row's own `scrollHeight`, which (since that row now needs
   `overflow-x: auto`, forcing overflow-y to clip/scroll too) showed an
   unwanted, unnecessary vertical scrollbar even though no visible
   content actually needed one. `display: none` removes it from layout
   entirely while closed, so it can no longer inflate anything. */
.mega-list__item:hover .region-flyout,
.mega-list__item.show .region-flyout {
  display: block;
  opacity: 1;
  visibility: visible;
  transform: translate(0, -50%);
  pointer-events: auto;
}
/* Once `.mega-dest-sections` needs `overflow-x: auto` (2026-09-21, so
   16 destinations per section can scroll instead of wrapping the whole
   row), the browser is forced to also clip vertically — overflow-x and
   overflow-y can't independently be scroll/visible, only one or the
   other computed for both once either isn't `visible`. That silently
   clipped this flyout whenever it extended above the row's own top
   edge (any item in roughly the first 2 rows). Fixed in main.js by
   reparenting the flyout to <body> with JS-computed `position: fixed`
   the moment it opens — no longer a descendant of the clipping
   container at all — so this class (not the ancestor-dependent
   `.show`/`:hover` selectors above, which stop matching the instant
   it's moved) is what actually shows it while reparented; z-index
   raised well past Bootstrap's own dropdown (1000) since the flyout
   now sits in its own top-level stacking context on <body>. */
.region-flyout--open {
  display: block;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  z-index: 1060;
}
.region-flyout__item {
  display: block;
  text-decoration: none;
  color: var(--ink);
  font-size: .84rem;
  font-weight: 500;
  white-space: nowrap;
  padding: .3rem .5rem;
  border-radius: .5rem;
  transition: background .12s ease;
}
.region-flyout__item:hover { background: var(--surface-alt); color: var(--brand); }

/* "Typ ubytovania" mega-menu hover flyout (2026-09-21) — same visual
   shape and reparent-to-<body> JS mechanism as .region-flyout above
   (shared function, main.js), kept as its own separate set of classes
   rather than refactored to share CSS rules with an already-recently-
   stabilized feature (History #109/#111 both fixed real regressions in
   the region-flyout's own CSS) — duplicating a small, proven-working
   shape here carries far less regression risk than merging it. Only
   real difference: the city list itself scrolls (`max-height` +
   `overflow-y: auto`) since a type can have far more matching cities
   than fit in one screen's height, per the user's own explicit ask. */
.type-flyout-item { position: relative; }
.type-flyout-item__chevron { font-size: .68rem; color: var(--muted); margin-left: .75rem; flex-shrink: 0; }
.type-city-flyout {
  display: none;
  position: absolute;
  left: 100%;
  top: 0;
  margin-left: .5rem;
  background: var(--surface);
  border-radius: .75rem;
  box-shadow: 0 10px 30px rgba(0,0,0,.14);
  padding: .5rem;
  min-width: 220px;
  opacity: 0;
  visibility: hidden;
  transform: translateX(-4px);
  transition: opacity .18s ease, transform .22s cubic-bezier(.16, 1, .3, 1), visibility .18s;
  pointer-events: none;
  z-index: 20;
}
.type-flyout-item:hover .type-city-flyout,
.type-flyout-item.show .type-city-flyout {
  display: block;
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
  pointer-events: auto;
}
.type-city-flyout--open {
  display: block;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  z-index: 1060;
}
/* Only the country matching the visitor's current Destinácie tab
   selection is ever shown (main.js toggles `.active` right before the
   flyout opens) — everything else stays `display:none` so an unrelated
   country's cities never flash into view even for a frame. */
.type-city-flyout__country { display: none; }
.type-city-flyout__country.active { display: block; }
.type-city-flyout__scroll {
  /* 320px is only the no-JS/no-hover CSS-`:hover` fallback ceiling — on a
     real hover-capable device, initHoverFlyout() overrides this inline
     with a viewport-derived max-height (2026-09-21, user's own explicit
     ask for "as tall as possible, only scrolls once genuinely needed"). */
  max-height: 320px;
  overflow-y: auto;
  padding-right: .25rem;
}
.type-city-flyout__item {
  display: block;
  text-decoration: none;
  color: var(--ink);
  font-size: .84rem;
  font-weight: 500;
  white-space: nowrap;
  padding: .3rem .5rem;
  border-radius: .5rem;
  transition: background .12s ease;
}
.type-city-flyout__item:hover { background: var(--surface-alt); color: var(--brand); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  background-image:
    linear-gradient(180deg, rgba(0,20,50,.72), rgba(0,10,28,.68)),
    url('https://images.unsplash.com/photo-1506905925346-21bda4d32df4?auto=format&fit=crop&w=1920&q=80');
  background-size: cover;
  background-position: center;
  color: #fff;
  padding: 45px 20px 30px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  overflow: hidden;
  transition: padding .25s ease;
}

/* Shown once a search/category filter is active, so results sit closer
   to the top of the page instead of forcing a long scroll past the hero. */
.hero--compact {
  padding: 32px 20px;
}
.hero--compact h1 { font-size: clamp(1.3rem, 2.4vw, 1.9rem); }
.hero--compact .subtitle { font-size: .92rem; }
.hero--compact .ai-search-hint { margin-top: .3rem; }

.hero h1 {
  font-size: clamp(1.6rem, 3.2vw, 2.5rem);
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1.15;
  text-transform: uppercase;
  text-shadow: 0 2px 12px rgba(0,0,0,0.35);
  margin: 0;
}

.hero p.subtitle {
  color: rgba(255,255,255,0.65);
  margin-top: 0.5rem;
  margin-bottom: 0;
  font-size: .95rem;
  font-weight: 400;
  line-height: 1.3;
}

.ai-search-wrap {
  position: relative;
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  /* .hero is a column flex container; auto cross-axis margins make a flex
     item shrink-to-content instead of stretching, which silently defeated
     max-width above. Explicit width:100% forces the stretch, then
     max-width clamps it (same pattern Bootstrap's .container uses). */
  align-self: center;
}

.live-search-results {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  background: var(--surface);
  border-radius: 1.25rem;
  box-shadow: 0 16px 40px rgba(0,0,0,.25);
  padding: .5rem;
  text-align: left;
  z-index: 20;
  max-height: 360px;
  overflow-y: auto;
}
.live-search-results__item {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .5rem .6rem;
  border-radius: .85rem;
  text-decoration: none;
  color: var(--ink);
  transition: background-color .15s ease;
}
.live-search-results__item:hover { background: var(--surface-alt); }
.live-search-results__item img {
  width: 3rem;
  height: 3rem;
  border-radius: .65rem;
  object-fit: cover;
  flex-shrink: 0;
}
.live-search-results__title { font-weight: 700; font-size: .88rem; }
.live-search-results__meta { font-size: .78rem; color: var(--muted); }
.live-search-results__loading,
.live-search-results__empty {
  padding: .75rem;
  text-align: center;
  font-size: .85rem;
  color: var(--muted);
}
.live-search-results__viewall {
  display: block;
  text-align: center;
  padding: .6rem;
  margin-top: .25rem;
  border-top: 1px solid var(--border);
  font-weight: 600;
  font-size: .85rem;
  color: var(--brand);
  text-decoration: none;
}

/* Structured, segmented search panel (Booking.com-style: Location / Type
   / Dates / Search as distinct fields in one bar) instead of a single
   pill input — reads as a serious booking tool rather than a chat box. */
.search-panel {
  max-width: 980px;
  margin: 1.1rem auto 0;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgba(0,0,0,.22);
  display: flex;
  align-items: stretch;
  overflow: hidden;
  text-align: left;
}
.search-panel__field {
  flex: 1 1 0;
  min-width: 0;
  padding: .55rem 1.1rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.search-panel__field label {
  font-size: .66rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  font-weight: 700;
  color: var(--muted);
  margin-bottom: .1rem;
}
.search-panel__field input,
.search-panel__field select {
  border: none;
  outline: none;
  background: transparent;
  padding: 0;
  font-size: .93rem;
  font-weight: 500;
  color: var(--ink);
  width: 100%;
  appearance: none;
}
/* The field itself has no visible border to move outline:none's focus
   indication onto, so the visible focus ring (WCAG 2.4.7) goes on the
   parent field wrapper instead when a keyboard user tabs into it. */
.search-panel__field:focus-within {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius);
}
.search-panel__field input::placeholder {
  color: var(--muted);
  font-weight: 400;
  opacity: .75;
}
.search-panel__field--type { flex: 0 1 190px; }
.search-panel__field--dates { flex: 0 1 150px; }
.search-panel__divider { width: 1px; background: var(--border); margin: .6rem 0; flex-shrink: 0; }
.search-panel__submit {
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  border: none;
  padding: 0 1.85rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background-color .15s ease;
}
.search-panel__submit:hover { background: var(--brand-dark); }
.search-panel__submit:disabled { opacity: .6; cursor: not-allowed; }

@media (max-width: 767.98px) {
  .search-panel { flex-direction: column; }
  .search-panel__divider { display: none; }
  .search-panel__field,
  .search-panel__field--type,
  .search-panel__field--dates { flex: 1 1 auto; border-bottom: 1px solid var(--border); }
  .search-panel__submit { padding: .9rem; }
}

/* ---------- Full-width "all listings" map (homepage, above the footer) ---------- */
.all-listings-map { width: 100%; }
.all-listings-map #allListingsMap {
  width: 100%;
  height: 266px; /* matches #heroSection's own rendered height, so the two sit at equal visual weight */
}
/* footer.php uses .mt-5 for spacing after regular page content, but
   right after this edge-to-edge map that reads as an unwanted gap.
   General sibling (~) because the map's own <link>/<script> tags sit
   between the section and the footer in the DOM. */
.all-listings-map ~ .site-footer { margin-top: 0 !important; }
.listings-map-popup {
  display: block;
  width: 180px;
  text-decoration: none;
  color: var(--ink);
}
.listings-map-popup img {
  width: 100%;
  height: 100px;
  object-fit: cover;
  border-radius: var(--radius);
  margin-bottom: .4rem;
}
.listings-map-popup__title {
  font-weight: 700;
  font-size: .85rem;
  line-height: 1.25;
  margin-bottom: .15rem;
}
.listings-map-popup__price {
  font-size: .8rem;
  font-weight: 600;
  color: var(--brand);
}
.leaflet-popup-content { margin: .6rem; }

/* ---------- Availability calendar (property.php) ---------- */
.avail-cal { min-width: 0; }
.avail-cal__header { font-weight: 700; font-size: .9rem; text-align: center; margin-bottom: .5rem; }
.pubcal-months { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.5rem; }
@media (max-width: 991.98px) {
  .pubcal-months { grid-template-columns: repeat(2, 1fr); }
  .pubcal-months .avail-cal:nth-child(3) { display: none; }
}
@media (max-width: 575.98px) {
  .pubcal-months { grid-template-columns: 1fr; }
  .pubcal-months .avail-cal:nth-child(2) { display: none; }
}
.avail-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.avail-cal__dow { font-size: .7rem; color: var(--muted); text-align: center; font-weight: 700; padding-bottom: .2rem; }
.avail-cal__day {
  aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem; border-radius: .4rem;
}
.avail-cal__day--free { background: #eef7ee; color: #1a5c1a; }
.avail-cal__day--busy { background: #fbe9e9; color: #a33; text-decoration: line-through; }
.avail-cal__day--empty { background: transparent; }
.avail-cal__legend { display: inline-block; width: .7rem; height: .7rem; border-radius: .2rem; margin-right: .25rem; vertical-align: middle; }
.avail-cal__legend--free { background: #eef7ee; border: 1px solid #1a5c1a; }
.avail-cal__legend--busy { background: #fbe9e9; border: 1px solid #a33; }

/* Public property.php guest calendar, bar style — no channel/guest
   detail (that's the host-only .ccal-* calendar below), just a single
   neutral "obsadené" color spanning check-in to check-out. */
.pubcal-dow { display: grid; grid-template-columns: repeat(7, 1fr); font-size: .68rem; color: var(--muted); text-align: center; font-weight: 700; padding-bottom: .2rem; }
.pubcal-week { display: grid; grid-template-columns: repeat(7, 1fr); position: relative; row-gap: 1px; margin-bottom: 1px; }
.pubcal-day { font-size: .74rem; text-align: center; padding: .1rem 0; color: var(--ink); }
.pubcal-day--muted { color: #c7ccd1; }
.pubcal-bar { border-radius: .25rem; background: #fbe9e9; color: #a33; font-size: .62rem; padding: 0 .3rem; height: 12px; display: flex; align-items: center; overflow: hidden; white-space: nowrap; margin-top: 1px; }

/* Host/admin channel-manager calendar (host/property-manage.php) */
.ccal-legend { display: flex; gap: 1rem; flex-wrap: wrap; }
.ccal-legend span { display: flex; align-items: center; gap: .3rem; }
.ccal-legend__dot { width: .6rem; height: .6rem; border-radius: 50%; flex-shrink: 0; display: inline-block; }
.ccal-dow { display: grid; grid-template-columns: repeat(7, 1fr); font-size: .72rem; color: var(--muted); text-align: center; font-weight: 700; padding-bottom: .3rem; }
.ccal-week { display: grid; grid-template-columns: repeat(7, 1fr); column-gap: 2px; row-gap: 2px; border-bottom: 1px solid var(--border); padding-bottom: 4px; margin-bottom: 4px; }
.ccal-day {
  font-size: .78rem;
  text-align: center;
  padding: .2rem 0;
  cursor: pointer;
  border-radius: .3rem;
}
.ccal-day:hover { background: var(--surface-tint); }
.ccal-day--muted { color: #c7ccd1; }
.ccal-bar {
  border-radius: .3rem;
  font-size: .68rem;
  font-weight: 600;
  padding: 0 .35rem;
  display: flex;
  align-items: center;
  overflow: hidden;
  white-space: nowrap;
  cursor: pointer;
}
.ccal-list__item {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .5rem .25rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}

/* ---------- Maps (Leaflet/OpenStreetMap — add/edit form picker + property page) ---------- */
.map-picker {
  height: 280px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  overflow: hidden;
}
.property-map {
  height: 320px;
  border-radius: var(--radius);
  overflow: hidden;
}
.nearby-attraction {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .55rem .75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.nearby-attraction__name { font-weight: 600; font-size: .88rem; }
.nearby-attraction__category { font-size: .75rem; color: var(--muted); text-transform: capitalize; }
.nearby-attraction__distance { font-size: .8rem; font-weight: 700; color: var(--brand); white-space: nowrap; }

/* ---------- Left sidebar filter panel ---------- */
.filter-sidebar { position: sticky; top: 1rem; }
.filter-group:not(:last-child) {
  border-bottom: 1px solid var(--border);
  padding-bottom: 1rem;
}
.filter-amenities__list .form-check { margin-bottom: .3rem; }

/* AJAX filter loading state (2026-09-21: real content now fades OUT to
   skeleton rows, then skeleton fades OUT to real content, rather than
   just dimming the old results in place — see main.js's fadeSwapPane()/
   buildSkeletonList()) — the transition lives on the pane itself since
   both fades toggle the same inline opacity style; .is-loading only
   blocks interaction while either fade/fetch is in flight. */
#resultsPane {
  transition: opacity .15s ease;
}
#resultsPane.is-loading {
  pointer-events: none;
}

/* ---------- Trust strip (homepage, below hero) ---------- */
.trust-strip { background: var(--surface); }
.trust-strip__heading {
  text-align: center;
  font-style: italic;
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--ink);
  margin-bottom: 1rem;
}
.trust-strip__icon {
  font-size: 1.4rem;
  color: var(--brand);
  margin-bottom: .4rem;
  display: inline-block;
}
.trust-strip__title {
  font-size: .92rem;
  font-weight: 700;
  margin-bottom: .2rem;
}
.trust-strip__desc {
  font-size: .82rem;
  color: var(--muted);
  margin-bottom: 0;
  line-height: 1.3;
}

.ai-search-hint {
  margin-top: 0.4rem;
  margin-left: auto;
  margin-right: auto;
  font-size: 0.78rem;
  font-weight: 400;
  color: rgba(255,255,255,0.55);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: .4rem;
  text-align: center;
}
.ai-search-hint .badge {
  background: rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.7);
  backdrop-filter: blur(6px);
  font-weight: 700;
  letter-spacing: .03em;
}

/* ---------- Property cards: cards separated by shadow alone (no
   border) — the clean look of Airbnb/Booking-style professional
   portals against the site's all-white canvas (--bg above), rather
   than a bordered-tile look. ---------- */
.property-card {
  background: var(--surface);
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 2px 8px rgba(0,0,0,0.05);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.property-card:hover {
  box-shadow: 0 4px 10px rgba(0,0,0,0.06), 0 16px 32px rgba(0,0,0,0.12);
  transform: translateY(-3px);
}

.property-card__image-wrap {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--surface-alt);
}
.property-card__image-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .3s ease;
}
.property-card:hover .property-card__image-wrap img {
  transform: scale(1.04);
}

.badge-onimage {
  position: absolute;
  top: .75rem;
  font-size: .72rem;
  font-weight: 700;
  padding: .35rem .65rem;
  border-radius: var(--radius);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.badge-type {
  left: .75rem;
  background: rgba(255,255,255,0.75);
  color: var(--ink);
  letter-spacing: 0.03em;
}
.badge-capacity {
  right: .75rem;
  background: rgba(0,0,0,0.45);
  color: #fff;
}
.badge-top {
  left: .75rem;
  top: auto;
  bottom: .75rem;
  background: #b8860b;
  color: #fff;
  font-weight: 800;
  letter-spacing: 0.04em;
}
/* TOP and "Overený partner" can both be true for one listing — stacked
   in one bottom-left column instead of two independently absolutely-
   positioned badges fighting over the same corner. */
.badge-onimage-stack { position: absolute; left: .75rem; bottom: .75rem; display: flex; flex-direction: column; align-items: flex-start; gap: .35rem; }
.badge-onimage-stack .badge-onimage { position: static; }
.badge-verified {
  background: #0d6efd;
  color: #fff;
  font-weight: 800;
  letter-spacing: 0.02em;
}

/* Favorite/compare/share icon cluster — bottom-right of the image is the
   one corner .badge-onimage doesn't already use (type top-left, capacity
   top-right, TOP badge bottom-left when promoted). */
.card-actions {
  position: absolute;
  right: .75rem;
  bottom: .75rem;
  display: flex;
  gap: .4rem;
  z-index: 2;
}
.card-action-btn {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  font-size: .95rem;
  transition: transform .15s ease, background-color .15s ease, color .15s ease;
}
.card-action-btn:hover { transform: scale(1.08); background: #fff; }
.card-action-btn--active { color: #e0245e; }
.card-action-btn--active .bi-heart::before { content: "\f415"; } /* bi-heart-fill */
.card-action-btn--copied { color: var(--brand); }

/* Sticky compare bar — global (includes/footer.php), builds up as the
   visitor adds items across different pages/category browses, not just
   within one page's card grid. */
.compare-bar {
  position: fixed;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  z-index: 1040;
  background: var(--ink);
  color: #fff;
  border-radius: 999px;
  padding: .6rem .6rem .6rem 1.1rem;
  display: flex;
  align-items: center;
  gap: .75rem;
  box-shadow: 0 10px 30px rgba(0,0,0,.25);
  max-width: calc(100vw - 2rem);
}
.compare-bar__count { font-weight: 700; }
.compare-bar__hint { font-size: .8rem; opacity: .75; }
.compare-bar:not(.compare-bar--ready) .compare-bar__go { opacity: .5; pointer-events: none; }
/* Reserves space for the fixed compare bar so it never floats on top of
   real content on a short page (e.g. compare.php with just 1-2 rows). */
body.has-compare-bar { padding-bottom: 4.5rem; }

/* GDPR cookie consent banner — z-index above the compare bar since it is
   a legal-consent gate, not a passive convenience widget. */
.cookie-banner {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1055;
  background: var(--surface);
  border-top: 1px solid var(--border);
  box-shadow: 0 -4px 20px rgba(0,0,0,.1);
  padding: 1rem 1.25rem;
  padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
}
.cookie-banner__inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  justify-content: space-between;
}
.cookie-banner__text { flex: 1 1 320px; font-size: .875rem; color: var(--ink); margin: 0; }
.cookie-banner__actions { display: flex; flex-wrap: wrap; gap: .5rem; }
@media (max-width: 575.98px) {
  .cookie-banner__actions { width: 100%; }
  .cookie-banner__actions .btn { flex: 1 1 auto; }
}
/* While the banner is showing, push every other fixed bottom-corner
   widget (chat bubble, compare bar) up above it — otherwise the banner's
   full-width div (it needs a solid background, so it can't just have a
   transparent cutout) sits on top of and intercepts clicks on whatever
   was already anchored to that corner. Generous, not measured, offsets:
   the banner's own height varies with viewport width/translated text
   length, and being a little too generous costs nothing visually. */
body.has-cookie-banner .chat-widget,
body.has-cookie-banner .compare-bar,
body.has-cookie-banner .inspector-toggle { bottom: 6.5rem; }
@media (max-width: 575.98px) {
  body.has-cookie-banner .chat-widget,
  body.has-cookie-banner .compare-bar,
  body.has-cookie-banner .inspector-toggle { bottom: 10rem; }
}

/* Real bug found live (2026-09-22, dark-mode toggle verification): the
   mobile off-canvas drawer's own theme-toggle row sits at the same fixed
   screen position as the chat bubble, which visually/functionally sat ON
   TOP of it — a tap meant for the switch opened the chat widget instead.
   Hiding the bubble entirely while any off-canvas menu is open (same
   "hide the floating widget rather than patch around it" choice already
   made for the cookie banner above) is simpler and more robust than
   repositioning one specific row, and correctly covers any future
   off-canvas content too, not just this one row. */
body:has(.offcanvas.show) .chat-widget { display: none; }

/* Skip-to-content link (WCAG 2.4.1) — visually hidden until focused via
   keyboard, so it never affects sighted mouse users' layout. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 2000;
  background: var(--brand);
  color: #fff;
  padding: .75rem 1.25rem;
  border-radius: 0 0 var(--radius) 0;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* Notification Center bell dropdown (assets/js/notifications.js) —
   shared markup/classes for both the public header's desktop dropdown
   and the admin panel's own bell. */
.notif-item {
  display: flex; align-items: flex-start; gap: .65rem;
  padding: .65rem .9rem; text-decoration: none; color: inherit;
  border-bottom: 1px solid var(--border);
}
.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background: var(--surface-alt); }
.notif-item--unread { background: rgba(var(--brand-rgb), .04); }
.notif-item__icon {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(var(--brand-rgb), .1); color: var(--brand); font-size: .9rem;
}
.notif-item__body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.notif-item__title { font-weight: 600; font-size: .84rem; color: var(--ink); }
.notif-item__message {
  font-size: .78rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.notif-item__time { font-size: .72rem; color: var(--muted); margin-top: .15rem; }
.notif-item__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand); flex-shrink: 0; margin-top: .3rem; }

.property-card__body {
  padding: 1rem 1.15rem 1.15rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.property-card__title {
  font-weight: 700;
  font-size: 1.05rem;
  margin-bottom: 0.25rem;
  color: var(--ink);
}
.property-card__title a {
  color: inherit;
  text-decoration: none;
}
.property-card__title a:hover {
  text-decoration: underline;
}

.property-card__location {
  color: var(--muted);
  font-size: 0.9rem;
  margin-bottom: 0.5rem;
}

/* OMNIBUS-directive disclosure (private individual vs. business host) */
.property-card__owner-type {
  font-size: 0.75rem;
  margin-bottom: 0.4rem;
}
.listing-row__specs .bi-person,
.listing-row__specs .bi-briefcase { margin-left: .25rem; }

.property-card__excerpt {
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.35;
  margin-bottom: 0.6rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.property-card__price {
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 0.75rem;
  margin-top: auto;
  padding-top: 0.5rem;
}
.property-card__price span {
  font-weight: 400;
  color: var(--muted);
  font-size: 0.85rem;
}

/* Gated-contacts placeholder on property.php — a generic masked string,
   never the real number (that never reaches the page source pre-unlock),
   blurred purely so the "locked" state reads as a phone number shape. */
.contact-blur {
  filter: blur(4px);
  user-select: none;
  pointer-events: none;
  letter-spacing: 1px;
  font-weight: 600;
  color: var(--muted);
  text-align: center;
  padding: 0.5rem 0;
}

.btn-outline-full {
  display: block;
  width: 100%;
  text-align: center;
  border: 1px solid var(--ink);
  color: var(--ink);
  font-weight: 600;
  font-size: 0.82rem;
  padding: 0.4rem 1rem;
  border-radius: .75rem;
  transition: background-color 0.15s ease, color 0.15s ease;
  text-decoration: none;
}
.btn-outline-full:hover {
  background: var(--ink);
  color: #fff;
}

/* ---------- Horizontal listing row (search/category/destination pages
   — the homepage keeps its .property-card grid above, unchanged) ---------- */
.listing-row-list {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.listing-row {
  display: flex;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: box-shadow .2s ease, transform .2s ease;
}
.listing-row:hover {
  box-shadow: 0 4px 10px rgba(0,0,0,0.06), 0 16px 32px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}
.listing-row__gallery {
  position: relative;
  flex: 0 0 300px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface-alt);
}
.listing-row__gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.listing-row__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,.85);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  opacity: 0;
  transition: opacity .15s ease, background-color .15s ease;
  z-index: 2;
}
.listing-row__gallery:hover .listing-row__nav { opacity: 1; }
.listing-row__nav:hover { background: #fff; }
.listing-row__nav--prev { left: .5rem; }
.listing-row__nav--next { right: .5rem; }
.listing-row__dots {
  position: absolute;
  bottom: .6rem;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: .3rem;
  z-index: 2;
}
.listing-row__dot {
  width: .35rem;
  height: .35rem;
  border-radius: 50%;
  background: rgba(255,255,255,.6);
}
.listing-row__dot.active { background: #fff; }

.listing-row__body {
  flex: 1 1 auto;
  display: flex;
  padding: 1.1rem 1.3rem;
  gap: 1rem;
  min-width: 0;
}
.listing-row__main { flex: 1 1 auto; min-width: 0; }
.listing-row__title {
  font-size: 1.15rem;
  font-weight: 800;
  margin-bottom: .25rem;
}
.listing-row__title a { color: var(--ink); text-decoration: none; }
.listing-row__title a:hover { color: var(--brand); }
.listing-row__location {
  font-size: .85rem;
  color: var(--muted);
  margin-bottom: .6rem;
}
.listing-row__specs {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  font-size: .82rem;
  color: var(--ink);
  margin-bottom: .6rem;
}
.listing-row__specs span { display: inline-flex; align-items: center; gap: .3rem; }
.listing-row__specs i { color: var(--muted); }
.listing-row__excerpt {
  font-size: .82rem;
  color: var(--muted);
  margin-bottom: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.listing-row__side {
  flex: 0 0 190px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: space-between;
  text-align: right;
  gap: .5rem;
}
.listing-row__rating {
  display: flex;
  align-items: baseline;
  gap: .35rem;
  justify-content: flex-end;
}
.listing-row__rating-word { font-size: .82rem; font-weight: 600; color: var(--ink); }
.listing-row__rating-score {
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  font-size: .85rem;
  padding: .15rem .5rem;
  border-radius: .4rem;
}
.listing-row__price { line-height: 1.25; }
.listing-row__price strong { font-size: 1.25rem; color: var(--ink); }
.listing-row__cta {
  width: 100%;
  font-weight: 700;
  white-space: nowrap;
}

@media (max-width: 767.98px) {
  .listing-row { flex-direction: column; }
  .listing-row__gallery { flex-basis: auto; aspect-ratio: 16 / 9; }
  .listing-row__body { flex-direction: column; padding: 1rem; }
  .listing-row__side { flex-basis: auto; align-items: stretch; text-align: left; }
  .listing-row__rating { justify-content: flex-start; }
  .listing-row__price { text-align: left; }
}

/* ---------- Filter sidebar map preview (lazy-inits Leaflet on click) ---------- */
.filter-map-preview__placeholder {
  padding: 1.75rem 1rem;
  text-align: center;
}
.filter-map-preview__placeholder i {
  font-size: 1.6rem;
  color: var(--brand);
  margin-bottom: .5rem;
  display: block;
}
.filter-map-preview__map {
  height: 220px;
  width: 100%;
}

/* ---------- Status badges (host/admin) ---------- */
.status-pill {
  display: inline-flex;
  align-items: center;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius);
}
.status-pending { background: #fef3c7; color: #92400e; }
.status-approved { background: #d1fae5; color: #065f46; }
.status-rejected { background: #fee2e2; color: #991b1b; }

/* ---------- Compact dashboard stat cards (host/dashboard.php) ----------
   Were plain Bootstrap-utility cards (border rounded-4 p-3, fs-4 value)
   that took up much more vertical space than 6-8 short numbers actually
   need — a direct user report ("zaberaju vela miesta na vysku"). */
.host-stat { border: 1px solid var(--border); border-radius: .75rem; padding: .55rem .75rem; }
.host-stat__value { font-size: 1.3rem; font-weight: 800; line-height: 1.15; color: var(--ink); }
.host-stat__label { font-size: .7rem; color: var(--muted); }

.host-feedback-widget {
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  border-radius: 1rem;
  color: #fff;
  padding: 1.75rem 2rem;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 2px 8px rgba(0,0,0,0.05);
}
.host-feedback-widget__title { font-weight: 800; font-size: 1.15rem; margin-bottom: .35rem; }
.host-feedback-widget__subtitle { color: rgba(255,255,255,.82); font-size: .9rem; max-width: 40rem; }
.host-feedback-widget .form-select, .host-feedback-widget .form-control {
  border: none;
}
.host-feedback-widget .form-control::placeholder { color: #6b7280; }

/* ---------- Off-canvas mobile menu & accordion ---------- */
.offcanvas-header { border-bottom: 1px solid var(--border); }
.accordion-item { border-color: var(--border); }
.accordion-button { font-weight: 600; }
.accordion-button:not(.collapsed) {
  color: var(--brand);
  background-color: var(--surface-tint);
  box-shadow: none;
}
.accordion-button:focus { box-shadow: none; border-color: var(--border); }

/* ---------- Animated stepper (add_property.php) ---------- */
.stepper { position: relative; padding: 0 .5rem; }
.stepper__track {
  position: absolute;
  top: 1.35rem;
  left: 2.5rem;
  right: 2.5rem;
  height: 3px;
  background: var(--border);
  border-radius: 999px;
  z-index: 1;
}
.stepper__progress {
  height: 100%;
  width: 0%;
  background: var(--brand);
  border-radius: 999px;
  transition: width .4s ease;
}
.stepper__steps {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
}
.stepper__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .5rem;
  flex: 1;
}
.stepper__circle {
  width: 2.7rem;
  height: 2.7rem;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: var(--muted);
  transition: all .25s ease;
}
.stepper__label {
  font-size: .75rem;
  font-weight: 600;
  color: var(--muted);
  transition: color .25s ease;
  text-align: center;
}
.stepper__step.active .stepper__circle {
  border-color: var(--brand);
  color: var(--brand);
  background: var(--surface-tint);
  transform: scale(1.1);
  box-shadow: 0 0 0 5px rgba(var(--brand-rgb),.12);
}
.stepper__step.active .stepper__label { color: var(--ink); }
.stepper__step.done .stepper__circle {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.stepper__step.done .stepper__label { color: var(--ink); }
@media (max-width: 575.98px) {
  .stepper__label { display: none; }
  .stepper__circle { width: 2.2rem; height: 2.2rem; font-size: .85rem; }
  .stepper__track { left: 1.75rem; right: 1.75rem; top: 1.1rem; }
}

/* ---------- Multi-step form panels ---------- */
.form-step { display: none; }
.form-step.active {
  display: block;
  animation: stepFadeIn .35s ease;
}
@keyframes stepFadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
.form-step-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 1.25rem;
  padding: 2rem;
  box-shadow: 0 2px 10px rgba(0,0,0,.03);
}
@media (max-width: 575.98px) {
  .form-step-card { padding: 1.25rem; }
}

.form-floating > label { color: var(--muted); }
.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label {
  color: var(--brand);
}

.ai-generate-btn {
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  color: #fff;
  font-weight: 600;
  border: none;
  transition: transform .15s ease, box-shadow .15s ease;
}
.ai-generate-btn:hover {
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(var(--brand-rgb),.3);
}

/* Amenity selection chips */
.amenity-check {
  position: relative;
  display: flex;
  align-items: center;
  gap: .75rem;
  border: 1.5px solid var(--border);
  border-radius: 1rem;
  padding: .85rem 1rem;
  cursor: pointer;
  background: var(--surface);
  transition: border-color .18s ease, background-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.amenity-check:hover {
  border-color: #d1d5db;
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0,0,0,.06);
}
.amenity-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.amenity-check__icon {
  width: 2.3rem;
  height: 2.3rem;
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 1rem;
  transition: background-color .18s ease, color .18s ease;
}
.amenity-check__label { font-weight: 600; font-size: .88rem; flex: 1; }
.amenity-check__check {
  opacity: 0;
  transform: scale(.5);
  color: var(--brand);
  font-size: 1.15rem;
  transition: opacity .18s ease, transform .18s ease;
}
.amenity-check:has(input:checked) {
  border-color: var(--brand);
  background: var(--surface-tint);
  box-shadow: 0 6px 16px rgba(var(--brand-rgb),.12);
}
.amenity-check:has(input:checked) .amenity-check__icon {
  background: var(--brand);
  color: #fff;
}
.amenity-check:has(input:checked) .amenity-check__check {
  opacity: 1;
  transform: scale(1);
}

/* ---------- Footer ---------- */
.site-footer { background: var(--surface); }

/* App-download teaser — no real app yet, so the badges are deliberately
   inert (a <div>, not a link/button) rather than pointing at a store page
   that doesn't exist. The "soon" ribbon is what keeps that honest instead
   of looking like a broken download link. */
.app-download {
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  border-radius: 1rem;
  color: #fff;
  padding: 1.75rem 2rem;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 2px 8px rgba(0,0,0,0.05);
}
.app-download__title { font-weight: 800; font-size: 1.15rem; margin-bottom: .35rem; }
.app-download__subtitle { color: rgba(255,255,255,.82); font-size: .875rem; max-width: 38rem; margin-bottom: 0; }
.app-badges { display: flex; flex-wrap: wrap; gap: .75rem; }
.app-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  background: #000;
  color: #fff;
  border-radius: var(--radius);
  padding: .5rem 1.1rem .5rem .9rem;
  cursor: default;
  user-select: none;
}
.app-badge i { font-size: 1.65rem; line-height: 1; }
.app-badge__text { display: flex; flex-direction: column; line-height: 1.1; }
.app-badge__text small { font-size: .62rem; text-transform: uppercase; letter-spacing: .04em; color: rgba(255,255,255,.75); }
.app-badge__text strong { font-size: .95rem; font-weight: 700; }
.app-badge__soon {
  position: absolute;
  top: -.55rem;
  right: -.5rem;
  background: #ffc107;
  color: #1a1a1a;
  font-size: .58rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .03em;
  padding: .18rem .5rem;
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
@media (max-width: 767.98px) {
  .app-download { text-align: center; }
  .app-download__subtitle { margin-left: auto; margin-right: auto; }
  .app-badges { justify-content: center; }
}

/* Facebook community card — deliberately plain HTML/CSS, no SDK/iframe/JS
   at all, so there is nothing to lazy-load and zero added page weight. */
.fb-community-card {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  background: var(--surface);
  border: 1px solid rgba(0,0,0,.07);
  border-radius: 1rem;
  padding: 1.15rem 1.4rem;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 2px 8px rgba(0,0,0,0.05);
}
.fb-community-card__icon {
  flex: 0 0 auto;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: #1877F2;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  line-height: 1;
}
.fb-community-card__body { flex: 1 1 auto; min-width: 0; }
.fb-community-card__name { font-weight: 700; font-size: .95rem; margin-bottom: .15rem; }
.fb-community-card__count { color: #6c757d; font-size: .82rem; margin-bottom: 0; }
.fb-community-card__btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  background: #1877F2;
  color: #fff;
  font-weight: 700;
  font-size: .85rem;
  padding: .6rem 1.15rem;
  border-radius: 999px;
  text-decoration: none;
  white-space: nowrap;
  transition: background .15s ease;
}
.fb-community-card__btn:hover { background: #145dbf; color: #fff; }
@media (max-width: 575.98px) {
  .fb-community-card { flex-wrap: wrap; text-align: center; justify-content: center; }
  .fb-community-card__body { flex-basis: 100%; }
  .fb-community-card__btn { flex-basis: 100%; justify-content: center; }
}

/* ---------- Phone dial-code picker (add/edit listing, register forms) ---------- */
.phone-picker { display: flex; gap: .5rem; }
.phone-picker .dropdown-toggle { flex-shrink: 0; white-space: nowrap; }
.phone-picker .form-control, .phone-picker .form-floating { flex: 1; min-width: 0; }
.phone-picker .dropdown-menu { max-height: 260px; overflow-y: auto; }

/* ---------- Photo manager (add/edit listing forms) ---------- */
.photo-manager__cell {
  position: relative;
  width: 110px;
  height: 110px;
  border-radius: .75rem;
  overflow: hidden;
  background: var(--surface-alt);
  border: 1px solid var(--border);
}
.photo-manager__thumb-link { display: block; width: 100%; height: 100%; }
.photo-manager__thumb-link img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-manager__spinner { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; color: var(--muted); }
.photo-manager__badge {
  position: absolute; left: .35rem; bottom: .35rem;
  background: rgba(0,0,0,.6); color: #fff; font-size: .62rem; font-weight: 700;
  padding: .15rem .45rem; border-radius: 999px; letter-spacing: .02em;
}
.photo-manager__remove {
  position: absolute; top: .25rem; right: .25rem; width: 22px; height: 22px;
  border-radius: 50%; border: none; background: rgba(0,0,0,.55); color: #fff;
  font-size: 1rem; line-height: 1; display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.photo-manager__remove:hover { background: rgba(0,0,0,.8); }
.photo-manager__grid { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: .75rem; }
.photo-manager__season-toggles {
  position: absolute; top: .25rem; left: .25rem; display: flex; gap: .2rem;
}
.photo-manager__season-btn {
  width: 22px; height: 22px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(0,0,0,.45); font-size: .7rem; line-height: 1;
  display: flex; align-items: center; justify-content: center; opacity: .7;
}
.photo-manager__season-btn:hover { opacity: 1; }
.photo-manager__season-btn.active { background: var(--brand); opacity: 1; box-shadow: 0 0 0 2px #fff; }

/* ---------- Misc ---------- */
.form-control:focus, .form-select:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 .2rem rgba(var(--brand-rgb),.15);
}

/* Defensive stacked-field spacing: force it via margin rather than
   trusting the flexbox `gap` utility alone, so fields never end up
   glued together regardless of browser/CDN quirks. */
.vstack { gap: 0 !important; }
.vstack > * + * { margin-top: 1rem; }
.vstack.gap-2 > * + * { margin-top: .5rem; }
.vstack.gap-4 > * + * { margin-top: 1.5rem; }
.row.g-3, .row.g-4, .row.g-2 { row-gap: 1rem; }
.row.g-2 { row-gap: .5rem; }
.row.g-4 { row-gap: 1.5rem; }

@media (max-width: 991.98px) {
  .mega-panel { min-width: 320px; }
}

/* ---------- AI režim (ai-add.php) ---------- */
.ai-hero { padding-bottom: 4rem; }
.ai-hero__badge {
  background: rgba(255,255,255,0.18);
  backdrop-filter: blur(6px);
  color: #fff;
  font-weight: 700;
  padding: .5rem 1rem;
  font-size: .8rem;
  display: inline-flex;
}
.ai-step:not(.d-none) { animation: stepFadeIn .35s ease; }

.pricing-card {
  position: relative;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 1.25rem;
  padding: 2rem 1.5rem;
  text-align: center;
  height: 100%;
  transition: transform .2s ease, box-shadow .2s ease;
}
.pricing-card:hover { transform: translateY(-4px); box-shadow: 0 12px 28px rgba(0,0,0,.08); }
.pricing-card--highlight {
  border-color: var(--brand);
  box-shadow: 0 12px 28px rgba(var(--brand-rgb),.15);
}
.pricing-card__badge {
  position: absolute;
  top: -.75rem;
  left: 50%;
  transform: translateX(-50%);
  background: var(--brand);
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  padding: .3rem .8rem;
  border-radius: var(--radius);
  white-space: nowrap;
}
.pricing-card__label { font-weight: 600; color: var(--muted); margin-bottom: .5rem; }
.pricing-card__price { font-size: 2.25rem; font-weight: 800; color: var(--ink); }
.pricing-card__price span { font-size: 1.1rem; font-weight: 600; color: var(--muted); }

/* ---------- Live chat widget ---------- */
.chat-widget {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 1050;
}
.chat-widget__toggle {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  border: none;
  font-size: 1.4rem;
  box-shadow: 0 8px 24px rgba(var(--brand-rgb),.35);
  transition: transform .18s ease, box-shadow .18s ease;
}
.chat-widget__toggle:hover { transform: scale(1.06); box-shadow: 0 10px 28px rgba(var(--brand-rgb),.45); }

.chat-widget__panel {
  position: absolute;
  right: 0;
  bottom: 4.25rem;
  width: 340px;
  max-width: calc(100vw - 2rem);
  height: 480px;
  max-height: 70vh;
  background: var(--surface);
  border-radius: 1.25rem;
  box-shadow: 0 20px 50px rgba(0,0,0,.2);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: stepFadeIn .25s ease;
}
.chat-widget__header {
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  color: #fff;
  font-weight: 700;
  padding: .9rem 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.chat-widget__messages {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: .6rem;
  background: var(--surface-alt);
}
.chat-msg {
  max-width: 85%;
  padding: .55rem .85rem;
  border-radius: 1rem;
  font-size: .88rem;
  line-height: 1.4;
}
.chat-msg--bot {
  align-self: flex-start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom-left-radius: .25rem;
}
.chat-msg--user {
  align-self: flex-end;
  background: var(--brand);
  color: #fff;
  border-bottom-right-radius: .25rem;
}
.chat-msg--thinking { color: var(--muted); font-style: italic; }

.chat-result-card {
  display: flex;
  gap: .6rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: .85rem;
  padding: .5rem;
  align-items: center;
  text-decoration: none;
  color: var(--ink);
  transition: box-shadow .15s ease;
}
.chat-result-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.08); }
.chat-result-card img { width: 3rem; height: 3rem; border-radius: .6rem; object-fit: cover; flex-shrink: 0; }
.chat-result-card__title { font-weight: 700; font-size: .82rem; }
.chat-result-card__meta { font-size: .75rem; color: var(--muted); }

.chat-widget__input {
  display: flex;
  gap: .5rem;
  padding: .75rem;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.chat-widget__input input {
  flex: 1;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5rem 1rem;
  font-size: .88rem;
  outline: none;
}
.chat-widget__input input:focus { border-color: var(--brand); }
.chat-widget__input button {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  border: none;
  flex-shrink: 0;
}
.chat-widget__input button:hover { background: var(--brand-dark); }

@media (max-width: 420px) {
  .chat-widget__panel { width: calc(100vw - 2rem); }
}

/* ---------- Property gallery (Hero Grid) ---------- */
.gallery-tile {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  background: var(--surface-alt);
  /* Grid/flex items default to min-height:auto, which refuses to shrink
     below an <img> child's intrinsic aspect-ratio height — without this
     override, a tall image inside a short grid row overflows its own
     tile and visually overlaps whatever sits below it (real bug, caught
     via a Playwright bounding-box check: stacked tiles were rendering
     ~286px tall inside a 156px row and covering the bottom row below). */
  min-height: 0;
  min-width: 0;
}
.gallery-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .3s ease;
}
.gallery-tile:hover img { transform: scale(1.04); }

.gallery-hero {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: .5rem;
  height: 320px;
  overflow: hidden;
}
.gallery-tile-stack {
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: .5rem;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}
.gallery-bottom-row {
  display: grid;
  gap: .5rem;
  height: 110px;
  margin-top: .5rem;
  overflow: hidden;
}
.gallery-tile__overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 15, 40, .62);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.05rem;
  text-align: center;
  padding: .5rem;
}
.gallery-grid--single .gallery-tile { height: 360px; }
.gallery-grid--two { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; height: 360px; }
.gallery-grid--two .gallery-tile { height: 100%; }

.gallery-placeholder-banner {
  position: relative;
  height: 300px;
  overflow: hidden;
}
.gallery-placeholder-banner img { width: 100%; height: 100%; object-fit: cover; }
.gallery-placeholder-banner__badge {
  position: absolute;
  top: 1rem;
  left: 1rem;
  background: rgba(0, 15, 40, .55);
  color: #fff;
  padding: .35rem .85rem;
  border-radius: 50px;
  font-size: .8rem;
  font-weight: 600;
}

@media (max-width: 767.98px) {
  .gallery-grid, .gallery-placeholder-banner--desktop { display: none !important; }
}
@media (min-width: 768px) {
  .gallery-carousel-wrap { display: none !important; }
}

/* Mobile touch carousel */
.gallery-carousel-wrap { position: relative; margin-bottom: 1.5rem; }
.gallery-carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  border-radius: 1rem;
  scrollbar-width: none;
}
.gallery-carousel::-webkit-scrollbar { display: none; }
.gallery-carousel__slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  aspect-ratio: 4 / 3;
  cursor: pointer;
}
.gallery-carousel__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-carousel__counter {
  position: absolute;
  bottom: .75rem;
  right: .75rem;
  background: rgba(0, 15, 40, .65);
  color: #fff;
  font-size: .8rem;
  font-weight: 600;
  padding: .25rem .7rem;
  border-radius: 50px;
}

/* Video (YouTube/Vimeo) — floating "play" card over the gallery area
   (property.php's .property-gallery-wrap), rather than a tile squeezed
   into the photo grid's own carefully-tuned per-count layouts. */
.property-gallery-wrap { position: relative; }
.gallery-video-btn {
  position: absolute;
  bottom: 1rem;
  right: 1rem;
  width: 160px;
  height: 90px;
  border-radius: .85rem;
  overflow: hidden;
  border: 2px solid rgba(255, 255, 255, .85);
  padding: 0;
  cursor: pointer;
  background: #0a1a2e;
  box-shadow: 0 6px 20px rgba(0, 10, 30, .35);
  z-index: 2;
}
.gallery-video-btn img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .75; }
.gallery-video-btn__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 2rem;
  background: rgba(0, 10, 30, .25);
  transition: background-color .15s ease;
}
.gallery-video-btn:hover .gallery-video-btn__overlay { background: rgba(0, 10, 30, .45); }
.gallery-video-btn__label {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  text-align: center;
  padding: .3rem .25rem;
  background: linear-gradient(to top, rgba(0, 10, 30, .85), transparent);
}
@media (max-width: 575.98px) {
  .gallery-video-btn { width: 120px; height: 68px; bottom: .6rem; right: .6rem; }
  .gallery-video-btn__overlay { font-size: 1.4rem; }
  .gallery-video-btn__label { font-size: .62rem; }
}

/* Lightbox */
.mu-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 8, 20, .94);
  z-index: 1080;
  display: none;
  align-items: center;
  justify-content: center;
}
.mu-lightbox.is-open { display: flex; }
.mu-lightbox__img { max-width: 92vw; max-height: 85vh; object-fit: contain; user-select: none; }
.mu-lightbox__close, .mu-lightbox__prev, .mu-lightbox__next {
  position: absolute;
  background: rgba(255, 255, 255, .12);
  color: #fff;
  border: 0;
  border-radius: 50%;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  cursor: pointer;
}
.mu-lightbox__close:hover, .mu-lightbox__prev:hover, .mu-lightbox__next:hover { background: rgba(255, 255, 255, .25); }
.mu-lightbox__close { top: 1.25rem; right: 1.25rem; }
.mu-lightbox__prev { left: 1.25rem; top: 50%; transform: translateY(-50%); }
.mu-lightbox__next { right: 1.25rem; top: 50%; transform: translateY(-50%); }
.mu-lightbox__counter {
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: .9rem;
  font-weight: 600;
  background: rgba(255, 255, 255, .12);
  padding: .3rem .9rem;
  border-radius: 50px;
}
@media (max-width: 575.98px) {
  .mu-lightbox__prev, .mu-lightbox__next { width: 38px; height: 38px; font-size: 1.1rem; }
}

/* Video lightbox — reuses .mu-lightbox's dark full-screen backdrop/close
   button, swapping the image for a responsive 16:9 iframe frame. A
   separate overlay from the photo one (not a mixed-in "slide") since a
   single video has no prev/next to navigate, and mixing an <iframe> into
   the photo lightbox's index-based showSlide() would complicate stopping
   playback on every photo navigation for no real benefit. */
.mu-video-lightbox__frame {
  width: min(92vw, 1100px);
  aspect-ratio: 16 / 9;
  max-height: 85vh;
}

/* ---------- Property-detail breadcrumbs (compact, muted) ---------- */
/* Scoped to property.php's own wrapper rather than the shared .breadcrumb
   class index.php also uses for its own (differently-shaped) trail. */
.property-breadcrumbs .breadcrumb {
  font-size: .8rem;
  color: #8c9196;
  margin-bottom: .5rem;
  flex-wrap: nowrap;
  overflow-x: auto;
  white-space: nowrap;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.property-breadcrumbs .breadcrumb::-webkit-scrollbar { display: none; }
.property-breadcrumbs .breadcrumb-item, .property-breadcrumbs .breadcrumb-item a {
  color: #8c9196;
}
.property-breadcrumbs .breadcrumb-item.active { color: #6c757d; }
.property-breadcrumbs .breadcrumb-item + .breadcrumb-item::before { color: #c3c7cc; }
.property-breadcrumbs .breadcrumb-item a:hover { color: var(--brand); text-decoration: underline; }

/* ---------- Property header (title / location / rating / badges / actions) ---------- */
.property-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.5rem;
}
.property-header__left { flex: 1 1 320px; min-width: 0; }
.property-header__title {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -.01em;
  margin-bottom: .35rem;
  line-height: 1.2;
}
.property-header__location {
  color: var(--muted);
  margin-bottom: 0;
}
.location-map-link {
  color: var(--brand);
  font-weight: 600;
  text-decoration: none;
  margin-left: .15rem;
  white-space: normal;
}
.location-map-link:hover { text-decoration: underline; }

/* Right column: exactly two rows — rating+badges together, then the
   action icons — both right-aligned so they read as one clean unit
   next to the left column instead of drifting apart vertically. */
.property-header__right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: .6rem;
  flex: 0 1 auto;
}
.property-header__top-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.property-header__rating {
  display: flex;
  align-items: center;
  gap: .3rem;
  text-decoration: none;
  color: inherit;
  white-space: nowrap;
}
.property-header__rating--empty { color: var(--muted); }
.property-header__stars { color: #f5a623; font-size: .85rem; letter-spacing: 1px; }
.property-header__badges {
  display: flex;
  gap: .4rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.badge-pastel-type { background: #e7f0fd; color: var(--brand); }
.badge-pastel-capacity { background: #eef2f6; color: #33475b; }
.property-header__actions {
  display: flex;
  gap: .5rem;
  justify-content: flex-end;
}

@media (max-width: 575.98px) {
  .property-header { align-items: flex-start; }
  .property-header__title { font-size: 1.5rem; }
  .property-header__right { width: 100%; align-items: flex-start; }
  .property-header__top-row { justify-content: flex-start; width: 100%; }
  .property-header__badges { justify-content: flex-start; }
  .property-header__actions { justify-content: flex-end; width: 100%; }
}

/* ---------- Section inspector (testing aid) ---------- */
.inspector-toggle {
  position: fixed;
  left: 1.25rem;
  bottom: 1.25rem;
  z-index: 1040;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: #1a1a1a;
  color: #fff;
  border: none;
  font-size: 1.1rem;
  box-shadow: 0 6px 18px rgba(0,0,0,.25);
  opacity: .55;
  transition: opacity .15s ease, transform .15s ease;
}
.inspector-toggle:hover { opacity: 1; transform: scale(1.05); }

body.inspect-mode [data-region] {
  outline: 2px dashed #ff385c;
  outline-offset: -2px;
  position: relative;
}
body.inspect-mode [data-region]::before {
  content: attr(data-region);
  position: absolute;
  top: 0;
  left: 0;
  background: #ff385c;
  color: #fff;
  font: 700 11px/1.4 Arial, sans-serif;
  padding: 2px 8px;
  z-index: 1045;
  border-bottom-right-radius: .5rem;
  pointer-events: none;
}

/* Page transitions (2026-09-21) — this is a plain server-rendered
   multi-page site (no client-side router), so the native cross-document
   View Transitions API is the whole mechanism: opting in via
   `navigation: auto` makes every normal same-origin navigation (link
   clicks, back/forward, a form's POST-redirect-GET) automatically
   capture a snapshot of the old and new page and cross-fade between
   them, entirely in the browser's own compositor — no JS, so it can
   never block a click handler or an AJAX call (the sidebar filter swap,
   the notification bell, etc. never trigger a real navigation, so this
   has zero effect on them either way). Only the timing is customized
   here; the cross-fade itself is the browser's own default animation on
   ::view-transition-old(root)/::view-transition-new(root), just sped up
   and re-eased to feel snappier than the ~300ms/ease default. */
@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.22s;
  animation-timing-function: ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Fallback for browsers with no View Transitions support at all (the
   @supports check itself is what "not (view-transition-name: none)"
   means — a browser that doesn't recognize that CSS property here also
   doesn't implement the API, so this block is inert everywhere the rule
   above already works, and is the ONLY thing that runs where it
   doesn't — never both at once). */
@supports not (view-transition-name: none) {
  @media (prefers-reduced-motion: no-preference) {
    body {
      animation: mu-fallback-page-fade-in 0.2s ease-in-out;
    }
  }
}

@keyframes mu-fallback-page-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Skeleton loaders (2026-09-21) — one reusable `.skeleton` class (a
   shimmering gray block) that main.js's buildSkeletonList() assembles
   into fake rows using the REAL .listing-row/__gallery/__body/__main/
   __side class names, so every dimension/gap/responsive breakpoint the
   real row already has applies to the skeleton for free; only content
   (image, text, button) is ever replaced by a .skeleton block. Used
   while the sidebar-filter AJAX swap (History #60/#61) is in flight,
   replacing the old opacity-dim loading state entirely. */
.skeleton {
  background: linear-gradient(90deg, #e9ebee 25%, #f6f7f9 37%, #e9ebee 63%);
  background-size: 400% 100%;
  animation: mu-skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: 4px;
  display: block;
}
.listing-row__gallery.skeleton { border-radius: 0; }

@keyframes mu-skeleton-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton {
    animation: none;
    background: var(--surface-alt);
  }
}

/* ============================================================
   Dark mode (2026-09-22)
   ------------------------------------------------------------
   Resolution happens in JS (includes/header.php's inline head
   script + assets/js/theme-toggle.js), never a bare CSS media
   query alone — the script reads localStorage first, falls back
   to `prefers-color-scheme`, and sets BOTH `data-theme` (this
   file's own tokens) and `data-bs-theme` (Bootstrap 5.3's own
   native dark-mode support, which handles every stock Bootstrap
   component — buttons, forms, modals, dropdowns' own base
   styling, badges, alerts — for free) on <html> in one pass, so
   the two systems can never disagree about which theme is active.
   Deliberately scoped to pages that load includes/header.php
   (public + host) — /adm never sets data-theme at all, so it
   always renders in the light tokens below regardless of the
   visitor's OS setting; a genuinely separate admin dark-mode
   pass (with its own toggle) wasn't asked for and isn't safely
   inferable from "add a switch next to the heart/bell icons",
   which only exist in the public/host header.

   Token values were chosen for contrast, not just inverted —
   --brand in particular is NOT the light-mode navy #003580
   turned up in lightness by a fixed formula: that navy reads as
   near-black-on-black wherever --brand is used as TEXT/icon
   color (the overwhelmingly common use in this file), so a
   distinct, brighter blue is used instead, still saturated
   enough to keep working as a button BACKGROUND with white text.
   ============================================================ */
:root[data-theme="dark"] {
  --brand: #3b82f6;
  --brand-dark: #60a5fa;
  --brand-rgb: 59,130,246;
  --ink: #e7eaee;
  --muted: #98a2b3;
  --border: #2b3542;
  --surface: #1a212b;
  --bg: #10151c;
  --surface-alt: #242e3a;
  --surface-tint: rgba(59,130,246,.16);
}

/* Elements that rely on Bootstrap's `shadow-lg border-0` pattern for
   visual separation (a black box-shadow reads fine floating over a
   WHITE page, but is nearly invisible floating over a dark one) — add
   back a real, visible border in dark mode specifically. Every card-
   style component below this point (.form-step-card, .listing-row,
   .pricing-card, .chat-msg--bot, etc.) already declares its own
   `border: 1px solid var(--border)` explicitly, so those need no
   extra rule here — they pick up the new dark border color for free
   the moment the token above changes. */
[data-theme="dark"] .dropdown-menu,
[data-theme="dark"] .mega-panel,
[data-theme="dark"] .type-city-flyout,
[data-theme="dark"] .region-flyout {
  border: 1px solid var(--border);
}

[data-theme="dark"] .skeleton {
  background: linear-gradient(90deg, #242e3a 25%, #313d4d 37%, #242e3a 63%);
}
[data-theme="dark"] .navbar-nav .nav-link:hover,
[data-theme="dark"] .navbar-nav .nav-link:focus {
  background-color: var(--surface-alt);
}
[data-theme="dark"] .lang-switch-btn:hover,
[data-theme="dark"] .user-chip:hover {
  background: var(--surface-alt);
  border-color: var(--border);
}

/* Real bug found live (2026-09-22, user report: "Pridať ubytovanie"
   invisible in dark mode) — root cause, confirmed by reading Bootstrap's
   own compiled CSS: .btn-outline-dark/.btn-dark are literal "near-black"
   colors (#212529) with NO [data-bs-theme=dark] override of their own
   anywhere in Bootstrap itself (unlike the semantic/brand button colors
   — primary/success/danger/warning — which Bootstrap DOES remap, and
   which stay visible regardless since they're saturated colors, not
   near-black). Every .btn-outline-dark/.btn-dark on this site (41
   occurrences across 10 files — nav "Pridať ubytovanie" CTA, the mobile
   language/currency picker's active-state pill, and several form/host
   page buttons) was reading as near-black-on-near-black. Fixed once,
   here, via Bootstrap's own CSS custom-property hooks on these classes
   (--bs-btn-*) rather than touching any of the 10 template files
   individually — every current AND future .btn-outline-dark/.btn-dark
   on the site is covered automatically. Colors reuse this file's own
   already-dark-mode-aware tokens rather than new hardcoded values, so
   they can never drift out of sync with the rest of the dark palette. */
[data-theme="dark"] .btn-outline-dark {
  --bs-btn-color: var(--ink);
  --bs-btn-border-color: var(--border);
  --bs-btn-hover-color: var(--bg);
  --bs-btn-hover-bg: var(--ink);
  --bs-btn-hover-border-color: var(--ink);
  --bs-btn-active-color: var(--bg);
  --bs-btn-active-bg: var(--ink);
  --bs-btn-active-border-color: var(--ink);
  --bs-btn-disabled-color: var(--muted);
  --bs-btn-disabled-border-color: var(--border);
}
[data-theme="dark"] .btn-dark {
  --bs-btn-color: var(--bg);
  --bs-btn-bg: var(--ink);
  --bs-btn-border-color: var(--ink);
  --bs-btn-hover-color: var(--bg);
  --bs-btn-hover-bg: var(--muted);
  --bs-btn-hover-border-color: var(--muted);
  --bs-btn-active-color: var(--bg);
  --bs-btn-active-bg: var(--muted);
  --bs-btn-active-border-color: var(--muted);
  --bs-btn-disabled-color: var(--bg);
  --bs-btn-disabled-bg: var(--ink);
  --bs-btn-disabled-border-color: var(--ink);
}

/* ---------- Elegant sun/moon theme switch ---------- */
.theme-switch {
  border: none;
  background: transparent;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  line-height: 0;
}
.theme-switch__track {
  width: 44px;
  height: 24px;
  border-radius: 999px;
  background: var(--border);
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 2px;
  transition: background-color .25s ease;
}
.theme-switch__thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.3);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: transform .3s cubic-bezier(.4,0,.2,1), background-color .25s ease;
}
.theme-switch__icon {
  position: absolute;
  font-size: .66rem;
  transition: opacity .2s ease, transform .25s ease;
}
.theme-switch__icon--sun { color: #f59e0b; opacity: 1; transform: scale(1) rotate(0deg); }
.theme-switch__icon--moon { color: #6366f1; opacity: 0; transform: scale(.4) rotate(-40deg); }
[data-theme="dark"] .theme-switch__track { background: var(--brand); }
[data-theme="dark"] .theme-switch__thumb { transform: translateX(20px); background: #1a212b; }
[data-theme="dark"] .theme-switch__icon--sun { opacity: 0; transform: scale(.4) rotate(40deg); }
[data-theme="dark"] .theme-switch__icon--moon { opacity: 1; transform: scale(1) rotate(0deg); color: #fbbf24; }
.theme-switch:focus-visible .theme-switch__track { outline: 2px solid var(--brand); outline-offset: 2px; }
