/* =========================================================================
   ZENEL — the sections of the homepage and the Works page.
   Both pages link this file, so a section is marked with the page it lives on.
   ========================================================================= */

@property --mx { syntax: "<percentage>"; inherits: true; initial-value: 50%; }
@property --my { syntax: "<percentage>"; inherits: true; initial-value: 50%; }

.marker {
  position: absolute;
  z-index: 3;
  color: var(--ink-faint);
  margin: 0;
  pointer-events: none;
}

.marker--tl { top: clamp(5rem, 12vh, 8rem); left: var(--gut); }
.marker--bl { bottom: clamp(2rem, 6vh, 4rem); left: var(--gut); }

/* -------------------------------------------------------------------------
   Threshold — HOME
   A hairline horizon draws itself, and the name rises out of it.
   ------------------------------------------------------------------------- */

.threshold {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 100svh;
  padding: 0 var(--gut);
  overflow: hidden;
}

.threshold__ghost {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  opacity: 0.42;
  animation: ghost-in 3s var(--ease) both;
}

/* The drawing peaks at 150 of 255, so opacity alone would only produce grey.
   Lift the source first, then fade it: 150 → 225 → an effective peak near 95,
   which reads as a drawing while staying well under the ~240 of the wordmark.
   The filter goes on the image, not the container, so it cannot disturb the
   `screen` blending that drops the black ground out. */
.threshold__ghost .boil__f {
  object-fit: cover;
  object-position: 50% 42%;
  filter: brightness(1.5);
}

.threshold__stage {
  position: relative;
  z-index: 2;
  text-align: center;
}

.mark {
  margin: 0;
  overflow: hidden; /* the horizon is the bottom edge — letters rise past it */
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(3.25rem, 15vw, 11rem);
  line-height: 0.92;
  letter-spacing: 0.2em;
  text-indent: 0.2em; /* balance the trailing letter-space */
}

.mark__l {
  display: inline-block;
  transform: translateY(110%);
  animation: rise 1.4s var(--ease) both;
  animation-delay: calc(0.36s + var(--i) * 0.085s);
}

.horizon {
  position: absolute;
  left: 50%;
  width: 100vw;
  height: 1px;
  margin-top: -1px;
  background: var(--ink);
  transform: translateX(-50%) scaleX(0);
  animation: draw 1.8s var(--ease) 0.1s both;
}

.scroll-cue {
  position: absolute;
  bottom: clamp(1.75rem, 5vh, 3rem);
  left: 50%;
  width: 1px;
  height: 3.5rem;
  overflow: hidden;
  background: var(--rule-soft);
  transform: translateX(-50%);
}

.scroll-cue::after {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 40%;
  background: var(--ink-dim);
  animation: cue 2.6s var(--ease) infinite;
}

@keyframes rise { to { transform: translateY(0); } }
@keyframes draw { to { transform: translateX(-50%) scaleX(1); } }
@keyframes ghost-in { from { opacity: 0; } }
@keyframes cue {
  0% { transform: translateY(-100%); }
  60%, 100% { transform: translateY(250%); }
}

/* -------------------------------------------------------------------------
   Fëmija — WORKS
   Three shots, advanced by scroll. Held frames keep boiling.
   ------------------------------------------------------------------------- */

.chapter {
  position: relative;
  height: 240vh;
}

.chapter__sticky {
  position: sticky;
  top: 0;
  display: grid;
  place-items: center;
  height: 100svh;
  overflow: hidden;
}

.chapter__art {
  width: min(100%, 78rem);
  height: 78svh;
  aspect-ratio: auto;
}

.chapter__art .boil__f { object-fit: contain; }

/* -------------------------------------------------------------------------
   The quote — HOME. The only prose on the site.
   ------------------------------------------------------------------------- */

.quote {
  position: relative;
  height: 260vh;
}

.quote__sticky {
  position: sticky;
  top: 0;
  display: grid;
  place-items: center;
  height: 100svh;
  padding: 0 var(--gut);
  overflow: hidden;
}

.quote__ghost {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  opacity: 0.09;
}

.quote__ghost .boil__f { object-fit: cover; }

.quote__body {
  position: relative;
  z-index: 2;
  max-width: min(100%, 46rem);
  margin: 0;
  font-size: clamp(1.35rem, 2.9vw, 2.15rem);
  line-height: 1.42;
  text-wrap: pretty;
}

.quote__body p { margin: 0 0 0.9em; }
.quote__body p:last-child { margin-bottom: 0; }

/* The clauses are visible by default and only hidden once the script has
   taken charge of revealing them. If the module never loads, the one piece
   of prose on this site is still simply there. */
.clause {
  display: inline;
  color: var(--ink);
  transition: opacity 0.9s var(--ease), filter 0.9s var(--ease);
}

.is-staged .clause { opacity: 0; filter: blur(3px); }
.is-staged .clause.is-lit { opacity: 0.62; filter: blur(0); }
.is-staged .clause.is-current { opacity: 1; filter: blur(0); }

