Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ Run `pnpm brand:verify` (included in `pnpm check`/CI). In the AlvenX workspace a
Visual changes require actual 390/900/1440px browser and resource-loading checks, comparison of
computed header geometry to an accepted Studio, and independent checkout verification.

The AlvenX wordmark is a native `data-alvenx-home` button with an accessible Back to top name.
Apply home-navigation revision 2026-09-04.1 from the shared interface contract: true document top,
no action when already at the top, preserved URL/history and product state, native keyboard
activation, visible focus and immediate scrolling under reduced motion.

## Testing standards

Use the layers needed by the phase:
Expand Down
19 changes: 19 additions & 0 deletions docs/assets/alvenx-ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,25 @@
height: auto;
}

/* Header home-navigation revision: 2026-09-04.1 */
.ax-product-header [data-alvenx-home] {
display: flex;
align-items: center;
flex: 0 0 auto;
width: var(--ax-product-header-wordmark-width);
min-height: var(--ax-control-height);
padding: 0;
border: 0;
border-radius: 12px;
background: transparent;
cursor: pointer;
}

.ax-product-header [data-alvenx-home]:focus-visible {
outline: 3px solid rgb(37 99 235 / 45%);
outline-offset: 4px;
}

.ax-metric-frame {
border: 1px solid var(--ax-rule);
}
Expand Down
5 changes: 3 additions & 2 deletions docs/assets/provenance.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{
"path": "docs/assets/alvenx-ui.css",
"source": "foundation/brand/interface/alvenx-ui.css",
"sha256": "7b94510cfa9fe9eebe452481f967a9482809c5158a326842971e1d457f86daf6"
"sha256": "b4bc3051213c2d9a1a37af80233d0b4978941d73c5945f6a792b84271e1d5c0c"
},
{
"path": "docs/assets/InstrumentSans-wdth-wght.woff2",
Expand All @@ -30,5 +30,6 @@
"sha256": "bc29b497c4e8316b2d248322a9cea670c2f0afc24ae0eb7bbaa54e02e00eebab"
}
],
"wordmarkAlignmentRevision": "2026-09-04.1"
"wordmarkAlignmentRevision": "2026-09-04.1",
"homeNavigationRevision": "2026-09-04.1"
}
8 changes: 8 additions & 0 deletions docs/brand.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ the subtitle-free 330×100 master, centered at 320px, followed by `<br>` and the
`<sub>FUNCTIONAL REGRESSION EVIDENCE</sub>` line before the H1. The Demo reuses that SVG at
160px inside `.ax-product-header`.

Header activation follows home-navigation revision **2026-09-04.1**: wrap the wordmark in a
native `type="button"` with `data-alvenx-home` and the accessible name `AlvenX — Back to top`.
Use the canonical CSS reset/focus rules. Pointer, Enter and Space return the current document
to its true top; activation at the top is a no-op. Preserve the complete URL/history, current
view, results and running work. Reduced motion scrolls immediately; other activation is smooth.
The implementation lives in `src/demo/public/index.html` and `app.js`; the real-browser
regression lives in `tests/playwright/demo.spec.ts`.

The shared CSS controls the static four-layer background, typography, glass surfaces and header
geometry. Product CSS may arrange the case/run workflow and add visible focus/reduced-motion
behavior; it must not override approved header values or redraw the logo.
Expand Down
28 changes: 28 additions & 0 deletions harness/context/03-brand-verifiable-demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,31 @@ Ten current computed header properties match the preserved accepted Studio refer
CSS is unchanged. Exact PR/main integration receipts are retained in
`.workspace/audits/reprolock-english-demo-20260904/` in the parent AlvenX workspace and the PR,
so recording the final merge does not change the tested source tree.

## AlvenX header activation follow-up — 2026-09-04

English PR #4 merged as `5b16d22`; both its PR and main Node 22/24 CI jobs passed and the
fixed D checkout was clean before the owner added uniform logo activation through the brand
coordinating task. Branch `codex/alvenx-header-home` implements that scoped request with one writer.
Baseline `pnpm brand:verify` and `pnpm test:browser` passed (4/4) before editing.

