Commit Graph
658 Commits
Author SHA1 Message Date
garrytanandcapy-ai[bot] f16be82fd3 design-lint: adversarial review tests and docs
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 14:39:27 +00:00
garrytanandcapy-ai[bot] fd67b88c5e design-lint: adversarial review fixes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 14:39:27 +00:00
garrytanandcapy-ai[bot] b1c5dc066f design-lint: thirteenth review cycle tests
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 13:32:37 +00:00
garrytanandcapy-ai[bot] e997d6fb4d design-lint: thirteenth review cycle fix
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 13:32:37 +00:00
garrytanandcapy-ai[bot] f1dcdea65c design-lint: twelfth review cycle tests and docs
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 13:18:22 +00:00
garrytanandcapy-ai[bot] 734e07f0a5 design-lint: twelfth review cycle fixes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 13:18:22 +00:00
garrytanandcapy-ai[bot] e6ed269add design-lint: eleventh review cycle tests
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:57:05 +00:00
garrytanandcapy-ai[bot] 7c9dab30ef design-lint: eleventh review cycle fixes
A nested rule under a parent longer than the selector cap falls back to the
parent's first part cut to 256 characters, the :is() wrapper is built only on
the expanding path, and every stored selector is cut at MAX_SELECTOR; the
limited stripTags counts visibility with the whitespace class its callers
collapse on and never cuts a surrogate pair; glWords slides its window by
innerHeight.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:57:05 +00:00
garrytanandcapy-ai[bot] 6d01b1f3cd design-lint: tenth review cycle tests and docs
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:46:34 +00:00
garrytanandcapy-ai[bot] e4a6adbf3a design-lint: tenth review cycle fixes
tooltip-focus-delay splits the transition value at top-level commas, so a
delay after cubic-bezier() or steps() is still read; nestSelector budgets one
substitution per '&' before expanding; stripTags with a limit stops reading
at the limit instead of after the next tag; accentedHeads reads each span's
text once and covers classes from one map; a JSX close tag with no '>' is
text, not a failure every ancestor rescans; selectorNames reads the tag that
opens an :is()/:where() list; a linked sheet that cannot be read is
unreadable, not unparseable; the space probes read their viewport from the
page; the internal-error title covers a page or stylesheet the lint could not
read.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:46:34 +00:00
garrytanandcapy-ai[bot] 50b1190241 design-lint: ninth review cycle performance tests and docs
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:27:57 +00:00
garrytanandcapy-ai[bot] 5afec19d5c design-lint: ninth review cycle performance fixes
css.ts selectorNames reads the tag and class names a selector list mentions
once, so nowrap coverage, wrapping coverage and the roman-em check answer per
element in constant time; shortProseOf reads elements by class from an index
built once per document; font-family-count keeps a Set of family keys; the
import scan gives the optional paren its own whitespace; a JSX expression that
runs to the end of the file fails every ancestor at once; the render locator
reads class and not data-class; tooltip-focus-delay reads the delay slot of
the transition shorthand, so 200ms is a duration like 0.2s.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:27:57 +00:00
garrytanandcapy-ai[bot] e501dc8589 design-lint: ninth review cycle tests
The fourth-cycle unclosed-run test states its own timeout: its per-fixture
bound is 8 s and the four fixtures together pass bun's 5 s default.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:19:29 +00:00
garrytanandcapy-ai[bot] b101f64951 design-lint: ninth review cycle fixes
nestSelector stops expanding a comma list nested in a comma list past an
8 KB selector, resolveVars never substitutes a token over MAX_RESOLVED and
stops growing a value past it, a stylesheet or <style> block the lint could
not parse (or a linked sheet over the size cap) is an internal-error finding
through the Skipped list, which now carries a kind; stripTags takes a visible
character limit so the emoji and label reads do not pay for an element that
runs to the end of the file; assets.ts records every quoted emoji finding
and component.ts splices the one at its line; columnCount drops named lines
inside repeat(); doc.text is built from the stray-blanked source;
Reporter.report returns the finding; the 1280 probes read their viewport
from the page; openTags loses its unused limit; the CHANGELOG hero-fold note
matches what the probe measures.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:19:29 +00:00
garrytanandcapy-ai[bot] d4bb11356f design-lint: eighth review cycle tests and docs
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:01:41 +00:00
garrytanandcapy-ai[bot] a84b030ca0 design-lint: eighth review cycle fixes
Waivers follow the context's shape, not the --scope flag: one html page keeps
page semantics under either scope (its claim reaches the sheet it links) and a
lone component beside an unlinked stylesheet answers for its own file only.
Every '<' that starts no tag is a stray spaced out of doc.src (a '<!' or '<?'
with a '>' ahead stays), an unclosed comment runs to the end of the file, the
three bare /<[^>]*>/ strips use stripTags, the copy tier drops open script,
style, template and nav tags nothing closes, component tags are paired once
per document, columnCount counts repeat() arithmetically, an unclosed
@starting-style block is read once, the import scan matches import shapes
only, the render locator refuses a non-letter tag and reads the class
attribute linearly, tickers are answered from the tree, a tooltip duration is
not a delay, class tokens are appended in a loop, the emoji dedupe is keyed by
the icon, the emoji classes spell U+FE0F and U+200D as escapes, the contrast
and focus viewports are named once, and the hero-fold title matches what the
probe measures.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 12:01:41 +00:00
garrytanandcapy-ai[bot] 0fb23304a6 design-lint: seventh review cycle tests and docs
test/design-lint-seventh-cycle.test.ts (13 tests) pins the stray-tag tail,
the shadow-layer split, the JSX generic and ancestor-closing cases, the
one-mode token table, the per-file component claims under both scopes with
their own suspected rules, the stylesheet beside components, the Reporter
file key, outline: none, the sign-in form, the shared tracking ceiling and
the missing-stylesheet warning. docs/design-lint.md: the token block and its
mode overrides, the stray-tag note, the component-directory claim scope,
the email-band exclusions, the missing-sheet warning and zero-chroma-neutrals
as a fourth narrow reading.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 11:28:11 +00:00
garrytanandcapy-ai[bot] 7da881d6e3 design-lint: seventh review cycle fixes
A tag start the scanner finds no '>' for is spaced out of doc.src, so every
'[^>]*>' scan over a page (the lint's and the craft check's) costs the page
its length; render's line lookup reads the same text. The JSX scanner skips
a generic element's type arguments and closes every element under a close
tag that names an open ancestor, as a browser would; a closer naming nothing
open is text. The token table is read in one colour mode: the base block's
last declaration wins and a prefers-color-scheme or data-theme override only
fills tokens the base never declares; a custom property declared in any
scope is a token definition, not a literal; a token finding points at the
declaration that won. In a directory of components, under either scope,
each file's claims answer for that file alone with its own suspected rules.
The Tailwind dedupe keys files the way Reporter prints them. outline: none is
not a ring for input-state-shift; a form with a password or a sign-in button
is not an email band; one CONTROL_TRACK_MAX_EM (0.04) for both halves of
wide-tracking; one CONTRAST_SLACK; hairline-under-shadow splits layers with
splitTop; a missing linked stylesheet is warned about; TwItem.toks and the
controlHeight scope guard are gone; zero-chroma-neutrals is titled for what
it reads. aside-render sets the device override or viewport only when a
sized step's size changes and clears it before an un-sized step.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 11:28:11 +00:00
garrytanandcapy-ai[bot] 504806efbb design-lint: sixth review cycle tests and docs
test/design-lint-sixth-cycle.test.ts (18 tests; 13 red at 3f0c62582) pins
the per-page work, the right-place findings, the rule judgements and the
waiver and render cells the state matrix named. The emoji-tile cap is
asserted exactly, the pixel-pass test says what it checks, the recorded slop
page now names its generic hero copy. docs/design-lint.md: the real-path
bound, the separator note, page and component claim scopes, hero-fold's
measured half, two more items the lint does not cover, the heading-pattern
exemption and the digit-range dash.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 10:55:07 +00:00
garrytanandcapy-ai[bot] be4086e03b design-lint: sixth review cycle fixes
line-length computes its floor only for a measure between 28 and 45ch and
answers shortProse once per class; wide-tracking resolves inherited case
through a prefix index instead of a scan of every rule; the JSX scanner
fails every ancestor of an element that ran to the end of the file at once;
the hairline-under-shadow pair reads class tokens instead of a two-sided
regex. tooltip-focus-delay names the sheet that holds the :focus delay;
the placeholder emoji scan reads the comment-blanked body for every kind;
fake-send finds its line in a component's script text. A stylesheet href is
bounded by its real path too. The LINT line's separator is kept out of
page-supplied text. Waivers: a component claim answers for its own file,
weighed against its own text; the Waiver shape is a reason string; refusals
go through Reporter. Render: a later fail replaces a warn with the same
evidence, a non-string fix is dropped, the timeout is a constant. Rules:
a meta label in mono is a costume, a leading-dot length reads as a fraction,
a percentage leading collides like a unitless one, an italic word after an
icon is still read, an italic rule on the word is not a display system, en
dashes between digits are ranges, and the catalog's two hero lines are
generic-hero-copy. The Tailwind parse cache and its eviction are gone.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 10:55:07 +00:00
garrytanandcapy-ai[bot] 3f0c62582c design-lint: fifth review cycle tests and docs
test/design-lint-fifth-cycle.test.ts (21 tests) pins the comment-dead placeholder, the linear-time digit run, 699k-rule sheet, unclosed JSX and tracked-label pages, per-sheet waivers and the remaining state-matrix cells, every wrong-shaped render field, and the rule judgements; the fourth-cycle shell test asserts the observable effect, the RSS assertion is structural, time bounds are widened for shared CI shards, the stale empty block is gone, and the FREE_FIXTURES inventory names both cycle files. docs/design-lint.md states the project-root bound on relative hrefs and the three narrow readings (whole-page focus ring, unconditional 4px scale, scroll-container-blind double-sticky).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 10:06:28 +00:00
garrytanandcapy-ai[bot] 1595ff68c2 design-lint: fifth review cycle fixes
The placeholder emoji scan reads the comment-blanked text, so markup inside <!-- --> is dead for every rule. A digit run, a long mono word and a run of scheme prefixes cost their length (FACT and UNSPLASH_URL only start at a token, twDataText bounds its text); a 2 MB sheet of 699k rules no longer blows the stack (rules are appended in loops); JsxScanner spends one failure budget across jsScan and el; the Tailwind had() lookup is a Set; accentedHeads indexes rules by class once; contexts drop their caches once their families have run; the parsed-token cache is bounded. treeOf gives a close tag its parent so a fact after an inline close is counted in its section. Waivers are keyed per rule for a page claim and per rule@sheet for a stylesheet claim, so two linked sheets each answer for their own findings. The render tier validates every page-supplied field (at.cls, ring colour and ratio, probe fg and threshold, PAGE_ERRORS entries, a malformed entry naming the render rule) and keeps its measured findings; lineOf answers from one line index. Rule judgement: a textarea's min-height is not control-height, attribute-selected inputs are read for input-state-shift, a glyph-only <i> is not an italic word, a bounce keyframe by name is bounce-easing, single-quoted inline styles are read, a project root is a package.json or .git. Housekeeping: Probes typed from PROBE_FNS, EYEBROW_* shared from chrome-eyebrow, WaiverClaim.raw and dead imports removed, evidence wording for tracked-only controls and black glass, emoji icon tiles capped like every other emoji path, unreadable files get their own fix text.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 10:06:28 +00:00
garrytanandcapy-ai[bot] 6a29e7e47e design-lint: heroIndexOf carries its own doc comment
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 09:26:32 +00:00
garrytanandcapy-ai[bot] c0422db7f2 design-lint: fourth-cycle simplifications and the pixel pass pinned without a browser
heroClasses reads the hero through heroIndexOf, check64 uses twMonoIsMaterial, check67Html imports capsRatio from chrome-eyebrow, sideStripes loses its bare block; a settle test drives confirmPixels with the swatch fixture (a claim dropped by the pixels behind it, one rewritten, a weak ring confirmed).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 09:26:03 +00:00
garrytanandcapy-ai[bot] bd2a86fdf7 design-lint: fourth review cycle tests and docs
test/design-lint-fourth-cycle.test.ts pins commented-out markup dead for every rule, unclosed <li> Tailwind frames and wireframe slots, linear-time unclosed runs and component scripts, cyclic var() and nested @media, leading-dot lengths, a symlinked lint root, oversize files reported, a whitespace-named stylesheet's waiver, the overused-font stems, width: min() caps, box-shadow rings, Meet headings below the hero, wrong-shaped render answers and the never-waivable refusals by class; the settle golden no longer repeats the kept width and expects the bad grade as tampering. docs/design-lint.md describes the caps, implicit closes, skipped-file findings and the matching rules.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 09:19:33 +00:00
garrytanandcapy-ai[bot] f5134ae2db design-lint: fourth review cycle fixes
Commented-out markup is dead for every rule (Doc.src is the comment-blanked text; craft copy, the module-script check and the border+shadow scan read it). Headings, buttons, links, labels, selects, forms and an open <p> close the way the browser closes them, a tree nests at most 512 deep, and the heading, footer-column, sign-up-button and span readers walk the shared pairing instead of lazy regexes, with each element's text computed once (textOf). Tailwind frames and wireframe slots answer from treeOf. resolveVars stops on a cycle and caps its size; every parseCss at-rule branch honours the depth guard and an inline <style> that fails to parse is skipped with a warning. cwd and lint roots are read through their real paths, a skipped source file is one internal-error finding, relative refs stay inside the project, a linked stylesheet over 2 MB is skipped. overused-font and banned-font match a catalog stem to a family name's first words; width: min()/clamp() caps a container; a box-shadow focus ring beside a border-colour change is not input-state-shift; Meet and triad headings below the hero are suspected; the stylesheet-waiver key goes through oneLine; pxOf reads leading-dot lengths; check67 precomputes selector bases; the render tier reports a wrong-shaped answer per probe and keeps every measured finding, flags a bad grade as tampering, and never repeats the kept width when merging horizontal-scroll.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 09:19:33 +00:00
garrytanandcapy-ai[bot] 9bb348df77 design-lint: document the third-cycle limits and waiver scope
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 08:27:41 +00:00
garrytanandcapy-ai[bot] fc2685b528 design-lint: third review cycle tests; render keeps the measured horizontal-scroll when merging widths
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 08:26:23 +00:00
garrytanandcapy-ai[bot] 6100d6e94d design-lint: third review cycle fixes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 08:21:13 +00:00
garrytanandcapy-ai[bot] ddaeabe1f4 design-lint: pair open and close tags once per document, scan markup in linear time, keep commented-out style and script dead
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 08:05:55 +00:00
garrytanandcapy-ai[bot] df6cd725c2 design-lint: second review cycle
Waivers settle once per page after both tiers, so a blocking rule only the
render tier suspects is waivable and one it measures is refused; a claim in a
stylesheet answers for that stylesheet on every page that links it (no
shared-word check), so a sheet shared by two pages is no longer waived on one
and refused on the other. Every printed field is one line with control
characters stripped; the waiver regex is linear and ends at a carriage
return; a root-relative href cannot climb out of the lint root. The ancestor
map closes optional end tags implicitly and pops to the matching open tag, so
unclosed <li> no longer makes it quadratic. The static tier reports outline:
none with no ring anywhere as missing-focus-visible at its line;
literal-outside-tokens needs a --color-* or --font-* token to exist; the
banned gradient includes indigo-to-violet; a new banned-font rule reads
gstack's BANNED_FONTS; MONO_FACE matches whole words; bold keywords and
tokens count as weight 700 for the contrast threshold. stylesFor reads only
the entries that can match; glOcclusion memoises the pinned walk; the
confirm screenshot is taken at 1x; a page that throws in the render tier is a
render finding and the CLI exits 3 on an internal error. Docs name the token
conventions and what the lint does not cover.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 07:44:56 +00:00
garrytanandcapy-ai[bot] 2bf81ad1f1 design-lint: name the tracked-caps thresholds once, string-aware brace scan, drop an unused parameter, clean up test tmpdirs
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 07:18:23 +00:00
garrytanandcapy-ai[bot] 31682440fe design-lint: ship review fixes
Waivers reach render findings; a blocking rule the lint only suspected is
waivable like any ask, a measured or absent Floor stays refused. A stylesheet
a page links from another directory belongs to that page and is not linted
again on its own; a stylesheet linted alone keeps its waivers. Root-relative
hrefs resolve against the lint root. Stylesheets are read and parsed once per
run. A rule family that throws reports internal-error at ask instead of a
silent pass; aria-labelledby and probe tag names are escaped before they
reach a RegExp; a probe result naming an unknown rule is a render finding,
not a crash; fix strings are one line. overused-font follows gstack's
catalog of display faces; one MONO_FACE list for every monospace check.
parseCss caps nesting depth; medianRgb uses histograms; glHide batches its
layout reads. Dead exports removed (isPage, openTags, over, ComponentTag,
PixelRect, the ids re-exports).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 07:14:50 +00:00
garrytanandcapy-ai[bot] 54d415bd2d design-lint: mark hallmark PAGE_ONLY gates and craft page checks pageOnly so --scope component drops them
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 07:00:05 +00:00
garrytanandcapy-ai[bot] a088fc3d8c feat(design-lint): section-gap measured in the render tier (gate 59, with the six-to-nine section count) and the hero action count; a free test over the recorded review slop page; usage, render glue, file walk, multi-page ownership and copy-tier tests; NOTICE and licences leave FREE_ONLY_PR_FILES so the paid-free boundary test stands
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 06:50:23 +00:00
garrytanandcapy-ai[bot] bf9d9c5b04 test(design-lint): register the lint fixtures as free fixtures and the hallmark licence texts as free-only PR files, so the PR paid lane stays narrow and test/free-fixtures.test.ts passes
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 06:35:05 +00:00
garrytanandcapy-ai[bot] e7b2521148 feat(design-lint): render tier merged; four probe modules join the ratchet; the clean hero sits at a fixed measure so text and visual stand together; CHANGELOG names the aside-render eval viewport
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 06:27:06 +00:00
garrytan 5232f86770 Merge remote-tracking branch 'origin/feat/design-lint-render' into feat/design-lint 2026-10-26 06:18:21 +00:00
garrytanandcapy-ai[bot] 07b2aa6527 feat(design-lint): render tier on gstack's own browser (sloplint-render port)
Ports hallmark's sloplint-render.mjs onto lib/aside-render: one tab per
page, the in-page probes installed once and run at each viewport, a second
pass with full-page screenshots only when a contrast claim needs the painted
pixels (a small PNG reader replaces canvas sampling). Gates 23, 25, 26a, 34,
40, 41, 44a-d, 49a/b, 58, 71, 72, 73, 75, 77-83, F17-F20, plus the page that
did not render. The stamp's posture, hero-shape, photo-shape and genre
guards are gone: the strict form applies. Focus rings are read by focusing
each control in turn (programmatic focus matches :focus-visible on the
daemon with no prior pointer input; a stylesheet scan is the fallback).

