/* =====================================================
   Home flow v3: the opening (velvet at first paint, the
   seal as the Play button, its hint), the stops' cues,
   the map hint and district cards, the stage inset.
   Film on (html.film-on, not .reduced): text the film
   already shows is .film-copy (visually hidden, still in
   the DOM: the H1 and the hero text too). No JS, reduced
   motion or a failed boot: everything in flow.
   ===================================================== */
.sr,
.film-on:not(.reduced) .film-copy,
.film-on:not(.reduced) .film-copy-inline,
.film-on:not(.reduced) .seal-play__label {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* the page scrolls only in the free-scroll phase (and without the film).
   The root alone carries the lock (it is the viewport's): a hidden body
   would become its own clip box and break the sticky FAQ card at a stop */
html.js:not(.reduced):not(.film-failed):not(.phase-scroll),
html.scroll-locked {
  overflow: hidden;
  overscroll-behavior: none;
}

/* ---- first paint: velvet at once, never a black wait --------------------
   Until the film boots (fonts, baked textures, scene builds) the stage shows
   the r1 velvet as plain CSS (the same tile and vignette, tex/), and the
   page text waits hidden; the film fades in over it at its first frame. */
html.js:not(.reduced) #film {
  background:
    radial-gradient(120% 95% at 50% 45%, rgba(20, 0, 2, 0) 40%, rgba(20, 0, 2, 0.55) 100%),
    url("../tex/velvet-23-512-lvmyjm.jpg") 50% 50% / max(26.667vw, 47.407vh) repeat,
    #561014;
}

html.js.is-portrait:not(.reduced) #film {
  background-size: 100% 100%, max(47.407vw, 26.667vh), auto;
}

html.js:not(.reduced) #stage {
  background: transparent;
}

/* the engine's opening fade would be a black frame: the velvet is already there */
html.js #fade {
  display: none;
}

html.js:not(.reduced) #scenes,
html.js:not(.reduced) #fx {
  opacity: 0;
}

html.film-on:not(.reduced) #scenes,
html.film-on:not(.reduced) #fx {
  opacity: 1;
  transition: opacity 0.35s ease;
}

html.js:not(.film-on):not(.reduced):not(.film-failed) :is(#main, #contact, #ui) {
  visibility: hidden;
}

/* CLS fix: once html.film-on is set, the zones sit in the flow at their natural
   height until lib/home-layout.js gives each one its scroll height (an inline
   height) a few frames later, and every section then jumps down the page. For
   about two frames the reviews and FAQ cards flash over the opening, and Chrome
   counts the jump as a layout shift of about 1.0.
   Until a zone has its inline height it is hidden with visibility only: layout
   and offsetHeight stay as they are, so the measuring in home-layout.js is not
   affected. Reduced motion (.reduced) and a failed boot (film-on is removed)
   never match this rule. */
html.film-on:not(.reduced) .zone:not([style*="height"]) {
  visibility: hidden;
}

/* ---- the opening: the seal is the Play button ----------------------------- */
.film-on:not(.reduced) .start {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
}

.start {
  padding: 120px 16px 48px;
  text-align: center;
  color: var(--pearl);
}

.start h1 {
  font: 400 clamp(34px, 5vw, 64px) / 1.08 var(--ff-display);
  letter-spacing: 0.04em;
  color: var(--gold-hi);
}

.seal-play {
  display: inline-block;
  margin-top: 24px;
  padding: 12px 30px;
  border-radius: 999px;
  font: 500 14px/1 var(--ff-sans);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--wine-deep);
  background: linear-gradient(180deg, #fff4cf, #d3b875);
}

/* film on: an invisible round hit area on the film's seal (home-ui.js sizes
   and places it); the film itself draws "PLAY" glowing in the seal */
.film-on:not(.reduced) .seal-play {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 6;
  width: 120px;
  height: 120px;
  margin: 0;
  padding: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  visibility: hidden;
  pointer-events: none;
  -webkit-tap-highlight-color: transparent;
}

.film-on:not(.reduced).phase-open .seal-play {
  visibility: visible;
  pointer-events: auto;
}

.film-on:not(.reduced) .seal-play:focus-visible {
  outline: 2px solid var(--gold-hi);
  outline-offset: 6px;
}

/* "Press Play to start": a quiet line under the lockup, between two hairlines */
.playhint {
  position: absolute;
  left: 50%;
  top: 0;
  display: flex;
  align-items: center;
  gap: 16px;
  transform: translate3d(-50%, 78vh, 0);
  white-space: nowrap;
  font: italic 500 clamp(18px, 1.5vw, 23px) / 1.2 var(--ff-serif);
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--champagne);
  text-shadow: 0 1px 14px rgba(20, 2, 4, 0.7);
  opacity: 0;
  transition: opacity 0.45s ease;
}

.playhint i {
  width: clamp(28px, 4vw, 54px);
  height: 1px;
  background: linear-gradient(90deg, rgba(211, 193, 129, 0), rgba(239, 226, 176, 0.9));
}

