/* ==========================================================================
   INTRO — the house, Girl Cat, the others, the threshold
   ========================================================================== */
.scroll-track { width: 1px; }
.stage { position: fixed; inset: 0; overflow: hidden; background: var(--black); pointer-events: none; }
.intro { position: absolute; inset: 0; }
.layer { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform, opacity; }
.shot__img { position: absolute; inset: 0; width: 100%; height: 100%; }

/* film: grain + vignette, very low */
.stage::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse 75% 70% at 50% 50%, transparent 55%, rgba(0,0,0,.5) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .4;
}
/* crossing the threshold: a glow of red light (never a black page) */
.passage {
  position: absolute; inset: 0; opacity: 0; pointer-events: none;
  background: radial-gradient(ellipse 65% 75% at 50% 50%, #d4161c 0%, #8a0710 38%, #3a0205 72%, #120001 100%);
}

/* ---------- the others: eyes that were always there ---------- */
.other { position: absolute; }
.eyes {
  position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; max-width: none;
  -webkit-mask-image: radial-gradient(closest-side, #000 55%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 55%, transparent 100%);
}
.eyes.is-awake { animation: eyes-blink var(--blink-dur, 7s) linear var(--blink-delay, 1s) infinite; }
/* one cycle = 4 blinks: three single, the fourth double (cycle = 4 × blinkEvery).
   At 1 blink/s each blink: closing ≈ 60 ms · closed ≈ 60 ms · opening ≈ 80 ms */
@keyframes eyes-blink {
  0%, 2%, 6%, 7%, 11%, 27%, 32%, 52%, 57%, 77%, 82%, 100% { opacity: 1; }
  3.5%, 4.5% { opacity: 0; }      /* the double blink, on the beat */
  8.5%, 9.5% { opacity: 0; }
  28.5%, 30% { opacity: 0; }      /* single */
  53.5%, 55% { opacity: 0; }      /* single */
  78.5%, 80% { opacity: 0; }      /* single */
}
.other__glow {
  position: absolute; inset: -60% -40%; opacity: 0; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(255, 30, 30, .55), rgba(212, 15, 22, .18) 40%, transparent 70%);
  mix-blend-mode: screen; animation: glow-pulse 3.6s ease-in-out infinite;
}
@keyframes glow-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }

/* ---------- ambient ---------- */
.shot__glow {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;
  mix-blend-mode: screen; opacity: var(--glow-min, .6);
  animation-name: glass-breathe; animation-timing-function: ease-in-out; animation-iteration-count: infinite;
}
.shot__glow--flicker { animation-name: glass-breathe, glass-flicker; animation-timing-function: ease-in-out, linear; }
@keyframes glass-breathe { 0%, 100% { opacity: var(--glow-min, .55); } 50% { opacity: var(--glow-max, .9); } }
/* a candle-like tremor, barely there: brightness only, so it combines with the breathing */
@keyframes glass-flicker {
  0%, 100% { filter: brightness(1); } 13% { filter: brightness(1.08); } 21% { filter: brightness(.96); }
  37% { filter: brightness(1.05); } 52% { filter: brightness(.98); } 68% { filter: brightness(1.1); } 81% { filter: brightness(.97); }
}

.leaf { position: absolute; width: 11px; height: 7px; opacity: 0; animation: leaf-fall 23s linear infinite; pointer-events: none; }
.leaf svg { width: 100%; height: 100%; display: block; }
@keyframes leaf-fall {
  0% { opacity: 0; transform: translate(0, 0) rotate(0); }
  2% { opacity: 1; }
  12% { transform: translate(38px, 160px) rotate(140deg); }
  22% { opacity: 1; transform: translate(12px, 330px) rotate(250deg); }
  26%, 100% { opacity: 0; transform: translate(40px, 400px) rotate(300deg); }
}