/* -------------------------------------------------------------------------
   Nisja — WORKS. The walk does not end; it only leaves the frame.
   ------------------------------------------------------------------------- */

.leaving {
  position: relative;
  padding: clamp(4rem, 14vh, 9rem) 0;
  overflow: hidden;
}

.leaving__track {
  display: flex;
  width: max-content;
  animation: drift 110s linear infinite;
}

.leaving__art {
  flex: 0 0 auto;
  width: 120vw;
  aspect-ratio: 1672 / 941;
  opacity: 0.85;
}

.leaving__art .boil__f { object-fit: cover; }

@keyframes drift { to { transform: translateX(-50%); } }

/* -------------------------------------------------------------------------
   Familja — WORKS. Forty people in the dark; you carry the only light.
   ------------------------------------------------------------------------- */

.familja {
  position: relative;
  height: 100svh;
  overflow: hidden;
  cursor: crosshair;
}

.familja__art {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  --mx: 50%;
  --my: 50%;
  -webkit-mask-image: radial-gradient(circle at var(--mx) var(--my),
    #000 0%, #000 9%, rgba(0, 0, 0, 0.55) 17%, rgba(0, 0, 0, 0.12) 26%, transparent 34%);
  mask-image: radial-gradient(circle at var(--mx) var(--my),
    #000 0%, #000 9%, rgba(0, 0, 0, 0.55) 17%, rgba(0, 0, 0, 0.12) 26%, transparent 34%);
}

.familja__art .boil__f { object-fit: cover; }

/* No pointer to follow — the lamp wanders on its own. */
.familja[data-lamp="auto"] .familja__art { animation: lamp 34s var(--ease) infinite; }

@keyframes lamp {
  0%   { --mx: 24%; --my: 62%; }
  25%  { --mx: 63%; --my: 40%; }
  50%  { --mx: 78%; --my: 71%; }
  75%  { --mx: 41%; --my: 33%; }
  100% { --mx: 24%; --my: 62%; }
}

/* Motion off: hold the lamp still rather than freezing it mid-sweep. */
@media (prefers-reduced-motion: reduce) {
  .familja__art {
    -webkit-mask-image: radial-gradient(circle at 50% 55%, #000 0%, #000 22%, rgba(0, 0, 0, 0.4) 40%, transparent 62%);
    mask-image: radial-gradient(circle at 50% 55%, #000 0%, #000 22%, rgba(0, 0, 0, 0.4) 40%, transparent 62%);
  }
}

/* -------------------------------------------------------------------------
   Shtatzënë — WORKS. A finished film, full bleed.
   ------------------------------------------------------------------------- */

.work-film {
  position: relative;
  height: 100svh;
  overflow: hidden;
  background: var(--bg);
}

.work-film__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Same treatment as the drawings: the film's black ground drops away
     instead of sitting on the page as a rectangle. */
  mix-blend-mode: screen;
}

/* -------------------------------------------------------------------------
   Malli — WORKS. Not made yet, and the page says so by being empty.
   Reuses the threshold's own language: a name rising out of a drawn line.
   ------------------------------------------------------------------------- */

.coming {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 100svh;
  padding: 0 var(--gut);
  overflow: hidden;
}

.coming__stage {
  position: relative;
  text-align: center;
}

.mark--work { font-size: clamp(2.5rem, 11vw, 7.5rem); }

.coming__note {
  margin: 1.75rem 0 0;
  color: var(--ink-faint);
}

/* Held until you arrive — otherwise the letters rise while the page loads,
   three screens above, and are sitting still by the time you get here.
   All of it hangs off `is-armed`, which the script adds only once it is
   actually in a position to release it. If the script never runs, Malli
   simply animates on load rather than never appearing at all. */
.coming.is-armed .mark__l,
.coming.is-armed .horizon { animation-play-state: paused; }

.coming.is-armed .coming__note {
  opacity: 0;
  transition: opacity 1.2s var(--ease) 1.1s;
}

.coming.is-armed.is-in .mark__l,
.coming.is-armed.is-in .horizon { animation-play-state: running; }

.coming.is-armed.is-in .coming__note { opacity: 1; }

/* -------------------------------------------------------------------------
   Narrow screens
   The tall scroll-scrubbed sections stay, but the art needs more room.
   ------------------------------------------------------------------------- */

@media (max-width: 44rem) {
  .chapter { height: 200vh; }
  .quote { height: 230vh; }
  .chapter__art { height: 62svh; }
  .leaving__art { width: 200vw; }

  .nav { gap: 1.1rem; }
}

/* Motion off: the sequences settle on a single shot and simply hold. */
@media (prefers-reduced-motion: reduce) {
  .chapter { height: auto; }
  .quote { height: auto; }
  .chapter__sticky,
  .quote__sticky { position: static; height: auto; padding-block: clamp(4rem, 14vh, 9rem); }
  .chapter__art { height: 70svh; }
  .leaving__track { animation: none; }
  .threshold__ghost,
  .mark__l { animation: none; }
  .mark__l { transform: none; }
  .horizon { transform: translateX(-50%); animation: none; }
  .scroll-cue::after { animation: none; }
}
