/* ==========================================================================
   Hôtel Le Chabrol — shared stylesheet
   All design tokens live in :root. Do not introduce values outside them.
   ========================================================================== */

:root {
  /* Palette */
  --cream:        #FAF6EA;
  --ivory:        #FFFDF8;
  --navy:         #17325E;
  --navy-deep:    #0F2244;
  --gold:         #C9A063;
  --brass-hover:  #755927;   /* accent button, hover: darker, contrast rises */
  --brass-press:  #6B5123;   /* accent button, pressed */
  --navy-press:   #0A1730;   /* primary button, pressed */
  --cream-press:  #EFE9D9;   /* primary button on a dark ground, pressed */
  --gold-antique: #8A6A2F;
  --ink:          #23211D;
  --stone:        #6B6459;

  /* Corner radius. Applied to objects with a container edge, never to the
     editorial photography: a card is a thing you tap, a hero is a thing you
     look at, and only the first of those wants a rounded corner. */
  --radius: 8px;

  /* The lift every pressable thing shares on hover. Only on hover, so the
     page at rest stays as flat as it has always been. */
  --lift:       0 6px 16px rgba(15, 34, 68, 0.18);
  --lift-deep:  0 8px 22px rgba(15, 34, 68, 0.26);

  /* Fallback block shown where a photograph has not landed yet */
  --placeholder: #E2DCCC;

  /* Hairlines — gold at low alpha, for borders only */
  --hair:         rgba(201, 160, 99, 0.45);
  --hair-soft:    rgba(201, 160, 99, 0.25);

  /* Type */
  --display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --ui:      'Jost', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  /* Rhythm */
  --page-max:  1160px;
  --measure:   64ch;
  --gutter:    clamp(1.25rem, 5vw, 3.5rem);
  --section-y: clamp(2.75rem, 7vw, 5.5rem);

  /* Focus ring — overridden on navy surfaces */
  --focus: var(--gold-antique);

  /* ----------------------------------------------------------------------
     Semantic layer, so the page can be repainted for dark mode.

     The palette above could not do this alone: --cream is both the page
     ground and the text on a navy band, and --navy is both a heading and the
     header's background. Flipping either would put dark text on a dark
     ground. These names separate the two jobs, and only these are redefined
     for dark. The navy header, page heads, bands and footer are already dark
     with light text, so they keep the raw palette and barely change.
     ---------------------------------------------------------------------- */
  --bg:          var(--cream);   /* the page itself */
  --surface:     var(--cream);   /* cards, room-nav tiles */
  --surface-2:   var(--ivory);   /* panels that sit above a surface */
  --text:        var(--ink);     /* body copy */
  --text-muted:  var(--stone);   /* captions, specs, secondary lines */
  --heading:     var(--navy);    /* headings and emphasis on a light ground */
  --ghost-tint:  rgba(23, 50, 94, 0.06);   /* ghost button hover */
  --ghost-press: rgba(23, 50, 94, 0.12);   /* ghost button active */
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--ui);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.75;
}

h1, h2, h3, h4, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

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

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;
  color: var(--heading);
  line-height: 1.12;
  letter-spacing: 0.005em;
}

h1 { font-size: clamp(2.25rem, 6vw, 3.75rem); }
h2 { font-size: clamp(1.75rem, 4vw, 2.6rem); }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem); font-weight: 400; line-height: 1.25; }
h4 { font-size: 1.05rem; font-weight: 500; }

p + p { margin-top: 1.1em; }

/* Jost ships 400 and 500 here and nothing heavier. Left alone, b and strong
   inherit the browser default of 700, which no loaded face can answer, so
   every bold word on the site was being synthesised: a smeared outline that
   reads lighter and blurrier than the text around it, not heavier. */
b, strong { font-weight: 500; }

.lede {
  font-family: var(--display);
  font-size: clamp(1.2rem, 2.4vw, 1.6rem);
  line-height: 1.55;
  color: var(--heading);
}

.prose { max-width: var(--measure); }
.prose p + p { margin-top: 1.1em; }

/* The privacy and terms pages are the only place .prose carries headings and
   lists; everywhere else it is a paragraph or two under a section head that
   supplies its own spacing. The global reset zeroes both, so a document has to
   ask for them back. Its subheads also sit a step below the page title rather
   than at section-head scale, which is what made them collide with the text
   above them. */
.prose > h2 {
  font-size: clamp(1.3rem, 2.2vw, 1.6rem);
  margin-top: 2.75rem;
  margin-bottom: 0.75rem;
}
/* The first subhead follows the decorative rule, not a paragraph. */
.prose > .rule + h2 { margin-top: 0.9rem; }

.prose ul {
  margin-top: 1.1em;
  padding-left: 1.2rem;
  list-style: disc;
  display: grid;
  gap: 0.5rem;
}
.prose li { padding-left: 0.2rem; }
.prose li::marker { color: var(--gold-antique); }
.prose ul + p { margin-top: 1.1em; }

.eyebrow {
  display: block;
  font-family: var(--ui);
  font-weight: 400;
  font-size: 0.75rem;
  line-height: 1.4;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-antique);
}

.caption {
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--text-muted);
}

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

/* Marks an unresolved fact. Grep for "todo" before launch. */
.todo {
  font-size: 0.75rem;
  font-style: italic;
  color: var(--text-muted);
  border-bottom: 1px dotted var(--stone);
}

/* --------------------------------------------------------------------------
   Signature rule — hairline with a lozenge at its centre
   -------------------------------------------------------------------------- */

/* Rendered on a <span>, not an <hr> — Chrome does not paint pseudo-elements
   on <hr>, which silently drops the lozenge. */
.rule {
  display: block;
  position: relative;
  width: min(100%, 13rem);
  height: 1px;
  background: var(--gold);
  border: 0;
  margin: 0 0 1.75rem;
}

.rule::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0.375rem;
  height: 0.375rem;
  background: var(--gold);
  transform: translate(-50%, -50%) rotate(45deg);
}

.rule--center { margin-inline: auto; }

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.wrap {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * 0.6); }

.section-head { margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.section-head .eyebrow { margin-bottom: 0.9rem; }
.section-head h2 { margin-bottom: 1rem; }
.section-head p { max-width: var(--measure); }

.section-head--center { text-align: center; }
.section-head--center p { margin-inline: auto; }

.grid { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); }

@media (min-width: 640px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}

/* --------------------------------------------------------------------------
   Nearby
   The distances row under the hero. Five items on a wide screen, two on a
   phone; the travel time is the thing being scanned, so it leads each item.
   -------------------------------------------------------------------------- */

.nearby {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2rem);
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--hair-soft);
  padding-top: clamp(1.5rem, 3vw, 2.25rem);
}

@media (min-width: 900px) {
  .nearby { grid-template-columns: repeat(5, 1fr); }
}

.nearby li {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

/* Drawn rather than photographed: five portrait photographs would need five
   photographs, and a hairline glyph in the same gold as .rule keeps the row
   quiet enough that the travel time still leads. */
.nearby__icon {
  width: 1.6rem;
  height: 1.6rem;
  display: block;
  color: var(--gold-antique);
  margin-bottom: 0.55rem;
}

/* The attraction icons are files rather than inline SVG, so they arrive as
   masks and take their colour the same way the amenity icons do. */
.nearby__icon--mask {
  background-color: var(--gold-antique);
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
}

.nearby__time {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.3rem, 2.2vw, 1.6rem);
  line-height: 1.15;
  color: var(--heading);
}

.nearby__place {
  font-family: var(--ui);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-antique);
}

