/* ============================================================
   ASTER HOTEL GROUP — HOME PAGE STYLES
   Used only on the main page: hero, about, rooms-section, location
   ============================================================ */

/* ============================================================
   HERO SECTION
   ============================================================ */
.hero {
  position: relative;
  width: 100%;
  height: 100vh;
  min-height: 680px;
  overflow: hidden;
}

.hero-bg {
  position: absolute;
  inset: 0;
  /* Two declarations on purpose, and the order matters.

     A background image cannot use <picture>, so the choice is made here. An old
     browser that does not understand image-set() ignores the second line and
     keeps the JPEG; a current one takes the second, prefers WebP, and falls back
     to the JPEG on its own if it cannot decode WebP. Nobody is left without a
     hero image.

     Paths stay relative: inside a stylesheet they resolve against the stylesheet,
     not the page, so the same rule works from / and from /en/. */
  background-image: url('../images/hero.jpg');
  background-image: image-set(
    url('../images/hero.webp') type('image/webp'),
    url('../images/hero.jpg') type('image/jpeg')
  );
  background-size: cover;
  background-position: center center;
  /* Slowly closer, 100% to 106% over 16s — Jun's choice from the demo,
     2026-09-29. It replaced the inherited 108% → 100% over 12s. The text
     contrast over this photograph was measured at every scale in between;
     re-measure if the scale, the photo or the overlay changes. */
  animation: heroCloser 16s var(--ease-soft) forwards;
}

@keyframes heroCloser {
  from { transform: scale(1); }
  to   { transform: scale(1.06); }
}

.hero-overlay {
  position: absolute;
  inset: 0;
  /* Two scrims, not one flat wash. Text sits at the top of the hero and at the
     bottom; the middle carries the building and stays light, so the photograph
     survives while every line of text clears its threshold.

     Measured 2026-09-08 against the actual pixels of hero.jpg, per element,
     with 8-bit rounding applied at both compositing steps. Before: nine of ten
     text elements failed, the worst at 1.71:1. After: all pass, none by less
     than 0.33, and none has a single pixel of its area below threshold.

     Stop positions track where the text actually falls — 7% nav, 18% eyebrow,
     69% title, 80% tagline, 91% buttons. Those moved on 2026-09-23 when the
     logo artwork made the header taller and pushed everything down: the eyebrow
     went from 15% to 18% and landed where the scrim had already begun to fade,
     dropping it to 4.02. The dark band now holds to 20% instead of 14%. Moving text vertically means measuring
     again; these numbers are not decoration. Same for a new hero photograph:
     they were derived from this image's pixels and do not transfer.

     REWORKED 2026-09-23. The first attempt at the brand palette tinted the scrim
     with Dark Chocolate, and it came out both too dark and visibly red. Both
     faults had one cause: Dark Chocolate is 74% brighter than the near-black it
     replaced, so it needed far more alpha to do the same job, and it is a warm
     brown, so all that alpha carried a red cast into the photograph.

     A scrim is not a brand surface. The brandbook assigns colours to text,
     backgrounds and accents; it says nothing about photographic overlays,
     because an overlay's job is to darken without tinting. So this one is a
     deep neutral, and the text over it was taken to full opacity — every point
     of transparency in the text was being paid for with extra darkness in the
     image.

     Result: the top band is 0.64 where the previous attempt needed 0.78, and
     the middle of the photograph opens up from 0.24 to 0.20 across a wider span.
     The building is visible again and the red cast is gone. */
  background: linear-gradient(
    to bottom,
    rgba(12, 11, 11, 0.64) 0%,
    rgba(12, 11, 11, 0.63) 20%,
    rgba(12, 11, 11, 0.20) 34%,
    rgba(12, 11, 11, 0.22) 55%,
    rgba(12, 11, 11, 0.58) 68%,
    rgba(12, 11, 11, 0.66) 80%,
    rgba(12, 11, 11, 0.68) 100%
  );
}

.hero-inner {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  /* Top padding clears the fixed header, which is now taller than it was: the
     horizontal logo stands 84px at 240px wide, plus 22px of padding above and
     below, so the header measures 129px against the 83px it used to. The old
     100px left the eyebrow sitting 29px underneath it. 150px restores a real
     gap. Re-check this if the logo width or the header padding changes. */
  padding: 150px 52px 52px;
}

