/* ============================================================================================
   Journey pages - combined stylesheet
   (AccommodationItem.cshtml - the hotel detail page - and ProductPage.cshtml - "Customise your
   holiday" - both link this one file now instead of their own separate AccommodationItemPage.css
   / ProductPage-v2.css files).

   This is a literal merge, not a rewrite: everything below is exactly what each file already
   had, selector-for-selector, just concatenated into one physical file so there's a single
   place to look instead of two. Every selector in both halves is still scoped to its own page
   root (.aip-page.../.pp-page...), so nothing in one half can affect the other page - each
   page's markup only ever matches its own half's classes.

   ---- Part 1: hotel detail page (was AccommodationItemPage.css) ----
   ============================================================================================ */

.aip-page {
  --aip-primary: #02aaa9;
  --aip-primary-dark: #218887;
  --aip-primary-deep: #104443;
  --aip-primary-mist: #def6f5;
  --aip-gold: #febb02;
  --aip-coral: #f9706a;
  --aip-green: #23ae24;
  --aip-green-text: #008009;
  --aip-green-soft: #dff6e1;
  --aip-red-soft: #ffe7e8;
  --aip-text: #3c4e5a;
  --aip-text-muted: #707070;
  --aip-ink: #141515;
  --aip-border: #d8e0e0;
  --aip-page-bg: #f3f6f6;
  --aip-font: "Lato", "Segoe UI", sans-serif;
  --aip-font-display: "Montserrat", "Lato", sans-serif;

  /* Base typography for every .aip-* component on this page, regardless of whether it sits
     inside an .aip-wrap (the anchors nav, book-dock, and the modals - siblings of .aip-wrap,
     not descendants - all need this too, not just the wrapped content). */
  font-family: var(--aip-font);
  color: var(--aip-text);
  line-height: 1.45;

  /* The prototype's own body background (search-results/styles.css, which hotel-product
     @imports) - two faint radial glows over a light grey-teal wash, not plain white. This is
     what makes every white .aip-panel/.aip-summary card actually read as a card instead of
     blending into the page - was missing entirely before since nothing had set it anywhere. */
  background:
    radial-gradient(1200px 420px at 10% -10%, rgba(2, 170, 169, 0.16), transparent 55%),
    radial-gradient(900px 380px at 100% 8%, rgba(254, 187, 2, 0.14), transparent 50%), var(--aip-page-bg);
}

.aip-page *,
.aip-page *::before,
.aip-page *::after {
  box-sizing: border-box;
}

/* Same global element resets the prototype applies via its own *, img, button/input/select, a,
   h1/h2/h3 rules - scoped to .aip-page (not the real global * selector) so nothing outside this
   page is touched. Matters most for rich-text content (Model.OverviewText,
   Model.HotelDescription, special-offer descriptions) - raw <a>/<h2>/<h3> tags coming straight
   out of the CMS with no class of their own, which would otherwise fall back to the site's own
   global styles (a different font/link colour) instead of this page's design. */
.aip-page img {
  max-width: 100%;
  display: block;
}

.aip-page button,
.aip-page input,
.aip-page select {
  font: inherit;
}

.aip-page h1,
.aip-page h2,
.aip-page h3 {
  margin: 0;
  color: var(--aip-primary-deep);
}

.aip-wrap {
  max-width: 1220px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ---- Breadcrumb / back link ---- */

.aip-crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 16px 0 10px;
  margin: 0;
  font-size: 13px;
  color: var(--aip-text-muted);
}

.aip-crumbs a {
  font-weight: 700;
  color: var(--aip-text-muted);
  text-decoration: none;
}

.aip-crumbs a:hover {
  color: var(--aip-primary-dark);
}

.aip-back-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--aip-primary);
  text-decoration: none;
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
}

.aip-back-link:hover {
  text-decoration: underline;
}

/* ---- Identity header ---- */

.aip-identity {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  align-items: flex-start;
  margin-bottom: 16px;
}

.aip-identity h1 {
  margin: 0 0 8px;
  font-family: var(--aip-font);
  font-size: clamp(26px, 3vw, 34px);
  font-weight: 800;
  color: var(--aip-primary-deep);
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.aip-stars {
  margin-left: 8px;
  font-size: 15px;
  letter-spacing: 1px;
  color: var(--aip-primary);
}

.aip-place {
  margin: 0;
  font-size: 15px;
  color: var(--aip-text-muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.aip-place a {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-weight: 700;
  color: var(--aip-primary);
  text-decoration: none;
}

.aip-place a:hover {
  text-decoration: underline;
}

.aip-place svg {
  width: 13px;
  height: 13px;
}

.aip-place__dot {
  color: var(--aip-border);
}

.aip-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.aip-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 700;
  border-radius: 999px;
  padding: 6px 11px;
  line-height: 1.2;
  background: var(--aip-primary-mist);
  color: var(--aip-primary-deep);
  border: 1px solid #bfe8e6;
}

.aip-pill i {
  font-size: 11px;
}

/* ---- Tripadvisor card ---- */

.aip-ta {
  flex-shrink: 0;
  display: flex;
  flex-direction: row;
  align-items: start;
  text-align: left;
  padding: 14px 16px;
  border-radius: 14px;
  background: #fff;
  border: 1px solid var(--aip-border);
  box-shadow: 0 8px 20px rgba(16, 68, 67, 0.06);
}

.aip-ta__score {
  margin: 0;
  font-family: var(--aip-font-display);
  font-size: 32px;
  font-weight: 800;
  line-height: 1;
  color: #00aa6c;
}

.aip-ta__brand {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  color: #00aa6c;
}

.aip-ta__owl {
  width: 18px;
  height: 18px;
}

.aip-ta__row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
}

.aip-ta__rating {
  display: block;
  height: 18px;
  width: auto;
}

.aip-ta__meta {
  font-size: 12px;
  color: var(--aip-text-muted);
  white-space: nowrap;
}

/* ---- Gallery ---- */

.aip-gallery {
  position: relative;
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  grid-template-areas: "hero tiles";
  gap: 6px;
  margin-bottom: 8px;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 12px 32px rgba(16, 68, 67, 0.12);
}

.aip-gallery__hero {
  grid-area: hero;
  min-height: 520px;
}

.aip-gallery__tiles {
  grid-area: tiles;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 6px;
}

.aip-gallery__flags,
.aip-photos-btn {
  grid-area: hero;
}

.aip-gallery__hero,
.aip-gallery__tiles button {
  position: relative;
  border: 0;
  padding: 0;
  background: #e7f2f2;
  cursor: pointer;
  display: block;
  overflow: hidden;
}

.aip-gallery__tiles button {
  min-height: 207px;
}

/* Absolute-fill instead of the img's own width/height:100% - percentage heights on an <img>
   only resolve against a parent with a self-established definite height, which a CSS grid
   item's own min-height (as opposed to a real height) doesn't reliably give it, and these
   buttons only had min-height - was leaving each real photo at its own natural aspect ratio
   instead of covering the tile, with visible background gaps below. */
.aip-gallery img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100% !important;
  object-fit: cover;
  transition: transform 0.35s ease;
}

.aip-gallery__hero:hover img,
.aip-gallery__tiles button:hover img {
  transform: scale(1.04);
}

.aip-gallery__flags {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

.aip-flag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
  padding: 5px 8px;
  border-radius: 4px;
  line-height: 1;
  background: var(--aip-primary-deep);
}

.aip-flag--deal {
  background: var(--aip-green-text);
}

.aip-photos-btn {
  position: absolute;
  left: auto;
  right: 12px;
  bottom: 12px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 8px 14px;
  border: 0;
  border-radius: 999px;
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  color: #fff;
  background: rgba(16, 68, 67, 0.86);
  cursor: pointer;
}

.aip-photos-btn:hover {
  background: var(--aip-primary-deep);
}

.aip-photos-btn svg {
  width: 16px;
  height: 16px;
}

/* ---- Sticky hand-off: search bar, then anchor nav ----
   .aip-search-wrapper's containing block is .aip-hero-sticky-zone (AccommodationItem.cshtml) -
   a plain wrapper spanning the search bar + identity header + gallery, i.e. everything up to
   .aip-anchors. That gives .aip-search-wrapper room to stay pinned at top:0 through all of that
   content; it can't stick past its own containing block's bottom edge, so it releases and scrolls
   away at the exact scroll position where .aip-anchors's natural (in-flow) position arrives at
   the top - which is precisely where .aip-hero-sticky-zone ends, since .aip-anchors is its very
   next sibling. .aip-anchors's own sticky top:0 then catches it right there, with no gap or
   overlap. */
.aip-search-wrapper {
  position: sticky;
  top: 0;
  z-index: 26;
  background: linear-gradient(180deg, #176e6d 0 36px, transparent 36px);
}

/* ---- On-page anchor nav ---- */

.aip-anchors {
  position: sticky;
  top: 0;
  z-index: 25;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--aip-border);
  margin: 8px 0 22px;
}

.aip-anchors__inner {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}

.aip-anchors__inner::-webkit-scrollbar {
  display: none;
}

.aip-anchors a {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 700;
  color: var(--aip-text);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}

.aip-anchors svg {
  width: 18px;
  height: 18px;
}

.aip-anchors a:hover,
.aip-anchors a.is-on {
  color: var(--aip-primary-dark);
}

.aip-anchors a.is-on {
  border-bottom-color: var(--aip-primary);
  color: var(--aip-primary);
}

/* ============================================================================
   Phase 2 - panel / prose / love / offers / hotel info feature-fold / amenities
   ============================================================================ */

.aip-product {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 24px;
  align-items: start;
  padding-bottom: 48px;
}

.aip-stack {
  display: grid;
  gap: 20px;
  min-width: 0;
}

.aip-panel {
  background: #fff;
  border: 1px solid var(--aip-border);
  border-radius: 16px;
  box-shadow: 0 10px 28px rgba(16, 68, 67, 0.07);
  padding: 24px 26px;
}

.aip-panel h2 {
  margin: 0 0 10px;
  font-family: var(--aip-font);
  font-size: 24px;
  font-weight: 800;
  color: var(--aip-primary-deep);
  letter-spacing: -0.02em;
  line-height: 1.25;
}

.aip-panel h3 {
  margin: 0 0 12px;
  font-size: 17px;
  font-weight: 800;
  color: var(--aip-ink);
  line-height: 1.35;
}

.aip-prose p {
  margin: 0 0 14px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--aip-text);
}

/* .aip-prose p:last-child {
  margin-bottom: 0;
} */

.aip-prose.is-collapsed > :nth-child(n + 3) {
  display: none;
}

.aip-prose h3 {
  margin: 18px 0 10px;
}

.aip-love-title {
  margin: 20px 0 12px;
  font-size: 15px;
  font-weight: 800;
  color: var(--aip-primary-deep);
}

.aip-love {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.aip-love li {
  position: relative;
  padding: 12px 14px 12px 36px;
  border-radius: 12px;
  background: var(--aip-green-soft, #dff6e1);
  font-size: 14px;
  font-weight: 700;
  color: var(--aip-green-text);
  line-height: 1.4;
}

.aip-love li::before {
  content: "\2713";
  position: absolute;
  left: 14px;
  top: 12px;
}

.aip-panel .aip-text-btn {
  margin-top: 8px;
}

.aip-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: #dff6e1;
  color: var(--aip-green-text);
  border: 1px solid #c8e8cc;
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 14px;
  margin: 4px 0 16px;
  line-height: 1.45;
}

.aip-banner svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
}

.aip-banner__lead {
  display: block;
  font-size: 15px;
  font-weight: 800;
  line-height: 1.3;
}

.aip-banner__sub {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.35;
}

.aip-offer-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.aip-offer-row {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--aip-border);
  border-radius: 12px;
  padding: 12px 14px;
  background: var(--aip-page-bg);
  font-size: 14px;
  font-weight: 700;
  color: var(--aip-primary-deep);
}

.aip-offer-row.is-perk {
  color: var(--aip-green-text);
  font-weight: 800;
}

.aip-offer-row__icon {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 8px;
  background: var(--aip-primary-mist);
  color: var(--aip-primary);
}