.nearby__how {
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   Testimonials
   Guests' own words at full size; the aggregate scores sit quietly beneath.
   A visitor sees the Google rating in search results whether it is published
   here or not, so it is better framed by the quotes than left to stand alone.
   -------------------------------------------------------------------------- */

.testimonials {
  display: grid;
  gap: clamp(1.75rem, 4vw, 2.75rem);
}

@media (min-width: 820px) {
  .testimonials { grid-template-columns: repeat(3, 1fr); }
}

.testimonials blockquote {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.testimonials blockquote p {
  font-family: var(--display);
  font-size: clamp(1.1rem, 2.2vw, 1.3rem);
  line-height: 1.45;
  color: var(--heading);
  margin: 0;
  text-wrap: pretty;
}

.testimonials cite {
  font-family: var(--ui);
  font-style: normal;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: auto;
}

.ratings {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  align-items: baseline;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 1px solid var(--hair-soft);
  font-family: var(--ui);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}

.ratings b {
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.35rem;
  letter-spacing: 0;
  color: var(--heading);
  margin-right: 0.4rem;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Suite bands
   One suite per full-width band, photograph and text alternating sides. The
   suites are the reason most guests choose the hotel, and a three-across grid
   gave them the same treatment as the ordinary rooms at a third of the size.
   Cream rather than navy: the photographs are warm, all terracotta, marble and
   brass, and a navy ground sat opposite them on the wheel and fought.
   -------------------------------------------------------------------------- */

/* A full-bleed photograph carries the section head, then the bands below.
   The gap is deliberately small: enough that each suite reads as its own
   block rather than one continuous strip, not so much that they scatter. */
.suite-hero { position: relative; }

.suite-hero .ph {
  aspect-ratio: auto;
  height: clamp(21rem, 50vh, 31rem);
}

.suite-hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  background: linear-gradient(to right,
              rgba(15, 34, 68, 0.90) 0%,
              rgba(15, 34, 68, 0.74) 42%,
              rgba(15, 34, 68, 0.22) 100%);
}
.suite-hero__overlay > .wrap { width: 100%; }
.suite-hero__overlay .eyebrow { color: var(--cream); }
.suite-hero__overlay h2 { color: var(--cream); max-width: 18ch; margin-bottom: 0; }
.suite-hero__overlay p {
  color: rgba(250, 246, 234, 0.9);
  max-width: 46ch;
  margin-top: 1rem;
}

.section--bands { padding-bottom: 0; }
.section--bands .section-head { margin-bottom: clamp(1.75rem, 4vw, 2.5rem); }

/* Navy band */
.band--navy {
  background: var(--navy);
  color: var(--cream);
  --focus: var(--gold);
}
.band--navy h1,
.band--navy h2,
.band--navy h3,
.band--navy h4 { color: var(--cream); }
.band--navy .eyebrow { color: var(--gold); }
.band--navy .lede { color: var(--cream); }
.band--navy .caption,
.band--navy .muted { color: rgba(250, 246, 234, 0.7); }

/* --- The dark-band contract ------------------------------------------------
   Two kinds of thing live inside a navy band, and they need opposite colours:

   1. Panels that paint their own light surface (.card). The descendant rules
      above would tint their text cream and make it vanish on ivory, so every
      such panel restates its colours at higher specificity here.
   2. Elements sitting directly on the navy. Anything whose default is a dark
      ink (.spec, .todo, .btn--ghost) is illegible there — stone on navy is
      2.17:1 — so each gets a light counterpart.
   Add to this block whenever a new panel or dark-ink element is introduced. */

.band--navy .card {
  background: var(--surface-2);
  color: var(--text);
  --focus: var(--gold-antique);
}
.band--navy .card h2,
.band--navy .card h3,
.band--navy .card h4 { color: var(--heading); }
.band--navy .card p,
.band--navy .card dd { color: var(--text); }
.band--navy .card .eyebrow { color: var(--gold-antique); }
.band--navy .card .spec,
.band--navy .card .spec li { color: var(--text-muted); }
.band--navy .card .caption,
.band--navy .card .muted { color: var(--text-muted); }
.band--navy .card .link { color: var(--heading); border-bottom-color: var(--hair); }
.band--navy .card .link:hover { border-bottom-color: var(--gold-antique); }
.band--navy .card .btn--ghost { border-color: var(--heading); color: var(--heading); }
.band--navy .card .btn--ghost:hover { border-color: var(--heading); background: var(--ghost-tint); }

.band--navy .card .price b { color: var(--heading); }
.band--navy .card .price span { color: var(--text-muted); }

.band--navy .spec,
.band--navy .spec li { color: rgba(250, 246, 234, 0.78); }
.band--navy .amenities,
.band--navy .amenities li { color: rgba(250, 246, 234, 0.78); }
.band--navy .price b { color: var(--cream); }
.band--navy .price span { color: rgba(250, 246, 234, 0.7); }
.band--navy .todo {
  color: rgba(250, 246, 234, 0.78);
  border-bottom-color: rgba(250, 246, 234, 0.45);
}
.band--navy .btn--ghost { border-color: var(--cream); color: var(--cream); }
.band--navy .btn--ghost:hover { border-color: var(--cream); background: rgba(250, 246, 234, 0.14); }
.band--navy .timeline { border-left-color: rgba(201, 160, 99, 0.5); }
.band--navy .timeline h3 { color: var(--cream); }
.band--navy .timeline__year { color: var(--gold); }
.band--navy .detail h2,
.band--navy .detail h3 { color: var(--cream); }
.band--navy .detail dt { color: var(--gold); }

/* --------------------------------------------------------------------------
   Image placeholders
   Set --img to point at a file. If it is unset or the file is missing, the
   ::before paints nothing and the labelled block underneath shows through.
   -------------------------------------------------------------------------- */

.ph {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--ratio, 4 / 3);
  background: var(--placeholder);
}

.ph::after {
  content: attr(data-label);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem 1rem;
  text-align: center;
  font-family: var(--ui);
  font-weight: 400;
  font-size: 0.75rem;
  line-height: 1.5;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);

  /* The gold rule-and-diamond from .rule, so a frame still waiting on its
     photograph reads as a deliberate blank plate rather than a failed load. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='9'%3E%3Cpath d='M0 4.5h52M68 4.5h52' stroke='%23C9A063' stroke-opacity='.55'/%3E%3Cpath d='M60 1.7l2.8 2.8L60 7.3l-2.8-2.8z' fill='%23C9A063'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center calc(50% - 1.4rem);
  background-size: min(120px, 60%) auto;
  box-shadow: inset 0 0 0 1px var(--hair-soft);
}

/* A frame that names a photograph is waiting for it, not missing it. The label
   would show only until the image lands on top, and on a phone pulling several
   megabytes that wait is long enough to read the text and watch it disappear —
   which is the flash. Keep the plate and its gold rule, drop the caption. A
   frame with no --img still shows its label, which is what it was for. */
.ph[style*="--img"]::after { content: ""; }

.ph::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: var(--img, none);
  background-size: cover;
  background-position: center;
}

/* --------------------------------------------------------------------------
   Gallery
   Controls are invisible until the gallery is hovered or something inside it
   takes focus. On touch, where there is no hover, they stay visible.
   -------------------------------------------------------------------------- */

.gallery { position: relative; }

.gallery__frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--ratio, 4 / 3);
  background: var(--placeholder);
}

.gallery__frame .ph {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s ease;
}
.gallery__frame .ph.is-active { opacity: 1; visibility: visible; }