.hero-top {
  display: flex;
  justify-content: center;
  opacity: 0;
  animation: fadeDown 1.2s ease-out 0.3s forwards;
}

.hero-eyebrow {
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.5em;
  text-transform: uppercase;
  color: var(--cream);
  font-weight: 400;
  padding: 0.5em 0 0.5em 0.5em;
}

@keyframes fadeDown {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: translateY(0); }
}

.hero-bottom {
  max-width: 1400px;
  margin: 0 auto;
  width: 100%;
  text-align: center;
}

.hero-title {
  font-family: var(--brand-serif);
  font-weight: 300;
  font-size: clamp(3.2rem, 7vw, 6.5rem);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--cream);
  margin-bottom: 32px;
  opacity: 0;
  animation: fadeUp 1.4s ease-out 0.6s forwards;
}

/* Warm Ivory, not an accent colour — same reason as .nav-logo em in shared.css.
   A photograph runs through every luminance there is, so any mid-tone dissolves
   somewhere on it: the old gold measured 1.00:1 across 57% of its own area here,
   and no overlay repaired that. Muted Brass is a mid-tone too and would behave
   the same way, only lighter. Only colours near the ends of the range survive an
   image. The word stays distinct through the italic. */
.hero-title em {
  font-style: italic;
  color: var(--cream);
  font-weight: 300;
}

.hero-tagline {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.05rem, 1.6vw, 1.4rem);
  letter-spacing: 0.04em;
  color: var(--cream);
  line-height: 1.4;
  margin-bottom: 56px;
  opacity: 0;
  animation: fadeUp 1.4s ease-out 1s forwards;
}

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

.hero-cta-row {
  display: flex;
  justify-content: center;
  gap: 140px;
  flex-wrap: wrap;
  opacity: 0;
  animation: fadeUp 1.4s ease-out 1.3s forwards;
}

/* The two first-screen actions are the button system's (shared.css, BUTTONS):
   Book Now .btn-primary, View Rooms .btn-text.btn-on-dark. The row only
   centres them; .hero-cta stays as a hook for the focus ring and the checks. */
.hero-cta-row { align-items: center; }

/* Two equal columns either side of the 140px gap, so the gap – where the
   «Листайте» cue sits – stays on the page's centre line although the two
   actions now differ in width. Phones keep the wrapping row (≤ 900px). */
@media (min-width: 901px) {
  .hero-cta-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 140px;
  }
  .hero-cta-row .hero-cta-primary { justify-self: end; }
  .hero-cta-row .hero-cta:not(.hero-cta-primary) { justify-self: start; }
}

.hero-scroll {
  position: absolute;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  opacity: 0;
  animation: fadeIn 1.2s ease-out 1.8s forwards;
  z-index: 3;
}

.hero-scroll-label {
  font-family: var(--sans);
  font-size: 0.6rem;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  /* 0.75, not 0.65: on the recalculated gradient the label measured 4.53:1 —
     a margin of 0.03 over threshold. Raising the label's own alpha fixes it
     without darkening the photograph any further. */
  color: rgba(244, 238, 227, 0.85);
  font-weight: 400;
}

.hero-scroll-line {
  width: 1px;
  height: 48px;
  background: linear-gradient(to bottom,
    rgba(244, 238, 227, 0.6),
    rgba(244, 238, 227, 0)
  );
  animation: scrollPulse 2.4s ease-in-out infinite;
}