.aip-offer-row.is-perk .aip-offer-row__icon {
  color: var(--aip-primary);
}

.aip-offer-row__icon svg,
.aip-offer-row__icon i {
  width: 16px;
  height: 16px;
  font-size: 14px;
}

/* :not(.aip-offer-row__icon) - that icon wrapper is also a literal <span>, so the bare "span"
   selector here was matching it too, and (being more specific than .aip-offer-row__icon's own
   width:32px rule) stretching it to flex:1 and sharing the row width with the text instead of
   staying a small fixed icon box. */
.aip-offer-row span:not(.aip-offer-row__icon) {
  min-width: 0;
  flex: 1;
}

.aip-hint {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--aip-text-muted);
}

.aip-panel.aip-feature {
  padding: 0;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(220px, 0.8fr);
  gap: 0;
  align-items: stretch;
}

.aip-feature > div {
  padding: 22px 24px;
}

.aip-feature h2 {
  margin-bottom: 12px;
}

.aip-feature h3 {
  margin-top: -4px;
  font-size: 16px;
  font-weight: 700;
  color: var(--aip-primary);
}

.aip-hl-media {
  position: relative;
  min-height: 280px;
  height: 100%;
  overflow: hidden;
}

.aip-hl-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.aip-amenity-grid {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.aip-amenity-grid li {
  font-size: 13px;
  font-weight: 700;
  padding: 8px 12px;
  border-radius: 999px;
  background: var(--aip-primary-mist);
  color: var(--aip-primary-deep);
}

.aip-panel details {
  margin-top: 16px;
}

.aip-panel summary {
  cursor: pointer;
  font-weight: 800;
  color: var(--aip-primary);
  list-style: none;
}

.aip-panel summary::-webkit-details-marker {
  display: none;
}

.aip-panel summary::after {
  content: " +";
  font-weight: 700;
}

.aip-panel details[open] summary::after {
  content: " \2013";
}

/* Smooth open/close for the amenities <details> (and any other .aip-panel details) - the
   direct non-summary child (the .aip-amenity-grid <ul>, here) is what accommodationItem.js
   animates via inline max-height, transitioning between 0 and its real measured scrollHeight
   rather than a guessed cap, since native <details> content can't be predicted the way the
   Highlights2 fold sections above can. The JS intercepts the summary click, so this is purely
   the transition target - no display:none/[open] toggling happens through CSS here. */
.aip-panel details > :not(summary) {
  overflow: hidden;
  transition: max-height 0.32s ease;
}

.aip-hl-kicker {
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--aip-primary);
}

.aip-hl-lead {
  margin: 0 0 14px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--aip-text);
}

.aip-hl-lead:last-child {
  margin-bottom: 0;
}

.aip-hl-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.aip-hl-cards li {
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--aip-page-bg);
}

.aip-hl-cards li:only-child {
  grid-column: 1 / -1;
}

/* Info Cards - Type 2 (Type dropdown on hotelHighlights2ItemInfoCardItem): single-column
   bordered cards instead of the Type 1 two-up grid above - ported from the prototype's
   .hl-venues. Heading/description styling (strong/span) is identical between the two, so it's
   shared via the selector list rather than duplicated. */
.aip-hl-venues {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.aip-hl-venues li {
  padding: 12px 14px 12px 16px;
  border-radius: 12px;
  background: var(--aip-page-bg);
  border-left: 3px solid var(--aip-primary);
}

.aip-hl-cards strong,
.aip-hl-venues strong {
  display: block;
  margin-bottom: 4px;
  font-size: 13px;
  font-weight: 800;
  color: var(--aip-primary-deep);
  line-height: 1.3;
}

.aip-hl-cards span,
.aip-hl-venues span {
  font-size: 13px;
  line-height: 1.45;
  color: var(--aip-text);
}

.aip-hl-slots {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.aip-hl-slots li {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--aip-primary-mist);
  font-size: 13px;
}

.aip-hl-slots strong {
  font-family: var(--aip-font-display);
  font-size: 12px;
  font-weight: 800;
  color: var(--aip-primary-deep);
}

.aip-hl-slots span {
  color: var(--aip-text);
}

.aip-hl-note {
  margin: 12px 0 0;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 10px;
  background: #f3f3f3;
  border: 1px solid var(--aip-border);
  font-size: 13px;
  line-height: 1.45;
  color: var(--aip-text);
}

.aip-hl-tag {
  flex-shrink: 0;
  margin-top: 1px;
  padding: 2px 7px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--aip-border);
  font-size: 11px;
  font-weight: 800;
  color: var(--aip-primary-deep);
}

/* ============================================================================
   Phase 3 - flight tickets, room cards
   ============================================================================ */

/* Flight ticket card - shared by both pages (was the .aip-ticket and .pp-ticket prefixed
   classes, two near-identical copies). Restored to the hotel page's original design - that was
   the correct one; the product page's copy is the one that gets dropped whenever the two
   disagree. .ticket__iata (splits the airport code into its own span) and .ticket__logo/
   .ticket__flight-label (airline logo image + airline-name caption, always both together
   underneath) match the hotel page's markup shape exactly.

   Values here are literal, not var(--aip-*)/var(--pp-*) - this class renders inside both
   .aip-page and .pp-page, which each only define their own prefixed tokens on their own root,
   so a shared class can't reliably reach across that divide. Both prefixes hold the identical
   values anyway (e.g. #218887 for primary-dark), so hardcoding here changes nothing on either
   page - it just stops relying on whichever one happens to be in scope. */
.ticket {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 132px;
  margin-bottom: 14px;
  border: 1px solid #d8e0e0;
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
}

.ticket:last-child {
  margin-bottom: 0;
}

.ticket__main {
  min-width: 0;
  padding: 16px 20px 18px;
}

.ticket__dir {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #218887;
}

.ticket__dir svg {
  width: 16px;
  height: 16px;
}

.ticket__route {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 110px minmax(0, 1fr);
  align-items: start;
  gap: 12px 16px;
}

.ticket__city {
  min-width: 0;
}

.ticket__time {
  display: block;
  font-family: "Montserrat", "Lato", sans-serif;
  font-size: 26px;
  font-weight: 700;
  color: #141515;
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.ticket__air {
  display: block;
  margin-top: 6px;
  font-size: 14px;
  font-weight: 700;
  color: #3c4e5a;
  line-height: 1.3;
}

.ticket__iata {
  color: #707070;
  font-weight: 700;
}

.ticket__date {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  font-weight: 400;
  color: #707070;
}

.ticket__city--arr {
  text-align: right;
}

.ticket__mid {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding-top: 8px;
  min-width: 0;
}

.ticket__dur {
  font-size: 12px;
  font-weight: 700;
  color: #707070;
}

.ticket__line {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 18px;
  color: #02aaa9;
  background: repeating-linear-gradient(90deg, #d8e0e0 0 5px, transparent 5px 9px) center / 100% 1px no-repeat;
}

.ticket__line svg {
  width: 16px;
  height: 16px;
  background: #fff;
  padding: 0 4px;
}

.ticket__stop {
  display: inline-block;
  border-radius: 999px;
  padding: 2px 8px;
  background: #eef1f1;
  color: #3c4e5a;
  font-size: 11px;
  font-weight: 700;
}

.ticket__stop.is-direct {
  background: #dff6e1;
  color: #008009;
}

.ticket__stub {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 14px 12px;
  text-align: center;
  background: #f4fafa;
  border-left: 1px dashed #c5d6d6;
}

.ticket__stub::before,
.ticket__stub::after {
  content: "";
  position: absolute;
  left: -8px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: inset 0 0 0 1px #d8e0e0;
}

.ticket__stub::before {
  top: -8px;
}

.ticket__stub::after {
  bottom: -8px;
}

.ticket__flight-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #707070;
}

.ticket__logo {
  display: block;
  max-width: 100px;
  max-height: 28px;
  margin-bottom: 2px;
}

.ticket__no {
  font-family: "Montserrat", "Lato", sans-serif;
  font-size: 16px;
  font-weight: 800;
  color: #02aaa9;
  line-height: 1.1;
}

@media (max-width: 860px) {
  .ticket {
    grid-template-columns: 1fr;
  }

  .ticket__stub {
    flex-direction: row;
    justify-content: space-between;
  }
}

.aip-room-card {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 0;
  align-items: stretch;
  overflow: hidden;
  border: 1px solid var(--aip-border);
  border-radius: 14px;
  background: var(--aip-page-bg);
  margin-bottom: 12px;
}

.aip-room-card:last-child {
  margin-bottom: 0;
}

.aip-room-card img {
  width: 100%;
  height: 100%;
  min-height: 200px;
  object-fit: cover;
}

.aip-room-card__body {
  padding: 18px 20px;
}

.aip-chip-board {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--aip-primary-mist);
  color: var(--aip-primary-deep);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 12px;
  font-weight: 700;
}

.aip-room-card h3 {
  margin: 0 0 8px;
  font-size: 17px;
  font-weight: 800;
  color: var(--aip-ink);
}

.aip-room-card__stay {
  margin: 10px 0 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--aip-ink);
}

.aip-room-card .aip-perks {
  margin: 12px 0;
  list-style: none;
  padding: 0;
  display: grid;
  gap: 3px;
}

.aip-room-card .aip-perks li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--aip-green-text, #008009);
}

.aip-room-card .aip-perks li::before {
  content: "";
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath stroke='%23008009' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' d='M3.2 8.4 6.3 11.4 12.8 4.6'/%3E%3C/svg%3E")
    center / 14px no-repeat;
}

.aip-room-card .aip-hint {
  margin: 8px 0 4px;
}

/* ============================================================================
   Phase 4 - reviews, location, "Included in your holiday" sidebar (ported
   from prototypes/customise-holiday/ per instruction, not hotel-product's own
   simpler .rail), payment plan modal
   ============================================================================ */

.aip-reviews-box {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 20px;
  border-radius: 14px;
  background: var(--aip-page-bg);
}

.aip-reviews-box__score {
  margin: 0;
  font-family: var(--aip-font-display);
  font-size: 42px;
  font-weight: 800;
  line-height: 1;
  color: #00aa6c;
}

.aip-reviews-box h3 {
  margin: 0 0 6px;
}

.aip-times {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.aip-times li {
  display: grid;
  grid-template-columns: 32px 132px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  font-size: 15px;
  line-height: 1.4;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--aip-page-bg);
}

.aip-times strong {
  font-family: var(--aip-font-display);
  font-size: 13px;
  font-weight: 800;
  color: var(--aip-primary-deep);
}

.aip-times span {
  color: var(--aip-text);
}

/* Icon badge, same treatment as .aip-offer-row__icon - the times list has no icon column of
   its own in the prototype (plain text-only rows), but this page's LocationFeatures content is
   real per-hotel icon+time+title data, so it keeps its icon badge here rather than dropping it. */
.aip-times__icon {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 8px;
  background: var(--aip-primary-mist);
  color: var(--aip-primary);
}

.aip-times__icon svg,
.aip-times__icon i {
  width: 16px;
  height: 16px;
  font-size: 14px;
}

/* ---- Sidebar ("summary" card) ---- */

.aip-summary {
  position: sticky;
  top: 76px;
  align-self: start;
  background: #fff;
  border: 1px solid var(--aip-border);
  border-radius: 12px;
  padding: 16px 16px 14px;
  box-shadow: 3px 3px 6px 0 rgba(0, 0, 0, 0.16);
}

.aip-summary h2 {
  color: var(--aip-ink);
  font-family: var(--aip-font);
  font-size: 16px;
  margin: 18px 0 8px;
  padding-top: 14px;
  border-top: 1px solid var(--aip-border);
}

.aip-summary__stay {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 800;
  color: var(--aip-ink);
}

.aip-summary__match {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--aip-green-text);
}

.aip-summary__match svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: 1px;
}

.aip-summary__pp {
  margin: 0;
  font-family: var(--aip-font-display);
  font-size: 34px;
  font-weight: 800;
  color: var(--aip-text);
  line-height: 1;
}

.aip-summary__pp small {
  margin-left: 2px;
  font-size: 16px;
  font-weight: 800;
}

.aip-summary__total {
  margin: 6px 0 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--aip-text);
}

