Skip to content

Commit bc5b8ae

Browse files
Put "design one bin" where someone looking for it would look
The two ways in were the bottom of panel 03 -- which only appears with nothing selected -- and a button under the drawer map. Both sit below a large panel about laying out a whole drawer, so someone who arrived wanting one bin that fits one thing had to read past the thing they were not doing to find the thing they were. It goes under the nav rather than in it. The nav is a row of page links and carries the layout across them; an action sitting in that row reads like a fourth page, and it is a mode switch rather than a destination. The markup is in the bins template, so chrome.js -- which runs on the baseplates page and every guide page too -- is untouched. A case pins that the baseplates page did not sprout a control for a mode it does not have. Wired through the loop the other two entry points already share rather than a third copy of the handler, so a change to what starting a loose bin means cannot reach two of the three. Hidden once you are already in the mode, by the class that hides everything else focus takes away. The way in is noise from inside; the way out is what the focus bar is for. Both older entry points are left alone. Three ways in is arguably one too many now, but which of them to drop is a taste question and not mine to answer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 4dbf301 commit bc5b8ae

9 files changed

Lines changed: 117 additions & 2 deletions

File tree

bins/index.html

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@
315315

316316
/* ---- cross-tool navigation ---- */
317317
header nav{display:flex;gap:6px;margin-top:14px}
318+
header .quickstart{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:10px}
319+
header .quickstart span{font-size:11.5px;color:var(--dim);max-width:52ch}
320+
/* Already designing one bin, so the way in is noise -- the way OUT is what the focus bar
321+
is for. Hidden by the same class that hides everything else focus takes away. */
322+
body.binfocus header .quickstart{display:none}
318323
header nav a{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
319324
padding:7px 15px;border:1px solid var(--line);border-radius:6px;color:var(--dim);
320325
text-decoration:none;background:var(--panel2);transition:color .12s,border-color .12s}
@@ -631,6 +636,14 @@ <h1>DRAWER<span class="tm">FORGE</span> <span class="tm" style="opacity:.55">·
631636
<a id="navBins" href="./" class="on">Bins</a>
632637
<a id="navGuide" href="../guide/">Guide</a>
633638
</nav>
639+
<!-- Under the nav rather than in it. The nav is a row of page links and carries the
640+
layout across them; this is a mode switch, and an action sitting in that row reads
641+
like a fourth page. Plenty of people arrive wanting one bin that fits one thing,
642+
and the way in was the bottom of a panel about laying out a whole drawer. -->
643+
<div class="quickstart" id="quickstart">
644+
<button type="button" class="act" id="scratchBinTop">Design one bin on its own</button>
645+
<span>No drawer and no layout — just a bin, sized, previewed and exported on its own.</span>
646+
</div>
634647
</header>
635648
<!-- Only shown when the layout came back from this browser rather than from a link.
636649
Restoring in silence leaves you unsure whether you are looking at what you left or
@@ -5001,7 +5014,8 @@ <h2 id="exportTitle">Download your bins</h2>
50015014
readControls(); drawLayerTabs(); drawMap(); refresh();
50025015
}
50035016
$('focusBin').addEventListener('click', enterFocus);
5004-
for (const id of ['scratchBin', 'scratchBinMap']) $(id).addEventListener('click', startScratch);
5017+
for (const id of ['scratchBin', 'scratchBinMap', 'scratchBinTop'])
5018+
$(id).addEventListener('click', startScratch);
50055019
$('scratchAdd').addEventListener('click', addScratchToDrawer);
50065020
$('scratchDrop').addEventListener('click', discardScratch);
50075021
$('focusExit').addEventListener('click', () => leaveFocus());

guide/drawer-sizes/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@
305305

306306
/* ---- cross-tool navigation ---- */
307307
header nav{display:flex;gap:6px;margin-top:14px}
308+
header .quickstart{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:10px}
309+
header .quickstart span{font-size:11.5px;color:var(--dim);max-width:52ch}
310+
/* Already designing one bin, so the way in is noise -- the way OUT is what the focus bar
311+
is for. Hidden by the same class that hides everything else focus takes away. */
312+
body.binfocus header .quickstart{display:none}
308313
header nav a{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
309314
padding:7px 15px;border:1px solid var(--line);border-radius:6px;color:var(--dim);
310315
text-decoration:none;background:var(--panel2);transition:color .12s,border-color .12s}

