/* Hotel detail screen — BEM naming */

/* ── Root container ─────────────────────────────────────── */

/* Figma 560:9767 — the design's content band runs nearly edge-to-edge on its
   ~1480px frame (~1416px of content, ~32px margins): a 1100px main column and
   a 300px rail. The old 72rem cap left ~180px of dead space on each side. */
.hotel-detail {
  max-width: 92rem;
  margin-left: auto;
  margin-right: auto;
  /* HMS-491 — bottom padding so the alt-hotels banner does not sit flush
     against the page footer. */
  padding: 0 1rem 2rem;
}

/* HMS-1127 — the chat-FAB clearance on #main-content (chatbot_widget.css) is
   dead space here: the footer follows and carries its own FAB/tabbar/sticky-bar
   clearance, so it only widened the gap between the banner and the footer. */
body:has(> .chatbot-widget) #main-content:has(.hotel-detail) {
  padding-bottom: 0;
}

/* ── Back link ──────────────────────────────────────────── */

.hotel-detail__back {
  padding: 1rem 0;
}

/* Figma 560:9767 — the back link is a bordered pill, not bare text */
.hotel-detail__back a {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.875rem;
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.5rem;
  background: var(--wa-color-surface-default);
  color: var(--wa-color-text-normal);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  transition: border-color 0.15s ease;
}

.hotel-detail__back a:hover {
  border-color: var(--wa-color-neutral-on-quiet);
}

.hotel-detail__back i {
  font-size: 0.75rem;
}

/* ── Two-column layout ─────────────────────────────────── */

.hotel-detail__layout {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.hotel-detail__main {
  min-width: 0;
}

/* Figma 560:10119 — the right rail holds the Price Summary card then the
   joined Check-in/Check-out box, and starts level with the photos. On narrow
   layouts it stacks below the main column; below 640px its contents are
   hidden entirely (see media block). */
.hotel-detail__rail {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  min-width: 0;
}

/* ── Photo gallery ─────────────────────────────────────── */

.photo-gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
  border-radius: 0.75rem;
  overflow: hidden;
}

/* Hero image */

/* height:auto is load-bearing at EVERY width, not just ≥1024px: the wrapper
   is a <button> grid item, and without it the box falls back to content
   height (~43px sliver) instead of the ratio-derived height. */
.photo-gallery__hero-wrapper {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  overflow: hidden;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: block;
}

.photo-gallery__hero {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Figma 560:9767 — the saved-favorites heart floats in a white circle over the
   gallery's top-right corner. The form wrapper (button_to) and the anonymous
   sign-in link take the same coordinates; the .photo-gallery__fav class styles
   the round body on whichever element carries it. */
.photo-gallery__wrap {
  position: relative;
}

.photo-gallery__fav {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--wa-color-surface-default);
  color: var(--wa-color-text-normal);
  font-size: 1rem;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  padding: 0;
}

.photo-gallery__fav--saved {
  color: var(--wa-color-brand);
}

.photo-gallery__fav:focus-visible {
  outline: 2px solid var(--wa-color-brand);
  outline-offset: 2px;
}

.photo-gallery__wrap form.button_to,
.photo-gallery__wrap > a.photo-gallery__fav {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  margin: 0;
}

/* Thumbnails — vertical stack on mobile */

.photo-gallery__thumbnails {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
}

.photo-gallery__thumbnail {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  height: auto;
  overflow: hidden;
  border-radius: 0.5rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: block;
}

.photo-gallery__thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Figma 560:9767 — the "+N photo" badge is a dark pill CENTERED on the last
   tile, not a corner chip. */
.photo-gallery__more-count {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--ek-color-scrim);
  color: var(--ek-color-on-scrim);
  padding: 0.25rem 0.625rem;
  border-radius: 0.375rem;
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Empty state — branded initials placeholder */

.photo-gallery--empty {
  aspect-ratio: 16 / 9;
  background: var(--wa-color-brand-90);
}

.photo-gallery__placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.photo-gallery__initials {
  font-size: 3rem;
  font-weight: 700;
  color: var(--wa-color-brand);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Focus affordance on the hero and thumbnail triggers (now <button>s) */

.photo-gallery__trigger:focus-visible {
  outline: var(--wa-focus-ring);
  outline-offset: 2px;
}

/* ── Hotel header ──────────────────────────────────────── */

/* Tight gap on mobile; Figma 560:10119's ~55px below the photo bottom is set
   at ≥1024px (see media block). */
.hotel-detail__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}

.hotel-detail__title-group {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.hotel-detail__name {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
  line-height: 1.2;
}

/* Name row — Figma 560:9767 pairs the name with a dark distance pill */

.hotel-detail__name-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.hotel-detail__distance-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.625rem;
  border-radius: 999px;
  background: var(--wa-color-neutral-fill-loud);
  color: var(--wa-color-neutral-on-loud);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Mobile-only elements (Figma 576:3879): the name-row heart and the
   distance/neighborhood meta line replace the pill and time boxes below 640px.
   Hidden by default; the ≤639.98px media block shows them.
   .hotel-detail__stay-mobile is the phone copy of the rail's stay-date picker —
   the rail itself is hidden below 640px, so a second render in the rooms
   section keeps the control reachable there (HMS-1499). */
.hotel-detail__fav-row,
.hotel-detail__venue-line,
.hotel-detail__stay-mobile,
.hotel-detail__rooms-title-short,
.hotel-detail__alt-link-short,
.room-type-card__book-short,
.room-type-card__avail-short,
.room-type-card__waitlist-short {
  display: none;
}

/* Tagline */

.hotel-detail__tagline {
  margin: 0;
  font-size: 1rem;
  color: var(--wa-color-text-quiet);
  line-height: 1.5;
}

/* Check-in / check-out times */

/* Figma 560:10119 — the two boxes join as one bordered component split down
   the middle, not two separate tiles. The joined box sits beside the hotel
   name in the header, right-aligned via margin-left:auto. */
.hotel-detail__times {
  display: flex;
  margin-top: 0;
  flex-shrink: 0;
  margin-left: auto;
}

.hotel-detail__time-box {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.625rem 1rem;
  border: 1px solid var(--wa-color-surface-border);
  background: var(--wa-color-neutral-fill-quiet);
}

.hotel-detail__time-box:first-child {
  border-radius: 0.5rem 0 0 0.5rem;
}

.hotel-detail__time-box:last-child {
  border-left: none;
  border-radius: 0 0.5rem 0.5rem 0;
}

/* A lone box is first AND last child, so the last-child rule above stripped its
   left border — restore both border and radius on all four sides. */
.hotel-detail__time-box:only-child {
  border-left: 1px solid var(--wa-color-surface-border);
  border-radius: 0.5rem;
}

.hotel-detail__time-label {
  font-size: 0.75rem;
  color: var(--wa-color-text-quiet);
}

.hotel-detail__time-value {
  font-size: 1rem;
  color: var(--wa-color-text-normal);
  font-weight: 700;
  white-space: nowrap;
}

/* ── Section titles ─────────────────────────────────────── */

.hotel-detail__section-title {
  margin: 0 0 1rem;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--wa-color-text-normal);
}