lib/aside-render: an eval step takes width/height like a screenshot step
(device metrics on Aside, viewport on browse, cleared after), and spec.file
may be an http(s) URL, opened as it is with nothing served.

The clean fixture gained border-box on its hero, a centred, taller hero
visual, a wrapping actions row, a statement-sized close head and a shorter
story paragraph: the browser showed the action below the 1280x800 fold, a
dead band under the hero, a 600px image spilling past a phone screen and a
thin close section.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 06:17:03 +00:00
garrytanandcapy-ai[bot] 9be95cf33e test(design-lint): the eyebrow-pass and tailwind-pass fixtures carry a skip link, main id and aria-current so the copy tier passes them too; waiver fixture gets a meta description
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 06:13:52 +00:00
garrytanandcapy-ai[bot] 22d39449d1 feat(design-lint): chrome, assets and finish families merged; maskedProse moves to html.ts; isTokenRule takes a Pick; ratchet watches every lint module
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 06:06:26 +00:00
garrytan 69a7ec0e82 Merge remote-tracking branch 'origin/feat/design-lint-chrome-assets-finish' into feat/design-lint 2026-10-26 06:03:12 +00:00
garrytanandcapy-ai[bot] 6dda84e531 feat(design-lint): port the chrome, assets and finish rule families from sloplint
Chrome (gates 19 42 46a 47 54 63 68 69 70 85): gate 19 split by tell onto
aphoristic-cadence, generic-hero-copy, generic-cta-copy, em-dash-overuse and
template-footer-line in rules/chrome-copy.ts (with the two-filled-buttons half
of F4 and the shared prose mask); the eyebrow in rules/chrome-eyebrow.ts; the
nav and footer shapes, invented proof, drawn chrome, placeholder services,
template punctuation, wireframe slots, repeated facts, the fake send and a
static version of the email-band close in rules/chrome.ts.

