Repository navigation
feat: add design group (gradient text, purple-blue gradient, violet accent, violet hex, shadcn violet theme) - #103
Merged
Merged
Conversation
…iolet hex rules (SLOP052-054)
The CSS re-parse of every <style> body roughly tripled the time to lint 300 real HTML pages (287 ms to 842 ms); with every style rule off by default the default run now matches the base binary (231 ms vs 229 ms). docs: README rule rows and Style linting section, CHANGELOG, AGENTS.md architecture bullets
Named colors no longer match inside var(), url() or identifiers; SLOP054 skips every custom-property definition; SLOP053 reads from-[#hex] stops; style values report correct columns for template strings and spaced attributes; line_col is memoized. Drops the unused contrast helpers and the ClassList wrapper, and adds check-level tests for all three rules.
wants_style keys on rules declaring STYLE_LANGS and checks the file lang first; a .scss comment that opens its line is extracted so ai-slop-ignore works; stale never-reached comments name Css.
Natlang column, Tier B exclusion list, STYLE_LANGS in the adding-a-rule step, suppression ceilings, tree-sitter-css beside the other grammars, a pt-BR clean twin, and a fatal error when a Design2Code or WebSight row has no text.
mgiovani
force-pushed
the
feat/design-style-layer
branch
from
October 14, 2026 15:58
a77cfe3 to
93c20a6
Compare
…widen SLOP055 forms
This was referenced Oct 14, 2026
…, tighten SLOP056 markers SLOP053 now needs an opaque stop on the blue side and one in the purple core, pairs from-/via-/to- stops only inside one variant and never within one hue name. SLOP056 stops counting --card and --radius as shadcn markers. Unitless hsl() saturation and lightness read as percentages, the violet floor moves to 248 so hex and oklch agree on indigo, SLOP054 reads 8-digit hex, SLOP052 reads case-insensitive and listed background-clip values. Messages name the matched utility or property. Unterminated quotes keep their last character, a rejected set of <style> ranges parses one range at a time, and // lines inside a /* */ block are not SCSS comments.
…yle gate lint_file returns early when no enabled rule (built-in or custom) lists the lang, so a run that disables the design group no longer parses stylesheets. wants_style checks enabled and lang before the group lookup. .min.css bundles resolve to no Lang.
…s bench git_clone_ref, git_clone_before and git_clone_sha land through one helper (prompt guard on every step), the four app-builder entries share their caveats and cells, the pinned-set fetch reuses read_text_files. Adds tests for git_files, pinned_set_revision and fetch_git_pinned_set, and derives the APPLICABLE design check from docs/rules.md.
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.
Summary
Adds a style layer so rules can read CSS, plus the first three rules of the new
designgroup. Closes #86 and #87. Part of #85 and epic #98.Lang::Csscovers.cssand.scss, parsed with tree-sitter-css. It joins neitherCODE_LANGSnorPROSE_LANGS, so no existing rule starts running on stylesheets.StyleDoc(src/style.rs) is built once per file and exposed asctx.style. It holds CSS declarations with absolute byte spans and Tailwind class tokens grouped per class attribute. Sources:<style>bodies, re-parsed through tree-sitterset_included_rangesso offsets stay absolute, plusstyle=andclass=attributes.className/classstrings (includingcn(...)arguments) andstyle={{...}}objects, with camelCase keys mapped to kebab-case.src/color.rs: pure color parsing (hex, rgb/rgba, hsl/hsla, named colors) and HSL conversion.StyleDocis built only when adesign-group rule is enabled for the file's lang. Built unconditionally, it tripled HTML lint time. With the gate, the default run is unchanged: 231 ms before vs 229 ms after, on 300 Design2Code pages.Rules (
designgroup; SLOP052, SLOP053, SLOP055 and SLOP056 Tier B on, SLOP054 Tier C off)background-clip: textplus a gradient, orbg-clip-textplus a gradient utility)from-purple/violet/indigowith a matchingvia/to, bracketed stopstext,bg,border,ring, ... with purple, violet or indigo 400-700, variants and opacity allowed) in class lists; flags the look, not the author--primary,--ring,--accent,--sidebar-primary,--chart-1set to a violet HSL triplet,oklch(), hex or rgb in a block that also defines at least two shadcn marker tokens (--card,--popover,--primary-foreground, ...); a lone brand--primaryand zinc, slate or blue presets stay quietThe five rules own disjoint spans (clip, gradient, bare hex, accent utility, theme token), and none overlaps SLOP009, SLOP018, SLOP021 or SLOP044.
First measurement (superseded)
WebSight's 2023-era AI pages contain none of these tells (0 hits for every rule), so they couldn't show separation. The app-builder cells in Tier decision below replace them as the AI split. The WebSight rows stay in
bench/candidates.toml.Dependency
tree-sitter-css = "0.25"(MIT). Regex cannot track nested blocks, strings and comments in CSS, and tree-sitter is the parser family the crate already uses.cargo tree -i tree-sittershows a single core (0.26.10).Cargo.lockgains onlytree-sitter-css;ccandtree-sitter-languagewere already locked.Tier decision
Scored on pinned public repos from four AI app builders (64 repos, 1,455 files; tsx, css, html under
src/, shadcncomponents/ui/and*.min.*excluded) against verified human files (Ant Design TSX, 11 named-maintainer Tailwind React apps pinned to late 2022 with their CSS, three pinned CSS repos; 1,275 files). Builder provenance markers: Lovablegpt-engineer-app[bot]commits (28 repos, 2026-06 to 2026-10), bolt.new.bolt/config.json(12, 2024-10 to 2026-03), Same.new.same/todos.md(12, 2025-05 to 2026-09), Replit AgentReplit-Commit-Author: Agenttrailer (12, 2025-06 to 2026-10). No pre-2020 Tailwind baseline exists.Bar: AI rate at least 3x the human rate, human rate at most 1% (2% AI floor as guidance only). Re-scored after the second review pass: SLOP053 now requires stops on both the blue side and the purple core (alpha at least 0.5) and pairs stops only within a variant; the SLOP056 marker and violet-floor changes moved no corpus count.
--card,--primary-foreground,--radius, ...) in the block, so a lone--primary: #9146ffstays quiet. Small denominators: most builder output keeps its theme in one index.css.Tailwind v3/v4. SLOP052, SLOP053 and SLOP055 read
bg-gradient-to-*,bg-linear-*,bg-radial,bg-conic, the!important marker before (v3) or after (v4) a utility, the v4tw:prefix, bracketed stops includingoklch()(underscores as spaces,color:hints,/opacity), and ignore the v4bg-(--brand)shorthand.color.rsparsesoklch()/oklab()(hue in deg, grad, rad, turn or none) and shadcn bare HSL triplets. Ceiling: a v3tw-config prefix is not read.Rows and per-rule notes are in
bench/candidates.toml.Notes
tests/integration.rs: a data-only"css"entry inLANG_DIRS, the same precedent as"html".LintContext.styleaddsstyle: Noneto every test literal. This is one mechanical commit..cssand.scssfiles now enter the walk, so existing custom rules can match them. CHANGELOG recommends excluding*.min.css.$varsand@includecan hide a neighboring declaration, and/* ai-slop-ignore */inside an HTML<style>block is not honored (use an HTML comment around the element).//suppression works in.scss.Verification
just checkpasses. The lib has 1066 tests, plus the integration, natlang and image harnesses.cargo install --path .followed bystopslop .: zero findings (the repo config selects ALL).--select designon the fixtures, only theslop_design.*files fire.