/* Figma 560:9767 — stars and the "View Reviews" link share one row. */
.hotel-detail__rating-row {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

/* ── Amenities ─────────────────────────────────────────── */
/* Groups stack single-column on phones; the wrapper grids them two across at
   ≥640px and four across at ≥1024px. */

.hotel-detail__amenities {
  margin-top: 1rem;
}

/* Figma 560:9767 — the groups sit side by side with no separators between
   them; each item is a light pill holding an icon and a name. */
.amenity-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.amenity-group__heading {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--wa-color-text-normal);
}

.amenity-group__items {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.amenity-feature {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  width: fit-content;
  padding: 0.25rem 0.5rem;
  border-radius: 0.5rem;
  background: var(--wa-color-neutral-fill-quiet);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--wa-color-text-normal);
  /* Figma pills are one line: icon + name. Long fixture names wrapped to a
     second line and turned each pill into a tall box. */
  white-space: nowrap;
}

.amenity-feature i {
  width: 1rem;
  text-align: center;
  color: var(--wa-color-brand);
}

/* ── Room type cards ───────────────────────────────────── */

.hotel-detail__rooms {
  margin-top: 1.5rem;
  padding-bottom: 2rem;
  scroll-margin-top: 1rem;
}

.hotel-detail__room-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* HMS-1407 — "Compare rooms" as the suggested-UI pill: light-blue fill,
   dark-blue label, small right chevron, no underline. fit-content keeps it
   hugging the text on both phone and desktop widths; the margins keep a
   consistent rhythm between the section title above and the room cards. */
.hotel-detail__compare-link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  width: fit-content;
  margin: 0.5rem 0 1rem;
  padding: 0.375rem 0.875rem;
  border-radius: 9999px;
  background: var(--wa-color-brand-fill-quiet);
  color: var(--wa-color-brand-on-quiet);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
}

.hotel-detail__compare-link i {
  font-size: 0.75rem;
}

/* Figma 560:9767 — the card is a horizontal ROW: small square thumbnail left,
   name + meta in the middle, rate stacked over the CTA on the right. */
.room-type-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem;
  background: var(--wa-color-surface-default);
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.75rem;
  transition: box-shadow 0.2s ease;
  /* HMS-502 — stretched-link parent: the name link's ::after covers the card
     so a click anywhere selects the room, matching what QA tried to do. */
  position: relative;
}

/* The name link is the one real anchor on a bookable card; ::after stretches
   it over the whole card so the card itself is the click target. Off-sale and
   selected cards render no name link at all; sold-out cards DO render one
   (selecting a sold-out room is a real summary state — "No rooms left in this
   block"), so the stretch is scoped away from them: their name link still
   works as a link, but a click on blank card space does not navigate. The
   card's own buttons sit above the stretched link at z-index 1 below. */
.room-type-card:not(.room-type-card--sold-out) .room-type-card__name-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* Buttons that do something OTHER than select must stay clickable above the
   stretched link: the details dialog trigger and every action-column control. */
.room-type-card__details-trigger,
.room-type-card__badge-hint,
.room-type-card__actions {
  position: relative;
  z-index: 1;
}

/* The room the price summary is describing. Figma's selected card carries a
   brand-tinted fill behind the border; no transform, because the card must not
   move when a guest picks it and the page re-renders. */
.room-type-card--selected {
  border-color: var(--wa-color-brand-fill-loud);
  box-shadow: 0 0 0 1px var(--wa-color-brand-fill-loud);
  background: var(--wa-color-brand-95);
}

.room-type-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

/* Thumbnail — a small rounded square, not the old full-width banner. The whole
   image is the select affordance on unselected cards, so the link fills it. */

.room-type-card__thumbnail {
  position: relative;
  width: 5.5rem;
  aspect-ratio: 1;
  border-radius: 0.5rem;
  overflow: hidden;
  flex-shrink: 0;
}

.room-type-card__thumb-link {
  display: block;
  width: 100%;
  height: 100%;
}

.room-type-card__thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.room-type-card__placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--wa-color-neutral-fill-quiet);
  color: var(--wa-color-text-quiet);
  font-size: 1.5rem;
}

/* Inline beside the room name, per Figma 560:9856 — it was absolutely positioned over
   the thumbnail, which put it on the photo rather than on the room, and left it
   floating over the bed icon when a hotel has no photo at all. The frame's pill is
   a quiet pink tint with a ban glyph, title case — not the old solid red LOUD tag. */
.room-type-card__soldout {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  vertical-align: middle;
  margin-left: 0.5rem;
  background: var(--wa-color-danger-fill-quiet);
  color: var(--wa-color-danger-on-quiet);
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}

/* HMS-1380 — the contracted-side label in the combined rate list. Quiet
   neutral where the live card's badge is brand-tinted: the block is the
   default here, the agency rate is the exception worth the colour. Same
   inline-pill slot as __soldout so the two never fight for a position. */
.room-type-card__source-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  vertical-align: middle;
  margin-left: 0.5rem;
  background: var(--wa-color-neutral-fill-quiet);
  color: var(--wa-color-text-quiet);
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}

/* HMS-1489 — the badge's (i) hint sits inline on the name line right after the
   source tag. It is a tooltip anchor, not a button: quiet colour, help cursor,
   and the z-index lift above comes from the shared rule so the stretched
   name-link overlay does not swallow its hover/focus. */
