Skip to content

fix: the eyebrow tell no longer counts a type role's default tracking - #212

Merged
vicmaster merged 1 commit into
masterfrom
eyebrow-tracking-calibration
Sep 3, 2026
Merged

fix: the eyebrow tell no longer counts a type role's default tracking#212
vicmaster merged 1 commit into
masterfrom
eyebrow-tracking-calibration

Conversation

@vicmaster

Copy link
Copy Markdown
Owner

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 letterSpacing above zero, and the soft personality sets letterSpacing: 0.25 on its label type 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:

How it qualifiedCount
textTransform: 'uppercase'154
Content already typed in capitals221
Tracking alone, sentence case18

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

  • Corpus canvases firing the tell: 1 before, 1 after — the same canvas. The single true positive is a screen whose labels are literally capitalised, and it still fires. No verdict changed anywhere.
  • Benchmark unchanged: hero 72, minimal 98, bad-contrast 82, matching the committed baselines. No re-baseline needed.
  • The existing fixture still passes.test-cliche has asserted since Phase 12 that letter-spaced labels count as eyebrows; its fixture uses letterSpacing: 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:full 100/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.

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.
@vicmaster
vicmaster merged commit 51e2dc1 into masterSep 3, 2026
3 checks passed
@vicmaster
vicmaster deleted the eyebrow-tracking-calibration branch September 3, 2026 17:17
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@vicmaster