/* Arrows. Circular glass rather than a square chip: they float over the
   photograph, so they belong to the image layer and not to the page chrome,
   which is why roundness here does not fight the flat editorial layout.
   Real chevrons with round caps, not a rotated CSS border. They fade in on
   hover; on touch there is no hover to reveal them with, so they are removed
   and the dots do the work instead. */
.gallery__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(15, 34, 68, 0.34);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  color: var(--cream);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.25s ease, background-color 0.25s ease;
}
.gallery__nav--prev { left: 0.75rem; }
.gallery__nav--next { right: 0.75rem; }
.gallery__nav:hover { background: rgba(15, 34, 68, 0.55); }

.gallery__nav svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  display: block;
}

/* A soft scrim so the dots hold over a bright photograph without needing a
   chrome capsule behind them. */
.gallery::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 5.5rem;
  background: linear-gradient(to top, rgba(15, 34, 68, 0.5), rgba(15, 34, 68, 0));
  pointer-events: none;
  z-index: 2;
}

/* Page dots. Always visible, because how many photographs there are is
   information, not a control that should have to be discovered. */
.gallery__dots {
  position: absolute;
  left: 50%;
  bottom: 0.95rem;
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.gallery__dot {
  position: relative;
  width: 0.44rem;
  height: 0.44rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(250, 246, 234, 0.5);
  cursor: pointer;
  transition: background-color 0.25s ease, transform 0.25s ease;
}
/* The dot is 7px because that is the right size to look at. The target around
   it is 44px, because that is the right size to hit. */
.gallery__dot::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 2.75rem;
  height: 2.75rem;
  transform: translate(-50%, -50%);
}
.gallery__dot:hover { background: rgba(250, 246, 234, 0.8); }
.gallery__dot.is-active {
  background: var(--cream);
  transform: scale(1.4);
}

.gallery:hover .gallery__nav,
.gallery:focus-within .gallery__nav { opacity: 1; }

/* On a touch screen there is no hover to reveal them with, so the arrows stay
   visible. Smaller, because on a phone the photograph is most of the screen and
   a full-size control sits heavily on it: the circle drops to 36px to look at,
   while a transparent ::after keeps the target at the 44px you have to hit. */
@media (hover: none) {
  .gallery__nav {
    opacity: 1;
    width: 2.25rem;
    height: 2.25rem;
    background: rgba(15, 34, 68, 0.44);
  }
  .gallery__nav::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 2.75rem;
    height: 2.75rem;
    transform: translate(-50%, -50%);
  }
  .gallery__nav svg { width: 0.95rem; height: 0.95rem; }
  .gallery__nav--prev { left: 0.5rem; }
  .gallery__nav--next { right: 0.5rem; }
}

/* --------------------------------------------------------------------------
   Lightbox
   -------------------------------------------------------------------------- */

[data-zoom] .ph { cursor: zoom-in; }
[data-zoom] .ph:focus-visible { outline: 2px solid var(--gold); outline-offset: -4px; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(15, 34, 68, 0.94);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1.5rem, 5vw, 3rem);
  --focus: var(--gold);
}
.lightbox[hidden] { display: none; }

.lightbox__figure {
  margin: 0;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.lightbox__figure img {
  display: block;
  max-height: calc(100vh - 9rem);
  width: auto;
  margin-inline: auto;
  border: 1px solid var(--hair-soft);
  border-radius: var(--radius);
}
.lightbox__figure figcaption {
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(250, 246, 234, 0.8);
  text-align: center;
}

.lightbox__close {
  position: absolute;
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 3vw, 2rem);
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  background: transparent;
  border: 1px solid var(--hair);
  cursor: pointer;
}
.lightbox__close::before,
.lightbox__close::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1rem;
  height: 1px;
  background: var(--cream);
}
.lightbox__close::before { transform: translate(-50%, -50%) rotate(45deg); }
.lightbox__close::after  { transform: translate(-50%, -50%) rotate(-45deg); }
.lightbox__close:hover { border-color: var(--gold); }

/* --------------------------------------------------------------------------
   Room detail pages
   -------------------------------------------------------------------------- */

.room-layout { display: grid; gap: clamp(2rem, 5vw, 3.5rem); }
@media (min-width: 900px) {
  .room-layout { grid-template-columns: 1.35fr 1fr; align-items: start; }
}

/* The room's own words sit under the photographs rather than in a section of
   their own further down, which both fills the column beside the facts panel
   and puts the description where someone looking at the pictures is looking. */
.room-prose { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.room-prose .rule { margin-bottom: 1.5rem; }

.room-facts {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 3vw, 2rem);
}
.room-facts h2 {
  font-size: 0.72rem;
  font-family: var(--ui);
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-antique);
  margin-bottom: 1.1rem;
}
.room-facts .price { margin-bottom: 1.5rem; }
.room-facts ul { display: grid; gap: 0.65rem; }
.room-facts li {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  font-size: 0.92rem;
  color: var(--text);
}
.room-facts li::before {
  content: "";
  width: 0.25rem;
  height: 0.25rem;
  background: var(--gold);
  transform: rotate(45deg);
  flex: none;
  position: relative;
  top: -0.2em;
}

/* A line that carries an icon drops the diamond, and centres rather than
   sitting on the baseline so the glyph lines up with the words. */
.room-facts li.has-icon { align-items: center; gap: 0.85rem; }
.room-facts li.has-icon::before { display: none; }

.fact-icon { display: none; }

@supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
  .fact-icon {
    display: block;
    width: 1.5rem;
    height: 1.5rem;
    flex: none;
    background-color: var(--gold-antique);
    -webkit-mask-size: contain;
            mask-size: contain;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-position: center;
            mask-position: center;
  }
}
.room-facts .btn { margin-top: 1.75rem; width: 100%; text-align: center; }

.back-link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--gold);
  margin-bottom: 1.25rem;
}
.back-link:hover { color: var(--cream); }

.room-nav {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.room-nav a {
  display: block;
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  text-decoration: none;
  background: var(--surface);
  overflow: hidden;
}
.room-nav a:hover { border-color: var(--gold); }

/* The room's first photograph. Decorative — the link text names the room —
   so it carries no alt and is hidden from assistive tech in the markup. */
.room-nav__img {
  display: block;
  aspect-ratio: 3 / 2;
  background-color: var(--placeholder);
  background-image: var(--img, none);
  background-size: cover;
  background-position: center;
}

.room-nav__body { display: block; padding: 1.1rem 1.25rem 1.25rem; }

.room-nav strong {
  display: block;
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.1rem;
  color: var(--heading);
  margin-bottom: 0.2rem;
}
.room-nav__group {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  /* Centred as a flex box rather than by padding alone. With inline-block,
     min-height dropped all of its slack below the text, which is what made
     the label sit high in the button. Measured after: within 0.2px of the
     optical centre, so no further nudge is warranted. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--ui);
  font-weight: 400;
  font-size: 0.78rem;
  line-height: 1;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 1rem 2rem;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  border-radius: var(--radius);
  transition: background-color 0.2s ease, color 0.2s ease,
              border-color 0.2s ease, box-shadow 0.2s ease,
              transform 0.2s ease;
}

.btn--solid {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--cream);
}
.btn--solid:hover { background: var(--navy-deep); border-color: var(--navy-deep); }
.btn--solid:active { background: var(--navy-press); border-color: var(--navy-press); }

/* The primary action. Solid where the secondaries are outlined. It inverts by
   ground rather than changing hue: cream on the dark header, hero and bands,
   navy on the cream sections, because a cream button on a cream page would be
   no button at all. Hover deepens, so contrast rises rather than merely
   changing. */
.btn--primary {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--cream);
}
.btn--primary:hover { background: var(--navy-deep); border-color: var(--navy-deep); }
.btn--primary:active { background: var(--navy-press); border-color: var(--navy-press); }

.site-header .btn--primary,
.page-head .btn--primary,
.hero__overlay .btn--primary,
.suite-hero__overlay .btn--primary,
.band--navy .btn--primary {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--navy);
}
.site-header .btn--primary:hover,
.page-head .btn--primary:hover,
.hero__overlay .btn--primary:hover,
.suite-hero__overlay .btn--primary:hover,
.band--navy .btn--primary:hover {
  background: var(--ivory);
  border-color: var(--ivory);
}
.site-header .btn--primary:active,
.page-head .btn--primary:active,
.hero__overlay .btn--primary:active,
.suite-hero__overlay .btn--primary:active,
.band--navy .btn--primary:active {
  background: var(--cream-press);
  border-color: var(--cream-press);
}

