@alfadocs/ui-kit-debug 1.44.0 → 1.46.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 (284) hide show
  1. package/dist/_chunks/{actions-cell-renderer-BXBy9c0f.js → actions-cell-renderer-B5m9lwgC.js} +2 -2
  2. package/dist/_chunks/{actions-cell-renderer-BXBy9c0f.js.map → actions-cell-renderer-B5m9lwgC.js.map} +1 -1
  3. package/dist/_chunks/ai-credits-notice-xszqOZTC.js +90 -0
  4. package/dist/_chunks/ai-credits-notice-xszqOZTC.js.map +1 -0
  5. package/dist/_chunks/ai-credits-notice.agent-C9L7orrP.js +17 -0
  6. package/dist/_chunks/ai-credits-notice.agent-C9L7orrP.js.map +1 -0
  7. package/dist/_chunks/{ai-consent-banner-D7I2U-cz.js → ai-permission-notice-D7I2U-cz.js} +1 -1
  8. package/dist/_chunks/ai-permission-notice-D7I2U-cz.js.map +1 -0
  9. package/dist/_chunks/ai-sparkle-D23NT8Z_.js +45 -0
  10. package/dist/_chunks/ai-sparkle-D23NT8Z_.js.map +1 -0
  11. package/dist/_chunks/{anamnesis-summary-rows-DQUqwWc1.js → anamnesis-summary-rows-DI-UX5r6.js} +2 -2
  12. package/dist/_chunks/{anamnesis-summary-rows-DQUqwWc1.js.map → anamnesis-summary-rows-DI-UX5r6.js.map} +1 -1
  13. package/dist/_chunks/{appointment-card-TgR_2GKS.js → appointment-card-DluZy8Iv.js} +2 -2
  14. package/dist/_chunks/{appointment-card-TgR_2GKS.js.map → appointment-card-DluZy8Iv.js.map} +1 -1
  15. package/dist/_chunks/{appointment-peek-abiR0T9e.js → appointment-peek-BsfCpiJs.js} +3 -3
  16. package/dist/_chunks/{appointment-peek-abiR0T9e.js.map → appointment-peek-BsfCpiJs.js.map} +1 -1
  17. package/dist/_chunks/{appointment-timeline-CCnyUYKz.js → appointment-timeline-Cs5f9viN.js} +3 -3
  18. package/dist/_chunks/{appointment-timeline-CCnyUYKz.js.map → appointment-timeline-Cs5f9viN.js.map} +1 -1
  19. package/dist/_chunks/{appointment-tray-N0yEI8UF.js → appointment-tray-CLrGGnKR.js} +2 -2
  20. package/dist/_chunks/{appointment-tray-N0yEI8UF.js.map → appointment-tray-CLrGGnKR.js.map} +1 -1
  21. package/dist/_chunks/baby-Dku-Xvg9.js +23 -0
  22. package/dist/_chunks/baby-Dku-Xvg9.js.map +1 -0
  23. package/dist/_chunks/{balance-badge-cell-o6LldMUA.js → balance-badge-cell-YGrYdrvR.js} +3 -3
  24. package/dist/_chunks/{balance-badge-cell-o6LldMUA.js.map → balance-badge-cell-YGrYdrvR.js.map} +1 -1
  25. package/dist/_chunks/{booking-D43ASl8y.js → booking-B7gA9gFB.js} +279 -296
  26. package/dist/_chunks/booking-B7gA9gFB.js.map +1 -0
  27. package/dist/_chunks/button-group-CA1tmu39.js +325 -0
  28. package/dist/_chunks/button-group-CA1tmu39.js.map +1 -0
  29. package/dist/_chunks/{calendar-U6N0F99w.js → calendar-OzSeTb4V.js} +2 -2
  30. package/dist/_chunks/{calendar-U6N0F99w.js.map → calendar-OzSeTb4V.js.map} +1 -1
  31. package/dist/_chunks/{calendar-event-card-DKUnT9Be.js → calendar-event-card-B6N5h1dO.js} +57 -48
  32. package/dist/_chunks/{calendar-event-card-DKUnT9Be.js.map → calendar-event-card-B6N5h1dO.js.map} +1 -1
  33. package/dist/_chunks/{calendar-workspace-DBYAtdyd.js → calendar-workspace-BB-BZT7W.js} +3002 -2912
  34. package/dist/_chunks/calendar-workspace-BB-BZT7W.js.map +1 -0
  35. package/dist/_chunks/{chart-PF2krCZC.js → chart-D8ucl8hH.js} +2 -2
  36. package/dist/_chunks/{chart-PF2krCZC.js.map → chart-D8ucl8hH.js.map} +1 -1
  37. package/dist/_chunks/{data-table-CcAx_I1w.js → data-table-DnKOmEVw.js} +2 -2
  38. package/dist/_chunks/{data-table-CcAx_I1w.js.map → data-table-DnKOmEVw.js.map} +1 -1
  39. package/dist/_chunks/{editable-currency-cell-renderer-Psb6XKHR.js → editable-currency-cell-renderer-OUkUv7U4.js} +2 -2
  40. package/dist/_chunks/{editable-currency-cell-renderer-Psb6XKHR.js.map → editable-currency-cell-renderer-OUkUv7U4.js.map} +1 -1
  41. package/dist/_chunks/{face-scheme-Bm6pe7R8.js → face-scheme-mIhwrQXt.js} +3 -3
  42. package/dist/_chunks/{face-scheme-Bm6pe7R8.js.map → face-scheme-mIhwrQXt.js.map} +1 -1
  43. package/dist/_chunks/{file-manager-BfLQxF5t.js → file-manager-DOcJGIx2.js} +4 -4
  44. package/dist/_chunks/{file-manager-BfLQxF5t.js.map → file-manager-DOcJGIx2.js.map} +1 -1
  45. package/dist/_chunks/{header-settings-CTe45iDy.js → header-settings-BEfx_-TF.js} +2 -2
  46. package/dist/_chunks/{header-settings-CTe45iDy.js.map → header-settings-BEfx_-TF.js.map} +1 -1
  47. package/dist/_chunks/{help-me-write-templates-GUeEn3Ff.js → help-me-write-templates-DHIwa4xR.js} +205 -199
  48. package/dist/_chunks/help-me-write-templates-DHIwa4xR.js.map +1 -0
  49. package/dist/_chunks/{hover-card-BMJBVqIf.js → hover-card-nUae8NPJ.js} +67 -62
  50. package/dist/_chunks/{hover-card-BMJBVqIf.js.map → hover-card-nUae8NPJ.js.map} +1 -1
  51. package/dist/_chunks/{icon-button-group-DkkdIygu.js → icon-button-group-DZKC6KGf.js} +181 -168
  52. package/dist/_chunks/icon-button-group-DZKC6KGf.js.map +1 -0
  53. package/dist/_chunks/kit-extensions-DuoFF1R3.js +94 -0
  54. package/dist/_chunks/kit-extensions-DuoFF1R3.js.map +1 -0
  55. package/dist/_chunks/{marketplace-app-shell-DdwPj03y.js → marketplace-app-shell-PB89Dkk_.js} +2 -2
  56. package/dist/_chunks/{marketplace-app-shell-DdwPj03y.js.map → marketplace-app-shell-PB89Dkk_.js.map} +1 -1
  57. package/dist/_chunks/{notes-panel-CY4KmDo-.js → notes-panel-CHbDDMx8.js} +83 -73
  58. package/dist/_chunks/notes-panel-CHbDDMx8.js.map +1 -0
  59. package/dist/_chunks/{patient-details-C8ImUrVg.js → patient-details-DUj1htsH.js} +2 -2
  60. package/dist/_chunks/{patient-details-C8ImUrVg.js.map → patient-details-DUj1htsH.js.map} +1 -1
  61. package/dist/_chunks/{patient-field-row-BRSOKvme.js → patient-field-row-CO0WR7yA.js} +2 -2
  62. package/dist/_chunks/patient-field-row-CO0WR7yA.js.map +1 -0
  63. package/dist/_chunks/{patient-summary-card-BhmKB2KR.js → patient-summary-card-DNzdYjxE.js} +59 -45
  64. package/dist/_chunks/patient-summary-card-DNzdYjxE.js.map +1 -0
  65. package/dist/_chunks/rich-text-editor-BwDV2XkZ.js +4153 -0
  66. package/dist/_chunks/rich-text-editor-BwDV2XkZ.js.map +1 -0
  67. package/dist/_chunks/{tasks-panel-CpcikOeY.js → tasks-panel-DncuBPIZ.js} +2 -2
  68. package/dist/_chunks/{tasks-panel-CpcikOeY.js.map → tasks-panel-DncuBPIZ.js.map} +1 -1
  69. package/dist/_chunks/{theme-toggle-bI0pgDDv.js → theme-toggle-BP0XRGMM.js} +2 -2
  70. package/dist/_chunks/{theme-toggle-bI0pgDDv.js.map → theme-toggle-BP0XRGMM.js.map} +1 -1
  71. package/dist/_chunks/use-ai-sparkle-Cf4yVTLB.js +76 -0
  72. package/dist/_chunks/use-ai-sparkle-Cf4yVTLB.js.map +1 -0
  73. package/dist/_chunks/{workflow-status-xeaJTzD3.js → workflow-status-CuJAOuKL.js} +43 -42
  74. package/dist/_chunks/{workflow-status-xeaJTzD3.js.map → workflow-status-CuJAOuKL.js.map} +1 -1
  75. package/dist/agent-catalog.json +32 -4
  76. package/dist/agent-i18n/en.json +1 -1
  77. package/dist/components/_shared/field-value.d.ts.map +1 -1
  78. package/dist/components/ai-credits-notice/ai-credits-notice.agent.d.ts +3 -0
  79. package/dist/components/ai-credits-notice/ai-credits-notice.agent.d.ts.map +1 -0
  80. package/dist/components/ai-credits-notice/ai-credits-notice.d.ts +48 -0
  81. package/dist/components/ai-credits-notice/ai-credits-notice.d.ts.map +1 -0
  82. package/dist/components/ai-credits-notice/index.d.ts +4 -0
  83. package/dist/components/ai-credits-notice/index.d.ts.map +1 -0
  84. package/dist/components/ai-credits-notice/index.js +7 -0
  85. package/dist/components/ai-credits-notice/index.js.map +1 -0
  86. package/dist/components/{ai-consent-banner/ai-consent-banner.agent.d.ts → ai-permission-notice/ai-permission-notice.agent.d.ts} +2 -2
  87. package/dist/components/ai-permission-notice/ai-permission-notice.agent.d.ts.map +1 -0
  88. package/dist/components/{ai-consent-banner/ai-consent-banner.d.ts → ai-permission-notice/ai-permission-notice.d.ts} +1 -1
  89. package/dist/components/ai-permission-notice/ai-permission-notice.d.ts.map +1 -0
  90. package/dist/components/ai-permission-notice/index.d.ts +4 -0
  91. package/dist/components/ai-permission-notice/index.d.ts.map +1 -0
  92. package/dist/components/{ai-consent-banner → ai-permission-notice}/index.js +1 -1
  93. package/dist/components/ai-sparkle/ai-sparkle.d.ts +24 -0
  94. package/dist/components/ai-sparkle/ai-sparkle.d.ts.map +1 -0
  95. package/dist/components/ai-sparkle/index.d.ts +3 -0
  96. package/dist/components/ai-sparkle/index.d.ts.map +1 -0
  97. package/dist/components/ai-sparkle/index.js +5 -0
  98. package/dist/components/ai-sparkle/index.js.map +1 -0
  99. package/dist/components/appointment-card/index.js +2 -2
  100. package/dist/components/appointment-peek/index.js +1 -1
  101. package/dist/components/appointment-timeline/index.js +1 -1
  102. package/dist/components/booking/index.js +1 -1
  103. package/dist/components/button-group/button-group.d.ts.map +1 -1
  104. package/dist/components/button-group/index.js +1 -1
  105. package/dist/components/calendar/index.js +1 -1
  106. package/dist/components/calendar-event-card/calendar-event-card.d.ts.map +1 -1
  107. package/dist/components/calendar-event-card/index.js +1 -1
  108. package/dist/components/chart/index.js +1 -1
  109. package/dist/components/data-table/index.js +3 -3
  110. package/dist/components/face-scheme/index.js +1 -1
  111. package/dist/components/file-manager/index.js +1 -1
  112. package/dist/components/header-settings/index.js +1 -1
  113. package/dist/components/hover-card/hover-card.d.ts +4 -0
  114. package/dist/components/hover-card/hover-card.d.ts.map +1 -1
  115. package/dist/components/hover-card/index.d.ts +1 -1
  116. package/dist/components/hover-card/index.d.ts.map +1 -1
  117. package/dist/components/hover-card/index.js +3 -2
  118. package/dist/components/icon-button-group/icon-button-group.d.ts.map +1 -1
  119. package/dist/components/icon-button-group/index.js +1 -1
  120. package/dist/components/index.d.ts +5 -3
  121. package/dist/components/index.d.ts.map +1 -1
  122. package/dist/components/notes-panel/index.js +1 -1
  123. package/dist/components/notes-panel/notes-panel.d.ts +10 -0
  124. package/dist/components/notes-panel/notes-panel.d.ts.map +1 -1
  125. package/dist/components/patient-details/index.js +1 -1
  126. package/dist/components/patient-summary-card/index.js +1 -1
  127. package/dist/components/patient-summary-card/patient-summary-card.d.ts.map +1 -1
  128. package/dist/components/patient-table/index.js +1 -1
  129. package/dist/components/rich-text-editor/editor-extensions.d.ts +54 -0
  130. package/dist/components/rich-text-editor/editor-extensions.d.ts.map +1 -0
  131. package/dist/components/rich-text-editor/editor-toolbar.d.ts +2 -1
  132. package/dist/components/rich-text-editor/editor-toolbar.d.ts.map +1 -1
  133. package/dist/components/rich-text-editor/help-me-write-overlay.d.ts +4 -0
  134. package/dist/components/rich-text-editor/help-me-write-overlay.d.ts.map +1 -1
  135. package/dist/components/rich-text-editor/index.d.ts +2 -0
  136. package/dist/components/rich-text-editor/index.d.ts.map +1 -1
  137. package/dist/components/rich-text-editor/index.js +6 -4
  138. package/dist/components/rich-text-editor/index.js.map +1 -1
  139. package/dist/components/rich-text-editor/kit-extensions.d.ts +4 -0
  140. package/dist/components/rich-text-editor/kit-extensions.d.ts.map +1 -0
  141. package/dist/components/rich-text-editor/rich-text-editor.d.ts +18 -2
  142. package/dist/components/rich-text-editor/rich-text-editor.d.ts.map +1 -1
  143. package/dist/components/tasks-panel/index.js +1 -1
  144. package/dist/components/theme-toggle/index.js +1 -1
  145. package/dist/components/workflow-status/index.js +1 -1
  146. package/dist/components/workflow-status/workflow-status.d.ts.map +1 -1
  147. package/dist/hooks/index.d.ts +1 -0
  148. package/dist/hooks/index.d.ts.map +1 -1
  149. package/dist/hooks/index.js +54 -48
  150. package/dist/hooks/index.js.map +1 -1
  151. package/dist/hooks/use-ai-sparkle.d.ts +91 -0
  152. package/dist/hooks/use-ai-sparkle.d.ts.map +1 -0
  153. package/dist/host-compat.css +2 -2
  154. package/dist/i18n/locales/ar.d.ts +31 -0
  155. package/dist/i18n/locales/ar.d.ts.map +1 -1
  156. package/dist/i18n/locales/ar.js +33 -2
  157. package/dist/i18n/locales/ar.js.map +1 -1
  158. package/dist/i18n/locales/de.d.ts +31 -0
  159. package/dist/i18n/locales/de.d.ts.map +1 -1
  160. package/dist/i18n/locales/de.js +33 -2
  161. package/dist/i18n/locales/de.js.map +1 -1
  162. package/dist/i18n/locales/el.d.ts +31 -0
  163. package/dist/i18n/locales/el.d.ts.map +1 -1
  164. package/dist/i18n/locales/el.js +33 -2
  165. package/dist/i18n/locales/el.js.map +1 -1
  166. package/dist/i18n/locales/en.d.ts +31 -0
  167. package/dist/i18n/locales/en.d.ts.map +1 -1
  168. package/dist/i18n/locales/en.js +33 -2
  169. package/dist/i18n/locales/en.js.map +1 -1
  170. package/dist/i18n/locales/es.d.ts +31 -0
  171. package/dist/i18n/locales/es.d.ts.map +1 -1
  172. package/dist/i18n/locales/es.js +33 -2
  173. package/dist/i18n/locales/es.js.map +1 -1
  174. package/dist/i18n/locales/fr.d.ts +31 -0
  175. package/dist/i18n/locales/fr.d.ts.map +1 -1
  176. package/dist/i18n/locales/fr.js +33 -2
  177. package/dist/i18n/locales/fr.js.map +1 -1
  178. package/dist/i18n/locales/hi.d.ts +31 -0
  179. package/dist/i18n/locales/hi.d.ts.map +1 -1
  180. package/dist/i18n/locales/hi.js +33 -2
  181. package/dist/i18n/locales/hi.js.map +1 -1
  182. package/dist/i18n/locales/it.d.ts +31 -0
  183. package/dist/i18n/locales/it.d.ts.map +1 -1
  184. package/dist/i18n/locales/it.js +33 -2
  185. package/dist/i18n/locales/it.js.map +1 -1
  186. package/dist/i18n/locales/ja.d.ts +31 -0
  187. package/dist/i18n/locales/ja.d.ts.map +1 -1
  188. package/dist/i18n/locales/ja.js +33 -2
  189. package/dist/i18n/locales/ja.js.map +1 -1
  190. package/dist/i18n/locales/nl.d.ts +31 -0
  191. package/dist/i18n/locales/nl.d.ts.map +1 -1
  192. package/dist/i18n/locales/nl.js +33 -2
  193. package/dist/i18n/locales/nl.js.map +1 -1
  194. package/dist/i18n/locales/pl.d.ts +31 -0
  195. package/dist/i18n/locales/pl.d.ts.map +1 -1
  196. package/dist/i18n/locales/pl.js +33 -2
  197. package/dist/i18n/locales/pl.js.map +1 -1
  198. package/dist/i18n/locales/pt.d.ts +31 -0
  199. package/dist/i18n/locales/pt.d.ts.map +1 -1
  200. package/dist/i18n/locales/pt.js +33 -2
  201. package/dist/i18n/locales/pt.js.map +1 -1
  202. package/dist/i18n/locales/ro.d.ts +31 -0
  203. package/dist/i18n/locales/ro.d.ts.map +1 -1
  204. package/dist/i18n/locales/ro.js +33 -2
  205. package/dist/i18n/locales/ro.js.map +1 -1
  206. package/dist/i18n/locales/ru.d.ts +31 -0
  207. package/dist/i18n/locales/ru.d.ts.map +1 -1
  208. package/dist/i18n/locales/ru.js +33 -2
  209. package/dist/i18n/locales/ru.js.map +1 -1
  210. package/dist/i18n/locales/sq.d.ts +31 -0
  211. package/dist/i18n/locales/sq.d.ts.map +1 -1
  212. package/dist/i18n/locales/sq.js +33 -2
  213. package/dist/i18n/locales/sq.js.map +1 -1
  214. package/dist/i18n/locales/sv.d.ts +31 -0
  215. package/dist/i18n/locales/sv.d.ts.map +1 -1
  216. package/dist/i18n/locales/sv.js +33 -2
  217. package/dist/i18n/locales/sv.js.map +1 -1
  218. package/dist/i18n/locales/tr.d.ts +31 -0
  219. package/dist/i18n/locales/tr.d.ts.map +1 -1
  220. package/dist/i18n/locales/tr.js +33 -2
  221. package/dist/i18n/locales/tr.js.map +1 -1
  222. package/dist/i18n/locales/zh.d.ts +31 -0
  223. package/dist/i18n/locales/zh.d.ts.map +1 -1
  224. package/dist/i18n/locales/zh.js +33 -2
  225. package/dist/i18n/locales/zh.js.map +1 -1
  226. package/dist/index.js +1113 -1102
  227. package/dist/index.js.map +1 -1
  228. package/dist/locales/ar.json +33 -2
  229. package/dist/locales/de.json +33 -2
  230. package/dist/locales/el.json +33 -2
  231. package/dist/locales/en.json +33 -2
  232. package/dist/locales/es.json +33 -2
  233. package/dist/locales/fr.json +33 -2
  234. package/dist/locales/hi.json +33 -2
  235. package/dist/locales/it.json +33 -2
  236. package/dist/locales/ja.json +33 -2
  237. package/dist/locales/nl.json +33 -2
  238. package/dist/locales/pl.json +33 -2
  239. package/dist/locales/pt.json +33 -2
  240. package/dist/locales/ro.json +33 -2
  241. package/dist/locales/ru.json +33 -2
  242. package/dist/locales/sq.json +33 -2
  243. package/dist/locales/sv.json +33 -2
  244. package/dist/locales/tr.json +33 -2
  245. package/dist/locales/zh.json +33 -2
  246. package/dist/patterns/anamnesis/index.js +1 -1
  247. package/dist/patterns/calendar/calendar-appointment-details.d.ts.map +1 -1
  248. package/dist/patterns/calendar/calendar-appointment-details.sections.d.ts.map +1 -1
  249. package/dist/patterns/calendar/calendar-bookings-panel.d.ts.map +1 -1
  250. package/dist/patterns/calendar/calendar-workspace.d.ts +6 -4
  251. package/dist/patterns/calendar/calendar-workspace.d.ts.map +1 -1
  252. package/dist/patterns/calendar/calendar.data.d.ts +9 -0
  253. package/dist/patterns/calendar/calendar.data.d.ts.map +1 -1
  254. package/dist/patterns/calendar/calendar.journey.d.ts +1 -1
  255. package/dist/patterns/calendar/calendar.journey.d.ts.map +1 -1
  256. package/dist/patterns/calendar/calendar.sheets.d.ts +16 -5
  257. package/dist/patterns/calendar/calendar.sheets.d.ts.map +1 -1
  258. package/dist/patterns/calendar/calendar.surface.d.ts.map +1 -1
  259. package/dist/patterns/calendar/calendar.types.d.ts +3 -1
  260. package/dist/patterns/calendar/calendar.types.d.ts.map +1 -1
  261. package/dist/patterns/calendar/index.js +1 -1
  262. package/dist/patterns/help-me-write-templates/help-me-write-templates.d.ts +11 -2
  263. package/dist/patterns/help-me-write-templates/help-me-write-templates.d.ts.map +1 -1
  264. package/dist/patterns/help-me-write-templates/index.js +1 -1
  265. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  266. package/dist/tokens.css +1 -1
  267. package/package.json +14 -4
  268. package/dist/_chunks/ai-consent-banner-D7I2U-cz.js.map +0 -1
  269. package/dist/_chunks/booking-D43ASl8y.js.map +0 -1
  270. package/dist/_chunks/button-group-R32U7SyV.js +0 -307
  271. package/dist/_chunks/button-group-R32U7SyV.js.map +0 -1
  272. package/dist/_chunks/calendar-workspace-DBYAtdyd.js.map +0 -1
  273. package/dist/_chunks/help-me-write-templates-GUeEn3Ff.js.map +0 -1
  274. package/dist/_chunks/icon-button-group-DkkdIygu.js.map +0 -1
  275. package/dist/_chunks/notes-panel-CY4KmDo-.js.map +0 -1
  276. package/dist/_chunks/patient-field-row-BRSOKvme.js.map +0 -1
  277. package/dist/_chunks/patient-summary-card-BhmKB2KR.js.map +0 -1
  278. package/dist/_chunks/rich-text-editor-BYE6kK4u.js +0 -3839
  279. package/dist/_chunks/rich-text-editor-BYE6kK4u.js.map +0 -1
  280. package/dist/components/ai-consent-banner/ai-consent-banner.agent.d.ts.map +0 -1
  281. package/dist/components/ai-consent-banner/ai-consent-banner.d.ts.map +0 -1
  282. package/dist/components/ai-consent-banner/index.d.ts +0 -4
  283. package/dist/components/ai-consent-banner/index.d.ts.map +0 -1
  284. /package/dist/components/{ai-consent-banner → ai-permission-notice}/index.js.map +0 -0