/* ---------- tree crowns, meadow fog, crows, near grass ---------- */
.crown { position: absolute; will-change: transform; animation: crown-sway 9s ease-in-out infinite; }
.crown img { display: block; width: 100%; height: 100%; }
@keyframes crown-sway {
  0%, 100% { transform: rotate(0deg); }
  30% { transform: rotate(var(--swing)); }
  45% { transform: rotate(calc(var(--swing) * .55)); }
  62% { transform: rotate(calc(var(--swing) * 1.15)); }
  80% { transform: rotate(calc(var(--swing) * .2)); }
}
.leafc { position: absolute; will-change: transform; animation: leaf-gust 7.5s ease-in-out infinite; }
.leafc__flutter { width: 100%; height: 100%; background-repeat: no-repeat; animation: leaf-flutter 2s ease-in-out infinite alternate; }
@keyframes leaf-flutter { from { transform: rotate(calc(var(--amp) * -1)); } to { transform: rotate(var(--amp)); } }
@keyframes leaf-gust {
  0%, 62%, 100% { transform: rotate(0deg); }
  70% { transform: rotate(var(--gust)); }
  76% { transform: rotate(calc(var(--gust) * -.35)); }
  82% { transform: rotate(calc(var(--gust) * .55)); }
  90% { transform: rotate(calc(var(--gust) * -.1)); }
}
.meadow-fog { position: absolute; overflow: hidden; pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 35%, #000 70%, transparent);
          mask-image: linear-gradient(180deg, transparent, #000 35%, #000 70%, transparent); }
.meadow-fog__band {
  position: absolute; left: -40%; top: 20%; width: 180%; height: 60%;
  background:
    radial-gradient(ellipse 14% 45% at 18% 55%, rgba(241, 237, 228, .5), transparent 70%),
    radial-gradient(ellipse 18% 38% at 47% 45%, rgba(241, 237, 228, .42), transparent 70%),
    radial-gradient(ellipse 12% 50% at 76% 60%, rgba(241, 237, 228, .5), transparent 70%);
  animation: meadow-drift 48s linear infinite;
}
.meadow-fog__band--b { top: 40%; animation-duration: 67s; animation-direction: reverse; opacity: .7; }
@keyframes meadow-drift { from { transform: translateX(-8%); } to { transform: translateX(14%); } }

.crow {
  position: absolute; left: 0; width: 64px; height: 32px; opacity: 0; fill: #070707;
  animation: crow-fly 20s linear infinite;
}
.crow svg { width: 100%; height: 100%; display: block; overflow: visible; transform: scale(var(--s, 1)); }
.crow__wing { transform-origin: 0 0; animation: wing-beat .42s ease-in-out infinite alternate; }
.crow__wing--back { opacity: .75; }
@keyframes wing-beat { from { transform: scaleY(1); } to { transform: scaleY(-.55); } }
@keyframes crow-fly {
  0% { opacity: 0; transform: translate(1760px, 0); }
  2% { opacity: 1; }
  30% { transform: translate(900px, -40px); }
  46% { opacity: 1; transform: translate(-120px, 20px); }
  47%, 100% { opacity: 0; transform: translate(-120px, 20px); }
}
.stem {
  position: absolute; transform-origin: 50% 100%; will-change: transform;
  transform: rotate(calc(var(--wind, 0deg) * var(--k, 1)));
}
.stem__sway { width: 100%; height: 100%; transform-origin: 50% 100%; animation: stem-sway 4.5s ease-in-out infinite; }
.stem svg { display: block; overflow: visible; fill: #070707; }
.stem--far svg { fill: #2b2a28; }
.layer--grass:not(.is-portrait) .stem--port, .layer--grass.is-portrait .stem--land { display: none; }
@keyframes stem-sway {
  0%, 100% { transform: rotate(calc(var(--amp) * -.6)); }
  35% { transform: rotate(var(--amp)); }
  60% { transform: rotate(calc(var(--amp) * .2)); }
  80% { transform: rotate(calc(var(--amp) * .75)); }
}

/* ---------- Girl Cat ---------- */
.girl { position: absolute; left: 0; top: 0; width: 0; height: 0; visibility: hidden; will-change: transform, opacity; }
.girl__frame { position: absolute; left: 0; top: 0; width: auto; max-width: none; transform-origin: 50% 100%; }
.girl__rig { position: absolute; left: 0; top: 0; transform-origin: 50% 100%; }
.girl__rig img { position: absolute; display: block; max-width: none; }
.rig__body { transform-origin: 50% 100%; }
.girl.is-idle .rig__body { animation: breathe 3.8s ease-in-out infinite; }
@keyframes breathe { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.006, 1.012); } }
/* video frames: breathe around the feet (the pose box sits at the feet point) */
.girl.is-idle.is-video .girl__pose { animation: pose-breathe 3.8s ease-in-out infinite; transform-origin: 0 0; }
@keyframes pose-breathe { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.004, 1.01); } }
.quinta__img { position: absolute; inset: 0; width: 100%; height: 100%; }
.girl__shadow {
  position: absolute; left: 0; top: -4px; height: 26px; transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at center, rgba(0,0,0,.6), transparent 70%);
}

