﻿/* =====================================================
   BOTTLE - FIXED SCROLL ELEMENT
   ===================================================== */

/**
 * The bottle lives outside the page flow.
 * JS drives transform (rotate + translateY) via inline style.
 * pointer-events: none so clicks pass through to content below.
 */
.bottle-fixed {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(20deg);
  height: 60vh;
  width: auto;
  max-width: 60vw;
  object-fit: contain;
  pointer-events: none;
  z-index: 10;
}

/* Overlay helper for bottle mouse events */
.bottle-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 60vh;
  width: 60vw;
  z-index: 100;
  cursor: grab;
  background: transparent;
  filter: drop-shadow(0 8px 32px rgba(0,0,0,0.18));
  will-change: transform;
}

/* =====================================================
   BOTTLE STAGE – 8-BOTTLE OVERVIEW / SELECTED SYSTEM
   ===================================================== */

/**
 * Full-viewport fixed layer. Items are positioned absolutely,
 * so showing or hiding any item has zero effect on the others.
 * pointer-events: none on the stage; restored per-item.
 */
.bottle-stage {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 20; /* above .page-content (z-index: 20); below arrows (50) and logo/nav (100) */
  pointer-events: none;
}

/* ── Individual bottle item ────────────────────────── */

/**
 * Each item sits at a fixed left position (CSS var --item-left
 * computed per-item by buildBottles() in main.js).
 * The bottleFloat keyframe embeds translate(-50%,-50%) so the
 * animation itself handles centring — sibling visibility never
 * influences this element's rendered position.
 * The `left` transition produces the smooth fly-back on showOverview().
 */
.bottle-item {
  position: absolute;
  top: var(--bottles-top, 50%);
  left: var(--item-left, 50%);
  cursor: pointer;
  pointer-events: auto;
  transition:
    left    0.55s ease,
    opacity var(--transition-medium),
    filter  var(--transition-medium),
    transform 0.3s cubic-bezier(0.4,0,0.2,1);
  animation: bottleFloat 3s ease-in-out infinite backwards;
  will-change: transform;
  transform: translate(-50%, -50%) scale(1);
  transform-origin: center center;
  z-index: 10;
}

.bottle-item:not(.is-selected) {
  transform-origin: center center;
  z-index: 30;
}

/*
 * Negative delays tell the browser the animation has already been running
 * for that duration, so items render at their mid-cycle position on the
 * very first paint — no 40-px jump. `animation-fill-mode: backwards`
 * ensures even the zero-delay item starts at the 0 % keyframe state.
 */
.bottle-item:nth-child(1) { animation-delay: -0.00s; }
.bottle-item:nth-child(2) { animation-delay: -0.35s; }
.bottle-item:nth-child(3) { animation-delay: -0.70s; }
.bottle-item:nth-child(4) { animation-delay: -1.05s; }
.bottle-item:nth-child(5) { animation-delay: -1.40s; }
.bottle-item:nth-child(6) { animation-delay: -1.75s; }
.bottle-item:nth-child(7) { animation-delay: -2.10s; }
.bottle-item:nth-child(8) { animation-delay: -2.45s; }

/**
 * Centering translate is baked into the keyframes. Because the
 * animation owns the transform, no separate centering is needed,
 * and the absolute `left` value is the only layout dependency.
 */
@keyframes bottleFloat {
  0%, 100% { transform: translate(-50%, -50%); }
  50%      { transform: translate(-50%, calc(-50% - 1.5vh)); }
}

/* Smooth top transition when bottles shift toward top on scroll */
.bottle-stage {
  transition: none;
}

/* ── Carousel mode (see carousel.css) ────────────── */

.bottle-item img {
  height: clamp(19.5vh, 22.5vw, 30vh);
  width: auto;
  display: block;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  /* smooth size change when entering / leaving selected state */
  transition: height var(--transition-medium);
  z-index: 100;
  position: relative;
}

/* ── Selected state ────────────────────────────────── */

/**
 * CSS transition on `left` (inherited from .bottle-item) slides
 * the bottle to centre on both enter AND leave — no JS needed.
 * animation: none frees transform for JS-driven float + scroll.
 */
.bottle-item.is-selected {
  /* No transform transition: JS rAF drives the float directly.
     A CSS transform transition would restart on every rAF write,
     causing constant compositor re-targeting — visible as stutter on iOS. */
  transition: left 0.55s ease;
  left: 50%;
  animation: none;
  cursor: default;
  /* Keeps slide-in/out keyframes aligned with selected JS transforms. */
  --rotate: 17deg;
  --scale: 1;
  --selected-y-offset: 0vh;
}

.bottle-item.is-selected img {
  height: 60vh;
  max-width: 60vw;
  object-fit: contain;
}

/* ── Visibility states ─────────────────────────────── */

/**
 * visibility:hidden keeps the item in the stacking context (unlike
 * display:none), so CSS transitions fire correctly when removed.
 */
