Visant Killer logo

Visant Killer

Community
pedrojaques99
visant-killer

Single UI audit door: runs detectors as a hard gate, applies frontend/motion/refine judgment, ends with an adversarial interrogation and a score. Use on "looks AI-made", "this is slop", "too cluttered", "tá com cara de IA", "tá slop", "tá poluído", "audita essa tela", "mata essa tela", "nível vale do silício", auditing UI before a PR.

Overview

Publisherpedrojaques99
Repositoryvisant-skills-public
Skill namevisant-killer
Stars
81
Forks
1
Bundled files
22
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 22 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by pedrojaques99 on GitHub. Read the source before you install it.

Installation

Install the Visant Killer AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/pedrojaques99/visant-skills-public/tree/main/visant-killer
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/pedrojaques99/visant-skills-public.git /tmp/visant-skills-public
mkdir -p .claude/skills
cp -r /tmp/visant-skills-public/visant-killer .claude/skills/visant-killer
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Visant Killer in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Visant Killer on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Visant Killer is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Visant Killer

Adversarial UI audit. The screen is the defendant, not the client. Two halves that do not replace each other: the gate (deterministic scripts, binary: AI tell, token, voice, chrome noise) and judgment (you, with the skills loaded), because AI slop survives any linter: the problem is decision, not syntax.

Rule zero (from visant-copy): only the fix of a confirmed defect goes into the file. What passes clean stays untouched, even if it sounds flat. Taste improvements go as a proposal table; the user picks line by line.

A green gate is not a seen screen. A frozen AnimatePresence in a lead form passed six gates. So killer-scan refuses "gate open" without the surface table and the record of having opened the screen.

Where each rule came from: references/cases.md. Stack. The gate reads React JSX. On Vue, Svelte, Astro or HTML it refuses (exit 2): audit by hand, plus the browser scans.

Hard prohibitions (you break them while writing, not reviewing)

ForbiddenWriteWhy
arrow glyph in text (→, ←, ↑, ↓) and hand-drawn icon SVGa real library icon (@phosphor-icons/react, @radix-ui/react-icons)LAW. The character arrow is Claude's nº1 habit: it inherits font metrics, drifts off the baseline, changes shape per family, has no controllable weight or size, and reads as text. A hand SVG is the same disease in more lines. Icons are library assets, always
hover:scale-*, whileHover={{ scale }}change color, shadow or borderscale on hover is the nº1 template tell; it moves neighboring layout and does not survive prefers-reduced-motion
hover that grows over neighboring textreserve the lane permanently and grow inside ithover reveals, hover does not run over things
hover:bg-accent when --accent is emphasishover:bg-muted or hover:bg-primaryemphasis turned into a mouse state. Check the token: in stock shadcn --accent is the neutral hover color, and there hover:bg-accent is right
border-accentborder-bordersame confusion: emphasis turned into chrome
backdrop-blur outside dialog/sheetsolid token backgroundcosts compositing on every scroll; on a card it is decoration paid in frames
white-space: nowrap in an overlay without max-widthmax-width: calc(100% - 12px) and let it wrapinside an overflow: hidden parent the word gets CUT, and the cut only exists after the font loads: no linter sees it
a fixed highlight (on: true, active: true) in an item factorythe condition that decides (on: q.live)a highlight that runs once per item lights up the whole list, and emphasis on everything is emphasis on nothing
two doors for the same kind of data on one screenone per screen, or names that say the difference (the detector only checks the same screen; a repeated name across screens is judgment)two identical URL fields side by side writing to different stores: people choose by luck
the same gap inside a group and between groups (space-y-4 on every level)tight inside, open between: each level at least 2× the one inside it (8 / 16 / 32)the eye groups by distance: when the label is as far from its value as from the next block, the screen reads wrong with every token right (catalog 6)
transition-alltransition-colors or an explicit listanimates what you did not ask for, layout included
duration-300+ on an interactive elementDUR.base / DUR.slowabove ~300ms the UI feels stuck
raw hex, rgb(), rgba()a token from the repo's own layerread how it stores values first: loose channels need hsl(var(--x)), a full color (oklch in current shadcn) is var(--x)
component demo with a fake frame, "hover me" caption, stacked variationsthe piece large and centered, one at a time, a quiet selectorcatalog 35-38: in the tile the piece disappears behind the explanation
the pretty state (glow, tilt, open menu) only on hoverborn in its best state; hover intensifiesit does not exist on touch, in the tile or in a screenshot (catalog 37)
clickable button/card without cursor: pointer; drag without graba rule in the shell (:is(button,[role=button],a[href]))Tailwind v4 preflight resets the cursor (catalog 46)
client copy in a library piecegeneric text, spoken pt-BRthe library sells to every client (catalog 42)

