@starci/skills 1.1.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 (321) hide show
  1. package/INDEX.md +74 -0
  2. package/INDEX.vi.md +75 -0
  3. package/README.md +44 -0
  4. package/README.vi.md +43 -0
  5. package/SKILL.md +135 -0
  6. package/SKILL.vi.md +128 -0
  7. package/alias/INDEX.md +104 -0
  8. package/alias/INDEX.vi.md +104 -0
  9. package/alias/alias.json +297 -0
  10. package/bin/starci-skills.mjs +219 -0
  11. package/knowledge/INDEX.md +22 -0
  12. package/knowledge/INDEX.vi.md +22 -0
  13. package/knowledge/grammars/starci/DNA.md +146 -0
  14. package/knowledge/grammars/starci/DNA.vi.md +146 -0
  15. package/knowledge/grammars/starci/INDEX.md +25 -0
  16. package/knowledge/grammars/starci/INDEX.vi.md +25 -0
  17. package/knowledge/grammars/starci/family.md +50 -0
  18. package/knowledge/grammars/starci/family.vi.md +50 -0
  19. package/knowledge/grammars/starci/idioms.md +120 -0
  20. package/knowledge/grammars/starci/idioms.vi.md +121 -0
  21. package/knowledge/grammars/starci/playbook.md +36 -0
  22. package/knowledge/grammars/starci/playbook.vi.md +35 -0
  23. package/knowledge/patterns/be/INDEX.md +29 -0
  24. package/knowledge/patterns/be/INDEX.vi.md +29 -0
  25. package/knowledge/patterns/be/comment.md +80 -0
  26. package/knowledge/patterns/be/comment.vi.md +80 -0
  27. package/knowledge/patterns/be/error.md +86 -0
  28. package/knowledge/patterns/be/error.vi.md +86 -0
  29. package/knowledge/patterns/be/folder.md +87 -0
  30. package/knowledge/patterns/be/folder.vi.md +86 -0
  31. package/knowledge/patterns/be/function.md +80 -0
  32. package/knowledge/patterns/be/function.vi.md +80 -0
  33. package/knowledge/patterns/be/imports.md +79 -0
  34. package/knowledge/patterns/be/imports.vi.md +79 -0
  35. package/knowledge/patterns/be/naming.md +87 -0
  36. package/knowledge/patterns/be/naming.vi.md +87 -0
  37. package/knowledge/patterns/be/test.md +79 -0
  38. package/knowledge/patterns/be/test.vi.md +79 -0
  39. package/knowledge/patterns/be/typing.md +73 -0
  40. package/knowledge/patterns/be/typing.vi.md +73 -0
  41. package/knowledge/patterns/fe/INDEX.md +29 -0
  42. package/knowledge/patterns/fe/INDEX.vi.md +29 -0
  43. package/knowledge/patterns/fe/comment.md +70 -0
  44. package/knowledge/patterns/fe/comment.vi.md +70 -0
  45. package/knowledge/patterns/fe/error.md +61 -0
  46. package/knowledge/patterns/fe/error.vi.md +61 -0
  47. package/knowledge/patterns/fe/folder.md +98 -0
  48. package/knowledge/patterns/fe/folder.vi.md +95 -0
  49. package/knowledge/patterns/fe/function.md +70 -0
  50. package/knowledge/patterns/fe/function.vi.md +70 -0
  51. package/knowledge/patterns/fe/imports.md +87 -0
  52. package/knowledge/patterns/fe/imports.vi.md +87 -0
  53. package/knowledge/patterns/fe/naming.md +77 -0
  54. package/knowledge/patterns/fe/naming.vi.md +77 -0
  55. package/knowledge/patterns/fe/test.md +73 -0
  56. package/knowledge/patterns/fe/test.vi.md +73 -0
  57. package/knowledge/patterns/fe/typing.md +67 -0
  58. package/knowledge/patterns/fe/typing.vi.md +67 -0
  59. package/knowledge/ui/INDEX.md +101 -0
  60. package/knowledge/ui/INDEX.vi.md +101 -0
  61. package/knowledge/ui/composition/INDEX.md +60 -0
  62. package/knowledge/ui/composition/INDEX.vi.md +63 -0
  63. package/knowledge/ui/composition/accent.md +73 -0
  64. package/knowledge/ui/composition/accent.vi.md +74 -0
  65. package/knowledge/ui/composition/action.md +55 -0
  66. package/knowledge/ui/composition/action.vi.md +56 -0
  67. package/knowledge/ui/composition/coverage.md +37 -0
  68. package/knowledge/ui/composition/coverage.vi.md +37 -0
  69. package/knowledge/ui/composition/cta.md +79 -0
  70. package/knowledge/ui/composition/cta.vi.md +79 -0
  71. package/knowledge/ui/composition/feedback.md +55 -0
  72. package/knowledge/ui/composition/feedback.vi.md +56 -0
  73. package/knowledge/ui/composition/hierarchy.md +83 -0
  74. package/knowledge/ui/composition/hierarchy.vi.md +82 -0
  75. package/knowledge/ui/composition/layout.md +91 -0
  76. package/knowledge/ui/composition/layout.vi.md +93 -0
  77. package/knowledge/ui/composition/responsive.md +67 -0
  78. package/knowledge/ui/composition/responsive.vi.md +67 -0
  79. package/knowledge/ui/composition/state.md +105 -0
  80. package/knowledge/ui/composition/state.vi.md +106 -0
  81. package/knowledge/ui/presentation/INDEX.md +94 -0
  82. package/knowledge/ui/presentation/INDEX.vi.md +69 -0
  83. package/knowledge/ui/presentation/boundary.md +170 -0
  84. package/knowledge/ui/presentation/boundary.vi.md +169 -0
  85. package/knowledge/ui/presentation/font.md +155 -0
  86. package/knowledge/ui/presentation/font.vi.md +156 -0
  87. package/knowledge/ui/presentation/gap.md +181 -0
  88. package/knowledge/ui/presentation/gap.vi.md +181 -0
  89. package/knowledge/ui/presentation/margin.md +168 -0
  90. package/knowledge/ui/presentation/margin.vi.md +171 -0
  91. package/knowledge/ui/presentation/measure.md +174 -0
  92. package/knowledge/ui/presentation/measure.vi.md +178 -0
  93. package/knowledge/ui/presentation/overflow.md +142 -0
  94. package/knowledge/ui/presentation/overflow.vi.md +142 -0
  95. package/knowledge/ui/presentation/padding.md +293 -0
  96. package/knowledge/ui/presentation/padding.vi.md +292 -0
  97. package/knowledge/ui/presentation/surface.md +166 -0
  98. package/knowledge/ui/presentation/surface.vi.md +166 -0
  99. package/knowledge/ui/presentation/text-flow.md +123 -0
  100. package/knowledge/ui/presentation/text-flow.vi.md +123 -0
  101. package/knowledge/ui/presentation/tone.md +114 -0
  102. package/knowledge/ui/presentation/tone.vi.md +113 -0
  103. package/knowledge/ui/proof/INDEX.md +55 -0
  104. package/knowledge/ui/proof/INDEX.vi.md +55 -0
  105. package/knowledge/ui/proof/accessibility.md +67 -0
  106. package/knowledge/ui/proof/accessibility.vi.md +68 -0
  107. package/knowledge/ui/proof/contrast.md +58 -0
  108. package/knowledge/ui/proof/contrast.vi.md +57 -0
  109. package/knowledge/ui/proof/focus.md +76 -0
  110. package/knowledge/ui/proof/focus.vi.md +76 -0
  111. package/knowledge/ui/proof/motion.md +63 -0
  112. package/knowledge/ui/proof/motion.vi.md +64 -0
  113. package/knowledge/ui/proof/render-truth.md +63 -0
  114. package/knowledge/ui/proof/render-truth.vi.md +63 -0
  115. package/operators/INDEX.md +199 -0
  116. package/operators/INDEX.vi.md +199 -0
  117. package/operators/architecture-decide/errors.json +115 -0
  118. package/operators/architecture-decide/operator.json +20 -0
  119. package/operators/architecture-decide/operator.md +133 -0
  120. package/operators/architecture-decide/operator.vi.md +130 -0
  121. package/operators/architecture-decide/self-test.mjs +221 -0
  122. package/operators/architecture-decide/validate.mjs +112 -0
  123. package/operators/backend-source-apply/errors.json +66 -0
  124. package/operators/backend-source-apply/operator.json +20 -0
  125. package/operators/backend-source-apply/operator.md +189 -0
  126. package/operators/backend-source-apply/operator.vi.md +185 -0
  127. package/operators/backend-source-apply/self-test.mjs +257 -0
  128. package/operators/backend-source-apply/validate.mjs +240 -0
  129. package/operators/business-decide/errors.json +78 -0
  130. package/operators/business-decide/operator.json +20 -0
  131. package/operators/business-decide/operator.md +176 -0
  132. package/operators/business-decide/operator.vi.md +174 -0
  133. package/operators/business-decide/self-test.mjs +225 -0
  134. package/operators/business-decide/validate.mjs +277 -0
  135. package/operators/content-generate/errors.json +106 -0
  136. package/operators/content-generate/operator.json +21 -0
  137. package/operators/content-generate/operator.md +155 -0
  138. package/operators/content-generate/operator.vi.md +155 -0
  139. package/operators/content-generate/self-test.mjs +288 -0
  140. package/operators/content-generate/validate.mjs +196 -0
  141. package/operators/errors.json +178 -0
  142. package/operators/frontend-direction-decide/errors.json +135 -0
  143. package/operators/frontend-direction-decide/operator.json +21 -0
  144. package/operators/frontend-direction-decide/operator.md +167 -0
  145. package/operators/frontend-direction-decide/operator.vi.md +167 -0
  146. package/operators/frontend-direction-decide/self-test.mjs +226 -0
  147. package/operators/frontend-direction-decide/validate.mjs +146 -0
  148. package/operators/frontend-presentation-resolve/errors.json +42 -0
  149. package/operators/frontend-presentation-resolve/operator.json +19 -0
  150. package/operators/frontend-presentation-resolve/operator.md +142 -0
  151. package/operators/frontend-presentation-resolve/operator.vi.md +140 -0
  152. package/operators/frontend-presentation-resolve/self-test.mjs +163 -0
  153. package/operators/frontend-presentation-resolve/validate.mjs +143 -0
  154. package/operators/frontend-source-apply/errors.json +30 -0
  155. package/operators/frontend-source-apply/operator.json +20 -0
  156. package/operators/frontend-source-apply/operator.md +127 -0
  157. package/operators/frontend-source-apply/operator.vi.md +126 -0
  158. package/operators/frontend-source-apply/self-test.mjs +214 -0
  159. package/operators/frontend-source-apply/validate.mjs +133 -0
  160. package/operators/frontend-surface-audit/errors.json +5 -0
  161. package/operators/frontend-surface-audit/operator.json +22 -0
  162. package/operators/frontend-surface-audit/operator.md +121 -0
  163. package/operators/frontend-surface-audit/operator.vi.md +121 -0
  164. package/operators/frontend-surface-audit/self-test.mjs +185 -0
  165. package/operators/frontend-surface-audit/validate.mjs +127 -0
  166. package/operators/git-publish/errors.json +54 -0
  167. package/operators/git-publish/operator.json +20 -0
  168. package/operators/git-publish/operator.md +180 -0
  169. package/operators/git-publish/operator.vi.md +178 -0
  170. package/operators/git-publish/self-test.mjs +177 -0
  171. package/operators/git-publish/validate.mjs +106 -0
  172. package/operators/platform-operate/errors.json +90 -0
  173. package/operators/platform-operate/operator.json +22 -0
  174. package/operators/platform-operate/operator.md +162 -0
  175. package/operators/platform-operate/operator.vi.md +160 -0
  176. package/operators/platform-operate/self-test.mjs +202 -0
  177. package/operators/platform-operate/validate.mjs +193 -0
  178. package/operators/quality-verify/errors.json +54 -0
  179. package/operators/quality-verify/operator.json +20 -0
  180. package/operators/quality-verify/operator.md +185 -0
  181. package/operators/quality-verify/operator.vi.md +177 -0
  182. package/operators/quality-verify/self-test.mjs +210 -0
  183. package/operators/quality-verify/validate.mjs +197 -0
  184. package/operators/release-deploy/errors.json +158 -0
  185. package/operators/release-deploy/operator.json +23 -0
  186. package/operators/release-deploy/operator.md +183 -0
  187. package/operators/release-deploy/operator.vi.md +181 -0
  188. package/operators/release-deploy/self-test.mjs +235 -0
  189. package/operators/release-deploy/validate.mjs +129 -0
  190. package/operators/uat-verify/errors.json +78 -0
  191. package/operators/uat-verify/operator.json +25 -0
  192. package/operators/uat-verify/operator.md +162 -0
  193. package/operators/uat-verify/operator.vi.md +161 -0
  194. package/operators/uat-verify/self-test.mjs +270 -0
  195. package/operators/uat-verify/validate.mjs +202 -0
  196. package/operators/workspace-bind/errors.json +90 -0
  197. package/operators/workspace-bind/operator.json +21 -0
  198. package/operators/workspace-bind/operator.md +148 -0
  199. package/operators/workspace-bind/operator.vi.md +148 -0
  200. package/operators/workspace-bind/self-test.mjs +205 -0
  201. package/operators/workspace-bind/validate.mjs +152 -0
  202. package/package.json +50 -0
  203. package/readiness/initialization/workspaces/commit-policy.json +91 -0
  204. package/readiness/initialization/workspaces/config.schema.json +35 -0
  205. package/readiness/initialization/workspaces/device-state.schema.json +54 -0
  206. package/readiness/initialization/workspaces/local-route.schema.json +206 -0
  207. package/readiness/initialization/workspaces/portable-route.schema.json +200 -0
  208. package/resources/INDEX.md +96 -0
  209. package/resources/INDEX.vi.md +99 -0
  210. package/resources/agents/profiles/claude.json +131 -0
  211. package/resources/agents/profiles/openai.json +131 -0
  212. package/resources/orchestrator.json +71 -0
  213. package/resources/tools.json +85 -0
  214. package/routing.json +272 -0
  215. package/scripts/alias-registry.mjs +31 -0
  216. package/scripts/device-state.mjs +497 -0
  217. package/scripts/device-state.spec.mjs +18 -0
  218. package/scripts/errors-registry.mjs +68 -0
  219. package/scripts/generate-alias-doc.mjs +66 -0
  220. package/scripts/generate-grammar-dna.mjs +387 -0
  221. package/scripts/generate-operators-index.mjs +95 -0
  222. package/scripts/generate-presentation-owned.mjs +681 -0
  223. package/scripts/install-cli.spec.mjs +74 -0
  224. package/scripts/json-schema.mjs +94 -0
  225. package/scripts/operator-md.mjs +96 -0
  226. package/scripts/run-operator-self-tests.mjs +36 -0
  227. package/scripts/validate-alias.mjs +165 -0
  228. package/scripts/validate-defaults.mjs +72 -0
  229. package/scripts/validate-knowledge-citations.mjs +90 -0
  230. package/scripts/validate-operator.mjs +125 -0
  231. package/scripts/validate-request.mjs +80 -0
  232. package/scripts/validate-resources.mjs +117 -0
  233. package/scripts/validate-response.mjs +141 -0
  234. package/scripts/validate-routing.mjs +91 -0
  235. package/scripts/validate-step.mjs +50 -0
  236. package/scripts/validate-templates.mjs +226 -0
  237. package/scripts/validate-templates.spec.mjs +144 -0
  238. package/scripts/validate-workflows.mjs +106 -0
  239. package/scripts/workspace-portable.mjs +389 -0
  240. package/scripts/workspace-portable.spec.mjs +246 -0
  241. package/templates/README.md +47 -0
  242. package/templates/README.vi.md +45 -0
  243. package/templates/changes.example.md +27 -0
  244. package/templates/grammars.template.md +34 -0
  245. package/templates/kinds/architecture-decision.contract.json +14 -0
  246. package/templates/kinds/architecture-decision.skeleton.md +52 -0
  247. package/templates/kinds/backend-source-application.contract.json +10 -0
  248. package/templates/kinds/backend-source-application.skeleton.md +34 -0
  249. package/templates/kinds/business-promise-authority.contract.json +13 -0
  250. package/templates/kinds/business-promise-authority.skeleton.md +67 -0
  251. package/templates/kinds/capture.schema.json +33 -0
  252. package/templates/kinds/changes.contract.json +10 -0
  253. package/templates/kinds/changes.skeleton.md +26 -0
  254. package/templates/kinds/checks.schema.json +44 -0
  255. package/templates/kinds/claims.schema.json +165 -0
  256. package/templates/kinds/conformance.schema.json +15 -0
  257. package/templates/kinds/content-brief.contract.json +12 -0
  258. package/templates/kinds/content-brief.skeleton.md +45 -0
  259. package/templates/kinds/content-generation-receipt.contract.json +11 -0
  260. package/templates/kinds/content-generation-receipt.skeleton.md +40 -0
  261. package/templates/kinds/content-review.contract.json +11 -0
  262. package/templates/kinds/content-review.skeleton.md +45 -0
  263. package/templates/kinds/contract.schema.json +28 -0
  264. package/templates/kinds/coverage-matrix.schema.json +86 -0
  265. package/templates/kinds/coverage.schema.json +62 -0
  266. package/templates/kinds/current-state.schema.json +40 -0
  267. package/templates/kinds/delta.schema.json +95 -0
  268. package/templates/kinds/e2e.schema.json +63 -0
  269. package/templates/kinds/frontend-direction-decision.contract.json +93 -0
  270. package/templates/kinds/frontend-direction-decision.skeleton.md +68 -0
  271. package/templates/kinds/frontend-presentation-resolution.contract.json +11 -0
  272. package/templates/kinds/frontend-presentation-resolution.skeleton.md +32 -0
  273. package/templates/kinds/frontend-source-application.contract.json +10 -0
  274. package/templates/kinds/frontend-source-application.skeleton.md +30 -0
  275. package/templates/kinds/frontend-surface-audit.contract.json +52 -0
  276. package/templates/kinds/frontend-surface-audit.skeleton.md +32 -0
  277. package/templates/kinds/gate-result.schema.json +64 -0
  278. package/templates/kinds/git-publication.contract.json +82 -0
  279. package/templates/kinds/git-publication.skeleton.md +61 -0
  280. package/templates/kinds/independent-critique.contract.json +9 -0
  281. package/templates/kinds/independent-critique.skeleton.md +28 -0
  282. package/templates/kinds/inventory.schema.json +35 -0
  283. package/templates/kinds/model.schema.json +99 -0
  284. package/templates/kinds/mutations.schema.json +65 -0
  285. package/templates/kinds/platform-operation-receipt.contract.json +76 -0
  286. package/templates/kinds/platform-operation-receipt.skeleton.md +54 -0
  287. package/templates/kinds/probes.schema.json +130 -0
  288. package/templates/kinds/proof.schema.json +17 -0
  289. package/templates/kinds/quality-verification.contract.json +87 -0
  290. package/templates/kinds/quality-verification.skeleton.md +58 -0
  291. package/templates/kinds/release-deployment.contract.json +85 -0
  292. package/templates/kinds/release-deployment.skeleton.md +67 -0
  293. package/templates/kinds/route.schema.json +293 -0
  294. package/templates/kinds/stack-model.schema.json +90 -0
  295. package/templates/kinds/uat-capture.schema.json +35 -0
  296. package/templates/kinds/uat-flow-verification.contract.json +11 -0
  297. package/templates/kinds/uat-flow-verification.skeleton.md +47 -0
  298. package/templates/kinds/uat-snapshot.schema.json +96 -0
  299. package/templates/kinds/uat-verdicts.schema.json +41 -0
  300. package/templates/kinds/ui-coverage.schema.json +77 -0
  301. package/templates/kinds/verdicts.schema.json +39 -0
  302. package/templates/kinds/workspace-route-binding.contract.json +12 -0
  303. package/templates/kinds/workspace-route-binding.skeleton.md +60 -0
  304. package/templates/kinds/writes.schema.json +37 -0
  305. package/templates/operator.template.md +73 -0
  306. package/templates/patterns.template.md +31 -0
  307. package/templates/step/request.schema.json +42 -0
  308. package/templates/step/response.schema.json +144 -0
  309. package/templates/ui-composition.template.md +36 -0
  310. package/templates/ui-presentation.template.md +57 -0
  311. package/templates/ui-proof.template.md +34 -0
  312. package/workflows/README.md +37 -0
  313. package/workflows/README.vi.md +37 -0
  314. package/workflows/backend-feature.json +59 -0
  315. package/workflows/content-unit.json +19 -0
  316. package/workflows/frontend-new-surface.json +81 -0
  317. package/workflows/frontend-reconstruct.json +67 -0
  318. package/workflows/frontend-refine.json +67 -0
  319. package/workflows/frontend-with-uat.json +78 -0
  320. package/workflows/full-feature.json +104 -0
  321. package/workflows/release.json +29 -0