.playhint i:last-child {
  transform: scaleX(-1);
}

.phase-open .playhint {
  opacity: 1;
  transition: opacity 0.9s ease 0.15s;
}

/* ---- the "Scroll" cue: every stop. Big enough to read at a glance, it bobs
   gently and its glow breathes (transform and opacity only) --------------- */
#ui {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
}

.cue {
  position: absolute;
  left: 50%;
  bottom: 28px;
  display: grid;
  justify-items: center;
  gap: 10px;
  transform: translate(-50%, 10px);
  font: 500 15px/1 var(--ff-sans);
  letter-spacing: 0.42em;
  padding-left: 0.42em;
  text-transform: uppercase;
  color: var(--gold-hi);
  text-shadow: 0 1px 10px rgba(20, 2, 4, 0.55);
  opacity: 0;
  transition: opacity 0.5s ease, transform 0.5s ease;
}

/* site.css shows the legacy cue as a block pinned by its top */
.film-on:not(.reduced) #cue {
  display: grid;
  top: auto;
}

.cue.is-on {
  opacity: 1;
  transform: translate(-50%, 0);
}

.cue.is-on > * {
  animation: cue-bob 2.2s ease-in-out infinite;
}

/* a soft glow that breathes behind the word */
.cue::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 190px;
  height: 120px;
  margin: -60px 0 0 -95px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(239, 226, 176, 0.32), rgba(239, 226, 176, 0));
  z-index: -1;
}

/* the cue animates only while it shows */
.cue.is-on::before {
  animation: cue-glow 2.2s ease-in-out infinite;
}

.cue.is-on .cue__mouse i {
  animation: cue-wheel 2.2s ease-in-out infinite;
}

/* a mouse outline with its wheel dot rolling down; touch screens: a chevron */
.cue__mouse {
  position: relative;
  width: 24px;
  height: 38px;
  border: 1.5px solid currentColor;
  border-radius: 13px;
}

.cue__mouse i {
  position: absolute;
  left: 50%;
  top: 7px;
  width: 3px;
  height: 7px;
  margin-left: -1.5px;
  border-radius: 2px;
  background: currentColor;
}

@media (hover: none) {
  .cue__mouse {
    width: 20px;
    height: 20px;
    border: 0;
    border-radius: 0;
  }

  .cue__mouse::before,
  .cue__mouse::after {
    content: "";
    position: absolute;
    left: 3px;
    width: 12px;
    height: 12px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
  }

  .cue__mouse::before {
    top: -4px;
    opacity: 0.45;
  }

  .cue__mouse::after {
    top: 4px;
  }

  .cue__mouse i {
    display: none;
  }
}

[data-tone="light"] .cue {
  color: #6f5626;
  text-shadow: 0 1px 10px rgba(255, 250, 236, 0.8);
}

[data-tone="light"] .cue::before {
  background: radial-gradient(closest-side, rgba(255, 252, 240, 0.75), rgba(255, 252, 240, 0));
}

/* phones: the fixed Book button sits bottom right; the cue rises above it */
@media (max-width: 899px), (orientation: portrait) {
  #cue {
    top: auto; /* site.css pins the legacy cue by its top */
    bottom: calc(max(16px, env(safe-area-inset-bottom)) + 70px);
  }
}

/* the pinned form fills the screen: no cue over its fields */
.book-pinned #cue {
  opacity: 0;
}

/* the up chevron shows only at the pinned form (the page goes on both ways);
   drawn by ::before, since the cue's bob animates the element's transform */
.cue__up {
  display: none;
  position: relative;
  width: 20px;
  height: 14px;
}

.cue__up::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 5px;
  width: 12px;
  height: 12px;
  border-left: 1.5px solid currentColor;
  border-top: 1.5px solid currentColor;
  transform: rotate(45deg);
}

/* phones: over a docked bottom sheet (home-ui.js, html.sheet-up) and at the
   pinned form the cue drops to the foot, left of the Book button, clear of
   the card's text and of the form's fields */
@media (max-width: 899px), (orientation: portrait) {
  .sheet-up #cue,
  .book-pinned #cue {
    bottom: max(12px, env(safe-area-inset-bottom));
  }

  .sheet-up #cue {
    left: calc(50% - 24px); /* left of the Book button (hidden at the pinned form) */
  }

  /* over the wine sheet the cue keeps its velvet colours on a cream scene */
  [data-tone="light"].sheet-up .cue {
    color: var(--gold-hi);
    text-shadow: 0 1px 10px rgba(20, 2, 4, 0.55);
  }

  [data-tone="light"].sheet-up .cue::before {
    background: none;
  }

  .book-pinned #cue.is-on {
    opacity: 1;
  }

  .book-pinned .cue__up {
    display: block;
  }
}

@keyframes cue-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(7px); }
}

