@jackuait/blok 0.19.2 → 0.21.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 (307) hide show
  1. package/dist/blok.cjs +1 -1
  2. package/dist/blok.iife.js +4 -4
  3. package/dist/blok.mjs +2 -2
  4. package/dist/blok.umd.js +41 -41
  5. package/dist/chunks/{blok-C8_pY9Bg.cjs → blok-Cz71HTuP.cjs} +13 -13
  6. package/dist/chunks/{blok-DCc23rzA.mjs → blok-x8D2aON2.mjs} +2645 -2116
  7. package/dist/chunks/constants-BK6kLyZB.cjs +606 -0
  8. package/dist/chunks/{constants-C3-Lh6Fs.mjs → constants-CLzXh7Tb.mjs} +392 -267
  9. package/dist/chunks/{i18next-loader-BBPMegxc.cjs → i18next-loader-DVakgVCy.cjs} +1 -1
  10. package/dist/chunks/{i18next-loader-K-ir8UKk.mjs → i18next-loader-DfIonnVO.mjs} +1 -1
  11. package/dist/chunks/{lightweight-i18n-LFW8S8u-.cjs → lightweight-i18n-BnIqQ5Cf.cjs} +1 -1
  12. package/dist/chunks/{lightweight-i18n-DJpMke7a.mjs → lightweight-i18n-Cj88c8gl.mjs} +15 -0
  13. package/dist/chunks/{messages-Bb80Csl3.mjs → messages-0EAci1N0.mjs} +15 -0
  14. package/dist/chunks/{messages-BkgBVEiE.cjs → messages-1jzEPeW5.cjs} +1 -1
  15. package/dist/chunks/{messages-CATH_uz1.mjs → messages-4CqVAaCY.mjs} +16 -1
  16. package/dist/chunks/{messages-DFHNw6PQ.cjs → messages-4Qka94cm.cjs} +1 -1
  17. package/dist/chunks/{messages-CBbgEXuO.cjs → messages-7wDDggws.cjs} +1 -1
  18. package/dist/chunks/{messages-B7st3eF_.cjs → messages-9VzB9Djh.cjs} +1 -1
  19. package/dist/chunks/{messages-B_cHWyWC.cjs → messages-9bK437Rh.cjs} +1 -1
  20. package/dist/chunks/{messages-CZddldga.cjs → messages-AtTKtjsQ.cjs} +1 -1
  21. package/dist/chunks/{messages-HJnG9r2l.mjs → messages-B1inw201.mjs} +16 -1
  22. package/dist/chunks/{messages-B-u5B7tY.cjs → messages-B4ZVgIh5.cjs} +1 -1
  23. package/dist/chunks/{messages-CJFSq8Fl.cjs → messages-B5bSFRCa.cjs} +1 -1
  24. package/dist/{messages-HVgCKIww2.mjs → chunks/messages-B705gxqz.mjs} +16 -1
  25. package/dist/{messages-Dq_RdEny2.mjs → chunks/messages-B7F3tX4u.mjs} +16 -1
  26. package/dist/chunks/{messages-NJAjMFXd.cjs → messages-BDer7I67.cjs} +1 -1
  27. package/dist/chunks/{messages-BV22YIZ_.cjs → messages-BEEGgtPo.cjs} +1 -1
  28. package/dist/{messages-bN4Zmk2m.mjs → chunks/messages-BGlEWmsB.mjs} +16 -1
  29. package/dist/{messages-Ao2vCNAH2.mjs → chunks/messages-BJJsuZhy.mjs} +16 -1
  30. package/dist/chunks/{messages-DjrfovG0.cjs → messages-BJcc9h6p.cjs} +1 -1
  31. package/dist/chunks/{messages-Hfo6uCIC.cjs → messages-BL-E2Kw3.cjs} +1 -1
  32. package/dist/{messages-8__-vX3U.mjs → chunks/messages-BLJGzntb.mjs} +16 -1
  33. package/dist/chunks/{messages-Au1UpgkX.cjs → messages-BLNieIb-.cjs} +1 -1
  34. package/dist/chunks/{messages-DQJcAz4s.cjs → messages-BRbGk1-Z.cjs} +1 -1
  35. package/dist/chunks/{messages-BwOUSDJR.mjs → messages-BUlZRNoO.mjs} +15 -0
  36. package/dist/{messages-BKGg4XYm2.mjs → chunks/messages-BWQF9y2r.mjs} +16 -1
  37. package/dist/chunks/{messages-UXS3zL9A2.cjs → messages-BWh9I5Jv2.cjs} +1 -1
  38. package/dist/chunks/{messages-B6dbtt1c.cjs → messages-BX86v7Ev.cjs} +1 -1
  39. package/dist/chunks/{messages-DIFwztFo.cjs → messages-BYpvkG9S.cjs} +1 -1
  40. package/dist/{messages-CDueJTe8.mjs → chunks/messages-Bdw_vAdq2.mjs} +16 -1
  41. package/dist/chunks/{messages-DIetNXTx.cjs → messages-BeQVEC9q.cjs} +1 -1
  42. package/dist/{messages-CusWGsl42.mjs → chunks/messages-BeTZTXZm.mjs} +16 -1
  43. package/dist/chunks/{messages-CmsAbu_A.cjs → messages-BhTlR4PP.cjs} +1 -1
  44. package/dist/chunks/{messages-C3rGCBi_.mjs → messages-BhnZTZbQ.mjs} +16 -1
  45. package/dist/{messages-BpwhHkFb2.mjs → chunks/messages-BqJdoBHm.mjs} +16 -1
  46. package/dist/chunks/{messages-zPUQsksJ.mjs → messages-BqPiH7QC.mjs} +16 -1
  47. package/dist/chunks/{messages-CjfEt9bg.cjs → messages-Br_qu_wR.cjs} +1 -1
  48. package/dist/chunks/{messages-DtaPHADA.cjs → messages-BscUmD6D.cjs} +1 -1
  49. package/dist/{messages-Cg6a88Bb2.mjs → chunks/messages-Btapuvxo.mjs} +16 -1
  50. package/dist/chunks/{messages-CEySIig9.cjs → messages-BwCw0TJ1.cjs} +1 -1
  51. package/dist/chunks/{messages-BO-L5oN9.mjs → messages-C3RDWmXV.mjs} +15 -0
  52. package/dist/chunks/{messages-CZJZ-au3.cjs → messages-C3SZsVB9.cjs} +1 -1
  53. package/dist/chunks/{messages-DQr7bXMD.mjs → messages-C65mLRVK.mjs} +16 -1
  54. package/dist/chunks/{messages-CT8djlV6.cjs → messages-C73dKqPT.cjs} +1 -1
  55. package/dist/chunks/{messages-DOqJ6ogK.cjs → messages-C8f4kUOB.cjs} +1 -1
  56. package/dist/{messages-yuNINyS1.mjs → chunks/messages-C9vfrzKQ.mjs} +16 -1
  57. package/dist/{messages-Grhv5SE_.mjs → chunks/messages-CEbe34zh.mjs} +15 -0
  58. package/dist/chunks/{messages-CcsM8Q7g.cjs → messages-CHEpECGv.cjs} +1 -1
  59. package/dist/chunks/{messages-DEg5FAg1.cjs → messages-CHP0nYRn.cjs} +1 -1
  60. package/dist/chunks/{messages-CjCn5IsF.mjs → messages-CIbh-0oJ.mjs} +16 -1
  61. package/dist/chunks/{messages-BHCepNsI.cjs → messages-CJC94Hci.cjs} +1 -1
  62. package/dist/chunks/{messages-ByNR9m9W.cjs → messages-CMP5dbqQ.cjs} +1 -1
  63. package/dist/chunks/{messages-DpNmnBjK.cjs → messages-CMm8FeOL.cjs} +1 -1
  64. package/dist/chunks/{messages-Da8yFc7l.cjs → messages-CNMPtWiq.cjs} +1 -1
  65. package/dist/{messages-CqZgsrVP2.mjs → chunks/messages-CQUr4lBa.mjs} +16 -1
  66. package/dist/{messages-Cvq2EFPT2.mjs → chunks/messages-CUuOX1k3.mjs} +16 -1
  67. package/dist/chunks/{messages-BsTzdfZF.cjs → messages-CVerbLou.cjs} +1 -1
  68. package/dist/{messages-CGiVoFTi.mjs → chunks/messages-CWW9OwKO.mjs} +16 -1
  69. package/dist/{messages-Da1woCgt2.mjs → chunks/messages-CWqap54p.mjs} +16 -1
  70. package/dist/{messages-CEGqNXnP.mjs → chunks/messages-CXNQBFHp.mjs} +16 -1
  71. package/dist/chunks/{messages-DgF8OkNr.mjs → messages-CYDhuSF4.mjs} +16 -1
  72. package/dist/chunks/{messages-Bp0LdGKj.mjs → messages-CYy3Zd3F.mjs} +15 -0
  73. package/dist/{messages-CUcUO5bC2.mjs → chunks/messages-C_BM_XHo.mjs} +16 -1
  74. package/dist/chunks/{messages-IqNWRaNS.cjs → messages-CbKOqXT6.cjs} +1 -1
  75. package/dist/chunks/{messages-Bmq--WTx.mjs → messages-CbxXU_Um.mjs} +15 -0
  76. package/dist/chunks/{messages-CVrOxu3J.cjs → messages-CcO-3_4k.cjs} +1 -1
  77. package/dist/chunks/{messages-D41fO84y.cjs → messages-CcTkC677.cjs} +1 -1
  78. package/dist/chunks/{messages-Cy-2_lIA.cjs → messages-CdEZ98_p.cjs} +1 -1
  79. package/dist/{messages-KyJQtOkh2.mjs → chunks/messages-CeZ1lo-o.mjs} +16 -1
  80. package/dist/chunks/{messages-D7H9JUDr.cjs → messages-CgFAGUJX.cjs} +1 -1
  81. package/dist/chunks/{messages-Dwl878eS.mjs → messages-CprMp4Va.mjs} +16 -1
  82. package/dist/{messages-wmS6Z2m82.mjs → chunks/messages-CtXDxPOq.mjs} +16 -1
  83. package/dist/{messages-DcQNeoPB.mjs → chunks/messages-Cutnm4AZ.mjs} +15 -0
  84. package/dist/chunks/{messages-cSBZ5qVe.mjs → messages-CwIC_sse.mjs} +16 -1
  85. package/dist/chunks/{messages-7LWW3BVh.mjs → messages-CwbTr9lL.mjs} +16 -1
  86. package/dist/chunks/{messages-ETJ7tQ9O.cjs → messages-CxIknrw4.cjs} +1 -1
  87. package/dist/{messages-VIQ8vjvS.mjs → chunks/messages-D0Jj7Dtw.mjs} +15 -0
  88. package/dist/chunks/{messages-SozFksSf.cjs → messages-D0th-I9S.cjs} +1 -1
  89. package/dist/chunks/{messages-gh5G15J1.cjs → messages-D1XTyTJz.cjs} +1 -1
  90. package/dist/chunks/{messages-DNtAzacv.mjs → messages-D24EoKbO.mjs} +16 -1
  91. package/dist/chunks/{messages-DDJkNbJy.mjs → messages-D2chjyLM.mjs} +16 -1
  92. package/dist/chunks/{messages-CqRtDVFO.cjs → messages-D6y13edn.cjs} +1 -1
  93. package/dist/chunks/{messages-EsX3eikv.cjs → messages-D86p1eQY.cjs} +1 -1
  94. package/dist/{messages-BwCgJUdq.mjs → chunks/messages-D8L_8amv.mjs} +16 -1
  95. package/dist/chunks/{messages-C2ptZOWh.cjs → messages-DC-yFRyF.cjs} +1 -1
  96. package/dist/{messages-BgPDPIkO.mjs → chunks/messages-DEPxxCNU.mjs} +16 -1
  97. package/dist/chunks/{messages-VeyvtTce.cjs → messages-DG9l5agQ.cjs} +1 -1
  98. package/dist/chunks/{messages-B6794_2J.cjs → messages-DIeUb2w-.cjs} +1 -1
  99. package/dist/chunks/{messages-COx3hDcP.cjs → messages-DJ-RX5EJ.cjs} +1 -1
  100. package/dist/chunks/{messages-Cvg_uTfy.mjs → messages-DJ7lbpBX.mjs} +16 -1
  101. package/dist/{messages-Cn3uvFq3.mjs → chunks/messages-DJH_kd46.mjs} +16 -1
  102. package/dist/chunks/{messages-CWFSMzug2.cjs → messages-DLYl6KdK2.cjs} +1 -1
  103. package/dist/{messages-Ch-SytN8.mjs → chunks/messages-DMcCkOtN.mjs} +16 -1
  104. package/dist/chunks/{messages-BdL8bmTL.mjs → messages-DQks74hq.mjs} +16 -1
  105. package/dist/chunks/{messages-D-QWtvWg.mjs → messages-DTiqggtG.mjs} +16 -1
  106. package/dist/chunks/{messages-typO_i_k.mjs → messages-DTsSYToI.mjs} +15 -0
  107. package/dist/{messages-CwvHO8gp2.mjs → chunks/messages-DU6TOz6v.mjs} +16 -1
  108. package/dist/chunks/{messages-DmjccFHq.cjs → messages-DUbZA-w_.cjs} +1 -1
  109. package/dist/chunks/{messages-DCwrXfck.cjs → messages-DVAU-8rH.cjs} +1 -1
  110. package/dist/chunks/{messages-Z4LYgfWc.cjs → messages-Df6vXDrY.cjs} +1 -1
  111. package/dist/chunks/{messages-9B1F-k48.cjs → messages-Dh79ToYM.cjs} +1 -1
  112. package/dist/chunks/{messages-CuMtymEs.cjs → messages-Dh9psewW.cjs} +1 -1
  113. package/dist/chunks/{messages-BjYhwRk7.cjs → messages-Dln2T0zJ.cjs} +1 -1
  114. package/dist/chunks/{messages-DT-JnTnw.cjs → messages-DoA0Ecoi.cjs} +1 -1
  115. package/dist/chunks/{messages-D-p-omWy.mjs → messages-Dre_MB7o.mjs} +16 -1
  116. package/dist/chunks/{messages-BveiGA2x.cjs → messages-Dv4oyF7T.cjs} +1 -1
  117. package/dist/{messages-C6R0bzW5.mjs → chunks/messages-FMAQkmg4.mjs} +15 -0
  118. package/dist/{messages-CQzOV7VE2.mjs → chunks/messages-GownDU-J.mjs} +16 -1
  119. package/dist/chunks/{messages-CH9SBR-i.cjs → messages-JYea02IT.cjs} +1 -1
  120. package/dist/chunks/{messages-BXp_U3uS.cjs → messages-JyzorVPx.cjs} +1 -1
  121. package/dist/{messages-BIgvPd6I2.mjs → chunks/messages-L70TFQAY.mjs} +16 -1
  122. package/dist/{messages-CskLLTiG2.mjs → chunks/messages-L8CslBBZ.mjs} +16 -1
  123. package/dist/chunks/{messages-CM8uUnPx.cjs → messages-LX9PuLsT.cjs} +1 -1
  124. package/dist/{messages-BarhGl2S2.mjs → chunks/messages-NFUr7Sxk.mjs} +16 -1
  125. package/dist/chunks/{messages-CGdCpNZ62.cjs → messages-PpRvDwOa2.cjs} +1 -1
  126. package/dist/chunks/{messages-ZMG7qQ3D.mjs → messages-QQ5-ET8y.mjs} +16 -1
  127. package/dist/{messages-DbE-riR52.mjs → chunks/messages-Stf6rn2I.mjs} +16 -1
  128. package/dist/chunks/{messages-D7sU-NqL.cjs → messages-T8hCmys7.cjs} +1 -1
  129. package/dist/chunks/{messages-DDX6I6MX.mjs → messages-TZtv60nI.mjs} +16 -1
  130. package/dist/chunks/{messages-CeLv1whu2.mjs → messages-V9bvFOFc2.mjs} +16 -1
  131. package/dist/chunks/{messages-tR0BdeVG.cjs → messages-Vp8CpYh3.cjs} +1 -1
  132. package/dist/chunks/{messages-DUWCkLYR.cjs → messages-XqCqLy0k.cjs} +1 -1
  133. package/dist/chunks/{messages-B01D7aHY.mjs → messages-_1y6EX7X.mjs} +16 -1
  134. package/dist/chunks/{messages-CXk-iM-i.mjs → messages-aTZglEV9.mjs} +16 -1
  135. package/dist/chunks/{messages-BHdKd7pH.cjs → messages-cSHh8Zgv.cjs} +1 -1
  136. package/dist/{messages-P5B61L1J2.mjs → chunks/messages-e8gxPi7a.mjs} +16 -1
  137. package/dist/{messages-CUFac9Qe.mjs → chunks/messages-hiwlrrr-.mjs} +16 -1
  138. package/dist/{messages-CeqpzGl9.mjs → chunks/messages-icPZhZ81.mjs} +15 -0
  139. package/dist/chunks/{messages-Byn9-dhb2.mjs → messages-lbwOYFxS2.mjs} +16 -1
  140. package/dist/chunks/{messages-B6yMdb3B.cjs → messages-lvo-9Be0.cjs} +1 -1
  141. package/dist/chunks/{messages-B2iaIrIu.mjs → messages-rm6jXexA.mjs} +16 -1
  142. package/dist/chunks/{messages-Ciq5_PsP.cjs → messages-sTyGkmbu.cjs} +1 -1
  143. package/dist/{messages-CF5MeYEt2.mjs → chunks/messages-uBwK-Ze2.mjs} +16 -1
  144. package/dist/chunks/{messages-BaVZgTrw.cjs → messages-uOISsfmj.cjs} +1 -1
  145. package/dist/{messages-L4sYfXpM.mjs → chunks/messages-wq0vxJ3p.mjs} +16 -1
  146. package/dist/chunks/{messages-CQT8TtiF.cjs → messages-z2DzBRgO.cjs} +1 -1
  147. package/dist/chunks/tools-BKjP4TXy.cjs +208 -0
  148. package/dist/chunks/{tools-fEI-EVng.mjs → tools-Bw8_CkhE.mjs} +2537 -2469
  149. package/dist/full.cjs +1 -1
  150. package/dist/full.mjs +3 -3
  151. package/dist/locales.mjs +82 -67
  152. package/dist/{messages-BlvF3pot.mjs → messages--sHkn4PD.mjs} +16 -1
  153. package/dist/{chunks/messages-QCaF3d92.mjs → messages-4mxgsYKZ2.mjs} +16 -1
  154. package/dist/{messages-zOl6jpOa.mjs → messages-6fQMeTiI.mjs} +16 -1
  155. package/dist/{messages-BRLWpOnP.mjs → messages-B22G0fir.mjs} +16 -1
  156. package/dist/{chunks/messages-kqnzps-X.mjs → messages-B908tGhl.mjs} +16 -1
  157. package/dist/{chunks/messages-C8_r3iTR2.mjs → messages-BAUvKI0_.mjs} +16 -1
  158. package/dist/{chunks/messages-BpMWMH9_.mjs → messages-BAfMwQnT2.mjs} +16 -1
  159. package/dist/{messages-Bmu3rJwO.mjs → messages-BCk7o4Pz.mjs} +16 -1
  160. package/dist/{messages-D4dovFzY2.mjs → messages-BG2BE6Sg2.mjs} +16 -1
  161. package/dist/{messages-DR2JBU-H.mjs → messages-BGe6GS_j.mjs} +16 -1
  162. package/dist/{chunks/messages-CeIzWL_4.mjs → messages-BHLrVFmZ2.mjs} +16 -1
  163. package/dist/{messages-BOWDzfkH.mjs → messages-BJjffJIu.mjs} +16 -1
  164. package/dist/{chunks/messages-DHv7knYB.mjs → messages-BSGZSOH32.mjs} +16 -1
  165. package/dist/{chunks/messages-BRTWvTAP.mjs → messages-BT6TyDYQ2.mjs} +16 -1
  166. package/dist/{messages-jQsl7cga2.mjs → messages-BWZ0_zUi2.mjs} +16 -1
  167. package/dist/{messages-lnxRz5rM.mjs → messages-BWhJgyhl.mjs} +16 -1
  168. package/dist/{chunks/messages-Xh-c7d4C.mjs → messages-BXqLaS2g2.mjs} +16 -1
  169. package/dist/{messages-gTUy3xjb.mjs → messages-BZiuFv_O.mjs} +15 -0
  170. package/dist/{chunks/messages-B_d857cA.mjs → messages-Bb-XEtyl.mjs} +15 -0
  171. package/dist/{messages-C9Kq8259.mjs → messages-BkKAnFz_.mjs} +15 -0
  172. package/dist/{chunks/messages-BUvlOqll.mjs → messages-BoLu5_Wp2.mjs} +16 -1
  173. package/dist/{messages-RXQKVFCJ.mjs → messages-BpqRzil6.mjs} +16 -1
  174. package/dist/{chunks/messages-CkosWGGH.mjs → messages-C2E8rQjb.mjs} +15 -0
  175. package/dist/{chunks/messages-jEbEE90_.mjs → messages-C2JJxi5D2.mjs} +16 -1
  176. package/dist/{messages-jsrzDVZy2.mjs → messages-C4d1_z432.mjs} +16 -1
  177. package/dist/{chunks/messages-MPe9FjYe.mjs → messages-C5Igyij0.mjs} +16 -1
  178. package/dist/{messages-CAnOyxrm.mjs → messages-C8fscB2J.mjs} +16 -1
  179. package/dist/{chunks/messages-CX0tJpOb.mjs → messages-CD8CgT1F.mjs} +16 -1
  180. package/dist/{messages-BKG0QHVl.mjs → messages-CDxPk3xE.mjs} +15 -0
  181. package/dist/{messages-hGop1gbF.mjs → messages-CGXrIdHT.mjs} +15 -0
  182. package/dist/{chunks/messages-DuHFGMCJ.mjs → messages-CHfkCxGQ2.mjs} +16 -1
  183. package/dist/{messages-fAEKzdUq.mjs → messages-CMvNzksb.mjs} +16 -1
  184. package/dist/{chunks/messages-t26x8wxB.mjs → messages-CSIhcdDx2.mjs} +16 -1
  185. package/dist/{messages-UJx6PvCL.mjs → messages-CW5z5hSz.mjs} +16 -1
  186. package/dist/{chunks/messages-CUPup5e3.mjs → messages-CYvpDx4p2.mjs} +16 -1
  187. package/dist/{chunks/messages-Ca9zIrBo.mjs → messages-CcTlmrYs.mjs} +16 -1
  188. package/dist/{messages-CcF4SO9W.mjs → messages-Ce8ShL0-.mjs} +16 -1
  189. package/dist/{chunks/messages-CbyVDo8y.mjs → messages-CgT32m3D.mjs} +15 -0
  190. package/dist/{chunks/messages-ypIHI9Fr.mjs → messages-CmCBnNtA2.mjs} +16 -1
  191. package/dist/{messages-DGAWjKQZ.mjs → messages-CneVTJSN.mjs} +16 -1
  192. package/dist/{messages-C5IE9mXm.mjs → messages-CpNerer8.mjs} +15 -0
  193. package/dist/{chunks/messages-D-s4_vnU.mjs → messages-Cs0L1gyv.mjs} +16 -1
  194. package/dist/{chunks/messages-BYCHzM7F.mjs → messages-CsGnp1wE2.mjs} +16 -1
  195. package/dist/{chunks/messages-D4u2PSQw.mjs → messages-CvbIxcr7.mjs} +16 -1
  196. package/dist/{chunks/messages-DuD4ut1b.mjs → messages-Cx6oQfMR2.mjs} +16 -1
  197. package/dist/{messages-BvutXmgt.mjs → messages-DBESJOhQ.mjs} +16 -1
  198. package/dist/{chunks/messages-Cl_pM31G.mjs → messages-DGOBPnKC2.mjs} +16 -1
  199. package/dist/{messages-B13GEFFu.mjs → messages-DK2AwXAp.mjs} +16 -1
  200. package/dist/{chunks/messages-CI2W7P-j.mjs → messages-DMbnesQ9.mjs} +16 -1
  201. package/dist/{messages-4drvqPN8.mjs → messages-DOiSOenW.mjs} +16 -1
  202. package/dist/{chunks/messages-5339ApgH.mjs → messages-DQqp_ANL.mjs} +16 -1
  203. package/dist/{chunks/messages-Ck1-ddbo.mjs → messages-DThG2jW-2.mjs} +16 -1
  204. package/dist/{chunks/messages-DQfi2DoY.mjs → messages-DXlB7Vpm.mjs} +16 -1
  205. package/dist/{chunks/messages-DjZoCJ00.mjs → messages-De0NAxJt.mjs} +15 -0
  206. package/dist/{messages-BI5B9bxE.mjs → messages-Depz8d3Q.mjs} +15 -0
  207. package/dist/{messages-BQaiScU1.mjs → messages-Dfsw3a8v.mjs} +16 -1
  208. package/dist/{messages-D9qgYMU82.mjs → messages-Dhmmqob82.mjs} +16 -1
  209. package/dist/{chunks/messages-DiODNXET.mjs → messages-DmNUAv0e2.mjs} +16 -1
  210. package/dist/{chunks/messages-3jkCmB_A.mjs → messages-DrQaJrDO.mjs} +16 -1
  211. package/dist/{messages-B2YnZIU2.mjs → messages-DsksuHtZ.mjs} +16 -1
  212. package/dist/{chunks/messages-m-A6ArIM.mjs → messages-DzOVTq3E2.mjs} +16 -1
  213. package/dist/{chunks/messages-C0swL9CY.mjs → messages-Igpt5WIA2.mjs} +16 -1
  214. package/dist/{chunks/messages-CIBYzzFy.mjs → messages-JhpGtjjS.mjs} +16 -1
  215. package/dist/{chunks/messages-BbZz_Anm.mjs → messages-WCy1wiGS2.mjs} +16 -1
  216. package/dist/{chunks/messages-CRUb9o5k.mjs → messages-XbA-jXKc.mjs} +15 -0
  217. package/dist/{chunks/messages-BeS9EOEO.mjs → messages-imHGm9SI2.mjs} +16 -1
  218. package/dist/{messages-BQhHthxq2.mjs → messages-yTNyxXRV2.mjs} +16 -1
  219. package/dist/react.cjs +1 -1
  220. package/dist/react.mjs +1 -1
  221. package/dist/tools.cjs +1 -1
  222. package/dist/tools.mjs +2 -2
  223. package/package.json +1 -1
  224. package/src/components/i18n/locales/am/messages.json +16 -1
  225. package/src/components/i18n/locales/ar/messages.json +16 -1
  226. package/src/components/i18n/locales/az/messages.json +16 -1
  227. package/src/components/i18n/locales/bg/messages.json +16 -1
  228. package/src/components/i18n/locales/bn/messages.json +16 -1
  229. package/src/components/i18n/locales/bs/messages.json +16 -1
  230. package/src/components/i18n/locales/cs/messages.json +16 -1
  231. package/src/components/i18n/locales/da/messages.json +16 -1
  232. package/src/components/i18n/locales/de/messages.json +16 -1
  233. package/src/components/i18n/locales/dv/messages.json +16 -1
  234. package/src/components/i18n/locales/el/messages.json +16 -1
  235. package/src/components/i18n/locales/en/messages.json +15 -0
  236. package/src/components/i18n/locales/es/messages.json +15 -0
  237. package/src/components/i18n/locales/et/messages.json +15 -0
  238. package/src/components/i18n/locales/fa/messages.json +15 -0
  239. package/src/components/i18n/locales/fi/messages.json +15 -0
  240. package/src/components/i18n/locales/fil/messages.json +15 -0
  241. package/src/components/i18n/locales/fr/messages.json +15 -0
  242. package/src/components/i18n/locales/gu/messages.json +15 -0
  243. package/src/components/i18n/locales/he/messages.json +15 -0
  244. package/src/components/i18n/locales/hi/messages.json +15 -0
  245. package/src/components/i18n/locales/hr/messages.json +15 -0
  246. package/src/components/i18n/locales/hu/messages.json +15 -0
  247. package/src/components/i18n/locales/hy/messages.json +16 -1
  248. package/src/components/i18n/locales/id/messages.json +16 -1
  249. package/src/components/i18n/locales/it/messages.json +16 -1
  250. package/src/components/i18n/locales/ja/messages.json +16 -1
  251. package/src/components/i18n/locales/ka/messages.json +16 -1
  252. package/src/components/i18n/locales/km/messages.json +16 -1
  253. package/src/components/i18n/locales/kn/messages.json +16 -1
  254. package/src/components/i18n/locales/ko/messages.json +16 -1
  255. package/src/components/i18n/locales/ku/messages.json +16 -1
  256. package/src/components/i18n/locales/lo/messages.json +16 -1
  257. package/src/components/i18n/locales/lt/messages.json +16 -1
  258. package/src/components/i18n/locales/lv/messages.json +16 -1
  259. package/src/components/i18n/locales/mk/messages.json +16 -1
  260. package/src/components/i18n/locales/ml/messages.json +16 -1
  261. package/src/components/i18n/locales/mn/messages.json +16 -1
  262. package/src/components/i18n/locales/mr/messages.json +16 -1
  263. package/src/components/i18n/locales/ms/messages.json +16 -1
  264. package/src/components/i18n/locales/my/messages.json +16 -1
  265. package/src/components/i18n/locales/ne/messages.json +16 -1
  266. package/src/components/i18n/locales/nl/messages.json +16 -1
  267. package/src/components/i18n/locales/no/messages.json +16 -1
  268. package/src/components/i18n/locales/pa/messages.json +16 -1
  269. package/src/components/i18n/locales/pl/messages.json +16 -1
  270. package/src/components/i18n/locales/ps/messages.json +16 -1
  271. package/src/components/i18n/locales/pt/messages.json +16 -1
  272. package/src/components/i18n/locales/ro/messages.json +16 -1
  273. package/src/components/i18n/locales/ru/messages.json +16 -1
  274. package/src/components/i18n/locales/sd/messages.json +16 -1
  275. package/src/components/i18n/locales/si/messages.json +16 -1
  276. package/src/components/i18n/locales/sk/messages.json +16 -1
  277. package/src/components/i18n/locales/sl/messages.json +16 -1
  278. package/src/components/i18n/locales/sq/messages.json +16 -1
  279. package/src/components/i18n/locales/sr/messages.json +16 -1
  280. package/src/components/i18n/locales/sv/messages.json +16 -1
  281. package/src/components/i18n/locales/sw/messages.json +16 -1
  282. package/src/components/i18n/locales/ta/messages.json +16 -1
  283. package/src/components/i18n/locales/te/messages.json +16 -1
  284. package/src/components/i18n/locales/th/messages.json +16 -1
  285. package/src/components/i18n/locales/tr/messages.json +16 -1
  286. package/src/components/i18n/locales/ug/messages.json +16 -1
  287. package/src/components/i18n/locales/uk/messages.json +16 -1
  288. package/src/components/i18n/locales/ur/messages.json +16 -1
  289. package/src/components/i18n/locales/vi/messages.json +16 -1
  290. package/src/components/i18n/locales/yi/messages.json +16 -1
  291. package/src/components/i18n/locales/zh/messages.json +16 -1
  292. package/src/components/modules/paste/handlers/blok-data-handler.ts +39 -23
  293. package/src/components/modules/paste/index.ts +38 -4
  294. package/src/components/modules/paste/notion-blocks-v3.ts +932 -0
  295. package/src/components/modules/paste/notion-preprocessor.ts +67 -0
  296. package/src/components/utils/media-empty-state.ts +48 -5
  297. package/src/styles/audio.css +348 -36
  298. package/src/styles/tables.css +10 -0
  299. package/src/tools/audio/constants.ts +6 -0
  300. package/src/tools/audio/controls.ts +53 -7
  301. package/src/tools/audio/cover-picker.ts +126 -0
  302. package/src/tools/audio/disc.ts +137 -0
  303. package/src/tools/audio/index.ts +114 -6
  304. package/src/tools/audio/liveliness.ts +26 -8
  305. package/src/tools/audio/ui.ts +39 -4
  306. package/dist/chunks/constants-R70ypRAK.cjs +0 -606
  307. package/dist/chunks/tools-DcbePIHF.cjs +0 -208
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Pre-process Notion clipboard HTML before sanitization.
3
+ *
4
+ * Notion encodes block/inline state with classes (`to-do-list`, `checkbox-on`,
5
+ * `toggle`, `callout`, `block-color-*`) and non-semantic markup that Blok's
6
+ * sanitizer strips. This function rewrites that markup into Blok's allowed
7
+ * semantic tag set BEFORE the sanitizer runs. It mirrors
8
+ * `preprocessGoogleDocsHtml` and is a no-op when the source is not Notion.
9
+ *
10
+ * Scope note: this is the HTML *fallback* path (Notion desktop app /
11
+ * cross-browser paste). The higher-fidelity path parses Notion's proprietary
12
+ * `text/_notion-blocks-v3-production` JSON flavor directly when present
13
+ * (web→web); see docs/plans/2026-06-22-notion-paste-migration-design.md §4.1b.
14
+ *
15
+ * @param html - raw clipboard HTML string
16
+ * @returns preprocessed HTML string (unchanged when not Notion)
17
+ */
18
+ export function preprocessNotionHtml(html: string): string {
19
+ const wrapper = document.createElement('div');
20
+
21
+ wrapper.innerHTML = html;
22
+
23
+ if (!isNotionClipboard(wrapper)) {
24
+ return html;
25
+ }
26
+
27
+ normalizeInlineMarks(wrapper);
28
+
29
+ return wrapper.innerHTML;
30
+ }
31
+
32
+ /**
33
+ * Centralized Notion clipboard signature. This is the ONE place to update
34
+ * when Notion changes its class names.
35
+ */
36
+ const NOTION_SIGNATURE_SELECTOR = [
37
+ 'figure.callout',
38
+ 'ul.to-do-list',
39
+ 'ul.toggle',
40
+ 'ol.numbered-list',
41
+ 'ul.bulleted-list',
42
+ '.notion-text-equation-token',
43
+ '[class*="block-color-"]',
44
+ 'figure.equation',
45
+ ].join(', ');
46
+
47
+ /**
48
+ * Whether the pasted markup originated from Notion.
49
+ */
50
+ function isNotionClipboard(wrapper: HTMLElement): boolean {
51
+ return wrapper.querySelector(NOTION_SIGNATURE_SELECTOR) !== null;
52
+ }
53
+
54
+ /**
55
+ * Rewrite inline marks that Blok's sanitizer strips into allowed equivalents.
56
+ *
57
+ * Notion emits strikethrough as `<del>`/`<strike>`, but Blok's strikethrough
58
+ * inline tool only whitelists `<s>` — so the others are dropped unless rewritten.
59
+ */
60
+ function normalizeInlineMarks(wrapper: HTMLElement): void {
61
+ wrapper.querySelectorAll('del, strike').forEach((el) => {
62
+ const s = document.createElement('s');
63
+
64
+ s.innerHTML = el.innerHTML;
65
+ el.replaceWith(s);
66
+ });
67
+ }
@@ -48,8 +48,22 @@ export interface MediaEmptyStateOptions {
48
48
  labels: MediaEmptyStateLabels;
49
49
  onFile(file: File): void;
50
50
  onUrl(url: string): void;
51
+ /**
52
+ * How the panel transitions when switching Upload/Link tabs:
53
+ * - `'reflow'` (default): ease the panel height between the two layouts and
54
+ * fade the incoming content in. Smooths the inline reflow of image/file
55
+ * blocks, where content below the card shifts with the height.
56
+ * - `'slide'`: keep the height instant and slide + fade the incoming panel in
57
+ * from the travel direction. A floating popover (audio cover-picker) has
58
+ * nothing reflowing beneath it, so a height tween only reads as lag — the
59
+ * directional slide gives the swap personality without the bottom-edge crawl.
60
+ * - `'none'`: swap instantly with no animation.
61
+ */
62
+ swap?: MediaEmptyStateSwap;
51
63
  }
