@haposoft/cafekit 0.16.6 → 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 (194) 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 +112 -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 +18 -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 +52 -6
  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/scripts/workflow-policy.cjs +22 -10
  68. package/src/claude/settings/settings.json +1 -32
  69. package/src/claude/skills/{question → ask}/SKILL.md +9 -75
  70. package/src/claude/skills/brainstorm/SKILL.md +43 -131
  71. package/src/claude/skills/code-review/SKILL.md +48 -17
  72. package/src/claude/skills/code-review/references/spec-compliance-review.md +2 -3
  73. package/src/claude/skills/code-review/references/verification-gate.md +22 -27
  74. package/src/claude/skills/debug/SKILL.md +29 -149
  75. package/src/claude/skills/develop/SKILL.md +27 -36
  76. package/src/claude/skills/develop/references/parallel-waves.md +0 -8
  77. package/src/claude/skills/develop/references/quality-gate.md +15 -13
  78. package/src/claude/skills/docs/SKILL.md +2 -2
  79. package/src/claude/skills/docs/references/update-workflow.md +1 -1
  80. package/src/claude/skills/fix/SKILL.md +153 -0
  81. package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
  82. package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
  83. package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
  84. package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
  85. package/src/claude/skills/git/SKILL.md +48 -9
  86. package/src/claude/skills/git/references/commit-protocols.md +35 -16
  87. package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
  88. package/src/claude/skills/orca/SKILL.md +9 -8
  89. package/src/claude/skills/research/SKILL.md +2 -0
  90. package/src/claude/skills/scout/SKILL.md +61 -0
  91. package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
  92. package/src/claude/skills/specs/SKILL.md +22 -29
  93. package/src/claude/skills/specs/references/review.md +8 -6
  94. package/src/claude/skills/specs/references/templates.md +38 -44
  95. package/src/claude/skills/sync/SKILL.md +8 -15
  96. package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
  97. package/src/claude/skills/sync/references/sync-protocols.md +4 -13
  98. package/src/claude/skills/test/SKILL.md +22 -3
  99. package/src/claude/skills/test/references/execution-strategy.md +83 -0
  100. package/src/claude/skills/test/references/failure-triage.md +1 -1
  101. package/src/claude/skills/ui-ux/LICENSE +21 -0
  102. package/src/claude/skills/ui-ux/SKILL.md +497 -0
  103. package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
  104. package/src/claude/skills/ui-ux/references/budgets.md +113 -0
  105. package/src/claude/skills/ui-ux/references/checklist.md +271 -0
  106. package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
  107. package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
  108. package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
  109. package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
  110. package/src/claude/skills/ui-ux/references/components/button.md +142 -0
  111. package/src/claude/skills/ui-ux/references/components/card.md +113 -0
  112. package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
  113. package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
  114. package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
  115. package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
  116. package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
  117. package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
  118. package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
  119. package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
  120. package/src/claude/skills/ui-ux/references/components/input.md +161 -0
  121. package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
  122. package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
  123. package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
  124. package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
  125. package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
  126. package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
  127. package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
  128. package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
  129. package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
  130. package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
  131. package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
  132. package/src/claude/skills/ui-ux/references/design-process.md +650 -0
  133. package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
  134. package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
  135. package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
  136. package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
  137. package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
  138. package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
  139. package/src/claude/skills/ui-ux/references/principles.md +408 -0
  140. package/src/claude/skills/ui-ux/references/refactor.md +245 -0
  141. package/src/claude/skills/ui-ux/references/responsive.md +195 -0
  142. package/src/claude/skills/ui-ux/references/review.md +528 -0
  143. package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
  144. package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
  145. package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
  146. package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
  147. package/src/claude/skills/ui-ux/references/styles.md +311 -0
  148. package/src/claude/skills/ui-ux/references/system.md +219 -0
  149. package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
  150. package/src/claude/skills/ui-ux/references/tokens.css +362 -0
  151. package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
  152. package/src/claude/skills/ui-ux/scripts/package.json +9 -0
  153. package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
  154. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  155. package/src/claude/status.cjs +149 -144
  156. package/src/codex/AGENTS.md +8 -13
  157. package/src/codex/hooks/agent.cjs +2 -1
  158. package/src/codex/hooks/lib/spec-receipt.cjs +5 -0
  159. package/src/codex/hooks/lib/spec-utils.cjs +0 -7
  160. package/src/codex/hooks/rules.cjs +2 -1
  161. package/src/codex/hooks/session.cjs +0 -2
  162. package/src/codex/hooks/spec-gate.cjs +8 -18
  163. package/src/codex/hooks.json +0 -20
  164. package/src/codex/rules/state-sync.md +3 -12
  165. package/src/common/AGENTS.md +2 -2
  166. package/src/omp/extensions/cafekit-bridge.mjs +6 -6
  167. package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
  168. package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
  169. package/src/claude/hooks/completion-authority-check.cjs +0 -56
  170. package/src/claude/hooks/completion-authority-state.cjs +0 -527
  171. package/src/claude/hooks/completion-authority.cjs +0 -163
  172. package/src/claude/hooks/semantic-review-authority.cjs +0 -154
  173. package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
  174. package/src/claude/hooks/usage.cjs +0 -197
  175. package/src/claude/skills/delegate/SKILL.md +0 -124
  176. package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
  177. package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
  178. package/src/claude/skills/hotfix/SKILL.md +0 -289
  179. package/src/claude/skills/inspect/SKILL.md +0 -142
  180. package/src/claude/skills/loop/SKILL.md +0 -114
  181. package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
  182. package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
  183. package/src/claude/skills/route/SKILL.md +0 -94
  184. package/src/claude/skills/route/references/agent-timing.md +0 -46
  185. package/src/claude/skills/route/references/chaining-patterns.md +0 -53
  186. package/src/claude/skills/route/references/task-taxonomy.md +0 -48
  187. package/src/codex/hooks/completion-authority-check.cjs +0 -67
  188. package/src/codex/hooks/completion-authority-state.cjs +0 -527
  189. package/src/codex/hooks/completion-authority.cjs +0 -109
  190. package/src/codex/hooks/semantic-review-authority.cjs +0 -130
  191. package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
  192. /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
  193. /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
  194. /package/src/claude/skills/{hotfix → fix}/references/workflow-specialized.md +0 -0
