Files
Joshua KingandClaude Opus 5 d9ed1898b9 Add the Extrudex Design System v3 bundle
Tokens (light + dark, neumorphism, 54/54 WCAG AA contrast pairs), the
self-hosted JetBrains Mono fonts, and interactive mockups of every screen
across three iterations. Iteration 3 is final: phone, tablet and desktop
tiers, device preview, and "empty spool weight" terminology. The build
scripts regenerate the screens byte-identically from source.

Implementation is tracked in Maestro feature UI Refresh - V3.0
(224b72a1-8d84-4970-97ea-5dafa4d8ea3b).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 11:31:50 -04:00

50 lines
5.0 KiB
HTML
Raw Permalink 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>
.dv-bar { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
.dv-row { display: flex; gap: var(--space-6); align-items: flex-start; flex-wrap: wrap; }
.dev { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.dev h2 { margin: 0; font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--tracking-caps-wide); color: var(--text-secondary); }
.bezel { border-radius: 36px; padding: 14px; background: linear-gradient(145deg, #3a3a40, #1b1b1e); box-shadow: var(--nm-raised-3); border: 1px solid var(--border-control); }
.bezel.tab { border-radius: 28px; padding: 18px; }
.screen { overflow: hidden; border-radius: 24px; background: var(--surface-page); position: relative; }
.bezel.tab .screen { border-radius: 12px; }
.screen iframe { border: 0; transform-origin: 0 0; position: absolute; left: 0; top: 0; }
.dv-list { display: flex; gap: 6px; flex-wrap: wrap; }
.dv-list button { font: var(--fw-medium) 12px/1 var(--font-body); padding: 8px 12px; border-radius: var(--radius-pill); border: 1px solid var(--border-control); background: var(--surface-raised); color: var(--text-primary); cursor: pointer; }
.dv-list button[aria-pressed="true"] { background: var(--accent-wash); border-color: var(--text-accent); color: var(--text-accent); font-weight: 700; }
.dv-list button[aria-pressed="true"]::before { content: "✓ "; }
.dv-list button:focus-visible { outline: var(--focus-width) solid var(--focus-ring); outline-offset: 2px; }
.bp { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: var(--space-3); }
.bp div { padding: var(--space-4); font-size: 13px; }
.bp b { display: block; margin-bottom: 4px; }
</style>
<script>
(function () {
var SCREENS = [['01-dashboard.html', 'Dashboard'], ['02-filament.html', 'Filament'], ['02-filament.html?f=low#spool=41&tab=weigh', 'Weigh panel'], ['03-prints.html', 'Prints'], ['04-printers.html', 'Printers'], ['05-lists.html', 'Lists'], ['06-labels.html', 'Labels'], ['07-access.html', 'Access'], ['08-system.html', 'System'], ['09-scan-holder.html', 'Scan: holder'], ['10-scan-spool.html?s=44', 'Scan: spool'], ['02-filament.html?palette=weigh', 'Palette']];
var DEV = [['Phone', 390, 844, 0.62, ''], ['Tablet portrait', 820, 1180, 0.46, 'tab'], ['Tablet landscape', 1180, 820, 0.5, 'tab']];
var q = new URLSearchParams(location.search);
var S = { i: +(q.get('i') || 0), theme: q.get('t') || 'dark' };
function url(u) { return u.replace(/(\?[^#]*)?(#.*)?$/, function (m, qs, h) { return (qs ? qs + '&' : '?') + 'theme=' + S.theme + (h || ''); }); }
function frames() {
return DEV.map(function (d) {
var w = Math.round(d[1] * d[3]), h = Math.round(d[2] * d[3]);
return '<div class="dev"><h2>' + d[0] + ' · ' + d[1] + ' × ' + d[2] + '</h2><div class="bezel ' + d[4] + '"><div class="screen" style="width:' + w + 'px;height:' + h + 'px"><iframe title="' + SCREENS[S.i][1] + ' on ' + d[0] + '" src="' + url(SCREENS[S.i][0]) + '" width="' + d[1] + '" height="' + d[2] + '" style="transform:scale(' + d[3] + ')"></iframe></div></div><a class="small" href="' + url(SCREENS[S.i][0]) + '" target="_blank" rel="noopener">Open full size ↗</a></div>';
}).join('');
}
function render() {
return '<header class="page-head"><div><h1>Devices</h1><p class="sum">Every screen on a phone and on a tablet, portrait and landscape. The frames are live, so you can click inside them.</p></div>' +
'<div class="tabs" role="group" aria-label="Preview theme"><button type="button" data-t="dark" aria-selected="' + (S.theme === 'dark') + '">Dark</button><button type="button" data-t="light" aria-selected="' + (S.theme === 'light') + '">Light</button></div></header>' +
'<div class="dv-list" role="group" aria-label="Screen">' + SCREENS.map(function (s, i) { return '<button type="button" data-i="' + i + '" aria-pressed="' + (i === S.i) + '">' + s[1] + '</button>'; }).join('') + '</div>' +
'<div class="dv-row">' + frames() + '</div>' +
'<section class="bp" aria-label="Breakpoints"><div class="nm-inset"><b>Phone · under 700 px</b>Bottom tab bar (4 + More) with badges, a floating + for the page\'s main action, panels as full-screen sheets, tables drop to 2–3 columns, 44 px touch targets.</div>' +
'<div class="nm-inset"><b>Tablet · 700–1180 px</b>Compact icon rail with labels and badges, panels as a 480 px side sheet over the page, low-priority columns hidden, no keyboard hints on touch.</div>' +
'<div class="nm-inset"><b>Desktop · over 1180 px</b>Full rail with the Manage group, a 520 px panel, all columns, keyboard shortcuts shown.</div></section>';
}
function redraw() { document.getElementById('page').innerHTML = render(); history.replaceState(null, '', location.pathname + '?i=' + S.i + '&t=' + S.theme); }
document.addEventListener('click', function (e) {
var a = e.target.closest('[data-i]'); if (a) { S.i = +a.getAttribute('data-i'); return redraw(); }
a = e.target.closest('[data-t]'); if (a) { S.theme = a.getAttribute('data-t'); return redraw(); }
});
X.init({ name: 'devices' }, render);
})();
</script>