@@ -0,0 +1,142 @@
1
+ # Overflow presentation
2
+
3
+ File này trả lời đúng một câu hỏi: khi nội dung vượt quá vùng của nó thì ranh giới nào làm chủ, và
4
+ nó làm gì.
5
+
6
+ Composition đã chọn cây DOM và [Measure](measure.md) đã chặn kích thước vùng. Overflow giải quyết
7
+ chuyện gì xảy ra ở mép của một ranh giới do ứng dụng sở hữu. Việc cắt và cuộn bên trong một card,
8
+ rail, khung bảng hay shell đều thuộc về Grammar.
9
+
10
+ ## Danh mục
11
+
12
+ | Rule | Hành vi ở ranh giới | Nội dung vượt mép |
13
+ | --- | --- | --- |
14
+ | OVERFLOW-1 | Hiện ra ngoài | Thoát khỏi ranh giới và vẫn đọc được |
15
+ | OVERFLOW-2 | Bị cắt | Bị cắt và không với tới được |
16
+ | OVERFLOW-3 | Cuộn một trục | Với tới được bằng cách cuộn trục đó |
17
+ | OVERFLOW-4 | Cuộn khi cần | Chỉ với tới được khi nó thật sự tồn tại |
18
+ | OVERFLOW-5 | Giữ lại trong vùng | Cuộn mà không trao cử chỉ đó cho trang |
19
+
20
+ Mỗi trục chỉ đúng một ranh giới làm chủ. Hai vùng cuộn lồng nhau trên cùng một trục nhốt người đọc ở
21
+ giữa, và không vùng nào tới cuối được một cách đáng tin.
22
+
23
+ ## Owner
24
+
25
+ | Owner | Nghĩa | Ứng dụng viết |
26
+ | --- | --- | --- |
27
+ | `App` | Ranh giới thuộc về ứng dụng | Viết class |
28
+ | Tên component | Common đã sở hữu ranh giới này | Không viết gì, chỉ ghép component |
29
+ | `—` | Common chưa có đường dùng công khai | Viết class, ghi nhận là workaround |
30
+
31
+ Một ranh giới cuộn không bao giờ viết một mình. Nó đi kèm một cái chặn từ [Measure](measure.md), vì
32
+ một vùng không có chặn chiều cao thì không bao giờ tràn, và class cuộn của nó chẳng làm gì cả.
33
+
34
+ ## Overflow mà Common đã sở hữu
35
+
36
+ Sinh từ claim của `@grammar/core` bằng `scripts/generate-presentation-owned.mjs`; muốn đổi thì sửa component, đừng sửa bảng này.
37
+
38
+ | Component | Phần tử hoặc điều kiện | Rule |
39
+ | --- | --- | --- |
40
+ | `ChatWorkspace` | conversation | OVERFLOW-4 |
41
+ | `ChatWorkspace` | conversation | OVERFLOW-5 |
42
+ | `ChatWorkspace` | drawer body, hasRail, isCompactRail | OVERFLOW-2 |
43
+ | `ChatWorkspace` | overlay rail, hasRail, isCompactRail | OVERFLOW-4 |
44
+ | `ChatWorkspace` | overlay rail, hasRail, isCompactRail | OVERFLOW-5 |
45
+ | `ChatWorkspace` | overlay rail, hasRail, not isCompactRail | OVERFLOW-4 |
46
+ | `ChatWorkspace` | overlay rail, hasRail, not isCompactRail | OVERFLOW-5 |
47
+ | `FencedCodeBlock` | root | OVERFLOW-4 |
48
+ | `HorizontalScrollRegion` | root | OVERFLOW-3 |
49
+ | `HorizontalScrollRegion` | root | OVERFLOW-5 |
50
+ | `IconTile` | root | OVERFLOW-2 |
51
+ | `MarkdownTableFrame` | root | OVERFLOW-4 |
52
+ | `MediaFrame` | root | OVERFLOW-2 |
53
+ | `OtpInput` | root | OVERFLOW-3 |
54
+ | `OtpInput` | root | OVERFLOW-5 |
55
+ | `Rail` | body, height!="fill" | OVERFLOW-3 |
56
+ | `Sidebar` | root | OVERFLOW-2 |
57
+ | `SurfaceAccordionCard` | accordion shell | OVERFLOW-2 |
58
+ | `SurfaceAccordionCard` | accordion shell, not bounded | OVERFLOW-1 |
59
+ | `SurfaceCard` | card content | OVERFLOW-2 |
60
+ | `SurfaceCard` | card content, frame="frameless" | OVERFLOW-1 |
61
+ | `SurfaceListCard` | root | OVERFLOW-2 |
62
+ | `Tabs` | scroll | OVERFLOW-4 |
63
+ | `VerticalScrollRegion` | root, isScrollable | OVERFLOW-3 |
64
+ | `WorkspaceShell` | floating layer, hasFloatingLayer | OVERFLOW-4 |
65
+
66
+ ## OVERFLOW-1 — Hiện ra ngoài
67
+
68
+ Ranh giới không cắt, vì phải cho một thứ gì đó được phép vượt qua nó.
69
+
70
+ | Case | Dùng khi | Owner | Render |
71
+ | --- | --- | --- | --- |
72
+ | Case 1 | Một vùng mà phần tử con mang focus ring, đổ bóng hay badge nằm ngoài hộp | `App` | Không viết class. Hiện ra ngoài là mặc định |
73
+ | Case 2 | Một surface không được cắt phần highlight của chính nó | `SurfaceCard` | Biến thể frameless đã giữ hiện ra ngoài sẵn |
74
+
75
+ Không phải rule này: để một vùng có chặn kích thước ở chế độ hiện ra ngoài chỉ vì lười quyết. Nội
76
+ dung thoát ra trong im lặng sẽ chồng lên thứ nằm ngay sau nó.
77
+
78
+ ## OVERFLOW-2 — Bị cắt
79
+
80
+ Nội dung bị cắt ở ranh giới và không với tới được.
81
+
82
+ | Case | Dùng khi | Owner | Render |
83
+ | --- | --- | --- | --- |
84
+ | Case 1 | Một vùng bo góc mà các phần tử con phải nằm gọn trong bán kính | `SurfaceCard` | Ghép card, nó đã cắt sẵn |
85
+ | Case 2 | Một viewport media crop ảnh theo khung cố định | `MediaFrame` | Ghép khung, nó đã cắt sẵn |
86
+ | Case 3 | Một vùng trang trí do app sở hữu, phần tràn không mang thông tin gì | `App` | `overflow-hidden` |
87
+
88
+ Cắt mất nội dung mà người đọc cần là mất dữ liệu trong im lặng. Nó trông đúng trên ảnh chụp ở một khổ
89
+ và hỏng ở khổ khác, và đó là lý do đây là loại lỗi overflow khó tìm nhất.
90
+
91
+ Không phải rule này: chữ không vừa chỗ. Cái đó thuộc [Text flow](text-flow.md), và nó cắt cụt một
92
+ cách nhìn thấy được chứ không biến mất.
93
+
94
+ ## OVERFLOW-3 — Cuộn một trục
95
+
96
+ Ranh giới luôn cuộn một trục, vì nội dung của nó vốn được dự tính là sẽ vượt quá.
97
+
98
+ | Case | Dùng khi | Owner | Render |
99
+ | --- | --- | --- | --- |
100
+ | Case 1 | Một hàng các mục cố ý rộng hơn viewport | `HorizontalScrollRegion` | Ghép region |
101
+ | Case 2 | Một panel hoặc danh sách có chặn kích thước mà nội dung cứ dài thêm | `VerticalScrollRegion` | Ghép region |
102
+ | Case 3 | Thân rail cuộn trong khi shell của nó đứng yên | `Rail` | Ghép rail |
103
+
104
+ Trục còn lại giữ bị cắt hoặc hiện ra ngoài, có chủ ý. Một vùng cuộn cả hai trục là giấu nội dung theo
105
+ một hướng mà người đọc chẳng có lý do gì để nhìn tới.
106
+
107
+ Không phải rule này: một vùng mà nội dung thường là vừa. Dùng OVERFLOW-4 để thanh cuộn chỉ hiện khi
108
+ nó có nghĩa.
109
+
110
+ ## OVERFLOW-4 — Cuộn khi cần
111
+
112
+ Ranh giới chỉ cuộn khi nội dung thật sự vượt quá nó.
113
+
114
+ | Case | Dùng khi | Owner | Render |
115
+ | --- | --- | --- | --- |
116
+ | Case 1 | Một bảng rộng nằm trong cột hẹp hơn | `MarkdownTableFrame` | Ghép khung |
117
+ | Case 2 | Những dòng code dài không được xuống dòng | `FencedCodeBlock` | Ghép khối |
118
+ | Case 3 | Một dải tab chỉ vượt chiều rộng ở một số ngôn ngữ | `Tabs` | Ghép tabs |
119
+ | Case 4 | Một vùng do app sở hữu, có chặn kích thước, nội dung thỉnh thoảng mới vượt | `App` | `overflow-auto` cùng cái chặn chiều cao tương ứng |
120
+
121
+ Không phải rule này: một thanh cuộn luôn hiện trên vùng mà nội dung thường vừa, vì lần đầu người đọc
122
+ thấy nó rỗng thì nó đọc lên như một lỗi.
123
+
124
+ ## OVERFLOW-5 — Giữ lại trong vùng
125
+
126
+ Việc cuộn dừng lại ở ranh giới này thay vì chạy tiếp vào trang phía sau.
127
+
128
+ | Case | Dùng khi | Owner | Render |
129
+ | --- | --- | --- | --- |
130
+ | Case 1 | Một panel, drawer hay overlay đang cuộn, nằm trên nội dung trang | `—` | `overscroll-contain` đi cùng rule cuộn |
131
+ | Case 2 | Một hàng ngang nằm trong một trang cuộn dọc | `HorizontalScrollRegion` | Ghép region, nó đã giữ trục ngang sẵn |
132
+
133
+ Không giữ lại thì khi cuộn tới cuối vùng bên trong, cử chỉ đó được trao cho trang và người đọc mất
134
+ dấu chỗ đang xem. Trên thiết bị cảm ứng còn tệ hơn, vì trang trôi ngay dưới ngón tay đang cuộn thứ
135
+ khác.
136
+
137
+ Không phải rule này: giữ lại trên chính vùng cuộn của trang, vì như vậy là nhốt người đọc.
138
+
139
+ ## File này không quyết định
140
+
141
+ Vùng lớn cỡ nào, và có chặn chiều cao hay không, thuộc về [Measure](measure.md). Chữ làm gì khi không
142
+ vừa thuộc về [Text flow](text-flow.md).
@@ -0,0 +1,293 @@
1
+ # Padding presentation
2
+
3
+ This file answers one question: given a boundary the application owns, how much space separates that
4
+ boundary from its content?
5
+
6
+ Composition has already chosen the DOM tree and the Grammar objects. Padding presentation resolves
7
+ the inset of application-owned pages, sections, and containers only. The inset inside a card, input,
8
+ button, or any other Grammar object belongs to Grammar.
9
+
10
+ ## Scale
11
+
12
+ `COMMON_SPACING_SCALE` is closed. The rule ID is the ordinal position on that scale. It is not the
13
+ Tailwind step number, and the two diverge from PADDING-5 onward.
14
+
15
+ | Rule | Class | Value | Common token |
16
+ | --- | --- | --- | --- |
17
+ | PADDING-0 | `p-0` | `0` | none |
18
+ | PADDING-1 | `p-1` | `.25rem` | none |
19
+ | PADDING-2 | `p-2` | `.5rem` | none |
20
+ | PADDING-3 | `p-3` | `.75rem` | none |
21
+ | PADDING-4 | `p-4` | `1rem` | none |
22
+ | PADDING-5 | `p-6` | `1.5rem` | none |
23
+ | PADDING-6 | `p-8` | `2rem` | none |
24
+
25
+ Common publishes no padding token. The internal insets below are reached through the components that
26
+ own them, not through a variable the application may set.
27
+
28
+ The page inset is the one exception and is not on this scale: `--grammar-page-inset` resolves to
29
+ `clamp(1rem, 3vw, 2rem)`, a responsive value owned by `PageContainer`. An application never
30
+ reproduces it with a fixed class.
31
+
32
+ The rem values resolve to `0 / 4 / 8 / 12 / 16 / 24 / 32` CSS pixels only at a computed root of
33
+ `16px`. Runtime checks use `expectedPx = remFactor * observedRootFontPx`.
34
+
35
+ ## Owner
36
+
37
+ Each case names who owns the inset. The owner decides whether the application writes a class at all.
38
+
39
+ | Owner | Meaning | Application writes |
40
+ | --- | --- | --- |
41
+ | `App` | The boundary belongs to the application | The class |
42
+ | A component name | Common already applies the inset inside that component | Nothing. Compose it |
43
+ | `—` | Common exposes no public path for this boundary | The class, recorded as a workaround |
44
+
45
+ Writing a class where a component is the owner is `APP_REIMPLEMENTATION`. Reaching into a Grammar
46
+ component with a selector or a passed class to change its inset is `APP_OVERRIDE`.
47
+
48
+ ## Padding Common already owns
49
+
50
+ Generated from `@grammar/core` claims by `scripts/generate-presentation-owned.mjs`; edit the component, not this table.
51
+
52
+ | Component | Element or condition | Rule |
53
+ | --- | --- | --- |
54
+ | `ChatWorkspace` | drawer body, hasRail, isCompactRail | PADDING-0 |
55
+ | `ChatWorkspace` | overlay rail, hasRail, isCompactRail | PADDING-4 |
56
+ | `ChatWorkspace` | overlay rail, hasRail, not isCompactRail | PADDING-4 |
57
+ | `ChatWorkspace` | rail trigger boundary, hasRail, isCompactRail | PADDING-2 |
58
+ | `ChatWorkspace` | rail trigger boundary, hasRail, isCompactRail | PADDING-4 |
59
+ | `ChatWorkspace` | rail trigger, hasRail, isCompactRail | PADDING-3 |
60
+ | `EmptyNotice` | root | PADDING-4 |
61
+ | `HorizontalScrollRegion` | root | PADDING-1 |
62
+ | `NavigationFeatureNav` | primary | PADDING-3 |
63
+ | `OtpInput` | root | PADDING-1 |
64
+ | `Rail` | body, inset="content" | PADDING-3 |
65
+ | `Rail` | body, inset="content" | PADDING-5 |
66
+ | `Sidebar` | footer, not (collapsed || footer == null) | PADDING-0 |
67
+ | `Sidebar` | footer, not (collapsed || footer == null) | PADDING-3 |
68
+ | `Sidebar` | group label, group.label!=undefined, not collapsed | PADDING-1 |
69
+ | `Sidebar` | group label, group.label!=undefined, not collapsed | PADDING-2 |
70
+ | `Sidebar` | group label, group.label!=undefined, not collapsed | PADDING-3 |
71
+ | `Sidebar` | header, not (collapsed || header == null) | PADDING-3 |
72
+ | `Sidebar` | icon button wrapper, canToggle | PADDING-2 |
73
+ | `Sidebar` | list box item, not collapsed | PADDING-2 |
74
+ | `Sidebar` | list box item, not collapsed | PADDING-3 |
75
+ | `Sidebar` | list box, collapsed | PADDING-2 |
76
+ | `Sidebar` | list box, not collapsed | PADDING-3 |
77
+ | `StaticStateRow` | root | PADDING-4 |
78
+ | `Subnav` | root | PADDING-3 |
79
+ | `SurfaceAccordionCard` | accordion body | PADDING-8 |
80
+ | `SurfaceAccordionCard` | accordion body wrapper | PADDING-0 |
81
+ | `SurfaceAccordionCard` | accordion trigger | PADDING-4 |
82
+ | `SurfaceCard` | card content, composition!="joined" | PADDING-4 |
83
+ | `SurfaceCard` | card content, composition="joined" | PADDING-0 |
84
+ | `SurfaceListCard` | root | PADDING-0 |
85
+ | `Tabs` | hero tabs tab | PADDING-3 |
86
+ | `Tabs` | root, inset="page" | PADDING-5 |
87
+ | `TextAction` | root, appearance="choice" | PADDING-1 |
88
+ | `TextAction` | root, appearance="choice" | PADDING-2 |
89
+ | `TextAction` | root, appearance="route" | PADDING-2 |
90
+ | `TextAction` | root, appearance="route" | PADDING-3 |
91
+ | `TextAction` | root, appearance="section" | PADDING-2 |
92
+ | `TextAction` | root, appearance="section" | PADDING-3 |
93
+ | `TextAction` | root, appearance="tab" | PADDING-3 |
94
+ | `Tooltip` | content | PADDING-1 |
95
+ | `Tooltip` | content | PADDING-2 |
96
+
97
+ ## Side contact
98
+
99
+ A boundary does not always take one value on all four sides. When a surface is flush and its child
100
+ bands own their own inset, each side takes its value from what that side touches.
101
+
102
+ | What the side touches | Value | Rule |
103
+ | --- | --- | --- |
104
+ | The outer edge of the surface | `1rem` | PADDING-4 |
105
+ | A separator between bands | `.75rem` | PADDING-3 |
106
+ | Nothing, because a child owns the edge | `0` | PADDING-0 |
107
+
108
+ A separator already draws the boundary, so the side meeting it needs less clearance than a bare outer
109
+ edge. Inline sides of a band always meet the outer edge, so they stay at `1rem`.
110
+
111
+ For a stack of bands this resolves to `px-4` throughout, `pt-4` on the first band, `pb-4` on the last,
112
+ and `.75rem` on every side that meets a separator. A band between two separators is `px-4 py-3`.
113
+
114
+ Common owns the flush surface itself through `composition="joined"`, which sets the content inset to
115
+ `0`. It exposes no path for the band insets, so those remain an application workaround.
116
+
117
+ ## PADDING-0 — `p-0` / `0`
118
+
119
+ The boundary contributes no space, because the content or a child already owns its own edge.
120
+
121
+ | Case | When | Owner | Render |
122
+ | --- | --- | --- | --- |
123
+ | Case 1 | A container that only groups children which each carry their own boundary | `App` | `<section className="p-0">` |
124
+ | Case 2 | Surface bands that must run flush to the card edge | `SurfaceCard` | `composition="joined"` already sets `0` |
125
+ | Case 3 | A list whose rows own their own inset | `SurfaceListCard` | Compose the card; no padding |
126
+
127
+ Not this rule: the one boundary protecting readable content keeps its inset. Use PADDING-4.
128
+
129
+ ## PADDING-1 — `p-1` / `.25rem`
130
+
131
+ The smallest equal inset, for a deliberately tiny container whose content nearly fills it.
132
+
133
+ | Case | When | Owner | Render |
134
+ | --- | --- | --- | --- |
135
+ | Case 1 | A compact marker or key floating over an app-owned canvas | `App` | `<aside className="p-1">` with `<Text size="xs">` |
136
+ | Case 2 | A scroll region reserving room so focus rings are not clipped | `HorizontalScrollRegion` | Compose the region; no padding |
137
+ | Case 3 | A short hint attached to a control | `Tooltip` | Compose the tooltip; no padding |
138
+
139
+ ## PADDING-2 — `p-2` / `.5rem`
140
+
141
+ A compact app-owned container that needs clear but economical edge space.
142
+
143
+ | Case | When | Owner | Render |
144
+ | --- | --- | --- | --- |
145
+ | Case 1 | A small auxiliary strip whose four sides share one inset | `App` | `<aside className="p-2">` with `<Text size="sm">` |
146
+ | Case 2 | A compact bar of controls above app-owned content | `App` | `<div className="flex items-center gap-2 p-2">` |
147
+
148
+ Not this rule: separation between siblings inside the container belongs to the parent gap, not to
149
+ padding. Use the matching GAP rule.
150
+
151
+ ## PADDING-3 — `p-3` / `.75rem`
152
+
153
+ A dense but readable inset for a compact app-owned section or nested container.
154
+
155
+ | Case | When | Owner | Render |
156
+ | --- | --- | --- | --- |
157
+ | Case 1 | A nested app container that owns a boundary distinct from its parent's | `App` | `<aside className="p-3">` inside a `p-4` section |
158
+ | Case 2 | The inline inset of a tab strip or secondary navigation | `Tabs`, `Subnav` | Compose the component; no padding |
159
+ | Case 3 | A band side that meets a separator inside a flush surface | `—` | `<div className="px-4 py-3">` between two separators |
160
+ | Case 4 | The separator-facing side of a metric cell or list row | `—` | `<div className="p-4 pb-3">`, or `pt-3` when the separator is above |
161
+
162
+ Not this rule: nesting the same inset for the same boundary and purpose doubles it. Parent and child
163
+ padding add along the path from outer border to final content.
164
+
165
+ ## PADDING-4 — `p-4` / `1rem`
166
+
167
+ The standard equal inset for readable content inside one app-owned boundary.
168
+
169
+ | Case | When | Owner | Render |
170
+ | --- | --- | --- | --- |
171
+ | Case 1 | An app section that owns the full distance from its border to its content | `App` | `<section className="p-4">` with `<Heading level={2}>` |
172
+ | Case 2 | Content inside a card | `SurfaceCard` | Compose the card; no padding |
173
+ | Case 3 | A disclosure trigger and its expanded panel | `SurfaceAccordionCard` | Compose the card; no padding |
174
+ | Case 4 | An empty-state notice | `EmptyNotice` | Compose the notice; no padding |
175
+ | Case 5 | A fenced code block | `FencedCodeBlock` | Compose the block; no padding |
176
+ | Case 6 | A band side that meets the outer edge of a flush surface | `—` | `pt-4` on the first band, `pb-4` on the last |
177
+ | Case 7 | The inline sides of any band inside a flush surface | `—` | `px-4` on every band, unchanged by position |
178
+
179
+ ## PADDING-5 — `p-6` / `1.5rem`
180
+
181
+ A substantial app-owned section that is intentionally more spacious than the standard inset.
182
+
183
+ | Case | When | Owner | Render |
184
+ | --- | --- | --- | --- |
185
+ | Case 1 | A section whose four sides share one deliberately generous boundary decision | `App` | `<section className="p-6">` |
186
+ | Case 2 | A tab frame carrying the page-level inline inset | `Tabs` | `inset="page"` already sets `1.5rem` |
187
+
188
+ Not this rule: distance between child sections is a gap, not an inset. Use GAP-5.
189
+
190
+ ## PADDING-6 — `p-8` / `2rem`
191
+
192
+ A deliberately generous frame around a large, low-density app region.
193
+
194
+ | Case | When | Owner | Render |
195
+ | --- | --- | --- | --- |
196
+ | Case 1 | A page region that needs strong equal clearance on every side | `App` | `<section className="p-8">` |
197
+ | Case 2 | An empty or waiting region occupying most of the viewport | `App` | `<section className="p-8">` with `<EmptyNotice>` |
198
+
199
+ Not this rule: as a default for ordinary containers it wastes the viewport. Use PADDING-4.
200
+
201
+ ## Composite insets
202
+
203
+ `PADDING-0` through `PADDING-6` are the scale: one rule, one value. From `PADDING-7` onward the rules
204
+ are named recipes whose sides deliberately take different values. The number keeps counting, but it
205
+ stops meaning a position on the scale, so a composite rule never appears in the scale table and never
206
+ introduces a value of its own. Every side of a composite resolves to a base rule.
207
+
208
+ Append the next number when a genuinely new asymmetric pattern appears. State the reason each side
209
+ differs; a recipe without one is a product decision, not a rule.
210
+
211
+ ## PADDING-7 — Inset step at the wider breakpoint
212
+
213
+ One boundary keeps its meaning across widths but takes more room once the width allows it. The
214
+ compact value and the wide value are adjacent rules, never a jump of two steps, and the block axis
215
+ follows only where the boundary itself is the owner.
216
+
217
+ Composed from: inline sides of the surface `1rem` → `1.5rem` (PADDING-4 → PADDING-5); a block side
218
+ meeting the outer edge `1rem` → `1.5rem` (PADDING-4 → PADDING-5); a block side meeting a separator
219
+ `.75rem` at both widths (PADDING-3).
220
+
221
+ | Case | When | Owner | Render |
222
+ | --- | --- | --- | --- |
223
+ | Case 1 | A decision surface whose inline inset opens up on a wider viewport | `—` | `<div className="px-4 sm:px-6">` |
224
+ | Case 2 | The same surface's outer-edge block sides, stepping with it | `—` | `<div className="px-4 pt-4 pb-4 sm:px-6 sm:pt-6 sm:pb-6">` |
225
+ | Case 3 | A separator-facing side inside that surface | `—` | `pt-3` stays `.75rem` at both widths |
226
+
227
+ Not this rule: a separator side does not step, because the separator draws the same line at every
228
+ width.
229
+
230
+ ## PADDING-8 — Subordinate content indented at the inline start
231
+
232
+ Content that belongs under the row above it, rather than beside it, indents one step at the inline
233
+ start. Only the start edge carries the hierarchy. The end edge has no such meaning, so it stays
234
+ aligned with its parent and the reading measure is not squeezed from both sides.
235
+
236
+ Composed from: inline start one step above the surface inset, `1.5rem` against a `1rem` surface
237
+ (PADDING-5); inline end the surface inset, unchanged (PADDING-4); block sides whatever each side
238
+ meets, by the side-contact rule (PADDING-3, PADDING-4).
239
+
240
+ | Case | When | Owner | Render |
241
+ | --- | --- | --- | --- |
242
+ | Case 1 | A disclosure body that reads as the answer belonging to the trigger above it | `—` | `<div className="ps-6 pe-4 py-3">` |
243
+ | Case 2 | A nested group whose rows belong to a named parent row | `—` | Same recipe, one step per level of nesting |
244
+
245
+ Not this rule: indenting both sides, which centres the content and reads as a separate inset block
246
+ rather than as subordinate content.
247
+
248
+ Common's disclosure currently applies `1rem` on both inline sides, so the indented form has no
249
+ published path. Repairing it belongs to the disclosure component, not to an application override.
250
+
251
+ ## PADDING-9 — Block inset of a routed block at the wider breakpoint
252
+
253
+ A routed block gives its own `main` a vertical inset that steps up once the width allows it, while
254
+ the inline inset stays with `PageContainer` (`--grammar-page-inset`). The two values are adjacent
255
+ rules on the scale, never a jump of two steps, and only the block axis is written here.
256
+
257
+ Composed from: block sides of the routed block `1.5rem` → `2rem` (PADDING-5 → PADDING-6); inline sides
258
+ none, because `PageContainer` owns them (MEASURE-1).
259
+
260
+ | Case | When | Owner | Render |
261
+ | --- | --- | --- | --- |
262
+ | Case 1 | The `main` of a routed block that sits directly under the page shell | `App` | `<main className="py-6 sm:py-8">` |
263
+
264
+ Evidence, four blocks writing the same pair: `blocks/commerce/ProSubscriptionBlock/classNames.ts`
265
+ (`proPageClassName`), `blocks/learn/CoursePlaygroundCatalog/classNames.ts`,
266
+ `blocks/learn/PlaygroundSession/classNames.ts`, `blocks/learn/PlaygroundSetup/classNames.ts`.
267
+
268
+ Not this rule: an inline inset on the same element, which duplicates the page inset the container
269
+ already draws. Use MEASURE-1 and leave the inline sides alone.
270
+
271
+ ## Axis variants
272
+
273
+ `px-*` and `py-*` are not separate rules. They apply an existing rule to one axis when the two axes
274
+ carry different boundary decisions.
275
+
276
+ | Axis | Class | Meaning |
277
+ | --- | --- | --- |
278
+ | Inline | `px-*` | The chosen rule applies to logical start and end only |
279
+ | Block | `py-*` | The chosen rule applies to block start and end only |
280
+ | One side | `pt-*`, `pb-*`, `ps-*`, `pe-*` | The chosen rule applies to that side only |
281
+
282
+ Per-side classes are what the side-contact rule needs, because the two block sides of one band often
283
+ take different values. `px-4 pt-4 pb-3` is PADDING-4 on three sides and PADDING-3 on the side meeting
284
+ a separator, and every side still names its own case.
285
+
286
+ On the same element the narrower class wins the sides it names rather than adding, so `p-4 pb-3`
287
+ resolves to `1rem` on three sides and `.75rem` at the bottom. Between nested elements padding does
288
+ add, which is why a wrapper introduced only to change one side produces an inset nobody intended.
289
+
290
+ ## What this file does not decide
291
+
292
+ Distance between siblings is [Gap](gap.md). External offsets are [Margin](margin.md). The page inset
293
+ belongs to `PageContainer` and is not an application decision.