/* ==========================================================================
   Sovana — the booking funnel after the results: ③ residence, ④ checkout,
   ⑤ payment, ⑥ confirmation. Layered on tokens.css + styles-alt.css.
   Same material as the rest of the ALT build: square, .t-* type only,
   hairlines, green shadows, white only when lifted.
   ========================================================================== */

.flow { padding-top: max(calc(var(--section-y) + 20px), 132px); }

/* ── Where you are — after raffles.com's booking steps (2026-09-24) ──────
   Labels and a chevron between; no numbers (removed by request). Steps
   already passed stay active (green) and link back to their page; the
   current one is green too; the ones ahead are muted. */
.steps {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
  list-style: none; margin: 0 0 clamp(28px, 3vw, 40px); padding: 0;
  color: var(--muted);
}
.steps li { display: flex; align-items: center; gap: 10px; }
.steps li + li::before {
  content: ""; width: 6px; height: 6px; margin-right: 8px;
  border-top: 1px solid currentColor; border-right: 1px solid currentColor;
  rotate: 45deg; opacity: .6;
}
.steps .is-done, .steps [aria-current="step"] { color: var(--green); }
/* a passed step is an underline link: the gold hairline wipes in */
.steps a { position: relative; padding-block: 4px; color: inherit; text-decoration: none; }
.steps a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--gold); transform: scaleX(0); transform-origin: left;
  transition: transform var(--duration) var(--ease-out);
}
.steps a:hover::after { transform: scaleX(1); }
.steps a:focus-visible { outline: 2px solid var(--gold-700); outline-offset: 4px; }

/* ── ④ ⑤ layout — after raffles.com/booking/complete (2026-09-24) ─────────
   The head (back link, steps, title, one line) left-aligned on the page's
   own light ground — the darker band was taken out by request — then the
   form card and the summary card, 48px apart. Head and cards share one
   measure, capped at 1440. The form fills its card. */
.flow--band { padding-top: max(calc(var(--section-y) + 20px), 132px); }
.flow-band, .flow__grid--band { max-width: 1440px; margin-inline: auto; }
.flow-band {
  display: flex; flex-direction: column; align-items: flex-start; gap: 14px;
  margin-bottom: clamp(32px, 4vw, 48px);
}
.flow-band .back { margin-bottom: clamp(4px, 1vw, 12px); }
.flow-band .steps { margin-bottom: clamp(12px, 2vw, 24px); }
.flow-band h1 { margin: 0; color: var(--green); text-wrap: balance; }
.flow-band p { margin: 0; color: var(--muted); }
.flow__grid.flow__grid--band {   /* doubled: the base .flow__grid sits later in the file */
  grid-template-columns: minmax(0, 65fr) minmax(0, 35fr);   /* 65 / 35, by request (55 / 45 tried first) */
  column-gap: 20px;   /* 48, then 24, then 20 — cards sit 20 apart on every page (2026-09-28) */
}
@media (max-width: 1080px) { .flow__grid.flow__grid--band { grid-template-columns: minmax(0, 1fr); } }
.flow-card {
  padding: clamp(24px, 4vw, 56px);
  background: var(--white);
  box-shadow: 0 0 0 1px var(--hairline-color), var(--shadow-card);
}
.flow-card__title {
  margin: 0 0 clamp(28px, 3vw, 44px); padding-bottom: 20px;
  border-bottom: var(--hairline); color: var(--green);
}
/* the form and the payment blocks fill the card */
.flow-card .co-form, .flow-card .pay-form, .flow-card .pay-box, .flow-card .pay-test { max-width: none; }
.flow-card .empty { padding-block: 0; }
.field__req { color: var(--muted); }
/* the summary's picture runs to the card's edges, as Raffles' hotel image */
.flow__grid--band .summary__thumb { margin: calc(-1 * var(--sum-pad)) calc(-1 * var(--sum-pad)) 22px; }

.back {
  position: relative; display: inline-flex; margin-bottom: 20px; padding: 5px 0;
  color: var(--green);
}
.back::after, .tlink::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--gold); transform: scaleX(0); transform-origin: left;
  transition: transform var(--duration) var(--ease-out);
}
.back:hover::after, .tlink:hover::after { transform: scaleX(1); }
.back:focus-visible, .tlink:focus-visible { outline: 2px solid var(--gold-700); outline-offset: 4px; }
.tlink { position: relative; padding-block: 4px; background: none; border: 0; cursor: pointer; color: var(--green); }

/* ── Two columns: the content, and a pinned summary ─────────────────────
   The summary is the one white surface on these pages, so it is lifted:
   hairline ring + card shadow. Sticky under the fixed nav. */
.flow__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 400px;
  gap: clamp(40px, 5vw, 80px); align-items: start;
}
.summary {
  --sum-pad: clamp(22px, 2.4vw, 32px);
  position: sticky; top: 116px;
  padding: var(--sum-pad);
  background: var(--white);
  box-shadow: 0 0 0 1px var(--hairline-color), var(--shadow-card);
}
.summary__name { margin: 0; color: var(--green); }
.summary__meta { margin: 6px 0 0; color: var(--muted); }
.summary__thumb { margin: 0 0 20px; aspect-ratio: 16 / 10; overflow: hidden; background: var(--ivory); }
.summary__thumb img { width: 100%; height: 100%; object-fit: cover; outline: 1px solid oklch(0 0 0 / .1); outline-offset: -1px; }
.summary__thumb--plan img { object-fit: contain; padding: 8px; outline: 0; }

