git / moonbite-network / templates/home_final.html · raw

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>MoonBite — Ten coins drop every two minutes. Nobody owns the tap.</title>
<meta name="description" content="No presale. No insiders. No founder allocation. Zero coins given away, ever. Every MoonBite is found by a computer doing the work. Try a guess in your browser.">
<meta property="og:type" content="website">
<meta property="og:site_name" content="MoonBite">
<meta property="og:title" content="Ten coins drop every two minutes. Nobody owns the tap.">
<meta property="og:description" content="No presale. No insiders. Zero coins given away, ever. Try mining in your browser.">
<meta property="og:image" content="https://moonbite.org/static/moonbite-logo.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Ten coins drop every two minutes. Nobody owns the tap.">
<meta name="twitter:description" content="No presale. No insiders. Zero coins given away, ever. Try mining in your browser.">
<meta name="theme-color" content="#0B0D12">
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/static/fonts/moonbite-fonts.css">
<style>
:root{
  --void:#0B0D12; --lift:#11141C; --bone:#F5F2EA; --ash:#8A8580; --gold:#D9A441; --gold-hi:#E8B95C;
  --rule:rgba(245,242,234,.10); --rule-2:rgba(245,242,234,.20);
  --ease:cubic-bezier(.22,1,.36,1);
  --display:'Archivo Black',Inter,system-ui,sans-serif;
  --sans:Inter,system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:ui-monospace,'SF Mono','Cascadia Mono',Consolas,Menlo,monospace;
  --max:1240px; --pad:clamp(18px,4vw,40px);
  color-scheme:dark;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--void);color:var(--bone);font:400 17px/1.6 var(--sans);-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit}
:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:6px}
.skip{position:absolute;left:-9999px;top:8px;background:var(--bone);color:var(--void);padding:8px 14px;border-radius:6px;z-index:100}
.skip:focus{left:8px}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.wrap{max-width:var(--max);margin:0 auto;padding:0 var(--pad)}
.eyebrow{font:700 12px/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--ash)}
.gold{color:var(--gold)}
#sky{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none}
.page{position:relative;z-index:1}


/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:54px;padding:0 26px;border-radius:999px;font:700 16px/1 var(--sans);
  text-decoration:none;cursor:pointer;border:1px solid transparent;transition:transform .12s var(--ease),background .24s var(--ease),border-color .24s var(--ease)}
.btn:active{transform:translateY(1px) scale(.99)}
.btn-gold{background:var(--gold);color:var(--void)}
.btn-gold:hover{background:var(--gold-hi)}
.btn-ghost{background:transparent;color:var(--bone);border-color:var(--rule-2)}
.btn-ghost:hover{border-color:var(--bone)}

section{position:relative;padding:clamp(96px,14vw,168px) 0}
.reveal{opacity:0;transform:translateY(18px);transition:opacity .6s var(--ease),transform .6s var(--ease)}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none;transition:none}}
.big{font:400 clamp(40px,7.6vw,104px)/.98 var(--display);letter-spacing:-.015em;margin:0}
.h2{font:400 clamp(34px,5.4vw,72px)/1.02 var(--display);letter-spacing:-.01em;margin:16px 0 24px;max-width:16ch}
.lede{font-size:clamp(18px,1.7vw,21px);line-height:1.55;max-width:38ch}
.sub{color:var(--ash)}

/* split-flap countdown */
.flap{display:inline-flex;align-items:center;gap:clamp(6px,1vw,10px)}
.flap .d{position:relative;display:inline-grid;place-items:center;width:clamp(48px,7vw,84px);height:clamp(64px,9.4vw,112px);
  background:var(--lift);border:1px solid var(--rule-2);border-radius:12px;font:400 clamp(36px,5.6vw,68px)/1 var(--mono);font-variant-numeric:tabular-nums;color:var(--bone);overflow:hidden}
.flap .d::after{content:"";position:absolute;left:0;right:0;top:50%;height:1px;background:rgba(0,0,0,.55)}
.flap .d.flip{animation:flip .26s var(--ease)}
@keyframes flip{0%{transform:rotateX(0)}45%{transform:rotateX(-80deg);filter:brightness(.6)}100%{transform:rotateX(0)}}
@media (prefers-reduced-motion:reduce){.flap .d.flip{animation:none}}
.flap .colon{font:400 clamp(30px,4.6vw,56px)/1 var(--mono);color:var(--ash)}
.flap.small .d{width:clamp(38px,4.6vw,56px);height:clamp(50px,6vw,74px);font-size:clamp(28px,3.6vw,44px);border-radius:10px}
.flap.small .colon{font-size:clamp(24px,3vw,36px)}

/* 1 hero */
.hero{min-height:calc(100svh - 66px);display:flex;align-items:center;padding:40px 0 72px}
.hero .wrap{width:100%}
.drop{display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-bottom:34px}
.drop .label{display:flex;flex-direction:column;gap:8px}
.drop .label .hint{font-size:13px;color:var(--ash)}
.mark{display:block}
.drop .mark{width:clamp(64px,8vw,96px);height:clamp(64px,8vw,96px);flex:none}
.hero .big{max-width:17ch;font-size:clamp(38px,6.4vw,88px)}
.hero .lede{margin:22px 0 30px}
.hero .drop{margin-bottom:26px}
.actions{display:flex;flex-wrap:wrap;gap:12px}
.score{margin-top:34px;display:flex;flex-wrap:wrap;gap:8px 22px;font-size:14px;color:var(--ash)}
.score b{color:var(--bone);font-weight:400}
.score .zero{color:var(--gold)}

