@haposoft/cafekit 0.16.7 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +14 -22
  2. package/bin/__tests__/codex-hooks-ownership.test.js +2 -2
  3. package/bin/__tests__/codex-hooks.test.js +0 -36
  4. package/bin/__tests__/codex-native.test.js +46 -88
  5. package/bin/__tests__/develop-contract.test.js +26 -57
  6. package/bin/__tests__/docs-sync-on-demand.test.js +93 -0
  7. package/bin/__tests__/grok-envelope.test.js +0 -56
  8. package/bin/__tests__/hook-payload.test.js +4 -6
  9. package/bin/__tests__/legacy-authority-decoupled.test.js +159 -0
  10. package/bin/__tests__/legacy-hooks-retired.test.js +221 -0
  11. package/bin/__tests__/omp-bridge.test.js +20 -17
  12. package/bin/__tests__/omp-hooks.test.js +0 -19
  13. package/bin/__tests__/optional-skill-inventory.test.js +112 -4
  14. package/bin/__tests__/orca-session.test.js +0 -2
  15. package/bin/__tests__/package-inventory.test.js +100 -541
  16. package/bin/__tests__/runtime-dir.test.js +0 -3
  17. package/bin/__tests__/runtime-schema.test.js +3 -2
  18. package/bin/__tests__/skill-routing-source.test.js +27 -15
  19. package/bin/__tests__/spec-narrowing.test.js +0 -27
  20. package/bin/__tests__/specs-v2-execution-closeout.test.js +4 -69
  21. package/bin/__tests__/ui-ux-skill.test.js +101 -0
  22. package/bin/__tests__/usage-hook-retired.test.js +114 -0
  23. package/bin/__tests__/validator-grounding.test.js +9 -28
  24. package/bin/phases/codex-runtime.js +24 -0
  25. package/bin/phases/omp-runtime.js +22 -0
  26. package/package.json +1 -1
  27. package/src/claude/CLAUDE.md +3 -10
  28. package/src/claude/agents/brainstormer.md +7 -3
  29. package/src/claude/agents/code-auditor.md +35 -50
  30. package/src/claude/agents/debugger.md +5 -79
  31. package/src/claude/agents/deployer.md +3 -5
  32. package/src/claude/agents/docs-keeper.md +2 -7
  33. package/src/claude/agents/implementer.md +6 -9
  34. package/src/claude/agents/inspector.md +2 -3
  35. package/src/claude/agents/project-manager.md +7 -15
  36. package/src/claude/agents/researcher.md +9 -3
  37. package/src/claude/agents/spec-maker.md +11 -11
  38. package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -1
  39. package/src/claude/hooks/__tests__/spec-gate.test.js +74 -3
  40. package/src/claude/hooks/__tests__/spec-state-touched.test.js +134 -0
  41. package/src/claude/hooks/__tests__/state.test.js +68 -0
  42. package/src/claude/hooks/__tests__/statusline.test.js +140 -11
  43. package/src/claude/hooks/agent.cjs +2 -1
  44. package/src/claude/hooks/lib/context.cjs +0 -89
  45. package/src/claude/hooks/lib/hook-payload.cjs +2 -2
  46. package/src/claude/hooks/rules.cjs +2 -1
  47. package/src/claude/hooks/session.cjs +0 -1
  48. package/src/claude/hooks/spec-gate.cjs +17 -28
  49. package/src/claude/hooks/spec-state.cjs +95 -1
  50. package/src/claude/hooks/state.cjs +21 -2
  51. package/src/claude/migration-manifest.json +30 -15
  52. package/src/claude/rules/ai-dev-rules.md +1 -1
  53. package/src/claude/rules/hook-protocols.md +8 -15
  54. package/src/claude/rules/manage-docs.md +9 -23
  55. package/src/claude/rules/orchestrator.md +3 -4
  56. package/src/claude/rules/review-audit-self-decision.md +3 -3
  57. package/src/claude/rules/skill-domain-routing.md +1 -3
  58. package/src/claude/rules/skill-workflow-routing.md +4 -5
  59. package/src/claude/rules/state-sync.md +3 -12
  60. package/src/claude/rules/workflow.md +10 -18
  61. package/src/claude/runtime.schema.json +5 -3
  62. package/src/claude/scripts/generate-skill-catalog.cjs +7 -6
  63. package/src/claude/scripts/provenance.cjs +23 -5
  64. package/src/claude/scripts/spec-receipt.cjs +24 -7
  65. package/src/claude/scripts/spec-resolver.cjs +1 -2
  66. package/src/claude/scripts/validate-spec-output.cjs +5 -32
  67. package/src/claude/settings/settings.json +1 -32
  68. package/src/claude/skills/{question → ask}/SKILL.md +9 -75
  69. package/src/claude/skills/brainstorm/SKILL.md +43 -131
  70. package/src/claude/skills/code-review/SKILL.md +48 -17
  71. package/src/claude/skills/code-review/references/spec-compliance-review.md +2 -3
  72. package/src/claude/skills/code-review/references/verification-gate.md +22 -27
  73. package/src/claude/skills/debug/SKILL.md +29 -149
  74. package/src/claude/skills/develop/SKILL.md +27 -36
  75. package/src/claude/skills/develop/references/parallel-waves.md +0 -8
  76. package/src/claude/skills/develop/references/quality-gate.md +15 -13
  77. package/src/claude/skills/docs/SKILL.md +2 -2
  78. package/src/claude/skills/docs/references/update-workflow.md +1 -1
  79. package/src/claude/skills/fix/SKILL.md +153 -0
  80. package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
  81. package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
  82. package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
  83. package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
  84. package/src/claude/skills/git/SKILL.md +48 -9
  85. package/src/claude/skills/git/references/commit-protocols.md +35 -16
  86. package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
  87. package/src/claude/skills/orca/SKILL.md +9 -8
  88. package/src/claude/skills/research/SKILL.md +2 -0
  89. package/src/claude/skills/scout/SKILL.md +61 -0
  90. package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
  91. package/src/claude/skills/specs/SKILL.md +22 -29
  92. package/src/claude/skills/specs/references/review.md +8 -6
  93. package/src/claude/skills/specs/references/templates.md +34 -41
  94. package/src/claude/skills/sync/SKILL.md +8 -15
  95. package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
  96. package/src/claude/skills/sync/references/sync-protocols.md +4 -13
  97. package/src/claude/skills/test/SKILL.md +22 -3
  98. package/src/claude/skills/test/references/execution-strategy.md +83 -0
  99. package/src/claude/skills/test/references/failure-triage.md +1 -1
  100. package/src/claude/skills/ui-ux/LICENSE +21 -0
  101. package/src/claude/skills/ui-ux/SKILL.md +497 -0
  102. package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
  103. package/src/claude/skills/ui-ux/references/budgets.md +113 -0
  104. package/src/claude/skills/ui-ux/references/checklist.md +271 -0
  105. package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
  106. package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
  107. package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
  108. package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
  109. package/src/claude/skills/ui-ux/references/components/button.md +142 -0
  110. package/src/claude/skills/ui-ux/references/components/card.md +113 -0
  111. package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
  112. package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
  113. package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
  114. package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
  115. package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
  116. package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
  117. package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
  118. package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
  119. package/src/claude/skills/ui-ux/references/components/input.md +161 -0
  120. package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
  121. package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
  122. package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
  123. package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
  124. package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
  125. package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
  126. package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
  127. package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
  128. package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
  129. package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
  130. package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
  131. package/src/claude/skills/ui-ux/references/design-process.md +650 -0
  132. package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
  133. package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
  134. package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
  135. package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
  136. package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
  137. package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
  138. package/src/claude/skills/ui-ux/references/principles.md +408 -0
  139. package/src/claude/skills/ui-ux/references/refactor.md +245 -0
  140. package/src/claude/skills/ui-ux/references/responsive.md +195 -0
  141. package/src/claude/skills/ui-ux/references/review.md +528 -0
  142. package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
  143. package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
  144. package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
  145. package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
  146. package/src/claude/skills/ui-ux/references/styles.md +311 -0
  147. package/src/claude/skills/ui-ux/references/system.md +219 -0
  148. package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
  149. package/src/claude/skills/ui-ux/references/tokens.css +362 -0
  150. package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
  151. package/src/claude/skills/ui-ux/scripts/package.json +9 -0
  152. package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
  153. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  154. package/src/claude/status.cjs +149 -144
  155. package/src/codex/AGENTS.md +8 -13
  156. package/src/codex/hooks/agent.cjs +2 -1
  157. package/src/codex/hooks/lib/spec-receipt.cjs +2 -2
  158. package/src/codex/hooks/lib/spec-utils.cjs +0 -7
  159. package/src/codex/hooks/rules.cjs +2 -1
  160. package/src/codex/hooks/session.cjs +0 -2
  161. package/src/codex/hooks/spec-gate.cjs +7 -18
  162. package/src/codex/hooks.json +0 -20
  163. package/src/codex/rules/state-sync.md +3 -12
  164. package/src/common/AGENTS.md +2 -2
  165. package/src/omp/extensions/cafekit-bridge.mjs +6 -6
  166. package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
  167. package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
  168. package/src/claude/hooks/completion-authority-check.cjs +0 -56
  169. package/src/claude/hooks/completion-authority-state.cjs +0 -527
  170. package/src/claude/hooks/completion-authority.cjs +0 -163
  171. package/src/claude/hooks/semantic-review-authority.cjs +0 -154
  172. package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
  173. package/src/claude/hooks/usage.cjs +0 -197
  174. package/src/claude/skills/delegate/SKILL.md +0 -124
  175. package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
  176. package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
  177. package/src/claude/skills/hotfix/SKILL.md +0 -289
  178. package/src/claude/skills/inspect/SKILL.md +0 -142
  179. package/src/claude/skills/loop/SKILL.md +0 -114
  180. package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
  181. package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
  182. package/src/claude/skills/route/SKILL.md +0 -94
  183. package/src/claude/skills/route/references/agent-timing.md +0 -46
  184. package/src/claude/skills/route/references/chaining-patterns.md +0 -53
  185. package/src/claude/skills/route/references/task-taxonomy.md +0 -48
  186. package/src/codex/hooks/completion-authority-check.cjs +0 -67
  187. package/src/codex/hooks/completion-authority-state.cjs +0 -527
  188. package/src/codex/hooks/completion-authority.cjs +0 -109
  189. package/src/codex/hooks/semantic-review-authority.cjs +0 -130
  190. package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
  191. /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
  192. /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
  193. /package/src/claude/skills/{hotfix → fix}/references/workflow-specialized.md +0 -0