.lines { margin: 20px 0 0; padding: 0; border-top: var(--hairline); }
.lines div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 12px 0; border-bottom: var(--hairline);
}
.lines dt { color: var(--muted); }
.lines dd { margin: 0; color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.lines .is-total dt, .lines .is-total dd { color: var(--green); }
.lines .is-tbc { color: var(--muted); }
.summary .btn { width: 100%; margin-top: 22px; }
.summary__note { margin: 12px 0 0; color: var(--muted); }
.summary .st { margin-top: 16px; }

/* ── the hold card (⑤) — a fact, not a threat (brief §5) ─────────────────
   Its own white card in the right column, below the summary
   (2026-09-25, by request — it was a caption inside the summary, then a bar
   under the title, then above the summary). The column is pinned as one,
   but at ~1040px it is taller than a laptop screen: at 1440x900 the card
   starts below the fold (measured, top at 1192px).
   Highlighted by place and size — the time at price size, a gold rule —
   never by an alarm colour. */
.pay-side { position: sticky; top: 116px; display: flex; flex-direction: column; gap: 20px; }
.pay-side > .summary { position: static; }
.holdbar {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  align-items: center; column-gap: 16px; row-gap: 14px;
  padding: 20px var(--sum-pad, 28px);
  background: var(--white); border-left: 2px solid var(--gold);
  box-shadow: 0 0 0 1px var(--hairline-color), var(--shadow-card);
  --sum-pad: clamp(22px, 2.4vw, 32px);
}
.holdbar__ico { width: 28px; height: 28px; color: var(--green); }
.holdbar__time { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.holdbar__label { color: var(--muted); }
.holdbar__time .t-price { color: var(--green); font-variant-numeric: tabular-nums; min-width: 3.2ch; }
.holdbar__note, .holdbar__ref { grid-column: 1 / -1; margin: 0; }
.holdbar__note { color: var(--ink); text-wrap: pretty; }
.holdbar__ref { padding-top: 14px; border-top: var(--hairline); color: var(--muted); }
.holdbar__ref b { font-weight: var(--weight-regular); color: var(--green); font-variant-numeric: tabular-nums; }
.holdbar.is-over .holdbar__time .t-price { color: var(--muted); }

/* reused from the results page: the availability status line */
.st { display: flex; align-items: baseline; gap: 10px; margin: 10px 0 0; color: var(--green); }
.st::before { content: ""; flex: none; width: 7px; height: 7px; transform: translateY(-1px); background: var(--gold); }
.st--booked::before { background: none; box-shadow: inset 0 0 0 1px var(--muted); }

.notice {
  display: flex; align-items: baseline; gap: 10px;
  margin: 0 0 28px; padding: 14px 18px;
  background: var(--ivory); color: var(--green);
  border-left: 2px solid var(--gold);
}


/* ── ③ Residence ────────────────────────────────────────────────────────── */
.res-head { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; margin-bottom: clamp(24px, 3vw, 36px); }
.res-head h1 { margin: 0; color: var(--green); }

.res-hero { margin: 0; aspect-ratio: 3 / 2; overflow: hidden; background: var(--ivory); }
.res-hero img { width: 100%; height: 100%; object-fit: cover; outline: 1px solid oklch(0 0 0 / .1); outline-offset: -1px; }
.res-hero--plan img { object-fit: contain; padding: clamp(12px, 2vw, 28px); outline: 0; }
.res-hero__cap { margin: 10px 0 0; color: var(--muted); }

/* No divider between the story's sections (2026-09-24, by request): the
   same total space the hairline used to split — padding + margin — as one
   margin, so the sections still read as separate. */
.res-block { margin-top: clamp(72px, 8vw, 112px); }
.res-block h2 { margin: 0 0 18px; color: var(--green); }
.res-block p { margin: 0; color: var(--muted); max-width: 62ch; }

.res-plan { margin: 0; padding: clamp(16px, 2vw, 28px); background: var(--ivory); border: 1px solid rgba(14, 43, 33, .09); }
.res-plan img { width: 100%; height: auto; display: block; }
.res-plan figcaption { margin-top: 12px; color: var(--muted); }

.res-block .tlink { margin-top: 18px; display: inline-block; }


/* ── ④ Checkout — it is a form and looks like one ──────────────────────── */
.co-head { margin-bottom: clamp(24px, 3vw, 36px); }
.co-head h1 { margin: 0; color: var(--green); }
.co-head p { margin: 10px 0 0; color: var(--muted); }
.co-form { display: flex; flex-direction: column; gap: 32px; max-width: 620px; }
.co-row { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; }
.co-form .field input, .co-form .field select { font: inherit; }
.field__err { margin: 0; color: var(--maroon); }       /* maroon: error text, its reserved use */
.field__err[hidden] { display: none; }
.field input[aria-invalid="true"] { border-bottom-color: var(--maroon); }
/* Before you pay — three numbered facts on hairline rows, above the action.
   Square numbers (ALT has no round shapes); the key word in green, not bold —
   the type system has one weight. */
.before { margin-top: 32px; }   /* 32 on top of the form's 32 gap: set apart from the fields, by request */
.before__title { margin: 0 0 8px; color: var(--green); }
.before__list { list-style: none; margin: 0; padding: 0; counter-reset: before; }
.before__list li {
  display: flex; align-items: baseline; gap: 16px; padding: 14px 0;   /* the text is one <span>, so <em> stays inline */
  color: var(--muted); counter-increment: before;
}
.before__list li + li { border-top: var(--hairline); }
.before__list li::before {
  content: counter(before); flex: none; display: grid; place-items: center;
  width: 26px; height: 26px; transform: translateY(-1px);
  background: var(--ivory); color: var(--green);
  font-size: var(--size-13); font-variant-numeric: tabular-nums;
}
.before__list em { font-style: normal; color: var(--green); }
/* the form's one action fills the form's width (2026-09-24, by request) */
.co-form .btn { align-self: stretch; width: 100%; }

/* ── ⑤ Payment — the site's own page, after staysanliving.com ───────────
   choose → instructions (waiting) → confirmation; failed and expired return
   here. The methods sit in groups (QRIS · bank transfer · e-wallet · card);
   the instructions are one hairline box: amount, the code, the steps. */
.testmode {
  margin: 0 0 28px; padding: 14px 18px; color: var(--green);
  border: 1px dashed rgba(14, 43, 33, .38);
}
.pay-form { display: flex; flex-direction: column; gap: 20px; max-width: 620px; }
.pay-lede { margin: -16px 0 24px; color: var(--muted); }
/* the four rows — radio, name + line, tag. The chosen one lifts to white
   with a green edge. The radio is ROUND — a ring with a filled dot, after
   raffles.com (2026-09-24, by request): the one deliberate exception to "no
   round shapes" in the ALT build, because a radio reads as a radio. Resting
   rows on --ivory — the darker ivory read too dark on the white card. */
.mrows { margin: 0; padding: 0; border: 0; display: grid; gap: 10px; min-width: 0; }
.mrow {
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 18px;
  padding: 18px 22px; cursor: pointer;
  background: var(--ivory); border: 1px solid var(--hairline-color);
  transition: background-color var(--dur-quick) var(--ease-out), border-color var(--dur-quick) var(--ease-out);
}
.mrow input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.mrow__dot { width: 20px; height: 20px; border: 1px solid rgba(14, 43, 33, .45); border-radius: 50%; display: grid; place-items: center; }
.mrow__dot::after { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--green); transform: scale(0); transition: transform var(--dur-quick) var(--ease-out); }
.mrow__text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mrow__text .t-lead { color: var(--green); }
.mrow__text small { color: var(--muted); }
.mrow__tag { color: var(--muted); text-align: right; }
/* the brands' own marks, small, in their own colours */
.mrow__side { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.mrow__logos { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px 18px; }   /* 10 first — wider by request */
.paylogo { display: block; height: 13px; width: auto; max-width: 64px; object-fit: contain; }   /* 18 first — smaller by request */
.paylogo--mastercard, .paylogo--jcb, .paylogo--bni { height: 15px; }
/* ShopeePay's mark is 5:1 — the width cap would shrink it below its neighbours */
.paylogo--shopeepay { height: 15px; max-width: none; }
.method--logo .paylogo--shopeepay { height: 17px; }
.method--logo > span { min-width: 96px; justify-content: center; }
.method--logo .paylogo { height: 15px; }
.mrow:hover { border-color: rgba(14, 43, 33, .28); }
.mrow:has(input:checked) { background: var(--white); border-color: var(--green); }
.mrow:has(input:checked) .mrow__dot { border-color: var(--green); }
.mrow:has(input:checked) .mrow__dot::after { transform: scale(1); }
.mrow:has(input:focus-visible) { outline: 2px solid var(--gold-700); outline-offset: 2px; }
/* what happens next, and which bank or wallet */
.mdetail { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 24px; text-align: center; background: var(--ivory); }
.mdetail p { margin: 0; color: var(--ink); max-width: 44ch; text-wrap: balance; }
.mdetail__pick { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.mdetail__pick .method > span { min-height: 44px; padding: 0 18px; background: var(--white); }
.mdetail .pay-phone { width: 100%; max-width: 360px; text-align: left; }
.pay-xendit { display: flex; align-items: flex-start; gap: 12px; margin: 0; padding: 14px 18px; color: var(--muted); border: 1px solid var(--hairline-color); }
.pay-xendit svg { flex: none; width: 19px; height: 19px; margin-top: 2px; color: var(--green); }
.flow-card .pay-form { max-width: none; }
.pay-form .pay-acts { margin-top: 12px; }
.pay-form .pay-acts .btn { width: 100%; }
.pay-phone { max-width: 360px; }
.pay-phone[hidden] { display: none; }
.field__opt { color: var(--muted); }
.method { position: relative; display: block; cursor: pointer; }
.method input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.method > span {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  min-height: 64px; padding: 0 20px;
  border: 1px solid rgba(14, 43, 33, .22); color: var(--green); background: none;
  transition: border-color var(--dur-quick) var(--ease-out), background-color var(--dur-quick) var(--ease-out);
}
.method small { color: var(--muted); }
.method:hover > span { background: rgba(14, 43, 33, .04); }
.method input:checked + span { border-color: var(--green); box-shadow: inset 0 0 0 1px var(--green); }
.method input:focus-visible + span { outline: 2px solid var(--gold-700); outline-offset: 2px; }
.pay-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; margin-top: 32px; }
.pay-acts .btn { min-width: 260px; }
.pay-acts .btn[aria-busy="true"] { opacity: .6; cursor: progress; }

.pay-box {
  max-width: 620px; padding: clamp(22px, 2.4vw, 32px);
  display: flex; flex-direction: column; align-items: flex-start; gap: 22px;
  border: 1px solid rgba(14, 43, 33, .22);
}
.pay-amount { display: flex; flex-direction: column; gap: 6px; }
.pay-amount span, .pay-label { margin: 0; color: var(--muted); }
.pay-amount b { font-weight: var(--weight-regular); color: var(--green); font-variant-numeric: tabular-nums; }
.pay-label { margin-bottom: -14px; }
.pay-code { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 20px; margin: 0; }
.pay-code b { font-weight: var(--weight-regular); color: var(--green); font-variant-numeric: tabular-nums; }   /* the amount's face and tracking */
.pay-qr { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.pay-qr svg { width: 220px; height: 220px; display: block; box-shadow: 0 0 0 1px var(--hairline-color); }
.pay-qr figcaption { color: var(--muted); }
.pay-sent { margin: 0; color: var(--green); }
.pay-out { min-width: 260px; }
.pay-steps { margin: 0; padding-left: 1.2em; list-style: decimal; color: var(--ink); display: grid; gap: 6px; }
.pay-steps li::marker { color: var(--gold-700); }
/* waiting — the same quiet square as the hold line */
.pay-wait { display: flex; align-items: baseline; gap: 10px; margin: 0; color: var(--muted); }
.pay-wait::before { content: ""; flex: none; width: 7px; height: 7px; background: var(--gold); transform: translateY(-1px); }
.pay-test { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px 24px; margin-top: 28px; padding-top: 18px; border-top: 1px dashed rgba(14, 43, 33, .38); max-width: 620px; }
.pay-test p { margin: 0; color: var(--muted); }
/* currency — display only, after staysanliving.com; payment stays IDR */
.cur { margin: 18px 0 0; }
.cur .pick__btn, .cur select { min-height: 0; }
.fx-note { margin: 12px 0 0; color: var(--muted); }
.fx-note[hidden] { display: none; }
/* the stay, as a pair: CHECK IN → CHECK OUT (2026-09-24) */
.stay {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: end; gap: 16px;
  margin: 22px 0 0; padding-bottom: 20px; border-bottom: var(--hairline);
}
.stay span.t-micro { display: block; margin-bottom: 8px; color: var(--muted); }
.stay b { font-weight: var(--weight-regular); color: var(--green); }
.stay__arrow { color: var(--gold-700); padding-bottom: 6px; }
.stay__arrow svg { display: block; width: 21px; height: 21px; }
.stay + .lines { margin-top: 0; border-top: 0; }
.lines .is-total { padding-top: 18px; }
.summary__foot { margin: 16px 0 0; color: var(--muted); }
/* currency in the summary: a quiet row, label left, value right, no underline */
.summary .cur { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 16px; margin: 16px 0 0; }
.summary .cur > label { margin: 0; }
.summary .cur .pick { width: auto; }
.summary .cur .pick__btn { width: auto; min-height: 0; padding: 4px 0; gap: 8px; border: 0; background: none; }
.summary .cur .pick__btn:focus-visible { outline: 2px solid var(--gold-700); outline-offset: 4px; }
.summary .cur .pick__panel { left: auto; right: 0; min-width: 140px; }

/* ── ⑥ Confirmation ─────────────────────────────────────────────────────── */
/* ⑥ — one centred column (2026-09-24, from the Figma "States" page). Cards
   are white and lifted, square as everything ALT; the tick is the one round
   shape here, like the payment radio — a tick reads as done. */
.ok { max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; align-items: stretch; gap: 16px; text-align: center; }
.ok__tick { align-self: center; display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; background: var(--green); color: var(--ivory); }
.ok__tick svg { width: 28px; height: 28px; }
.ok h1 { margin: 12px 0 0; color: var(--green); text-wrap: balance; }
.ok__lede { margin: 0 auto 12px; color: var(--muted); max-width: 46ch; text-wrap: balance; }
.ok__ref { display: flex; justify-content: space-between; align-items: center; margin: 0; padding: 16px 20px; background: var(--white); box-shadow: 0 0 0 1px var(--hairline-color); }
.ok__ref span { color: var(--muted); }
.ok__ref b { font-weight: var(--weight-regular); color: var(--green); font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.ok__card { padding: 24px; text-align: left; background: var(--white); box-shadow: 0 0 0 1px var(--hairline-color), var(--shadow-card); }
.ok__res { display: flex; align-items: center; gap: 16px; padding-bottom: 20px; border-bottom: var(--hairline); }
.ok__res img { flex: none; width: 64px; height: 64px; object-fit: cover; }
.ok__res img.is-plan { object-fit: contain; background: var(--ivory); }
.ok__res h2 { margin: 0; color: var(--green); }
.ok__res p { margin: 4px 0 0; color: var(--muted); }
.ok__card .stay { margin-top: 18px; }
.ok__paid { display: flex; justify-content: space-between; gap: 16px; margin: 16px 0 0; color: var(--muted); }
.ok__paid b { font-weight: var(--weight-regular); color: var(--green); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ok__h { margin: 0 0 8px; color: var(--green); }
.ok__acct {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 22px 24px; text-align: left; background: var(--green); color: var(--ivory);
}
.ok__acct h2 { margin: 0; color: var(--ivory); }
.ok__acct p { margin: 6px 0 0; color: rgba(252, 251, 248, .72); max-width: 40ch; }
.ok__acct .btn { flex: none; }
.ok__acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 8px; }
@media (max-width: 640px) { .ok__acct { flex-direction: column; align-items: flex-start; } }

@media print {
  .nav, .footer, .ok__acts, .ok__acct, .preview-chip, .steps { display: none !important; }
  .flow { padding-top: 0; }
}

/* ── Preview label, shared with the results page ─────────────────────── */
.preview-chip {
  position: fixed; left: 16px; bottom: 16px; z-index: 50; margin: 0;
  padding: 8px 12px; background: var(--green); color: var(--ivory);
  box-shadow: var(--shadow-card);
}

/* ── Narrow ──────────────────────────────────────────────────────────── */
@media (max-width: 1080px) {
  .flow__grid { grid-template-columns: 1fr; }
  /* on a phone the summary leads — the guest never loses the price */
  .flow__grid > .summary, .flow__grid > .pay-side { position: static; order: -1; }
}
@media (max-width: 1080px) {
  /* the picture is on the page already; the summary only needs the facts */
  .flow__grid > .summary .summary__thumb,
  .flow__grid > .pay-side .summary__thumb { display: none; }
}
@media (max-width: 640px) {
  /* one line on a phone: the four labels do not fit 342px, so only the
     current step shows, as "Step 2 of 4 · Your details" (the ← link above
     is the way back) */
  .steps li:not([aria-current]) { display: none; }
  .steps li[aria-current]::before { content: "Step " attr(data-n) " of 4 · "; width: auto; height: auto; margin: 0; border: 0; rotate: none; opacity: 1; }
  .ok__acts .btn { width: 100%; }
  .book--card .book__field { padding: 12px; gap: 8px; }
  .book--card .book__field:not(:nth-child(3)) .book__ico { display: none; }   /* the dates need the width */
  .co-row { grid-template-columns: 1fr; }
  .co-form .btn, .pay-acts .btn { width: 100%; min-width: 0; }
  /* the tag drops under the name on a phone, so the name keeps one line */
  .mrow { grid-template-columns: auto minmax(0, 1fr); gap: 6px 16px; padding: 16px 18px; }
  .mrow__side { grid-column: 2; align-items: flex-start; }
  .mrow__tag { text-align: left; }
  .mrow__logos { justify-content: flex-start; }
}

/* ── Shared bits these pages need that live in styles-avail.css there ─── */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.empty { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; padding: clamp(24px, 4vw, 48px) 0; }
.empty h1, .empty h2 { margin: 0; color: var(--green); }
.empty p { margin: 0; color: var(--muted); max-width: 56ch; }
.empty__acts { display: flex; flex-wrap: wrap; align-items: center; gap: 28px; margin-top: 8px; }


/* ══ ③ RESIDENCE · booking card after wander.com/property ════════════════ */

.res-grid { margin-top: clamp(32px, 4vw, 56px); }
/* 200px between the story and the booking card (2026-09-24, by request) —
   reached from ~1820 up; it scales down below that so the story column,
   which carries its own Details column, keeps its width on a laptop. */
.flow__grid.res-grid { column-gap: clamp(80px, 11vw, 200px); }
.res-block--first { margin-top: 0; }
/* About the residence: a short description — the summary, the export's
   space line, and its notes said once and briefly. The lists moved to
   Amenities (2026-09-24). */
.res-about #x-inside > p { margin-top: 14px; }
/* Two-line blocks balanced, not one long line and a short one (2026-09-24,
   by request) — the rule the headings already follow, applied to the
   description because it sits at 18px and runs two lines. */
.res-about p { text-wrap: balance; }
.res-about {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(200px, 240px);
  gap: clamp(32px, 4vw, 64px); align-items: start;
}
/* DETAILS, after Raffles: a label, then hairline rows with a line icon. */
.res-details__label { margin: 0 0 10px; }
.res-details ul { list-style: none; margin: 0; padding: 0; border-top: var(--hairline); }
.res-details li { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: var(--hairline); color: var(--ink); }
@media (max-width: 900px) { .res-about { grid-template-columns: 1fr; } }

/* ── The booking card: dates and guests stay editable ─────────────────── */
.bookcard__price { margin: 0 0 18px; color: var(--green); }
.bookcard__price .t-caption { color: var(--muted); }
/* the booking bar's markup, set as a stacked form inside the card */
.book.book--card {
  position: relative; left: auto; bottom: auto; transform: none; z-index: 5;
  width: 100%; display: grid; grid-template-columns: 1fr 1fr;
  background: none;
  box-shadow: 0 0 0 1px rgba(14, 43, 33, .22);
}
.book.book--card::before { content: none; }   /* sits in the card: no frost */
.book--card .book__field { min-width: 0; padding: 14px 16px; gap: 10px; }
.book--card .book__field + .book__field { border-left: var(--hairline); }
.book--card .book__field:nth-child(3) { grid-column: 1 / -1; border-left: 0; border-top: var(--hairline); }
.book--card .book__ico { width: 19px; height: 19px; }
/* 24px between the card's three parts — currency, the stay fields, the
   money lines (2026-09-24, by request; they sat 0–4px apart) */
.bookcard .cur { margin-bottom: 24px; }
#bc-body > .lines:first-child { margin-top: 40px; }   /* 24 first, 40 by request */
/* panels drop down and open toward the page, not off the card's right edge */
.book--card .pick__panel { top: 100%; bottom: auto; transform: translateY(-4px); max-height: none; }
.book--card .pick.is-open .pick__panel { transform: none; }
.book--card .pick--calhost .pick__panel { left: auto; right: 0; }
.bookcard .lines { margin-top: 18px; }
.bookcard .st { margin-top: 16px; }

/* ── The viewer ── */
.viewer {
  width: min(1200px, calc(100% - 2 * var(--gutter))); max-height: calc(100svh - 48px);
  padding: 0; border: 0; background: var(--ivory); color: var(--ink); box-shadow: var(--shadow-soft);
}
.viewer::backdrop { background: rgba(0, 0, 0, .72); }
.viewer__in { display: flex; flex-direction: column; max-height: inherit; }
.viewer__head { display: flex; justify-content: space-between; align-items: center; gap: 20px; padding: 16px 22px; border-bottom: var(--hairline); }
.viewer__title { margin: 0; color: var(--green); }
.viewer__cap { margin: 2px 0 0; color: var(--muted); }
.viewer__body { flex: 1; min-height: 0; display: grid; place-items: center; background: var(--green); }
.viewer__body img, .viewer__body video { max-width: 100%; max-height: calc(100svh - 140px); display: block; }
.viewer__body .viewer__plan { background: var(--ivory); padding: 16px; }
.viewer__body iframe { width: 100%; aspect-ratio: 16 / 9; border: 0; }
/* The viewer holding text (house rules): ivory, scrolls inside. The head
   keeps only Close — the title is set in the body's left column (and stays
   in the head for screen readers, which is what the dialog is labelled by). */
.viewer--text { width: min(1120px, calc(100% - 2 * var(--gutter))); }
.viewer--text .viewer__head { justify-content: flex-end; padding-bottom: 0; border-bottom: 0; }
.viewer--text .viewer__head > div { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.viewer--text .viewer__body { display: block; overflow-y: auto; padding: 8px clamp(20px, 5vw, 72px) clamp(32px, 5vw, 72px); background: var(--ivory); }
/* House rules, after raffles.com's offer page: two columns, a lead on the
   left with the fine print under a hairline, hairline lists on the right */
/* on a phone the fine print goes last, after the rules themselves */
.rules {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto 1fr;
  grid-template-areas: "lead lists" "fine lists"; column-gap: clamp(40px, 7vw, 120px); align-items: start;
}
.rules__lead { grid-area: lead; }
.rules__lists { grid-area: lists; }
.rules__fine { grid-area: fine; }
.rules__title { margin: 0; color: var(--green); text-wrap: balance; }
.rules__desc { margin: 20px 0 0; color: var(--ink); text-wrap: pretty; }
.rules__fine { margin-top: 32px; padding-top: 28px; border-top: var(--hairline); }
.rules__fine .t-body-sm { margin: 12px 0 0; color: var(--muted); font-style: italic; text-wrap: pretty; }
.rules__lists > .t-eyebrow { margin: 0 0 8px; }
.rules__lists > .t-eyebrow ~ .t-eyebrow { margin-top: 36px; }
.rules .xlist li { padding: 10px 0; }
.rules .xlist li::before { content: none; }
.rules__note { margin: 12px 0 0; color: var(--muted); text-wrap: pretty; }
@media (max-width: 720px) { .rules { grid-template-columns: 1fr; grid-template-rows: none; grid-template-areas: "lead" "lists" "fine"; } .rules__lists { margin-top: 32px; } .rules__fine { border-top: 0; padding-top: 0; } }
#x-rules .rules__intro { margin: 16px 0 0; max-width: 60ch; color: var(--ink); }
#x-rules .xamen__all { margin-top: 24px; }
.planbox__close {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 4px;
  background: none; border: 0; cursor: pointer; color: var(--green);
}
.planbox__close svg { width: 17px; height: 17px; }
.planbox__close:focus-visible { outline: 2px solid var(--gold-700); outline-offset: 2px; }

@media (max-width: 1080px) {
  /* the booking card leads on narrow screens, but after the pictures */
  .res-grid > .bookcard { order: -1; }
}


/* ══ ③ HERO · after wilde.com/porto/clerigos ════════════════════════════
   The photograph full-bleed under the transparent nav, the name set low on
   it, the other media as underline actions along its foot. Same scrim
   language as the home hero, lighter: the type sits in the bottom third. */
.rhero {
  position: relative; overflow: hidden; display: flex; align-items: flex-end;
  min-height: 520px; height: 78vh; height: 78svh; max-height: 820px;
  background: var(--green);
}
.rhero__media, .rhero__scrim { position: absolute; inset: 0; }
.rhero__media img { width: 100%; height: 100%; object-fit: cover; }
.rhero__scrim {
  background: linear-gradient(to bottom, rgba(0,0,0,.30) 0%, rgba(0,0,0,.04) 30%, rgba(0,0,0,.50) 100%);
}
.rhero__inner {
  position: relative; width: 100%;
  padding: 0 var(--frame-x) clamp(28px, 3vw, 44px);
  display: flex; flex-direction: column; align-items: flex-start; gap: 16px;
  color: var(--ivory);
}
.rhero__title { margin: 0; color: var(--ivory); }
.rhero__bar {
  display: flex; flex-wrap: wrap; gap: 8px 32px; width: 100%;
  margin-top: 14px; padding-top: 18px; border-top: 1px solid rgba(252, 251, 248, .28);
}
.rhero__act {
  position: relative; display: inline-flex; align-items: center; gap: 10px;
  padding: 6px 0; background: none; border: 0; cursor: pointer; color: var(--ivory);
}
.rhero__act svg { width: 19px; height: 19px; }
.rhero__act::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--gold); transform: scaleX(0); transform-origin: left;
  transition: transform var(--duration) var(--ease-out);
}
.rhero__act:hover::after { transform: scaleX(1); }
.rhero__act:focus-visible { outline: 2px solid var(--gold); outline-offset: 4px; }
.rhero__act--soon { cursor: default; opacity: .7; }
/* Show all photos: a real outline button, pushed to the right end */
.rhero__bar { align-items: center; }
.rhero__all { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; }   /* the .btn padding — 54 tall like every button (14 / 22, 50 tall, until the 2026-09-29 audit) */
.rhero__all svg { width: 19px; height: 19px; }
.rhero__all:active { scale: .96; }
/* White at rest, GOLD on hover over the photograph (2026-09-24, by request;
   it was green) — the dark-ground button's hover, green label on gold, the
   one place a gold fill is allowed. Over a floor plan (light ground) it stays
   green. White is a lifted surface in this system, so it carries the hairline
   ring and the card shadow even here. Selectors doubled to outrank
   .btn--ghost(-media). */
.rhero__all.rhero__all {
  background: var(--white); color: var(--green); border-color: var(--white);
  box-shadow: 0 0 0 1px var(--hairline-color), var(--shadow-card);
}
.rhero__all.rhero__all:hover { background: var(--green); color: var(--ivory); border-color: var(--green); }
.rhero__all.btn--ghost-media:hover { background: var(--gold); color: var(--green); border-color: var(--gold); }
.rhero__all.rhero__all:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
@media (max-width: 640px) { .rhero__all { margin-left: 0; width: 100%; justify-content: center; } }
.rhero__act--soon::after { content: none; }

/* no photograph: the plan on its own paper, dark type, solid nav */
.rhero--plan { background: var(--ivory); align-items: stretch; height: auto; max-height: none; }
/* The back link hangs under the nav (133-163px), so the plan starts below it. */
/* no back link over the hero any more (removed 2026-09-24): the plan starts 32px under the nav */
.rhero--plan .rhero__media { position: relative; flex: 1 1 55%; padding: calc(93px + 32px) 0 32px var(--frame-x); }
.rhero--plan .rhero__media img { object-fit: contain; }
.rhero--plan .rhero__inner { flex: 1 1 45%; justify-content: flex-end; padding-top: calc(93px + 32px); color: var(--green); }
.rhero--plan .rhero__title,
.rhero--plan .rhero__act { color: var(--green); }
.rhero--plan .rhero__bar { border-top-color: var(--hairline-color); }
.rhero__note { margin: 0; color: var(--muted); }

.res-flow { padding-top: clamp(48px, 5vw, 80px); }
.res-flow .res-grid { margin-top: 0; }

/* ══ OTHER RESIDENCES — nearest free dates, at the foot ═════════════════ */
.others__head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 18px; margin-bottom: var(--head-gap); }   /* centred (2026-09-29, by request) */
.others__head h2 { margin: 0; color: var(--green); }
/* Four across. The card body is the home collection card's (2026-09-28, by
   request) in one column — status, rate, Discover more; no description and
   no spec column. A long rate wraps its "/ night" under it. */
.others__list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 40px 20px; }   /* 20 between cards across; 40 between rows (2026-09-29, by request — 64 before) */
.ocard .unit__body { grid-template-columns: minmax(0, 1fr); }
.ocard .unit__price { flex-wrap: wrap; }
.ocard { display: flex; }   /* the li stretches to the row; the link fills it */
.ocard__link { display: flex; flex-direction: column; color: inherit; flex: 1 1 auto; }   /* so Discover more lines up across the row (2026-09-29 audit) */
.ocard__media { margin: 0; aspect-ratio: 4 / 3; overflow: hidden; background: var(--ivory); }
.ocard__media img { width: 100%; height: 100%; object-fit: cover; transition: scale var(--duration) var(--ease-out); outline: 1px solid oklch(0 0 0 / .1); outline-offset: -1px; }
.ocard__media--plan img { object-fit: contain; padding: 8px; outline: 0; }
.ocard__link:hover img { scale: 1.03; }
.ocard__link:focus-visible { outline: 2px solid var(--gold-700); outline-offset: 4px; }
.ocard .st { margin: 0; }
.ocard__link:hover .unit__more::after { transform: scaleX(1); }
.ocard.is-booked .ocard__media img { opacity: .5; }

@media (max-width: 900px) {
  .rhero--plan { flex-direction: column; }
  .rhero--plan .rhero__media { padding: calc(93px + 16px) var(--frame-x) 0; height: calc(56vw + 16px); flex: none; }
  .rhero--plan .rhero__inner { padding-top: 24px; }
}
@media (max-width: 1080px) { .others__list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .others__list { grid-template-columns: 1fr; } }
/* stacked, the head sits closer to the cards (2026-09-29, by request) */
@media (max-width: 1080px) { .others__head { margin-bottom: 32px; } .others__list { row-gap: 64px; } }   /* rooms further apart again (2026-09-29, by request — 40) */

/* hero photo opens the gallery — the whole picture is the button */
.rhero__open { display: block; width: 100%; height: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.rhero__open img { width: 100%; height: 100%; object-fit: cover; }
/* the scrim must not swallow the click on the photograph beneath it */
.rhero__scrim { pointer-events: none; }
.rhero__inner { pointer-events: none; }
.rhero__inner > * { pointer-events: auto; }

/* ── story column: plan, film, map ── */
/* anchors the room label (.plans__label, styles-alt.css) once the SVG is inlined */
.res-plan__frame { position: relative; }
.res-plan__frame svg { display: block; width: 100%; height: auto; }
.res-plan__cap { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 8px 20px; }
/* a section's short description: lines of even length (2026-09-24, by request) */
.res-lede { text-wrap: balance; }
.nobr { white-space: nowrap; }

/* ══ SHOW ALL PHOTOS · after Airbnb / Wander ════════════════════════════
   A full-screen sheet: grouped grids of every picture; one tap opens the
   picture in an OVERLAY on top of the grid (2026-09-24, by request) — the
   grid stays behind it, dimmed and blurred, instead of being swapped out
   for a green page. × or a click on the dark ground returns to the grid. */
.photos {
  position: fixed;             /* anchors the single-photo overlay */
  width: 100vw; max-width: none; height: 100vh; height: 100dvh; max-height: none;
  margin: 0; padding: 0; border: 0; background: var(--white); color: var(--ink);
}
.photos::backdrop { background: var(--white); }
.photos[open] { display: flex; flex-direction: column; }
.photos__bar {
  flex: none; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px;
  padding: 14px var(--frame-x); border-bottom: var(--hairline); background: var(--white);
}
.photos__close { justify-self: start; min-height: 44px; padding: 0 4px; background: none; border: 0; cursor: pointer; color: var(--green); }
.photos__close:focus-visible { outline: 2px solid var(--gold-700); outline-offset: 2px; }
.photos__title { margin: 0; color: var(--green); }
.photos__count { justify-self: end; color: var(--muted); }
.photos__body { flex: 1; overflow-y: auto; padding: clamp(28px, 4vw, 56px) var(--frame-x) 80px; }
.photos__body[hidden] { display: none; }
.photos__group { max-width: 1100px; margin: 0 auto clamp(40px, 5vw, 72px); }
.photos__group h3 { margin: 0 0 18px; color: var(--green); }
/* two up, every third picture full width — the rhythm of a photo tour */
.photos__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.photos__item { display: block; padding: 0; border: 0; background: var(--ivory); cursor: zoom-in; aspect-ratio: 4 / 3; overflow: hidden; }
.photos__item:nth-child(3n + 1) { grid-column: 1 / -1; aspect-ratio: 16 / 9; }
/* a picture left alone on its row takes the row */
.photos__item:nth-child(3n + 2):last-child { grid-column: 1 / -1; aspect-ratio: 16 / 9; }
.photos__item img { width: 100%; height: 100%; object-fit: cover; transition: scale var(--duration) var(--ease-out); }
.photos__item:hover img { scale: 1.02; }
.photos__item.is-plan img { object-fit: contain; padding: 16px; }
.photos__item:focus-visible { outline: 2px solid var(--gold-700); outline-offset: 3px; }

.photos__one {
  position: absolute; inset: 0; z-index: 2;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  gap: 12px; padding: 72px 20px 20px;
  /* A scrim, not a surface: neutral black like the hero's, since a green
     one would cast over the photograph's own colour. .55, lightened from
     .82 by request — the grid should still be felt behind the picture. */
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  animation: photos-in var(--dur-enter) var(--ease-out);
}
.photos__one[hidden] { display: none; }
@keyframes photos-in { from { opacity: 0; } }
.photos__x {
  position: absolute; top: 16px; right: 20px;
  display: grid; place-items: center; width: 44px; height: 44px; cursor: pointer;
  background: none; border: 0; color: var(--ivory);
  transition: background-color var(--dur-quick) var(--ease-out), scale var(--dur-quick) var(--ease-out);
}
.photos__x:hover { background: rgba(252, 251, 248, .12); }
.photos__x:active { scale: .96; }
.photos__x:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.photos__x svg { width: 24px; height: 24px; }
.photos__fig { margin: 0; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-height: 0; }
.photos__fig img { max-width: 100%; max-height: calc(100% - 40px); object-fit: contain; }
.photos__fig img.is-plan { background: var(--ivory); padding: 16px; }
.photos__fig figcaption { color: rgba(252, 251, 248, .8); text-align: center; }
.photos__step {
  display: grid; place-items: center; width: 48px; height: 48px; cursor: pointer;
  background: none; border: 1px solid rgba(252, 251, 248, .4); color: var(--ivory);
  transition: background-color var(--dur-quick) var(--ease-out), scale var(--dur-quick) var(--ease-out);
}
.photos__step:hover { background: rgba(252, 251, 248, .12); }
.photos__step:active { scale: .96; }
.photos__step:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.photos__step svg { width: 19px; height: 19px; }
.photos__step--prev svg { transform: scaleX(-1); }

@media (max-width: 640px) {
  .photos__grid { grid-template-columns: 1fr; }
  .photos__item:nth-child(3n + 1) { aspect-ratio: 4 / 3; }
  .photos__one { grid-template-columns: 1fr 1fr; grid-template-rows: minmax(0, 1fr) auto; }
  .photos__fig { grid-column: 1 / -1; grid-row: 1; }
  .photos__step { grid-row: 2; justify-self: center; }
}

/* ══ ③ THE CLIENT'S DETAIL — in the residence, amenities, house rules ═══ */
.xlist { list-style: none; margin: 0; padding: 0; }
.xlist li { position: relative; padding: 8px 0 8px 18px; border-bottom: var(--hairline); color: var(--ink); }
.xlist li::before { content: ""; position: absolute; left: 0; top: 50%; width: 6px; height: 6px; margin-top: -3px; background: var(--gold); }
/* THREE COLUMNS THAT RUN DOWN (2026-09-24, by request): a grid flowing by
   column, so the list reads top to bottom, then across. The row count is set
   by the page script from --cols and the items showing, so the columns split
   evenly by COUNT (4/4/4) — CSS columns balanced by height and came out 3/5/4. */
.xamen {
  --cols: 3;
  list-style: none; margin: 18px 0 0; padding: 0;
  display: grid; grid-auto-flow: column; grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  column-gap: 32px; align-content: start;
}
.xamen li { display: flex; align-items: center; gap: 14px; min-width: 0; padding: 10px 0; color: var(--ink); }   /* no dividers, by request */
/* One line each (by request): the labels are shortened in the page script;
   this only catches one that still overruns a narrow column. */
.xamen li span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* One line icon per amenity (2026-09-24, by request) — the spec icons'
   stroke and size family, a step larger because they lead a row. */
.amen-ico { flex: none; width: 26px; height: 26px; color: var(--green); }
.xamen li[hidden] { display: none; }
/* 3 only where a column holds ~25 characters on one line */
@media (max-width: 1600px) { .xamen { --cols: 2; } }
/* just above 1080 the booking card still sits beside the story, and the
   story is at its narrowest: one column there */
@media (min-width: 1081px) and (max-width: 1180px) { .xamen { --cols: 1; } }
/* An underline link, not a boxed button (2026-09-24, by request): the
   hairline shows at rest so it reads as an action, and turns gold on hover. */
.xamen__all { margin-top: 22px; }
.xamen__all::after { transform: scaleX(1); background: rgba(14, 43, 33, .28); transition: background-color var(--duration) var(--ease-out); }
.xamen__all:hover::after { background: var(--gold); }
@media (max-width: 640px) { .xamen { --cols: 1; } }

/* ══ THE STICKY BAR on the residence page, phone and tablet (2026-09-30, by
   request — after wander.com/property). Written by residence.html's
   stickybar(): the dates (a link that opens the calendar), the total for
   the nights or the card's status, and the card's own action, solid.
   Hidden above 1080, where the card itself stays pinned beside the story,
   and while the card is on screen (.is-shown comes off). White, the
   hairline on top, the card shadow turned upward. */
.sbar { display: none; }
@media (max-width: 1080px) {
  .sbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 25;
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 12px var(--gutter) calc(12px + env(safe-area-inset-bottom));
    background: var(--white); border-top: var(--hairline);
    box-shadow: 0 -12px 32px -18px rgba(var(--shadow-rgb), .18);
    translate: 0 110%; visibility: hidden;
    transition: translate var(--duration) var(--ease-out), visibility 0s linear var(--duration);
  }
  .sbar.is-shown { translate: 0 0; visibility: visible; transition: translate var(--duration) var(--ease-out), visibility 0s; }
  .sbar__stay { min-width: 0; }
  .sbar__dates {
    display: block; padding: 0; border: 0; background: none; cursor: pointer;
    color: var(--ink); text-decoration: underline; text-underline-offset: 4px;
    text-decoration-color: rgba(14, 43, 33, .35);
  }
  .sbar__line { margin: 2px 0 0; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .sbar .btn { flex: none; align-self: center; }
  /* the page's foot and the prototype chip clear the bar while it shows */
  html.has-sbar body { padding-bottom: 84px; }
  html.has-sbar .preview-chip { bottom: 96px; }   /* a ?state= preview only */
}
/* PHONES (≤720, 2026-09-30, by request): the booking card leaves the page
   and becomes a bottom SHEET, opened from the sticky bar's dates; the bar is
   there from the first screen. The card keeps every control it had. */
.bookcard__x { display: none; }
.cardsheet-veil { display: none; }
@media (max-width: 720px) {
  .res-grid > .bookcard {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 900;
    margin: 0; max-height: 88svh; overflow-y: auto; overscroll-behavior: contain;
    padding-bottom: calc(24px + env(safe-area-inset-bottom));
    translate: 0 105%; visibility: hidden;
    transition: translate var(--duration) var(--ease-out), visibility 0s linear var(--duration);
  }
  html.has-cardsheet .res-grid > .bookcard {
    translate: 0 0; visibility: visible;
    transition: translate var(--duration) var(--ease-out), visibility 0s;
  }
  .bookcard__x {
    display: grid; place-items: center; width: 44px; height: 44px; margin: -8px -8px 0 auto;
    background: none; border: 0; color: var(--green); cursor: pointer;
  }
  .bookcard__x svg { width: 22px; height: 22px; }
  .cardsheet-veil {
    display: block; position: fixed; inset: 0; z-index: 899;
    background: rgba(0, 0, 0, .45); opacity: 0; pointer-events: none;
    transition: opacity var(--duration) var(--ease-out);
  }
  html.has-cardsheet .cardsheet-veil { opacity: 1; pointer-events: auto; }
  html.has-cardsheet, html.has-cardsheet body { overflow: hidden; }
  /* a CLOSED picker panel inside the sheet is taken out of the layout, not
     just made invisible: the desktop calendar panel (never used here — the
     calendar is its own full-screen sheet on phones) hung ~370px below the
     card's content and let the sheet scroll into empty white */
  .bookcard .pick:not(.is-open) > .pick__panel { display: none; }
}