The native `AlvenX — Back to top` button wraps the unchanged wordmark. Its click handler returns
immediately at scrollY zero, otherwise scrolls the current document to top zero while preserving
scrollX; reduced motion uses `instant`, otherwise `smooth`. No navigation or execution state is
changed. The exact approved canonical CSS now includes the button reset and visible focus rules;
its SHA-256 is `b4bc3051213c2d9a1a37af80233d0b4978941d73c5945f6a792b84271e1d5c0c`.
Provenance records independent home-navigation revision `2026-09-04.1`.

Actual `pnpm check` passed 80/80 unit/process and 4/4 browser tests. Existing browser coverage now
checks pointer, Enter and Space under normal and reduced motion, true document top, activation
at the top, and preservation of the selected saved result, export, expanded source, URL/hash,
history and document lifetime. The three widths retain the canonical geometry and 160px wordmark;
the button has visible keyboard focus. All historical and recorded evidence verifiers passed.
`pnpm package:smoke` passed (108 files / 370,413 bytes before this receipt update).
Shared brand validation passed 22 assets, five README headers and five header-navigation contracts;
workspace validation passed five independent repositories. Independent read-only review passed.

The independent source export and exact PR/main CI integration receipts are recorded after the
source commit in `.workspace/audits/reprolock-header-home-20260904/` in the parent workspace and
the PR. This follow-up preserves all raw experiments and screenshots and does not repeat or
reclassify the historical 20+20 experiment. Product stage remains `SPIKE_CONDITIONAL`.
15 changes: 15 additions & 0 deletions plans/03-brand-verifiable-demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,18 @@ merge receipts are retained in the PR and local audit without changing the teste
- [x] English copy, documentation and current screenshot.
- [x] Browser/resource/layout, independent-export and configured engineering checks.
- [x] Independent review; exact-head PR/merge receipts close integration in the PR/local audit.

## AlvenX header activation — 2026-09-04

After English PR #4 merged as `5b16d22`, the owner requested the same header-logo activation
across all AlvenX interfaces through the coordinating brand task. ReproLock remains under one
writer in the fixed D checkout, branch `codex/alvenx-header-home`. Baseline `pnpm brand:verify`
and `pnpm test:browser` passed (4/4) before editing.