/* The accent. One button on the site wears it: the invitation into the suites
   at the foot of the homepage showcase. Antique gold with a cream label, the
   same gold as the eyebrows and rules, so it reads as warmth rather than as a
   second primary. Hover darkens: 4.7:1 -> 6.1:1. */
.btn--accent {
  background: var(--gold-antique);
  border-color: var(--gold-antique);
  color: var(--cream);
}
.btn--accent:hover { background: var(--brass-hover); border-color: var(--brass-hover); }
.btn--accent:active { background: var(--brass-press); border-color: var(--brass-press); }

/* Secondary actions. Outlined where the primary is filled, and on hover they
   light up rather than inverting: the border reaches full strength and a wash
   comes in behind. A flip changed everything and improved nothing. */
.btn--ghost {
  border-color: var(--heading);
  color: var(--heading);
}
.btn--ghost:hover { background: var(--ghost-tint); }
.btn--ghost:active { background: var(--ghost-press); }

/* The same, on a dark ground. */
.btn--light {
  border-color: var(--cream);
  color: var(--cream);
}
.btn--light:hover { background: rgba(250, 246, 234, 0.14); }
.btn--light:active { background: rgba(250, 246, 234, 0.24); }

.btn--sm {
  padding: 0.85rem 1.4rem;
  font-size: 0.75rem;
  min-height: 2.75rem;
}

/* Quiet text link with a gold underline */
.link {
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--gold-antique);
  border-bottom: 1px solid var(--hair);
  padding-bottom: 0.2rem;
  transition: border-color 0.25s ease;
}
.link:hover { border-bottom-color: var(--gold-antique); }

/* Contact links read as data, not as labels: no uppercasing, and a phone
   number must never break across lines mid-digits. */
.link[href^="tel:"],
.link[href^="mailto:"] {
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: 1rem;
}
.link[href^="tel:"] { white-space: nowrap; }

/* The same reasoning for a link inside a sentence in a document: it is part of
   the sentence, not a label beside it. Scoped to running prose, so a .link
   standing alone as a call to action keeps its uppercase treatment. */
.prose p .link {
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: 1rem;
}

.band--navy .link { color: var(--gold); border-bottom-color: rgba(201, 160, 99, 0.5); }
.band--navy .link:hover { border-bottom-color: var(--gold); }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 2rem;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--navy);
  border-bottom: 1px solid var(--hair-soft);
  --focus: var(--gold);
}

.site-header__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 0.85rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.brand {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 2.75rem;
  text-decoration: none;
  line-height: 1.15;
  flex: none;
}
.brand__name {
  display: block;
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.35rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cream);
}
.brand__sub {
  display: block;
  font-family: var(--ui);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold);
  margin-top: 0.2rem;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 2.1vw, 1.9rem);
}
.nav__list a {
  white-space: nowrap;          /* seven items must never break mid-label */
  font-size: 0.76rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--cream);
  padding-bottom: 0.25rem;
  border-bottom: 1px solid transparent;
  transition: border-color 0.25s ease;
}
.nav__list a:hover { border-bottom-color: var(--gold); }
.nav__list a[aria-current="page"] { border-bottom-color: var(--gold); }

.header-book { flex: none; }

/* Language switcher.
   Lives in the header rather than only the footer so it is visible without
   scrolling, and outside <nav> so the collapsing menu never hides it. It points
   at the current page's counterpart, not at the other language's home page. */
.header-lang {
  flex: none;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.4rem 0.15rem;
  font-family: var(--ui);
  font-weight: 400;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  /* Cream, not gold: gold clears AA on navy at 5.3:1 but reads as a muted
     ornament beside the Book now button. Cream is 11.7:1 and reads as a
     control. No border either — a second box next to the button is clutter. */
  color: var(--cream);
  border-bottom: 1px solid transparent;
}
.header-lang:hover { border-bottom-color: var(--gold); }

/* The nav already sits hard right on wide screens; the auto margin is only
   needed once the nav collapses and leaves a gap. */
@media (min-width: 1024px) {
  .header-lang { margin-left: 0.35rem; }
}

/* Once the menu collapses the hamburger belongs at the far right, where a
   thumb expects it, with the language link just inside it. */
@media (max-width: 1023px) {
  .header-lang { order: 2; }
  .nav-toggle { order: 3; }
}

@media (max-width: 400px) {
  .header-lang { padding: 0.35rem 0.5rem; letter-spacing: 0.1em; }
}

/* Hamburger */
.nav-toggle {
  display: none;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--hair);
  background: transparent;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
}
.nav-toggle span {
  display: block;
  width: 1.1rem;
  height: 1px;
  background: var(--gold);
}

@media (max-width: 1023px) {
  .nav-toggle { display: flex; }
  .header-book { display: none; }

  .nav {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    background: var(--navy-deep);
    border-bottom: 1px solid var(--hair-soft);
    display: none;
  }
  .site-header[data-open="true"] .nav { display: block; }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.5rem var(--gutter) 1.75rem;
  }
  .nav__list a {
    display: block;
    padding: 0.95rem 0;
    border-bottom: 1px solid var(--hair-soft);
  }
  .nav__list a:hover,
  .nav__list a[aria-current="page"] { border-bottom-color: var(--hair-soft); color: var(--gold); }
  .nav__book { margin-top: 1.5rem; }
  .nav__book .btn { display: block; text-align: center; }
}

@media (min-width: 1024px) {
  .nav__book { display: none; }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero { position: relative; }

.hero .ph {
  aspect-ratio: auto;
  height: clamp(24rem, 70vh, 42rem);
}


/* Keep the placeholder label clear of the hero copy */
.hero .ph::after {
  align-items: flex-start;
  justify-content: flex-start;
  text-align: left;
  padding: 1.5rem var(--gutter);
}

.hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: rgba(15, 34, 68, 0.66);
  display: flex;
  align-items: flex-end;
  --focus: var(--gold);
}

.hero__inner {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(2.5rem, 6vw, 4.5rem);
}

/* Cream, not gold. Measured against the brightest pixel actually behind it,
   gold on the scrimmed photograph comes to 2.2:1 where a label this size
   needs 4.5:1; cream reaches 4.9:1. page-head--photo already did this. */
.hero__overlay .eyebrow { color: var(--cream); margin-bottom: 1rem; }
.hero__overlay h1 { color: var(--cream); max-width: 18ch; }
.hero__overlay p {
  color: rgba(250, 246, 234, 0.94);
  max-width: 48ch;
  margin-top: 1.25rem;
}