.aip-summary__discount {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--aip-coral);
}

.aip-summary__pay {
  margin: 12px 0 0;
  padding: 10px 12px;
  background: var(--aip-primary-mist);
  border: 1px solid #bfe8e6;
  border-radius: 8px;
  font-size: 13px;
  color: var(--aip-text);
  line-height: 1.45;
}

.aip-summary__pay strong {
  display: block;
  font-weight: 800;
  color: var(--aip-text);
}

.aip-summary__pay .aip-text-btn {
  display: block;
  margin: 6px 0 0 auto;
  text-align: right;
}

.aip-summary .aip-btn--block {
  margin-top: 12px;
}

.aip-summary .aip-atol {
  margin: 10px 0 0;
  justify-content: flex-start;
}

.aip-urgency {
  margin: 8px 0 0;
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--aip-coral);
  font-size: 12px;
  font-weight: 800;
}

.aip-urgency svg {
  width: 14px;
  height: 14px;
}

.aip-atol {
  position: relative;
  margin: 8px 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: help;
}

.aip-atol__logo {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.aip-atol__label {
  font-size: 11px;
  font-weight: 800;
  color: var(--aip-green-text);
  border-bottom: 1px dotted currentColor;
}

.aip-atol__tip {
  position: absolute;
  left: 0;
  bottom: calc(100% + 10px);
  z-index: 6;
  width: min(220px, calc(100% + 8px));
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--aip-primary-deep);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.45;
  box-shadow: 0 10px 22px rgba(60, 78, 90, 0.22);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.aip-atol__tip::after {
  content: "";
  position: absolute;
  left: 18px;
  bottom: -5px;
  width: 10px;
  height: 10px;
  background: var(--aip-primary-deep);
  transform: rotate(45deg);
}

.aip-atol:hover .aip-atol__tip,
.aip-atol:focus .aip-atol__tip,
.aip-atol:focus-visible .aip-atol__tip {
  opacity: 1;
  visibility: visible;
}

.aip-include {
  list-style: none;
  margin: 0;
  padding: 0;
}

.aip-include__card {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 8px 10px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid #e7eeee;
}

.aip-include__card:last-child {
  border-bottom: 0;
}

.aip-include__card:not(:has(.aip-include__edit)) {
  grid-template-columns: 28px minmax(0, 1fr);
}

.aip-include__card--stack,
.aip-include__card--extras {
  align-items: start;
}

.aip-include__icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  color: var(--aip-primary-deep);
}

.aip-include__icon svg {
  width: 18px;
  height: 18px;
}

.aip-include__value {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--aip-ink);
  line-height: 1.3;
}

.aip-include__hint {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--aip-text);
  line-height: 1.35;
}

/* Ported from the hotel-product prototype's own .include__label/.include__note - replaces the
   removed .aip-include__edit "Other dates"/"Other airports"/etc links (see RenderSummaryCard()'s
   own comment on why those are gone) with an explanatory line inside the card itself. */
.aip-include__label {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--aip-text-muted);
}

.aip-include__note {
  margin: 8px 0 0;
  padding: 8px 10px;
  border-radius: 6px;
  background: var(--aip-green-soft);
  color: var(--aip-green-text);
  font-size: 12px;
  font-weight: 800;
  line-height: 1.35;
}

.aip-include__perks {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 3px;
}

.aip-include__perks li {
  position: relative;
  padding-left: 14px;
  font-size: 12px;
  font-weight: 700;
  color: var(--aip-green-text);
  line-height: 1.3;
}

.aip-include__perks li::before {
  content: "\2713";
  position: absolute;
  left: 0;
}

.aip-include__edit {
  font-size: 12px;
  font-weight: 700;
  color: var(--aip-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
  align-self: start;
  margin-top: 1px;
}

.aip-include__edit:hover {
  color: var(--aip-primary-dark);
}

.aip-text-btn {
  border: 0;
  background: none;
  color: var(--aip-primary);
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  padding: 0;
}

.aip-text-btn:hover {
  text-decoration: underline;
}

.aip-hl-more {
  margin-top: 14px;
}

/* Modal shell (.aip-bmodal*) - ported from the prototype's base .modal/.modal__head/.modal__x/
   .modal__body (customise-holiday/styles.css) so Bootstrap's stock modal chrome (square
   corners, plain header rule, small grey X) matches the design's rounded card + circular
   close button instead. Scoped to .modal-content so it only touches modals opted in via this
   class (currently just the Highlights 2 "See all details" popups). Named "bmodal" (Bootstrap
   modal) rather than "modal" specifically to not collide with the unrelated .aip-modal* family
   in AipSearchDropdowns.css, which styles the search bar's native <dialog> popups - same-looking
   prefix, different components, different markup (.modal-content descendant vs a <dialog> root),
   and until this rename both files defined .aip-modal/.aip-modal__head/.aip-modal__x/
   .aip-modal__body with different rules, so whichever stylesheet loaded last silently won for
   any shared property. */
.aip-bmodal {
  border: 0;
  border-radius: 16px;
  box-shadow: 0 18px 40px rgba(16, 68, 67, 0.2);
}

.aip-bmodal__head {
  align-items: flex-start;
  padding: 18px 22px;
  border: 0;
}

.aip-bmodal__title {
  margin: 0;
  font-size: 20px;
  font-weight: 800;
  color: var(--aip-primary-deep);
}

.aip-bmodal__x {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 0;
  border-radius: 50%;
  background: #eef1f1;
  color: var(--aip-text);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.aip-bmodal__x:hover {
  background: #e4e8e8;
}

.aip-bmodal__body {
  padding: 0 22px 22px;
}

/* "See all details" popup (Highlights 2 - Show Popup / Popup Custom HTML / Images fields) -
   wide-and-short like the prototype's dialog.modal--guide (640px wide, capped height), not
   Bootstrap's default narrower/unbounded-height modal. The extra ".modal-dialog" in the
   selector out-specifies Bootstrap's own ".modal-dialog { max-width }" rule so this always
   wins regardless of stylesheet load order. Paired with modal-dialog-scrollable on the
   element itself (see AccommodationItem.cshtml) so only .modal-body scrolls once content
   exceeds the capped height - the header stays put, matching the prototype's behaviour. */
.modal-dialog.aip-guide-dialog {
  max-width: min(640px, calc(100vw - 24px));
}

.aip-guide-dialog .modal-content {
  max-height: min(92vh, 860px);
}

/* Thin scrollbar for the scrollable body - Windows/Chrome's default is a fat 17px bar the
   prototype never had to deal with (it doesn't scroll in the static mock). */
.aip-guide-dialog .modal-body {
  scrollbar-width: thin;
  scrollbar-color: var(--aip-border) transparent;
}

.aip-guide-dialog .modal-body::-webkit-scrollbar {
  width: 6px;
}

.aip-guide-dialog .modal-body::-webkit-scrollbar-track {
  background: transparent;
}

.aip-guide-dialog .modal-body::-webkit-scrollbar-thumb {
  background: var(--aip-border);
  border-radius: 999px;
}

.aip-guide-dialog .modal-body::-webkit-scrollbar-thumb:hover {
  background: var(--aip-primary);
}

.aip-guide-hero {
  position: relative;
  margin: 0 0 16px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--aip-page-bg);
}

.aip-guide-hero img {
  display: none;
  width: 100%;
  height: 240px;
  object-fit: cover;
}

.aip-guide-hero img.is-active {
  display: block;
}

.aip-guide-hero__nav {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 6px;
  border-radius: 999px;
  background: rgba(16, 68, 67, 0.55);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}

.aip-guide-hero__btn {
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 50%;
  background: #fff;
  color: var(--aip-primary-dark);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.aip-guide-hero__btn:hover,
.aip-guide-hero__btn:focus-visible {
  background: var(--aip-primary-mist);
}

.aip-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 20px;
  border-radius: 10px;
  border: 0;
  font: inherit;
  font-size: 14px;
  font-weight: 800;
  text-decoration: none;
  cursor: pointer;
}

.aip-btn--block {
  width: 100%;
}

.aip-btn--primary.aip-btn--gold {
  background: var(--aip-gold);
  color: var(--aip-primary-deep);
}

.aip-btn--primary.aip-btn--gold:hover {
  background: #e5a800;
}

.aip-btn--ghost {
  background: #fff;
  color: var(--aip-primary-deep);
  box-shadow: inset 0 0 0 1px var(--aip-border);
}

.aip-btn--ghost:hover {
  background: var(--aip-page-bg);
}

.aip-btn svg {
  width: 16px;
  height: 16px;
}

/* Room detail popup ("View more details" on the room card) - ported from the prototype's
   #modal-room / .room-sheet (customise-holiday/styles.css). Reuses .aip-bmodal for the rounded
   card shell. Shared with the product page's own room-details popup (was .pp-room-sheet* - a
   plainer, unstyled-Bootstrap-modal version); this hotel-page design is the one both pages use
   now. Values are literal, not var(--aip-*) - see the .ticket comment above for why a class
   shared across both .aip-page and .pp-page can't rely on either page's own prefixed tokens. */
.room-dialog {
  max-width: min(980px, calc(100vw - 24px));
}

.room-shell {
  position: relative;
  max-height: min(92vh, 820px);
}

.room-shell__close {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
}

.room-sheet {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(280px, 0.95fr);
  gap: 22px;
  padding: 22px 22px 8px;
}

.room-hero {
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  background: #f3f6f6;
}

.room-hero img {
  display: none;
  width: 100%;
  height: 320px;
  object-fit: cover;
}

.room-hero img.is-active {
  display: block;
}

.room-hero__nav {
  position: absolute;
  top: 50%;
  left: 10px;
  z-index: 1;
  width: 36px;
  height: 36px;
  margin-top: -18px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: #141515;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.room-hero__nav--next {
  left: auto;
  right: 10px;
}

.room-thumbs {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 8px;
  margin-top: 10px;
}

.room-thumbs button {
  padding: 0;
  border: 0;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px #d8e0e0;
  background: #fff;
}

.room-thumbs button.is-on {
  box-shadow: inset 0 0 0 2px #02aaa9;
}

.room-thumbs img {
  width: 100%;
  height: 56px;
  object-fit: cover;
  display: block;
}

.room-sheet__copy h2 {
  margin: 0 36px 12px 0;
  font-size: 28px;
  font-weight: 800;
  color: #141515;
}

.room-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
}

.room-tags li {
  display: inline-flex;
  align-items: center;
  padding: 6px 10px;
  border: 1px solid #d8e0e0;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #3c4e5a;
}

.room-blurb {
  margin: 0 0 14px;
  font-size: 14px;
  line-height: 1.5;
  color: #3c4e5a;
}

.room-stat {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px;
  font-size: 14px;
  color: #3c4e5a;
}

.room-stat span {
  font-weight: 800;
  color: #141515;
}

.room-stat svg {
  width: 18px;
  height: 18px;
  color: #218887;
}

.room-sheet__copy h3 {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 800;
  color: #141515;
}

.room-includes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 16px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.room-includes li {
  position: relative;
  padding-left: 18px;
  font-size: 13px;
  font-weight: 700;
  color: #3c4e5a;
  line-height: 1.35;
}

.room-includes li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: #02aaa9;
  font-weight: 800;
}

.room-sheet__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 22px;
  border-top: 1px solid #d8e0e0;
}

.room-detail-price {
  margin: 0;
  font-family: "Montserrat", "Lato", sans-serif;
  font-size: 22px;
  font-weight: 800;
  color: #3c4e5a;
}

/* ---- Mobile "book dock" bar + sheet modal (replaces the old #mobPricePanel) ---- */

.aip-book-dock {
  display: none;
}

.aip-summary-sheet .modal-content {
  border: 0;
  border-radius: 18px 18px 0 0;
}

.aip-summary-sheet .modal-dialog {
  margin: auto 0 0;
  max-width: 100%;
  height: min(92dvh, 820px);
  max-height: 92dvh;
  display: flex;
  align-items: flex-end;
}

.aip-summary-sheet .modal-body {
  overflow: auto;
  padding: 16px 16px calc(20px + env(safe-area-inset-bottom));
}