Use the canonical native `data-alvenx-home` button and shared CSS revision 2026-09-04.1.
Activation returns the document to its true top, does nothing at the top, respects reduced
motion and preserves the URL/history, current view, results and running work. Keep the existing
160px wordmark and header geometry. Update the existing browser coverage for pointer/keyboard
activation and retained state, verify the canonical assets and independent export, then review,
submit, follow both Node CI jobs, merge and synchronize D main. Preserve the English delivery
and all historical evidence; this changes interface behavior only.
2 changes: 2 additions & 0 deletions scripts/verify-brand.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export async function verifyBrand(root) {
assert.equal(provenance.schemaVersion, 1);
assert.equal(provenance.brandRevision, "2026-08-24.1");
assert.equal(provenance.interfaceRevision, "2026-08-25.2");
assert.equal(provenance.homeNavigationRevision, "2026-09-04.1");
const names = [
"alvenx-wordmark.svg",
"alvenx-monogram.svg",
Expand Down Expand Up @@ -43,6 +44,7 @@ export async function verifyBrand(root) {
readmes: readmes.length,
brandRevision: provenance.brandRevision,
interfaceRevision: provenance.interfaceRevision,
homeNavigationRevision: provenance.homeNavigationRevision,
};
}

Expand Down
9 changes: 9 additions & 0 deletions src/demo/public/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ const results = {
"browser-runtime-error": "Browser runtime error",
};

document.querySelector("[data-alvenx-home]").addEventListener("click", () => {
if (window.scrollY === 0) return;
window.scrollTo({
top: 0,
left: window.scrollX,
behavior: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "instant" : "smooth",
});
});

async function control(action) {
const response = await fetch(`/api/${action}`, {
method: "POST",
Expand Down
2 changes: 1 addition & 1 deletion src/demo/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<body class="ax-canvas">
<a class="skip-link" href="#main">Skip to verification workspace</a>
<header class="ax-product-header">
<img class="ax-product-header__wordmark" src="/assets/alvenx-wordmark.svg" width="330" height="100" alt="AlvenX">
<button type="button" data-alvenx-home aria-label="AlvenX — Back to top"><img class="ax-product-header__wordmark" src="/assets/alvenx-wordmark.svg" width="330" height="100" alt="AlvenX"></button>
<nav aria-label="Product"><a href="#main">ReproLock</a><span class="local-tag">LOCAL</span></nav>
</header>
<main id="main">
Expand Down
40 changes: 39 additions & 1 deletion tests/playwright/demo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ test("Demo loads standalone brand resources and preserves canonical responsive h
page.on("pageerror", (error) => errors.push(error.message));
await page.goto(demo.address);
await expect(page.locator("html")).toHaveAttribute("lang", "en");
const home = page.getByRole("button", { name: "AlvenX — Back to top", exact: true });
await expect(home).toHaveAttribute("type", "button");
await expect(home).toHaveAttribute("data-alvenx-home", "");
await expect(page.locator("#history-verification")).toContainText("frozen inputs verified");
for (const width of [390, 900, 1440]) {
await page.setViewportSize({ width, height: 1000 });
Expand Down Expand Up @@ -70,6 +73,8 @@ test("Demo loads standalone brand resources and preserves canonical responsive h
expect(
await page.locator("#start").evaluate((element) => getComputedStyle(element).outlineStyle),
).toBe("solid");
await home.focus();
expect(await home.evaluate((element) => getComputedStyle(element).outlineStyle)).toBe("solid");
await page.emulateMedia({ reducedMotion: "reduce" });
expect(await page.evaluate(() => getComputedStyle(document.documentElement).scrollBehavior)).toBe(
"auto",
Expand All @@ -85,7 +90,7 @@ test("Demo loads standalone brand resources and preserves canonical responsive h
expect(errors).toEqual([]);
});

test("startup failure has zero current observations and can be reopened without reloading", async ({
test("saved startup failure survives header home activation without navigation or reloading", async ({
page,
}) => {
await page.goto(demo.address);
Expand All @@ -100,6 +105,39 @@ test("startup failure has zero current observations and can be reopened without
await expect(page.locator("#timing")).toContainText("Not re-executed");
const exported = await page.request.get(`${demo.address}/api/export/${id}`);
expect((await exported.json()).schemaVersion).toBe(1);

await page.getByRole("link", { name: "ReproLock", exact: true }).click();
await page.getByText("Inspect the frozen test", { exact: true }).click();
const retainedState = () =>
page.evaluate(() => ({
url: location.href,
historyLength: history.length,
historyState: history.state,
documentStarted: performance.timeOrigin,
run: document.querySelector(".run-panel")?.textContent,
export: document.querySelector("#export")?.getAttribute("href"),
sourceOpen: document.querySelector(".source-detail")?.hasAttribute("open"),
}));
const before = await retainedState();
expect(before.url).toContain("#main");
expect(before.sourceOpen).toBe(true);
const home = page.getByRole("button", { name: "AlvenX — Back to top", exact: true });
for (const reducedMotion of ["no-preference", "reduce"] as const) {
await page.emulateMedia({ reducedMotion });
for (const activation of ["click", "Enter", "Space"]) {
await page.evaluate(() =>
window.scrollTo({ top: document.documentElement.scrollHeight, behavior: "instant" }),
);
await expect.poll(() => page.evaluate(() => window.scrollY)).toBeGreaterThan(0);
if (activation === "click") await home.click();
else await home.press(activation);
await expect.poll(() => page.evaluate(() => window.scrollY)).toBe(0);
expect(await retainedState()).toEqual(before);
}
await home.click();
expect(await page.evaluate(() => window.scrollY)).toBe(0);
expect(await retainedState()).toEqual(before);
}
});

test("concurrent controls admit exactly one configured run and reject foreign control requests", async ({
Expand Down