Assets (gates 30 33 40 41 49 76): emoji icons, mixed icon libraries, unlabelled
svg/canvas, contrast pairs and surface inks (suspected at ask in the static
tier), wrapping labels split into button-label-wraps and link-wraps, broken
images and stock hotlinks.

Finish (F1-F9 F15 F16 F21-F24): all polish except fake-avatar.

Tests cover every id with a negative control and a planted positive; the clean
fixture gains scrollbar-color so its committed palette themes every browser
surface.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 06:02:06 +00:00
garrytanandcapy-ai[bot] e8e61f2dba chore(design-lint): drop unused colour test imports
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 05:52:29 +00:00
garrytanandcapy-ai[bot] 95eee7e4e1 chore(design-lint): tidy the colour test imports; control-height page-only; lazy-lcp title
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 05:52:11 +00:00
garrytan 95b19fdbca Merge remote-tracking branch 'origin/feat/design-lint-structure-motion' into feat/design-lint 2026-10-26 05:51:29 +00:00
garrytanandcapy-ai[bot] aed2b149e6 fix(design-lint): the Tailwind gradient half of 2a/2b lives in the component family only
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 05:51:29 +00:00
garrytanandcapy-ai[bot] 3113f54d55 feat(design-lint): port the structure and motion rule families from sloplint
Structure: template-cards, nested-cards, vh-height, raw-spacing, off-scale-spacing, overflow-x-unclipped (static half), bare-fr-track, display-head-unwrapped, radio-tab-jump, double-sticky, screen-word-budget (static half), and a conservative static half of wide-container. Motion: layout-transition, spacing-transition, hover-tells, bounce-easing, focus-ring-fade, tooltip-focus-delay, autorotate-no-pause, missing-focus-visible, missing-states, missing-reduced-motion, autoplay-unmuted, lazy-lcp, video-without-poster, input-state-shift, control-height (static half), content-hidden-at-rest. Every rule has a planted positive and a negative control; the clean fixture lede drops to eleven words so the hero-paragraph budget holds.
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 05:50:22 +00:00
garrytan dfd6693d51 Merge remote-tracking branch 'origin/feat/design-lint-tailwind' into feat/design-lint 2026-10-26 05:50:06 +00:00
garrytanandcapy-ai[bot] ab8bb491ac fix(design-lint): mark line-length, cream-palette and the caps leading rules page-only
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-26 05:50:05 +00:00