/* ==========================================================================
   Pine Hill Falls: effects.css
   Everything that is supposed to feel wrong. All of it is driven by classes
   that js/effects.js adds, and all of it is toned down for reduced motion.
   ========================================================================== */

/* ---------- Flicker: the "-ruin" twin sits on top, invisible ---------- */
.photo .ruin {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; pointer-events: none;
}
.photo.is-flickering .ruin { animation: ruin-flicker 1.1s steps(1, end) forwards; }
@keyframes ruin-flicker {
  0%   { opacity: 1; }
  7%   { opacity: 0; }
  12%  { opacity: 1; }
  78%  { opacity: 1; filter: brightness(0.9); }
  84%  { opacity: 0; }
  90%  { opacity: 0.6; }
  100% { opacity: 0; }
}

/* ---------- The smile: the photo drifts, the mouth does not ---------- */
/* .smile-layer is a copy of the portrait, clipped to the mouth area
   (see data-smile on the element). It never moves. */
.photo .smile-layer {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  pointer-events: none; opacity: 0;
}
.photo.is-smiling img:not(.smile-layer):not(.ruin) {
  animation: portrait-drift 7s ease-in-out both;
}
.photo.is-smiling .smile-layer { opacity: 1; }
@keyframes portrait-drift {
  0%   { transform: translate(0, 0) rotate(0); }
  35%  { transform: translate(-1.6%, 0.8%) rotate(-0.8deg); }
  70%  { transform: translate(1.2%, -0.5%) rotate(0.6deg); }
  100% { transform: translate(0, 0) rotate(0); }
}

/* ---------- Words that correct themselves ---------- */
.mutate { transition: color 1.6s ease; }
.mutate.has-mutated { color: inherit; }

/* ---------- Uncensored edition: stronger on hover ---------- */
.edition--uncensored .book:hover .book__body,
.edition--uncensored:focus-within .book__body {
  animation: book-tremble 0.35s linear 2;
}
@keyframes book-tremble {
  0%, 100% { transform: rotateY(-12deg) rotateX(1deg) translate(0, 0); }
  25% { transform: rotateY(-12.6deg) rotateX(1deg) translate(-1px, 1px); }
  50% { transform: rotateY(-11.4deg) rotateX(1deg) translate(1px, -1px); }
  75% { transform: rotateY(-12.3deg) rotateX(1deg) translate(-1px, 0); }
}
.edition--uncensored .book:hover .cover-art__neon,
.edition--uncensored:focus-within .cover-art__neon {
  animation: neon-sputter 1.6s steps(1, end) infinite;
}
@keyframes neon-sputter {
  0%, 18%, 22%, 56%, 60%, 100% { opacity: 1; }
  20%, 58% { opacity: 0.25; }
  59% { opacity: 0.8; }
}
/* The red glow that spills onto the counter */
.edition--uncensored { position: relative; }
.edition--uncensored::before {
  content: ""; position: absolute; left: -1rem; right: -1rem; top: 0; height: 60%;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(255, 30, 40, 0.18), transparent 100%);
  opacity: 0.5; transition: opacity 0.4s; pointer-events: none; z-index: -1;
}
.edition--uncensored:hover::before, .edition--uncensored:focus-within::before { opacity: 1; }

/* ---------- 3:12: the night mode (between 3:00 and 3:59 a.m.) ---------- */
html.is-night body {
  position: relative;
  background-color: #151b19;
  color: #d6d2c6;
}
html.is-night .site-header { background: linear-gradient(#232b28, #1b2220); border-bottom-color: #3b4a44; }
html.is-night .site-header__town, html.is-night .site-header__brand { color: #cfd6cf; }
html.is-night .site-header__tagline { color: #9fb4a5; }
html.is-night .site-header__state { color: #9aa39c; }
html.is-night .site-nav__list a[aria-current="page"] { background: #2d3a34; color: #e6e1d3; }
html.is-night .utility, html.is-night .site-footer { background: #0f1412; }
html.is-night .site-nav { background: #1c3525; }
html.is-night .welcome-band { background: #10161a; }
html.is-night .mayor__body, html.is-night .newcomers, html.is-night .notices ul {
  background: #1f2624; border-color: #34403c;
}
html.is-night .bar-heading { background: #22302b; border-bottom-color: #5a6b4a; }
html.is-night .photo img:not(.ruin):not(.smile-layer) { filter: brightness(0.55) saturate(0.4) contrast(1.05); }
html.is-night .festival-card { background: #8d7a2e; }
html.is-night .breadcrumb { color: #9aa39c; }

.night-notice {
  display: none;
  position: sticky; top: 0; z-index: 90;
  background: #0b0f0d; color: #e9e4d6; text-align: center;
  font-style: italic; padding: 0.8rem 1rem; border-bottom: 1px solid #2c3632;
}
html.is-night .night-notice { display: block; }

/* Bare footprints, walking up the page towards the town hall */
.footprints {
  position: absolute; inset: 0; pointer-events: none; z-index: 5; overflow: hidden; display: none;
}
html.is-night .footprints { display: block; }
.footprints svg {
  position: absolute; width: 1.6rem; height: 3rem; fill: rgba(200, 205, 195, 0.14);
  opacity: 0; animation: step-appear 1s ease forwards;
}
@keyframes step-appear { to { opacity: 1; } }

/* ---------- Reduced motion: keep the unease, drop the movement ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  /* No flashing: the photo slowly fades into its ruin and back */
  .photo.is-flickering .ruin {
    animation: ruin-fade 3.2s ease-in-out forwards !important;
    animation-duration: 3.2s !important;
  }
  .photo.is-smiling img { animation: none !important; }
  .book__body { transform: rotateY(-18deg); }
  .edition--uncensored .book:hover .book__body,
  .edition--uncensored:focus-within .book__body { animation: none; }
  .edition--uncensored .book:hover .cover-art__neon { animation: none; opacity: 1; }
  .footprints svg { animation: none; opacity: 1; }
}

/* With the real cover: a red neon wash that sputters over the uncensored book */
.book.has-cover .book__front::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse at 50% 18%, rgba(255, 40, 50, 0.45), transparent 60%);
  mix-blend-mode: screen;
}
.edition--uncensored .book.has-cover:hover .book__front::after,
.edition--uncensored:focus-within .book.has-cover .book__front::after {
  animation: neon-sputter 1.6s steps(1, end) infinite;
}
@media (prefers-reduced-motion: reduce) {
  .edition--uncensored .book.has-cover:hover .book__front::after { animation: none; opacity: 0.6; }
}

@keyframes ruin-fade {
  0% { opacity: 0; }
  35% { opacity: 1; }
  65% { opacity: 1; }
  100% { opacity: 0; }
}