Exceptions exist (route transition, marketing piece, #fff/#000 as a WCAG contrast reference, blur in a Dialog, scrim over a photo). An exception goes with a written reason on the line, in the scanner format (references/gates.md), never with a mute audit-ignore.

Scripts (<skill-dir> is the folder holding this file; replace it with the real path):

bash
K=<skill-dir>/scripts/killer-scan.mjs
R=<skill-dir>/../visant-refine/scripts/refine-scan.mjs
D=<skill-dir>/scripts/dist-scan.mjs
C=<skill-dir>/../visant-copy/scripts/copy-lint.mjs
T=<skill-dir>/scripts/corta-scan.js; E=${T%corta-scan.js}ritmo-scan.js  # IN THE BROWSER (Step 5): clipping; spacing
V=<skill-dir>/scripts/verify-screens.mjs  # opens the app logged in (Step 5)
# grafo.mjs is a library (import graph for --roots and repeated-door), not a CLI

Step 0: Root first (large target)

A target of dozens of files starts by grouping findings by root: node $K --roots <target> (shared pieces ranked by fan-out × findings, how). One wrong container produces hundreds of leaves with the same symptom, pointing at the wrong file. Primitives and the shell come before any page; only then --all to split the rest by file.

Step 1: Classify the target (never skip)

The tier decides how much interrogation the target deserves; a wrong tier wastes context, or audits what pays the bills too shallowly.

TierThe target isSignalsInterrogation
T1 Leafone component, one card, one list row1 to 3 files, no route of its own, does not write to the database5 questions
T2 Routea whole screenhas page.tsx, has states (loading, empty, error), has keyboard12 questions
T3 Corea flow that moves money, identity, or several routesdatabase writes, billing, permissions, onboarding, sales pipeline20 questions plus positioning

Mixed target: classify by region, not folder (a billing row inside a listing screen is T3 inside a T2).

Complaint only about excess ("too much text", "cluttered", "template look", "tá poluído", "muita label"): go straight to declutter.md, the path that needs nothing of the house (any repo, any language, no linter).

Step 2: Gate (runs before reading the code)

Report first, detector second (an exit code feels like completion, and agents stop there):

bash
node $K --init-report AUDIT.md <target>    # skeleton, one row per route (Shell hint to confirm)
# fill the table BEFORE fixing anything
node $K --report AUDIT.md <target>

Without a complete --report it prints GATE INCOMPLETE and exits 1 (details). Two required columns:

  • surface: A acquisition (not yet a customer), B work (uses it every day), C trust (money, permission, destructive action). A instincts on a B screen is the most expensive frontend mistake.
  • business variable: what this element moves. Dash, "TBD" or empty is rejected: filling it with nothing is skipping the step.

The ## Screen seen section (exact heading; ## Tela vista also parses) is the other half: one row per screen opened, with route, width, data state and what happened. Read environment.md first: the dev server lies.

killer-scan runs four detectors, prints one scoreboard and ends with a gates: N/4 ran [...] line naming anything skipped: impeccable (AI tells); token (the repo's audit:design-like gate, else a labeled built-in FALLBACK for raw hex/rgb/hsl and palette classes, aware of the repo's token layer); copy (voice, only on strings that reach the eye: JSX text, label, title, placeholder, aria-label, alt); chrome noise (noise-scan: each line defensible, the sum unreadable). Details and the 24 noise rules: gates.md.

Discover the target repo's gates. The four detectors are the floor. Look at package.json scripts named lint/audit/design/token/ui/theme/i18n/ratchet and at scripts/ for unwired scanners; run what exists on the target; record what ran and what was skipped, and why (commands).

Side gates: node $R <target> when there is a chart, gauge or animation; node $D <app-root> on surface A, before polish, because a page that shares without a card or converts without an event is not fixable by tokens and no UI detector lights up (distribution.md).

A failed gate becomes a fix, not a proposal, after confirming each finding at file:line (legacy code is noisy; fixing unread lines writes bugs).

  • A confirmed false positive has ONE right fix: repair the rule and lock the case in the fixture, never an audit-ignore in the file (it hides the next one).
  • Written exception: EXCEPTION to <scanner>/<rule>: reason (or EXCEÇÃO ao) on the line or up to 8 above; mute allowlists are forbidden (contract).
  • CI ratchet: re-record a baseline only when the total dropped, never to absorb a rise, always over the whole app (gates.md).
  • Rule before finding: many findings, almost none real, means the defect is in the RULE. Group by folder, read the rule's intent, scope it with a reason written inside the rule, then fix what is left (false-positives.md).

Step 3: Judgment (load by tier, not everything always)

Skill memory is not the skill; load by tier, and report what was not loaded.

TierLoadDo not load
T1 leafnothing beyond this skillthe four. The prohibitions table and the slop-catalog are enough for a card
T2 routevisant-frontend + visant-motionrevenue-centric-design, unless the route sells something
T3 coreall fournone

Lean T3 (tight context): only each SKILL.md; a reference only for a finding. Order: visant-frontend (the cut test: every element names the business variable it moves, or it goes; the Step 2 surface table is its output), then visant-motion (easing/duration SSoT and feel gotchas), visant-copy (voice; the gate caught syntax), revenue-centric-design (only as Step 4 ammunition).

Read slop-catalog.md before judging (slop that passes every linter: symptom, cause, fix). Several agents at once: exclusive file ownership, i18n by fragment merged once, measure after edits stop (multi-agent.md).

Step 4: Devil's advocate

The goal is the concept change that makes half the pixel work unnecessary. Question bank per tier: devils-advocate.md.

  • Pick the tier's questions, no more (extra on T1 is philosophy about a card). The fixed block F1 to F6 runs on every tier: reuse, design-system consistency, measured responsiveness and performance, progressive flow for the ICP, what to hide or iconize, what is missing for Silicon Valley level.
  • Answer it yourself first, with file:line. A question handed back with no attempt is laziness dressed as rigor. Only what changes what gets built and the code cannot answer goes to the user, with your recommendation first.
  • Name the revenue-centric-design mechanism when there is one (attention hierarchy, Swiss Knife Index, optimal play, default as decision, promise the size of the proof). Naming the lever is the value.
  • One question that kills the screen beats twelve token fixes. If the honest answer is "this screen should not exist", write that.
  • T2 and T3 get a reviewer who cannot read your defense: a fresh agent with the frames, never your plan or reasons (how).

Step 5: Verification (what compiles is not what someone saw)

First, open the screen (it fills ## Screen seen). App behind login: node $V from the target repo (overflow, cut text, raw i18n keys, console, /api 4xx/5xx, empty screen, theme; paid routes locked). Published URL: corta-url.mjs <base> route. By hand: $T/$E in the console. Flags: verification.md. Before measuring, the four signals in environment.md: route warmed up, hydration confirmed by a DOM mark (not readyState), real data including the worst record, node count matching the page opened by hand.

Then, and only then (whatever did not run goes in the report):

CheckHow
types and lintnpx tsc --noEmit and the repo's lint. Never next build with dev running (it breaks .next)
horizontal overflow$V (estouro column): scrollWidth - clientWidth of the document at 390px, re-measured after each fix. Not on an element: a decorative blob under overflow-hidden once became 64px of overflow that did not exist
cut text and stacked overlay$V (corta column) or $T in the console: a word eaten by a clipping parent, an overlay covering another in the same corner, a piece that left its box
spacing that lies$V (spacing column), corta-url.mjs, or $E in the console (ritmo()): more space inside a group than between groups, three levels with the same gap, one sibling drifting a few px. Off-scale values (15px, p-[13px]) are the repo's scale linter, not this (gates.md)
distributiondoes the page exist outside itself? title, description, share card, conversion event, sitemap, robots (distribution.md)
real datathe screen with the best record and the worst; empty hides every overflow
light theme$V --theme both. A dark-first app breaks in light where nobody looks
backend failurerun with the backend down. Silent zero is the dominant lie: a failed fetch that paints "0" is indistinguishable from a real zero
keyboardfocus-visible reaches everything hover reveals
feelDevTools, Animations, 25% speed

Step 6: Report

The same AUDIT.md, now with findings and score first, never just chat text (scorecard.md). ## Not checked is required: widths, states and data you did not see, or "nothing" with the screens that prove it. A score is not a compliment: 100 on the gate with a T3 and no positioning interrogation is an incomplete audit, and the report says so.

Do not

  • Declare a high score without running the script, or a "full pass" with the surface table blank. The score comes from the process, not the vibe.
  • Create a new design-system component without explicit permission. Reuse and parametrize; if a piece is missing, look first in the Visant library (ui.visantlabs.com, 150+ audited items; index at /llms.txt, sheet at /r/<name>.md), then the official shadcn primitive. Both install via npx shadcn@latest add @visant/<name> (registry "@visant": "https://ui.visantlabs.com/r/{name}.json" in components.json); say so before.
  • Fix leaves before roots (Step 0, --roots).
  • Open a route that spends credits on load without the verify-screens lock.
  • Refactor on top of a reported defect without confirming it in the code. Diagnosis is file:line, not opinion.
  • Declare done without having opened the screen: the line this whole skill exists to defend.
  • Clear a finding by hiding what it points at. The cause goes, not the symptom.
  • Re-run a green gate on an unchanged screen. Stop and get the fresh reviewer.
  • Apply it to a gambling, casino or betting product. Refuse and explain: it is a reuse condition of revenue-centric-design, not taste.

Credits and lineage: references/credits.md.

Neighbors

  • [[visant-design]]: the door when the ask is not yet an audit
  • [[visant-frontend]]: decide what the screen should be; this skill judges what it is
  • [[visant-motion]]: how to fix what moves badly
  • [[visant-refine]]: how to fix a chart or panel
  • [[visant-copy]]: rewrite the words; this skill only flags them
  • [[visant-preflight]]: the entry gate; this is the exit gate
  • [[visant-new-site]] (Visant internal): the client site flow, which ends here
  • [[visant-registry]] (Visant internal): where a missing piece comes from; publicly, ui.visantlabs.com

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Visant Killer AI skill do?

Single UI audit door: runs detectors as a hard gate, applies frontend/motion/refine judgment, ends with an adversarial interrogation and a score. Use on "looks AI-made", "this is slop", "too cluttered", "tá com cara de IA", "tá slop", "tá poluído", "audita essa tela", "mata essa tela", "nível vale do silício", auditing UI before a PR.

Why use Visant Killer on TypingMind?

Because you install it once and use it with any model. Visant Killer is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Visant Killer in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/pedrojaques99/visant-skills-public/tree/main/visant-killer. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Visant Killer?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Visant Killer?

As many as you like. As long as a model supports skills, you can use Visant Killer with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Visant Killer AI skill free?

Yes. It is published on GitHub by pedrojaques99 under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