/* css/xp-viewer.css — the product stage of the fruit pages (« chambre froide », the charter's sage). Page: css/xp-fruit.css · js/xp/pages/fruit.js
   · 3D: js/xp/viewer.js. The stage is a rounded sage fog chamber holding, bottom to top:
     .fp-img--ice    the fruit's pre-rendered ice tile (viewer.js ICE_DIR): the first and only thing shown until 3D is up
     .fp-img--fruit  (flat) the unfrozen cutout, cross-faded in by « Ouvrir le fruit »
     .xpp-canvas     (3D) bootPage's one WebGL canvas; the viewer frames its block on .fp-img--ice's layout box
     .fp-note / .fp-toggle  « Glisser pour tourner » / « La coupe … » and « Ouvrir le fruit / Refermer » (opaque pills:
                     never a backdrop-filter over the live canvas)
   States on .fp-chamber: has-img (tile decoded: the chamber appears with it) · is-3d / is-flat · is-live (first 3D frames
   drawn: the canvas cross-fades over the tile) · is-ready (cross-fade done) · is-open (visitor's choice) · is-coupe (the
   opened fruit is on show) · is-unfrozen / is-thawing (flat reveal) · is-touched (dragged once) · is-dragging. */

.fp-chamber { --fp-room: 64px; --fp-s: 84cqmin; --fp-fruit: 66cqmin;
  position: relative; overflow: hidden; container-type: size; isolation: isolate; height: min(94vw, 480px);
  background: var(--sauge);
  transition: opacity .6s ease-out;
  touch-action: pan-y; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; cursor: pointer; }
html.js .fp-chamber:not(.has-img) { opacity: 0; } /* with JS it appears with its decoded still; without, at once */
.fp-chamber.is-live { cursor: grab; }
.fp-chamber.is-dragging { cursor: grabbing; }
@media (min-width: 1024px) {
  .fp-chamber { height: calc(100vh - var(--top-h, 76px) - 36px); height: calc(100svh - var(--top-h, 76px) - 36px); min-height: 520px; max-height: 900px; }
}

/* the fog chamber: the viewer's backdrop (viewer.js CHAMBER, sage: field on top, a deeper sage fog around the block, a
   lit haze above) approximated in CSS behind the tile, so the canvas cross-fades in without the chamber changing much.
   Sizes follow the tile (--fp-s) and its centre, like the shader (on a pseudo-element: cq units resolve on the chamber). */
.fp-chamber::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  --cy: calc((100cqh - var(--fp-room)) / 2);
  background:
    radial-gradient(calc(var(--fp-s) * .998) calc(var(--fp-s) * .688) at calc(50% - var(--fp-s) * .1117) calc(var(--cy) - var(--fp-s) * .3746),
      rgb(240 246 242 / .6), rgb(240 246 242 / .5) 25%, rgb(240 246 242 / .25) 50%, rgb(240 246 242 / .05) 75%, rgb(240 246 242 / 0)),
    radial-gradient(circle calc(var(--fp-s) * 1.4246) at 50% var(--cy),
      rgb(160 179 169) 0, rgb(160 179 169) 12%, rgb(160 179 169 / .86) 25%, rgb(160 179 169 / .56) 40%, rgb(160 179 169 / .32) 55%,
      rgb(160 179 169 / .13) 75%, rgb(160 179 169 / 0)),
    linear-gradient(to bottom, #C9D6CF, #CCD9D2 33.333%, #D7E1DB 66.667%, #D7E1DB); }
/* the camera's soft vignette (post chain), over the tile too, as in the render */
.fp-chamber::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; mix-blend-mode: multiply;
  background: radial-gradient(farthest-corner at 50% 50%, rgb(100 122 110 / 0) 45%, rgb(100 122 110 / .035) 65%, rgb(100 122 110 / .095) 85%, rgb(100 122 110 / .13)); }

/* tile image: an exact square box centred above the control's room (no transform: js/xp/viewer.js reads its layout box
   to frame the 3D block on it). --fp-k (fruit.js, from the tile's alpha) enlarges a slim fruit's tile. */
.fp-img { --w: var(--fp-s); position: absolute; z-index: 0; left: calc(50% - var(--w) / 2); top: calc((100% - var(--fp-room)) / 2 - var(--w) / 2);
  width: var(--w); height: var(--w); max-width: none; display: block; pointer-events: none; -webkit-user-drag: none; }