@keyframes cue-glow {
  0%, 100% { opacity: 0.35; transform: scale(0.9); }
  50% { opacity: 1; transform: scale(1.08); }
}

@keyframes cue-wheel {
  0% { transform: translateY(0); opacity: 1; }
  70% { transform: translateY(12px); opacity: 0; }
  100% { transform: translateY(0); opacity: 0; }
}

/* ---- map stop: "Hover (Tap) a location to learn more", on the right ------ */
.maphint {
  position: absolute;
  right: max(4vw, 24px);
  top: 50%;
  display: grid;
  justify-items: end;
  gap: 12px;
  max-width: 320px;
  transform: translate3d(12px, -50%, 0);
  text-align: right;
  font: italic 500 clamp(21px, 1.7vw, 27px) / 1.25 var(--ff-serif);
  color: #5e1418;
  opacity: 0;
  transition: opacity 0.4s ease, transform 0.4s ease;
}

/* a gold hairline that draws out over it, and a small pin ring that pulses */
.maphint::before {
  content: "";
  width: 64px;
  height: 1px;
  background: linear-gradient(90deg, rgba(201, 178, 110, 0), #b0904a);
}

.maphint::after {
  content: "";
  position: absolute;
  right: 74px;
  top: -5px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1.5px solid #a8873f;
}

.map-on.phase-stop .maphint::after {
  animation: maphint-ring 2.4s ease-out infinite;
}

.film-on:not(.reduced).map-on.phase-stop .maphint {
  opacity: 1;
  transform: translate3d(0, -50%, 0);
  transition: opacity 0.9s ease 0.2s, transform 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 0.2s;
}

@media (hover: hover) {
  .maphint__tap {
    display: none;
  }
}

@media (hover: none) {
  .maphint__hover {
    display: none;
  }
}

/* phones: on the right over the lake, clear of the pins and the cue */
.is-portrait .maphint {
  right: 16px;
  top: auto;
  bottom: calc(max(16px, env(safe-area-inset-bottom)) + 170px);
  max-width: 58vw;
  transform: translate3d(12px, 0, 0);
  font-size: 19px;
}

.film-on.is-portrait:not(.reduced).map-on.phase-stop .maphint {
  transform: translate3d(0, 0, 0);
}

@keyframes maphint-ring {
  0% { transform: scale(0.6); opacity: 1; }
  80%, 100% { transform: scale(2.2); opacity: 0; }
}

/* ---- map: district hit areas and cards -------------------------------- */
.dhits {
  display: none;
}

/* fixed over the film, inside the map zone (Tab order follows the story) */
.film-on:not(.reduced) .dhits {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  visibility: hidden;
}

.film-on:not(.reduced).map-on .dhits {
  visibility: visible;
}

.dhit {
  position: absolute;
  left: 0;
  top: 0;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  pointer-events: auto;
}

.dhit__ring {
  position: absolute;
  inset: 18%;
  border-radius: 50%;
  border: 1.5px solid rgba(143, 116, 52, 0.0);
  transition: inset 0.3s ease, border-color 0.3s ease, background-color 0.3s ease;
}

.dhit:hover .dhit__ring,
.dhit:focus-visible .dhit__ring,
.dhit.is-active .dhit__ring {
  inset: 0;
  border-color: rgba(143, 116, 52, 0.85);
  background-color: rgba(239, 226, 176, 0.22);
}

.dhit:focus-visible {
  outline: 2px solid #7d6430;
  outline-offset: 3px;
}

.dcards {
  list-style: none;
}

.film-on:not(.reduced) .dcards {
  position: fixed;
  inset: 0;
  z-index: 7;
  pointer-events: none;
}

.dcard {
  max-width: 680px;
  margin: 0 auto 24px;
  padding: 26px 28px 24px;
  border-radius: 6px;
  color: var(--velvet-ink, #efece3);
  background: var(--tex-card-velvet, radial-gradient(120% 90% at 50% 40%, #6b1418, #3e0a0c 70%, #2a0507));
  background-color: #3e0a0c;
  box-shadow: 0 24px 60px rgba(30, 10, 4, 0.35), 0 3px 10px rgba(30, 10, 4, 0.25);
  font: 400 16px/1.6 var(--ff-sans);
}

.dcard h3 {
  font: 400 30px/1.1 var(--ff-display);
  color: var(--gold-hi);
  margin-bottom: 10px;
}

.film-on:not(.reduced) .dcard {
  position: absolute;
  left: 0;
  top: 0;
  width: min(360px, calc(100vw - 32px));
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.28s ease, visibility 0s linear 0.28s;
}

.film-on:not(.reduced) .dcard.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.28s ease;
}

/* phones: the picture sits below the header over cream scenes and the r7
   dial (home-run.js headerInset); the band it leaves matches the paper over
   cream and stays velvet over the dial (a cream band there read as a stray
   white strip under the header) */
#film {
  transition: background-color 0.4s ease;
}

html.js.stage-inset[data-tone="light"] #film {
  background: #ece4d3;
}
