/* ---------------------------------------------------------------------
   The portal layer.

   Structure and density come from the "Portal A Zoznam" reference:
   small radii, quiet shadows, a white search card over a flat ground,
   a chip row, and cards that carry the decision. Colour and type stay
   ours — the reference's cold grey (#eceef0) is the option that was
   deliberately rejected when the page background was chosen, and its
   system font stack would give the site no voice at all.

   The premise, and the reason this replaces home.css on public pages: a
   portal's job is to get someone to the offers, so the design must not
   be the thing that gets noticed. Everything here is sized to let the
   photographs and the prices carry the page.

   One typeface does the work (Work Sans, already loaded). Newsreader
   appears once, on the page title. The homepage's second pair —
   Alegreya + Source Sans 3 — is gone from the public site: two voices
   met exactly where a visitor was trying to choose.
--------------------------------------------------------------------- */

:root {
  /* Ground and surfaces. --paper and the ink scale come from brand.css;
     these are the portal-specific steps between them. */
  --portal-line: rgba(28, 31, 34, 0.10);
  --portal-line-strong: rgba(28, 31, 34, 0.22);
  --portal-field: #f6f5f2;

  /* The reference's shadows, which are what make a flat ground read as
     layered without a single border being visible. */
  --lift-1: 0 1px 2px rgba(20, 24, 27, 0.05);
  --lift-2: 0 2px 8px rgba(20, 24, 27, 0.08);
  --lift-3: 0 8px 20px rgba(20, 24, 27, 0.13);

  /* Small radii throughout. Large ones read as decoration; these read
     as edges. */
  --r-sm: 5px;
  --r-md: 6px;

  --portal-max: 1280px;
}

body.portal {
  /* The reference's own stack. Overridden here rather than in brand.css
     so it stays scoped to the public portal — the host portal and the
     booking status page keep the brand faces. Both `--sans` and
     `--serif` are remapped, since the reference sets one face for
     everything and the rules below reach for either. */
  --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;

  background: var(--paper);
  font-family: var(--sans);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
}

.portal-shell {
  width: 100%;
  max-width: var(--portal-max);
  margin: 0 auto;
  padding: 0 16px;
}

@media (min-width: 720px) {
  .portal-shell { padding: 0 28px; }
}

/* ---- Header ---------------------------------------------------------- */
/* White, thin, and pinned. It is chrome, not a statement — the previous
   version put a full-height illustrated scene here and pushed every
   offer below the fold. */

.portal-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: #fff;
  box-shadow: 0 1px 2px rgba(20, 24, 27, 0.06);
}
.portal-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px ;
}
@media (min-width: 720px) {
  .portal-header-inner { padding: 14px 0; }
}
/* `flex: none` so the search beside it cannot squeeze the logo, and a
   flex box so the mark sits on the bar's centre line rather than on the
   text baseline — that offset is what made the two ends of the header
   look unevenly padded. */
.portal-logo { flex: none; display: flex; align-items: center; }
.portal-logo img { height: 26px; width: auto; display: block; }