/* 2 manifesto */
.mani .line{display:block}
.mani .r{text-align:right}
.mani .dim{color:var(--ash)}
.rules{margin:clamp(72px,10vw,120px) 0 0;padding:0;list-style:none;border-top:1px solid var(--rule-2)}
.rules li{display:flex;align-items:baseline;gap:clamp(16px,3vw,40px);padding:clamp(16px,2.4vw,26px) 0;border-bottom:1px solid var(--rule)}
.rules .n{font:400 14px/1 var(--mono);color:var(--gold);min-width:2.2em}
.rules .t{font:400 clamp(30px,5.4vw,68px)/1.02 var(--display);letter-spacing:-.01em}
.proofline{margin-top:28px;font-size:14px;color:var(--ash)}
.proofline .mono{color:var(--bone);word-break:break-all}
.proofline a{color:var(--gold);text-underline-offset:3px}

/* 3 play */
.play{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(40px,6vw,88px);align-items:center}
.engine{border:1px solid var(--rule-2);border-radius:22px;background:rgba(17,20,28,.72);padding:clamp(22px,3vw,34px);backdrop-filter:blur(6px)}
.engine .row{display:grid;grid-template-columns:1.35fr 1.15fr .7fr;gap:16px;margin-bottom:24px}
.engine .row .v{white-space:nowrap;word-break:normal;font-size:clamp(18px,2vw,26px)}
.engine .k{display:block;font:700 11px/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--ash);margin-bottom:10px}
.engine .v{font-size:clamp(20px,2.4vw,28px);line-height:1.1;word-break:break-all}
.best{font:400 13px/1.7 var(--mono);color:var(--ash);word-break:break-all;margin:0 0 24px;min-height:3.4em}
.best .z{color:var(--gold)}
.hold{width:100%;min-height:76px;font-size:18px;touch-action:none;user-select:none;-webkit-user-select:none;position:relative;overflow:hidden}
.hold .fill{position:absolute;inset:0;background:rgba(11,13,18,.18);transform-origin:left;transform:scaleX(0)}
.hold[aria-pressed="true"]{background:var(--gold-hi)}
.engine .fine{font-size:13px;color:var(--ash);margin:14px 0 0}

