/tests/fixtures/antipatterns/heading-rhythm.html\",\n \"line\": 0,\n \"snippet\": \" \\\"pass-band\\\": children flush against bg on right/left (no inset)\"\n },\n {\n \"antipattern\": \"low-contrast\",\n \"name\": \"Low contrast text\",\n \"description\": \"Text does not meet WCAG AA contrast requirements (4.5:1 for body, 3:1 for large text). Increase the contrast between text and background.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"2.6:1 (need 4.5:1) — text #94a3b8 on #ffffff\"\n },\n {\n \"antipattern\": \"hero-eyebrow-chip\",\n \"name\": \"Hero eyebrow / pill chip\",\n \"description\": \"A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"eyebrow chip (tracked-caps) \\\"AI-NATIVE WORKFLOWS\\\" above h1 \\\"Eyebrow Above Hero\\\"\"\n },\n {\n \"antipattern\": \"hero-eyebrow-chip\",\n \"name\": \"Hero eyebrow / pill chip\",\n \"description\": \"A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"eyebrow chip (tracked-caps) \\\"NEW IN 2026\\\" above h1 \\\"Span Eyebrow Above Hero\\\"\"\n },\n {\n \"antipattern\": \"hero-eyebrow-chip\",\n \"name\": \"Hero eyebrow / pill chip\",\n \"description\": \"A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"eyebrow chip (tracked-caps) \\\"FEATURED\\\" above h1 \\\"Pill Chip Above Hero\\\"\"\n },\n {\n \"antipattern\": \"hero-eyebrow-chip\",\n \"name\": \"Hero eyebrow / pill chip\",\n \"description\": \"A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"eyebrow chip (tracked-caps) \\\"NEW\\\" above h1 \\\"Already Uppercase Text\\\"\"\n },\n {\n \"antipattern\": \"hero-eyebrow-chip\",\n \"name\": \"Hero eyebrow / pill chip\",\n \"description\": \"A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"eyebrow chip (tracked-caps) \\\"A VERY LONG UPPERCASE TABLE OF CONTENTS \\\" above h1 \\\"Long Uppercase Sentence Above Hero\\\"\"\n },\n {\n \"antipattern\": \"all-caps-body\",\n \"name\": \"All-caps body text\",\n \"description\": \"Long passages in uppercase are hard to read. We recognize words by shape (ascenders and descenders), which all-caps removes. Reserve uppercase for short labels and headings.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"text-transform: uppercase on 46 chars of body text\"\n },\n {\n \"antipattern\": \"overused-font\",\n \"name\": \"Overused font\",\n \"description\": \"Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"Primary font: inter\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hero-eyebrow-chip.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"SECTION KICKER\\\" above h1 \\\"Body-Sized Heading Below Eyebrow\\\"\"\n },\n {\n \"antipattern\": \"overused-font\",\n \"name\": \"Overused font\",\n \"description\": \"Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/hook-inline-ignore.html\",\n \"line\": 0,\n \"snippet\": \"Primary font: roboto\"\n },\n {\n \"antipattern\": \"icon-tile-stack\",\n \"name\": \"Icon tile stacked above heading\",\n \"description\": \"A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"80x80px icon tile above h3 \\\"Lightning Fast\\\"\"\n },\n {\n \"antipattern\": \"icon-tile-stack\",\n \"name\": \"Icon tile stacked above heading\",\n \"description\": \"A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"64x64px icon tile above h3 \\\"Secure Storage\\\"\"\n },\n {\n \"antipattern\": \"icon-tile-stack\",\n \"name\": \"Icon tile stacked above heading\",\n \"description\": \"A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"72x72px icon tile above h3 \\\"Easy Setup\\\"\"\n },\n {\n \"antipattern\": \"icon-tile-stack\",\n \"name\": \"Icon tile stacked above heading\",\n \"description\": \"A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"96x96px icon tile above h3 \\\"Powerful Analytics\\\"\"\n },\n {\n \"antipattern\": \"icon-tile-stack\",\n \"name\": \"Icon tile stacked above heading\",\n \"description\": \"A small rounded-square icon container above a heading is the universal AI feature-card template — every generator outputs this exact shape. Try a side-by-side icon and heading, or let the icon sit in flow without its own container.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"48x48px icon tile above h3 \\\"Emoji Inline Icon\\\"\"\n },\n {\n \"antipattern\": \"flat-type-hierarchy\",\n \"name\": \"Flat type hierarchy\",\n \"description\": \"Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"Sizes: 14px, 16px, 18px, 24px (ratio 1.7:1)\"\n },\n {\n \"antipattern\": \"ai-color-palette\",\n \"name\": \"AI color palette\",\n \"description\": \"Purple/violet gradients and cyan-on-dark are the most recognizable tells of AI-generated UIs. Choose a distinctive, intentional palette.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"Purple/violet accent colors detected\"\n },\n {\n \"antipattern\": \"marketing-buzzword\",\n \"name\": \"Marketing buzzword\",\n \"description\": \"Generic SaaS phrases (streamline / empower / supercharge / world-class / enterprise-grade / next-generation / cutting-edge / etc) are instant AI tells. Pick a specific verb and noun that says what the product literally does.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/icon-tile-stack.html\",\n \"line\": 0,\n \"snippet\": \"1 buzzword phrase: \\\"ure Storage Enterprise-grade security fo\\\"\"\n },\n {\n \"antipattern\": \"overused-font\",\n \"name\": \"Overused font\",\n \"description\": \"Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/image-backed-contrast.html\",\n \"line\": 0,\n \"snippet\": \"Primary font: arial\"\n },\n {\n \"antipattern\": \"italic-serif-display\",\n \"name\": \"Italic serif display headline\",\n \"description\": \"Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/italic-serif-display.html\",\n \"line\": 0,\n \"snippet\": \"italic serif h1 (fraunces) at 88px \\\"Fraunces 88px italic\\\"\"\n },\n {\n \"antipattern\": \"italic-serif-display\",\n \"name\": \"Italic serif display headline\",\n \"description\": \"Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/italic-serif-display.html\",\n \"line\": 0,\n \"snippet\": \"italic serif h1 (recoleta) at 64px \\\"Recoleta 64px italic\\\"\"\n },\n {\n \"antipattern\": \"italic-serif-display\",\n \"name\": \"Italic serif display headline\",\n \"description\": \"Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/italic-serif-display.html\",\n \"line\": 0,\n \"snippet\": \"italic serif h1 (playfair display) at 72px \\\"Playfair 72px italic\\\"\"\n },\n {\n \"antipattern\": \"italic-serif-display\",\n \"name\": \"Italic serif display headline\",\n \"description\": \"Oversized italic serif (Fraunces, Recoleta, Playfair, Newsreader-italic) as the primary hero headline reads as taste in isolation but has become the universal AI-startup landing page hero. Set roman, or move to a non-serif display face. Editorial / magazine register may legitimately want this — judge by context.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/italic-serif-display.html\",\n \"line\": 0,\n \"snippet\": \"italic serif h1 (customserifface) at 56px \\\"Unknown Serif Generic Fallback\\\"\"\n },\n {\n \"antipattern\": \"overused-font\",\n \"name\": \"Overused font\",\n \"description\": \"Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/italic-serif-display.html\",\n \"line\": 0,\n \"snippet\": \"Primary font: fraunces\"\n },\n {\n \"antipattern\": \"overused-font\",\n \"name\": \"Overused font\",\n \"description\": \"Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/italic-serif-display.html\",\n \"line\": 0,\n \"snippet\": \"Primary font: recoleta\"\n },\n {\n \"antipattern\": \"overused-font\",\n \"name\": \"Overused font\",\n \"description\": \"Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/italic-serif-display.html\",\n \"line\": 0,\n \"snippet\": \"Primary font: inter\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/jsx-should-flag.jsx\",\n \"line\": 8,\n \"snippet\": \"border-l-4\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/jsx-should-flag.jsx\",\n \"line\": 35,\n \"snippet\": \"borderLeft: '4px solid\"\n },\n {\n \"antipattern\": \"gradient-text\",\n \"name\": \"Gradient text\",\n \"description\": \"Gradient text is decorative rather than meaningful — a common AI tell, especially on headings and metrics. Use solid colors for text.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/jsx-should-flag.jsx\",\n \"line\": 22,\n \"snippet\": \"bg-clip-text + bg-gradient\"\n },\n {\n \"antipattern\": \"ai-color-palette\",\n \"name\": \"AI color palette\",\n \"description\": \"Purple/violet gradients and cyan-on-dark are the most recognizable tells of AI-generated UIs. Choose a distinctive, intentional palette.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/jsx-should-flag.jsx\",\n \"line\": 10,\n \"snippet\": \"text-purple-500 on heading\"\n },\n {\n \"antipattern\": \"ai-color-palette\",\n \"name\": \"AI color palette\",\n \"description\": \"Purple/violet gradients and cyan-on-dark are the most recognizable tells of AI-generated UIs. Choose a distinctive, intentional palette.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/jsx-should-flag.jsx\",\n \"line\": 22,\n \"snippet\": \"from-purple-400 gradient\"\n },\n {\n \"antipattern\": \"bounce-easing\",\n \"name\": \"Bounce or elastic easing\",\n \"description\": \"Bounce and elastic easing feel dated and tacky. Real objects decelerate smoothly — use exponential easing (ease-out-quart/quint/expo) instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/jsx-should-flag.jsx\",\n \"line\": 50,\n \"snippet\": \"animate-bounce (Tailwind)\"\n },\n {\n \"antipattern\": \"layout-transition\",\n \"name\": \"Layout property animation\",\n \"description\": \"Animating width, height, padding, or margin causes layout thrash and janky performance. Use transform and opacity instead, or grid-template-rows for height animations.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/jsx-should-flag.jsx\",\n \"line\": 51,\n \"snippet\": \"transition: width\"\n },\n {\n \"antipattern\": \"hero-eyebrow-chip\",\n \"name\": \"Hero eyebrow / pill chip\",\n \"description\": \"A tiny uppercase letter-spaced label sitting immediately above an oversized hero headline — or the same shape rendered as a pill chip — is now the default AI SaaS hero. Drop the eyebrow, integrate the kicker into the headline, or run it as a navigation breadcrumb instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"eyebrow chip (tracked-caps) \\\"Platform overview\\\" above h1 \\\"\\\"Hero Owned By Hero Rule\\\"\\\"\"\n },\n {\n \"antipattern\": \"wide-tracking\",\n \"name\": \"Wide letter spacing on body text\",\n \"description\": \"Letter spacing above 0.05em on body text disrupts natural character groupings and slows reading. Reserve wide tracking for short uppercase labels only.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"letter-spacing: 0.11em on body text\"\n },\n {\n \"antipattern\": \"overused-font\",\n \"name\": \"Overused font\",\n \"description\": \"Inter, Roboto, Fraunces, Geist, Plus Jakarta Sans, and Space Grotesk are used on so many sites they no longer feel distinctive. Each new wave of AI-generated UIs converges on the same handful of faces. Choose a face that gives your interface personality.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"Primary font: arial\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"Invitation protocol\\\" above h2 \\\"A Single Kicker Still Flags\\\"\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"Output model\\\" above h2 \\\"Standard Tracking Kicker\\\"\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"Preview sequence\\\" above h3 \\\"Kicker Above An H3\\\"\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"Access window\\\" above h4 \\\"Kicker Above An H4\\\"\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"Platform notes\\\" above h1 \\\"Sub Hero Heading\\\"\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"materials briefing\\\" above h2 \\\"Small Caps Kicker\\\"\"\n },\n {\n \"antipattern\": \"kicker-above-heading\",\n \"name\": \"Kicker / eyebrow label above heading\",\n \"description\": \"A tiny tracked uppercase or small-caps label sitting as its own block directly above a heading is banned outright, repeated or not. Generated kickers never earn their place: the heading carries its own weight. Delete the label and let the heading speak; if the words matter, work them into the heading or the body.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"kicker \\\"Field studies\\\" above div \\\"Heading Role Kicker\\\"\"\n },\n {\n \"antipattern\": \"cream-palette\",\n \"name\": \"Cream / beige palette\",\n \"description\": \"A warm cream or beige page background has become the default \\\"tasteful\\\" AI surface, reached for by reflex. Choose a background that comes from a deliberate palette, not the safe warm off-white.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \"cream/beige page background rgb(246, 242, 236)\"\n },\n {\n \"antipattern\": \"skipped-heading\",\n \"name\": \"Skipped heading level\",\n \"description\": \"Heading levels should not skip (e.g. h1 then h3 with no h2). Screen readers use heading hierarchy for navigation. Skipping levels breaks the document outline.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \" \\\"\\\"Page Title After Nav\\\"\\\" followed by \\\"\\\"48%\\\"\\\" (missing h2)\"\n },\n {\n \"antipattern\": \"skipped-heading\",\n \"name\": \"Skipped heading level\",\n \"description\": \"Heading levels should not skip (e.g. h1 then h3 with no h2). Screen readers use heading hierarchy for navigation. Skipping levels breaks the document outline.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/kicker-above-heading.html\",\n \"line\": 0,\n \"snippet\": \" \\\"\\\"Hero Owned By Hero Rule\\\"\\\" followed by \\\"\\\"Garden Suite\\\"\\\" (missing h2)\"\n },\n {\n \"antipattern\": \"flat-type-hierarchy\",\n \"name\": \"Flat type hierarchy\",\n \"description\": \"Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/layout.html\",\n \"line\": 0,\n \"snippet\": \"Sizes: 11px, 14px, 16px (ratio 1.5:1)\"\n },\n {\n \"antipattern\": \"nested-cards\",\n \"name\": \"Nested cards\",\n \"description\": \"Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/layout.html\",\n \"line\": 0,\n \"snippet\": \"Card inside card (div)\"\n },\n {\n \"antipattern\": \"nested-cards\",\n \"name\": \"Nested cards\",\n \"description\": \"Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/layout.html\",\n \"line\": 0,\n \"snippet\": \"Card inside card (div)\"\n },\n {\n \"antipattern\": \"nested-cards\",\n \"name\": \"Nested cards\",\n \"description\": \"Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/layout.html\",\n \"line\": 0,\n \"snippet\": \"Card inside card (div)\"\n },\n {\n \"antipattern\": \"nested-cards\",\n \"name\": \"Nested cards\",\n \"description\": \"Cards inside cards create visual noise and excessive depth. Flatten the hierarchy — use spacing, typography, and dividers instead of nesting containers.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/layout.html\",\n \"line\": 0,\n \"snippet\": \"Card inside card (div)\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/linked-stylesheet.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 12px\"\n },\n {\n \"antipattern\": \"border-accent-on-rounded\",\n \"name\": \"Border accent on rounded element\",\n \"description\": \"Thick accent border on a rounded card — the border clashes with the rounded corners. Remove the border or the border-radius.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/linked-stylesheet.html\",\n \"line\": 0,\n \"snippet\": \"border-top: 3px + border-radius: 12px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/linked-stylesheet.html\",\n \"line\": 0,\n \"snippet\": \"border-top: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 3px + border-radius: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 6px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 6px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 6px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 3px + border-radius: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 6px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 5px + border-radius: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-right: 4px + border-radius: 4px\"\n },\n {\n \"antipattern\": \"side-tab\",\n \"name\": \"Side-tab accent border\",\n \"description\": \"Thick colored border on one side of a card — the most recognizable tell of AI-generated UIs. Use a subtler accent or remove it entirely.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"border-left: 4px + border-radius: 6px\"\n },\n {\n \"antipattern\": \"low-contrast\",\n \"name\": \"Low contrast text\",\n \"description\": \"Text does not meet WCAG AA contrast requirements (4.5:1 for body, 3:1 for large text). Increase the contrast between text and background.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"4.49:1 (need 4.5:1) — text #64748b on #fef7f2\"\n },\n {\n \"antipattern\": \"flat-type-hierarchy\",\n \"name\": \"Flat type hierarchy\",\n \"description\": \"Font sizes are too close together — no clear visual hierarchy. Use fewer sizes with more contrast (aim for at least a 1.25 ratio between steps).\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/modern-color-borders.html\",\n \"line\": 0,\n \"snippet\": \"Sizes: 13px, 14px, 16px (ratio 1.2:1)\"\n },\n {\n \"antipattern\": \"bounce-easing\",\n \"name\": \"Bounce or elastic easing\",\n \"description\": \"Bounce and elastic easing feel dated and tacky. Real objects decelerate smoothly — use exponential easing (ease-out-quart/quint/expo) instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/motion.html\",\n \"line\": 0,\n \"snippet\": \"animation: bounce-keyframe\"\n },\n {\n \"antipattern\": \"bounce-easing\",\n \"name\": \"Bounce or elastic easing\",\n \"description\": \"Bounce and elastic easing feel dated and tacky. Real objects decelerate smoothly — use exponential easing (ease-out-quart/quint/expo) instead.\",\n \"severity\": \"warning\",\n \"category\": \"slop\",\n \"file\": \"/tests/fixtures/antipatterns/motion.html\",\n \"line\": 0,\n \"snippet\": \"cubic-bezier(0.68, -0.55, 0.265, 1.55)\"\n },\n {\n \"antipattern\": \"layout-transition\",\n \"name\": \"Layout property animation\",\n \"description\": \"Animating width, height, padding, or margin causes layout thrash and janky performance. Use transform and opacity instead, or grid-template-rows for height animations.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"/tests/fixtures/antipatterns/motion.html\",\n \"line\": 0,\n \"snippet\": \"transition: width\"\n },\n {\n \"antipattern\": \"layout-transition\",\n \"name\": \"Layout property animation\",\n \"description\": \"Animating width, height, padding, or margin causes layout thrash and janky performance. Use transform and opacity instead, or grid-template-rows for height animations.\",\n \"severity\": \"warning\",\n \"category\": \"quality\",\n \"file\": \"