@keyframes scrollPulse {
  0%, 100% { transform: scaleY(1);   transform-origin: top; }
  50%      { transform: scaleY(0.4); transform-origin: top; }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (max-width: 900px) {
  /* 104px, not 84: the mobile header is 80px tall with the ASTER wordmark in it,
     and 84 left a 4px gap that read as a collision. */
  .hero-inner    { padding: 104px 20px 28px; }
  .hero-title    { margin-bottom: 24px; }
  .hero-tagline  { margin-bottom: 40px; }
  .hero-cta-row  { gap: 12px 28px; }
  .hero-eyebrow  { font-size: 0.6rem; letter-spacing: 0.22em; }
  .hero-scroll   { display: none; }

  /* Phones: the lower scrim starts earlier. On a phone the title sits at
     55–82% of the hero (measured on 360–414px screens), higher than on a
     computer, and its top edge fell where the scrim was still light. With the
     slow zoom to 106% the Russian title came down to 3.10 against 3.0 — a
     0.10 margin; Jun asked for at least 0.3 in every frame (2026-09-29).
     The building in the middle keeps the desktop's light band. */
  .hero-overlay {
    background: linear-gradient(
      to bottom,
      rgba(12, 11, 11, 0.64) 0%,
      rgba(12, 11, 11, 0.63) 20%,
      rgba(12, 11, 11, 0.20) 34%,
      rgba(12, 11, 11, 0.22) 44%,
      rgba(12, 11, 11, 0.42) 54%,
      rgba(12, 11, 11, 0.58) 64%,
      rgba(12, 11, 11, 0.66) 80%,
      rgba(12, 11, 11, 0.68) 100%
    );
  }
}

/* ============================================================
   ABOUT SECTION
   ============================================================ */
.about {
  background: var(--cream);
  padding: 80px 52px;
  min-height: 100vh;
  display: flex;
  align-items: center;
}

.about-inner {
  max-width: 1400px;
  margin: 0 auto;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: center;
}

/* Ratio taken from the photograph itself: about-lobby.jpg is 1600×971.

   It used to be 4/5 — a portrait frame holding a landscape photograph, so
   `cover` scaled to fill and discarded 51% of the picture. Half the lobby was
   cropped away by the browser, with nobody choosing which half.

   Decided 2026-09-08: these are the only originals that exist, there is no
   reshoot, and outpainting was ruled out because inventing interior detail that
   the hotel does not have belongs to the same category as an unverified claim in
   the copy. So the layout follows the photograph instead of the other way round.

   Change this ratio only alongside the file. */
.about-photo-wrap {
  position: relative;
  aspect-ratio: 1600 / 971;
  overflow: hidden;
}

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

.about-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.2rem, 3.6vw, 3.2rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: var(--ink);
  margin-bottom: 28px;
}

.about-title em {
  font-style: italic;
  color: var(--brass);
}

.about-text {
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.75;
  color: rgba(43, 27, 24, 0.72);
  font-weight: 300;
  margin-bottom: 16px;
}

.about-text strong {
  font-weight: 500;
  color: var(--ink);
}

.about-text em {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  color: var(--brass);
  font-size: 1.05rem;
}

.about-recognition {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px solid rgba(168, 137, 87, 0.22);
}

.about-recognition-label {
  font-family: var(--sans);
  font-size: 0.65rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--oxblood);
  font-weight: 500;
  margin-bottom: 12px;
}

.about-recognition-list {
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.9rem;
  line-height: 1.6;
  color: rgba(43, 27, 24, 0.68);
  font-weight: 400;
}

.about-recognition-list strong {
  font-style: normal;
  font-weight: 500;
  color: var(--ink);
}

.about-iso {
  margin-top: 14px;
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}

.about-iso-label {
  font-family: var(--sans);
  font-size: 0.62rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: rgba(43, 27, 24, 0.65);
  font-weight: 500;
}

.about-iso-list {
  font-family: var(--sans);
  font-size: 0.78rem;
  color: rgba(43, 27, 24, 0.65);
  font-weight: 400;
  letter-spacing: 0.06em;
}

@media (max-width: 900px) {
  .about       { padding: 60px 24px; min-height: auto; }
  .about-inner { grid-template-columns: 1fr; gap: 40px; }
  /* Same ratio as desktop — it is the photograph's own, and the photograph does
     not change shape on a phone. Was 4/3 here, which cropped 19%. */
  .about-photo-wrap { aspect-ratio: 1600 / 971; }
  /* Noto Serif Display is wider than the Times that stood in for Russian before
     2026-10-07: at 35px «Добро пожаловать в» is 366px and broke as «…пожаловать /
     в» on phones (Jun). The size now follows the column (100vw − 48px of padding;
     the line is 10.4× the font size), so the first line always fits. The &nbsp;
     before «в» in the markup keeps the preposition with its word in any case. */
  html:lang(ru) .about-title { font-size: min(2.2rem, calc((100vw - 48px) / 10.6)); }
}

