Files
design-v3/index.html
T
2026-09-25 10:26:24 -04:00

80 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<style>
.map { padding: var(--space-5); }
.map svg { width: 100%; height: auto; display: block; }
.map .node rect { fill: var(--surface-raised); stroke: var(--border-control); stroke-width: 1.5; }
.map .node.hub rect { fill: var(--accent-wash); stroke: var(--text-accent); stroke-width: 2; }
.map .node.page rect { stroke: var(--text-primary); }
.map text { fill: var(--text-primary); font-family: var(--font-mono); font-size: 13px; }
.map text.s { fill: var(--text-secondary); font-size: 11px; }
.map .e { stroke: var(--text-secondary); stroke-width: 1.5; fill: none; }
.map .e.hot { stroke: var(--text-accent); stroke-width: 2; }
.map .lbl { fill: var(--text-secondary); font-size: 10.5px; }
.map a:focus-visible rect { stroke: var(--focus-ring); stroke-width: 3; }
.flows { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr)); gap: var(--space-4); }
.flow { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
.flow h3 { margin: 0; font-size: 15px; }
.flow ol { margin: 0; padding-left: 20px; font-size: 13px; color: var(--text-secondary); display: flex; flex-direction: column; gap: 4px; }
.flow ol b { color: var(--text-primary); }
.flow .btn { align-self: flex-start; }
.compare { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: var(--space-4); }
.compare > div { padding: var(--space-4); font-size: 13px; }
.compare h3 { margin: 0 0 8px; font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--tracking-caps-wide); color: var(--text-secondary); }
.compare ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; }
</style>
<script>
(function () {
function node(x, y, w, h, t, s, cls, href) {
var inner = '<g class="node ' + cls + '"><rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '" rx="14"/><text x="' + (x + 16) + '" y="' + (y + 26) + '" font-weight="700">' + t + '</text>' + s.map(function (l, i) { return '<text class="s" x="' + (x + 16) + '" y="' + (y + 46 + i * 16) + '">' + l + '</text>'; }).join('') + '</g>';
return href ? '<a href="' + href + '">' + inner + '</a>' : inner;
}
function edge(d, hot, lx, ly, label) { return '<path class="e' + (hot ? ' hot' : '') + '" d="' + d + '" marker-end="url(#ar' + (hot ? 'h' : '') + ')"/>' + (label ? '<text class="lbl" x="' + lx + '" y="' + ly + '">' + label + '</text>' : ''); }
function svg() {
return '<svg viewBox="0 -50 1100 600" role="img" aria-labelledby="map-t map-d"><title id="map-t">Extrudex iteration 2 flow map</title><desc id="map-d">Four pages share one navigation, a command palette and a detail panel. The Dashboard links into each page\'s filtered views; spools, prints and holders open in the panel from any page.</desc>' +
'<defs><marker id="ar" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 10 5 0 10z" fill="var(--text-secondary)"/></marker><marker id="arh" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 10 5 0 10z" fill="var(--text-accent)"/></marker></defs>' +
node(30, 30, 230, 110, 'Dashboard', ['“Needs you” queue', 'stock · recent prints', 'printers · running low'], 'page', '01-dashboard.html') +
node(310, 30, 230, 110, 'Filament', ['saved views + counts', 'Stock / Weights columns', 'weigh session'], 'page', '02-filament.html') +
node(590, 30, 230, 110, 'Prints', ['Needs attention queue', 'All · Running · Archived', 'batch attribute'], 'page', '03-prints.html') +
node(870, 30, 200, 110, 'Printers', ['urgency order', 'holders + Load', 'connection state'], 'page', '04-printers.html') +
node(250, 300, 600, 130, 'Detail panel (#spool= · #print= · #load=)', ['Spool: Overview · Weigh · Move · Edit (+ 409 / 400 states)', 'Print: what it needs, fixed in place · provenance explained', 'Load: pick a stored spool for a holder with space', 'Opens over any page · Esc / back closes · ↑↓ / j k step through the list'], 'hub', '02-filament.html#spool=47') +
node(30, 450, 300, 90, '⌘K / “/” palette', ['spools · prints · printers', '“weigh copper” jumps straight in'], 'hub', null) +
node(770, 450, 300, 90, 'Toasts + badges', ['every save confirms what changed', 'nav counts update immediately'], '', null) +
edge('M262 85 L306 85', 1, 262, 76, 'views') +
edge('M180 30 C180 -18 705 -18 705 26', 1, 395, -8, 'Review N prints') +
edge('M110 30 C110 -38 970 -38 970 26', 1, 520, -30, 'Open printer') +
edge('M145 140 C145 230 330 250 400 298', 1, 150, 225, 'spool / print rows') +
edge('M425 140 L470 298', 1, 452, 230, 'row / ↵') +
edge('M705 140 L640 298', 1, 680, 230, 'row / fix') +
edge('M970 140 C970 230 860 270 800 298', 1, 900, 235, 'spool · + Load') +
edge('M180 450 C180 400 240 380 248 380', 0, 120, 420, 'open anything') +
edge('M850 380 C900 400 920 420 920 448', 0, 930, 415, 'after save') +
'</svg>';
}
var FLOWS = [
['Morning check (≈1 min)', ['<b>Dashboard</b> opens on “Needs you”', 'Review 3 → <b>Use</b> the same-color suggestion', 'Badge on <b>Prints</b> drops as each one clears'], '01-dashboard.html', 'Start on the Dashboard'],
['Weigh the low spools', ['<b>Filament → Low</b> view', '<b>Start weighing</b>: type the scale reading', 'See before → after, then <b>Save & weigh next</b>'], '02-filament.html?f=low', 'Open low stock'],
['Load a spool into a printer', ['<b>Printers</b> → A1 AMS Lite → <b>+ Load</b>', 'Filter stored spools, pick one', 'Toast confirms; the holder fill updates'], '04-printers.html#printer=3', 'Open A1'],
['Find anything', ['Press <b>/</b> or <b>⌘K</b> on any page', 'Type <i>copper</i>, <i>#47</i> or <i>weigh black</i>', '↵ opens the panel right there'], '02-filament.html', 'Try it on Filament'],
['Someone changed it first (409)', ['Spool #47 → <b>Edit</b>', 'Demo state: <b>409 conflict</b>', 'Side-by-side; reapply your change, or discard it'], '02-filament.html#spool=47&tab=edit', 'Open the editor'],
['A spool with no empty spool weight', ['<b>Empty spool weight unverified</b> view (7)', 'Weigh tab explains why it can\'t weigh yet', 'Pick a spool type, or weigh the empty spool'], '02-filament.html?f=tare#spool=44&tab=weigh', 'Open #44'],
['A printer drops off', ['<b>Printers</b>: A1 sits first with a warning border', 'Toggle <b>dev today / + feature branch</b>', 'What happens on reconnect is spelled out'], '04-printers.html#printer=3', 'Open Printers'],
['Label new spools', ['<b>Labels</b> → Needs a label (4)', 'Previews at real 51 × 21 mm proportions', '<b>Download</b>: they\'re marked printed on success'], '06-labels.html', 'Open Labels'],
['Load spools at the printer (phone)', ['Scan the <b>AMS Lite</b> holder label', 'Scan spool labels: each loads, returns or moves', 'A full holder says so; nothing changes'], '09-scan-holder.html?c=5', 'Open scan session'],
['Weigh from a label (phone)', ['Scan a spool label with no session active', 'See where it lives; type the scale reading', 'Before → after, then <b>Save</b>'], '10-scan-spool.html?s=41', 'Open #41'],
['Fix a wrong attribution', ['Print <b>Benchy_x4</b> → <b>Change spool</b>', 'See: 46 g goes back to Elegoo Black', 'Pick the right spool; cost re-rates'], '03-prints.html?tab=all#print=211', 'Open Benchy_x4'],
['Add or remove a printer', ['<b>Printers → + Add printer</b>: brand filters models', 'Remove asks for the exact name', 'Refused while its holders still hold spools'], '04-printers.html#premove=3', 'Try removing A1'],
['Palette commands', ['<b>/</b> then <i>load copper into p1s ext</i>', 'or <i>attribute bracket to black</i>', '↵ does it; a toast confirms'], '02-filament.html?palette=load%20', 'Open palette'],
['When the data is not live', ['Mockup pill (bottom left) → <b>Simulate polling failure</b>', 'Header turns amber, banner says the data\'s age', '<b>Replay first load</b> shows skeletons'], '01-dashboard.html', 'Open Dashboard']
];
function render() {
return '<header class="page-head"><div><h1>Flow map</h1><p class="sum">Iteration 3 · every screen, how they connect, and <b>' + FLOWS.length + ' flows</b> to click through</p></div><div class="actions"><a class="btn" href="../../iteration-2/screens/index.html">← Iteration 2</a><a class="btn btn-primary" href="devices.html">Devices →</a></div></header>' +
'<section class="map nm-raised" aria-label="Flow diagram">' + svg() + '</section>' +
'<section class="stack" style="gap:12px" aria-labelledby="sc-h"><h2 class="section" id="sc-h" style="margin:0">All screens · <a href="devices.html">see them on phone and tablet →</a></h2><div class="flows">' +
[['01-dashboard.html', 'Dashboard', 'Needs you · stock · recent prints'], ['02-filament.html', 'Filament', 'views · weigh session · panel'], ['03-prints.html', 'Prints', 'attention queue · history'], ['04-printers.html', 'Printers', 'holders · load · admin panels'], ['05-lists.html', 'Lists', 'the 5 name parts + spool types'], ['06-labels.html', 'Labels', 'spool + holder QR labels'], ['07-access.html', 'Access', 'people · sessions · API tokens'], ['08-system.html', 'System', 'weekly report · audit · device'], ['09-scan-holder.html', 'Scan: holder', 'phone · load/return/move'], ['10-scan-spool.html', 'Scan: spool', 'phone · weigh from a label']].map(function (s2) { return '<a class="flow nm-raised" style="text-decoration:none;color:inherit;padding:14px 16px" href="' + s2[0] + '"><h3>' + s2[1] + ' →</h3><span class="small muted">' + s2[2] + '</span></a>'; }).join('') + '</div></section>' +
'<section aria-labelledby="fl-h" class="stack" style="gap:12px"><h2 class="section" id="fl-h" style="margin:0">Try these flows</h2><div class="flows">' + FLOWS.map(function (f) { return '<article class="flow nm-raised"><h3>' + f[0] + '</h3><ol>' + f[1].map(function (s) { return '<li>' + s + '</li>'; }).join('') + '</ol><a class="btn btn-sm" href="' + f[2] + '">' + f[3] + ' →</a></article>'; }).join('') + '</div></section>' +
'<section class="compare" aria-label="What changed"><div class="nm-inset"><h3>Iteration 1</h3><ul><li>“Prints” and “All prints” were dead ends</li><li>Edit left the list for a separate page</li><li>A spool in an AMS slot or low-stock list went nowhere</li><li>Every data point was a loud chip, so a legend was needed</li><li>No freshness, loading or error state</li><li>Invented “slot 2” positions the database doesn\'t store</li></ul></div>' +
'<div class="nm-raised"><h3>Iteration 2</h3><ul><li>Every spool, print and holder opens one shared panel, deep-linkable</li><li>Dashboard leads with what needs doing, each item one click from the fix</li><li>Chips only for state; provenance is quiet text with a tooltip</li><li>Palette, badges, toasts, j/k stepping, Esc/back to close</li><li>“Live · updated 3s ago”, with an honest offline state</li><li>Holders show fill (“3 / 4”), not tray positions</li></ul></div></section>';
}
X.init({ name: 'map' }, render);
})();
</script>