.aip-summary-sheet .aip-summary {
  position: static;
  border: 0;
  box-shadow: none;
  padding: 0;
}

.aip-summary-sheet__handle {
  display: block;
  width: 36px;
  height: 4px;
  margin: 0 auto 8px;
  border-radius: 999px;
  background: #d0d8d8;
}

/* ---- Payment plan modal ---- */

.aip-pay-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin: 0 0 8px;
  padding: 12px 14px;
  background: var(--aip-primary-mist);
  border-radius: 10px;
  color: var(--aip-primary-dark);
  font-weight: 700;
}

.aip-pay-total strong {
  font-family: var(--aip-font-display);
  font-size: 22px;
  font-weight: 800;
  color: var(--aip-primary-deep);
}

.aip-schedule {
  list-style: none;
  margin: 0;
  padding: 0;
}

.aip-step {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid #e7eeee;
}

.aip-step__n {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--aip-primary-mist);
  color: var(--aip-primary-deep);
  font-size: 14px;
  font-weight: 800;
}

.aip-step.is-now .aip-step__n {
  background: var(--aip-primary);
  color: #fff;
}

/* :not([class]) - this is a catch-all for raw, unclassed rich-text links (Model.OverviewText,
   Model.HotelDescription etc. straight out of the CMS, same reason .aip-page h1/h2/h3 near the
   top of this file are reset), not meant to touch component links that already carry their own
   colour via their own class (.aip-back-link, .aip-include__edit, ...). Written as plain ".aip-page
   a" it still matched those too - "class + tag" (0,1,1) beats a lone custom class like
   .aip-back-link (0,1,0) regardless of which rule comes later in the file, silently overriding
   them. :not([class]) makes it stop matching classed anchors at all, which is both more correct
   for what this rule is actually for and sidesteps the specificity fight entirely, rather than
   patching every individual component class that happens to be an <a>. */
.aip-page a:not([class]) {
  color: var(--aip-primary-dark);
}

/* ============================================================================
   RESPONSIVE
   All breakpoints for this page live here, after every base/desktop rule above,
   grouped by breakpoint (widest first) - previously scattered across each phase
   as that phase was built, which meant a mobile override could end up sitting
   *before* its own selector's base rule if the base rule was added in a later
   phase further down the file (media queries add no specificity of their own -
   a later *unconditional* rule for the same selector always wins over an
   earlier media-scoped one, regardless of viewport, so those overrides were
   silently dead at every screen width, not just above the breakpoint - this bit
   .aip-panel's own mobile padding twice over before being caught). Consolidating
   here means every base rule now unconditionally precedes every override that
   targets it, so that class of bug can't recur.
   ============================================================================ */

@media (max-width: 1140px) {
  .aip-product {
    grid-template-columns: 1fr;
  }

  /* Visual order only (grid "order", not a DOM move) - .aip-summary still comes after
     .aip-stack in the markup, so reading/tab order is unaffected, it just paints first once
     stacked to one column. .aip-summary's own base rule is "position: sticky; top: 16px" -
     built for sitting in the desktop two-column layout, pinned alongside a taller .aip-stack
     scrolling past it. In this single-column stack it has no taller sibling to stay pinned
     against, so sticky here just glues the whole card to the top of the viewport as the page
     scrolls - static cancels that back to normal in-flow positioning. */
  .aip-summary {
    order: -1;
    position: static;
    top: auto;
  }
}

@media (max-width: 980px) {
  .aip-book-dock {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    background: #fff;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
    box-shadow: 0 -8px 24px rgba(16, 68, 67, 0.12);
  }

  .aip-book-dock__quote {
    appearance: none;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
    color: inherit;
  }

  .aip-book-dock__quote strong {
    display: block;
    font-family: var(--aip-font-display);
    font-size: 18px;
    color: var(--aip-text);
  }

  .aip-book-dock__quote span {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--aip-text-muted);
  }

  body {
    padding-bottom: 68px;
  }
}
@media (max-width: 860px) {
  /* ---- Header / hero (wrap, back-link, identity, tripadvisor, gallery, anchor nav) ---- */
  .aip-wrap {
    padding: 0 12px;
  }
  .aip-search-wrap {
    padding: 0 0 8px;
  }
  /* .ticket__stub's own mobile rule (shared with the product page) already covers this. */

  /* Search bar is NOT sticky on mobile (explicit request) - only .aip-anchors keeps the sticky
     hand-off below this width. Overrides the base position:sticky rule above. */
  .aip-search-wrapper {
    position: static;
    top: auto;
  }

  .aip-crumbs {
    display: none;
  }

  .aip-identity {
    margin-bottom: 8px;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
  }

  .aip-identity h1 {
    font-size: 22px;
  }
  .aip-ta {
    width: 100%;
  }

  .aip-gallery {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    grid-template-columns: none;
    grid-template-areas: none;
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* legacy Edge/IE */
  }

  /* Was ".aip-gallery::webkit-scrollbar" - missing the leading "-" so it wasn't a valid
     pseudo-element and never matched anything. That let the native horizontal scrollbar
     render for real, consuming vertical space and pushing everything below the gallery
     down (looked like a stray gap above .aip-anchors on non-overlay-scrollbar setups). */
  .aip-gallery::-webkit-scrollbar {
    display: none;
  }

  .aip-gallery__tiles {
    display: contents;
  }

  .aip-gallery__hero,
  .aip-gallery__tiles button {
    flex: 0 0 82%;
    min-height: 200px;
    height: 200px;
    scroll-snap-align: start;
    border-radius: 0;
  }

  .aip-anchors a {
    min-height: 48px;
    font-size: 13px;
    padding: 8px 12px;
  }

  /* ---- Panel base + highlight cards/slots ---- */
  .aip-hl-cards {
    grid-template-columns: 1fr;
  }

  .aip-hl-slots li {
    grid-template-columns: 100px minmax(0, 1fr);
  }

  /* Was originally in the Phase 1 mobile block (~line 437, before .aip-panel's own base rule
     even existed further down at ~line 514) - same specificity (0,1,0) on both sides means
     source order alone decides, and a later *unconditional* rule for the same selector always
     beats an earlier media-scoped one regardless of viewport, so it was permanently dead at
     every screen width, not just overridden above 860px. Media queries don't add specificity;
     they're just a conditional wrapper, so this only actually takes effect moved down here,
     after the base rule it's meant to override. */
  .aip-panel {
    padding: 16px;
  }

  /* ---- Mobile fold-accordion (Hotel Info feature blocks) ---- */
  .aip-feature,
  .aip-panel.aip-feature,
  .aip-room-card,
  .aip-love,
  .aip-amenity-grid {
    grid-template-columns: 1fr;
  }

  .aip-feature > div {
    padding: 16px;
  }

  .aip-feature .aip-hl-media {
    min-height: 180px;
    height: 200px;
  }

  /* Isolates this section's internal layout changes (the accordion opening/closing) from the
     browser's style/layout bookkeeping for the rest of the page - a cheap, zero-visual-risk
     hint that reduces how much work each animation frame costs. Doesn't eliminate the reflow
     that pushes later content down (that's real, unavoidable - the section genuinely gets
     taller), but cuts the overhead around it. */
  .aip-fold {
    contain: layout style;
  }

  /* Smooth fold-accordion open/close instead of the old display:none/block snap. Scoped to
     .aip-fold specifically (not every .aip-feature - the plain Hotel Info section's own
     .aip-hl-media has no is-open toggle at all and must stay visible at its normal height
     always). Collapsed state zeroes height and delays visibility to the end of the close
     transition so the content drops out of tab order/AT only once actually invisible; the open
     state transitions immediately (no delay) so the reveal is visible from the start.
     .aip-fold-body's max-height while open is "none" (fully natural height, no cap) - a fixed
     guessed cap (e.g. 2000px) looked broken here: real content only ever needs ~200-700px, so
     on an ease curve the box reached its actual size in well under half the transition's
     duration, reading as an abrupt snap rather than a smooth open. accommodationItem.js's
     fold-accordion handler instead measures the real scrollHeight per click and drives an exact
     inline max-height during the animation (same pattern as the amenities <details> above),
     clearing it back to this "none" resting value once the open transition finishes - this rule
     is just the idle state, not what's actually animated against. */
  .aip-fold-body {
    max-height: none;
    overflow: hidden;
    visibility: visible;
    transition: max-height 0.32s ease;
  }

  .aip-fold:not(.is-open) .aip-fold-body {
    max-height: 0;
    visibility: hidden;
    transition:
      max-height 0.32s ease,
      visibility 0s linear 0.32s;
  }

  /* .aip-hl-media's own height no longer transitions at all - it used to run its own ~300ms
     height animation in parallel with .aip-fold-body's (both are layout-affecting: every frame
     forces the browser to re-run layout for everything below on the page, not just paint). Two
     of those at once is expensive, and under any real CPU load - verified with Playwright's CPU
     throttling, not just guessed - the browser visibly couldn't keep up: it would sit stuck on
     one frame for 60-80ms while the main thread caught up, then jump, which is exactly what
     "appears from nowhere and then resizes" is. The container's height now flips in a single
     instant step (still just one cheap reflow, bundled into whichever frame .aip-fold-body's
     own animation is already forcing) with no transition of its own. The actual visible motion
     for the photo now comes entirely from the <img>'s own opacity/transform below, which are
     compositor-only properties - they animate on their own thread and stay smooth completely
     independent of how busy layout/JS is at that moment, unlike height ever can. */
  .aip-fold:not(.is-open) .aip-hl-media {
    height: 0;
    min-height: 0;
    overflow: hidden;
    visibility: hidden;
    transition: visibility 0s linear 0.32s;
  }

  .aip-fold.is-open .aip-hl-media {
    height: 180px;
    visibility: visible;
  }

  /* The <img> inside is normally height:100% of .aip-hl-media (AccommodationItemPage.css,
     desktop rule) - fine when the container's height is static, but pinning it to the fixed
     final height here keeps it decoupled from the container's own (now instant, not animated)
     height changes. The actual reveal is this fade + gentle scale-up, not a height/clip wipe -
     compositor-only, so it can't ever look choppy regardless of device load. */
  .aip-fold .aip-hl-media img {
    height: 180px;
    opacity: 0;
    transform: scale(0.96);
    transition:
      opacity 0.32s ease,
      transform 0.32s ease;
  }

  .aip-fold.is-open .aip-hl-media img {
    opacity: 1;
    transform: scale(1);
  }

  .aip-fold h2 {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin: 0;
    cursor: pointer;
  }

  .aip-fold h2::after {
    content: "";
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    margin-right: 4px;
    border-right: 2px solid var(--aip-primary);
    border-bottom: 2px solid var(--aip-primary);
    transform: rotate(45deg);
    transition: transform 0.15s ease;
  }

  .aip-fold.is-open h2::after {
    transform: rotate(-135deg);
    margin-top: 6px;
  }

  /* ---- Room card ---- (.ticket's own mobile rule, shared with the product page, covers the
     ticket stacking now) */
  .aip-room-card {
    grid-template-columns: 1fr;
  }

  /* ---- Room detail dialog ---- */
  .aip-room-sheet {
    grid-template-columns: 1fr;
    padding: 16px 14px 8px;
  }

  .aip-room-hero img {
    height: 220px;
  }

  .aip-room-thumbs {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .aip-room-includes {
    grid-template-columns: 1fr;
  }

  .aip-room-sheet__foot {
    flex-direction: column;
    align-items: stretch;
  }

  /* ---- Times list (location features) ---- */
  .aip-times li {
    grid-template-columns: 28px 100px minmax(0, 1fr);
    gap: 10px;
  }
}

/* ============================================================================================
   ---- Part 2: product page (was ProductPage-v2.css) ----
   ============================================================================================ */

/* ============================================================================================
   Product page ("Customise your holiday") - new design, ported from:
   F:\CyprusParadise-NewDesigns\prototypes\customise-holiday\

   Being rolled out in phases, same convention as AccommodationItemPage.css on the hotel detail
   page - loaded ALONGSIDE the legacy ProductPage.css, not instead of it: sections not yet
   rebuilt (the calendar, flights, rooms/board, transfers and price-summary panels) still rely
   on the old stylesheet/markup until their phase lands. This page is a Vue 3 app
   (wwwroot/js/productpage/productpage.js) with real working booking/pricing logic, unlike the
   hotel detail page's plain-Razor rebuild - so later phases restyle the existing Vue templates
   in place rather than rewriting them; this file only ever adds CSS classes, it never changes
   what data drives them.

   Phase 1 (this phase): page scaffold + hero + search-bar capsule + sticky anchor nav + mobile
   book-dock scaffold. Everything below is scoped under .pp-page so nothing else on the site is
   touched - "pp-" ("ProductPage") rather than reusing "aip-" (that's the hotel detail page's own
   namespace) or "cp-" (already used site-wide by this page's own legacy calendar classes).
   ============================================================================================ */

.pp-page {
  /* Same source values as AccommodationItemPage.css's --aip-* tokens - both copied 1:1 from
     CyprusParadise-NewDesigns/assets/tokens/tokens.css's --cp-* custom properties. */
  --pp-primary: #02aaa9;
  --pp-primary-dark: #218887;
  --pp-primary-deep: #104443;
  --pp-primary-mist: #def6f5;
  --pp-gold: #febb02;
  --pp-coral: #f9706a;
  --pp-green: #23ae24;
  --pp-green-text: #008009;
  --pp-green-soft: #dff6e1;
  --pp-red-soft: #ffe7e8;
  --pp-text: #3c4e5a;
  --pp-text-muted: #707070;
  --pp-ink: #141515;
  --pp-border: #d8e0e0;
  --pp-page-bg: #f3f6f6;
  --pp-font: "Lato", "Segoe UI", sans-serif;
  --pp-font-display: "Montserrat", "Lato", sans-serif;

  font-family: var(--pp-font);
  color: var(--pp-text);
  line-height: 1.45;

  /* The prototype's own body background (search-results/styles.css, which customise-holiday
     @imports) - a faint radial glow over a light grey-teal wash, not plain white. Makes every
     white .pp-panel/.pp-summary card (added in later phases) read as a card instead of blending
     into the page. */
  background:
    radial-gradient(1200px 420px at 10% -10%, rgba(2, 170, 169, 0.16), transparent 55%),
    radial-gradient(900px 380px at 100% 8%, rgba(254, 187, 2, 0.14), transparent 50%), var(--pp-page-bg);
}

.pp-page *,
.pp-page *::before,
.pp-page *::after {
  box-sizing: border-box;
}

.pp-page img {
  max-width: 100%;
  display: block;
}

.pp-page button,
.pp-page input,
.pp-page select {
  font: inherit;
}

.pp-page a {
  color: var(--pp-primary-dark);
}

.pp-page h1,
.pp-page h2,
.pp-page h3 {
  margin: 0;
  color: var(--pp-primary-deep);
}

.pp-wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ---- Hero ----
   Ported from the prototype's .hotel-hero* - full-bleed image with an overlay identity card
   (location, board-basis chip, H1, hotel name+stars, Tripadvisor rating, stay summary). Every
   value below is real per-booking data (Model.Accommodation/Model.FormData), not prototype
   placeholder copy. */
.pp-hero {
  /* NOT overflow:hidden - .pp-hero__card below deliberately overlaps past this box's own
     bottom edge (negative margin, like the prototype's .hotel-hero__card) to sit "on top of"
     the page background below. overflow:hidden here would clip that overlap and cut the card's
     own content off instead of just the image, which is what was happening. Rounding (where
     wanted) belongs on .pp-hero__bg/.pp-hero__veil themselves instead - see below - not this
     container. */
  position: relative;
  min-height: 280px;
  display: flex;
  align-items: flex-end;
}

.pp-hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center bottom;
  /* border-radius: 0 0 var(--pp-radius, 14px) var(--pp-radius, 14px); */
}