/* ============================================================
   ROOMS SECTION
   ============================================================ */
.rooms {
  min-height: 100vh;
  padding: 120px 52px;
  display: flex;
  align-items: center;
  /* The fanned room cards are positioned with fixed translate() offsets, and on
     a 390px screen the widest of them reaches 5px past the viewport, giving the
     whole page a horizontal scrollbar. Pre-existing — the offsets are in px and
     owe nothing to the typeface; it simply went unnoticed until the mobile pass.
     `clip` rather than `hidden`: it stops the overflow without turning the
     section into a scroll container. `hidden` first for browsers without clip. */
  overflow-x: hidden;
  overflow-x: clip;
}

.rooms-inner {
  max-width: 1400px;
  margin: 0 auto;
  width: 100%;
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 80px;
  align-items: center;
}

/* One frame, four photographs, four different shapes — 1.728, 1.756, 1.989 and
   2.013. They cross-fade in place, so the frame cannot resize per room without
   the whole section jumping every time a guest moves between categories.

   1.865 is the geometric mean of the narrowest and the widest, which is the
   single ratio that minimises the worst case. Crop falls from 23–34% to 6–7%,
   spread evenly rather than punishing the two wide ones.

   Was 4/3 (1.333), a ratio belonging to none of the four. Recalculate this
   number if any room photograph is replaced. */
.rooms-stack {
  position: relative;
  aspect-ratio: 1.865;
  width: 100%;
}

.room-photo {
  position: absolute;
  inset: 0;
  overflow: hidden;
  transition: opacity 0.5s ease;
  box-shadow: 0 30px 60px rgba(43, 27, 24, 0.25);
}

.room-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.room-photo[data-room="deluxe"] {
  transform: translate(0, 0) rotate(-1.5deg) scale(1);
  z-index: 4;
  opacity: 0.55;
}
.room-photo[data-room="family"] {
  transform: translate(-28px, 22px) rotate(4deg) scale(0.94);
  z-index: 3;
  opacity: 0.35;
}
.room-photo[data-room="double"] {
  transform: translate(36px, -18px) rotate(-5deg) scale(0.92);
  z-index: 2;
  opacity: 0.2;
}
.room-photo[data-room="twin"] {
  transform: translate(-14px, -32px) rotate(2.5deg) scale(0.88);
  z-index: 1;
  opacity: 0.15;
}

.room-photo.active {
  opacity: 1 !important;
  z-index: 10 !important;
}

.rooms-content {
  padding-left: 40px;
}

.rooms-eyebrow {
  font-size: 0.7rem;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  color: var(--oxblood);
  margin-bottom: 24px;
  font-weight: 400;
}

.rooms-title {
  font-family: var(--serif);
  font-size: clamp(2.2rem, 3.5vw, 3rem);
  font-weight: 400;
  line-height: 1.05;
  color: var(--ink);
  margin-bottom: 56px;
  letter-spacing: -0.01em;
}

.rooms-title em {
  font-style: italic;
  color: var(--brass);
}

.rooms-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.room-item {
  position: relative;
  border-bottom: 1px solid rgba(168, 137, 87, 0.15);
}

