north-scape/relayboard

Relayboard: accessible team boards with audited actions, dependency maps, and shared web/MCP use cases.

A remix template · 0 remixes · Remix north-scape/relayboard

app/boards/doors/static/index.html

<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Relayboard — a little more flow</title><link rel="stylesheet" href="/static/style.css"><script src="/static/app.js" defer></script></head>
<body><a class="skip" href="#main">Skip to board</a><div class="app-shell"><aside class="sidebar"><a class="brand" href="/" aria-label="Relayboard home"><span class="brand-mark" aria-hidden="true">r<span>↗</span></span>Relayboard</a><p class="sidebar-caption">YOUR WORK, IN MOTION</p><div class="nav-heading"><h2>Boards</h2><button id="new-board" class="icon-button" aria-label="Create board">+</button></div><nav id="boards" aria-label="Your boards"></nav><div class="sidebar-note"><span class="spark" aria-hidden="true">✳</span><strong>One board. Two ways in.</strong><p>Plan here, or take real action from your AI assistant.</p><button id="connect-help" class="text-button">Connect your assistant ↗</button></div><footer><span class="status-dot"></span> Powered by Dodil <a href="/.dodil/auth/logout">Sign out</a></footer></aside>
<main id="main"><header class="topbar"><span>Workspace <span aria-hidden="true">/</span> <span id="breadcrumb">Your boards</span></span><span class="pill">WEB + MCP</span></header><div id="notice" role="status" aria-live="polite" hidden></div><section class="workspace"><div class="page-heading"><div><p class="eyebrow">MAKE ROOM FOR GREAT WORK</p><h1 id="board-title">A little more flow.</h1><p id="board-subtitle">A clear place for your team's next big thing.</p></div><div class="heading-actions"><span id="role" class="role-badge" hidden></span><button id="members-button" class="secondary" hidden>People</button><button id="summary-button" class="secondary" hidden>✳ Briefing</button><button id="activity-button" class="secondary" hidden>Activity</button><button id="add-card" class="primary" hidden>+ New card</button></div></div><div id="toolbar" class="toolbar" hidden><div class="filters" role="group" aria-label="Filter cards"><button class="filter active" data-filter="all" aria-pressed="true">All cards <span id="all-count">0</span></button><button class="filter" data-filter="overdue" aria-pressed="false">Overdue <span id="overdue-count">0</span></button><button class="filter" data-filter="week" aria-pressed="false">Due next 7 days</button><button id="mine-filter" class="filter" data-filter="mine" aria-pressed="false" hidden>My week</button></div><label class="search"><span aria-hidden="true">⌕</span><input id="search" type="search" placeholder="Find a card…" aria-label="Search cards"></label></div><div id="board-content" aria-live="polite"><div class="empty-state"><div class="empty-symbol" aria-hidden="true">↗</div><h2>Good work starts with a clear board.</h2><p>Create a board, invite your people, and give every idea a next step.</p><button id="empty-create" class="primary">Create your first board</button></div></div><p id="board-tip" class="board-tip" hidden>Drag cards between columns, or use the Move menu on any card. Your changes stay in the activity log.</p></section></main></div>
<dialog id="editor"><form id="card-form"><div class="dialog-heading"><div><p class="eyebrow">A NEXT STEP, MADE CLEAR</p><h2 id="editor-title">New card</h2><span id="editor-reference" class="card-reference" hidden></span></div><button type="button" class="icon-button close-dialog" aria-label="Close card editor">×</button></div><label>Title<input name="title" required maxlength="180" placeholder="What needs to happen?" autocomplete="off"></label><label>Description<textarea name="description" rows="4" maxlength="6000" placeholder="Context, links, and what done looks like…"></textarea></label><div class="field-row"><label>Assignee<select name="assignee"><option value="">Unassigned</option></select></label><label>Due date<input name="due_date" type="date"></label></div><div class="field-row"><label>List<select name="list_name"></select></label><label>Labels<input name="labels" placeholder="design, launch" maxlength="500"><small>Separate labels with commas</small></label></div><div id="dependency-area" hidden><label>Blocked by<select id="blocker-select" multiple size="4" aria-describedby="blocker-help"></select></label><p id="blocker-help" class="small muted">Hold Ctrl or ⌘ to select multiple cards. Dependency changes are saved separately.</p><button id="save-blockers" type="button" class="secondary">Save dependencies</button><button id="show-blockers" type="button" class="secondary">What is blocking this?</button><ul id="blocker-result"></ul></div><section id="task-checklist-area" hidden aria-labelledby="task-checklist-title"><div class="checklist-heading"><h3 id="task-checklist-title">Checklist</h3><span id="checklist-progress" class="small muted"></span></div><ul id="task-checklist" class="task-checklist"></ul><div id="checklist-add" class="checklist-add"><label class="sr-only" for="checklist-new-step">New checklist step</label><input id="checklist-new-step" maxlength="300" placeholder="Add a concrete next step…" autocomplete="off"><button id="add-checklist-step" type="button" class="secondary">Add step</button></div><p class="small muted">Checklist edits stay in this draft until you choose Save card.</p></section><div id="ai-area" hidden><button id="checklist" type="button" class="secondary">✳ Suggest a checklist</button><button id="similar" type="button" class="secondary">Find similar cards</button><ul id="similar-result"></ul><p class="small muted">Review each AI suggestion. Adding it to the draft does not save it.</p><ul id="checklist-result" class="checklist-suggestions"></ul><button id="use-checklist" type="button" class="secondary" hidden disabled>Add selected to card draft</button><p id="checklist-feedback" class="small" role="status" aria-live="polite"></p></div><p class="form-error" role="alert" hidden></p><div class="dialog-footer"><button type="button" class="secondary close-dialog">Cancel</button><button type="submit" class="primary">Save card</button></div></form></dialog>
<dialog id="board-dialog"><form id="board-form"><div class="dialog-heading"><h2>Create a board</h2><button type="button" class="icon-button close-dialog" aria-label="Close create board">×</button></div><p class="muted">A shared home for a project, a team, or a bright idea. You'll be the owner.</p><label>Board name<input name="title" required maxlength="100" placeholder="e.g. Product launch" autocomplete="off"></label><p class="form-error" role="alert" hidden></p><div class="dialog-footer"><button type="button" class="secondary close-dialog">Cancel</button><button type="submit" class="primary">Create board</button></div></form></dialog>
<dialog id="people-dialog"><div class="dialog-heading"><div><p class="eyebrow">BETTER, TOGETHER</p><h2>Board people</h2></div><button type="button" class="icon-button close-dialog" aria-label="Close people">×</button></div><ul id="member-list" class="member-list"></ul><form id="remove-member-form" class="removal-confirm" hidden><h3>Remove board access?</h3><p id="remove-member-message"></p><p class="form-error" role="alert" hidden></p><div class="removal-actions"><button id="cancel-member-removal" type="button" class="secondary">Keep access</button><button type="submit" class="primary">Remove access</button></div></form><form id="member-form"><h3>Add or update a person</h3><p class="small muted">Grant access by sign-in email. They must sign in through this app's Dodil user pool; no email is sent.</p><label>Email<input name="email" type="email" required maxlength="254" placeholder="teammate@example.com"></label><label>Role<select name="role"><option value="member">Member — can edit cards</option><option value="viewer">Viewer — read only</option></select></label><p class="form-error" role="alert" hidden></p><div class="dialog-footer"><button type="submit" class="primary">Save access</button></div></form></dialog>
<dialog id="activity-dialog"><div class="dialog-heading"><div><p class="eyebrow">THE STORY SO FAR</p><h2>Board activity</h2></div><button type="button" class="icon-button close-dialog" aria-label="Close activity">×</button></div><ol id="activity-list" class="activity-list"></ol></dialog>
<dialog id="summary-dialog"><div class="dialog-heading"><div><p class="eyebrow">YOUR BOARD, AT A GLANCE</p><h2>Board briefing</h2></div><button type="button" class="icon-button close-dialog" aria-label="Close briefing">×</button></div><p class="small muted">AI-generated summary. Verify it against your board before acting.</p><p id="summary-result"></p></dialog><dialog id="help-dialog"><div class="dialog-heading"><h2>Your board, in conversation.</h2><button type="button" class="icon-button close-dialog" aria-label="Close connection help">×</button></div><p>Add this app's MCP address as a custom connector in your assistant:</p><code id="mcp-address"></code><p>Sign in with your Dodil app identity. A pool owner may need to approve your assistant's client once; see the README.</p><div class="prompt-example">“What's on my plate this week?”<br>“Add a card ‘Send invoice’ to Doing.”<br>“Move that card to Done.”</div><p class="muted small">Your assistant has the same board access and role as you. It never gets raw database access.</p></dialog>
</body></html>