rgboards/rg-boards

Lanes, team task boards you run from the web or from Claude/ChatGPT (MCP). FastAPI + DataK3 + appid + Dodil Models.

A remix template · 0 remixes · Remix rgboards/rg-boards

app/boards/doors/static/landing.html

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Lanes · team boards you can run from Claude</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='8' fill='%230d9488'/><rect x='7' y='8' width='4' height='16' rx='2' fill='white'/><rect x='14' y='8' width='4' height='11' rx='2' fill='white'/><rect x='21' y='8' width='4' height='7' rx='2' fill='white'/></svg>">
<style>
:root{--ink:#0b1220;--mute:#5b6b82;--line:#e3e8ef;--accent:#0d9488;--accent-d:#0f766e;--soft:#f3f7f9}
*{box-sizing:border-box}
body{margin:0;font:15px/1.55 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--ink);background:#fff}
a{color:inherit}
.wrap{max-width:68rem;margin:0 auto;padding:0 1.5rem}
.top{display:flex;align-items:center;gap:.6rem;padding:1.1rem 0}
.logo{display:flex;align-items:center;gap:.55rem;font-weight:800;font-size:1.2rem;letter-spacing:-.01em}
.logo i{display:inline-flex;gap:3px;align-items:flex-start;background:var(--accent);padding:6px 7px;border-radius:8px}
.logo i b{display:block;width:4px;border-radius:2px;background:#fff}
.sp{flex:1}
.btn{display:inline-flex;align-items:center;gap:.4rem;border-radius:10px;padding:.65rem 1.15rem;font-weight:600;text-decoration:none;border:1px solid var(--line);background:#fff;cursor:pointer;font:inherit;font-weight:600}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.primary:hover{background:var(--accent-d)}
.btn:hover{border-color:#c5cfdb}
.hero{display:grid;grid-template-columns:1.05fr 1fr;gap:3rem;align-items:center;padding:2.5rem 0 3rem}
.eyebrow{display:inline-block;font-size:.78rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent-d);background:#ccfbf1;border-radius:999px;padding:.2rem .7rem}
h1{font-size:2.9rem;line-height:1.08;letter-spacing:-.03em;margin:.8rem 0 1rem}
h1 em{font-style:normal;color:var(--accent)}
.lead{color:var(--mute);font-size:1.08rem;max-width:34rem}
.cta{display:flex;gap:.7rem;margin:1.6rem 0 .6rem;flex-wrap:wrap}
.small{font-size:.85rem;color:var(--mute)}
/* a little board, drawn in CSS */
.mock{background:linear-gradient(160deg,#0f172a,#13304a);border-radius:18px;padding:1rem;box-shadow:0 30px 70px -20px rgba(15,23,42,.45)}
.mock .bar{display:flex;gap:.4rem;align-items:center;color:#cbd5e1;font-size:.8rem;margin-bottom:.8rem}
.mock .bar b{color:#fff;font-size:.95rem}
.mock .role{margin-left:auto;background:#1e3a5f;color:#93c5fd;border-radius:999px;padding:.1rem .55rem;font-size:.7rem;font-weight:700}
.mcols{display:grid;grid-template-columns:repeat(3,1fr);gap:.55rem}
.mcol{background:rgba(255,255,255,.07);border-radius:10px;padding:.45rem}
.mcol h5{margin:.1rem .2rem .45rem;color:#cbd5e1;font-size:.72rem;text-transform:uppercase;letter-spacing:.06em}
.mc{background:#fff;border-radius:8px;padding:.45rem .5rem;margin-bottom:.4rem;font-size:.75rem;border-left:3px solid transparent}
.mc.late{border-left-color:#dc2626}.mc.blk{border-left-color:#d97706}
.mc .n{color:#94a3b8;font-size:.65rem}
.mc .chips{display:flex;gap:.25rem;margin-top:.3rem;flex-wrap:wrap}
.ch{font-size:.62rem;font-weight:700;border-radius:4px;padding:0 .3rem}
.ch.r{background:#fee2e2;color:#b91c1c}.ch.a{background:#fef3c7;color:#b45309}.ch.t{background:#ccfbf1;color:#0f766e}.ch.v{background:#ede9fe;color:#6d28d9}
.mchat{margin-top:.7rem;background:rgba(255,255,255,.08);border-radius:10px;padding:.55rem .7rem;color:#e2e8f0;font-size:.76rem}
.mchat b{color:#5eead4}
section.demo{background:var(--soft);border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:2.5rem 0}
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}
.acct{background:#fff;border:1px solid var(--line);border-radius:14px;padding:1rem 1.1rem}
.acct .r{display:inline-block;font-size:.72rem;font-weight:700;border-radius:999px;padding:.12rem .6rem;margin-bottom:.5rem}
.r.owner{background:#ccfbf1;color:#0f766e}.r.member{background:#dbeafe;color:#1d4ed8}.r.viewer{background:#f1f5f9;color:#475569}
.acct code{display:block;font-size:.88rem;margin:.15rem 0 .45rem;word-break:break-all}
.acct p{margin:0;color:var(--mute);font-size:.85rem}
.copy{border:none;background:none;color:var(--accent-d);font-weight:600;cursor:pointer;padding:0;font:inherit;font-size:.8rem}
.pw{margin-top:1rem;font-size:.92rem}
.pw code{background:#fff;border:1px solid var(--line);border-radius:6px;padding:.15rem .45rem}
h2{font-size:1.5rem;letter-spacing:-.02em;margin:0 0 .4rem}
.feat{display:grid;grid-template-columns:repeat(3,1fr);gap:1.4rem;padding:2.8rem 0}
.feat h3{font-size:1rem;margin:.2rem 0 .3rem}
.feat p{margin:0;color:var(--mute);font-size:.92rem}
.ico{width:2.1rem;height:2.1rem;border-radius:9px;background:#ccfbf1;color:var(--accent-d);display:flex;align-items:center;justify-content:center;font-weight:800}
.mcp{display:grid;grid-template-columns:1fr 1fr;gap:1.5rem;padding:0 0 3rem;align-items:start}
.box{border:1px solid var(--line);border-radius:14px;padding:1.1rem 1.2rem}
.box ol{margin:.4rem 0 0;padding-left:1.2rem;color:#334155}
.box li{margin:.25rem 0}
.box code{background:var(--soft);border-radius:5px;padding:.08rem .35rem;font-size:.85rem}
.ask{margin:.25rem 0;color:#334155}
footer{border-top:1px solid var(--line);padding:1.2rem 0 2rem;color:var(--mute);font-size:.85rem}
footer b{color:var(--ink);font-weight:600}
@media(max-width:860px){.hero,.mcp{grid-template-columns:1fr}.cards,.feat{grid-template-columns:1fr}h1{font-size:2.2rem}}
</style>
</head>
<body>
<div class="wrap">
  <div class="top">
    <div class="logo"><i><b style="height:14px"></b><b style="height:10px"></b><b style="height:6px"></b></i>Lanes</div>
    <div class="sp"></div>
    <a class="btn primary" href="/.dodil/auth/login?return_to=/">Sign in</a>
  </div>

  <div class="hero">
    <div>
      <span class="eyebrow">Team boards · web + AI</span>
      <h1>Plan the work on a board.<br><em>Ask Claude</em> what's next.</h1>
      <p class="lead">Lanes is a small, fast task board for teams: boards, lists and numbered cards with owners, members and read-only viewers. Everything you can click, Claude or ChatGPT can do over MCP, as you, seeing only your boards.</p>
      <div class="cta">
        <a class="btn primary" href="/.dodil/auth/login?return_to=/">Sign in to Lanes →</a>
        <a class="btn" href="#connect">Connect Claude / ChatGPT</a>
      </div>
      <div class="small">Sign-in by Dodil appid. No passwords stored by this app.</div>
    </div>
    <div class="mock" aria-hidden="true">
      <div class="bar"><b>Product Launch</b> · 5 lists · 16 cards <span class="role">VIEWER · READ ONLY</span></div>
      <div class="mcols">
        <div class="mcol"><h5>To do</h5>
          <div class="mc blk"><div class="n">#3</div>Ship v1 to production<div class="chips"><span class="ch a">Blocked by #2</span><span class="ch v">release</span></div></div>
          <div class="mc late"><div class="n">#9</div>Fix login redirect on mobile<div class="chips"><span class="ch r">Overdue</span><span class="ch r">bug</span></div></div>
        </div>
        <div class="mcol"><h5>Doing</h5>
          <div class="mc blk"><div class="n">#2</div>Final QA pass on checkout<div class="chips"><span class="ch a">Blocked by #9</span><span class="ch t">qa</span></div></div>
          <div class="mc late"><div class="n">#1</div>Write launch blog post<div class="chips"><span class="ch r">Overdue</span></div></div>
        </div>
        <div class="mcol"><h5>Done</h5>
          <div class="mc"><div class="n">#5</div>Pricing page copy<div class="chips"><span class="ch t">content</span></div></div>
          <div class="mc"><div class="n">#6</div>Set up billing sandbox</div>
        </div>
      </div>
      <div class="mchat"><b>You → Claude:</b> what is blocking the launch?<br><b>Claude:</b> #3 waits on #2 QA, which waits on #9 the mobile login bug (Marco, overdue). Start with #9.</div>
    </div>
  </div>
</div>

{{DEMO}}

<div class="wrap">
  <div class="feat">
    <div><div class="ico">◫</div><h3>Boards, lists, numbered cards</h3><p>Title, description, assignee, due date and labels. Drag cards between lists. Say “card 12” to a person or an AI.</p></div>
    <div><div class="ico">◎</div><h3>Roles that hold</h3><p>Owner invites, members edit, viewers only read. Nobody sees a board they aren't on, on the web or through MCP.</p></div>
    <div><div class="ico">↺</div><h3>Every change recorded</h3><p>Who, when, which field, old → new. Per card and per board.</p></div>
    <div><div class="ico">⛓</div><h3>Blocked-by chains</h3><p>Link cards, then ask “what is blocking the launch?” Lanes walks the chain and tells you where to start.</p></div>
    <div><div class="ico">!</div><h3>Overdue, flagged</h3><p>Anything past due and not done turns red on the board, in the sidebar and in “What's overdue?”.</p></div>
    <div><div class="ico">✦</div><h3>AI that does the chores</h3><p>Turn a card into a checklist, find cards like this one by meaning, and get a short daily summary. Dodil Models only.</p></div>
  </div>

  <div class="mcp" id="connect">
    <div class="box">
      <h2>Connect Claude or ChatGPT</h2>
      <ol>
        <li>Claude: Settings → Connectors → <b>Add custom connector</b>. ChatGPT: Settings → Connectors → Create (developer mode).</li>
        <li>URL: <code id="mcpurl">/mcp</code> <button class="copy" data-copy-from="mcpurl">copy</button></li>
        <li>Sign in with your Lanes account. The assistant now acts as you.</li>
      </ol>
    </div>
    <div class="box">
      <h2>Then ask</h2>
      <p class="ask">“What's on my plate this week?”</p>
      <p class="ask">“Add a card ‘Send invoice’ to Doing on the Ops board.”</p>
      <p class="ask">“Move card 12 to Done.”</p>
      <p class="ask">“What's overdue?” · “What is blocking the launch?”</p>
    </div>
  </div>
</div>

<footer><div class="wrap">Lanes runs entirely on Dodil: <b>DataK3</b> stores it, <b>appid</b> signs you in, <b>Ignite</b> runs it, <b>Dodil Models</b> powers the AI. MIT licensed · remix it into your own org with one command.</div></footer>
<script>
document.getElementById('mcpurl').textContent=location.origin+'/mcp';
document.querySelectorAll('[data-copy],[data-copy-from]').forEach(b=>b.onclick=()=>{
  const v=b.dataset.copy||document.getElementById(b.dataset.copyFrom).textContent;
  navigator.clipboard&&navigator.clipboard.writeText(v);const t=b.textContent;b.textContent='copied';setTimeout(()=>b.textContent=t,1200)});
</script>
</body>
</html>