:root{
  --bg:#0c0808;          /* warm off-black */
  --fg:#e8dfd2;          /* bone */
  --ghost:#2c2320;
  --red:#8f0a0a;         /* oxblood, not neon */
  --wet:rgba(255,96,72,.5);
  box-sizing:border-box;
  padding-top:env(safe-area-inset-top,0px);
  padding-bottom:env(safe-area-inset-bottom,0px);
}
html{scroll-padding-top:env(safe-area-inset-top,0px);background:#0c0808}
*,*::before,*::after{box-sizing:inherit}
body{
  margin:0;background:var(--bg);color:var(--fg);
  font-family:"Cormorant Garamond","Iowan Old Style",Georgia,serif;
  overflow-x:hidden;position:relative;
}
/* the ending is a cut: no transition at all */
body.inverted{--bg:#e8dfd2;--fg:#0c0808;--ghost:#cfc4b5}
main.jolt{animation:jolt .2s steps(2) 1}
@keyframes jolt{0%{transform:translate(-7px,3px)}50%{transform:translate(5px,-4px)}100%{transform:none}}

/* film grain */
body::before{content:"";position:fixed;inset:-10%;z-index:6;pointer-events:none;opacity:.09;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  animation:grain .9s steps(1) infinite}
@keyframes grain{25%{transform:translate(-3%,2%)}50%{transform:translate(2%,-3%)}75%{transform:translate(-2%,-1%)}}

/* pulse in the ears: vignette that beats faster as you read */
#vig{position:fixed;inset:0;z-index:4;pointer-events:none;
  background:radial-gradient(ellipse at center,transparent var(--vs),rgba(45,0,0,.9) 100%);
  animation:beat 1.6s infinite}
@keyframes beat{0%,100%{opacity:.35}12%{opacity:.85}24%{opacity:.4}38%{opacity:.7}60%{opacity:.35}}
body.inverted #vig{display:none}

/* the drip: swells, stalls, lets go */
#drip{position:fixed;top:0;right:clamp(10px,3vw,36px);width:2px;height:0;background:var(--red);z-index:5;pointer-events:none;
  transition:height 1.3s cubic-bezier(.3,0,.1,1)}
#drip::after{content:"";position:absolute;left:50%;bottom:-10px;width:9px;height:14px;transform:translateX(-50%);background:var(--red);border-radius:50% 50% 50% 50% / 30% 30% 70% 70%}
body.inverted #drip{display:none}

/* stanzas */
.stanza{min-height:100svh;display:flex;align-items:center;padding:16vh clamp(24px,8vw,120px)}
.stanza:nth-of-type(even){justify-content:flex-end}
.stanza p{margin:0;max-width:24em;font-weight:300;font-size:clamp(1.7rem,4.4vw,3.4rem);line-height:1.28;letter-spacing:-.005em}

/* words snap on, they don't fade */
.w{display:inline-block;color:var(--ghost)}
.w.on{color:var(--fg)}
.w.on:not([data-fx]){animation:flinch var(--j,.25s) steps(4,end) both}
@keyframes flinch{
  0%{opacity:.15;transform:translate(-.04em,.05em) skewX(-7deg)}
  55%{opacity:1;transform:translate(.02em,-.02em) skewX(2deg)}
  100%{opacity:1;transform:none}}

