app
Adom Gantt
Public Made by Adomby adom
Interactive Gantt chart viewer for project timelines, with a table view and an analytics page over the same data. Data-driven, dark by default with a print-friendly light mode, and fully editable in the browser: drag bars to move or resize, multi-select and batch-shift dates, manage dependency arrows inline, reorder rows, filter by phase, and undo. One click auto-schedules the whole plan so every dependency lines up finish-to-start on working days, skipping weekends and US federal holidays, push
master
Drew Owens
Publish 0.80.0
eb7d34d
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
<!doctype html>
<!--
The "what lives where" diagram (client-vs-server/where-it-lives.png, shown on the main
README and on this folder's sub-page). This file is its source: edit it when what lives
where changes, then re-render the PNG with the test Chrome, at 1400 px wide and twice the
pixels (see docs/RELEASING.md):
node test/render-diagram.mjs
Brand fonts: Familjen Grotesk (titles), Satoshi (text), JetBrains Mono (labels). They are
used from the system when installed, and the first two from Google Fonts otherwise.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=1400">
<title>What lives where</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Familjen+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400&display=swap" rel="stylesheet">
<style>
:root {
--bg: #0d1117; --card: #161b22; --line: #262c36; --border: #30363d;
--text: #e6edf3; --text2: #9aa4b2; --muted: #6e7681;
--purple: #9b7bff; --purple-line: #7c5cff; --teal: #1fc7b6; --amber: #e3b341;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); }
body { width: 1400px; font-family: 'Satoshi', Arial, sans-serif; color: var(--text); }
.frame { padding: 44px 44px 40px; }
h1 { font-family: 'Familjen Grotesk', sans-serif; font-weight: 700; font-size: 28px; margin: 0 0 6px; letter-spacing: -0.2px; }
.lede { font-size: 16.5px; color: var(--text2); margin: 0 0 30px; }
.lede b { color: var(--text); }
.cols { display: grid; grid-template-columns: 300px 372px 1fr 440px; gap: 0 18px; align-items: stretch; }
.card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 22px 22px 20px; }
.card.browser { border-color: var(--purple-line); }
.card.server { border-color: var(--teal); box-shadow: 0 0 0 1px rgba(31,199,182,.12), 0 0 28px rgba(31,199,182,.10); }
.kicker { font-family: 'JetBrains Mono', monospace; font-size: 12.5px; letter-spacing: 2.6px; color: var(--muted); text-transform: uppercase; margin-bottom: 10px; }
.browser .kicker { color: var(--purple); }
.server .kicker { color: var(--teal); }
h2 { font-family: 'Familjen Grotesk', sans-serif; font-weight: 700; font-size: 21px; margin: 0 0 6px; }
.sub { font-size: 14px; color: var(--text2); margin: 0 0 14px; line-height: 1.4; }
ul { list-style: none; margin: 0; padding: 0; }
li { position: relative; padding: 9px 0 9px 22px; border-top: 1px solid var(--line); font-size: 15px; line-height: 1.38; }
li::before { content: ''; position: absolute; left: 3px; top: 15px; width: 7px; height: 7px; border-radius: 2px; background: #5b6370; }
.browser li::before { background: var(--purple); }
.server li::before { background: var(--teal); }
li b { font-weight: 700; }
.key { font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--amber); border: 1px solid rgba(227,179,65,.55); border-radius: 4px; padding: 1px 5px; margin-left: 6px; }
.foot { font-size: 12.5px; color: var(--text2); margin: 14px 0 0; line-height: 1.45; }
.arrows { display: flex; flex-direction: column; justify-content: center; gap: 86px; text-align: center; color: var(--teal); font-size: 13px; line-height: 1.38; }
.arrows > div { max-width: 150px; margin: 0 auto; }
.arrow { display: block; margin: 6px auto; width: 74px; height: 12px; }
.live { margin-top: 18px; border: 1px dashed rgba(31,199,182,.7); border-radius: 12px; padding: 16px 20px; display: flex; align-items: center; gap: 18px; }
.live .kicker { color: var(--teal); margin: 0; white-space: nowrap; }
.live p { margin: 0; font-size: 15px; line-height: 1.45; }
.chip { display: inline-flex; align-items: center; justify-content: center; width: 21px; height: 21px; border-radius: 50%; font-family: 'Familjen Grotesk', sans-serif; font-size: 9.5px; font-weight: 700; color: #0d1117; vertical-align: -5px; margin: 0 1px; }
.so { margin-top: 16px; background: #1b1830; border-left: 3px solid var(--purple-line); border-radius: 0 10px 10px 0; padding: 13px 16px; font-size: 15px; line-height: 1.45; }
</style>
</head>
<body>
<div class="frame" id="diagram">
<h1>Where each thing lives in Adom Gantt</h1>
<p class="lede">Two kinds of state: how <b>you</b> are looking at the plan stays in your browser; the <b>plan itself</b> lives on the server and is the same for everyone.</p>
<div class="cols">
<div class="card tab">
<div class="kicker">Only this tab</div>
<h2>Gone on reload</h2>
<p class="sub">Nobody else sees it. Not even your other tabs.</p>
<ul>
<li>The section, Milestone and Dependencies chips in the legend (hide or dim)</li>
<li>What you have selected, the open editor, where you have scrolled</li>
<li>Undo history, your own changes only<span class="key">Ctrl+Z</span></li>
<li>"See what the team sees" preview</li>
</ul>
</div>
<div class="card browser">
<div class="kicker">This browser</div>
<h2>Remembered, never shared</h2>
<p class="sub">Your view only. Kept for this plan in this browser, across reloads.</p>
<ul>
<li><b>Collapse all</b>, each section's fold, and which tasks' subtasks you opened (folded until you do)</li>
<li><b>Owner</b> (one filter for the chart and the table), Current, Overdue and tag filters</li>
<li>Lens: Gantt, Table, Analytics, Setup</li>
<li>Days / weeks / months, text size, light or dark, milestone style, Today line</li>
<li>Critical path highlight</li>
<li>Name column width; table columns and sort</li>
<li>Which legend chips are folded away</li>
<li>Which answers and notices in Requests you have seen</li>
</ul>
<p class="foot">Every tab of this plan in this browser shares these. Another computer or browser starts from the plan's defaults.</p>
</div>
<div class="arrows">
<div>your changes go out field by field, in about a second
<svg class="arrow" viewBox="0 0 74 12"><path d="M2 6h62" stroke="currentColor" stroke-width="2" fill="none"/><path d="M62 1l10 5-10 5z" fill="currentColor"/></svg></div>
<div><svg class="arrow" viewBox="0 0 74 12"><path d="M72 6H10" stroke="currentColor" stroke-width="2" fill="none"/><path d="M12 1L2 6l10 5z" fill="currentColor"/></svg>
everyone else's arrive live; a tab that falls behind fetches the whole plan</div>
</div>
<div class="card server">
<div class="kicker">The plan's server</div>
<h2>The plan: same for everyone</h2>
<p class="sub">Saved by the adom-gantt server, on every teammate's screen within a second.</p>
<ul>
<li><b>Every task and milestone:</b> name, dates, owner, status, notes, tags, effort, provenance link, dependencies, the task it sits under</li>
<li><b>Sections:</b> names, colours, leads, order; each row's place, under its task or in its section; tag colours</li>
<li>Anything that moves dates: dragging a bar, editing a row, <b>Auto-schedule</b> (owner only)</li>
<li><b>Project dates and the working calendar</b> on Setup (owner only)</li>
<li>Adding, deleting, pasting and importing rows</li>
<li><b>Requests:</b> who asked whom to take a task, the answers, the notices of moved dates; <b>People</b>: the account behind each owner name</li>
<li>The changelog (who changed what), daily backups</li>
<li>Sharing and the Google Chat digest (owner only)</li>
</ul>
</div>
</div>
<div class="live">
<div class="kicker">Live, never saved</div>
<p>Who has the plan open <span class="chip" style="background:#1fc7b6">DO</span><span class="chip" style="background:#e3b341">AB</span>, and which rows each person has selected, the coloured rows with initials. The server passes it on and forgets it when they close the tab.</p>
</div>
<div class="so"><b>So:</b> when you press Collapse all, filter to Unassigned, or switch to the table, only your screen changes. When you drag a bar, change a status or press Auto-schedule, everyone's does. Setting someone else as the owner asks them first, and moving their dates tells them.</div>
</div>
</body>
</html>