/span>
              <span class="pn-info-v">14d 3h</span>
            </div>
            <div class="pn-info-cell">
              <span class="pn-info-k">channels</span>
              <span class="pn-info-v">3</span>
            </div>
            <div class="pn-info-cell">
              <span class="pn-info-k">hostname</span>
              <span class="pn-info-v">watchdog@bots.your.domain</span>
            </div>
          </div>
          <div class="pn-log">
            <div class="pn-log-line sys">
              <span class="pn-log-time">14:01</span>
              <span class="pn-log-nick"></span>
              <span class="pn-log-text">&mdash; watchdog connected to #lobby, #dev, #offtopic</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:03</span>
              <span class="pn-log-nick" style="color:var(--nb)">reed</span>
              <span class="pn-log-text">has anyone looked at the mass join thing from earlier</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:03</span>
              <span class="pn-log-nick" style="color:var(--nc)">hako</span>
              <span class="pn-log-text">yeah it was drones. already handled</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:04</span>
              <span class="pn-log-nick" style="color:var(--na)">moth</span>
              <span class="pn-log-text"><span class="pn-log-cmd">!warn</span> xflood</span>
            </div>
            <div class="pn-log-line bot">
              <span class="pn-log-time">14:04</span>
              <span class="pn-log-nick">watchdog</span>
              <span class="pn-log-text">xflood: warning 1/3</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:05</span>
              <span class="pn-log-nick" style="color:var(--nd)">juno</span>
              <span class="pn-log-text">persistent one</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:07</span>
              <span class="pn-log-nick" style="color:var(--ne)">sol</span>
              <span class="pn-log-text">unrelated but does anyone have a good vps in .se</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:08</span>
              <span class="pn-log-nick" style="color:var(--nb)">reed</span>
              <span class="pn-log-text">njalla maybe</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:08</span>
              <span class="pn-log-nick" style="color:var(--nc)">hako</span>
              <span class="pn-log-text">sol: bahnhof</span>
            </div>
            <div class="pn-log-line">
              <span class="pn-log-time">14:09</span>
              <span class="pn-log-nick" style="color:var(--ne)">sol</span>
              <span class="pn-log-text">oh bahnhof is good actually. thanks</span>
            </div>
          </div>
        </div>
      </div>
      <div class="pn-statusbar">
        <div class="pn-statusbar-live">
          <span class="pn-pulse"></span>
          connected &middot; 4 bots across 3 networks
        </div>
        <span>last restart: never</span>
      </div>
    </div>
  </section>

  <section class="features reveal">
    <div class="feat">
      <div class="feat-label">uptime</div>
      <div class="feat-body">
        <h3>your bot stays in the channel</h3>
        <p>we keep the process running and the connection open. you don't need a server, a screen session, or a laptop that never sleeps.</p>
      </div>
    </div>
    <div class="feat">
      <div class="feat-label">deploy</div>
      <div class="feat-body">
        <h3>push code, bot goes live</h3>
        <p>point us at a git repo and we build on push. or upload a script. either way it's running in seconds.</p>
      </div>
    </div>
    <div class="feat">
      <div class="feat-label">networks</div>
      <div class="feat-body">
        <h3>any network</h3>
        <p>libera, oftc, rizon, your own ircd, whatever. run bots on multiple networks from one account.</p>
      </div>
    </div>
    <div class="feat">
      <div class="feat-label">hostname</div>
      <div class="feat-body">
        <h3>watchdog@bots.your.domain</h3>
        <p>on pro, your bots mask with a hostname you control. <code>/whois</code> shows your name, not ours.</p>
      </div>
    </div>
    <div class="feat">
      <div class="feat-label">recovery</div>
      <div class="feat-body">
        <h3>it comes back on its own</h3>
        <p>if your bot crashes, we restart it with backoff. every plan, including free. logs are there when you want to see what happened.</p>
      </div>
    </div>
  </section>

  <section class="marketplace reveal">
    <div class="section-label">marketplace</div>
    <div class="mp-grid">
      <a href="/marketplace/linkbot" class="mp-card">
        <div class="mp-card-head">
          <span class="mp-card-name">linkbot</span>
          <span class="mp-card-tag">free</span>
        </div>
        <p class="mp-card-desc">fetches page titles for URLs posted in channel</p>
        <div class="mp-card-meta">
          <span>1.2k deploys</span>
          <span>by irc.bot</span>
        </div>
      </a>
      <a href="/marketplace/rsswatch" class="mp-card">
        <div class="mp-card-head">
          <span class="mp-card-name">rsswatch</span>
          <span class="mp-card-tag">free</span>
        </div>
        <p class="mp-card-desc">posts new RSS/Atom items to a channel on a schedule</p>
        <div class="mp-card-meta">
          <span>840 deploys</span>
          <span>by irc.bot</span>
        </div>
      </a>
      <a href="/marketplace/sed" class="mp-card">
        <div class="mp-card-head">
          <span class="mp-card-name">sed</span>
          <span class="mp-card-tag">free</span>
        </div>
        <p class="mp-card-desc">s/typo/fix/ &mdash; regex corrections for messages</p>
        <div class="mp-card-meta">
          <span>2.1k deploys</span>
          <span>by community</span>
        </div>
      </a>
      <a href="/marketplace/watchdog" class="mp-card">
        <div class="mp-card-head">
          <span class="mp-card-name">watchdog</span>
          <span class="mp-card-tag">free</span>
        </div>
        <p class="mp-card-desc">moderation bot with warnings, kicks, and stats</p>
        <div class="mp-card-meta">
          <span>680 deploys</span>
          <span>by irc.bot</span>
        </div>
      </a>
    </div>
  </section>

  <section class="setup reveal">
    <div class="section-label">deploy</div>
    <div class="terminal">
      <div class="terminal-chrome">
        <div class="dots"><span></span><span></span><span></span></div>
        <span>terminal</span>
      </div>
      <div class="terminal-body">
        <span class="cm"># from a git repo</span><br>
        <span class="pr">$</span> ircbot deploy --repo git@github.com:you/mybot.git<br>
        <span class="gap"></span>
        <span class="cm"># or a single script</span><br>
        <span class="pr">$</span> ircbot deploy --file bot.py --network libera<br>
        <span class="gap"></span>
        <span class="cm"># check status</span><br>
        <span class="pr">$</span> ircbot status<br>
        <span style="color:var(--g)">&#9679;</span> mybot &nbsp;libera.chat &nbsp;uptime 2d 11h<br>
        <span class="gap"></span>
        <span class="cm"># done</span>
      </div>
    </div>
  </section>

  <section class="pricing reveal" id="pricing">
    <div class="section-label">pricing</div>
    <div class="price-table">
      <div class="pt-row pt-head">
        <div class="pt-cell"></div>
        <div class="pt-cell">
          <span class="plan-name">free</span>
          <span class="plan-price">$0</span>
        </div>
        <div class="pt-cell">
          <span class="plan-name">pro</span>
          <span class="plan-price">$6 <span>/mo</span></span>
        </div>
        <div class="pt-cell">
          <span class="plan-name">team</span>
          <span class="plan-price">$18 <span>/mo</span></span>
        </div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">bots</div>
        <div class="pt-cell">1</div>
        <div class="pt-cell">5</div>
        <div class="pt-cell">unlimited</div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">networks</div>
        <div class="pt-cell">1</div>
        <div class="pt-cell">unlimited</div>
        <div class="pt-cell">unlimited</div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">deploy</div>
        <div class="pt-cell">upload</div>
        <div class="pt-cell">git + upload</div>
        <div class="pt-cell">git + upload</div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">marketplace</div>
        <div class="pt-cell pt-dim">&mdash;</div>
        <div class="pt-cell">full access</div>
        <div class="pt-cell">full access</div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">hostname</div>
        <div class="pt-cell pt-dim">&mdash;</div>
        <div class="pt-cell">custom</div>
        <div class="pt-cell">custom</div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">restart</div>
        <div class="pt-cell">auto</div>
        <div class="pt-cell">auto</div>
        <div class="pt-cell">auto</div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">support</div>
        <div class="pt-cell pt-dim">&mdash;</div>
        <div class="pt-cell">irc</div>
        <div class="pt-cell">irc</div>
      </div>
      <div class="pt-row">
        <div class="pt-cell">members</div>
        <div class="pt-cell pt-dim">&mdash;</div>
        <div class="pt-cell pt-dim">&mdash;</div>
        <div class="pt-cell">up to 10</div>
      </div>
      <div class="pt-actions">
        <div class="pt-cell"></div>
        <div class="pt-cell"><a href="/signup" class="pt-btn pt-btn-o">start free</a></div>
        <div class="pt-cell"><a href="/signup?plan=pro" class="pt-btn pt-btn-f">go pro</a></div>
        <div class="pt-cell"><a href="/signup?plan=team" class="pt-btn pt-btn-f">go team</a></div>
      </div>
    </div>
  </section>

  <footer class="footer">
    <span class="mark">irc<span class="dot"></span>bot</span>
    <div class="footer-links">
      <a href="/docs">docs</a>
      <a href="/status">status</a>
      <a href="/marketplace">marketplace</a>
      <a href="/faq">faq</a>
      <a href="/cli">cli</a>
      <a href="https://github.com/ircbot">github</a>
      <a href="mailto:hi@irc.bot">hi@irc.bot</a>
    </div>
  </footer>

