Skip to content

Commit d59e796

Browse files
committed
Restore landing lower-section layouts and browser regression checks
1 parent 6b630fc commit d59e796

4 files changed

Lines changed: 82 additions & 1 deletion

File tree

‎docs/Features/BenchmarkComparisons.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,3 +1366,19 @@ Node-to-BDN consumer, validates all 36 case identities and reports, and performs
13661366
its mutation rejection oracle. Root joins the source-reviewed proposal and runs
13671367
that gate through the unified Aspire entry; neither source review nor a build
13681368
establishes consumer execution or comparative performance qualification.
1369+
1370+
## Landing lower-section layout regression (2026-10-06)
1371+
1372+
REQ-BC-LAYOUT-001 / AC-BC-LAYOUT-001: qualification status retains two desktop
1373+
columns and one mobile column; methodology retains three desktop columns and
1374+
stacked mobile steps. The reproduce command stays inset within its padded
1375+
terminal, and footer links align with the main content without horizontal page
1376+
overflow at the existing responsive viewport widths. TASK-BC-LAYOUT-001 restores
1377+
only styles used by the current semantic landing. ADR-040 remains the owning
1378+
design decision; no new boundary, dependency or public contract is introduced.
1379+
1380+
Automated mapping: `SiteBrowserVisualAssertions.AssertLowerSectionsAsync` checks
1381+
real rendered bounding boxes in both the measured responsive browser case and
1382+
`SiteContentBrowserTests` desktop/mobile case through the Aspire `site` entry.
1383+
A missing lower-section stylesheet must fail these assertions. Native build,
1384+
site qualification and actual Website/Pages delivery evidence remain required.

‎site/Features/BenchmarkComparisons/styles.css‎

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,47 @@ tr:last-child td { border-bottom: 0; }
221221
.load-error { margin: 1rem 0 0; padding: .8rem 1rem; border-radius: 12px; background: var(--kl-bad-bg); color: var(--kl-bad-ink); font-weight: 600; }
222222
.retry-button { margin-top: .8rem; }
223223

224-
/* Evidence receipt: perforated provenance slip */
224+
/* Claims ledger */
225+
.ledger-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem; margin-bottom: 1.4rem; }
226+
.ledger-col { padding: 1.5rem; border-radius: var(--kl-radius-lg); }
227+
.ledger-col h3 { margin: 0 0 1rem; font-size: 1.3rem; }
228+
.ledger-col ul { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
229+
.ledger-col li { display: grid; grid-template-columns: 1.4rem minmax(0, 1fr); gap: .6rem; padding: .7rem 0; border-top: 1px solid var(--kl-line); font-size: .95rem; }
230+
.ledger-col li::before { display: grid; place-items: center; width: 1.4rem; height: 1.4rem; border-radius: 50%; font: 700 .72rem/1 var(--kl-font-mono); }
231+
.ledger-col--open { border: 1px solid var(--kl-stroke); background: var(--kl-sheen), var(--kl-surface); box-shadow: var(--kl-shadow); }
232+
.ledger-col--open li::before { content: "✓"; background: var(--kl-graphite); color: #fff; }
233+
.ledger-col--held { border: 1px dashed var(--kl-line-strong); background: transparent; }
234+
.ledger-col--held li { color: var(--kl-ink-2); }
235+
.ledger-col--held li::before { content: "–"; border: 1px solid var(--kl-line-strong); color: var(--kl-muted); }
236+
237+
/* Method rail */
238+
.method-rail { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem; margin: 0; padding: 0; list-style: none; }
239+
.method-rail li { position: relative; display: grid; align-content: start; gap: .3rem; }
240+
.method-rail li::after { content: ""; position: absolute; top: 1.15rem; left: 3rem; right: -1.6rem; height: 1px; background: var(--kl-line-strong); }
241+
.method-rail li:last-child::after { display: none; }
242+
.method-rail h3 { margin-top: .9rem; }
243+
244+
/* Reproduce terminal */
245+
.reproduce-inner { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); align-items: center; gap: 2rem; padding: clamp(1.6rem, 4.5vw, 3.2rem); border-radius: var(--kl-radius-xl); }
246+
.reproduce .eyebrow, .reproduce p { color: var(--kl-on-graphite-muted); }
247+
.reproduce h2 { margin-bottom: 1rem; color: #fff; }
248+
.reproduce p { margin: 0; }
249+
.command-box { min-width: 0; display: flex; align-items: center; gap: .7rem; padding: .6rem .6rem .6rem 1.1rem; border: 1px solid var(--kl-graphite-line); border-radius: 16px; background: rgba(0, 0, 0, .35); }
250+
.prompt { color: var(--kl-lilac); font: 700 .9rem var(--kl-font-mono); }
251+
.command-box code { flex: 1; min-width: 0; overflow-x: auto; color: var(--kl-on-graphite); font: .82rem/1.5 var(--kl-font-mono); white-space: nowrap; scrollbar-width: none; }
252+
.command-box button { flex: none; min-height: 38px; padding: 0 1rem; border: 0; border-radius: 10px; background: var(--kl-iris); color: var(--kl-graphite); font-size: .82rem; font-weight: 700; cursor: pointer; }
253+
254+
/* Footer */
255+
.site-footer { margin-top: var(--section-gap); padding: 0 max(var(--gutter), calc((100% - var(--page)) / 2)) 2rem; overflow: hidden; }
256+
.footer-mark { margin: 0 0 -.06em; font: 800 clamp(4.5rem, 21vw, 18rem)/.8 var(--kl-font-display); letter-spacing: -.07em; color: transparent; background: linear-gradient(180deg, rgba(17, 18, 20, .14), rgba(17, 18, 20, 0)); -webkit-background-clip: text; background-clip: text; user-select: none; }
257+
.footer-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem 2rem; padding-top: 1.4rem; border-top: 1px solid var(--kl-line-strong); }
258+
.footer-links { display: flex; gap: 1.4rem; font-size: .9rem; }
259+
.footer-links a { color: var(--kl-ink-2); text-decoration: none; }
260+
.footer-links a:hover { color: var(--kl-ink); }
261+
.made-by { margin: 0; color: var(--kl-muted); font-size: .9rem; }
262+
.made-by a { color: var(--kl-ink); font-weight: 650; }
263+
264+
/* Responsive */
225265
@media (max-width: 1080px) {
226266
.hero { grid-template-columns: minmax(0, 1fr); }
227267
.hero-lede { grid-column: 1; }

‎tests/KeyLoad.SiteTests/Features/BenchmarkComparisons/Assertions/SiteBrowserVisualAssertions.cs‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public static async Task AssertResponsive(SiteBrowserChrome chrome, Cancellation
1313
[SiteBrowserTokens.DeviceScaleFactorField] = SiteBrowserTokens.One,
1414
[SiteBrowserTokens.MobileField] = false,
1515
}, cancellationToken);
16+
await AssertLowerSectionsAsync(chrome.Cdp, cancellationToken);
1617
var overflow = await chrome.Cdp.EvaluateAsync(SiteBrowserUiTokens.OverflowScript, false, cancellationToken);
1718
await Assert.That(overflow.GetBoolean()).IsFalse();
1819
if (width <= SiteBrowserUiTokens.ViewportMobileWidth)
@@ -23,6 +24,28 @@ public static async Task AssertResponsive(SiteBrowserChrome chrome, Cancellation
2324
}
2425
}
2526

