/* ==========================================================================
   bottle-showcase.css — Apex Holding / Greppo Propria
   PURPOSE: the pop-up showcase that assets/js/cinema/bottle-showcase.js opens
   over one product — a full-viewport overlay in which the wine's 3D bottle is
   large, centred, turnable, and buyable.

   LOAD ORDER: AFTER bottle-viewer.css, i.e. LAST. Like every file in the cinema
   layer this is PURELY ADDITIVE: it introduces its own .bshow__* namespace plus
   the [data-bottle-showcase] hook and the one .bshow-open opener button, and it
   overrides no existing rule by name. The rendered bottle inside it is still
   bottle-viewer.js's own .bv__* stage, styled by bottle-viewer.css; this file
   never touches those classes.

   Add it to a page with, after bottle-viewer.css:
     <link rel="stylesheet" href="../assets/css/bottle-showcase.css">
   The module injects this link itself if the page has not, so the two states —
   linked and not — are identical.

   THE ART DIRECTION, in the client's own terms: "a bottle set on a table under a
   single warm lamp, not a product on a white studio sweep." So the ground is a
   deep, softly vignetted pool of candle-amber over cellar-dark, drawn from the
   world's own --w-* tokens; the bottle sits in a pool of light rather than on a
   sweep. bottle-viewer.js lights the glass itself (its warm and cool moods); the
   DOM here only builds the room around it.

   COLOUR comes only from the --w-* semantic tokens and the scale tokens, so the
   showcase takes on whatever world hosts it with no per-world rule in this file.

   RULES OBSERVED
     - Only --w-* semantic tokens and the scale tokens. No raw hex except the
       black scrim wash, which is a shade of the room and not a brand colour.
     - No !important. Interactive targets never smaller than 44px.
     - Transitions animate transform / opacity / colour / box-shadow only.
   ========================================================================== */


/* --------------------------------------------------------------------------
   0. Local tokens
   Namespaced --bshow-* so tokens.css keeps sole ownership of its own names.
   --bshow-dx / --bshow-dy / --bshow-scale are written by the script at open,
   from the card's measured position, and cleared on close.
   -------------------------------------------------------------------------- */

.bshow {
  --bshow-dur-open: 620ms;
  --bshow-dur-close: 420ms;
  --bshow-ease: var(--ease-out-soft, cubic-bezier(0.22, 1, 0.36, 1));
  --bshow-pad: clamp(1rem, 2.5vw, 2.5rem);
  --bshow-panel-w: clamp(19rem, 30vw, 26rem);

  /* The starting transform for the grow-in. Overwritten per open. */
  --bshow-dx: 0px;
  --bshow-dy: 0px;
  --bshow-scale: 0.3;
}


/* --------------------------------------------------------------------------
   1. The overlay
   Fixed to the viewport, above the site header and the panels, below the skip
   link. It is [hidden] between opens, so it costs the page nothing when shut.
   -------------------------------------------------------------------------- */

.bshow {
  position: fixed;
  inset: 0;
  z-index: var(--z-switcher, 500);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--bshow-pad);
}

.bshow[hidden] {
  display: none;
}

