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
← Commit history
0.8.7: move the text size control to the right end of the header
The left cluster was doing too much: brand, lens toggle, text size, then the
project. It is back to brand, toggle, project.
Keeping the control's position invariant meant reckoning with the fact that the
right-hand group is right-aligned, which inverts where stable lives: in a
left-anchored row the first element is fixed, in a right-aligned one it is the
last. So it goes in as the final child of .actions, past the help button. Its
right edge is now the header's own right padding, and everything that hides or
changes width, milestone style, theme, the button labels below 1460px, sits
upstream of it where it cannot reach.
Left cluster is 112px narrower: it ran to 379px, it now ends at 267px.
5 files changed
+32−9
README.md+1−1@@ -36,7 +36,7 @@ Interactive Gantt chart viewer for project timelines. Data-driven, dark by defau **Move the whole plan.** The project start sits in the header. Change it and every task, milestone and phase shifts by the same number of days, so durations and the gaps between them survive. Revert puts the plan back to the data file's own start. It is one undo step and one changelog entry, not 26. -**Text size.** A-minus and A-plus in the header step the whole app between 85% and 150% in seven steps, chart and table together. The percentage between them is the reset. Rows, bars and the axis grow with the type, so nothing is clipped, and the choice persists.+**Text size.** A-minus and A-plus at the right end of the header step the whole app between 85% and 150% in seven steps, chart and table together. The percentage between them is the reset. Rows, bars and the axis grow with the type, so nothing is clipped, and the choice persists. **Fit to the pane.** One click on Fit picks the finest cell size that shows the whole plan without scrolling sideways, then stretches the cells to fill the width exactly. Click it again after resizing the window to re-fit.
docs/BUILD-NOTES.md+18@@ -3,6 +3,24 @@ Decisions taken while building, and the places where the plan and the code disagreed. Newest first. +## Build notes, 2026-08-07 (0.8.7)++The text-size control moved from the left cluster to the far right of the header.+The left was doing too much: brand, toggle, text size, then the project. It is+back to brand, lens toggle, project.++The control had to keep its position invariant, and the right-hand group is+right-aligned, which inverts where "stable" lives: in a left-anchored row the+first element is fixed, in a right-aligned one it is the last. So it went in as+the final child of .actions, past the help button. Its right edge is now the+header's own right padding, and everything that hides or changes width (milestone+style, theme, the button labels below 1460px) sits upstream of it where it cannot+reach. Measured 16px from the header's right edge at 1600, 1280 and 1100, and the+rect is identical across milestone-style, theme and view switches and while+stepping the scale itself.++Left cluster is 112px narrower: it used to run to 379px, it now ends at 267px.+ ## Build notes, 2026-08-07 (0.8.6, user feedback) **The header named one project three times.** Brand carried an app-name and a
gantt.html+11−6@@ -434,7 +434,11 @@ table.data-table { font-size: calc(12px * var(--fs)); min-width: calc(900px * va /* The scale control itself never scales: it is chrome, and a control that grew as you pressed it would walk away from the pointer. */-.fs-ctl { display: flex; align-items: stretch; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; flex-shrink: 0; background: var(--bg); }+/* Last child of the right-aligned .actions group, which is the only position in+ that group that cannot move: its right edge is the header's right padding, and+ everything that hides or changes label (milestone style, theme, the button+ labels under 1460px) is upstream of it. */+.fs-ctl { display: flex; align-items: stretch; height: 24px; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; flex-shrink: 0; background: var(--bg); } .fs-ctl button { background: none; border: none; color: var(--text2); cursor: pointer; padding: 0; transition: background 0.15s, color 0.15s; display: flex; align-items: center; justify-content: center; } .fs-ctl button:hover { background: rgba(255,255,255,0.05); color: var(--text); } .fs-ctl .fs-btn { width: 26px; }@@ -728,11 +732,6 @@ $('hdr').innerHTML = ` <button class="vt-btn" data-view="table" role="tab"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 9.5h18M3 15h18M10 9.5V20"/></svg>Table</button> </div>- <div class="fs-ctl" id="fsCtl">- <button class="fs-btn" id="fsDown" title="Smaller text"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><text x="12" y="17" text-anchor="middle" font-family="Familjen Grotesk,sans-serif" font-size="14" font-weight="600">A</text></svg></button>- <button class="fs-pct" id="fsPct" title="Text size. Click to go back to 100%"></button>- <button class="fs-btn fs-big" id="fsUp" title="Larger text"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><text x="12" y="19" text-anchor="middle" font-family="Familjen Grotesk,sans-serif" font-size="20" font-weight="600">A</text></svg></button>- </div> <div class="vsep"></div> <!-- One title, one subtitle. The brand used to repeat the project as an app-name plus a second subtitle, so a single plan was named three times. -->@@ -755,6 +754,12 @@ $('hdr').innerHTML = ` <button class="act-btn" id="btnImport" title="Import a plan: JSON, CSV, MS Project XML or Jira CSV"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 3v12m0 0l-4-4m4 4l4-4M4 17v2a2 2 0 002 2h12a2 2 0 002-2v-2"/></svg><span class="btn-label">Import</span></button> <button class="act-btn" id="btnExport" title="Export this plan: JSON, CSV, SVG or a self-contained HTML snapshot"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 21V9m0 0l4 4m-4-4l-4 4M4 7V5a2 2 0 012-2h12a2 2 0 012 2v2"/></svg><span class="btn-label">Export</span></button> <button class="act-btn" id="btnHelp" style="font-family:'Familjen Grotesk',sans-serif;font-size:14px;font-weight:600;padding:4px 9px">?</button>+ <div class="vsep"></div>+ <div class="fs-ctl" id="fsCtl">+ <button class="fs-btn" id="fsDown" title="Smaller text"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><text x="12" y="17" text-anchor="middle" font-family="Familjen Grotesk,sans-serif" font-size="14" font-weight="600">A</text></svg></button>+ <button class="fs-pct" id="fsPct" title="Text size. Click to go back to 100%"></button>+ <button class="fs-btn fs-big" id="fsUp" title="Larger text"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><text x="12" y="19" text-anchor="middle" font-family="Familjen Grotesk,sans-serif" font-size="20" font-weight="600">A</text></svg></button>+ </div> </div>`; applyView(); // again, now that the toggle buttons exist
package.json+1−1@@ -2,7 +2,7 @@ "slug": "adom-gantt", "title": "Adom Gantt", "type": "app",- "version": "0.8.6",+ "version": "0.8.7", "description": "Interactive Gantt chart viewer for project timelines, with a table view 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. Toggle to the table for every task and milestone as a row with owner, deadline and status, filtered per owner and edited in place. Every edit is recorded in an append-only changelog so an AI can read what a human changed and build on it. Imports JSON, CSV, MS Project XML and Jira CSV; exports JSON, CSV, SVG and a self-contained HTML snapshot.", "main": "server.js", "bin": {
page.json+1−1@@ -2,7 +2,7 @@ "slug": "adom-gantt", "title": "Adom Gantt", "type": "app",- "version": "0.8.6",+ "version": "0.8.7", "description": "Interactive Gantt chart viewer for project timelines, with a table view 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. Toggle to the table for every task and milestone as a row with owner, deadline and status, filtered per owner and edited in place. Every edit is recorded in an append-only changelog so an AI can read what a human changed and build on it. Imports JSON, CSV, MS Project XML and Jira CSV; exports JSON, CSV, SVG and a self-contained HTML snapshot.", "main": "server.js", "bin": {