/* Compact page header for interior pages */
.page-head {
  position: relative;
  background: var(--navy);
  color: var(--cream);
  padding-block: clamp(2.5rem, 6vw, 4.25rem);
  --focus: var(--gold);
}
.page-head > .wrap { position: relative; z-index: 2; }

/* Optional photograph behind the band. Set --img on the section. If the file
   is absent the ::before paints nothing and the flat navy shows instead, so
   the band is never broken by a missing image. */
.page-head--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--img, none);
  background-size: cover;
  background-position: center;
}
.page-head--photo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(15, 34, 68, 0.75);
}

/* Gold reaches only 2.2:1 against a pale photograph under this overlay, so the
   eyebrow switches to cream here. Gold stays as ornament on the rule below. */
.page-head.page-head--photo .eyebrow { color: var(--cream); }
.page-head .eyebrow { color: var(--gold); margin-bottom: 1rem; }
.page-head h1 { color: var(--cream); max-width: 20ch; }
.page-head p {
  color: rgba(250, 246, 234, 0.85);
  max-width: var(--measure);
  margin-top: 1.5rem;
}

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

/* A card brings its own background, so it must bring its own text colours.
   Inheriting them means cream-on-cream the moment a card sits in a dark band.
   Same rule applies to any panel below that paints its own surface. */
.card {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  /* The photograph sits flush against the border, so without clipping the card
     would round while the image inside kept its square corners. */
  overflow: hidden;
  display: flex;
  flex-direction: column;
  --focus: var(--gold-antique);
  /* The whole card is a click target (see .card__foot .link below). Isolating
     keeps .ph's image, painted on a ::before at z-index 1, underneath it. */
  position: relative;
  isolation: isolate;
}

/* One link, stretched over the entire card. Using the existing Details anchor
   rather than adding a second one keeps a single tab stop and a single thing
   for a screen reader to announce. */
.card__foot .link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
}

.card:hover { border-color: var(--gold); }
.card:hover .link { border-bottom-color: var(--gold-antique); }

.card h2,
.card h3,
.card h4 { color: var(--heading); }
.card p,
.card dd { color: var(--text); }
.card .eyebrow { color: var(--gold-antique); }
.card .spec,
.card .spec li { color: var(--text-muted); }
.card .caption,
.card .muted { color: var(--text-muted); }
.card .link { color: var(--heading); border-bottom-color: var(--hair); }
.card .link:hover { border-bottom-color: var(--gold-antique); }

.card__body {
  padding: 1.5rem 1.5rem 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  flex: 1;
}

.card__body h3 { margin-bottom: 0.1rem; }
.card__body p { font-size: 0.95rem; }
.card__foot { margin-top: auto; padding-top: 0.85rem; }

/* --------------------------------------------------------------------------
   Price
   -------------------------------------------------------------------------- */

.price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.25rem;
}
.price b {
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.45rem;
  line-height: 1;
  color: var(--heading);
}
.price span {
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Universal amenities, listed once rather than repeated on every room */
.amenities {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  max-width: 60rem;
}
.amenities li { display: flex; align-items: center; gap: 0.6rem; }
.amenities li::before {
  content: "";
  width: 0.25rem;
  height: 0.25rem;
  background: var(--gold);
  transform: rotate(45deg);
  flex: none;
}

/* Amenity grid.
   The icons are single-colour artwork carried as CSS masks rather than <img>,
   so they take their colour from the surface they sit on: antique gold on
   cream, brighter gold on navy. Guarded by @supports, because without mask
   support the element would paint as a solid gold square. */
.amenities--icons {
  display: grid;
  /* Fixed counts rather than auto-fit: the list is ten items, and auto-fit
     lands them seven-then-three, which reads as an accident. */
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.75rem, 3.5vw, 2.5rem) clamp(0.75rem, 2vw, 1.5rem);
  max-width: none;
  font-size: 0.78rem;
  line-height: 1.45;
  letter-spacing: 0.04em;
  text-transform: none;
}

.amenities--icons li {
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.75rem;
}

@media (min-width: 560px) { .amenities--icons { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 860px) { .amenities--icons { grid-template-columns: repeat(5, 1fr); } }

/* Eight items divide evenly into four columns; the five-column default would
   leave three stranded on a second row. */
@media (min-width: 860px) {
  .amenities--icons.is-eight { grid-template-columns: repeat(4, 1fr); }
}

/* The diamond bullet belongs to the plain list, not this one. */
.amenities--icons li::before { display: none; }

.amenity-icon { display: none; }

@supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
  .amenity-icon {
    display: block;
    width: 2.75rem;
    height: 2.75rem;
    flex: none;
    background-color: var(--gold-antique);
    -webkit-mask-size: contain;
            mask-size: contain;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-position: center;
            mask-position: center;
  }
  .band--navy .amenity-icon { background-color: var(--gold); }
}

.spec {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  font-size: 0.76rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.spec li { display: flex; align-items: center; gap: 0.55rem; }

/* An item that carries an icon drops the lozenge. Same masks and the same
   keyword mapping as the room facts panel, so a room's card and its own page
   never disagree about which feature gets which glyph. */
.spec li.has-icon::before { display: none; }

.spec-icon { display: none; }

@supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
  .spec-icon {
    display: block;
    width: 1.15rem;
    height: 1.15rem;
    flex: none;
    background-color: var(--gold-antique);
    -webkit-mask-size: contain;
            mask-size: contain;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-position: center;
            mask-position: center;
  }
  .band--navy .spec-icon { background-color: var(--gold); }
  /* ...but a card sitting inside that band is cream again, so its icons go
     back to the darker gold. Light gold on cream measures 2.2:1. */
  .band--navy .card .spec-icon,
  .band--navy .room-nav .spec-icon { background-color: var(--gold-antique); }
  /* Over a photograph, the icons take the light gold like the eyebrow. */
  .hero__overlay .spec-icon,
  .suite-hero__overlay .spec-icon { background-color: var(--gold); }
}

/* A leading lozenge on every item, not a separator between items. As a
   separator it orphaned onto the next line whenever the list wrapped, so a
   one-line list read "a ◆ b" and a wrapped one read "a / ◆ b". */
.spec li::before {
  content: "";
  width: 0.25rem;
  height: 0.25rem;
  background: var(--gold);
  transform: rotate(45deg);
  flex: none;
}

/* --------------------------------------------------------------------------
   Alternating feature rows — used on the suites page
   -------------------------------------------------------------------------- */

.feature {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
.feature + .feature { margin-top: clamp(2.25rem, 5vw, 4rem); }

@media (min-width: 860px) {
  .feature { grid-template-columns: 1fr 1fr; }
  .feature--flip .feature__media { order: 2; }
}

.feature__body .eyebrow { margin-bottom: 0.9rem; }
.feature__body h2,
.feature__body h3 {
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  font-weight: 400;
  margin-bottom: 1.1rem;
}

/* A label-sized heading inside a feature body; the rule above sizes h2/h3 for
   the row title, which is far too large for a sub-heading. */
.feature__body h3.subhead {
  font-family: var(--ui);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-antique);
  margin-top: 2rem;
  margin-bottom: 0.9rem;
}
.band--navy .feature__body h3.subhead { color: var(--gold); }
.feature__body .spec { margin-top: 1.4rem; }

/* --------------------------------------------------------------------------
   Detail list — contact page
   -------------------------------------------------------------------------- */

.details { display: grid; gap: 2.25rem; }
@media (min-width: 700px) { .details { grid-template-columns: repeat(2, 1fr); } }