.room-type-card__badge-hint {
  margin-left: 0.375rem;
  color: var(--wa-color-text-quiet);
  font-size: 0.8125rem;
  cursor: help;
  vertical-align: middle;
}

/* Card body — info middle, rate + CTA stacked in the right column */

.room-type-card__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
}

.room-type-card__info {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.room-type-card__name {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--wa-color-text-normal);
  line-height: 1.3;
}

/* The name is the select affordance on unselected cards — it must read as the
   room's name, not as blue link chrome. */
.room-type-card__name-link {
  color: inherit;
  text-decoration: none;
}

.room-type-card__name-link:hover {
  text-decoration: underline;
  text-underline-offset: 0.125rem;
}

/* Figma 560:9767 meta — "1–2 guests · 12 rooms left" as one line; the
   separator only appears between two facts. */
.room-type-card__meta {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

.room-type-card__meta > span + span::before {
  content: "·";
  margin-right: 0.375rem;
}

.room-type-card__capacity {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

/* Bed type sits in the meta line as the same kind of fact as capacity, so it
   takes the same treatment. Absent entirely when the column is unset, so there
   is no empty state to style. */
.room-type-card__bed {
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

.room-type-card__availability {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
  font-weight: 500;
}

/* Figma 560:9767's right column — rate stacked over the CTA. */

.room-type-card__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 0.375rem;
  flex-shrink: 0;
}

/* The upgrade offer sits in the right column with rate and CTA. No flex basis:
   inside the column direction a basis is a HEIGHT, which would pad every
   offered card with 10rem of dead space. On the compact row layout the mobile
   rule restores the wrap-and-fill basis. */
.room-type-card__upgrade {
  font-size: 0.875rem;
  color: var(--wa-color-text-quiet);
}

.room-type-card__rate {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.room-type-card__per-night {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--wa-color-text-quiet);
}

/* Mobile-only "0 rooms available" on the sold-out row (Figma 576:3879).
   Hidden ≥640px — the desktop card deliberately shows no count (560:9856). */
.room-type-card__none {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--wa-color-danger);
}

/* HMS-1494 — the "not available for these dates" line under the room name.
   Same slot as __none but quiet text that wraps at every width: the message
   names the block's whole window, so it cannot share the soldout pill's
   nowrap. Not danger red — the room exists, just not for the searched stay. */
.room-type-card__window {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--wa-color-text-quiet);
}

/* Payment terms (HMS-444) — real contract data. Kept on desktop; the compact
   mobile row hides it (Figma 576:3879 shows two facts only). The rule lives
   before the ≤639.98px block so the mobile display:none can win the cascade —
   when it sat after the media block it overrode the hide. */
.room-type-card__pay {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--wa-color-text-quiet);
}

/* ── Sidebar — price summary ───────────────────────────── */

/* HMS-1499 — the stay-date picker's card: same chrome as the price summary so
   the rail reads as one column of booking controls. */
.hotel-detail__stay {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.75rem;
  background: var(--wa-color-surface-default);
}

