Capture (4a): - stabilize: dwell-scroll settling pass + known-library pre-reveal neutralization after lazy promotion, so every viewport snapshot records the post-reveal steady state (about-page sections no longer captured blanket-hidden: 24 base `invisible` wrappers -> 0) - probeReveals: extended to the visibility + entrance-animation family; DittoMotion replays them (JS re-hide on mount, IntersectionObserver reveal, 4s force-reveal failsafe) so SSR/non-JS still shows content - assets: 206 range-response bodies are no longer stored as full assets (full-fetch fallback) + video magic-byte validation - the about-page hero video is now a valid 6.0MB ftyp mp4 instead of 18.9KB of garbage Generate (4b): - css: hidden-node geometry policy - a visibility:hidden box with a 0x0 captured bbox at a band becomes display:none there; an OCCUPYING hidden box gets the captured per-viewport geometry instead of the baked canonical one. Also covers the ancestor-hidden-at-base case (the cropin.com/cotton slider arrow: hide inherited from an elementor-widget ancestor at every width parked a desktop left:548px box inside a 375px viewport -> body.scrollWidth 585; now 375 on both verified pages) - tailwind: bare-zero utility gating - font-size:0 -> text-[0px] and letter-spacing:0 -> tracking-[0px] (text-0/tracking-0 are silently invalid in Tailwind v4; fixes permanently-visible map labels on the cotton Global-presence section) Verified: 87/87 compiler tests green, full-workspace suite green, regenerated cropin.com + /cotton/ builds measure 375px scrollWidth at a 375px viewport, and a fresh /about/ clone renders all reveal sections with scroll-replay against the live site. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
44 lines
2.0 KiB
TypeScript
44 lines
2.0 KiB
TypeScript
import { describe, it } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { declToUtil } from "../src/generate/tailwind.js";
|
|
|
|
// Zero-value gating. A named `-0` step only exists for props on Tailwind's spacing (or numeric)
|
|
// scales; for the rest the class compiles to NOTHING — a silent no-op that ships the wrong style
|
|
// (a map label captured at font-size:0 painted at the inherited 20px because `text-0` isn't a
|
|
// utility). Zeros for scale-less props must stay arbitrary so the declaration really compiles.
|
|
describe("declToUtil zero values", () => {
|
|
it("emits arbitrary text-[0px] for font-size:0 (no text-0 utility in v4)", () => {
|
|
assert.equal(declToUtil("font-size", "0px"), "text-[0px]");
|
|
assert.equal(declToUtil("font-size", "0"), "text-[0px]");
|
|
});
|
|
|
|
it("emits arbitrary tracking-[0px] for letter-spacing:0 (no tracking-0 utility in v4)", () => {
|
|
assert.equal(declToUtil("letter-spacing", "0px"), "tracking-[0px]");
|
|
assert.equal(declToUtil("letter-spacing", "0"), "tracking-[0px]");
|
|
});
|
|
|
|
it("emits arbitrary rounded corners for radius:0 (radius scale has no numeric 0)", () => {
|
|
assert.equal(declToUtil("border-top-left-radius", "0px"), "rounded-tl-[0px]");
|
|
});
|
|
|
|
it("keeps the named -0 for spacing-scale props", () => {
|
|
assert.equal(declToUtil("width", "0px"), "w-0");
|
|
assert.equal(declToUtil("width", "0"), "w-0");
|
|
assert.equal(declToUtil("top", "0px"), "top-0");
|
|
assert.equal(declToUtil("margin-left", "0px"), "ml-0");
|
|
assert.equal(declToUtil("line-height", "0px"), "leading-0");
|
|
});
|
|
|
|
it("keeps the named -0 for numeric scales that include 0", () => {
|
|
assert.equal(declToUtil("flex-grow", "0"), "grow-0");
|
|
assert.equal(declToUtil("flex-shrink", "0"), "shrink-0");
|
|
assert.equal(declToUtil("order", "0"), "order-0");
|
|
assert.equal(declToUtil("z-index", "0"), "z-0");
|
|
});
|
|
|
|
it("leaves non-zero values untouched", () => {
|
|
assert.equal(declToUtil("font-size", "20px"), "text-[20px]");
|
|
assert.equal(declToUtil("letter-spacing", "-0.5px"), "tracking-[-0.5px]");
|
|
});
|
|
});
|