.bottle-item.is-hidden {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

/**
 * Transient class applied just before is-hidden.
 * Lets the bottle fade out smoothly before disappearing.
 * animation:none ensures no keyframe overrides opacity.
 */
.bottle-item.is-leaving {
  opacity: 0;
  pointer-events: none;
  animation: none;
}

/**
 * Applied to both outgoing and incoming items during arrow / swipe cycling.
 * Suppresses the `left` CSS transition so the position snap is instant
 * and only the transform keyframe animation is seen.
 */
.bottle-item.is-cycling {
  transition: opacity var(--transition-medium), filter var(--transition-medium);
  /* left transition intentionally omitted */
}

/**
 * Applied during an instant bottle swap (hovered circle click in fullscreen).
 * Suppresses ALL transitions on the item and its img so neither the `left`
 * nor the `height` (img) animate — the swap appears completely instantaneous.
 * Removed after one requestAnimationFrame.
 */
.bottle-item.is-instant,
.bottle-item.is-instant img {
  transition: none !important;
}

/**
 * Applied to the selected bottle at the start of showOverview().
 * animation:none prevents the CSS float from fighting the transition.
 * JS sets transform to translate(-50%,-50%) so the bottle eases back
 * to its neutral position before the CSS animation takes over.
 */
.bottle-item.is-returning {
  animation: none;
  transition: transform 0.35s ease, left 0.55s ease;
}

/* ── Fly-out (overview → selected) ────────────────── */

/**
 * Non-chosen bottles fly radially outward with scale + blur.
 * JS sets --fly-x to ±130vw before adding this class.
 * The 0% keyframe matches bottleFloat's resting position exactly
 * so there is no transform jump at animation start.
 */
@keyframes flyOut {
  0%   {
    transform: translate(-50%, -50%)                             scale(1);
    filter:    blur(0px);
    opacity:   1;
  }
  100% {
    transform: translate(calc(-50% + var(--fly-x, 130vw)), -50%) scale(2.5);
    filter:    blur(24px);
    opacity:   0;
  }
}

.bottle-item.is-flying-out {
  animation: flyOut 0.45s cubic-bezier(0.4, 0, 1, 1) forwards;
  pointer-events: none;
}

/* ── Slide animations (arrow / swipe cycling) ───────── */

/**
 * All four keyframes keep the current selected y-offset and scale as the
 * baseline, so there is no reset frame when fullscreen bottles are swapped.
 * ±120vw guarantees off-screen exit/entry on any screen width.
 */
@keyframes slideOutLeft  {
  from { transform: translate(-50%, calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 1; }
  to   { transform: translate(calc(-50% - 120vw), calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 0; }
}
@keyframes slideOutRight {
  from { transform: translate(-50%, calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 1; }
  to   { transform: translate(calc(-50% + 120vw), calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 0; }
}
@keyframes slideInFromLeft {
  from { transform: translate(calc(-50% - 120vw), calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 0; }
  to   { transform: translate(-50%, calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 1; }
}
@keyframes slideInFromRight {
  from { transform: translate(calc(-50% + 120vw), calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 0; }
  to   { transform: translate(-50%, calc(-50% + var(--selected-y-offset, 0vh))) rotate(var(--rotate, 17deg)) scale(var(--scale, 1)); opacity: 1; }
}

/* Selectors come after .bottle-item.is-selected in the sheet, so
   same specificity but later order — animation wins over `animation: none`. */
.bottle-item.is-sliding-out-left  { animation: slideOutLeft     0.38s ease-in  forwards; pointer-events: none; }
.bottle-item.is-sliding-out-right { animation: slideOutRight    0.38s ease-in  forwards; pointer-events: none; }
.bottle-item.is-sliding-in-left   { animation: slideInFromLeft  0.40s ease-out forwards; }
.bottle-item.is-sliding-in-right  { animation: slideInFromRight 0.40s ease-out forwards; }

/* =====================================================
   BOTTLE ARROWS  (arrow cycling, left / right edge)
   ===================================================== */

.bottle-arrow {
  position: fixed;
  top: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(44px, 6vw, 72px);
  height: clamp(44px, 6vw, 72px);
  aspect-ratio: 1 / 1;
  transform: translateY(-50%);
  z-index: 50;
  background: transparent;
  border: none;
  border-radius: var(--radius-m);
  cursor: pointer;
  color: var(--ci-highlight-color);
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 0;
  padding: 0 0 0.1em 0; /* compensate for Bahnschrift optical baseline offset */
  opacity: 0.75;
  transition:
    opacity     var(--transition-fast),
    color       var(--transition-medium);
  user-select: none;
}

.bottle-arrow:hover { opacity: 1; }

.bottle-arrow--left  { left:  var(--spacing-s); }
.bottle-arrow--right { right: var(--spacing-s); }

/* native [hidden] — ensure display: none even with specificity battles */
.bottle-arrow[hidden] { display: none !important; }

/* Shop CTA button – fixed, above the bottles, visible in selected mode only */
.shop-btn {
  position: fixed;
  top: calc(var(--spacing-m) + 80px); /* below the logo */
  left: 50%;
  transform: translateX(-50%);
  z-index: 40; /* above bottle-stage (25), below arrows (50) */
  white-space: nowrap;
}

.shop-btn[hidden] { display: none !important; }