.detail h2,
.detail h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem); font-weight: 400; margin-bottom: 0.6rem; }
.detail p { font-size: 0.95rem; }

.detail dl { margin: 0; }
.detail dt {
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-antique);
  margin-top: 1rem;
}
.detail dd { margin: 0.15rem 0 0; }

/* --------------------------------------------------------------------------
   Timeline — story page
   -------------------------------------------------------------------------- */

.timeline {
  border-left: 1px solid var(--hair);
  padding-left: clamp(1.25rem, 3vw, 2rem);
  display: grid;
  gap: 1.75rem;
  max-width: var(--measure);
}
.timeline__year {
  font-family: var(--ui);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-antique);
  margin-bottom: 0.3rem;
}
.timeline h3 { font-size: 1.15rem; margin-bottom: 0.35rem; }
.timeline p { font-size: 0.95rem; }

/* --------------------------------------------------------------------------
   Map embed
   Google's iframe ships with width/height attributes; those are overridden so
   it fills a 4/3 frame like the photograph it replaced, at any screen width.
   -------------------------------------------------------------------------- */

.map-embed {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--placeholder);
  border: 1px solid var(--hair-soft);
}

.map-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* --------------------------------------------------------------------------
   Social reels
   Self-hosted MP4s, muted and looping. Browsers allow autoplay only when a
   video is muted, so these carry no sound by design. They play only while on
   screen, and not at all if the visitor has asked for reduced motion.
   -------------------------------------------------------------------------- */

.reel-grid {
  display: grid;
  gap: clamp(0.75rem, 2vw, 1.25rem);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 860px) {
  .reel-grid { grid-template-columns: repeat(4, 1fr); }
}

.reel {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--placeholder);
  border: 1px solid var(--hair);
}

.reel::after {                     /* shows through until a file is dropped in */
  content: attr(data-label);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem 1rem;
  text-align: center;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);

  /* The gold rule-and-diamond from .rule, so a frame still waiting on its
     photograph reads as a deliberate blank plate rather than a failed load. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='9'%3E%3Cpath d='M0 4.5h52M68 4.5h52' stroke='%23C9A063' stroke-opacity='.55'/%3E%3Cpath d='M60 1.7l2.8 2.8L60 7.3l-2.8-2.8z' fill='%23C9A063'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center calc(50% - 1.4rem);
  background-size: min(120px, 60%) auto;
}

/* An empty <video> paints solid black, which would hide the label below it.
   It stays invisible until a file actually loads. */
.reel video {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.reel.is-live video { opacity: 1; }

/* No film, nothing to play and nowhere to send anyone: the controls and the
   social link stay out until a file loads, leaving a clean labelled plate. */
.reel:not(.is-live) .reel__toggle,
.reel:not(.is-live) .reel__sound,
.reel:not(.is-live) .reel__link { display: none; }

/* Controls.
   Nothing sits on top of a film until you ask for it — the same rule the
   galleries follow. Play/pause top left, sound top right, the post link along
   the bottom; all three fade in on hover or when something inside takes focus,
   so a keyboard reaches them too. Both buttons share one navy-on-cream
   treatment because they now sit side by side.
   -------------------------------------------------------------------------- */

/* The same object as .gallery__nav: a blurred translucent disc that lets the
   picture read through it, rather than a bordered panel laid on top. One
   control language for every overlay on the site. */
.reel__toggle,
.reel__sound {
  position: absolute;
  z-index: 3;
  top: 0.6rem;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(15, 34, 68, 0.34);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  color: var(--cream);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.25s ease, background-color 0.25s ease;
}
.reel__toggle { left: 0.6rem; }
.reel__sound { right: 0.6rem; }

.reel__toggle:hover,
.reel__sound:hover { background: rgba(15, 34, 68, 0.55); }

.reel__toggle::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 0.55rem solid currentColor;
  border-top: 0.36rem solid transparent;
  border-bottom: 0.36rem solid transparent;
  margin-left: 0.15rem;
}
.reel__toggle[aria-pressed="true"]::before {
  width: 0.55rem;
  height: 0.6rem;
  border: 0;
  margin-left: 0;
  background: currentColor;
  clip-path: polygon(0 0, 35% 0, 35% 100%, 0 100%, 0 0, 65% 0, 100% 0, 100% 100%, 65% 100%, 65% 0);
}

.reel__ico { width: 1.05rem; height: 1.05rem; display: block; }
.reel__ico--on { display: none; }
.reel__sound[aria-pressed="true"] .reel__ico--off { display: none; }
.reel__sound[aria-pressed="true"] .reel__ico--on { display: block; }

/* The text equivalent of those discs: a floating pill on the same blur, sized
   to its words and centred, instead of an opaque bar welded to the bottom
   edge. It clears the tile's rounded corners rather than fighting them. */
.reel__link {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: 0.6rem;
  transform: translateX(-50%);
  max-width: calc(100% - 1.2rem);
  padding: 0.6rem 0.95rem;
  border-radius: 999px;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  text-decoration: none;
  color: var(--cream);
  background: rgba(15, 34, 68, 0.34);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  opacity: 0;
  transition: opacity 0.25s ease, background-color 0.25s ease;
}
.reel__link:hover { background: rgba(15, 34, 68, 0.55); }

.reel.is-live:hover .reel__toggle,
.reel.is-live:hover .reel__sound,
.reel.is-live:hover .reel__link,
.reel.is-live:focus-within .reel__toggle,
.reel.is-live:focus-within .reel__sound,
.reel.is-live:focus-within .reel__link { opacity: 1; }

/* No hover to reveal them with, so leave them showing. */
@media (hover: none) {
  .reel.is-live .reel__toggle,
  .reel.is-live .reel__sound,
  .reel.is-live .reel__link { opacity: 1; }
}

/* --------------------------------------------------------------------------
   Social links
   -------------------------------------------------------------------------- */

.social {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  margin-top: 1.25rem;
}
.social a {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--hair-soft);
  border-radius: var(--radius);
  color: var(--gold);
}
.social a:hover { border-color: var(--gold); color: var(--cream); }
.social svg { width: 1.05rem; height: 1.05rem; fill: currentColor; display: block; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--navy-deep);
  color: rgba(250, 246, 234, 0.75);
  padding-block: clamp(2.5rem, 5.5vw, 3.75rem);
  font-size: 0.9rem;
  --focus: var(--gold);
}

.site-footer a { text-decoration: none; }
.site-footer a:hover { color: var(--gold); }

.footer-grid { display: grid; gap: 2.5rem; }
@media (min-width: 760px) {
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; gap: 3rem; }
}

.site-footer h2 {
  font-size: 0.72rem;
  font-family: var(--ui);
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 1.1rem;
}

.footer-brand .brand__name { font-size: 1.5rem; }
.footer-brand address {
  font-style: normal;
  margin-top: 1.25rem;
  line-height: 1.8;
}

.footer-links { display: grid; gap: 0.6rem; }

.footer-bottom {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--hair-soft);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  align-items: center;
  font-size: 0.8rem;
}