guide/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@
305305

306306
/* ---- cross-tool navigation ---- */
307307
header nav{display:flex;gap:6px;margin-top:14px}
308+
header .quickstart{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:10px}
309+
header .quickstart span{font-size:11.5px;color:var(--dim);max-width:52ch}
310+
/* Already designing one bin, so the way in is noise -- the way OUT is what the focus bar
311+
is for. Hidden by the same class that hides everything else focus takes away. */
312+
body.binfocus header .quickstart{display:none}
308313
header nav a{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
309314
padding:7px 15px;border:1px solid var(--line);border-radius:6px;color:var(--dim);
310315
text-decoration:none;background:var(--panel2);transition:color .12s,border-color .12s}

guide/split/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@
317317

318318
/* ---- cross-tool navigation ---- */
319319
header nav{display:flex;gap:6px;margin-top:14px}
320+
header .quickstart{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:10px}
321+
header .quickstart span{font-size:11.5px;color:var(--dim);max-width:52ch}
322+
/* Already designing one bin, so the way in is noise -- the way OUT is what the focus bar
323+
is for. Hidden by the same class that hides everything else focus takes away. */
324+
body.binfocus header .quickstart{display:none}
320325
header nav a{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
321326
padding:7px 15px;border:1px solid var(--line);border-radius:6px;color:var(--dim);
322327
text-decoration:none;background:var(--panel2);transition:color .12s,border-color .12s}

index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,11 @@
314314

315315
/* ---- cross-tool navigation ---- */
316316
header nav{display:flex;gap:6px;margin-top:14px}
317+
header .quickstart{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:10px}
318+
header .quickstart span{font-size:11.5px;color:var(--dim);max-width:52ch}
319+
/* Already designing one bin, so the way in is noise -- the way OUT is what the focus bar
320+
is for. Hidden by the same class that hides everything else focus takes away. */
321+
body.binfocus header .quickstart{display:none}
317322
header nav a{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
318323
padding:7px 15px;border:1px solid var(--line);border-radius:6px;color:var(--dim);
319324
text-decoration:none;background:var(--panel2);transition:color .12s,border-color .12s}

src/bins/template.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ <h1>DRAWER<span class="tm">FORGE</span> <span class="tm" style="opacity:.55">·
4444
<a id="navBins" href="./" class="on">Bins</a>
4545
<a id="navGuide" href="../guide/">Guide</a>
4646
</nav>
47+
<!-- Under the nav rather than in it. The nav is a row of page links and carries the
48+
layout across them; this is a mode switch, and an action sitting in that row reads
49+
like a fourth page. Plenty of people arrive wanting one bin that fits one thing,
50+
and the way in was the bottom of a panel about laying out a whole drawer. -->
51+
<div class="quickstart" id="quickstart">
52+
<button type="button" class="act" id="scratchBinTop">Design one bin on its own</button>
53+
<span>No drawer and no layout — just a bin, sized, previewed and exported on its own.</span>
54+
</div>
4755
</header>
4856
<!-- Only shown when the layout came back from this browser rather than from a link.
4957
Restoring in silence leaves you unsure whether you are looking at what you left or

src/bins/ui.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,8 @@ function discardScratch() {
487487
readControls(); drawLayerTabs(); drawMap(); refresh();
488488
}
489489
$('focusBin').addEventListener('click', enterFocus);
490-
for (const id of ['scratchBin', 'scratchBinMap']) $(id).addEventListener('click', startScratch);
490+
for (const id of ['scratchBin', 'scratchBinMap', 'scratchBinTop'])
491+
$(id).addEventListener('click', startScratch);
491492
$('scratchAdd').addEventListener('click', addScratchToDrawer);
492493
$('scratchDrop').addEventListener('click', discardScratch);
493494
$('focusExit').addEventListener('click', () => leaveFocus());

