/* `clip` (not hidden): a focus() must never be able to scroll the gate */
.kc-gate.has-scene { overflow: clip; }

/* Gate film: sits UNDER the guide's foliage. The leaves and the guide move off by transform; nothing fades over them.
   gate-1 (the clip's first frame) is already there before the tap, the clip starts under it, the last frame holds, alive. */
.kc-film {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: #1a1024;
}
/* portrait hangs from the top like the Act I stage: a tablet crops the tail, never the spire */
.kc-film__box {
  position: absolute;
  top: 0;
  left: 50%;
  width: max(100%, 56.25dvh);
  aspect-ratio: 9 / 16;
  transform: translateX(-50%);
  background: #1a1024;
}
.kc-film__bg { display: none; }
.kc-film__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.kc-film__start, .kc-film__final { position: absolute; inset: 0; }
.kc-film__start { opacity: 1; transition: opacity 500ms ease; }
.kc-gate.is-film-playing .kc-film__start, .kc-gate.is-film-held .kc-film__start { opacity: 0; }
.kc-film__final { opacity: 0; transition: opacity 700ms ease; }
.kc-gate.is-film-held .kc-film__final { opacity: 1; }
/* The stills are re-renders of the clip's frames, ~3 % larger and shifted: this maps them back onto the video.
   Measured by gradient NCC against frames 0 and 216 (see the gate film report). */
.kc-film__align {
  --asx: .970; --asy: .9875; --ax: -1.62%; --ay: -.93%;
  position: absolute;
  inset: 0;
  transform: translate(var(--ax), var(--ay)) scale(var(--asx), var(--asy));
}
.kc-film__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* a slow breath over the whole held frame; the hair strips breathe inside it */
.kc-gate.is-film-held .kc-film__final { animation: kc-film-breathe 14s ease-in-out infinite alternate; transform-origin: 30% 38%; }
@keyframes kc-film-breathe { from { transform: scale(1); } to { transform: scale(1.012); } }
.kc-film__scrim {
  position: absolute;
  inset: auto 0 0;
  height: 58%;
  opacity: 0;
  background: linear-gradient(to top, rgba(26,16,36,.9) 0%, rgba(26,16,36,.78) 38%, rgba(26,16,36,.42) 70%, rgba(26,16,36,0) 100%);
  transition: opacity 900ms ease 300ms;
}
.kc-gate.is-film-held .kc-film__scrim { opacity: 1; }

.kc-life__hair {
  position: absolute;
  background-repeat: no-repeat;
  will-change: transform;
  -webkit-mask-image: radial-gradient(ellipse at 50% 50%, #000 52%, transparent 78%);
  mask-image: radial-gradient(ellipse at 50% 50%, #000 52%, transparent 78%);
}
.kc-life__mote {
  position: absolute;
  left: var(--x);
  bottom: 8%;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,236,190,.95), rgba(255,214,150,0) 70%);
  opacity: 0;
  animation: kc-mote var(--d) linear var(--s) infinite;
}
@keyframes kc-mote {
  0% { opacity: 0; transform: translate(0, 0); }
  15% { opacity: .85; }
  85% { opacity: .5; }
  100% { opacity: 0; transform: translate(var(--w), -62dvh); }
}
.kc-film__align.is-paused .kc-life__mote { animation-play-state: paused; }
.kc-film__align.is-still .kc-life__mote { display: none; }

/* the film covers the Act I stage once held: stop painting its sprites */
.kc-gate.is-film-held .kc-stage:not(.kc-stage--hit) { visibility: hidden; }

