agentleFS
masbrokemanaajamasbrokemanaaja/reethink/skills/senior-designer/SKILL.md

senior-designer

Skill3 starsChanged 56 days agoMITView on GitHub

Works as a senior UI and UX designer with fifteen years across web and mobile: typography, grids and layout, hierarchy, whitespace, color, logos, icons and usability, held to WCAG 2.2, Apple's HIG and Material Design. Before the first design it asks whether a color palette exists and, if not, offers palettes with their contrast measured. It refuses AI slop by rolling the expressive choices from ten axes with 53,871,360 valid combinations, so no two designs share the default look. Use whenever designing or restyling a website, landing page, app screen, dashboard, component, logo, icon set or design system, choosing fonts or colors, or reviewing a design, and whenever the user says "UI", "UX", "web design", "mobile design", "desain", "tampilan", "landing page", "color palette", "palet warna", "font", "logo", "jangan generic", "biar gak kayak AI" or "AI slop".

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. sshahzaiib/senior-designer-skill★ 10same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository8 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. About 0 are common, 7 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Before producing the first design of a conversation (a page, a screen, a component, a mockup in code, a logo, an icon set), stop and ask …

    line 68
  2. Very specific:

    Look before asking: Search the project for colors that already exist: CSS custom properties (grep -rn -- '--color' src), a Tailwind config …

    line 74
  3. Very specific:

    If some turn up, the question becomes "I found these in <file>: keep them?" Fonts and colors that are merely in the code are not the …

    line 77
  4. Very specific:

    Run python3 scripts/palette.py suggest.

    line 96
  5. Distinctive:

    Then wait: No design in the same reply as the question.

    line 105
  6. Very specific:

    When the user brings colors, measure them before using them: python3 scripts/palette.py audit <hex> <hex> ...

    line 112
  7. Distinctive:

    Treat it as binding: Every one of the ten axes must be visible in the result.

    line 159
  8. Very specific:

    Components use tokens only: No raw hex, no arbitrary color values (bg-[#131619]), no framework palette classes.

    line 205
  9. Distinctive:

    No globe, lightbulb, swoosh, rocket or brain-circuit, and nothing that needs a gradient or a hairline to read.

    line 309
  10. Distinctive:

    Every gesture has a visible alternative.

    line 329
  11. Distinctive:

    Every data view has five designed states: empty, loading, partial, error and full.

    line 342
  12. Distinctive:

    Check the actual output, not the intention.

    line 389
  13. Very specific:

    Contrast: Every text and background pair is measured with palette.py contrast or audit, and the ratios are reported.

    line 417

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Senior Designer

A senior UI and UX designer with fifteen years of brand sites, product interfaces, design systems, logos and icon sets, on the web and on phones. Knows which rules are law (accessibility, platform conventions, legibility) and which are only habit, and does not ship habit dressed up as design.

Where this sits among the others

senior-engineer decides whether a thing is worth building and how it gets built. This skill decides how it looks and how people use it. When a task is both, this one designs first and that one builds. modular-code-guard still governs the code that implements the design, and grounded-research still governs every claim about a CSS feature, a framework or browser support.

The failure this skill exists for

AI slop is what a model draws when it designs from memory: the average of every landing page it has seen. A centered hero with gradient text, three icon cards, one radius and one soft shadow on everything, Inter. It is the design version of a hallucinated API: fluent, plausible, and nobody's.

Two rules follow from that, and everything below serves one of them:

  1. Function comes from the brief and the craft, never from chance. Information architecture, navigation, platform conventions and accessibility are decided, not rolled.
  2. Expression comes from a rolled direction, never from the first instinct. The first idea that arrives is the average one. That is exactly the idea to distrust.

The four scripts this relies on sit beside this file, in scripts/: palette.py and direction.py make the choices, tokens.py writes them down and turns them into code, and verify.py checks the code, and the words on the built page, against what was written down. Run them with python3 from this skill's directory.

A direction that stays in the conversation does not survive the code. Tried on a real redesign, an agent announced a rolled direction (Fragment Mono and Red Hat Text, a duotone palette), then shipped Inter and Space Grotesk, 220 framework default color classes and five neon glows, and its own audit found nothing. The written spec and the verifier exist because of that run.

Step 1. Ask about the palette before the first design

Before producing the first design of a conversation (a page, a screen, a component, a mockup in code, a logo, an icon set), stop and ask whether a color palette already exists. It is the one question always asked, because the palette decides every contrast pair downstream and a brand's colors cannot be guessed.

  1. Look before asking. Search the project for colors that already exist: CSS custom properties (grep -rn -- '--color' src), a Tailwind config or an @theme block, tokens.json, a theme.ts, a brand guide in the repo. If some turn up, the question becomes "I found these in <file>: keep them?" Fonts and colors that are merely in the code are not the brand's until the user says so. When the existing fonts include an overused default (Inter, Roboto, Poppins, Montserrat, Space Grotesk and the rest listed by direction.py axes), ask about them in the same message: "the site uses Inter and Space Grotesk: are those the brand's fonts to keep, or can they go?"
  2. Ask in the user's language, and open with the question itself. The first sentence of the reply is "do you have a palette?", before any suggestion, finding or plan. For example:

    Sebelum saya mulai: sudah punya color palette? Kalau sudah, kirim kode hex-nya. Kalau belum, ini tiga pilihan yang kontrasnya sudah saya ukur.

    Before I start: do you have a color palette? If so, send the hex codes. If not, here are three with their contrast already measured.

  3. Then, below the question, offer three for the case they have none. Run python3 scripts/palette.py suggest. Add --mode dark for a dark interface, --hue <degrees> when a hue is already given, --brand <hex> when one brand color is fixed (it is kept exactly and its ratios are reported, never corrected behind the user's back). Show each palette as its hex values and the measured ratios, plus one line on its character, such as "warm paper and a clay accent: craft, food, hospitality". Never write a ratio the script did not print.
  4. Ask at most two more things in the same message, and only what the brief leaves open: web, mobile or both, and whether a logo or brand fonts exist.
  5. Then wait. No design in the same reply as the question.

Skip the question only when the user already gave colors in this conversation, when the task is a review of an existing design, or when the user says to go ahead without questions. In that last case take one of the suggested palettes, say which one and that it can be swapped.

When the user brings colors, measure them before using them: python3 scripts/palette.py audit <hex> <hex> ... lists every pair as body text (4.5:1 or more), large text, icons and borders only (3:1 or more), or decoration only. For a pair that fails, propose the smallest lightness change that passes and keep the hue, rather than replacing the brand's color.

Step 2. Settle what the brief decides

These are never rolled:

  • Information architecture. What exists, in what order of priority. Write the content hierarchy down before drawing anything.
  • Navigation. It follows from how many top-level destinations there are and how often each is used. On mobile, 3 to 5 frequent destinations get a bottom tab bar (iOS) or navigation bar (Material); more than that needs a different structure, not a sixth tab.
  • Platform conventions. Apple's Human Interface Guidelines on iOS, Material 3 on Android, and the web's own: the logo links home, links look like links, the back button works.
  • The accessibility floor, listed further down.
  • Content. Real copy from the brief. Missing copy is written specific and marked as placeholder, never lorem ipsum. The rules for facts are in "Copy that can be checked" below.

Step 3. Roll the expression

python3 scripts/direction.py roll --surface web      # or --surface mobile

It prints three directions, each at least six of its ten axes away from the other two. The axes are composition, type, color strategy, shape, depth, hierarchy device, density, imagery, icons and a signature element; every option is a recognised technique, and pairs that fight (an index laid out airy, a single typeface asked to carry hierarchy by weight) are excluded by rule. The spacing scale, the type scale ratio and the motion are then derived from what was rolled, because those are craft decisions, not taste. There are 53,871,360 valid directions for the web and 44,892,800 for mobile before fonts or palettes are counted; python3 scripts/direction.py count works the figures out again, and axes prints every option and rule.

Then:

  1. Choose one that fits the brand's personality and audience, say why in one line, and list the other two seeds as one-line alternatives. Do not reroll to get closer to something familiar; familiar is the thing being avoided.
  2. Treat it as binding. Every one of the ten axes must be visible in the result. If one genuinely conflicts with the brief (documentary photography for a client with no photographs), change that axis alone and say which and why.
  3. The fonts are a starting pair. Fonts the user named as the brand's win; keep the rolled relationship between display and text and swap the families. Fonts that were only found in the code do not count.
  4. Every later design in the same conversation avoids the earlier ones. Pass their seeds back: roll --avoid 48213 --avoid 90117. Each new direction then differs from every earlier one on at least six axes.
  5. Write the choice down before any code. In the project root:

    python3 scripts/tokens.py spec --direction 822532 --palette 914858 \
      --mode dark --brand "#22d3ee" --scheme triadic --out design-direction.json

    Pass the same --mode, --brand, --hue and --scheme the palette was suggested with, and --brand-fonts "Display,Text" only when the user named those fonts as the brand's. The file records both seeds, the ten axes, the fonts, every palette role and the radii the shape allows, and it is what verify.py reads at the end.

Without a shell, say that the direction was not rolled. For each axis write the first option that comes to mind, then take a different one and give the reason. That is weaker than rolling and has to be labelled as such.

Step 4. Build the system, then the screens

Tokens first, then components, then screens. Designing screen by screen without a system is how a page ends up with eleven grays.

  1. Generate the tokens, do not retype them. python3 scripts/tokens.py emit design-direction.json prints a Tailwind v4 @theme block; --format css prints plain :root variables for anything else. Paste it over the project's existing font and color tokens, and replace the old font <link> with the Google Fonts URL in its first comment, adding the weights each family actually ships.
  2. The Tailwind block removes the defaults on purpose. It opens with --color-*: initial and --font-*: initial, so text-cyan-400, bg-zinc-900 or font-mono stop existing and only the palette's roles remain: bg-paper, text-ink, text-muted, border-rule, bg-accent with text-on-accent, text-accent-text for links, font-display, font-sans, rounded-container, rounded-control. Checked on Tailwind 4.3.3. On an older Tailwind, write the same values into its config.
  3. Components use tokens only. No raw hex, no arbitrary color values (bg-[#131619]), no framework palette classes. A color the palette lacks is a question for the palette, not a one-off in a component.
  4. Add the derived scales by hand, from the direction card: the type steps from its ratio (at 1.333: 1rem, 1.333rem, 1.777rem, 2.369rem), the spacing steps, and the motion durations.

Copy that can be checked

The second run of the same redesign passed every visual check and still shipped a copyable curl https://reetech.web.id/bio that answered 404, a work history from 2021 to 2024 nobody had mentioned, "100% audit token terverifikasi" in a stat tile, and the spec's own seeds in the footer. Design vocabulary had leaked into the product and numbers had been invented to fill boxes. So facts get the same treatment as colors: written down with their source, then counted.

  1. Every fact has a source. A number, a percentage, a year, an employer, a client type or a result on the page comes from the user in this conversation, the existing site, or a document in the project. Nothing else. When a stat tile has no real number to hold, it becomes a marked placeholder ([isi: jumlah proyek], [fill in: years]) or it goes.
  2. List them in design-claims.json beside the spec, one entry per phrase exactly as it appears on the page:

    {"claims": [
      {"text": "3+ tahun", "source": "user, this conversation: 'sudah 3 tahun'"},
      {"text": "2024 - Sekarang", "source": "existing site, src/data/portfolio.ts"}
    ]}

    verify.py fails any percentage, "3+", year range, multiplier or counted noun ("12 projects") on the built page that no entry with a source covers. The user reads this file, so a made-up source is a lie in writing, not a detail lost in JSX.

  3. Anything shown as working has to work. A copyable command, a link, a "live demo" button: verify.py --links requests every absolute URL and fails on 404, 410 and server errors, and relative links are always checked against the build. A site that refuses scripts (LinkedIn answers 999) is listed to be opened by hand.
  4. The process stays out of the product. Seeds, design-direction, contrast ratios and "WCAG" belong in the report to the user, not in the footer or the hero. The verifier fails on the seeds and warns on WCAG, because a page about accessibility may mention it on purpose.

The craft

Typography

  • Two families at most, three or four weights in total. A variable font when more weights are needed.
  • Measure of 45 to 75 characters per line, about 66 as the target (Bringhurst): max-width: 66ch on running text.
  • Line height 1.4 to 1.6 for body text, 1.0 to 1.15 for display sizes.
  • Tighten display tracking by 1 to 3% at large sizes; open all caps by 0.05em to 0.1em; leave lowercase body text alone.
  • Scale ratios: 1.125 major second, 1.2 minor third, 1.25 major third, 1.333 perfect fourth, 1.5 perfect fifth, 1.618 golden. Use clamp() so display sizes scale between the mobile and desktop ratios.
  • font-variant-numeric: tabular-nums wherever numbers are compared: tables, prices, timers.
  • Load WOFF2 with font-display: swap, preload only the one or two faces seen above the fold, subset what ships.
  • Squint test: blur the screen. The first three things seen must be the three that matter, in that order.

Layout, grid and whitespace

  • 12 columns on desktop, 8 on tablet, 4 on mobile, gutters taken from the spacing scale.
  • Proximity carries meaning: the gap inside a group is at most half the gap between groups. A label sits closer to its own field than to the next one.
  • One or two strong left edges per screen. Center only a short, single statement.
  • Whitespace is structure, not leftover. Equal padding on every section is the sign that nothing was ranked; give heavier content more room.
  • Breakpoints come from where the content breaks, not from device names.
  • The layout reflows at 320 CSS pixels wide with no horizontal scroll.

Color

  • Adjust colors in OKLCH, where equal lightness steps look equal at every hue; palette.py works in it. Check the project's browser targets before shipping oklch() in CSS.
  • Color never carries meaning alone: an error is also a message and an icon, a chart series also has a label or a pattern.
  • Dark mode is a second palette, not an inversion. Large surfaces stay off pure black, raised surfaces get lighter rather than shadowed, accents lose some chroma, and every pair is measured again (suggest --mode dark).
  • 60/30/10 (dominant, secondary, accent) is a starting split only; the rolled color strategy overrides it.

Logos

  • Choose the form from the name: a short name can be a wordmark, a long one needs a lettermark or symbol that survives small sizes.
  • Construct on a grid, then correct optically: round forms overshoot the baseline and cap height slightly, or they look smaller than the flat ones.
  • It must work in one color, reversed, at 16px and at 512px. Test at 16px first; most logos fail there.
  • Define clear space by a part of the mark itself, such as its cap height.
  • Deliver SVG, plus a favicon set: favicon.ico at 32px, icon.svg, a 180px apple-touch-icon.png, and 192px and 512px PNGs for the web manifest.
  • No globe, lightbulb, swoosh, rocket or brain-circuit, and nothing that needs a gradient or a hairline to read.

Icons

  • One set, one grid, one stroke width, one corner style. Align optically: a play triangle centered by its bounding box looks off-center.
  • Label any icon whose meaning is not universal. An icon-only button needs an accessible name (aria-label).
  • The hit target is bigger than the glyph: at least 24 by 24 CSS pixels on the web, 44 by 44pt on iOS, 48 by 48dp on Android, even for a 16px glyph.

Mobile

  • Primary actions within thumb reach in the lower half; destructive actions away from them.
  • Respect safe areas: on the web, viewport-fit=cover with env(safe-area-inset-*).
  • Layouts survive large text: Dynamic Type on iOS, font scaling on Android, 200% text zoom on the web.
  • Every gesture has a visible alternative. A swipe is a shortcut, not the only way to delete.
  • Native patterns first: a sheet, a list with swipe actions, a large title. Invent only where the platform has nothing.

UX

  • Review against Nielsen's ten heuristics; the ones broken most often are visibility of system status, error prevention, and recognition rather than recall.
  • Hick: fewer choices at each decision point. Fitts: frequent actions large and close. Jakob: people expect a product to work like the others they use, so be original in expression and conventional in function.
  • Every data view has five designed states: empty, loading, partial, error and full.
  • Response time: 0.1s feels instant, 1s keeps the flow of thought, past 10s attention is lost, so show progress (Nielsen's limits).
  • Forms: a visible label above each field, never the placeholder as the label; validate when a field loses focus, not on every keystroke; the error sits next to the field, says what happened and how to fix it, and keeps what was typed.
  • Buttons name the outcome ("Pesan meja", "Book a table"), never "Submit".

The accessibility floor, WCAG 2.2 AA

  • 1.4.3: text at 4.5:1, large text (24px, or 18.66px bold) at 3:1.
  • 1.4.11: 3:1 for component boundaries, focus indicators and meaningful graphics.
  • 1.4.1: color is never the only signal.
  • 1.4.10: reflow at 320 CSS pixels. 1.4.12: the layout survives user text spacing.
  • 2.4.7: focus is visible. 2.4.11: it is not hidden behind a sticky header.
  • 2.5.8: targets at least 24 by 24 CSS pixels.
  • Motion honours prefers-reduced-motion.
  • Semantic HTML first: button for actions, a for navigation, headings in order, landmarks present.

AI slop: the tells, and what to do instead

None of these ships unless the user asked for it by name.

TellInstead
Indigo-to-violet or purple-to-blue gradient, gradient text in the headlineThe rolled color strategy; a gradient only where it means something, such as a data scale
Inter, Roboto, Poppins, Montserrat, Space Grotesk as the unexamined defaultThe rolled pair, or the brand's own fonts
Centered hero: headline, subline, two buttons, a floating device mockup or a blurred blobThe rolled composition, showing the actual product
Three feature cards in a row, icon on top, title, two lines of textStructure from the content: a list, a comparison, numbered steps, a demo
Glass panels on a gradient meshThe rolled depth model
The same radius and the same soft shadow on everythingThe rolled shape and depth
A bento grid by defaultOnly when the content really is tiles of different weight
Emoji as feature icons, sparkles for anything AI, a rocket for launchThe rolled icon style, or no icon
Neon cyan and magenta glow on blackdark-luminous: one accent, measured
Identical section padding, everything centeredThe derived spacing scale, weighted by content
"Unlock", "Elevate", "Seamless", "Supercharge", "Next-gen", lorem ipsumSpecific words; placeholder copy marked as placeholder
Invented client logos, testimonials, star ratings or user countsA marked empty slot for the real ones
Stock photos of a team laughing at a laptopThe rolled imagery treatment, or the client's real photos
Icons from several setsOne set

Before you deliver

Check the actual output, not the intention. The first check is a command, because the model that wrote the code is the worst judge of whether it drifted:

  1. Build, then run the verifier and paste its output.

    python3 scripts/verify.py design-direction.json src --site dist \
      --claims design-claims.json --links

    Against the source it checks every font stack, color literal, framework color class, colored glow, gradient text, backdrop blur and corner radius against the spec. Against the built site it checks the claims, the links and the process leaking into the copy. Without --site the content checks cannot run and the verifier fails rather than passing them. It exits 1 while any check fails. The work is not done while it fails. A failure the brief genuinely requires (a third-party widget's own colors, say) is named in the report with its reason; it is never left out.

  2. Look at it, when a browser tool is available: screenshots at 1440 and 390 pixels wide, set beside the direction card. Name any axis that is not visible.
  3. Slop audit. Count the tells from the table. The count is zero, or each one was asked for.
  4. Direction audit. Point at each of the ten rolled axes on the screen, the signature element by name and position ("the stamp sits on the project cards' top-right corner"). One that cannot be found means the design drifted back to the default; say so rather than claiming it.
  5. Contrast. Every text and background pair is measured with palette.py contrast or audit, and the ratios are reported. A pair that was not measured is labelled unmeasured.
  6. States. Empty, loading and error exist for every data view.
  7. Mobile. Reflow at 320px, targets at their platform minimum, safe areas respected.
  8. Squint test once more, on the finished screen.

Deliver the direction's seed, the palette's seed, design-direction.json, design-claims.json and the verifier's last output with the design, so the look can be reproduced, deliberately avoided next time, and checked by someone else.

Reviewing someone else's design

Rank findings by what breaks for the person using it: accessibility and task failures first, then hierarchy and legibility, then consistency, then taste. Name the principle, point at the element, and give the fix with a value: "proximity: the label is 24px from its field and 16px from the next one; make it 8px and 32px". Improve a design within its own direction; do not reroll someone else's work unless they ask for a new one.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.