/* jenjen.club v2 — static landing. Palette/fonts = brand/fyp_style_v1 (approved FYP v3b).
   ink #0D0710 · wine #3A0B24 (soft light only) · pink #FF2D8C (single accent) · bone #F5EEF1 · chrome #B9B2BD
   Fonts: Schibsted Grotesk SemiBold for all text. Pirata One exists only inside the sign picture. */
@font-face{font-family:"Schibsted Grotesk";font-weight:600;font-style:normal;font-display:swap;
  src:url(fonts/SchibstedGrotesk-600-latin.woff2) format("woff2")}
:root{
  --ink:#0D0710;--wine:#3A0B24;--pink:#FF2D8C;--bone:#F5EEF1;--chrome:#B9B2BD;
  --line:rgba(185,178,189,.16);
  --reserve:410px;           /* height kept for links + 18+ (variant B overrides) */
  /* u = css px per 1 unit of the 1080-wide video canvas (same composition as the FYP end card:
     sign 660u wide ~ 61-66% of a phone screen, CTA 62u right under it). Limits: width, height, desktop max. */
  --u:min(calc(100vw / 1000),max(0.3px,calc((100vh - var(--reserve)) / 794)),0.55px);
}
@supports (height:100svh){:root{--u:min(calc(100vw / 1000),max(0.3px,calc((100svh - var(--reserve)) / 794)),0.55px)}}
*{box-sizing:border-box;margin:0;padding:0}
html{background:
    radial-gradient(ellipse 52% calc(var(--u)*520) at 50% calc(var(--u)*430),rgba(58,11,36,.62) 0%,rgba(58,11,36,.22) 55%,rgba(58,11,36,0) 100%) no-repeat,
    var(--ink);touch-action:pan-y pinch-zoom;-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{min-height:100vh;min-height:100svh;color:var(--bone);
  font:600 20px/1.3 "Schibsted Grotesk",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  display:flex;flex-direction:column;align-items:center;overflow-x:hidden;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  background:none}
.sprite{position:absolute;width:0;height:0;overflow:hidden}

/* hero = sign + CTA, same order and proportions as the FYP end card */
.hero{width:100%;flex:none;display:flex;flex-direction:column;align-items:center}
.hang{z-index:1;width:100%;height:calc(var(--u)*700);position:relative;clip-path:inset(-170vh -60vw -400px -60vw)}
.sign{position:absolute;left:50%;top:calc(var(--u)*-60);width:calc(var(--u)*700);height:calc(var(--u)*840);
  margin-left:calc(var(--u)*-350);transform-origin:50% calc(var(--u)*60);
  background:none;border:0;padding:0;cursor:pointer;touch-action:none;pointer-events:none;-webkit-tap-highlight-color:transparent;will-change:transform}
@media (hover:hover) and (pointer:fine){.sign .bd{cursor:grab}.sign .bd:active{cursor:grabbing}}
/* the chain above the pivot is static (it hangs from the ceiling, only the part below the pivot swings): 150vh of tile above the hang.
   One tile period is 96 source px = 64u; the image's chain boundary sits 60u above the pivot, hence the 4u phase (-60u = +4u mod 64u). */
.hang::before{content:"";position:absolute;left:50%;bottom:100%;width:calc(var(--u)*100);margin-left:calc(var(--u)*-50);height:150vh;
  background:url(assets/chain_tile.webp) 0 calc(100% + var(--u)*4)/calc(var(--u)*100) calc(var(--u)*64) repeat-y;pointer-events:none}
/* pull-down overscroll (iOS rubber band): fixed layer one viewport tall right above the viewport = same chain + the continued glow,
   so the revealed area is not empty (html carries ink + the glow too) */
.fx{position:fixed;left:0;right:0;top:-100vh;height:calc(100vh + 3px);z-index:-1;pointer-events:none;
  background:
    url(assets/chain_tile.webp) 50% calc(100% + var(--u)*4 - 3px)/calc(var(--u)*100) calc(var(--u)*64) repeat-y,
    radial-gradient(ellipse 52% calc(var(--u)*520) at 50% calc(100% + var(--u)*430),rgba(58,11,36,.62) 0%,rgba(58,11,36,.22) 55%,rgba(58,11,36,0) 100%) no-repeat}
.sign img{position:absolute;left:0;top:0;display:block;width:100%;height:100%;pointer-events:none;user-select:none;-webkit-user-drag:none}
/* one picture, two layers: chain + upper ring (.cl) and the sign (.bd) that turns around the ring joint (y 628 of 1260 px = 49.84%) */
.sign .sg{position:absolute;left:0;width:100%;height:0;transform-origin:50% 0;display:block}   /* one rigid chain link: anchor at its top joint, the next link hangs from its bottom joint */
.sign .sg.jt{top:calc(var(--u)*59.778)}                    /* last joint = the ring: carries the sign */
.sign .si,.sign .bd{left:0;width:calc(var(--u)*700);height:calc(var(--u)*840)}
.sign .si{clip-path:inset(0)}                              /* (each link clips its own slice inline) */
.sign .bd{top:calc(var(--u)*-418.667);clip-path:inset(49.2% 0 0 0);transform-origin:50% 49.84%;will-change:transform;pointer-events:auto;cursor:pointer;touch-action:none}
.sign:focus-visible{outline:2px solid var(--pink);outline-offset:calc(var(--u)*-20)}
.cta{position:relative;z-index:2;margin-top:calc(var(--u)*32);--halo:0 0 .3em rgba(13,7,16,.55);text-shadow:var(--halo);font-size:max(20px,calc(var(--u)*62));line-height:1.1;letter-spacing:.005em;color:var(--bone);text-align:center}
.cta b{font-weight:600;color:var(--pink)}

/* block sits between CTA and 18+: spacers share the free height 1:1.3 (a bit above optical centre), never less than 36px under the CTA */
main{position:relative;z-index:2;flex:1;width:100%;display:flex;flex-direction:column;align-items:center;padding:0 24px 20px}
main::before,main::after{content:"";display:block;flex:1 1 0}
main::before{min-height:36px;margin-top:calc(var(--u)*20)}
main::after{flex-grow:1.3;min-height:12px}
.links{list-style:none;width:100%}
nav{width:100%;display:flex;justify-content:center}
.links a{position:relative;isolation:isolate;display:flex;color:var(--bone);text-decoration:none;
  -webkit-tap-highlight-color:transparent}
.links a::before{content:"";position:absolute;z-index:-1;opacity:0;transition:opacity .25s ease-out;pointer-events:none}
.links a:hover::before,.links a:active::before,.links a:focus-visible::before{opacity:1}
.links a:focus-visible{outline:0}
.ic{display:block;width:22px;height:22px;flex:none;background:currentColor;-webkit-mask:var(--m) center/contain no-repeat;mask:var(--m) center/contain no-repeat;color:var(--chrome);transition:color .25s ease-out}
.i-fansly{--m:url(assets/icons/fansly.png)}.i-stripchat{--m:url(assets/icons/stripchat.png)}.i-chaturbate{--m:url(assets/icons/chaturbate.png)}.i-x{--m:url(assets/icons/x.svg)}
.ar{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:butt;stroke-linejoin:miter;color:var(--chrome);transition:color .25s ease-out,transform .25s ease-out}
.links a:hover .ic,.links a:active .ic,.links a:focus-visible .ic{color:var(--bone)}
.links a:hover .ar,.links a:active .ar,.links a:focus-visible .ar{color:var(--pink);transform:translate(2px,-2px)}
.age{position:relative;z-index:2;flex:none;padding:6px 0 max(26px,env(safe-area-inset-bottom));font-size:14px;letter-spacing:.12em;color:var(--chrome)}
[hidden]{display:none!important}

/* ---- A: icon left, name, arrow right, hairlines. Fixed 22px icon box, 56px rows ---- */
.va .links{width:calc(var(--u)*655);min-width:260px;max-width:340px}
.va .links li{position:relative}
.va .links li::before,.va .links li:last-child::after{content:"";position:absolute;left:0;right:0;height:1px;background:var(--line);pointer-events:none}
.va .links li::before{top:0}
.va .links li:last-child::after{bottom:0}
.va .links a{align-items:center;gap:16px;height:56px;padding:0 2px}
.va .links a::before{inset:0;background:linear-gradient(90deg,rgba(58,11,36,0),rgba(58,11,36,.75) 45%,rgba(58,11,36,0))}
.va .nm{text-shadow:var(--halo,0 0 .3em rgba(13,7,16,.55));flex:1;font-size:15px;line-height:1;letter-spacing:.06em;color:var(--chrome);transition:color .25s ease-out;transform:translateY(-.5px)}
.va .links a:hover .nm,.va .links a:active .nm,.va .links a:focus-visible .nm{color:var(--bone)}
.va .ar{width:14px;height:14px}
.va .links li:first-child .ar{color:var(--pink)}

/* ---- B: four big icons in a row, label under ---- */
.vb{--reserve:280px}
.vb .links{max-width:400px;display:flex;border-top:1px solid var(--line);padding-top:14px}
.vb .links li{flex:1}
.vb .links a{flex-direction:column;align-items:center;justify-content:center;gap:12px;min-height:96px}
.vb .links a::before{width:76px;height:76px;left:50%;top:50%;margin:-44px 0 0 -38px;border-radius:50%;
  background:radial-gradient(circle,rgba(58,11,36,.9) 0%,rgba(58,11,36,0) 70%)}
.vb .ic{width:32px;height:32px;color:var(--bone)}
.vb .nm{font-size:14px;letter-spacing:.08em;color:var(--chrome)}
.vb .ar{display:none}

/* ---- motion: sign motion is done by app.js (drop, swing, kicks, drag). Here: CTA + links (all play once, transform/opacity only except the pink glow) ---- */
.js:not(.go) .sign{transform:translateY(calc(var(--u)*-800))}
/* CTA: typed char by char after the sign lands (0.5 s, 52 ms per char slot, tiny pop per char). Every char is laid out from the start
   (opacity only), so nothing shifts. "follow." is typed bold (outline, same advance widths) hot pink with a soft glow, holds 0.35 s,
   then one quick snap/punch back to the normal SemiBold pink without glow. Done at ~1.9 s. */
.cta{--t0:.5s;--cs:52ms}
.cta i{font-style:normal;display:inline-block;position:relative}
.cta b{display:inline-block;transform-origin:6% 100%}
.js .cta i{opacity:0}
.js.go .cta i{animation:ty .16s cubic-bezier(.2,.9,.3,1.2) calc(var(--t0) + var(--c)*var(--cs)) both}
.js.go .cta b{animation:snap .24s cubic-bezier(.2,.9,.3,1) 1.7s both}
/* typing caret: a thin pink bar that sits after the char being typed (absolute, so no layout shift); stays .38 s after the last char, then gone */
.cta i::after{content:"";position:absolute;left:100%;margin-left:.02em;top:.14em;bottom:.1em;width:.055em;border-radius:1px;background:var(--pink);opacity:0;pointer-events:none}
.js.go .cta i::after{animation:caret calc(var(--cs)*var(--k,1)) linear calc(var(--t0) + var(--c)*var(--cs)) both}
.js.go .cta i.z::after{animation:caret .4s linear calc(var(--t0) + var(--c)*var(--cs)) both}
@keyframes caret{0%,92%{opacity:1}100%{opacity:0}}
@keyframes ty{0%{opacity:0;transform:translateY(.12em) scale(.65)}55%{opacity:1;transform:translateY(0) scale(1.14)}100%{opacity:1;transform:none}}
@keyframes snap{
  0%{transform:scale(1);-webkit-text-stroke:.03em var(--pink);text-shadow:0 0 .35em rgba(255,45,140,.85),0 0 .9em rgba(255,45,140,.45)}
  35%{transform:scale(1.12);-webkit-text-stroke:.012em var(--pink);text-shadow:0 0 .5em rgba(255,45,140,.9),0 0 1.1em rgba(255,45,140,.5)}
  100%{transform:scale(1);-webkit-text-stroke:0 var(--pink);text-shadow:var(--halo)}
}
/* link rows: after the CTA beat; stagger 105 ms; hairlines draw from the centre; icon/arrow fade in after the label */
.links{--t:1.6s}
.js .links li::before,.js .links li:last-child::after{transform:scaleX(0);transform-origin:50% 50%}
.js .links a{transform:translateY(9px)}
.js .links .nm,.js .links .ic,.js .links .ar{opacity:0}
.js.go .links li::before{animation:ln .5s cubic-bezier(.2,.8,.2,1) calc(var(--t) + var(--i)*105ms) both}
.js.go .links li:last-child::after{animation:ln .5s cubic-bezier(.2,.8,.2,1) calc(var(--t) + var(--i)*105ms + .12s) both}
.js.go .links a{animation:rw .45s cubic-bezier(.2,.8,.2,1) calc(var(--t) + var(--i)*105ms) both}
.js.go .links .nm{animation:fd .4s ease-out calc(var(--t) + var(--i)*105ms) both}
.js.go .links .ic,.js.go .links .ar{animation:fd .4s ease-out calc(var(--t) + var(--i)*105ms + .14s) both}
@keyframes ln{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes rw{from{transform:translateY(9px)}to{transform:none}}
@keyframes fd{from{opacity:0}to{opacity:1}}
/* one soft pink pulse behind the fansly arrow once the last row is in */
.va .links li:first-child a::after{content:"";position:absolute;right:-12px;top:50%;width:38px;height:38px;margin-top:-19px;border-radius:50%;
  background:radial-gradient(circle,rgba(255,45,140,.5) 0%,rgba(255,45,140,0) 68%);opacity:0;pointer-events:none;z-index:-1}
.js.go .va .links li:first-child a::after,.js.go.va .links li:first-child a::after{animation:pulse .9s ease-out 2.55s both}
@keyframes pulse{0%{opacity:0;transform:scale(.6)}35%{opacity:1}100%{opacity:0;transform:scale(1.25)}}
.js .age.rise{opacity:0}
.js.go .age.rise{animation:rise .25s cubic-bezier(.215,.61,.355,1) both;animation-delay:calc(var(--d,0s) + var(--i)*90ms)}
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .js .sign{transform:none!important}
  .cta i::after{display:none!important}
  .js .rise,.js .cta i,.js .cta b,.js .links .nm,.js .links .ic,.js .links .ar{opacity:1!important;animation:none!important;transform:none!important}
  .js .links a{transform:none!important;animation:none!important}
  .js .links li::before,.js .links li:last-child::after{transform:none!important;animation:none!important}
  .va .links li:first-child a::after{animation:none!important;opacity:0}
  .links a::before,.ic,.ar{transition:none}
  .links a:hover .ar{transform:none}
}
