{
  "meta": {
    "name": "Tiny UX Baseline",
    "version": "0.1.0",
    "ruleOrder": [
      "web-standard",
      "industry-principle",
      "tiny-default",
      "project-exception"
    ]
  },
  "sources": [
    {
      "id": "nng-heuristics",
      "title": "Nielsen Norman Group — 10 Usability Heuristics",
      "url": "https://www.nngroup.com/articles/ten-usability-heuristics/",
      "use": "用于状态可见、自然映射、用户控制、一致性、错误预防、识别优于回忆和极简设计。"
    },
    {
      "id": "wcag-22",
      "title": "W3C — Web Content Accessibility Guidelines 2.2",
      "url": "https://www.w3.org/TR/WCAG22/",
      "use": "用于焦点、键盘、目标尺寸、对比度、减少动态与替代交互。"
    },
    {
      "id": "wai-carousel",
      "title": "W3C WAI-ARIA — Carousel Pattern",
      "url": "https://www.w3.org/WAI/ARIA/apg/patterns/carousel/",
      "use": "用于自动轮播停止控制、悬停/聚焦暂停、前后切换控制和无障碍标签。"
    },
    {
      "id": "apple-motion",
      "title": "Apple Human Interface Guidelines — Motion",
      "url": "https://developer.apple.com/design/human-interface-guidelines/motion",
      "use": "用于目的明确、可预期、不妨碍任务的动效设计。"
    }
  ],
  "rules": [
    {
      "id": "UX-001",
      "level": "must",
      "layer": "industry-principle",
      "title": "状态必须被看见",
      "appliesTo": [
        "按钮",
        "提交",
        "加载",
        "轮播",
        "筛选"
      ],
      "rule": "用户动作后要在合理时间内呈现结果、进行中状态或失败原因；不能把等待伪装成无响应。",
      "why": "减少猜测，让用户知道系统正在做什么。",
      "sourceIds": [
        "nng-heuristics"
      ],
      "verify": [
        "加载、保存、切换至少有一种清晰的状态反馈",
        "失败信息用用户能理解的语言并提供下一步"
      ]
    },
    {
      "id": "UX-002",
      "level": "must",
      "layer": "industry-principle",
      "title": "方向、文案与结果必须自然对应",
      "appliesTo": [
        "轮播",
        "分页",
        "返回",
        "排序",
        "拖拽"
      ],
      "rule": "操作提示的方向、页面运动和结果必须符合用户的空间预期。右箭头的下一张对应向前的横向切换；左箭头相反。",
      "why": "保持自然映射和一致性，减少学习成本。",
      "sourceIds": [
        "nng-heuristics"
      ],
      "verify": [
        "点击右箭头，新内容从右进入、旧内容向左离开",
        "上一张使用严格相反的方向",
        "箭头、键盘和滑动的语义一致"
      ]
    },
    {
      "id": "UX-003",
      "level": "must",
      "layer": "web-standard",
      "title": "自动轮播始终让用户重新掌握控制权",
      "appliesTo": [
        "自动轮播"
      ],
      "rule": "自动轮播必须提供清楚的停止/继续控制；鼠标悬停或键盘焦点进入后暂停，不自行恢复。",
      "why": "避免内容在阅读或辅助技术使用过程中意外变化。",
      "sourceIds": [
        "wai-carousel"
      ],
      "verify": [
        "悬停暂停",
        "Tab 聚焦暂停",
        "停止后只由用户主动继续",
        "前后按钮使用原生 button 或等效语义"
      ]
    },
    {
      "id": "UX-004",
      "level": "must",
      "layer": "tiny-default",
      "title": "轮播横向连续交接，不出现空白帧",
      "appliesTo": [
        "内容轮播",
        "作品卡片",
        "瞬间卡片"
      ],
      "rule": "同组卡片保持一致的外框高度；新旧内容在同一容器内横向交叠交接，不采用先清空、后加载的切换。",
      "why": "维持阅读上下文，减少视觉暂留和页面跳动。",
      "sourceIds": [
        "nng-heuristics",
        "apple-motion"
      ],
      "verify": [
        "切换期间容器不塌陷",
        "相邻内容在切换前已预载",
        "无空白阶段",
        "减少动态时立即替换且保留状态"
      ]
    },
    {
      "id": "UX-005",
      "level": "must",
      "layer": "web-standard",
      "title": "移动端不把阅读任务塞进卡片内部滚动",
      "appliesTo": [
        "移动端卡片",
        "弹层",
        "内容轮播"
      ],
      "rule": "移动端卡片的文本区可以由统一最小高度承托，但不能依赖内部滚动才能读完核心内容。",
      "why": "避免嵌套滚动抢占手势，并确保内容可发现。",
      "sourceIds": [
        "nng-heuristics",
        "wcag-22"
      ],
      "verify": [
        "核心标题、正文和主要操作在卡片自然高度内可见",
        "同组移动卡片维持统一最低高度",
        "不出现仅为阅读而设置的 overflow-y:auto"
      ]
    },
    {
      "id": "UX-006",
      "level": "must",
      "layer": "web-standard",
      "title": "动效应帮助理解，并允许减少动态",
      "appliesTo": [
        "所有动效"
      ],
      "rule": "动效用于解释空间关系、反馈状态或增加轻量生命力；必须尊重 prefers-reduced-motion，不能阻断阅读或操作。",
      "why": "动效是反馈，不应成为负担。",
      "sourceIds": [
        "wcag-22",
        "apple-motion"
      ],
      "verify": [
        "减少动态时取消位移、连续轮播和粒子效果",
        "核心操作不等待装饰动画结束",
        "动效时间通常控制在 140–420ms"
      ]
    },
    {
      "id": "UX-007",
      "level": "must",
      "layer": "web-standard",
      "title": "键盘、焦点与触控同等成立",
      "appliesTo": [
        "链接",
        "按钮",
        "筛选",
        "轮播",
        "弹层"
      ],
      "rule": "鼠标悬停只能增强，不是理解或完成核心操作的唯一途径；可互动元素必须有清晰焦点与可点击触控区域。",
      "why": "让键盘、触控和辅助技术用户都能完成同一任务。",
      "sourceIds": [
        "wcag-22",
        "wai-carousel"
      ],
      "verify": [
        "Tab 顺序可预测",
        "焦点轮廓可见",
        "不以 hover 作为唯一入口",
        "触控目标达到可用尺寸"
      ]
    },
    {
      "id": "UX-008",
      "level": "should",
      "layer": "tiny-default",
      "title": "横向视觉素材默认使用 16:9",
      "appliesTo": [
        "作品封面",
        "瞬间配图",
        "内容横图"
      ],
      "rule": "同一轮播或同一作品列表使用统一横向画幅，默认 16:9；用 object-fit: cover 并保留安全裁切。",
      "why": "稳定不同内容下的卡片高度与浏览节奏。",
      "sourceIds": [
        "nng-heuristics"
      ],
      "verify": [
        "同一列表的图片框尺寸一致",
        "关键主体不被窄屏裁掉",
        "图片框有系统圆角"
      ]
    },
    {
      "id": "UX-009",
      "level": "should",
      "layer": "tiny-default",
      "title": "装饰不争夺任务优先级",
      "appliesTo": [
        "贴纸",
        "手绘元素",
        "鼠标效果",
        "纸张纹理"
      ],
      "rule": "装饰元素只承担温度、节奏和叙事，不遮挡文字、操作或焦点，也不承担信息传达的唯一职责。",
      "why": "Tiny 的手作感必须服务内容，而不是制造干扰。",
      "sourceIds": [
        "nng-heuristics"
      ],
      "verify": [
        "正文与按钮始终可读、可点",
        "装饰在小屏幕自动简化",
        "关闭动效后功能仍完整"
      ]
    }
  ]
}