/* final copy */
.kc-final {
  position: relative;
  margin-top: auto;
  margin-bottom: .9rem;
  display: grid;
  justify-items: center;
  gap: .35rem;
  text-align: center;
}
.kc-final { visibility: hidden; }
.kc-gate.is-film-held .kc-final { visibility: visible; }
.kc-final > :not(.kc-final__name) { opacity: 0; }
.kc-final__eyebrow {
  margin: 0;
  font-family: "Cormorant Garamond", ui-serif, Georgia, serif;
  font-style: italic;
  font-size: clamp(1.35rem, 5.9vw, 1.8rem);
  letter-spacing: .1em;
  margin-bottom: .35rem;
  color: #fff6dc;
  /* a tight dark halo plus a wide one: legible over the lit stone of the balcony without a box behind it */
  text-shadow: 0 1px 2px rgba(20,10,28,.9), 0 0 10px rgba(20,10,28,.85), 0 0 24px rgba(20,10,28,.55);
}
.kc-final__name {
  margin: 0;
  font-family: "Tangled", "Cormorant Garamond", ui-serif, Georgia, serif;
  font-weight: 400;
  font-size: clamp(4.2rem, 24vw, 7rem);
  line-height: .95;
  padding-bottom: 1.7rem;
  color: #fbe9b7;
  text-shadow: 0 2px 22px rgba(26,16,36,.75), 0 0 34px rgba(255,200,120,.35);
}
.kc-final__date {
  margin: 0;
  font-family: "Cormorant Garamond", ui-serif, Georgia, serif;
  font-size: clamp(.95rem, 4vw, 1.2rem);
  letter-spacing: .24em;
  color: #fbf1d8;
  text-shadow: 0 1px 10px rgba(26,16,36,.95), 0 0 3px rgba(26,16,36,.7);
}
/* The way in: the warm gold pill the braid winds around. Static shadow only: animating box-shadow repaints the gate. */
.kc-final__enter {
  margin-top: .9rem;
  min-height: 52px;
  padding: .75rem 2.1rem;
  border: 1px solid rgba(251,233,183,.8);
  border-radius: 999px;
  background: linear-gradient(180deg, rgb(251,233,183), rgb(228,186,108)); /* opaque: the back strokes of the braid must not show through */
  color: #2a1a33;
  font-family: "Cormorant Garamond", ui-serif, Georgia, serif;
  font-size: 1.1rem;
  font-weight: 400;
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 6px 26px rgba(26,16,36,.5);
}
.kc-final__enter:focus-visible { outline: 3px solid #fff4d2; outline-offset: 4px; }
/* the fall hands the button to inline transforms: the entrance animation must not keep holding it */
.kc-final__enter.is-dropping { animation: none !important; opacity: 1; will-change: transform; }

/* The braid: two canvases around the button's layer. Back strokes sit under the copy and the pill, front strokes over it. */
.kc-braid { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; opacity: 0; transition: opacity 600ms ease; }
.kc-braid--back { z-index: 9; }
.kc-braid--front { z-index: 10; }
.kc-gate.has-scene .kc-gate__content { z-index: 10; }

/* The lanterns: far off in the valley they light, climb the sky growing as they come, cross the top edge and are gone.
   Between the film and the copy; the page adds the glow, the sprite carries none. */
.kc-lanterns { position: absolute; inset: 0; z-index: 5; pointer-events: none; overflow: hidden; }
.kc-lanterns.is-gone { display: none; }
.kc-lamp { position: absolute; left: 0; top: 0; width: min(24vw, 150px); opacity: 0; transform-origin: 50% 50%; will-change: transform, opacity; }
.kc-lamp img { display: block; position: relative; width: 100%; height: auto; }
.kc-lamp__glow {
  position: absolute;
  inset: -45% -60%;
  background: radial-gradient(circle at 50% 52%, rgba(255,208,120,.5), rgba(255,170,70,.16) 36%, rgba(255,170,70,0) 64%);
  opacity: .92;
}
.kc-gate.is-film-held .kc-final > :not(.kc-final__name) { animation: kc-final-in 900ms ease-out both; }
.kc-final__name { opacity: 1; } /* the letters carry their own entrance (gate-name.mjs); without JS the name simply shows */
.kc-gate.is-film-held .kc-final > :nth-child(1) { animation-delay: 900ms; }  /* eyebrow, once the focus shade has settled */
.kc-gate.is-film-held .kc-final > :nth-child(3) { animation-delay: 2300ms; } /* date, after the name has lit */
.kc-gate.is-film-held .kc-final > :nth-child(4) { animation-delay: 2800ms; } /* the way in last */
@keyframes kc-final-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.kc-gate.is-film-playing #gate-title, .kc-gate.is-film-held #gate-title { opacity: 0; transition: opacity 600ms ease; }

/* landscape: the clip is 9:16, so it stands as a column over its own blurred sky */
@media (min-aspect-ratio: 1/1) {
  .kc-film__bg {
    display: block;
    position: absolute;
    inset: 0;
    /* 64 px, pre-blurred and darkened: a live blur(30px) over this area drops software compositors under 30 fps */
    background: url("../../assets/gate/gate-final-bg.webp") center / cover no-repeat;
  }
  .kc-film__box { width: auto; height: 100%; }
  /* the column is 56.25dvh wide in the middle: the copy takes the dark left side, never Azula */
  .kc-final {
    position: absolute;
    top: 50%;
    right: calc(50% + 28.125dvh + 2vw);
    left: 3vw;
    margin: 0;
    transform: translateY(-50%);
  }
  .kc-final__name { font-size: clamp(3rem, 22dvh, 6rem); }
  .kc-final__date { font-size: .9rem; letter-spacing: .14em; white-space: nowrap; }
  .kc-final__enter { padding: .55rem 1.2rem; font-size: 1rem; letter-spacing: .1em; white-space: nowrap; }
}

@media (prefers-reduced-motion: reduce) {
  .kc-film__start, .kc-film__final, .kc-film__scrim { transition: none !important; }
  .kc-gate.is-film-held .kc-film__final { animation: none !important; }
  .kc-final > :not(.kc-final__name) { opacity: 1; animation: none !important; }
  .kc-focus { transition: none !important; }
}

/* the open hotspot is spent after the tap: it must never sit over the way in */
.kc-gate[data-gate-state="opening"] .kc-gate__guide { pointer-events: none; }

.kc-name__ch { display: inline-block; will-change: transform, opacity, filter; }
.kc-final__name[role="img"] { display: block; }

/* The focal shade: a soft vignette centred on the name that draws the eye in. Static once settled: it costs nothing. */
.kc-focus {
  position: absolute;
  inset: 0;
  z-index: 8;
  pointer-events: none;
  opacity: 0;
  --fx: 50%; --fy: 72%;
  background: radial-gradient(ellipse 78% 46% at var(--fx) var(--fy), rgba(12,7,18,0) 0, rgba(12,7,18,0) 30%, rgba(12,7,18,.5) 100%);
  /* it fades in below the balcony: the focus is the name, Azula's own light stays untouched */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 36%, #000 56%);
  mask-image: linear-gradient(to bottom, transparent 0, transparent 36%, #000 56%);
  transition: opacity 1200ms ease;
}
.kc-gate.is-film-held .kc-focus { opacity: 1; }