.portal-cta {
  background: var(--forest);
  color: #fff;
  border: none;
  border-radius: var(--r-sm);
  padding: 8px 15px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
}
.portal-cta:hover { background: var(--forest-dark); color: #fff; text-decoration: none; }

/* One row of five codes inside the menu drawer, the current one
   inverted. The reference's three-to-a-row grid also carried each
   language's own name, which took five rows of pills to say what the
   codes say — and the menu's height is the scarce thing here, not its
   width. */
.lang-switcher { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.lang-switcher a {
  display: flex; align-items: center; justify-content: center;
  padding: 8px 4px; border-radius: var(--r-sm);
  border: 1px solid rgba(24,28,31,.14); background: #fff; color: #3f464b;
  font-size: 12px; text-transform: uppercase; font-weight: 700;
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.lang-switcher a:hover { background: #f4f5f7; text-decoration: none; }
.lang-switcher a[aria-current="true"] { background: #16191c; border-color: #16191c; color: #fff; }

/* ---- Search ---------------------------------------------------------- */
/* One card, fields divided by hairlines, and the only saturated colour
   on the page on its button. Above the listings and above the fold,
   because it is the first thing anyone does. */

.portal-search {
  background: #fff;
  border-radius: var(--r-md);
  box-shadow: var(--lift-2);
  padding: 6px;
  margin-bottom: 16px;
}
@media (min-width: 720px) { .portal-search { padding: 8px; } }

.portal-search-bar { display: flex; flex-direction: column; gap: 2px; }
.portal-search-group { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
@media (min-width: 720px) {
  .portal-search-bar { display: flex; flex-direction: row; align-items: stretch; gap: 6px; }
  .portal-search-group {
    display: grid;
    grid-template-columns: 1.2fr 1.5fr 0.9fr;
    align-items: stretch;
    flex: 1;
    gap: 2px;
  }
}

.portal-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 13px;
  border-bottom: 1px solid rgba(28, 31, 34, 0.07);
}
@media (min-width: 720px) {
  .portal-field { padding: 8px 16px; border-bottom: none; border-right: 1px solid rgba(28, 31, 34, 0.07); }
  /* last-of-type, not nth-last-child: the hidden filter inputs sit
     between the last field and the button and would throw the count. */
  .portal-field:last-of-type { border-right: none; }
}
.portal-field label {
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  font-weight: 600;
  margin: 0;
}
/* Unstyled inputs: the card is the control, the input inside it should
   be invisible until focused. A bordered box inside a bordered box is
   the visual noise this layout exists to remove. */
.portal-field input {
  border: none;
  background: none;
  padding: 0;
  min-height: 0;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  width: 100%;
}
.portal-field input:focus { outline: none; border: none; }
.portal-field:focus-within { background: var(--portal-field); border-radius: 4px; }

/* ---- Date-range popover (search-calendar.js) -------------------------
   Two native <input type=date> stay in the field, hidden, as the form's
   real values; this is the widget the JS builds in front of them. */
.portal-dates { position: relative; }
.portal-dates-trigger {
  border: none; background: none; padding: 0; margin: 0; width: 100%;
  text-align: left; font-family: inherit; font-size: 14px; color: var(--faint);
  cursor: pointer;
}
.portal-dates-trigger.has-value { color: var(--ink); font-weight: 600; }

.portal-dates-panel {
  position: absolute; left: 0; top: calc(100% + 10px); z-index: 50;
  width: min(660px, 92vw); background: #fff; border-radius: var(--r-md);
  box-shadow: 0 14px 36px rgba(10,19,13,.3); padding: 16px 18px 14px;
  color: #1c1f22;
}

/* The booking card's two labelled cells. Hidden until the widget marks
   the field enhanced, so a no-JS visitor gets the native inputs instead
   of two buttons that would do nothing. */
.booking-date-cell { display: none; }
.is-date-enhanced .booking-date-cell {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  padding: 9px 11px; border: none; background: none; font-family: inherit;
  color: var(--ink); font-size: 13.5px; cursor: pointer; text-align: left;
}
.is-date-enhanced .booking-date-cell:first-of-type { border-right: 1px solid var(--portal-line); }
.is-date-enhanced .booking-date-cell:hover { background: var(--portal-field); }
.booking-date-cell [data-date-value] { color: var(--faint); }
.booking-date-cell.has-value [data-date-value] { color: var(--ink); }

/* The aside is ~340px and the panel is 660px, so it opens leftward from
   the card's right edge rather than off the side of the viewport. */
.booking-date-grid { position: relative; }
.booking-aside .portal-dates-panel { left: auto; right: 0; }

.portal-cal-nav { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 12px; }
.portal-cal-arrow {
  width: 32px; height: 32px; border-radius: 5px; border: 1px solid rgba(24,28,31,.14);
  background: #fff; color: #16191c; display: flex; align-items: center; justify-content: center;
  font-size: 16px; cursor: pointer; font-family: inherit;
}
.portal-cal-arrow:hover:not(:disabled) { background: #f4f5f7; }
.portal-cal-close {
  width: 32px; height: 32px; margin-left: 8px; flex: none;
  border: 1px solid rgba(24,28,31,.14); border-radius: 5px; background: #fff;
  color: #4a5257; font-family: inherit; font-size: 17px; line-height: 1;
  display: grid; place-items: center; cursor: pointer;
}
.portal-cal-close:hover { background: #f4f5f7; color: #16191c; }
.portal-cal-arrow:disabled { border-color: rgba(24,28,31,.08); color: rgba(24,28,31,.22); cursor: default; }

.portal-cal-heads { flex: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 24px; text-align: center; }
.portal-cal-heads span { font-size: 14.5px; font-weight: 600; color: #16191c; }

.portal-cal-months { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
@media (max-width: 719px) {
  .portal-cal-heads { grid-template-columns: 1fr; }
  .portal-cal-heads span + span { display: none; }
  .portal-cal-months { grid-template-columns: 1fr; }
  .portal-cal-month + .portal-cal-month { display: none; }
}
.portal-cal-weekdays, .portal-cal-days { display: grid; grid-template-columns: repeat(7,1fr); gap: 2px; }
.portal-cal-weekdays { margin-bottom: 4px; padding: 6px 0; border-radius: 5px; background: #f4f5f7; }
.portal-cal-weekday { text-align: center; font-size: 11.5px; font-weight: 500; color: #7d848a; }
.portal-cal-weekday.is-weekend { color: #8a6224; font-weight: 600; }
.portal-cal-day {
  aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%; background: transparent; color: #1c1f22;
  font-family: inherit; font-size: 13px; padding: 0; cursor: pointer;
}
.portal-cal-day.is-blank { visibility: hidden; cursor: default; }
.portal-cal-day.is-disabled { color: rgba(24,28,31,.25); cursor: default; }
.portal-cal-day.is-weekend { color: #8a6224; font-weight: 600; }
.portal-cal-day.is-in-range { background: rgba(217,168,78,.22); }
.portal-cal-day.is-edge { background: #16191c; color: #fff; font-weight: 600; }
.portal-cal-day:hover:not(.is-disabled):not(.is-blank):not(.is-edge) { background: rgba(24,28,31,.08); }

.portal-cal-presets { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(24,28,31,.09); }
.portal-cal-preset {
  display: flex; align-items: center; gap: 7px;
  font-family: inherit; font-size: 12.5px; padding: 9px 14px; border-radius: 5px; cursor: pointer;
  background: #fff; color: #4a5257; border: 1px solid rgba(24,28,31,.14);
}
.portal-cal-preset:hover { background: #f4f5f7; }

.portal-search-btn {
  background: var(--gold-cta, #d9a84e);
  color: #16191c;
  border: none;
  border-radius: 4px;
  padding: 13px;
  margin-top: 4px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
@media (min-width: 720px) {
  .portal-search-btn { padding: 0 28px; margin-top: 0; }
}
.portal-search-btn:hover { background: #cd9a3f; }
.portal-search-btn .count { opacity: 0.55; font-weight: 500; }

/* ---- Title row and chips --------------------------------------------- */

.portal-title-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 14px;
}
@media (min-width: 720px) {
  .portal-title-row { flex-direction: row; align-items: center; justify-content: space-between; }
}
.portal-title {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 21px;
  letter-spacing: -0.012em;
  color: var(--ink);
  margin: 0;
}
@media (min-width: 720px) { .portal-title { font-size: 24px; } }
.portal-count { font-size: 12.5px; color: var(--muted); }

/* Horizontal scroll rather than a wrapping block: a wrapped chip row
   pushes the first card off the screen on a phone, which is the one
   thing this layout must not do. */
.portal-chips {
  display: flex;
  align-items: stretch;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 2px;
}
.portal-chips::-webkit-scrollbar { display: none; }
.portal-chip {
  font-family: inherit;
  font-size: 12px;
  padding: 9px 15px;
  border-radius: var(--r-sm);
  white-space: nowrap;
  flex: none;
  background: #fff;
  color: var(--body);
  border: 1px solid var(--portal-line);
  box-shadow: var(--lift-1);
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}
.portal-chip:hover { border-color: var(--portal-line-strong); color: var(--ink); text-decoration: none; }
/* Ink, not the brand green: the reference marks a chosen filter by
   inverting it, and green here reads as a status rather than a
   selection next to the black one on the cards. */
.portal-chip[aria-pressed="true"] {
  background: #16191c;
  border-color: #16191c;
  color: #fff;
  font-weight: 500;
}
.portal-chip[aria-pressed="true"]:hover { color: #fff; border-color: #16191c; }

/* ---- Cards ----------------------------------------------------------- */

.portal-grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .portal-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .portal-grid { grid-template-columns: repeat(3, 1fr); } }

.portal-card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--lift-2);
  color: inherit;
  transition: box-shadow 0.16s ease, transform 0.16s ease;
}
.portal-card:hover {
  box-shadow: var(--lift-3);
  transform: translateY(-2px);
  text-decoration: none;
  color: inherit;
}
.portal-card-media {
  position: relative;
  aspect-ratio: 16 / 11;
  background: linear-gradient(150deg, #e4e1da, #d3cfc6);
}
.portal-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.portal-card-media .empty {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: 12px;
}
.portal-card-body {
  padding: 14px 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
}
.portal-card-name {
  font-size: 15.5px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.008em;
}
.portal-card-tagline { font-size: 13px; font-weight: 500; color: var(--body); line-height: 1.45; }
.portal-card-meta { font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.portal-card-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 12px;
}
.portal-price { font-size: 13.5px; color: var(--ink); }
.portal-price strong { font-weight: 600; }
.portal-price .per { color: var(--muted); }
/* The total for the chosen dates, which is what a guest actually
   compares — a nightly rate is a number they still have to do
   arithmetic on. */
.portal-price .total { font-size: 16px; font-weight: 600; }
.portal-card-action {
  background: var(--portal-field);
  border: 1px solid var(--portal-line);
  border-radius: var(--r-sm);
  padding: 9px 14px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
}
.portal-card:hover .portal-card-action { background: var(--paper); }

/* ---- Map teaser ------------------------------------------------------ */
/* The illustrated guide, demoted to one quiet row. It is editorial
   content worth having and worth indexing; it is not on the path to a
   booking, and it used to sit across that path. */

.portal-teaser {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  background: #fff;
  border-radius: var(--r-md);
  padding: 16px 18px;
  box-shadow: var(--lift-2);
  margin-top: 20px;
}
@media (min-width: 720px) {
  .portal-teaser { flex-direction: row; align-items: center; justify-content: space-between; }
}
.portal-teaser-title { font-size: 15.5px; font-weight: 600; letter-spacing: -0.008em; color: var(--ink); }
.portal-teaser-sub { font-size: 12.5px; color: var(--muted); }

/* ---- Mobile filter sheet --------------------------------------------- */
/* A sticky bar and a <details> sheet, so filtering works with
   JavaScript off — the same reason the chips are links. */

.portal-sticky {
  position: sticky;
  bottom: 0;
  z-index: 30;
  display: flex;
  gap: 8px;
  padding: 10px 0 12px;
  background: linear-gradient(rgba(241, 239, 235, 0), var(--paper) 45%);
}
@media (min-width: 900px) { .portal-sticky { display: none; } }
.portal-sticky > * { flex: 1; text-align: center; }
.portal-sticky .primary {
  background: var(--forest); color: #fff; border: none;
  border-radius: var(--r-sm); padding: 12px;
  font-family: inherit; font-size: 13.5px; font-weight: 500;
  box-shadow: 0 4px 12px rgba(20, 24, 27, 0.2);
}
.portal-sticky .secondary {
  background: #fff; color: var(--ink);
  border: 1px solid var(--portal-line); border-radius: var(--r-sm);
  padding: 12px; font-family: inherit; font-size: 13.5px;
  box-shadow: 0 4px 12px rgba(20, 24, 27, 0.12);
}

.portal-empty {
  background: #fff;
  border-radius: var(--r-md);
  box-shadow: var(--lift-2);
  padding: 26px 20px;
  text-align: center;
}
.portal-empty h2 { font-size: 18px; margin-bottom: 6px; }
.portal-empty p { color: var(--muted); font-size: 13.5px; margin: 0; }

.portal-main { padding: 16px 0 8px; }
@media (min-width: 720px) { .portal-main { padding: 20px 0 12px; } }

/* ---- Listing page ----------------------------------------------------
   Not in the reference, which covers the list only — but the shared
   chrome changed underneath it, so it moves to the same weight rather
   than being left as the one page still speaking the old language.
   Same rules: white cards on the flat ground, hairlines, small radii,
   one typeface.
--------------------------------------------------------------------- */

.listing-head { margin-bottom: 16px; }
.listing-head h1 {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(23px, 4vw, 30px);
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 6px;
}
.listing-facts {
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  font-size: 13px; color: var(--muted); margin: 0;
}

.listing-gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
  border-radius: var(--r-md);
  overflow: hidden;
  margin-bottom: 18px;
  box-shadow: var(--lift-2);
}
@media (min-width: 720px) { .listing-gallery { grid-template-columns: 2fr 1fr; } }
.listing-gallery img { display: block; width: 100%; height: 100%; object-fit: cover; }
.listing-gallery-main { aspect-ratio: 16 / 10; }
.listing-gallery-side { display: grid; gap: 6px; }
.listing-gallery-side img { aspect-ratio: 16 / 10; }
.listing-gallery-empty {
  aspect-ratio: 16 / 7;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(150deg, #e4e1da, #d3cfc6);
  color: var(--muted); font-size: 13px;
  border-radius: var(--r-md); margin-bottom: 18px;
}

.panel {
  background: #fff;
  border-radius: var(--r-md);
  box-shadow: var(--lift-2);
  padding: 18px;
  margin-bottom: 14px;
}
.panel h2 { font-family: var(--serif); font-weight: 500; font-size: 18px; color: var(--ink); margin: 0 0 8px; }
.panel p { font-size: 14px; line-height: 1.65; color: var(--body); }
.panel p:last-child { margin-bottom: 0; }

.tag-list { display: flex; flex-wrap: wrap; gap: 7px; list-style: none; padding: 0; margin: 0; }
.tag-list li {
  background: var(--portal-field);
  border: 1px solid var(--portal-line);
  border-radius: var(--r-sm);
  padding: 6px 12px;
  font-size: 12.5px;
  color: var(--body);
}

/* Each bookable unit. The chosen one is marked by its border, not by a
   fill — a filled row next to a white card reads as a different kind of
   element rather than a selected one. */
.offer {
  border: 1px solid var(--portal-line);
  border-radius: var(--r-sm);
  padding: 13px 15px;
  margin-bottom: 8px;
  background: #fff;
}
.offer:has(input:checked) { border-color: var(--forest); box-shadow: inset 0 0 0 1px var(--forest); }
.offer label { display: flex; align-items: center; gap: 11px; margin: 0; cursor: pointer; font-weight: 400; }
.offer input[type=radio] { width: 18px; height: 18px; flex: 0 0 auto; accent-color: var(--forest); }
.offer-name { font-weight: 600; font-size: 14px; color: var(--ink); flex: 1 1 auto; }
.offer-price { font-size: 15px; font-weight: 600; color: var(--ink); }
.offer-detail { font-size: 12.5px; color: var(--muted); margin: 5px 0 0 29px; }

.breakdown { list-style: none; padding: 0; margin: 0; font-size: 13.5px; }
.breakdown li { display: flex; justify-content: space-between; gap: 16px; padding: 4px 0; color: var(--body); }
.breakdown li.total {
  border-top: 1px solid var(--portal-line);
  margin-top: 6px; padding-top: 9px;
  font-size: 15px; color: var(--ink); font-weight: 600;
}
.breakdown .discount { color: var(--ok); }

.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.field > label { margin: 0; font-size: 12px; font-weight: 600; color: var(--body); }
.field input {
  border: 1px solid var(--portal-line);
  border-radius: var(--r-sm);
  padding: 10px 12px;
  font-size: 14px;
  font-family: inherit;
  min-height: 0;
}
.field input:focus { outline: none; border-color: var(--forest); box-shadow: 0 0 0 3px rgba(47, 74, 55, 0.12); }
.field .hint { font-size: 12px; color: var(--muted); }

.note-quiet {
  background: var(--portal-field);
  border-left: 3px solid var(--forest);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 11px 14px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--body);
}
.note-quiet p { margin: 0; }

.btn-submit {
  width: 100%;
  background: var(--forest);
  color: #fff;
  border: none;
  border-radius: var(--r-sm);
  padding: 13px;
  font-family: inherit;
  font-size: 14.5px;
  font-weight: 500;
  cursor: pointer;
  margin-top: 14px;
}
.btn-submit:hover { background: var(--forest-dark); }

.crumb { font-size: 12px; color: var(--faint); margin-bottom: 12px; }
.crumb a { color: var(--faint); }
.crumb a:hover { color: var(--muted); }

body.portal { background: #eceef0; color: #1c1f22; }
/* A fixed height rather than padding plus a min-height: the search pill
   is the tallest thing in the bar, and with padding it decided the bar's
   height itself and left the gap above and below uneven. A fixed height
   with centred items is symmetric whatever sits inside it — and it is
   what the filter bar below sticks to, so it has to be knowable. */
body.portal { --header-h: 72px; }
.portal-header { background: linear-gradient(147deg, #1c3627 0%, #132318 58%, #0a130d 100%); box-shadow: 0 2px 10px rgba(10,19,13,.24); }
.portal-header-inner { height: var(--header-h); min-height: 0; padding-top: 0; padding-bottom: 0; align-items: center; }
.portal-logo img { height: 36px; }
.portal-header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 18px; color: #e7e2d3; font-size: 13px; }
.portal-login { display: flex; align-items: center; gap: 7px; color: rgba(255,255,255,.75); }
.portal-login:hover { color: #fff; text-decoration: none; }
.portal-menu { position: relative; }
.portal-menu summary { display: flex; align-items: center; gap: 8px; color: #fff; cursor: pointer; font-weight: 600; list-style: none; }
.portal-menu summary::-webkit-details-marker { display: none; }
/* The menu drawer. A 340px panel under the header on desktop; a
   full-height sheet from the right edge on a phone, where it also gets
   the title bar and sign-in row the reference shows only there. */
.portal-menu-scrim { position: fixed; inset: 0; z-index: 80; background: rgba(10,19,13,.18); }
.portal-menu-popover {
  position: fixed; z-index: 90;
  top: calc(var(--header-h) + 8px); right: max(28px, calc((100vw - var(--portal-max)) / 2 + 28px));
  width: 340px; max-height: calc(100vh - var(--header-h) - 32px);
  border-radius: var(--r-md); background: #fff; color: #1c1f22;
  box-shadow: 0 18px 44px rgba(10,19,13,.32);
  display: flex; flex-direction: column; overflow-x: hidden; overflow-y: auto; text-align: left;
}
/* Title bar and sign-in row are the phone drawer's, per the reference. */
.portal-menu-head { display: none; }
.portal-menu-head { align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px 12px; border-bottom: 1px solid rgba(24,28,31,.09); }
.portal-menu-head > span { font-size: 15px; font-weight: 700; color: #16191c; }
.portal-menu-close { width: 32px; height: 32px; flex: none; border: none; border-radius: 16px; background: #f4f5f7; color: #16191c; display: flex; align-items: center; justify-content: center; cursor: pointer; }

.portal-menu-prefs { display: flex; flex-direction: column; gap: 10px; padding: 14px 20px; border-top: 1px solid rgba(24,28,31,.09); }
.portal-menu-sectitle { display: flex; align-items: center; gap: 9px; }
.portal-menu-sectitle span { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #7d848a; }
.portal-menu-sectitle svg { flex: none; }
.portal-menu-sectitle + .portal-menu-sectitle { margin-top: 6px; }

.portal-menu-group { display: flex; flex-direction: column; padding: 12px 0 8px; border-top: 1px solid rgba(24,28,31,.09); }
.portal-menu-grouptitle { padding: 2px 20px 6px; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #7d848a; }
.portal-menu-row { display: flex; align-items: center; gap: 13px; padding: 11px 20px; font-size: 13.5px; color: #3f464b; }
a.portal-menu-row:hover { background: #f4f5f7; text-decoration: none; }
span.portal-menu-row { opacity: .55; cursor: not-allowed; }
/* The reference's 24px icon chip, so labels line up whatever glyph
   sits in front of them. */
.portal-menu-row i {
  flex: none; width: 24px; height: 24px; border-radius: var(--r-sm); background: #f0f2f0;
  display: flex; align-items: center; justify-content: center;
  color: #1c3627; font-style: normal; font-size: 13px;
}
.portal-menu-row small { margin-left: auto; color: #8a6224; }

.portal-menu-foot { margin-top: auto; padding: 14px 20px 18px; border-top: 1px solid rgba(24,28,31,.09); display: flex; flex-direction: column; gap: 4px; }
.portal-menu-foot-title { display: block; font-size: 13px; font-weight: 600; color: #1c3627; }
.portal-menu-foot-title small { color: #8a6224; font-weight: 400; }
.portal-menu-foot-sub { font-size: 11.5px; color: #7d848a; }
.portal-main { padding-top: 22px; }
/* The filter bar sits straight under the header and paints its own
   ground, so the page's top padding only opens a strip of bare page
   between two bars — expensive on a phone, where it is the first screen
   being spent on nothing. The bar's own padding is the breathing room.
   Pages without the bar (a listing) keep the padding. */
.portal-main:has(.portal-filterbar) { padding-top: 0; }
.portal-search { border: 1px solid rgba(24,28,31,.06); }
@media (min-width: 720px) { .portal-search-group { grid-template-columns: 1.2fr 1.5fr .9fr; } }
.portal-destination strong { font-size: 14px; font-weight: 600; color: #16191c; white-space: nowrap; }
.portal-field-label { font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: #9aa1a7; font-weight: 600; }
.portal-eyebrow { display: flex; align-items: center; gap: 10px; color: #8b8378; font-size: 10.5px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; }
.portal-eyebrow::before { content: ""; width: 24px; height: 1px; background: #d9a84e; }
.portal-intro { padding-top: 14px !important; }
.portal-intro .portal-eyebrow { margin-bottom: 9px; }
.portal-quick { display: flex; align-items: center; gap: 8px; overflow-x: auto; margin: -4px 0 18px; scrollbar-width: none; }
.portal-quick > span { flex: none; color: #8b8378; font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; margin-right: 3px; }
/* The filter bar. Sticky directly under the header, so the controls stay
   reachable however far down the list you are; `--header-h` is what the
   two agree on. It is full-bleed and paints the page ground, otherwise
   the cards would show through it as they scroll past underneath. */
.portal-filterbar {
  position: sticky; top: var(--header-h); z-index: 30;
  display: flex; flex-direction: column; gap: 10px;
  margin: 0 0 14px; padding: 10px 0;
  background: #eceef0; box-shadow: 0 1px 0 rgba(24,28,31,.08);
}
/* Scrolls rather than overflows. Every control in here is flex:none —
   they cannot shrink — so on a narrow screen their sum is wider than
   the viewport and, without this, the row widens the whole page and
   the reader gets a horizontal scrollbar on the document. */
.portal-filterbar-row {
  display: flex; align-items: center; gap: 8px;
  overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;
}
.portal-filterbar-row::-webkit-scrollbar { display: none; }
.portal-filterbar-count { margin-left: auto; flex: none; color: #8b8378; font-size: 12.5px; white-space: nowrap; }

.portal-filters { flex: none; }
.portal-filters > summary { list-style: none; }
.portal-filters > summary::-webkit-details-marker { display: none; }
/* Open inverts the pill and turns the chevron over, so the control says
   which state it is in rather than only what it would do. The hover
   colour has to be restated: the shared `.portal-tool:hover` paints the
   label #16191c, which is this pill's own background once it is open —
   black on black. */
.portal-filters[open] > summary,
.portal-filters[open] > summary:hover { background: #16191c; border-color: #16191c; color: #fff; }
.portal-filters[open] .portal-filters-chevron { transform: rotate(180deg); }
.portal-filters-chevron { transition: transform .16s ease; }

/* The number of filters applied, as its own badge rather than a
   dot-and-digit run into the label: it is a count, not a suffix. */
.portal-filters-count {
  display: inline-grid; place-items: center; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 999px;
  background: var(--gold-cta, #d9a84e); color: #16191c;
  font-size: 11px; font-weight: 600; line-height: 1;
}

/* The chips are a row of their own beneath the controls, revealed by
   "Filtre". Without `:has()` they stay showing: a usable page rather
   than a button that appears to do nothing. */
.portal-chips-row { position: relative; display: none; }
.portal-filterbar:has(.portal-filters[open]) .portal-chips-row { display: block; }
@supports not selector(:has(*)) {
  .portal-chips-row { display: block; }
}
.portal-chips-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; display: grid; place-items: center;
  border: 1px solid rgba(24,28,31,.14); border-radius: 50%; background: #fff;
  color: #16191c; cursor: pointer; box-shadow: 0 2px 8px rgba(20,24,27,.18);
}
.portal-chips-arrow:hover { background: #f4f5f7; }
.portal-chips-prev { left: 0; }
.portal-chips-next { right: 0; }

.portal-sort { position: relative; flex: none; }
.portal-sort > summary { list-style: none; }
.portal-sort > summary::-webkit-details-marker { display: none; }
.portal-sort[open] > summary { border-color: rgba(24,28,31,.28); color: #16191c; }
.portal-sort-popover {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 200px; z-index: 60;
  display: flex; flex-direction: column; padding: 6px 0;
  border-radius: var(--r-md); background: #fff; color: #1c1f22;
  box-shadow: 0 16px 38px rgba(10,19,13,.32);
}
.portal-sort-popover a { padding: 8px 16px; color: #3f464b; font-size: 13px; }
.portal-sort-popover a:hover { background: #f4f5f7; text-decoration: none; }
.portal-sort-popover a[aria-current="true"] { color: var(--ink); font-weight: 600; }
.portal-tool { flex: none; border: 1px solid rgba(24,28,31,.13); border-radius: 5px; background: #fff; padding: 9px 15px; color: #4a5257; font: 500 12.5px/1.4 var(--sans); box-shadow: var(--lift-1); cursor: pointer; }
.portal-tool:hover:not(:disabled) { border-color: rgba(24,28,31,.28); color: #16191c; text-decoration: none; }
.portal-tool:disabled { opacity: .45; cursor: not-allowed; }
.portal-tool-strong { color: #16191c; font-weight: 600; }
.portal-count strong { color: #16191c; }
.portal-favourite { position: absolute; top: 9px; right: 9px; width: 30px; height: 30px; display: grid; place-items: center; border: 0; border-radius: 50%; background: rgba(255,255,255,.92); color: #4a5257; font-size: 17px; cursor: pointer; box-shadow: 0 1px 5px rgba(0,0,0,.12); }
.portal-media-price { display: none; position: absolute; left: 9px; top: 9px; padding: 5px 9px; border-radius: 5px; background: rgba(255,255,255,.94); color: #16191c; font-size: 11px; font-weight: 600; }
/* The map is a mode, not a block on the page. A map taller than the
   window is a trap: the page has to scroll to reveal the rest of it, but
   the wheel and the touch belong to Leaflet, so it never scrolls and the
   pins below the fold cannot be reached. Every map-first site answers
   this the same way — while the map is open the document stops
   scrolling and the map is exactly the window. One scroll container,
   so there is no gesture for the two of them to fight over.

   Height comes from the flex chain below rather than a viewport
   calculation minus the chrome: the filter bar's own height changes
   when the chips open, and any hard-coded offset is wrong the moment it
   does. `dvh` and not `vh` because on a phone `vh` measures the window
   with the address bar rolled away, which puts the bottom of the map
   under it. */
.listing-map { position: relative; z-index: 0; isolation: isolate; flex: 1; min-height: 240px; overflow: hidden; overscroll-behavior: contain; border-radius: 7px; background: #dfe5dd; box-shadow: var(--lift-2); }
/* The window is handed to <body>, which is already a flex column, and
   the map takes whatever the header and the filter bar leave. Nothing
   here subtracts a measurement: the first version took the viewport
   minus `--header-h`, which assumes the header is exactly that tall —
   on a desktop the search pill makes it taller, so the map hung past
   the bottom edge and took the popup card with it. Leftover space
   cannot be wrong the way a subtraction can. */
body.showing-listing-map { overflow: hidden; height: 100vh; height: 100dvh; }
/* <main> is in the chain too. It is the flex child of <body>, and
   `.portal-main` sits inside it — leaving it out broke the run of
   heights silently: `flex: 1` further down had no definite space to
   claim, so the map fell back on its `min-height` and drew a 240px
   strip. `flex-basis: 0` rather than `auto` so it takes the leftover
   room instead of starting from its content's height, and `min-height:
   0` because a flex item will not shrink below its content otherwise. */
body.showing-listing-map main { display: flex; flex-direction: column; flex: 1 1 0; min-height: 0; padding: 0; }
body.showing-listing-map .portal-main,
body.showing-listing-map .portal-main > .portal-shell { display: flex; flex-direction: column; min-height: 0; }
body.showing-listing-map .portal-main { flex: 1 1 0; height: auto; padding-bottom: 0; }
body.showing-listing-map .portal-main > .portal-shell { flex: 1; }
/* Unreachable while the page cannot scroll, and it would otherwise take
   its height out of the map. */
body.showing-listing-map .site-footer { display: none; }
/* The count and the active filters are already on the map, in the
   floating bar at its top left; repeating them here would cost the map
   a line of height to say nothing new. */
body.showing-listing-map .portal-title-row { display: none; }
body.showing-listing-map .portal-sticky { flex: none; }
.listing-map-error { position: absolute; left: 50%; top: 50%; z-index: 700; transform: translate(-50%,-50%); max-width: 320px; padding: 12px 16px; border: 1px solid var(--danger-line); border-radius: 6px; background: var(--danger-bg); color: var(--danger); font-size: 13px; text-align: center; }
#listing-map-canvas { position: absolute; inset: 0; z-index: 1; }
.listing-map-top { position: absolute; left: 12px; top: 12px; z-index: 500; display: flex; align-items: center; gap: 8px; }
.listing-map-top span { padding: 9px 13px; border: 1px solid rgba(24,28,31,.12); border-radius: 5px; background: #fff; color: #4a5257; font-size: 12px; box-shadow: var(--lift-2); }
.listing-price-pin { display: block; transform: translate(-50%,-50%); padding: 6px 10px; border: 1px solid rgba(24,28,31,.18); border-radius: 5px; background: #fff; color: #16191c; font: 600 12px/1 var(--sans); box-shadow: 0 2px 7px rgba(20,24,27,.24); white-space: nowrap; }
.listing-price-pin.is-active { border-color: #16191c; background: #16191c; color: #fff; }
.listing-map-card { position: absolute; left: 12px; bottom: 12px; z-index: 600; width: 310px; overflow: hidden; border-radius: 7px; background: #fff; box-shadow: 0 12px 34px rgba(20,24,27,.28); }
/* Over the image, where there is always something dark enough behind it
   — the empty-photo panel is grey, so the button carries its own white
   disc rather than trusting the backdrop. */
/* One icon at a time, naming the mode the button leads to. */
.portal-map-toggle [data-map-icon="list"],
body.showing-listing-map .portal-map-toggle [data-map-icon="map"] { display: none; }
body.showing-listing-map .portal-map-toggle [data-map-icon="list"] { display: block; }
.listing-map-card-close {
  position: absolute; right: 8px; top: 8px; z-index: 2;
  width: 28px; height: 28px; display: grid; place-items: center;
  padding: 0; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.94); color: #16191c; cursor: pointer;
  box-shadow: 0 1px 5px rgba(20,24,27,.24);
}
.listing-map-card img, .listing-map-card-empty { width: 100%; aspect-ratio: 16/9; object-fit: cover; display: flex; align-items: center; justify-content: center; background: #dfe2e5; color: #7d848a; font-size: 12px; }
.listing-map-card-body { padding: 13px 15px 15px; }
.listing-map-card-body small { color: #8b8378; }
.listing-map-card-body h2 { margin: 3px 0; font: 600 17px/1.25 var(--sans); }
.listing-map-card-body p { margin: 0 0 12px; color: #7d848a; font-size: 12.5px; }
.listing-map-card-body > div { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; }
.listing-map-card-body > div span span { color: #7d848a; font-size: 11px; }
.listing-map-card-body a { color: #8a6224; font-size: 12.5px; font-weight: 600; }
.listing-topbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.listing-topbar .crumb { margin: 0; }
.listing-actions { display: flex; gap: 8px; }
.listing-actions button { padding: 8px 13px; border: 1px solid var(--portal-line); border-radius: 5px; background: #fff; color: #1c1f22; font: 500 12.5px var(--sans); cursor: pointer; }
.listing-actions button:disabled { opacity: .5; cursor: not-allowed; }
.listing-head { margin-bottom: 18px; }
.listing-head h1 { font-family: var(--sans); font-size: clamp(26px,4vw,34px); font-weight: 600; }
.listing-gallery { grid-template-columns: 1.9fr 1fr; gap: 8px; border-radius: 8px; margin-bottom: 24px; box-shadow: none; }
.listing-gallery-main-wrap { position: relative; min-height: 100%; }
.listing-gallery-main { aspect-ratio: 16/9; border-radius: 8px; }
.listing-gallery-side { gap: 8px; }
.listing-gallery-side img { aspect-ratio: 16/9; border-radius: 6px; }
.listing-gallery-count { position: absolute; left: 12px; bottom: 12px; padding: 5px 10px; border-radius: 5px; background: rgba(255,255,255,.92); color: #4a5257; font-size: 11px; }
.listing-layout { display: grid; grid-template-columns: minmax(0,1fr) 340px; align-items: start; gap: 38px; }
.listing-content { min-width: 0; }
.listing-fact-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }
.listing-fact-chips span { padding: 8px 13px; border: 1px solid var(--portal-line); border-radius: 6px; background: #f3f4f6; color: #16191c; font-size: 12.5px; }
.listing-section { margin-bottom: 30px; }
.listing-section h2 { margin: 0 0 12px; font: 600 19px/1.3 var(--sans); }
.listing-description p { color: #474d52; font-size: 14.5px; line-height: 1.72; }
.amenity-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; margin: 0; padding: 0; list-style: none; }
.amenity-grid li { display: flex; align-items: center; gap: 9px; padding: 10px 0; border-bottom: 1px solid rgba(24,28,31,.08); color: #474d52; font-size: 13.5px; }
.amenity-grid li span { width: 5px; height: 5px; border-radius: 50%; background: #d9a84e; }
.listing-section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 10px; }
.listing-section-head h2 { margin-top: 5px; }
.listing-section-head > span { color: #7d848a; font-size: 12.5px; }
.availability { padding: 18px; border: 1px solid var(--portal-line); border-radius: 8px; background: #fff; box-shadow: var(--lift-2); }
.availability-legend { display: flex; justify-content: flex-end; gap: 16px; margin-bottom: 10px; color: #7d848a; font-size: 11px; }
.availability-legend span { display: flex; align-items: center; gap: 6px; }
.availability-legend i { width: 8px; height: 8px; border-radius: 50%; }
.availability-legend .free { background: #d9a84e; }
.availability-legend .taken { background: rgba(24,28,31,.16); }
.availability-months { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.availability-month h3 { margin: 0 0 9px; text-align: center; font: 600 15px var(--sans); }
.availability-weekdays, .availability-days { display: grid; grid-template-columns: repeat(7,1fr); gap: 2px; }
.availability-weekdays { margin-bottom: 4px; padding: 5px 0; border-radius: 5px; background: #f4f5f7; }
.availability-weekdays span { text-align: center; color: #7d848a; font-size: 10px; font-weight: 600; }
.calendar-day, .calendar-blank { aspect-ratio: 1; }
.calendar-day { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; border: 0; border-radius: 5px; background: transparent; color: #16191c; font-family: var(--sans); cursor: pointer; }
.calendar-day span { font-size: 12px; }
.calendar-day small { color: #9aa1a7; font-size: 8.5px; }
.calendar-day:hover { background: #f3f4f6; }
.calendar-day.is-taken { color: rgba(24,28,31,.26); text-decoration: line-through; cursor: default; }
.calendar-day.is-taken small { color: rgba(24,28,31,.2); }
.calendar-day.is-start, .calendar-day.is-end { background: #16191c; color: #fff; font-weight: 600; }
.calendar-day.is-start small, .calendar-day.is-end small { color: rgba(255,255,255,.65); }
.calendar-day.is-in-range { background: rgba(217,168,78,.22); }
.listing-location { position: relative; height: 190px; overflow: hidden; border: 1px solid var(--portal-line); border-radius: 8px; }
.listing-location svg { width: 100%; height: 100%; }
.listing-location > span { position: absolute; left: 12px; bottom: 12px; padding: 7px 12px; border: 1px solid var(--portal-line); border-radius: 5px; background: rgba(255,255,255,.94); color: #5b6166; font-size: 11.5px; }
.booking-aside { position: sticky; top: 92px; }
.booking-card { padding: 18px; border: 1px solid rgba(24,28,31,.13); border-radius: 8px; background: #fff; box-shadow: var(--lift-2); }
.booking-price { display: flex; align-items: baseline; gap: 7px; margin-bottom: 14px; }
.booking-price strong { color: #16191c; font-size: 22px; }
.booking-price span { color: #7d848a; font-size: 12px; }
.booking-date-grid { display: grid; grid-template-columns: 1fr 1fr; overflow: hidden; border: 1px solid var(--portal-line-strong); border-radius: 6px; }
.booking-card form > label, .booking-date-grid label { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 9px 11px; color: #9aa1a7; font-size: 9px; letter-spacing: .09em; text-transform: uppercase; }
.booking-date-grid label:first-child { border-right: 1px solid var(--portal-line); }
.booking-card input[type="date"], .booking-card input[type="number"] { min-height: 0; padding: 0; border: 0; border-radius: 0; font-size: 13px; letter-spacing: 0; }
.booking-guests { margin: 7px 0 12px !important; border: 1px solid var(--portal-line-strong); border-radius: 6px; }
.booking-card .portal-search-btn { width: 100%; min-height: 44px; margin: 0 0 12px; }
.booking-card .note-quiet, .booking-card .msg { margin-top: 12px; }
.booking-card .breakdown { margin: 14px 0; }
.listing-mobile-cta { display: none; }
.listing-occupied { margin-top: 14px; }

@media (max-width: 899px) {
  .portal-login { display: none; }
  .portal-header-actions { margin-left: auto; gap: 10px; }
  /* Icon-only, and a flex box with one visible child so the glyph
     actually lands in the middle. The old rule was a grid whose second
     item was the label's text node, which took a row of its own and
     shifted the icon up. */
  .portal-menu-label { display: none; }
  .portal-menu summary { width: 38px; height: 38px; display: flex; align-items: center; justify-content: center; gap: 0; }
  .portal-menu-burger { width: 22px; height: 22px; }
  /* Full-height sheet off the right edge, with the title bar and
     sign-in row the reference gives the phone drawer. */
  .portal-menu-popover {
    top: 0; right: 0; bottom: 0; width: min(90vw, 360px);
    max-height: none; border-radius: 0;
  }
  .portal-menu-scrim { background: rgba(10,19,13,.42); }
  .portal-menu-head { display: flex; }
  .portal-media-price { display: block; }
  .listing-layout { display: block; }
  .booking-aside { position: static; margin-top: 24px; }
  .listing-mobile-cta { position: sticky; bottom: 10px; z-index: 28; display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 18px; padding: 10px 10px 10px 15px; border-radius: 7px; background: #fff; color: #16191c; box-shadow: 0 6px 24px rgba(20,24,27,.2); }
  .listing-mobile-cta:hover { text-decoration: none; }
  .listing-mobile-cta b { padding: 11px 20px; border-radius: 5px; background: #d9a84e; }
}

@media (max-width: 719px) {
  body.portal { --header-h: 60px; }
  .portal-logo img { height: 29px; }
  /* Equal ends: the logo and the burger are both fixed, the search
     takes whatever is left between them and shrinks to fit rather than
     pushing either one against an edge. */
  /* Both ends measured from what you can see, not from the boxes.
     Left: the shell's 16px, plus ~1.6px of transparent margin inside
     the logo's own viewBox at this height (12.6 units x 29/234).
     Right: the shell's 16px, less the 8px of slack around the burger's
     22px glyph inside its 38px tap target. -6px lands the icon at
     ~17.6px, level with the logo's first ink. */
  .portal-header-inner { gap: 10px; }
  .portal-header-actions { flex: none; gap: 6px; margin-right: 0px; }
  /* Shrink-to-fit rather than fill: the pill takes the width its own
     text needs and no more, so the logo keeps its room. Tapping it
     opens the full card, which is the "expand" — the pill itself only
     ever shows the summary. */
  .portal-header-search { flex: 0 1 auto; min-width: 0; }
  .portal-search-summary { padding: 9px 12px; font-size: 13px; }
  .portal-search-summary-dest { display: none; }
  /* The burger box is square and centred, so its glyph lands on the
     same centre line as the logo and the search pill. */
  .portal-menu summary { width: 32px; height: 32px; padding: 0; }
  .portal-main { padding-top: 14px; }
  .portal-search-bar, .portal-search-group { gap: 0; }
  .portal-destination { border-bottom: 1px solid rgba(28,31,34,.07); }
  .portal-filterbar { margin-bottom: 12px; }
  /* The reference's phone bar carries the three controls and no count —
     the same number is already on the line directly beneath it, and it
     is the widest thing competing for the row. */
  .portal-filterbar-count { display: none; }
  .portal-title-row { margin-top: 2px; }
  .portal-card-body { padding: 11px 13px 12px; }
  .portal-card-action { display: none; }
  .portal-card-foot { padding-top: 7px; }
  .listing-map { margin: 0 -4px; }
  .listing-map-top span { display: none; }
  /* Centred rather than pinned to the bottom edge. The map is only as
     tall as the window here, and a card anchored to the bottom ran out
     of room — its price and its link, the two things the card exists
     for, fell past the edge and were clipped away. The middle is the one
     place that cannot run out, whatever the card ends up containing. The
     × is what dismisses it, so covering the map is no longer a trap. */
  .listing-map-card {
    left: 10px; right: 10px; bottom: auto; top: 50%; width: auto;
    transform: translateY(-50%);
    display: grid; grid-template-columns: 112px 1fr;
  }
  .listing-map-card img, .listing-map-card-empty { height: 100%; aspect-ratio: auto; }
  .listing-topbar { align-items: flex-start; }
  .listing-actions button:first-child { display: none; }
  .listing-head h1 { font-size: 25px; }
  .listing-gallery { display: block; margin-left: -16px; margin-right: -16px; border-radius: 0; }
  .listing-gallery-main { aspect-ratio: 4/3; border-radius: 0; }
  .listing-gallery-side { display: none; }
  .amenity-grid, .availability-months { grid-template-columns: 1fr; }
  .availability-months .availability-month + .availability-month { display: none; }
  .availability { margin-left: -4px; margin-right: -4px; padding: 14px 10px; }
  .listing-section-head { align-items: flex-start; flex-direction: column; gap: 4px; }
  .availability-legend { justify-content: flex-start; }
  .booking-card { padding: 15px; }
}

/* ---- Search embedded in the header (reference: "Portal A Zoznam") --- */
/* In the header at every width, as the reference has it. Wide screens
   lay the fields out in a row beside the logo; narrow ones collapse the
   whole thing behind a one-line summary and drop the expanded card out
   of the header as an overlay, so the bar keeps the fixed height the
   sticky filter row is measured against. */
.portal-header-search { position: static; }
.portal-search-summary {
  display: flex; align-items: center; gap: 8px; width: 100%; min-width: 0;
  padding: 9px 14px; border: none; border-radius: var(--r-md);
  background: #fff; color: #16191c; cursor: pointer;
  font-family: inherit; font-size: 13.5px; text-align: left;
}
.portal-search-summary > svg { flex: none; }
/* min-width:0 on both the button and the text: a flex item will not
   shrink below its own min-content by default, so without these the
   nowrap summary sets a floor on the header's width instead of
   ellipsising, and a long one pushes the row wider than the screen. */
.portal-search-summary > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* The date pair inside one field cell: two native inputs reading as a
   single range, the way the reference's one date control does. */
/* `display:flex` outranks the UA sheet's `[hidden] { display: none }`,
   so the attribute needs restating — without this the native inputs stay
   visible next to the widget's own trigger. */
.portal-date-pair[hidden] { display: none; }
.portal-date-pair { display: flex; align-items: center; gap: 4px; min-width: 0; }
.portal-date-pair input { flex: 1; min-width: 0; }
.portal-date-pair > span { flex: none; color: var(--faint); }

.portal-tool { display: inline-flex; align-items: center; gap: 8px; }
.portal-filter-state { display: flex; align-items: baseline; gap: 10px; color: var(--faint); font-size: 12px; }
.portal-filter-state a { color: var(--muted); text-decoration: underline; }
.portal-filter-state a:hover { color: var(--ink); }

/* ---- The header search on a phone -----------------------------------
   The summary is the whole control until it is tapped; the card then
   drops out of the header as an overlay so the bar's height — and the
   filter row stuck to it — does not move. */
@media (max-width: 1199px) {
  .portal-header-inner { gap: 12px; }
  .portal-header-search { flex: 1 1 auto; min-width: 0; }
  .portal-header-search.portal-search {
    background: none; border: none; box-shadow: none; padding: 0; margin: 0;
  }
  .portal-header-search .portal-search-bar {
    display: flex; flex-direction: column; gap: 8px;
  }
  /* The corners are rounded on the end fields rather than by clipping
     the group: `overflow: hidden` here also clips the date popover,
     which hangs out of this box by design. */
  .portal-header-search .portal-search-group {
    display: flex; flex-direction: column; gap: 0;
    background: #fff; border-radius: var(--r-md);
  }
  .portal-header-search .portal-field {
    padding: 9px 14px; border-right: none;
    border-bottom: 1px solid rgba(24,28,31,.1);
  }
  .portal-header-search .portal-field:first-child { border-radius: var(--r-md) var(--r-md) 0 0; }
  .portal-header-search .portal-field:last-child { border-bottom: none; border-radius: 0 0 var(--r-md) var(--r-md); }
  .portal-header-search .portal-search-btn { width: 100%; padding: 13px; border-radius: var(--r-md); }

  /* Collapsed is the default once the script has taken over: the
     summary shows, the card is an overlay hanging off the header. */
  .portal-header-search.is-collapsed .portal-search-bar { display: none; }
  .portal-header-search.is-expanded .portal-search-summary { display: none; }
  .portal-header-search.is-expanded .portal-search-bar {
    position: absolute; left: 0; right: 0; top: 100%; z-index: 45;
    padding: 0 16px 14px;
    background: linear-gradient(147deg, #1c3627 0%, #132318 58%, #0a130d 100%);
    box-shadow: 0 12px 24px rgba(10,19,13,.28);
  }

  /* The reference's phone bar: the sort keeps only its current value,
     the map toggle keeps only its icon. */
  .portal-sort-prefix { display: none; }
  .portal-map-toggle [data-map-toggle-label] { display: none; }
  .portal-map-toggle { padding: 9px 12px; }
}

@media (min-width: 1200px) {
  .portal-header-inner { gap: 28px; }
  .portal-header-search { display: block; flex: 1 1 auto; min-width: 0; }
  .portal-search-summary { display: none; }

  /* Two boxes with a gap between them, as in the reference: the white
     pill holds the three fields with hairline dividers, and the gold
     button is its own rounded box alongside — not a coloured cell
     inside the pill. The form itself carries neither, so it can hold
     both. `flex-direction` must be restated on the bar: the base rule
     stacks it into a column for phones, and only the ≥720px grid rule
     overrode that, which this row does not use. */
  .portal-header-search.portal-search {
    background: none; border: none; box-shadow: none;
    padding: 0; margin: 0; min-width: 0;
  }
  .portal-header-search .portal-search-bar {
    display: flex; flex-direction: row; align-items: stretch; gap: 6px; min-width: 0;
  }
  .portal-header-search .portal-search-group {
    display: flex; flex-direction: row; align-items: stretch; flex: 1; min-width: 0;
    background: #fff; border: 1px solid rgba(10,19,13,0.2); border-radius: var(--r-md);
  }
  .portal-header-search .portal-field {
    flex: 1; min-width: 0; padding: 7px 14px; border-bottom: none;
    border-right: 1px solid rgba(24,28,31,0.1); border-radius: 0;
  }
  .portal-header-search .portal-field:last-child { border-right: none; }
  .portal-header-search .portal-destination { flex: 1.3; }
  .portal-header-search .portal-dates { flex: 1.5; }
  .portal-header-search .portal-destination strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .portal-header-search .portal-search-btn {
    flex: none; padding: 0 22px; border-radius: var(--r-md); margin: 0;
  }
  /* Icon-only on desktop, exactly as the reference hides the label. */
  .portal-header-search .portal-search-btn-label { display: none; }
}

/* ---- Info pages -------------------------------------------------------
   Legal, FAQ, Kontakt, O obci, Kam na výlet, Oblúbené — the six pages
   that share one sidebar+content shell in the "Typové stránky" reference.
   Same tokens as everywhere else on the portal (--r-md, --lift-2); the
   236px sidebar and the measurements below are the reference's own.
--------------------------------------------------------------------- */

.info-shell {
  max-width: 1180px; width: 100%; margin: 0 auto; box-sizing: border-box;
  padding: 34px 16px 56px;
  display: grid; grid-template-columns: 1fr; gap: 24px; align-items: start;
}
@media (min-width: 900px) {
  .info-shell { grid-template-columns: 236px minmax(0, 1fr); gap: 44px; padding: 34px 32px 56px; }
}

.info-sidebar {
  display: flex; flex-direction: column; gap: 20px;
  background: #fff; border-radius: var(--r-md); box-shadow: var(--lift-2);
  padding: 18px 4px 20px;
}
@media (min-width: 900px) { .info-sidebar { position: sticky; top: 20px; } }
.info-sidebar-group { display: flex; flex-direction: column; gap: 2px; }
.info-sidebar-title {
  padding: 0 18px 7px; font-size: 11px; font-weight: 700;
  letter-spacing: 0.09em; text-transform: uppercase; color: #9aa1a7;
}
.info-sidebar-link {
  text-align: left; background: none; border: none;
  border-left: 2px solid transparent; padding: 8px 18px;
  font-family: inherit; font-size: 13.5px; color: var(--body);
  transition: background .14s ease;
}
.info-sidebar-link:hover { background: #f4f5f7; text-decoration: none; }
.info-sidebar-link[aria-current="page"] {
  background: #f4f5f7; border-left-color: var(--forest);
  color: var(--ink); font-weight: 600;
}

.info-content { display: flex; flex-direction: column; gap: 22px; min-width: 0; }
.info-header { display: flex; flex-direction: column; gap: 9px; }
.info-eyebrow {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: #9aa1a7;
}
.info-title {
  margin: 0; font-size: 30px; font-weight: 600; letter-spacing: -0.022em;
  line-height: 1.2; color: var(--ink); text-wrap: pretty;
}
.info-lede { font-size: 14px; line-height: 1.6; color: var(--muted); max-width: 640px; }

/* Legal text and O obci's descriptive blocks share the same card. */
.legal-card, .village-blocks {
  background: #fff; border-radius: var(--r-md); box-shadow: var(--lift-2);
  padding: 32px 20px 38px; max-width: 760px;
}
@media (min-width: 600px) { .legal-card, .village-blocks { padding: 32px 36px 38px; } }
.legal-meta {
  display: flex; align-items: center; gap: 14px;
  padding-bottom: 20px; margin-bottom: 8px;
  border-bottom: 1px solid var(--portal-line); font-size: 12.5px; color: var(--muted);
}
.legal-meta-sep { width: 1px; height: 12px; background: var(--portal-line-strong); }
.legal-body h3, .village-block h2 {
  margin: 14px 0 8px; font-size: 16.5px; font-weight: 600;
  letter-spacing: -0.01em; color: var(--ink);
}
.legal-body h3:first-child, .village-block:first-child h2 { margin-top: 0; }
.legal-body p, .legal-body li, .village-block p {
  margin: 0 0 8px; font-size: 14.5px; line-height: 1.72; color: var(--body); text-wrap: pretty;
}
.legal-body ul { margin: 0 0 8px; padding-left: 20px; }
.village-block { padding: 14px 0; }
.village-block:not(:last-child) { border-bottom: 1px solid var(--portal-line); }

/* FAQ */
.faq-list { display: flex; flex-direction: column; gap: 8px; max-width: 760px; }
.faq-item { background: #fff; border-radius: var(--r-md); box-shadow: var(--lift-2); overflow: hidden; }
.faq-item summary {
  list-style: none; display: flex; align-items: center; gap: 14px;
  padding: 17px 20px; font-size: 14.5px; font-weight: 600; color: var(--ink); cursor: pointer;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary svg { flex: none; transition: transform .18s ease; }
.faq-item[open] summary svg { transform: rotate(180deg); }
.faq-item-body { padding: 0 20px 18px; font-size: 14px; line-height: 1.7; color: var(--body); text-wrap: pretty; }
.faq-cta {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: var(--forest); border-radius: var(--r-md); padding: 20px 22px; margin-top: 10px;
  color: #e7e2d3; font-size: 14px; line-height: 1.55;
}
.faq-cta a { flex: none; background: var(--gold-cta, #d9a84e); color: #16191c; border-radius: 5px; padding: 10px 18px; font-size: 13.5px; font-weight: 600; }
.faq-cta a:hover { text-decoration: none; }

/* Kontakt */
.contact-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; max-width: 900px; }
@media (min-width: 760px) { .contact-grid { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); } }
.contact-form-card, .contact-aside-card {
  background: #fff; border-radius: var(--r-md); box-shadow: var(--lift-2);
  padding: 26px 20px 28px; display: flex; flex-direction: column; gap: 16px;
}
@media (min-width: 480px) { .contact-form-card, .contact-aside-card { padding: 26px 28px 28px; } }
.contact-field { display: flex; flex-direction: column; gap: 6px; }
.contact-field-row { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 480px) { .contact-field-row { grid-template-columns: 1fr 1fr; } }
.contact-field span:first-child { font-size: 12.5px; font-weight: 600; color: var(--body); }
.contact-field input, .contact-field select, .contact-field textarea {
  box-sizing: border-box; width: 100%; background: #fff;
  border: 1px solid var(--portal-line-strong); border-radius: 5px;
  padding: 10px 12px; font-family: inherit; font-size: 14px; color: var(--ink);
}
.contact-field textarea { resize: vertical; line-height: 1.6; }
.contact-consent { display: flex; align-items: flex-start; gap: 9px; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.contact-consent input { margin: 2px 0 0; width: 15px; height: 15px; accent-color: var(--forest); flex: none; }
.contact-aside-row { display: flex; flex-direction: column; gap: 3px; }
.contact-aside-row span:first-child { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #9aa1a7; }
.contact-aside-row span.value { font-size: 14.5px; font-weight: 600; color: var(--ink); }
.contact-aside-row span.note { font-size: 12.5px; color: var(--muted); }
.contact-map-placeholder {
  height: 190px; border-radius: var(--r-md); background: var(--portal-field);
  border: 1px dashed var(--portal-line-strong);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  color: #9aa1a7; font-size: 12px;
}

/* O obci */
.village-panorama {
  height: 220px; border-radius: var(--r-md); background: var(--portal-field);
  border: 1px dashed var(--portal-line-strong);
  display: flex; align-items: center; justify-content: center;
  color: #9aa1a7; font-size: 12.5px;
}
@media (min-width: 600px) { .village-panorama { height: 300px; } }
.village-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (min-width: 600px) { .village-facts { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.village-fact { background: #fff; border-radius: var(--r-md); box-shadow: var(--lift-2); padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; }
.village-fact-value { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); }
.village-fact-label { font-size: 12.5px; color: var(--muted); }

/* Kam na výlet */
.trip-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 640px) { .trip-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 980px) { .trip-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.trip-card { background: #fff; border-radius: var(--r-md); overflow: hidden; box-shadow: var(--lift-2); display: flex; flex-direction: column; }
.trip-card-photo {
  height: 150px; background: var(--portal-field); border-bottom: 1px dashed var(--portal-line-strong);
  display: flex; align-items: center; justify-content: center; color: #9aa1a7; font-size: 11.5px;
}
.trip-card-body { padding: 15px 17px 17px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.trip-card-kind { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #9aa1a7; }
.trip-card-name { font-size: 15.5px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
.trip-card-desc { font-size: 13px; line-height: 1.6; color: var(--muted); flex: 1; text-wrap: pretty; }
.trip-card-meta {
  display: flex; align-items: center; gap: 10px; padding-top: 9px; margin-top: 3px;
  border-top: 1px solid var(--portal-line); font-size: 12.5px; color: var(--body);
}
.trip-card-meta-sep { width: 1px; height: 11px; background: var(--portal-line-strong); }

/* Oblúbené */
.favourites-empty {
  background: #fff; border-radius: var(--r-md); box-shadow: var(--lift-2);
  padding: 48px 24px 54px; display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center;
}
@media (min-width: 480px) { .favourites-empty { padding: 64px 40px 70px; } }
.favourites-empty-icon { width: 56px; height: 56px; border-radius: 28px; background: #f4f5f7; display: flex; align-items: center; justify-content: center; }
.favourites-empty-title { font-size: 19px; font-weight: 600; letter-spacing: -0.015em; color: var(--ink); }
.favourites-empty-text { font-size: 14px; line-height: 1.65; color: var(--muted); max-width: 400px; }

/* One heart, two states — real now rather than a disabled placeholder. */
.portal-favourite[aria-pressed="true"] { color: #c0392b; }
.portal-favourite[aria-pressed="true"]::before { content: "♥"; }
.portal-favourite[aria-pressed="false"]::before { content: "♡"; }
.listing-map-card-favourite {
  position: absolute; left: 8px; top: 8px; z-index: 2;
  width: 28px; height: 28px; display: grid; place-items: center;
  padding: 0; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.94); color: #4a5257; cursor: pointer;
  box-shadow: 0 1px 5px rgba(20,24,27,.24); font-size: 14px;
}
.listing-map-card-favourite[aria-pressed="true"] { color: #c0392b; }

/* 404 */
.not-found { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; padding: 72px 20px 96px; text-align: center; }
.not-found-title { margin: 0; font-size: 32px; font-weight: 600; letter-spacing: -0.025em; color: var(--ink); max-width: 520px; text-wrap: pretty; }
.not-found-text { font-size: 14.5px; line-height: 1.65; color: var(--muted); max-width: 420px; text-wrap: pretty; }
.not-found-links { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 20px; margin-top: 6px; font-size: 13.5px; }
.not-found-links a { color: var(--forest); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
