/* Photo stage — a single centred print on paper.
 *
 * Layout rule taken from the reference: the image sits in a fixed centred
 * box and is *contained* in it, so a portrait fills the box height and a
 * landscape fills its width. That yields the characteristic "constant
 * height, variable width" rhythm as photos swap, with no layout shift —
 * the box never changes size, only the picture inside it.
 *
 * The swap itself is instantaneous, not a crossfade. Two layers exist only
 * so a decoded image is always ready to show; they are never animated.
 */

.stage {
  position: relative;
  display: grid;
  /* A single full-height row, so the photo box can size against it with
     height:100% while still being centred inside it. */
  grid-template-rows: 1fr;
  place-items: center;
  width: 100%;
  height: 100vh;
  height: 100svh; /* accounts for mobile browser chrome */
  overflow: hidden;
  /* Mobile : le doigt pilote la scène (swap au glissement) — aucun scroll ni
     zoom de page ne se déclenche depuis la scène, sur les deux axes. */
  touch-action: none;
  overscroll-behavior: none;
  background-color: var(--c-paper);

  /* Safe zone. The brand mark occupies the top band and the fixed bottom bar
     the lower one; the photo is confined to what remains, so it can never
     touch or pass under either. */
  --safe-top: 7rem;
  --safe-bottom: 6.5rem;
  padding-top: var(--safe-top);
  padding-bottom: var(--safe-bottom);
}

/* L'accueil est une scène plein écran : on verrouille tout défilement du
   document (rebond iOS compris), dans les deux axes. Ciblé par la classe posée
   sur le <body> d'index.html, donc sans effet sur les autres pages. */
body.home {
  overflow: hidden;
  overscroll-behavior: none;
}

/* The fixed box every photo is fitted into: exactly the safe zone, so the
 * tallest possible portrait still clears the chrome at both ends. Because
 * photos are *contained*, a portrait fills the height and a landscape fills
 * the width — the box itself never changes size, so nothing shifts on swap. */
.stage__viewport {
  position: relative;
  width: min(52vw, 900px);
  /* Fills the safe zone, whatever height the stage has been given — the
     homepage now shares the viewport with a footer, so this can't be
     measured against 100svh. */
  height: 100%;
  /* The heroes aren't a link and shouldn't invite a save — no hand cursor. */
  cursor: default;
  /* Hidden until the first photo has decoded, so no empty box flashes. */
  opacity: 0;
  transition: opacity var(--d-base) var(--ease-out);
}

.stage__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  /* Discourage casual copying: no drag-to-save, no selection. Pointer events
     pass through to the stage so the pointer-driven swap still works. */
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
}

.stage__layer[data-active='true'] {
  opacity: 1;
}

.stage[data-ready='true'] .stage__viewport {
  opacity: 1;
}

/* --- Chrome ----------------------------------------------------------- */

.stage__chrome {
  position: absolute;
  inset: 0;
  z-index: var(--z-chrome);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--gutter);
  pointer-events: none;
}

.stage__chrome a,
.stage__chrome button {
  pointer-events: auto;
}

.stage__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-5);
}

/* Caption of the current photo. Kept minimal: the reference shows none, but
   this is a shop — the title and entry price are the reason to click. */
.stage__caption {
  font-size: var(--t-sm);
  min-height: 1.4em;
}

.stage__caption-title {
  font-weight: 500;
}

.stage__caption-location,
.stage__caption-price {
  color: var(--c-muted);
}

/* --- Small screens ----------------------------------------------------- */

@media (max-width: 820px) {
  .stage {
    --safe-top: 5rem;
    --safe-bottom: 5.5rem;
  }
  .stage__viewport {
    width: min(86vw, 560px);
  }
  .stage__foot {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s-2);
  }
}

@media (hover: none) {
  .stage__viewport { cursor: default; }
}
