fix: the eyebrow tell no longer counts a type role's default tracking - #212
Merged
Conversation
The third finding from building the v2.1.0 checkout example. Eleven ordinary form labels — "Email", "Full name", "City" — were counted as decorative eyebrows, because the tell qualified any small text with letterSpacing above zero and the `soft` personality sets letterSpacing on its `label` type role. Every label in the design inherited an eyebrow signal it never asked for. The threshold is measured rather than guessed. Across a 112-canvas corpus (the 11 shipped patterns plus 101 real canvases) the tell counted 393 texts: 154 by textTransform, 221 by content already typed in capitals, and 18 by tracking alone. Every one of those 18 was a form label or a tab. Their tracking runs 0.3 to 0.6 and comes from a type role; tracking chosen deliberately as an eyebrow treatment sits at 1 to 2. The two classes separate cleanly, so the floor sits at 1, with margin on both sides. Capitalised content now qualifies on its own terms rather than incidentally through tracking, which is what the corpus actually contains — "MODULES", "YEAR TO DATE" — and is the same design decision as textTransform, authored differently. The change is strictly narrowing: every text it stops counting was counted before, and nothing new starts counting. Measured effects, all confirmed rather than assumed: - corpus canvases firing the tell: 1 before, 1 after, the same canvas — the one true positive is preserved - benchmark: hero 72, minimal 98, bad-contrast 82, unchanged from baselines - the existing fixture asserting letter-spaced labels count (letterSpacing 2) still passes, because 2 is above the floor Verified: test:full 100/100, discoverability 117/117.
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
The third and last finding from building the v2.1.0 checkout example, held back from #211 because it changes evaluator behaviour and deserved measurement rather than a guess.
The bug
Eleven ordinary form labels — "Email", "Full name", "City" — were counted as decorative eyebrows on the checkout, and the tell fired. The cause is that it qualified any small text with
letterSpacingabove zero, and thesoftpersonality setsletterSpacing: 0.25on itslabeltype role. Every label in a form-heavy design inherited an eyebrow signal it never asked for. Working around it meant overriding the type role, which is the wrong lever.The measurement
Rather than pick a rule that made my screen pass, I measured the tell across a 112-canvas corpus — the 11 shipped patterns plus 101 real canvases from the registered repositories.
It counted 393 texts:
textTransform: 'uppercase'Every one of those 18 was a form label or a tab — "Name", "Unit", "Cadence", "Aggregation", "TAB · The candidate". None was a genuine eyebrow.
Then the discriminator. Role-inherited tracking on those false positives runs 0.3 to 0.6 (min 0.3, max 0.6). Tracking chosen deliberately as an eyebrow treatment runs 1 to 2 — the genuine capitalised labels in the corpus reach 1.5, and the existing test fixture uses 2. The two classes separate cleanly with nothing in between, so the floor sits at 1.
The change
An eyebrow is now small text that reads as a designed label: uppercase via
textTransform, or content already typed in capitals, or tracking at 1 or above.Capitalised content qualifying on its own terms is worth calling out. That is what the corpus actually contains — "MODULES", "YEAR TO DATE" — and it is the same design decision as
textTransform, just authored differently. It was already being counted, incidentally, because such text is usually tracked too.The change is strictly narrowing. Every text it stops counting was counted before; nothing new starts counting, so no canvas can begin failing because of it.
Measured effects, not assumed
test-clichehas asserted since Phase 12 that letter-spaced labels count as eyebrows; its fixture usesletterSpacing: 2, above the floor, so the behaviour it protects is intact. I would have flagged it rather than quietly rewriting it.What this trades away
A sentence-case eyebrow tracked at less than 1 would now be missed. The corpus contains no example, and the alternative is the systematic false positive above, but it is a real trade and the reasoning is written at the code rather than left in a commit message.
Verified
npm run test:full100/100, discoverability 117/117, benchmark green. GUIDELINES now states the signature precisely, including that a form label with a type role's light tracking is not an eyebrow.