mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-21 18:47:02 +03:00
The review threads on #840 found four ways the new rendered rules were still measuring something other than what the reader sees. - `line-length` read one `getClientRects()` box per direct text node and called each of them a rendered line. An inline `<strong>` in the middle of a sentence is its own text node, so one visual line arrived as two fragments and the paragraph's characters were divided between them — and the `<strong>`'s own text was never measured at all while its characters still counted toward `text_len`. Both halves of the measure are the same text now: the probe collects the rects of every text node under the element, and `Dom::text_line_rects` merges the ones that share a row back into the line they rendered as. A column of long lines split by inline markup used to charge nothing; it charges now, and a wrapped sentence in two fragments is one line, not two. - The same function divided every rect by the line box to recover a line count. On live per-line rects that was double-counting: a leading tighter than the glyph box makes `round(height / line_box)` 2, and one long line pushed twice satisfied "at least two long lines". Nothing is divided any more, because nothing that reaches the rule is a union. - The union was what a snapshot-backed scan had — the extension's offscreen document and any strict-CSP page — and a union of a long first line and a short tail is the same union as two even lines, so every line inferred from it was invented. The capture records the rects now (`dl`, with `textLines` on the snapshot saying it did), and a capture that did not answers `None`: the rule stands down rather than guessing. That is also what any other DOM that cannot split a wrapped run answers. - `ai-color-palette` accumulated its tell hues before the scoped ignores ran. A cyan tell inside a `data-impeccable-ignore="ai-color-palette"` subtree opened the page-wide two-hue gate and charged neon ink on an element nobody had waived. Ignored content now gets no vote. - `declared_component_selectors` took every backticked class in DESIGN.md as a declaration, including the ones the document writes down in order to forbid them. "Do not write a new `.hero-cta-primary`" exempted `.hero-cta-primary` from `kicker-above-heading` — the parser silencing exactly the misuse the document was written to catch. Each occurrence is read in the document's own structure now: the heading chain above it (a "Don't" section, and its subsections with it) and the clause it sits in, where a clause is cut on punctuation and on the phrases that turn a sentence around. "No ALL CAPS outside the `.eyebrow` class" still declares `.eyebrow`, because what "no" governs ends at "outside"; a class the document calls deprecated anywhere is declared nowhere. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LQBUunp8QttxZqihybNmtL