/* ---------- the balloon ---------- */
.balloon { position: absolute; visibility: hidden; opacity: 0; will-change: transform, opacity; }
.balloon__img { position: absolute; inset: 0; width: 100%; height: 100%; }
.balloon__text {
  position: absolute; margin: 0; display: flex; align-items: center; justify-content: center;
  text-align: center; font-family: var(--font-balloon); line-height: 1.02; letter-spacing: .01em;
  color: var(--ink); text-transform: lowercase;
}

/* ---------- threshold: the door opens ---------- */
.threshold { position: absolute; inset: 0; visibility: hidden; }
.doorway { position: absolute; overflow: hidden; background: #1a0000; }
.doorway__room {
  position: absolute; inset: 0; background-size: cover; background-position: 55% 55%;
  opacity: .15; filter: saturate(.85) contrast(1.05);
}
.doorway__light {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, #120000 0%, #6a0307 35%, #d40f16 72%, #ff2a2a 88%, #8a0409 100%);
  box-shadow: inset 0 0 24px 8px rgba(0,0,0,.65);
}
.doorway__pulse {
  position: absolute; inset: 0; background: radial-gradient(ellipse 70% 60% at 70% 50%, rgba(255, 60, 50, .55), transparent 70%);
  mix-blend-mode: screen; animation: door-breathe 2.8s ease-in-out infinite;
}
@keyframes door-breathe { 0%, 100% { opacity: .25; } 50% { opacity: .9; } }
/* light only (no room inside): a glowing red with a hot core */
.threshold--light .doorway__light {
  background: radial-gradient(ellipse 60% 55% at 58% 55%, #ff7a5c 0%, #ff3326 26%, #e0121a 52%, #7a0408 88%, #3a0003 100%);
  box-shadow: inset 0 0 18px 6px rgba(40, 0, 0, .55);
}
/* the grinning cat in the red light: a slow, uneasy breath */
/* screen-space: 100×100 box, placed and scaled by threshold.js; above TENET (z 10) for the crossfade */
.door-face { position: fixed; left: 0; top: 0; width: 100px; height: 100px; z-index: 12; transform-origin: 0 0;
  visibility: hidden; opacity: 0; pointer-events: none; will-change: transform, opacity; }
.door-face img { display: block; width: 100%; height: 100%; animation: face-breathe 3.4s ease-in-out infinite;
  filter: drop-shadow(0 0 6px rgba(255, 40, 30, .55)); }
@keyframes face-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.035); } }
/* red light glowing out of the open doorway, around the frame */
.door-bloom { position: absolute; opacity: 0; pointer-events: none; mix-blend-mode: screen; }
.door-bloom__pulse {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 44% 50% at 50% 56%, rgba(255, 60, 40, 1), rgba(230, 20, 26, .55) 38%, rgba(160, 8, 14, .18) 58%, transparent 74%);
  animation: bloom-breathe 2.8s ease-in-out infinite;
}
@keyframes bloom-breathe { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }
.door-spill { position: absolute; left: 0; top: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; }
.door-spill__pulse {
  position: absolute; inset: 0; mix-blend-mode: multiply;
  background: linear-gradient(180deg, rgba(255, 30, 30, .95) 0%, rgba(212, 15, 22, .55) 40%, transparent 100%);
  animation: spill-breathe 2.8s ease-in-out infinite;
}
@keyframes spill-breathe { 0%, 100% { opacity: .75; } 50% { opacity: 1; } }
.door-hinge { position: absolute; perspective: 520px; }
.door-leaf {
  position: absolute; inset: 0; transform-origin: 0 50%; background-repeat: no-repeat;
  will-change: transform; box-shadow: 6px 0 14px rgba(0,0,0,.6);
}
.door-hit { position: absolute; pointer-events: none; }
.threshold.is-clickable .door-hit { pointer-events: auto; cursor: pointer; }
.threshold:has(.door-hit:hover) .doorway__light { filter: brightness(1.25) saturate(1.15); }
.threshold:has(.door-hit:hover) .door-leaf { filter: brightness(1.2) !important; }
.door-a11y[hidden], .beat-a11y[hidden] { display: none; }
/* once the balloon is there, the whole scene can be clicked to continue */
body.can-continue { cursor: pointer; }
.beat-a11y:focus { position: fixed; left: 50%; bottom: 32px; transform: translateX(-50%); z-index: 40;
  background: var(--offwhite); color: var(--black); border: 0; padding: 10px 16px; font: 500 14px var(--font-body); }

