@alfadocs/ui-kit-debug 0.25.2 → 0.30.1
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.
- package/dist/_chunks/booking-Bw9eOU4k.js +2292 -0
- package/dist/_chunks/booking-Bw9eOU4k.js.map +1 -0
- package/dist/_chunks/{calendar-9eOXumpH.js → calendar-WWNx448i.js} +10 -9
- package/dist/_chunks/{calendar-9eOXumpH.js.map → calendar-WWNx448i.js.map} +1 -1
- package/dist/_chunks/checkbox-mwbrPZDY.js.map +1 -1
- package/dist/_chunks/{contact-card-CeEfEAxh.js → contact-card-DYbp--s-.js} +2 -2
- package/dist/_chunks/{contact-card-CeEfEAxh.js.map → contact-card-DYbp--s-.js.map} +1 -1
- package/dist/_chunks/{header-B8V_sNPy.js → header-CkMb1TZS.js} +23 -23
- package/dist/_chunks/header-CkMb1TZS.js.map +1 -0
- package/dist/_chunks/heart-pulse-CvuyFKHB.js +21 -0
- package/dist/_chunks/heart-pulse-CvuyFKHB.js.map +1 -0
- package/dist/_chunks/{link-DmM5IevO.js → link-DrD_cRUg.js} +50 -45
- package/dist/_chunks/link-DrD_cRUg.js.map +1 -0
- package/dist/_chunks/parseISO-Dk4xa7q6.js +120 -0
- package/dist/_chunks/parseISO-Dk4xa7q6.js.map +1 -0
- package/dist/_chunks/patient-search-DuSoGG2t.js +1113 -0
- package/dist/_chunks/patient-search-DuSoGG2t.js.map +1 -0
- package/dist/_chunks/{patient-shell-Bq8CjRYF.js → patient-shell-CAXYzbRw.js} +2 -2
- package/dist/_chunks/{patient-shell-Bq8CjRYF.js.map → patient-shell-CAXYzbRw.js.map} +1 -1
- package/dist/_chunks/public-footer.agent-DivkKdG4.js +537 -0
- package/dist/_chunks/public-footer.agent-DivkKdG4.js.map +1 -0
- package/dist/_chunks/reviews-panel-CFttsfuC.js +513 -0
- package/dist/_chunks/reviews-panel-CFttsfuC.js.map +1 -0
- package/dist/_chunks/slot-grid-B2zprPcv.js +387 -0
- package/dist/_chunks/slot-grid-B2zprPcv.js.map +1 -0
- package/dist/_chunks/stethoscope-DT5qCW8Y.js +18 -0
- package/dist/_chunks/stethoscope-DT5qCW8Y.js.map +1 -0
- package/dist/agent-catalog.json +117 -22
- package/dist/components/booking/booking-types.d.ts +167 -0
- package/dist/components/booking/booking-types.d.ts.map +1 -0
- package/dist/components/booking/booking.agent.d.ts +1 -1
- package/dist/components/booking/booking.agent.d.ts.map +1 -1
- package/dist/components/booking/booking.d.ts +4 -89
- package/dist/components/booking/booking.d.ts.map +1 -1
- package/dist/components/booking/cascade.d.ts +96 -0
- package/dist/components/booking/cascade.d.ts.map +1 -0
- package/dist/components/booking/details-form.d.ts +39 -0
- package/dist/components/booking/details-form.d.ts.map +1 -0
- package/dist/components/booking/index.d.ts +2 -1
- package/dist/components/booking/index.d.ts.map +1 -1
- package/dist/components/booking/index.js +5 -3
- package/dist/components/calendar/index.js +1 -1
- package/dist/components/checkbox/checkbox.d.ts +6 -2
- package/dist/components/checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/contact-card/index.js +1 -1
- package/dist/components/header/index.js +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/link/index.js +1 -1
- package/dist/components/link/link.d.ts +7 -0
- package/dist/components/link/link.d.ts.map +1 -1
- package/dist/components/patient-search/index.d.ts +4 -0
- package/dist/components/patient-search/index.d.ts.map +1 -0
- package/dist/components/patient-search/index.js +6 -0
- package/dist/components/patient-search/index.js.map +1 -0
- package/dist/components/patient-search/patient-search.agent.d.ts +4 -0
- package/dist/components/patient-search/patient-search.agent.d.ts.map +1 -0
- package/dist/components/patient-search/patient-search.d.ts +112 -0
- package/dist/components/patient-search/patient-search.d.ts.map +1 -0
- package/dist/components/public-footer/index.d.ts +6 -0
- package/dist/components/public-footer/index.d.ts.map +1 -0
- package/dist/components/public-footer/index.js +10 -0
- package/dist/components/public-footer/index.js.map +1 -0
- package/dist/components/public-footer/legal-urls.d.ts +18 -0
- package/dist/components/public-footer/legal-urls.d.ts.map +1 -0
- package/dist/components/public-footer/public-footer.agent.d.ts +4 -0
- package/dist/components/public-footer/public-footer.agent.d.ts.map +1 -0
- package/dist/components/public-footer/public-footer.d.ts +58 -0
- package/dist/components/public-footer/public-footer.d.ts.map +1 -0
- package/dist/components/public-footer/socials.d.ts +9 -0
- package/dist/components/public-footer/socials.d.ts.map +1 -0
- package/dist/components/reviews-panel/index.d.ts +4 -0
- package/dist/components/reviews-panel/index.d.ts.map +1 -0
- package/dist/components/reviews-panel/index.js +6 -0
- package/dist/components/reviews-panel/index.js.map +1 -0
- package/dist/components/reviews-panel/reviews-panel.agent.d.ts +4 -0
- package/dist/components/reviews-panel/reviews-panel.agent.d.ts.map +1 -0
- package/dist/components/reviews-panel/reviews-panel.d.ts +76 -0
- package/dist/components/reviews-panel/reviews-panel.d.ts.map +1 -0
- package/dist/components/slot-grid/index.js +1 -1
- package/dist/i18n/config.js +3994 -38
- package/dist/i18n/config.js.map +1 -1
- package/dist/i18n/locales/ar.d.ts +221 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/de.d.ts +221 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/el.d.ts +221 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/es.d.ts +221 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/fr.d.ts +221 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/hi.d.ts +221 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/ja.d.ts +221 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/nl.d.ts +221 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.d.ts +221 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pt.d.ts +221 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/ro.d.ts +221 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ru.d.ts +221 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/sq.d.ts +221 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sv.d.ts +221 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/tr.d.ts +221 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/zh.d.ts +221 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/resources.d.ts +442 -0
- package/dist/i18n/resources.d.ts.map +1 -1
- package/dist/index.js +351 -336
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +222 -1
- package/dist/locales/de.json +222 -1
- package/dist/locales/el.json +222 -1
- package/dist/locales/en.json +222 -1
- package/dist/locales/es.json +222 -1
- package/dist/locales/fr.json +222 -1
- package/dist/locales/hi.json +222 -1
- package/dist/locales/it.json +222 -1
- package/dist/locales/ja.json +222 -1
- package/dist/locales/nl.json +222 -1
- package/dist/locales/pl.json +222 -1
- package/dist/locales/pt.json +222 -1
- package/dist/locales/ro.json +222 -1
- package/dist/locales/ru.json +222 -1
- package/dist/locales/sq.json +222 -1
- package/dist/locales/sv.json +222 -1
- package/dist/locales/tr.json +222 -1
- package/dist/locales/zh.json +222 -1
- package/dist/patterns/patient-shell/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +17 -1
- package/dist/_chunks/booking-CXngC-1u.js +0 -1743
- package/dist/_chunks/booking-CXngC-1u.js.map +0 -1
- package/dist/_chunks/header-B8V_sNPy.js.map +0 -1
- package/dist/_chunks/link-DmM5IevO.js.map +0 -1
- package/dist/_chunks/slot-grid-DoodeQGZ.js +0 -502
- package/dist/_chunks/slot-grid-DoodeQGZ.js.map +0 -1
- package/dist/_chunks/stethoscope-B8kpbtjh.js +0 -35
- package/dist/_chunks/stethoscope-B8kpbtjh.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"booking-CXngC-1u.js","sources":["../../node_modules/lucide-react/dist/esm/icons/activity.js","../../node_modules/lucide-react/dist/esm/icons/baby.js","../../node_modules/lucide-react/dist/esm/icons/bone.js","../../node_modules/lucide-react/dist/esm/icons/brain.js","../../node_modules/lucide-react/dist/esm/icons/calendar-range.js","../../node_modules/lucide-react/dist/esm/icons/clipboard-check.js","../../node_modules/lucide-react/dist/esm/icons/ear.js","../../node_modules/lucide-react/dist/esm/icons/microscope.js","../../node_modules/lucide-react/dist/esm/icons/pill.js","../../node_modules/lucide-react/dist/esm/icons/scan-line.js","../../node_modules/lucide-react/dist/esm/icons/scissors.js","../../node_modules/lucide-react/dist/esm/icons/smile.js","../../node_modules/lucide-react/dist/esm/icons/sunset.js","../../node_modules/lucide-react/dist/esm/icons/syringe.js","../../node_modules/date-fns/subMonths.js","../../src/components/booking/booking.agent.ts","../../src/components/booking/booking.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\",\n key: \"169zse\"\n }\n ]\n];\nconst Activity = createLucideIcon(\"activity\", __iconNode);\n\nexport { __iconNode, Activity as default };\n//# sourceMappingURL=activity.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 16c.5.3 1.2.5 2 .5s1.5-.2 2-.5\", key: \"1u7htd\" }],\n [\"path\", { d: \"M15 12h.01\", key: \"1k8ypt\" }],\n [\n \"path\",\n {\n d: \"M19.38 6.813A9 9 0 0 1 20.8 10.2a2 2 0 0 1 0 3.6 9 9 0 0 1-17.6 0 2 2 0 0 1 0-3.6A9 9 0 0 1 12 3c2 0 3.5 1.1 3.5 2.5s-.9 2.5-2 2.5c-.8 0-1.5-.4-1.5-1\",\n key: \"11xh7x\"\n }\n ],\n [\"path\", { d: \"M9 12h.01\", key: \"157uk2\" }]\n];\nconst Baby = createLucideIcon(\"baby\", __iconNode);\n\nexport { __iconNode, Baby as default };\n//# sourceMappingURL=baby.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M17 10c.7-.7 1.69 0 2.5 0a2.5 2.5 0 1 0 0-5 .5.5 0 0 1-.5-.5 2.5 2.5 0 1 0-5 0c0 .81.7 1.8 0 2.5l-7 7c-.7.7-1.69 0-2.5 0a2.5 2.5 0 0 0 0 5c.28 0 .5.22.5.5a2.5 2.5 0 1 0 5 0c0-.81-.7-1.8 0-2.5Z\",\n key: \"w610uw\"\n }\n ]\n];\nconst Bone = createLucideIcon(\"bone\", __iconNode);\n\nexport { __iconNode, Bone as default };\n//# sourceMappingURL=bone.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 18V5\", key: \"adv99a\" }],\n [\"path\", { d: \"M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4\", key: \"1e3is1\" }],\n [\"path\", { d: \"M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5\", key: \"1gqd8o\" }],\n [\"path\", { d: \"M17.997 5.125a4 4 0 0 1 2.526 5.77\", key: \"iwvgf7\" }],\n [\"path\", { d: \"M18 18a4 4 0 0 0 2-7.464\", key: \"efp6ie\" }],\n [\"path\", { d: \"M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517\", key: \"1gq6am\" }],\n [\"path\", { d: \"M6 18a4 4 0 0 1-2-7.464\", key: \"k1g0md\" }],\n [\"path\", { d: \"M6.003 5.125a4 4 0 0 0-2.526 5.77\", key: \"q97ue3\" }]\n];\nconst Brain = createLucideIcon(\"brain\", __iconNode);\n\nexport { __iconNode, Brain as default };\n//# sourceMappingURL=brain.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"4\", rx: \"2\", key: \"1hopcy\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"path\", { d: \"M3 10h18\", key: \"8toen8\" }],\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M17 14h-6\", key: \"bkmgh3\" }],\n [\"path\", { d: \"M13 18H7\", key: \"bb0bb7\" }],\n [\"path\", { d: \"M7 14h.01\", key: \"1qa3f1\" }],\n [\"path\", { d: \"M17 18h.01\", key: \"1bdyru\" }]\n];\nconst CalendarRange = createLucideIcon(\"calendar-range\", __iconNode);\n\nexport { __iconNode, CalendarRange as default };\n//# sourceMappingURL=calendar-range.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"8\", height: \"4\", x: \"8\", y: \"2\", rx: \"1\", ry: \"1\", key: \"tgr4d6\" }],\n [\n \"path\",\n {\n d: \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\",\n key: \"116196\"\n }\n ],\n [\"path\", { d: \"m9 14 2 2 4-4\", key: \"df797q\" }]\n];\nconst ClipboardCheck = createLucideIcon(\"clipboard-check\", __iconNode);\n\nexport { __iconNode, ClipboardCheck as default };\n//# sourceMappingURL=clipboard-check.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M6 8.5a6.5 6.5 0 1 1 13 0c0 6-6 6-6 10a3.5 3.5 0 1 1-7 0\", key: \"1dfaln\" }],\n [\"path\", { d: \"M15 8.5a2.5 2.5 0 0 0-5 0v1a2 2 0 1 1 0 4\", key: \"1qnva7\" }]\n];\nconst Ear = createLucideIcon(\"ear\", __iconNode);\n\nexport { __iconNode, Ear as default };\n//# sourceMappingURL=ear.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M6 18h8\", key: \"1borvv\" }],\n [\"path\", { d: \"M3 22h18\", key: \"8prr45\" }],\n [\"path\", { d: \"M14 22a7 7 0 1 0 0-14h-1\", key: \"1jwaiy\" }],\n [\"path\", { d: \"M9 14h2\", key: \"197e7h\" }],\n [\"path\", { d: \"M9 12a2 2 0 0 1-2-2V6h6v4a2 2 0 0 1-2 2Z\", key: \"1bmzmy\" }],\n [\"path\", { d: \"M12 6V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3\", key: \"1drr47\" }]\n];\nconst Microscope = createLucideIcon(\"microscope\", __iconNode);\n\nexport { __iconNode, Microscope as default };\n//# sourceMappingURL=microscope.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"m10.5 20.5 10-10a4.95 4.95 0 1 0-7-7l-10 10a4.95 4.95 0 1 0 7 7Z\", key: \"wa1lgi\" }\n ],\n [\"path\", { d: \"m8.5 8.5 7 7\", key: \"rvfmvr\" }]\n];\nconst Pill = createLucideIcon(\"pill\", __iconNode);\n\nexport { __iconNode, Pill as default };\n//# sourceMappingURL=pill.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 7V5a2 2 0 0 1 2-2h2\", key: \"aa7l1z\" }],\n [\"path\", { d: \"M17 3h2a2 2 0 0 1 2 2v2\", key: \"4qcy5o\" }],\n [\"path\", { d: \"M21 17v2a2 2 0 0 1-2 2h-2\", key: \"6vwrx8\" }],\n [\"path\", { d: \"M7 21H5a2 2 0 0 1-2-2v-2\", key: \"ioqczr\" }],\n [\"path\", { d: \"M7 12h10\", key: \"b7w52i\" }]\n];\nconst ScanLine = createLucideIcon(\"scan-line\", __iconNode);\n\nexport { __iconNode, ScanLine as default };\n//# sourceMappingURL=scan-line.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n];\nconst Scissors = createLucideIcon(\"scissors\", __iconNode);\n\nexport { __iconNode, Scissors as default };\n//# sourceMappingURL=scissors.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M8 14s1.5 2 4 2 4-2 4-2\", key: \"1y1vjs\" }],\n [\"line\", { x1: \"9\", x2: \"9.01\", y1: \"9\", y2: \"9\", key: \"yxxnd0\" }],\n [\"line\", { x1: \"15\", x2: \"15.01\", y1: \"9\", y2: \"9\", key: \"1p4y9e\" }]\n];\nconst Smile = createLucideIcon(\"smile\", __iconNode);\n\nexport { __iconNode, Smile as default };\n//# sourceMappingURL=smile.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 10V2\", key: \"16sf7g\" }],\n [\"path\", { d: \"m4.93 10.93 1.41 1.41\", key: \"2a7f42\" }],\n [\"path\", { d: \"M2 18h2\", key: \"j10viu\" }],\n [\"path\", { d: \"M20 18h2\", key: \"wocana\" }],\n [\"path\", { d: \"m19.07 10.93-1.41 1.41\", key: \"15zs5n\" }],\n [\"path\", { d: \"M22 22H2\", key: \"19qnx5\" }],\n [\"path\", { d: \"m16 6-4 4-4-4\", key: \"6wukr\" }],\n [\"path\", { d: \"M16 18a4 4 0 0 0-8 0\", key: \"1lzouq\" }]\n];\nconst Sunset = createLucideIcon(\"sunset\", __iconNode);\n\nexport { __iconNode, Sunset as default };\n//# sourceMappingURL=sunset.js.map\n","/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m18 2 4 4\", key: \"22kx64\" }],\n [\"path\", { d: \"m17 7 3-3\", key: \"1w1zoj\" }],\n [\"path\", { d: \"M19 9 8.7 19.3c-1 1-2.5 1-3.4 0l-.6-.6c-1-1-1-2.5 0-3.4L15 5\", key: \"1exhtz\" }],\n [\"path\", { d: \"m9 11 4 4\", key: \"rovt3i\" }],\n [\"path\", { d: \"m5 19-3 3\", key: \"59f2uf\" }],\n [\"path\", { d: \"m14 4 6 6\", key: \"yqp9t2\" }]\n];\nconst Syringe = createLucideIcon(\"syringe\", __iconNode);\n\nexport { __iconNode, Syringe as default };\n//# sourceMappingURL=syringe.js.map\n","import { addMonths } from \"./addMonths.js\";\n\n/**\n * The subMonths function options.\n */\n\n/**\n * @name subMonths\n * @category Month Helpers\n * @summary Subtract the specified number of months from the given date.\n *\n * @description\n * Subtract the specified number of months from the given date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The date to be changed\n * @param amount - The amount of months to be subtracted.\n * @param options - An object with options\n *\n * @returns The new date with the months subtracted\n *\n * @example\n * // Subtract 5 months from 1 February 2015:\n * const result = subMonths(new Date(2015, 1, 1), 5)\n * //=> Mon Sep 01 2014 00:00:00\n */\nexport function subMonths(date, amount, options) {\n return addMonths(date, -amount, options);\n}\n\n// Fallback for modularized imports:\nexport default subMonths;\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — Booking. */\n/* */\n/* The Booking component consolidates appointment-booking variants into */\n/* a single component. The adapter exposes step navigation and the */\n/* active variant so a host agent can drive any of the five layouts */\n/* (`inline-list`, `accordion`, `calendar`, `flexible`, `progress`). */\n/* The booking value itself is owned by the consumer and flows through */\n/* the `value` / `onChange` contract — never read here. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { BookingHandle } from './booking';\n\nexport const bookingAgent: AgentAdapter<BookingHandle> = {\n id: 'booking',\n capabilities: ['navigate', 'view_change'],\n state: {\n currentStep: {\n type: 'number',\n descriptionKey: 'ui.agent.booking.state.currentStep',\n description:\n 'Zero-indexed active step within the active variant. Variants with no step machine report 0.',\n read: (handle) => handle.getCurrentStep(),\n },\n totalSteps: {\n type: 'number',\n descriptionKey: 'ui.agent.booking.state.totalSteps',\n description:\n 'Total number of steps in the active variant. Single-screen variants report 1.',\n read: (handle) => handle.getTotalSteps(),\n },\n variant: {\n type: 'string',\n descriptionKey: 'ui.agent.booking.state.variant',\n description:\n 'Active variant — one of `inline-list`, `accordion`, `calendar`, `flexible`, `progress`.',\n read: (handle) => handle.getVariant(),\n },\n },\n actions: {\n goto_step: {\n safety: 'read',\n argsType: '{ step: number }',\n descriptionKey: 'ui.agent.booking.actions.gotoStep',\n description:\n 'Jump to the given step within the active variant. Steps beyond first-incomplete are gated internally.',\n invoke: (handle, args: { step: number }) => {\n handle.gotoStep(args.step);\n },\n },\n next: {\n safety: 'read',\n descriptionKey: 'ui.agent.booking.actions.next',\n description:\n 'Advance to the next step when the current step has a valid value.',\n invoke: (handle) => {\n handle.next();\n },\n },\n previous: {\n safety: 'read',\n descriptionKey: 'ui.agent.booking.actions.previous',\n description: 'Return to the previous step.',\n invoke: (handle) => {\n handle.previous();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'booking',\n description: 'Marks the Booking root region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n Activity,\n Baby,\n Bone,\n Brain,\n CalendarRange,\n ChevronLeft,\n ChevronRight,\n ClipboardCheck,\n Ear,\n Eye,\n HeartPulse,\n Microscope,\n Moon,\n Pill,\n ScanLine,\n Scissors,\n Search,\n Smile,\n Sparkles,\n Stethoscope,\n Sun,\n Sunset,\n Syringe,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n addMonths,\n endOfMonth,\n format as fnsFormat,\n isSameDay,\n isSameMonth,\n parseISO,\n startOfMonth,\n subMonths,\n} from 'date-fns';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { bookingAgent } from './booking.agent';\nimport { Button } from '../button/button';\nimport { IconButton } from '../button/icon-button';\nimport { TextInput } from '../text-input/text-input';\nimport {\n SuggestionChip,\n SuggestionChipGroup,\n} from '../suggestion-chip/suggestion-chip';\nimport { Select, type SelectOption } from '../select/select';\nimport { Autocomplete } from '../autocomplete/autocomplete';\nimport {\n DateRangePicker,\n type DateRangeValue,\n} from '../date-range-picker/date-range-picker';\nimport {\n SlotGrid,\n type SlotGridDay,\n type SlotGridSlot,\n} from '../slot-grid/slot-grid';\nimport {\n StepperAccordion,\n type AccordionStepSpec,\n} from '../stepper-accordion/stepper-accordion';\nimport { StepperProgress } from '../stepper-progress/stepper-progress';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { Skeleton } from '../skeleton/skeleton';\n\n/* -------------------------------------------------------------------- */\n/* Booking */\n/* */\n/* High-level domain widget that consolidates the five appointment- */\n/* booking layouts a consumer might want to A/B test on a single */\n/* practice page. A single `variant` prop drives the layout — every */\n/* variant honours the same `value` / `onChange` contract and the same */\n/* composition slots (`filtersSlot`, `detailsSlot`, `ctaSlot`). */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\nexport type BookingVariant =\n | 'inline-list'\n | 'accordion'\n | 'calendar'\n | 'flexible'\n | 'progress';\n\n/** Service offering rendered in the service selector of every variant. */\nexport interface BookingService {\n id: string;\n /** Already-translated label (consumer owns data i18n). */\n label: string;\n /** Duration in minutes — shown alongside the label. */\n durationMin: number;\n /** Optional secondary line, e.g. \"Prima visita o consulto\". */\n description?: string;\n /** Optional price token — already formatted by the consumer. */\n price?: string;\n /** Optional payment hint — \"Paga in studio\" / \"Paga online\". */\n paymentHint?: string;\n /** Optional specialty id used to filter when a specialty chip is active. */\n specialtyId?: string;\n /** Optional icon — defaults to a stethoscope glyph. */\n icon?: ReactNode;\n}\n\n/** Specialty chip rendered above the service list in `inline-list`. */\nexport interface BookingSpecialty {\n id: string;\n label: string;\n /**\n * Optional icon override. When omitted, a keyword-based heuristic picks\n * an icon from the specialty's label (cardio → HeartPulse, derma →\n * Sparkles, etc.) and renders it in the accent colour.\n */\n icon?: ReactNode;\n}\n\n/** One slot in an `availableSlots[date]` array. */\nexport interface BookingSlot {\n /** Stable key — consumer-defined. Opaque to the component. */\n key: string;\n /** HH:mm 24h. */\n time: string;\n available: boolean;\n /** Optional tooltip explaining a disabled slot. */\n unavailableReason?: string;\n}\n\n/** Booking selection — controlled by the consumer. */\nexport interface BookingValue {\n serviceId?: string;\n specialtyId?: string;\n /** ISO yyyy-mm-dd. */\n date?: string;\n /** HH:mm 24h. */\n time?: string;\n /** Slot lookup key — opaque to the component; passed through to onSubmit. */\n slotKey?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Root variants */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n 'ds:flex ds:w-full ds:flex-col ds:text-[var(--foreground)]',\n {\n variants: {\n variant: {\n 'inline-list': 'ds:gap-[var(--spacing-md)]',\n accordion: 'ds:gap-[var(--spacing-md)]',\n calendar: 'ds:gap-[var(--spacing-md)]',\n flexible: 'ds:gap-[var(--spacing-lg)]',\n progress: 'ds:gap-[var(--spacing-sm)]',\n },\n },\n defaultVariants: {\n variant: 'inline-list',\n },\n },\n);\n\n/* -------------------------------------------------------------------- */\n/* Public props */\n/* -------------------------------------------------------------------- */\n\nexport interface BookingProps\n extends\n Omit<\n ComponentPropsWithoutRef<'div'>,\n 'aria-label' | 'onChange' | 'onSubmit'\n >,\n VariantProps<typeof rootVariants> {\n services: BookingService[];\n /** Optional — hides the specialty chip row when absent. */\n specialties?: BookingSpecialty[];\n availableDates: string[];\n availableSlots: Record<string, BookingSlot[]>;\n value: BookingValue;\n onChange: (next: BookingValue) => void;\n onSubmit?: (value: BookingValue) => void;\n\n /** Optional pre-filter slot rendered above the variant body. */\n filtersSlot?: ReactNode;\n /** Optional details/contact form rendered after the slot pick. */\n detailsSlot?: ReactNode;\n /** Optional sticky CTA strip below the body. */\n ctaSlot?: ReactNode;\n /** Header content. `null` omits the header. Defaults to variant title + subtitle. */\n heading?: ReactNode;\n\n loadingDates?: boolean;\n loadingSlots?: boolean;\n\n /** Override aria-label on the root region. */\n 'aria-label'?: string;\n\n /** Agent-readiness instance id. */\n id?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Imperative handle */\n/* -------------------------------------------------------------------- */\n\nexport interface BookingHandle {\n getCurrentStep: () => number;\n getTotalSteps: () => number;\n gotoStep: (step: number) => void;\n next: () => void;\n previous: () => void;\n getVariant: () => BookingVariant;\n}\n\n/* -------------------------------------------------------------------- */\n/* Icon inference */\n/* */\n/* Service cards and specialty chips both want a glyph but a consumer */\n/* rarely provides one. We pick from a small keyword-driven table so the */\n/* output feels intentional out of the box — \"Cardiologia\" → HeartPulse, */\n/* \"Pulizia\" → Smile, \"Risonanza\" → ScanLine, etc. Consumers can always */\n/* override via `BookingService.icon` / `BookingSpecialty.icon`. */\n/* -------------------------------------------------------------------- */\n\ntype IconRule = readonly [RegExp, LucideIcon];\n\n// Order matters — more-specific patterns come first so they win the\n// `pickIcon` walk. \"Medicina estetica\" must match Syringe before the\n// generic \"medic\" rule would map it to Activity.\n//\n// Patterns use a LEADING `\\b` so a stem only matches at a word start\n// (we don't want \"subdermal\" to trigger the derma rule), but NO trailing\n// boundary — Italian medical labels grow long suffixes (\"Odontoiatria\",\n// \"Cardiologia\", \"Dermatologia\", \"Medicina\"), and `\\bodonto\\b` would\n// reject all of them.\nconst SERVICE_ICON_RULES: readonly IconRule[] = [\n // Aesthetic medicine (filler / botox / mesotherapy) — needle imagery is\n // the cross-cultural shorthand. Comes before the dermatology rule so\n // \"medicina estetica\" doesn't get pulled into the skin family.\n [\n /\\b(estetic|aesthetic|botox|filler|mesoterap|chirurgia\\s*plastic)/i,\n Syringe,\n ],\n [/\\b(cardio|ecg|elettrocardio|ecocardio|cuore|heart)/i, HeartPulse],\n [/\\b(dent|odonto|tooth|teeth|pulizia|igien|smile)/i, Smile],\n [/\\b(oftalmo|ocul|ophthal|vision|occhi|eye)/i, Eye],\n [/\\b(otorin|udito|orecchi|hearing|ear)/i, Ear],\n [/\\b(neuro|brain|cervello)/i, Brain],\n [/\\b(pediatr|child|bambin)/i, Baby],\n [/\\b(ortop|ortho|osteo|skeleton|ossa|bone)/i, Bone],\n [/\\b(lab|analis|test|sang|esami)/i, Microscope],\n [/\\b(farmaco|pharm|pillol|refill)/i, Pill],\n [/\\b(chirurg|surg|intervent|operat)/i, Scissors],\n [/\\b(scan|rx|x-?ray|raggi|imag|radio|risonan|ecograf|ultras)/i, ScanLine],\n [/\\b(vacc|inject|inie|punto)/i, Syringe],\n // Medical dermatology — separate from aesthetic, picked up later.\n [/\\b(derma|skin|pelle)/i, Sparkles],\n [/\\b(prima\\s*visit|first\\s*visit|consult|consulto|valutaz)/i, ClipboardCheck],\n [/\\b(general|medicin|family|control|check[-\\s]?up)/i, Activity],\n];\n\nconst SPECIALTY_ICON_RULES: readonly IconRule[] = SERVICE_ICON_RULES;\n\nfunction pickIcon(text: string, rules: readonly IconRule[]): LucideIcon | null {\n for (const [pattern, Icon] of rules) {\n if (pattern.test(text)) return Icon;\n }\n return null;\n}\n\nfunction inferServiceIcon(service: BookingService): ReactNode {\n if (service.icon) return service.icon;\n const haystack = `${service.label} ${service.description ?? ''}`;\n const Icon = pickIcon(haystack, SERVICE_ICON_RULES) ?? Stethoscope;\n return <Icon aria-hidden=\"true\" className=\"ds:size-5\" />;\n}\n\nfunction inferSpecialtyIcon(specialty: BookingSpecialty): ReactNode {\n if (specialty.icon) return specialty.icon;\n const Icon = pickIcon(specialty.label, SPECIALTY_ICON_RULES) ?? Sparkles;\n return (\n <Icon\n aria-hidden=\"true\"\n className=\"ds:size-3.5 ds:text-[color:var(--accent)]\"\n />\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Shared helpers */\n/* -------------------------------------------------------------------- */\n\nfunction isoOf(date: Date): string {\n return fnsFormat(date, 'yyyy-MM-dd');\n}\n\n/** Total step count per variant — drives the imperative handle. */\nconst TOTAL_STEPS: Record<BookingVariant, number> = {\n 'inline-list': 4, // service, date, time, details\n accordion: 3, // service, date+time, confirm\n calendar: 2, // service, confirm\n flexible: 2, // service+date-range, confirm\n progress: 3, // service, date+time, confirm\n};\n\nfunction deriveCurrentStep(\n variant: BookingVariant,\n value: BookingValue,\n): number {\n // For each variant, walk the value fields in order and return the\n // index of the first unfilled requirement. This stays in sync with\n // the visual flow because it derives from the controlled selection.\n switch (variant) {\n case 'inline-list':\n if (!value.serviceId) return 0;\n if (!value.date) return 1;\n if (!value.time) return 2;\n return 3;\n case 'accordion':\n if (!value.serviceId) return 0;\n if (!value.date || !value.time) return 1;\n return 2;\n case 'calendar':\n if (!value.serviceId) return 0;\n if (!value.date || !value.time) return 0;\n return 1;\n case 'flexible':\n if (!value.serviceId) return 0;\n return 1;\n case 'progress':\n if (!value.serviceId) return 0;\n if (!value.date || !value.time) return 1;\n return 2;\n /* c8 ignore next */\n default:\n return 0;\n }\n}\n\n/* -------------------------------------------------------------------- */\n/* MonthGrid — inline 6×7 day grid with roving tabindex */\n/* -------------------------------------------------------------------- */\n\ninterface MonthGridProps {\n /** ISO date strings considered \"available\". */\n availableDates: string[];\n /** Selected ISO date — drives `aria-selected`. */\n selectedDate?: string;\n /** Fires when the user picks a day. */\n onSelectDate: (iso: string) => void;\n /** Locale for `Intl.DateTimeFormat` formatting. */\n locale: string;\n /** Skeleton mode. */\n loading?: boolean;\n}\n\nconst monthCellBase = [\n 'ds:relative ds:flex ds:items-center ds:justify-center',\n 'ds:min-h-[var(--min-target-size)] ds:min-w-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[length:var(--font-size-sm)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\nconst monthCellVariants = cva(monthCellBase, {\n variants: {\n state: {\n available:\n 'ds:cursor-pointer ds:text-[var(--foreground)] ds:hover:bg-[var(--muted)]/30',\n unavailable: 'ds:cursor-not-allowed ds:text-[var(--muted-foreground)]/60',\n selected:\n 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)] ds:font-[var(--font-weight-semibold)]',\n outside: 'ds:text-[var(--muted-foreground)]/40',\n },\n },\n defaultVariants: { state: 'unavailable' },\n});\n\nfunction MonthGrid({\n availableDates,\n selectedDate,\n onSelectDate,\n locale,\n loading,\n}: MonthGridProps) {\n const { t } = useTranslation();\n\n const initialMonth = useMemo<Date>(() => {\n if (selectedDate) return startOfMonth(parseISO(selectedDate));\n if (availableDates.length > 0) {\n return startOfMonth(parseISO(availableDates[0]));\n }\n return startOfMonth(new Date());\n }, [selectedDate, availableDates]);\n\n const [viewMonth, setViewMonth] = useState<Date>(initialMonth);\n const [focusDate, setFocusDate] = useState<Date | null>(null);\n\n // Build a 6-week grid that starts on Sunday and covers the whole month.\n // We do this manually so the cell layout is deterministic across locales\n // (avoids the case where a buggy Intl polyfill flips firstDayOfWeek).\n const cells = useMemo(() => {\n const monthStart = startOfMonth(viewMonth);\n const monthEnd = endOfMonth(viewMonth);\n const startWeekday = monthStart.getDay(); // 0 = Sunday\n const totalDays = monthEnd.getDate();\n const grid: Date[] = [];\n // Leading days from previous month\n for (let i = startWeekday; i > 0; i -= 1) {\n const d = new Date(monthStart);\n d.setDate(monthStart.getDate() - i);\n grid.push(d);\n }\n // Current month\n for (let i = 0; i < totalDays; i += 1) {\n const d = new Date(monthStart);\n d.setDate(monthStart.getDate() + i);\n grid.push(d);\n }\n // Trailing days to fill 42-cell grid\n while (grid.length < 42) {\n const last = grid[grid.length - 1];\n const d = new Date(last);\n d.setDate(last.getDate() + 1);\n grid.push(d);\n }\n return grid;\n }, [viewMonth]);\n\n const monthLabel = useMemo(() => {\n try {\n return new Intl.DateTimeFormat(locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth);\n } catch {\n return fnsFormat(viewMonth, 'MMMM yyyy');\n }\n }, [viewMonth, locale]);\n\n // Weekday labels (Sun–Sat) — localised via Intl.\n const weekdayLabels = useMemo(() => {\n const base = new Date(2024, 0, 7); // 2024-01-07 is a Sunday\n return Array.from({ length: 7 }, (_, i) => {\n const d = new Date(base);\n d.setDate(base.getDate() + i);\n try {\n return new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(d);\n } catch {\n return fnsFormat(d, 'EEE');\n }\n });\n }, [locale]);\n\n const availableSet = useMemo(() => new Set(availableDates), [availableDates]);\n\n const isAvailable = useCallback(\n (date: Date) => availableSet.has(isoOf(date)),\n [availableSet],\n );\n\n // Active cell for roving tabindex — selected day, then first available,\n // then today.\n const rovingDate = useMemo<Date | null>(() => {\n if (focusDate) return focusDate;\n if (selectedDate) return parseISO(selectedDate);\n const firstAvailable = cells.find(\n (d) => isSameMonth(d, viewMonth) && isAvailable(d),\n );\n if (firstAvailable) return firstAvailable;\n return cells.find((d) => isSameMonth(d, viewMonth)) ?? null;\n }, [focusDate, selectedDate, cells, viewMonth, isAvailable]);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, current: Date) => {\n let next: Date | null = null;\n switch (event.key) {\n case 'ArrowLeft':\n next = new Date(current);\n next.setDate(current.getDate() - 1);\n break;\n case 'ArrowRight':\n next = new Date(current);\n next.setDate(current.getDate() + 1);\n break;\n case 'ArrowUp':\n next = new Date(current);\n next.setDate(current.getDate() - 7);\n break;\n case 'ArrowDown':\n next = new Date(current);\n next.setDate(current.getDate() + 7);\n break;\n case 'Home':\n next = new Date(current);\n next.setDate(current.getDate() - current.getDay());\n break;\n case 'End':\n next = new Date(current);\n next.setDate(current.getDate() + (6 - current.getDay()));\n break;\n case 'Enter':\n case ' ': {\n event.preventDefault();\n if (isAvailable(current)) onSelectDate(isoOf(current));\n return;\n }\n default:\n return;\n }\n if (!next) return;\n event.preventDefault();\n if (!isSameMonth(next, viewMonth)) {\n setViewMonth(startOfMonth(next));\n }\n setFocusDate(next);\n },\n [isAvailable, onSelectDate, viewMonth],\n );\n\n if (loading) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={t('common.loading')}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n <Skeleton variant=\"text\" width=\"40%\" />\n <div className=\"ds:grid ds:grid-cols-7 ds:gap-[var(--spacing-2xs)]\">\n {Array.from({ length: 42 }, (_, i) => (\n <Skeleton key={`mg-skel-${i}`} variant=\"rounded\" height=\"2.5rem\" />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n // The accessible name lives on the inner `role=\"grid\"` further down\n // (see line ~610 below). Don't add `role=\"group\"` here — Note 14 from\n // the a11y review: the outer `group` is redundant with the inner\n // `grid` and adds noise to AT linearisation.\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <IconButton\n icon={<ChevronLeft />}\n aria-label={t('booking.previousMonth')}\n size=\"sm\"\n intent=\"ghost\"\n flipIconInRtl\n onClick={() => {\n setViewMonth((m) => subMonths(m, 1));\n setFocusDate(null);\n }}\n />\n <span\n className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)]\"\n aria-live=\"polite\"\n >\n {monthLabel}\n </span>\n <IconButton\n icon={<ChevronRight />}\n aria-label={t('booking.nextMonth')}\n size=\"sm\"\n intent=\"ghost\"\n flipIconInRtl\n onClick={() => {\n setViewMonth((m) => addMonths(m, 1));\n setFocusDate(null);\n }}\n />\n </div>\n <div\n role=\"grid\"\n aria-label={t('booking.monthGridLabel')}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <div\n role=\"row\"\n className=\"ds:grid ds:grid-cols-7 ds:gap-[var(--spacing-2xs)]\"\n >\n {weekdayLabels.map((label, i) => (\n <div\n key={`wd-${i}`}\n role=\"columnheader\"\n className=\"type-meta ds:text-center ds:text-[var(--muted-foreground)] ds:font-[var(--font-weight-medium)]\"\n >\n {label}\n </div>\n ))}\n </div>\n {Array.from({ length: 6 }, (_, rowIndex) => (\n <div\n key={`mg-row-${rowIndex}`}\n role=\"row\"\n className=\"ds:grid ds:grid-cols-7 ds:gap-[var(--spacing-2xs)]\"\n >\n {cells\n .slice(rowIndex * 7, rowIndex * 7 + 7)\n .map((date, colIndex) => {\n const i = rowIndex * 7 + colIndex;\n const inMonth = isSameMonth(date, viewMonth);\n const available = inMonth && isAvailable(date);\n const isSelected = selectedDate\n ? isSameDay(date, parseISO(selectedDate))\n : false;\n const state:\n | 'available'\n | 'unavailable'\n | 'selected'\n | 'outside' = !inMonth\n ? 'outside'\n : isSelected\n ? 'selected'\n : available\n ? 'available'\n : 'unavailable';\n const isRoving = rovingDate\n ? isSameDay(rovingDate, date)\n : false;\n const dayLabel = (() => {\n try {\n return new Intl.DateTimeFormat(locale, {\n dateStyle: 'full',\n }).format(date);\n } catch {\n return fnsFormat(date, 'PPP');\n }\n })();\n return (\n <button\n key={`mg-cell-${i}`}\n type=\"button\"\n role=\"gridcell\"\n aria-label={dayLabel}\n aria-selected={isSelected || undefined}\n aria-disabled={!available || undefined}\n tabIndex={isRoving ? 0 : -1}\n disabled={!available}\n onClick={() => {\n if (available) onSelectDate(isoOf(date));\n }}\n onKeyDown={(e) => handleKeyDown(e, date)}\n className={monthCellVariants({ state })}\n >\n <span aria-hidden=\"true\">{date.getDate()}</span>\n </button>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* ServiceGrid — radiogroup with roving tabindex, full-card click target */\n/* -------------------------------------------------------------------- */\n\ninterface ServiceGridProps {\n services: BookingService[];\n selectedServiceId?: string;\n onSelectService: (id: string) => void;\n}\n\nconst serviceCardVariants = cva(\n [\n 'ds:relative ds:flex ds:w-full ds:items-center ds:gap-[var(--spacing-md)]',\n // Explicit floor — composition tends to give us enough vertical space\n // via the icon + label + meta stack, but a service card with a short\n // label and no description shouldn't dip below the 44/48 target size.\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-md)] ds:border',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]',\n 'ds:text-start',\n 'ds:transition-[background-color,border-color]',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:cursor-pointer',\n ].join(' '),\n {\n variants: {\n state: {\n idle: 'ds:border-[var(--border)] ds:bg-[var(--card)] ds:hover:border-[var(--primary)]/40',\n selected:\n 'ds:border-[var(--primary)] ds:bg-[var(--primary)]/5 ds:shadow-[var(--shadow-sm)]',\n },\n },\n defaultVariants: { state: 'idle' },\n },\n);\n\n// ServiceGrid is a hand-rolled radiogroup, NOT Radix `RadioGroup`. The\n// PRS §05 Radix-first rule lists `RadioGroup` as a Radix-covered surface,\n// but Radix's RadioGroup wraps each option in a small circle indicator +\n// label — it doesn't expose the slots we need to render a full-card click\n// target (icon · label · duration · description · price · payment hint).\n// Re-implementing the full-card layout on top of Radix would still need\n// us to recreate the roving-tabindex (Radix RadioGroup uses a single\n// tabstop per group anyway), so a hand-rolled radiogroup is the lighter\n// surface here. Keyboard contract follows WAI-ARIA radiogroup: arrow keys\n// move focus + selection, Home / End jump to the ends, Enter / Space\n// confirm. Tested in `booking.test.tsx`.\nfunction ServiceGrid({\n services,\n selectedServiceId,\n onSelectService,\n}: ServiceGridProps) {\n const { t } = useTranslation();\n const groupId = useId();\n\n const [focusIndex, setFocusIndex] = useState<number>(() => {\n if (selectedServiceId) {\n const i = services.findIndex((s) => s.id === selectedServiceId);\n if (i >= 0) return i;\n }\n return 0;\n });\n\n // Refs for each card so we can focus on arrow navigation.\n const cardRefs = useRef<Map<number, HTMLButtonElement>>(new Map());\n\n const focusAt = useCallback((index: number) => {\n const node = cardRefs.current.get(index);\n if (node) node.focus();\n }, []);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, index: number, id: string) => {\n const total = services.length;\n if (total === 0) return;\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowRight': {\n event.preventDefault();\n const next = (index + 1) % total;\n setFocusIndex(next);\n focusAt(next);\n break;\n }\n case 'ArrowUp':\n case 'ArrowLeft': {\n event.preventDefault();\n const prev = (index - 1 + total) % total;\n setFocusIndex(prev);\n focusAt(prev);\n break;\n }\n case 'Home': {\n event.preventDefault();\n setFocusIndex(0);\n focusAt(0);\n break;\n }\n case 'End': {\n event.preventDefault();\n const last = total - 1;\n setFocusIndex(last);\n focusAt(last);\n break;\n }\n case 'Enter':\n case ' ': {\n event.preventDefault();\n onSelectService(id);\n break;\n }\n default:\n break;\n }\n },\n [services.length, focusAt, onSelectService],\n );\n\n if (services.length === 0) {\n return (\n <EmptyState\n variant=\"no-results\"\n title={t('emptyState.noResults.title')}\n description={t('emptyState.noResults.description')}\n />\n );\n }\n\n return (\n <div\n role=\"radiogroup\"\n aria-label={t('booking.serviceListLabel')}\n id={groupId}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n {services.map((service, index) => {\n const isSelected = selectedServiceId === service.id;\n const isFocused = focusIndex === index;\n const tabIndex = isFocused ? 0 : -1;\n const ariaLabel = t('booking.serviceCardLabel', {\n label: service.label,\n duration: service.durationMin,\n });\n const iconNode = inferServiceIcon(service);\n return (\n <button\n key={service.id}\n ref={(node) => {\n if (node) cardRefs.current.set(index, node);\n else cardRefs.current.delete(index);\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n aria-label={ariaLabel}\n tabIndex={tabIndex}\n onClick={() => onSelectService(service.id)}\n onFocus={() => setFocusIndex(index)}\n onKeyDown={(e) => handleKeyDown(e, index, service.id)}\n className={serviceCardVariants({\n state: isSelected ? 'selected' : 'idle',\n })}\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:flex ds:size-10 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-sm)] ds:bg-[var(--primary)]/10 ds:text-[var(--primary)]\"\n >\n {iconNode}\n </span>\n <span className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <span className=\"ds:flex ds:flex-wrap ds:items-baseline ds:gap-[var(--spacing-sm)]\">\n <span className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)]\">\n {service.label}\n </span>\n <span className=\"type-meta ds:text-[var(--muted-foreground)]\">\n {t('booking.serviceSummary', {\n minutes: service.durationMin,\n })}\n </span>\n </span>\n {service.description ? (\n <span className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {service.description}\n </span>\n ) : null}\n </span>\n <span className=\"ds:flex ds:shrink-0 ds:flex-col ds:items-end ds:gap-[var(--spacing-2xs)]\">\n {service.price ? (\n <span className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)]\">\n {service.price}\n </span>\n ) : null}\n {service.paymentHint ? (\n <span className=\"type-meta ds:text-[var(--muted-foreground)]\">\n {service.paymentHint}\n </span>\n ) : null}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Internal variant-body props */\n/* -------------------------------------------------------------------- */\n\ninterface VariantBodyProps {\n services: BookingService[];\n specialties: BookingSpecialty[];\n availableDates: string[];\n availableSlots: Record<string, BookingSlot[]>;\n value: BookingValue;\n onChange: (next: BookingValue) => void;\n onSubmit?: (value: BookingValue) => void;\n detailsSlot?: ReactNode;\n loadingDates?: boolean;\n loadingSlots?: boolean;\n locale: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Selection helpers */\n/* -------------------------------------------------------------------- */\n\nfunction buildSlotGridDay(isoDate: string, slots: BookingSlot[]): SlotGridDay {\n const date = parseISO(isoDate);\n return {\n date,\n slots: slots.map<SlotGridSlot>((s) => {\n // Compose a real Date for the slot from the day + HH:mm so Intl can\n // format it consistently. We don't expose a date-only path.\n const [hh, mm] = s.time.split(':').map((x) => parseInt(x, 10));\n const start = new Date(date);\n start.setHours(hh ?? 0, mm ?? 0, 0, 0);\n return {\n id: s.key,\n start,\n available: s.available,\n label: s.time,\n };\n }),\n };\n}\n\n/* -------------------------------------------------------------------- */\n/* GroupedTimeSlots */\n/* */\n/* Richer drop-in for the calendar variant's slot column: shows the */\n/* selected date as a heading, groups slots by morning / afternoon / */\n/* evening with a Sun / Sunset / Moon glyph, and renders each slot as a */\n/* tappable chip. Falls back to a friendly empty state when no slots */\n/* match the day. */\n/* -------------------------------------------------------------------- */\n\nconst slotChipVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center ds:gap-[var(--spacing-2xs)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-2xs)] ds:pb-[var(--spacing-2xs)]',\n 'ds:rounded-[var(--radius-md)] ds:border',\n 'ds:text-[length:var(--font-size-sm)] ds:font-[var(--font-weight-medium)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:disabled:cursor-not-allowed ds:disabled:opacity-50',\n 'ds:forced-colors:border-[ButtonText] ds:forced-colors:text-[ButtonText]',\n ].join(' '),\n {\n variants: {\n state: {\n idle: 'ds:border-[color:var(--border)] ds:bg-[color:var(--background)] ds:text-[color:var(--foreground)] ds:hover:enabled:bg-[color:var(--muted)]/40',\n selected:\n 'ds:border-[color:var(--primary)] ds:bg-[color:var(--primary)] ds:text-[color:var(--primary-foreground)]',\n unavailable:\n 'ds:border-dashed ds:border-[color:var(--border)] ds:bg-transparent ds:text-[color:var(--muted-foreground)]',\n },\n },\n defaultVariants: { state: 'idle' },\n },\n);\n\ntype TimeOfDay = 'morning' | 'afternoon' | 'evening';\n\nfunction bucketForTime(time: string): TimeOfDay {\n const [hh] = time.split(':').map((s) => parseInt(s, 10));\n const hour = Number.isFinite(hh) ? hh : 0;\n if (hour < 12) return 'morning';\n if (hour < 17) return 'afternoon';\n return 'evening';\n}\n\nconst BUCKET_ICONS: Record<TimeOfDay, LucideIcon> = {\n morning: Sun,\n afternoon: Sunset,\n evening: Moon,\n};\n\ninterface GroupedTimeSlotsProps {\n date: string;\n slots: BookingSlot[];\n selectedSlotKey?: string;\n onSelect: (slot: BookingSlot) => void;\n loading?: boolean;\n locale: string;\n}\n\nfunction GroupedTimeSlots({\n date,\n slots,\n selectedSlotKey,\n onSelect,\n loading,\n locale,\n}: GroupedTimeSlotsProps) {\n const { t } = useTranslation();\n\n const dateLabel = useMemo(() => {\n try {\n return new Intl.DateTimeFormat(locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n }).format(parseISO(date));\n } catch {\n return date;\n }\n }, [date, locale]);\n\n const groups = useMemo(() => {\n const result: Record<TimeOfDay, BookingSlot[]> = {\n morning: [],\n afternoon: [],\n evening: [],\n };\n for (const slot of slots) {\n result[bucketForTime(slot.time)].push(slot);\n }\n return result;\n }, [slots]);\n\n const availableCount = slots.filter((s) => s.available).length;\n const order: TimeOfDay[] = ['morning', 'afternoon', 'evening'];\n\n if (loading) {\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <Skeleton variant=\"text\" width=\"60%\" />\n {[0, 1].map((row) => (\n <div\n key={row}\n className=\"ds:grid ds:grid-cols-3 ds:gap-[var(--spacing-xs)]\"\n >\n {[0, 1, 2].map((c) => (\n <Skeleton key={c} variant=\"rounded\" height=\"44px\" />\n ))}\n </div>\n ))}\n </div>\n );\n }\n\n if (availableCount === 0) {\n return (\n <EmptyState variant=\"no-results\" title={t('booking.noSlotsForDate')} />\n );\n }\n\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <div className=\"ds:flex ds:items-baseline ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <CalendarRange\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:text-[color:var(--accent)]\"\n />\n <h3 className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)] ds:m-0\">\n {dateLabel}\n </h3>\n </div>\n <span className=\"type-meta ds:text-[var(--muted-foreground)]\">\n {t('booking.slotsAvailable', { count: availableCount })}\n </span>\n </div>\n {order.map((bucket) => {\n const items = groups[bucket];\n if (items.length === 0) return null;\n const Icon = BUCKET_ICONS[bucket];\n return (\n <div\n key={bucket}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:text-[color:var(--muted-foreground)]\">\n <Icon aria-hidden=\"true\" className=\"ds:size-3.5\" />\n <span className=\"type-meta ds:font-[var(--font-weight-semibold)] ds:uppercase\">\n {t(`booking.timeOfDay.${bucket}`)}\n </span>\n </div>\n <div\n role=\"group\"\n aria-label={t(`booking.timeOfDay.${bucket}`)}\n className=\"ds:grid ds:grid-cols-3 ds:gap-[var(--spacing-xs)] ds:sm:grid-cols-4\"\n >\n {items.map((slot) => {\n const isSelected = slot.key === selectedSlotKey;\n const state = !slot.available\n ? 'unavailable'\n : isSelected\n ? 'selected'\n : 'idle';\n return (\n <button\n key={slot.key}\n type=\"button\"\n data-slot-id={slot.key}\n disabled={!slot.available}\n aria-pressed={isSelected}\n aria-label={\n slot.unavailableReason && !slot.available\n ? `${slot.time} — ${slot.unavailableReason}`\n : t('booking.slotAvailableLabel', { time: slot.time })\n }\n onClick={() => slot.available && onSelect(slot)}\n className={slotChipVariants({ state })}\n >\n {slot.time}\n </button>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* InlineListBody — Lovable mockup */\n/* -------------------------------------------------------------------- */\n\nfunction InlineListBody({\n services,\n specialties,\n availableDates,\n availableSlots,\n value,\n onChange,\n onSubmit,\n detailsSlot,\n loadingDates,\n loadingSlots,\n locale,\n}: VariantBodyProps) {\n const { t } = useTranslation();\n const [query, setQuery] = useState('');\n\n // Focus management — when progressive disclosure reveals a new step,\n // pull keyboard focus to that step's heading (tabIndex=-1) so the user\n // doesn't Tab through every preceding control. Pattern matches\n // `src/components/stepper-accordion/stepper-accordion.tsx` and the\n // a11y guidance in `src/docs/05-accessibility.mdx`.\n const dateHeadingRef = useRef<HTMLHeadingElement>(null);\n const timeHeadingRef = useRef<HTMLHeadingElement>(null);\n const prevServiceRef = useRef(Boolean(value.serviceId));\n const prevDateRef = useRef(Boolean(value.date));\n useEffect(() => {\n const isPicked = Boolean(value.serviceId);\n if (!prevServiceRef.current && isPicked) {\n requestAnimationFrame(() => dateHeadingRef.current?.focus());\n }\n prevServiceRef.current = isPicked;\n }, [value.serviceId]);\n useEffect(() => {\n const isPicked = Boolean(value.date);\n if (!prevDateRef.current && isPicked) {\n requestAnimationFrame(() => timeHeadingRef.current?.focus());\n }\n prevDateRef.current = isPicked;\n }, [value.date]);\n\n // Specialty filter applies on top of free-text query.\n const filteredServices = useMemo(() => {\n const q = query.trim().toLowerCase();\n return services.filter((s) => {\n if (\n value.specialtyId &&\n s.specialtyId &&\n s.specialtyId !== value.specialtyId\n ) {\n return false;\n }\n if (!q) return true;\n const haystack = `${s.label} ${s.description ?? ''}`.toLowerCase();\n return haystack.includes(q);\n });\n }, [services, query, value.specialtyId]);\n\n const selectedService = useMemo(\n () => services.find((s) => s.id === value.serviceId),\n [services, value.serviceId],\n );\n\n const dayForGrid = useMemo<SlotGridDay[] | null>(() => {\n if (!value.date) return null;\n const slots = availableSlots[value.date] ?? [];\n return [buildSlotGridDay(value.date, slots)];\n }, [value.date, availableSlots]);\n\n const handleSpecialtyToggle = (id: string) => {\n onChange({\n ...value,\n specialtyId: value.specialtyId === id ? undefined : id,\n // Clear downstream selections when filter changes.\n serviceId: undefined,\n date: undefined,\n time: undefined,\n slotKey: undefined,\n });\n };\n\n const handlePickService = (id: string) => {\n onChange({\n ...value,\n serviceId: id,\n // Clear downstream selections when service changes.\n date: undefined,\n time: undefined,\n slotKey: undefined,\n });\n };\n\n const handlePickDate = (iso: string) => {\n onChange({\n ...value,\n date: iso,\n time: undefined,\n slotKey: undefined,\n });\n };\n\n const handlePickSlot = (slot: SlotGridSlot) => {\n onChange({\n ...value,\n slotKey: slot.id,\n time:\n typeof slot.label === 'string'\n ? slot.label\n : fnsFormat(\n slot.start instanceof Date ? slot.start : parseISO(slot.start),\n 'HH:mm',\n ),\n });\n };\n\n const canSubmit =\n Boolean(value.serviceId) && Boolean(value.date) && Boolean(value.slotKey);\n\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Search row */}\n <TextInput\n placeholder={t('booking.searchPlaceholder')}\n aria-label={t('booking.searchLabel')}\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n startAdornment={<Search aria-hidden=\"true\" className=\"ds:size-4\" />}\n />\n\n {/* Specialty chip row */}\n {specialties.length > 0 ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3 className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)] ds:m-0\">\n {t('booking.browseBySpecialty')}\n </h3>\n <SuggestionChipGroup label={t('booking.browseBySpecialty')}>\n {specialties.map((sp) => (\n <SuggestionChip\n key={sp.id}\n value={sp.id}\n keepOnSelect\n intent={value.specialtyId === sp.id ? 'suggestion' : 'default'}\n aria-pressed={value.specialtyId === sp.id || undefined}\n startIcon={inferSpecialtyIcon(sp)}\n onSelect={() => handleSpecialtyToggle(sp.id)}\n >\n {sp.label}\n </SuggestionChip>\n ))}\n </SuggestionChipGroup>\n </div>\n ) : null}\n\n {/* Step 1: service list */}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3 className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)] ds:m-0\">\n {t('booking.pickService')}\n </h3>\n <ServiceGrid\n services={filteredServices}\n selectedServiceId={value.serviceId}\n onSelectService={handlePickService}\n />\n </div>\n\n {/* Step 2: date — progressive disclosure */}\n {selectedService ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3\n ref={dateHeadingRef}\n tabIndex={-1}\n className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)] ds:m-0 ds:focus:outline-none\"\n >\n {t('booking.pickDate')}\n </h3>\n {availableDates.length === 0 && !loadingDates ? (\n <EmptyState\n variant=\"no-results\"\n title={t('booking.noAvailability')}\n />\n ) : (\n <MonthGrid\n availableDates={availableDates}\n selectedDate={value.date}\n onSelectDate={handlePickDate}\n locale={locale}\n loading={loadingDates}\n />\n )}\n </div>\n ) : null}\n\n {/* Step 3: time — progressive disclosure */}\n {selectedService && value.date && dayForGrid ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3\n ref={timeHeadingRef}\n tabIndex={-1}\n className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)] ds:m-0 ds:focus:outline-none\"\n >\n {t('booking.pickTime')}\n </h3>\n <SlotGrid\n days={dayForGrid}\n state={loadingSlots ? 'loading' : 'default'}\n selectedSlotId={value.slotKey}\n onSlotSelect={handlePickSlot}\n locale={locale}\n />\n </div>\n ) : null}\n\n {/* Details + confirm */}\n {selectedService && value.slotKey ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {detailsSlot}\n <Button\n intent=\"primary\"\n size=\"md\"\n disabled={!canSubmit}\n onClick={() => onSubmit?.(value)}\n >\n {t('booking.actions.confirm')}\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* AccordionBody — three-step accordion */\n/* -------------------------------------------------------------------- */\n\nfunction AccordionBody({\n services,\n availableDates,\n availableSlots,\n value,\n onChange,\n onSubmit,\n detailsSlot,\n loadingDates,\n loadingSlots,\n locale,\n}: VariantBodyProps) {\n const { t } = useTranslation();\n const derivedStep = useMemo(\n () => deriveCurrentStep('accordion', value),\n [value],\n );\n const [activeStep, setActiveStep] = useState(derivedStep);\n\n // Auto-advance when downstream selection completes the current step.\n useEffect(() => {\n setActiveStep((prev) => Math.max(prev, derivedStep));\n }, [derivedStep]);\n\n const serviceOptions = useMemo<SelectOption[]>(\n () =>\n services.map((s) => ({\n value: s.id,\n label: `${s.label} · ${t('booking.serviceSummary', {\n minutes: s.durationMin,\n })}`,\n })),\n [services, t],\n );\n\n const selectedService = services.find((s) => s.id === value.serviceId);\n\n const dayForGrid = useMemo<SlotGridDay[] | null>(() => {\n if (!value.date) return null;\n const slots = availableSlots[value.date] ?? [];\n return [buildSlotGridDay(value.date, slots)];\n }, [value.date, availableSlots]);\n\n const dateTimeSummary = useMemo(() => {\n if (!value.date || !value.time) return undefined;\n try {\n const formatted = new Intl.DateTimeFormat(locale, {\n dateStyle: 'long',\n }).format(parseISO(value.date));\n return t('booking.dateTimeSummary', {\n date: formatted,\n time: value.time,\n });\n } catch {\n return `${value.date} ${value.time}`;\n }\n }, [value.date, value.time, locale, t]);\n\n const steps: AccordionStepSpec[] = [\n {\n label: t('booking.pickServiceLabel'),\n summary: selectedService?.label,\n status: value.serviceId ? 'completed' : undefined,\n content: (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <Select\n options={serviceOptions}\n value={value.serviceId ?? ''}\n onValueChange={(next) =>\n onChange({\n ...value,\n serviceId: next || undefined,\n date: undefined,\n time: undefined,\n slotKey: undefined,\n })\n }\n aria-label={t('booking.pickServiceLabel')}\n placeholder={t('booking.pickServiceLabel')}\n />\n </div>\n ),\n },\n {\n label: t('booking.pickDateLabel'),\n summary: dateTimeSummary,\n status: value.date && value.time ? 'completed' : undefined,\n content: (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:md:flex-row\">\n <div className=\"ds:flex-1 ds:min-w-0\">\n <MonthGrid\n availableDates={availableDates}\n selectedDate={value.date}\n onSelectDate={(iso) =>\n onChange({\n ...value,\n date: iso,\n time: undefined,\n slotKey: undefined,\n })\n }\n locale={locale}\n loading={loadingDates}\n />\n </div>\n <div className=\"ds:flex-1 ds:min-w-0\">\n {value.date && dayForGrid ? (\n <SlotGrid\n days={dayForGrid}\n state={loadingSlots ? 'loading' : 'default'}\n selectedSlotId={value.slotKey}\n onSlotSelect={(slot) =>\n onChange({\n ...value,\n slotKey: slot.id,\n time:\n typeof slot.label === 'string'\n ? slot.label\n : fnsFormat(\n slot.start instanceof Date\n ? slot.start\n : parseISO(slot.start),\n 'HH:mm',\n ),\n })\n }\n locale={locale}\n />\n ) : (\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {t('booking.pickDate')}\n </p>\n )}\n </div>\n </div>\n ),\n },\n {\n label: t('booking.confirmStep'),\n content: (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {detailsSlot ?? (\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {selectedService?.label}\n {dateTimeSummary ? ` — ${dateTimeSummary}` : ''}\n </p>\n )}\n <Button\n intent=\"primary\"\n size=\"md\"\n disabled={!value.serviceId || !value.slotKey}\n onClick={() => onSubmit?.(value)}\n >\n {t('booking.actions.confirm')}\n </Button>\n </div>\n ),\n },\n ];\n\n return (\n <StepperAccordion\n activeStep={activeStep}\n steps={steps}\n onStepChange={setActiveStep}\n />\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* CalendarBody — single-screen calendar */\n/* -------------------------------------------------------------------- */\n\nfunction CalendarBody({\n services,\n availableDates,\n availableSlots,\n value,\n onChange,\n onSubmit,\n detailsSlot,\n loadingDates,\n loadingSlots,\n locale,\n}: VariantBodyProps) {\n const { t } = useTranslation();\n\n // The brief calls for `Autocomplete` once `services.length > 8` to\n // keep long catalogues navigable. Deferred: `Autocomplete`'s API is\n // async (`loadOptions: (query) => Promise<…>`) and wrapping the in-\n // memory service list in a Promise + an AbortSignal-aware loader is\n // material extra surface area. Filed as a follow-up — current Select\n // remains usable for catalogues up to ~30 services.\n const serviceOptions = useMemo<SelectOption[]>(\n () =>\n services.map((s) => ({\n value: s.id,\n label: `${s.label} · ${t('booking.serviceSummary', {\n minutes: s.durationMin,\n })}`,\n })),\n [services, t],\n );\n\n const daySlots = useMemo<BookingSlot[]>(() => {\n if (!value.date) return [];\n return availableSlots[value.date] ?? [];\n }, [value.date, availableSlots]);\n\n // Focus management: when the user picks a date, pull focus into the\n // slot column so keyboard users can act on the freshly-revealed slots\n // without re-Tabbing through the MonthGrid.\n const slotPanelRef = useRef<HTMLDivElement>(null);\n const prevDateRef = useRef(Boolean(value.date));\n useEffect(() => {\n const isPicked = Boolean(value.date);\n if (!prevDateRef.current && isPicked) {\n requestAnimationFrame(() => {\n const target = slotPanelRef.current?.querySelector<HTMLElement>(\n 'button:not([disabled]), h4, [tabindex=\"0\"]',\n );\n target?.focus();\n });\n }\n prevDateRef.current = isPicked;\n }, [value.date]);\n\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <Select\n options={serviceOptions}\n value={value.serviceId ?? ''}\n onValueChange={(next) =>\n onChange({\n ...value,\n serviceId: next || undefined,\n date: undefined,\n time: undefined,\n slotKey: undefined,\n })\n }\n aria-label={t('booking.pickServiceLabel')}\n placeholder={t('booking.pickServiceLabel')}\n />\n <div className=\"ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-md)] ds:md:grid-cols-2\">\n <div className=\"ds:min-w-0\">\n {availableDates.length === 0 && !loadingDates ? (\n <EmptyState\n variant=\"no-results\"\n title={t('booking.noAvailability')}\n />\n ) : (\n <MonthGrid\n availableDates={availableDates}\n selectedDate={value.date}\n onSelectDate={(iso) =>\n onChange({\n ...value,\n date: iso,\n time: undefined,\n slotKey: undefined,\n })\n }\n locale={locale}\n loading={loadingDates}\n />\n )}\n </div>\n <div ref={slotPanelRef} className=\"ds:min-w-0\">\n {value.date ? (\n <GroupedTimeSlots\n date={value.date}\n slots={daySlots}\n selectedSlotKey={value.slotKey}\n loading={loadingSlots}\n locale={locale}\n onSelect={(slot) =>\n onChange({\n ...value,\n slotKey: slot.key,\n time: slot.time,\n })\n }\n />\n ) : (\n <div className=\"ds:flex ds:h-full ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-xs)] ds:rounded-[var(--radius-md)] ds:border ds:border-dashed ds:border-[color:var(--border)] ds:p-[var(--spacing-md)] ds:text-center\">\n <CalendarRange\n aria-hidden=\"true\"\n className=\"ds:size-5 ds:text-[color:var(--accent)]\"\n />\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)] ds:m-0\">\n {t('booking.pickDate')}\n </p>\n </div>\n )}\n </div>\n </div>\n {value.slotKey ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {detailsSlot}\n <Button\n intent=\"primary\"\n size=\"md\"\n disabled={!value.serviceId || !value.slotKey}\n onClick={() => onSubmit?.(value)}\n >\n {t('booking.actions.confirm')}\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* FlexibleBody — autocomplete + date range + multi-day grid */\n/* -------------------------------------------------------------------- */\n\nfunction FlexibleBody({\n services,\n specialties,\n availableDates,\n availableSlots,\n value,\n onChange,\n onSubmit,\n detailsSlot,\n loadingSlots,\n locale,\n}: VariantBodyProps) {\n const { t } = useTranslation();\n\n // Local range state for the DateRangePicker — we surface the full date\n // every time the picker fires so downstream slot grid stays in sync.\n const [range, setRange] = useState<DateRangeValue>(() => {\n if (value.date) {\n const start = parseISO(value.date);\n return { from: start, to: start };\n }\n if (availableDates.length > 0) {\n return {\n from: parseISO(availableDates[0]),\n to: parseISO(availableDates[availableDates.length - 1]),\n };\n }\n return {};\n });\n\n const filteredServices = useMemo(() => {\n if (!value.specialtyId) return services;\n return services.filter(\n (s) => !s.specialtyId || s.specialtyId === value.specialtyId,\n );\n }, [services, value.specialtyId]);\n\n // Build multi-day grid from the range.\n const daysInRange = useMemo<string[]>(() => {\n if (!range.from || !range.to) return availableDates;\n const out: string[] = [];\n const from = range.from;\n const to = range.to;\n const cursor = new Date(from);\n while (cursor.getTime() <= to.getTime()) {\n out.push(isoOf(cursor));\n cursor.setDate(cursor.getDate() + 1);\n }\n return out.filter((d) => availableDates.includes(d));\n }, [range.from, range.to, availableDates]);\n\n const gridDays = useMemo<SlotGridDay[]>(\n () =>\n daysInRange.map((iso) =>\n buildSlotGridDay(iso, availableSlots[iso] ?? []),\n ),\n [daysInRange, availableSlots],\n );\n\n const handleAutocompleteSelect = (option: { value: string }) => {\n onChange({\n ...value,\n serviceId: option.value,\n date: undefined,\n time: undefined,\n slotKey: undefined,\n });\n };\n\n const loadOptions = useCallback(\n async (query: string) => {\n const q = query.trim().toLowerCase();\n return filteredServices\n .filter((s) => (!q ? true : s.label.toLowerCase().includes(q)))\n .map((s) => ({\n value: s.id,\n label: `${s.label} · ${t('booking.serviceSummary', {\n minutes: s.durationMin,\n })}`,\n }));\n },\n [filteredServices, t],\n );\n\n const selectedService = services.find((s) => s.id === value.serviceId);\n void selectedService;\n\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <Autocomplete\n placeholder={t('booking.searchPlaceholder')}\n aria-label={t('booking.searchLabel')}\n loadOptions={loadOptions}\n onSelect={handleAutocompleteSelect}\n startAdornment={<Search aria-hidden=\"true\" className=\"ds:size-4\" />}\n />\n\n {specialties.length > 0 ? (\n <SuggestionChipGroup label={t('booking.browseBySpecialty')}>\n {specialties.map((sp) => (\n <SuggestionChip\n key={sp.id}\n value={sp.id}\n keepOnSelect\n intent={value.specialtyId === sp.id ? 'suggestion' : 'default'}\n aria-pressed={value.specialtyId === sp.id || undefined}\n startIcon={inferSpecialtyIcon(sp)}\n onSelect={() =>\n onChange({\n ...value,\n specialtyId: value.specialtyId === sp.id ? undefined : sp.id,\n serviceId: undefined,\n date: undefined,\n time: undefined,\n slotKey: undefined,\n })\n }\n >\n {sp.label}\n </SuggestionChip>\n ))}\n </SuggestionChipGroup>\n ) : null}\n\n <DateRangePicker\n value={range}\n onChange={(next) => {\n setRange(next);\n if (next.from) {\n onChange({\n ...value,\n date: isoOf(next.from),\n time: undefined,\n slotKey: undefined,\n });\n }\n }}\n />\n\n <SlotGrid\n days={gridDays}\n state={loadingSlots ? 'loading' : 'default'}\n selectedSlotId={value.slotKey}\n onSlotSelect={(slot, day) => {\n const date = day.date instanceof Date ? day.date : parseISO(day.date);\n onChange({\n ...value,\n date: isoOf(date),\n slotKey: slot.id,\n time:\n typeof slot.label === 'string'\n ? slot.label\n : fnsFormat(\n slot.start instanceof Date\n ? slot.start\n : parseISO(slot.start),\n 'HH:mm',\n ),\n });\n }}\n locale={locale}\n />\n\n {value.slotKey ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {detailsSlot}\n <Button\n intent=\"primary\"\n size=\"md\"\n disabled={!value.serviceId || !value.slotKey}\n onClick={() => onSubmit?.(value)}\n >\n {t('booking.actions.confirm')}\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* ProgressBody — compact wizard */\n/* -------------------------------------------------------------------- */\n\nfunction ProgressBody({\n services,\n availableDates,\n availableSlots,\n value,\n onChange,\n onSubmit,\n detailsSlot,\n loadingDates,\n loadingSlots,\n locale,\n}: VariantBodyProps) {\n const { t } = useTranslation();\n const derivedStep = useMemo(\n () => deriveCurrentStep('progress', value),\n [value],\n );\n const [step, setStep] = useState(derivedStep);\n\n useEffect(() => {\n setStep((prev) => Math.max(prev, derivedStep));\n }, [derivedStep]);\n\n // Focus management: each step transition pulls focus into the matching\n // step body. `stepBodyRef` wraps every step's content so we can scan\n // for the first focusable on each change.\n const stepBodyRef = useRef<HTMLDivElement>(null);\n const isFirstRenderRef = useRef(true);\n useEffect(() => {\n if (isFirstRenderRef.current) {\n isFirstRenderRef.current = false;\n return;\n }\n requestAnimationFrame(() => {\n const target = stepBodyRef.current?.querySelector<HTMLElement>(\n 'button:not([disabled]), [role=\"combobox\"], input, textarea, [tabindex=\"0\"]',\n );\n target?.focus();\n });\n }, [step]);\n\n const steps = [\n { label: t('booking.pickServiceLabel') },\n { label: t('booking.pickDateLabel') },\n { label: t('booking.confirmStep') },\n ];\n\n const serviceOptions = useMemo<SelectOption[]>(\n () =>\n services.map((s) => ({\n value: s.id,\n label: `${s.label} · ${t('booking.serviceSummary', {\n minutes: s.durationMin,\n })}`,\n })),\n [services, t],\n );\n\n const dayForGrid = useMemo<SlotGridDay[] | null>(() => {\n if (!value.date) return null;\n const slots = availableSlots[value.date] ?? [];\n return [buildSlotGridDay(value.date, slots)];\n }, [value.date, availableSlots]);\n\n const canAdvance = (current: number) => {\n if (current === 0) return Boolean(value.serviceId);\n if (current === 1) return Boolean(value.date && value.time);\n return true;\n };\n\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <StepperProgress activeStep={step} steps={steps} onStepChange={setStep} />\n <div\n ref={stepBodyRef}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n {step === 0 ? (\n <Select\n options={serviceOptions}\n value={value.serviceId ?? ''}\n onValueChange={(next) =>\n onChange({\n ...value,\n serviceId: next || undefined,\n date: undefined,\n time: undefined,\n slotKey: undefined,\n })\n }\n aria-label={t('booking.pickServiceLabel')}\n placeholder={t('booking.pickServiceLabel')}\n />\n ) : null}\n {step === 1 ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <MonthGrid\n availableDates={availableDates}\n selectedDate={value.date}\n onSelectDate={(iso) =>\n onChange({\n ...value,\n date: iso,\n time: undefined,\n slotKey: undefined,\n })\n }\n locale={locale}\n loading={loadingDates}\n />\n {value.date && dayForGrid ? (\n <SlotGrid\n days={dayForGrid}\n state={loadingSlots ? 'loading' : 'default'}\n selectedSlotId={value.slotKey}\n onSlotSelect={(slot) =>\n onChange({\n ...value,\n slotKey: slot.id,\n time:\n typeof slot.label === 'string'\n ? slot.label\n : fnsFormat(\n slot.start instanceof Date\n ? slot.start\n : parseISO(slot.start),\n 'HH:mm',\n ),\n })\n }\n locale={locale}\n />\n ) : null}\n </div>\n ) : null}\n {step === 2 ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {detailsSlot}\n </div>\n ) : null}\n </div>\n\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <Button\n intent=\"ghost\"\n size=\"md\"\n disabled={step === 0}\n onClick={() => setStep((s) => Math.max(0, s - 1))}\n >\n {t('booking.actions.back')}\n </Button>\n {step < 2 ? (\n <Button\n intent=\"primary\"\n size=\"md\"\n disabled={!canAdvance(step)}\n onClick={() => setStep((s) => Math.min(steps.length - 1, s + 1))}\n >\n {t('booking.actions.next')}\n </Button>\n ) : (\n <Button\n intent=\"primary\"\n size=\"md\"\n disabled={!value.serviceId || !value.slotKey}\n onClick={() => onSubmit?.(value)}\n >\n {t('booking.actions.confirm')}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const Booking = forwardRef<HTMLDivElement, BookingProps>(\n (\n {\n variant = 'inline-list',\n services,\n specialties,\n availableDates,\n availableSlots,\n value,\n onChange,\n onSubmit,\n filtersSlot,\n detailsSlot,\n ctaSlot,\n heading,\n loadingDates,\n loadingSlots,\n 'aria-label': ariaLabel,\n id,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const resolvedVariant = (variant ?? 'inline-list') as BookingVariant;\n const locale = i18n.language ?? 'en';\n\n // Derive the current step from the controlled value — keeps the\n // imperative handle's `getCurrentStep` consistent with what the user\n // sees regardless of which variant body is active.\n const totalSteps = TOTAL_STEPS[resolvedVariant];\n const [stepOverride, setStepOverride] = useState<number | null>(null);\n const derivedStep = deriveCurrentStep(resolvedVariant, value);\n const activeStep = stepOverride ?? derivedStep;\n\n const handle = useMemo<BookingHandle>(\n () => ({\n getCurrentStep: () => activeStep,\n getTotalSteps: () => totalSteps,\n gotoStep: (step: number) => {\n const clamped = Math.max(0, Math.min(step, totalSteps - 1));\n setStepOverride(clamped);\n },\n next: () => {\n if (activeStep < totalSteps - 1) setStepOverride(activeStep + 1);\n },\n previous: () => {\n if (activeStep > 0) setStepOverride(activeStep - 1);\n },\n getVariant: () => resolvedVariant,\n }),\n [activeStep, totalSteps, resolvedVariant],\n );\n\n const rootRef = useRef<HTMLDivElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLDivElement, []);\n useAgentRegistration(bookingAgent, handle, id);\n\n // Agent-readiness: when an external driver invokes `gotoStep` (or\n // `next` / `previous`) on the imperative handle, focus must follow.\n // Without this, a screen-reader / keyboard user driven via the\n // adapter sees the visible step swap silently while their focus\n // stays on whatever was previously focused. We focus the first\n // focusable inside the root region so the variant body itself\n // decides what counts (its own step-aware effects handle the rest).\n const isFirstHandleRenderRef = useRef(true);\n useEffect(() => {\n if (isFirstHandleRenderRef.current) {\n isFirstHandleRenderRef.current = false;\n return;\n }\n if (stepOverride == null) return;\n requestAnimationFrame(() => {\n const target = rootRef.current?.querySelector<HTMLElement>(\n 'button:not([disabled]), [role=\"combobox\"], input:not([disabled]), textarea, h3[tabindex=\"-1\"]',\n );\n target?.focus();\n });\n }, [stepOverride]);\n\n const headerTitle =\n resolvedVariant === 'inline-list'\n ? t('booking.inlineList.title')\n : resolvedVariant === 'accordion'\n ? t('booking.accordion.title')\n : resolvedVariant === 'calendar'\n ? t('booking.calendar.title')\n : resolvedVariant === 'flexible'\n ? t('booking.flexible.title')\n : t('booking.progress.title');\n\n const headerSubtitle =\n resolvedVariant === 'inline-list'\n ? t('booking.inlineList.subtitle')\n : resolvedVariant === 'accordion'\n ? t('booking.accordion.subtitle')\n : resolvedVariant === 'calendar'\n ? t('booking.calendar.subtitle')\n : resolvedVariant === 'flexible'\n ? t('booking.flexible.subtitle')\n : t('booking.progress.subtitle');\n\n const resolvedAriaLabel = ariaLabel ?? t('booking.regionLabel');\n\n const headerNode =\n heading === null ? null : heading !== undefined ? (\n heading\n ) : (\n // Plain <div> here, not <header>: the booking root carries\n // `role=\"region\"`, which already has an accessible name via\n // `aria-labelledby`. Using a second nested `<header>` would\n // emit a banner landmark inside a region landmark, which axe's\n // `landmark-banner-is-top-level` rule flags as a moderate\n // violation. The visual styling is identical.\n <div\n className={[\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]',\n resolvedVariant === 'inline-list'\n ? [\n 'ds:rounded-[var(--radius-md)]',\n 'ds:bg-[image:var(--gradient-hero-brand)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n ].join(' ')\n : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <h2 className=\"type-title-card ds:text-[var(--foreground)] ds:m-0\">\n {headerTitle}\n </h2>\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)] ds:m-0\">\n {headerSubtitle}\n </p>\n </div>\n );\n\n const bodyProps: VariantBodyProps = {\n services,\n specialties: specialties ?? [],\n availableDates,\n availableSlots,\n value,\n onChange,\n onSubmit,\n detailsSlot,\n loadingDates,\n loadingSlots,\n locale,\n };\n\n const body = (() => {\n switch (resolvedVariant) {\n case 'inline-list':\n return <InlineListBody {...bodyProps} />;\n case 'accordion':\n return <AccordionBody {...bodyProps} />;\n case 'calendar':\n return <CalendarBody {...bodyProps} />;\n case 'flexible':\n return <FlexibleBody {...bodyProps} />;\n case 'progress':\n return <ProgressBody {...bodyProps} />;\n /* c8 ignore next 2 */\n default:\n return null;\n }\n })();\n\n return (\n <div\n ref={rootRef}\n role=\"region\"\n aria-label={resolvedAriaLabel}\n id={id}\n data-component=\"booking\"\n data-component-id={id}\n data-variant={resolvedVariant}\n className={rootVariants({ variant: resolvedVariant, className })}\n {...rest}\n >\n {headerNode}\n {filtersSlot}\n {body}\n {ctaSlot}\n </div>\n );\n },\n);\n\nBooking.displayName = 'Booking';\n"],"names":["__iconNode","Activity","createLucideIcon","Baby","Bone","Brain","CalendarRange","ClipboardCheck","Ear","Microscope","Pill","ScanLine","Scissors","Smile","Sunset","Syringe","subMonths","date","amount","options","addMonths","bookingAgent","handle","args","rootVariants","cva","SERVICE_ICON_RULES","HeartPulse","Eye","Sparkles","SPECIALTY_ICON_RULES","pickIcon","text","rules","pattern","Icon","inferServiceIcon","service","haystack","Stethoscope","jsx","inferSpecialtyIcon","specialty","isoOf","fnsFormat","TOTAL_STEPS","deriveCurrentStep","variant","value","monthCellBase","monthCellVariants","MonthGrid","availableDates","selectedDate","onSelectDate","locale","loading","t","useTranslation","initialMonth","useMemo","startOfMonth","parseISO","viewMonth","setViewMonth","useState","focusDate","setFocusDate","cells","monthStart","monthEnd","endOfMonth","startWeekday","totalDays","grid","i","d","last","monthLabel","weekdayLabels","base","_","availableSet","isAvailable","useCallback","rovingDate","firstAvailable","isSameMonth","handleKeyDown","event","current","next","jsxs","Skeleton","IconButton","ChevronLeft","m","ChevronRight","label","rowIndex","colIndex","inMonth","available","isSelected","isSameDay","state","isRoving","dayLabel","e","serviceCardVariants","ServiceGrid","services","selectedServiceId","onSelectService","groupId","useId","focusIndex","setFocusIndex","s","cardRefs","useRef","focusAt","index","node","id","total","prev","EmptyState","tabIndex","ariaLabel","iconNode","buildSlotGridDay","isoDate","slots","hh","mm","x","start","slotChipVariants","bucketForTime","time","hour","BUCKET_ICONS","Sun","Moon","GroupedTimeSlots","selectedSlotKey","onSelect","dateLabel","groups","result","slot","availableCount","order","row","c","bucket","items","InlineListBody","specialties","availableSlots","onChange","onSubmit","detailsSlot","loadingDates","loadingSlots","query","setQuery","dateHeadingRef","timeHeadingRef","prevServiceRef","prevDateRef","useEffect","isPicked","_a","filteredServices","q","selectedService","dayForGrid","handleSpecialtyToggle","handlePickService","handlePickDate","iso","handlePickSlot","canSubmit","TextInput","Search","SuggestionChipGroup","sp","SuggestionChip","SlotGrid","Button","AccordionBody","derivedStep","activeStep","setActiveStep","serviceOptions","dateTimeSummary","formatted","steps","Select","StepperAccordion","CalendarBody","daySlots","slotPanelRef","target","FlexibleBody","range","setRange","daysInRange","out","from","to","cursor","gridDays","handleAutocompleteSelect","option","loadOptions","Autocomplete","DateRangePicker","day","ProgressBody","step","setStep","stepBodyRef","isFirstRenderRef","canAdvance","StepperProgress","Booking","forwardRef","filtersSlot","ctaSlot","heading","className","rest","ref","i18n","resolvedVariant","totalSteps","stepOverride","setStepOverride","clamped","rootRef","useImperativeHandle","useAgentRegistration","isFirstHandleRenderRef","headerTitle","headerSubtitle","resolvedAriaLabel","headerNode","bodyProps","body"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"header-B8V_sNPy.js","sources":["../../src/components/header/header.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Menu } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst rootVariants = cva(\n [\n 'ds:w-full',\n // Fixed height — a Header is always the `lg` token (64px). Using `h-*`\n // (not `min-h-*`) pins the row regardless of how Storybook's Canvas /\n // docs wrapper stretches the story's layout.\n 'ds:h-[var(--header-height-lg)]',\n // `flex items-stretch` lets the inner div fill the full cross-axis so\n // the flex-centered content sits on the true vertical midline.\n 'ds:flex ds:items-stretch',\n // Pin to the top of the page — `sticky` keeps the Header in normal\n // document flow (so content below isn't occluded and the docs Canvas\n // doesn't leak the Header over adjacent preview blocks) but stays\n // anchored to the viewport while the nearest scroll ancestor scrolls.\n 'ds:sticky ds:inset-block-start-0 ds:z-[var(--z-sticky)]',\n 'ds:bg-[var(--background)]',\n 'ds:text-[color:var(--foreground)]',\n // Shadow recipe follows `Brand/Shadows` — one tier between states, never\n // two. Resting: flat, no shadow. Scrolled: --shadow-md (tooltip/menu tier)\n // paired with a 1-px --border so elevation still reads without the shadow\n // in forced-colors / print, where UAs strip box-shadow. Transition is\n // gated on `motion-reduce` so users opting out of motion still get the\n // static elevation without animated lift.\n 'ds:transition-[border-color,box-shadow] ds:motion-reduce:transition-none',\n 'ds:border-block-end ds:border-transparent',\n 'ds:data-[scrolled=true]:border-[color:var(--border)]',\n 'ds:data-[scrolled=true]:shadow-[var(--shadow-md)]',\n // Windows HCM: always show the border — forced-colors strips box-shadow\n // entirely, so the border is the only separation cue the user gets.\n 'ds:forced-colors:border-[color:CanvasText]',\n // Print: strip shadow, keep border so the header still reads as a\n // bounded surface on paper.\n 'ds:print:shadow-none ds:print:border-[color:var(--border)]',\n ].join(' '),\n {\n variants: {\n variant: {\n // Brand surface — primary-tinted background with primary-foreground\n // ink. Token rescopes are narrowed to `start` + `end` slots so chrome\n // (IconButton outline border, Logo monochrome, focus rings) re-tints\n // automatically. The `center` slot is excluded because SearchBar paints\n // its own `var(--background)` surface and must keep the document's\n // --foreground / --muted-foreground for its icon, placeholder, border,\n // kbd chip, and hover state.\n //\n // Contrast: --primary-foreground (#fff) over --primary (violet-500) is\n // 4.6:1 — passes WCAG AA for normal text. Muted-foreground is also set\n // to pure primary-foreground so any muted text in the header clears AA.\n //\n // Dark-mode override: in dark mode --primary is magenta-500 — using it\n // as the full-width header surface puts a hot-pink bar at the top of\n // every page, which the Apr 2026 brand guide's own dark mockups never\n // do (fuchsia is reserved for CTAs). We shift the header bg to\n // --background (blue-500) in dark so the header blends with the Dark\n // Blue brand surface at the same level as the Sidebar; separation\n // from the main canvas (which we offset to blue-700) is carried by\n // the existing scroll-shadow + border. White --primary-foreground ink\n // on blue-500 clears AAA (~12.8:1).\n brand: [\n 'ds:bg-[var(--primary)] ds:text-[color:var(--primary-foreground)]',\n 'ds:[.theme-dark_&]:bg-[var(--background)]',\n 'ds:[&_[data-header-slot=start]]:[--foreground:var(--primary-foreground)]',\n 'ds:[&_[data-header-slot=start]]:[--muted-foreground:var(--primary-foreground)]',\n 'ds:[&_[data-header-slot=start]]:[--border:color-mix(in_srgb,var(--primary-foreground)_40%,transparent)]',\n 'ds:[&_[data-header-slot=start]]:[--muted:color-mix(in_srgb,var(--primary-foreground)_16%,transparent)]',\n 'ds:[&_[data-header-slot=start]]:[--ring:var(--primary-foreground)]',\n 'ds:[&_[data-header-slot=end]]:[--foreground:var(--primary-foreground)]',\n 'ds:[&_[data-header-slot=end]]:[--muted-foreground:var(--primary-foreground)]',\n 'ds:[&_[data-header-slot=end]]:[--border:color-mix(in_srgb,var(--primary-foreground)_40%,transparent)]',\n 'ds:[&_[data-header-slot=end]]:[--muted:color-mix(in_srgb,var(--primary-foreground)_16%,transparent)]',\n 'ds:[&_[data-header-slot=end]]:[--ring:var(--primary-foreground)]',\n ].join(' '),\n // Light surface — plain page background with primary-coloured chrome.\n // Start + end slots rescope --foreground, --border, --ring to --primary\n // so IconButton borders/icons render in the brand hue while the\n // HeaderBrand wordmark keeps its bicolor artwork and the SearchBar\n // (center slot) is untouched.\n light: [\n 'ds:bg-[var(--background)] ds:text-[color:var(--foreground)]',\n 'ds:[&_[data-header-slot=start]]:[--foreground:var(--primary)]',\n 'ds:[&_[data-header-slot=start]]:[--border:var(--primary)]',\n 'ds:[&_[data-header-slot=start]]:[--ring:var(--primary)]',\n 'ds:[&_[data-header-slot=end]]:[--foreground:var(--primary)]',\n 'ds:[&_[data-header-slot=end]]:[--border:var(--primary)]',\n 'ds:[&_[data-header-slot=end]]:[--ring:var(--primary)]',\n ].join(' '),\n },\n },\n defaultVariants: {\n variant: 'brand',\n },\n },\n);\n\nconst innerVariants = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:w-full ds:h-full',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n ].join(' '),\n);\n\nconst slotStartVariants = cva(\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]',\n);\nconst slotCenterVariants = cva(\n 'ds:hidden ds:md:flex ds:flex-1 ds:min-w-0 ds:items-center ds:justify-center ds:gap-[var(--spacing-sm)]',\n);\nconst slotEndVariants = cva(\n 'ds:ms-auto ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]',\n);\n\nconst brandVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:text-[length:var(--font-size-base)] ds:font-[var(--font-weight-semibold)]',\n // `leading-none` zeros the anchor's line-height so the Logo SVG sits at\n // the geometric centre of the flex cross-axis — otherwise the residual\n // line-box above ascenders / below descenders nudges the SVG upward.\n 'ds:leading-none',\n // Inherit foreground from the Header root so the `brand` variant's\n // --primary-foreground ink cascades here without an override prop.\n 'ds:text-[color:currentColor]',\n 'ds:no-underline',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:min-h-[var(--min-target-size)]',\n ].join(' '),\n);\n\nconst brandDividerVariants = cva(\n [\n 'ds:hidden ds:md:inline-block',\n 'ds:border-inline-start ds:border-[color:var(--border)]',\n 'ds:self-stretch ds:my-[var(--spacing-xs)]',\n ].join(' '),\n);\n\nconst skipLinkVariants = cva(\n [\n 'ds:sr-only ds:focus:not-sr-only',\n 'ds:focus:absolute ds:focus:inset-inline-start-[var(--spacing-sm)] ds:focus:inset-block-start-[var(--spacing-sm)]',\n 'ds:focus:z-[calc(var(--z-sticky)+1)]',\n 'ds:focus:ps-[var(--spacing-sm)] ds:focus:pe-[var(--spacing-sm)] ds:focus:pbs-[var(--spacing-xs)] ds:focus:pbe-[var(--spacing-xs)]',\n 'ds:focus:bg-[var(--background)] ds:focus:text-[color:var(--foreground)]',\n 'ds:focus:border ds:focus:border-[color:var(--border)]',\n 'ds:focus:rounded-[var(--radius-sm)]',\n 'ds:focus:outline-[length:var(--focus-ring-width)] ds:focus:outline-solid ds:focus:outline-[color:var(--ring)]',\n 'ds:forced-colors:focus:outline-[CanvasText]',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport interface HeaderProps\n extends\n Omit<HTMLAttributes<HTMLElement>, 'role' | 'children'>,\n VariantProps<typeof rootVariants> {\n children: ReactNode;\n /** Override the default landmark name. */\n 'aria-label'?: string;\n /** Enable the scroll-linked border + shadow (default `true`). */\n scrollLinkedElevation?: boolean;\n}\n\nexport const Header = forwardRef<HTMLElement, HeaderProps>(\n (\n {\n variant = 'brand',\n className,\n children,\n scrollLinkedElevation = true,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const label = ariaLabel ?? t('navigation.header.label', 'Page header');\n\n /* ---- Scroll-linked border / shadow ---------------------------- */\n const sentinelRef = useRef<HTMLDivElement | null>(null);\n const [scrolled, setScrolled] = useState(false);\n useEffect(() => {\n if (!scrollLinkedElevation) return undefined;\n const sentinel = sentinelRef.current;\n if (!sentinel) return undefined;\n if (typeof IntersectionObserver === 'undefined') return undefined;\n const io = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n // When the sentinel scrolls out of view (isIntersecting=false),\n // the user has scrolled past the top — flip the elevation on.\n setScrolled(!entry.isIntersecting);\n },\n { threshold: 0 },\n );\n io.observe(sentinel);\n return () => io.disconnect();\n }, [scrollLinkedElevation]);\n\n return (\n <>\n {/* 1px sentinel above the sticky header so the IntersectionObserver\n fires when the user scrolls past the top. Kept outside the\n <header> so it doesn't affect landmark semantics. */}\n {scrollLinkedElevation ? (\n <div\n ref={sentinelRef}\n aria-hidden=\"true\"\n className=\"ds:block ds:h-px ds:w-full\"\n />\n ) : null}\n <header\n ref={ref}\n role=\"banner\"\n aria-label={label}\n data-component=\"header\"\n data-scrolled={scrolled ? 'true' : undefined}\n className={rootVariants({ variant, className })}\n {...rest}\n >\n <div className={innerVariants()}>{children}</div>\n </header>\n </>\n );\n },\n);\nHeader.displayName = 'Header';\n\n/* ------------------------------------------------------------------ */\n/* Slot wrappers */\n/* ------------------------------------------------------------------ */\n\nexport const HeaderStart = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-header-slot=\"start\"\n className={[slotStartVariants(), className].filter(Boolean).join(' ')}\n {...props}\n />\n));\nHeaderStart.displayName = 'HeaderStart';\n\nexport const HeaderCenter = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-header-slot=\"center\"\n className={[slotCenterVariants(), className].filter(Boolean).join(' ')}\n {...props}\n />\n));\nHeaderCenter.displayName = 'HeaderCenter';\n\nexport const HeaderEnd = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-header-slot=\"end\"\n className={[slotEndVariants(), className].filter(Boolean).join(' ')}\n {...props}\n />\n));\nHeaderEnd.displayName = 'HeaderEnd';\n\n/* ------------------------------------------------------------------ */\n/* Brand */\n/* ------------------------------------------------------------------ */\n\nexport interface HeaderBrandProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n /** Logo slot — an <svg> / <img>. Must carry its own accessible name via aria-label on the wrapping component OR a visible wordmark child. */\n logo?: ReactNode;\n /** Visible wordmark / product name. Sits after the logo. */\n children?: ReactNode;\n /** Destination href. Defaults to \"/\". */\n href?: string;\n}\n\nexport const HeaderBrand = forwardRef<HTMLAnchorElement, HeaderBrandProps>(\n ({ logo, children, href = '/', className, ...props }, ref) => {\n if (import.meta.env.DEV && !props['aria-label'] && !children) {\n console.warn(\n 'HeaderBrand: pass `aria-label` or visible children — a logo-only brand link without a name has no accessible name.',\n );\n }\n return (\n <a\n ref={ref}\n href={href}\n className={[brandVariants(), className].filter(Boolean).join(' ')}\n {...props}\n >\n {logo ? (\n <span\n aria-hidden={children ? 'true' : undefined}\n className=\"ds:inline-flex ds:items-center\"\n >\n {logo}\n </span>\n ) : null}\n {children ? <span className=\"ds:truncate\">{children}</span> : null}\n </a>\n );\n },\n);\nHeaderBrand.displayName = 'HeaderBrand';\n\n/* ------------------------------------------------------------------ */\n/* Brand divider */\n/* ------------------------------------------------------------------ */\n\nexport function HeaderBrandDivider({\n className,\n ...props\n}: HTMLAttributes<HTMLSpanElement>): ReactNode {\n return (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={[brandDividerVariants(), className].filter(Boolean).join(' ')}\n {...props}\n />\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Menu button (mobile drawer trigger) */\n/* ------------------------------------------------------------------ */\n\nexport interface HeaderMenuButtonProps {\n onMenuOpen: () => void;\n 'aria-label'?: string;\n className?: string;\n}\n\nexport const HeaderMenuButton = forwardRef<\n HTMLButtonElement,\n HeaderMenuButtonProps\n>(({ onMenuOpen, 'aria-label': ariaLabel, className }, ref) => {\n const { t } = useTranslation();\n return (\n <IconButton\n ref={ref}\n // Show on mobile; hide above md breakpoint.\n className={['ds:md:hidden', className].filter(Boolean).join(' ')}\n icon={<Menu aria-hidden />}\n aria-label={ariaLabel ?? t('navigation.sidebar.open', 'Open menu')}\n onClick={onMenuOpen}\n />\n );\n});\nHeaderMenuButton.displayName = 'HeaderMenuButton';\n\n/* ------------------------------------------------------------------ */\n/* SkipLink */\n/* ------------------------------------------------------------------ */\n\nexport interface HeaderSkipLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n href: string;\n children?: ReactNode;\n}\n\nexport const HeaderSkipLink = forwardRef<\n HTMLAnchorElement,\n HeaderSkipLinkProps\n>(({ href, children, className, ...props }, ref) => {\n const { t } = useTranslation();\n return (\n <a\n ref={ref}\n href={href}\n className={[skipLinkVariants(), className].filter(Boolean).join(' ')}\n {...props}\n >\n {children ?? t('navigation.nav.skipToContent', 'Skip to content')}\n </a>\n );\n});\nHeaderSkipLink.displayName = 'HeaderSkipLink';\n"],"names":["rootVariants","cva","innerVariants","slotStartVariants","slotCenterVariants","slotEndVariants","brandVariants","brandDividerVariants","skipLinkVariants","Header","forwardRef","variant","className","children","scrollLinkedElevation","ariaLabel","rest","ref","t","useTranslation","label","sentinelRef","useRef","scrolled","setScrolled","useState","useEffect","sentinel","io","entries","entry","jsxs","Fragment","jsx","HeaderStart","props","HeaderCenter","HeaderEnd","HeaderBrand","logo","href","HeaderBrandDivider","HeaderMenuButton","onMenuOpen","IconButton","Menu","HeaderSkipLink"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"link-DmM5IevO.js","sources":["../../src/components/link/link.tsx"],"sourcesContent":["import { forwardRef, type AnchorHTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ExternalLink } from 'lucide-react';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\n/**\n * Link is the semantic anchor primitive for inline navigation —\n * privacy / terms in form copy, external \"remote support\" links in\n * sidebars, in-paragraph references inside info-tip body copy.\n *\n * For action affordances that *look* like a link but trigger UI rather\n * than navigation, use `<Button intent=\"link\">` instead — the semantic\n * boundary matters for screen readers and keyboard users.\n */\nconst linkVariants = cva(\n [\n 'ds:underline-offset-4',\n 'ds:rounded-[var(--radius-xs)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50 ds:aria-disabled:no-underline',\n ].join(' '),\n {\n variants: {\n intent: {\n // `--primary` already maps to `magenta-700` in light-accent and\n // `magenta-500` in dark (see tokens/index.css), so the accent\n // contrast trade-off in §11 of CLAUDE.md is handled at the\n // token layer, not here.\n default:\n 'ds:text-primary ds:underline ds:hover:text-primary-hover ds:active:opacity-80',\n subtle:\n 'ds:text-muted-foreground ds:no-underline ds:hover:text-foreground ds:hover:underline ds:active:opacity-80',\n inverted:\n 'ds:text-primary-foreground ds:underline ds:hover:opacity-90 ds:active:opacity-80',\n },\n weight: {\n normal: 'ds:font-normal',\n strong: 'ds:font-semibold',\n },\n // When the link carries an icon, the anchor itself becomes a flex\n // container so glyphs centre on the text optical centre — the\n // previous `vertical-align: -0.125em` heuristic over-corrected when\n // the link was the only thing on its line (e.g. each <li> of a\n // vertical sidebar nav). Text-only links remain plain `inline` so\n // they wrap naturally inside a paragraph.\n hasIcon: {\n no: 'ds:inline',\n yes: 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]',\n },\n },\n defaultVariants: {\n intent: 'default',\n weight: 'normal',\n hasIcon: 'no',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface LinkProps\n extends\n Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>,\n VariantProps<typeof linkVariants> {\n /** Anchor target. Required — the whole point of the component. */\n href: string;\n /**\n * Flag the link as opening in a new browsing context. Automatically\n * adds `target=\"_blank\"` + `rel=\"noopener noreferrer\"` and renders a\n * trailing `ExternalLink` icon with an i18n'd aria-label.\n */\n external?: boolean;\n /**\n * Render the link in a non-interactive disabled state. Strips `href`,\n * adds `aria-disabled` + `role=\"link\"`, suppresses the underline.\n * Prefer hiding the link entirely when possible — disabled links are\n * a usability anti-pattern outside of state-machine flows.\n */\n disabled?: boolean;\n /** Optional leading icon (inline-start). */\n startIcon?: ReactNode;\n /** Optional trailing icon (inline-end). Ignored when `external`. */\n endIcon?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>(\n (\n {\n href,\n external = false,\n disabled = false,\n startIcon,\n endIcon,\n intent,\n weight,\n className,\n children,\n target,\n rel,\n onClick,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const effectiveTarget = external ? '_blank' : target;\n const effectiveRel = external\n ? [rel, 'noopener', 'noreferrer'].filter(Boolean).join(' ')\n : rel;\n\n const externalLabel = t('link.opensInNewTab', 'Opens in a new tab');\n\n const handleClick: AnchorHTMLAttributes<HTMLAnchorElement>['onClick'] = (\n event,\n ) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n onClick?.(event);\n };\n\n const hasIcon = Boolean(startIcon || endIcon || external);\n\n return (\n <a\n ref={ref}\n // When disabled, drop href so the link is not actionable; pair\n // with aria-disabled + role=\"link\" so AT still announces the\n // role (the implicit role disappears once href is removed).\n href={disabled ? undefined : href}\n role={disabled ? 'link' : undefined}\n aria-disabled={disabled || undefined}\n target={effectiveTarget}\n rel={effectiveRel || undefined}\n onClick={handleClick}\n data-component=\"link\"\n data-intent={intent ?? 'default'}\n className={linkVariants({\n intent,\n weight,\n hasIcon: hasIcon ? 'yes' : 'no',\n className,\n })}\n {...rest}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:[&_svg]:size-[1em]\"\n >\n {startIcon}\n </span>\n ) : null}\n {children}\n {external ? (\n <span\n className=\"ds:inline-flex ds:items-center\"\n aria-label={externalLabel}\n >\n <ExternalLink aria-hidden=\"true\" className=\"ds:size-[1em]\" />\n </span>\n ) : endIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:[&_svg]:size-[1em]\"\n >\n {endIcon}\n </span>\n ) : null}\n </a>\n );\n },\n);\n\nLink.displayName = 'Link';\n"],"names":["linkVariants","cva","Link","forwardRef","href","external","disabled","startIcon","endIcon","intent","weight","className","children","target","rel","onClick","rest","ref","t","useTranslation","effectiveTarget","effectiveRel","externalLabel","jsxs","event","jsx","ExternalLink"],"mappings":";;;;;AAkBA,MAAMA,IAAeC;AAAA,EACnB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,QAKN,SACE;AAAA,QACF,QACE;AAAA,QACF,UACE;AAAA,MAAA;AAAA,MAEJ,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQV,SAAS;AAAA,QACP,IAAI;AAAA,QACJ,KAAK;AAAA,MAAA;AAAA,IACP;AAAA,IAEF,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GAmCaC,IAAOC;AAAA,EAClB,CACE;AAAA,IACE,MAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,SAAAC;AAAA,IACA,QAAAC;AAAA,IACA,QAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,QAAAC;AAAA,IACA,KAAAC;AAAA,IACA,SAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAM,EAAE,GAAAC,EAAA,IAAMC,EAAA,GAERC,IAAkBf,IAAW,WAAWQ,GACxCQ,IAAehB,IACjB,CAACS,GAAK,YAAY,YAAY,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,IACxDA,GAEEQ,IAAgBJ,EAAE,sBAAsB,oBAAoB;AAclE,WACE,gBAAAK;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAN;AAAA,QAIA,MAAMX,IAAW,SAAYF;AAAA,QAC7B,MAAME,IAAW,SAAS;AAAA,QAC1B,iBAAeA,KAAY;AAAA,QAC3B,QAAQc;AAAA,QACR,KAAKC,KAAgB;AAAA,QACrB,SAvBoE,CACtEG,MACG;AACH,cAAIlB,GAAU;AACZ,YAAAkB,EAAM,eAAA;AACN;AAAA,UACF;AACA,UAAAT,KAAA,QAAAA,EAAUS;AAAA,QACZ;AAAA,QAgBI,kBAAe;AAAA,QACf,eAAaf,KAAU;AAAA,QACvB,WAAWT,EAAa;AAAA,UACtB,QAAAS;AAAA,UACA,QAAAC;AAAA,UACA,SAnBU,GAAQH,KAAaC,KAAWH,KAmBvB,QAAQ;AAAA,UAC3B,WAAAM;AAAA,QAAA,CACD;AAAA,QACA,GAAGK;AAAA,QAEH,UAAA;AAAA,UAAAT,IACC,gBAAAkB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,eAAY;AAAA,cACZ,WAAU;AAAA,cAET,UAAAlB;AAAA,YAAA;AAAA,UAAA,IAED;AAAA,UACHK;AAAA,UACAP,IACC,gBAAAoB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,cAAYH;AAAA,cAEZ,UAAA,gBAAAG,EAACC,GAAA,EAAa,eAAY,QAAO,WAAU,gBAAA,CAAgB;AAAA,YAAA;AAAA,UAAA,IAE3DlB,IACF,gBAAAiB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,eAAY;AAAA,cACZ,WAAU;AAAA,cAET,UAAAjB;AAAA,YAAA;AAAA,UAAA,IAED;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AAEAN,EAAK,cAAc;"}
|