Fix the contrast and motion defects the light-base inversion left behind - #61
Merged
Merged
Conversation
Inverting the page to a light base moved --txt to near-black without
re-checking the rules that paint text onto a dark surface. Six of them had
a duplicate declaration overriding a correct earlier one:
- .nav-links a resolved to --txt-2 over the hero (2.4:1). Colour now lives
on .nav / .nav.scrolled, and the base rule no longer sets it.
- .tile b declared no colour at all, so the six app names in the workspace
grid inherited near-black onto dark screenshots at 1.0:1 while their
lighter subtitles read fine. The figcaption ramp also faded out above the
title; it now stays opaque where the name sits.
- summary:hover was #fff on the white page, so hovering a FAQ question
erased it.
- details[open] .x kept --txt-2 on #202730, leaving the one element that
carries open state with no visible state.
- :focus-visible used the near-black --bone over the hero (1.1:1) across
the first nine tab stops.
- The wordmark and the hamburger bars stayed light inside the opened mobile
menu, against a --void panel.
Drop the .bleed::after blend veil. Its top stop was opaque --void, which put
a white wash over the first 121px of the console recording, and its bottom
stop covered another 167px: 288px of 758px, and precisely the zones the app
draws its live status bar and its timeline in. The chip carries its own
scrim, so the gradient bought nothing. Bands butt instead.
Make the scroll reveals additive rather than load-bearing. All 43 blocks
started at opacity 0 with no scripting fallback, so a visitor with JS blocked
got three background images and nothing else; and because the observer
unobserved on first intersection, any block the viewport jumped over stayed
invisible for good. An End-key press stranded eleven, including a 560px band
that rendered as pure white. The hidden state is now gated on a .js class set
inline, and the observer is idempotent instead of one-shot.
Also:
- .shot had no position:relative, so its caption chip escaped to the
initial containing block and landed on the hero 5,000px above itself.
The .reveal transform hid this until .in set transform:none.
- Merge the evidence chain and the agent split into one inverted band. They
were two sections on the same --surface tone separated by a 1px hairline,
which read as 1,030px of a single flat empty block in the stretch of the
page that already had the least happening.
- Set the display numerals in Archivo. Geist Mono gives the comma a full
monospace advance, so the headline figures read as "21 , 186".
- Start heroSettle at exit 62%. It had the hero block at opacity 0.22 by
scrollY 700 of a 900px hero, dimming the primary CTA while it was still
on screen and still being read.
- Put the hero mp4 before the webm. That webm encode is 2.34MB against the
mp4's 1.74MB, so source order was serving every Chrome and Firefox
visitor 34% more bytes for the heaviest asset above the fold.
website/wrangler.toml sets [assets] directory = ".", so every file beside the page is a candidate for public upload — including .env, which holds a live OPENROUTER_API_KEY, plus the client notes, the build plan and the image generator scripts. Pages used to exclude dotfiles and node_modules automatically. Workers static assets does not: it uploads whatever is in the directory unless .assetsignore says otherwise, so this file is the only thing standing between the key and projectvelocity.org/.env. Deploying from a directory that contains only page content is still the safer habit, since this list has to stay in step with whatever lands in the folder.
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.
Follow-up to the light-base inversion (bf49562). Reviewing the page against
palantir.com surfaced a set of defects that were invisible at a glance but
destroyed information, plus two that broke the page outright for some visitors.
Every number below was measured in the browser before and after.
Text that could not be read
Inverting to a light base moved
--txtto near-black without re-checking therules that paint onto a dark surface. Six had a duplicate declaration
overriding a correct earlier one:
.tile b).nav-links a):focus-visible).copy-btn)details[open] .x).tile bdeclared no colour at all, so the six app names inherited near-blackonto dark screenshots while their lighter subtitles read fine — the section is
titled "Twelve apps, one workspace" and is that claim's only evidence.
summary:hoverwas#fffon the white page, so hovering a FAQ question erasedit.
The blend veil was eating the product
.bleed::afterhad an opaque--voidtop stop, putting a white wash over thefirst 121px of the console recording, and a 92%-black bottom stop covering
another 167px. That is 288px of 758px, and precisely the two zones the app
draws its live status bar (
LINK live · FEEDS 6/6 live · CLOCK live) and itstimeline in. The chip carries its own scrim, so the gradient bought nothing.
Bands butt instead.
Scroll reveals were load-bearing
All 43
.revealblocks started atopacity: 0with no scripting fallback, soa visitor with JS blocked got three background images and nothing else — the
headline, every stat, the comparison table, the FAQ and both CTAs all gone.
And because the observer unobserved on first intersection, any block the
viewport jumped over stayed invisible for good: an End-key press stranded
eleven, including a 560px band that rendered as pure white.
The hidden state is now gated on a
.jsclass set inline, and the observer isidempotent rather than one-shot. Verified: 0/43 stranded after jumping to the
bottom and scrolling back.
Also
.shothad noposition: relative, so its caption chip escaped to theinitial containing block and rendered on the hero 5,000px above itself. The
.revealtransform masked this until.insettransform: none..nav-footwas declaredz-index: 43then re-declared39, and.nav-linksis42with an opaquebackground, so
elementFromPointat the button's centre returned.nav-links. Keyboard could reach it; a thumb could not.were two sections on the same
--surfacetone separated by a 1px hairline,reading as 1,030px of a single flat empty block in the stretch of the page
that already had the least happening. All six text roles pass AA on the new
ground.
full monospace advance, so the headline figures read as "21 , 186".
heroSettlenow starts atexit 62%. It had the hero block at opacity 0.22by scrollY 700 of a 900px hero, dimming the primary CTA while it was still on
screen and still being read.
<source>order flipped to mp4 first. That webm encode is 2.34MBagainst the mp4's 1.74MB, so order was serving every Chrome and Firefox
visitor 34% more bytes for the heaviest asset above the fold.
Asset upload safety
website/wrangler.tomlsets[assets] directory = ".", so every file besidethe page is upload-eligible — including
.env, which holds a liveOPENROUTER_API_KEY. Automatic dotfile exclusion was Pages behaviour; Workersstatic assets uploads whatever is in the directory. Added
.assetsignore.Deploying from a directory containing only page content is still safer, since
that list has to stay in step with whatever lands in the folder.
Verification
Deployed and checked on projectvelocity.org: all fixes present, and the
sensitive paths return 404 with an empty body —
/.env,/CLIENT-NOTES.md,/wrangler.toml,/scripts/generate-bands.mjs.Untouched and still open: the workspace grid still uses static screenshots
rather than hover video, there is no artifact in the evidence band, and three
domain thumbnails still show imagery borrowed from other domains.