schema: ai-cjm-component-contract/v1 id: testimonial version: 1.0.0 status: stable owner: AI CJM Design purpose: Передаёт атрибутированный опыт реального человека как доказательство. use_when: - Есть точная цитата или evidence-backed paraphrase. evidence: - id: production-style url: https://aicjm.ru/edu/styles.css?v=20260811-edu-canon locator: .review-grid, .review-grid article, .review-grid blockquote, .review-grid a supports: - anatomy - variant:quote-card - size:default - state:default - id: production-dom url: https://aicjm.ru/edu/ locator: .review-grid article containing blockquote and attribution supports: - approved-example - content anatomy: - id: quote required: true role: Точный текст или помеченный paraphrase. - id: person required: true role: Имя и роль. - id: portrait required: false role: Проверенный asset. - id: source required: true role: Evidence locator. variants: - id: quote-card status: stable description: Полная цитата. evidence_refs: - production-style - id: compact status: candidate description: Короткий proof fragment. 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: not-applicable basis: not-applicable description: hover is not owned by testimonial. focus-visible: status: not-applicable basis: not-applicable description: focus-visible is not owned by testimonial. active: status: not-applicable basis: not-applicable description: active is not owned by testimonial. selected: status: not-applicable basis: not-applicable description: selected is not owned by testimonial. open: status: not-applicable basis: not-applicable description: open is not owned by testimonial. disabled: status: not-applicable basis: not-applicable description: disabled is not owned by testimonial. loading: status: not-applicable basis: not-applicable description: loading is not owned by testimonial. success: status: not-applicable basis: not-applicable description: success is not owned by testimonial. error: status: not-applicable basis: not-applicable description: error is not owned by testimonial. empty: status: not-applicable basis: not-applicable description: empty is not owned by testimonial. responsive: mode: quote-grid-to-quote-list reading_order: DOM order remains authoritative in every mode. rules: - Keep quote before attribution and source action. - Collapse the quote grid to one column before line length becomes compressed. - Do not truncate quotations to equalize card height. accessibility: pattern: attributed-blockquote semantics: - Use blockquote with visible attribution and a source/case link when available. keyboard: - The quote owns no keyboard behavior; source link uses text-link. focus: - Focus remains on the source link and never on decorative quote marks. motion: - Quote meaning does not depend on carousel or reveal motion. tokens: - surface.card - text.primary - text.secondary - border.default - type.size.lead - type.line-height.body content: required: - Цитата. - Имя. - Роль. - Источник. constraints: - Verbatim сохраняет формулировку. - Paraphrase явно не оформляется кавычками. do: - Связывать отзыв с конкретным изменением в работе. dont: - Не сочинять цитату из общего впечатления. examples: approved: status: stable description: Компонент testimonial в указанном scoped production locator. evidence: https://aicjm.ru/edu/ prohibited: description: Не сочинять цитату из общего впечатления. acceptance: - id: testimonial-1 criterion: Source locator воспроизводим. method: manual - id: testimonial-2 criterion: Атрибуция видима рядом с текстом. method: manual