27+
public static async Task AssertLowerSectionsAsync(SiteBrowserCdpClient cdp, CancellationToken token)
28+
{
29+
const string script = """
30+
(() => {
31+
const box = selector => document.querySelector(selector).getBoundingClientRect();
32+
const desktop = innerWidth > 760;
33+
const steps = [...document.querySelectorAll('.method-rail li')].map(x => x.getBoundingClientRect());
34+
const claims = [...document.querySelectorAll('.ledger-col')].map(x => x.getBoundingClientRect());
35+
const terminal = box('.reproduce-inner'), command = box('.command-box');
36+
const footer = box('.site-footer'), links = box('.footer-links');
37+
return steps.length === 3 && claims.length === 2 &&
38+
(desktop ? steps.every(x => Math.abs(x.top - steps[0].top) < 1) && claims[1].left >= claims[0].right
39+
: steps[1].top >= steps[0].bottom && claims[1].top >= claims[0].bottom) &&
40+
command.left > terminal.left && command.right < terminal.right &&
41+
command.top > terminal.top && command.bottom < terminal.bottom &&
42+
links.left >= box('.method-rail').left && footer.top >= terminal.bottom &&
43+
document.documentElement.scrollWidth <= innerWidth;
44+
})()
45+
""";
46+
await Assert.That((await cdp.EvaluateAsync(script, false, token)).GetBoolean()).IsTrue();
47+
}
48+
2649
public static async Task AssertSceneLifecycle(SiteBrowserChrome chrome, string baseUrl,
2750
CancellationToken cancellationToken)
2851
{

‎tests/KeyLoad.SiteTests/Features/BenchmarkComparisons/Cases/SiteContentBrowserTests.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public async Task AC_BC_WEB_003_RealChromeShowsDesktopMobileSceneAndAccurateEmpt
1818
var cdp = browser.Chrome.Cdp;
1919
await Assert.That(await cdp.WaitForExpressionAsync(SiteContentBrowserTokens.ContentReadyPredicate, token)).IsTrue();
2020
await SiteBrowserVisualAssertions.AssertSceneIsLazyBeforeHeroNavigation(cdp, token);
21+
await SiteBrowserVisualAssertions.AssertLowerSectionsAsync(cdp, token);
2122
var desktop = await ReadContentStateAsync(browser.Chrome.Cdp, token);
2223
await AssertContentStateAsync(desktop, SiteContentTokens.DesktopPosterSuffix);
2324
var desktopRequests = await AssertLocalRequestsAsync(browser.Chrome.Cdp, browser.BaseUrl, token);
@@ -38,6 +39,7 @@ await Assert.That(sceneRequests.Any(url => url.EndsWith(SiteAssetTokens.SceneMod
3839
[SiteBrowserTokens.MobileField] = true,
3940
}, token);
4041
await browser.Chrome.NavigateAsync(browser.BaseUrl + SiteAssetTokens.IndexHtml + SiteBrowserTokens.PageHideFragment, token);
42+
await SiteBrowserVisualAssertions.AssertLowerSectionsAsync(cdp, token);
4143
var mobile = await ReadContentStateAsync(browser.Chrome.Cdp, token);
4244
await AssertContentStateAsync(mobile, SiteContentTokens.MobilePosterSuffix);
4345
await Assert.That(mobile.GetProperty(SiteContentBrowserTokens.Mobile).GetBoolean()).IsTrue();

0 commit comments

Comments
 (0)