52
64
 
65
+ export type MediaEmptyStateSwap = 'reflow' | 'slide' | 'none';
66
+
53
67
  const MIME_LABELS: Record<string, string> = {
54
68
  'image/jpeg': 'JPG',
55
69
  'image/jpg': 'JPG',
@@ -170,6 +184,26 @@ function animatePanelSwap(panel: HTMLElement, startHeight: number): void {
170
184
  }
171
185
  }
172
186
 
187
+ /**
188
+ * Slides the freshly-rendered panel content in from the travel direction while
189
+ * fading it up — `dir` is +1 when moving to a tab on the right, -1 to the left.
190
+ * The panel keeps its new height instantly; only the content moves, so there is
191
+ * no bottom-edge crawl (the part that read as lag in a floating popover).
192
+ */
193
+ function animatePanelContent(panel: HTMLElement, dir: number): void {
194
+ const dx = dir * 12;
195
+ for (const child of Array.from(panel.children)) {
196
+ if (!canAnimate(child)) continue;
197
+ child.animate(
198
+ [
199
+ { opacity: 0, transform: `translateX(${dx}px)` },
200
+ { opacity: 1, transform: 'translateX(0)' },
201
+ ],
202
+ { duration: 200, easing: SWAP_EASING, fill: 'backwards' }
203
+ );
204
+ }
205
+ }
206
+
173
207
  export function renderMediaEmptyState(opts: MediaEmptyStateOptions): MediaEmptyStateElement {
174
208
  const { labels } = opts;
175
209
  const types = opts.acceptTypes;
@@ -177,6 +211,8 @@ export function renderMediaEmptyState(opts: MediaEmptyStateOptions): MediaEmptyS
177
211
  const formats = formatsLabel(types);
178
212
  const sizeHint = opts.maxSize !== undefined ? formatBytes(opts.maxSize) : '';
179
213
 
214
+ const swapMode: MediaEmptyStateSwap = opts.swap ?? 'reflow';
215
+
180
216
  const root = document.createElement('div') as unknown as MediaEmptyStateElement;
181
217
  root.className = 'blok-media-empty';
182
218
  root.setAttribute('data-blok-media-empty-state', '');
@@ -349,10 +385,17 @@ export function renderMediaEmptyState(opts: MediaEmptyStateOptions): MediaEmptyS
349
385
  queueMicrotask(() => urlInput.focus());
350
386
  };