.lang {
  display: flex;
  gap: 1rem;
  align-items: center;
}
.lang a {
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.lang a[aria-current="true"] { color: var(--gold); }
.lang span[aria-hidden="true"] { color: var(--hair); }

/* --------------------------------------------------------------------------
   Theme toggle
   Sits in the footer beside the language links and borrows their typography,
   because it is the same kind of control: a switch between two versions of
   the same page. It is a button, not a link — it changes how this page looks
   rather than going anywhere.
   -------------------------------------------------------------------------- */
.theme-toggle {
  font-family: var(--ui);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: inherit;
  background: none;
  border: 0;
  border-bottom: 1px solid transparent;
  padding: 0 0 0.15rem;
  min-height: 2.75rem;      /* a touch target, like the language links */
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  transition: border-color 0.25s ease, color 0.25s ease;
}
.theme-toggle:hover { border-bottom-color: var(--gold); color: var(--gold); }
.theme-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* The lamp fills in when the dark theme is on, so the control shows its state
   and not only its action. */
.theme-toggle__icon { width: 0.95rem; height: 0.95rem; flex: none; }


/* --------------------------------------------------------------------------
   Skip link
   -------------------------------------------------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--cream);
  color: var(--navy);
  padding: 0.9rem 1.5rem;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
}
.skip:focus { left: 0; }

/* ==========================================================================
   Platform behaviour
   Apple's HIG asks for three things a stylesheet can actually honour: keep
   content clear of the notch and the home indicator, give touch its own
   feedback rather than the browser's grey flash, and respect the reader's
   accessibility settings. Reduced motion is handled at the top of this file.
   ========================================================================== */

/* Safe areas. The viewport is now viewport-fit=cover, which lets the page
   paint edge to edge; these keep the words out of the hardware. */
.wrap {
  padding-inline:
    max(var(--gutter), env(safe-area-inset-left))
    max(var(--gutter), env(safe-area-inset-right));
}

.site-header { padding-top: env(safe-area-inset-top); }

.site-footer {
  padding-bottom: calc(clamp(2.5rem, 5.5vw, 3.75rem) + env(safe-area-inset-bottom));
}

.lightbox {
  padding:
    env(safe-area-inset-top)
    env(safe-area-inset-right)
    env(safe-area-inset-bottom)
    env(safe-area-inset-left);
}

/* Touch feedback. The default is a grey rectangle that ignores the palette;
   a gold wash at low alpha reads as the site rather than as the browser. */
body {
  -webkit-tap-highlight-color: rgba(201, 160, 99, 0.24);
}

/* Increase Contrast. When the reader has asked the system for more contrast,
   hairlines stop being decorative and muted text stops being muted. */
@media (prefers-contrast: more) {
  :root {
    --hair:      rgba(138, 106, 47, 0.85);
    --hair-soft: rgba(138, 106, 47, 0.55);
    --stone:     #55503F;
  }
  .site-footer { color: rgba(250, 246, 234, 0.95); }
  .btn { border-width: 2px; }
  .link { border-bottom-width: 2px; }
}

/* The footer language pair is a control, not prose, so it takes a control's
   target size rather than a text link's. */
.footer-bottom .lang a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-inline: 0.15rem;
}

/* ==========================================================================
   Interface guidelines
   The remaining items from Vercel's web interface guidelines that apply to a
   site of static pages. Anything about forms, hydration or list virtualisation
   is not relevant here; what follows is.
   ========================================================================== */

/* Tell the browser which schemes exist, so form controls, scrollbars and the
   canvas behind the page match rather than defaulting to light. */
:root { color-scheme: light; }

/* --------------------------------------------------------------------------
   Dark mode
   Three states, not two. An explicit choice stamps data-theme on <html>; the
   default "system" setting stamps nothing, so only prefers-color-scheme
   separates light from dark there. The media query is guarded against an
   explicit light choice, and the [data-theme="dark"] rule repeats the tokens
   so the toggle wins in both directions.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  color-scheme: dark;

  /* A ladder of navy-biased darks, so the surfaces that were already dark in
     light mode still separate from the page:
       bg  #0B111F  <  footer/nav #0F2244  <  cards  <  header/band #17325E
     The navy bands therefore stay legible without being repainted: in light
     mode they are darker than the page, in dark mode lighter. Either way they
     read as a distinct zone, and their cream text needs no change. */
  --bg:          #0B111F;
  --surface:     #141C2E;
  --surface-2:   #223354;   /* lifts above both the page and a navy band */
  --text:        #E6E1D4;   /* warm off-white, the cream's relative */
  --text-muted:  #A29B8B;
  --heading:     #F2EDE0;
  --placeholder: #1C2536;

  /* The antique gold is a darkened gold for light grounds. On a dark ground
     that role inverts: it has to be lighter than the base gold, not darker. */
  --gold-antique: #D7B478;
  --focus:        #D7B478;

  --hair:      rgba(201, 160, 99, 0.30);
  --hair-soft: rgba(201, 160, 99, 0.16);

  --ghost-tint:  rgba(230, 225, 212, 0.08);
  --ghost-press: rgba(230, 225, 212, 0.14);

  /* Shadows have to come from black, not navy: a navy shadow on a navy ground
     is invisible. */
  --lift:      0 6px 16px rgba(0, 0, 0, 0.45);
  --lift-deep: 0 8px 22px rgba(0, 0, 0, 0.55);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  /* A ladder of navy-biased darks, so the surfaces that were already dark in
     light mode still separate from the page:
       bg  #0B111F  <  footer/nav #0F2244  <  cards  <  header/band #17325E
     The navy bands therefore stay legible without being repainted: in light
     mode they are darker than the page, in dark mode lighter. Either way they
     read as a distinct zone, and their cream text needs no change. */
  --bg:          #0B111F;
  --surface:     #141C2E;
  --surface-2:   #223354;   /* lifts above both the page and a navy band */
  --text:        #E6E1D4;   /* warm off-white, the cream's relative */
  --text-muted:  #A29B8B;
  --heading:     #F2EDE0;
  --placeholder: #1C2536;

  /* The antique gold is a darkened gold for light grounds. On a dark ground
     that role inverts: it has to be lighter than the base gold, not darker. */
  --gold-antique: #D7B478;
  --focus:        #D7B478;

  --hair:      rgba(201, 160, 99, 0.30);
  --hair-soft: rgba(201, 160, 99, 0.16);

  --ghost-tint:  rgba(230, 225, 212, 0.08);
  --ghost-press: rgba(230, 225, 212, 0.14);

  /* Shadows have to come from black, not navy: a navy shadow on a navy ground
     is invisible. */
  --lift:      0 6px 16px rgba(0, 0, 0, 0.45);
  --lift-deep: 0 8px 22px rgba(0, 0, 0, 0.55);
}

/* No double-tap zoom on anything you are meant to press. */
a, button, summary, [role="button"], input, select, label {
  touch-action: manipulation;
}

/* The header is sticky, so an anchored jump has to clear it or the target
   lands underneath. This includes the skip link. */
:target,
#main,
h1[id], h2[id], h3[id], .section[id] {
  scroll-margin-top: 5.5rem;
}

/* Scrolling inside the lightbox must not chain to the page behind it. */
.lightbox { overscroll-behavior: contain; }

/* Digits that are read in columns or compared against each other. */
.price b,
.nearby__time,
.timeline__year,
.ratings b,
.tel {
  font-variant-numeric: tabular-nums;
}

/* Tidier rag: the browser avoids leaving a single word on the last line. */
p, li, figcaption, blockquote { text-wrap: pretty; }

/* A single action closing a full-bleed showcase. Centred, because it belongs
   to the whole run of bands above it rather than to the last one, and given
   room so it does not look bolted onto the final band. */
.btn-row--close {
  justify-content: center;
  margin-top: clamp(2.25rem, 5vw, 3.5rem);
}