.pp-hero__veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: 0 0 var(--pp-radius, 14px) var(--pp-radius, 14px);
  background:
    linear-gradient(90deg, rgba(16, 68, 67, 0.42) 0%, rgba(16, 68, 67, 0.12) 48%, transparent 72%),
    linear-gradient(180deg, rgba(16, 68, 67, 0.12) 0%, rgba(16, 68, 67, 0.08) 38%, rgba(16, 68, 67, 0.48) 100%);
}

.pp-hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-top: 28px;
}

.pp-hero__card {
  max-width: 460px;
  margin: 0 0 -32px;
  padding: 22px 24px 20px;
  background: #fff;
  color: var(--pp-text);
  border-radius: 8px;
  border-top: 3px solid var(--pp-primary);
  box-shadow: 0 16px 40px rgba(16, 68, 67, 0.18);
}

.pp-hero__kicker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
}

.pp-hero__place {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pp-primary-dark);
}

.pp-hero h1 {
  margin: 0;
  font-family: var(--pp-font-display);
  letter-spacing: -0.03em;
  font-size: clamp(24px, 3.2vw, 32px);
  color: var(--pp-text);
}

.pp-hero__name {
  margin: 8px 0 6px;
  font-size: 16px;
  font-weight: 700;
}

.pp-hero__stars {
  margin-left: 6px;
  letter-spacing: 1px;
  color: var(--pp-gold);
}

.pp-hero__stay {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pp-text-muted);
}

.pp-hero__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
}

.pp-hero__edit {
  font-size: 13px;
  font-weight: 800;
  color: var(--pp-primary-dark);
  text-decoration: none;
  white-space: nowrap;
}

.pp-hero__edit:hover {
  text-decoration: underline;
}

.pp-hero .pp-chip-board {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--pp-primary-mist);
  color: var(--pp-primary-deep);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 12px;
  font-weight: 700;
}

.pp-chip-board svg {
  width: 13px;
  height: 13px;
}
/* Tripadvisor mini-card, ported from the prototype's .ta/.ta__dots (a CSS-drawn 5-dot rating
   rather than an image, unlike the hotel detail page's .aip-ta - matches this design's own
   idiom). Dot fullness is computed server-side from the real TripAdvisor.Rating value. */
.pp-ta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--pp-text);
  margin-bottom: 6px;
}

.pp-ta__dots {
  display: flex;
  gap: 3px;
}

.pp-ta__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--pp-border);
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}

.pp-ta__dot.is-full {
  background: #00aa6c;
}

.pp-ta__dot.is-half::after {
  content: "";
  position: absolute;
  inset: 0;
  left: 50%;
  background: #00aa6c;
}

/* Real Tripadvisor rating bubble image (tripAdvisorRatingImageUrl, straight off the CMS node -
   see AccommodationItem.cshtml's own .aip-ta__rating), shown instead of .pp-ta__dots above
   whenever the CMS actually has one. Sized to sit on the same 13px text baseline as .pp-ta__meta
   next to it. */
.pp-ta__rating {
  display: block;
  height: 14px;
  width: auto;
  flex-shrink: 0;
}

.pp-ta__meta {
  color: var(--pp-text-muted);
}

/* Clearance for .pp-hero__card's own -28px/-32px overlap (below) - without this, whatever
   follows the hero sits right up against (or under) the bottom of that overlapping card instead
   of clearing it. Exactly the prototype's own fix: .hotel-hero + .page { padding-top: 56px; } -
   same 56px value, ~ (any later sibling) rather than + since .pp-book-dock (display:none at
   desktop widths, so it takes up no flow space either way) sits between them in the DOM. */
.pp-hero ~ .productDetailPage {
  padding-top: 56px;
}

@media (min-width: 721px) {
  .pp-hero {
    min-height: 240px;
  }

  .pp-hero__veil {
    background: linear-gradient(
      180deg,
      rgba(16, 68, 67, 0.08) 0%,
      rgba(16, 68, 67, 0.06) 50%,
      rgba(16, 68, 67, 0.32) 100%
    );
  }

  .pp-hero__card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "kicker ta"
      "title title"
      "name name"
      "foot foot";
    gap: 6px 24px;
    align-items: center;
    max-width: none;
    margin-bottom: -28px;
    padding: 16px 22px 14px;
  }

  .pp-hero__kicker {
    grid-area: kicker;
    margin: 0;
  }

  .pp-hero h1 {
    grid-area: title;
    font-size: 26px;
  }

  .pp-hero__name {
    grid-area: name;
    margin: 0;
  }

  .pp-hero .pp-ta {
    grid-area: ta;
    justify-self: end;
  }

  .pp-hero__foot {
    grid-area: foot;
    margin-top: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--pp-border);
  }
}

/* Mobile hero polish, ported from the prototype's own @media (max-width: 720px)/(max-width:
   480px) .hotel-hero* rules - the single-column layout below the 721px grid breakpoint above
   still needs its own spacing/type-scale tweaks to match, not just the grid being dropped. */
@media (max-width: 720px) {
  .pp-hero__inner {
    padding-top: 56px;
    padding-left: 12px;
    padding-right: 12px;
  }

  .pp-hero__card {
    max-width: none;
    margin: 0 0 -20px;
    padding: 16px 16px 14px;
  }

  .pp-hero__kicker {
    margin-bottom: 8px;
    gap: 8px;
  }

  .pp-hero__place {
    font-size: 11px;
  }

  .pp-hero .pp-chip-board {
    padding: 4px 10px;
    font-size: 11px;
  }

  .pp-hero h1 {
    font-size: 22px;
  }

  .pp-hero__name {
    margin: 6px 0 8px;
    font-size: 15px;
  }

  .pp-hero .pp-ta {
    margin-bottom: 8px;
    font-size: 12px;
  }

  .pp-hero__stay {
    font-size: 13px;
  }

  .pp-hero__foot {
    margin-top: 10px;
    padding-top: 10px;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .pp-hero ~ .productDetailPage {
    padding-top: 36px;
  }
}

@media (max-width: 480px) {
  .pp-hero {
    min-height: 280px;
  }

  .pp-hero__card {
    padding: 14px;
  }

  .pp-hero h1 {
    font-size: 20px;
  }
}

/* ---- Search-bar capsule ----
   Ported from the prototype's .search-bar - a read-only display of the real booking values
   (this project's real airport/date/room pickers live in the shared, page-agnostic
   SearchTabModals.cshtml/HolidaySearchTab.cshtml widget, not part of this page's own design
   system) - clicking any field or the search button opens that same real widget via
   $('.editSearch').slideToggle(), exactly like the hotel detail page's .aip-search-bar. */
.pp-search-bar {
  margin: 0 0 16px;
  background: var(--pp-gold);
  border-radius: 14px;
  padding: 8px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  gap: 6px;
  box-shadow: 0 16px 40px rgba(16, 68, 67, 0.18);
}

.pp-search-bar__field {
  /* appearance: none belongs here (not just on the two fields that are real <button>s - Departure
     airport is still a <div>, which ignores it harmlessly) so a real <button> using this same
     class (Departure date/Duration's own ppOpenDate/ppOpenNights) doesn't keep any native button
     chrome the rest of this rule doesn't already override. */
  appearance: none;
  background: #fff;
  border: 0;
  border-radius: 10px;
  padding: 8px 12px 10px;
  display: flex;
  flex-direction: column;
  min-width: 0;
  text-align: left;
  cursor: pointer;
  font: inherit;
}

.pp-search-bar__field span {
  font-size: 11px;
  font-weight: 700;
  color: var(--pp-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.pp-search-bar__field strong {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  min-height: 24px;
  color: var(--pp-ink);
  font-size: 14px;
  font-weight: 700;
}

.pp-search-bar__icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--pp-primary-dark);
}

.pp-search-bar__input {
  min-width: 0;
  flex: 1;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: inherit;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: inherit;
}

.pp-search-bar__input::placeholder {
  color: var(--pp-text-muted);
  opacity: 1;
}

.pp-search-bar__input:disabled {
  opacity: 1;
  -webkit-text-fill-color: currentColor;
}

.pp-search-bar__btn {
  min-width: 112px;
  min-height: 48px;
  border: 0;
  border-radius: 10px;
  padding: 10px 16px;
  background: linear-gradient(180deg, #14b8b6, var(--pp-primary));
  color: #fff;
  font: inherit;
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(2, 170, 169, 0.28);
}

.pp-search-bar__btn:hover {
  background: var(--pp-primary-deep);
}

@media (max-width: 860px) {
  .pp-search-bar {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .pp-search-bar__btn {
    grid-column: 1 / -1;
  }
}

@media (max-width: 860px) {
  .pp-wrap {
    padding: 0 12px;
  }

  .pp-hero__card {
    max-width: none;
  }
}

/* ---- Mobile book-dock ----
   Replaces the old .mob-price-panel/#stickyPanel bar. Fixed to the viewport bottom only below
   980px, opens the existing #mobPricePanel modal (its content gets reskinned in a later phase;
   this phase only restyles the trigger bar itself so the mobile "Book Now" flow keeps working
   throughout the rollout). */
.pp-book-dock {
  display: none;
}

@media (max-width: 980px) {
  .pp-book-dock {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    background: #fff;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
    box-shadow: 0 -8px 24px rgba(16, 68, 67, 0.12);
  }

  .pp-book-dock__quote {
    appearance: none;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
    color: inherit;
  }

  .pp-book-dock__quote strong {
    display: block;
    font-family: var(--pp-font-display);
    font-size: 18px;
    color: var(--pp-text);
  }

  .pp-book-dock__quote span {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--pp-text-muted);
  }

  body:has(.pp-page) {
    padding-bottom: 68px;
  }
}

/* ============================================================================
   Phase 2 - Dates panel (#dates): panel shell, banner, calendar grid, cal-foot
   ============================================================================ */

.pp-panel {
  background: #fff;
  border-radius: 18px;
  padding: 22px;
  box-shadow: 0 10px 28px rgba(16, 68, 67, 0.08);
}

.pp-panel__head {
  display: flex;
  gap: 14px;
  margin-bottom: 16px;
}

.pp-panel__num {
  margin: 0;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: 12px;
  background: var(--pp-primary-mist);
  color: var(--pp-primary-deep);
  display: grid;
  place-items: center;
  font-family: var(--pp-font-display);
  font-weight: 700;
}

.pp-panel h2 {
  color: var(--pp-primary-deep);
  font-size: 22px;
}

.pp-panel__head p {
  margin: 4px 0 0;
  color: var(--pp-text-muted);
  font-size: 14px;
}

/* ---- Banner (reused by every panel that needs one, not just Dates) ---- */
.pp-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--pp-green-soft);
  color: var(--pp-green-text);
  border: 1px solid #c8e8cc;
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 14px;
  margin: 0 0 16px;
  line-height: 1.45;
}