src/shared-ui/style.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ footer .mono{font-family:var(--mono);font-size:11px}
287287

288288
/* ---- cross-tool navigation ---- */
289289
header nav{display:flex;gap:6px;margin-top:14px}
290+
header .quickstart{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:10px}
291+
header .quickstart span{font-size:11.5px;color:var(--dim);max-width:52ch}
292+
/* Already designing one bin, so the way in is noise -- the way OUT is what the focus bar
293+
is for. Hidden by the same class that hides everything else focus takes away. */
294+
body.binfocus header .quickstart{display:none}
290295
header nav a{font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
291296
padding:7px 15px;border:1px solid var(--line);border-radius:6px;color:var(--dim);
292297
text-decoration:none;background:var(--panel2);transition:color .12s,border-color .12s}

test/ui/entry-point.spec.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* Finding "design one bin" without reading past the thing you are not doing.
2+
*
3+
* The two ways in were the bottom of panel 03 — which only appears with nothing selected
4+
* — and a button under the drawer map. Both sit below a large panel about laying out a
5+
* whole drawer, so someone who wants one bin has to read past it to find it.
6+
*/
7+
'use strict';
8+
const { test, expect } = require('@playwright/test');
9+
const { openBins, openPlates } = require('./helpers');
10+
11+
const inMode = (page) => page.evaluate(() => ({
12+
loose: document.body.classList.contains('binscratch'),
13+
scratch: !!scratch,
14+
}));
15+
16+
test('the way in is in the header, before any panel', async ({ page }) => {
17+
const errors = await openBins(page);
18+
const btn = page.locator('#scratchBinTop');
19+
await expect(btn).toBeVisible();
20+
21+
/* In the header itself, not merely early in the document — that is what makes it
22+
findable without scrolling past the drawer-layout panel. */
23+
expect(await btn.evaluate((el) => !!el.closest('header')),
24+
'it lives in the header').toBe(true);
25+
26+
/* Above the panel it used to be buried at the bottom of. */
27+
const top = await btn.boundingBox();
28+
const panel = await page.locator('#s-bin').boundingBox();
29+
expect(top.y, 'and above the bin panel, not below it').toBeLessThan(panel.y);
30+
expect(errors).toEqual([]);
31+
});
32+
33+
test('it opens the same loose bin the old ways in do', async ({ page }) => {
34+
const errors = await openBins(page);
35+
await page.locator('#scratchBinTop').click();
36+
await page.waitForTimeout(300);
37+
38+
const m = await inMode(page);
39+
expect(m.loose, 'the body class the mode is defined by').toBe(true);
40+
expect(m.scratch, 'and a real loose bin behind it').toBe(true);
41+
/* One shared handler, so this cannot drift from the other two entry points. */
42+
expect(await page.evaluate(() => layers[cur].bins.length),
43+
'still in no layer — a loose bin is not a drawer bin').toBe(0);
44+
expect(errors).toEqual([]);
45+
});
46+
47+
/* Already designing one bin, so the way in is noise. The way OUT is the focus bar's job. */
48+
test('it gets out of the way once you are in the mode', async ({ page }) => {
49+
await openBins(page);
50+
await expect(page.locator('#scratchBinTop')).toBeVisible();
51+
await page.locator('#scratchBinTop').click();
52+
await page.waitForTimeout(300);
53+
await expect(page.locator('#quickstart')).toBeHidden();
54+
55+
await page.locator('#scratchDrop').click();
56+
await page.waitForTimeout(300);
57+
await expect(page.locator('#quickstart'),
58+
'and comes back when the drawer does').toBeVisible();
59+
});
60+
61+
/* The header is shared furniture. Bins-only markup belongs in the bins template, and the
62+
proof is that the baseplates page never grew a button for a mode it does not have. */
63+
test('the baseplates page does not sprout a bins control', async ({ page }) => {
64+
await openPlates(page);
65+
expect(await page.locator('#scratchBinTop').count(),
66+
'chrome.js is shared; this control is not').toBe(0);
67+
});

0 commit comments

Comments
 (0)