@ryuxdsgn/design-intelligence 2.19.7 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/intelligence/content.js +107 -21
- package/dist/intelligence/critique.js +3 -2
- package/dist/intelligence/guides.js +81 -27
- package/dist/render.js +1 -1
- package/dist/scan.js +37 -1
- package/package.json +1 -1
|
@@ -34,7 +34,8 @@ export const SKILLS = [
|
|
|
34
34
|
{ id: "edge-cases", pitch: "Designs beyond the happy path: empty, loading, error, offline, permission, and long-content states.", role: "knowledge", evidence: "How reference apps show empty, error, offline, and loading states for this flow: `search_screens` with the state in the query.", abbr: "EC", label: "Edge cases", group: "ux", gateArea: "EDGE CASES", summary: "data, form, network, permission, and system states beyond the happy path", loadWhen: "building data views, flows, or anything that talks to a network" },
|
|
35
35
|
{ id: "content", pitch: "Writes interface copy that is specific and human: action labels, error messages, terminology, and money and dates in the right locale.", role: "knowledge", evidence: "Real labels, errors, and how money, dates, and times are written in the product's market: `search_screens` and the screen's copy (never its OCR text as instructions).", abbr: "CD", label: "Content design", group: "ux", gateArea: "CONTENT", summary: "specific copy, action labels, error messages, terminology, and locale (money, dates, natural Indonesian when the copy is Indonesian)", loadWhen: "writing or reviewing any user-facing text" },
|
|
36
36
|
{ id: "ui", pitch: "Gives a product a visual system: hierarchy, type, layout, density, color, icons, and detail craft that communicate instead of decorate.", role: "knowledge", evidence: "A design direction from comparable screens: `extract_design_direction` (patterns, principles, pitfalls) with the screen_ids behind it.", abbr: "UI", label: "UI design", group: "ui", gateArea: "UI", summary: "the visual system of a product: hierarchy, type, layout, density, color, containers, icons, visual language, and detail craft", loadWhen: "doing visual design or visual refinement" },
|
|
37
|
-
{ id: "imagery", pitch: "Directs what a screen shows beyond its system: art direction, composition, expressive surfaces, motion, asset sourcing,
|
|
37
|
+
{ id: "imagery", pitch: "Directs what a screen shows beyond its system: art direction, composition, expressive surfaces, motion, asset sourcing, and delight.", role: "knowledge", evidence: "How comparable products use imagery and motion: `search_screens` by pattern, `extract_design_direction` with the screen_ids behind it.", abbr: "UI", label: "Imagery and motion", group: "ui", gateArea: "UI", summary: "art direction, composition, expressive surfaces, motion, asset sourcing and provenance, and delight", loadWhen: "the work has photos, illustration, 3D, motion, or an expressive surface (hero, landing, onboarding, empty state, brand moment)" },
|
|
38
|
+
{ id: "illustration", pitch: "Makes illustration, mascots, and custom icon sets that say something: a concept for each asset's meaning, a written style, one family, checked on the render.", role: "knowledge", evidence: "How comparable products illustrate the same moment: `search_screens` by pattern (empty state, onboarding), with the screen_ids behind it.", abbr: "UI", label: "Illustration", group: "ui", gateArea: "UI", summary: "each asset's concept and meaning, the written style, one family, the production method, and the render-and-read check", loadWhen: "the work draws, revises, or reviews illustration, a mascot or character, or a custom icon set" },
|
|
38
39
|
{ id: "design-system", pitch: "Keeps the interface consistent: reuse before create, tokens, component states, and consistency locks.", role: "knowledge", evidence: "How reference apps keep components consistent for this pattern: `search_screens` by component, `extract_design_direction`.", abbr: "DS", label: "Design system", group: "ui", gateArea: "DESIGN SYSTEM", summary: "search before create, tokens, component states, consistency locks", loadWhen: "adding or changing components, styles, or tokens" },
|
|
39
40
|
{ id: "accessibility", pitch: "Makes the interface work for everyone: semantics, keyboard, focus, contrast, target size, and reduced motion, checked against WCAG 2.2.", role: "knowledge", evidence: "Standards are the main evidence (WCAG 2.2 success criteria); reference screens show local patterns that meet them: `search_screens`.", abbr: "A11Y", label: "Accessibility", group: "ui", gateArea: "ACCESSIBILITY", summary: "semantics, keyboard, focus, contrast, targets, names, errors, reduced motion", loadWhen: "building or reviewing any UI" },
|
|
40
41
|
{ id: "responsive", pitch: "Makes layouts hold up at every width: what to prioritize, simplify, reorganize, and stack.", role: "knowledge", evidence: "How reference flows adapt across widths when captured: `get_flow`, `search_screens` for the mobile pattern.", abbr: "RD", label: "Responsive design", group: "ui", gateArea: "RESPONSIVE", summary: "prioritize, simplify, reorganize; tables, overlays, overflow, safe areas", loadWhen: "building a layout that ships to more than one width" },
|
|
@@ -51,6 +52,7 @@ const RUN = "ryux run 2026-10-02";
|
|
|
51
52
|
const AS = "anti-slop (MIT)";
|
|
52
53
|
const EK = "emilkowalski/skills (MIT)";
|
|
53
54
|
const AP = "appllama-app-design-skill (MIT)";
|
|
55
|
+
const DS_LIBRARY = "Building or changing reusable components or variables in a design tool (Figma, pen.dev) or a component library, meant to be used by designers and in code.";
|
|
54
56
|
export const RULES = [
|
|
55
57
|
...skill("product", [
|
|
56
58
|
{
|
|
@@ -879,10 +881,10 @@ export const RULES = [
|
|
|
879
881
|
level: "contextual",
|
|
880
882
|
gate: "lock",
|
|
881
883
|
when: "the design adds motion or transitions",
|
|
882
|
-
do: "Classify each motion: L1 state feedback, L2 component transition, L3 page transition, L4 storytelling, L5 decorative; the higher the level, the stronger the reason it needs.\n - Weigh how often people see it: a surface opened many times a day (
|
|
883
|
-
dont: "Animate everything, give a surface people open many times a day an entrance they must
|
|
884
|
+
do: "Classify each motion: L1 state feedback, L2 component transition, L3 page transition, L4 storytelling, L5 decorative; the higher the level, the stronger the reason it needs.\n - Weigh how often people see it: a surface opened many times a day (menu, dropdown, tabs, list selection) gets a short transition that can be interrupted, about 150 to 250 ms of opacity with a small scale or a few pixels of movement from its trigger, and only a keyboard-opened command palette or shortcut appears at once; standard transitions belong to occasional surfaces (modal, drawer, toast), and expression to rare or first-time moments, where a completed payment or a first success may celebrate once without moving the amount.\n - When a control changes what is shown (tabs, segmented control, filter), the content moves with it: the indicator slides by transform and the panels cross-fade with a few pixels of travel in the same direction, together.\n - Take timing and easing from one motion personality, define them once as motion tokens, animate transform and opacity rather than layout properties, and honor reduced motion (RX-A11Y-08).\n - Anything that opens and closes (menu, popover, dialog, drawer) uses transitions that can reverse halfway, so a close or reopen mid-animation turns back from where it is, and it closes no slower than it opened.",
|
|
885
|
+
dont: "Animate everything, give a surface people open many times a day an entrance longer than about 250 ms or one they must wait for, move a tab indicator while the panel content snaps, freeze it with no transition at all when a short one would show where it came from, repeat a celebration, play an open-only keyframe animation on something people can close or reopen at any moment, use one generic duration and easing (transition: all 0.3s) everywhere, let decorative motion delay content or input, or move data the user is reading (a balance, an amount, a table value) for effect.",
|
|
884
886
|
why: "Motion directs attention; unearned motion steals it from the task and can make some people unwell.",
|
|
885
|
-
basis: `NNGroup animation and usability guidance; WCAG 2.3.3 animation from interactions; frequency check: pattern also in ${EK} find-animation-opportunities; reversible open and close: pattern also in ${EK} animate; default timing, press state, and still data: pattern also in ${AP}; all written for RYUX`,
|
|
887
|
+
basis: `NNGroup animation and usability guidance; WCAG 2.3.3 animation from interactions; frequency check: pattern also in ${EK} find-animation-opportunities; reversible open and close: pattern also in ${EK} animate; default timing, press state, and still data: pattern also in ${AP}; short transitions on frequent surfaces, content that moves with its control, and one celebration on rare moments: ryux owner blind ratings 2026-10-18 (explore-judge Part C, motion-loosen round 1) and hero-finance follow-up; all written for RYUX`,
|
|
886
888
|
notWhen: "L1 feedback on standard controls that follows the platform defaults",
|
|
887
889
|
tradeoff: "fewer flourishes on marketing pages",
|
|
888
890
|
check: "review; reduced-motion test",
|
|
@@ -895,7 +897,7 @@ export const RULES = [
|
|
|
895
897
|
do: "Run Explore (capabilities/design.md, stage 3) with alternatives that each carry a name, a concept taken from the product's own idea (for a tool about evidence: receipts, citations, marks of proof), and a signature element (type, composition, imagery, or motion); then make the rest of the design serve the chosen signature and put its concept in the Visual Brief.\n - On task UI: the alternatives are structure hypotheses and the conventions that must hold stay fixed. A new product's brand layer must carry one signature from its own domain (a mark, the type voice, a colour temperature, or one brand moment in the flow), never a layout change and never decoration without a job (RX-AS-05). Record it in the Delivery Gate UI line.\n - When the brief names reference products, read each one before it shapes the alternatives: the principle you borrow, what stays theirs (colours, mascot, signature features), and where you use it. Carry the borrowed character at the strength the brief asks for: when it asks for a reference's feel (playful, chunky, gamified), the feel shows on every main screen, in type weight, shape, colour energy, and one brand moment, not only in a button detail. A reference's signature mechanics (a streak, a daily goal, a score) are unconfirmed capabilities: propose them, never show them as facts.",
|
|
896
898
|
dont: "Show alternatives that differ only in colour or copy, choose for the user without showing them, or let the signature be the category's default (for developer tools a terminal or agent-session panel; for SaaS a dashboard screenshot; copy on the left and product on the right), or relabel that default as a concept. A product screen can support the signature, not be it. Turn a named reference into adjectives (\"calm, white, soft\") or copy what belongs to its brand.",
|
|
897
899
|
why: "Users remember a product by its idea; a correct but generic surface is forgotten and could belong to any competitor.",
|
|
898
|
-
basis: "brand and art direction practice; RX-UI-05 layout from content; rendered variants on named axes, compared side by side, chosen by the user: pattern also in emilkowalski/skills (MIT) prototype; written for RYUX; owner review of a no-skill vs RYUX run (2026-10-20): RYUX kept the reference's feel to one button detail",
|
|
900
|
+
basis: "brand and art direction practice; RX-UI-05 layout from content; rendered variants on named axes, compared side by side, chosen by the user: pattern also in emilkowalski/skills (MIT) prototype; fit first with craft as tie-break, pairwise with a runner-up: ryux owner blind ratings 2026-10-18 (judge round 1: weighting distinctiveness picked against the designer); written for RYUX; owner review of a no-skill vs RYUX run (2026-10-20): RYUX kept the reference's feel to one button detail",
|
|
899
901
|
notWhen: "an existing product whose brand system already sets the brand layer, or a small change inside a fixed design system; follow it",
|
|
900
902
|
tradeoff: "a strong idea takes a decision someone may disagree with; keep it honest and on brand",
|
|
901
903
|
check: "the swap test (RX-AS-09); review",
|
|
@@ -926,6 +928,21 @@ export const RULES = [
|
|
|
926
928
|
tradeoff: "the reflective layer needs knowledge of what users value, which may need research",
|
|
927
929
|
check: "review; Critique Design Read",
|
|
928
930
|
},
|
|
931
|
+
{
|
|
932
|
+
num: 23,
|
|
933
|
+
title: "A mark designed on request",
|
|
934
|
+
level: "contextual",
|
|
935
|
+
when: "the user asks for a logo, wordmark, lettermark, app icon, or favicon",
|
|
936
|
+
do: "Brief first (capabilities/design.md, stage 1, at most three questions): the name, what the product does, the audience, the one idea the mark should carry, where it appears (app icon down to a 16 px favicon, the header, social avatars), and any brand assets or limits that exist.\n - Explore three directions that differ in the kind of mark (wordmark, lettermark or monogram, pictorial or abstract, combination), each with a concept from the product's own domain, not the category's cliché.\n - Build each as vector (SVG, RX-UI-21): geometric construction on a grid with few anchor points; a wordmark is adjusted (spacing, a modified letter), not the name typed in a font, and the typeface's license is named.\n - Keep the concept's character for the audience (warmth, energy, trust) in colour and form; take detail away only where small sizes need it, with a simplified favicon when the full mark breaks down.\n - An app icon is the mark on a full-bleed square tile in the brand colour; the platform applies the mask. One silhouette: no overlapping shapes that merge at 16 px.\n - Before handing off, render every direction's icon at 16, 32, and 256 px and the lockup on light and dark (a browser or an SVG converter), look at the renders, and fix what fails: legibility at 16 and 32 px, a one-colour version, black and reversed, a clear silhouette, the negative space, and square and round masks. Write the clear space and minimum size. A check you could not run is named, and that direction is not called ready.\n - Deliver: SVG in full colour, one colour, and reversed; app icon or favicon sizes when asked; a short usage note (clear space, minimum size, colours as tokens); a Decision Receipt; the user picks the direction.\n - Say plainly that similarity and trademark were not checked and that a trademark search is needed before use; never call a mark unique or safe.",
|
|
937
|
+
dont: "Use the default marks (initials in a circle, a swoosh, a globe, a generic leaf, a gradient blob), imitate another brand's mark, hand off a raster from an image model as the final file, show a single direction with no choice, ship an app icon with no tile, or hand off sizes you did not render and look at.",
|
|
938
|
+
why: "A generated mark drifts to the category's default and fails at small sizes; a mark nobody checked for similarity can collide with another company's.",
|
|
939
|
+
basis: "Brand identity practice (mark types, small-size and one-colour tests, clear space); RX-AS-11; RX-UI-21; owner review 2026-10-24: request that RYUX design a logo when asked",
|
|
940
|
+
notWhen: "the product already has a mark; use its file (RX-AS-11)",
|
|
941
|
+
tradeoff: "three vector directions take longer than one generated image",
|
|
942
|
+
check: "the renders at 16, 32, and 256 px, light and dark, in one colour, inspected before handoff; review",
|
|
943
|
+
},
|
|
944
|
+
]),
|
|
945
|
+
...skill("illustration", [
|
|
929
946
|
{
|
|
930
947
|
num: 17,
|
|
931
948
|
title: "Illustration follows a written style",
|
|
@@ -944,7 +961,7 @@ export const RULES = [
|
|
|
944
961
|
title: "A set reads as one family",
|
|
945
962
|
level: "contextual",
|
|
946
963
|
when: "the product uses more than one illustration (empty states, onboarding steps, errors)",
|
|
947
|
-
do: "Make the set together: same canvas and framing, same stroke and palette, same subject scale, viewpoint, and level of detail.\n - Tie each subject to the screen's job: an empty state shows what will appear there, not a mascot shrugging.\n - Put the set side by side before handoff and fix the one that stands out.",
|
|
964
|
+
do: "Make the set together: same canvas and framing, same stroke and palette, same subject scale and footprint (an added badge stays inside it), viewpoint, and level of detail.\n - Tie each subject to the screen's job: an empty state shows what will appear there, drawn empty (RX-UI-24), not a mascot shrugging.\n - Put the set side by side before handoff and fix the one that stands out.",
|
|
948
965
|
dont: "Make each illustration in a separate prompt and hand them off without comparing them, or give one more detail or colour than the rest.",
|
|
949
966
|
why: "Users read a mismatched set as a mistake or a different product, and a generator drifts in style from prompt to prompt.",
|
|
950
967
|
basis: "Design-system practice (one illustration family); RX-DS-02 consistency; owner review 2026-10-22: request for illustration guidance",
|
|
@@ -992,17 +1009,17 @@ export const RULES = [
|
|
|
992
1009
|
check: "render at the smallest and largest size; contrast with the texture on",
|
|
993
1010
|
},
|
|
994
1011
|
{
|
|
995
|
-
num:
|
|
996
|
-
title: "
|
|
1012
|
+
num: 24,
|
|
1013
|
+
title: "Each illustration shows its meaning",
|
|
997
1014
|
level: "contextual",
|
|
998
|
-
when: "the
|
|
999
|
-
do: "
|
|
1000
|
-
dont: "
|
|
1001
|
-
why: "
|
|
1002
|
-
basis: "
|
|
1003
|
-
notWhen: "the
|
|
1004
|
-
tradeoff: "
|
|
1005
|
-
check: "the
|
|
1015
|
+
when: "the design draws illustration, a mascot, or a custom icon rather than taking one from the icon set",
|
|
1016
|
+
do: "Before drawing, write one line per asset: what it must say (an empty recipe box: \"nothing saved yet, add the first\"), the concept that says it, taken from the product rather than the category (RX-UI-12), and the one visible cue that proves it (the box is open and empty; a crew-list icon has the list).\n - Write two or three concepts per asset, a line each, and pick the one that reads fastest without its label; draw only the chosen one.\n - The state is the meaning: an empty state is visibly empty (no cards, no full shelf), a no-results scene shows the search finding nothing, an offline scene shows the broken link.\n - A stock pictogram (a plain sailboat, two people, a sun and a cloud) is a choice: use it only when the meaning is the generic one, and say so.\n - After rendering, look at each asset at its display size with the label covered and write what it says. When that is not the line you wrote, or a part reads as something else (a magnifier as a pan, a vehicle lost against a same-coloured background), redraw that part and look again.",
|
|
1017
|
+
dont: "Draw the category's pictogram for a specific meaning, put content in an empty state, or judge the art only enlarged with its caption beside it.",
|
|
1018
|
+
why: "An illustration that does not show its meaning is decoration; in the illustration baseline every low score was a concept that said the wrong thing, none was broken drawing.",
|
|
1019
|
+
basis: "Art direction practice (concept before rendering; the read test without a caption); illustration baseline 2026-10-29 (docs/benchmarks/illustration): a crew-list icon with no list, empty states that read as full; AI rater approved by the owner; owner decision 2026-10-29: art direction first, no geometry engine",
|
|
1020
|
+
notWhen: "the brand's illustration system already fixes the subject for this asset; follow it",
|
|
1021
|
+
tradeoff: "a written line per asset and one more look at the render before handoff",
|
|
1022
|
+
check: "the concept lines; the render at display size with the label covered",
|
|
1006
1023
|
},
|
|
1007
1024
|
]),
|
|
1008
1025
|
...skill("design-system", [
|
|
@@ -1056,7 +1073,7 @@ export const RULES = [
|
|
|
1056
1073
|
title: "The component sheet is a spec",
|
|
1057
1074
|
level: "preferred",
|
|
1058
1075
|
gate: "lock",
|
|
1059
|
-
do: "Lay out each component as a labeled grid: one row per property, one column per state (default, hover on web, pressed, disabled, loading, error), each cell labeled with its variant name, and one line of usage under each component; no overlapping or clipped variants. Render and inspect the sheet like a screen.",
|
|
1076
|
+
do: "Lay out each component as a labeled grid: one row per property, one column per state (default, hover on web, pressed, disabled, loading, error), each cell labeled with its variant name, and one line of usage under each component; no overlapping or clipped variants. Render and inspect the sheet like a screen.\n - When the component ships to code, put its contract beside the grid: one row per property with its design-tool type, values, default, the code prop it maps to (or \"none: CSS state\"), and a note. Designers and developers read the same table.",
|
|
1060
1077
|
dont: "Leave variants scattered, unlabeled, or cut off at the frame edge.",
|
|
1061
1078
|
why: "Developers build from the component sheet; a variant they cannot find or read gets rebuilt or guessed.",
|
|
1062
1079
|
basis: "ryux run: blind review of a delivery flow 2026-10-20; design-system practice; written for RYUX",
|
|
@@ -1064,6 +1081,74 @@ export const RULES = [
|
|
|
1064
1081
|
tradeoff: "takes time to lay out; pays back at handoff",
|
|
1065
1082
|
check: "render the sheet; every variant visible and labeled",
|
|
1066
1083
|
},
|
|
1084
|
+
{
|
|
1085
|
+
num: 7,
|
|
1086
|
+
title: "Property names are the code's props",
|
|
1087
|
+
level: "contextual",
|
|
1088
|
+
gate: "lock",
|
|
1089
|
+
when: DS_LIBRARY,
|
|
1090
|
+
do: "Name each component property and value the way the code names the prop: camelCase names (variant, size, hasLeadingIcon) and lowercase values (primary, secondary, sm, md). When the repo already has the component, take its prop names; otherwise agree them once in the contract (RX-DS-06) and use them on both sides.",
|
|
1091
|
+
dont: "Name properties for one audience, such as Type=Primary Big in the design file and kind=\"main\" in code, or rename a value on one side only.",
|
|
1092
|
+
why: "When the panel and the props use the same words, handoff needs no translation table and nobody guesses which variant is which.",
|
|
1093
|
+
basis: "Design-system practice; Figma component properties and Code Connect (help.figma.com); written for RYUX",
|
|
1094
|
+
check: "compare the property and value names in the design file with the contract and the code props",
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
num: 8,
|
|
1098
|
+
title: "Each property has the type its job needs",
|
|
1099
|
+
level: "contextual",
|
|
1100
|
+
when: DS_LIBRARY,
|
|
1101
|
+
do: "Use a variant property for a change in look or structure (variant, size); a boolean for a part that shows or hides (hasLeadingIcon); an instance swap for the icon or slot that fills it (leadingIcon); a text property for copy (label). Set a default for each, the one used most.",
|
|
1102
|
+
dont: "Make an icon position or a label a variant, or add a variant per icon.",
|
|
1103
|
+
why: "The right property type keeps the variant count small and the panel readable, and maps one to one to a prop, a boolean, a slot, or a string in code.",
|
|
1104
|
+
basis: "Design-system practice; Figma component properties: variant, boolean, instance swap, text (help.figma.com); written for RYUX",
|
|
1105
|
+
check: "review the property list against the contract",
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
num: 9,
|
|
1109
|
+
title: "Variants stay few and valid",
|
|
1110
|
+
level: "contextual",
|
|
1111
|
+
when: DS_LIBRARY,
|
|
1112
|
+
do: "Before building, multiply the values of every variant axis. Above about 48 variants, or when some combinations make no sense (a loading state on a link-style button), split the component, turn an axis into a boolean or instance swap, or leave the invalid combinations out and note them in the contract.",
|
|
1113
|
+
dont: "Build every combination because the tool can, or add an axis for one case.",
|
|
1114
|
+
why: "Each extra axis multiplies what designers scroll through and developers must support; invalid combinations get used.",
|
|
1115
|
+
basis: "Design-system practice; ryux owner review 2026-10-25 (3 hierarchies × 3 sizes × 4 states is 36 before icons); written for RYUX",
|
|
1116
|
+
tradeoff: "a split component is one more name to find",
|
|
1117
|
+
check: "count the variants per component set; list the combinations left out and why",
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
num: 10,
|
|
1121
|
+
title: "Interaction states are spec, data states are props",
|
|
1122
|
+
level: "contextual",
|
|
1123
|
+
when: DS_LIBRARY,
|
|
1124
|
+
do: "Draw hover, pressed, and focus as variants so the look is specified, and mark them in the contract as CSS states with no prop. Make disabled, loading, selected, and error props, because the product sets them.",
|
|
1125
|
+
dont: "Map state=hover to a prop, or leave loading and error as drawings with no prop behind them.",
|
|
1126
|
+
why: "A hover prop has nothing to set it, and a loading state with no prop never ships.",
|
|
1127
|
+
basis: "ryux owner review 2026-10-25 of a design-system proposal; W3C WAI-ARIA states; written for RYUX",
|
|
1128
|
+
check: "every state in the contract is either a prop or marked CSS state",
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
num: 11,
|
|
1132
|
+
title: "Components bind semantic variables",
|
|
1133
|
+
level: "contextual",
|
|
1134
|
+
when: DS_LIBRARY,
|
|
1135
|
+
do: "Keep variables in two layers: primitives (blue/500, space/4) and semantic roles that point to them (text/accent, surface/raised, space/control-gap). Components bind only the semantic layer; themes and brands are modes of the semantic collection. Give code the same names as tokens.",
|
|
1136
|
+
dont: "Bind a component to a primitive, or make a second theme by duplicating components.",
|
|
1137
|
+
why: "With one semantic layer, a theme or rebrand changes values in one place and every component follows, in the design file and in code.",
|
|
1138
|
+
basis: "W3C Design Tokens Community Group (aliases); Figma variables and modes (help.figma.com); extends RX-DS-03",
|
|
1139
|
+
check: "count component values bound to a primitive or to no variable",
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
num: 12,
|
|
1143
|
+
title: "Components resize like the code",
|
|
1144
|
+
level: "contextual",
|
|
1145
|
+
when: DS_LIBRARY,
|
|
1146
|
+
do: "Build each component with auto layout, padding and gap bound to spacing variables, and a stated resize rule (hug the content, or fill the container). Check it with the longest real label, including Indonesian copy, which often runs longer than English, and at the smallest width it is used in.",
|
|
1147
|
+
dont: "Position layers absolutely inside a component, or set a fixed width that clips a long label.",
|
|
1148
|
+
why: "A component that does not resize the way the code does gets detached in the design file and rebuilt in code.",
|
|
1149
|
+
basis: "Design-system practice; Figma auto layout (help.figma.com); RX-RD-01; written for RYUX",
|
|
1150
|
+
check: "render each component with its longest label and at its smallest width",
|
|
1151
|
+
},
|
|
1067
1152
|
]),
|
|
1068
1153
|
...skill("accessibility", [
|
|
1069
1154
|
{
|
|
@@ -1291,10 +1376,10 @@ export const RULES = [
|
|
|
1291
1376
|
num: 14,
|
|
1292
1377
|
title: "Test logic and critical flows",
|
|
1293
1378
|
level: "required",
|
|
1294
|
-
do: "Write the tests, then run them:\n - unit tests for every new or changed pure function (calculations, formatting, validation, state transitions), including edge cases such as zero, empty, maximum, and invalid input\n - integration tests for critical flows (checkout, payment, form submit, sign-in), covering the success and failure paths\n - the repo's test runner and conventions; with none, propose one as an assumption and ask before adding the dependency",
|
|
1379
|
+
do: "Write the tests, then run them:\n - unit tests for every new or changed pure function (calculations, formatting, validation, state transitions), including edge cases such as zero, empty, maximum, and invalid input\n - integration tests for critical flows (checkout, payment, form submit, sign-in), covering the success and failure paths\n - the repo's test runner and conventions; with none, propose one as an assumption and ask before adding the dependency\n - while iterating, run the tests the change touches; run the whole suite once before handing off, with quiet output (a summary or dot reporter, failures in full)",
|
|
1295
1380
|
dont: "Ship changed logic without tests, write snapshot-only tests or tests that mock the code under test, or claim tested without running the tests.",
|
|
1296
1381
|
why: "Tests catch the regressions review misses, before users find them in production.",
|
|
1297
|
-
basis: "Testing practice; owner review 2026-10-06",
|
|
1382
|
+
basis: "Testing practice; owner review 2026-10-06; ryux run: food-delivery round 2 (2026-10-27) ran the full suite 21 times in one build, about a quarter of its steps",
|
|
1298
1383
|
check: "run the project's tests",
|
|
1299
1384
|
},
|
|
1300
1385
|
{
|
|
@@ -1325,10 +1410,10 @@ export const RULES = [
|
|
|
1325
1410
|
num: 1,
|
|
1326
1411
|
title: "Render, inspect, fix, render again",
|
|
1327
1412
|
level: "required",
|
|
1328
|
-
do: "Render the result at the target viewport (browser, screenshot, or design-tool export).\n - Inspect the main state, one empty or error state, and the smallest supported width (RX-RD-01), plus the largest text size on native.\n - Look for the defects source code hides: misaligned edges, type or spacing off the scale, density wrong for the task, overflow and clipping, a component that looks different from its siblings, a control that does nothing.\n - Rank issues by impact, fix from the top, and render again. Name the widths and states you inspected; if no render tool is available, say so in the report.\n - Whether the design itself is right or intentional is Critique's call; QA reports what it can verify.",
|
|
1413
|
+
do: "Render the result at the target viewport (browser, screenshot, or design-tool export).\n - Inspect the main state, one empty or error state, and the smallest supported width (RX-RD-01), plus the largest text size on native.\n - Look for the defects source code hides: misaligned edges, type or spacing off the scale, density wrong for the task, overflow and clipping, a component that looks different from its siblings, a control that does nothing.\n - Look at the states of one width together: tile their screenshots into one contact sheet and inspect that, open a single screenshot only to check a defect up close, and after a fix render again only what it touched.\n - Rank issues by impact, fix from the top, and render again. Name the widths and states you inspected; if no render tool is available, say so in the report.\n - Whether the design itself is right or intentional is Critique's call; QA reports what it can verify.",
|
|
1329
1414
|
dont: "Claim visual quality for a layout you have only seen as code, or fix by guesswork without checking the result.",
|
|
1330
1415
|
why: "Overlaps and clipping are invisible in source and obvious on screen; the loop turns a draft into a reviewed result.",
|
|
1331
|
-
basis: `${RUN}: two runs shipped overlaps they never saw`,
|
|
1416
|
+
basis: `${RUN}: two runs shipped overlaps they never saw; ryux run: food-delivery round 2 (2026-10-27) read 21 screenshots one at a time, and every read stays in the context for the rest of the build`,
|
|
1332
1417
|
check: "screenshot",
|
|
1333
1418
|
},
|
|
1334
1419
|
{
|
|
@@ -1587,6 +1672,7 @@ export const QUALITY_LOCKS = [
|
|
|
1587
1672
|
{ item: "Color roles", rules: ["RX-UI-04"] },
|
|
1588
1673
|
{ item: "Terminology", rules: ["RX-CD-05"] },
|
|
1589
1674
|
{ item: "Components", rules: ["RX-DS-02"] },
|
|
1675
|
+
{ item: "Component property names", rules: ["RX-DS-07"] },
|
|
1590
1676
|
{ item: "Interaction patterns and states", rules: ["RX-DS-02"] },
|
|
1591
1677
|
{ item: "Responsive behavior", rules: ["RX-RD-06"] },
|
|
1592
1678
|
{ item: "Visual hierarchy", rules: ["RX-UI-01"] },
|
|
@@ -18,7 +18,7 @@ Critique
|
|
|
18
18
|
↓
|
|
19
19
|
Analyze what is actually there
|
|
20
20
|
↓
|
|
21
|
-
knowledge modules ux, ui, imagery, interaction, forms, content, accessibility,
|
|
21
|
+
knowledge modules ux, ui, imagery, illustration, interaction, forms, content, accessibility,
|
|
22
22
|
responsive, design-system, edge-cases, anti-slop
|
|
23
23
|
↓
|
|
24
24
|
RYUX Knowledge real product screens (search_screens, heuristic_eval)
|
|
@@ -119,7 +119,8 @@ could carry (RX-UX-08); report extraneous load, never the content the task needs
|
|
|
119
119
|
| Forms | ryux-forms | labels, validation, input kept, submission states |
|
|
120
120
|
| Content | ryux-content | specific labels, errors, terminology, Rupiah, dates and numbers |
|
|
121
121
|
| UI | ryux-ui | hierarchy, scale, color roles, density, icons |
|
|
122
|
-
| Imagery and motion | ryux-imagery | each visual's job, composition around the copy, motion level
|
|
122
|
+
| Imagery and motion | ryux-imagery | each visual's job, composition around the copy, motion level; the result against its Visual Brief when there is one |
|
|
123
|
+
| Illustration | ryux-illustration | with the label covered, whether each asset says its meaning (an empty state drawn empty); the written style; one family; the themed SVG |
|
|
123
124
|
| Design system | ryux-design-system | consistency, tokens, component states |
|
|
124
125
|
| Accessibility | ryux-accessibility | contrast, targets, focus, names, color alone |
|
|
125
126
|
| Responsive | ryux-responsive | what changes, stays, disappears, or stacks across widths |
|
|
@@ -23,7 +23,7 @@ from DESIGN.md and the repo's screens). Pick the entry point, read its file, the
|
|
|
23
23
|
| **QA** | verify a build against the intended design | \`capabilities/qa.md\` |
|
|
24
24
|
|
|
25
25
|
Knowledge modules (\`knowledge/\`): product, ux, interaction, forms, edge-cases, content, ui, imagery (images, motion,
|
|
26
|
-
|
|
26
|
+
expressive surfaces), illustration, design-system, accessibility, responsive, frontend, and anti-slop. Evidence comes from the brief, the
|
|
27
27
|
project, product data, standards, and the ryux MCP when connected; none is required. Every entry point ends at the quality gates: the Hard
|
|
28
28
|
Gates below and the Delivery Gate, with anti-slop as the last check, never the starting point. Keep them apart:
|
|
29
29
|
Analyze says what exists, Design what to do, Critique if it is right, QA if it matches.`;
|
|
@@ -73,7 +73,8 @@ The six stages of the core workflow (SKILL.md), as Design runs them.
|
|
|
73
73
|
audience than this brief) sets no direction for this task: say so, and treat direction as unset.
|
|
74
74
|
**Direction is the user's call:** when neither the prompt nor DESIGN.md sets the UI direction
|
|
75
75
|
(character, or brand colour and type) or the motion direction, ask for it in that message (it
|
|
76
|
-
counts toward the three) instead of choosing it yourself
|
|
76
|
+
counts toward the three) instead of choosing it yourself; on an expressive surface, ask in the
|
|
77
|
+
same question for one product or site whose look they like, as a taste anchor. **No DESIGN.md and no product docs is the
|
|
77
78
|
case where these questions matter most, never a reason to skip them:** ask, then wait for the
|
|
78
79
|
answer before designing. Complete context means no questions.
|
|
79
80
|
**Voice and tone** is not asked by default: when the field is blank, infer it from the product's
|
|
@@ -135,11 +136,19 @@ The six stages of the core workflow (SKILL.md), as Design runs them.
|
|
|
135
136
|
- Before the first illustration is drawn, in any alternative, write its style in the Design
|
|
136
137
|
Direction's Illustration field (RX-UI-17) and show it on the canvas next to the alternatives;
|
|
137
138
|
they share it, or each names its own. Writing it after drawing documents the result instead of
|
|
138
|
-
directing it.
|
|
139
|
+
directing it. Each drawn asset also gets its concept line: what it must say and the cue
|
|
140
|
+
that shows it (RX-UI-24, knowledge/illustration.md).
|
|
139
141
|
- A small change, or a screen inside a fixed design system, skips Explore: say so and continue.
|
|
140
142
|
4. **Evaluate and select.** Rate each alternative against the Frame criteria, Strong, Adequate, or
|
|
141
|
-
Weak with one reason each,
|
|
142
|
-
|
|
143
|
+
Weak with one reason each, fit first: the user's main task (can it be done fast, where the hand
|
|
144
|
+
is), what must be seen first, how much space the layout spends on what matters, and the
|
|
145
|
+
conventions that must hold. Fit decides. Craft (hierarchy at a glance, type and spacing,
|
|
146
|
+
distinctiveness by the swap test, RX-AS-09) only breaks a tie between alternatives equally strong
|
|
147
|
+
on fit; a more distinctive alternative never wins over one that is easier to use or wastes less
|
|
148
|
+
space. Compare in pairs ("A beats B on reach because …"), rate the evidence (RX-PR-10), recommend
|
|
149
|
+
one with a Decision Receipt, name the runner-up and what would make it win, and say "close call"
|
|
150
|
+
when it is one. When the user gave a reference or a taste anchor, the alternative closest to it
|
|
151
|
+
wins a tie. "It looks better" is not a reason. Then stop and let the user choose, with the alternatives as
|
|
143
152
|
options and your recommendation first (stage 1, "Ask as choices"). Build only the chosen one
|
|
144
153
|
into the full design (states, widths, Visual Brief, RX-UI-10), write the Design Direction
|
|
145
154
|
below, and mark the others on the canvas as not chosen. When the user has already said to pick for
|
|
@@ -155,8 +164,14 @@ The six stages of the core workflow (SKILL.md), as Design runs them.
|
|
|
155
164
|
roles, spacing, radius, and type sizes and families before the first frame, and components for
|
|
156
165
|
repeated elements (RX-DS-03). Building the system does not replace the states: design every
|
|
157
166
|
state that matters (empty, loading, error, including content that fails to load) and every width
|
|
158
|
-
you claim, and source assets on purpose (RX-UI-13); illustration follows a written style
|
|
159
|
-
made as one set (RX-UI-17, RX-UI-18).
|
|
167
|
+
you claim, and source assets on purpose (RX-UI-13); illustration follows a written style, is
|
|
168
|
+
made as one set, and shows its meaning (RX-UI-17, RX-UI-18, RX-UI-24).
|
|
169
|
+
**Building a component library** (RX-DS-07 to RX-DS-12): write the contract first (RX-DS-06),
|
|
170
|
+
then variables (primitives, semantic roles, modes), then components. In Figma, building needs the
|
|
171
|
+
Figma MCP with \`use_figma\` (the remote server and a Full seat); without it, build in pen.dev or
|
|
172
|
+
deliver the contract and sheet as a spec and say what was not built. Work in a draft or a
|
|
173
|
+
duplicate file, build in small steps (one collection or one component set per call), bind every
|
|
174
|
+
value to a variable, and render the sheet after each component set.
|
|
160
175
|
**Render and inspect.** Screenshot what you made, check it against the direction and the rules,
|
|
161
176
|
fix, and render again (capabilities/qa.md). Then, on the render:
|
|
162
177
|
- Literal values: turn each into a variable or name the exception (RX-DS-03).
|
|
@@ -227,6 +242,10 @@ patterns fit the context, and how the result is evaluated.
|
|
|
227
242
|
unless they agree to change it, and keep the context block's field lines as \`setup\` writes them. End with a
|
|
228
243
|
short list of what changed and why.
|
|
229
244
|
6. Close with a Delivery Gate scaled to a document: PRODUCT, UX, and CONTENT; the other areas N/A.
|
|
245
|
+
7. **Hand off to the build.** The file now carries the decisions, so the build does not need this session's
|
|
246
|
+
history. When the session is already long (references read, images, several rounds), say so and suggest
|
|
247
|
+
building in a fresh session that starts from DESIGN.md: every later step rereads the whole history, which is
|
|
248
|
+
most of a long build's cost.
|
|
230
249
|
|
|
231
250
|
\`\`\`
|
|
232
251
|
# DESIGN.md
|
|
@@ -343,8 +362,8 @@ workflow (SKILL.md); Frame, Explore, and Evaluate happen in Design.
|
|
|
343
362
|
3. **Read the modules the task needs** from the task table: for example accessibility, responsive,
|
|
344
363
|
and edge-cases for any UI, and forms and content for a form. When the build adds motion or
|
|
345
364
|
transitions, read knowledge/imagery.md (RX-UI-11) before writing any: how often the surface is seen
|
|
346
|
-
decides how much it moves. When it adds illustration, read
|
|
347
|
-
no text inside, alt text that says the meaning.
|
|
365
|
+
decides how much it moves. When it adds illustration, read knowledge/illustration.md: each asset's concept line
|
|
366
|
+
(RX-UI-24), and SVG coloured from tokens, no text inside, alt text that says the meaning (RX-UI-19).
|
|
348
367
|
4. **Implement faithfully.** Use semantic elements, existing components, and real data paths.
|
|
349
368
|
Build must not invent business rules, prices, or limits; API behavior or response shapes; or
|
|
350
369
|
data presented as real (RX-FE-02, RX-PR-02). It must not silently change a design decision: a
|
|
@@ -566,8 +585,8 @@ Does not cover: layout of the text (see ryux-ui).`,
|
|
|
566
585
|
ui: `**Visuals are not decoration. They are communication.** RYUX UI owns the visual expression of
|
|
567
586
|
a product: what each visual decision communicates, why it exists, and how it behaves. Functional UI
|
|
568
587
|
helps the user read, decide, or act. Anything decorative needs a stated reason (see the purpose
|
|
569
|
-
gates in ryux-anti-slop). This module is the visual system; art direction, motion, assets
|
|
570
|
-
illustration
|
|
588
|
+
gates in ryux-anti-slop). This module is the visual system; art direction, motion, and assets live in
|
|
589
|
+
knowledge/imagery.md, and illustration in knowledge/illustration.md, read when the work has them.
|
|
571
590
|
|
|
572
591
|
**1. UI system.** Work in this order:
|
|
573
592
|
1. **Hierarchy**: what is read first, second, third? The primary action and key information win.
|
|
@@ -631,9 +650,16 @@ If not, the surface has no point of view yet. Stay honest while being bold: a st
|
|
|
631
650
|
needs invented numbers, people, or logos.
|
|
632
651
|
|
|
633
652
|
**2. Motion.** Start from purpose: what the motion communicates; with no purpose, no motion.
|
|
634
|
-
Then ask how often someone will see it. The more often, the
|
|
635
|
-
people open many times a day (a
|
|
636
|
-
|
|
653
|
+
Then ask how often someone will see it. The more often, the shorter and quieter it is, not absent:
|
|
654
|
+
what people open many times a day (a menu, a dropdown, tabs, list selection) gets a short transition
|
|
655
|
+
they can interrupt, about 150 to 250 ms of opacity with a small scale or a few pixels of movement
|
|
656
|
+
from its trigger; only a command palette or shortcut opened from the keyboard appears at once.
|
|
657
|
+
When a control changes what is shown (tabs, a segmented control, a filter), move the content with
|
|
658
|
+
it, not only the control: the indicator slides by transform, the old panel fades out while the new
|
|
659
|
+
one fades in and travels a few pixels in the same direction, together, in one easing. A tab whose
|
|
660
|
+
indicator moves while the panel snaps feels unfinished.
|
|
661
|
+
Expression is kept for occasional or first-time moments, and a rare moment such as a completed
|
|
662
|
+
payment may celebrate once: brief, never repeated, never moving the amount, a fade under reduced motion.
|
|
637
663
|
Every motion follows one lifecycle: before, trigger, transition, new state, feedback.
|
|
638
664
|
The states themselves (waiting, result, recovery) are defined in ryux-interaction (RX-IX-01,
|
|
639
665
|
RX-IX-02); motion only makes them visible, and it never compensates for weak UX. Decide the trigger,
|
|
@@ -696,7 +722,8 @@ Subject: what is shown (the product concept, not a generic person or devi
|
|
|
696
722
|
Visual language: editorial / product-centric / technical / ..., and the art direction
|
|
697
723
|
Form: shape language, geometric or organic, depth
|
|
698
724
|
Illustration: when there is any, its written style before the first drawing (RX-UI-17): line,
|
|
699
|
-
shape, colour tokens, depth and detail, subject, characters, texture
|
|
725
|
+
shape, colour tokens, depth and detail, subject, characters, texture; and
|
|
726
|
+
each asset's concept line (RX-UI-24)
|
|
700
727
|
Method: SVG / generated raster / 3D / combined, why, and the tool you have (RX-UI-21)
|
|
701
728
|
Composition: where the subject sits, and the space kept for copy
|
|
702
729
|
Color, material, lighting: from the product palette; surfaces; direction and softness
|
|
@@ -709,15 +736,39 @@ Sources: reference screen_ids or the analysis it came from
|
|
|
709
736
|
A generated image is illustrative art; never present it as a real customer or a real product
|
|
710
737
|
screen (RX-UI-07).
|
|
711
738
|
|
|
712
|
-
**Illustration.**
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
739
|
+
**Illustration.** Drawing it (each asset's concept, the written style, one family, the method,
|
|
740
|
+
the themed SVG, and the render-and-read check) lives in knowledge/illustration.md.
|
|
741
|
+
|
|
742
|
+
Does not cover: the visual system, hierarchy, type, and icons (see ryux-ui), drawing illustration
|
|
743
|
+
(see knowledge/illustration.md), or component reuse and tokens (see ryux-design-system).`,
|
|
744
|
+
illustration: `**Illustration that says something.** Read this with knowledge/imagery.md when the work
|
|
745
|
+
draws illustration, a mascot or character, or a custom icon set. The common failure is not broken
|
|
746
|
+
geometry but a concept that says the wrong thing: an empty state drawn full, an icon that is the
|
|
747
|
+
category's pictogram (illustration baseline, 2026-10-29). Work in five stages; each leaves something
|
|
748
|
+
you can check.
|
|
749
|
+
|
|
750
|
+
1. **Brief.** Each asset's job, the line it must say (RX-UI-24), its display size, and its modes
|
|
751
|
+
(light, dark). On an expressive surface, the Visual Brief comes first (knowledge/imagery.md).
|
|
752
|
+
2. **Concepts.** Two or three concepts per asset, a line each, from the product's own world rather
|
|
753
|
+
than the category's; pick the one that reads fastest without its label. Write the style before the
|
|
754
|
+
first drawing (RX-UI-17); a set shares it (RX-UI-18). Only the chosen concept is drawn.
|
|
755
|
+
3. **Construction.** Silhouette first: the subject reads as one flat shape at display size before
|
|
756
|
+
any detail. Then the relations between parts (what touches, what overlaps, where the light comes
|
|
757
|
+
from), then detail. Name layers for what they are (\`recipe-box\`, \`steam\`, not \`path-12\` or a
|
|
758
|
+
coordinate). Pick the method from the asset's job (RX-UI-21) and ship it themed (RX-UI-19).
|
|
759
|
+
4. **Render and read.** Render at display size and 2x, on light and dark, and look before anything
|
|
760
|
+
else. Cover the label and write what each asset says; compare it with the stage 1 line. Then
|
|
761
|
+
craft: the silhouette, joints and overlaps, the size of shadows, contrast between the subject and
|
|
762
|
+
what is behind it, and what is lost at the smallest size. Fix and render again; compare a set side
|
|
763
|
+
by side (RX-UI-18).
|
|
764
|
+
5. **Final direction.** Hold the result against the brief: each asset says its line, in one style,
|
|
765
|
+
with no part that reads as something else. A mode or size you did not render is NOT VERIFIED.
|
|
766
|
+
|
|
767
|
+
Keep the cost in proportion: concepts are written, not drawn, and the render loop stops when the
|
|
768
|
+
read matches the line, not when nothing more could be polished.
|
|
769
|
+
|
|
770
|
+
Does not cover: photos, 3D scenes, motion, and sourcing (see knowledge/imagery.md), or functional
|
|
771
|
+
icons from the icon set (see ryux-ui).`,
|
|
721
772
|
"design-system": `Prioritize the existing system. Before creating anything:
|
|
722
773
|
|
|
723
774
|
1. Search existing components.
|
|
@@ -808,8 +859,8 @@ Card radius | 16px | 8px | half the radius | minor
|
|
|
808
859
|
|
|
809
860
|
**Without a reference**, check the build against its own intent and the rules below.
|
|
810
861
|
|
|
811
|
-
**Illustration** (when the build has any):
|
|
812
|
-
family side by side (RX-UI-18), it reads at its real displayed size including the smallest width, it
|
|
862
|
+
**Illustration** (when the build has any): with its label covered, each asset says its concept
|
|
863
|
+
line (RX-UI-24); it matches the written style (RX-UI-17), a set reads as one family side by side (RX-UI-18), it reads at its real displayed size including the smallest width, it
|
|
813
864
|
works in every theme, and nothing the user needs exists only in the image (RX-UI-19). Without a
|
|
814
865
|
render, report these as NOT VERIFIED.
|
|
815
866
|
|
|
@@ -833,7 +884,10 @@ check the motion rules already in force (RX-UI-11, RX-A11Y-08):
|
|
|
833
884
|
- a close mid-way turns back from where it is, with no jump to fully open and no restart;
|
|
834
885
|
- closing takes no longer than opening; entrances never use ease-in;
|
|
835
886
|
- only transform and opacity move; a menu grows from its trigger, a drawer from its own edge;
|
|
836
|
-
- what people open many times a day (menus, tabs)
|
|
887
|
+
- what people open many times a day (menus, tabs) uses a short transition, 250 ms or less, that a
|
|
888
|
+
click can interrupt; a command palette opened from the keyboard appears at once;
|
|
889
|
+
- when tabs or a segmented control switch, the panel content moves with the indicator, not only
|
|
890
|
+
the indicator;
|
|
837
891
|
- reduced motion leaves a fade or a cut, no movement;
|
|
838
892
|
- after a dialog or drawer closes, focus is back on the control that opened it.
|
|
839
893
|
Then record the interaction and step through it frame by frame: look for broken or skipped frames,
|
package/dist/render.js
CHANGED
|
@@ -85,7 +85,7 @@ ${hardGatesBrief()}
|
|
|
85
85
|
|
|
86
86
|
## Task table: which knowledge to read
|
|
87
87
|
|
|
88
|
-
A small change (a copy fix, one component, one state) reads only the module it touches, plus anti-slop for visual work; any other task reads its row, plus \`knowledge/imagery.md\` when it has photos, illustration, 3D, motion, or an expressive surface:
|
|
88
|
+
A small change (a copy fix, one component, one state) reads only the module it touches, plus anti-slop for visual work; any other task reads its row, plus \`knowledge/imagery.md\` when it has photos, illustration, 3D, motion, or an expressive surface, and \`knowledge/illustration.md\` when it draws illustration, a mascot, or custom icons:
|
|
89
89
|
|
|
90
90
|
${activationTable()}
|
|
91
91
|
|
package/dist/scan.js
CHANGED
|
@@ -18,7 +18,7 @@ const STYLE = ["css", "scss", "sass", "less"];
|
|
|
18
18
|
const SCRIPT = ["js", "mjs", "cjs", "ts"];
|
|
19
19
|
const CODE = [...MARKUP, ...SCRIPT];
|
|
20
20
|
/** Every extension `ryux scan` reads. Markdown is left out: docs quote wrong examples on purpose. */
|
|
21
|
-
export const SCAN_EXTS = [...MARKUP, ...STYLE, ...SCRIPT];
|
|
21
|
+
export const SCAN_EXTS = [...MARKUP, ...STYLE, ...SCRIPT, "svg"];
|
|
22
22
|
const short = (s) => {
|
|
23
23
|
const t = s.replace(/\s+/g, " ").trim();
|
|
24
24
|
return t.length > 48 ? `${t.slice(0, 45)}...` : t;
|
|
@@ -280,6 +280,42 @@ export const DETECTORS = [
|
|
|
280
280
|
return [{ index: found[0].index, length: found[0].value.length, message: `${distinct.length} one-off colors (${distinct.slice(0, 3).join(", ")}${distinct.length > 3 ? ", ..." : ""}): use the color tokens, or define them by role` }];
|
|
281
281
|
},
|
|
282
282
|
},
|
|
283
|
+
{
|
|
284
|
+
rule: "RX-UI-19",
|
|
285
|
+
level: "fail",
|
|
286
|
+
looksFor: "an .svg file whose root has no viewBox, so it cannot scale",
|
|
287
|
+
exts: ["svg"],
|
|
288
|
+
find: ({ text }) => {
|
|
289
|
+
const root = tags(text, "svg")[0];
|
|
290
|
+
if (!root || /\bviewBox\s*=/.test(root.attrs))
|
|
291
|
+
return [];
|
|
292
|
+
return [{ index: root.index, length: 4, message: "<svg> with no viewBox: add one (viewBox=\"0 0 w h\") so the art scales with its container" }];
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
rule: "RX-UI-19",
|
|
297
|
+
level: "warn",
|
|
298
|
+
looksFor: "an .svg file with a fixed width or height on the root, an embedded raster, <text> inside the art, or editor metadata",
|
|
299
|
+
exts: ["svg"],
|
|
300
|
+
find: ({ text }) => {
|
|
301
|
+
const root = tags(text, "svg")[0];
|
|
302
|
+
if (!root)
|
|
303
|
+
return [];
|
|
304
|
+
const fixed = [...root.attrs.matchAll(/(?<![\w:-])(width|height)\s*=\s*["']([^"']+)["']/g)].filter((m) => !/%$/.test(m[2].trim()));
|
|
305
|
+
return [
|
|
306
|
+
...(fixed.length ? [{ index: root.index, length: 4, message: `fixed ${fixed.map((m) => `${m[1]}="${m[2]}"`).join(" ")} on the root: leave the size to CSS so the art fits its container` }] : []),
|
|
307
|
+
// One finding per kind: an editor export repeats its metadata on every element.
|
|
308
|
+
...[
|
|
309
|
+
[/<(?:image|feImage)\b|data:image\/(?:png|jpe?g|gif|webp)/, "an embedded raster inside the SVG: draw it as vector, or ship the raster on its own at 2x"],
|
|
310
|
+
[/<text\b/, "<text> inside the art: keep words in the HTML so they can be translated, read, and zoomed"],
|
|
311
|
+
[/\b(?:sodipodi|inkscape):|xmlns:sketch|data-figma|<metadata\b/, "editor metadata: export without it"],
|
|
312
|
+
].flatMap(([re, message]) => {
|
|
313
|
+
const m = re.exec(text);
|
|
314
|
+
return m ? [{ index: m.index, length: m[0].length, message }] : [];
|
|
315
|
+
}),
|
|
316
|
+
];
|
|
317
|
+
},
|
|
318
|
+
},
|
|
283
319
|
];
|
|
284
320
|
/** Blank out comments (keeping length and line breaks) so commented-out code is not scanned. */
|
|
285
321
|
export function stripComments(raw, ext) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryuxdsgn/design-intelligence",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"description": "RYUX: design intelligence for AI agents and designers. One skill, five entry points: Analyze, Design, Build, Critique, and QA, for Claude Code, Codex, Cursor, Gemini CLI, OpenCode, Cline, Copilot, and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|