.pp-banner svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
}

.pp-banner__lead {
  display: block;
  font-size: 15px;
  font-weight: 800;
  line-height: 1.3;
}

.pp-banner__sub {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.35;
}

/* ---- Calendar ----
   Ported from the prototype's .cal/.day - a flat CSS grid of day buttons rather than the old
   FullCalendar-lookalike <table> markup, driven by the exact same calendarMonths/isSelectedDay/
   isHighlightedDay/isLastHighlightedDay/isBestPriceDay Vue bindings productpage.js already had
   (goToPrevMonth/goToNextMonth are the one real addition - see productpage.js's own comment on
   viewedMonthKey for why: calendarEvents already carries more than one month of price data, the
   grid just never had a way to page across it before). */
.pp-cal {
  background: #fff;
  border: 1px solid var(--pp-border);
  border-radius: 16px;
  overflow: hidden;
}

.pp-month-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0;
  padding: 12px 14px;
  border-bottom: 1px solid var(--pp-border);
}

.pp-month-nav h3 {
  margin: 0;
  font-family: var(--pp-font-display);
  font-size: 16px;
  font-weight: 800;
  color: var(--pp-primary-deep);
}

.pp-icon-btn {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--pp-border);
  background: #fff;
  border-radius: 999px;
  color: var(--pp-text);
  cursor: pointer;
}

.pp-icon-btn svg {
  width: 18px;
  height: 18px;
}

.pp-icon-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.pp-weekdays,
.pp-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.pp-weekdays {
  background: var(--pp-primary-dark);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
}

.pp-weekdays span {
  padding: 9px 2px;
}

.pp-grid {
  gap: 4px;
  padding: 10px;
  background: var(--pp-page-bg);
}

.pp-day {
  appearance: none;
  position: relative;
  overflow: hidden;
  border: 0;
  background: #fff;
  border-radius: 10px;
  min-height: 92px;
  padding: 7px 7px 8px;
  text-align: left;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  font: inherit;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px var(--pp-border);
  transition: box-shadow 0.15s ease, transform 0.15s ease, background 0.15s ease;
}

.pp-day:hover:not(:disabled) {
  z-index: 1;
  transform: translateY(-1px);
  box-shadow: inset 0 0 0 2px var(--pp-gold);
}

.pp-day:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 2px var(--pp-gold);
}

.pp-day__num {
  position: relative;
  z-index: 1;
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-text-muted);
}

.pp-day__price {
  position: relative;
  z-index: 1;
  margin-top: auto;
  align-self: center;
  font-family: var(--pp-font-display);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--pp-primary-deep);
}

.pp-day__stay {
  position: relative;
  z-index: 1;
  margin: auto 0 2px;
  width: 100%;
  padding-right: 4px;
  text-align: center;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
}

.pp-day__mark {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 7px 3px 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
  pointer-events: none;
}

.pp-day.is-start .pp-day__price {
  margin-top: 0;
  font-size: 17px;
  color: #fff;
}

.pp-day__leg {
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  line-height: 1;
  color: #fff;
}

.pp-day__plane {
  width: 14px;
  height: 14px;
  color: #fff;
  flex-shrink: 0;
}

.pp-day.is-end .pp-day__mark {
  background: #fff;
  box-shadow: 0 2px 8px rgba(16, 68, 67, 0.12);
}

.pp-day.is-end .pp-day__plane,
.pp-day.is-end .pp-day__leg {
  color: var(--pp-primary-dark);
}

.pp-day__best {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 1;
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--pp-green-soft);
  color: var(--pp-green-text);
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.pp-day.is-best .pp-day__price {
  color: var(--pp-green-text);
}

.pp-day.is-in-range::before,
.pp-day.is-end::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 4px;
  background: var(--pp-primary);
}

.pp-day.is-in-range,
.pp-day.is-end {
  background: var(--pp-primary-mist);
  box-shadow: inset 0 0 0 1px rgba(2, 170, 169, 0.38);
}

.pp-day.is-in-range .pp-day__num,
.pp-day.is-end .pp-day__num {
  color: var(--pp-primary-deep);
}

.pp-day.is-start {
  background: var(--pp-primary);
  box-shadow:
    inset 0 0 0 1px var(--pp-primary),
    0 10px 20px rgba(2, 170, 169, 0.28);
}

.pp-day.is-start .pp-day__num,
.pp-day.is-start .pp-day__price,
.pp-day.is-start.is-best .pp-day__price {
  color: #fff;
}

.pp-day.is-end:disabled,
.pp-day.is-in-range:disabled {
  cursor: default;
}

.pp-day.is-end:disabled {
  background: var(--pp-primary-mist);
}

.pp-day.is-muted {
  background: transparent;
  color: #c5cccc;
  cursor: default;
  box-shadow: none;
}

.pp-day.is-muted .pp-day__num {
  color: #c5cccc;
}

.pp-day.is-unavailable {
  background: #f6f7f7;
  color: #8a9494;
  cursor: default;
  box-shadow: inset 0 0 0 1px dashed #c8d2d2;
}

.pp-day.is-unavailable .pp-day__num {
  color: #9aa3a3;
}

.pp-day__na {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  align-self: stretch;
  gap: 4px;
  color: #8a9494;
  pointer-events: none;
}

.pp-day__na svg {
  width: 18px;
  height: 18px;
}

.pp-day__na-text {
  font-size: 10px;
  font-weight: 800;
  line-height: 1.15;
  text-align: center;
}

.pp-day.is-in-range:disabled {
  cursor: default;
}

.pp-day:disabled .pp-day__price {
  display: none;
}

/* ---- Cal-foot: legend + booking summary ---- */
.pp-cal-foot {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  border-top: 1px solid var(--pp-border);
  background: var(--pp-page-bg);
}

.pp-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 12px;
}

.pp-legend li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  border-radius: 999px;
  background: #fff;
  color: var(--pp-text-muted);
  font-weight: 700;
  box-shadow: inset 0 0 0 1px var(--pp-border);
}

.pp-swatch {
  width: 12px;
  height: 12px;
  border-radius: 4px;
  display: inline-block;
  flex-shrink: 0;
}

.pp-swatch--selected {
  background: var(--pp-primary);
}
.pp-swatch--best {
  background: var(--pp-green);
}
.pp-swatch--available {
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--pp-border);
}
.pp-swatch--unavailable {
  background: #f6f7f7;
  box-shadow: inset 0 0 0 1px dashed #c8d2d2;
  position: relative;
}

.pp-swatch--unavailable::after {
  content: "";
  position: absolute;
  left: 2px;
  right: 2px;
  top: 50%;
  height: 1.5px;
  background: #8a9494;
  transform: rotate(-42deg);
}

.pp-cal-summary {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(210px, 0.85fr);
  gap: 12px;
  align-items: stretch;
}

.pp-cal-trip {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid var(--pp-border);
  border-radius: 12px;
}

.pp-cal-leg {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.pp-cal-leg p {
  margin: 0;
  min-width: 0;
}

.pp-cal-leg p span {
  display: block;
  font-size: 11px;
  font-weight: 700;
  color: var(--pp-text-muted);
}

.pp-cal-leg strong {
  display: block;
  margin-top: 2px;
  font-size: 15px;
  font-weight: 800;
  color: var(--pp-ink);
  line-height: 1.25;
}

.pp-cal-leg__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--pp-primary);
  color: #fff;
  flex-shrink: 0;
}

.pp-cal-leg__icon svg {
  display: block;
  width: 22px;
  height: 22px;
}

.pp-cal-leg__icon--back {
  background: var(--pp-primary-dark);
}

.pp-cal-trip__stay {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: 7px 12px;
  border-radius: 999px;
  background: var(--pp-primary-mist);
  color: var(--pp-primary-deep);
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
  text-align: center;
}

.pp-cal-price {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 16px 18px;
  border-radius: 12px;
  background: var(--pp-primary);
  color: #fff;
  text-align: left;
}

.pp-cal-price__note {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.82);
}

.pp-cal-price__pp {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
  color: #fff;
}

.pp-cal-price__pp span {
  font-family: var(--pp-font-display);
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  color: #fff;
}

.pp-cal-price__pp small {
  font-size: 14px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.85);
}

.pp-cal-price__total {
  margin: 6px 0 0;
  font-size: 13px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.82);
}

@media (max-width: 720px) {
  .pp-cal-summary {
    grid-template-columns: 1fr;
  }

  .pp-cal-trip {
    grid-template-columns: 1fr;
    text-align: center;
    justify-items: center;
  }

  .pp-day {
    min-height: 68px;
    padding: 5px 4px 6px;
  }

  .pp-day__price {
    font-size: 14px;
  }

  .pp-legend li:nth-child(n + 3) {
    display: none;
  }
}

/* ---- "We've updated your holiday" confirmation (ppModalDateUpdate) -----------------------
   Ported from the customise-holiday prototype's own .modal--update/.update-hero/.update-pills/
   .update-kicker/.update-tiles/.update-foot - shown after picking a new date directly in this
   calendar (see Calendar.cshtml's own header comment on this dialog + the goToPrevMonth-adjacent
   selectAlternativeDate() in productpage.js). .pp-modal/.pp-modal__x/.pp-modal__body/
   .pp-modal__foot/.pp-btn/.pp-btn--primary are the same shared dialog chrome
   ProductPageSearchDropdowns.css's search-tab popovers already use - only what's new to this
   one specific dialog lives here. ---------------------------------------------------------- */
/* .pp-modal.pp-modal--update (not just .pp-modal--update alone) so this reliably beats the base
   .pp-modal's own width (ProductPageSearchDropdowns.css) regardless of which of the two files
   the browser happens to apply last - same specificity otherwise, so load order would decide it
   (that's what made this show at the base 420px width instead of 680px). The @media(max-width:
   860px) bottom-sheet override (ProductPageSearchDropdowns.css) explicitly re-lists
   .pp-modal--update at the same two-class specificity so it still wins there, same as it already
   does for .pp-modal--wide/--date/--nights. */
