/* NoENT! site, direction A "Signal": a calm app-marketing site in the game's skin.
   Shared by index.html and cards.html. Hand-written, no frameworks. */

@font-face{font-family:'Orbitron';font-weight:900;font-display:swap;src:url(/fonts/Orbitron-Black.ttf)}
@font-face{font-family:'Chakra Petch';font-weight:400;font-display:swap;src:url(/fonts/ChakraPetch-Regular.ttf)}
@font-face{font-family:'Chakra Petch';font-weight:600;font-display:swap;src:url(/fonts/ChakraPetch-SemiBold.ttf)}
@font-face{font-family:'Chakra Petch';font-weight:700;font-display:swap;src:url(/fonts/ChakraPetch-Bold.ttf)}
@font-face{font-family:'Share Tech Mono';font-display:swap;src:url(/fonts/ShareTechMono-Regular.ttf)}

:root{
  --ground:#06080B; --ground2:#0C1016; --lift:#111722; --edge:#1A2230;
  --text:#E6EDF5; --soft:#C9D3DF; --dim:#7D8A9C; --faint:#3B4656; --white:#F4F7FF;
  --magenta:#FF2E88; --cyan:#2EF2FF; --signal:#3DFF8A; --violet:#B26BFF; --indigo:#7C8CFF;
  --amber:#FF9F1C; --gold:#FFE14D; --red:#FF3B3B; --green:#9BFF3D;
  --sans:'Chakra Petch',system-ui,sans-serif; --mono:'Share Tech Mono',ui-monospace,monospace;
  --wrap:1120px; --gut:16px; --r:18px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
html,body{margin:0;background:var(--ground);color:var(--text)}
/* Mock-up B's faded grid under everything; the hero paints solid ground over it, so the rain is
   the hero's alone and the grid fades in below it (Dean, 6 Oct 2026). */
body{background:
  linear-gradient(rgba(46,242,255,.035) 1px,transparent 1px) 0 0/28px 28px,
  linear-gradient(90deg,rgba(46,242,255,.035) 1px,transparent 1px) 0 0/28px 28px,
  var(--ground)}
.gridfade{position:relative;height:0;pointer-events:none}
.gridfade::before{content:"";position:absolute;left:0;right:0;top:0;height:220px;
  background:linear-gradient(var(--ground),transparent)}
body{font-family:var(--sans);font-size:17px;line-height:1.6;overflow-x:hidden;-webkit-font-smoothing:antialiased}
img{max-width:100%;display:block}
a{color:inherit}
h1,h2,h3{font-weight:700;line-height:1.1;margin:0;color:var(--white);letter-spacing:-.01em}
p{margin:0}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gut)}
@media (min-width:720px){:root{--gut:32px}}
.skip{position:absolute;left:-999px;top:8px;background:var(--white);color:var(--ground);padding:10px 14px;border-radius:8px;z-index:100}
.skip:focus{left:8px}
:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}

/* ---------- header: slim, sticky, logo and a pill nav ---------- */
.top{position:sticky;top:0;z-index:50;background:rgba(6,8,11,.78);
  -webkit-backdrop-filter:saturate(1.4) blur(14px);backdrop-filter:saturate(1.4) blur(14px);
  border-bottom:1px solid transparent;transition:border-color .3s}
.top.scrolled{border-bottom-color:var(--edge)}
.top .wrap{display:flex;align-items:center;gap:16px;height:64px}
.brand{display:flex;align-items:center;min-height:44px;text-decoration:none}
.brand .glitch-logo{font-size:21px;line-height:1}
.tagline{display:block;font-family:var(--mono);letter-spacing:.4em;color:var(--dim);text-transform:uppercase}
.top nav{margin:0 auto}
.pills{display:none;margin:0;padding:4px;gap:2px;list-style:none;
  background:var(--ground2);border:1px solid var(--edge);border-radius:99px}
.pills a{display:block;padding:8px 16px;border-radius:99px;font-size:14px;font-weight:600;
  color:var(--dim);text-decoration:none;transition:color .2s,background .2s}
