Skip to content

design.contrast

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.

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.

  • query
  • behaviorally_verified
  • module design
  • #design
  • #ui
  • #accessibility
  • #introspection

Exposure

Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.

surfaceas
MCPtool majordomus_design_contrast
HTTPGET /api/v1/design/contrast operationId design.contrast
command line

Schemas

The canonical input and output, from the Rust types; the MCP tool schema and the OpenAPI parameters and responses are derived from these.

input · Empty

No input.

No properties: the capability takes no input.

JSON Schema
{
  "additionalProperties": false,
  "description": "No input.",
  "title": "Empty",
  "type": "object"
}

output · ContrastReport

Every pair the declaration and its consumers state, measured.

propertytyperequireddescription
composed integer yes Declarations skipped because their value is composed at run time.
findings array yes One line per enforced pair that falls short, naming role, ground, theme, measured ratio and required ratio.
fingerprint string yes The fingerprint of the declaration measured.
measured integer yes How many pairs were derived and measured.
minimum_non_text number yes The ratio asked of a non-text element that carries meaning.
minimum_text number yes The ratio asked of text.
pairs array yes Every pair, in a stable order: theme, then what it carries, then the two tokens.
readable boolean yes Whether every enforced pair reaches its threshold.
sources array yes The stylesheets read, and whether each was found.
standard string yes The standard the thresholds come from.
JSON Schema
{
  "$defs": {
    "Carries": {
      "description": "What a colour is doing where it was found.",
      "oneOf": [
        {
          "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.",
          "type": "string"
        }
      ]
    },
    "Measured": {
      "description": "One measured pair: a foreground on a ground, in one theme.",
      "properties": {
        "carries": {
          "$ref": "#/$defs/Carries",
          "description": "Text, or a border."
        },
        "enforced": {
          "description": "Whether falling short is a finding. False for a border; see the module documentation.",
          "type": "boolean"
        },
        "foreground": {
          "description": "The foreground token, as the declaration names it (`muted`, `ok`).",
          "type": "string"
        },
        "foreground_entry": {
          "description": "The palette entry it resolves to in this theme.",
          "type": "string"
        },
        "foreground_value": {
          "description": "The literal that entry holds.",
          "type": "string"
        },
        "ground": {
          "description": "The ground token.",
          "type": "string"
        },
        "ground_entry": {
          "description": "The palette entry the ground resolves to in this theme.",
          "type": "string"
        },
        "ground_value": {
          "description": "The literal that entry holds.",
          "type": "string"
        },
        "passes": {
          "description": "Whether it reaches it.",
          "type": "boolean"
        },
        "ratio": {
          "description": "The measured ratio, to two decimal places.",
          "format": "double",
          "type": "number"
        },
        "required": {
          "description": "What the standard asks of this pair.",
          "format": "double",
          "type": "number"
        },
        "seen": {
          "description": "Where the pair was read: the stylesheet and the selector that states it.",
          "type": "string"
        },
        "theme": {
          "description": "`light` or `dark`.",
          "type": "string"
        }
      },
      "required": [
        "foreground",
        "foreground_entry",
        "foreground_value",
        "ground",
        "ground_entry",
        "ground_value",
        "theme",
        "carries",
        "ratio",
        "required",
        "passes",
        "enforced",
        "seen"
      ],
      "type": "object"
    },
    "Source": {
      "description": "One stylesheet the pair set was derived from.",
      "properties": {
        "path": {
          "description": "Where it was read from, as the caller named it.",
          "type": "string"
        },
        "rules": {
          "description": "How many rules of it state a colour.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "path",
        "rules"
      ],
      "type": "object"
    }
  },
  "description": "Every pair the declaration and its consumers state, measured.",
  "properties": {
    "composed": {
      "description": "Declarations skipped because their value is composed at run time.",
      "format": "uint",
      "minimum": 0,
      "type": "integer"
    },
    "findings": {
      "description": "One line per enforced pair that falls short, naming role, ground, theme, measured\nratio and required ratio.",
      "items": {
        "type": "string"
      },
      "type": "array"
    },
    "fingerprint": {
      "description": "The fingerprint of the declaration measured.",
      "type": "string"
    },
    "measured": {
      "description": "How many pairs were derived and measured.",
      "format": "uint",
      "minimum": 0,
      "type": "integer"
    },
    "minimum_non_text": {
      "description": "The ratio asked of a non-text element that carries meaning.",
      "format": "double",
      "type": "number"
    },
    "minimum_text": {
      "description": "The ratio asked of text.",
      "format": "double",
      "type": "number"
    },
    "pairs": {
      "description": "Every pair, in a stable order: theme, then what it carries, then the two tokens.",
      "items": {
        "$ref": "#/$defs/Measured"
      },
      "type": "array"
    },
    "readable": {
      "description": "Whether every enforced pair reaches its threshold.",
      "type": "boolean"
    },
    "sources": {
      "description": "The stylesheets read, and whether each was found.",
      "items": {
        "$ref": "#/$defs/Source"
      },
      "type": "array"
    },
    "standard": {
      "description": "The standard the thresholds come from.",
      "type": "string"
    }
  },
  "required": [
    "fingerprint",
    "standard",
    "minimum_text",
    "minimum_non_text",
    "sources",
    "measured",
    "pairs",
    "composed",
    "findings",
    "readable"
  ],
  "title": "ContrastReport",
  "type": "object"
}

Policies

benchmark
required — a target on every transport the exposure declares; the cases are the input type's
cache
disabled — every call runs the handler

Benchmark targets

Derived from the registry for this repository: one requirement per transport, and the cases the input type provides. The whole matrix is on the benchmarks page.

transportstatecasestargets
directcovered1default
mcpcovered1default
httpcovered1default