/* The row header is a real <button>: native keyboard, focus and semantics */
.room-item-head {
  position: relative; /* anchors the ::before marker to the title row */
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 20px;
  width: 100%;
  padding: 22px 0;
  background: none;
  border: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.room-item-head:focus-visible {
  outline: 1px solid var(--oxblood);
  outline-offset: 4px;
}

.room-item:first-child {
  border-top: 1px solid rgba(168, 137, 87, 0.15);
}

.room-item-name {
  font-family: var(--serif);
  font-size: 1.6rem;
  font-weight: 400;
  color: rgba(43, 27, 24, 0.65);
  letter-spacing: -0.01em;
  transition: color 0.4s ease, transform 0.4s ease;
  line-height: 1;
}

.room-item-meta {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(43, 27, 24, 0.65);
  transition: color 0.4s ease, opacity 0.4s ease;
}

.room-item.active .room-item-name,
.room-item:hover .room-item-name {
  color: var(--ink);
  transform: translateX(16px);
}

.room-item.active .room-item-meta,
.room-item:hover .room-item-meta {
  color: var(--oxblood);
}

.room-item-head::before {
  content: '';
  position: absolute;
  left: -4px;
  top: 50%;
  width: 0;
  height: 1px;
  background: var(--oxblood);
  transform: translateY(-50%);
  transition: width 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.room-item.active .room-item-head::before,
.room-item:hover .room-item-head::before {
  width: 12px;
}

.room-item-details {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  visibility: hidden; /* also takes the Reserve button out of the tab order */
  overflow: hidden;
  transition: grid-template-rows 0.5s ease, opacity 0.4s ease, visibility 0.4s,
              margin 0.4s ease;
  margin-top: 0;
}

.room-item-details-inner {
  min-height: 0; /* lets the grid row clip its own content */
}

.room-item.active .room-item-details {
  grid-template-rows: 1fr;
  opacity: 1;
  visibility: visible;
  margin-top: 16px;
}

.room-description {
  font-size: 0.88rem;
  line-height: 1.75;
  color: rgba(43, 27, 24, 0.65);
  margin-bottom: 16px;
  max-width: 480px;
}

.room-details-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  /* The 54px Select Room button (2026-10-14) no longer fits beside the rate
     note on a narrow phone; it drops under it instead of leaving the screen. */
  gap: 16px 24px;
  /* Room under the 54px button before the card's hairline */
  padding-bottom: 24px;
}

/* Short factual line under each description — what differs by category */
.room-spec {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(43, 27, 24, 0.65);
  margin-bottom: 18px;
}

/* Sits where the price used to. Rates are deliberately not published:
   they move with season and currency, and a room card carrying no rate
   reads as restraint rather than omission. The Bnovo widget takes this
   slot at Stage 8. */
.room-rate-note {
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(43, 27, 24, 0.65);
}

/* Select Room: .btn-primary (shared.css, BUTTONS) */
.room-reserve-btn { flex: none; }

/* The shared standard, stated once rather than repeated in all four cards */
.rooms-standard {
  margin-top: 40px;
  padding-top: 24px;
  /* No border here. Every .room-item already carries a border-bottom, so the
     last one draws a line directly above this block; a border-top added a
     second, parallel line 64px below the first. Spacing separates it. */
}

.rooms-standard-label {
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--oxblood);
  font-weight: 500;
  margin-bottom: 14px;
}

.rooms-standard-list {
  font-size: 0.82rem;
  line-height: 1.9;
  color: rgba(43, 27, 24, 0.65);
  max-width: 520px;
}

@media (max-width: 900px) {
  .rooms       { min-height: 100vh; padding: 60px 24px; }
  .rooms-standard { margin-top: 32px; }
  .rooms-inner { grid-template-columns: 1fr; gap: 40px; }
  .rooms-content { padding-left: 0; }
  .room-item-name { font-size: 1.3rem; }
  /* The fanned cards behind (translated 36px, turned 5°) ran 4–5px past the
     screen edge on phones (tools/checks/geometry.py, 2026-10-10). */
  .rooms-stack { width: calc(100% - 28px); margin: 0 auto; }
}

/* ============================================================
   LOCATION SECTION
   ============================================================ */
.location {
  background: var(--cream);
  padding: 140px 52px 120px;
}

.location-inner {
  max-width: 1400px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 100px;
  align-items: center;
}

.location-eyebrow {
  font-size: 0.78rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--oxblood);
  font-weight: 500;
  margin-bottom: 20px;
}

.location-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.4rem, 4vw, 3.4rem);
  line-height: 1.05;
  letter-spacing: 0.01em;
  color: var(--ink);
  margin-bottom: 32px;
}

.location-title em {
  font-style: italic;
  color: var(--brass);
}

.location-desc {
  font-size: 1rem;
  line-height: 1.8;
  color: rgba(43, 27, 24, 0.65);
  margin-bottom: 48px;
  max-width: 480px;
}

.location-details {
  display: flex;
  flex-direction: column;
  gap: 28px;
  margin-bottom: 48px;
}