.pills a:hover{color:var(--text)}
.pills a[aria-current=page]{color:var(--white);background:var(--lift)}
.top .get{display:none;margin-left:auto;padding:9px 16px;border-radius:99px;font-size:14px;font-weight:600;
  text-decoration:none;color:var(--ground);background:var(--white)}
.menu{margin-left:auto;width:44px;height:44px;display:grid;place-items:center;border:1px solid var(--edge);
  border-radius:12px;background:var(--ground2);color:var(--text);cursor:pointer}
.menu svg{width:20px;height:20px}
.drawer{display:none;border-top:1px solid var(--edge);background:rgba(6,8,11,.96)}
.drawer.open{display:block}
.drawer ul{list-style:none;margin:0;padding:8px var(--gut) 16px}
.drawer a{display:flex;align-items:center;min-height:48px;font-weight:600;color:var(--soft);text-decoration:none;
  border-bottom:1px solid var(--edge)}
.drawer li:last-child a{border-bottom:0}
.drawer a[aria-current=page]{color:var(--cyan)}
@media (max-width:879px){.top nav:not(.drawer){display:none}}
@media (min-width:880px){
  .pills{display:flex}.top .get{display:block;margin-left:0}.menu,.drawer,.drawer.open{display:none}
}

/* ---------- type helpers ---------- */
.kicker{font-family:var(--mono);font-size:13px;letter-spacing:.24em;text-transform:uppercase;color:var(--cyan)}
.kicker.m{color:var(--magenta)}.kicker.s{color:var(--signal)}
.lede{color:var(--dim);font-size:18px;line-height:1.6}
.accent{color:var(--cyan)}.hot{color:var(--magenta)}
.mono{font-family:var(--mono)}

section{position:relative}
.sec{padding:96px 0}
@media (max-width:719px){.sec{padding:72px 0}}
.sec-head{text-align:center;max-width:640px;margin:0 auto 56px}
.sec-head h2{font-size:clamp(30px,5vw,46px);margin:14px 0 16px}