.pp-modal.pp-modal--update {
  width: min(680px, calc(100vw - 24px));
  max-height: min(92dvh, 880px);
  padding: 0;
}

/* display: flex scoped to [open] specifically - set unconditionally (as this first was) it
   overrides the UA stylesheet's dialog:not([open]) { display: none } (an author-origin rule
   always beats a UA-origin one regardless of specificity), so the card never actually left the
   page flow when closed and just sat there full of stale content instead ("stuck in the
   background" - it wasn't a JS close-handler bug, .close() was already working correctly). */
.pp-modal.pp-modal--update[open] {
  display: flex;
  flex-direction: column;
}

.pp-update-hero {
  position: relative;
  margin: 0;
  padding: 28px 28px 22px;
  background:
    radial-gradient(420px 160px at 100% 0%, rgba(255, 255, 255, 0.14), transparent 60%),
    linear-gradient(160deg, var(--pp-primary-dark), var(--pp-primary));
  color: #fff;
  text-align: center;
  border-radius: 16px 16px 0 0;
}

.pp-update-hero h2 {
  margin: 10px 0 6px;
  font-family: var(--pp-font-display);
  color: #fff;
  font-size: 22px;
}

.pp-update-hero p {
  margin: 0 auto;
  max-width: 36em;
  font-size: 14px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.88);
}

.pp-update-hero .pp-modal__x {
  position: absolute;
  top: 10px;
  right: 10px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
}

.pp-update-hero .pp-modal__x:hover {
  background: rgba(255, 255, 255, 0.24);
}

.pp-update-check {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: 0 auto;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}

.pp-update-check svg {
  width: 22px;
  height: 22px;
}

.pp-update-body {
  padding: 18px 22px 16px;
  overflow: auto;
  flex: 1;
  min-height: 0;
}

.pp-update-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}

.pp-update-pills span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border: 1px solid var(--pp-border);
  border-radius: 999px;
  background: #fff;
  font-size: 13px;
  font-weight: 700;
  color: var(--pp-ink);
}

.pp-update-pills svg {
  width: 16px;
  height: 16px;
  color: var(--pp-primary);
}

.pp-update-kicker {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pp-text-muted);
}

.pp-update-kicker svg {
  width: 14px;
  height: 14px;
  color: var(--pp-primary);
}

/* The dialog's own Flights section reuses the page's real .ticket cards (see Calendar.cshtml)
   rather than a simplified summary row, so no .pp-update-leg* CSS of its own is needed here. */

.pp-update-tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}

/* .pp-modal--update .pp-update-tile (not just .pp-update-tile alone) so this reliably beats
   .pp-page a's own color: var(--pp-primary-dark) (both .pp-update-tile and .pp-update-tip below
   are <a> tags, and a single class loses a specificity tie against a class+tag selector like
   .pp-page a - was showing teal link text here instead of the intended colors). */
.pp-modal--update .pp-update-tile {
  display: grid;
  gap: 4px;
  padding: 12px;
  border: 1px solid var(--pp-border);
  border-radius: 12px;
  background: var(--pp-page-bg);
  text-decoration: none;
  color: inherit;
  min-height: 100%;
}

.pp-update-tile:hover {
  border-color: var(--pp-primary);
  background: var(--pp-primary-mist);
}

.pp-update-tile svg {
  width: 22px;
  height: 22px;
  color: var(--pp-primary);
}

.pp-update-tile strong {
  font-size: 13px;
  color: var(--pp-ink);
}

.pp-update-tile span {
  font-size: 12px;
  color: var(--pp-text-muted);
  line-height: 1.35;
}

/* Ported from the prototype's own .update-tip - the reassurance line under the tiles ("You can
   change flights and rooms on this page..."). Same .pp-update-jump click-then-scroll behaviour
   as the tiles above (see productPageSearchDropdowns.js). */
.pp-modal--update .pp-update-tip {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 10px 12px;
  background: var(--pp-green-soft);
  color: var(--pp-green-text);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  line-height: 1.35;
}

.pp-update-tip::before {
  content: "i";
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--pp-green-text);
  color: #fff;
  font-size: 11px;
  font-style: italic;
}

.pp-update-tip:hover {
  text-decoration: underline;
}

.pp-update-foot > div p {
  margin: 0;
}

.pp-update-foot > div > p:first-child {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pp-text-muted);
}

.pp-update-price__pp {
  font-size: 14px;
  font-weight: 700;
  color: var(--pp-text);
}

.pp-update-price__pp span {
  font-family: var(--pp-font-display);
  font-size: 26px;
  font-weight: 800;
}

.pp-update-price__total {
  margin-top: 2px;
  font-size: 13px;
  color: var(--pp-text-muted);
}

.pp-update-price__save {
  margin-top: 4px;
  font-size: 13px;
  font-weight: 800;
  color: var(--pp-coral, #f9706a);
}

@media (max-width: 720px) {
  .pp-update-tiles {
    grid-template-columns: 1fr;
  }

  .pp-update-foot {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ============================================================================
   Phase 3-6 - Flights, Rooms/board, Transfers, price summary + modals. Ported
   the same way as Phases 1-2: existing Vue bindings kept exactly as they were,
   only the surrounding markup/classes changed.
   ============================================================================ */

/* ---- Buttons (shared by every panel below) ---- */
.pp-btn {
  border: 0;
  border-radius: 10px;
  min-height: 48px;
  padding: 10px 18px;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.pp-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

.pp-btn--primary {
  background: linear-gradient(180deg, #14b8b6, var(--pp-primary));
  color: #fff;
  box-shadow: 0 8px 18px rgba(2, 170, 169, 0.28);
}

.pp-btn--primary:hover {
  background: var(--pp-primary-deep);
}

.pp-btn--gold {
  background: var(--pp-gold);
  color: var(--pp-primary-deep);
  box-shadow: inset 0 0 0 1px #c99400;
}

.pp-btn--primary.pp-btn--gold:hover,
.pp-btn--gold:hover {
  background: #f0b000;
}

.pp-btn--ghost-dark {
  background: #fff;
  color: var(--pp-primary-deep);
  box-shadow: inset 0 0 0 1px var(--pp-border);
}

.pp-btn--ghost-dark:hover {
  box-shadow: inset 0 0 0 1px var(--pp-primary);
}

.pp-btn--block {
  width: 100%;
}

.pp-text-btn {
  border: 0;
  background: none;
  color: var(--pp-primary);
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  padding: 0;
}

.pp-text-btn:hover {
  text-decoration: underline;
}

.pp-hint {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--pp-text-muted);
}

/* ---- Flights: ticket cards ---- */
/* .ticket* (shared with the hotel detail page) now covers this - see the "Flight ticket card"
   block near the top of this file. */

/* ---- Luggage allowance (no prototype equivalent on this page - own card using the same
   panel/typography language, per the plan's Phase-3 note) ---- */
.pp-luggage {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  align-items: center;
  padding: 16px;
  border: 1px solid var(--pp-border);
  border-radius: 12px;
  background: var(--pp-page-bg);
  margin-top: 12px;
}

.pp-luggage + .pp-luggage {
  margin-top: 10px;
}

.pp-luggage__icon img {
  width: 40px;
  height: 40px;
}

.pp-luggage__title {
  margin: 8px 0 0;
  font-size: 14px;
  font-weight: 800;
  color: var(--pp-primary-deep);
}

.pp-luggage__note {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--pp-text-muted);
}

.pp-stepper {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: center;
}

.pp-stepper button {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--pp-border);
  background: #fff;
  font-size: 18px;
  font-weight: 800;
  color: var(--pp-primary-dark);
  cursor: pointer;
}

.pp-stepper input {
  width: 36px;
  text-align: center;
  border: 0;
  background: none;
  font-weight: 800;
  font-size: 15px;
  color: var(--pp-ink);
}

.pp-luggage__total {
  text-align: right;
}

.pp-luggage__total strong {
  display: block;
  font-family: var(--pp-font-display);
  font-size: 16px;
  color: var(--pp-primary-deep);
}

@media (max-width: 640px) {
  .pp-luggage {
    grid-template-columns: 1fr 1fr;
  }
}

/* ---- Board basis picker ---- */
.pp-board-title {
  margin: 0 0 14px;
  font-size: 20px;
  font-weight: 800;
  color: var(--pp-ink);
}

.pp-board-picks {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.pp-board-pick {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 20px 18px 18px;
  border: 1px solid var(--pp-border);
  border-radius: 12px;
  background: #fff;
  color: var(--pp-text);
  cursor: pointer;
  text-align: left;
  min-height: 100%;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.15s ease,
    background 0.15s ease;
}

.pp-board-pick:hover {
  transform: translateY(-2px);
  border-color: var(--pp-primary);
  box-shadow: 0 10px 24px rgba(16, 68, 67, 0.1);
}

.pp-board-pick:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 2px var(--pp-gold);
}

.pp-board-pick.is-on {
  background: radial-gradient(420px 160px at 100% 0%, rgba(2, 170, 169, 0.12), transparent 60%), var(--pp-primary-mist);
  border-color: var(--pp-primary);
  box-shadow: 0 10px 24px rgba(2, 170, 169, 0.16);
}

.pp-board-pick__mark {
  position: absolute;
  top: 14px;
  right: 14px;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid #c5d0d0;
  background: #fff;
  color: #fff;
}

.pp-board-pick.is-on .pp-board-pick__mark {
  background: var(--pp-primary);
  border-color: var(--pp-primary);
}

.pp-board-pick__mark svg {
  width: 14px;
  height: 14px;
}

.pp-board-pick__name {
  margin-top: 4px;
  font-size: 16px;
  font-weight: 800;
  color: var(--pp-ink);
  line-height: 1.25;
}

.pp-board-pick__price {
  margin-top: auto;
  padding-top: 8px;
  font-family: var(--pp-font-display);
  font-size: 18px;
  font-weight: 800;
  color: var(--pp-text);
  letter-spacing: -0.03em;
  line-height: 1;
}

.pp-board-pick__price small {
  margin-left: 4px;
  font-family: var(--pp-font);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0;
  color: var(--pp-text-muted);
}

.pp-board-note {
  margin: 10px 0 16px;
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-text-muted);
}

@media (max-width: 720px) {
  .pp-board-picks {
    grid-template-columns: 1fr 1fr;
  }
}

/* ---- Room cards ---- */
.pp-room-group + .pp-room-group {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--pp-border);
}

.pp-room-group__title {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 800;
  color: var(--pp-primary-deep);
}

.pp-rooms {
  display: grid;
  gap: 12px;
}

.pp-room {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr) 168px;
  gap: 14px;
  align-items: start;
  border: 1px solid #e4eeee;
  border-radius: 14px;
  padding: 10px;
  background: #fff;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    background 0.15s ease;
}

.pp-room.is-on {
  border-color: var(--pp-primary);
  background: #fff;
  box-shadow: 0 10px 24px rgba(2, 170, 169, 0.1);
}

.pp-room__photo {
  position: relative;
  margin: 0;
  min-height: 168px;
  height: 100%;
}

.pp-room__photo img {
  width: 100%;
  height: 100%;
  min-height: 168px;
  max-height: 220px;
  object-fit: cover;
  border-radius: 10px;
}

/* Ported from the prototype's own .room__chosen - the "Selected" pill on a chosen room's photo. */
.pp-room__chosen {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 1;
  padding: 6px 10px;
  border-radius: 999px;
  background: var(--pp-primary);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: 0 6px 14px rgba(2, 170, 169, 0.28);
}

.pp-room__info {
  min-width: 0;
}

.pp-room__name {
  margin: 0 0 4px;
  font-size: 16px;
  font-weight: 800;
  color: var(--pp-primary-deep);
  cursor: pointer;
}

.pp-room__view {
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-primary);
  cursor: pointer;
}

/* Replaces .pp-room__view above - a real <button>, not a plain clickable span (ported from the
   prototype's own .room-details). */
