From e9a7749153f2c88f0eede95f9e07a3cd02f1293d Mon Sep 17 00:00:00 2001 From: ZDDC Date: Sat, 9 May 2026 20:27:23 -0500 Subject: [PATCH] style(nav): mount stage strip above the header instead of below MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Project-level chrome (where in the project) belongs OUTSIDE tool-level chrome (which tool / theme / help) in reading order. Stage strip now sits above .app-header rather than after it. One-line behavioral change in shared/nav.js (insertBefore(strip, header) instead of insertBefore(strip, header.nextSibling)) plus the matching nav.spec.js assertion. Visual hierarchy is now: ┌─────────────────────────────────────────┐ │ projA / Archive · Working · … (strip) │ ← outer scope ├─────────────────────────────────────────┤ │ [logo] ZDDC Archive v… [theme][help] │ ← tool chrome ├─────────────────────────────────────────┤ │ page content │ └─────────────────────────────────────────┘ Co-Authored-By: Claude Opus 4.7 (1M context) --- shared/nav.js | 11 +++++++---- tests/nav.spec.js | 8 ++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/shared/nav.js b/shared/nav.js index 00b4bbc..c46ca2d 100644 --- a/shared/nav.js +++ b/shared/nav.js @@ -110,15 +110,18 @@ var header = document.querySelector('.app-header'); if (!header) return; // Don't double-mount if a tool's main.js calls us a second time. - if (header.nextElementSibling && - header.nextElementSibling.classList && - header.nextElementSibling.classList.contains('zddc-stage-strip')) { + if (header.previousElementSibling && + header.previousElementSibling.classList && + header.previousElementSibling.classList.contains('zddc-stage-strip')) { return; } var project = projectSegment(location.pathname); var active = currentStage(location.pathname); var strip = buildStrip(project, active); - header.parentNode.insertBefore(strip, header.nextSibling); + // Mount ABOVE the header — the strip is project-level chrome + // (where in the project), the header is tool-level chrome (which + // tool, theme, help). Reading order matches outer-to-inner scope. + header.parentNode.insertBefore(strip, header); } // Expose for tests + opt-out. diff --git a/tests/nav.spec.js b/tests/nav.spec.js index 4dbd79e..95f9c26 100644 --- a/tests/nav.spec.js +++ b/tests/nav.spec.js @@ -79,13 +79,13 @@ test.describe('shared/nav.js stage strip', () => { ]); }); - test('mounts immediately under the app-header', async ({ page }) => { + test('mounts immediately above the app-header', async ({ page }) => { await page.goto(`${baseUrl}/projA/archive.html`, { waitUntil: 'load' }); - const next = await page.evaluate(() => { + const prev = await page.evaluate(() => { const h = document.querySelector('.app-header'); - return h && h.nextElementSibling && h.nextElementSibling.className; + return h && h.previousElementSibling && h.previousElementSibling.className; }); - expect(next).toContain('zddc-stage-strip'); + expect(prev).toContain('zddc-stage-strip'); }); });