/* =========================================================
   WHYSOEZ — red / minimal / atmosphere
   ========================================================= */

:root{
  --void:#030303;
  --ash:#c9c4bd;
  --dim:#5a5551;
  --red:#ff1414;
  --red-deep:#5c0000;
  --disp:"Haettenschweiler","Arial Narrow Bold","Impact",sans-serif;
  --mono:"Courier New",ui-monospace,Consolas,monospace;
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}

body{
  background:var(--void);
  color:var(--ash);
  font-family:var(--mono);
  font-size:15px;
  line-height:1.7;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
body.locked{overflow:hidden;height:100vh}

::selection{background:var(--red);color:#fff}
a{color:inherit;text-decoration:none}

/* display type isn't meant to be dragged over — only the
   story copy and the email stay selectable */
.name,.top,.hero__line,.link,.foot span,.gate,.snd{
  user-select:none;-webkit-user-select:none;
}

/* ---------------- scrollbar ---------------- */
html{scrollbar-width:thin;scrollbar-color:#6d0000 #070707}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:#070707}
::-webkit-scrollbar-thumb{
  background:linear-gradient(180deg,var(--red),var(--red-deep));
  border:2px solid #070707;
}
::-webkit-scrollbar-thumb:hover{background:var(--red)}

/* ---------------- ambient layers ---------------- */
.embers{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;opacity:.9}

/* Slow drifting smoke — depth behind the embers.
   No blur filter: these are radial gradients that already fade
   to transparent, so a 70px blur on three viewport-sized layers
   was costing a lot of compositing for no visible difference. */
.smoke{
  position:fixed;z-index:0;pointer-events:none;
  border-radius:50%;will-change:transform;
}
.s1{
  width:120vw;height:70vh;left:-30vw;top:8vh;
  background:radial-gradient(ellipse,rgba(120,0,0,.20) 0%,rgba(60,0,0,.10) 45%,transparent 72%);
  animation:drift1 54s ease-in-out infinite;
}
.s2{
  width:90vw;height:80vh;right:-25vw;top:32vh;
  background:radial-gradient(ellipse,rgba(180,10,10,.13) 0%,rgba(40,0,0,.08) 50%,transparent 74%);
  animation:drift2 71s ease-in-out infinite;
}
.s3{
  width:110vw;height:60vh;left:-10vw;bottom:-10vh;
  background:radial-gradient(ellipse,rgba(90,0,0,.18) 0%,transparent 70%);
  animation:drift3 63s ease-in-out infinite;
}
@keyframes drift1{
  0%,100%{transform:translate(0,0) scale(1)}
  50%{transform:translate(9vw,-5vh) scale(1.16)}
}
@keyframes drift2{
  0%,100%{transform:translate(0,0) scale(1.1)}
  50%{transform:translate(-11vw,6vh) scale(.92)}
}
@keyframes drift3{
  0%,100%{transform:translate(0,0) scale(1)}
  50%{transform:translate(6vw,-4vh) scale(1.2)}
}

.halo{
  position:fixed;top:0;left:0;width:760px;height:760px;z-index:1;pointer-events:none;
  margin:-380px 0 0 -380px;
  background:radial-gradient(circle,rgba(255,20,20,.16) 0%,rgba(255,20,20,.05) 38%,transparent 68%);
  mix-blend-mode:screen;will-change:transform;
}

/* inset only needs to cover the ±2% drift below. At -140% this
   was painting a surface roughly 14x the viewport every frame. */
.grain{
  position:fixed;inset:-15%;z-index:60;pointer-events:none;opacity:.11;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 1.1s steps(4) infinite;
}
@keyframes grain{
  0%{transform:translate(0,0)}25%{transform:translate(-2%,1%)}
  50%{transform:translate(1%,-2%)}75%{transform:translate(-1%,-1%)}100%{transform:translate(0,0)}
}

.vig{
  position:fixed;inset:0;z-index:59;pointer-events:none;
  background:radial-gradient(ellipse 90% 70% at 50% 45%,transparent 30%,rgba(0,0,0,.9) 100%);
}

/* ---------------- cursor ----------------
   the native cursor is ONLY hidden once JS confirms the
   replacement is live (body.cc) — never hide it blind.  */
/* z-index 200+ keeps these above EVERYTHING, gate included —
   the cursor must never be painted under another layer */
.cur-dot,.cur-ghost,.cur-ring{
  position:fixed;top:0;left:0;z-index:202;pointer-events:none;
  border-radius:50%;opacity:0;will-change:transform;
  transition:opacity .35s ease;
}
body.cc .cur-dot,body.cc .cur-ghost,body.cc .cur-ring{opacity:1}
body.cc.out .cur-dot,body.cc.out .cur-ghost,body.cc.out .cur-ring{opacity:0}
body.cc,body.cc a,body.cc button{cursor:none}

.cur-dot{
  width:8px;height:8px;margin:-4px 0 0 -4px;
  background:radial-gradient(circle,#fff 0%,#ffd9d2 28%,var(--red) 70%);
  box-shadow:0 0 12px 3px rgba(255,20,20,.9),0 0 28px 8px rgba(255,20,20,.35);
}
.cur-ghost{
  width:6px;height:6px;margin:-3px 0 0 -3px;
  background:var(--red);filter:blur(1px);
}
body.cc #curG1{opacity:.5}
body.cc #curG2{opacity:.28}
body.cc #curG3{opacity:.14}
#curG2{width:5px;height:5px;margin:-2.5px 0 0 -2.5px}
#curG3{width:4px;height:4px;margin:-2px 0 0 -2px}

.cur-ring{
  width:38px;height:38px;margin:-19px 0 0 -19px;z-index:201;
  border:1px solid rgba(255,20,20,.55);
  transition:opacity .35s ease,width .3s cubic-bezier(.5,0,.2,1),
             height .3s cubic-bezier(.5,0,.2,1),margin .3s cubic-bezier(.5,0,.2,1),
             border-color .3s ease,background .3s ease;
}
body.cc .cur-ring.on{
  width:78px;height:78px;margin:-39px 0 0 -39px;
  border-color:rgba(255,20,20,.95);
  background:rgba(255,20,20,.07);
  box-shadow:0 0 30px rgba(255,20,20,.3),inset 0 0 24px rgba(255,20,20,.18);
}
body.cc .cur-ring.press{
  width:26px;height:26px;margin:-13px 0 0 -13px;border-color:#fff;
}

@media (pointer:coarse){
  .cur-dot,.cur-ghost,.cur-ring,.halo{display:none}
}

/* =========================================================
   GATE
   ========================================================= */
.gate{
  position:fixed;inset:0;z-index:100;overflow:hidden;
  background:radial-gradient(ellipse 80% 60% at 50% 50%,#0d0203 0%,#040404 55%,#020202 100%);
}

/* The detonation: light born inside the word, expanding past
   the edges of the screen. Pure transform + opacity. */
.gate__bloom{
  position:absolute;left:50%;top:48%;
  width:64vmax;height:64vmax;margin:-32vmax 0 0 -32vmax;
  border-radius:50%;pointer-events:none;z-index:3;
  background:radial-gradient(circle,
    rgba(255,255,255,.98) 0%,
    rgba(255,214,205,.72) 22%,
    rgba(255,70,40,.34) 44%,
    rgba(255,20,20,0) 70%);
  opacity:0;transform:scale(.04);will-change:transform,opacity;
}
.gate.gone .gate__bloom{animation:bloom .85s cubic-bezier(.22,.68,.24,1) forwards}
@keyframes bloom{
  0%  {opacity:0;   transform:scale(.04)}
  16% {opacity:1;   transform:scale(.5)}
  100%{opacity:0;   transform:scale(2.9)}
}

.gate__inner{
  position:relative;z-index:2;height:100%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
}
/* the word rushes the viewer as the light takes it */
.gate.gone .gate__inner{
  opacity:0;transform:scale(1.5);
  transition:opacity .3s ease .04s,transform .8s cubic-bezier(.3,0,.15,1);
}
.gate.gone .gate__lit{opacity:1}

/* ---- the wash. Cool white, so it reads as a cut of light
   against everything red rather than a fade to grey. ---- */
.flash{
  position:fixed;inset:0;z-index:150;pointer-events:none;opacity:0;
  background:radial-gradient(circle at 50% 46%,#fff 0%,#f4f8ff 42%,#dae6ff 100%);
  will-change:opacity;
}
body.igniting .flash{animation:wash 1.45s cubic-bezier(.36,0,.16,1) forwards}
@keyframes wash{
  0%  {opacity:0}
  13% {opacity:1}
  27% {opacity:1}
  100%{opacity:0}
}

.gate__aura{
  position:absolute;left:50%;top:50%;width:min(900px,110vw);height:min(900px,110vw);
  transform:translate(-50%,-50%);pointer-events:none;
  background:radial-gradient(circle,rgba(255,20,20,.10) 0%,rgba(90,0,0,.06) 38%,transparent 66%);
  animation:breathe 8s ease-in-out infinite;
}

.gate__tag{
  font-size:9px;letter-spacing:.62em;text-indent:.62em;color:#3a3330;
  margin-bottom:34px;opacity:0;animation:gatein 1s ease .25s forwards;
}

/* dead word — ignites only when you point at it */
.gate__btn{
  position:relative;display:block;background:none;border:0;padding:0;
  font-family:var(--disp);font-weight:400;text-transform:uppercase;
  font-size:clamp(66px,13.5vw,186px);line-height:1;letter-spacing:.04em;
  margin:26px 0 30px;
  opacity:0;transition:opacity .9s ease;
}
.gate:not(.loading) .gate__btn{opacity:1}
.gate.loading .gate__btn{pointer-events:none}

/* sits over the button's slot so the swap costs no layout shift */
.gate__load{
  position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);
  font-size:10px;letter-spacing:.52em;text-indent:.52em;
  color:#4a4441;white-space:nowrap;pointer-events:none;
  transition:opacity .45s ease;
}
.gate:not(.loading) .gate__load{opacity:0}
.gate__btn > span{display:block;white-space:nowrap}
.gate__dark{
  background:linear-gradient(178deg,#5e1a11 0%,#360906 52%,#170303 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
/* glow via drop-shadow so it follows the LETTERS.
   a blurred duplicate underneath just reads as a red box. */
.gate__lit{
  position:absolute;inset:0;width:100%;opacity:0;
  background:linear-gradient(178deg,#fff6f4 0%,#ff2a1a 44%,#8d0000 80%,#2e0000 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 0 24px rgba(255,20,20,.6)) drop-shadow(0 0 64px rgba(255,20,20,.3));
  transition:opacity 1.2s ease;
}
.gate__btn:hover .gate__lit{opacity:1;transition:opacity 1.1s cubic-bezier(.4,0,.5,1)}

.gate__hint{
  font-size:9px;letter-spacing:.44em;text-indent:.44em;color:#2b2725;
  margin-top:34px;opacity:0;transition:opacity .9s ease .3s;
}
.gate:not(.loading) .gate__hint{opacity:1}
@keyframes gatein{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

.gate.gone{pointer-events:none}
.gate.gone .gate__lit{opacity:1}

/* =========================================================
   SOUND TOGGLE
   ========================================================= */
.snd{
  position:fixed;right:26px;bottom:26px;z-index:56;
  display:none;align-items:flex-end;gap:3px;height:20px;
  background:none;border:0;padding:6px;opacity:.45;
  transition:opacity .3s ease;
}
body.entered .snd{display:flex}
.snd:hover{opacity:1}
.snd i{display:block;width:2px;height:5px;background:var(--red);transition:height .3s ease}
.snd.on i{animation:eq .9s ease-in-out infinite}
.snd.on i:nth-child(2){animation-delay:.15s}
.snd.on i:nth-child(3){animation-delay:.3s}
.snd.on i:nth-child(4){animation-delay:.45s}
@keyframes eq{0%,100%{height:4px}50%{height:16px}}
.snd:not(.on) i{height:3px;background:#4a4441}

/* =========================================================
   TOP BAR
   ========================================================= */
.top{
  position:fixed;top:0;left:0;right:0;z-index:50;
  display:flex;justify-content:space-between;align-items:center;
  padding:26px 30px;font-size:10px;letter-spacing:.42em;color:var(--dim);
}
.top::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,rgba(3,3,3,.92) 0%,rgba(3,3,3,.6) 55%,transparent 100%);
}
.top__mark{color:var(--ash)}

/* =========================================================
   HERO
   ========================================================= */
.hero{
  position:relative;z-index:2;min-height:100svh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:0 24px;text-align:center;
}

.hero__aura{
  position:absolute;left:50%;top:48%;width:min(1100px,120vw);height:min(1100px,120vw);
  transform:translate(-50%,-50%);pointer-events:none;
  background:radial-gradient(circle,rgba(255,20,20,.13) 0%,rgba(92,0,0,.09) 34%,transparent 62%);
  animation:breathe 9s ease-in-out infinite;
}
@keyframes breathe{
  0%,100%{transform:translate(-50%,-50%) scale(1);opacity:.85}
  50%{transform:translate(-50%,-50%) scale(1.14);opacity:1}
}

/* ---- the name: dark by default, lights up on hover ----
   No idle flicker here. A periodic dip read as a rendering
   glitch rather than an effect — the word should sit dead
   still until the cursor touches it. */
.name{
  position:relative;font-family:var(--disp);font-weight:400;
  font-size:clamp(88px,19vw,300px);line-height:.85;
  letter-spacing:-.015em;text-transform:uppercase;
  will-change:transform;
}
.name > span{display:block}

/* the dead, unlit state */
.name__dark{
  background:linear-gradient(178deg,#5b1a12 0%,#3a0a06 45%,#1c0302 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* WHOLE word ignites while the cursor is over it.
   glow is drop-shadow, not a blurred duplicate, so the light
   takes the shape of the letters instead of a rectangle. */
.name__lit{
  position:absolute;inset:0;width:100%;opacity:0;
  background:linear-gradient(178deg,#fff2f0 0%,#ff2a1a 42%,#8d0000 78%,#2e0000 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 0 26px rgba(255,20,20,.55)) drop-shadow(0 0 72px rgba(255,20,20,.28));
  transition:opacity 1.6s ease;                          /* cooling back down */
}
.name:hover .name__lit{
  opacity:1;
  transition:opacity 1.5s cubic-bezier(.4,0,.5,1);       /* filament warming up */
}

/* NOTE: a cursor-masked highlight layer used to live here. A
   mask on the parent breaks `background-clip:text` on its
   children — the gradient paints its whole box instead of the
   glyphs, which shows up as a rectangle behind the word. Don't
   reintroduce it. The name is now built exactly like ENTER. */

.hero__line{
  margin-top:34px;font-size:11px;letter-spacing:.5em;color:var(--dim);
  text-transform:uppercase;
}
/* The site settles out of the light — a slow camera easing to
   rest rather than a slide. Expo-out is what makes it feel
   expensive: fast off the mark, long quiet landing.
   (never target .name here — JS owns its transform on scroll) */
body.entered .hero{animation:arrive 1.7s cubic-bezier(.16,1,.3,1) .26s both}
@keyframes arrive{
  from{opacity:0;transform:scale(1.075)}
  to  {opacity:1;transform:none}
}
body.entered .hero__line{animation:riseIn 1.2s ease .72s both}
body.entered .top{animation:riseIn 1s ease .86s both}
/* its own keyframe — .scroll is centred with translateX(-50%),
   which plain riseIn would wipe out */
body.entered .scroll{animation:riseInCentred 1s ease 1s both}
@keyframes riseInCentred{
  from{opacity:0;transform:translateX(-50%) translateY(16px)}
  to  {opacity:1;transform:translateX(-50%)}
}
body.entered .hero__aura{animation:breathe 9s ease-in-out infinite,flare 1.6s ease .3s both}
@keyframes riseIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes flare{from{opacity:0}55%{opacity:1.5}to{opacity:1}}

/* ---- scroll cue: the site's own tiny-mono voice, no red ---- */
.scroll{
  position:absolute;bottom:38px;left:50%;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:11px;
  font-size:9px;letter-spacing:.5em;text-indent:.5em;color:#4a4441;
  transition:opacity .6s ease,color .4s ease;
}
.scroll:hover{color:#b9b2aa}
.scroll__arrow{
  font-size:13px;letter-spacing:0;text-indent:0;line-height:1;
  animation:nudge 2.6s ease-in-out infinite;
}
@keyframes nudge{
  0%,100%{transform:translateY(0);opacity:.4}
  50%{transform:translateY(7px);opacity:1}
}
/* gets out of the way the moment it's been understood */
body.scrolled .scroll{opacity:0;pointer-events:none}

/* =========================================================
   STORY
   ========================================================= */
.story{position:relative;z-index:2;max-width:760px;margin:0 auto;padding:200px 24px}
.story__p{font-size:clamp(20px,2.6vw,30px);line-height:1.65;color:#e6e1da;margin-bottom:56px}
.story__p.dim{color:var(--red);font-size:clamp(16px,2vw,22px);letter-spacing:.04em}

/* =========================================================
   LINKS
   ========================================================= */
.links{position:relative;z-index:2;max-width:900px;margin:0 auto;padding:0 24px 200px}
.link{
  position:relative;display:flex;align-items:center;justify-content:space-between;
  padding:34px 6px;border-top:1px solid #171313;
  transition:padding .45s cubic-bezier(.6,0,.2,1);
}
.link:last-child{border-bottom:1px solid #171313}
.link__name{
  font-family:var(--disp);font-size:clamp(34px,5.6vw,72px);line-height:1;
  color:#7d7770;transition:color .4s,text-shadow .4s;
}
.link__go{font-size:16px;color:#2e2a28;transition:color .4s,transform .45s cubic-bezier(.6,0,.2,1)}
.link:hover{padding-left:26px}
.link:hover .link__name{color:#fff;text-shadow:0 0 26px rgba(255,20,20,.85),0 0 60px rgba(255,20,20,.45)}
.link:hover .link__go{color:var(--red);transform:translateX(10px)}

/* =========================================================
   FOOTER
   ========================================================= */
.foot{
  position:relative;z-index:2;
  display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;
  padding:30px;border-top:1px solid #141010;
  font-size:10px;letter-spacing:.34em;color:var(--dim);
}
.foot a:hover{color:var(--red)}

/* =========================================================
   REVEAL
   ========================================================= */
.reveal{
  opacity:0;transform:translateY(26px);filter:blur(9px);
  transition:opacity 1.1s ease,transform 1.1s cubic-bezier(.5,0,.15,1),filter 1.1s ease;
  transition-delay:var(--d,0s);
}
.reveal.in{opacity:1;transform:none;filter:blur(0)}

/* =========================================================
   SMALL SCREENS
   ========================================================= */
@media(max-width:640px){
  .top{padding:20px 18px;font-size:9px;letter-spacing:.28em}
  .hero__line{letter-spacing:.34em}
  .story{padding:130px 24px}
  .story__p{margin-bottom:44px}
  .links{padding-bottom:130px}
  .link{padding:26px 4px}
  .foot{flex-direction:column;align-items:flex-start;gap:10px}
  .snd{right:18px;bottom:18px}
  .gate__hint{letter-spacing:.3em;text-indent:.3em}
  .gate__tag{letter-spacing:.45em;text-indent:.45em}
}

/* prefers-reduced-motion is intentionally NOT honoured — see the
   note at the top of script.js. Every effect runs for every
   visitor. Re-adding a reduce block here would also require
   flipping the reduced flag in script.js. */