/* blood: dark, ragged edges, a thin wet highlight */
.w.r.on{color:var(--blood);font-style:italic;font-weight:500;text-shadow:0 1px 0 var(--wet);filter:url(#bleed)}
.end .w.r.on{text-shadow:none}

/* words that do what they mean */
.retreat{transition:transform .45s cubic-bezier(.2,.9,.3,1)}
.c{display:inline-block}
.corrode.on .c{animation:rot 6s ease-in forwards;animation-delay:calc(var(--d)*4s)}
@keyframes rot{to{opacity:var(--o);transform:translateY(.05em) scaleY(.78)}}
.choke.on{letter-spacing:-.075em;animation:choke .7s cubic-bezier(.9,0,.1,1) both}
@keyframes choke{from{letter-spacing:.32em}}
.sag.on{transform-origin:0 0;animation:sag 4.2s ease-in-out infinite alternate}
@keyframes sag{from{transform:rotate(-3deg)}to{transform:rotate(5deg) translateY(.06em)}}
.drip{position:relative}
.drip.on::after{content:"";position:absolute;left:52%;top:78%;width:.14em;height:.22em;background:var(--red);
  border-radius:50% 50% 50% 50% / 30% 30% 70% 70%;animation:fall 3.4s cubic-bezier(.5,0,1,.6) infinite}
@keyframes fall{0%{transform:translateY(0) scale(.2);opacity:0}22%{transform:translateY(0) scale(1);opacity:1}100%{transform:translateY(2.8em) scale(1);opacity:0}}
.slice{position:relative;--sx:.07em}
.slice.on{color:transparent;text-shadow:none;filter:none}
.slice.on::before,.slice.on::after{position:absolute;left:0;top:0;white-space:nowrap;color:var(--blood);content:attr(data-w);text-shadow:none}
.slice.on::before{clip-path:inset(0 0 56% 0);transform:translateX(calc(var(--sx)*-1))}
.slice.on::after{clip-path:inset(47% 0 0 0);transform:translateX(var(--sx))}
.slice.shame{--sx:.16em}
.narrow p{max-width:24em;font-size:clamp(1.15rem,2.3vw,1.7rem);line-height:1.55;letter-spacing:.01em}
.drift{display:block;text-align:right;margin-top:.3em}
.drift .w{display:block;line-height:1.7;padding-right:calc(var(--i)*.35em)}
.drift .w:last-child{font-size:1.35em}

.end{min-height:100svh;display:flex;flex-direction:column;justify-content:center;padding:0 clamp(24px,8vw,120px)}
.end p{margin:0;font-weight:500;font-style:italic;font-size:clamp(2.6rem,10vw,9rem);line-height:.95;letter-spacing:-.025em}
.bar{margin-top:clamp(24px,6vh,60px);height:4px;width:100%;background:var(--red);clip-path:inset(0 100% 0 0)}
.end.seen .bar{clip-path:inset(0 0 0 0);transition:clip-path .16s steps(6)}
footer{height:30svh}

@media (prefers-reduced-motion:reduce){
  .w.on,.w.on:not([data-fx]),.corrode.on .c,.choke.on,.sag.on,.drip.on::after,#vig,body::before,main.jolt{animation:none}
  #drip{transition:none}
  .end.seen .bar{transition:none}
}
@media (max-width:600px){.stanza p{max-width:none}}

/* ---- registered props: let colour, vignette and bites animate ---- */
@property --blood{syntax:"<color>";inherits:true;initial-value:#e0201a}
@property --vs{syntax:"<percentage>";inherits:false;initial-value:42%}
@property --b{syntax:"<length>";inherits:false;initial-value:0px}

/* blood ages: arterial when the word lands, dry and brown nine seconds later */
.w.r{--blood:#e0201a;transition:--blood 9s cubic-bezier(.2,.7,.3,1)}
.w.r.on{--blood:#6e0d0b}
.w.r:not(.on){transition-duration:.2s}

/* stillness: the vignette closes in, words you linger on die */
#vig{transition:--vs 6s}
body.still #vig{--vs:8%}
.w.on.decay{color:var(--ghost);transition:color 4s}

/* the held breath before the cut */
body.hush #vig,body.hush #drip,body.hush #stains,body.hush main{visibility:hidden}

/* marks on the page: drops, smears, fingerprints of the reader */
#stains{position:absolute;inset:0;z-index:3;pointer-events:none;overflow:hidden}
.st{position:absolute;background:#6e0d0b;animation:stain 9s ease-out both}
@keyframes stain{0%{scale:.2;background:#e8241b}6%{scale:1}100%{background:#6e0d0b}}

/* words with bodies */
.gnaw.on{--b:.1em;--gm:radial-gradient(circle at 4% 15%,transparent var(--b),#000 calc(var(--b) + .5px)),radial-gradient(circle at 55% 100%,transparent var(--b),#000 calc(var(--b) + .5px)),radial-gradient(circle at 96% 70%,transparent var(--b),#000 calc(var(--b) + .5px));
  -webkit-mask-image:var(--gm);mask-image:var(--gm);-webkit-mask-composite:source-in;mask-composite:intersect;animation:gnaw 5s ease-in forwards}
@keyframes gnaw{from{--b:0px}to{--b:.14em}}
.wound,.crack{position:relative}
.wound.on::after{content:"";position:absolute;left:-4%;width:108%;top:56%;height:0;border-radius:50%;background:#c4160f;box-shadow:0 0 .14em #ff3a26;animation:wound 2.4s cubic-bezier(.3,0,.2,1) .5s forwards}
@keyframes wound{to{height:.1em}}
.crack.on::after{content:"";position:absolute;left:0;bottom:-.08em;width:100%;height:.1em;background:var(--red);transform:scaleX(0);transform-origin:0 50%;
  clip-path:polygon(0 40%,10% 10%,20% 90%,34% 20%,46% 80%,60% 15%,74% 85%,88% 30%,100% 55%,100% 65%,88% 45%,74% 100%,60% 30%,46% 95%,34% 40%,20% 100%,10% 30%,0 60%);animation:draw 1.8s steps(10) .3s forwards}
@keyframes draw{to{transform:scaleX(1)}}
.gleam.on{color:transparent;background:linear-gradient(100deg,var(--fg) 42%,#fff 50%,var(--fg) 58%) 150% 0/260% 100%;-webkit-background-clip:text;background-clip:text;animation:gleam 3.6s ease-in-out infinite}
@keyframes gleam{to{background-position:-50% 0}}
.avert.on{animation:avert 3s ease-in-out .3s forwards}
@keyframes avert{to{transform:translate(0,-.12em) rotate(-5deg);opacity:.4}}
.starve.on{animation:starve 8s ease-out forwards}
@keyframes starve{to{letter-spacing:.14em;opacity:.45}}

@media (prefers-reduced-motion:reduce){
  .gnaw.on,.wound.on::after,.crack.on::after,.gleam.on,.avert.on,.starve.on,.st{animation:none}
  .crack.on::after{transform:none}.wound.on::after{height:.1em}.w.r{transition:none}
}

/* gashes and runners for "mutilated failure" */
.st.sl{transform-origin:0 50%;animation:swipe 9s ease-out both}
@keyframes swipe{0%{scale:0 1;background:#e8241b}2%{scale:1 1}100%{background:#6e0d0b}}
.st.rn{animation:stain 9s ease-out both,run 5s cubic-bezier(.4,0,.8,1) forwards}
@keyframes run{to{height:var(--h)}}
@media (prefers-reduced-motion:reduce){.st.sl,.st.rn{animation:none}}