.location-detail {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  padding-bottom: 24px;
  border-bottom: 1px solid rgba(168, 137, 87, 0.18);
}

.location-detail:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.location-detail-icon {
  color: var(--oxblood);
  font-size: 1rem;
  min-width: 22px;
  padding-top: 4px;
}

.location-detail-text {
  flex: 1;
}

.location-detail-label {
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--oxblood);
  font-weight: 500;
  margin-bottom: 6px;
}

.location-detail-main {
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  font-weight: 400;
}

.location-detail-sub {
  display: block;
  font-size: 0.82rem;
  color: rgba(43, 27, 24, 0.65);
  margin-top: 4px;
  line-height: 1.5;
}

.location-btn {
  /* Directions: .btn-outline (shared.css, BUTTONS) – a secondary action;
     booking is the page's primary. */
}

.location-map {
  aspect-ratio: 4 / 5;
  overflow: hidden;
  /* Dusted Rose at low alpha, not at full strength. The brandbook calls it a
     "мягкий дополнительный фон" — soft. This sits behind the map iframe and is
     only visible while the map loads; the token it replaced was a barely-there
     off-white, and the brand colour undiluted turned that into a pink flash. */
  background: rgba(201, 154, 139, 0.28);
  position: relative;
}

.gmap-iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.brand-pin {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -100%);
  pointer-events: auto;
  text-decoration: none;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
}

.brand-pin-label {
  font-family: var(--brand-serif);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink);
  background: var(--cream);
  padding: 6px 14px;
  border-radius: 4px;
  box-shadow: 0 4px 14px rgba(43, 27, 24, 0.18);
  white-space: nowrap;
  margin-bottom: 10px;
  border: 1px solid rgba(90, 23, 32, 0.25);
  letter-spacing: 0.01em;
  transition: transform 0.3s ease;
}

.brand-pin:hover .brand-pin-label {
  transform: translateY(-2px);
}

.brand-pin-dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--oxblood);
  border: 3px solid var(--cream);
  box-shadow: 0 4px 14px rgba(90, 23, 32, 0.6);
  position: relative;
  z-index: 2;
}

.brand-pin-pulse {
  position: absolute;
  bottom: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--oxblood);
  animation: brandPulse 2s ease-out infinite;
  z-index: 1;
}

@keyframes brandPulse {
  0%   { transform: scale(1);   opacity: 0.7; }
  100% { transform: scale(3.5); opacity: 0; }
}

@media (max-width: 900px) {
  .location { padding: 80px 24px; }
  .location-inner {
    grid-template-columns: 1fr;
    gap: 48px;
  }
  .location-map {
    aspect-ratio: 4 / 3;
  }
}

/* ---------- The Dining motion on the home page (Jun, 2026-10-08) ----------
   About, Rooms and Location: photos open from the sand pill (data-plate),
   titles arrive line by line (data-lines), a hairline is drawn above each
   section (data-rule). The first screen and the rooms switching are as before. */
.about,
.rooms,
.location {
  position: relative;
  /* A menu link stops with the hairline 24px under the header, on every screen.
     The section itself starts --rule-top above its hairline, so a stop at the
     section's top left the line 56px down on a computer and read as "too low"
     (Jun, 2026-10-11). Lenis and a native jump both honour scroll-margin. */
  --rule-top: 56px;
  scroll-margin-top: calc(24px - var(--rule-top));
}

.home-rule {
  position: absolute;
  top: var(--rule-top);
  left: max(52px, calc((100vw - 1400px) / 2));
  right: max(52px, calc((100vw - 1400px) / 2));
  height: 1px;
  background: rgba(168, 137, 87, 0.4);
}

/* The pin appears once the map under it has loaded (motion.js). A keyboard
   focus still shows it at once. */
.location-map .brand-pin {
  transition: opacity 0.6s var(--ease-soft);
}

.location-map.is-map-loading .brand-pin {
  opacity: 0;
  pointer-events: none;
}

.location-map.is-map-loading .brand-pin:focus-visible {
  opacity: 1;
}

@media (max-width: 900px) {
  .about,
  .rooms,
  .location {
    --rule-top: 28px;
  }

  .home-rule {
    left: 24px;
    right: 24px;
  }
}