/* ---------- the cat on the window sill ---------- */
.sill-cat { position: absolute; pointer-events: none; filter: drop-shadow(0 0 1.5px rgba(255, 40, 30, .45)); }
.sill-cat svg { display: block; overflow: visible; }
.sc__ink { fill: #070707; stroke: #070707; }
.sc__ink ellipse, .sc__ink path:not(.sc__tail) { stroke: none; }
.sc__eyes ellipse { fill: #f1ede4; }
.sc__body { transform-origin: 52px 44px; animation: sc-breathe 3.6s ease-in-out infinite; }
.sc__head { transform-origin: 30px 38px; animation: sc-head var(--head-every, 7s) ease-in-out infinite; }
.sc__ear--l { transform-origin: 18px 18px; animation: sc-ear var(--head-every, 7s) ease-in-out 1.3s infinite; }
.sc__ear--r { transform-origin: 30px 16px; animation: sc-ear-r var(--head-every, 7s) ease-in-out 3.1s infinite; }
.sc__eyes { transform-origin: 25px 27px; animation: sc-blink 4.3s linear infinite; }
@keyframes sc-breathe { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.01, 1.04); } }
/* mostly still; now and then the head tilts and comes back */
@keyframes sc-head {
  0%, 52%, 100% { transform: rotate(0deg); }
  58%, 70% { transform: rotate(-9deg); }
  76% { transform: rotate(3deg); }
  82% { transform: rotate(0deg); }
}
@keyframes sc-ear { 0%, 30%, 38%, 100% { transform: rotate(0deg); } 32% { transform: rotate(-16deg); } 34% { transform: rotate(4deg); } 36% { transform: rotate(-8deg); } }
@keyframes sc-ear-r { 0%, 60%, 66%, 100% { transform: rotate(0deg); } 62% { transform: rotate(14deg); } 64% { transform: rotate(-3deg); } }
@keyframes sc-blink { 0%, 88%, 94%, 100% { transform: scaleY(1); } 91% { transform: scaleY(.1); } }

/* ?debug */
.debug-p { position: fixed; left: 12px; bottom: 12px; z-index: 90; font: 12px/1 ui-monospace, monospace; color: #0ff; background: rgba(0,0,0,.6); padding: 6px 8px; }

@media (prefers-reduced-motion: reduce) {
  .eyes.is-awake, .shot__glow, .other__glow, .crown, .leafc, .leafc__flutter, .meadow-fog__band, .stem__sway, .rig__body, .girl__pose, .sc__body, .sc__head, .sc__ear--l, .sc__ear--r, .sc__eyes,
  .doorway__pulse, .door-spill__pulse, .door-bloom__pulse, .door-face img { animation: none !important; }
  .crow { display: none; }
  .shot__glow { opacity: .7; }
  .leaf { display: none; }
}

/* the scroll hint on the intro (js/intro/scroll-hint.js): half transparent, bottom centre */
.scroll-hint { position: fixed; z-index: 40; left: 50%; bottom: clamp(18px, 4.5vh, 44px); margin: 0; transform: translateX(-50%);
  pointer-events: none; opacity: 0; transition: opacity .9s ease; text-align: center;
  font: 500 12px/1 var(--font-grotesk); letter-spacing: .36em; padding-left: .36em; text-transform: uppercase;
  color: rgba(241, 237, 228, .68); text-shadow: 0 1px 10px rgba(0, 0, 0, .6); mix-blend-mode: normal; }
.scroll-hint::after { content: ''; display: block; width: 1.5px; height: 38px; margin: 12px auto 0; filter: drop-shadow(0 0 3px rgba(0, 0, 0, .7));
  background: linear-gradient(currentColor 50%, transparent 50%) 0 0 / 1.5px 76px; animation: scroll-hint-line 1.8s ease-in-out infinite; }
@keyframes scroll-hint-line { from { background-position: 0 -38px; } to { background-position: 0 38px; } }
.rm .scroll-hint::after { animation: none; background: currentColor; opacity: .6; }
