Band coverage for never-visible occupying items, page-height trust guard, font materialization integrity

- Items never visible at the canonical viewport (carousel slides off-screen
  at every captured width) now fall through to per-viewport geometry bands
  when they occupy layout, instead of freezing canonical geometry
- The explicit-height probe trust excludes body/html/main and any wrapper
  whose height matches the page scrollHeight - page-height nodes keep
  flowing, and the layout height gate stays meaningful
- @font-face and style-rule url() harvesting resolves against the OWNING
  stylesheet's href (walking @import nesting), not document.baseURI;
  font bytes are magic-byte validated at the storage choke point (HTML
  bodies from catch-all 200 routes are rejected); font-face dedup prefers
  the variant whose source actually resolved, deterministically

415 tests pass (16 new), typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samraaj Bath
2026-07-04 04:29:50 -07:00
co-authored by Claude Fable 5
parent 1d68f16f96
commit 994d2bc21e
7 changed files with 491 additions and 28 deletions
+61
View File
@@ -269,6 +269,31 @@ describe("generateCss hidden-node banded geometry", () => {
assert.ok(mobile.includes("visibility:hidden"), `child should carry the hide, got: ${mobile}`);
assert.ok(!mobile.includes("left:10px"), `ancestor-hidden child must not emit geometry, got: ${mobile}`);
});
it("emits per-band geometry for an occupying slide off-viewport at EVERY width, base included", () => {
// A carousel slide 612: a shrink-0 flex item off-screen RIGHT at every captured width — 375,
// the 1280 canonical base, AND 1920 — so it is never ownHidden, never ancestor-hidden, and never
// visibleByVp[base]=true (the walker marks `bbox.x >= vpW` invisible). It is NOT suppressed
// (no opacity:0 / visibility:hidden) and stays IN FLOW, so it still sets its flex track's
// cross-size. Without a band the base's canonical desktop width freezes across every viewport and
// inflates the mobile track. The band must carry THIS width's measured geometry.
const slide = nodeAt("n2", "div", {
375: { cs: { display: "block", position: "static", opacity: "1", width: "220px" }, bbox: { x: 400, y: 0, width: 220, height: 432 }, visible: false },
1280: { cs: { display: "block", position: "static", opacity: "1", width: "285px" }, bbox: { x: 1500, y: 0, width: 285, height: 532 }, visible: false },
1920: { cs: { display: "block", position: "static", opacity: "1", width: "285px" }, bbox: { x: 2200, y: 0, width: 285, height: 532 }, visible: false },
});
const track = nodeAt("n1", "div", {
375: { cs: { display: "flex", position: "relative" }, bbox: { x: 0, y: 0, width: 375, height: 432 } },
1280: { cs: { display: "flex", position: "relative" }, bbox: { x: 0, y: 0, width: 1280, height: 532 } },
1920: { cs: { display: "flex", position: "relative" }, bbox: { x: 0, y: 0, width: 1920, height: 532 } },
}, [slide]);
const root = nodeAt("n0", "body", {}, [track]);
const css = generateCss(ir3(root), new Map());
assert.ok(baseRule(css, "n2").includes("width:285px"), `base bakes canonical width, got: ${baseRule(css, "n2")}`);
const mobile = bandRule(css, /max-width/, "n2");
assert.ok(mobile.includes("width:220px"), `mobile band must carry the measured 220px width, got: ${mobile}`);
assert.ok(!mobile.includes("display:none"), "an occupying off-viewport slide must stay in layout");
});
});
// Fix 1 — mobile nav chip-strip overlap. A horizontally-scrollable flex strip (overflow-x:auto
@@ -924,6 +949,42 @@ describe("generateCss authored-height kept via own probe (T3)", () => {
});
});
// R2 — the own-probe height trust (T3) must NEVER bake a document-height wrapper. A body/html/main
// landmark, or any node whose captured box IS the page scroll height, probes hAuto:false/hFill:false
// as document-level re-measure noise (min-h-screen + %-height chain), not an authored height. Baking
// it pins the page to a fixed height — which, under an overflow:hidden main, hard-clips content drift
// and blinds the layout gate's heightDelta. Such wrappers must keep flowing (auto height).
describe("generateCss own-probe height trust never bakes a page-height wrapper (R2)", () => {
const explicit = (): RawSizing => ({ wAuto: false, wFill: false, hAuto: false, hFill: false });
// xIr sets perViewport.scrollHeight = 800 at every viewport.
function pageWrapper(tag: string, h: number) {
// A non-leaf wrapper with an in-flow child, whose own probe reads authored (hAuto/hFill false).
const child = xNode("n2", "div", Object.fromEntries(XVPS.map((vp) => [vp, { cs: { display: "block", position: "static" }, bbox: { x: 0, y: 0, width: vp, height: h } }])));
const wrap = xNode("n1", tag, Object.fromEntries(XVPS.map((vp) => [vp, { cs: { display: "block", position: "static", height: `${h}px` }, bbox: { x: 0, y: 0, width: vp, height: h }, sizing: explicit() }])), [child]);
return xNode("n0", "body", Object.fromEntries(XVPS.map((vp) => [vp, { bbox: { x: 0, y: 0, width: vp, height: h } }])), [wrap]);
}
it("does NOT bake a <main> landmark height even when its own probe is authored", () => {
const css = generateCss(xIr(pageWrapper("main", 800)), new Map());
const all = allRulesX(css, "n1");
assert.ok(!/height:800px/.test(all), `main landmark must keep flowing, got: ${all}`);
});
it("does NOT bake a wrapper whose captured height IS the page scroll height (±2%)", () => {
// 792 is within 2% of the 800px scrollHeight — a page-height wrapper, not authored content.
const css = generateCss(xIr(pageWrapper("div", 792)), new Map());
const all = allRulesX(css, "n1");
assert.ok(!/height:792px/.test(all), `near-page-height wrapper must keep flowing, got: ${all}`);
});
it("still bakes a genuinely authored height well below the page height", () => {
// 300px is far from the 800px scrollHeight — a real authored box (the T3 case) still survives.
const css = generateCss(xIr(pageWrapper("div", 300)), new Map());
const all = allRulesX(css, "n1");
assert.ok(/height:300px/.test(all), `authored sub-page height must still survive, got: ${all}`);
});
});
// C1 (css side) — a computed `grid-template-rows: subgrid` is a STRUCTURAL keyword, not a baked px
// regime. It must NEVER be dropped by the reflow-mode dropGridRows path (which strips px row tracks).
describe("collectNodeRules never drops a subgrid rows template (C1)", () => {