/* ==========================================================================
   Showreel
   ==========================================================================
   Ported from showreel.tsx, showreel-atmosphere.tsx and
   showreel-atmosphere.module.css.

   How it works, because the markup does not read as obvious:

   The video is pinned at a fixed size inside an outer box and never moves or
   scales. A clipping window sits in front of it. On load that window is inset
   all round, so you see only the centre of the video. Scroll a little into the
   section and the window opens to full bleed, revealing the rest.

   One value drives it: the window insets by --crop and the inner wrapper
   counter-insets by -1 * --crop, so the video always equals the outer box
   whatever --crop is. The inner wrapper is a plain div on purpose: unlike a
   replaced element such as <video>, a non-replaced element does stretch to
   fill all four insets.

   Reduced motion renders the open frame statically. Nothing animates.
   ========================================================================== */

.showreel {
  --crop: clamp(12px, 4.5vw, 64px);
  --frame-radius: 24px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  position: relative;
  /* Sticky track: the stage height plus the scroll distance the crop needs. */
  height: calc(min(100svh - 72px, 56.25vw + 96px) + 16svh);
  isolation: isolate;
  background: var(--background);
}

.showreel[data-expanded="true"] {
  --crop: 0px;
  --frame-radius: 12px;
}

/* 72px is the navbar height. The stage pins directly beneath it. */
.showreel__stage {
  position: sticky;
  top: 72px;
  display: flex;
  height: min(calc(100svh - 72px), calc(56.25vw + 96px));
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* Outer box: a true 16:9 frame capped by height and centred, so the video
   fills it exactly instead of stretching into a wide letterbox. */
.showreel__frame {
  position: relative;
  margin-inline: auto;
  aspect-ratio: 16 / 9;
  width: 100%;
  max-height: 84svh;
  max-width: 149svh;
}

.showreel__window {
  position: absolute;
  inset: var(--crop);
  overflow: hidden;
  border-radius: var(--frame-radius);
  box-shadow: var(--shadow-2xl);
  transition: inset 700ms var(--ease), border-radius 700ms var(--ease);
}

.showreel__inner {
  position: absolute;
  inset: calc(-1 * var(--crop));
  transition: inset 700ms var(--ease);
}

.showreel__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (prefers-reduced-motion: reduce) {
  .showreel__window,
  .showreel__inner { transition: none; }
}

/* Click anywhere on the video to open the full-screen player. Sits below the
   corner controls so it cannot swallow their clicks. */
.showreel__catcher {
  position: absolute;
  inset: 0;
  z-index: 0;
  cursor: pointer;
}

.showreel__catcher:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: -2px;
}

/* --------------------------------------------------------------------------
   Controls. 44px round, on a dark scrim so they read over any frame of the
   video. Mute top right, pause bottom left, matching the original.
   -------------------------------------------------------------------------- */
.showreel__control {
  position: absolute;
  z-index: 10;
  display: flex;
  width: 2.75rem;
  height: 2.75rem;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background-color: rgb(10 10 10 / 0.55);
  color: #ffffff;
  backdrop-filter: blur(8px);
  transition: background-color 150ms ease;
}