.hotel-detail__stay-title {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.price-summary {
  position: static;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.75rem;
  background: var(--wa-color-surface-default);
}

/* Tier badge */

.price-summary__tier {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.price-summary__tier-heading {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.price-summary__badge {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  background: var(--wa-color-brand-90);
  color: var(--wa-color-brand);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  width: fit-content;
}

/* Figma 560:9767 tints the tier badge gold for a VIP — General keeps the
   brand tint. The gold pair is a theme token (tools/test_theme.py forbids
   hex outside eventkrowd_theme.css). */
.price-summary__badge--vip {
  background: var(--ek-color-vip-gold-quiet);
  color: var(--ek-color-vip-gold);
}

/* Price breakdown */

.price-summary__breakdown {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.price-summary__title {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.price-summary__line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
}

.price-summary__label {
  font-size: 0.875rem;
  color: var(--wa-color-text-quiet);
}

.price-summary__value {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--wa-color-text-normal);
  text-align: right;
}

/* Figma 560:9767 — one hairline separates the room facts (Dates, Nights,
   Room Type, Nightly Rate) from the money rows (Taxes, Total). The
   total carries no second rule. */
.price-summary__divider {
  border-top: 1px solid var(--wa-color-surface-border);
  margin: 0.125rem 0;
}

.price-summary__line--total {
  padding-top: 0.25rem;
}

.price-summary__value--total {
  font-size: 1.125rem;
  font-weight: 700;
}

/* HMS-778 — a saving reads as good news; same success color the booking
   confirmation's discount line uses. */
.price-summary__line--discount .price-summary__value {
  color: var(--wa-color-success-on-quiet);
}

/* Book button */

.price-summary__book-btn {
  width: 100%;
}

/* Cancellation policy */

.price-summary__cancellation {
  padding-top: 0.5rem;
  border-top: 1px solid var(--wa-color-neutral-border-quiet);
}

.price-summary__cancellation-heading {
  margin: 0 0 0.375rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.price-summary__cancellation-text {
  margin: 0;
  font-size: 0.75rem;
  color: var(--wa-color-text-quiet);
  line-height: 1.5;
}

/* HMS-765 — same tier rows the funnel prints, at this card's text size. The
   double-class selector must out-specify .booking-review__tiers' `margin: 0`,
   which loads after this file and would otherwise flatten the gap. */
.price-summary__cancellation .price-summary__cancellation-tiers {
  margin-top: 0.5rem;
  font-size: 0.75rem;
}

/* ── Tablet (≥ 640px) ─────────────────────────────────── */

@media (min-width: 640px) {
  .hotel-detail {
    /* HMS-491 — the shorthand must carry the bottom padding too: a bare
       `padding: 0 …` would reset it and the banner is flush again. */
    padding: 0 1.5rem 2rem;
  }

  /* Thumbnails side-by-side */
  .photo-gallery__thumbnails {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Amenity groups — two across */
  .hotel-detail__amenity-groups {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
  }

  .amenity-group {
    border-bottom: none;
    padding-bottom: 0;
  }

  /* The "0 rooms available" line is mobile-only (Figma 576:3879). The desktop
     card deliberately shows no count on a sold-out room (560:9856). */
  .room-type-card__none {
    display: none;
  }
}

/* ── Desktop (≥ 1024px) — two columns ─────────────────── */

@media (min-width: 1024px) {
  .hotel-detail {
    padding: 0 2rem 2rem;
  }

  /* Two-column layout — Figma 560:9767's split is a ~1100px main column and a
     ~300px rail (16px between), not halves. */
  .hotel-detail__layout {
    flex-direction: row;
    gap: 1rem;
  }

  .hotel-detail__main {
    flex: 1;
    min-width: 0;
  }

  .hotel-detail__rail {
    flex: 0 0 18.75rem;
    align-self: flex-start;
  }

  /* Photo gallery — Figma's split is hero ~850px to a ~240px thumb column
     (≈11:3) INSIDE the ~1060px main column; the ~300px rail sits further
     right, level with the photos. */
  .photo-gallery {
    grid-template-columns: 11fr 3fr;
  }

  /* Figma 560:10119 — ~55px between the photo bottom and the name row on
     desktop; the mobile frames run tighter. */
  .hotel-detail__header {
    margin-top: 3.5rem;
  }

  /* Figma pins the save heart to the HERO's top-right corner — the 11fr
     column's right edge. Anchored to the wrap's outer edge instead it would
     sit over the first thumbnail. */
  .photo-gallery__wrap form.button_to,
  .photo-gallery__wrap > a.photo-gallery__fav {
    right: calc((100% - 0.5rem) * 3 / 14 + 1.25rem);
  }

  /* ...except the no-photo state: --empty's background paints the FULL wrap
     width (the placeholder initials just sit in the 11fr cell), so the
     band's corner is the wrap edge — the base 0.75rem is the right anchor. */
  .photo-gallery__wrap:has(.photo-gallery--empty) form.button_to,
  .photo-gallery__wrap:has(.photo-gallery--empty) > a.photo-gallery__fav {
    right: 0.75rem;
  }

  /* Figma 560:9767's hero is 1100x615 — the 16:9 crop. The explicit height:
     auto is load-bearing, not redundant: the wrapper is a <button> grid item,
     and without it the box falls back to content height (~43px, floored by
     min-height to 320px) instead of the ratio-derived ~605px. Verified live. */
  .photo-gallery__hero-wrapper {
    aspect-ratio: 16 / 9;
    height: auto;
    min-height: 20rem;
  }

  .photo-gallery__thumbnails {
    grid-template-columns: 1fr;
  }

  /* Figma's thumb tiles are 300x195 — 3:2 landscape, three of which plus the
     8px gaps stand within a few px of the 16:9 hero's height. A definite
     ratio on each tile is what keeps them photo-sized: the earlier 1fr row
     sizing collapsed to content height, which for a portrait source meant
     ~390px tiles dragging the whole gallery to 1188px (and for an <img> that
     reports no intrinsic size, 43px slivers). */
  .photo-gallery__thumbnail {
    aspect-ratio: 3 / 2;
    height: auto;
    border-radius: 0.25rem;
  }

  /* Amenity groups — four across */
  .hotel-detail__amenity-groups {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* The sold-out counterpart of .price-summary__book-btn, which occupies this slot
   when the room CAN be booked. It had no rule at all, so the sidebar's primary
   position rendered as bare body text. Same block geometry as the button so the
   card does not change shape between the two states — a layout that jumps when a
   room sells out reads as a bug. */
.price-summary__unavailable {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin: 0;
  padding: 0.75rem 1rem;
  border: 1px dashed var(--wa-color-neutral-border-normal);
  border-radius: 0.375rem;
  background: var(--wa-color-neutral-fill-quiet);
  color: var(--wa-color-text-quiet);
  font-size: 0.9375rem;
  font-weight: 500;
  text-align: center;
}

/* HMS-1139 — the "booking has closed" note under the dashed total when the
   quoted block is past its cutoff; quiet text so it reads as a fact, not a CTA. */
.price-summary__closed-note {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

/* The waitlist action, in both its forms: the POST button a signed-in guest gets
   and the sign-in link everyone else gets. It had no rule at all and computed
   rgb(47, 50, 63) — the dark default this repo has shipped twice — on the slot the
   design gives the card's primary action. Same block geometry as .price-summary__
   unavailable so the card does not change shape when a room sells out. Loud brand,
   matching .waitlist-offer__accept: joining is the one positive action left. */
.room-type-card__waitlist {
  /* HMS-938 — inline-flex so the label and arrow center on both axes inside
     the button's box. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--wa-color-brand-fill-loud);
  border-radius: var(--wa-border-radius-m);
  background: var(--wa-color-brand-fill-loud);
  color: var(--wa-color-brand-on-loud);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

/* NO .room-type-card__waitlist-note RULE. The plain-text stand-in it styled was
   removed: it repeated the Sold Out pill beside the room name, and Figma 560:9856
   states that once. The slot stays empty until HMS-43 gives it a real Join Waitlist
   button, which will need its own rule rather than this one. */

/* ── Mobile-only pieces (Figma 576:3879 / 576:3733) ──────────────────── */

@media (max-width: 639.98px) {
  /* The mobile frame flattens the grouped amenity columns into one horizontal
     scrolling strip of chips — no group headings. HMS-1406 — the strip used
     display:contents to dissolve the group wrappers into the scroller, but a
     contents-flattened child can be skipped when a mobile engine builds the
     scrollable overflow, which left the strip unwipeable on iOS. The groups
     are real nested flex rows now: same flat chip line and gap rhythm,
     ordinary boxes the scroller can always measure. */
  .hotel-detail__amenity-groups {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
  }

  .amenity-group {
    display: flex;
    flex-direction: row;
    gap: 0.5rem;
    flex: 0 0 auto;
  }

  .amenity-group__items {
    display: flex;
    flex-direction: row;
    gap: 0.5rem;
  }

  .amenity-group__heading {
    display: none;
  }

  .amenity-feature {
    flex: 0 0 auto;
  }

  /* The mobile frame carries no check-in/out boxes, no dark distance pill,
     and no sidebar — one quiet meta row under the stars covers the venue
     facts ("0.1 mi from venue · Downtown"). Hiding the rail removes its
     layout gap too. */
  .hotel-detail__times,
  .hotel-detail__rail,
  .hotel-detail__distance-pill,
  .photo-gallery__wrap .photo-gallery__fav,
  .photo-gallery__wrap form.button_to,
  .hotel-detail__back {
    display: none;
  }

  .hotel-detail__name-row {
    justify-content: space-between;
    gap: 0.5rem;
  }

  /* The heart moves onto the name row — the mobile frame has no gallery strip
     for it to float on. Same real control rendered in the name row; the
     gallery copy is hidden above. */
  .hotel-detail__fav {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    border: 1px solid var(--wa-color-surface-border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--wa-color-surface-default);
    color: var(--wa-color-text-normal);
    font-size: 1rem;
    cursor: pointer;
    padding: 0;
    flex-shrink: 0;
    text-decoration: none;
  }

  .hotel-detail__fav--saved {
    color: var(--wa-color-brand);
  }

  .hotel-detail__fav-row .button_to {
    display: contents;
  }

  .hotel-detail__fav-row {
    display: block;
  }

  /* Inline on the stars row in Figma 576:3879: "★★★★★ · 0.1 mi from venue ·
     Downtown" — muted gold, no icon. */
  .hotel-detail__venue-line {
    display: inline;
    font-size: 0.8125rem;
    color: var(--ek-color-vip-gold);
    margin: 0;
  }

  .star-rating ~ .hotel-detail__venue-line::before {
    content: "·";
    margin-right: 0.375rem;
  }

  /* Compact room rows — the design replaces the full card with a single
     filled row: name + availability left, rate + BOOK right. */
  .room-type-card {
    border: none;
    border-radius: 0.5rem;
    background: var(--wa-color-neutral-fill-quiet);
  }

  .room-type-card:hover {
    transform: none;
    box-shadow: none;
  }

  /* The compact rule above zeroes the border and flattens the background —
     without this the selected room kept only a 1px hairline ring and read
     identical to its unselected siblings. */
  .room-type-card--selected {
    border: 1px solid var(--wa-color-brand-fill-loud);
    box-shadow: 0 0 0 1px var(--wa-color-brand-fill-loud);
    background: var(--wa-color-brand-95);
  }

  .room-type-card__thumbnail,
  .room-type-card__bed,
  .room-type-card__capacity {
    display: none;
  }

  /* With capacity hidden, a lone "rooms left" span must not inherit the ·
     separator that only exists to split two facts. */
  .room-type-card__meta > span + span::before {
    content: none;
    margin-right: 0;
  }

  /* One compact row: info left, rate+CTA stacked right (Figma 576:3879).
     The base card already stacks the actions column on desktop — the row
     override above the fold wrapped the waitlist line and upgrade text into
     their own rows, which is how the card grew to four rows tall. */
  .room-type-card__body {
    flex-wrap: nowrap;
  }

  .room-type-card__info {
    flex: 1;
    min-width: 0;
  }

  /* Facts Figma's compact row does not show — the payment-terms line and the
     waitlist count stay desktop-only. The upgrade OFFER text stays: its
     "Book this upgrade" button renders in the same column, and hiding the
     text would leave a context-free CTA. */
  .room-type-card__pay,
  .room-type-card__waitlist-line {
    display: none;
  }

  /* flex item default shrink would let a wide footer action (the two-line
     waitlist button) squeeze the rate until "from" wraps onto its own line —
     the natural ~8.4rem fits beside every footer action at this width. */
  .room-type-card__rate {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 0.9375rem;
  }

  /* The waitlist action is an outlined button in the mobile design, not the
     filled primary it is on desktop. */
  .room-type-card__waitlist {
    padding: 0.5rem 0.875rem;
    background: transparent;
    color: var(--wa-color-brand-fill-loud);
    border: 1px solid var(--wa-color-brand-fill-loud);
    border-radius: 0.375rem;
  }

  /* The fixed sticky bar (Figma 576:3879): from-rate + stay arithmetic left,
     Select Room right. The extra right padding clears the chatbot toggle —
     a 3.5rem circle pinned 1.5rem from the corner — so the CTA is never the
     element it floats over. The bottom padding must clear the bar's real
     height: ~4.6rem with one-line copy, ~7.5rem if a longer locale wraps it
     back to two lines per span. */
  .hotel-detail--sticky {
    /* HMS-1127 — the footer below already reserves the bar + tabbar stack
       (portal_header.css, HMS-367), so the page keeps only HMS-491's 2rem.
       Reserving it here too left a ~340px blank band under the banner. */
    padding-bottom: 2rem;
  }

  .hotel-detail__stickybar {
    position: fixed;
    inset-inline: 0;
    /* HMS-464 — the bar stacks ABOVE the bottom portal tabbar (~3.5rem plus
       its safe-area padding, the same offset the chatbot FAB already uses in
       portal_header.css). At bottom:0 the tabbar's z-index 950 covered the
       bar and made its Book Now unreachable; the offset is the tabbar's own
       --portal-tabbar-h so the two stack flush (HMS-1409). */
    bottom: calc(var(--portal-tabbar-h, 3.5rem) + env(safe-area-inset-bottom, 0px));
    z-index: 900;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 5.5rem 0.75rem 0.5rem;
    background: var(--wa-color-surface-raised);
    border-top: 1px solid var(--wa-color-neutral-border-quiet);
    box-shadow: var(--wa-shadow-l);
  }

  .hotel-detail__stickybar-copy {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
  }

  .hotel-detail__stickybar-rate {
    font-size: 1rem;
    font-weight: 700;
    color: var(--wa-color-text-normal);
  }

  .hotel-detail__stickybar-stay {
    font-size: 0.8125rem;
    color: var(--wa-color-text-quiet);
  }

  /* The copy column only has ~11rem to work with once the chatbot clearance
     and CTA are paid for. A 0.875rem CTA (font-size cascades into the shadow
     button, so its em padding shrinks with it) buys enough width for the
     English rate and stay lines to each hold one line; longer locales still
     wrap, which the page padding above already budgets for. */
  .hotel-detail__stickybar wa-button {
    flex-shrink: 0;
    font-size: 0.875rem;
  }

  /* Figma 576:3879 — the mobile sold-out row reads "King Suite · SOLD OUT":
     the status is middot-joined to the name in quiet text, not a red tag.
     The red in the design belongs to the "0 rooms available" line below. */
  .room-type-card__soldout {
    background: none;
    padding: 0;
    border-radius: 0;
    margin-left: 0.25rem;
    color: var(--wa-color-text-quiet);
    font-size: inherit;
    letter-spacing: normal;
    text-transform: uppercase;
  }

  .room-type-card__soldout i {
    display: none;
  }

  /* Figma 576:3879 — the sold-out row's right column carries only the
     outlined waitlist CTA; no rate. The card gets a --sold-out modifier in
     markup; plain sellable rows keep their rate. */
  .room-type-card--sold-out .room-type-card__rate {
    display: none;
  }

  /* The anonymous CTA's long "Sign in to join the waitlist" squeezed the name
     column into a multi-line wrap — the compact label matches the signed-in
     button. The "0 rooms available" line holds one line like the frame. */
  .room-type-card__waitlist-full {
    display: none;
  }

  .room-type-card__waitlist-short {
    display: inline;
  }

  .room-type-card__none {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* The "· Sold Out" status never splits mid-phrase — it wraps to a second
     line as one unit when the name is long. */
  .room-type-card__soldout {
    white-space: nowrap;
  }

  /* A sold-out card WITH an upgrade offer needs a second row: the offer text
     plus its "Book this upgrade" CTA can't share the compact row with the
     name. The body wraps so the actions column takes a full row below —
     taller than Figma's simple sold-out row, but the offer has no Figma
     analog and a readable card beats a 27px name column. */
  .room-type-card--upgrade .room-type-card__body {
    flex-wrap: wrap;
  }

  .room-type-card--upgrade .room-type-card__actions {
    flex: 1 0 100%;
    flex-direction: column;
    align-items: flex-start;
    margin-top: 0.375rem;
  }

  .room-type-card__soldout::before {
    content: "·";
    margin-right: 0.375rem;
    color: var(--wa-color-text-quiet);
  }

  /* The mobile bar's compact CTA reads "BOOK" (uppercase); the desktop card
     keeps "Book Now". */
  .room-type-card__book-full {
    display: none;
  }

  .room-type-card__book-short {
    display: inline;
    text-transform: uppercase;
    letter-spacing: 0.03em;
  }

  /* "12 rooms" on the compact row — the desktop "N rooms left" wording hides. */
  .room-type-card__avail-full {
    display: none;
  }

  .room-type-card__avail-short {
    display: inline;
  }

  /* Figma 576:3879 shows no negotiated badge on mobile — name, stars + meta
     line, tagline only. The two-class selectors are load-bearing: the badge's
     own display rules sit LATER in this file (HMS-438 concierge block), so a
     one-class hide would lose the cascade and the badge would leak through. */
  .hotel-detail__title-group .hotel-detail__negotiated-badge,
  .hotel-detail__title-group .hotel-detail__sponsored-badge,
  .hotel-detail__title-group .hotel-detail__hq-badge {
    display: none;
  }

  /* "Available Rooms" on mobile — the desktop heading keeps its longer text. */
  .hotel-detail__rooms-title-full {
    display: none;
  }

  .hotel-detail__rooms-title-short {
    display: inline;
  }

  /* HMS-1499 — the rooms-section copy of the stay picker, hidden at ≥640px by
     the base rule above; the rail's copy covers tablet and desktop. */
  .hotel-detail__stay-mobile {
    display: block;
    margin-bottom: 1rem;
  }

  /* Figma 576:3879's banner is one short line — "More options at nearby
     hotels →". The desktop copy sentence and link label both hide. */
  .hotel-detail__alt-copy,
  .hotel-detail__alt-link-full {
    display: none;
  }

  .hotel-detail__alt-link-short {
    display: inline;
  }

  .hotel-detail__alt-banner {
    justify-content: center;
  }

  /* Figma 576:3879 shows the description as a bare paragraph under the meta
     line — no "About" heading. */
  .hotel-detail__description .hotel-detail__section-title {
    display: none;
  }
}

@media (min-width: 640px) {
  .hotel-detail__stickybar {
    display: none;
  }
}

/* Figma 576:3879 — on mobile the sticky bar IS the price summary: the desktop
   card is not rendered at all below 640px, where its rows would only restate
   what the bar already says. */
@media (max-width: 639.98px) {
  .price-summary {
    display: none;
  }
}

/* HMS-438 — Concierge density on the detail page: negotiated badge by the
   title, full address line, expandable policy block, special-rate label and
   cancel terms on room cards. */

.hotel-detail__negotiated-badge {
  display: inline-block;
  align-self: start;
  width: fit-content;
  padding: 0.125rem 0.625rem;
  border-radius: 9999px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  /* brand fill + on-loud text — same token pair the file uses for filled badges */
  background: var(--wa-color-brand-fill-loud);
  color: var(--wa-color-brand-on-loud);
}

/* HMS-447 — Headquarters/Official badge. Gold accent reads as the prestige
   marker beside the neutral negotiated chip. */
.hotel-detail__hq-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  align-self: start;
  width: fit-content;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--wa-color-warning-on-quiet);
  background: var(--wa-color-warning-fill-quiet);
  border-radius: 9999px;
  padding: 0.125rem 0.625rem;
}

/* HMS-1385 — featured-hotel badge: the solid brand pill the search card's
   sponsored badge wears, placed beside the negotiated chip. */
.hotel-detail__sponsored-badge {
  display: inline-block;
  align-self: start;
  width: fit-content;
  padding: 0.125rem 0.625rem;
  border-radius: 9999px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  background: var(--wa-color-brand-fill-normal);
  color: var(--wa-color-brand-on-normal);
}


/* Figma 560:9767 — "7 people on waitlist · Position #8" under the waitlist CTA.
   flex-basis forces it onto its own row in the wrapped mobile flex; on desktop
   it just stacks inside the right column like the rate and button. */
.room-type-card__waitlist-line {
  margin: 0;
  flex-basis: 100%;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

/* ── Photo lightbox (HMS-443) ──────────────────────────── */

.photo-lightbox {
  padding: 0;
  border: none;
  background: transparent;
  /* Shrink-wraps its content instead of pinning a fixed width: fit-content
     hugs the image (capped at min(72rem, 82vw)) and still overrides Web
     Awesome's native.css width:32rem <dialog> pin. */
  width: fit-content;
  max-width: 96vw;
  max-height: 92vh;
  /* <dialog>'s UA default overflow:auto clips the desktop chevrons that sit
     outside the card at -3.25rem — they painted unreachable and every click
     hit the dialog instead. The stage self-limits (img ≤70vh) so visible is
     safe. */
  overflow: visible;
  /* HMS-562 — native.css aligns open-dialog children to `start`, which pinned
     the stage at the left edge. Center the stage + filmstrip so a narrow
     image sits in the middle of the scrim and the close button anchors to
     the image's true top-right corner. */
  align-items: center;
}

.photo-lightbox::backdrop {
  background: rgb(0 0 0 / 0.78);
}

.photo-lightbox__stage {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

/* Positioning frame: shrink-wraps the img because the buttons are
   absolutely positioned against it. */
.photo-lightbox__frame {
  position: relative;
}

.photo-lightbox__stage img {
  max-width: min(72rem, 82vw);
  max-height: calc(92vh - 8.5rem);
  object-fit: contain;
  border-radius: 0.5rem;
  display: block;
}

.photo-lightbox__counter {
  color: var(--ek-color-on-scrim);
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: center;
}

/* Figma photos-popup — the controls are small square light tiles, not dark
   circles: the X sits inside the card's top-right corner and the chevrons
   float OUTSIDE the card on the backdrop (≥1024px, where the margins can
   hold them). */
.photo-lightbox__nav,
.photo-lightbox__close {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: none;
  border-radius: 0.5rem;
  background: var(--wa-color-surface-default);
  color: var(--wa-color-text-normal);
  font-size: 1rem;
  cursor: pointer;
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.35);
}

/* The frame wraps exactly the image, so 50% is the photo's true midline. */
.photo-lightbox__nav { top: 50%; transform: translateY(-50%); }
.photo-lightbox__prev { left: -3.25rem; }
.photo-lightbox__next { right: -3.25rem; }
.photo-lightbox__close { top: 0.875rem; right: -3.25rem; }

.photo-lightbox__nav:hover,
.photo-lightbox__close:hover {
  background: var(--wa-color-surface-raised);
}

.photo-lightbox__nav:focus-visible,
.photo-lightbox__close:focus-visible {
  outline: var(--wa-focus-ring);
  outline-offset: 2px;
}

/* HMS-443 — Figma 567-3283 filmstrip: every photo as a small thumb along the
   bottom of the lightbox so the viewer can jump, not only step. */
.photo-lightbox__filmstrip {
  display: flex;
  gap: 0.375rem;
  justify-content: safe center;
  overflow-x: auto;
  /* The stage is content-sized now; without a cap a long strip would stretch
     the dialog past the image. */
  max-width: min(72rem, 90vw);
  padding: 0.25rem 0.125rem;
}

.photo-lightbox__filmstrip-thumb {
  flex: 0 0 auto;
  width: 9rem;
  height: 5.25rem;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 0.5rem;
  overflow: hidden;
  background: none;
  cursor: pointer;
  opacity: 0.65;
}

.photo-lightbox__filmstrip-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.photo-lightbox__filmstrip-thumb--active {
  border-color: var(--ek-color-on-scrim);
  opacity: 1;
}

.photo-lightbox__filmstrip-thumb:focus-visible {
  outline: var(--wa-focus-ring);
  outline-offset: 2px;
}

@media (max-width: 639.98px) {
  .photo-lightbox__filmstrip-thumb {
    width: 4.5rem;
    height: 2.75rem;
  }
}

/* The image cap (min(72rem, 82vw)) — not the dialog width — guarantees ≥9vw
   of side margin, so the -3.25rem chevron tiles always fit outside the photo
   from 640px up. Below 960px the margin gets tight, so the chevrons tuck back
   inside the photo edge and the close button comes back onto the image. */
@media (max-width: 959.98px) {
  .photo-lightbox__prev { left: 0.5rem; }
  .photo-lightbox__next { right: 0.5rem; }
  /* HMS-1405 — the frame shrink-wraps the photo, so on a short image the
     midline chevron lands on the same spot as the top-corner X (both sit in
     the image's right lane). Pin the X to the viewport's top-right corner
     instead: a scrim-level control that stays clear of the on-image arrows
     at any image height. */
  .photo-lightbox__close { position: fixed; top: 0.875rem; right: 0.875rem; }
}

.photo-lightbox--single .photo-lightbox__nav,
.photo-lightbox--single .photo-lightbox__counter,
.photo-lightbox--single .photo-lightbox__filmstrip {
  display: none;
}

/* HMS-446 — nightly availability disclosure under the room list. The toggle
   reads like the adjacent compare link; the tables are plain quiet grids that
   stack full-width on narrow screens. */
.hotel-detail__nightly {
  margin-top: 1rem;
}

.hotel-detail__nightly-toggle {
  cursor: pointer;
  color: var(--wa-color-brand);
  font-size: 0.875rem;
  font-weight: 600;
}

.hotel-detail__nightly-table {
  width: 100%;
  margin-top: 0.75rem;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.hotel-detail__nightly-table caption {
  text-align: left;
  font-weight: 600;
  padding-bottom: 0.25rem;
}

.hotel-detail__nightly-table th,
.hotel-detail__nightly-table td {
  text-align: left;
  padding: 0.375rem 0.5rem;
  border-bottom: 1px solid var(--wa-color-neutral-border-quiet);
}

.hotel-detail__nightly-table thead th {
  font-size: 0.75rem;
  color: var(--wa-color-text-quiet);
  font-weight: 600;
}

/* ── HMS-451 — guest reviews + alternative-hotels banner (Figma 560:9767 / 560:9856) ── */

.hotel-detail__reviews-link {
  color: var(--wa-color-brand);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  /* The mobile meta row squeezes the link against the stars row and wrapped
     it to two lines — keep it on one. */
  white-space: nowrap;
}

.hotel-detail__reviews-link:hover {
  text-decoration: underline;
}

.hotel-detail__reviews {
  margin-top: 2rem;
}

.guest-review {
  margin-top: 1rem;
  padding: 1rem;
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.5rem;
}

.guest-review__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.guest-review__who {
  display: inline-block;
  margin-top: 0.5rem;
  font-weight: 600;
  font-size: 0.9375rem;
}

.guest-review__date {
  color: var(--wa-color-text-quiet);
  font-size: 0.8125rem;
}

.guest-review__body {
  margin: 0.5rem 0 0;
  color: var(--wa-color-text-normal);
  font-size: 0.9375rem;
}

.guest-review__response {
  margin-top: 0.75rem;
  padding: 0.75rem 1rem;
  background: var(--wa-color-surface-raised);
  border-radius: 0.5rem;
}

.guest-review__response-label {
  display: block;
  font-size: 0.8125rem;
  margin-bottom: 0.25rem;
}

.guest-review__response-body {
  margin: 0;
  font-size: 0.875rem;
  color: var(--wa-color-text-quiet);
}

/* Figma 560:9767 — a solid quiet bar, not a bordered card */
.hotel-detail__alt-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2rem;
  padding: 1rem 1.25rem;
  border-radius: 0.5rem;
  background: var(--wa-color-neutral-fill-quiet);
}

.hotel-detail__alt-copy {
  margin: 0;
  min-width: 0;
  color: var(--wa-color-text-quiet);
  font-size: 0.9375rem;
}

.hotel-detail__alt-link {
  color: var(--wa-color-brand);
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
}

.hotel-detail__alt-link:hover {
  text-decoration: underline;
}

/* ── HMS-369 room detail modal ─────────────────────────── */

dialog.room-modal {
  border: 0;
  padding: 0;
  border-radius: 0.75rem;
  max-width: min(32rem, 92vw);
  width: 100%;
}

dialog.room-modal::backdrop {
  background: rgba(0, 0, 0, 0.5);
}

.room-modal__frame {
  position: relative;
  /* HMS-728 — the dialog is display:flex, which shrink-wraps this frame to
     its content. With a photo the image's width masked it; without one the
     close button anchored to a mid-modal edge. Always fill the dialog. */
  width: 100%;
}

.room-modal__close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 0;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.5);
  color: var(--wa-color-surface-default);
  cursor: pointer;
}

.room-modal__photo {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
  border-radius: 0.75rem 0.75rem 0 0;
}

.room-modal__body {
  padding: 1.25rem;
}

.room-modal__name {
  margin: 0 0 0.75rem;
  /* HMS-728 — the absolutely-positioned close button sits 0.75rem from the
     frame's top-right at 2.25rem wide; reserve its lane so a photo-less
     modal's title never runs underneath it. */
  padding-right: 3rem;
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--wa-color-text-normal);
}

.room-modal__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  font-size: 0.875rem;
  color: var(--wa-color-text-quiet);
}

.room-modal__facts > * {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.room-modal__heading {
  margin: 1.25rem 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--wa-color-text-quiet);
  text-transform: uppercase;
  letter-spacing: 0.025em;
}

.room-modal__amenities {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.room-modal__chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  background: var(--wa-color-neutral-fill-quiet);
  border-radius: 999px;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

.room-type-card__details-trigger {
  float: right;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 0;
  background: none;
  color: var(--wa-color-text-quiet);
  cursor: pointer;
}

/* ── Map card (HMS-574) ─────────────────────────────────── */

/* Rail card: same border/radius/background as the other rail cards
   (.hotel-detail__times, .price-summary). overflow:hidden clips the map's
   corners to the card radius. */
.hotel-detail__map-card {
  border: 1px solid var(--wa-color-surface-border);
  border-radius: 0.75rem;
  background: var(--wa-color-surface-default);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

.hotel-detail__map {
  width: 100%;
  height: 200px;
}

.hotel-detail__map-card-body {
  padding: var(--spacing-3, 0.75rem);
}

.hotel-detail__map-address {
  margin: 0;
  font-size: 1rem;
  color: var(--wa-color-text-quiet);
}

.hotel-detail__map-distance {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

/* Action link, matching .hotel-detail__reviews-link / .hotel-detail__alt-link:
   brand color, semibold, no underline until hover. The gap leaves room for the
   leading fa-solid fa-diamond-turn-right icon the markup adds. */
.hotel-detail__map-directions {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--wa-color-brand);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
}

.hotel-detail__map-directions:hover {
  text-decoration: underline;
}

/* HMS-603 — the map card lives in the main column at every width now; the
   rail carries only the price summary, so there is no separate mobile slot. */
.hotel-detail__location {
  margin-top: 1.5rem;
}

/* HMS-1380 — a live GDS rate inside the contracted block list. Same row-card
   skeleton as .room-type-card (icon tile left where the block card puts its
   thumbnail, info middle, rate column right) so the two sources read as one
   list; the dashed border and broadcast icon mark it as the agency feed —
   never a bookable block, and it gets no hover affordance because there is
   nothing to click. */
.live-rate-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem;
  background: var(--wa-color-surface-default);
  border: 1px dashed var(--wa-color-surface-border);
  border-radius: 0.75rem;
}

.live-rate-card__icon {
  width: 5.5rem;
  aspect-ratio: 1;
  border-radius: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--wa-color-neutral-fill-quiet);
  color: var(--wa-color-text-quiet);
  font-size: 1.5rem;
  flex-shrink: 0;
}

.live-rate-card__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
}

.live-rate-card__info {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.live-rate-card__name {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--wa-color-text-normal);
  line-height: 1.3;
}

/* Brand-tinted counterpart to the neutral __source-tag: the live badge is
   the exception a guest needs to notice. */
.live-rate-card__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  vertical-align: middle;
  margin-left: 0.5rem;
  background: var(--wa-color-brand-fill-quiet);
  color: var(--wa-color-brand-on-quiet);
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}

.live-rate-card__note,
.live-rate-card__meta {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--wa-color-text-quiet);
}

.live-rate-card__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 0.375rem;
  flex-shrink: 0;
}

.live-rate-card__rate {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--wa-color-text-normal);
}

.live-rate-card__per-night {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--wa-color-text-quiet);
}

.live-rate-card__agency {
  font-size: 0.75rem;
  color: var(--wa-color-text-quiet);
}

@media (max-width: 639.98px) {
  /* Compact like the mobile room-type-card row: smaller tile, rate that
     cannot wrap, and the agency line drops — the badge still says where
     the rate comes from. */
  .live-rate-card {
    gap: 0.75rem;
  }

  .live-rate-card__icon {
    width: 3rem;
    font-size: 1rem;
  }

  .live-rate-card__rate {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 0.9375rem;
  }

  .live-rate-card__agency {
    display: none;
  }
}