351
387
 
352
- const activate = (kind: SourceKind, animate = false): void => {
353
- const startHeight = animate && canAnimate(panel) && !prefersReducedMotion()
388
+ const activate = (kind: SourceKind, transition = false): void => {
389
+ const prevKind = card.getAttribute('data-active-tab') as SourceKind | null;
390
+ const motion = transition
391
+ && swapMode !== 'none'
392
+ && canAnimate(panel)
393
+ && !prefersReducedMotion();
394
+ // Capture the reflow start-height before the content swaps (height tween only).
395
+ const startHeight = motion && swapMode === 'reflow'
354
396
  ? panel.getBoundingClientRect().height
355
397
  : null;
398
+ const dir = prevKind ? Math.sign(tabKinds.indexOf(kind) - tabKinds.indexOf(prevKind)) : 0;
356
399
 
357
400
  const activeTab = tabList[tabKinds.indexOf(kind)];
358
401
  for (const tab of tabList) {
@@ -367,9 +410,9 @@ export function renderMediaEmptyState(opts: MediaEmptyStateOptions): MediaEmptyS
367
410
  if (kind === 'upload') renderUpload();
368
411
  else renderEmbed();
369
412
 
370
- if (startHeight !== null) {
371
- animatePanelSwap(panel, startHeight);
372
- }
413
+ if (!motion) return;
414
+ if (swapMode === 'reflow' && startHeight !== null) animatePanelSwap(panel, startHeight);
415
+ else if (swapMode === 'slide') animatePanelContent(panel, dir);
373
416
  };
374
417
 
375
418
  tabList.forEach((tab, idx) => {
@@ -20,7 +20,10 @@
20
20
  --blok-audio-pad: var(--blok-space-3-5);
21
21
  --blok-audio-radius: var(--blok-radius-md);
22
22
  --blok-audio-wave-height: 56px;
23
- --blok-audio-bar-height: 3px;
23
+ --blok-audio-bar-height: 4px;
24
+ /* lift the slim slider thumbs (volume + speed) off the track so they read as
25
+ tactile pucks rather than flat dots */
26
+ --blok-audio-thumb-shadow: 0 1px 2px rgba(0, 0, 0, 0.28);
24
27
  --blok-audio-ctrl-size: 30px;
25
28
  --blok-audio-play-size: 36px;
26
29
  --blok-audio-bar: var(--blok-border-subtle);
@@ -33,6 +36,46 @@
33
36
  --blok-audio-speed-pct: 50%;
34
37
  --blok-audio-pulse-ring: color-mix(in srgb, var(--blok-text-primary) 20%, transparent);
35
38
 
39
+ /* no-cover vinyl placeholder — a glossy black record. The disc body is built
40
+ from --blok-overlay-dark (near-black in both themes) so it always reads as
41
+ vinyl, not a grey CD; grooves + sheen are white at low alpha, the label is
42
+ a cream-white puck, the spindle is a crisp dark dot. A fixed specular sits
43
+ above the disc (placeholder::after) so grooves shimmer *under* it as it spins. */
44
+ --blok-audio-disc-size: 92px;
45
+ --blok-audio-groove-w: 0.75px;
46
+ --blok-audio-groove-gap: 2px;
47
+ --blok-audio-cover-glow: color-mix(in srgb, var(--blok-bg-primary) 55%, transparent);
48
+ /* glossy black record body: a near-black face with a centre→edge vignette so it
49
+ reads as a curved, light-catching surface rather than a flat circle. */
50
+ --blok-audio-disc-base: var(--blok-overlay-dark);
51
+ --blok-audio-disc-deep: color-mix(in srgb, #000 42%, var(--blok-overlay-dark));
52
+ --blok-audio-disc-edge: color-mix(in srgb, var(--blok-text-on-dark) 6%, var(--blok-overlay-dark));
53
+ --blok-audio-disc-groove: color-mix(in srgb, var(--blok-text-on-dark) 8%, transparent);
54
+ --blok-audio-disc-rim: color-mix(in srgb, var(--blok-text-on-dark) 16%, transparent);
55
+ --blok-audio-disc-rim-light: color-mix(in srgb, var(--blok-text-on-dark) 26%, transparent);
56
+ /* fixed specular reflection — two bright bands of "light" the grooves shimmer
57
+ under as the disc spins (this is what sells real glossy vinyl). */
58
+ --blok-audio-disc-sheen: color-mix(in srgb, var(--blok-text-on-dark) 32%, transparent);
59
+ --blok-audio-disc-sheen-soft: color-mix(in srgb, var(--blok-text-on-dark) 12%, transparent);
60
+ /* a soft highlight wedge printed on the disc — sweeps round with the grooves so
61
+ the (otherwise radially-symmetric) spin actually reads as motion. */
62
+ --blok-audio-disc-shine: color-mix(in srgb, var(--blok-text-on-dark) 10%, transparent);
63
+ /* centre label — a matte, faintly warm cream puck (not a flat white disc) */
64
+ --blok-audio-disc-label: color-mix(in srgb, var(--blok-text-on-dark) 93%, var(--blok-overlay-dark));
65
+ --blok-audio-disc-label-hi: var(--blok-text-on-dark);
66
+ --blok-audio-disc-label-edge: color-mix(in srgb, var(--blok-text-on-dark) 72%, var(--blok-overlay-dark));
67
+ --blok-audio-disc-label-ring: color-mix(in srgb, var(--blok-overlay-dark) 24%, transparent);
68
+ --blok-audio-disc-hole: var(--blok-overlay-dark);
69
+ /* opaque fill for the reflection mask (only its alpha matters) */
70
+ --blok-audio-mask-solid: #000;
71
+ /* depth shadows for the disc rim, label lift and spindle catch-light */
72
+ --blok-audio-disc-inner-shadow: rgba(0, 0, 0, 0.5);
73
+ --blok-audio-label-shadow: rgba(0, 0, 0, 0.35);
74
+ --blok-audio-spindle-catch: rgba(255, 255, 255, 0.4);
75
+ /* cover overlay button — a semi-transparent dark scrim (same near-black as
76
+ the disc, blended down to ~45% opacity so the art shows through) */
77
+ --blok-audio-cover-scrim: color-mix(in srgb, var(--blok-overlay-dark) 50%, transparent);
78
+
36
79
  position: relative;
37
80
  margin: var(--blok-space-2-5) 0;
38
81
  font-family: var(--blok-font-family, var(--blok-font-sans));
@@ -70,6 +113,20 @@
70
113
  display: none;
71
114
  }
72
115
 
116
+ /* Top-of-card toolbar anchor — a zero-size marker the editor centers the +/tunes
117
+ buttons on. Pinned to the top-left of the grid; line-height stays a hair above 0
118
+ (the positioner floors a 0 line-height back to its 24px default), so the buttons
119
+ land flush with the top of the cover art. */
120
+ [data-blok-tool="audio"] .blok-audio-toolbar-anchor {
121
+ grid-column: 1;
122
+ grid-row: 1;
123
+ align-self: start;
124
+ width: 0;
125
+ height: 0;
126
+ line-height: 1px;
127
+ pointer-events: none;
128
+ }
129
+
73
130
  /* ----- block selection ------------------------------------ */
74
131
  [data-blok-element-content].bg-selection:has([data-blok-tool="audio"]) {
75
132
  background-color: transparent;
@@ -100,13 +157,215 @@
100
157
  object-fit: cover;
101
158
  display: block;
102
159
  }
160
+
161
+ /* ----- change-cover overlay button (edit mode only) -------- */
162
+ /* Stretches across the full cover panel; stays invisible until the cover
163
+ is hovered or the button receives keyboard focus — preventing it from
164
+ obscuring the art in read-only contexts. */
165
+ [data-blok-tool="audio"] .blok-audio-cover__change {
166
+ position: absolute;
167
+ inset: 0;
168
+ display: grid;
169
+ place-items: center;
170
+ border: 0;
171
+ margin: 0;
172
+ padding: 0;
173
+ cursor: pointer;
174
+ color: var(--blok-text-on-dark);
175
+ background: var(--blok-audio-cover-scrim);
176
+ opacity: 0;
177
+ transition: opacity var(--blok-duration-base) ease;
178
+ }
179
+ [data-blok-tool="audio"] .blok-audio-cover:hover .blok-audio-cover__change,
180
+ [data-blok-tool="audio"] .blok-audio-cover.is-picker-open .blok-audio-cover__change,
181
+ [data-blok-tool="audio"] .blok-audio-cover__change:focus-visible {
182
+ opacity: 1;
183
+ }
184
+ [data-blok-tool="audio"] .blok-audio-cover__change svg {
185
+ width: 20px;
186
+ height: 20px;
187
+ pointer-events: none;
188
+ }
189
+
190
+ /* ----- cover-picker dialog (top-layer promoted) ------------- */
191
+ /* The dialog is its own elevated surface so the media-empty card inside layers
192
+ correctly. Two UA/reset hazards to beat:
193
+ 1. The `[data-blok-top-layer][popover]` reset in main.css (specificity 0,0,2,0)
194
+ forces width:auto and strips border/padding — without an explicit width the
195
+ flex-column surface collapses to a ~2px sliver. So every box-model property
196
+ is re-asserted with matching specificity (mirrors the image-lightbox /
197
+ file-preview precedent).
198
+ 2. The UA `[popover]` rule paints `background: Canvas` (white) and the reset
199
+ does NOT clear it. The media-empty card uses --blok-bg-secondary, which in
200
+ the dark theme is a translucent white overlay meant to sit on a dark parent;
201
+ over the white canvas it reads white. Painting the dialog with the solid
202
+ --blok-bg-primary surface gives that overlay the dark backdrop it expects.
203
+ Width stays a plain length (not a --blok-space token) per the proven pattern;
204
+ the other surface tokens resolve fine on the promoted element (colors +
205
+ spacing are bridged to [data-blok-top-layer]). The base rule covers the
206
+ no-Popover-API fallback (element stays in normal flow, no reset applied). */
207
+ .blok-audio-cover-picker,
208
+ .blok-audio-cover-picker[data-blok-top-layer][popover] {
209
+ z-index: 1;
210
+ width: min(440px, calc(100vw - 32px));
211
+ padding: var(--blok-space-2);
212
+ background: var(--blok-bg-primary);
213
+ border: 1px solid var(--blok-border-subtle);
214
+ border-radius: var(--blok-radius-lg);
215
+ box-shadow: var(--blok-popover-box-shadow);
216
+ }
217
+ /* The picker lives at document.body, outside blok's scoped border-box reset, so
218
+ its subtree would default to content-box. The media-empty Upload/Link height-
219
+ swap animation measures the border-box height but animates the `height`
220
+ property — under content-box that adds the panel padding on top, overshooting
221
+ then snapping back (a visible height jump). Match the inline (border-box)
222
+ context the component was built for. */
223
+ .blok-audio-cover-picker,
224
+ .blok-audio-cover-picker * {
225
+ box-sizing: border-box;
226
+ }
227
+
228
+ /* Entrance — the picker rises + scales up from its top-left anchor corner so it
229
+ reads as growing out of the cover, matching the block's own mount language
230
+ (blok-audio-rise / --blok-ease-popover). The directional content slide between
231
+ the Upload/Link tabs is driven from media-empty-state.ts (WAAPI). */
232
+ .blok-audio-cover-picker {
233
+ transform-origin: top left;
234
+ animation: blok-audio-cover-picker-in var(--blok-duration-slow) var(--blok-ease-popover) both;
235
+ }
236
+
237
+ @keyframes blok-audio-cover-picker-in {
238
+ from { opacity: 0; transform: translateY(-6px) scale(0.96); }
239
+ to { opacity: 1; transform: translateY(0) scale(1); }
240
+ }
241
+
242
+ @media (prefers-reduced-motion: reduce) {
243
+ .blok-audio-cover-picker { animation: none; }
244
+ }
245
+
246
+ /* ----- no-cover placeholder: a glossy black vinyl record --- */
103
247
  [data-blok-tool="audio"] .blok-audio-cover__placeholder {
248
+ position: relative;
104
249
  display: flex;
250
+ align-items: center;
251
+ justify-content: center;
252
+ width: 100%;
253
+ height: 100%;
254
+ /* faint top-centre sheen so the panel has depth behind the disc */
255
+ background: radial-gradient(120% 90% at 50% 36%, var(--blok-audio-cover-glow), transparent 70%);
105
256
  }
106
- [data-blok-tool="audio"] .blok-audio-cover__placeholder svg {
107
- width: 34px;
108
- height: 34px;
109
- color: var(--blok-text-tertiary);
257
+
258
+ /* fixed specular glint pinned over the disc — it does NOT rotate, so the grooves
259
+ shimmer beneath it as the record spins (the bit that sells the motion). */
260
+ [data-blok-tool="audio"] .blok-audio-cover__placeholder::after {
261
+ content: "";
262
+ position: absolute;
263
+ top: 50%;
264
+ left: 50%;
265
+ width: var(--blok-audio-disc-size);
266
+ height: var(--blok-audio-disc-size);
267
+ transform: translate(-50%, -50%);
268
+ border-radius: var(--blok-radius-pill);
269
+ background:
270
+ /* bright crescent of light along the top rim */
271
+ radial-gradient(72% 50% at 50% 2%, var(--blok-audio-disc-sheen), transparent 60%),
272
+ /* the main gloss: two opposed soft bands (a vinyl "bow-tie" reflection) */
273
+ conic-gradient(
274
+ from 142deg at 50% 50%,
275
+ transparent 0 6%,
276
+ var(--blok-audio-disc-sheen) 15%,
277
+ transparent 30% 64%,
278
+ var(--blok-audio-disc-sheen-soft) 80%,
279
+ transparent 92% 100%
280
+ ),
281
+ /* faint bounce light in the lower-right quadrant */
282
+ radial-gradient(44% 36% at 72% 84%, var(--blok-audio-disc-sheen-soft), transparent 62%);
283
+ /* the gloss only lives on the vinyl — keep it off the matte paper label */
284
+ mask: radial-gradient(circle at center, transparent 30%, var(--blok-audio-mask-solid) 40%);
285
+ -webkit-mask: radial-gradient(circle at center, transparent 30%, var(--blok-audio-mask-solid) 40%);
286
+ pointer-events: none;
287
+ }
288
+
289
+ /* the record body: fine concentric grooves over a near-black radial face,
290
+ lifted off the panel by an inset rim + soft shadow. Its rotation is driven
291
+ imperatively by disc.ts (transform: rotate), which spins the platter up on
292
+ play and lets it coast down on pause — so the disc has real inertia rather
293
+ than snapping on/off with a CSS animation. */
294
+ [data-blok-tool="audio"] .blok-audio-cover__disc {
295
+ position: relative;
296
+ will-change: transform;
297
+ width: var(--blok-audio-disc-size);
298
+ height: var(--blok-audio-disc-size);
299
+ border-radius: var(--blok-radius-pill);
300
+ background:
301
+ /* soft shine wedge that rotates with the grooves (rotation feedback) */
302
+ conic-gradient(
303
+ from 210deg,
304
+ transparent 0 64%,
305
+ var(--blok-audio-disc-shine) 78%,
306
+ transparent 92% 100%
307
+ ),
308
+ /* a bright hairline run just inside the edge — the glossy outer bevel */
309
+ radial-gradient(
310
+ circle at center,
311
+ transparent 82%,
312
+ var(--blok-audio-disc-rim-light) 85% 87%,
313
+ transparent 90%
314
+ ),
315
+ /* fine concentric grooves */
316
+ repeating-radial-gradient(
317
+ circle at center,
318
+ var(--blok-audio-disc-groove) 0 var(--blok-audio-groove-w),
319
+ transparent var(--blok-audio-groove-w) var(--blok-audio-groove-gap)
320
+ ),
321
+ /* glossy black face with a centre→edge vignette (curved-surface shading) */
322
+ radial-gradient(
323
+ circle at center,
324
+ var(--blok-audio-disc-edge) 0 14%,
325
+ var(--blok-audio-disc-base) 44%,
326
+ var(--blok-audio-disc-base) 72%,
327
+ var(--blok-audio-disc-deep) 100%
328
+ );
329
+ box-shadow:
330
+ inset 0 0 0 1px var(--blok-audio-disc-rim),
331
+ inset 0 0 7px var(--blok-audio-disc-inner-shadow),
332
+ var(--blok-image-shadow-resting);
333
+ }
334
+
335
+ /* centre label — a small matte cream puck with a printed concentric ring */
336
+ [data-blok-tool="audio"] .blok-audio-cover__disc::before {
337
+ content: "";
338
+ position: absolute;
339
+ inset: 36%;
340
+ border-radius: var(--blok-radius-pill);
341
+ background:
342
+ /* a thin printed ring near the label rim */
343
+ radial-gradient(
344
+ circle at center,
345
+ transparent 58%,
346
+ var(--blok-audio-disc-label-ring) 60% 64%,
347
+ transparent 66%
348
+ ),
349
+ /* paper with a soft off-axis sheen */
350
+ radial-gradient(
351
+ circle at 40% 34%,
352
+ var(--blok-audio-disc-label-hi),
353
+ var(--blok-audio-disc-label) 52%,
354
+ var(--blok-audio-disc-label-edge)
355
+ );
356
+ box-shadow:
357
+ inset 0 0 0 1px var(--blok-audio-disc-rim),
358
+ 0 1px 1px var(--blok-audio-label-shadow);
359
+ }
360
+
361
+ /* spindle hole — a crisp dark dot with a tiny rim catch */
362
+ [data-blok-tool="audio"] .blok-audio-cover__disc::after {
363
+ content: "";
364
+ position: absolute;
365
+ inset: 47%;
366
+ border-radius: var(--blok-radius-pill);
367
+ background: var(--blok-audio-disc-hole);
368
+ box-shadow: inset 0 1px 1px var(--blok-audio-spindle-catch);
110
369
  }
111
370
 
112
371
  /* ----- right column (title + artist + waveform + controls) - */
@@ -180,8 +439,12 @@
180
439
  margin-top: var(--blok-space-1);
181
440
  }
182
441
 
183
- /* generic control button */
184
- [data-blok-tool="audio"] .blok-audio-controls [data-role] {
442
+ /* generic control button — scoped to <button> so the volume <input> and the
443
+ time <span> (both carry data-role) keep their own slim/text styling instead
444
+ of being clobbered into a 30px pill. Every button-specific rule below is also
445
+ anchored on `button[data-role…]` so they share this rule's specificity and
446
+ win on source order. */
447
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role] {
185
448
  flex-shrink: 0;
186
449
  display: inline-grid;
187
450
  place-items: center;
@@ -195,20 +458,20 @@
195
458
  cursor: pointer;
196
459
  transition: background var(--blok-duration-base) ease, color var(--blok-duration-base) ease, transform var(--blok-duration-base) ease;
197
460
  }
198
- [data-blok-tool="audio"] .blok-audio-controls [data-role]:hover {
461
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role]:hover {
199
462
  background: var(--blok-bg-hover);
200
463
  color: var(--blok-text-primary);
201
464
  }
202
- [data-blok-tool="audio"] .blok-audio-controls [data-role]:active {
465
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role]:active {
203
466
  transform: scale(0.92);
204
467
  }
205
- [data-blok-tool="audio"] .blok-audio-controls [data-role] svg {
468
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role] svg {
206
469
  width: 17px;
207
470
  height: 17px;
208
471
  }
209
472
 
210
473
  /* play / pause — filled black puck */
211
- [data-blok-tool="audio"] .blok-audio-controls [data-role="audio-play"] {
474
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role="audio-play"] {
212
475
  width: var(--blok-audio-play-size);
213
476
  height: var(--blok-audio-play-size);
214
477
  margin-right: var(--blok-space-0-5);
@@ -216,15 +479,15 @@
216
479
  color: var(--blok-bg-primary);
217
480
  box-shadow: var(--blok-image-shadow-resting);
218
481
  }
219
- [data-blok-tool="audio"] .blok-audio-controls [data-role="audio-play"]:hover {
482
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role="audio-play"]:hover {
220
483
  background: var(--blok-text-primary);
221
484
  color: var(--blok-bg-primary);
222
485
  transform: scale(1.05);
223
486
  }
224
- [data-blok-tool="audio"] .blok-audio-controls [data-role="audio-play"]:active {
487
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role="audio-play"]:active {
225
488
  transform: scale(0.96);
226
489
  }
227
- [data-blok-tool="audio"] .blok-audio-controls [data-role="audio-play"] svg {
490
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role="audio-play"] svg {
228
491
  width: 19px;
229
492
  height: 19px;
230
493
  }
@@ -278,6 +541,7 @@
278
541
  height: 12px;
279
542
  border-radius: var(--blok-radius-pill);
280
543
  background: var(--blok-text-primary);
544
+ box-shadow: var(--blok-audio-thumb-shadow);
281
545
  }
282
546
  [data-blok-tool="audio"] .blok-audio-controls__volume::-moz-range-thumb {
283
547
  width: 12px;
@@ -285,14 +549,15 @@
285
549
  border: 0;
286
550
  border-radius: var(--blok-radius-pill);
287
551
  background: var(--blok-text-primary);
552
+ box-shadow: var(--blok-audio-thumb-shadow);
288
553
  }
289
554
 
290
555
  /* loop active state — neutral black, no accent color */
291
- [data-blok-tool="audio"] .blok-audio-controls [data-role="audio-loop"][aria-pressed="true"] {
556
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role="audio-loop"][aria-pressed="true"] {
292
557
  color: var(--blok-bg-primary);
293
558
  background: var(--blok-text-primary);
294
559
  }
295
- [data-blok-tool="audio"] .blok-audio-controls [data-role="audio-loop"][aria-pressed="true"]:hover {
560
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role="audio-loop"][aria-pressed="true"]:hover {
296
561
  color: var(--blok-bg-primary);
297
562
  background: var(--blok-text-primary);
298
563
  }
@@ -303,7 +568,7 @@
303
568
  display: inline-flex;
304
569
  flex-shrink: 0;
305
570
  }
306
- [data-blok-tool="audio"] .blok-audio-controls [data-role="audio-speed"][aria-expanded="true"] {
571
+ [data-blok-tool="audio"] .blok-audio-controls button[data-role="audio-speed"][aria-expanded="true"] {
307
572
  background: var(--blok-bg-hover);
308
573
  color: var(--blok-text-primary);
309
574
  }
@@ -332,10 +597,50 @@
332
597
  margin-bottom: var(--blok-space-2);
333
598
  }
334
599
 
600
+ /* − [slider] + — flat icon steppers flank a flexible track (mirrors the video
601
+ player's speed control). */
602
+ [data-blok-tool="audio"] .blok-audio-controls__speed-slider-row {
603
+ display: flex;
604
+ align-items: center;
605
+ gap: var(--blok-space-1-5);
606
+ margin-bottom: var(--blok-space-2);
607
+ }
608
+ [data-blok-tool="audio"] .blok-audio-controls__speed-step {
609
+ display: grid;
610
+ place-items: center;
611
+ flex-shrink: 0;
612
+ width: 24px;
613
+ height: 24px;
614
+ padding: 0;
615
+ border: 0;
616
+ border-radius: var(--blok-radius-sm);
617
+ background: transparent;
618
+ color: var(--blok-text-tertiary);
619
+ cursor: pointer;
620
+ transition: background var(--blok-duration-base) ease, color var(--blok-duration-base) ease, transform var(--blok-duration-base) ease, opacity var(--blok-duration-base) ease;
621
+ }
622
+ [data-blok-tool="audio"] .blok-audio-controls__speed-step:hover {
623
+ background: var(--blok-bg-hover);
624
+ color: var(--blok-text-primary);
625
+ }
626
+ [data-blok-tool="audio"] .blok-audio-controls__speed-step:active {
627
+ transform: scale(0.92);
628
+ }
629
+ [data-blok-tool="audio"] .blok-audio-controls__speed-step:disabled {
630
+ opacity: 0.35;
631
+ cursor: default;
632
+ transform: none;
633
+ }
634
+ [data-blok-tool="audio"] .blok-audio-controls__speed-step svg {
635
+ width: 15px;
636
+ height: 15px;
637
+ }
638
+
335
639
  [data-blok-tool="audio"] .blok-audio-controls__speed-slider {
336
- width: 100%;
640
+ flex: 1 1 auto;
641
+ min-width: 0;
337
642
  height: var(--blok-audio-bar-height);
338
- margin: 0 0 var(--blok-space-2);
643
+ margin: 0;
339
644
  -webkit-appearance: none;
340
645
  appearance: none;
341
646
  background: linear-gradient(
@@ -353,6 +658,7 @@
353
658
  height: 12px;
354
659
  border-radius: var(--blok-radius-pill);
355
660
  background: var(--blok-text-primary);
661
+ box-shadow: var(--blok-audio-thumb-shadow);
356
662
  }
357
663
  [data-blok-tool="audio"] .blok-audio-controls__speed-slider::-moz-range-thumb {
358
664
  width: 12px;
@@ -360,6 +666,7 @@
360
666
  border: 0;
361
667
  border-radius: var(--blok-radius-pill);
362
668
  background: var(--blok-text-primary);
669
+ box-shadow: var(--blok-audio-thumb-shadow);
363
670
  }
364
671
 
365
672
  [data-blok-tool="audio"] .blok-audio-controls__speed-chips {
@@ -386,30 +693,29 @@
386
693
  }
387
694
 
388
695
  /* ----- caption row (full-width footer) --------------------
389
- The row is a single-track grid wrapper so it can collapse to zero height
390
- (grid-template-rows 1fr 0fr) when the caption is toggled, while the inner
391
- element holds the actual padding/border that fade out with it. */
696
+ The row claims its full height in a single layout step; the visible reveal
697
+ rides transform + opacity on the inner, keeping the whole animation on the
698
+ compositor. This is deliberate: animating the row's *height* would resize the
699
+ card every frame, forcing a re-raster of its 24px-blur box-shadow and the
700
+ high-DPI waveform canvas each frame — which is what made the toggle lag.
701
+ overflow:hidden clips the inner as it slides; padding/border live on the
702
+ caption child below so they're clipped too. */
392
703
  [data-blok-tool="audio"] .blok-audio-caption-row {
393
704
  grid-column: 1 / -1;
394
705
  grid-row: 2;
395
- display: grid;
396
- grid-template-rows: 1fr;
397
- transition:
398
- grid-template-rows var(--blok-duration-slow) var(--blok-ease-popover),
399
- opacity var(--blok-duration-slow) var(--blok-ease-popover);
400
- }
401
- [data-blok-tool="audio"] .blok-audio-caption-row.is-collapsed {
402
- grid-template-rows: 0fr;
403
- opacity: 0;
706
+ overflow: hidden;
404
707
  }
405
- /* overflow:hidden + min-height:0 lets the grid track collapse fully to 0; the
406
- padding/border live on the caption child below so they get clipped too. */
407
708
  [data-blok-tool="audio"] .blok-audio-caption-row__inner {
408
- min-height: 0;
409
- overflow: hidden;
410
709
  display: flex;
411
710
  align-items: flex-start;
412
711
  gap: var(--blok-space-2);
712
+ transition:
713
+ transform var(--blok-duration-slow) var(--blok-ease-popover),
714
+ opacity var(--blok-duration-slow) var(--blok-ease-popover);
715
+ }
716
+ [data-blok-tool="audio"] .blok-audio-caption-row.is-collapsed .blok-audio-caption-row__inner {
717
+ transform: translateY(6px);
718
+ opacity: 0;
413
719
  }
414
720
  [data-blok-tool="audio"] .blok-audio-caption {
415
721
  flex: 1 1 auto;
@@ -518,6 +824,9 @@
518
824
  50% { height: 96%; }
519
825
  }
520
826
 
827
+ /* The vinyl placeholder's spin is driven by disc.ts (inertial rotation via
828
+ transform), not a CSS animation — see the .blok-audio-cover__disc rule. */
829
+
521
830
  /* ----- 3. play puck heartbeat while playing ---------------------- */
522
831
  [data-blok-tool="audio"] .blok-audio-inner[data-playing="true"] .blok-audio-controls [data-role="audio-play"] {
523
832
  animation: blok-audio-pulse var(--blok-duration-rotation) var(--blok-ease-spring) infinite;
@@ -546,6 +855,9 @@
546
855
  }
547
856
  /* The badge still appears while playing — it just holds steady. */
548
857
  [data-blok-tool="audio"] .blok-audio-eq { transition: none; }
858
+ /* The record holds still under reduced motion (disc.ts skips the spin loop). */
549
859
  /* Caption appears/disappears instantly (JS also takes the instant path). */
550
- [data-blok-tool="audio"] .blok-audio-caption-row { transition: none; }
860
+ [data-blok-tool="audio"] .blok-audio-caption-row__inner { transition: none; }
861
+ /* Cover overlay button appears instantly — no fade. */
862
+ [data-blok-tool="audio"] .blok-audio-cover__change { transition: none; }
551
863
  }