/* The night street stage: sky, model host, fog, siren, vignette and the
   lighting applied to the CSS 3D faces. Light goes on faces, never as
   opacity or filter on a model group, so the 3D depth survives. */
.sh-nightfall { --power: 1; --siren: 0; --dusk: #07080a; position: relative; background: var(--sh-ink-0); color: var(--sh-fg); }
.sh-nightfall__stage { position: relative; height: 100vh; height: 100svh; min-height: 320px; overflow: hidden; isolation: isolate; background: var(--sh-ink-0); }
.sh-nightfall__sky, .sh-film__dusk, .sh-nightfall__fog, .sh-nightfall__siren, .sh-nightfall__vignette { position: absolute; inset: 0; pointer-events: none; }
.sh-nightfall__sky {
  background: radial-gradient(ellipse 70% 42% at 58% 70%, rgba(214, 150, 84, .13), transparent 70%),
    radial-gradient(ellipse 55% 50% at 80% 12%, #1a2230, transparent 72%),
    linear-gradient(180deg, #050608 0%, #0a0e15 38%, #111822 66%, #0b0f16 84%, #07080a 100%);
}
.sh-nightfall__stars {
  position: absolute; inset: 0 0 50%; opacity: calc(var(--power) * .6);
  background-image: radial-gradient(1px 1px at 12% 22%, #dfe6f2, transparent), radial-gradient(1px 1px at 27% 9%, #c9d3e6, transparent),
    radial-gradient(1.4px 1.4px at 41% 31%, #eef2fa, transparent), radial-gradient(1px 1px at 58% 14%, #c9d3e6, transparent),
    radial-gradient(1px 1px at 66% 38%, #dfe6f2, transparent), radial-gradient(1.2px 1.2px at 84% 26%, #eef2fa, transparent),
    radial-gradient(1px 1px at 92% 11%, #c9d3e6, transparent), radial-gradient(1px 1px at 6% 41%, #dfe6f2, transparent);
}
.sh-nightfall__moon {
  position: absolute; right: 12%; top: 13%; width: clamp(16px, 1.8vw, 26px); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 38% 36%, #fbf6e6, #d9d2bd 62%, #b9b39f);
  box-shadow: 0 0 40px 10px rgb(210 222 255 / 14%), 0 0 140px 50px rgb(160 180 230 / 7%);
}
.sh-film__dusk { z-index: 0; background: var(--sh-ink-0); opacity: 0; }
.sh-nightfall__model { position: absolute; inset: 0; z-index: 1; perspective: 1800px; perspective-origin: 50% 39%; }
.sh-nightfall__model .sh-model { top: 58%; }
.sh-nightfall__fog { z-index: 2; overflow: hidden; opacity: .3; transition: opacity var(--sh-dur-3); }
.sh-nightfall__fog span {
  position: absolute; left: -30%; width: 160%; height: 42%; border-radius: 50%;
  background: radial-gradient(ellipse at 50% 50%, rgb(150 168 196 / 30%), transparent 68%);
}
.sh-nightfall__fog span:nth-child(1) { bottom: 2%; }
.sh-nightfall__fog span:nth-child(2) { bottom: 26%; height: 30%; opacity: .7; }
.sh-nightfall__fog span:nth-child(3) { bottom: -8%; height: 26%; opacity: .9; }
.sh-nightfall.is-haunted .sh-nightfall__fog span { animation: sh-fog-drift 34s ease-in-out infinite alternate; }
.sh-nightfall.is-haunted .sh-nightfall__fog span:nth-child(2) { animation-duration: 47s; animation-direction: alternate-reverse; }
.sh-nightfall.is-haunted .sh-nightfall__fog span:nth-child(3) { animation-duration: 61s; }
@keyframes sh-fog-drift { from { transform: translateX(-7%); } to { transform: translateX(7%); } }
.sh-nightfall__siren { z-index: 2; mix-blend-mode: screen; opacity: var(--siren); }
.sh-nightfall__siren::before, .sh-nightfall__siren::after { content: ""; position: absolute; inset: 0; }
.sh-nightfall__siren::before { background: radial-gradient(ellipse 58% 60% at 34% 64%, rgb(40 112 255 / 30%), transparent 70%); }
.sh-nightfall__siren::after { background: radial-gradient(ellipse 50% 54% at 68% 60%, rgb(226 59 77 / 22%), transparent 70%); opacity: .35; }
.sh-nightfall.is-haunted .sh-nightfall__siren::before { animation: sh-siren 1s ease-in-out infinite alternate; }
.sh-nightfall.is-haunted .sh-nightfall__siren::after { animation: sh-siren 1s ease-in-out infinite alternate-reverse; }
@keyframes sh-siren { from { opacity: .25; } to { opacity: 1; } }
.sh-nightfall__vignette {
  z-index: 4;
  background: radial-gradient(ellipse 84% 76% at 50% 52%, transparent 48%, rgb(3 4 6 / 55%) 100%),
    linear-gradient(180deg, rgba(7, 8, 10, .62) 0, rgba(7, 8, 10, 0) 26%), linear-gradient(0deg, rgba(7, 8, 10, .74) 0, rgba(7, 8, 10, 0) 32%);
}

/* Face lighting. */
.sh-nightfall .sh-model__face::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: #06090f; opacity: .38; }
.sh-nightfall .sh-model__face--roof::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: rgb(126 152 204 / 12%); }
.sh-nightfall .sh-model__road::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: var(--power);
  background: radial-gradient(ellipse 4% 70% at 37% 0%, rgb(255 206 140 / 38%), transparent 70%),
    radial-gradient(ellipse 4% 64% at 61% 0%, rgb(255 206 140 / 32%), transparent 70%),
    linear-gradient(180deg, rgb(120 150 200 / 10%), transparent 60%);
}
.sh-nightfall .sh-model__cornice, .sh-nightfall .sh-model__downpipe { box-shadow: inset 0 0 0 999px rgb(6 9 15 / 58%); }
.sh-nightfall .sh-model__window::before, .sh-nightfall .sh-model__window::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
.sh-nightfall .sh-model__window::before { background: #0a0f18; opacity: .82; }
.sh-nightfall .sh-model__window::after { opacity: clamp(0, calc((var(--power) - var(--on, 2)) * 8), 1); }
.sh-nightfall .sh-model__window.is-tv::after { background: linear-gradient(180deg, #b8d0ff, #6f8fd8); box-shadow: 0 0 12px 4px rgb(130 165 255 / 42%); }
.sh-nightfall.is-haunted .sh-model__window.is-tv::after { animation: sh-tv 3.1s steps(1, end) infinite; }
@keyframes sh-tv { 0%, 100% { opacity: 1; } 23% { opacity: .62; } 41% { opacity: .95; } 58% { opacity: .75; } }
.sh-nightfall .sh-model__pane::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: rgb(8 11 18 / 80%); }
.sh-nightfall .sh-model__building--brick .sh-model__pane::before {
  opacity: var(--power); background: radial-gradient(ellipse at 50% 30%, #ffe4ae, #f2a35d 62%, #a45a2c); box-shadow: 0 0 16px 5px rgb(255 190 110 / 42%);
}
.sh-nightfall .sh-model__building--stone .sh-model__pane::before { background: radial-gradient(ellipse at 50% 26%, rgb(222 232 255 / 50%), rgb(8 11 18 / 82%) 70%); }
.sh-nightfall .sh-model__building--stone .sh-model__pane--door::before { background: radial-gradient(circle at 50% 22%, rgb(120 170 255 / 70%) 0 8%, rgb(8 11 18 / 88%) 30%); }
.sh-nightfall .sh-model__building--green .sh-model__pane::before { background: radial-gradient(ellipse at 50% 34%, rgb(255 236 190 / 55%), rgb(8 11 18 / 80%) 72%); }
.sh-nightfall.is-alarm .sh-model__building--green .sh-model__pane::before { background: radial-gradient(ellipse at 50% 40%, rgb(255 70 70 / 58%), rgb(8 11 18 / 85%) 70%); }
.sh-nightfall.is-alarm.is-haunted .sh-model__building--green .sh-model__pane::before { animation: sh-alarm 1.1s steps(1, end) infinite; }
@keyframes sh-alarm { 50% { background: rgb(8 11 18 / 85%); } }
.sh-night__alarm { position: absolute; right: 10px; bottom: 58px; width: 5px; height: 5px; border-radius: 50%; background: #5a2323; }
.sh-nightfall.is-alarm .sh-night__alarm { background: #ff4a4a; box-shadow: 0 0 10px 3px rgb(255 60 60 / 70%); }
.sh-nightfall.is-alarm.is-haunted .sh-night__alarm { animation: sh-alarm-dot 1.1s steps(1, end) infinite; }
@keyframes sh-alarm-dot { 50% { background: #5a2323; box-shadow: none; } }
.sh-nightfall .sh-model__lamp-head { background: #fff6dc; box-shadow: 0 0 calc(6px + var(--power) * 22px) calc(var(--power) * 6px) rgb(255 214 150 / calc(var(--power) * 85%)); }
.sh-nightfall .sh-model__light-pool { opacity: calc(var(--power) * (1 - var(--map, 0))); background: radial-gradient(ellipse, rgb(255 214 150 / 62%), transparent 70%); }
.sh-nightfall.is-haunted .sh-model__lamp-group.is-flicker .sh-model__lamp-head { animation: sh-flicker 5.3s steps(1, end) infinite; }
@keyframes sh-flicker { 0%, 18%, 23%, 61%, 64%, 100% { opacity: 1; } 19%, 22% { opacity: .25; } 62% { opacity: .45; } 63% { opacity: .1; } }
.sh-nightfall .sh-heist-car__lightbar > .sh-model__face::after { background: linear-gradient(90deg, #6fb6ff 0 48%, #ff4b5c 52%); }
.sh-nightfall .sh-heist-car .sh-model__face::before { opacity: .12; }
.sh-nightfall .sh-heist-car--police .sh-heist-car__body > .sh-model__face--roof,
.sh-nightfall .sh-heist-car--police .sh-heist-car__cabin > .sh-model__face--roof { box-shadow: inset 0 0 12px rgb(120 175 255 / calc(var(--siren) * 55%)); }

/* The thief and the torch on the jeweller's door. */
.sh-thief { position: absolute; left: 0; top: 0; width: 18px; height: 30px; transform-origin: 50% 100%; }
.sh-thief svg { display: block; width: 100%; height: 100%; overflow: visible; }
.sh-thief__lens { filter: drop-shadow(0 0 2px #fff3d6); }
.sh-thief__shadow { position: absolute; left: 0; top: 0; width: 22px; height: 8px; border-radius: 50%; background: radial-gradient(ellipse, rgb(0 0 0 / 55%), transparent 70%); }
.sh-night__torch { position: absolute; inset: 0; pointer-events: none; }
.sh-night__torch span { position: absolute; left: 0; top: 0; border-radius: 50%; }
.sh-night__torch span:nth-child(1) {
  width: 56px; height: 36px; margin: -18px 0 0 -28px; opacity: calc(var(--beam, 0) * .9);
  transform: translate(var(--spot-x, 0), var(--spot-y, 0)); background: radial-gradient(ellipse, rgb(255 240 205 / 36%), transparent 70%);
}
.sh-night__torch span:nth-child(2) {
  width: 18px; height: 12px; margin: -6px 0 0 -9px; opacity: var(--beam, 0);
  transform: translate(var(--spot-x, 0), var(--spot-y, 0)); background: radial-gradient(ellipse, #fffaf0 0 22%, rgb(255 236 196 / 70%) 45%, transparent 72%);
}
.sh-night__torch span:nth-child(3) {
  width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 0; opacity: var(--glint, 0); background: #fffdf6;
  transform: translate(30px, 150px) scale(calc(.3 + var(--glint, 0) * 1.1));
  clip-path: polygon(50% 0, 57% 43%, 100% 50%, 57% 57%, 50% 100%, 43% 57%, 0 50%, 43% 43%); filter: drop-shadow(0 0 3px #d9f1ff);
}
.sh-nightfall.is-paused .sh-nightfall__fog span { animation-play-state: paused; }
@media (max-width: 767px) and (orientation: portrait) { .sh-nightfall__model .sh-model { top: 56%; } }
@media (max-height: 500px) and (orientation: landscape) { .sh-nightfall__model .sh-model { top: 60%; } }
@media (prefers-reduced-motion: reduce) {
  .sh-nightfall__fog span, .sh-nightfall .sh-model__lamp-head, .sh-nightfall .sh-model__window::after,
  .sh-nightfall__siren::before, .sh-nightfall__siren::after, .sh-night__alarm { animation: none !important; }
}
@media print { .sh-nightfall { display: none; } }

/* The painted street (sh-paint.ts): one canvas under the thin DOM model that
   keeps the tactical map and labels on the same camera. The canvas draws its
   own sky, fog, rain and siren light, so the CSS versions stand down. */
.sh-paint { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
.sh-nightfall__stage.is-painted .sh-nightfall__sky > *, .sh-nightfall__stage.is-painted .sh-nightfall__fog,
.sh-nightfall__stage.is-painted .sh-nightfall__siren { display: none; }