/* The facts on an 'other rooms' card. Bed, then capacity, then what makes the
   room different: the same order on every card, because cards that list their
   facts in different orders cannot be compared at a glance. Same icon
   vocabulary as the detail pages, so a guest reads one language throughout. */
.room-nav__specs {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--hair-soft);
}

.room-nav__spec {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--ui);
  font-size: 0.78rem;
  line-height: 1.35;
  color: var(--text-muted);
}

.room-nav__spec .spec-icon {
  width: 1rem;
  height: 1rem;
}

/* A gallery is a framed photograph like any other, so it takes the same corner:
   the suites page, the room pages, anywhere it stands on its own. Inside a
   listing card it must not, because the card already clips it and a second
   radius there would round the photograph away from the card's own edge. */
.gallery__frame { border-radius: var(--radius); }
.card .gallery__frame { border-radius: 0; }

/* The hotel is on the left of the hero photograph and its sign on the right,
   around 71% to 90% across. As the viewport narrows the frame keeps its height
   but loses width, so a centred crop lands on the hedges between the two and
   the sign disappears. Biasing right keeps the sign in frame down to 390px. */
@media (max-width: 900px) {
  .hero .ph::before { background-position: 85% center; }

  /* The copy was anchored to the bottom of the frame, which on a narrow screen
     put the headline straight across the sign while the sky above it sat empty.
     Anchoring to the top drops the words onto the sky and leaves the sign clear
     underneath, which is the one thing in the photograph worth reading. */
  .hero__overlay { align-items: stretch; }
  .hero__inner {
    display: flex;
    flex-direction: column;
    /* Set so the copy block ends just above the LE CHABROL lettering on the
       sign, which is the one part of the picture that has to stay readable.
       Retuned when the three perks were added: they cost two lines on a
       narrow screen, so the block starts higher to end in the same place. */
    padding-top: clamp(1.75rem, 4.5vh, 3rem);
    /* Lifted clear of the hedge at the foot of the photograph, so the row
       sits in the band between the base of the sign and the bushes. Tied
       to viewport height because the frame itself is 70vh tall. */
    padding-bottom: clamp(3.5rem, 10vh, 7rem);
  }

  /* Words at the top, buttons at the bottom, and the sign left uncovered in
     the band between them. On the wide layout the whole block sits together
     at the foot of the frame, where there is nothing behind it to hide. */
  .hero__inner .btn-row { margin-top: auto; }
}

/* The three things that close a booking, in the hero. Over a photograph the
   list needs the light gold and cream the rest of the overlay uses, not the
   stone-on-cream it takes in a card. */
.spec--perks {
  margin-top: 1.25rem;
  gap: 0.5rem 1.4rem;
}
.hero__overlay .spec--perks { color: var(--cream); }

/* --------------------------------------------------------------------------
   One hover language
   Everything you can press behaves the same way: it rises off the page and it
   deepens. A gold hairline alone was too quiet to read as an affordance, and
   on a touch screen there is no hover at all, so :active carries the identical
   signal on press. Nothing lifts at rest, so the page keeps its flat, printed
   look until you reach for it.
   -------------------------------------------------------------------------- */
.card,
.room-nav a {
  transition: border-color 0.2s ease, box-shadow 0.25s ease, transform 0.25s ease;
}
.card .ph::before,
.room-nav__img {
  transition: filter 0.3s ease, transform 0.45s ease;
}

@media (hover: hover) {
  .btn:hover {
    transform: translateY(-2px);
    box-shadow: var(--lift);
  }

  .card:hover,
  .room-nav a:hover {
    transform: translateY(-3px);
    box-shadow: var(--lift-deep);
    border-color: var(--gold);
  }
  /* The photograph darkens and eases in behind the crop, which is what makes
     the card read as one object rather than a picture with text under it. */
  .card:hover .ph::before,
  .room-nav a:hover .room-nav__img {
    filter: brightness(0.72);
    transform: scale(1.04);
  }
}

/* Press. On a touch screen this is the whole interaction, so it has to carry
   on its own: the object settles back down and the photograph stays dark. */
.btn:active { transform: translateY(0); box-shadow: none; }

.card:active,
.room-nav a:active {
  transform: translateY(0);
  box-shadow: var(--lift);
  border-color: var(--gold);
}
.card:active .ph::before,
.room-nav a:active .room-nav__img { filter: brightness(0.72); }

/* The same signal for anyone arriving by keyboard. */
.card:focus-within,
.room-nav a:focus-visible { border-color: var(--gold); box-shadow: var(--lift); }
.card:focus-within .ph::before,
.room-nav a:focus-visible .room-nav__img { filter: brightness(0.72); }

/* Asked for less motion: keep the darkening, which is the information, and
   drop the travel, which is the decoration. */
@media (prefers-reduced-motion: reduce) {
  .btn:hover,
  .card:hover,
  .room-nav a:hover { transform: none; }
  .card:hover .ph::before,
  .room-nav a:hover .room-nav__img { transform: none; }
}

/* The toll-free number, in the footer of every page. Given its own line under
   the address rather than buried in the link columns, because a guest who
   wants to talk to the front desk should not have to go looking. */
.footer-tel {
  margin-top: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.footer-tel span {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}
.footer-tel a {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--cream);
  text-decoration: none;
  border-bottom: 1px solid rgba(201, 160, 99, 0.45);
  padding-bottom: 0.1rem;
  align-self: flex-start;
}
.footer-tel a:hover { border-bottom-color: var(--gold); }

/* --------------------------------------------------------------------------
   Wide cards, for the suites on the homepage
   A suite is sold on the room itself, so the photograph gets half the width
   rather than a thumbnail above the copy, and the sides alternate down the
   run. It is still a card, though: bordered, rounded, one click target, which
   is what separates it from the flush full-bleed band this replaced.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .card--wide {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  /* Grid children default to min-width:auto, which lets the photograph compute
     a width from its height and ride over the copy beside it. */
  .card--wide > * { min-width: 0; }

  .card--wide .ph {
    aspect-ratio: auto;
    height: 100%;
    min-height: 22rem;
  }

  .card--wide .card__body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: clamp(1.75rem, 3.5vw, 3rem);
  }

  /* Alternate which side the photograph falls on. */
  .suite-cards > .card--wide:nth-child(even) > .ph,
  .suite-cards > .card--wide:nth-child(even) > .gallery { order: 2; }

  /* On the listing pages the media is a gallery, not a bare photograph, so the
     gallery is the grid child and has to take the column height itself. Left
     alone its frame keeps the 4/3 ratio and the copy beside it hangs past the
     bottom edge of the picture. */
  .card--wide > .gallery,
  .card--wide > .gallery .gallery__frame { height: 100%; }
  .card--wide > .gallery .gallery__frame {
    aspect-ratio: auto;
    min-height: 22rem;
  }
}

/* The hero perks stack on a narrow screen. Wrapped in a row they broke two-
   and-one, which reads as an accident rather than a list; one per line reads
   as three things you get. The wide layout keeps them on a single row. */
@media (max-width: 900px) {
  .spec--perks {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }
}

/* A photograph with visible corners takes the corner. Full-bleed images run to
   the screen edge and have no side corners to round, so the hero, the suites
   banner and the page-head bands stay square; every framed photograph inside
   the page gutter is rounded like the cards. */
.wrap .ph { border-radius: var(--radius); }

/* Except where something around them already rounds and clips: a card, an
   other-rooms link, or a gallery frame. A second radius inside one of those
   pulls the photograph away from the edge that is already curved. */
.card .ph,
.room-nav a .ph,
.gallery .ph { border-radius: 0; }
