Pin the first screen at 390x844 on the nine pages a buyer lands on - #364
Merged
Conversation
Apolloccrypt
force-pushed
the
test/first-screen-geometry
branch
from
September 2, 2026 19:37
7335b20 to
94a202a
Compare
Every copper pin in this repo reads markup. A CSS line moves the words
without touching them: margin-top:400px on .about-byline leaves /about
with the same HTML, the same DOM and a green suite, and drops the name
of the person behind the product below a 390x844 phone screen.
tests/pricing-fold.test.mjs already measures this for /pricing. This is
the same instrument pointed at the other nine pages. Bottom edge from
getBoundingClientRect, asserted against 844, and a failure names the
measured value and the overshoot:
/ H1 215, audience 442, first action 512, the Community and
business plans split 579, split heading 725
/parasign audience 544, first action 622, free limit 760
/parasend audience 492, first action 570, free limit 727
/about name 489, title 525, actions 596 and 654
/security bounded promise 476, who is behind it 662, actions 728/788
/trust lede 422, actions 488 and 548
/docs buyer line 237, buttons 414 and 464
/help first two answers 419 and 639
/download status sentence 284, sub 374, both buttons 449
Every page also asserts scrollWidth = clientWidth = 390, so a card that
overflows its grid is caught the way /pricing was.
The font is forced to DejaVu Sans. design-system.css resolves --sans and
--mono to system stacks with no @font-face, so page height depends on the
machine: the first run of this file was green on Fedora, where
ui-sans-serif resolves to Cantarell, and red on ubuntu-latest, where it
resolves to DejaVu. A gate whose numbers depend on the runner is not a
gate.
Under that wider face two claims do not fit, and both are real rather
than an artefact of the measurement:
/parasign the SES scope statement ends at 863, 19px over. On a wide
face a buyer scrolls to learn the signature is not a
qualified one.
/help the third answer ends at 860, 16px over. That is the answer
saying the documents live in Germany.
They are pinned in place instead of to the fold, so they cannot drift
further, and the suite goes red if either is fixed without dropping its
pin. The SES claim is measured on a text range: its paragraph runs to
911 by design, and what has to be readable is the sentence.
No copy changed and no attribute was added: every selector is an id or
class the pages already carry. The suite imports playwright, so
sign-e2e picks it up with the other browser suites.
Sabotage, one CSS shove per page, all nine red on the right claim:
.home-actions, .ps-actions on both product pages, .about-byline,
.hero-by, .hero-cta, .docs-hero-actions and .buyer-qa at 400px, and
.dl-actions at 430px. margin-top replaces the element's own margin
rather than adding to it, so 400px on .dl-actions is a 372px move and
lands 23px short of the edge, which is the measurement working.
Apolloccrypt
force-pushed
the
test/first-screen-geometry
branch
from
September 2, 2026 19:42
94a202a to
3906ee8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every copper pin in this repo reads markup. The text is in the HTML, so the
assertion is green, and none of them looks at where that text ends up on a
screen. A single CSS line moves it:
margin-top: 400pxon.about-bylineleaves /about with the same words, the same DOM and the same passing suite, and
pushes the name of the person behind the product below a 390x844 phone screen.
tests/pricing-fold.test.mjsalready measures this for /pricing. This is thesame instrument pointed at the other nine pages.
The font had to be forced, and that is the finding
design-system.cssresolves--sansand--monoto system stacks with no@font-faceanywhere. The same page is therefore a different height on everymachine. The first push of this branch was green here and red in CI:
ui-sans-serifresolves to Cantarell on Fedora and to DejaVu Sans onubuntu-latest, and /parasign moved 63px between them, /help 41px.
A gate whose numbers depend on the runner is not a gate, so the suite forces
DejaVu Sans/DejaVu Sans Monoon every page. That is what CI rendersanyway and it is the widest of the faces in play, so a developer now reads the
same numbers the gate does. DejaVu arrives with
playwright install --with-deps; the resolved family is printed in every failure message, so a runon a machine without it says so rather than looking like a layout regression.
What is pinned
Bottom edge from
getBoundingClientRect(), in CSS pixels from the top of thedocument, Chromium at 390x844, signed out, served from
frontend/the waydeploy/nginx-paramant-live.confroutes it. These are the numbers the suiteprints today.
/[data-home="out"] h1[data-home="out"] p.lede/sign[data-home="out"] .home-actions a[data-home="out"] p.hero-note#split-h/parasignp.ps-who/sign.ps-actions a.btn-primaryp.ps-fine.scope-note p/parasendp.ps-who/parashare.ps-actions a.btn-primaryp.ps-sub/about.about-byline .n.about-byline .t/pricing.hero-cta a.btn-primary/security.hero-cta a.btn-secondary/security.page-hero .lede.hero-by/pricing.hero-cta a.btn-primary/verify.hero-cta a.btn-secondary/trust.page-hero .lede/security.hero-cta a.btn-primary/pricing.hero-cta a.btn-secondary/docsp.docs-buyer#quickstart.docs-hero-actions a.docs-hero-btn/pricing/help.buyer-qa-item p.buyer-qa-a/downloadheader.dl-lead h1header.dl-lead p.dl-sub/.dl-actions a.btn-primary/pricing.dl-actions a.btn-outlineAll nine pages also assert
scrollWidth == clientWidth == 390. Equal, notmerely no wider: a page that lays out narrower than the screen is the same bug
seen from the other side. This is the defect /pricing shipped, where a
white-space: nowrapbutton set the min-content width of the whole grid trackand clipped every tier card.
Two claims do not fit, and both are real
Marked
(below)above. On a narrow face they sit on the first screen and thereviewers read them there; on a wide one they hang over the edge.
/parasign/helpI did not loosen the rule to 863 and I did not touch the pages, which is not a
test's job. Those two claims are pinned in place instead of to the fold:
each holds its measured bottom with 2px for a Chromium rounding change, so it
cannot drift further while it waits to be fixed, and the suite goes red with an
explicit message if someone fixes the page without dropping the pin.
Both are small copy or spacing jobs. Worth a follow-up, not worth blocking a
measuring instrument that did exactly what it was built to do on its first run.
Three decisions worth naming
The bottom edge, never the top. A line whose top sits at y=830 is on screen
and unreadable. Every assertion compares
bottomagainst 844 and the failuremessage names the measured value and the overshoot:
One claim is measured on a text range, not its block. The SES scope note on
/parasign sits in a paragraph running to y=911, and that is by design: it goes
on to say what a ParaSign signature is not, under eIDAS and QES. Asserting the
block bottom would be red on a page nobody broke. What has to be readable before
a buyer signs is the sentence, so the test builds a
Rangeover that phrase andmeasures its own line boxes.
Text is checked as well as geometry. Every claim carries the words it
expects, so a selector that silently starts matching a different same-classed
element fails on the text rather than on a number that happens to still fit.
No copy changed, no attribute added
The task allowed a
data-foldhook where no stable one existed. None wasneeded: every claim rides an id or class the pages already carry
(
[data-home="out"],#split-h,.ps-who,.about-byline .n,.hero-by,.docs-buyer,.buyer-qa-a,.dl-lead). The diff is one new file. The onlypage that lacked a hook was /download, and #358 landed a hero with real classes
while this was being written.
Sabotage, one CSS shove per page
A
<style>block appended before</body>, suite rerun, page reverted. All ninered, each on the claim the shove actually moved.
/.home-actions{margin-top:400px}/parasign.ps-actions{margin-top:400px}/parasend.ps-actions{margin-top:400px}/about.about-byline{margin-top:400px}/security.hero-by{margin-top:400px}/trust.hero-cta{margin-top:400px}/docs.docs-hero-actions{margin-top:400px}/help.buyer-qa{margin-top:400px}/download.dl-actions{margin-top:430px}/download is worth reading twice.
margin-topreplaces the element's ownmargin rather than adding to it, and
.dl-actionsalready carriesmargin-top:28px. A 400px shove is a 372px move, the buttons land at 821, andthe suite stays green because they are still readable. That is the measurement
working, not a gap in it. 430px moves them to 851 and it goes red.
CI
The suite imports
playwright, so.github/workflows/sign-e2e.yml:40picks itup with the other browser suites by import, with no workflow change. That
selector was written for exactly this.
Tests
tests/first-screen.test.mjs: 9 pages, all passgrep -l "from 'playwright'" tests/*.mjsminus sign-full and product-heartbeat: 21/21tests/sign-full.test.mjs: 33/33grep -L "from 'playwright'" tests/*.mjs: 153 tests, 151 pass, 2 skipped, 0 failtests/static-sanity.sh: PASS, all 11 checks clear, including 10 (commit style) and 11 (test-scope guard, 111 suites)