.fp-img--ice { --w: calc(var(--fp-s) * var(--fp-k, 1)); transition: opacity .5s ease-out, transform .8s cubic-bezier(.22, 1, .36, 1), filter .55s ease-out; }
.fp-img--fruit { --w: var(--fp-fruit); object-fit: contain; opacity: 0;
  filter: drop-shadow(0 26px 30px rgb(30 50 40 / .22)) blur(8px); transform: scale(.9);
  transition: opacity .5s ease-out, transform .9s cubic-bezier(.22, 1, .36, 1), filter .7s ease-out; }
.fp-chamber.is-wide-fruit { --fp-fruit: 74cqmin; }

/* flat reveal: the ice flashes white and dissolves, the fruit out of its ice settles in */
.fp-chamber.is-unfrozen .fp-img--ice { opacity: 0; transform: scale(1.08); filter: blur(10px) brightness(1.35); }
.fp-chamber.is-unfrozen .fp-img--fruit { opacity: 1; transform: none; filter: drop-shadow(0 26px 30px rgb(30 50 40 / .22)); }
.fp-chamber.is-thawing .fp-img--fruit { transition-delay: .12s, .12s, .12s; }

/* 3D: the canvas fills the chamber (overrides the shell's fixed full-page canvas) and cross-fades over the tile */
html .fp-chamber .xpp-canvas { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; opacity: 0; transition: opacity .9s ease-out; pointer-events: none; }
html .fp-chamber.is-live .xpp-canvas { opacity: 1; }
html .fp-chamber.is-flat .xpp-canvas { display: none; }

/* ---------- top-left note: the hint (3D) ↔ « La coupe » (opened): opaque pills ---------- */
.fp-note { position: absolute; z-index: 2; left: 14px; top: 14px; right: 14px; margin: 0; pointer-events: none; }
.fp-note > span { position: absolute; left: 0; top: 0; max-width: 100%; padding: 8px 14px; border-radius: var(--r-ctl); background: var(--paper); color: var(--ink-2);
  font: 400 14px/1.3 var(--font-sans); opacity: 0; transform: translateY(4px); transition: opacity .5s ease-out, transform .6s ease-out; }
.fp-note__k { color: var(--ink); }
.fp-chamber.is-ready:not(.is-touched):not(.is-coupe) .fp-note__hint { opacity: 1; transform: none; transition-delay: .6s; }
.fp-chamber.is-coupe .fp-note__coupe { opacity: 1; transform: none; }

/* ---------- « Ouvrir le fruit / Refermer »: an opaque paper pill ---------- */
.fp-toggle { position: absolute; z-index: 2; left: 50%; bottom: 12px; transform: translateX(-50%);
  display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 46px; padding: 0 20px 0 16px; white-space: nowrap;
  border: 1px solid var(--ink); border-radius: var(--r-ctl); background: var(--paper); color: var(--ink);
  font: 400 12.5px/1 var(--font-sans); letter-spacing: var(--tr-btn); text-transform: uppercase; cursor: pointer; transition: background .2s ease-out, color .2s ease-out; }
@media (hover: hover) { .fp-toggle:hover { background: var(--ink); color: var(--cta-ink); } }
.fp-toggle:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
/* a « + » that turns into « × » while open */
.fp-toggle__ico { position: relative; flex: none; width: 14px; height: 14px; transition: transform .6s cubic-bezier(.22, 1, .36, 1); }
.fp-toggle__ico::before, .fp-toggle__ico::after { content: ""; position: absolute; left: 0; right: 0; top: 6.4px; height: 1.2px; border-radius: 1px; background: currentColor; }
.fp-toggle__ico::after { transform: rotate(90deg); }
.fp-chamber.is-open .fp-toggle__ico { transform: rotate(135deg); }

@media (max-width: 1023.98px) {
  .fp-chamber { --fp-room: 60px; --fp-s: 86cqmin; --fp-fruit: 70cqmin; }
  .fp-chamber.is-wide-fruit { --fp-fruit: 80cqmin; }
  .fp-note > span { font-size: 13.5px; padding: 6px 11px; }
}
@media (prefers-reduced-motion: reduce) {
  .fp-chamber, .fp-img, .fp-note > span, .fp-toggle, .fp-toggle__ico { transition: none !important; }
}
