@toa.io/extensions.configuration 1.0.0-alpha.272 → 1.0.0-alpha.274

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 (522) hide show
  1. package/CHANGELOG.md +210 -0
  2. package/components/configuration.values/manifest.toa.yaml +158 -0
  3. package/components/configuration.values/source/create.ts +56 -0
  4. package/components/configuration.values/source/fetch.ts +24 -0
  5. package/components/configuration.values/source/get.ts +33 -0
  6. package/components/configuration.values/source/lib/map.test.ts +34 -0
  7. package/components/configuration.values/source/lib/map.ts +34 -0
  8. package/components/configuration.values/source/lib/resolve.ts +54 -0
  9. package/components/configuration.values/source/list.ts +19 -0
  10. package/components/configuration.values/tsconfig.json +9 -0
  11. package/cucumber.js +8 -0
  12. package/features/site/_app/immutable/asset.js +1 -0
  13. package/features/site/index.html +6 -0
  14. package/features/steps/UI.ts +88 -0
  15. package/features/steps/tsconfig.json +9 -0
  16. package/features/ui.feature +85 -0
  17. package/package.json +14 -7
  18. package/readme.md +160 -47
  19. package/schemas/annotation.cos.yaml +29 -1
  20. package/schemas/manifest.cos.yaml +9 -3
  21. package/source/Aspect.test.ts +84 -8
  22. package/source/Aspect.ts +59 -5
  23. package/source/Client.test.ts +104 -0
  24. package/source/Client.ts +258 -0
  25. package/source/Composition.ts +57 -0
  26. package/source/Factory.ts +28 -5
  27. package/source/Secret.test.ts +29 -0
  28. package/source/Secret.ts +29 -0
  29. package/source/UI.ts +197 -0
  30. package/source/configuration.test.ts +92 -39
  31. package/source/configuration.ts +30 -11
  32. package/source/const.ts +17 -0
  33. package/source/deployment.test.ts +80 -1
  34. package/source/deployment.ts +73 -24
  35. package/source/epoch.test.ts +26 -0
  36. package/source/epoch.ts +21 -0
  37. package/source/index.ts +2 -1
  38. package/transpiled/Aspect.d.ts +18 -4
  39. package/transpiled/Aspect.js +47 -3
  40. package/transpiled/Aspect.js.map +1 -1
  41. package/transpiled/Aspect.test.js +59 -9
  42. package/transpiled/Aspect.test.js.map +1 -1
  43. package/transpiled/Client.d.ts +61 -0
  44. package/transpiled/Client.js +173 -0
  45. package/transpiled/Client.js.map +1 -0
  46. package/transpiled/Client.test.d.ts +1 -0
  47. package/transpiled/Client.test.js +77 -0
  48. package/transpiled/Client.test.js.map +1 -0
  49. package/transpiled/Composition.d.ts +14 -0
  50. package/transpiled/Composition.js +43 -0
  51. package/transpiled/Composition.js.map +1 -0
  52. package/transpiled/Factory.d.ts +8 -2
  53. package/transpiled/Factory.js +17 -2
  54. package/transpiled/Factory.js.map +1 -1
  55. package/transpiled/Secret.d.ts +13 -0
  56. package/transpiled/Secret.js +26 -0
  57. package/transpiled/Secret.js.map +1 -0
  58. package/transpiled/Secret.test.d.ts +1 -0
  59. package/transpiled/Secret.test.js +26 -0
  60. package/transpiled/Secret.test.js.map +1 -0
  61. package/transpiled/UI.d.ts +25 -0
  62. package/transpiled/UI.js +186 -0
  63. package/transpiled/UI.js.map +1 -0
  64. package/transpiled/configuration.d.ts +7 -2
  65. package/transpiled/configuration.js +31 -13
  66. package/transpiled/configuration.js.map +1 -1
  67. package/transpiled/configuration.test.js +84 -37
  68. package/transpiled/configuration.test.js.map +1 -1
  69. package/transpiled/const.d.ts +11 -0
  70. package/transpiled/const.js +14 -0
  71. package/transpiled/const.js.map +1 -0
  72. package/transpiled/deployment.d.ts +10 -4
  73. package/transpiled/deployment.js +57 -21
  74. package/transpiled/deployment.js.map +1 -1
  75. package/transpiled/deployment.test.js +60 -0
  76. package/transpiled/deployment.test.js.map +1 -1
  77. package/transpiled/epoch.d.ts +2 -0
  78. package/transpiled/epoch.js +21 -0
  79. package/transpiled/epoch.js.map +1 -0
  80. package/transpiled/epoch.test.d.ts +1 -0
  81. package/transpiled/epoch.test.js +22 -0
  82. package/transpiled/epoch.test.js.map +1 -0
  83. package/transpiled/index.d.ts +2 -1
  84. package/transpiled/index.js +4 -1
  85. package/transpiled/index.js.map +1 -1
  86. package/transpiled/tsconfig.tsbuildinfo +1 -1
  87. package/ui/.agents/skills/antcn/SKILL.md +91 -0
  88. package/ui/.agents/skills/antcn/references/analytics.md +78 -0
  89. package/ui/.agents/skills/antcn/references/bridge.md +41 -0
  90. package/ui/.agents/skills/antcn/references/clipboard.md +23 -0
  91. package/ui/.agents/skills/antcn/references/dismissable.md +75 -0
  92. package/ui/.agents/skills/antcn/references/dropdown.md +153 -0
  93. package/ui/.agents/skills/antcn/references/fragments.md +29 -0
  94. package/ui/.agents/skills/antcn/references/fullscreen.md +157 -0
  95. package/ui/.agents/skills/antcn/references/geo.md +27 -0
  96. package/ui/.agents/skills/antcn/references/globals.md +31 -0
  97. package/ui/.agents/skills/antcn/references/grammatical-form.md +69 -0
  98. package/ui/.agents/skills/antcn/references/hints.md +44 -0
  99. package/ui/.agents/skills/antcn/references/hold.md +34 -0
  100. package/ui/.agents/skills/antcn/references/iam.md +117 -0
  101. package/ui/.agents/skills/antcn/references/input-form.md +34 -0
  102. package/ui/.agents/skills/antcn/references/locale.md +66 -0
  103. package/ui/.agents/skills/antcn/references/net.md +33 -0
  104. package/ui/.agents/skills/antcn/references/panel.md +44 -0
  105. package/ui/.agents/skills/antcn/references/passkeys.md +27 -0
  106. package/ui/.agents/skills/antcn/references/payments.md +99 -0
  107. package/ui/.agents/skills/antcn/references/realtime.md +69 -0
  108. package/ui/.agents/skills/antcn/references/scrollable.md +39 -0
  109. package/ui/.agents/skills/antcn/references/selector.md +71 -0
  110. package/ui/.agents/skills/antcn/references/shake.md +36 -0
  111. package/ui/.agents/skills/antcn/references/share.md +28 -0
  112. package/ui/.agents/skills/antcn/references/shell.md +139 -0
  113. package/ui/.agents/skills/antcn/references/stack.md +53 -0
  114. package/ui/.agents/skills/antcn/references/system.md +149 -0
  115. package/ui/.agents/skills/antcn/references/taptap.md +28 -0
  116. package/ui/.agents/skills/antcn/references/tools.md +68 -0
  117. package/ui/.agents/skills/antcn/references/transmission.md +96 -0
  118. package/ui/.agents/skills/shadcn-svelte/SKILL.md +227 -0
  119. package/ui/.agents/skills/shadcn-svelte/agents/openai.yml +5 -0
  120. package/ui/.agents/skills/shadcn-svelte/assets/shadcn-svelte-small.png +0 -0
  121. package/ui/.agents/skills/shadcn-svelte/assets/shadcn-svelte.png +0 -0
  122. package/ui/.agents/skills/shadcn-svelte/cli.md +166 -0
  123. package/ui/.agents/skills/shadcn-svelte/customization.md +213 -0
  124. package/ui/.agents/skills/shadcn-svelte/evals/evals.json +47 -0
  125. package/ui/.agents/skills/shadcn-svelte/rules/composition.md +244 -0
  126. package/ui/.agents/skills/shadcn-svelte/rules/forms.md +234 -0
  127. package/ui/.agents/skills/shadcn-svelte/rules/icons.md +107 -0
  128. package/ui/.agents/skills/shadcn-svelte/rules/styling.md +195 -0
  129. package/ui/.agents/skills/svas/SKILL.md +169 -0
  130. package/ui/.agents/skills/svas/references/patterns.md +95 -0
  131. package/ui/.agents/skills/svintl/SKILL.md +176 -0
  132. package/ui/.claude/settings.json +15 -0
  133. package/ui/.codex/hooks.json +15 -0
  134. package/ui/.cursor/hooks.json +11 -0
  135. package/ui/.env.example +1 -0
  136. package/ui/.prettierrc +9 -0
  137. package/ui/.vscode/extensions.json +7 -0
  138. package/ui/.vscode/settings.json +27 -0
  139. package/ui/AGENTS.md +51 -0
  140. package/ui/architecture.md +390 -0
  141. package/ui/components.json +20 -0
  142. package/ui/eslint.config.js +152 -0
  143. package/ui/features/base.ts +2 -0
  144. package/ui/features/boot.feature +5 -0
  145. package/ui/features/steps/authentication.ts +34 -0
  146. package/ui/features/steps/navigaton.ts +37 -0
  147. package/ui/features/steps/typing.ts +24 -0
  148. package/ui/package-lock.json +8173 -0
  149. package/ui/package.json +76 -0
  150. package/ui/playwright.config.ts +13 -0
  151. package/ui/skills-lock.json +30 -0
  152. package/ui/src/@/configuration/index.ts +1 -0
  153. package/ui/src/@/configuration/svc/create.ts +29 -0
  154. package/ui/src/@/configuration/svc/index.ts +3 -0
  155. package/ui/src/@/configuration/svc/net/Configuration.ts +18 -0
  156. package/ui/src/@/configuration/svc/net/index.ts +2 -0
  157. package/ui/src/@/configuration/svc/net/interface.ts +35 -0
  158. package/ui/src/@/configuration/svc/store.ts +14 -0
  159. package/ui/src/@/configuration/ui/Configurations.svelte +85 -0
  160. package/ui/src/@/configuration/ui/Configurations.ts +5 -0
  161. package/ui/src/@/configuration/ui/Create.svelte +64 -0
  162. package/ui/src/@/configuration/ui/Create.ts +7 -0
  163. package/ui/src/@/configuration/ui/Form.svelte +75 -0
  164. package/ui/src/@/configuration/ui/Form.ts +79 -0
  165. package/ui/src/@/configuration/ui/Row.svelte +44 -0
  166. package/ui/src/@/configuration/ui/Row.ts +9 -0
  167. package/ui/src/@/configuration/ui/Value.svelte +33 -0
  168. package/ui/src/@/configuration/ui/Value.ts +6 -0
  169. package/ui/src/@/configuration/ui/index.ts +9 -0
  170. package/ui/src/@/configuration/ui/intl/built.js +38 -0
  171. package/ui/src/@/configuration/ui/intl/context.yaml +51 -0
  172. package/ui/src/@/configuration/ui/intl/en-US.yaml +21 -0
  173. package/ui/src/@/configuration/ui/intl/index.ts +9 -0
  174. package/ui/src/@/configuration/ui/intl/types.ts +31 -0
  175. package/ui/src/@/configuration/ui/read.test.ts +75 -0
  176. package/ui/src/@/configuration/ui/read.ts +102 -0
  177. package/ui/src/@/configuration/ui/ui.test.ts +69 -0
  178. package/ui/src/@/configuration/ui/ui.ts +115 -0
  179. package/ui/src/@/iam/index.ts +1 -0
  180. package/ui/src/@/iam/rc.ts +22 -0
  181. package/ui/src/@/iam/svc/authenticated.ts +17 -0
  182. package/ui/src/@/iam/svc/basic.ts +23 -0
  183. package/ui/src/@/iam/svc/index.ts +10 -0
  184. package/ui/src/@/iam/svc/logout.ts +5 -0
  185. package/ui/src/@/iam/svc/named.ts +16 -0
  186. package/ui/src/@/iam/svc/net/Echo.ts +9 -0
  187. package/ui/src/@/iam/svc/net/basic/index.ts +1 -0
  188. package/ui/src/@/iam/svc/net/basic/interface.ts +15 -0
  189. package/ui/src/@/iam/svc/net/federation/index.ts +1 -0
  190. package/ui/src/@/iam/svc/net/federation/interface.ts +12 -0
  191. package/ui/src/@/iam/svc/net/index.ts +6 -0
  192. package/ui/src/@/iam/svc/net/interface.ts +17 -0
  193. package/ui/src/@/iam/svc/net/otp/index.ts +1 -0
  194. package/ui/src/@/iam/svc/net/otp/interface.ts +14 -0
  195. package/ui/src/@/iam/svc/net/passkeys/index.ts +1 -0
  196. package/ui/src/@/iam/svc/net/passkeys/interface.ts +12 -0
  197. package/ui/src/@/iam/svc/oidc/apple.ts +47 -0
  198. package/ui/src/@/iam/svc/oidc/authenticate.ts +62 -0
  199. package/ui/src/@/iam/svc/oidc/google.ts +45 -0
  200. package/ui/src/@/iam/svc/oidc/hello.ts +82 -0
  201. package/ui/src/@/iam/svc/oidc/index.ts +3 -0
  202. package/ui/src/@/iam/svc/oidc/nonce.ts +5 -0
  203. package/ui/src/@/iam/svc/oidc/providers.ts +28 -0
  204. package/ui/src/@/iam/svc/oidc/standard.ts +28 -0
  205. package/ui/src/@/iam/svc/otp.ts +18 -0
  206. package/ui/src/@/iam/svc/passkeys/create.ts +20 -0
  207. package/ui/src/@/iam/svc/passkeys/index.ts +2 -0
  208. package/ui/src/@/iam/svc/passkeys/login.ts +21 -0
  209. package/ui/src/@/iam/svc/store.ts +36 -0
  210. package/ui/src/@/iam/svc/sync.ts +18 -0
  211. package/ui/src/@/iam/svc/transfer.ts +11 -0
  212. package/ui/src/@/iam/svc/update.ts +8 -0
  213. package/ui/src/@/iam/ui/AccountLike.ts +4 -0
  214. package/ui/src/@/iam/ui/Authenticated.svelte +37 -0
  215. package/ui/src/@/iam/ui/Authenticated.ts +10 -0
  216. package/ui/src/@/iam/ui/Authentication.svelte +50 -0
  217. package/ui/src/@/iam/ui/Authentication.ts +9 -0
  218. package/ui/src/@/iam/ui/Authorized.svelte +32 -0
  219. package/ui/src/@/iam/ui/Authorized.ts +65 -0
  220. package/ui/src/@/iam/ui/Card.svelte +14 -0
  221. package/ui/src/@/iam/ui/Card.ts +7 -0
  222. package/ui/src/@/iam/ui/Refresh.svelte +39 -0
  223. package/ui/src/@/iam/ui/credentials/Credentials.svelte +26 -0
  224. package/ui/src/@/iam/ui/credentials/Credentials.ts +5 -0
  225. package/ui/src/@/iam/ui/credentials/Provider.svelte +24 -0
  226. package/ui/src/@/iam/ui/credentials/Provider.ts +5 -0
  227. package/ui/src/@/iam/ui/credentials/index.ts +1 -0
  228. package/ui/src/@/iam/ui/credentials/passkeys/Key.svelte +42 -0
  229. package/ui/src/@/iam/ui/credentials/passkeys/Key.ts +29 -0
  230. package/ui/src/@/iam/ui/credentials/passkeys/Manager.svelte +83 -0
  231. package/ui/src/@/iam/ui/credentials/passkeys/Manager.ts +5 -0
  232. package/ui/src/@/iam/ui/credentials/passkeys/Passkeys.svelte +39 -0
  233. package/ui/src/@/iam/ui/credentials/passkeys/Summary.svelte +27 -0
  234. package/ui/src/@/iam/ui/credentials/passkeys/Summary.ts +5 -0
  235. package/ui/src/@/iam/ui/credentials/passkeys/index.ts +1 -0
  236. package/ui/src/@/iam/ui/credentials/providers.ts +15 -0
  237. package/ui/src/@/iam/ui/credentials/transfer/Qr.svelte +24 -0
  238. package/ui/src/@/iam/ui/credentials/transfer/Qr.ts +3 -0
  239. package/ui/src/@/iam/ui/credentials/transfer/Transfer.svelte +48 -0
  240. package/ui/src/@/iam/ui/credentials/transfer/Transfer.ts +5 -0
  241. package/ui/src/@/iam/ui/credentials/transfer/index.ts +1 -0
  242. package/ui/src/@/iam/ui/index.ts +3 -0
  243. package/ui/src/@/iam/ui/intl/built.js +79 -0
  244. package/ui/src/@/iam/ui/intl/context.yaml +91 -0
  245. package/ui/src/@/iam/ui/intl/en-US.yaml +64 -0
  246. package/ui/src/@/iam/ui/intl/index.ts +10 -0
  247. package/ui/src/@/iam/ui/intl/types.ts +70 -0
  248. package/ui/src/@/iam/ui/oidc/Authentication.svelte +16 -0
  249. package/ui/src/@/iam/ui/oidc/Authentication.ts +5 -0
  250. package/ui/src/@/iam/ui/oidc/Button.svelte +36 -0
  251. package/ui/src/@/iam/ui/oidc/Button.ts +11 -0
  252. package/ui/src/@/iam/ui/oidc/Refresh.svelte +16 -0
  253. package/ui/src/@/iam/ui/oidc/icons/Apple.svelte +19 -0
  254. package/ui/src/@/iam/ui/oidc/icons/Google.svelte +31 -0
  255. package/ui/src/@/iam/ui/oidc/icons/index.ts +11 -0
  256. package/ui/src/@/iam/ui/oidc/index.ts +2 -0
  257. package/ui/src/@/iam/ui/passkey/Authentication.svelte +64 -0
  258. package/ui/src/@/iam/ui/passkey/Authentication.ts +8 -0
  259. package/ui/src/@/iam/ui/passkey/Create.svelte +53 -0
  260. package/ui/src/@/iam/ui/passkey/Create.ts +7 -0
  261. package/ui/src/@/iam/ui/passkey/Login.svelte +29 -0
  262. package/ui/src/@/iam/ui/passkey/Refresh.svelte +29 -0
  263. package/ui/src/@/iam/ui/passkey/index.ts +2 -0
  264. package/ui/src/@/iam/ui/password/Authentication.svelte +19 -0
  265. package/ui/src/@/iam/ui/password/Authentication.ts +8 -0
  266. package/ui/src/@/iam/ui/password/Form.svelte +151 -0
  267. package/ui/src/@/iam/ui/password/Form.ts +6 -0
  268. package/ui/src/@/iam/ui/password/Password.svelte +39 -0
  269. package/ui/src/@/iam/ui/password/Password.ts +6 -0
  270. package/ui/src/@/iam/ui/password/Refresh.svelte +5 -0
  271. package/ui/src/@/iam/ui/password/index.ts +2 -0
  272. package/ui/src/@/net/index.ts +1 -0
  273. package/ui/src/@/net/svc/index.ts +3 -0
  274. package/ui/src/@/net/svc/origin.ts +8 -0
  275. package/ui/src/@/net/svc/query.test.ts +45 -0
  276. package/ui/src/@/net/svc/query.ts +25 -0
  277. package/ui/src/@/passkeys/index.ts +1 -0
  278. package/ui/src/@/passkeys/svc/add.ts +15 -0
  279. package/ui/src/@/passkeys/svc/create.ts +58 -0
  280. package/ui/src/@/passkeys/svc/credentials/convert.ts +32 -0
  281. package/ui/src/@/passkeys/svc/credentials/create.ts +34 -0
  282. package/ui/src/@/passkeys/svc/credentials/get.ts +14 -0
  283. package/ui/src/@/passkeys/svc/credentials/index.ts +3 -0
  284. package/ui/src/@/passkeys/svc/credentials/key.ts +10 -0
  285. package/ui/src/@/passkeys/svc/get.ts +10 -0
  286. package/ui/src/@/passkeys/svc/index.ts +6 -0
  287. package/ui/src/@/passkeys/svc/net/CreationResponse.ts +15 -0
  288. package/ui/src/@/passkeys/svc/net/Passkey.ts +8 -0
  289. package/ui/src/@/passkeys/svc/net/RequestResponse.ts +12 -0
  290. package/ui/src/@/passkeys/svc/net/challenges/Options.ts +21 -0
  291. package/ui/src/@/passkeys/svc/net/challenges/index.ts +2 -0
  292. package/ui/src/@/passkeys/svc/net/challenges/interface.ts +16 -0
  293. package/ui/src/@/passkeys/svc/net/index.ts +4 -0
  294. package/ui/src/@/passkeys/svc/net/interface.ts +29 -0
  295. package/ui/src/@/passkeys/svc/remove.ts +13 -0
  296. package/ui/src/@/passkeys/svc/request.ts +50 -0
  297. package/ui/src/@/passkeys/svc/store.ts +13 -0
  298. package/ui/src/@/passkeys/svc/supported.ts +1 -0
  299. package/ui/src/@/passkeys/ui/aaguid.json +150 -0
  300. package/ui/src/@/realtime/events.ts +1 -0
  301. package/ui/src/@/realtime/index.ts +1 -0
  302. package/ui/src/@/realtime/rc.ts +13 -0
  303. package/ui/src/@/realtime/svc/connect.ts +67 -0
  304. package/ui/src/@/realtime/svc/events.ts +17 -0
  305. package/ui/src/@/realtime/svc/index.ts +5 -0
  306. package/ui/src/@/realtime/svc/net/Message.ts +6 -0
  307. package/ui/src/@/realtime/svc/net/index.ts +2 -0
  308. package/ui/src/@/realtime/svc/net/interface.ts +13 -0
  309. package/ui/src/@/realtime/svc/reset.ts +5 -0
  310. package/ui/src/@/realtime/svc/status.ts +12 -0
  311. package/ui/src/@/realtime/svc/store.ts +30 -0
  312. package/ui/src/@/realtime/svc/time.ts +15 -0
  313. package/ui/src/app.d.ts +20 -0
  314. package/ui/src/app.html +13 -0
  315. package/ui/src/config/index.ts +70 -0
  316. package/ui/src/lib/assets/favicon.svg +1 -0
  317. package/ui/src/lib/components/clipboard/Clipboard.svelte +63 -0
  318. package/ui/src/lib/components/clipboard/Clipboard.ts +12 -0
  319. package/ui/src/lib/components/clipboard/index.ts +1 -0
  320. package/ui/src/lib/components/dismissable/Dismissable.svelte +81 -0
  321. package/ui/src/lib/components/dismissable/Dismissable.ts +7 -0
  322. package/ui/src/lib/components/dismissable/index.ts +1 -0
  323. package/ui/src/lib/components/dropdown/Back.svelte +14 -0
  324. package/ui/src/lib/components/dropdown/Back.ts +3 -0
  325. package/ui/src/lib/components/dropdown/Content.svelte +76 -0
  326. package/ui/src/lib/components/dropdown/Content.ts +13 -0
  327. package/ui/src/lib/components/dropdown/Context.ts +18 -0
  328. package/ui/src/lib/components/dropdown/Group.svelte +24 -0
  329. package/ui/src/lib/components/dropdown/Group.ts +8 -0
  330. package/ui/src/lib/components/dropdown/GroupContext.ts +15 -0
  331. package/ui/src/lib/components/dropdown/Item.svelte +31 -0
  332. package/ui/src/lib/components/dropdown/Item.ts +5 -0
  333. package/ui/src/lib/components/dropdown/Layer.svelte +11 -0
  334. package/ui/src/lib/components/dropdown/Layer.ts +7 -0
  335. package/ui/src/lib/components/dropdown/Root.svelte +88 -0
  336. package/ui/src/lib/components/dropdown/Root.ts +6 -0
  337. package/ui/src/lib/components/dropdown/Separator.svelte +13 -0
  338. package/ui/src/lib/components/dropdown/Separator.ts +5 -0
  339. package/ui/src/lib/components/dropdown/Trigger.svelte +33 -0
  340. package/ui/src/lib/components/dropdown/Trigger.ts +5 -0
  341. package/ui/src/lib/components/dropdown/index.ts +8 -0
  342. package/ui/src/lib/components/fullscreen/Fullscreen.svelte +97 -0
  343. package/ui/src/lib/components/fullscreen/Fullscreen.ts +18 -0
  344. package/ui/src/lib/components/fullscreen/Overlay.svelte +15 -0
  345. package/ui/src/lib/components/fullscreen/Overlay.ts +7 -0
  346. package/ui/src/lib/components/fullscreen/index.ts +2 -0
  347. package/ui/src/lib/components/hold/Hold.svelte +133 -0
  348. package/ui/src/lib/components/hold/Hold.ts +23 -0
  349. package/ui/src/lib/components/hold/index.ts +1 -0
  350. package/ui/src/lib/components/scrollable/Scrollable.svelte +49 -0
  351. package/ui/src/lib/components/scrollable/Scrollable.ts +117 -0
  352. package/ui/src/lib/components/scrollable/index.ts +2 -0
  353. package/ui/src/lib/components/shake/Shake.svelte +62 -0
  354. package/ui/src/lib/components/shake/Shake.ts +7 -0
  355. package/ui/src/lib/components/shake/index.ts +1 -0
  356. package/ui/src/lib/components/share/Share.svelte +58 -0
  357. package/ui/src/lib/components/share/Share.ts +9 -0
  358. package/ui/src/lib/components/share/index.ts +1 -0
  359. package/ui/src/lib/components/shell/Attention.svelte +11 -0
  360. package/ui/src/lib/components/shell/Attention.ts +6 -0
  361. package/ui/src/lib/components/shell/Header.svelte +18 -0
  362. package/ui/src/lib/components/shell/Header.ts +7 -0
  363. package/ui/src/lib/components/shell/Screen.svelte +28 -0
  364. package/ui/src/lib/components/shell/Screen.ts +11 -0
  365. package/ui/src/lib/components/shell/Sticky.svelte +23 -0
  366. package/ui/src/lib/components/shell/Sticky.ts +8 -0
  367. package/ui/src/lib/components/shell/Underlay.svelte +21 -0
  368. package/ui/src/lib/components/shell/Underlay.ts +6 -0
  369. package/ui/src/lib/components/shell/index.ts +6 -0
  370. package/ui/src/lib/components/shell/nav/Actions.svelte +31 -0
  371. package/ui/src/lib/components/shell/nav/Actions.ts +16 -0
  372. package/ui/src/lib/components/shell/nav/Back.svelte +20 -0
  373. package/ui/src/lib/components/shell/nav/Back.ts +9 -0
  374. package/ui/src/lib/components/shell/nav/Bar.svelte +24 -0
  375. package/ui/src/lib/components/shell/nav/Bar.ts +3 -0
  376. package/ui/src/lib/components/shell/nav/Button.svelte +64 -0
  377. package/ui/src/lib/components/shell/nav/Button.ts +7 -0
  378. package/ui/src/lib/components/shell/nav/Nav.svelte +62 -0
  379. package/ui/src/lib/components/shell/nav/Nav.ts +35 -0
  380. package/ui/src/lib/components/shell/nav/Return.svelte +29 -0
  381. package/ui/src/lib/components/shell/nav/Return.ts +15 -0
  382. package/ui/src/lib/components/shell/nav/Sections.svelte +58 -0
  383. package/ui/src/lib/components/shell/nav/Sections.ts +6 -0
  384. package/ui/src/lib/components/shell/nav/Toolbar.svelte +73 -0
  385. package/ui/src/lib/components/shell/nav/Toolbar.ts +3 -0
  386. package/ui/src/lib/components/shell/nav/history.ts +36 -0
  387. package/ui/src/lib/components/shell/nav/index.ts +5 -0
  388. package/ui/src/lib/components/shell/nav/store.ts +24 -0
  389. package/ui/src/lib/components/ui/alert/alert-action.svelte +20 -0
  390. package/ui/src/lib/components/ui/alert/alert-description.svelte +23 -0
  391. package/ui/src/lib/components/ui/alert/alert-title.svelte +23 -0
  392. package/ui/src/lib/components/ui/alert/alert.svelte +43 -0
  393. package/ui/src/lib/components/ui/alert/index.ts +17 -0
  394. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +27 -0
  395. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +27 -0
  396. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +32 -0
  397. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
  398. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +23 -0
  399. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
  400. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-media.svelte +20 -0
  401. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +17 -0
  402. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte +7 -0
  403. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
  404. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
  405. package/ui/src/lib/components/ui/alert-dialog/alert-dialog.svelte +7 -0
  406. package/ui/src/lib/components/ui/alert-dialog/index.ts +40 -0
  407. package/ui/src/lib/components/ui/badge/badge.svelte +49 -0
  408. package/ui/src/lib/components/ui/badge/index.ts +2 -0
  409. package/ui/src/lib/components/ui/button/button.svelte +82 -0
  410. package/ui/src/lib/components/ui/button/index.ts +17 -0
  411. package/ui/src/lib/components/ui/button-group/button-group-separator.svelte +23 -0
  412. package/ui/src/lib/components/ui/button-group/button-group-text.svelte +28 -0
  413. package/ui/src/lib/components/ui/button-group/button-group.svelte +46 -0
  414. package/ui/src/lib/components/ui/button-group/index.ts +15 -0
  415. package/ui/src/lib/components/ui/card/card-action.svelte +23 -0
  416. package/ui/src/lib/components/ui/card/card-content.svelte +20 -0
  417. package/ui/src/lib/components/ui/card/card-description.svelte +20 -0
  418. package/ui/src/lib/components/ui/card/card-footer.svelte +20 -0
  419. package/ui/src/lib/components/ui/card/card-header.svelte +23 -0
  420. package/ui/src/lib/components/ui/card/card-title.svelte +20 -0
  421. package/ui/src/lib/components/ui/card/card.svelte +22 -0
  422. package/ui/src/lib/components/ui/card/index.ts +25 -0
  423. package/ui/src/lib/components/ui/checkbox/checkbox.svelte +39 -0
  424. package/ui/src/lib/components/ui/checkbox/index.ts +6 -0
  425. package/ui/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
  426. package/ui/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  427. package/ui/src/lib/components/ui/collapsible/collapsible.svelte +20 -0
  428. package/ui/src/lib/components/ui/collapsible/index.ts +13 -0
  429. package/ui/src/lib/components/ui/input/index.ts +7 -0
  430. package/ui/src/lib/components/ui/input/input.svelte +48 -0
  431. package/ui/src/lib/components/ui/input-otp/index.ts +15 -0
  432. package/ui/src/lib/components/ui/input-otp/input-otp-group.svelte +20 -0
  433. package/ui/src/lib/components/ui/input-otp/input-otp-separator.svelte +27 -0
  434. package/ui/src/lib/components/ui/input-otp/input-otp-slot.svelte +31 -0
  435. package/ui/src/lib/components/ui/input-otp/input-otp.svelte +23 -0
  436. package/ui/src/lib/components/ui/item/index.ts +34 -0
  437. package/ui/src/lib/components/ui/item/item-actions.svelte +20 -0
  438. package/ui/src/lib/components/ui/item/item-content.svelte +23 -0
  439. package/ui/src/lib/components/ui/item/item-description.svelte +23 -0
  440. package/ui/src/lib/components/ui/item/item-footer.svelte +20 -0
  441. package/ui/src/lib/components/ui/item/item-group.svelte +21 -0
  442. package/ui/src/lib/components/ui/item/item-header.svelte +20 -0
  443. package/ui/src/lib/components/ui/item/item-media.svelte +42 -0
  444. package/ui/src/lib/components/ui/item/item-separator.svelte +19 -0
  445. package/ui/src/lib/components/ui/item/item-title.svelte +20 -0
  446. package/ui/src/lib/components/ui/item/item.svelte +61 -0
  447. package/ui/src/lib/components/ui/kbd/index.ts +10 -0
  448. package/ui/src/lib/components/ui/kbd/kbd-group.svelte +20 -0
  449. package/ui/src/lib/components/ui/kbd/kbd.svelte +23 -0
  450. package/ui/src/lib/components/ui/label/index.ts +7 -0
  451. package/ui/src/lib/components/ui/label/label.svelte +20 -0
  452. package/ui/src/lib/components/ui/progress/index.ts +7 -0
  453. package/ui/src/lib/components/ui/progress/progress.svelte +27 -0
  454. package/ui/src/lib/components/ui/select/index.ts +37 -0
  455. package/ui/src/lib/components/ui/select/select-content.svelte +45 -0
  456. package/ui/src/lib/components/ui/select/select-group-heading.svelte +21 -0
  457. package/ui/src/lib/components/ui/select/select-group.svelte +17 -0
  458. package/ui/src/lib/components/ui/select/select-item.svelte +40 -0
  459. package/ui/src/lib/components/ui/select/select-label.svelte +20 -0
  460. package/ui/src/lib/components/ui/select/select-portal.svelte +7 -0
  461. package/ui/src/lib/components/ui/select/select-scroll-down-button.svelte +20 -0
  462. package/ui/src/lib/components/ui/select/select-scroll-up-button.svelte +20 -0
  463. package/ui/src/lib/components/ui/select/select-separator.svelte +18 -0
  464. package/ui/src/lib/components/ui/select/select-trigger.svelte +29 -0
  465. package/ui/src/lib/components/ui/select/select.svelte +11 -0
  466. package/ui/src/lib/components/ui/separator/index.ts +7 -0
  467. package/ui/src/lib/components/ui/separator/separator.svelte +23 -0
  468. package/ui/src/lib/components/ui/spinner/index.ts +1 -0
  469. package/ui/src/lib/components/ui/spinner/spinner.svelte +18 -0
  470. package/ui/src/lib/components/ui/tabs/index.ts +18 -0
  471. package/ui/src/lib/components/ui/tabs/tabs-content.svelte +17 -0
  472. package/ui/src/lib/components/ui/tabs/tabs-list.svelte +40 -0
  473. package/ui/src/lib/components/ui/tabs/tabs-trigger.svelte +23 -0
  474. package/ui/src/lib/components/ui/tabs/tabs.svelte +19 -0
  475. package/ui/src/lib/components/ui/textarea/index.ts +7 -0
  476. package/ui/src/lib/components/ui/textarea/textarea.svelte +22 -0
  477. package/ui/src/lib/intl/bcp.ts +25 -0
  478. package/ui/src/lib/intl/built.js +18 -0
  479. package/ui/src/lib/intl/context.yaml +18 -0
  480. package/ui/src/lib/intl/en-US.yaml +6 -0
  481. package/ui/src/lib/intl/index.ts +65 -0
  482. package/ui/src/lib/intl/types.ts +19 -0
  483. package/ui/src/lib/tools/ago.ts +10 -0
  484. package/ui/src/lib/tools/assert.ts +3 -0
  485. package/ui/src/lib/tools/cap.ts +5 -0
  486. package/ui/src/lib/tools/clicks.ts +25 -0
  487. package/ui/src/lib/tools/contextmenu.ts +19 -0
  488. package/ui/src/lib/tools/convert.ts +32 -0
  489. package/ui/src/lib/tools/currency.test.ts +10 -0
  490. package/ui/src/lib/tools/currency.ts +55 -0
  491. package/ui/src/lib/tools/date.test.ts +21 -0
  492. package/ui/src/lib/tools/date.ts +35 -0
  493. package/ui/src/lib/tools/delay.ts +7 -0
  494. package/ui/src/lib/tools/image.ts +39 -0
  495. package/ui/src/lib/tools/index.ts +20 -0
  496. package/ui/src/lib/tools/location.ts +41 -0
  497. package/ui/src/lib/tools/metronome.ts +11 -0
  498. package/ui/src/lib/tools/mq.ts +84 -0
  499. package/ui/src/lib/tools/onsubmit.ts +21 -0
  500. package/ui/src/lib/tools/random.ts +15 -0
  501. package/ui/src/lib/tools/search.ts +25 -0
  502. package/ui/src/lib/tools/timeout.ts +26 -0
  503. package/ui/src/lib/tools/transition.ts +207 -0
  504. package/ui/src/lib/tools/types.ts +3 -0
  505. package/ui/src/lib/tools/uuid.test.ts +28 -0
  506. package/ui/src/lib/tools/uuid.ts +9 -0
  507. package/ui/src/lib/typeset.css +502 -0
  508. package/ui/src/lib/utils.ts +12 -0
  509. package/ui/src/routes/(private)/+layout.svelte +112 -0
  510. package/ui/src/routes/(private)/+page.svelte +7 -0
  511. package/ui/src/routes/(private)/[component]/+page.svelte +77 -0
  512. package/ui/src/routes/+layout.svelte +25 -0
  513. package/ui/src/routes/+layout.ts +14 -0
  514. package/ui/src/routes/layout.css +232 -0
  515. package/ui/static/robots.txt +3 -0
  516. package/ui/svelte.config.js +36 -0
  517. package/ui/tools/feat.js +43 -0
  518. package/ui/tools/hooks/README.md +13 -0
  519. package/ui/tools/hooks/guard-intl.sh +40 -0
  520. package/ui/tools/shad.js +7 -0
  521. package/ui/tsconfig.json +20 -0
  522. package/ui/vite.config.ts +8 -0
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: antcn
3
+ description: Ready-to-install Svelte components and utils. You MUST use these components to compose your UI unless you have a very good reason to write your own.
4
+ ---
5
+
6
+ # antcn — Svelte component registry
7
+
8
+ Svelte components and utilities at `https://cn.ants.dev`.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ npx shadcn-svelte add -y -o https://cn.ants.dev/r/<name>.json
14
+ ```
15
+
16
+ If the project has no `components.json`, run `npx shadcn-svelte init` first.
17
+
18
+ ## Catalog
19
+
20
+ **Before building any Svelte component or utility, scan this catalog.** If something here fits — even loosely — install it and adapt it to the project instead of writing your own. These are the building blocks; reuse beats rebuild.
21
+
22
+ One line per item below. **Before installing, read its full reference at `references/<name>.md`** (bundled next to this skill — a plain local file read, no network): props/API, dependencies, and post-install wiring to use it correctly in one pass. The one-liner is for recognizing a match; the reference is the documentation you act on. The CLI merges CSS but not layouts, so the reference also lists the manual steps it can't do for you (e.g. `onNavigate(navigate)` in the root layout, peer npm packages).
23
+
24
+ Each one-liner describes **what the item lets you do** and **when to reach for it**.
25
+
26
+ `tools` and the shared global CSS usually arrive **transitively** via another component's `registryDependencies` (e.g. `hold` pulls `tools`) — install them standalone only when you want the utility set or theme tokens on their own.
27
+
28
+ The catalog has two tracks: **Components** (presentational UI blocks, inline English, no backend) and **Solutions** (vertical app-domain slices that ship service logic, UI, and their own i18n, installed under your `@/<name>`).
29
+
30
+ ## Components
31
+
32
+ - **shell** — mobile-first app shell with bottom navigation, section tabs, nested-route back behavior, and slots for headers and toolbars. Reach for it when building a PWA-style layout with fixed nav and contextual actions.
33
+ - **stack** — collapsible card stack with expand/collapse animation and an optional toolbar. Reach for it when several cards should peek behind the first and fan out on tap.
34
+ - **scrollable** — horizontal snap scroller with scroll-to-index, bleed-to-viewport, and infinite loop. Reach for carousels, pickers, and edge-to-edge horizontal lists.
35
+ - **panel** — tappable list row with left/right/icon slots and swipe-reveal trailing actions. Reach for contact lists, settings rows, or anywhere a row needs inline actions.
36
+ - **fullscreen** — tap-to-expand overlay with morph animation, optional toolbar, and programmatic show/hide. Reach for it when a thumbnail or card should open into an immersive fullscreen layer.
37
+ - **dismissable** — swipe-to-dismiss wrapper with optional slide-out animation and programmatic dismiss/remove. Reach for notification stacks, banners, or flick-away cards.
38
+ - **dropdown** — action menu with anchor positioning, morph animation, and nested layers. Reach for toolbar overflow, contextual actions, or multi-step pickers.
39
+ - **input-form** — inline text field that auto-saves on blur or Enter when the value changed. Reach for editable display names and other single-field edits without a save button.
40
+ - **hold** — hold-to-confirm button for dangerous actions: fires only after a brief hold, with countdown feedback. Reach for it instead of a confirmation dialog when inline confirmation is enough.
41
+ - **clipboard** — copy-to-clipboard button with loading and success states; supports async text. Reach for copying IDs, invite links, or other strings without a separate input.
42
+ - **share** — share button with clipboard fallback when native share is unavailable. Reach for invite links and other share payloads on mobile-first flows.
43
+ - **selector** — card-style single- or multi-choice picker with radio or checkbox indicators. Reach for plan pickers, settings toggles, or tappable option lists.
44
+ - **taptap** — multi-tap gate that fires only after N consecutive taps within a gap. Reach for accidental-tap protection on destructive or rare actions.
45
+ - **shake** — brief horizontal shake on a bound wrapper. Reach for obvious validation failures on small forms where error copy adds little value.
46
+ - **tools** — shared helpers for dates, currency, media queries, view transitions, navigation glue, and common browser utilities. Reach for the same helper set antcn components rely on.
47
+ - **globals** — shared theme tokens and Tailwind globals for constructive color, standalone/tim variants, and morph transitions. Reach for consistent styling across antcn components.
48
+
49
+ <!--
50
+ Fixed catalog order: tools, globals, hold, shell. Append one line per newly registered item as `**<name>** — <capabilities>. Reach for <use case>.` Capabilities only — what the consumer can do with it, not how it's built. Avoid: internal structure (sub-components, exports, file layout), dependencies (shadcn, sibling items, npm/libs), function/store/type names, props, install commands, transitively-pulled notes. Those live in references/<name>.md (auto-generated from the item README by the reference-bundler).
51
+ -->
52
+
53
+ ## Solutions
54
+
55
+ Vertical app-domain slices (auth, notifications, realtime, …) that ship service logic, UI, and their own i18n. Install the same way; the whole `svc/` + `ui/` + `ui/intl/` tree lands under your `@/<name>`:
56
+
57
+ ```sh
58
+ npx shadcn-svelte add -y -o https://cn.ants.dev/r/<name>.json
59
+ ```
60
+
61
+ Solutions that ship i18n read a **host svintl mount** at `$lib/intl` — the consumer owns it (the CLI can't scaffold it). Set it up once: run `npx intl hola`, then have its `index.ts` export a persisted `selected` writable plus `locale`, `locales`, `dictionaries`, and the `Grammar` type. Each Solution uses a subset, and its bundled `ui/intl/` copy derives from this host.
62
+
63
+ Then reconcile the Solution's dictionary to your locale set:
64
+
65
+ ```sh
66
+ npx intl import <name> src/@/<name>/ui/intl
67
+ ```
68
+
69
+ Each Solution's reference (`references/<name>.md`) lists the `$config` fields it needs and any consumer wiring (e.g. interfaces to extend). Sibling Solutions arrive automatically via `local:` dependencies.
70
+
71
+ ### Grammatical form (cross-cutting i18n)
72
+
73
+ Some languages word a message by the subject's grammatical gender (`{name} added` vs Russian `добавил`/`добавила`). This is a translation concern that spans the svintl host, the account, and your UI — owned by no single Solution. Enable it once with `npx intl genders he she none` (the listed tokens become a generated `Grammar` union in `$lib/intl`; the last is the neutral/fallback). Gender-varying dictionary entries then become functions taking the gender as their **last** argument — `(name, gender) => …`, or just `(gender) => …` when the phrase has no other placeholders. The subject's gender is stored per account as `grammar?: Grammar | null` (antcn's `iam` carries it on `Echo`); pass _that account's_ value into the dictionary function — the subject's gender, not the viewer's. Full mechanics, consumption modes, and examples: `references/grammatical-form.md`.
74
+
75
+ <!--
76
+ Append one line per registered Solution as `**<name>** — <capabilities>. Reach for <use case>.` Same rule as Components — consumer-facing capabilities, not internal structure, dependencies, API names, or wiring. Details live in references/<name>.md.
77
+ -->
78
+
79
+ - **net** — shared API client and query helpers for declaring backend resources. Reach for any feature or Solution that talks to your API.
80
+ - **passkeys** — register, list, and revoke passkeys for the signed-in account. Reach for passwordless login or a passkey manager screen.
81
+ - **iam** — complete sign-in and account management: password, OTP, passkeys, Google/Apple OIDC, session sync, expiry refresh, and credential management including cross-device QR transfer. Reach for a full authentication surface.
82
+ - **locale** — let users pick their language via a horizontal scroller of native names or a compact settings dropdown. Reach for in-app locale switching.
83
+ - **hints** — track per-user onboarding hints: show once, snooze, or dismiss permanently. Reach for first-run tips, permission prompts, and one-shot nudges.
84
+ - **realtime** — live server-pushed events with auto-reconnect tied to sign-in, a debug dashboard, and server-clock sync. Reach for UI that must react to backend push in real time.
85
+ - **transmission** — push notification permission, subscription, per-domain toggles, and ready-made permission/scopes UI. Reach for web or mobile push with user-configurable topics.
86
+ - **analytics** — GA4/GTM event tracking and a cookie-consent banner. Reach for analytics or ads conversion measurement with GDPR-style consent.
87
+ - **bridge** — talk to a native app from the WebView: detect platform, drive native purchases, and receive native push. Reach for hybrid app integration.
88
+ - **fragments** — single-use URL hash tokens for deep links and payment redirects that won't re-fire on reload. Reach for one-time return URLs.
89
+ - **geo** — look up the visitor's consent zone to decide whether a cookie banner is required. Reach for privacy-jurisdiction gating before loading trackers.
90
+ - **payments** — subscription paywall with tier selection, benefits, and checkout via App Store, Google Play, or Stripe. Reach for selling subscriptions in-app.
91
+ - **system** — user-controlled PWA updates surfaced as a version card that tracks the running build, shows live download progress, and offers a one-tap install once an update is ready, plus a browsable localized changelog history the app version derives from, an app-wide escape from insecure in-app webviews out to the system browser, and CI that auto-generates translated release notes and publishes tagged releases on merge. Reach for the PWA update, release-notes, and webview-escape layer of an installed app.
@@ -0,0 +1,78 @@
1
+ # analytics
2
+
3
+ Consent-first GA4 + Google Tag Manager analytics. A typed `track()` dual-dispatches to a GA4 property (via a `gtag` shim) and/or a GTM container; a Consent Mode v2 cookie banner collects consent before any non-essential storage, shown only to visitors inside a prior-consent jurisdiction (resolved through `geo`) and auto-granting elsewhere. Events are an open interface each domain owns and augments.
4
+
5
+ ## Environment
6
+
7
+ Configured through `VITE_*` env vars (read at build via `import.meta.env`, so no custom `envPrefix` is needed). Set whichever delivery you use — at least one `id` must be present or the whole stack no-ops:
8
+
9
+ | Var | Example | Notes |
10
+ | ------------------ | -------------- | --------------------------------------------------------------------- |
11
+ | `VITE_GA_ID` | `G-XXXXXXXXXX` | GA4 Measurement ID. When set, events go to GA4 via `gtag` (takes priority). |
12
+ | `VITE_GTM_ID` | `GTM-XXXXXXX` | GTM container ID. Used for `track()` only when `VITE_GA_ID` is unset; otherwise the container still sees gtag's push as a Custom Event. |
13
+ | `VITE_GTM_AUTH` | `abc123…` | Optional — GTM Environment snippet auth param. Empty for the Live environment. |
14
+ | `VITE_GTM_PREVIEW` | `env-3` | Optional — GTM Environment snippet preview param. Empty for Live. |
15
+
16
+ ## Notes
17
+
18
+ - **Bootstrap with `rc()`.** Run it once on app start (see Usage). It emits the `consent default` + `platform` user-property commands, resolves the consent zone, then either auto-grants (out of zone), re-applies a stored choice, or opens the banner. It no-ops when neither id is set.
19
+ - **Page-view title.** Pass `<Analytics title={…}>` the resolved page title so the `page_view` event isn't subject to the SPA `document.title` race.
20
+ - **Re-opening consent.** `<Manage>` is an optional "Cookie settings" button (place it in a footer or settings row); it renders only inside a prior-consent zone once a choice has been made.
21
+ - **Banner copy.** Ships its own svintl mount in the registry's four locales with neutral copy. After install, reconcile it to your locale set: `npx intl import analytics src/@/analytics/ui/intl`. The body links to `/privacy/` — point it at your policy via the mount.
22
+ - **Native iOS shell.** `settle('ios_shell')` resolves to `denied` (App Store privacy expectations); adjust the platform branch in `rc.ts` if your wrapper differs.
23
+
24
+ ## Usage
25
+
26
+ Bootstrap once on app start — resolves the consent zone and opens the banner when consent is required:
27
+
28
+ ```ts
29
+ import { rc } from '@/analytics/rc'
30
+
31
+ onMount(rc)
32
+ ```
33
+
34
+ Mount the loaders and banner near the app root. `<Analytics>` injects the gtag.js / gtm.js loaders and fires a `page_view` on every SPA navigation; `<Consent>` renders the banner while consent is pending:
35
+
36
+ ```svelte
37
+ <script lang="ts">
38
+ import { Analytics, Consent } from '@/analytics/ui'
39
+ import { page } from '$app/state'
40
+ </script>
41
+
42
+ <svelte:head>
43
+ <Analytics title={page.data.title ?? document.title} />
44
+ </svelte:head>
45
+
46
+ <Consent />
47
+ ```
48
+
49
+ Declare your domain's events by augmenting the open `Events` interface — keeping event names and parameter types owned by the domain that fires them (dependency direction domain → analytics). `@/analytics` itself owns only `page_view` and `purchase`:
50
+
51
+ ```ts
52
+ // src/@/your-domain/svc/events.ts
53
+ declare module '@/analytics' {
54
+ interface Events {
55
+ sign_up: { method: 'passkey' | 'password' | 'google' | 'apple' }
56
+ }
57
+ }
58
+ ```
59
+
60
+ Then fire it, type-checked, from anywhere:
61
+
62
+ ```ts
63
+ import { track } from '@/analytics'
64
+
65
+ track('sign_up', { method: 'passkey' })
66
+ ```
67
+
68
+ ## Props
69
+
70
+ ### `<Analytics>`
71
+
72
+ | Prop | Type | Default | Notes |
73
+ | ------- | -------- | ------- | ---------------------------------------------------------------------------- |
74
+ | `title` | `string` | — | Resolved page title sent with each `page_view` (avoids the SPA title race). |
75
+
76
+ ### `<Consent>` / `<Manage>`
77
+
78
+ No props — both read the consent stores directly. `<Consent>` shows the banner while consent is pending; `<Manage>` renders only inside a prior-consent zone once a choice has been made.
@@ -0,0 +1,41 @@
1
+ # bridge
2
+
3
+ ## Notes
4
+
5
+ You build the native side. It is reachable through two contracts the CLI cannot wire for you:
6
+
7
+ - **The message channel.** Your native host receives requests on `window.webkit.messageHandlers.bridge` and must post each reply/event back as a `window` `'bridge'` `CustomEvent` (a `Detail`). `available()` is `true` only inside such a host; in a plain browser `platform`/`version` are `null` and `semver()` is `false`, so gate any request on `available()` (a request fired with no host never gets a reply).
8
+ - **The detection markers** — change these to match your wrapper:
9
+ - **Android package id** (`svc/bridge.ts`) — detected by `document.referrer.startsWith('android-app://com.example.twa')`. Replace the placeholder `com.example.twa` with your Trusted Web Activity package id.
10
+ - **`PWAShell` UA marker** (`svc/bridge.ts`) — iOS is detected by a `PWAShell` token in `navigator.userAgent`, with the version parsed from `PWAShell/<version>`. Have your iOS WebView host append the same marker (`… PWAShell/1.2.3`), or change both regexes to your own.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { bridge } from '@/bridge'
16
+
17
+ if (bridge.platform === 'ios' && bridge.semver('>=1.2.0')) {
18
+ if (await bridge.purchases.available()) {
19
+ const products = await bridge.purchases.products(['premium_yearly'])
20
+ // …drive a purchase, then bridge.purchases.finish(transactionID)
21
+ }
22
+ }
23
+
24
+ bridge.transmission.onNotificationClick((n) => {
25
+ if (n.action) location.assign(n.action)
26
+ })
27
+ ```
28
+
29
+ ## API
30
+
31
+ | Symbol | Description |
32
+ | ------------------------------- | -------------------------------------------------------------------------------------------- |
33
+ | `bridge.platform` | `'ios' \| 'android' \| null` — native host detected from UA / referrer; `null` in a browser. |
34
+ | `bridge.version` | Native host version string parsed from the `PWAShell/<version>` UA marker, else `null`. |
35
+ | `bridge.semver(pattern)` | `true` when `version` satisfies the semver `pattern`; `false` when there is no native host. |
36
+ | `bridge.available()` | `true` when the native message handler is reachable in the current environment. |
37
+ | `bridge.purchases` | StoreKit operations: `available()`, `products(ids)`, `purchase(id, token)`, `restore()`, `manage()`, `finish(txId)`. |
38
+ | `bridge.transmission` | Push channel: `address()`, `permission()`, `request()`, `delete()`, `onNotification(cb)`, `onNotificationClick(cb)`. |
39
+ | `on(key, cb)` / `send(label, args?)` | Low-level transport: subscribe to a reply id / event label, or fire-and-forget a message. |
40
+
41
+ Every `purchases`/`transmission` request resolves to its typed result **or** an `Error` (a native-side failure) — narrow with `instanceof Error` before use.
@@ -0,0 +1,23 @@
1
+ # Clipboard
2
+
3
+ Copies `text` (string or async retriever) to the system clipboard. Shows a checkmark for 2s after success. Disabled when `navigator.clipboard` is unavailable (non-secure context).
4
+
5
+ ## Usage
6
+
7
+ ```svelte
8
+ <script lang="ts">
9
+ import { Clipboard } from '$com/clipboard'
10
+ </script>
11
+
12
+ <Clipboard text="https://example.com/join/abc" label="Copy link" variant="outline" />
13
+ ```
14
+
15
+ ## Props
16
+
17
+ | Prop | Type | Default | Notes |
18
+ | -------- | ---------------------------- | ------- | -------------------------------------------------- |
19
+ | `text` | `string \| () => Promise<string>` | — | Value to copy. Retriever may return `null` to skip. |
20
+ | `label` | `string` | — | Button label. Omit for icon-only. |
21
+ | `oncopy` | `() => void` | — | Fires after a successful copy. |
22
+
23
+ All other props pass through to the underlying `Button`.
@@ -0,0 +1,75 @@
1
+ # Dismissable
2
+
3
+ Horizontal swipe-to-dismiss wrapper with optional slide-out animation. Swiping far enough triggers `ondismiss` immediately; calling `dismiss()` on a bound instance plays the slide-out first, then `ondismiss`. `remove()` animates out without calling `ondismiss`.
4
+
5
+ Set `dismissable={false}` to disable the swipe sentinel — use when dismissal is programmatic only.
6
+
7
+ ## Usage
8
+
9
+ ### Swipe to dismiss
10
+
11
+ ```svelte
12
+ <script lang="ts">
13
+ import { Dismissable } from '$com/dismissable'
14
+
15
+ let visible = $state(true)
16
+
17
+ async function ondismiss() {
18
+ visible = false
19
+ }
20
+ </script>
21
+
22
+ {#if visible}
23
+ <Dismissable {ondismiss}>
24
+ <div class="rounded-lg border bg-muted px-4 py-3">Swipe left to dismiss</div>
25
+ </Dismissable>
26
+ {/if}
27
+ ```
28
+
29
+ ### Clear all
30
+
31
+ Bind each row, call `remove()` on every ref with a short stagger (`delay` from `$lib/tools`), then drop them from state — `remove()` skips per-row `ondismiss`.
32
+
33
+ ```svelte
34
+ <script lang="ts">
35
+ import { Dismissable } from '$com/dismissable'
36
+ import { delay } from '$lib/tools'
37
+
38
+ type Ref = { remove: () => Promise<void> | void }
39
+
40
+ let items = $state(['One', 'Two', 'Three'])
41
+ const refs = $state<Array<Ref | undefined>>([])
42
+
43
+ async function clearAll() {
44
+ const removed = refs.map((ref, i) => delay(() => ref?.remove(), i * 50))
45
+
46
+ await Promise.all(removed)
47
+ items = []
48
+ }
49
+ </script>
50
+
51
+ <button onclick={clearAll}>Clear all</button>
52
+
53
+ {#each items as item, i (item)}
54
+ <Dismissable bind:this={refs[i]} ondismiss={() => (items = items.filter((x) => x !== item))}>
55
+ <div class="rounded-lg border bg-muted px-4 py-3">{item}</div>
56
+ </Dismissable>
57
+ {/each}
58
+ ```
59
+
60
+ ## Props
61
+
62
+ | Prop | Type | Default | Notes |
63
+ | ------------- | --------------------------------- | ------- | --------------------------------------------------------------------- |
64
+ | `children` | `Snippet` | — | Content inside the swipe track. |
65
+ | `ondismiss` | `() => Promise<void> \| void` | — | Swipe-to-sentinel fires immediately; `dismiss()` fires after animation. |
66
+ | `dismissable` | `boolean` | `true` | When `false`, hides the swipe sentinel and disables swipe dismissal. |
67
+
68
+ ## Instance methods
69
+
70
+ Bind with `bind:this` to call programmatic dismissal:
71
+
72
+ | Method | Notes |
73
+ | ---------- | -------------------------------------------------------------- |
74
+ | `dismiss()` | Slide-out animation, then `ondismiss`. |
75
+ | `remove()` | Slide-out animation only — no `ondismiss`. |
@@ -0,0 +1,153 @@
1
+ # Dropdown
2
+
3
+ Composable action menu with CSS anchor positioning, view-transition morph on open/close, and optional nested layers. Import as a namespace (`import * as Dropdown from '$com/dropdown'`).
4
+
5
+ ## Usage
6
+
7
+ ### Basic
8
+
9
+ ```svelte
10
+ <script lang="ts">
11
+ import { Ellipsis } from '@lucide/svelte'
12
+ import * as Dropdown from '$com/dropdown'
13
+
14
+ let menu: Dropdown.Root | undefined
15
+ </script>
16
+
17
+ <Dropdown.Root bind:this={menu}>
18
+ <Dropdown.Trigger variant="outline" size="icon">
19
+ <Ellipsis />
20
+ </Dropdown.Trigger>
21
+ <Dropdown.Content>
22
+ <Dropdown.Group direction="col">
23
+ <Dropdown.Item onclick={() => menu?.close()}>Edit</Dropdown.Item>
24
+ <Dropdown.Item>More…</Dropdown.Item>
25
+ </Dropdown.Group>
26
+ </Dropdown.Content>
27
+ </Dropdown.Root>
28
+ ```
29
+
30
+ ### Nested layers
31
+
32
+ Initially layers with `name` are hidden. Items with `layer` push a named layer. `Back` pops the current layer.
33
+
34
+ ```svelte
35
+ <script lang="ts">
36
+ import { Ellipsis } from '@lucide/svelte'
37
+ import * as Dropdown from '$com/dropdown'
38
+
39
+ let menu: Dropdown.Root | undefined
40
+ </script>
41
+
42
+ <Dropdown.Root bind:this={menu}>
43
+ <Dropdown.Trigger variant="outline" size="icon">
44
+ <Ellipsis />
45
+ </Dropdown.Trigger>
46
+ <Dropdown.Content>
47
+ <Dropdown.Layer>
48
+ <Dropdown.Group direction="col">
49
+ <Dropdown.Item onclick={() => menu?.close()}>Edit</Dropdown.Item>
50
+ <Dropdown.Item layer="more">More…</Dropdown.Item>
51
+ </Dropdown.Group>
52
+ </Dropdown.Layer>
53
+ <Dropdown.Layer name="more">
54
+ <Dropdown.Group direction="col">
55
+ <Dropdown.Back />
56
+ <Dropdown.Item onclick={() => menu?.close()}>Archive</Dropdown.Item>
57
+ </Dropdown.Group>
58
+ </Dropdown.Layer>
59
+ </Dropdown.Content>
60
+ </Dropdown.Root>
61
+ ```
62
+
63
+ ### Actions
64
+
65
+ Typical use case for Dropdown is navigation actions.
66
+ Wrap it with `<Actions>` from `shell` component, pass `active` store to control mute of the main navigation.
67
+
68
+ ```svelte
69
+ <script lang="ts">
70
+ import { writable } from 'svelte/store'
71
+ import { Actions } from '$com/shell'
72
+ import * as Dropdown from '$com/dropdown'
73
+
74
+ const active = writable(false)
75
+ </script>
76
+
77
+ <Actions active={active}>
78
+ <Dropdown.Root bind:this={menu} onopen={(open) => active.set(open)}>
79
+ <Dropdown.Trigger variant="outline" size="icon">
80
+ <Ellipsis />
81
+ </Dropdown.Trigger>
82
+ <Dropdown.Content>
83
+ <Dropdown.Group direction="col">
84
+ <Dropdown.Item onclick={() => menu?.close()}>Edit</Dropdown.Item>
85
+ <Dropdown.Item>More…</Dropdown.Item>
86
+ </Dropdown.Group>
87
+ </Dropdown.Content>
88
+ </Dropdown.Root>
89
+ </Actions>
90
+ ```
91
+
92
+ ## Props
93
+
94
+ ### Root
95
+
96
+ | Prop | Type | Default | Notes |
97
+ | ---------- | ------------------------- | ------- | ------------------------------------------ |
98
+ | `children` | `Snippet` | — | `Trigger` and `Content` slots. |
99
+ | `onopen` | `(open: boolean) => void` | — | Fires when open state changes. |
100
+
101
+ **Methods** (via `bind:this`): `open()`, `close()`.
102
+
103
+ ### Trigger
104
+
105
+ Extends shadcn `Button` props (`variant`, `size`, `class`, …).
106
+
107
+ | Prop | Type | Default | Notes |
108
+ | ---------- | --------- | ------- | ------------------------------------ |
109
+ | `children` | `Snippet` | — | Trigger label or icon. |
110
+ | `id` | `string` | — | Passed to the underlying `Button`. |
111
+
112
+ ### Content
113
+
114
+ | Prop | Type | Default | Notes |
115
+ | ---------- | -------------------------------------------------------------------- | --------------- | --------------------------------------------------------------------- |
116
+ | `children` | `Snippet` | — | `Layer`, `Group`, `Item`, `Separator` slots. |
117
+ | `class` | `ClassValue` | — | Panel wrapper classes. |
118
+ | `position` | `'start-top' \| 'start-bottom' \| 'end-top' \| 'end-bottom'` | `'end-bottom'` | Corner where menu aligns with the trigger; menu grows outward from it. |
119
+
120
+ ### Layer
121
+
122
+ | Prop | Type | Default | Notes |
123
+ | ---------- | --------- | ------- | --------------------------------------------------------------------- |
124
+ | `name` | `string` | `''` | Layer id. Default layer uses `''`; push targets use a non-empty name. |
125
+ | `children` | `Snippet` | — | Shown when this layer is active. |
126
+
127
+ ### Group
128
+
129
+ | Prop | Type | Default | Notes |
130
+ | ----------- | ------------------ | ------- | ------------------------------------------ |
131
+ | `children` | `Snippet` | — | `Item` or custom content. |
132
+ | `direction` | `'col' \| 'row'` | `'col'` | Layout for items; affects `itemVariants`. |
133
+ | `class` | `ClassValue` | — | Wrapper classes. |
134
+
135
+ ### Item
136
+
137
+ Extends shadcn `Button` props. Export `itemVariants` for custom buttons in a row group.
138
+
139
+ | Prop | Type | Default | Notes |
140
+ | ---------- | --------- | --------- | ------------------------------------------------------------- |
141
+ | `children` | `Snippet` | — | Row content (icon + label). |
142
+ | `layer` | `string` | — | When set, click pushes this layer instead of calling `onclick`. |
143
+ | `variant` | `string` | `'ghost'` | Button variant. |
144
+
145
+ ### Back
146
+
147
+ Same props as `Item` except `onclick` / `layer` (handled internally). Optional label snippet after the back arrow.
148
+
149
+ ### Separator
150
+
151
+ | Prop | Type | Default | Notes |
152
+ | ---------- | --------- | ------- | ---------------------------------- |
153
+ | `children` | `Snippet` | — | Optional centered label between rules. |
@@ -0,0 +1,29 @@
1
+ # fragments
2
+
3
+ ## Notes
4
+
5
+ - **Mount `<Fragments />` once** in your root `+layout.svelte`. It runs on the first (landing) navigation only and drives the consume-on-read cleanup; without it, read values are never stripped from the hash.
6
+ - `fragment(name)` returns the value present in the landing URL's hash, or `null` when absent. The hash is snapshotted once at module load, so reads are stable across the session even as the bar is rewritten; the actual URL is cleaned on the next navigation.
7
+ - SSR-safe: on the server the hash is empty, so `fragment()` returns `null` and `<Fragments />` is inert until hydration.
8
+
9
+ ## Usage
10
+
11
+ ```svelte
12
+ <!-- src/routes/+layout.svelte -->
13
+ <script lang="ts">
14
+ import { Fragments } from '@/fragments/ui'
15
+ </script>
16
+
17
+ <Fragments />
18
+ {@render children()}
19
+ ```
20
+
21
+ ```ts
22
+ // anywhere a one-shot hash value is expected, e.g. a returning redirect
23
+ import { fragment } from '@/fragments'
24
+
25
+ const session = fragment('stripe')
26
+ if (session) {
27
+ // …resume the flow for this session id; the hash is cleaned on next navigation
28
+ }
29
+ ```
@@ -0,0 +1,157 @@
1
+ # Fullscreen
2
+
3
+ Tap-to-expand overlay portaled to `body`. Wraps open/close in `transit()` for view transitions. Default mode: `children` is the trigger and the fullscreen body. Use `content` when the trigger and the overlay body should differ.
4
+
5
+ ## Usage
6
+
7
+ ### Zoom a thumbnail
8
+
9
+ Same markup in the trigger and in fullscreen — good for photo zoom. Put `view-transition-name` on the image; add `fullscreen-content` for correct morph stacking.
10
+
11
+ ```svelte
12
+ <script lang="ts">
13
+ import { Fullscreen } from '$com/fullscreen'
14
+
15
+ const id = 'photo-1'
16
+ let zoomed = $state<string | null>(null)
17
+ </script>
18
+
19
+ <Fullscreen class="h-[300px]" fragile onshow={() => (zoomed = id)} x={false}>
20
+ <img
21
+ src="/photo.jpg"
22
+ alt=""
23
+ class="h-full object-contain fullscreen-content"
24
+ style={`${zoomed === id ? 'view-transition-name: photo;' : ''} view-transition-class: transition-spring transition-morph;`} />
25
+ </Fullscreen>
26
+ ```
27
+
28
+ Set the transition name only while open (`onshow` + conditional style) when several Fullscreens sit in a list — otherwise every thumbnail joins the same morph.
29
+
30
+ ### Button → content
31
+
32
+ When a button (or file input, share target, …) opens different fullscreen UI, split trigger and body: `controlled`, `content`, and `bind:this` → `show()` / `hide()`.
33
+
34
+ Morph from the button into `content` with `takeoff` + `styles` (same transition name on both sides):
35
+
36
+ ```svelte
37
+ <script lang="ts">
38
+ import { Button } from '$ui/button'
39
+ import { styles, takeoff } from '$lib/tools'
40
+ import { Fullscreen } from '$com/fullscreen'
41
+
42
+ const morph = 'transition-spring transition-morph fullscreen-content'
43
+
44
+ let fullscreen = $state<Fullscreen | null>(null)
45
+ const contentStyle = styles('upload', morph)
46
+
47
+ function open() {
48
+ takeoff('upload-button', 'upload', morph)
49
+ fullscreen?.show()
50
+ }
51
+ </script>
52
+
53
+ <Fullscreen bind:this={fullscreen} controlled>
54
+ <Button id="upload-button" onclick={open}>Upload</Button>
55
+ {#snippet content()}
56
+ <div class="max-w-md p-4 fullscreen-content" style={$contentStyle}>
57
+ <!-- progress, preview, … -->
58
+ </div>
59
+ {/snippet}
60
+ </Fullscreen>
61
+ ```
62
+
63
+ No visible trigger? Pass an empty `<div></div>` as `children` and call `show()` from `onMount` (share-target flow).
64
+
65
+ ### Overlay toolbar
66
+
67
+ Actions above the content — delete, share, etc. Disable the default ✕ (`x={false}`) when the overlay dismisses.
68
+
69
+ ```svelte
70
+ <script lang="ts">
71
+ import { Hold } from '$com/hold'
72
+ import { Fullscreen } from '$com/fullscreen'
73
+
74
+ let fullscreen = $state<Fullscreen | null>(null)
75
+ </script>
76
+
77
+ <Fullscreen bind:this={fullscreen} fragile x={false}>
78
+ <img src="/photo.jpg" alt="" class="fullscreen-content" style="view-transition-name: photo; …" />
79
+ {#snippet overlay()}
80
+ <div class="flex justify-end p-4 tim:pt-[env(safe-area-inset-top)]">
81
+ <Hold label="hold to delete" variant="outline" size="icon" onclick={() => fullscreen?.hide()}>
82
+ <!-- icon -->
83
+ </Hold>
84
+ </div>
85
+ {/snippet}
86
+ </Fullscreen>
87
+ ```
88
+
89
+ ### Store-driven open
90
+
91
+ When `open` comes from a store or parent, still wrap the flip in `transit()` — `show()` / `hide()` do that; raw `open = true` skips the animation.
92
+
93
+ ```svelte
94
+ <script lang="ts">
95
+ import { transit } from '$lib/tools'
96
+ import { Fullscreen } from '$com/fullscreen'
97
+
98
+ let open = $state(false)
99
+
100
+ async function present() {
101
+ await transit(() => (open = true))
102
+ }
103
+ </script>
104
+
105
+ <Fullscreen bind:open>
106
+ <div></div>
107
+ {#snippet content()}
108
+ <!-- paywall, modal flow, … -->
109
+ {/snippet}
110
+ </Fullscreen>
111
+ ```
112
+
113
+ Optional: `takeoff(sourceId, name, classes)` before `transit` when morphing from another element on the page (CTA button → paywall card).
114
+
115
+ ## Props
116
+
117
+ | Prop | Type | Default | Notes |
118
+ | ------------ | -------------- | ------- | --------------------------------------------------------------------- |
119
+ | `children` | `Snippet` | — | Trigger markup; also fullscreen body when `content` is omitted. |
120
+ | `content` | `Snippet` | — | Fullscreen-only body; trigger stays on the page. |
121
+ | `overlay` | `Snippet` | — | Toolbar/actions above content; rendered inside `Overlay`. |
122
+ | `open` | `boolean` | `false` | Bindable. Mutate inside `transit()` unless using `show()` / `hide()`. |
123
+ | `onshow` | `() => void` | — | Fires when `show()` starts. |
124
+ | `onhide` | `() => void` | — | Fires after the close transition finishes. |
125
+ | `class` | `ClassValue` | — | Classes on the trigger button (ignored when `controlled`). |
126
+ | `fragile` | `boolean` | `false` | Close on backdrop pointer down. |
127
+ | `controlled` | `boolean` | `false` | No built-in trigger; call `show()` / `hide()` yourself. |
128
+ | `x` | `boolean` | `true` | Top-trailing close button. |
129
+
130
+ `bind:this` exposes `show()` and `hide()`. `Overlay` accepts `children` and optional `class`.
131
+
132
+ ## Notes
133
+
134
+ ### Opening and closing
135
+
136
+ - Prefer `show()` / `hide()` or `await transit(() => (open = …))`. Assigning `open` directly bypasses the view transition.
137
+ - In `controlled` mode, Escape and backdrop tap (`fragile`) do nothing — close with `hide()`, `transit(() => (open = false))`, or a control in `overlay`.
138
+ - Pair `controlled` + `bind:open` when async work should finish only while open: `if (open) callback?.(id)`.
139
+
140
+ ### `children` vs `content`
141
+
142
+ | Setup | Trigger | Fullscreen body | Typical use |
143
+ | ----- | ------- | --------------- | ----------- |
144
+ | `children` only | wrapped in a button | same `children` | Thumbnail zoom |
145
+ | `controlled` + `content` | `children` stays in place | `content` snippet | Button → upload progress, paywall |
146
+
147
+ ### View transitions
148
+
149
+ - Shared name on source and target: inline `view-transition-name` on the thumbnail, or `takeoff(id, name, classes)` + `styles(name, classes)` on `content`.
150
+ - Add `view-transition-class: transition-spring transition-morph` and class `fullscreen-content` on the morphing element — matches built-in z-index (`::view-transition-group(.fullscreen-content)`).
151
+ - Content above the default stack? Add a scoped rule, e.g. `::view-transition-group(paywall) { z-index: 4; }`.
152
+ - List of items: unique name per row; set it only for the open item (see thumbnail example above).
153
+
154
+ ### Overlay
155
+
156
+ - Set `x={false}` when `overlay` owns dismiss/delete.
157
+ - The built-in trigger hides `[data-slot=fullscreen-overlay]` descendants so overlay chrome does not appear in the thumbnail.