.pp-room-details {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0 0 10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pp-primary);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.pp-room-details svg {
  width: 14px;
  height: 14px;
}

.pp-room__board {
  display: inline-block;
  margin-top: 8px;
  padding: 4px 8px;
  background: var(--pp-page-bg);
  border-radius: 4px;
  font-size: 12px;
  font-weight: 800;
  color: var(--pp-ink);
}

/* Ported from the prototype's own .room-board - replaces .pp-room__board above (same look,
   without the extra margin-top now that it isn't the last element in the card any more). */
.pp-room-board {
  display: inline-block;
  margin: 0 0 10px;
  padding: 4px 8px;
  background: var(--pp-page-bg);
  border-radius: 4px;
  font-size: 12px;
  font-weight: 800;
  color: var(--pp-ink);
}

/* Feature chips - ported from the prototype's own .room-chips, filled with this room's real CMS
   Facilities (thisRoomFacilities() in productpage.js) instead of the prototype's hardcoded
   "Free WiFi"/"Sleeps 2 adults" placeholders. */
.pp-room-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
}

.pp-room-chips li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  border: 1px solid var(--pp-border);
  border-radius: 999px;
  background: var(--pp-page-bg);
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-text);
  line-height: 1;
}

.pp-room-chips svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--pp-primary-dark);
}

/* Checklist - ported from the prototype's own .room-perks, filled with this room's real CMS
   UsPs (thisRoomUSPs()) instead of the prototype's hardcoded perk copy. */
.pp-room-perks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
}

.pp-room-perks li {
  position: relative;
  padding-left: 16px;
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-green-text);
  line-height: 1.35;
}

.pp-room-perks li::before {
  content: "\2713";
  position: absolute;
  left: 0;
}

.pp-room__price {
  text-align: right;
}

.pp-room.is-on .pp-room__price {
  background: radial-gradient(280px 120px at 100% 0%, rgba(2, 170, 169, 0.14), transparent 62%), var(--pp-primary-mist);
  border-radius: 10px;
  padding: 12px 12px 10px;
}

.pp-room__price strong {
  display: block;
  font-family: var(--pp-font-display);
  font-size: 18px;
  color: var(--pp-text);
}

.pp-room__price span {
  display: block;
  font-size: 12px;
  color: var(--pp-text-muted);
}

/* A little more emphasis than the plain per-night line below it (matches the prototype's own
   .room-price__pp vs .room-price__extra) - this is the real unit.PricePerPerson figure. */
.pp-room__price .pp-room-price__pp {
  margin-top: 2px;
  font-family: var(--pp-font-display);
  font-weight: 800;
  color: var(--pp-text);
}

.pp-room__price button {
  margin-top: 8px;
  width: 100%;
  min-height: 40px;
  border: 0;
  border-radius: 8px;
  padding: 8px 14px;
  background: var(--pp-primary);
  color: #fff;
  font-weight: 700;
  cursor: pointer;
}

.pp-room.is-on .pp-room__price button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: #fff;
  color: var(--pp-primary);
  box-shadow: inset 0 0 0 2px var(--pp-primary);
}

.pp-room-empty {
  margin: 0;
  padding: 16px 4px;
  color: var(--pp-text-muted);
  font-size: 14px;
  text-align: center;
}

.pp-room--unpriced {
  opacity: 0.65;
}

.pp-room--unpriced .pp-room__price {
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-text-muted);
}

@media (max-width: 720px) {
  .pp-room {
    grid-template-columns: 1fr;
  }

  .pp-room__photo {
    min-height: 140px;
  }

  .pp-room__price {
    text-align: left;
  }
}

/* ---- Room detail modal ---- */
/* .room-* (shared with the hotel detail page) now covers this - see the "Room detail popup"
   block near the top of this file. */

/* ---- Transfers ---- */
.pp-transfers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px;
}

.pp-transfer {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 16px 14px;
  border: 1px solid var(--pp-border);
  border-radius: 12px;
  background: #fff;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.pp-transfer:hover {
  border-color: var(--pp-primary);
}

.pp-transfer.is-on {
  background: var(--pp-primary-mist);
  border-color: var(--pp-primary);
  box-shadow: 0 10px 24px rgba(2, 170, 169, 0.16);
}

.pp-transfer__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: var(--pp-primary-mist);
  color: var(--pp-primary-dark);
}

.pp-transfer.is-on .pp-transfer__icon {
  background: var(--pp-primary);
  color: #fff;
}

.pp-transfer__icon svg {
  width: 20px;
  height: 20px;
}

.pp-transfer__name {
  font-size: 15px;
  font-weight: 800;
  color: var(--pp-ink);
}

.pp-transfer__price {
  font-size: 13px;
  font-weight: 800;
  color: var(--pp-primary-deep);
}

.pp-transfer__mark {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 22px;
  height: 22px;
  color: var(--pp-text-muted);
}

.pp-transfer.is-on .pp-transfer__mark {
  color: var(--pp-primary);
}

/* ---- Price summary sidebar ---- */
.pp-summary {
  position: sticky;
  top: 16px;
  align-self: start;
  background: #fff;
  border: 1px solid var(--pp-border);
  border-radius: 12px;
  padding: 16px 16px 14px;
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16);
}

.pp-summary h2 {
  color: var(--pp-ink);
  font-family: var(--pp-font);
  font-size: 16px;
  margin: 18px 0 8px;
  padding-top: 14px;
  border-top: 1px solid var(--pp-border);
}

.pp-summary__stay {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 800;
  color: var(--pp-ink);
}

.pp-summary__match {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--pp-green-text);
}

.pp-summary__match svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: 1px;
}

.pp-summary__discount {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--pp-coral);
}

.pp-summary__pp {
  margin: 0;
  font-family: var(--pp-font-display);
  font-size: 34px;
  font-weight: 800;
  color: var(--pp-text);
  line-height: 1;
}

.pp-summary__pp small {
  margin-left: 2px;
  font-size: 16px;
  font-weight: 800;
}

.pp-summary__total {
  margin: 6px 0 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--pp-text);
}

.pp-summary__pay {
  margin: 12px 0 0;
  padding: 10px 12px;
  background: var(--pp-primary-mist);
  border: 1px solid #bfe8e6;
  border-radius: 8px;
  font-size: 13px;
  color: var(--pp-text);
  line-height: 1.45;
}

.pp-summary__pay strong {
  display: block;
  font-weight: 800;
  color: var(--pp-text);
}

.pp-summary__pay .pp-text-btn {
  display: block;
  margin: 6px 0 0 auto;
  text-align: right;
}

.pp-summary .pp-btn--block {
  margin-top: 12px;
}

.pp-summary .pp-atol {
  margin: 10px 0 0;
  justify-content: flex-start;
}

.pp-atol {
  position: relative;
  margin: 8px 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: help;
}

.pp-atol__logo {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.pp-atol__label {
  font-size: 11px;
  font-weight: 800;
  color: var(--pp-green-text);
  border-bottom: 1px dotted currentColor;
}

.pp-atol__tip {
  position: absolute;
  left: 0;
  bottom: calc(100% + 10px);
  z-index: 6;
  width: min(220px, calc(100% + 8px));
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--pp-primary-deep);
  color: #fff;
  font-size: 12px;
  line-height: 1.4;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease;
}

.pp-atol__tip::after {
  content: "";
  position: absolute;
  left: 18px;
  bottom: -5px;
  width: 10px;
  height: 10px;
  background: var(--pp-primary-deep);
  transform: rotate(45deg);
}

.pp-atol:hover .pp-atol__tip,
.pp-atol:focus .pp-atol__tip,
.pp-atol:focus-visible .pp-atol__tip {
  opacity: 1;
  visibility: visible;
}

.pp-include {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pp-include__card {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 8px 10px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--pp-grey, #ededeb);
}

.pp-include__card:last-child {
  border-bottom: 0;
}

.pp-include__card--stack,
.pp-include__card--extras {
  align-items: start;
}

.pp-include__icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  color: var(--pp-primary-deep);
}

.pp-include__icon svg {
  width: 18px;
  height: 18px;
}

.pp-include__value {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--pp-ink);
  line-height: 1.3;
}

.pp-include__hint {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--pp-text);
  line-height: 1.35;
}

.pp-include__perks {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 3px;
}

.pp-include__perks li {
  position: relative;
  padding-left: 14px;
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-green-text);
  line-height: 1.3;
}

.pp-include__perks li::before {
  content: "\2713";
  position: absolute;
  left: 0;
}

.pp-include__edit {
  font-size: 12px;
  font-weight: 700;
  color: var(--pp-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
  align-self: start;
}

/* ---- Generic modal chrome (Bootstrap .modal-content stays load-bearing; this only reskins
   its inner surfaces to match the new design's card look, same as every panel above) ---- */
.pp-modal .modal-content {
  border: 0;
  border-radius: 14px;
}

.pp-modal .modal-header {
  border: 0;
  padding: 18px 20px 0;
}

.pp-modal .modal-title,
.pp-modal h2 {
  margin: 0;
  font-family: var(--pp-font-display);
  font-size: 19px;
  font-weight: 800;
  color: var(--pp-primary-deep);
}

.pp-modal .modal-body {
  padding: 12px 20px 20px;
}

.pp-modal .modal-footer {
  border: 0;
  padding: 0 20px 20px;
}

/* ---- Payment plan modal ---- */
.pp-pay-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--pp-page-bg);
  font-weight: 800;
  color: var(--pp-primary-deep);
  margin: 0 0 12px;
}

.pp-schedule {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.pp-step {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--pp-border);
  border-radius: 10px;
}

.pp-step.is-now {
  background: var(--pp-primary-mist);
  border-color: var(--pp-primary);
}

.pp-step__n {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--pp-border);
  font-weight: 800;
  color: var(--pp-primary-deep);
}

.pp-pay-note {
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--pp-text-muted);
}

/* ---- Alternate flights modal (two-pane filter/results) ---- */
.modal-dialog.pp-modal--alt-flights {
  max-width: 900px;
}

.pp-chg-offer__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--pp-border);
}

.pp-chg-check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 400;
  color: var(--pp-text);
  margin-bottom: 6px;
  cursor: pointer;
}

.pp-chg-check input {
  width: 16px;
  height: 16px;
  accent-color: var(--pp-primary);
}

.pp-chg-results .pagination {
  margin-top: 12px;
}

.pp-chg-results .page-link {
  color: var(--pp-primary-dark);
  border-color: var(--pp-border);
}

.pp-chg-results .page-link.active,
.pp-chg-results .page-item .page-link.active {
  background: var(--pp-primary);
  border-color: var(--pp-primary);
  color: #fff;
}

.pp-chg-body {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 18px;
}

.pp-chg-filters {
  min-width: 0;
  padding-right: 4px;
  border-right: 1px solid var(--pp-border);
}

.pp-chg-filters__head {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 800;
  color: var(--pp-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.pp-chg-set {
  margin: 0 0 16px;
}

.pp-chg-set legend {
  font-size: 12px;
  font-weight: 800;
  color: var(--pp-primary-deep);
  margin-bottom: 6px;
}

.pp-chg-check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  margin-bottom: 6px;
  cursor: pointer;
}

.pp-chg-results {
  min-width: 0;
}

.pp-chg-offer {
  border: 1px solid var(--pp-border);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 10px;
}

.pp-chg-offer.is-selected {
  border-color: var(--pp-primary);
  background: var(--pp-primary-mist);
}

.pp-chg-empty {
  padding: 24px;
  text-align: center;
  color: var(--pp-text-muted);
}

@media (max-width: 720px) {
  .pp-chg-body {
    grid-template-columns: 1fr;
  }

  .pp-chg-filters {
    border-right: 0;
    border-bottom: 1px solid var(--pp-border);
    padding-bottom: 10px;
  }
}

.pp-product {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 22px;
  align-items: start;
  padding-top: 56px;
  padding-bottom: 64px;
}

.pp-stack {
  display: grid;
  gap: 16px;
  min-width: 0;
}

@media (max-width: 1100px) {
  .pp-product {
    grid-template-columns: 1fr;
  }

  .pp-product > .pp-summary {
    display: none;
  }
}