/* the guess card */
.card{margin-top:28px;border-radius:22px;border:1px solid var(--gold);background:linear-gradient(160deg,#151926,#0E1118);padding:26px 26px 22px;display:none}
.card.show{display:block;animation:rise .5s var(--ease)}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.card .top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px}
.card .top svg{width:34px;height:34px}
.card .tag{font:700 11px/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.card .num{font:400 clamp(34px,4.4vw,52px)/1 var(--display);margin:4px 0 6px}
.card .cap{color:var(--ash);font-size:14px;margin:0 0 16px}
.card .hex{font:400 12px/1.6 var(--mono);color:var(--ash);word-break:break-all;margin:0 0 18px;padding-top:14px;border-top:1px solid var(--rule)}
.card .hex .z{color:var(--gold)}
.card .share{display:flex;flex-wrap:wrap;gap:10px}
.card .share .btn{min-height:44px;padding:0 18px;font-size:14px}
.card .share .btn-gold{flex:1 1 auto}

/* 4 live */
.rail{display:flex;margin-top:56px;border-top:1px solid var(--rule-2);border-bottom:1px solid var(--rule-2);overflow-x:auto;scrollbar-width:thin}
.cell{flex:1 0 170px;padding:26px 22px 26px 0}
.cell + .cell{padding-left:22px;border-left:1px solid var(--rule)}
.cell .k{display:block;font:700 11px/1 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--ash);margin-bottom:16px;white-space:nowrap}
.cell .v{font-size:clamp(24px,2.8vw,34px);line-height:1.1;white-space:nowrap}
.cell .v.small{font-size:15px;padding-top:10px}
.livenote{margin-top:16px;font-size:14px;color:var(--ash)}
.live-head{display:flex;align-items:center;gap:18px}
.live-head .mark{width:52px;height:52px}

/* 5 laptop */
.duo{display:grid;grid-template-columns:1fr 1fr;gap:clamp(40px,6vw,96px);align-items:end}
.duo p{font-size:clamp(17px,1.5vw,19px);line-height:1.7;margin:0 0 18px}

/* 6 scarcity */
.halvings{display:grid;grid-template-columns:repeat(5,1fr);margin-top:64px;border-top:1px solid var(--rule-2)}
.halvings div{padding:22px 16px 0 0}
.halvings div + div{padding-left:16px;border-left:1px solid var(--rule)}
.halvings .amt{font:400 clamp(30px,4.4vw,60px)/1 var(--display)}
.halvings .when{display:block;margin-top:12px;font-size:13px;color:var(--ash)}
.halvings .now .amt{color:var(--gold)}
.halvings .now .when{color:var(--bone)}
.capline{margin-top:40px;font-size:15px;color:var(--ash);max-width:62ch}

/* 7 steps */
.steps{list-style:none;margin:56px 0 48px;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:0;border-top:1px solid var(--rule-2)}
.steps li{padding:28px 28px 0 0}
.steps li + li{padding-left:28px;border-left:1px solid var(--rule)}
.steps .n{font:400 clamp(44px,5vw,64px)/1 var(--display);color:var(--gold)}
.steps h3{font:800 21px/1.3 var(--sans);margin:18px 0 10px}
.steps p{color:var(--ash);margin:0;font-size:15px}

/* 8 answers */
.qa{max-width:860px;border-top:1px solid var(--rule-2);margin-top:40px}
.qa h3{margin:0}
.qa button{all:unset;box-sizing:border-box;display:flex;width:100%;justify-content:space-between;gap:20px;padding:22px 0;cursor:pointer;
  border-bottom:1px solid var(--rule);font:700 clamp(18px,1.8vw,22px)/1.35 var(--sans);color:var(--bone)}
.qa button:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.qa .i{font:400 20px/1 var(--mono);color:var(--ash)}
.qa .a{padding:6px 0 26px;border-bottom:1px solid var(--rule);max-width:64ch;color:var(--bone)}
.qa .a p{margin:0}

/* 9 final */
.final{text-align:center}
.final .big{max-width:none}
.final .flap{margin:40px 0 16px}
.final .hint{color:var(--ash);font-size:14px;margin:0 0 36px}
.final .actions{justify-content:center}


@media (max-width:1024px){
}
@media (max-width:820px){
  .play,.duo{grid-template-columns:1fr}
  .steps{grid-template-columns:1fr}
  .steps li,.steps li + li{padding:26px 0 0;border-left:0}
  .steps li + li{margin-top:26px;border-top:1px solid var(--rule)}
  .halvings{grid-template-columns:repeat(3,1fr)}
  .halvings div:nth-child(n+4){display:none}
  .mani .r{text-align:left}
}
@media (max-width:520px){
  body{font-size:16px}
  .actions .btn{flex:1 1 100%}
  .engine .row{grid-template-columns:1fr 1fr}
  .engine .row div:last-child{grid-column:1 / -1}
  .drop{gap:16px}
}
</style>
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<canvas id="sky" aria-hidden="true"></canvas>

<div class="page">
{% include "partials/site_header.html" %}

<main id="main">

<!-- 1 HERO: the drop -->
<section class="hero" aria-labelledby="h-hero">
  <div class="wrap">
    <div class="drop">
      <svg class="mark" viewBox="-150 -150 300 300" role="img" aria-label="MoonBite mark. It takes a bite each time the network finds a block.">
        <defs><mask id="bite-a" maskUnits="userSpaceOnUse" x="-150" y="-150" width="300" height="300">
          <rect x="-150" y="-150" width="300" height="300" fill="#000"/><circle cx="0" cy="0" r="100" fill="#fff"/>
          <circle data-bite cx="67.18" cy="-67.18" r="62" fill="#000"/></mask></defs>
        <rect x="-150" y="-150" width="300" height="300" fill="#F5F2EA" mask="url(#bite-a)"/>
        <rect x="-127.5" y="-40.5" width="255" height="13" fill="#D9A441"/><rect x="-127.5" y="11.5" width="255" height="13" fill="#D9A441"/>
      </svg>
      <div class="label">
        <span class="eyebrow" data-cd-label>Next drop expected in</span>
        <div class="flap" data-cd role="timer" aria-live="off">
          <span class="d">0</span><span class="d">2</span><span class="colon">:</span><span class="d">0</span><span class="d">0</span>
        </div>
        <span class="hint" data-cd-hint>A drop lands every two minutes on average.</span>
      </div>
    </div>
    <h1 id="h-hero" class="big">Ten coins drop every two minutes. Nobody owns the tap.</h1>
    <p class="lede">No presale. No insiders. No founder allocation. Every MoonBite in existence was found by a computer doing the work, and the next ten are up for grabs <span data-lede-when>right now</span>.</p>
    <div class="actions">
      <a class="btn btn-gold" href="/mine">Join the hunt</a>
      <a class="btn btn-ghost" href="#play">Try a guess in your browser</a>
    </div>
    <p class="score mono" aria-live="polite">
      <span>Drop <b data-bind="height">&mdash;</b></span>
      <span><b data-bind="supply">&mdash;</b> MBITE found so far</span>
      <span class="zero">0 given away. Ever.</span>
    </p>
  </div>
</section>

<!-- 2 MANIFESTO -->
<section class="mani" aria-labelledby="h-mani">
  <div class="wrap">
    <h2 id="h-mani" class="big reveal">
      <span class="line">Every other coin</span>
      <span class="line dim">started with a pile.</span>
      <span class="line r">This one</span>
      <span class="line r gold">started with zero.</span>
    </h2>
    <ul class="rules reveal" aria-label="The rules">
      <li><span class="n">01</span><span class="t">No presale.</span></li>
      <li><span class="n">02</span><span class="t">No insiders.</span></li>
      <li><span class="n">03</span><span class="t">No founder allocation.</span></li>
      <li><span class="n">04</span><span class="t">No way in but work.</span></li>
    </ul>
    <p class="proofline reveal">Don't take our word for it. Block zero paid nobody, and anyone can check it on their own node with <span class="mono">getblockhash 0</span>. Who mined the first blocks is public too: <a href="/governance/ADR-006">ADR-006</a>.</p>
  </div>
</section>

<!-- 3 PLAY: the viral loop -->
<section id="play" aria-labelledby="h-play">
  <div class="wrap play">
    <div class="reveal">
      <p class="eyebrow">Try it</p>
      <h2 id="h-play" class="h2">Mining is a lottery where the tickets are math.</h2>
      <p class="lede sub">Your computer guesses a number. Almost every guess loses. The one that comes out small enough wins the next ten coins. Hold the button and watch your browser do the real idea, live.</p>
      <p class="sub" style="font-size:15px;margin-top:20px">Every zero at the front of a guess is sixteen times rarer than the last. See how far you get.</p>
    </div>
    <div class="reveal">
      <div class="engine" id="engine">
        <div class="row">
          <div><span class="k">Your guesses</span><span class="v mono" id="g-n">0</span></div>
          <div><span class="k">Per second</span><span class="v mono" id="g-r">0</span></div>
          <div><span class="k">Best zeros</span><span class="v mono gold" id="g-z">0</span></div>
        </div>
        <p class="best" id="g-best" aria-live="polite">Your closest guess will appear here.</p>
        <button class="btn btn-gold hold" id="g-hold" type="button" aria-pressed="false"><span class="fill" id="g-fill"></span><span id="g-label">Hold to guess</span></button>
        <p class="fine">A toy version of the real puzzle (SHA-256 here, RandomX on the network). It earns nothing and sends nothing anywhere. The real thing is one download away.</p>
      </div>

      <div class="card" id="card" role="region" aria-label="Your guess card">
        <div class="top">
          <span class="tag">MoonBite guess card</span>
          <svg viewBox="-150 -150 300 300" aria-hidden="true"><path fill="#F5F2EA" d="M 13.99 -99.02 A 100 100 0 1 0 99.02 -13.99 A 62 62 0 0 1 13.99 -99.02 Z"/><rect x="-127.5" y="-40.5" width="255" height="13" fill="#D9A441"/><rect x="-127.5" y="11.5" width="255" height="13" fill="#D9A441"/></svg>
        </div>
        <p class="num mono" id="c-n">0</p>
        <p class="cap" id="c-cap">guesses in my browser. Closest: 0 zeros.</p>
        <p class="hex" id="c-hex"></p>
        <div class="share">
          <button class="btn btn-gold" type="button" id="c-share">Share my card</button>
          <a class="btn btn-ghost" id="c-x" href="#" target="_blank" rel="noopener noreferrer">Post on X</a>
          <button class="btn btn-ghost" type="button" id="c-copy">Copy</button>
        </div>
      </div>
    </div>
  </div>
</section>

<!-- 4 LIVE -->
<section aria-labelledby="h-live">
  <div class="wrap">
    <div class="live-head reveal">
      <svg class="mark" viewBox="-150 -150 300 300" aria-hidden="true">
        <defs><mask id="bite-b" maskUnits="userSpaceOnUse" x="-150" y="-150" width="300" height="300">
          <rect x="-150" y="-150" width="300" height="300" fill="#000"/><circle cx="0" cy="0" r="100" fill="#fff"/>
          <circle data-bite cx="67.18" cy="-67.18" r="62" fill="#000"/></mask></defs>
        <rect x="-150" y="-150" width="300" height="300" fill="#F5F2EA" mask="url(#bite-b)"/>
        <rect x="-127.5" y="-40.5" width="255" height="13" fill="#D9A441"/><rect x="-127.5" y="11.5" width="255" height="13" fill="#D9A441"/>
      </svg>
      <p class="eyebrow">Live, right now</p>
    </div>
    <h2 id="h-live" class="h2 reveal">It is running whether or not you are watching.</h2>
    <p class="lede sub reveal">These numbers come straight from the network. The moon takes a bite every time someone, somewhere, finds a block.</p>
    <div class="rail reveal" aria-live="polite">
      <div class="cell"><span class="k">Drops so far</span><span class="v mono gold" data-bind="height">&mdash;</span></div>
      <div class="cell"><span class="k">Coins found</span><span class="v mono" data-bind="supply">&mdash;</span></div>
      <div class="cell"><span class="k">Coins given away</span><span class="v mono">0</span></div>
      <div class="cell"><span class="k">Drops per day</span><span class="v mono">720</span></div>
      <div class="cell"><span class="k">Latest block</span><span class="v mono small" data-bind="tipshort" id="tipcell">&mdash;</span></div>
    </div>
    <p class="livenote" id="livenote">Connecting to the network&hellip;</p>
  </div>
</section>

<!-- 5 LAPTOP -->
<section aria-labelledby="h-laptop">
  <div class="wrap duo">
    <h2 id="h-laptop" class="h2 reveal" style="margin:0">Built so your laptop still counts.</h2>
    <div class="reveal">
      <p>Most coins were eaten by warehouses full of custom chips. Ordinary people got priced out of their own network.</p>
      <p>MoonBite runs on RandomX, a puzzle designed for the kind of processor already sitting on your desk. Custom hardware has a small edge here, not a crushing one.</p>
      <p class="sub">That balance has to be defended, not assumed, and we say so plainly.</p>
    </div>
  </div>
</section>

<!-- 6 SCARCITY -->
<section aria-labelledby="h-scarce">
  <div class="wrap">
    <h2 id="h-scarce" class="h2 reveal">The drop only ever gets smaller.</h2>
    <p class="lede sub reveal">Every 1,650,000 blocks, about six years, the drop is cut in half. No vote can change it. A node that tried would be ignored by every other node.</p>
    <div class="halvings reveal">
      <div class="now"><span class="amt mono">10</span><span class="when">now</span></div>
      <div><span class="amt mono">5</span><span class="when">around 2032</span></div>
      <div><span class="amt mono">2.5</span><span class="when">around 2039</span></div>
      <div><span class="amt mono">1.25</span><span class="when">around 2045</span></div>
      <div><span class="amt mono">0.625</span><span class="when">around 2051</span></div>
    </div>
    <p class="capline reveal">About 33,000,000 MBITE will ever exist. After the last drop, miners are paid by transaction fees alone, a question every fixed-supply coin still has to answer. Ours is written down in <a href="/governance">ADR-011</a>.</p>
  </div>
</section>

<!-- 7 START -->
<section aria-labelledby="h-start">
  <div class="wrap">
    <h2 id="h-start" class="h2 reveal">Three steps. About ten minutes.</h2>
    <ol class="steps reveal">
      <li><span class="n">1</span><h3>Get the wallet.</h3><p>Free, open source, and yours alone. Nobody, including us, can touch what is in it.</p></li>
      <li><span class="n">2</span><h3>Write down twelve words.</h3><p>On paper. They are your whole account. No email, no password reset, no support desk.</p></li>
      <li><span class="n">3</span><h3>Run the miner.</h3><p>One command. Your computer starts guessing, and every block it wins pays you directly.</p></li>
    </ol>
    <div class="actions reveal">
      <a class="btn btn-gold" href="/mine">Start mining</a>
      <a class="btn btn-ghost" href="/get-wallet">Get the wallet</a>
    </div>
  </div>
</section>

<!-- 8 STRAIGHT ANSWERS -->
<section aria-labelledby="h-qa">
  <div class="wrap">
    <h2 id="h-qa" class="h2 reveal">Straight answers.</h2>
    <div class="qa reveal" id="qa">
      <h3><button type="button" aria-expanded="false" aria-controls="a1">What is it worth?<span class="i" aria-hidden="true">+</span></button></h3>
      <div class="a" id="a1" hidden><p>Nothing official. No exchange lists it and it has no price, and it may never have one. Mine it because it is interesting, not because anyone promised you money. Anyone offering to sell you MoonBite is lying.</p></div>
      <h3><button type="button" aria-expanded="false" aria-controls="a2">Is this a scam?<span class="i" aria-hidden="true">+</span></button></h3>
      <div class="a" id="a2" hidden><p>Scams need you to buy something. There is nothing to buy here, and the code is public for anyone to read.</p></div>
      <h3><button type="button" aria-expanded="false" aria-controls="a3">Who made it?<span class="i" aria-hidden="true">+</span></button></h3>
      <div class="a" id="a3" hidden><p>Anonymous builders. You don't have to trust names: the rules are enforced by every node, and any early mining by the builders is disclosed in ADR-006.</p></div>
      <h3><button type="button" aria-expanded="false" aria-controls="a4">Isn't it just a Litecoin copy?<span class="i" aria-hidden="true">+</span></button></h3>
      <div class="a" id="a4" hidden><p>The engine is a fork of Litecoin Core, which is a fork of Bitcoin Core. On purpose: money code is the worst place to be original. What changed is listed for developers, line by line.</p></div>
      <h3><button type="button" aria-expanded="false" aria-controls="a5">Doesn't mining waste electricity?<span class="i" aria-hidden="true">+</span></button></h3>
      <div class="a" id="a5" hidden><p>It uses electricity, and that is the point. Work you cannot fake is the only way in that cannot be handed to a friend.</p></div>
      <h3><button type="button" aria-expanded="false" aria-controls="a6">What if this website disappears?<span class="i" aria-hidden="true">+</span></button></h3>
      <div class="a" id="a6" hidden><p>The network does not need it. The software is public, and the chain keeps going as long as anyone keeps mining.</p></div>
    </div>
  </div>
</section>

<!-- 9 FINAL -->
<section class="final" aria-labelledby="h-final">
  <div class="wrap">
    <h2 id="h-final" class="big reveal" data-final-head>The tap is open.</h2>
    <div class="flap small reveal" data-cd aria-hidden="true">
      <span class="d">0</span><span class="d">2</span><span class="colon">:</span><span class="d">0</span><span class="d">0</span>
    </div>
    <p class="hint reveal" data-cd-hint>until the next drop, on average.</p>
    <div class="actions reveal">
      <a class="btn btn-gold" href="/mine">Join the hunt</a>
      <a class="btn btn-ghost" href="#play">Try a guess first</a>
    </div>
  </div>
</section>

</main>

{% include "partials/site_footer.html" %}
</div>

<script nonce="{{ csp_nonce }}">
(function(){
  "use strict";
  var REDUCED = matchMedia("(prefers-reduced-motion: reduce)").matches;
  var TARGET = 120, SUBSIDY = 10;
  var fmt = function(n){ return Number(n).toLocaleString("en-US"); };

  /* ---------- night sky: one continuous field, drifting with scroll ---------- */
  var sky = document.getElementById("sky"), sc = sky.getContext("2d"), stars = [], W = 0, H = 0;
  function seed(){
    var dpr = Math.min(devicePixelRatio || 1, 2); W = innerWidth; H = innerHeight;
    sky.width = W*dpr; sky.height = H*dpr; sc.setTransform(dpr,0,0,dpr,0,0);
    stars = []; for (var i = 0, n = Math.round(W*H/5000); i < n; i++){ var z = Math.random();
      stars.push({x:Math.random()*W, y:Math.random()*H*3, z:z, r:.3+z*1.1, a:.15+z*.6, t:Math.random()*6.28}); }
  }
  function paint(t){
    sc.clearRect(0,0,W,H); var sy = scrollY || 0;
    for (var i = 0; i < stars.length; i++){ var s = stars[i];
      var y = ((s.y - sy*(.04+s.z*.24) + (REDUCED?0:t*.004*(.2+s.z))) % (H*3) + H*3) % (H*3);
      if (y > H) continue;
      sc.globalAlpha = s.a*(REDUCED?1:.75+.25*Math.sin(s.t+t*.0011)); sc.fillStyle = "#F5F2EA";
      sc.beginPath(); sc.arc(s.x,y,s.r,0,6.2832); sc.fill(); }
    sc.globalAlpha = 1;
  }
  seed();
  if (REDUCED){ paint(0); addEventListener("scroll", function(){ paint(0); }, {passive:true}); }
  else (function loop(t){ paint(t); requestAnimationFrame(loop); })(0);
  addEventListener("resize", function(){ seed(); if (REDUCED) paint(0); });

  /* ---------- reveal ---------- */
  var rv = document.querySelectorAll(".reveal");
  if ("IntersectionObserver" in window && !REDUCED){
    var io = new IntersectionObserver(function(es){ es.forEach(function(e){ if (e.isIntersecting){ e.target.classList.add("in"); io.unobserve(e.target); } }); }, {rootMargin:"0px 0px -6% 0px"});
    rv.forEach(function(el){ io.observe(el); });
  } else rv.forEach(function(el){ el.classList.add("in"); });

  /* ---------- the bite: fires on every real block ---------- */
  var bites = document.querySelectorAll("[data-bite]");
  function bite(){
    if (REDUCED) return;
    var t0 = null;
    (function step(ts){ if (!t0) t0 = ts; var p = Math.min((ts-t0)/600,1);
      var e = p < .4 ? 1-Math.pow(1-p/.4,3) : Math.pow(1-(p-.4)/.6,3);
      bites.forEach(function(c){ c.setAttribute("r", (62+12*e).toFixed(2)); });
      if (p < 1) requestAnimationFrame(step); })(performance.now());
  }

  /* ---------- countdown to the next drop ---------- */
  var flaps = document.querySelectorAll("[data-cd]"), cdLabel = document.querySelector("[data-cd-label]"), hints = document.querySelectorAll("[data-cd-hint]");
  var lastBlockAt = null, exact = false, launchAt = null;
  var finalHead = document.querySelector("[data-final-head]"), ledeWhen = document.querySelector("[data-lede-when]");
  /* Before the public launch the chain sits at block 0. Its genesis block is
     stamped 2 h after launch and no block may be more than 2 h ahead of the
     clock, so mining opens exactly at genesis time - 2 h: count down to that. */
  function preLaunch(){
    var left = Math.ceil((launchAt - Date.now())/1000);
    if (left <= 0) return false;
    var d = Math.floor(left/86400), h = Math.floor(left%86400/3600), m = Math.floor(left%3600/60), s = left%60;
    var unit;
    if (d > 0){ setFlap(("0"+d).slice(-2) + ("0"+h).slice(-2)); unit = "days : hours"; }
    else if (h > 0){ setFlap(("0"+h).slice(-2) + ("0"+m).slice(-2)); unit = "hours : minutes"; }
    else { setFlap(("0"+m).slice(-2) + ("0"+s).slice(-2)); unit = "minutes : seconds"; }
    // Shown in Central European time (CET/CEST, as Paris/Berlin), the launch's reference zone.
    var when = new Date(launchAt).toLocaleString("en-GB", {timeZone:"Europe/Paris", weekday:"long", day:"numeric", month:"long", hour:"2-digit", minute:"2-digit", timeZoneName:"short"});
    cdLabel.textContent = "Mining opens in (" + unit + ")";
    hints[0].textContent = when + ". Nobody can mine a single coin before then, us included: the rule is written into the genesis block.";
    if (hints[1]) hints[1].textContent = unit + " until the tap opens.";
    if (ledeWhen) ledeWhen.textContent = "from the moment it opens";
    if (finalHead) finalHead.textContent = "The tap opens " + new Date(launchAt).toLocaleString("en-GB", {timeZone:"Europe/Paris", weekday:"long"}) + ".";
    return true;
  }
  function setFlap(str){
    flaps.forEach(function(f){ var ds = f.querySelectorAll(".d");
      for (var i = 0; i < 4; i++){ if (ds[i].textContent !== str[i]){ ds[i].textContent = str[i];
        if (!REDUCED){ ds[i].classList.remove("flip"); void ds[i].offsetWidth; ds[i].classList.add("flip"); } } } });
  }
  function cdTick(){
    if (launchAt !== null && preLaunch()) return;
    if (finalHead && finalHead.textContent !== "The tap is open.") finalHead.textContent = "The tap is open.";
    if (ledeWhen && ledeWhen.textContent !== "right now") ledeWhen.textContent = "right now";
    if (hints[1] && hints[1].textContent !== "until the next drop, on average.") hints[1].textContent = "until the next drop, on average.";
    if (launchAt !== null){   /* launched, block 1 not found yet: genesis is stamped in the future, so don't time from it */
      setFlap("0000"); cdLabel.textContent = "Mining is open. Block 1 is still unclaimed.";
      hints[0].textContent = "Nobody has found the first block yet. Start the miner and it could be yours."; return; }
    if (lastBlockAt === null){ setFlap("0200"); return; }
    var left = Math.round(TARGET - (Date.now() - lastBlockAt)/1000);
    if (left <= 0){ setFlap("0000"); cdLabel.textContent = "Next drop: any second now";
      hints[0].textContent = "Blocks arrive at random. Two minutes is the average, not a schedule."; return; }
    var m = Math.floor(left/60), s = left % 60;
    setFlap(("0"+m).slice(-2) + ("0"+s).slice(-2));
    cdLabel.textContent = exact ? "Next drop expected in" : "Next drop expected in about";
    hints[0].textContent = exact ? "Two minutes on average. Blocks arrive at random." : "Timed from the last block this page saw arrive.";
  }
  setInterval(cdTick, 1000);

  /* ---------- live chain ---------- */
  function bind(k, v){ document.querySelectorAll('[data-bind="'+k+'"]').forEach(function(el){ el.textContent = v; }); }
  var lastHeight = null, live = false, note = document.getElementById("livenote");
  function apply(d){
    var h = Number(d.height);
    bind("height", fmt(h)); bind("supply", Number(d.total_money_coins).toLocaleString("en-US",{maximumFractionDigits:2}));
    if (d.tip_hash){ bind("tip", d.tip_hash); bind("tipshort", d.tip_hash.slice(0,10)+"…"+d.tip_hash.slice(-6));
      var tc = document.getElementById("tipcell"); if (tc) tc.title = d.tip_hash; }
    launchAt = (h === 0 && d.tip_time) ? (Number(d.tip_time) - 7200)*1000 : null;
    if (d.tip_time){ lastBlockAt = Number(d.tip_time)*1000; exact = true; }
    else if (lastHeight === null || h > lastHeight){ if (lastHeight !== null || lastBlockAt === null) lastBlockAt = Date.now(); }
    if (lastHeight !== null && h > lastHeight){ bite(); if (!d.tip_time) lastBlockAt = Date.now(); }
    lastHeight = h; live = true;
    note.textContent = "Refreshed from the network every 15 seconds. Nothing on this page is a mock-up.";
  }
  function poll(){
    fetch("/api/blockchain/info", {cache:"no-store"}).then(function(r){ return r.json(); }).then(function(d){
      if (d && d.status !== "error" && d.height !== undefined) apply(d); else throw 0;
    }).catch(function(){ if (!live) note.textContent = "The network did not answer this page just now. Nothing above is being invented to fill the gap."; });
  }
  poll(); setInterval(poll, 15000);

  /* ---------- the guessing engine: real SHA-256, fast enough to feel ---------- */
  var K = new Uint32Array([0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
    0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
    0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
    0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2]);
  var Wd = new Uint32Array(64), OUT = new Uint32Array(8), SEED = (Math.random()*0xffffffff)>>>0;
  function sha(nonce){
    Wd[0]=SEED; Wd[1]=nonce>>>0; Wd[2]=0x80000000; for (var i=3;i<15;i++) Wd[i]=0; Wd[15]=64;
    for (i=16;i<64;i++){ var x=Wd[i-15], y=Wd[i-2];
      var s0=((x>>>7)|(x<<25))^((x>>>18)|(x<<14))^(x>>>3), s1=((y>>>17)|(y<<15))^((y>>>19)|(y<<13))^(y>>>10);
      Wd[i]=(Wd[i-16]+s0+Wd[i-7]+s1)|0; }
    var a=0x6a09e667,b=0xbb67ae85,c=0x3c6ef372,d=0xa54ff53a,e=0x510e527f,f=0x9b05688c,g=0x1f83d9ab,h=0x5be0cd19;
    for (i=0;i<64;i++){
      var S1=((e>>>6)|(e<<26))^((e>>>11)|(e<<21))^((e>>>25)|(e<<7)), ch=(e&f)^(~e&g), t1=(h+S1+ch+K[i]+Wd[i])|0;
      var S0=((a>>>2)|(a<<30))^((a>>>13)|(a<<19))^((a>>>22)|(a<<10)), mj=(a&b)^(a&c)^(b&c), t2=(S0+mj)|0;
      h=g; g=f; f=e; e=(d+t1)|0; d=c; c=b; b=a; a=(t1+t2)|0; }
    OUT[0]=(a+0x6a09e667)>>>0; OUT[1]=(b+0xbb67ae85)>>>0; OUT[2]=(c+0x3c6ef372)>>>0; OUT[3]=(d+0xa54ff53a)>>>0;
    OUT[4]=(e+0x510e527f)>>>0; OUT[5]=(f+0x9b05688c)>>>0; OUT[6]=(g+0x1f83d9ab)>>>0; OUT[7]=(h+0x5be0cd19)>>>0;
  }
  function zeros(){ var n = 0; for (var w = 0; w < 8; w++){ var v = OUT[w]; if (v === 0){ n += 8; continue; } n += Math.clz32(v) >> 2; break; } return n; }
  function hex(){ var s = ""; for (var w = 0; w < 8; w++) s += ("0000000" + OUT[w].toString(16)).slice(-8); return s; }

  var gN = document.getElementById("g-n"), gR = document.getElementById("g-r"), gZ = document.getElementById("g-z"), gBest = document.getElementById("g-best"),
      hold = document.getElementById("g-hold"), gLabel = document.getElementById("g-label"), gFill = document.getElementById("g-fill"), card = document.getElementById("card");
  var nonce = 0, total = 0, best = -1, bestHex = "", running = false, sessionStart = 0, rateLog = [];
  function paintHex(h, z){ return '<span class="z">' + h.slice(0,z) + '</span>' + h.slice(z); }
  function work(){
    if (!running) return;
    var t0 = performance.now(), done = 0;
    while (performance.now() - t0 < 14){
      for (var j = 0; j < 2000; j++){ sha(nonce++); var z = zeros();
        if (z > best){ best = z; bestHex = hex(); } }
      done += 2000;
    }
    total += done; rateLog.push([performance.now(), done]);
    gFill.style.transform = "scaleX(" + Math.min((performance.now() - sessionStart)/8000, 1) + ")";
    setTimeout(work, 0);
  }
  setInterval(function(){
    var now = performance.now(); rateLog = rateLog.filter(function(x){ return now - x[0] < 1000; });
    var r = rateLog.reduce(function(s,x){ return s + x[1]; }, 0);
    gN.textContent = fmt(total); gR.textContent = running ? fmt(r) : "0"; gZ.textContent = Math.max(best,0);
    if (best >= 0) gBest.innerHTML = "Closest guess so far: " + paintHex(bestHex, best);
  }, 120);
  function start(){ if (running) return; running = true; sessionStart = performance.now(); hold.setAttribute("aria-pressed","true"); gLabel.textContent = "Guessing… let go to stop"; setTimeout(work, 0); }
  function stop(){ if (!running) return; running = false; hold.setAttribute("aria-pressed","false"); gLabel.textContent = "Hold to guess again"; gFill.style.transform = "scaleX(0)"; if (total > 0) showCard(); }
  hold.addEventListener("pointerdown", function(e){ e.preventDefault(); start(); try { hold.setPointerCapture(e.pointerId); } catch (_) {} });
  hold.addEventListener("pointerup", stop); hold.addEventListener("pointercancel", stop); hold.addEventListener("lostpointercapture", stop);
  hold.addEventListener("keydown", function(e){ if ((e.key === " " || e.key === "Enter") && !e.repeat){ e.preventDefault(); start(); } });
  hold.addEventListener("keyup", function(e){ if (e.key === " " || e.key === "Enter"){ e.preventDefault(); stop(); } });
  hold.addEventListener("contextmenu", function(e){ e.preventDefault(); });

  /* ---------- the guess card: the shareable artifact ---------- */
  var SITE = "https://moonbite.org/";
  function shareText(){
    return "I made " + fmt(total) + " guesses mining MoonBite in my browser. Closest: " + best + " leading zeros. " +
      "Ten coins drop every two minutes and nobody owns the tap. Zero given away, ever. Beat me:";
  }
  function showCard(){
    document.getElementById("c-n").textContent = fmt(total);
    document.getElementById("c-cap").textContent = "guesses in my browser. Closest: " + best + " leading zero" + (best === 1 ? "" : "s") + ".";
    document.getElementById("c-hex").innerHTML = paintHex(bestHex, best);
    document.getElementById("c-x").href = "https://x.com/intent/post?text=" + encodeURIComponent(shareText()) + "&url=" + encodeURIComponent(SITE + "#play");
    card.classList.add("show");
  }
  document.getElementById("c-share").addEventListener("click", function(){
    var data = {title: "My MoonBite guess card", text: shareText(), url: SITE + "#play"};
    if (navigator.share) navigator.share(data).catch(function(){});
    else copyCard(document.getElementById("c-share"));
  });
  function copyCard(btn){
    var t = shareText() + " " + SITE + "#play", label = btn.textContent;
    (navigator.clipboard ? navigator.clipboard.writeText(t) : Promise.reject()).then(function(){ btn.textContent = "Copied"; setTimeout(function(){ btn.textContent = label; }, 1400); })
      .catch(function(){ btn.textContent = "Copy failed"; });
  }
  document.getElementById("c-copy").addEventListener("click", function(){ copyCard(this); });

  /* ---------- straight answers: one open at a time ---------- */
  var qs = document.querySelectorAll("#qa button");
  qs.forEach(function(b){ b.addEventListener("click", function(){
    var open = b.getAttribute("aria-expanded") === "true";
    qs.forEach(function(o){ o.setAttribute("aria-expanded","false"); document.getElementById(o.getAttribute("aria-controls")).hidden = true; o.querySelector(".i").textContent = "+"; });
    if (!open){ b.setAttribute("aria-expanded","true"); document.getElementById(b.getAttribute("aria-controls")).hidden = false; b.querySelector(".i").textContent = "−"; }
  }); });
})();
</script>
</body>
</html>