@@ -0,0 +1,235 @@
1
+ # Hình khối và bố cục — luật F
2
+
3
+ Nguồn duy nhất cho mọi luật về khối, lưới, khoảng cách. Con số cụ thể ở
4
+ `budgets.md`. Luật về màn hẹp ở `responsive.md`.
5
+
6
+ ---
7
+
8
+ ## Khối
9
+
10
+ **F1. Bo góc gán theo vai trò và CHIỀU CAO, không gán theo cảm hứng.**
11
+
12
+ Bốn bậc, hết:
13
+
14
+ | Bậc | Giá trị | Cho |
15
+ | --- | --- | --- |
16
+ | Tròn | `rounded-full` | Avatar, chip, badge, thứ tròn |
17
+ | Lớn | `rounded-2xl` 16px | Card, khung dropdown, modal |
18
+ | Giữa | `rounded-xl` 12px | **Mặc định.** Mọi phần tử **cao từ 40px trở lên**: nút, ô nhập, link sidebar, dòng danh sách có hover, mục menu cao 40px |
19
+ | Nhỏ | `rounded-lg` 8px | **Chỉ** phần tử **cao dưới 40px** (36px trở xuống): nút nhỏ `h-9`, mục menu gọn, icon button `h-7`/`h-8`, ô vuông nhỏ |
20
+
21
+ **Luật chiều cao: từ 40px trở lên thì tối thiểu 12px.** Nhìn chiều cao phần tử
22
+ trước rồi mới chọn bậc, đừng chọn theo tên loại ("mục menu thì 8px"). Mục menu
23
+ cao 40px mà bo 8px thì góc trông cứng, lạc tông với nút và ô nhập 12px đứng gần
24
+ (chủ dự án chốt). Dưới 40px thì 12px bắt đầu tròn quá so với chiều
25
+ cao, nên hạ về 8px.
26
+
27
+ Dùng `rounded-md`, `rounded` hay số tuỳ chế là đẻ bậc thứ năm. *Ngoại lệ có tên:
28
+ ô checkbox, 20px bo `rounded-md`, 16px bo `rounded` (`components/choice-controls.md`):
29
+ ô vuông nhỏ hơn 24px mà bo 8px thì thành gần tròn, lẫn với radio.* Chỉ bo thứ **có nền hoặc có
30
+ viền**; link chữ giữa dòng thì không bo.
31
+
32
+ Bo lồng nhau giảm dần theo độ sâu — xem `M19`.
33
+
34
+ **F2. Lồng khối tối đa hai tầng.** Card lồng card lồng card là dấu hiệu chưa
35
+ quyết định cái gì chứa cái gì.
36
+
37
+ **F3. Không mỗi mục một card.**
38
+
39
+ Nhiều mục cùng loại thì gom vào **một khối**, chia bằng đường kẻ. Bốn card trắng
40
+ giống hệt nhau xếp lưới thì mắt đọc ra bốn khối ngang hàng, không đọc ra một
41
+ danh sách.
42
+
43
+ Dòng tiêu đề của danh sách (icon + nhãn, số liệu bên phải) và dòng hành động cuối
44
+ ("Xem tất cả") nằm **TRONG** khung, không nằm ngoài.
45
+
46
+ *Ngoại lệ: thẻ kanban*, vì nó là vật kéo thả được.
47
+
48
+ **F4. Không bọc bảng vào card.** Bảng đã tự có khung bằng đường kẻ rồi: chính bảng là một khung trắng viền mảnh, không lồng thêm card có padding bên ngoài.
49
+
50
+ **F5. Không chia đều ba cột chỉ vì có ba mục.** Bố cục theo mức quan trọng.
51
+ Widget quan trọng nhất chiếm nhiều cột hơn.
52
+
53
+ **F6. Phần tử nổi bật trong một nhóm chỉ cần một dấu hiệu.** Card đã có badge và
54
+ đã cao hơn hai card kia thì đừng thêm viền nữa. Ba dấu hiệu cho một việc là thừa
55
+ hai, và cái thừa luôn là cái rẻ tiền nhất.
56
+
57
+ **F7. Không hero chiếm nguyên màn hình.** Trong app thì vào là thấy việc — không
58
+ banner, không dòng chào mừng chiếm chỗ.
59
+
60
+ ---
61
+
62
+ ## Thẳng hàng
63
+
64
+ **F8. Card cùng lưới thẳng hàng theo từng tầng, không chỉ thẳng chân.**
65
+
66
+ Mô tả dài ngắn khác nhau thì khối giá, đường kẻ ngang, danh sách và nút đều lệch.
67
+ Cho khối mô tả một `min-h` cố định. **Đường kẻ ngang của ba card không thẳng là
68
+ thứ mắt bắt được ngay.**
69
+
70
+ **F9. Thẳng chân bằng `mt-auto` cho nút hành động.** Số dòng nội dung lệch nhau
71
+ là chuyện thường, nút vẫn phải cùng độ cao.
72
+
73
+ **F10. Widget bị kéo cao hơn nội dung thì nội dung giãn theo.**
74
+
75
+ Card `row-span-2` thì cho nội dung nở bằng `flex-1` kèm `min-h`. Đừng đóng cứng
76
+ chiều cao rồi `mt-auto` đẩy xuống đáy — phần trên thành khoảng trống chết.
77
+
78
+ `mt-auto` chỉ dành cho **nút**, không dành cho khối nội dung.
79
+
80
+ *Cách kiểm:* widget nào có khoảng trống chết quá một phần ba chiều cao là nội
81
+ dung chưa giãn.
82
+
83
+ ---
84
+
85
+ ## Khoảng thở
86
+
87
+ **F11. Khoảng thở trong thẻ rộng hơn bro tưởng.** Padding trong thẻ ~20–24px ở
88
+ desktop, dòng danh sách ~12–16px chiều dọc, khoảng giữa các thẻ đều nhau. Con số
89
+ chính xác ở `budgets.md`.
90
+
91
+ **F12. Thẻ nhỏ vẫn là thẻ.** Thẻ kanban, thẻ trong lưới nhiều cột, thẻ trong
92
+ panel hẹp đều bám thang chung. Đừng tự hạ xuống một bậc cho gọn — gọn quá thành
93
+ chật. Bậc nhỏ nhất chỉ dành cho chip, nhãn và ô điều khiển nhỏ.
94
+
95
+ **F13. Phần tử có nền hover phải có padding đủ bốn phía.**
96
+
97
+ Chỉ đặt `py` mà quên `px` thì lúc thường không thấy gì, nhưng vừa hover là nền
98
+ hiện ra ôm sát chữ, chữ dính lề trái phải, nhìn như lỗi.
99
+
100
+ Muốn chữ vẫn thẳng lề với các khối khác mà nền hover vẫn tràn rộng ra thì dùng
101
+ đúng kỹ thuật này:
102
+
103
+ ```html
104
+ <!-- Sai: hover xong chữ dính hai mép -->
105
+ <li class="py-3 hover:bg-item-hover">…</li>
106
+
107
+ <!-- Đúng: nền tràn ra ngoài lề, chữ vẫn thẳng hàng. Card không padding ngang, mỗi khối
108
+ tự mang px: tiêu đề px-5, khối danh sách px-2 (= 5 − 3) để chữ dòng px-3 thẳng tiêu đề -->
109
+ <section class="rounded-2xl bg-surface py-5">
110
+ <h2 class="px-5">…</h2>
111
+ <ul class="px-2">
112
+ <li class="rounded-xl px-3 py-3 hover:bg-item-hover">…</li>
113
+ </ul>
114
+ </section>
115
+ ```
116
+
117
+ Không kéo danh sách ra bằng `-mx-3` (`N11`). Bản padding từng khối và bản `-mx-*` trùng từng
118
+ pixel (chữ tiêu đề, ô tick, nền dòng). Ô trong bảng cùng cách: ô chứa nút bớt padding đúng bằng `px` của nút (`td` `px-2` khi
119
+ nút `px-2`, các ô khác `px-4`), không kéo nút ra.
120
+
121
+ **F14. Không spacing tuỳ hứng, không bo góc tuỳ hứng.** Lấy từ `budgets.md`.
122
+
123
+ Bẫy đi kèm: thanh tiến độ, chip và badge bo bằng **nửa chiều cao** thì đừng ghi
124
+ một con số tình cờ đúng bằng nửa chiều cao lúc đó — dùng `rounded-full`. Đổi
125
+ chiều cao là bo sai ngay, mà không ai nhớ để sửa kèm.
126
+
127
+ ---
128
+
129
+ ## Icon
130
+
131
+ **F15. Icon nét mảnh, một màu xám, và cả màn chỉ dùng một bộ.** Không SVG inline
132
+ tự vẽ, không emoji. Lấy ở đâu thì tuỳ dự án có gì:
133
+
134
+ | Dự án | Lấy icon ở đâu |
135
+ | --- | --- |
136
+ | Có npm | `lucide-react` (mặc định), hoặc bộ icon họ đã cài sẵn — đừng thêm bộ thứ hai |
137
+ | Không có npm, HTML thuần | Lucide qua CDN, hoặc dán SVG của Lucide vào. Vẫn là Lucide, chỉ khác cách nạp |
138
+ | Họ đã có bộ icon riêng | Dùng bộ của họ. Trộn hai bộ icon vào một màn lộ ngay |
139
+
140
+ Luật ở đây là **nét mảnh, một màu, đồng bộ** — không phải tên thư viện.
141
+
142
+ **F16. Ngoại lệ: logo thương hiệu bên thứ ba.** Nút đăng nhập bằng Google, Apple,
143
+ GitHub phải có đúng logo của họ, giữ nguyên màu gốc, dán SVG thẳng vào. Lucide
144
+ không có, và đây là dấu hiệu nhận diện mang chức năng.
145
+
146
+ **F17. Cùng một nhóm thì cùng một icon, trừ khi từng mục thật sự khác nghĩa.**
147
+
148
+ Ô icon cạnh từng mục thì mỗi mục **được phép một icon khác nhau**, miễn cùng bộ,
149
+ cùng độ dày nét, cùng màu, cùng kiểu hộp. Nhưng ba icon **giống hệt nhau** cho ba
150
+ mục thì ô icon mất sạch ý nghĩa — thà bỏ hẳn.
151
+
152
+ **F18. Nút chỉ có icon phải có `aria-label`, và phải cao bằng nút chữ đứng cạnh.**
153
+
154
+ ---
155
+
156
+ ## Hiệu ứng
157
+
158
+ **F19. Không glassmorphism.** `backdrop-blur` chỉ khi phía sau **thật sự** có ảnh
159
+ — ví dụ người dùng đặt được ảnh nền nên độ trong của vỏ đổi theo. Không có ảnh
160
+ nền thì không blur.
161
+
162
+ *Gu flat — phong cách khác đã chọn theo `P1` thì xem `P2` trong `references/styles.md`.*
163
+
164
+ **F20. Không viền phát sáng, không `ring-4`, không shadow màu neon.**
165
+
166
+ *Gu flat — phong cách khác đã chọn theo `P1` thì xem `P2` trong `references/styles.md`.*
167
+
168
+ **F21. Không `border-dashed`.** Hai ngoại lệ: khung kéo thả tệp, và ô rỗng trong
169
+ board hay lịch.
170
+
171
+ **F22. Không animate hình khối.** Không `scale-105` khi hover, không nhấc lên,
172
+ không đổ bóng thêm.
173
+
174
+ *Gu flat — phong cách khác đã chọn theo `P1` thì xem `P2` trong `references/styles.md`.*
175
+
176
+ **F23. Không hiệu ứng xuất hiện cho nội dung tĩnh.** Không fade-in cả trang,
177
+ không cho biểu đồ tự vẽ, cột tự mọc, số tự đếm lên.
178
+
179
+ **F24. Không `transition-all`** trừ đúng một chỗ: card hover. Còn lại là
180
+ `transition-colors`.
181
+
182
+ ---
183
+
184
+ ## Đường chia
185
+
186
+ **F25. Đường chia trong khối có padding phải tràn hết bề ngang, không thụt theo
187
+ padding.**
188
+
189
+ Dropdown, card, panel đều có `p-*` quanh nội dung. Đặt `<hr>` vào trong đó thì
190
+ nó thụt vào hai đầu, thành một đoạn gạch lơ lửng giữa khối — nhìn như vẽ hụt chứ
191
+ không như một vách ngăn.
192
+
193
+ Đường chia là thứ **chia khối**, nên nó phải chạm hai mép khối. Hai cách, chọn
194
+ theo cấu trúc:
195
+
196
+ Chọn cách theo **nền hover của mục có thụt vào so với mép khung hay không**:
197
+
198
+ ```html
199
+ <!-- Cách 1 — menu, dropdown: mục hover thụt vào, cách mép khung một khe.
200
+ Khung chỉ padding dọc; khe ngang nằm ở từng nhóm mục, vạch đứng giữa hai nhóm nên tự chạm mép. -->
201
+ <div class="rounded-2xl py-1">
202
+ <div class="px-1">
203
+ <button class="flex h-10 w-full items-center rounded-xl px-3">…</button>
204
+ </div>
205
+ <hr class="my-1 border-border" />
206
+ <div class="px-1">
207
+ <button class="flex h-10 w-full items-center rounded-xl px-3">…</button>
208
+ </div>
209
+ </div>
210
+
211
+ <!-- Cách 2 — danh sách trong card: dòng tràn hết bề ngang, không thụt.
212
+ Khung không padding ngang, padding nằm ở từng dòng. -->
213
+ <div class="py-1.5">
214
+ <a class="block px-4 py-3">…</a>
215
+ <hr class="border-border" />
216
+ <a class="block px-4 py-3">…</a>
217
+ </div>
218
+ ```
219
+
220
+ **Đừng dùng cách 2 cho menu.** Bỏ padding ngang của khung là nền hover chạm sát
221
+ mép, mất khe hở, và bo góc của mục với bo góc của khung không còn đồng tâm
222
+ (`M19`).
223
+
224
+ **Cách 1 không kéo vạch ra bằng `-mx-*`** (`N11`). Để khung `p-2` rồi cho vạch
225
+ `-mx-2` thì hai con số phải khớp nhau, đổi padding khung mà quên đổi âm lề là vạch lại hụt
226
+ hoặc tràn khỏi khung. Gom mục thành nhóm `px-*` thì không còn số nào phải khớp. Nhóm
227
+ chỉ là `<div>` trơn, không `role`: trình đọc màn hình vẫn thấy các `menuitem` là con của
228
+ `menu`. Vị trí từng mục, từng vạch và chiều cao menu trùng từng pixel với bản `-mx-1`.
229
+
230
+ Cùng lý do, `divide-y` trên danh sách trong card cũng tràn hết bề ngang — xem
231
+ `references/components/card.md`.
232
+
233
+ Ngoại lệ duy nhất: đường chia **giữa các dòng của một danh sách** mà muốn bắt đầu
234
+ thẳng hàng với chữ (bỏ qua avatar bên trái). Cái đó là thụt có chủ ý, và phải
235
+ thụt đúng bằng chiều rộng avatar cộng gap, không phải bằng padding.