@@ -0,0 +1,204 @@
1
+ # Bảng giá
2
+
3
+ > ⚑ Rút ra từ một lượt dựng thật (trang giá khoá học 3 gói).
4
+
5
+ **Một bố cục mặc định, dựng luôn.** Người dùng muốn kiểu khác (gộp một khối,
6
+ nút lên trên, bảng so sánh, gói nổi bật chỉ viền thay vì đảo màu…) thì họ nói, mình sửa theo. Đừng bày
7
+ phương án.
8
+
9
+ Đây là trang trình diễn, **giá luôn là font body** (`T3`).
10
+
11
+ ---
12
+
13
+ ## Đầu trang
14
+
15
+ **Căn giữa**, tên trang cỡ hero, câu dẫn một câu. Gần như mọi trang bảng giá đứng
16
+ riêng đều làm vậy: ba card đối xứng bên dưới, đầu trang lệch trái thì cả trang
17
+ nghiêng một bên. Đây là ngoại lệ của `T12`, chỉ vì chữ ngắn (tên một dòng, câu dẫn
18
+ tối đa hai dòng).
19
+
20
+ ```html
21
+ <header class="text-center">
22
+ <h1 class="text-balance font-heading text-2xl font-bold text-foreground sm:text-3xl">…</h1>
23
+ <p class="mx-auto mt-3 max-w-[55ch] text-balance text-sm/6 text-muted sm:text-base/7">…</p>
24
+ </header>
25
+ <div class="mt-8 sm:mt-12 …"><!-- dãy gói --></div>
26
+ ```
27
+
28
+ - **Tên trang `sm:text-3xl`, không phải `2xl`.** Giá là `3xl`; tên trang `2xl`
29
+ (24px) nằm trên ba con số 30px thì trang không có đầu, mắt nhảy thẳng vào giá
30
+ mà không biết đang xem gì. Tên trang bằng cỡ giá là đủ: nó
31
+ đứng một mình, căn giữa, font tiêu đề, không cần to hơn nữa.
32
+ - Trang bảng giá **nằm trong khung app** (Cài đặt → Gói cước) thì không theo mục
33
+ này: tên trang `xl` căn trái như mọi trang app (`budgets.md`).
34
+
35
+ ---
36
+
37
+ ## Bố cục
38
+
39
+ ```
40
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
41
+ │ Tên │ │ Tên [bdg]│ │ Tên │ 1 tên, badge nổi bật bên phải
42
+ │ mô tả │ │ mô tả │ │ mô tả │ 2 đúng 1 câu
43
+ │ GIÁ /th │ │ GIÁ /th │ │ GIÁ /th │ 3 giá + đơn vị cùng dòng
44
+ │ dòng phụ │ │ dòng phụ │ │ dòng phụ │ 4 điều kiện của giá
45
+ ├──────────┤ ├──────────┤ ├──────────┤ đường chia tràn mép card (F25)
46
+ │ Bao gồm: │ │ Mọi thứ… │ │ Mọi thứ… │ 5 tiêu đề danh sách
47
+ │ ✓ ... │ │ ✓ ... │ │ ✓ ... │ 6 tính năng
48
+ │ – ... │ │ ✓ ... │ │ ✓ ... │
49
+ │ [ nút ] │ │ [ NÚT ] │ │ [ nút ] │ 7 nút, luôn đáy card
50
+ └──────────┘ └──────────┘ └──────────┘
51
+ ```
52
+
53
+ Các card rộng bằng nhau, cao bằng nhau. Hàng giữa các card căn bằng `subgrid`,
54
+ không chừa `min-h-*` (đoán độ dài chữ là sai ngay ở ca `S8`):
55
+
56
+ ```html
57
+ <div class="grid gap-4 lg:grid-cols-3">
58
+ <!-- row-span-7 = số hàng trong sơ đồ. Thêm hàng thì đổi cả hai số. -->
59
+ <!-- Card chỉ padding DỌC, từng hàng tự px-7: vạch dưới giá tự tràn mép, không margin âm (N11). -->
60
+ <article class="row-span-7 grid grid-rows-subgrid gap-y-0 rounded-2xl border border-border bg-surface py-7 *:px-7">
61
+ …
62
+ </article>
63
+ </div>
64
+ ```
65
+
66
+ Gói nào cũng đủ 7 hàng. Thiếu dòng phụ thì để phần tử rỗng, đừng bỏ.
67
+
68
+ **Vạch giữa phần giá và phần tính năng kẻ bằng `--border-strong`**, tràn mép card
69
+ (`F25`): `border-t border-border-strong` trên hàng tiêu đề danh sách. Card chỉ có
70
+ padding dọc (`py-7`), padding ngang nằm ở từng hàng (`*:px-7`), nên vạch tự chạm hai
71
+ mép card; không `-mx-7` (`N11`).
72
+ Cùng lý do với đường chia "hoặc" ở `form.md`: `--border` (`#f7f7f8`) đứng một mình
73
+ trên card trắng chỉ 1.06 : 1, vạch biến mất, card đọc thành một khối chữ liền. Viền ngoài card vẫn `--border`: card trắng trên nền trang xám đã
74
+ tự tách.
75
+
76
+ Màn hẹp: một cột dưới `lg`, giữ thứ tự rẻ đến đắt, và **chặn bề rộng khi xếp
77
+ chồng**: `mx-auto max-w-lg lg:max-w-none`. Không chặn thì ở 768px mỗi card rộng
78
+ 650px: danh sách tính năng chiếm một phần ba bên trái, còn lại trống, nút dài
79
+ 615px trông như thanh ngang. Card gói là thứ đọc dọc, rộng
80
+ ~500px là vừa, như khi đứng cạnh nhau ở màn rộng.
81
+
82
+ ```html
83
+ <div class="mx-auto mt-8 grid max-w-lg grid-cols-1 gap-4 sm:mt-12 lg:max-w-none lg:grid-cols-3">
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Từng hàng
89
+
90
+ | Hàng | Làm | Đừng |
91
+ | --- | --- | --- |
92
+ | Tên | `text-lg font-semibold`, tối đa khoảng 3 từ | To bằng giá. Đây là **ngoại lệ có chủ ý của `T8`**: giá là thứ đọc đầu tiên |
93
+ | Mô tả | Đúng 1 câu, gói nào cũng có | Gói có gói không |
94
+ | Giá | `text-3xl font-bold tabular-nums`, đơn vị `/tháng` cùng dòng, căn `baseline`. Gói miễn phí ghi "Miễn phí" | "0đ" |
95
+ | Dòng phụ | Điều kiện riêng của gói (`T22`), **vừa một dòng**: "Trả theo năm: 990.000đ/tháng" | Câu dài bị chẻ giữa con số (`T10`) |
96
+ | Tiêu đề danh sách | "Bao gồm:" ở gói thấp nhất, "Mọi thứ trong Pro, thêm:" ở gói trên. `text-sm text-muted` | "Toàn bộ quyền lợi của gói Pro" viết thành một mục có dấu check |
97
+ | Tính năng | Check nét `Check` lucide `size-4`. Mục không có: `Minus` + chữ `--muted`. Con số đứng đầu: "4 buổi kèm 1-1 mỗi tháng" | Check tròn tô đặc, check mờ cho mục không có |
98
+ | Nút | Rộng hết card, **`h-12`** ở mọi bề rộng, chữ `text-sm font-medium`. Chữ là động từ + gói: "Đăng ký gói Pro" | Ba nút cùng chữ "Chọn gói". Nút `h-10` của app |
99
+
100
+ **Nút `h-12`, không `h-10`.** Đây là hành động chính của cả trang, nằm đáy một card
101
+ cao ~520px dưới con số 30px: nút 40px trông mỏng, như nút phụ trong toolbar (chủ dự
102
+ án thấy "hơi thấp"). Cùng ngoại lệ với form đăng nhập đứng riêng
103
+ (`form.md`): màn chỉ có một việc thì nút của việc đó to hơn một bậc.
104
+
105
+ ---
106
+
107
+ ## Gói nổi bật: card đảo màu + badge
108
+
109
+ 1. **Card nền tối**: `bg-primary`, chữ `text-primary-foreground`. Tính năng, tên,
110
+ giá, check đều `text-primary-foreground`; chữ phụ (mô tả, `/tháng`, dòng phụ,
111
+ tiêu đề danh sách) `text-primary-foreground/70`; vạch dưới giá
112
+ `border-primary-foreground/15`. Viền card cùng màu nền.
113
+ 2. **Badge** góc phải hàng tên: `rounded-full px-2.5 py-1 text-xs font-medium
114
+ bg-primary-foreground/15 text-primary-foreground`, chữ nói lý do ("Phổ biến nhất").
115
+ Không emoji, không ngôi sao (`T21`).
116
+ 3. **Nút đảo theo card**: nền trắng chữ tối,
117
+ `bg-surface text-foreground hover:bg-surface/90`. Dự án trả vòng focus lại (`I14`) thì
118
+ `focus-visible:ring-primary-foreground/60 focus-visible:ring-offset-primary`: offset mặc định
119
+ là màu `--surface`, trên card tối thành một viền trắng thừa.
120
+
121
+ ```html
122
+ <article class="… rounded-2xl border border-primary bg-primary py-7 text-primary-foreground *:px-7">
123
+ <div class="flex items-center justify-between gap-3">
124
+ <h2 class="text-lg font-semibold">Pro</h2>
125
+ <span class="rounded-full bg-primary-foreground/15 px-2.5 py-1 text-xs font-medium">Phổ biến nhất</span>
126
+ </div>
127
+ <p class="mt-2 text-sm/6 text-primary-foreground/70">…</p>
128
+ …
129
+ <button class="h-12 w-full cursor-pointer rounded-xl bg-surface text-sm font-medium text-foreground outline-hidden hover:bg-surface/90">Đăng ký gói Pro</button>
130
+ </article>
131
+ ```
132
+
133
+ **Vì sao đảo màu.** Chỉ có badge + nút primary thì ba card trắng giống hệt,
134
+ mắt không có chỗ dừng (chủ dự án thấy "chưa wow"). So ba cách: chỉ badge + nút (phẳng, không gói nào nổi), viền 1px `--primary` quanh
135
+ card (có nổi nhưng phải nhìn kỹ mới thấy), card đảo màu (thấy ngay từ xa, vẫn phẳng:
136
+ không bóng, không phóng to). Card đảo màu là cách phổ biến nhất ở các trang giá dùng
137
+ màu trung tính. Chữ phụ `/70` trên `#181818` đo ~8:1; `--primary` có sắc thì đo lại,
138
+ dưới 4.5:1 thì lên `/80`.
139
+
140
+ Không làm card cao hơn, to hơn, vòng sáng, bóng, `scale-105` (`F20`, `F22`): màu nền
141
+ đã đủ. Đề không có gói nào cần đẩy thì ba card cùng trắng, không badge.
142
+
143
+ Nút các gói khác: **nền `--secondary`**, không viền
144
+ — variant `secondary` ở `../components/button.md`. Nút rộng hết card mà chỉ có
145
+ viền mảnh thì trông rỗng.
146
+
147
+ ---
148
+
149
+ ## Màu thương hiệu
150
+
151
+ Màu nhấn chỉ nằm ở **card của gói nổi bật**. Còn lại trung tính (`M2`, `M3`).
152
+
153
+ | Thứ | Theo `--primary`? |
154
+ | --- | --- |
155
+ | Nền card gói nổi bật | Có. Cả badge và nút bên trong đi theo card (mục trên) |
156
+ | Check, giá, tên gói ở card trắng | Không. Check tô màu ở cả dãy là gói nổi bật hết nổi; giá màu nhấn đọc ra là link, màu sáng còn không đạt tương phản (`P3`) |
157
+ | Nút các gói khác | Không |
158
+
159
+ ---
160
+
161
+ ## Những thứ không dựng nếu đề không nhắc
162
+
163
+ - **Nút chuyển tháng/năm.** Có giá năm thì ghi ở dòng phụ dưới giá. Đề nhắc giảm giá trả năm mà không đưa số thì hỏi số, không bịa (`S7`).
164
+ - **FAQ** (`S1`). Có thì dựng theo mục "Câu hỏi thường gặp" dưới đây.
165
+ - **Bảng so sánh** (`S1`).
166
+
167
+ ---
168
+
169
+ ## Câu hỏi thường gặp
170
+
171
+ **Accordion trong MỘT khung trắng, đóng hết lúc vào trang**, một cột giữa trang.
172
+ Người ta đến trang giá để chọn gói; FAQ là chỗ tra khi còn vướng, nên chỉ cần thấy
173
+ danh sách câu hỏi, bấm câu nào mở câu đó. Bung hết thì FAQ dài gần bằng dãy gói
174
+ (chủ dự án thấy "bung ra hết"). Hầu hết trang giá đều dùng accordion ở
175
+ đây. Đây là ngoại lệ của `I17`: FAQ ở trang giá luôn accordion, dù dưới 6 câu.
176
+
177
+ Mỗi câu là một mục accordion, dựng đúng theo `../components/accordion.md` (padding,
178
+ chuyển động, hover, khung, cách kiểm đều nằm ở đó). Phần riêng của trang giá:
179
+
180
+ ```tsx
181
+ // faq-section.tsx
182
+ <section className="mx-auto mt-16 max-w-3xl sm:mt-20">
183
+ <h2 className="text-center font-heading text-xl font-bold text-foreground">Câu hỏi thường gặp</h2>
184
+
185
+ <div className="mt-6 divide-y divide-border overflow-hidden rounded-2xl border border-border bg-surface">
186
+ {faqItems.map((item) => (
187
+ <AccordionItem key={item.question} title={item.question}>{item.answer}</AccordionItem>
188
+ ))}
189
+ </div>
190
+ </section>
191
+ ```
192
+
193
+ - **Khung `max-w-3xl` giữa trang**, đủ để câu hỏi dài nhất vừa một dòng ở desktop. Đừng
194
+ `max-w-lg` (512px, chọn để câu trả lời ≤ 75 ký tự): câu hỏi "Đang học gói Tự học,
195
+ muốn lên gói Pro thì phần đã học có mất không?" xuống dòng khi hàng còn trống, và khung
196
+ chỉ rộng nửa dãy card. Đo:
197
+ `max-w-2xl` câu hỏi một dòng, câu trả lời 2 dòng ~89 ký tự; `max-w-3xl` cả hai một dòng.
198
+ Câu trả lời FAQ là 1–2 câu, đọc một hơi, không phải đoạn văn nên không tính trần `T11`.
199
+ - **Tiêu đề `font-heading font-bold`, căn giữa, cùng họ chữ với tên trang.** Trang trình
200
+ diễn có font tiêu đề thì mọi tiêu đề cấp trang (`h1`, `h2` của từng phần) dùng chung nó;
201
+ để `h2` font body thì trang có hai tiêu đề lớn hai kiểu chữ. Tên
202
+ gói, câu hỏi vẫn font body (`T2`).
203
+ - **Cách dãy gói `mt-16 sm:mt-20`**: phần khác của trang, không phải card thứ tư.
204
+ - **Đóng hết lúc vào trang.**
@@ -0,0 +1,35 @@
1
+ # Luật chủ dự án đã chốt
2
+
3
+ Những luật dưới đây chủ dự án đã xem bản dựng thật rồi mới quyết. **Không lật, không làm
4
+ khác đi**, kể cả khi số đông làm khác hay có lý lẽ nghe hợp lý. Muốn đổi thì hỏi chủ dự án
5
+ trước.
6
+
7
+ Cột **"Lý lẽ đã bị bác"** ghi đúng những câu từng dẫn tới bản sai. Viết spec mà thấy mình
8
+ đang nghĩ ra một câu giống vậy thì dừng lại: đó là lỗi cũ quay lại.
9
+
10
+ **Khi nào mở file này:** viết mục mới hoặc sửa spec có nói tới màu nút, mức nặng của nút
11
+ (`primary`, `outline`, `secondary`, đỏ, trung tính), bo góc, cỡ chữ tiêu đề, hover, focus,
12
+ chuyển động. Sửa skill xong chạy `node skills/ui-ux/scripts/lint-skill.mjs` (từ gốc repo).
13
+
14
+ | # | Luật đã chốt | Chốt ngày | Lý lẽ đã bị bác | Luật gốc |
15
+ | --- | --- | --- | --- | --- |
16
+ | 1 | Việc nguy hiểm tô đỏ theo ba câu của `I4` (mất dữ liệu, kết thúc thứ đang chạy, cắt quyền). Đăng xuất, đăng xuất hàng loạt, huỷ gói đều đỏ | 23/09, 26/09, 27/09/2026 | "Không mất dữ liệu nên trung tính". "Vẫn dùng được tới hết kỳ nên không đỏ". "Nhiều app để trung tính" | `rules-state.md` `I4` |
17
+ | 2 | Nút nguy hiểm là nền mờ `rose-500/10`, chữ `rose-700`, luôn hiện | 21/09/2026 | Đỏ đặc `bg-rose-500 text-white`. Viền đỏ | `rules-state.md` `I4`, `components/button.md` |
18
+ | 3 | Hộp xác nhận việc nguy hiểm đỏ như hộp xoá. Hộp trung tính (icon xám, nút `primary`) chỉ khi ba câu của `I4` đều "không" | 26/09, 27/09/2026 | Lấy hộp đăng xuất hàng loạt, hộp huỷ gói làm ví dụ cho hộp trung tính | `layouts/overlay.md` |
19
+ | 4 | `outline` là nút mặc định; `secondary` không thay nó | 21/09/2026 | Đổi mặc định sang `secondary` cho "có mặt rõ hơn" | `components/button.md` |
20
+ | 5 | Nút viền rê vào chỉ đổi nền `--button-hover` (`#f1f1f3`), viền giữ nguyên | 26/09/2026 | Viền đậm lên `foreground/20`. `hover:bg-background` (tan vào nền trang) | `components/button.md` |
21
+ | 6 | Nút lọc dạng dropdown ngoài form không có hover, như ô Select | 25/09/2026 | Mượn hover nút viền: tô nền xám, rồi viền đậm lên | `components/choice-controls.md` |
22
+ | 7 | Tab trạng thái dưới `sm` thành nút dropdown có nhãn "Trạng thái:" | 25/09/2026 | Nút chỉ ghi "Tất cả · 32", không nhãn | `layouts/app.md`, "Bảng dữ liệu" |
23
+ | 8 | Dòng bảng tick checkbox: đã chọn và đang rê cùng một nền mờ (`I10`). Chỉ dòng bảng: sidebar và cây thư mục rê `hover:bg-item-hover`, đang chọn `bg-secondary` + `font-medium`, không màu nhấn, không viền (đổi 29/09/2026) | 23/09, 29/09/2026 | "Mỗi trạng thái phải một nền khác" cho dòng bảng. Áp "cùng một nền" sang sidebar, cây thư mục. Tô màu nhấn mục sidebar đang chọn | `principles.md` `N2`, `layouts/app.md`, `components/tree.md` |
24
+ | 9 | Focus ô nhập: viền `--border-focus` + `ring-2` mờ (`I13`) | 21/09/2026 | Tăng độ đậm ring thành vòng viền thứ hai | `components/input.md` |
25
+ | 10 | Bo góc theo chiều cao: từ 40px trở lên tối thiểu 12px, dưới 40px thì 8px | 21/09/2026 | Chọn theo tên loại ("mục menu thì 8px") | `rules-form.md` |
26
+ | 11 | Tên trang `xl`, `2xl` chỉ cho hero | 16/09/2026 | Tên trang `2xl` ở desktop | `budgets.md` |
27
+ | 12 | Panel trượt 500ms vào, 350ms ra | 23/09/2026 | Rút ngắn 300/200ms cho "nhanh hơn". `linear` | `layouts/overlay.md` |
28
+ | 13 | Thanh cuộn ẩn bằng màu trong suốt, giữ bề rộng 4px | 08/09/2026 | `scrollbar-width: none` (nội dung bị đẩy ngang khi thanh hiện) | `tokens.css` |
29
+ | 14 | Hàng tab cuộn ngang ở màn hẹp: chỉ gợi ý cho người dùng chọn cách báo "còn nữa", không áp sẵn | 25/09/2026 | Tự áp dropdown hoặc thanh cuộn luôn hiện | `responsive.md` |
30
+ | 15 | Dấu `*` trường bắt buộc tô đỏ | 25/09/2026 | Dấu `*` xám cho "đỡ ồn" | `rules-color.md`, `principles.md` |
31
+ | 16 | Không vẽ vòng focus ở nút, link, tab, chip, checkbox, card, dòng; chỉ trả lại khi đề yêu cầu accessibility (`I14`). Ngoại lệ lúc soi: dự án tự vẽ vòng focus mà một chỗ Tab tới không thấy gì thì báo Lệch hệ, sửa theo vòng của họ | 28/09, 30/09/2026 | "Thiếu vòng focus là trượt WCAG 2.4.7", thêm lại khi soi thấy Tab tới không có dấu | `rules-state.md` `I13` |
32
+ | 17 | Mặc định là nhánh `U` (brief, wireframe, chọn, dựng) cho mọi đề dựng hay làm lại một màn, tiếng Việt hay tiếng Anh; lối khác chỉ khi đề nói rõ | 29/09/2026 | "Dựng luôn một bố cục mặc định, không hỏi" cho đề chỉ nói "dựng màn X" | `SKILL.md` câu 1, `design-process.md` |
33
+ | 18 | Đường kẻ dưới header và dưới đầu sidebar dùng `border-border`, cùng màu vạch chia trong menu, popover | 01/10/2026 | "`--border` trên nền trắng gần như tàng hình, đường chia mất tác dụng" nên dùng `--border-strong` (luật 21/09/2026) | `layouts/app.md` "Khung app có sidebar", `rules-color.md` |
34
+
35
+ Chủ dự án chốt thêm luật nào thì thêm một dòng ở đây, cùng lúc với chỗ sửa ở luật gốc.