</div>
<script>
document.addEventListener('DOMContentLoaded',()=>{
  // reveal animation
  const obs=new IntersectionObserver(es=>{es.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');obs.unobserve(e.target)}})},{threshold:.1});
  document.querySelectorAll('.reveal').forEach(el=>obs.observe(el));

  // bot data
  const bots={
    watchdog:{
      chrome:'<b>watchdog</b> &mdash; #lobby on libera.chat',
      info:[
        {k:'status',v:'running',accent:true},
        {k:'uptime',v:'14d 3h'},
        {k:'channels',v:'3'},
        {k:'hostname',v:'watchdog@bots.your.domain'}
      ],
      log:[
        {sys:true,time:'14:01',text:'&mdash; watchdog connected to #lobby, #dev, #offtopic'},
        {time:'14:03',nick:'reed',color:'var(--nb)',text:'has anyone looked at the mass join thing from earlier'},
        {time:'14:03',nick:'hako',color:'var(--nc)',text:'yeah it was drones. already handled'},
        {time:'14:04',nick:'moth',color:'var(--na)',text:'<span class="pn-log-cmd">!warn</span> xflood'},
        {bot:true,time:'14:04',nick:'watchdog',text:'xflood: warning 1/3'},
        {time:'14:05',nick:'juno',color:'var(--nd)',text:'persistent one'},
        {time:'14:07',nick:'sol',color:'var(--ne)',text:'unrelated but does anyone have a good vps in .se'},
        {time:'14:08',nick:'reed',color:'var(--nb)',text:'njalla maybe'},
        {time:'14:08',nick:'hako',color:'var(--nc)',text:'sol: bahnhof'},
        {time:'14:09',nick:'sol',color:'var(--ne)',text:'oh bahnhof is good actually. thanks'}
      ]
    },
    logbot:{
      chrome:'<b>logbot</b> &mdash; #dev on libera.chat',
      info:[
        {k:'status',v:'running',accent:true},
        {k:'uptime',v:'31d 18h'},
        {k:'channels',v:'2'},
        {k:'hostname',v:'logbot@bots.your.domain'}
      ],
      log:[
        {sys:true,time:'09:00',text:'&mdash; logbot connected to #dev, #ops'},
        {time:'09:14',nick:'reed',color:'var(--nb)',text:'pushed the null fix btw'},
        {time:'09:15',nick:'moth',color:'var(--na)',text:'the one from yesterday?'},
        {time:'09:15',nick:'reed',color:'var(--nb)',text:'yeah'},
        {time:'09:18',nick:'juno',color:'var(--nd)',text:'reed: did you rebase or merge'},
        {time:'09:19',nick:'reed',color:'var(--nb)',text:'rebase. was clean'},
        {time:'09:22',nick:'sol',color:'var(--ne)',text:'anyone in the config loader rn'},
        {time:'09:22',nick:'hako',color:'var(--nc)',text:'no go ahead'},
        {time:'09:25',nick:'sol',color:'var(--ne)',text:'i made mass today btw'},
        {time:'09:25',nick:'moth',color:'var(--na)',text:'nice. what kind'}
      ]
    },
    linkbot:{
      chrome:'<b>linkbot</b> &mdash; #general on oftc',
      info:[
        {k:'status',v:'running',accent:true},
        {k:'uptime',v:'8d 22h'},
        {k:'channels',v:'1'},
        {k:'hostname',v:'linkbot@bots.your.domain'}
      ],
      log:[
        {sys:true,time:'11:00',text:'&mdash; linkbot connected to #general'},
        {time:'11:04',nick:'moth',color:'var(--na)',text:'https://openresty.org/en/changelog-1025003.html'},
        {bot:true,time:'11:04',nick:'linkbot',text:'^ OpenResty 1.25.3.1 Changelog'},
        {time:'11:05',nick:'juno',color:'var(--nd)',text:'oh finally'},
        {time:'11:06',nick:'moth',color:'var(--na)',text:'took them long enough'},
        {time:'11:09',nick:'sol',color:'var(--ne)',text:'https://www.phoronix.com/news/Linux-6.13-Released'},
        {bot:true,time:'11:09',nick:'linkbot',text:'^ Linux 6.13 Released - Phoronix'},
        {time:'11:10',nick:'reed',color:'var(--nb)',text:'anyone running it'},
        {time:'11:11',nick:'moth',color:'var(--na)',text:'since rc4. solid so far'},
        {time:'11:12',nick:'hako',color:'var(--nc)',text:'i should update. still on 6.11'}
      ]
    },
    quizzer:{
      chrome:'<b>quizzer</b> &mdash; #trivia on rizon',
      info:[
        {k:'status',v:'stopped'},
        {k:'uptime',v:'&mdash;'},
        {k:'channels',v:'1'},
        {k:'hostname',v:'quizzer@bots.your.domain'}
      ],
      log:[
        {sys:true,time:'20:00',text:'&mdash; quizzer connected to #trivia'},
        {bot:true,time:'20:31',nick:'quizzer',text:'Q12: first compiled programming language?'},
        {time:'20:32',nick:'hako',color:'var(--nc)',text:'uhhh'},
        {time:'20:32',nick:'sol',color:'var(--ne)',text:'fortran'},
        {bot:true,time:'20:32',nick:'quizzer',text:'correct! sol: 8 pts'},
        {time:'20:33',nick:'moth',color:'var(--na)',text:'every single time'},
        {time:'20:33',nick:'juno',color:'var(--nd)',text:'sol do you just have these memorized'},
        {time:'20:34',nick:'sol',color:'var(--ne)',text:'maybe'},
        {sys:true,time:'20:35',text:'&mdash; round ended. sol wins with 8 points'},
        {sys:true,time:'20:41',text:'&mdash; quizzer disconnected (manual stop)'}
      ]
    }
  };

  function renderInfo(info){
    return info.map(c=>`<div class="pn-info-cell"><span class="pn-info-k">${c.k}</span><span class="pn-info-v${c.accent?' accent':''}">${c.v}</span></div>`).join('');
  }

  function renderLog(log){
    return log.map(l=>{
      const cls=l.sys?'pn-log-line sys':l.bot?'pn-log-line bot':'pn-log-line';
      const nick=l.sys?'':l.bot?l.nick:`<span style="color:${l.color}">${l.nick}</span>`;
      return `<div class="${cls}"><span class="pn-log-time">${l.time}</span><span class="pn-log-nick">${nick}</span><span class="pn-log-text">${l.text}</span></div>`;
    }).join('');
  }

  const chromeLabel=document.querySelector('.pn-chrome-left span:last-child');
  const infoStrip=document.querySelector('.pn-info');
  const logArea=document.querySelector('.pn-log');
  const sbItems=document.querySelectorAll('.pn-sb-bot[data-bot]');

  sbItems.forEach(item=>{
    item.addEventListener('click',()=>{
      const id=item.dataset.bot;
      const bot=bots[id];
      if(!bot)return;
      sbItems.forEach(s=>s.classList.remove('active'));
      item.classList.add('active');
      chromeLabel.innerHTML=bot.chrome;
      infoStrip.innerHTML=renderInfo(bot.info);
      logArea.innerHTML=renderLog(bot.log);
    });
  });
});
</script>
</body>
</html>
ØA
—Eoúô