schema: ai-cjm-component-contract/v1 id: form-control version: 1.0.0 status: stable owner: AI CJM Design purpose: Собирает одно значение с явной label, instruction и feedback association. use_when: - Форма требует text input, textarea или select. evidence: - id: production-style url: https://aicjm.ru/edu/styles.css?v=20260811-edu-canon locator: .lead-form label, .lead-form input, .lead-form textarea, .lead-form input:focus, .lead-form textarea:focus, .lead-form__consent.is-invalid supports: - anatomy - variant:text - variant:textarea - size:default - state:default - state:error - id: production-dom url: https://aicjm.ru/edu/ locator: .lead-form label > input, .lead-form label > textarea and consent input supports: - approved-example - content anatomy: - id: label required: true role: Постоянная подпись. - id: control required: true role: Native input textarea или select. - id: hint required: false role: Формат или пояснение. - id: status required: false role: Связанное validation message. variants: - id: text status: stable description: Однострочное поле. evidence_refs: - production-style - id: textarea status: stable description: Многострочное поле. evidence_refs: - production-style - id: select status: candidate description: Native selection. sizes: - id: default status: stable description: Размер определяется содержимым и перечисленными semantic/component tokens; raw dimensions запрещены. evidence_refs: - production-style states: default: status: stable basis: observed description: default is observed at the exact production locator in evidence_refs. evidence_refs: - production-style hover: status: candidate basis: normative-gap description: Proposed hover contract for form-control; approval is required before production use. behavior: Apply a nonessential semantic-token cue while the pointer is over the owned interactive target. semantics: No ARIA change; hover never exposes hidden required content. token_refs: - component.input.background - component.input.text - component.input.border transition: Enter on pointer hover and return to default on pointer exit. acceptance: - hover behavior, semantics, token refs and transition pass the form-control manual state check. focus-visible: status: candidate basis: normative-gap description: Proposed focus-visible contract for form-control; approval is required before production use. behavior: Render focus.ring without changing layout or relying on hover. semantics: Keep the native element in DOM order and expose keyboard focus visibly. token_refs: - component.input.background - component.input.text - component.input.border transition: Enter for keyboard-origin focus and return to default on blur. acceptance: - focus-visible behavior, semantics, token refs and transition pass the form-control manual state check. active: status: not-applicable basis: not-applicable description: active is not owned by form-control. selected: status: not-applicable basis: not-applicable description: selected is not owned by form-control. open: status: not-applicable basis: not-applicable description: open is not owned by form-control. disabled: status: candidate basis: normative-gap description: Proposed disabled contract for form-control; approval is required before production use. behavior: Prevent activation or editing while preserving label, context and layout. semantics: Use native disabled where available; otherwise aria-disabled=true and suppress activation. token_refs: - component.input.background - component.input.text - component.input.border transition: Enter only when the action is unavailable and return to default when it becomes available. acceptance: - disabled behavior, semantics, token refs and transition pass the form-control manual state check. loading: status: not-applicable basis: not-applicable description: Loading belongs to lead-form submission, not an individual control. success: status: not-applicable basis: not-applicable description: Success message is owned by validation-status. error: status: stable basis: observed description: error is observed at the exact production locator in evidence_refs. evidence_refs: - production-style empty: status: not-applicable basis: not-applicable description: An empty value is default input content, not a component state. responsive: mode: label-control-message-stack reading_order: DOM order remains authoritative in every mode. rules: - Keep label, control, hint and validation message in one source-order stack. - Control fills its form column; label and error never move to a side rail. - Textarea may grow vertically without causing horizontal overflow. accessibility: pattern: labelled-native-form-control semantics: - Use native input/textarea/select with label, aria-describedby and aria-invalid when error is present. keyboard: - Tab enters the control; native keys edit/select; Escape does not erase entered data. focus: - Focus stays on the control; validation never steals focus during typing. motion: - Focus/error transitions use motion.duration.state or no motion under reduced motion. tokens: - component.input.background - component.input.text - component.input.border - component.input.border-focus - component.input.border-width - component.input.radius - component.input.minimum-height - component.input.padding-inline - focus.ring content: required: - Видимая label. - Конкретная hint при необходимости. constraints: - Placeholder не заменяет label. - Required обозначен текстом и semantics. do: - Связывать label/description/error по id. dont: - Не удалять outline без доступной замены. examples: approved: status: stable description: Компонент form-control в указанном scoped production locator. evidence: https://aicjm.ru/edu/ prohibited: description: Не удалять outline без доступной замены. acceptance: - id: form-control-1 criterion: Default boundary проходит 3:1. method: manual - id: form-control-2 criterion: Error объявляется screen reader и не кодируется одним цветом. method: manual