/* The wash. A shade of the room, deepened so the lit bottle reads against it. */
.bshow__scrim {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      120% 100% at 50% 42%,
      color-mix(in srgb, var(--w-base, #16171a) 62%, transparent) 0%,
      color-mix(in srgb, var(--w-base, #16171a) 90%, #000) 62%,
      rgba(0, 0, 0, 0.92) 100%
    );
  opacity: 0;
  transition: opacity var(--bshow-dur-open) var(--bshow-ease);
  cursor: pointer;
}

.bshow.is-open .bshow__scrim {
  opacity: 1;
}

.bshow.is-closing .bshow__scrim {
  opacity: 0;
  transition-duration: var(--bshow-dur-close);
}


/* --------------------------------------------------------------------------
   2. The dialog
   A single card holding the stage and the copy. On a wide viewport the stage
   sits left and the copy right; stacked below that.
   -------------------------------------------------------------------------- */

.bshow__dialog {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--bshow-panel-w);
  gap: clamp(1rem, 2vw, 2rem);
  width: min(100%, 74rem);
  max-height: 100%;
  padding: clamp(1rem, 2vw, 1.75rem);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--w-accent, #c9a24b) 26%, var(--w-line, rgba(255, 255, 255, 0.14)));
  border-radius: var(--radius-lg, 20px);
  background:
    radial-gradient(
      100% 70% at 30% 22%,
      color-mix(in srgb, var(--w-accent, #c9a24b) 12%, transparent) 0%,
      transparent 60%
    ),
    linear-gradient(
      to bottom,
      var(--w-surface-2, #1d1f23) 0%,
      var(--w-surface, #16171a) 46%,
      var(--w-base-2, #101114) 100%
    );
  box-shadow: var(--shadow-3, 0 24px 64px -16px rgba(0, 0, 0, 0.6));

  opacity: 0;
  transform: scale(0.94);
  transition:
    opacity var(--bshow-dur-open) var(--bshow-ease),
    transform var(--bshow-dur-open) var(--bshow-ease);
}

/* The grow-in from the card's place. The script measures the card and writes
   the offset and scale; is-entering paints that transformed first frame, and
   is-open releases it so the dialog eases to its own place and size. */
.bshow.is-grown.is-entering .bshow__dialog {
  opacity: 0.4;
  transform: translate(var(--bshow-dx), var(--bshow-dy)) scale(var(--bshow-scale));
  transition: none;
}

.bshow.is-open .bshow__dialog {
  opacity: 1;
  transform: none;
}

.bshow.is-closing .bshow__dialog {
  opacity: 0;
  transition-duration: var(--bshow-dur-close);
}

/* When the open was measured, the close reverses the very same move, so the
   dialog shrinks back toward the card rather than merely fading in place. */
.bshow.is-grown.is-closing .bshow__dialog {
  transform: translate(var(--bshow-dx), var(--bshow-dy)) scale(var(--bshow-scale));
}

@media (max-width: 52rem) {
  .bshow__dialog {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    width: min(100%, 34rem);
  }
}


/* --------------------------------------------------------------------------
   3. The close control
   -------------------------------------------------------------------------- */

.bshow__close {
  position: absolute;
  top: var(--space-3, 0.75rem);
  right: var(--space-3, 0.75rem);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--w-line, rgba(255, 255, 255, 0.14));
  border-radius: var(--radius-pill, 999px);
  background-color: color-mix(in srgb, var(--w-base, #16171a) 70%, transparent);
  color: var(--w-text, #e8e8e8);
  cursor: pointer;
  transition:
    transform var(--dur-micro, 200ms) var(--bshow-ease),
    border-color var(--dur-micro, 200ms) var(--bshow-ease),
    background-color var(--dur-micro, 200ms) var(--bshow-ease);
}

.bshow__close:hover,
.bshow__close:focus-visible {
  transform: scale(1.05);
  border-color: var(--w-accent, #c9a24b);
  background-color: color-mix(in srgb, var(--w-accent, #c9a24b) 16%, var(--w-base, #16171a));
}

.bshow__close:focus-visible {
  outline: 2px solid var(--w-focus, #7cc0ff);
  outline-offset: 2px;
}

.bshow__close .bshow__glyph {
  font-size: 1.5rem;
  line-height: 1;
}


/* --------------------------------------------------------------------------
   4. The stage — the room the bottle stands in
   The pool is a soft floor of light; the mount holds bottle-viewer.js's own
   stage, which fills it. The ghost is the card's borrowed frame, laid over the
   mount for the first instant of the open and faded out on the first live frame.
   -------------------------------------------------------------------------- */

.bshow__stage {
  position: relative;
  min-height: clamp(16rem, 52vh, 34rem);
  border-radius: var(--radius-md, 10px);
  overflow: hidden;
  background:
    radial-gradient(
      120% 90% at 50% 30%,
      color-mix(in srgb, var(--w-surface, #16171a) 70%, transparent) 0%,
      transparent 72%
    ),
    linear-gradient(
      to bottom,
      var(--w-base-2, #101114) 0%,
      var(--w-base, #16171a) 100%
    );
}

/* The pool of light on the floor, low and centred, so the bottle reads as
   standing in it rather than floating. Decorative, behind the bottle. */
.bshow__pool {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(
      42% 24% at 50% 82%,
      color-mix(in srgb, var(--w-accent, #c9a24b) 22%, transparent) 0%,
      color-mix(in srgb, var(--w-accent, #c9a24b) 8%, transparent) 40%,
      transparent 74%
    );
}

.bshow__mount {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The [data-bottle-viewer] the script drops in. Its own stylesheet draws the
   .bv__stage inside; here it is only told to fill the room and drop its own
   frame, because the room already is the frame. The token overrides give
   bottle-viewer.js a taller, transparent stage than a card would. */
.bshow__viewer.bshow__viewer {
  --bv-ratio: auto;
  --bv-min-height: 0px;
  --bv-max-height: none;
  --bv-radius: 0px;
  --bv-line: transparent;
  --bv-surface: transparent;
  --bv-surface-2: transparent;
  --bv-base: transparent;

  width: 100%;
  height: 100%;
  margin: 0;
}

/* The room supplies the frame, so the inner stage carries none of its own and
   lets the pool of light show through. */
.bshow__viewer .bv__stage {
  width: 100%;
  height: 100%;
  min-height: 0;
  max-height: none;
  aspect-ratio: auto;
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* The fallback, when there is no WebGL2 to draw into: the caption, centred in
   the room, so the showcase is never empty even with the 3D absent. */
.bshow__viewer:not([data-bv-state]) {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6, 2rem);
  aspect-ratio: auto;
  min-height: 0;
  max-height: none;
  border: 0;
  background: transparent;
}

.bshow__ghost {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  opacity: 1;
  transition: opacity 420ms var(--bshow-ease);
}

.bshow__ghost.is-gone {
  opacity: 0;
}


/* --------------------------------------------------------------------------
   5. The copy column
   -------------------------------------------------------------------------- */

.bshow__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 1rem);
  min-width: 0;
  padding-block: var(--space-2, 0.5rem);
  overflow-y: auto;
}

.bshow__eyebrow {
  margin: 0;
  font-family: var(--font-utility, monospace);
  font-size: var(--step--1, 0.85rem);
  letter-spacing: var(--track-wide, 0.08em);
  text-transform: uppercase;
  color: var(--w-text-dim, #9aa0a6);
}

.bshow__eyebrow[hidden],
.bshow__notes[hidden],
.bshow__price[hidden],
.bshow__cta[hidden],
.bshow__inert[hidden] {
  display: none;
}

.bshow__title {
  margin: 0;
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--step-3, 1.8rem);
  line-height: var(--lh-snug, 1.2);
  letter-spacing: var(--track-tight, -0.02em);
  color: var(--w-text, #e8e8e8);
  text-wrap: balance;
}

.bshow__notes {
  margin: 0;
  font-family: var(--font-body, inherit);
  font-size: var(--step-0, 1rem);
  line-height: var(--lh-body, 1.6);
  color: var(--w-text-dim, #9aa0a6);
  text-wrap: pretty;
}

.bshow__hint {
  margin: 0;
  font-family: var(--font-body, inherit);
  font-size: var(--step--1, 0.85rem);
  letter-spacing: 0.03em;
  color: var(--w-text-dim, #9aa0a6);
  opacity: 0.85;
}


/* --------------------------------------------------------------------------
   6. The controls — presets and zoom
   Every one is a real button, ≥44px, with a visible focus ring and a name.
   -------------------------------------------------------------------------- */

.bshow__tools {
  display: flex;
  flex-direction: column;
  gap: var(--space-3, 0.75rem);
}

.bshow__tools[hidden] {
  display: none;
}

.bshow__group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2, 0.5rem);
}

.bshow__group--zoom {
  align-items: center;
}

/* The preset views. A quiet outlined chip that fills faintly on engagement —
   the same restraint as .btn--ghost, but sized for a row of four. */
.bshow__view {
  flex: 1 1 auto;
  min-height: 2.75rem;
  padding: var(--space-2, 0.5rem) var(--space-4, 1rem);
  border: 1px solid var(--w-line, rgba(255, 255, 255, 0.14));
  border-radius: var(--radius-sm, 4px);
  background-color: transparent;
  color: var(--w-text, #e8e8e8);
  font-family: var(--font-utility, monospace);
  font-size: var(--step--1, 0.85rem);
  letter-spacing: var(--track-wide, 0.08em);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition:
    transform var(--dur-micro, 200ms) var(--bshow-ease),
    border-color var(--dur-micro, 200ms) var(--bshow-ease),
    background-color var(--dur-micro, 200ms) var(--bshow-ease),
    color var(--dur-micro, 200ms) var(--bshow-ease);
}

.bshow__view:hover,
.bshow__view:focus-visible {
  transform: translateY(-1px);
  border-color: var(--w-accent, #c9a24b);
  background-color: color-mix(in srgb, var(--w-accent, #c9a24b) 12%, transparent);
  color: var(--w-accent-soft, #f2daa8);
}

.bshow__view:focus-visible,
.bshow__zoom:focus-visible {
  outline: 2px solid var(--w-focus, #7cc0ff);
  outline-offset: 2px;
}

.bshow__view:active,
.bshow__zoom:active {
  transform: translateY(0);
}

.bshow__zoom {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--w-line, rgba(255, 255, 255, 0.14));
  border-radius: var(--radius-sm, 4px);
  background-color: transparent;
  color: var(--w-text, #e8e8e8);
  cursor: pointer;
  transition:
    transform var(--dur-micro, 200ms) var(--bshow-ease),
    border-color var(--dur-micro, 200ms) var(--bshow-ease),
    background-color var(--dur-micro, 200ms) var(--bshow-ease);
}

.bshow__zoom:hover,
.bshow__zoom:focus-visible {
  border-color: var(--w-accent, #c9a24b);
  background-color: color-mix(in srgb, var(--w-accent, #c9a24b) 12%, transparent);
}

.bshow__zoom .bshow__glyph {
  font-size: 1.4rem;
  line-height: 1;
}

.bshow__readout {
  min-width: 3.2ch;
  font-family: var(--font-utility, monospace);
  font-size: var(--step--1, 0.85rem);
  letter-spacing: var(--track-wide, 0.08em);
  color: var(--w-text-dim, #9aa0a6);
  font-variant-numeric: tabular-nums;
}


/* --------------------------------------------------------------------------
   7. The foot — price and the one button
   Mirrors the card's foot so the showcase and the card read as one house.
   -------------------------------------------------------------------------- */

.bshow__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 1rem);
  margin-block-start: auto;
  padding-block-start: var(--space-5, 1.5rem);
  border-block-start: 1px solid var(--w-line, rgba(255, 255, 255, 0.14));
}

.bshow__price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
  margin: 0;
}

.bshow__figure {
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--step-4, 2.2rem);
  line-height: var(--lh-tight, 1.06);
  letter-spacing: var(--track-tight, -0.02em);
  color: var(--w-accent, #c9a24b);
  font-variant-numeric: tabular-nums;
}

.bshow__currency {
  font-family: var(--font-utility, monospace);
  font-size: var(--step--1, 0.85rem);
  letter-spacing: var(--track-widest, 0.18em);
  text-transform: uppercase;
  color: var(--w-text-dim, #9aa0a6);
}

/* .btn / .btn--primary / .btn--block carry the box; this only lifts it a touch,
   exactly as commerce.css does for the card's own CTA. */
.bshow__cta {
  min-height: 3rem;
  letter-spacing: var(--track-wide, 0.08em);
}

.bshow__inert {
  display: flex;
  align-items: center;
  gap: var(--space-3, 0.75rem);
  min-height: 2.75rem;
  margin: 0;
  font-family: var(--font-utility, monospace);
  font-size: var(--step--1, 0.85rem);
  letter-spacing: var(--track-wide, 0.08em);
  text-transform: uppercase;
  color: var(--w-text-dim, #9aa0a6);
}

.bshow__inert::before {
  content: "";
  flex: none;
  inline-size: var(--space-5, 1.5rem);
  block-size: 1px;
  background-color: var(--w-accent, #c9a24b);
}


/* --------------------------------------------------------------------------
   8. The opener on each card
   A quiet ghost button under the bottle. .btn / .btn--ghost carry the skin; this
   only pins it under the frame with a little breathing room.
   -------------------------------------------------------------------------- */

.bshow-open {
  margin-block-start: var(--space-4, 1rem);
  margin-inline: var(--space-6, 2rem);
  width: calc(100% - 2 * var(--space-6, 2rem));
}

@media (max-width: 40em) {
  .bshow-open {
    margin-inline: var(--space-5, 1.5rem);
    width: calc(100% - 2 * var(--space-5, 1.5rem));
  }
}


/* --------------------------------------------------------------------------
   9. The visually-hidden description
   Its own rule rather than a shared utility, so this file depends on nothing
   outside itself.
   -------------------------------------------------------------------------- */

.bshow__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* --------------------------------------------------------------------------
   10. prefers-reduced-motion — the complete alternate cut, with NO content loss
   The overlay is a plain cross-fade with no growth and no travel; the ghost is
   never captured by the script, so there is nothing to fade. Everything the
   showcase DOES — turning, the presets, zoom, the price, the button — is still
   there and still works; bottle-showcase.js has already made the presets jump
   and the zoom snap. This only removes the imposed motion.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .bshow__scrim,
  .bshow__dialog {
    transition-property: opacity;
    transition-duration: 160ms;
  }

  .bshow.is-grown.is-entering .bshow__dialog,
  .bshow.is-grown.is-closing .bshow__dialog,
  .bshow.is-open .bshow__dialog {
    transform: none;
  }

  .bshow__view,
  .bshow__zoom,
  .bshow__close {
    transition: none;
  }

  .bshow__ghost {
    transition: none;
  }
}


/* --------------------------------------------------------------------------
   11. Forced colours
   Keep the frame, the controls and the focus rings legible when the OS is
   drawing the palette. The rendered bottle is a bitmap and is left alone.
   -------------------------------------------------------------------------- */

@media (forced-colors: active) {
  .bshow__dialog,
  .bshow__stage,
  .bshow__view,
  .bshow__zoom,
  .bshow__close {
    border-color: CanvasText;
  }

  .bshow__view:hover,
  .bshow__view:focus-visible,
  .bshow__zoom:hover,
  .bshow__zoom:focus-visible,
  .bshow__close:hover,
  .bshow__close:focus-visible {
    border-color: Highlight;
  }

  .bshow__close:focus-visible,
  .bshow__view:focus-visible,
  .bshow__zoom:focus-visible {
    outline-color: Highlight;
  }
}
