/* Frame grow stage. One media box drawn as a filled plate with a 1px stroke on the corner squares' centre line and
   an 8px square on each corner (the source's SVG: 608 x 398 viewBox, rects inset 4, squares 8 x 8, picture inset
   one square). Closed, the plate is a point at the centre, the four squares sit on that point and the picture is at
   scale(0). Live (.is-live, set by part.js via band-trigger), after a 1 s hold, the plate and stroke grow out to
   full size while the squares fly to the corners (500 ms, GSAP's default power1.out = 1 - (1 - t)^2), and in the
   SAME instant the picture scales up from nothing on its own steeper curve (600 ms cubic-bezier(.33,1,.32,1)), so
   the picture outruns the frame early and the frame lines arrive around it a beat later. Closing has no hold. */
.fgs {
  --fgs-ink: #ff0000;                                   /* stroke + corner squares */
  --fgs-paper: #000;                                    /* plate fill behind the picture */
  --fgs-dot: 8px;                                       /* corner squares */
  --fgs-stroke: 1px;
  --fgs-inset: var(--fgs-dot);                          /* picture inset from the outer edge (one square) */
  --fgs-hold: 1000ms;                                   /* beat between the trigger and the open */
  --fgs-frame-dur: 500ms;
  --fgs-frame-ease: cubic-bezier(0.3333, 0.6667, 0.6667, 1);   /* exact quadratic out (GSAP power1.out) */
  --fgs-media-dur: 600ms;
  --fgs-media-ease: cubic-bezier(0.33, 1, 0.32, 1);
  position: relative;
  display: block;
  margin: 0;
  aspect-ratio: 608 / 398;
}
.fgs__plate {                                           /* fill + stroke, growing from the centre */
  position: absolute;
  inset: 50%;
  background: var(--fgs-paper);
  outline: var(--fgs-stroke) solid var(--fgs-ink);
  outline-offset: calc(var(--fgs-stroke) / -2);
  pointer-events: none;
  transition: inset var(--fgs-frame-dur) var(--fgs-frame-ease);
}
.fgs__dots { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.fgs__dots i {                                          /* the four squares, leaving the centre for the corners */
  position: absolute;
  width: var(--fgs-dot); height: var(--fgs-dot);
  left: calc(50% - var(--fgs-dot) / 2); top: calc(50% - var(--fgs-dot) / 2);
  background: var(--fgs-ink);
  transition: left var(--fgs-frame-dur) var(--fgs-frame-ease), top var(--fgs-frame-dur) var(--fgs-frame-ease);
}
.fgs__media {                                           /* any content: img, video, canvas, a div */
  position: absolute;
  inset: var(--fgs-inset);
  display: block;
  overflow: hidden;
  transform: scale(0);
  transform-origin: 50% 50%;
  transition: transform var(--fgs-media-dur) var(--fgs-media-ease);
  z-index: 1;
}
.fgs__media > img, .fgs__media > video, .fgs__media > canvas { display: block; width: 100%; height: 100%; object-fit: cover; }

/* open: the hold applies on the way in only */
.fgs.is-live .fgs__plate { inset: calc(var(--fgs-dot) / 2); transition-delay: var(--fgs-hold); }
.fgs.is-live .fgs__dots i { transition-delay: var(--fgs-hold); }
.fgs.is-live .fgs__dots i:nth-child(1) { left: 0; top: 0; }
.fgs.is-live .fgs__dots i:nth-child(2) { left: calc(100% - var(--fgs-dot)); top: 0; }
.fgs.is-live .fgs__dots i:nth-child(3) { left: 0; top: calc(100% - var(--fgs-dot)); }
.fgs.is-live .fgs__dots i:nth-child(4) { left: calc(100% - var(--fgs-dot)); top: calc(100% - var(--fgs-dot)); }
.fgs.is-live .fgs__media { transform: none; transition-delay: var(--fgs-hold); }

/* snap: jump to the current state with no motion (replay resets through it; the light path and reduced motion use it) */
.fgs--snap .fgs__plate, .fgs--snap .fgs__dots i, .fgs--snap .fgs__media { transition: none !important; }
@media (prefers-reduced-motion: reduce) {
  .fgs__plate, .fgs__dots i, .fgs__media { transition: none !important; }
}