@@ -1,4 +1,4 @@
1
- import { jsxs as l, jsx as e } from "react/jsx-runtime";
1
+ import { jsxs as i, jsx as e } from "react/jsx-runtime";
2
2
  import { forwardRef as M } from "react";
3
3
  import { useTranslation as T } from "react-i18next";
4
4
  import { c as W } from "./index-D2ZczOXr.js";
@@ -64,7 +64,7 @@ const ce = {
64
64
  done: J,
65
65
  cancelled: q,
66
66
  absent: Y
67
- }, i = "ds:inline-flex ds:size-4.5 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-full)] ds:bg-[color:var(--card)] ds:border ds:border-[color:var(--border)] ds:shadow-[var(--shadow-sm)]", ue = "ds:inline-block ds:h-3 ds:w-[6ch] ds:align-middle ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:animate-[skeleton-pulse_calc(var(--animation-duration)*8)_ease-in-out_infinite] ds:motion-reduce:animate-none ds:forced-colors:bg-[GrayText] ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText] ds:forced-colors:animate-none", c = {
67
+ }, o = "ds:inline-flex ds:size-4.5 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-full)] ds:bg-[color:var(--card)] ds:border ds:border-[color:var(--border)] ds:shadow-[var(--shadow-sm)]", ue = "ds:inline-block ds:h-3 ds:w-[6ch] ds:align-middle ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:animate-[skeleton-pulse_calc(var(--animation-duration)*8)_ease-in-out_infinite] ds:motion-reduce:animate-none ds:forced-colors:bg-[GrayText] ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText] ds:forced-colors:animate-none", c = {
68
68
  success: "ds:text-[color:var(--success-foreground)]",
69
69
  info: "ds:text-[color:var(--info-foreground)]",
70
70
  warning: "ds:text-[color:var(--warning-foreground)]",
@@ -78,14 +78,14 @@ const ce = {
78
78
  done: "success",
79
79
  cancelled: "error",
80
80
  absent: "warning"
81
- }, ve = {
81
+ }, pe = {
82
82
  confirmed: "calendar.status.confirmed",
83
83
  waiting: "calendar.status.waiting",
84
84
  in_care: "calendar.status.inCare",
85
85
  done: "calendar.status.done",
86
86
  cancelled: "calendar.status.cancelled",
87
87
  absent: "calendar.status.absent"
88
- }, pe = W(
88
+ }, fe = W(
89
89
  [
90
90
  // Block root; the appointment content is a wrap-capable flex row
91
91
  // (inline-flowing text cell beside the icon column — structurally
@@ -203,7 +203,7 @@ const ce = {
203
203
  colorStyle: "solid"
204
204
  }
205
205
  }
206
- ), fe = M(
206
+ ), ve = M(
207
207
  ({
208
208
  title: a,
209
209
  suffix: r,
@@ -211,7 +211,7 @@ const ce = {
211
211
  showTime: d = !0,
212
212
  allDay: t = !1,
213
213
  status: s,
214
- backgroundColor: o,
214
+ backgroundColor: l,
215
215
  textColor: m,
216
216
  borderColor: h,
217
217
  isBookedOnline: g = !1,
@@ -222,7 +222,7 @@ const ce = {
222
222
  isRecurring: z,
223
223
  isTask: u = !1,
224
224
  isDraft: b = !1,
225
- detailsPending: v = !1,
225
+ detailsPending: p = !1,
226
226
  colorStyle: j = "solid",
227
227
  resourceLabel: B,
228
228
  privacyMasked: I = !1,
@@ -232,21 +232,21 @@ const ce = {
232
232
  "aria-label": O,
233
233
  ...R
234
234
  }, U) => {
235
- const { t: p } = T(), x = s ? ce[s] : null, G = !!x || !!g || !!N || !!w || !!k || !!S || !!z, H = s ? p(ve[s]) : void 0, K = v ? p("calendar.eventKind.pendingDetails") : b ? p("calendar.eventKind.draft") : u ? p("calendar.eventKind.task") : void 0, V = O ?? [a, n, B, H, K].filter(Boolean).join(", "), $ = v ? "pending-details" : b ? "draft" : u ? "task" : "appointment", f = !u && !b && j === "tinted", _ = !f && !m && o ? le(o) : null, E = f ? o ? { "--calendar-event-accent": o } : void 0 : o || m || h ? {
236
- ...o ? { "--calendar-event-bg": o } : {},
235
+ const { t: f } = T(), x = s ? ce[s] : null, G = !!x || !!g || !!N || !!w || !!k || !!S || !!z, H = s ? f(pe[s]) : void 0, K = p ? f("calendar.eventKind.pendingDetails") : b ? f("calendar.eventKind.draft") : u ? f("calendar.eventKind.task") : void 0, V = O ?? [a, n, B, H, K].filter(Boolean).join(", "), $ = p ? "pending-details" : b ? "draft" : u ? "task" : "appointment", v = !u && !b && j === "tinted", _ = !v && !m && l ? le(l) : null, E = v ? l ? { "--calendar-event-accent": l } : void 0 : l || m || h ? {
236
+ ...l ? { "--calendar-event-bg": l } : {},
237
237
  ...m ? { "--calendar-event-text": m } : _ === "on-light" ? { "--calendar-event-text": "var(--event-ink-on-light)" } : _ === "on-dark" ? { "--calendar-event-text": "var(--event-ink-on-dark)" } : {},
238
238
  ...h ? { "--calendar-event-border": h } : {}
239
239
  } : void 0, D = y || E ? { ...y, ...E } : void 0;
240
- return /* @__PURE__ */ l(
240
+ return /* @__PURE__ */ i(
241
241
  "div",
242
242
  {
243
243
  ref: U,
244
244
  ...R,
245
- className: pe({
245
+ className: fe({
246
246
  status: s ?? "none",
247
247
  bookedOnline: g,
248
248
  kind: $,
249
- colorStyle: f ? "tinted" : "solid",
249
+ colorStyle: v ? "tinted" : "solid",
250
250
  className: A
251
251
  }),
252
252
  style: D,
@@ -255,25 +255,25 @@ const ce = {
255
255
  "data-event-id": L,
256
256
  "data-kind": $,
257
257
  "data-status": s ?? "none",
258
- "data-contrast": f ? "tinted" : m ? "custom" : _ ?? "default",
258
+ "data-contrast": v ? "tinted" : m ? "custom" : _ ?? "default",
259
259
  children: [
260
- u && !v ? (
260
+ u && !p ? (
261
261
  /* Task cards lead with ONE line — glyph + title inline. A task is
262
262
  typically a 30-min block whose visible height fits a single
263
263
  line; the appointment layout below would spend that line on the
264
264
  indicator row and clip the title entirely. Tasks carry none of
265
265
  the appointment flags, so the row loses nothing. */
266
- /* @__PURE__ */ l("span", { className: "ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
266
+ /* @__PURE__ */ i("span", { className: "ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
267
267
  /* @__PURE__ */ e(
268
268
  "span",
269
269
  {
270
270
  "aria-hidden": "true",
271
- className: `${i} ds:text-[color:var(--muted-foreground)]`,
271
+ className: `${o} ds:text-[color:var(--muted-foreground)]`,
272
272
  children: /* @__PURE__ */ e(X, { size: 11, "aria-hidden": "true" })
273
273
  }
274
274
  ),
275
275
  d && !t && n ? /* @__PURE__ */ e("span", { className: "ds:whitespace-nowrap ds:text-[length:var(--font-size-xs)]", children: n }) : null,
276
- /* @__PURE__ */ e("span", { className: "ds:[min-inline-size:0] ds:font-[var(--font-weight-semibold)] ds:truncate ds:text-start", children: I ? /* @__PURE__ */ l("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
276
+ /* @__PURE__ */ e("span", { className: "ds:[min-inline-size:0] ds:font-[var(--font-weight-semibold)] ds:truncate ds:text-start", children: I ? /* @__PURE__ */ i("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
277
277
  /* @__PURE__ */ e(C, { size: 12, "aria-hidden": "true" }),
278
278
  a
279
279
  ] }) : a })
@@ -286,33 +286,42 @@ const ce = {
286
286
  unlike a float (inline text paints ABOVE floats, which
287
287
  produced glyphs-through-icons in sliver-width columns). A
288
288
  one-line sliver still reads "09:15 Name" plus icons. */
289
- /* @__PURE__ */ l("span", { className: "ds:flex ds:h-full ds:items-stretch ds:gap-[var(--spacing-2xs)]", children: [
290
- /* @__PURE__ */ l("span", { className: "ds:min-w-[var(--spacing-2xl)] ds:flex-1 ds:overflow-hidden ds:break-normal", children: [
291
- d && !t && n ? (
292
- // No opacity here — composing 70% over saturated bgs drops
293
- // effective contrast below WCAG AA. The smaller
294
- // font-size-xs vs the title's font-weight-semibold provides
295
- // sufficient visual hierarchy.
296
- /* @__PURE__ */ e("span", { className: "ds:me-[var(--spacing-2xs)] ds:whitespace-nowrap ds:text-[length:var(--font-size-xs)]", children: n })
297
- ) : null,
298
- /* @__PURE__ */ e("span", { className: "ds:font-[var(--font-weight-semibold)]", children: v ? (
299
- /* No name yet — and nothing invented in its place. */
300
- /* @__PURE__ */ e("span", { "aria-hidden": "true", className: ue })
301
- ) : I ? (
302
- /* The eye + mask get their own start padding so the
303
- redaction doesn't crowd the time. */
304
- /* @__PURE__ */ l("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:ps-[var(--spacing-2xs)] ds:align-middle", children: [
305
- /* @__PURE__ */ e(C, { size: 12, "aria-hidden": "true" }),
306
- a
307
- ] })
308
- ) : a }),
289
+ /* @__PURE__ */ i("span", { className: "ds:flex ds:h-full ds:items-stretch ds:gap-[var(--spacing-2xs)]", children: [
290
+ /* @__PURE__ */ i("span", { className: "ds:min-w-[var(--spacing-2xl)] ds:flex-1 ds:overflow-hidden ds:break-normal", children: [
291
+ /* @__PURE__ */ i("span", { className: "ds:flex ds:min-w-0 ds:items-baseline ds:gap-[var(--spacing-2xs)]", children: [
292
+ d && !t && n ? (
293
+ // No opacity here — composing 70% over saturated bgs drops
294
+ // effective contrast below WCAG AA. The smaller
295
+ // font-size-xs vs the title's font-weight-semibold provides
296
+ // sufficient visual hierarchy.
297
+ /* @__PURE__ */ e(
298
+ "span",
299
+ {
300
+ className: "ds:max-w-[55%] ds:shrink-0 ds:truncate ds:whitespace-nowrap ds:text-[length:var(--font-size-xs)]",
301
+ title: n,
302
+ children: n
303
+ }
304
+ )
305
+ ) : null,
306
+ /* @__PURE__ */ e("span", { className: "ds:min-w-0 ds:flex-1 ds:truncate ds:font-[var(--font-weight-semibold)]", children: p ? (
307
+ /* No name yet — and nothing invented in its place. */
308
+ /* @__PURE__ */ e("span", { "aria-hidden": "true", className: ue })
309
+ ) : I ? (
310
+ /* The eye + mask get their own start padding so the
311
+ redaction doesn't crowd the time. */
312
+ /* @__PURE__ */ i("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:ps-[var(--spacing-2xs)] ds:align-middle", children: [
313
+ /* @__PURE__ */ e(C, { size: 12, "aria-hidden": "true" }),
314
+ a
315
+ ] })
316
+ ) : a })
317
+ ] }),
309
318
  r ? (
310
319
  /* Second line inside the text cell — beside the plate,
311
320
  never beneath it. */
312
321
  /* @__PURE__ */ e("span", { className: "ds:block ds:truncate ds:text-[length:var(--font-size-xs)]", children: r })
313
322
  ) : null
314
323
  ] }),
315
- /* @__PURE__ */ l(
324
+ /* @__PURE__ */ i(
316
325
  "span",
317
326
  {
318
327
  className: G ? (
@@ -335,7 +344,7 @@ const ce = {
335
344
  "span",
336
345
  {
337
346
  "aria-hidden": "true",
338
- className: `${i} ${c[me[s]]}`,
347
+ className: `${o} ${c[me[s]]}`,
339
348
  children: /* @__PURE__ */ e(x, { size: 11, "aria-hidden": "true" })
340
349
  }
341
350
  ) : null,
@@ -343,7 +352,7 @@ const ce = {
343
352
  "span",
344
353
  {
345
354
  "aria-hidden": "true",
346
- className: `${i} ${c.info}`,
355
+ className: `${o} ${c.info}`,
347
356
  children: /* @__PURE__ */ e(P, { size: 11, "aria-hidden": "true" })
348
357
  }
349
358
  ) : null,
@@ -351,7 +360,7 @@ const ce = {
351
360
  "span",
352
361
  {
353
362
  "aria-hidden": "true",
354
- className: `${i} ${c.warning}`,
363
+ className: `${o} ${c.warning}`,
355
364
  children: /* @__PURE__ */ e(ee, { size: 11, "aria-hidden": "true" })
356
365
  }
357
366
  ) : null,
@@ -359,7 +368,7 @@ const ce = {
359
368
  "span",
360
369
  {
361
370
  "aria-hidden": "true",
362
- className: `${i} ${c.accent}`,
371
+ className: `${o} ${c.accent}`,
363
372
  children: /* @__PURE__ */ e(ne, { size: 11, "aria-hidden": "true" })
364
373
  }
365
374
  ) : null,
@@ -367,7 +376,7 @@ const ce = {
367
376
  "span",
368
377
  {
369
378
  "aria-hidden": "true",
370
- className: `${i} ${c.warning}`,
379
+ className: `${o} ${c.warning}`,
371
380
  children: /* @__PURE__ */ e(te, { size: 11, "aria-hidden": "true" })
372
381
  }
373
382
  ) : null,
@@ -375,7 +384,7 @@ const ce = {
375
384
  "span",
376
385
  {
377
386
  "aria-hidden": "true",
378
- className: `${i} ${c.info}`,
387
+ className: `${o} ${c.info}`,
379
388
  children: /* @__PURE__ */ e(re, { size: 11, "aria-hidden": "true" })
380
389
  }
381
390
  ) : null,
@@ -383,7 +392,7 @@ const ce = {
383
392
  "span",
384
393
  {
385
394
  "aria-hidden": "true",
386
- className: `${i} ${c.info}`,
395
+ className: `${o} ${c.info}`,
387
396
  children: /* @__PURE__ */ e(se, { size: 11, "aria-hidden": "true" })
388
397
  }
389
398
  ) : null
@@ -403,10 +412,10 @@ const ce = {
403
412
  );
404
413
  }
405
414
  );
406
- fe.displayName = "CalendarEventCard";
415
+ ve.displayName = "CalendarEventCard";
407
416
  export {
408
- fe as C,
417
+ ve as C,
409
418
  te as E,
410
419
  Be as w
411
420
  };
412
- //# sourceMappingURL=calendar-event-card-DKUnT9Be.js.map
421
+ //# sourceMappingURL=calendar-event-card-B6N5h1dO.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"calendar-event-card-DKUnT9Be.js","sources":["../../node_modules/lucide-react/dist/esm/icons/euro.mjs","../../src/components/_shared/contrast-warning.ts","../../src/components/calendar-event-card/calendar-event-card.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M4 10h12\", key: \"1y6xl8\" }],\n [\"path\", { d: \"M4 14h9\", key: \"1loblj\" }],\n [\n \"path\",\n {\n d: \"M19 6a7.7 7.7 0 0 0-5.2-2A7.9 7.9 0 0 0 6 12c0 4.4 3.5 8 7.8 8 2 0 3.8-.8 5.2-2\",\n key: \"1j6lzo\"\n }\n ]\n];\nconst Euro = createLucideIcon(\"euro\", __iconNode);\n\nexport { __iconNode, Euro as default };\n//# sourceMappingURL=euro.mjs.map\n","/* ------------------------------------------------------------------ */\n/* Shared contrast guardrail — Calendar + CalendarEventCard */\n/* */\n/* The consuming app supplies runtime hex pairs at several surfaces: */\n/* - event.backgroundColor / event.textColor (+ event.borderColor) */\n/* - modeBannerColor / modeBannerTextColor */\n/* - resource.color / resource.shortTitleTextColor */\n/* */\n/* When the text half of the pair is also a hex (i.e. both halves come */\n/* from the caller), we can validate them synchronously and warn the */\n/* consuming-app developer during DEV if the pair fails WCAG AA normal */\n/* text (4.5:1). When only the background half is supplied, */\n/* `resolveInk` derives a provably AA-safe black/white ink for it. */\n/* Every helper is a no-op in production builds. */\n/* ------------------------------------------------------------------ */\n\n/* Module-level dedup set — keyed on the (bg, fg, context) tuple so the\n same bad pair moving around the calendar only warns once per session.\n Exposed via `resetContrastWarnings()` for test isolation. */\nconst warnedTuples = new Set<string>();\n\n/** Reset the dedup set — intended for use between tests. */\nexport function resetContrastWarnings(): void {\n warnedTuples.clear();\n}\n\n/**\n * Parse a 3-char or 6-char `#RRGGBB` hex string into a linear sRGB\n * triple in the [0,1] range. Returns `null` for any input the caller\n * can't parse (malformed prefix, bad length, non-hex characters) —\n * the helper stays silent in that case rather than emitting noise.\n */\nfunction parseHex(hex: string): [number, number, number] | null {\n if (typeof hex !== 'string') return null;\n const trimmed = hex.trim();\n if (!trimmed.startsWith('#')) return null;\n const body = trimmed.slice(1);\n let r: number;\n let g: number;\n let b: number;\n if (body.length === 3) {\n if (!/^[0-9a-f]{3}$/i.test(body)) return null;\n r = parseInt(body[0] + body[0], 16);\n g = parseInt(body[1] + body[1], 16);\n b = parseInt(body[2] + body[2], 16);\n } else if (body.length === 6) {\n if (!/^[0-9a-f]{6}$/i.test(body)) return null;\n r = parseInt(body.slice(0, 2), 16);\n g = parseInt(body.slice(2, 4), 16);\n b = parseInt(body.slice(4, 6), 16);\n } else {\n return null;\n }\n return [r / 255, g / 255, b / 255];\n}\n\n/**\n * WCAG 2.1 relative luminance. Each channel is gamma-corrected then\n * weighted against the CIE photopic sensitivity of the human eye.\n * https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n */\nfunction relativeLuminance([r, g, b]: [number, number, number]): number {\n const lin = (c: number): number =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);\n}\n\n/**\n * WCAG 2.1 contrast ratio. Always returns a value in [1, 21]; the\n * relative-luminance lighter-over-darker convention is applied here.\n */\nfunction contrastRatio(\n bg: [number, number, number],\n fg: [number, number, number],\n): number {\n const l1 = relativeLuminance(bg);\n const l2 = relativeLuminance(fg);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * DEV-only WCAG AA guardrail for caller-supplied hex pairs.\n *\n * - No-op when `import.meta.env.DEV` is false.\n * - No-op when either half of the pair is missing (the \"fg missing →\n * inherits DS token\" case is a docs concern; the DS token isn't a\n * hex at runtime so we can't check it here).\n * - No-op when either hex can't be parsed (silent — not the helper's\n * concern to police malformed input).\n * - Deduplicated by `(bgHex, fgHex, contextLabel)` tuple so moving a\n * ratio-bad event around the calendar doesn't spam the console.\n *\n * @param bgHex - Caller-supplied background hex (e.g. `'#c2185b'`)\n * @param fgHex - Caller-supplied foreground hex (e.g. `'#ffffff'`)\n * @param contextLabel - Short description for the warning (e.g. `'event e1'`).\n */\nexport function warnLowContrast(\n bgHex: string | undefined,\n fgHex: string | undefined,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (!bgHex || !fgHex) return;\n\n const bg = parseHex(bgHex);\n const fg = parseHex(fgHex);\n if (!bg || !fg) return;\n\n const ratio = contrastRatio(bg, fg);\n if (ratio >= 4.5) return;\n\n const key = `${bgHex}|${fgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n /* `bg` parsed successfully above, so `resolveInk(bgHex)` is guaranteed\n to produce a compliant ink — the omit-textColor hint is always valid\n at this point. */\n console.warn(\n `[Calendar] Low contrast on ${contextLabel}: ${bgHex} / ${fgHex} (ratio ${ratio.toFixed(\n 2,\n )}, target 4.5). Pass a matching textColor/fgHex, pick a higher-contrast background, or omit textColor to let the kit choose a compliant ink.`,\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Ink derivation — bg-only caller colours */\n/* ------------------------------------------------------------------ */\n\nexport type EventInk = 'on-light' | 'on-dark';\n\n/**\n * Pick the ink for an arbitrary opaque bg hex. Returns `null` when the\n * input can't be parsed (`#rgb` / `#rrggbb` only).\n *\n * The threshold 0.1791 is the relative luminance at which\n * `contrast(bg, #fff) === contrast(bg, #000)`; the better of the two\n * always yields ≥ 4.58:1 (the minimum, at a mid-grey ≈ `#757575`) —\n * provably WCAG AA-safe for any opaque background.\n */\nexport function resolveInk(bgHex: string): EventInk | null {\n const bg = parseHex(bgHex);\n if (!bg) return null;\n // threshold where contrast(bg, #fff) === contrast(bg, #000)\n return relativeLuminance(bg) > 0.1791 ? 'on-light' : 'on-dark';\n}\n\n/**\n * DEV-only, one-shot warning for a caller `backgroundColor` the kit can't\n * parse (`rgb(…)`, keywords, malformed hex). The browser can still paint\n * it, but the text falls back to the token default and contrast can't be\n * verified. Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnUnparseableBackground(\n bgHex: string,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (parseHex(bgHex)) return;\n\n const key = `unparseable|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Unparseable backgroundColor on ${contextLabel}: \"${bgHex}\". ` +\n `Expected #rgb or #rrggbb — contrast cannot be verified and the text ` +\n `colour falls back to the token default.`,\n );\n}\n\n/**\n * DEV-only, one-shot warning for a near-white `backgroundColor`\n * (relative luminance > 0.9) supplied without a `borderColor` — the\n * event may be invisible against the calendar grid. The kit warns, it\n * does not repaint (delineation is decorative under WCAG 1.4.11 and the\n * consumer owns the picker colour). Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnLowDelineation(bgHex: string, contextLabel: string): void {\n if (!import.meta.env.DEV) return;\n\n const bg = parseHex(bgHex);\n if (!bg) return;\n if (relativeLuminance(bg) <= 0.9) return;\n\n const key = `delineation|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Light backgroundColor without borderColor on ${contextLabel}: ` +\n `${bgHex} may be invisible against the grid — pass a borderColor ` +\n `(the platform convention sends a light-grey border for white backgrounds).`,\n );\n}\n","/* ------------------------------------------------------------------ */\n/* CalendarEventCard — the single painted surface of a calendar event. */\n/* */\n/* Colour model (platform parity): the caller's picker hex */\n/* (backgroundColor / textColor / borderColor) is the ONLY thing that */\n/* paints the card. `status` never paints the surface — it selects an */\n/* icon and (for `cancelled`) a line-through. When no picker colour */\n/* is supplied the surface falls back to the theme's --primary / */\n/* --primary-foreground pair. */\n/* */\n/* Non-interactive by design: inside FullCalendar the outer harness */\n/* anchor owns click/drag/focus; standalone consumers wrap the card in */\n/* their own button/link. No onClick in the contract. */\n/* ------------------------------------------------------------------ */\n\nimport { forwardRef } from 'react';\nimport type { CSSProperties, HTMLAttributes } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\nimport {\n ThumbsUp,\n Clock,\n Stethoscope,\n Check,\n Ban,\n UserX,\n Globe,\n TriangleAlert,\n HeartPulse,\n Euro,\n Video,\n Repeat,\n EyeOff,\n ClipboardCheck,\n type LucideIcon,\n} from 'lucide-react';\n// Type-only import — erased at build, no runtime cycle with calendar.tsx's\n// runtime import of this card. Do NOT convert to a value import.\nimport type { CalendarEventStatus } from '../calendar/calendar';\nimport {\n warnLowContrast,\n resolveInk,\n warnUnparseableBackground,\n warnLowDelineation,\n} from '../_shared/contrast-warning';\n\n/* ------------------------------------------------------------------ */\n/* Status lookups */\n/* ------------------------------------------------------------------ */\n\nconst STATUS_ICON: Record<CalendarEventStatus, LucideIcon> = {\n confirmed: ThumbsUp,\n waiting: Clock,\n in_care: Stethoscope,\n done: Check,\n cancelled: Ban,\n absent: UserX,\n};\n\n/* Status → i18n key lookup. Kept as a literal object (not a template)\n so static-analysis extractors can find every key. Keys already exist\n in all 18 locale bundles — do not add new ones here. */\n/* Indicator DISC — option D of the design review: each glyph in a small\n circle on the plain card surface (hairline border + row-lift shadow)\n with the SEMANTIC colour as icon ink. Chip-grade contrast on any\n picker colour without a plate; ink tokens mirror Badge's variants so\n the vocabulary stays one system. */\nconst INDICATOR_DISC_BASE =\n 'ds:inline-flex ds:size-4.5 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-full)] ds:bg-[color:var(--card)] ds:border ds:border-[color:var(--border)] ds:shadow-[var(--shadow-sm)]';\n\n/* DETAILS-PENDING bar — the Skeleton component's own classes, inlined on\n a <span>: Skeleton renders a <div>, which cannot live inside the card's\n inline text cell. Decorative (aria-hidden) because the composed\n aria-label already carries the localised \"loading details\" word. */\nconst PENDING_BAR_CLASS =\n 'ds:inline-block ds:h-3 ds:w-[6ch] ds:align-middle ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:animate-[skeleton-pulse_calc(var(--animation-duration)*8)_ease-in-out_infinite] ds:motion-reduce:animate-none ds:forced-colors:bg-[GrayText] ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText] ds:forced-colors:animate-none';\n\ntype IndicatorTone = 'success' | 'info' | 'warning' | 'error' | 'accent';\n\nconst INDICATOR_DISC_TONE: Record<IndicatorTone, string> = {\n success: 'ds:text-[color:var(--success-foreground)]',\n info: 'ds:text-[color:var(--info-foreground)]',\n warning: 'ds:text-[color:var(--warning-foreground)]',\n error: 'ds:text-[color:var(--error-foreground)]',\n // Same AA-clearing accent mix Badge's accentSoft uses for its ink.\n accent:\n 'ds:text-[color:color-mix(in_srgb,var(--accent)_40%,var(--foreground))]',\n};\n\n/* Status → disc tone — the same semantic mapping as the accent bar. */\nconst STATUS_DISC_TONE: Record<CalendarEventStatus, IndicatorTone> = {\n confirmed: 'success',\n waiting: 'info',\n in_care: 'accent',\n done: 'success',\n cancelled: 'error',\n absent: 'warning',\n};\n\nconst STATUS_LABEL_KEYS: Record<CalendarEventStatus, string> = {\n confirmed: 'calendar.status.confirmed',\n waiting: 'calendar.status.waiting',\n in_care: 'calendar.status.inCare',\n done: 'calendar.status.done',\n cancelled: 'calendar.status.cancelled',\n absent: 'calendar.status.absent',\n};\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst calendarEventCardVariants = cva(\n [\n // Block root; the appointment content is a wrap-capable flex row\n // (inline-flowing text cell beside the icon column — structurally\n // overlap-safe). Tight padding and line-height so sliver-height\n // harnesses show a full text line.\n //\n // `@container/eventcard` makes the card's own inline size the query\n // basis for the indicator column below. FullCalendar sizes the\n // harness by lane count, so a dense day splits a column into\n // 30-40px slivers with no media query anywhere near that width —\n // only a container query can see it. Safe here: the root is a\n // BLOCK, never a flex parent, so `container-type` cannot collapse a\n // flex child (see rich-text-editor/editor-toolbar.tsx for the same\n // precaution).\n 'ds:relative ds:block ds:@container/eventcard',\n 'ds:w-full ds:h-full',\n 'ds:ps-[var(--spacing-2xs)] ds:pe-[var(--spacing-2xs)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[length:var(--font-size-sm)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:leading-tight ds:text-start',\n 'ds:overflow-hidden',\n // kept verbatim from the former base (inert on a non-focusable div\n // inside FC; harmless)\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n // SINGLE PAINTED SURFACE — always present, never conditional. One\n // declaration per paint channel; value chain = \"caller custom prop,\n // else token\". This structurally eliminates the CVA-vs-override\n // specificity race (the old double-paint bug) — stylesheet order\n // becomes irrelevant.\n 'ds:[background-color:var(--calendar-event-bg,var(--primary))]',\n 'ds:[color:var(--calendar-event-text,var(--primary-foreground))]',\n 'ds:border ds:[border-color:var(--calendar-event-border,transparent)]',\n ].join(' '),\n {\n variants: {\n // Do not add colour classes to this axis — status is icon + aria\n // only; a unit test asserts identical computed background\n // across all six statuses.\n status: {\n none: '',\n confirmed: '',\n waiting: '',\n in_care: '',\n done: '',\n cancelled: 'ds:line-through',\n absent: '',\n },\n bookedOnline: {\n // class name kept as a stable inert DOM hook; the stripe paint\n // lives here (moved from fullcalendar-theme.css) so it works in\n // the card's own stories, outside .fc-theme-alfadocs.\n // currentcolor = resolved ink, so stripes stay visible over any\n // picker colour.\n true: 'event-booked-online ds:bg-[image:repeating-linear-gradient(45deg,transparent,transparent_4px,color-mix(in_srgb,currentcolor_10%,transparent)_4px,color-mix(in_srgb,currentcolor_10%,transparent)_8px)]',\n false: '',\n },\n // Task treatment: CUSTOM-PROPERTY assignments only — the consuming\n // background-color / color / border-color declarations stay in the\n // base above, so this cannot re-open the CVA-vs-override specificity\n // race, and a caller's inline picker hex (set as the same custom\n // properties via `style`) still wins. `border-dashed` is a\n // border-style declaration — no property collision either.\n kind: {\n // The appointment's COLOUR IDENTITY edge — a thick start border\n // in the event colour, platform-agenda style, so the colour\n // reads even on sliver-height cards. Tasks keep the 1px edge:\n // muted to-dos carry no colour identity.\n appointment: 'ds:border-s-4',\n // Draft treatment — an appointment being COMPOSED, not yet saved\n // (the slot a user just picked, mirrored on the grid while the\n // editor is open). Same custom-property-only discipline as\n // `task`: dashed outline over a light primary tint, so the\n // placeholder reads as pending rather than as a booked slot.\n draft: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--primary)_10%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--primary)]',\n ].join(' '),\n // Details pending — the block IS a booked appointment, so it\n // keeps the colour-identity edge and assigns no paint of its own.\n // Only the NAME is missing; the bar above stands in for it.\n 'pending-details': 'ds:border-s-4',\n task: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:var(--muted)]',\n 'ds:[--calendar-event-text:var(--muted-foreground)]',\n 'ds:[--calendar-event-border:color-mix(in_srgb,currentcolor_45%,transparent)]',\n ].join(' '),\n },\n // Tinted colour scheme — the chip-family look: the picker colour\n // becomes a SOLID BORDER over a light tint of itself (theme-aware\n // via color-mix with --card), text on the theme's foreground\n // tokens. Custom-property assignments only — the painted\n // declarations stay in the base. The runtime hex arrives as\n // `--calendar-event-accent` (inline). Never combined with the task\n // variant: the component forces `solid` for tasks so exactly one\n // class-level assignment of each property exists per render.\n colorStyle: {\n solid: '',\n tinted: [\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_12%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--calendar-event-accent,var(--primary))]',\n ].join(' '),\n },\n },\n defaultVariants: {\n status: 'none',\n bookedOnline: false,\n kind: 'appointment',\n colorStyle: 'solid',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\n/**\n * The single painted surface of a calendar event.\n *\n * Colour model (platform parity): the caller's picker hex\n * (`backgroundColor` / `textColor` / `borderColor`) is the ONLY thing that\n * paints the card. `status` never paints the surface — it selects an icon\n * and (for `cancelled`) a line-through.\n *\n * Non-interactive by design: inside FullCalendar the outer harness anchor\n * owns click/drag/focus; standalone consumers wrap the card in their own\n * button/link. No onClick in the contract.\n */\nexport interface CalendarEventCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /**\n * Primary line. Pass the ALREADY-MASKED title when privacy applies — the\n * card never receives a name it must not render, so it cannot leak it\n * (visually or via the composed aria-label).\n */\n title: string;\n /**\n * Secondary description line, normal weight, truncated. Note: the\n * Calendar's privacy mode does NOT mask the suffix (current behaviour,\n * preserved deliberately).\n */\n suffix?: string;\n /**\n * Pre-formatted, localised time range (e.g. \"09:00 – 09:45\"). The\n * Calendar adapter computes it via Intl.DateTimeFormat.formatRange.\n * Included in the composed aria-label whenever present (even when the\n * visual time line is suppressed via showTime/allDay — matches today's\n * Calendar behaviour byte-for-byte).\n */\n rangeText?: string;\n /**\n * Gates the VISUAL time line only (aria keeps rangeText). Mirrors\n * CalendarProps.showTime. @default true\n */\n showTime?: boolean;\n /**\n * All-day events suppress the visual time line (aria keeps rangeText).\n * @default false\n */\n allDay?: boolean;\n\n /**\n * Lifecycle state (6-state, matches the platform DoctorAppointment\n * lifecycle) → status icon + line-through for `cancelled` +\n * localised label in the aria-label. NEVER paints the\n * card surface.\n */\n status?: CalendarEventStatus;\n\n /**\n * Runtime hex (#rgb or #rrggbb) from the consumer's colour picker — THE\n * painted surface. Injected as `--calendar-event-bg` via the sanctioned\n * inline custom-property pattern (23-constraints §inline-style exception).\n */\n backgroundColor?: string;\n /**\n * Runtime hex paired with backgroundColor. When omitted while\n * backgroundColor is set, the card auto-derives black/white ink by\n * luminance (provably WCAG AA ≥ 4.58:1 for any opaque colour).\n */\n textColor?: string;\n /**\n * Runtime hex border for delineating light surfaces. The platform sends\n * '#cccccc' when backgroundColor is '#ffffff' and omits it otherwise.\n * Falls back to transparent; border-width is constant (1px always\n * rendered), so toggling never shifts layout and event boundaries\n * survive forced-colors / Windows High Contrast for free.\n */\n borderColor?: string;\n\n /* Indicator icons — names identical to CalendarEvent fields (1:1 map). */\n /** Globe icon + diagonal stripe overlay. */\n isBookedOnline?: boolean;\n /** AlertTriangle icon. */\n hasUnassignedPatient?: boolean;\n /** HeartPulse icon. */\n hasHighlightedAnamnesis?: boolean;\n /** Euro icon. */\n hasBillableAmount?: boolean;\n /** Video icon. */\n isTelehealth?: boolean;\n /**\n * Repeat icon — this event belongs to a REPEATING SERIES. Set it on\n * every occurrence, not only the first: the flag answers \"will moving\n * or deleting this touch other appointments?\", which is true of a\n * modified occurrence too. Series ROLE (which row owns the rule) is a\n * separate concern — see `CalendarEvent.isRecurrenceParent`.\n */\n isRecurring?: boolean;\n /**\n * Task treatment — a calendar-scheduled to-do renders distinctly from an\n * appointment: dashed outline (derived from the resolved ink when no\n * `borderColor` is supplied), muted default surface (an explicit\n * `backgroundColor`/`textColor` still wins), a leading clipboard glyph,\n * and a localised \"task\" word appended to the accessible name. Emitted as\n * `data-kind=\"task\"` for DOM hooks.\n */\n isTask?: boolean;\n /**\n * Draft treatment — a placeholder for an appointment being composed:\n * the slot the user just picked, mirrored on the grid while the editor\n * is open. Dashed outline over a light primary tint, with a localised\n * \"draft\" word appended to the accessible name. Emitted as\n * `data-kind=\"draft\"`. Takes precedence over `isTask`, and like a task\n * it forces the solid paint path so exactly one class-level assignment\n * of each paint custom property exists per render.\n */\n isDraft?: boolean;\n /**\n * Details-pending treatment — a REAL booked appointment an\n * occupancy-first host drew from the slot it occupies while it still\n * fetches whose it is. The card keeps its colour and size and renders an\n * `aria-hidden` skeleton bar where the title goes, with the localised\n * \"loading details\" word in the accessible name and\n * `data-kind=\"pending-details\"` as the hook. Wins over `isDraft`/`isTask`.\n */\n detailsPending?: boolean;\n /**\n * Colour scheme for the picker colour. `'solid'` (default) is the\n * platform model — the hex paints the whole surface, ink auto-derived.\n * `'tinted'` is the chip-family scheme: the hex becomes a SOLID BORDER\n * over a light tint of itself (theme-aware via color-mix with `--card`),\n * with text on the theme's foreground tokens — `textColor` and\n * `borderColor` are ignored under it. Tasks keep their muted dashed\n * treatment regardless.\n */\n colorStyle?: 'solid' | 'tinted';\n\n /**\n * Resource title (chair/operator) woven into the composed aria-label\n * only — never rendered visually. The Calendar adapter resolves\n * resourceId → title before passing it.\n */\n resourceLabel?: string;\n /**\n * The title is a privacy MASK (the Calendar's privacy mode swapped the\n * patient name for `privacyModeTitle`). Renders a crossed-out-eye glyph\n * beside the mask so the redaction is legible as deliberate, with its\n * own breathing room after the time.\n */\n privacyMasked?: boolean;\n /**\n * Stable event id → emitted as `data-event-id` (Calendar.focusEvent\n * targets it) and used as the contrast-warning dedup context.\n */\n eventId?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const CalendarEventCard = forwardRef<\n HTMLDivElement,\n CalendarEventCardProps\n>(\n (\n {\n title,\n suffix,\n rangeText,\n showTime = true,\n allDay = false,\n status,\n backgroundColor,\n textColor,\n borderColor,\n isBookedOnline = false,\n hasUnassignedPatient,\n hasHighlightedAnamnesis,\n hasBillableAmount,\n isTelehealth,\n isRecurring,\n isTask = false,\n isDraft = false,\n detailsPending = false,\n colorStyle = 'solid',\n resourceLabel,\n privacyMasked = false,\n eventId,\n className,\n style,\n 'aria-label': ariaLabelProp,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const StatusIcon = status ? STATUS_ICON[status] : null;\n const hasIndicators =\n Boolean(StatusIcon) ||\n Boolean(isBookedOnline) ||\n Boolean(hasUnassignedPatient) ||\n Boolean(hasHighlightedAnamnesis) ||\n Boolean(hasBillableAmount) ||\n Boolean(isTelehealth) ||\n Boolean(isRecurring);\n const statusLabel = status ? t(STATUS_LABEL_KEYS[status]) : undefined;\n const kindLabel = detailsPending\n ? t('calendar.eventKind.pendingDetails')\n : isDraft\n ? t('calendar.eventKind.draft')\n : isTask\n ? t('calendar.eventKind.task')\n : undefined;\n\n /* Accessible name — the Calendar's historical composition, with the\n localised \"task\" word appended for task cards so screen-reader users\n get the same appointment-vs-task distinction the dashed outline and\n clipboard glyph carry visually. An explicit consumer-supplied\n aria-label wins. rangeText is always included when present, even when\n the visual time line is hidden. */\n const ariaLabel =\n ariaLabelProp ??\n [title, rangeText, resourceLabel, statusLabel, kindLabel]\n .filter(Boolean)\n .join(', ');\n\n const kind = detailsPending\n ? 'pending-details'\n : isDraft\n ? 'draft'\n : isTask\n ? 'task'\n : 'appointment';\n\n /* Tasks force the solid path — their muted variant owns the paint\n custom properties, so the tinted class must never co-assign them. */\n const tinted = !isTask && !isDraft && colorStyle === 'tinted';\n\n /* Ink derivation — solid scheme only, when the caller paints the\n surface without pairing a text colour. */\n const ink =\n !tinted && !textColor && backgroundColor\n ? resolveInk(backgroundColor)\n : null;\n\n /* DEV-only guardrails — every helper no-ops in production and dedupes\n per session, so calling during render is safe. The tinted scheme\n paints text on theme tokens over a 12% tint, so the solid-scheme\n pair checks don't apply there. */\n const warnContext = eventId ? `event ${eventId}` : 'calendar-event-card';\n if (!tinted) {\n warnLowContrast(backgroundColor, textColor, warnContext);\n if (backgroundColor && !textColor) {\n // no-ops when the hex is parseable (i.e. when resolveInk succeeded)\n warnUnparseableBackground(backgroundColor, warnContext);\n }\n if (backgroundColor && !borderColor) {\n // no-ops unless the background is near-white (luminance > 0.9)\n warnLowDelineation(backgroundColor, warnContext);\n }\n }\n\n /* Per-event colour override: the consuming app passes runtime hex from\n its colour picker. 23-constraints permits inline `style` only as a\n CSS custom-property setter for runtime values that can't be\n enumerated at build time — the consuming background-color / color /\n border-color declarations live in the CVA base as Tailwind arbitrary\n values with token fallbacks. */\n const colourOverrides: CSSProperties | undefined = tinted\n ? backgroundColor\n ? ({ '--calendar-event-accent': backgroundColor } as CSSProperties)\n : undefined\n : backgroundColor || textColor || borderColor\n ? ({\n ...(backgroundColor\n ? { '--calendar-event-bg': backgroundColor }\n : {}),\n ...(textColor\n ? { '--calendar-event-text': textColor }\n : ink === 'on-light'\n ? { '--calendar-event-text': 'var(--event-ink-on-light)' }\n : ink === 'on-dark'\n ? { '--calendar-event-text': 'var(--event-ink-on-dark)' }\n : {}),\n ...(borderColor ? { '--calendar-event-border': borderColor } : {}),\n } as CSSProperties)\n : undefined;\n\n const mergedStyle: CSSProperties | undefined =\n style || colourOverrides ? { ...style, ...colourOverrides } : undefined;\n\n return (\n <div\n ref={ref}\n {...rest}\n className={calendarEventCardVariants({\n status: status ?? 'none',\n bookedOnline: isBookedOnline,\n kind,\n colorStyle: tinted ? 'tinted' : 'solid',\n className,\n })}\n // eslint-disable-next-line react/forbid-dom-props -- caller-supplied event bg/text/border hex injected via CSS variables (23-constraints §inline-style exception)\n style={mergedStyle}\n aria-label={ariaLabel}\n data-component=\"calendar-event-card\"\n data-event-id={eventId}\n data-kind={kind}\n data-status={status ?? 'none'}\n data-contrast={\n tinted ? 'tinted' : textColor ? 'custom' : (ink ?? 'default')\n }\n >\n {isTask && !detailsPending ? (\n /* Task cards lead with ONE line — glyph + title inline. A task is\n typically a 30-min block whose visible height fits a single\n line; the appointment layout below would spend that line on the\n indicator row and clip the title entirely. Tasks carry none of\n the appointment flags, so the row loses nothing. */\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]\">\n {/* Same card-surface disc as the appointment indicators —\n muted ink, since a task carries no semantic tone. */}\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ds:text-[color:var(--muted-foreground)]`}\n >\n <ClipboardCheck size={11} aria-hidden=\"true\" />\n </span>\n {showTime && !allDay && rangeText ? (\n <span className=\"ds:whitespace-nowrap ds:text-[length:var(--font-size-xs)]\">\n {rangeText}\n </span>\n ) : null}\n <span className=\"ds:[min-inline-size:0] ds:font-[var(--font-weight-semibold)] ds:truncate ds:text-start\">\n {privacyMasked ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <EyeOff size={12} aria-hidden=\"true\" />\n {title}\n </span>\n ) : (\n title\n )}\n </span>\n </span>\n ) : (\n /* Platform-density layout with STRUCTURAL overlap-safety: the\n first row is a flex pair — an inline-flowing text cell (time,\n then the semibold name; wraps when taller cards allow) beside\n a fixed icon column. Flex cells cannot paint over each other,\n unlike a float (inline text paints ABOVE floats, which\n produced glyphs-through-icons in sliver-width columns). A\n one-line sliver still reads \"09:15 Name\" plus icons. */\n <span className=\"ds:flex ds:h-full ds:items-stretch ds:gap-[var(--spacing-2xs)]\">\n {/* overflow-hidden + break-normal: words never shatter into\n per-character stacks in sliver-width tiles — overlong words\n clip inside the cell instead (platform behaviour).\n\n min-w floor (NOT min-w-0): the indicator column is\n `shrink-0`, so without a floor flexbox settles the text\n cell at zero and a many-flag event renders as nothing but\n decorative discs even on a full-width column. The floor\n makes the discs — which are aria-hidden and duplicated in\n the composed aria-label — the thing that gets pushed past\n the card's clip edge, never the patient's name. */}\n <span className=\"ds:min-w-[var(--spacing-2xl)] ds:flex-1 ds:overflow-hidden ds:break-normal\">\n {showTime && !allDay && rangeText ? (\n // No opacity here — composing 70% over saturated bgs drops\n // effective contrast below WCAG AA. The smaller\n // font-size-xs vs the title's font-weight-semibold provides\n // sufficient visual hierarchy.\n <span className=\"ds:me-[var(--spacing-2xs)] ds:whitespace-nowrap ds:text-[length:var(--font-size-xs)]\">\n {rangeText}\n </span>\n ) : null}\n <span className=\"ds:font-[var(--font-weight-semibold)]\">\n {detailsPending ? (\n /* No name yet — and nothing invented in its place. */\n <span aria-hidden=\"true\" className={PENDING_BAR_CLASS} />\n ) : privacyMasked ? (\n /* The eye + mask get their own start padding so the\n redaction doesn't crowd the time. */\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:ps-[var(--spacing-2xs)] ds:align-middle\">\n <EyeOff size={12} aria-hidden=\"true\" />\n {title}\n </span>\n ) : (\n title\n )}\n </span>\n {suffix ? (\n /* Second line inside the text cell — beside the plate,\n never beneath it. */\n <span className=\"ds:block ds:truncate ds:text-[length:var(--font-size-xs)]\">\n {suffix}\n </span>\n ) : null}\n </span>\n <span\n className={\n hasIndicators\n ? /* Vertically CENTRED indicator column — each disc is\n its own card-surface circle, so no plate and no\n colour-on-colour.\n\n Hidden below 128px of CARD width: three discs are\n 58px, so on a 34px overlap sliver the shrink-0\n column outran the whole card and the time and name\n were laid out at zero. Decoration must not outrank\n the only content, and nothing is lost — every disc\n is aria-hidden and its meaning already sits in the\n composed aria-label, which a sliver card still\n carries in full. */\n 'ds:hidden ds:@[128px]/eventcard:flex ds:shrink-0 ds:items-center ds:gap-[var(--spacing-2xs)] ds:self-center'\n : 'ds:hidden'\n }\n >\n {/* Semantic icon CHIPS (the anamnesis heart-chip idiom:\n icon-only Badge, tinted + bordered) — self-contained\n contrast on ANY picker surface, where bare currentcolor\n glyphs got lost. All decorative: the composed\n aria-label carries the status; chips are aria-hidden. */}\n {StatusIcon && status ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE[STATUS_DISC_TONE[status]]}`}\n >\n <StatusIcon size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {isBookedOnline ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.info}`}\n >\n <Globe size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {hasUnassignedPatient ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.warning}`}\n >\n <TriangleAlert size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {hasHighlightedAnamnesis ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.accent}`}\n >\n <HeartPulse size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {hasBillableAmount ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.warning}`}\n >\n <Euro size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {isTelehealth ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.info}`}\n >\n <Video size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {isRecurring ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.info}`}\n >\n <Repeat size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n </span>\n </span>\n )}\n {isTask && showTime && !allDay && rangeText ? (\n <span className=\"ds:text-[length:var(--font-size-xs)]\">\n {rangeText}\n </span>\n ) : null}\n {isTask && suffix ? (\n /* Task cards keep the below-row suffix (their branch has no\n text cell / plate split). */\n <span className=\"ds:block ds:truncate ds:text-[length:var(--font-size-xs)]\">\n {suffix}\n </span>\n ) : null}\n </div>\n );\n },\n);\nCalendarEventCard.displayName = 'CalendarEventCard';\n"],"names":["__iconNode","Euro","createLucideIcon","parseHex","hex","trimmed","body","r","g","b","relativeLuminance","lin","c","warnLowContrast","bgHex","fgHex","contextLabel","resolveInk","bg","STATUS_ICON","ThumbsUp","Clock","Stethoscope","Check","Ban","UserX","INDICATOR_DISC_BASE","PENDING_BAR_CLASS","INDICATOR_DISC_TONE","STATUS_DISC_TONE","STATUS_LABEL_KEYS","calendarEventCardVariants","cva","CalendarEventCard","forwardRef","title","suffix","rangeText","showTime","allDay","status","backgroundColor","textColor","borderColor","isBookedOnline","hasUnassignedPatient","hasHighlightedAnamnesis","hasBillableAmount","isTelehealth","isRecurring","isTask","isDraft","detailsPending","colorStyle","resourceLabel","privacyMasked","eventId","className","style","ariaLabelProp","rest","ref","t","useTranslation","StatusIcon","hasIndicators","statusLabel","kindLabel","ariaLabel","kind","tinted","ink","colourOverrides","mergedStyle","jsxs","jsx","ClipboardCheck","EyeOff","Globe","TriangleAlert","HeartPulse","Video","Repeat"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"calendar-event-card-B6N5h1dO.js","sources":["../../node_modules/lucide-react/dist/esm/icons/euro.mjs","../../src/components/_shared/contrast-warning.ts","../../src/components/calendar-event-card/calendar-event-card.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M4 10h12\", key: \"1y6xl8\" }],\n [\"path\", { d: \"M4 14h9\", key: \"1loblj\" }],\n [\n \"path\",\n {\n d: \"M19 6a7.7 7.7 0 0 0-5.2-2A7.9 7.9 0 0 0 6 12c0 4.4 3.5 8 7.8 8 2 0 3.8-.8 5.2-2\",\n key: \"1j6lzo\"\n }\n ]\n];\nconst Euro = createLucideIcon(\"euro\", __iconNode);\n\nexport { __iconNode, Euro as default };\n//# sourceMappingURL=euro.mjs.map\n","/* ------------------------------------------------------------------ */\n/* Shared contrast guardrail — Calendar + CalendarEventCard */\n/* */\n/* The consuming app supplies runtime hex pairs at several surfaces: */\n/* - event.backgroundColor / event.textColor (+ event.borderColor) */\n/* - modeBannerColor / modeBannerTextColor */\n/* - resource.color / resource.shortTitleTextColor */\n/* */\n/* When the text half of the pair is also a hex (i.e. both halves come */\n/* from the caller), we can validate them synchronously and warn the */\n/* consuming-app developer during DEV if the pair fails WCAG AA normal */\n/* text (4.5:1). When only the background half is supplied, */\n/* `resolveInk` derives a provably AA-safe black/white ink for it. */\n/* Every helper is a no-op in production builds. */\n/* ------------------------------------------------------------------ */\n\n/* Module-level dedup set — keyed on the (bg, fg, context) tuple so the\n same bad pair moving around the calendar only warns once per session.\n Exposed via `resetContrastWarnings()` for test isolation. */\nconst warnedTuples = new Set<string>();\n\n/** Reset the dedup set — intended for use between tests. */\nexport function resetContrastWarnings(): void {\n warnedTuples.clear();\n}\n\n/**\n * Parse a 3-char or 6-char `#RRGGBB` hex string into a linear sRGB\n * triple in the [0,1] range. Returns `null` for any input the caller\n * can't parse (malformed prefix, bad length, non-hex characters) —\n * the helper stays silent in that case rather than emitting noise.\n */\nfunction parseHex(hex: string): [number, number, number] | null {\n if (typeof hex !== 'string') return null;\n const trimmed = hex.trim();\n if (!trimmed.startsWith('#')) return null;\n const body = trimmed.slice(1);\n let r: number;\n let g: number;\n let b: number;\n if (body.length === 3) {\n if (!/^[0-9a-f]{3}$/i.test(body)) return null;\n r = parseInt(body[0] + body[0], 16);\n g = parseInt(body[1] + body[1], 16);\n b = parseInt(body[2] + body[2], 16);\n } else if (body.length === 6) {\n if (!/^[0-9a-f]{6}$/i.test(body)) return null;\n r = parseInt(body.slice(0, 2), 16);\n g = parseInt(body.slice(2, 4), 16);\n b = parseInt(body.slice(4, 6), 16);\n } else {\n return null;\n }\n return [r / 255, g / 255, b / 255];\n}\n\n/**\n * WCAG 2.1 relative luminance. Each channel is gamma-corrected then\n * weighted against the CIE photopic sensitivity of the human eye.\n * https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n */\nfunction relativeLuminance([r, g, b]: [number, number, number]): number {\n const lin = (c: number): number =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);\n}\n\n/**\n * WCAG 2.1 contrast ratio. Always returns a value in [1, 21]; the\n * relative-luminance lighter-over-darker convention is applied here.\n */\nfunction contrastRatio(\n bg: [number, number, number],\n fg: [number, number, number],\n): number {\n const l1 = relativeLuminance(bg);\n const l2 = relativeLuminance(fg);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * DEV-only WCAG AA guardrail for caller-supplied hex pairs.\n *\n * - No-op when `import.meta.env.DEV` is false.\n * - No-op when either half of the pair is missing (the \"fg missing →\n * inherits DS token\" case is a docs concern; the DS token isn't a\n * hex at runtime so we can't check it here).\n * - No-op when either hex can't be parsed (silent — not the helper's\n * concern to police malformed input).\n * - Deduplicated by `(bgHex, fgHex, contextLabel)` tuple so moving a\n * ratio-bad event around the calendar doesn't spam the console.\n *\n * @param bgHex - Caller-supplied background hex (e.g. `'#c2185b'`)\n * @param fgHex - Caller-supplied foreground hex (e.g. `'#ffffff'`)\n * @param contextLabel - Short description for the warning (e.g. `'event e1'`).\n */\nexport function warnLowContrast(\n bgHex: string | undefined,\n fgHex: string | undefined,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (!bgHex || !fgHex) return;\n\n const bg = parseHex(bgHex);\n const fg = parseHex(fgHex);\n if (!bg || !fg) return;\n\n const ratio = contrastRatio(bg, fg);\n if (ratio >= 4.5) return;\n\n const key = `${bgHex}|${fgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n /* `bg` parsed successfully above, so `resolveInk(bgHex)` is guaranteed\n to produce a compliant ink — the omit-textColor hint is always valid\n at this point. */\n console.warn(\n `[Calendar] Low contrast on ${contextLabel}: ${bgHex} / ${fgHex} (ratio ${ratio.toFixed(\n 2,\n )}, target 4.5). Pass a matching textColor/fgHex, pick a higher-contrast background, or omit textColor to let the kit choose a compliant ink.`,\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Ink derivation — bg-only caller colours */\n/* ------------------------------------------------------------------ */\n\nexport type EventInk = 'on-light' | 'on-dark';\n\n/**\n * Pick the ink for an arbitrary opaque bg hex. Returns `null` when the\n * input can't be parsed (`#rgb` / `#rrggbb` only).\n *\n * The threshold 0.1791 is the relative luminance at which\n * `contrast(bg, #fff) === contrast(bg, #000)`; the better of the two\n * always yields ≥ 4.58:1 (the minimum, at a mid-grey ≈ `#757575`) —\n * provably WCAG AA-safe for any opaque background.\n */\nexport function resolveInk(bgHex: string): EventInk | null {\n const bg = parseHex(bgHex);\n if (!bg) return null;\n // threshold where contrast(bg, #fff) === contrast(bg, #000)\n return relativeLuminance(bg) > 0.1791 ? 'on-light' : 'on-dark';\n}\n\n/**\n * DEV-only, one-shot warning for a caller `backgroundColor` the kit can't\n * parse (`rgb(…)`, keywords, malformed hex). The browser can still paint\n * it, but the text falls back to the token default and contrast can't be\n * verified. Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnUnparseableBackground(\n bgHex: string,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (parseHex(bgHex)) return;\n\n const key = `unparseable|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Unparseable backgroundColor on ${contextLabel}: \"${bgHex}\". ` +\n `Expected #rgb or #rrggbb — contrast cannot be verified and the text ` +\n `colour falls back to the token default.`,\n );\n}\n\n/**\n * DEV-only, one-shot warning for a near-white `backgroundColor`\n * (relative luminance > 0.9) supplied without a `borderColor` — the\n * event may be invisible against the calendar grid. The kit warns, it\n * does not repaint (delineation is decorative under WCAG 1.4.11 and the\n * consumer owns the picker colour). Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnLowDelineation(bgHex: string, contextLabel: string): void {\n if (!import.meta.env.DEV) return;\n\n const bg = parseHex(bgHex);\n if (!bg) return;\n if (relativeLuminance(bg) <= 0.9) return;\n\n const key = `delineation|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Light backgroundColor without borderColor on ${contextLabel}: ` +\n `${bgHex} may be invisible against the grid — pass a borderColor ` +\n `(the platform convention sends a light-grey border for white backgrounds).`,\n );\n}\n","/* ------------------------------------------------------------------ */\n/* CalendarEventCard — the single painted surface of a calendar event. */\n/* */\n/* Colour model (platform parity): the caller's picker hex */\n/* (backgroundColor / textColor / borderColor) is the ONLY thing that */\n/* paints the card. `status` never paints the surface — it selects an */\n/* icon and (for `cancelled`) a line-through. When no picker colour */\n/* is supplied the surface falls back to the theme's --primary / */\n/* --primary-foreground pair. */\n/* */\n/* Non-interactive by design: inside FullCalendar the outer harness */\n/* anchor owns click/drag/focus; standalone consumers wrap the card in */\n/* their own button/link. No onClick in the contract. */\n/* ------------------------------------------------------------------ */\n\nimport { forwardRef } from 'react';\nimport type { CSSProperties, HTMLAttributes } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\nimport {\n ThumbsUp,\n Clock,\n Stethoscope,\n Check,\n Ban,\n UserX,\n Globe,\n TriangleAlert,\n HeartPulse,\n Euro,\n Video,\n Repeat,\n EyeOff,\n ClipboardCheck,\n type LucideIcon,\n} from 'lucide-react';\n// Type-only import — erased at build, no runtime cycle with calendar.tsx's\n// runtime import of this card. Do NOT convert to a value import.\nimport type { CalendarEventStatus } from '../calendar/calendar';\nimport {\n warnLowContrast,\n resolveInk,\n warnUnparseableBackground,\n warnLowDelineation,\n} from '../_shared/contrast-warning';\n\n/* ------------------------------------------------------------------ */\n/* Status lookups */\n/* ------------------------------------------------------------------ */\n\nconst STATUS_ICON: Record<CalendarEventStatus, LucideIcon> = {\n confirmed: ThumbsUp,\n waiting: Clock,\n in_care: Stethoscope,\n done: Check,\n cancelled: Ban,\n absent: UserX,\n};\n\n/* Status → i18n key lookup. Kept as a literal object (not a template)\n so static-analysis extractors can find every key. Keys already exist\n in all 18 locale bundles — do not add new ones here. */\n/* Indicator DISC — option D of the design review: each glyph in a small\n circle on the plain card surface (hairline border + row-lift shadow)\n with the SEMANTIC colour as icon ink. Chip-grade contrast on any\n picker colour without a plate; ink tokens mirror Badge's variants so\n the vocabulary stays one system. */\nconst INDICATOR_DISC_BASE =\n 'ds:inline-flex ds:size-4.5 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-full)] ds:bg-[color:var(--card)] ds:border ds:border-[color:var(--border)] ds:shadow-[var(--shadow-sm)]';\n\n/* DETAILS-PENDING bar — the Skeleton component's own classes, inlined on\n a <span>: Skeleton renders a <div>, which cannot live inside the card's\n inline text cell. Decorative (aria-hidden) because the composed\n aria-label already carries the localised \"loading details\" word. */\nconst PENDING_BAR_CLASS =\n 'ds:inline-block ds:h-3 ds:w-[6ch] ds:align-middle ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:animate-[skeleton-pulse_calc(var(--animation-duration)*8)_ease-in-out_infinite] ds:motion-reduce:animate-none ds:forced-colors:bg-[GrayText] ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText] ds:forced-colors:animate-none';\n\ntype IndicatorTone = 'success' | 'info' | 'warning' | 'error' | 'accent';\n\nconst INDICATOR_DISC_TONE: Record<IndicatorTone, string> = {\n success: 'ds:text-[color:var(--success-foreground)]',\n info: 'ds:text-[color:var(--info-foreground)]',\n warning: 'ds:text-[color:var(--warning-foreground)]',\n error: 'ds:text-[color:var(--error-foreground)]',\n // Same AA-clearing accent mix Badge's accentSoft uses for its ink.\n accent:\n 'ds:text-[color:color-mix(in_srgb,var(--accent)_40%,var(--foreground))]',\n};\n\n/* Status → disc tone — the same semantic mapping as the accent bar. */\nconst STATUS_DISC_TONE: Record<CalendarEventStatus, IndicatorTone> = {\n confirmed: 'success',\n waiting: 'info',\n in_care: 'accent',\n done: 'success',\n cancelled: 'error',\n absent: 'warning',\n};\n\nconst STATUS_LABEL_KEYS: Record<CalendarEventStatus, string> = {\n confirmed: 'calendar.status.confirmed',\n waiting: 'calendar.status.waiting',\n in_care: 'calendar.status.inCare',\n done: 'calendar.status.done',\n cancelled: 'calendar.status.cancelled',\n absent: 'calendar.status.absent',\n};\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst calendarEventCardVariants = cva(\n [\n // Block root; the appointment content is a wrap-capable flex row\n // (inline-flowing text cell beside the icon column — structurally\n // overlap-safe). Tight padding and line-height so sliver-height\n // harnesses show a full text line.\n //\n // `@container/eventcard` makes the card's own inline size the query\n // basis for the indicator column below. FullCalendar sizes the\n // harness by lane count, so a dense day splits a column into\n // 30-40px slivers with no media query anywhere near that width —\n // only a container query can see it. Safe here: the root is a\n // BLOCK, never a flex parent, so `container-type` cannot collapse a\n // flex child (see rich-text-editor/editor-toolbar.tsx for the same\n // precaution).\n 'ds:relative ds:block ds:@container/eventcard',\n 'ds:w-full ds:h-full',\n 'ds:ps-[var(--spacing-2xs)] ds:pe-[var(--spacing-2xs)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[length:var(--font-size-sm)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:leading-tight ds:text-start',\n 'ds:overflow-hidden',\n // kept verbatim from the former base (inert on a non-focusable div\n // inside FC; harmless)\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n // SINGLE PAINTED SURFACE — always present, never conditional. One\n // declaration per paint channel; value chain = \"caller custom prop,\n // else token\". This structurally eliminates the CVA-vs-override\n // specificity race (the old double-paint bug) — stylesheet order\n // becomes irrelevant.\n 'ds:[background-color:var(--calendar-event-bg,var(--primary))]',\n 'ds:[color:var(--calendar-event-text,var(--primary-foreground))]',\n 'ds:border ds:[border-color:var(--calendar-event-border,transparent)]',\n ].join(' '),\n {\n variants: {\n // Do not add colour classes to this axis — status is icon + aria\n // only; a unit test asserts identical computed background\n // across all six statuses.\n status: {\n none: '',\n confirmed: '',\n waiting: '',\n in_care: '',\n done: '',\n cancelled: 'ds:line-through',\n absent: '',\n },\n bookedOnline: {\n // class name kept as a stable inert DOM hook; the stripe paint\n // lives here (moved from fullcalendar-theme.css) so it works in\n // the card's own stories, outside .fc-theme-alfadocs.\n // currentcolor = resolved ink, so stripes stay visible over any\n // picker colour.\n true: 'event-booked-online ds:bg-[image:repeating-linear-gradient(45deg,transparent,transparent_4px,color-mix(in_srgb,currentcolor_10%,transparent)_4px,color-mix(in_srgb,currentcolor_10%,transparent)_8px)]',\n false: '',\n },\n // Task treatment: CUSTOM-PROPERTY assignments only — the consuming\n // background-color / color / border-color declarations stay in the\n // base above, so this cannot re-open the CVA-vs-override specificity\n // race, and a caller's inline picker hex (set as the same custom\n // properties via `style`) still wins. `border-dashed` is a\n // border-style declaration — no property collision either.\n kind: {\n // The appointment's COLOUR IDENTITY edge — a thick start border\n // in the event colour, platform-agenda style, so the colour\n // reads even on sliver-height cards. Tasks keep the 1px edge:\n // muted to-dos carry no colour identity.\n appointment: 'ds:border-s-4',\n // Draft treatment — an appointment being COMPOSED, not yet saved\n // (the slot a user just picked, mirrored on the grid while the\n // editor is open). Same custom-property-only discipline as\n // `task`: dashed outline over a light primary tint, so the\n // placeholder reads as pending rather than as a booked slot.\n draft: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--primary)_10%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--primary)]',\n ].join(' '),\n // Details pending — the block IS a booked appointment, so it\n // keeps the colour-identity edge and assigns no paint of its own.\n // Only the NAME is missing; the bar above stands in for it.\n 'pending-details': 'ds:border-s-4',\n task: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:var(--muted)]',\n 'ds:[--calendar-event-text:var(--muted-foreground)]',\n 'ds:[--calendar-event-border:color-mix(in_srgb,currentcolor_45%,transparent)]',\n ].join(' '),\n },\n // Tinted colour scheme — the chip-family look: the picker colour\n // becomes a SOLID BORDER over a light tint of itself (theme-aware\n // via color-mix with --card), text on the theme's foreground\n // tokens. Custom-property assignments only — the painted\n // declarations stay in the base. The runtime hex arrives as\n // `--calendar-event-accent` (inline). Never combined with the task\n // variant: the component forces `solid` for tasks so exactly one\n // class-level assignment of each property exists per render.\n colorStyle: {\n solid: '',\n tinted: [\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_12%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--calendar-event-accent,var(--primary))]',\n ].join(' '),\n },\n },\n defaultVariants: {\n status: 'none',\n bookedOnline: false,\n kind: 'appointment',\n colorStyle: 'solid',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\n/**\n * The single painted surface of a calendar event.\n *\n * Colour model (platform parity): the caller's picker hex\n * (`backgroundColor` / `textColor` / `borderColor`) is the ONLY thing that\n * paints the card. `status` never paints the surface — it selects an icon\n * and (for `cancelled`) a line-through.\n *\n * Non-interactive by design: inside FullCalendar the outer harness anchor\n * owns click/drag/focus; standalone consumers wrap the card in their own\n * button/link. No onClick in the contract.\n */\nexport interface CalendarEventCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /**\n * Primary line. Pass the ALREADY-MASKED title when privacy applies — the\n * card never receives a name it must not render, so it cannot leak it\n * (visually or via the composed aria-label).\n */\n title: string;\n /**\n * Secondary description line, normal weight, truncated. Note: the\n * Calendar's privacy mode does NOT mask the suffix (current behaviour,\n * preserved deliberately).\n */\n suffix?: string;\n /**\n * Pre-formatted, localised time range (e.g. \"09:00 – 09:45\"). The\n * Calendar adapter computes it via Intl.DateTimeFormat.formatRange.\n * Included in the composed aria-label whenever present (even when the\n * visual time line is suppressed via showTime/allDay — matches today's\n * Calendar behaviour byte-for-byte).\n */\n rangeText?: string;\n /**\n * Gates the VISUAL time line only (aria keeps rangeText). Mirrors\n * CalendarProps.showTime. @default true\n */\n showTime?: boolean;\n /**\n * All-day events suppress the visual time line (aria keeps rangeText).\n * @default false\n */\n allDay?: boolean;\n\n /**\n * Lifecycle state (6-state, matches the platform DoctorAppointment\n * lifecycle) → status icon + line-through for `cancelled` +\n * localised label in the aria-label. NEVER paints the\n * card surface.\n */\n status?: CalendarEventStatus;\n\n /**\n * Runtime hex (#rgb or #rrggbb) from the consumer's colour picker — THE\n * painted surface. Injected as `--calendar-event-bg` via the sanctioned\n * inline custom-property pattern (23-constraints §inline-style exception).\n */\n backgroundColor?: string;\n /**\n * Runtime hex paired with backgroundColor. When omitted while\n * backgroundColor is set, the card auto-derives black/white ink by\n * luminance (provably WCAG AA ≥ 4.58:1 for any opaque colour).\n */\n textColor?: string;\n /**\n * Runtime hex border for delineating light surfaces. The platform sends\n * '#cccccc' when backgroundColor is '#ffffff' and omits it otherwise.\n * Falls back to transparent; border-width is constant (1px always\n * rendered), so toggling never shifts layout and event boundaries\n * survive forced-colors / Windows High Contrast for free.\n */\n borderColor?: string;\n\n /* Indicator icons — names identical to CalendarEvent fields (1:1 map). */\n /** Globe icon + diagonal stripe overlay. */\n isBookedOnline?: boolean;\n /** AlertTriangle icon. */\n hasUnassignedPatient?: boolean;\n /** HeartPulse icon. */\n hasHighlightedAnamnesis?: boolean;\n /** Euro icon. */\n hasBillableAmount?: boolean;\n /** Video icon. */\n isTelehealth?: boolean;\n /**\n * Repeat icon — this event belongs to a REPEATING SERIES. Set it on\n * every occurrence, not only the first: the flag answers \"will moving\n * or deleting this touch other appointments?\", which is true of a\n * modified occurrence too. Series ROLE (which row owns the rule) is a\n * separate concern — see `CalendarEvent.isRecurrenceParent`.\n */\n isRecurring?: boolean;\n /**\n * Task treatment — a calendar-scheduled to-do renders distinctly from an\n * appointment: dashed outline (derived from the resolved ink when no\n * `borderColor` is supplied), muted default surface (an explicit\n * `backgroundColor`/`textColor` still wins), a leading clipboard glyph,\n * and a localised \"task\" word appended to the accessible name. Emitted as\n * `data-kind=\"task\"` for DOM hooks.\n */\n isTask?: boolean;\n /**\n * Draft treatment — a placeholder for an appointment being composed:\n * the slot the user just picked, mirrored on the grid while the editor\n * is open. Dashed outline over a light primary tint, with a localised\n * \"draft\" word appended to the accessible name. Emitted as\n * `data-kind=\"draft\"`. Takes precedence over `isTask`, and like a task\n * it forces the solid paint path so exactly one class-level assignment\n * of each paint custom property exists per render.\n */\n isDraft?: boolean;\n /**\n * Details-pending treatment — a REAL booked appointment an\n * occupancy-first host drew from the slot it occupies while it still\n * fetches whose it is. The card keeps its colour and size and renders an\n * `aria-hidden` skeleton bar where the title goes, with the localised\n * \"loading details\" word in the accessible name and\n * `data-kind=\"pending-details\"` as the hook. Wins over `isDraft`/`isTask`.\n */\n detailsPending?: boolean;\n /**\n * Colour scheme for the picker colour. `'solid'` (default) is the\n * platform model — the hex paints the whole surface, ink auto-derived.\n * `'tinted'` is the chip-family scheme: the hex becomes a SOLID BORDER\n * over a light tint of itself (theme-aware via color-mix with `--card`),\n * with text on the theme's foreground tokens — `textColor` and\n * `borderColor` are ignored under it. Tasks keep their muted dashed\n * treatment regardless.\n */\n colorStyle?: 'solid' | 'tinted';\n\n /**\n * Resource title (chair/operator) woven into the composed aria-label\n * only — never rendered visually. The Calendar adapter resolves\n * resourceId → title before passing it.\n */\n resourceLabel?: string;\n /**\n * The title is a privacy MASK (the Calendar's privacy mode swapped the\n * patient name for `privacyModeTitle`). Renders a crossed-out-eye glyph\n * beside the mask so the redaction is legible as deliberate, with its\n * own breathing room after the time.\n */\n privacyMasked?: boolean;\n /**\n * Stable event id → emitted as `data-event-id` (Calendar.focusEvent\n * targets it) and used as the contrast-warning dedup context.\n */\n eventId?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const CalendarEventCard = forwardRef<\n HTMLDivElement,\n CalendarEventCardProps\n>(\n (\n {\n title,\n suffix,\n rangeText,\n showTime = true,\n allDay = false,\n status,\n backgroundColor,\n textColor,\n borderColor,\n isBookedOnline = false,\n hasUnassignedPatient,\n hasHighlightedAnamnesis,\n hasBillableAmount,\n isTelehealth,\n isRecurring,\n isTask = false,\n isDraft = false,\n detailsPending = false,\n colorStyle = 'solid',\n resourceLabel,\n privacyMasked = false,\n eventId,\n className,\n style,\n 'aria-label': ariaLabelProp,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const StatusIcon = status ? STATUS_ICON[status] : null;\n const hasIndicators =\n Boolean(StatusIcon) ||\n Boolean(isBookedOnline) ||\n Boolean(hasUnassignedPatient) ||\n Boolean(hasHighlightedAnamnesis) ||\n Boolean(hasBillableAmount) ||\n Boolean(isTelehealth) ||\n Boolean(isRecurring);\n const statusLabel = status ? t(STATUS_LABEL_KEYS[status]) : undefined;\n const kindLabel = detailsPending\n ? t('calendar.eventKind.pendingDetails')\n : isDraft\n ? t('calendar.eventKind.draft')\n : isTask\n ? t('calendar.eventKind.task')\n : undefined;\n\n /* Accessible name — the Calendar's historical composition, with the\n localised \"task\" word appended for task cards so screen-reader users\n get the same appointment-vs-task distinction the dashed outline and\n clipboard glyph carry visually. An explicit consumer-supplied\n aria-label wins. rangeText is always included when present, even when\n the visual time line is hidden. */\n const ariaLabel =\n ariaLabelProp ??\n [title, rangeText, resourceLabel, statusLabel, kindLabel]\n .filter(Boolean)\n .join(', ');\n\n const kind = detailsPending\n ? 'pending-details'\n : isDraft\n ? 'draft'\n : isTask\n ? 'task'\n : 'appointment';\n\n /* Tasks force the solid path — their muted variant owns the paint\n custom properties, so the tinted class must never co-assign them. */\n const tinted = !isTask && !isDraft && colorStyle === 'tinted';\n\n /* Ink derivation — solid scheme only, when the caller paints the\n surface without pairing a text colour. */\n const ink =\n !tinted && !textColor && backgroundColor\n ? resolveInk(backgroundColor)\n : null;\n\n /* DEV-only guardrails — every helper no-ops in production and dedupes\n per session, so calling during render is safe. The tinted scheme\n paints text on theme tokens over a 12% tint, so the solid-scheme\n pair checks don't apply there. */\n const warnContext = eventId ? `event ${eventId}` : 'calendar-event-card';\n if (!tinted) {\n warnLowContrast(backgroundColor, textColor, warnContext);\n if (backgroundColor && !textColor) {\n // no-ops when the hex is parseable (i.e. when resolveInk succeeded)\n warnUnparseableBackground(backgroundColor, warnContext);\n }\n if (backgroundColor && !borderColor) {\n // no-ops unless the background is near-white (luminance > 0.9)\n warnLowDelineation(backgroundColor, warnContext);\n }\n }\n\n /* Per-event colour override: the consuming app passes runtime hex from\n its colour picker. 23-constraints permits inline `style` only as a\n CSS custom-property setter for runtime values that can't be\n enumerated at build time — the consuming background-color / color /\n border-color declarations live in the CVA base as Tailwind arbitrary\n values with token fallbacks. */\n const colourOverrides: CSSProperties | undefined = tinted\n ? backgroundColor\n ? ({ '--calendar-event-accent': backgroundColor } as CSSProperties)\n : undefined\n : backgroundColor || textColor || borderColor\n ? ({\n ...(backgroundColor\n ? { '--calendar-event-bg': backgroundColor }\n : {}),\n ...(textColor\n ? { '--calendar-event-text': textColor }\n : ink === 'on-light'\n ? { '--calendar-event-text': 'var(--event-ink-on-light)' }\n : ink === 'on-dark'\n ? { '--calendar-event-text': 'var(--event-ink-on-dark)' }\n : {}),\n ...(borderColor ? { '--calendar-event-border': borderColor } : {}),\n } as CSSProperties)\n : undefined;\n\n const mergedStyle: CSSProperties | undefined =\n style || colourOverrides ? { ...style, ...colourOverrides } : undefined;\n\n return (\n <div\n ref={ref}\n {...rest}\n className={calendarEventCardVariants({\n status: status ?? 'none',\n bookedOnline: isBookedOnline,\n kind,\n colorStyle: tinted ? 'tinted' : 'solid',\n className,\n })}\n // eslint-disable-next-line react/forbid-dom-props -- caller-supplied event bg/text/border hex injected via CSS variables (23-constraints §inline-style exception)\n style={mergedStyle}\n aria-label={ariaLabel}\n data-component=\"calendar-event-card\"\n data-event-id={eventId}\n data-kind={kind}\n data-status={status ?? 'none'}\n data-contrast={\n tinted ? 'tinted' : textColor ? 'custom' : (ink ?? 'default')\n }\n >\n {isTask && !detailsPending ? (\n /* Task cards lead with ONE line — glyph + title inline. A task is\n typically a 30-min block whose visible height fits a single\n line; the appointment layout below would spend that line on the\n indicator row and clip the title entirely. Tasks carry none of\n the appointment flags, so the row loses nothing. */\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]\">\n {/* Same card-surface disc as the appointment indicators —\n muted ink, since a task carries no semantic tone. */}\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ds:text-[color:var(--muted-foreground)]`}\n >\n <ClipboardCheck size={11} aria-hidden=\"true\" />\n </span>\n {showTime && !allDay && rangeText ? (\n <span className=\"ds:whitespace-nowrap ds:text-[length:var(--font-size-xs)]\">\n {rangeText}\n </span>\n ) : null}\n <span className=\"ds:[min-inline-size:0] ds:font-[var(--font-weight-semibold)] ds:truncate ds:text-start\">\n {privacyMasked ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <EyeOff size={12} aria-hidden=\"true\" />\n {title}\n </span>\n ) : (\n title\n )}\n </span>\n </span>\n ) : (\n /* Platform-density layout with STRUCTURAL overlap-safety: the\n first row is a flex pair — an inline-flowing text cell (time,\n then the semibold name; wraps when taller cards allow) beside\n a fixed icon column. Flex cells cannot paint over each other,\n unlike a float (inline text paints ABOVE floats, which\n produced glyphs-through-icons in sliver-width columns). A\n one-line sliver still reads \"09:15 Name\" plus icons. */\n <span className=\"ds:flex ds:h-full ds:items-stretch ds:gap-[var(--spacing-2xs)]\">\n {/* overflow-hidden + break-normal: words never shatter into\n per-character stacks in sliver-width tiles — overlong words\n clip inside the cell instead (platform behaviour).\n\n min-w floor (NOT min-w-0): the indicator column is\n `shrink-0`, so without a floor flexbox settles the text\n cell at zero and a many-flag event renders as nothing but\n decorative discs even on a full-width column. The floor\n makes the discs — which are aria-hidden and duplicated in\n the composed aria-label — the thing that gets pushed past\n the card's clip edge, never the patient's name. */}\n <span className=\"ds:min-w-[var(--spacing-2xl)] ds:flex-1 ds:overflow-hidden ds:break-normal\">\n {/* The time and the name used to share one inline run, which\n let a wide CJK range (no spaces to break on) claim\n whatever width it needed and hard-clip whatever came\n after — invisibly, since the cell above already hides\n overflow, so nothing here visually spilled the card but\n the name could vanish entirely behind a long range. A\n proper flex row gives each its own shrink/truncate\n budget: the range keeps its natural width up to just\n over half the cell, the name gets everything left over,\n and BOTH ellipsize rather than clip mid-glyph. The full\n range still rides the composed aria-label, and `title`\n repeats it as a pointer tooltip since the visual line\n can now truncate it. */}\n <span className=\"ds:flex ds:min-w-0 ds:items-baseline ds:gap-[var(--spacing-2xs)]\">\n {showTime && !allDay && rangeText ? (\n // No opacity here — composing 70% over saturated bgs drops\n // effective contrast below WCAG AA. The smaller\n // font-size-xs vs the title's font-weight-semibold provides\n // sufficient visual hierarchy.\n <span\n className=\"ds:max-w-[55%] ds:shrink-0 ds:truncate ds:whitespace-nowrap ds:text-[length:var(--font-size-xs)]\"\n title={rangeText}\n >\n {rangeText}\n </span>\n ) : null}\n <span className=\"ds:min-w-0 ds:flex-1 ds:truncate ds:font-[var(--font-weight-semibold)]\">\n {detailsPending ? (\n /* No name yet — and nothing invented in its place. */\n <span aria-hidden=\"true\" className={PENDING_BAR_CLASS} />\n ) : privacyMasked ? (\n /* The eye + mask get their own start padding so the\n redaction doesn't crowd the time. */\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:ps-[var(--spacing-2xs)] ds:align-middle\">\n <EyeOff size={12} aria-hidden=\"true\" />\n {title}\n </span>\n ) : (\n title\n )}\n </span>\n </span>\n {suffix ? (\n /* Second line inside the text cell — beside the plate,\n never beneath it. */\n <span className=\"ds:block ds:truncate ds:text-[length:var(--font-size-xs)]\">\n {suffix}\n </span>\n ) : null}\n </span>\n <span\n className={\n hasIndicators\n ? /* Vertically CENTRED indicator column — each disc is\n its own card-surface circle, so no plate and no\n colour-on-colour.\n\n Hidden below 128px of CARD width: three discs are\n 58px, so on a 34px overlap sliver the shrink-0\n column outran the whole card and the time and name\n were laid out at zero. Decoration must not outrank\n the only content, and nothing is lost — every disc\n is aria-hidden and its meaning already sits in the\n composed aria-label, which a sliver card still\n carries in full. */\n 'ds:hidden ds:@[128px]/eventcard:flex ds:shrink-0 ds:items-center ds:gap-[var(--spacing-2xs)] ds:self-center'\n : 'ds:hidden'\n }\n >\n {/* Semantic icon CHIPS (the anamnesis heart-chip idiom:\n icon-only Badge, tinted + bordered) — self-contained\n contrast on ANY picker surface, where bare currentcolor\n glyphs got lost. All decorative: the composed\n aria-label carries the status; chips are aria-hidden. */}\n {StatusIcon && status ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE[STATUS_DISC_TONE[status]]}`}\n >\n <StatusIcon size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {isBookedOnline ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.info}`}\n >\n <Globe size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {hasUnassignedPatient ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.warning}`}\n >\n <TriangleAlert size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {hasHighlightedAnamnesis ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.accent}`}\n >\n <HeartPulse size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {hasBillableAmount ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.warning}`}\n >\n <Euro size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {isTelehealth ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.info}`}\n >\n <Video size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n {isRecurring ? (\n <span\n aria-hidden=\"true\"\n className={`${INDICATOR_DISC_BASE} ${INDICATOR_DISC_TONE.info}`}\n >\n <Repeat size={11} aria-hidden=\"true\" />\n </span>\n ) : null}\n </span>\n </span>\n )}\n {isTask && showTime && !allDay && rangeText ? (\n <span className=\"ds:text-[length:var(--font-size-xs)]\">\n {rangeText}\n </span>\n ) : null}\n {isTask && suffix ? (\n /* Task cards keep the below-row suffix (their branch has no\n text cell / plate split). */\n <span className=\"ds:block ds:truncate ds:text-[length:var(--font-size-xs)]\">\n {suffix}\n </span>\n ) : null}\n </div>\n );\n },\n);\nCalendarEventCard.displayName = 'CalendarEventCard';\n"],"names":["__iconNode","Euro","createLucideIcon","parseHex","hex","trimmed","body","r","g","b","relativeLuminance","lin","c","warnLowContrast","bgHex","fgHex","contextLabel","resolveInk","bg","STATUS_ICON","ThumbsUp","Clock","Stethoscope","Check","Ban","UserX","INDICATOR_DISC_BASE","PENDING_BAR_CLASS","INDICATOR_DISC_TONE","STATUS_DISC_TONE","STATUS_LABEL_KEYS","calendarEventCardVariants","cva","CalendarEventCard","forwardRef","title","suffix","rangeText","showTime","allDay","status","backgroundColor","textColor","borderColor","isBookedOnline","hasUnassignedPatient","hasHighlightedAnamnesis","hasBillableAmount","isTelehealth","isRecurring","isTask","isDraft","detailsPending","colorStyle","resourceLabel","privacyMasked","eventId","className","style","ariaLabelProp","rest","ref","t","useTranslation","StatusIcon","hasIndicators","statusLabel","kindLabel","ariaLabel","kind","tinted","ink","colourOverrides","mergedStyle","jsxs","jsx","ClipboardCheck","EyeOff","Globe","TriangleAlert","HeartPulse","Video","Repeat"],"mappings":"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","x_google_ignoreList":[0]}