.showreel__control:hover { background-color: rgb(10 10 10 / 0.75); }
.showreel__control:focus-visible { outline: 2px solid #ffffff; outline-offset: 2px; }
.showreel__control svg { width: 1.25rem; height: 1.25rem; }

@media (prefers-reduced-motion: reduce) {
  .showreel__control { transition: none; }
}

.showreel__control--mute { right: 1rem; top: 1rem; }
.showreel__control--pause { bottom: 1rem; left: 1rem; }

/* The play glyph is optically left-heavy, so it is nudged right to sit centred
   in the circle. The pause glyph needs no nudge. */
.showreel__control--pause .showreel__icon-play { margin-left: 0.125rem; }

/* Which glyph shows follows the button's own state, so the icon and the
   accessible label can never disagree. */
.showreel__control--pause .showreel__icon-play,
.showreel__control--pause[data-paused="true"] .showreel__icon-pause,
.showreel__control--mute .showreel__icon-unmuted,
.showreel__control--mute[data-muted="false"] .showreel__icon-muted {
  display: none;
}
.showreel__control--pause[data-paused="true"] .showreel__icon-play,
.showreel__control--mute[data-muted="false"] .showreel__icon-unmuted {
  display: block;
}

.showreel__icon-play,
.showreel__icon-pause { fill: currentColor; }

/* --------------------------------------------------------------------------
   Atmosphere. A still cloud plate behind the pinned player, plus a
   transparent glass horse sitting higher than the player, rendered as
   animated ASCII by js/showreel-light.js.

   These offsets are layout tuning for one composition, not tokens.
   -------------------------------------------------------------------------- */
.showreel__atmosphere {
  position: absolute;
  inset: -220px 0 0;
  overflow: hidden;
  pointer-events: none;
  z-index: -1;
  mask-image: linear-gradient(to bottom, transparent 0%, #000 20%, #000 72%, transparent 100%);
}

.showreel__clouds {
  position: absolute;
  inset: 220px 0 0;
  background: url("../../img/hero/cloud-plate-v9.webp") 70% top / cover no-repeat;
  mask-image: linear-gradient(transparent, #000 22%, #000 70%, transparent);
}

.showreel__horse {
  position: absolute;
  top: -132px;
  right: -5%;
  width: 100%;
  aspect-ratio: 1672 / 941;
  min-height: 650px;
  opacity: 0.55;
  mask-image: linear-gradient(#000 66%, transparent 98%);
}

/* The still image is the fallback for reduced motion and for no WebGL. The
   canvas replaces it only once it has actually rendered a frame. */
.showreel__sculpture,
.showreel__reflections {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 70% top;
  pointer-events: none;
}

.showreel__reflections,
.showreel__horse[data-rendered="true"] .showreel__sculpture {
  opacity: 0;
}

@media (max-width: 640px) {
  .showreel__atmosphere { top: -108px; }
  .showreel__clouds { top: 108px; }
  .showreel__horse {
    top: -64px;
    right: -8%;
    height: 440px;
    min-height: 0;
  }
}

/* --------------------------------------------------------------------------
   Full-screen player overlay
   -------------------------------------------------------------------------- */
.showreel__overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgb(10 10 10 / 0.9);
  padding: 1rem;
  backdrop-filter: blur(4px);
}

.showreel__overlay[hidden] { display: none; }

.showreel__overlay-close {
  position: fixed;
  right: 1.5rem;
  top: 1.5rem;
  z-index: 10;
  display: flex;
  width: 2.75rem;
  height: 2.75rem;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background-color: rgb(255 255 255 / 0.1);
  color: #ffffff;
  transition: background-color 150ms ease;
}

.showreel__overlay-close:hover { background-color: rgb(255 255 255 / 0.2); }
.showreel__overlay-close svg { width: 1.5rem; height: 1.5rem; }

@media (prefers-reduced-motion: reduce) {
  .showreel__overlay-close { transition: none; }
}

.showreel__overlay-video {
  max-height: 100%;
  width: 100%;
  max-width: 72rem;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2xl);
}


/* --------------------------------------------------------------------------
   20 Oct 2026 (Hulusi): one control bar instead of two round corner buttons.
   Play / pause, stop, sound, elapsed time, a progress line, and "Agrandir"
   for focus mode. Sharp, on a dark glass strip at the foot of the film, the
   same bar in focus mode. Hidden while no film is wired (data-media-pending).
   -------------------------------------------------------------------------- */
.showreel__bar {
  position: absolute; left: 1rem; right: 1rem; bottom: 1rem; z-index: 10;
  display: flex; align-items: center; gap: .25rem;
  padding: .25rem; background: rgb(10 12 16 / .62); color: #fff;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.showreel[data-media-pending="true"] .showreel__bar { display: none; }
.showreel__btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-width: 2.75rem; height: 2.75rem; padding: 0 .625rem;
  border: 0; border-radius: 0; background: transparent; color: inherit; cursor: pointer;
  font: inherit; font-size: .9375rem; transition: background-color 150ms ease;
}
.showreel__btn:hover { background: rgb(255 255 255 / .12); }
.showreel__btn:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
.showreel__btn svg { width: 1.125rem; height: 1.125rem; }
.showreel__btn .showreel__icon-play, .showreel__btn .showreel__icon-pause { fill: currentColor; }
.showreel__btn[data-paused="false"] .showreel__icon-play,
.showreel__btn[data-paused="true"] .showreel__icon-pause,
.showreel__btn[data-muted="true"] .showreel__icon-unmuted,
.showreel__btn[data-muted="false"] .showreel__icon-muted { display: none; }
.showreel__time { min-width: 3rem; padding: 0 .5rem; font-size: .875rem; font-variant-numeric: tabular-nums; color: rgb(255 255 255 / .8); }
.showreel__track { flex: 1; height: 2px; background: rgb(255 255 255 / .25); overflow: hidden; }
.showreel__progress { display: block; height: 100%; background: #fff; transform-origin: left center; transform: scaleX(0); }
.showreel__btn--focus { margin-left: .5rem; padding: 0 1rem; background: var(--brand, #0052f8); }
.showreel__btn--focus:hover { background: #0047d6; }
@media (max-width: 640px) {
  .showreel__bar { left: .5rem; right: .5rem; bottom: .5rem; }
  .showreel__time { display: none; }
  .showreel__btn--focus span { display: none; }
}
@media (prefers-reduced-motion: reduce) { .showreel__btn { transition: none; } }

/* Focus mode: the film large over the dark page, its own bar under it. */
.showreel__overlay-stage { position: relative; width: 100%; max-width: 80rem; }
.showreel__overlay-video { display: block; width: 100%; max-height: calc(100vh - 8rem); border-radius: 0; background: #000; }
.showreel__overlay-stage .showreel__bar { position: static; margin-top: .5rem; }
.showreel__overlay-close { border-radius: 0; }
.showreel__overlay { z-index: 1000; } /* above the sticky navbar in focus mode */
/* The bar matches the film's width: the stage is sized to a 16:9 film that
   fits the window height, the film letterboxes inside it. */
.showreel__overlay-stage { width: min(80rem, calc((100vh - 9rem) * 16 / 9)); }
.showreel__overlay-video { aspect-ratio: 16 / 9; max-height: none; object-fit: contain; }
html .showreel__overlay .showreel__overlay-video { max-width: none; width: 100%; }

/* 20 Oct, round 2 (Hulusi: "no need for the progress bar; buttons separated
   and bigger"): no time, no line. Each control is its own dark glass square,
   larger, with a gap between them; "Agrandir" sits apart on the right. */
.showreel__bar { gap: .5rem; padding: 0; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.showreel__spacer { flex: 1; }
.showreel__btn {
  min-width: 3.5rem; height: 3.5rem; padding: 0 1rem;
  background: rgb(10 12 16 / .6); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.showreel__btn:hover { background: rgb(10 12 16 / .82); }
.showreel__btn svg { width: 1.375rem; height: 1.375rem; }
.showreel__btn--focus { padding: 0 1.25rem; font-size: 1rem; background: var(--brand, #0052f8); }
.showreel__btn--focus:hover { background: #0047d6; }
@media (max-width: 640px) { .showreel__btn { min-width: 3rem; height: 3rem; padding: 0 .75rem; } }
/* 20 Oct: "Agrandir" in the top right corner of the film. */
.showreel__btn--corner { position: absolute; top: 1rem; right: 1rem; z-index: 10; margin: 0; }
.showreel[data-media-pending="true"] .showreel__btn--corner { display: none; }
@media (max-width: 640px) { .showreel__btn--corner { top: .5rem; right: .5rem; } }

/* Hidden showreel (21 Oct 2026, until the new film): the section's own
   display rules would beat the hidden attribute, so it is restated here. */
.showreel[hidden], .showreel__overlay[data-showreel-off] { display: none !important; }
