design.contrast
Whether the declared colours can be read
What it is
Every foreground the design puts on a ground, in both themes, measured against WCAG 2.1 AA: the pair, the palette entries behind it, the ratio and the threshold. The pairs are not a list — they are derived from the declaration, which files each status's text with its own ground, and from the primitives that consume it, where a rule that sets a colour and a background states a pair and a rule that sets only a colour states a foreground that lands on every ground a container sets. A pair below the threshold is a finding that names the role, the ground, the theme, the measured ratio and the required one.
Descriptor
- Canonical id
design.contrast- Module
design- Kind
- query
- Stability
- behaviorallyverified
- Provenance
- declared
- Source
apps/majordomus-cli/src/capability/builtin/design.rs- Cache
disabled- Benchmark
required- Tags
- designuiaccessibilityintrospection
Run
queryProjections
| Interface | As | Where |
|---|---|---|
| MCP tool | majordomus_design_contrast | - |
| MCP resource | not exposed | - |
| HTTP | GET /api/v1/design/contrast | Swagger |
| Command line | not exposed | - |
Schemas
Input · Empty
{
"type": "object",
"additionalProperties": false,
"description": "No input.",
"title": "Empty"
}Output · ContrastReport
{
"type": "object",
"properties": {
"fingerprint": {
"type": "string",
"description": "The fingerprint of the declaration measured."
},
"standard": {
"type": "string",
"description": "The standard the thresholds come from."
},
"minimum_text": {
"type": "number",
"format": "double",
"description": "The ratio asked of text."
},
"minimum_non_text": {
"type": "number",
"format": "double",
"description": "The ratio asked of a non-text element that carries meaning."
},
"sources": {
"type": "array",
"items": {
"$ref": "#/$defs/Source"
},
"description": "The stylesheets read, and whether each was found."
},
"measured": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "How many pairs were derived and measured."
},
"pairs": {
"type": "array",
"items": {
"$ref": "#/$defs/Measured"
},
"description": "Every pair, in a stable order: theme, then what it carries, then the two tokens."
},
"composed": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "Declarations skipped because their value is composed at run time."
},
"findings": {
"type": "array",
"items": {
"type": "string"
},
"description": "One line per enforced pair that falls short, naming role, ground, theme, measured\nratio and required ratio."
},
"readable": {
"type": "boolean",
"description": "Whether every enforced pair reaches its threshold."
}
},
"required": [
"fingerprint",
"standard",
"minimum_text",
"minimum_non_text",
"sources",
"measured",
"pairs",
"composed",
"findings",
"readable"
],
"description": "Every pair the declaration and its consumers state, measured.",
"title": "ContrastReport",
"$defs": {
"Source": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Where it was read from, as the caller named it."
},
"rules": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "How many rules of it state a colour."
}
},
"required": [
"path",
"rules"
],
"description": "One stylesheet the pair set was derived from."
},
"Measured": {
"type": "object",
"properties": {
"foreground": {
"type": "string",
"description": "The foreground token, as the declaration names it (`muted`, `ok`)."
},
"foreground_entry": {
"type": "string",
"description": "The palette entry it resolves to in this theme."
},
"foreground_value": {
"type": "string",
"description": "The literal that entry holds."
},
"ground": {
"type": "string",
"description": "The ground token."
},
"ground_entry": {
"type": "string",
"description": "The palette entry the ground resolves to in this theme."
},
"ground_value": {
"type": "string",
"description": "The literal that entry holds."
},
"theme": {
"type": "string",
"description": "`light` or `dark`."
},
"carries": {
"$ref": "#/$defs/Carries",
"description": "Text, or a border."
},
"ratio": {
"type": "number",
"format": "double",
"description": "The measured ratio, to two decimal places."
},
"required": {
"type": "number",
"format": "double",
"description": "What the standard asks of this pair."
},
"passes": {
"type": "boolean",
"description": "Whether it reaches it."
},
"enforced": {
"type": "boolean",
"description": "Whether falling short is a finding. False for a border; see the module documentation."
},
"seen": {
"type": "string",
"description": "Where the pair was read: the stylesheet and the selector that states it."
}
},
"required": [
"foreground",
"foreground_entry",
"foreground_value",
"ground",
"ground_entry",
"ground_value",
"theme",
"carries",
"ratio",
"required",
"passes",
"enforced",
"seen"
],
"description": "One measured pair: a foreground on a ground, in one theme."
},
"Carries": {
"oneOf": [
{
"type": "string",
"const": "text",
"description": "Text: held to `MINIMUM_TEXT`."
},
{
"type": "string",
"const": "non_text",
"description": "A border or an outline: measured against `MINIMUM_NON_TEXT`, reported, not enforced."
}
],
"description": "What a colour is doing where it was found."
}
}
}Examples
These are the capability's own benchmark cases: the same inputs the benchmark runs and the OpenAPI document shows.
default
{}