/* ---------- store badge placeholders: App Store pre-order and Google Play pre-register ---------- */
.store{display:flex;flex-direction:column;align-items:center;gap:10px}
.badge{display:inline-flex;align-items:center;gap:10px;min-height:52px;padding:8px 20px 8px 16px;border-radius:12px;
  background:#000;border:1px solid #2c3442;color:#fff;text-decoration:none;user-select:none;transition:border-color .15s}
.badge[href]:hover{border-color:var(--cyan)}
.badge[href]:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
.badge[aria-disabled="true"]{cursor:not-allowed}
.badge svg{width:26px;height:30px;flex:none}
.badge span{display:flex;flex-direction:column;line-height:1.05;font-family:-apple-system,system-ui,sans-serif}
.badge small{font-size:11px;letter-spacing:.02em}
.badge b{font-size:22px;font-weight:600;letter-spacing:-.01em}
.stores{display:flex;flex-wrap:wrap;justify-content:center;gap:12px}
.soon{font-family:var(--mono);font-size:11px;letter-spacing:.2em;color:var(--signal);
  border:1px solid color-mix(in srgb,var(--signal) 35%,transparent);border-radius:99px;padding:3px 10px}

/* ---------- phones: a CSS frame round the raw captures ---------- */
.phone{position:relative;width:var(--w,260px);aspect-ratio:600/1305;padding:9px;border-radius:calc(var(--w,260px) * .17);
  background:linear-gradient(145deg,#232b38,#0b0f15 40%,#151b25);
  box-shadow:0 0 0 1px #2a3341,0 40px 80px -20px rgba(0,0,0,.9),0 0 60px -10px var(--glow,rgba(46,242,255,.18))}
.phone img{width:100%;height:100%;object-fit:cover;border-radius:calc(var(--w,260px) * .14);background:var(--ground)}
.phone::after{content:"";position:absolute;inset:9px;border-radius:calc(var(--w,260px) * .14);pointer-events:none;
  background:linear-gradient(120deg,rgba(255,255,255,.07),transparent 35%)}

/* ---------- reveal on scroll ---------- */
.js .rv{opacity:0;transform:translateY(22px);transition:opacity .8s ease,transform .8s cubic-bezier(.2,.7,.2,1)}
.js .rv.in{opacity:1;transform:none}
.js .rv.d1{transition-delay:.1s}.js .rv.d2{transition-delay:.2s}.js .rv.d3{transition-delay:.3s}

/* ---------- buttons and links ---------- */
.more{display:inline-flex;align-items:center;gap:8px;min-height:44px;font-weight:600;color:var(--cyan);text-decoration:none}
.more::after{content:"";width:8px;height:8px;border-top:2px solid currentColor;border-right:2px solid currentColor;transform:rotate(45deg);transition:transform .2s}
.more:hover::after{transform:translateX(3px) rotate(45deg)}

/* ---------- final CTA ---------- */
.cta{text-align:center;padding:110px 0 120px;border-top:1px solid var(--edge);
  background:radial-gradient(50% 60% at 50% 100%,rgba(255,46,136,.10),transparent 70%),
             radial-gradient(40% 50% at 50% 0%,rgba(46,242,255,.06),transparent 70%)}
.cta h2{font-size:clamp(34px,6vw,60px);margin:14px 0 18px}
.cta .lede{max-width:520px;margin:0 auto 36px}

/* ---------- footer ---------- */
.foot{border-top:1px solid var(--edge);padding:48px 0 40px;color:var(--dim);font-size:14px}
.foot .row{display:flex;flex-wrap:wrap;gap:24px 40px;justify-content:space-between;align-items:flex-start}
.foot .brandline{max-width:300px}
.foot .brandline b{display:block;font-weight:700;font-size:18px;color:var(--white);margin-bottom:6px}
.foot nav{display:flex;flex-wrap:wrap;gap:4px 28px}
.foot nav div{display:flex;flex-direction:column}
.foot nav b{font-family:var(--mono);font-weight:400;font-size:11px;letter-spacing:.2em;color:var(--faint);margin-bottom:4px}
.foot nav a{color:var(--soft);text-decoration:none;min-height:36px;display:flex;align-items:center}
.foot nav a:hover{color:var(--white)}
.foot .legal{margin-top:40px;padding-top:24px;border-top:1px solid var(--edge);display:flex;flex-direction:column;gap:6px;align-items:center;text-align:center}
.foot .legal small{font-size:12.5px;color:var(--faint)}
@media (max-width:719px){.foot nav a{min-height:44px}}

/* the signature row (recipe, verbatim) */
.made{margin:0;font-size:12.5px;color:var(--dim)}
.made a{color:var(--dim)}
.heart-flutter{color:#ff5a6e;position:relative;display:inline-block;cursor:pointer;user-select:none;-webkit-user-select:none;transition:transform .2s cubic-bezier(.4,0,.2,1)}
.heart-flutter:hover{transform:scale(1.18)}
.heart-flutter:focus-visible{outline:2px solid currentColor;outline-offset:3px;border-radius:3px}
.heart-particle{position:absolute;pointer-events:none;opacity:0;left:50%;top:50%}

/* ---------- rain canvases ---------- */
canvas.rain,canvas.coderain{display:block;width:100%;height:100%}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .js .rv{opacity:1;transform:none;transition:none}
  *,*::before,*::after{animation:none!important;transition:none!important}
}

/* The NoENT! glitch logo, a port of the app's GlitchLogo (app/NoENT/NetworkKit.swift) as it plays
   on the home screen. The word is white Orbitron 900 with a fixed cyan split left and magenta split
   right and a magenta glow; over it, a cyan copy and a magenta copy are each cut to a horizontal
   band that jumps on a 2.6 s cycle. The bands, their timings and offsets are the app's g1 and g2
   tables exactly (offsets in the app are points at size 58, so here they are 58ths of an em).
   On arrival it springs in from 0.86, as the home screen does.

   Usage (the page must declare the Orbitron @font-face):
     <h1 class="glitch-logo" data-text="NoENT!">NoENT!</h1>
   Size it with font-size. Add .still to stop the slices (the knockout screen's "not glitching"). */

.glitch-logo{
  position:relative;display:inline-block;margin:0;
  font-family:'Orbitron',sans-serif;font-weight:900;line-height:1.15;white-space:nowrap;
  color:#F4F7FF;
  text-shadow:calc(-3em/58) 0 0 rgba(46,242,255,.85),
              calc(3em/58) 0 0 rgba(255,46,136,.85),
              0 0 calc(26em/58) rgba(255,46,136,.5);
  animation:glitch-logo-in .9s cubic-bezier(.34,1.56,.64,1) .06s both;
}
.glitch-logo::before,.glitch-logo::after{
  content:attr(data-text);position:absolute;left:0;top:0;width:100%;height:100%;
  text-shadow:none;pointer-events:none;
}
.glitch-logo::before{color:#2EF2FF;animation:glitch-logo-g1 2.6s step-end infinite}
.glitch-logo::after{color:#FF2E88;animation:glitch-logo-g2 2.6s step-end infinite}

/* g1: (from, top, bottom, dx) = (0, .18, .58, -4) (.30, .70, .08, -7) (.31, .40, .40, -7) (.60, .05, .85, -3) */
@keyframes glitch-logo-g1{
  0%  {clip-path:inset(18% 0 58% 0);transform:translateX(calc(-4em/58))}
  30% {clip-path:inset(70% 0 8% 0); transform:translateX(calc(-7em/58))}
  31% {clip-path:inset(40% 0 40% 0);transform:translateX(calc(-7em/58))}
  60% {clip-path:inset(5% 0 85% 0); transform:translateX(calc(-3em/58))}
  100%{clip-path:inset(5% 0 85% 0); transform:translateX(calc(-3em/58))}
}
/* g2: (0, .62, .12, 4) (.25, .10, .75, 6) (.26, .48, .30, 6) (.70, .80, .04, 3) */
@keyframes glitch-logo-g2{
  0%  {clip-path:inset(62% 0 12% 0);transform:translateX(calc(4em/58))}
  25% {clip-path:inset(10% 0 75% 0);transform:translateX(calc(6em/58))}
  26% {clip-path:inset(48% 0 30% 0);transform:translateX(calc(6em/58))}
  70% {clip-path:inset(80% 0 4% 0); transform:translateX(calc(3em/58))}
  100%{clip-path:inset(80% 0 4% 0); transform:translateX(calc(3em/58))}
}
/* The home screen's arrival: spring(response .62, damping .62) from scale .86 and opacity 0. */
@keyframes glitch-logo-in{from{opacity:0;transform:scale(.86)}to{opacity:1;transform:scale(1)}}

.glitch-logo.still::before,.glitch-logo.still::after{display:none}
@media (prefers-reduced-motion:reduce){
  .glitch-logo{animation:none}
  .glitch-logo::before,.glitch-logo::after{display:none}
}

/* A locked character's face, encrypted (EncryptedPortrait.swift). See encrypted.js. The amber ring
   and the lock low on the face are RosterView's: low, because centred it landed on the expression. */
.enc{position:relative;display:block;width:100%;height:100%;border-radius:50%;overflow:hidden;
  background:#06080B;box-shadow:inset 0 0 0 3px #FF9F1C}
.enc img{position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated;image-rendering:crisp-edges;
  border-radius:50%}
.enc canvas{position:absolute;inset:0;width:100%;height:100%;opacity:.7;pointer-events:none}
.enc b{position:absolute;left:50%;top:50%;transform:translate(-50%,calc(-50% - var(--s) * .04));
  font:400 max(8px,calc(var(--s) * .075))/1 'Share Tech Mono',ui-monospace,monospace;
  letter-spacing:calc(var(--s) * .016);color:#E6EDF5;background:rgba(6,8,11,.75);padding:3px 6px;border-radius:99px;white-space:nowrap}
.enc i{position:absolute;left:50%;bottom:calc(var(--s) * .07);transform:translateX(-50%);display:block;
  width:calc(var(--s) * .16);height:calc(var(--s) * .18);color:#FF9F1C;
  filter:drop-shadow(0 0 4px rgba(0,0,0,.9)) drop-shadow(0 0 8px rgba(0,0,0,.6))}
.enc i svg{display:block;width:100%;height:100%}
