@jasonshimmy/cer-material 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +989 -0
  2. package/dist/components/md-app-bar.d.ts +1 -0
  3. package/dist/components/md-badge.d.ts +1 -0
  4. package/dist/components/md-bottom-sheet.d.ts +1 -0
  5. package/dist/components/md-button-group.d.ts +1 -0
  6. package/dist/components/md-button.d.ts +1 -0
  7. package/dist/components/md-card.d.ts +1 -0
  8. package/dist/components/md-carousel.d.ts +1 -0
  9. package/dist/components/md-checkbox.d.ts +1 -0
  10. package/dist/components/md-chip.d.ts +1 -0
  11. package/dist/components/md-date-picker.d.ts +1 -0
  12. package/dist/components/md-dialog.d.ts +1 -0
  13. package/dist/components/md-divider.d.ts +1 -0
  14. package/dist/components/md-fab-menu.d.ts +1 -0
  15. package/dist/components/md-fab.d.ts +1 -0
  16. package/dist/components/md-icon-button.d.ts +1 -0
  17. package/dist/components/md-list.d.ts +1 -0
  18. package/dist/components/md-loading-indicator.d.ts +1 -0
  19. package/dist/components/md-menu.d.ts +1 -0
  20. package/dist/components/md-navigation-bar.d.ts +1 -0
  21. package/dist/components/md-navigation-drawer.d.ts +1 -0
  22. package/dist/components/md-navigation-rail.d.ts +1 -0
  23. package/dist/components/md-progress.d.ts +1 -0
  24. package/dist/components/md-radio.d.ts +1 -0
  25. package/dist/components/md-search.d.ts +1 -0
  26. package/dist/components/md-segmented-button.d.ts +1 -0
  27. package/dist/components/md-side-sheet.d.ts +1 -0
  28. package/dist/components/md-slider.d.ts +1 -0
  29. package/dist/components/md-snackbar.d.ts +1 -0
  30. package/dist/components/md-split-button.d.ts +1 -0
  31. package/dist/components/md-switch.d.ts +1 -0
  32. package/dist/components/md-tabs.d.ts +1 -0
  33. package/dist/components/md-text-field.d.ts +1 -0
  34. package/dist/components/md-time-picker.d.ts +1 -0
  35. package/dist/components/md-tooltip.d.ts +1 -0
  36. package/dist/composables/useControlledValue.d.ts +14 -0
  37. package/dist/composables/useEscapeKey.d.ts +16 -0
  38. package/dist/composables/useFocusReturn.d.ts +18 -0
  39. package/dist/composables/useFocusTrap.d.ts +31 -0
  40. package/dist/composables/useListKeyNav.d.ts +42 -0
  41. package/dist/composables/useScrollLock.d.ts +4 -0
  42. package/dist/index.cjs +5030 -0
  43. package/dist/index.cjs.map +1 -0
  44. package/dist/index.d.ts +7 -0
  45. package/dist/index.js +6250 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/theme.cjs +137 -0
  48. package/dist/theme.cjs.map +1 -0
  49. package/dist/theme.d.ts +14 -0
  50. package/dist/theme.js +148 -0
  51. package/dist/theme.js.map +1 -0
  52. package/dist/vite.svg +1 -0
  53. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/components/md-app-bar.ts","../src/components/md-badge.ts","../src/composables/useEscapeKey.ts","../src/composables/useFocusTrap.ts","../src/composables/useScrollLock.ts","../src/components/md-bottom-sheet.ts","../src/components/md-button-group.ts","../src/components/md-button.ts","../src/components/md-card.ts","../src/components/md-carousel.ts","../src/components/md-checkbox.ts","../src/components/md-chip.ts","../src/components/md-date-picker.ts","../src/components/md-dialog.ts","../src/components/md-divider.ts","../src/components/md-fab-menu.ts","../src/components/md-fab.ts","../src/components/md-icon-button.ts","../src/components/md-list.ts","../src/components/md-loading-indicator.ts","../src/composables/useListKeyNav.ts","../src/composables/useFocusReturn.ts","../src/components/md-menu.ts","../src/components/md-navigation-bar.ts","../src/components/md-navigation-drawer.ts","../src/components/md-navigation-rail.ts","../src/components/md-progress.ts","../src/components/md-radio.ts","../src/components/md-search.ts","../src/components/md-segmented-button.ts","../src/components/md-side-sheet.ts","../src/components/md-slider.ts","../src/components/md-snackbar.ts","../src/components/md-split-button.ts","../src/components/md-switch.ts","../src/components/md-tabs.ts","../src/components/md-text-field.ts","../src/components/md-time-picker.ts","../src/components/md-tooltip.ts","../src/composables/useControlledValue.ts"],"sourcesContent":["import { component, html, css, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-app-bar', () => {\n const props = useProps({\n variant: 'small' as 'small' | 'medium' | 'large' | 'center',\n title: '',\n leadingIcon: 'menu',\n trailingIcons: [] as string[],\n scrolled: false,\n });\n const emit = useEmit();\n\n useStyle(() => css`\n :host { display: block; }\n\n .app-bar {\n background: var(--md-sys-color-surface, #FFFBFE);\n display: flex;\n align-items: center;\n width: 100%;\n transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1),\n background-color 280ms;\n }\n .app-bar.scrolled {\n background: var(--md-sys-color-surface-container, #F3EDF7);\n box-shadow: var(--md-sys-elevation-2);\n }\n\n /* ── Small / Center ── */\n .small, .center {\n height: 64px;\n padding: 0 4px;\n flex-direction: row;\n gap: 4px;\n }\n\n /* ── Medium ── */\n .medium {\n min-height: 112px;\n padding: 8px 4px 20px;\n flex-direction: column;\n align-items: flex-start;\n }\n .medium .top-row {\n display: flex;\n align-items: center;\n width: 100%;\n padding: 0;\n height: 64px;\n }\n .medium .title {\n padding: 0 16px;\n font-size: 24px;\n line-height: 32px;\n }\n\n /* ── Large ── */\n .large {\n min-height: 152px;\n padding: 8px 4px 28px;\n flex-direction: column;\n align-items: flex-start;\n }\n .large .top-row {\n display: flex;\n align-items: center;\n width: 100%;\n height: 64px;\n }\n .large .title {\n padding: 0 16px;\n font-size: 28px;\n line-height: 36px;\n }\n\n .icon-btn {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n outline: none;\n position: relative;\n overflow: hidden;\n flex-shrink: 0;\n }\n .icon-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .icon-btn:hover::before { opacity: 0.08; }\n .icon-btn:focus::before { opacity: 0.12; }\n .icon-btn:active::before { opacity: 0.12; }\n\n .nav-icon,\n .action-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n\n .title-area {\n flex: 1;\n overflow: hidden;\n }\n\n .title {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 22px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 4px;\n }\n\n .center .title-area { text-align: center; }\n\n .trailing-actions {\n display: flex;\n align-items: center;\n gap: 0;\n flex-shrink: 0;\n }\n\n .top-row { display: flex; align-items: center; width: 100%; }\n `);\n\n const isColumn = props.variant === 'medium' || props.variant === 'large';\n const safeTrailingIcons = Array.isArray(props.trailingIcons) ? props.trailingIcons : [];\n\n return html`\n <header :class=\"${{\n 'app-bar': true,\n [props.variant]: true,\n scrolled: props.scrolled,\n }}\">\n <div class=\"top-row\">\n ${when(!!props.leadingIcon, () => html`\n <button type=\"button\" class=\"icon-btn\" aria-label=\"Navigation\" @click=\"${() => emit('nav')}\">\n <span class=\"nav-icon\" aria-hidden=\"true\">${props.leadingIcon}</span>\n </button>\n `)}\n\n ${when(!isColumn, () => html`\n <div class=\"title-area\">\n <span class=\"title\">${props.title}<slot name=\"title\"></slot></span>\n </div>\n `)}\n\n <div class=\"trailing-actions\">\n <slot name=\"trailing\"></slot>\n ${safeTrailingIcons.map((icon: string) => html`\n <button type=\"button\" class=\"icon-btn\" aria-label=\"${icon}\" @click=\"${() => emit('action', icon)}\">\n <span class=\"action-icon\" aria-hidden=\"true\">${icon}</span>\n </button>\n `)}\n </div>\n </div>\n\n ${when(isColumn, () => html`\n <div class=\"title-area\">\n <span class=\"title\">${props.title}<slot name=\"title\"></slot></span>\n </div>\n `)}\n </header>\n `;\n});\n","import { component, html, css, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-badge', () => {\n const props = useProps({\n value: '' as string | number,\n small: false,\n });\n\n useStyle(() => css`\n :host { display: inline-block; position: relative; }\n\n .host-wrapper { position: relative; display: inline-flex; }\n\n .badge {\n position: absolute;\n top: -4px;\n right: -4px;\n background: var(--md-sys-color-error, #B3261E);\n color: var(--md-sys-color-on-error, #fff);\n border-radius: 99px;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n z-index: 1;\n }\n .badge.small {\n width: 6px;\n height: 6px;\n top: -2px;\n right: -2px;\n }\n .badge.large {\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n }\n `);\n\n return html`\n <div class=\"host-wrapper\">\n <slot></slot>\n ${when(props.small || !!props.value, () => html`\n <span :class=\"${{ badge: true, small: props.small, large: !props.small }}\" aria-hidden=\"true\">\n ${when(!props.small, () => html`${String(props.value)}`)}\n </span>\n `)}\n </div>\n `;\n});\n","import { createComposable, useOnConnected, useOnDisconnected } from '@jasonshimmy/custom-elements-runtime';\n\n/**\n * Registers a document-level `keydown` listener for the Escape key that fires\n * for the lifetime of the host element. The provided `guard` function is\n * called on every keydown; when it returns `true` the event is cancelled and\n * `onEscape` is invoked.\n *\n * Using `createComposable` ensures the lifecycle hooks are bound to the correct\n * component context even when called from outside the component render closure.\n *\n * @example\n * useEscapeKey(\n * () => props.open, // guard: only active when open\n * () => emit('close'),\n * )();\n */\nexport function useEscapeKey(guard: () => boolean, onEscape: () => void) {\n return createComposable(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n if (!guard()) return;\n e.preventDefault();\n onEscape();\n };\n\n useOnConnected(() => { document.addEventListener('keydown', handler); });\n useOnDisconnected(() => { document.removeEventListener('keydown', handler); });\n });\n}\n","import { getCurrentComponentContext } from '@jasonshimmy/custom-elements-runtime';\n\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n 'details > summary:not([disabled])',\n].join(', ');\n\nfunction isVisible(el: HTMLElement): boolean {\n if ((el as unknown as { hidden?: boolean }).hidden) return false;\n const s = getComputedStyle(el);\n return s.display !== 'none' && s.visibility !== 'hidden';\n}\n\n/**\n * Recursively collects focusable elements, drilling into:\n * - Shadow roots of custom elements (e.g. the <button> inside <md-button>)\n * - Slotted light-DOM elements assigned to any <slot>\n *\n * This ensures the focus trap works even when all interactive elements are\n * custom components (like <md-button>) rather than native HTML elements.\n */\nfunction collectDeepTabbables(root: Element | ShadowRoot, out: HTMLElement[]): void {\n for (const child of Array.from(root.children)) {\n const el = child as HTMLElement;\n if (el.tagName === 'SLOT') {\n for (const assigned of (el as HTMLSlotElement).assignedElements({ flatten: true })) {\n collectDeepTabbables(assigned, out);\n }\n } else if (el.shadowRoot) {\n // Custom element: focus lands on its internal focusable, not the host\n collectDeepTabbables(el.shadowRoot, out);\n } else if (el.matches(FOCUSABLE) && isVisible(el)) {\n out.push(el);\n } else {\n collectDeepTabbables(el, out);\n }\n }\n}\n\nfunction getFocusableDeep(container: Element | ShadowRoot): HTMLElement[] {\n const out: HTMLElement[] = [];\n collectDeepTabbables(container, out);\n return out;\n}\n\nfunction getDeepActiveElement(): HTMLElement | null {\n let el: Element | null = document.activeElement;\n while (el?.shadowRoot?.activeElement) el = el.shadowRoot.activeElement;\n return el as HTMLElement | null;\n}\n\n/**\n * Creates a focus trap for an overlay.\n *\n * Wire the returned callbacks directly into a CER `Transition`:\n * `onAfterEnter: trap.onAfterEnter, onAfterLeave: trap.onAfterLeave`\n *\n * State is stored on the component context so it survives re-renders without\n * losing the saved \"previous focus\" element or leaking event listeners.\n *\n * Behaviour:\n * - `onAfterEnter(el)`: saves the currently focused element, registers a\n * Tab/Shift+Tab keydown guard, and focuses the first tabbable inside `el`.\n * - `onAfterLeave()`: removes the keydown guard and restores focus to the\n * previously focused element.\n * - `cleanup()`: removes the keydown guard — call from `useOnDisconnected`\n * to avoid leaks if the component is removed while the overlay is open.\n *\n * Drills into shadow roots so nested custom elements (e.g. `<md-button>`)\n * are discovered and included in the tab cycle.\n *\n * @example\n * const trap = createFocusTrap();\n * useOnDisconnected(() => trap.cleanup());\n * // In template:\n * Transition({ show: props.open, onAfterEnter: trap.onAfterEnter, onAfterLeave: trap.onAfterLeave }, html`...`)\n */\nexport function createFocusTrap() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctx = getCurrentComponentContext() as any;\n\n // Persist state on the context — the context object lives for the lifetime\n // of the component instance and survives re-renders, so onAfterLeave always\n // reads the previousFocus that onAfterEnter saved even if a re-render\n // occurred in between.\n if (!ctx.__mdFocusTrap) {\n const state = {\n container: null as Element | null,\n previousFocus: null as HTMLElement | null,\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab' || !state.container) return;\n const focusable = getFocusableDeep(state.container);\n if (!focusable.length) return;\n const active = getDeepActiveElement();\n const idx = active ? focusable.indexOf(active) : -1;\n if (e.shiftKey) {\n if (idx <= 0) { e.preventDefault(); focusable[focusable.length - 1].focus(); }\n } else {\n if (idx === focusable.length - 1 || idx < 0) { e.preventDefault(); focusable[0].focus(); }\n }\n };\n\n ctx.__mdFocusTrap = {\n onAfterEnter(el: HTMLElement) {\n state.container = el;\n state.previousFocus = getDeepActiveElement();\n document.addEventListener('keydown', handleKeyDown);\n getFocusableDeep(el)[0]?.focus();\n },\n onAfterLeave() {\n document.removeEventListener('keydown', handleKeyDown);\n state.previousFocus?.focus();\n state.previousFocus = null;\n state.container = null;\n },\n cleanup() {\n document.removeEventListener('keydown', handleKeyDown);\n state.container = null;\n },\n };\n }\n\n return ctx.__mdFocusTrap as {\n onAfterEnter: (el: HTMLElement) => void;\n onAfterLeave: () => void;\n cleanup: () => void;\n };\n}\n\n","// Global reference counter so multiple overlays stacking don't conflict.\nlet lockCount = 0;\nlet savedOverflow = '';\nlet savedPaddingRight = '';\n\nexport function useScrollLock() {\n return {\n lock() {\n if (lockCount === 0) {\n // Measure scrollbar width before hiding overflow so we can compensate\n // and prevent layout shift when the scrollbar disappears.\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n savedOverflow = document.body.style.overflow;\n savedPaddingRight = document.body.style.paddingRight;\n document.body.style.overflow = 'hidden';\n if (scrollbarWidth > 0) {\n const current = parseFloat(savedPaddingRight) || 0;\n document.body.style.paddingRight = `${current + scrollbarWidth}px`;\n }\n }\n lockCount++;\n },\n unlock() {\n if (lockCount <= 0) return;\n lockCount--;\n if (lockCount === 0) {\n document.body.style.overflow = savedOverflow;\n document.body.style.paddingRight = savedPaddingRight;\n }\n },\n };\n}\n","import { component, html, css, defineModel, useProps, useEmit, useStyle, useOnDisconnected } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { createFocusTrap } from '../composables/useFocusTrap';\nimport { useScrollLock } from '../composables/useScrollLock';\n\ncomponent('md-bottom-sheet', () => {\n const props = useProps({\n headline: '',\n showHandle: true,\n variant: 'standard' as 'standard' | 'modal',\n });\n const emit = useEmit();\n const open = defineModel('open', false);\n\n // ── Drag-to-dismiss (plain mutable state — no re-renders needed) ──────\n let sheetEl: HTMLElement | null = null;\n let dragStartY = 0;\n let dragStartTime = 0;\n let isDragging = false;\n // Set to true by the drag dismiss path so onBeforeLeave skips a redundant animation.\n let dragDismissed = false;\n // Holds the element reference between transitionend and onBeforeLeave so\n // the hook can disable the leave transition without relying on sheetEl\n // (which is nulled out at the end of onHandlePointerUp).\n let dismissedEl: HTMLElement | null = null;\n\n // Thresholds per MD3 spec guidance:\n // dismiss if dragged more than 40% of sheet height, or flicked fast.\n const DISMISS_RATIO = 0.4; // fraction of sheet height\n const DISMISS_VELOCITY = 500; // px / s\n\n function onHandlePointerDown(e: PointerEvent) {\n if (!open.value) return;\n const handle = e.currentTarget as HTMLElement;\n sheetEl = (handle.closest('.modal-bottom-sheet') ?? handle.closest('.standard-bottom-sheet')) as HTMLElement | null;\n if (!sheetEl) return;\n\n isDragging = true;\n dragStartY = e.clientY;\n dragStartTime = performance.now();\n\n // Disable the CSS transition while the finger is down so the sheet\n // tracks the pointer with zero lag.\n sheetEl.style.transition = 'none';\n // Route all subsequent pointer events to this element (works across\n // shadow-DOM boundary and when the pointer leaves the handle bounds).\n handle.setPointerCapture(e.pointerId);\n e.preventDefault();\n }\n\n function onHandlePointerMove(e: PointerEvent) {\n if (!isDragging || !sheetEl) return;\n // Only allow downward translation (clamp negative deltas to 0).\n const delta = Math.max(0, e.clientY - dragStartY);\n sheetEl.style.transform = `translateY(${delta}px)`;\n }\n\n function onHandlePointerUp(e: PointerEvent) {\n if (!isDragging || !sheetEl) return;\n isDragging = false;\n\n const delta = Math.max(0, e.clientY - dragStartY);\n const elapsed = (performance.now() - dragStartTime) / 1000; // seconds\n const velocity = elapsed > 0 ? delta / elapsed : 0;\n\n const shouldDismiss =\n delta > sheetEl.offsetHeight * DISMISS_RATIO ||\n velocity > DISMISS_VELOCITY;\n\n // Re-enable the CSS transition for snap-back.\n sheetEl.style.transition = '';\n\n if (shouldDismiss) {\n // Explicitly set the transition inline for the off-screen slide — the\n // CER leave classes (sheet-leave-active) haven't been applied yet at\n // this point, so clearing the inline transition above would leave no\n // active transition and the transform change would be instant.\n sheetEl.style.transition = 'transform 300ms cubic-bezier(0.4, 0, 0.2, 1)';\n sheetEl.style.transform = 'translateY(100%)';\n const target = sheetEl;\n const onEnd = () => {\n target.removeEventListener('transitionend', onEnd);\n // Mark as drag-dismissed so the Transition onBeforeLeave hook skips\n // its own animation — the sheet is already off-screen at this point.\n // Do NOT clear the inline transform here; clearing it would snap the\n // sheet back to translateY(0) before the leave animation begins.\n dragDismissed = true;\n dismissedEl = target;\n emit('close');\n open.value = false; };\n target.addEventListener('transitionend', onEnd);\n } else {\n // Snap back to fully open.\n sheetEl.style.transform = '';\n }\n sheetEl = null;\n }\n\n const handleEscKey = () => { emit('close'); open.value = false; };\n\n // Only modal variant uses escape key, focus trap, and scroll lock.\n useEscapeKey(() => open.value && props.variant === 'modal', handleEscKey)();\n const trap = createFocusTrap();\n useOnDisconnected(() => trap.cleanup());\n const scrollLock = useScrollLock();\n\n useStyle(() => css`\n :host { display: contents; }\n\n /* ── Scrim (modal only) ─────────────────────────────────────── */\n .scrim {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.32);\n z-index: 500;\n }\n .scrim-enter-from, .scrim-leave-to {\n opacity: 0;\n pointer-events: none;\n }\n .scrim-enter-active, .scrim-leave-active {\n transition: opacity 250ms ease-out;\n }\n\n /* ── Modal bottom sheet: overlays content with scrim ─────────── */\n .modal-bottom-sheet {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n max-height: 90vh;\n background: var(--md-sys-color-surface-container-low, #F7F2FA);\n border-radius: 28px 28px 0 0;\n z-index: 501;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .modal-enter-from, .modal-leave-to {\n transform: translateY(100%);\n pointer-events: none;\n }\n .modal-enter-active, .modal-leave-active {\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* ── Standard bottom sheet: coexists with primary content ────── */\n .standard-bottom-sheet {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n max-height: 90vh;\n background: var(--md-sys-color-surface-container-low, #F7F2FA);\n border-radius: 28px 28px 0 0;\n z-index: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .standard-enter-from, .standard-leave-to {\n transform: translateY(100%);\n pointer-events: none;\n }\n .standard-enter-active, .standard-leave-active {\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .drag-handle {\n display: flex;\n justify-content: center;\n align-items: center;\n /* 48px minimum touch target (MD3 spec). Pill is vertically centred inside. */\n min-height: 48px;\n flex-shrink: 0;\n cursor: grab;\n /* Prevent the browser from hijacking the vertical gesture as a page scroll. */\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n }\n .drag-handle:active { cursor: grabbing; }\n .drag-handle-bar {\n width: 32px;\n height: 4px;\n border-radius: 2px;\n background: var(--md-sys-color-on-surface-variant, #49454F);\n opacity: 0.4;\n /* Slightly scale up on active for tactile feedback. */\n transition: transform 100ms ease, opacity 100ms ease;\n }\n .drag-handle:active .drag-handle-bar {\n transform: scaleX(1.15);\n opacity: 0.6;\n }\n\n .sheet-header {\n padding: 16px 24px 8px;\n flex-shrink: 0;\n }\n .sheet-headline {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 24px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n margin: 0;\n }\n\n .sheet-content {\n overflow-y: auto;\n padding: 8px 24px 24px;\n flex: 1;\n }\n `);\n\n // Scrim and sheet panel are conditionally mounted via Transition so the DOM\n // is clean when closed. The drag-dismiss flag prevents a double leave animation.\n return html`\n ${Transition({\n show: open.value && props.variant === 'modal',\n name: 'md-scrim',\n enterFrom: 'scrim-enter-from',\n enterActive: 'scrim-enter-active',\n leaveActive: 'scrim-leave-active',\n leaveTo: 'scrim-leave-to',\n }, html`\n <div\n class=\"scrim\"\n @click=\"${() => { emit('close'); open.value = false; }}\"\n ></div>\n `)}\n\n ${props.variant === 'modal'\n ? Transition({\n show: open.value,\n name: 'md-modal-sheet',\n enterFrom: 'modal-enter-from',\n enterActive: 'modal-enter-active',\n leaveActive: 'modal-leave-active',\n leaveTo: 'modal-leave-to',\n onBeforeLeave: () => {\n if (dragDismissed) {\n dragDismissed = false;\n if (dismissedEl) {\n dismissedEl.style.transition = 'none';\n dismissedEl = null;\n }\n }\n },\n onBeforeEnter: scrollLock.lock,\n onAfterEnter: trap.onAfterEnter,\n onAfterLeave: () => { trap.onAfterLeave(); scrollLock.unlock(); },\n }, html`\n <div\n class=\"modal-bottom-sheet\"\n role=\"dialog\"\n aria-modal=\"true\"\n :bind=\"${{ 'aria-labelledby': props.headline ? 'bottom-sheet-headline' : null }}\"\n >\n ${when(props.showHandle, () => html`\n <div\n class=\"drag-handle\"\n role=\"button\"\n aria-label=\"Drag down to dismiss\"\n tabindex=\"0\"\n @pointerdown=\"${onHandlePointerDown}\"\n @pointermove=\"${onHandlePointerMove}\"\n @pointerup=\"${onHandlePointerUp}\"\n @pointercancel=\"${onHandlePointerUp}\"\n @keydown=\"${(e: KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); emit('close'); open.value = false; } }}\"\n >\n <div class=\"drag-handle-bar\"></div>\n </div>\n `)}\n ${when(!!props.headline, () => html`\n <div class=\"sheet-header\">\n <h2 class=\"sheet-headline\" id=\"bottom-sheet-headline\">${props.headline}</h2>\n </div>\n `)}\n <div class=\"sheet-content\">\n <slot></slot>\n </div>\n </div>\n `)\n : Transition({\n show: open.value,\n name: 'md-standard-sheet',\n enterFrom: 'standard-enter-from',\n enterActive: 'standard-enter-active',\n leaveActive: 'standard-leave-active',\n leaveTo: 'standard-leave-to',\n onBeforeLeave: () => {\n if (dragDismissed) {\n dragDismissed = false;\n if (dismissedEl) {\n dismissedEl.style.transition = 'none';\n dismissedEl = null;\n }\n }\n },\n }, html`\n <div\n class=\"standard-bottom-sheet\"\n role=\"complementary\"\n :bind=\"${{ 'aria-labelledby': props.headline ? 'bottom-sheet-headline' : null }}\"\n >\n ${when(props.showHandle, () => html`\n <div\n class=\"drag-handle\"\n role=\"button\"\n aria-label=\"Drag down to collapse\"\n tabindex=\"0\"\n @pointerdown=\"${onHandlePointerDown}\"\n @pointermove=\"${onHandlePointerMove}\"\n @pointerup=\"${onHandlePointerUp}\"\n @pointercancel=\"${onHandlePointerUp}\"\n @keydown=\"${(e: KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); emit('close'); open.value = false; } }}\"\n >\n <div class=\"drag-handle-bar\"></div>\n </div>\n `)}\n ${when(!!props.headline, () => html`\n <div class=\"sheet-header\">\n <h2 class=\"sheet-headline\" id=\"bottom-sheet-headline\">${props.headline}</h2>\n </div>\n `)}\n <div class=\"sheet-content\">\n <slot></slot>\n </div>\n </div>\n `)\n }\n `;\n});\n","import { component, html, css, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when, each } from '@jasonshimmy/custom-elements-runtime/directives';\n\n/**\n * md-button-group\n *\n * MD3 Button groups — horizontally connected group of buttons that share borders.\n * Spec: https://m3.material.io/components/button-groups\n *\n * Props:\n * variant — 'filled' | 'outlined' | 'tonal' | 'text' | 'elevated'\n * disabled — disable all buttons\n * items — array of { id, label, icon?, disabled? }\n *\n * Emits:\n * click — { id, index }\n */\n\ninterface ButtonGroupItem {\n id: string;\n label: string;\n icon?: string;\n disabled?: boolean;\n}\n\ncomponent('md-button-group', () => {\n const props = useProps({\n variant: 'outlined' as 'filled' | 'outlined' | 'tonal' | 'text' | 'elevated',\n disabled: false,\n items: [] as ButtonGroupItem[],\n });\n const emit = useEmit();\n\n useStyle(() => css`\n :host { display: inline-flex; vertical-align: middle; }\n\n .group {\n display: inline-flex;\n align-items: stretch;\n }\n\n /* Each button in the group */\n .group-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n height: 40px;\n padding: 0 20px;\n border: none;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n line-height: 20px;\n outline: none;\n position: relative;\n overflow: hidden;\n transition: box-shadow 280ms cubic-bezier(0.4,0,0.2,1);\n user-select: none;\n white-space: nowrap;\n -webkit-font-smoothing: antialiased;\n /* Flatten adjacent radii to create connected look */\n border-radius: 0;\n }\n /* First button: round left corners */\n .group-btn:first-child { border-radius: 20px 0 0 20px; }\n /* Last button: round right corners */\n .group-btn:last-child { border-radius: 0 20px 20px 0; }\n /* Only child */\n .group-btn:only-child { border-radius: 20px; }\n\n .group-btn:disabled { cursor: not-allowed; pointer-events: none; }\n\n /* State layer */\n .group-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4,0,0.2,1);\n pointer-events: none;\n }\n .group-btn:hover::before { opacity: 0.08; }\n .group-btn:focus::before { opacity: 0.12; }\n .group-btn:active::before { opacity: 0.12; }\n .group-btn:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); outline-offset: 2px; z-index: 1; }\n\n /* ── Filled ── */\n .filled .group-btn {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n .filled .group-btn::before { background: var(--md-sys-color-on-primary, #FFFFFF); }\n .filled .group-btn:hover { box-shadow: var(--md-sys-elevation-1); }\n .filled .group-btn:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); }\n /* Divider between filled buttons */\n .filled .group-btn + .group-btn {\n border-left: 1px solid var(--md-sys-color-on-primary, #FFFFFF);\n opacity: 0.5;\n }\n\n /* ── Outlined ── */\n .outlined .group-btn {\n background: transparent;\n color: var(--md-sys-color-primary, #6750A4);\n border: 1px solid var(--md-sys-color-outline, #79747E);\n }\n .outlined .group-btn::before { background: var(--md-sys-color-primary, #6750A4); }\n /* Collapse adjacent borders */\n .outlined .group-btn + .group-btn { margin-left: -1px; }\n .outlined .group-btn:disabled { color: rgba(28,27,31,.38); border-color: rgba(28,27,31,.12); }\n\n /* ── Tonal ── */\n .tonal .group-btn {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n .tonal .group-btn::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n .tonal .group-btn:hover { box-shadow: var(--md-sys-elevation-1); }\n .tonal .group-btn + .group-btn {\n border-left: 1px solid var(--md-sys-color-on-secondary-container, #1D192B);\n opacity: 0.2;\n }\n .tonal .group-btn:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); }\n\n /* ── Text ── */\n .text .group-btn {\n background: transparent;\n color: var(--md-sys-color-primary, #6750A4);\n padding: 0 12px;\n }\n .text .group-btn::before { background: var(--md-sys-color-primary, #6750A4); }\n .text .group-btn + .group-btn {\n border-left: 1px solid var(--md-sys-color-outline-variant, #CAC4D0);\n }\n .text .group-btn:disabled { color: rgba(28,27,31,.38); }\n\n /* ── Elevated ── */\n .elevated .group-btn {\n background: var(--md-sys-color-surface-container-low, #F7F2FA);\n color: var(--md-sys-color-primary, #6750A4);\n box-shadow: var(--md-sys-elevation-1);\n }\n .elevated .group-btn::before { background: var(--md-sys-color-primary, #6750A4); }\n .elevated .group-btn:hover { box-shadow: var(--md-sys-elevation-2); }\n .elevated .group-btn + .group-btn {\n border-left: 1px solid var(--md-sys-color-outline-variant, #CAC4D0);\n }\n .elevated .group-btn:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); box-shadow: none; }\n\n /* Icon within button */\n .btn-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-style: normal;\n font-variation-settings: 'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 18;\n }\n `);\n\n return html`\n <div :class=\"${{ group: true, [props.variant]: true }}\" role=\"group\">\n ${each(props.items, (item, i) => html`\n <button\n class=\"group-btn\"\n aria-label=\"${item.label}\"\n ?disabled=\"${props.disabled || item.disabled}\"\n @click=\"${(e: Event) => { e.stopPropagation(); emit('click', { id: item.id, index: i }); }}\"\n >\n ${when(!!item.icon, () => html`<span class=\"btn-icon\" aria-hidden=\"true\">${item.icon}</span>`)}\n ${item.label}\n </button>\n `)}\n </div>\n `;\n});\n","import { component, html, css, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-button', () => {\n const props = useProps({\n variant: 'filled' as 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal',\n label: '',\n icon: '',\n type: 'button' as 'button' | 'submit' | 'reset',\n disabled: false,\n });\n useStyle(() => css`\n :host { display: inline-flex; vertical-align: middle; }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n height: 40px;\n padding: 0 24px;\n border-radius: 20px;\n border: none;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n line-height: 20px;\n outline: none;\n position: relative;\n overflow: hidden;\n transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n white-space: nowrap;\n -webkit-font-smoothing: antialiased;\n }\n button:disabled { cursor: not-allowed; pointer-events: none; }\n\n /* state layer */\n button::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n pointer-events: none;\n }\n button:hover::before { opacity: 0.08; }\n button:focus::before { opacity: 0.12; }\n button:active::before { opacity: 0.12; }\n\n /* ── Filled ── */\n .filled {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #fff);\n }\n .filled::before { background: var(--md-sys-color-on-primary, #fff); }\n .filled:hover { box-shadow: var(--md-sys-elevation-1); }\n .filled:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); box-shadow: none; }\n\n /* ── Outlined ── */\n .outlined {\n background: transparent;\n color: var(--md-sys-color-primary, #6750A4);\n border: 1px solid var(--md-sys-color-outline, #79747E);\n }\n .outlined::before { background: var(--md-sys-color-primary, #6750A4); }\n .outlined:disabled { border-color: rgba(28,27,31,.12); color: rgba(28,27,31,.38); }\n\n /* ── Text ── */\n .text {\n background: transparent;\n color: var(--md-sys-color-primary, #6750A4);\n padding: 0 12px;\n }\n .text::before { background: var(--md-sys-color-primary, #6750A4); }\n .text:disabled { color: rgba(28,27,31,.38); }\n\n /* ── Elevated ── */\n .elevated {\n background: var(--md-sys-color-surface-container-low, #F7F2FA);\n color: var(--md-sys-color-primary, #6750A4);\n box-shadow: var(--md-sys-elevation-1);\n }\n .elevated::before { background: var(--md-sys-color-primary, #6750A4); }\n .elevated:hover { box-shadow: var(--md-sys-elevation-2); }\n .elevated:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); box-shadow: none; }\n\n /* ── Tonal ── */\n .tonal {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n .tonal::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n .tonal:hover { box-shadow: var(--md-sys-elevation-1); }\n .tonal:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); box-shadow: none; }\n\n /* icon with text: reduce left padding for non-text variants; text variant swaps l/r */\n .has-icon { padding-left: 16px; }\n .text.has-icon { padding-left: 12px; padding-right: 16px; }\n\n .icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: 400;\n font-style: normal;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n }\n `);\n\n return html`\n <button\n :type=\"${props.type}\"\n :class=\"${{\n [props.variant]: true,\n 'has-icon': !!props.icon,\n }}\"\n :disabled=\"${props.disabled}\"\n >\n ${when(!!props.icon, () => html`<span class=\"icon\" aria-hidden=\"true\">${props.icon}</span>`)}\n ${props.label}<slot></slot>\n </button>\n `;\n});\n","import { component, html, css, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\n\ncomponent('md-card', () => {\n const props = useProps({\n variant: 'elevated' as 'elevated' | 'filled' | 'outlined',\n clickable: false,\n });\n const emit = useEmit();\n\n useStyle(() => css`\n :host { display: block; }\n\n .card {\n border-radius: 12px;\n overflow: hidden;\n position: relative;\n transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .card.clickable { cursor: pointer; }\n\n .card::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n pointer-events: none;\n }\n .card.clickable:hover::before { opacity: 0.08; }\n .card.clickable:focus::before { opacity: 0.12; }\n .card.clickable:active::before { opacity: 0.12; }\n\n /* ── Elevated ── */\n .elevated {\n background: var(--md-sys-color-surface-container-low, #F7F2FA);\n box-shadow: var(--md-sys-elevation-1);\n }\n .elevated::before { background: var(--md-sys-color-on-surface, #1C1B1F); }\n .elevated.clickable:hover { box-shadow: var(--md-sys-elevation-2); }\n\n /* ── Filled ── */\n .filled {\n background: var(--md-sys-color-surface-container-highest, #E6E0E9);\n }\n .filled::before { background: var(--md-sys-color-on-surface, #1C1B1F); }\n .filled.clickable:hover { box-shadow: var(--md-sys-elevation-1); }\n\n /* ── Outlined ── */\n .outlined {\n background: var(--md-sys-color-surface, #FFFBFE);\n border: 1px solid var(--md-sys-color-outline-variant, #CAC4D0);\n }\n .outlined::before { background: var(--md-sys-color-on-surface, #1C1B1F); }\n .outlined.clickable:hover { box-shadow: var(--md-sys-elevation-1); }\n `);\n\n return html`\n <div\n :class=\"${{\n card: true,\n [props.variant]: true,\n clickable: props.clickable,\n }}\"\n tabindex=\"${props.clickable ? '0' : undefined}\"\n :bind=\"${{ role: props.clickable ? 'button' : null }}\"\n @click=\"${() => props.clickable && emit('click')}\"\n @keydown=\"${(e: KeyboardEvent) => {\n if (props.clickable && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n emit('click');\n }\n }}\"\n >\n <slot></slot>\n </div>\n `;\n});\n","import { component, html, css, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { each, when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ninterface CarouselItem {\n id: string;\n headline?: string;\n supportingText?: string;\n image?: string;\n color?: string;\n}\n\ncomponent('md-carousel', () => {\n const props = useProps({\n items: [] as CarouselItem[],\n variant: 'multi-browse' as 'multi-browse' | 'uncontained' | 'full-screen',\n });\n const emit = useEmit();\n\n useStyle(() => css`\n :host { display: block; }\n\n .carousel {\n display: flex;\n gap: 8px;\n overflow-x: auto;\n scroll-snap-type: x mandatory;\n scrollbar-width: none;\n padding: 4px 0 8px;\n -webkit-overflow-scrolling: touch;\n }\n .carousel::-webkit-scrollbar { display: none; }\n\n .carousel-item {\n flex-shrink: 0;\n scroll-snap-align: start;\n border-radius: 16px;\n overflow: hidden;\n position: relative;\n cursor: pointer;\n transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .carousel-item:hover { transform: scale(1.02); }\n\n /* multi-browse: first item wide, rest smaller */\n .multi-browse .carousel-item { width: 160px; height: 220px; }\n .multi-browse .carousel-item:first-child { width: 220px; }\n\n .uncontained .carousel-item { width: 220px; height: 220px; }\n\n .full-screen .carousel-item {\n width: calc(100% - 32px);\n height: 320px;\n }\n\n .item-bg {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n\n .item-placeholder {\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--md-sys-color-surface-variant, #E7E0EC);\n }\n .placeholder-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 48px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 48;\n }\n\n .item-overlay {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n padding: 12px 16px;\n background: linear-gradient(transparent, rgba(0,0,0,0.55));\n color: #fff;\n }\n .item-headline {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n margin: 0;\n line-height: 20px;\n }\n .item-supporting {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 12px;\n font-weight: 400;\n margin: 0;\n opacity: 0.8;\n line-height: 16px;\n }\n `);\n\n return html`\n <div :class=\"${{ carousel: true, [props.variant]: true }}\" role=\"list\">\n ${each(\n Array.isArray(props.items) ? props.items : [],\n (item: CarouselItem) => html`\n <div key=\"${item.id}\" class=\"carousel-item\" role=\"listitem\" tabindex=\"0\" aria-label=\"${item.headline || item.id}\" @click=\"${() => emit('select', item.id)}\" @keydown=\"${(e: KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); emit('select', item.id); } }}\">\n ${item.image\n ? html`<img class=\"item-bg\" src=\"${item.image}\" alt=\"${item.headline || ''}\" loading=\"lazy\">`\n : html`\n <div class=\"item-placeholder\" style=\"${item.color ? 'background:' + item.color : ''}\">\n <span class=\"placeholder-icon\" aria-hidden=\"true\">image</span>\n </div>\n `\n }\n ${when(!!(item.headline || item.supportingText), () => html`\n <div class=\"item-overlay\">\n ${when(!!item.headline, () => html`<p class=\"item-headline\">${item.headline}</p>`)}\n ${when(!!item.supportingText, () => html`<p class=\"item-supporting\">${item.supportingText}</p>`)}\n </div>\n `)}\n </div>\n `,\n )}\n </div>\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\n\ncomponent('md-checkbox', () => {\n const props = useProps({\n indeterminate: false,\n disabled: false,\n label: '',\n });\n const emit = useEmit();\n const checked = defineModel('checked', false);\n\n useStyle(() => css`\n :host { display: inline-flex; align-items: center; vertical-align: middle; }\n\n label {\n display: inline-flex;\n align-items: center;\n gap: 12px;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n user-select: none;\n }\n label.disabled { opacity: 0.38; cursor: not-allowed; }\n\n .checkbox-container {\n width: 40px;\n height: 40px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n position: relative;\n flex-shrink: 0;\n }\n .checkbox-container::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .checkbox-container.checked::before,\n .checkbox-container.indeterminate::before {\n background: var(--md-sys-color-primary, #6750A4);\n }\n label:hover .checkbox-container::before { opacity: 0.08; }\n label:focus-within .checkbox-container::before { opacity: 0.12; }\n label:active .checkbox-container::before { opacity: 0.12; }\n\n input[type=\"checkbox\"] {\n position: absolute;\n opacity: 0;\n width: 40px;\n height: 40px;\n margin: 0;\n cursor: pointer;\n }\n input[type=\"checkbox\"]:disabled { cursor: not-allowed; }\n\n .box {\n width: 18px;\n height: 18px;\n border-radius: 2px;\n border: 2px solid var(--md-sys-color-on-surface-variant, #49454F);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 200ms, border-color 200ms;\n position: relative;\n flex-shrink: 0;\n }\n .checked .box,\n .indeterminate .box {\n background: var(--md-sys-color-primary, #6750A4);\n border-color: var(--md-sys-color-primary, #6750A4);\n }\n\n .check-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 14px;\n font-weight: 700;\n font-style: normal;\n color: var(--md-sys-color-on-primary, #fff);\n display: none;\n line-height: 1;\n font-variation-settings: 'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 20;\n }\n .checked .check-icon { display: block; }\n .indeterminate .check-icon { display: block; }\n `);\n\n return html`\n <label :class=\"${{ disabled: props.disabled }}\">\n <div :class=\"${{\n 'checkbox-container': true,\n checked: checked.value,\n indeterminate: props.indeterminate,\n }}\">\n <input\n type=\"checkbox\"\n :checked=\"${checked.value}\"\n :disabled=\"${props.disabled}\"\n :bind=\"${{ indeterminate: props.indeterminate }}\"\n @change=\"${(e: Event) => { emit('change', (e.target as HTMLInputElement).checked); checked.value = (e.target as HTMLInputElement).checked; }}\"\n />\n <div class=\"box\">\n <span class=\"check-icon\" aria-hidden=\"true\">${props.indeterminate ? 'remove' : 'check'}</span>\n </div>\n </div>\n ${props.label}\n </label>\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-chip', () => {\n const props = useProps({\n variant: 'assist' as 'assist' | 'filter' | 'input' | 'suggestion',\n label: '',\n icon: '',\n disabled: false,\n });\n const emit = useEmit();\n const selected = defineModel('selected', false);\n\n useStyle(() => css`\n :host { display: inline-flex; vertical-align: middle; }\n\n .chip {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 32px;\n padding: 0 16px;\n border-radius: 8px;\n border: 1px solid var(--md-sys-color-outline, #79747E);\n background: transparent;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n outline: none;\n position: relative;\n overflow: hidden;\n transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1),\n background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n white-space: nowrap;\n }\n .chip:disabled { opacity: 0.38; cursor: not-allowed; pointer-events: none; }\n\n .chip::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n opacity: 0;\n background: var(--md-sys-color-on-surface-variant, #49454F);\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .chip:hover::before { opacity: 0.08; }\n .chip:focus::before { opacity: 0.12; }\n .chip:active::before { opacity: 0.12; }\n\n /* ── Filter selected state ── */\n .chip.selected {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n border-color: transparent;\n }\n .chip.selected::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n\n /* ── Assist & Suggestion elevated ── */\n .chip.elevated {\n background: var(--md-sys-color-surface-container-low, #F7F2FA);\n border-color: transparent;\n box-shadow: var(--md-sys-elevation-1);\n }\n .chip.elevated:hover { box-shadow: var(--md-sys-elevation-2); }\n\n .has-icon { padding-left: 8px; }\n\n .icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-style: normal;\n display: inline-block;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n }\n .selected .icon { font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20; }\n\n .close-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-style: normal;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n border-radius: 50%;\n width: 18px;\n height: 18px;\n cursor: pointer;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n position: relative;\n overflow: hidden;\n }\n .close-icon::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n transition: opacity 200ms;\n }\n .close-icon:hover::before { opacity: 0.08; }\n .close-icon:focus::before { opacity: 0.12; }\n .close-icon:active::before { opacity: 0.12; }\n `);\n\n const isElevated = props.variant === 'assist' || props.variant === 'suggestion';\n const checkIcon = selected.value && props.variant === 'filter' ? 'check' : props.icon;\n\n return html`\n <div\n :class=\"${{\n chip: true,\n selected: selected.value,\n elevated: isElevated,\n 'has-icon': !!checkIcon,\n }}\"\n role=\"${props.variant === 'filter' ? 'checkbox' : 'button'}\"\n :bind=\"${{ 'aria-checked': props.variant === 'filter' ? String(selected.value) : null }}\"\n :aria-disabled=\"${String(props.disabled)}\"\n tabindex=\"${props.disabled ? -1 : 0}\"\n @click=\"${() => { if (!props.disabled) { emit('click'); if (props.variant === 'filter') selected.value = !selected.value; } }}\"\n @keydown=\"${(e: KeyboardEvent) => { if (!props.disabled && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); emit('click'); if (props.variant === 'filter') selected.value = !selected.value; } }}\"\n >\n ${when(!!checkIcon, () => html`<span class=\"icon\" aria-hidden=\"true\">${checkIcon}</span>`)}\n ${props.label}\n ${when(props.variant === 'input', () => html`\n <span\n class=\"close-icon\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Remove ${props.label}\"\n @click=\"${(e: Event) => { e.stopPropagation(); emit('remove'); }}\"\n @keydown=\"${(e: KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); emit('remove'); } }}\"\n >close</span>\n `)}\n </div>\n `;\n});\n","import { component, html, css, ref, watch, computed, defineModel, useProps, useEmit, useStyle, useOnDisconnected } from '@jasonshimmy/custom-elements-runtime';\nimport { when, each } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { createFocusTrap } from '../composables/useFocusTrap';\nimport { useScrollLock } from '../composables/useScrollLock';\n\n// ── helpers ────────────────────────────────────────────────────────────────\nconst DAYS_OF_WEEK = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];\nconst MONTH_NAMES = [\n 'January','February','March','April','May','June',\n 'July','August','September','October','November','December',\n];\n\nfunction isoToDate(iso: string): Date | null {\n if (!iso) return null;\n const d = new Date(iso + 'T00:00:00');\n return isNaN(d.getTime()) ? null : d;\n}\n\nfunction dateToIso(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n}\n\nfunction sameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate();\n}\n\n/** Format ISO date as \"Mon, Mar 9\" for dialog headline (MD3 spec). */\nfunction formatHeadline(iso: string): string {\n const d = isoToDate(iso);\n if (!d) return '——/——/————';\n return d.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });\n}\n\n/** Format ISO date as \"Mar 9\" for range endpoints in headline. */\nfunction formatRangeDate(iso: string): string {\n const d = isoToDate(iso);\n if (!d) return '—';\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\ninterface CalendarDay {\n key: string;\n date: Date;\n inMonth: boolean;\n isToday: boolean;\n isSelected: boolean;\n isRangeStart: boolean;\n isRangeEnd: boolean;\n isInRange: boolean;\n disabled: boolean;\n label: string;\n}\n\nfunction buildCalendar(\n year: number,\n month: number,\n selected: Date | null,\n rangeStart: Date | null,\n rangeEnd: Date | null,\n minDate: Date | null,\n maxDate: Date | null,\n): CalendarDay[] {\n const today = new Date();\n const firstDay = new Date(year, month, 1);\n const startOffset = firstDay.getDay(); // 0=Sun\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n const prevMonthDays = new Date(year, month, 0).getDate();\n\n const cells: CalendarDay[] = [];\n\n // Fill leading days from previous month\n for (let i = startOffset - 1; i >= 0; i--) {\n const d = new Date(year, month - 1, prevMonthDays - i);\n cells.push(makeCell(d, false, today, selected, rangeStart, rangeEnd, minDate, maxDate));\n }\n\n // Current month\n for (let d = 1; d <= daysInMonth; d++) {\n const date = new Date(year, month, d);\n cells.push(makeCell(date, true, today, selected, rangeStart, rangeEnd, minDate, maxDate));\n }\n\n // Trailing days to fill 6 rows\n const remaining = 42 - cells.length;\n for (let d = 1; d <= remaining; d++) {\n const date = new Date(year, month + 1, d);\n cells.push(makeCell(date, false, today, selected, rangeStart, rangeEnd, minDate, maxDate));\n }\n\n return cells;\n}\n\nfunction makeCell(\n date: Date,\n inMonth: boolean,\n today: Date,\n selected: Date | null,\n rangeStart: Date | null,\n rangeEnd: Date | null,\n minDate: Date | null,\n maxDate: Date | null,\n): CalendarDay {\n const t = date.getTime();\n const isSelected = selected ? sameDay(date, selected) : false;\n const isRangeStart = rangeStart ? sameDay(date, rangeStart) : false;\n const isRangeEnd = rangeEnd ? sameDay(date, rangeEnd) : false;\n let isInRange = false;\n if (rangeStart && rangeEnd) {\n isInRange = t > rangeStart.getTime() && t < rangeEnd.getTime();\n }\n const disabled = (minDate ? t < minDate.getTime() : false) ||\n (maxDate ? t > maxDate.getTime() : false);\n return {\n key: dateToIso(date),\n date,\n inMonth,\n isToday: sameDay(date, today),\n isSelected,\n isRangeStart,\n isRangeEnd,\n isInRange,\n disabled,\n label: String(date.getDate()),\n };\n}\n\n// ── component ──────────────────────────────────────────────────────────────\ncomponent('md-date-picker', () => {\n const props = useProps({\n /** 'dialog' | 'docked' */\n variant: 'dialog' as 'dialog' | 'docked',\n /** ISO date string for range start */\n rangeStart: '',\n /** ISO date string for range end */\n rangeEnd: '',\n /** min selectable date (ISO) */\n min: '',\n /** max selectable date (ISO) */\n max: '',\n /** label shown on the trigger text field */\n label: 'Select date',\n ariaLabel: 'Date picker',\n open: false,\n });\n const emit = useEmit();\n const modelValue = defineModel('');\n const open = ref(props.open);\n watch(() => props.open, v => { open.value = v; });\n\n // ── view state ────────────────────────────────────────────────────────\n // 'day' | 'month' | 'year'\n const view = ref<'day' | 'month' | 'year'>('day');\n // currently viewed month/year\n const viewYear = ref(new Date().getFullYear());\n const viewMonth = ref(new Date().getMonth());\n\n // initialize from value prop\n const initFromValue = () => {\n const d = isoToDate(modelValue.value);\n if (d) { viewYear.value = d.getFullYear(); viewMonth.value = d.getMonth(); }\n };\n initFromValue();\n watch(() => modelValue.value, initFromValue);\n\n // ── pending selection (dialog mode) ──────────────────────────────────\n // Dialog mode: day clicks update a pending value; OK confirms, Cancel discards.\n const pendingValue = ref(modelValue.value);\n watch(() => modelValue.value, (v) => { pendingValue.value = v; });\n watch(() => open.value, (isOpen) => { if (isOpen) pendingValue.value = modelValue.value; });\n\n // ── docked mode open state ──────────────────────────────────────────\n const toggleDocked = () => { const v = !open.value; open.value = v; emit('update:open', v); };\n\n // ── computed helpers ──────────────────────────────────────────────────\n const selectedDate = computed(() =>\n isoToDate(props.variant === 'dialog' ? pendingValue.value : modelValue.value));\n const rangeStartDt = computed(() => isoToDate(props.rangeStart));\n const rangeEndDt = computed(() => isoToDate(props.rangeEnd));\n const minDt = computed(() => isoToDate(props.min));\n const maxDt = computed(() => isoToDate(props.max));\n\n const calendarDays = computed(() =>\n buildCalendar(\n viewYear.value, viewMonth.value,\n selectedDate.value,\n rangeStartDt.value, rangeEndDt.value,\n minDt.value, maxDt.value,\n )\n );\n\n const monthLabel = computed(() =>\n `${MONTH_NAMES[viewMonth.value]} ${viewYear.value}`\n );\n\n // years list for year picker (current-20 … current+20)\n const yearList = computed(() => {\n const base = viewYear.value;\n const years: number[] = [];\n for (let y = base - 20; y <= base + 20; y++) years.push(y);\n return years;\n });\n\n // ── navigation ────────────────────────────────────────────────────────\n const prevMonth = () => {\n if (viewMonth.value === 0) { viewMonth.value = 11; viewYear.value--; }\n else viewMonth.value--;\n };\n const nextMonth = () => {\n if (viewMonth.value === 11) { viewMonth.value = 0; viewYear.value++; }\n else viewMonth.value++;\n };\n\n // ── selection ─────────────────────────────────────────────────────────\n const selectDay = (day: CalendarDay) => {\n if (day.disabled) return;\n const iso = dateToIso(day.date);\n if (props.variant === 'dialog') {\n // Stage selection; confirmed by OK button\n pendingValue.value = iso;\n } else {\n emit('change', iso);\n modelValue.value = iso;\n open.value = false;\n emit('update:open', false);\n }\n };\n\n const selectYear = (y: number) => {\n viewYear.value = y;\n view.value = 'day';\n };\n\n // ── modal focus/scroll ────────────────────────────────────────────────\n const isModal = computed(() => props.variant === 'dialog');\n useEscapeKey(\n () => (open.value && isModal.value) || open.value,\n () => { open.value = false; emit('update:open', false); emit('close'); })();\n const trap = createFocusTrap();\n useOnDisconnected(() => trap.cleanup());\n const scrollLock = useScrollLock();\n\n // ── styles ────────────────────────────────────────────────────────────\n useStyle(() => css`\n :host { display: contents; }\n\n /* ── Scrim (modal only) ── */\n .scrim {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.32);\n z-index: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .scrim-enter-from { opacity: 0; }\n .scrim-enter-from .picker { transform: scale(0.92); opacity: 0; }\n .scrim-enter-active { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1); }\n .scrim-enter-active .picker { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1), transform 200ms cubic-bezier(0.4,0,0.2,1); }\n .scrim-leave-to { opacity: 0; pointer-events: none; }\n .scrim-leave-to .picker { transform: scale(0.92); opacity: 0; }\n .scrim-leave-active { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1); }\n .scrim-leave-active .picker { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1), transform 200ms cubic-bezier(0.4,0,0.2,1); }\n\n /* ── Docked (inline open) ── */\n .docked-enter-from { opacity: 0; transform: translateY(-4px); }\n .docked-enter-active { transition: opacity 150ms cubic-bezier(0.4,0,0.2,1), transform 150ms cubic-bezier(0.4,0,0.2,1); }\n .docked-leave-to { opacity: 0; transform: translateY(-4px); }\n .docked-leave-active { transition: opacity 100ms cubic-bezier(0.4,0,0.2,1), transform 100ms cubic-bezier(0.4,0,0.2,1); }\n\n /* ── Picker container ── */\n .picker {\n background: var(--md-sys-color-surface-container-high, #ECE6F0);\n border-radius: 28px;\n width: 360px;\n max-width: calc(100vw - 48px);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: var(--md-sys-elevation-3, 0 4px 8px 3px rgba(0,0,0,.15), 0 1px 3px rgba(0,0,0,.3));\n }\n\n /* ── Headline ── */\n .picker-headline {\n padding: 24px 24px 0;\n }\n .picker-headline-label {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 12px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n margin: 0 0 4px;\n }\n .picker-headline-value {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 36px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n margin: 0 0 16px;\n }\n\n /* ── Divider ── */\n .picker-divider {\n height: 1px;\n background: var(--md-sys-color-outline-variant, #CAC4D0);\n margin: 0 0 8px;\n }\n\n /* ── Calendar header ── */\n .cal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 12px 4px 24px;\n }\n .cal-header-month {\n display: flex;\n align-items: center;\n gap: 4px;\n cursor: pointer;\n border: none;\n background: transparent;\n padding: 4px 8px;\n border-radius: 8px;\n outline: none;\n }\n .cal-header-month:hover {\n background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent);\n }\n .cal-header-month:focus-visible {\n outline: 2px solid var(--md-sys-color-primary, #6750A4);\n outline-offset: 2px;\n }\n .cal-header-month-label {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 14px;\n font-weight: 500;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n padding: 4px 4px 4px 0;\n }\n .cal-header-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 18;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .cal-header-nav {\n display: flex;\n gap: 4px;\n }\n .cal-header-nav.nav-hidden { visibility: hidden; pointer-events: none; }\n\n /* ── Fixed-height body for consistent layout ── */\n .cal-body {\n height: 304px;\n overflow-y: auto;\n }\n\n /* ── Weekday labels ── */\n .cal-weekdays {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n padding: 0 12px;\n margin-bottom: 2px;\n }\n .cal-weekday {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 12px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n text-align: center;\n height: 40px;\n line-height: 40px;\n }\n\n /* ── Calendar grid ── */\n .cal-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n padding: 0 12px;\n }\n .cal-day {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n justify-self: center;\n cursor: pointer;\n border-radius: 50%;\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 14px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n outline: none;\n background: transparent;\n border: none;\n padding: 0;\n user-select: none;\n }\n .cal-day:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); outline-offset: 2px; }\n .cal-day.outside { color: var(--md-sys-color-on-surface-variant, #49454F); opacity: 0.38; }\n .cal-day.today::before {\n content: '';\n position: absolute;\n inset: 4px;\n border-radius: 50%;\n border: 1px solid var(--md-sys-color-primary, #6750A4);\n pointer-events: none;\n }\n .cal-day.selected {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n .cal-day.range-start,\n .cal-day.range-end {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n .cal-day.in-range {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #21005D);\n border-radius: 0;\n width: 100%;\n justify-self: stretch;\n }\n .cal-day.range-start { border-radius: 50% 0 0 50%; width: 100%; justify-self: stretch; }\n .cal-day.range-end { border-radius: 0 50% 50% 0; width: 100%; justify-self: stretch; }\n .cal-day:hover:not(.selected):not(.range-start):not(.range-end):not(.disabled) {\n background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent);\n }\n .cal-day.disabled { color: var(--md-sys-color-on-surface, #1C1B1F); opacity: 0.38; cursor: not-allowed; }\n\n /* ── Year list ── */\n .year-list {\n padding: 8px 12px;\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n justify-content: center;\n }\n .year-item {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 14px;\n padding: 8px 16px;\n border-radius: 20px;\n cursor: pointer;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n border: none;\n background: transparent;\n outline: none;\n }\n .year-item:hover {\n background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent);\n }\n .year-item.selected {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n .year-item:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); outline-offset: 2px; }\n\n /* ── Month list ── */\n .month-list {\n padding: 8px 12px;\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 4px;\n }\n .month-item {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 14px;\n padding: 10px 8px;\n border-radius: 20px;\n cursor: pointer;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n border: none;\n background: transparent;\n text-align: center;\n outline: none;\n }\n .month-item:hover {\n background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent);\n }\n .month-item.selected {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n .month-item:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); outline-offset: 2px; }\n\n /* ── Navigation icon button ── */\n .nav-btn {\n width: 40px;\n height: 40px;\n border: none;\n background: transparent;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n padding: 0;\n outline: none;\n }\n .nav-btn:hover { background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent); }\n .nav-btn:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); outline-offset: 2px; }\n .nav-btn-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 20px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 20;\n }\n\n /* ── Actions ── */\n .picker-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 12px 20px;\n }\n\n /* ── Docked trigger ── */\n .docked-wrapper { position: relative; }\n .docked-picker {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n z-index: 100;\n }\n\n /* ── Docked input field ── */\n .docked-field {\n display: flex;\n align-items: center;\n height: 56px;\n border-radius: 4px;\n border: 1px solid var(--md-sys-color-outline, #79747E);\n padding: 0 12px;\n cursor: pointer;\n background: transparent;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n }\n .docked-field:hover { border-color: var(--md-sys-color-on-surface, #1C1B1F); }\n .docked-field:focus-within { border-color: var(--md-sys-color-primary, #6750A4); border-width: 2px; padding: 0 11px; }\n .docked-field-input {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 16px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n cursor: pointer;\n }\n .docked-field-input::placeholder {\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .docked-field-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n margin-left: 8px;\n }\n .docked-field-label {\n position: absolute;\n left: 12px;\n top: -8px;\n background: var(--md-sys-color-surface, #FFFBFE);\n padding: 0 4px;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .docked-field:focus-within .docked-field-label {\n color: var(--md-sys-color-primary, #6750A4);\n }\n `);\n\n // ── headline display ──────────────────────────────────────────────────\n const headlineValue = computed(() => {\n if (props.rangeStart || props.rangeEnd) {\n const s = props.rangeStart ? formatRangeDate(props.rangeStart) : '—';\n const e = props.rangeEnd ? formatRangeDate(props.rangeEnd) : '—';\n return `${s} – ${e}`;\n }\n const val = props.variant === 'dialog' ? pendingValue.value : modelValue.value;\n return val ? formatHeadline(val) : '——/——/————';\n });\n\n // ── calendar body ─────────────────────────────────────────────────────\n const renderCalendar = () => html`\n <div class=\"cal-header\">\n <button\n type=\"button\"\n class=\"cal-header-month\"\n @click=\"${() => { view.value = view.value === 'year' ? 'day' : 'year'; }}\"\n aria-label=\"Switch to year view\"\n aria-expanded=\"${view.value === 'year'}\"\n >\n <span class=\"cal-header-month-label\">${monthLabel.value}</span>\n <span class=\"cal-header-icon\" aria-hidden=\"true\">\n ${view.value === 'year' ? 'arrow_drop_up' : 'arrow_drop_down'}\n </span>\n </button>\n <div :class=\"${{ 'cal-header-nav': true, 'nav-hidden': view.value !== 'day' }}\">\n <button type=\"button\" class=\"nav-btn\" aria-label=\"Previous month\"\n @click=\"${(e: Event) => { e.stopPropagation(); if (viewMonth.value === 0) { viewMonth.value = 11; viewYear.value--; } else { viewMonth.value--; } }}\"\n >\n <span class=\"nav-btn-icon\" aria-hidden=\"true\">chevron_left</span>\n </button>\n <button type=\"button\" class=\"nav-btn\" aria-label=\"Next month\"\n @click=\"${(e: Event) => { e.stopPropagation(); if (viewMonth.value === 11) { viewMonth.value = 0; viewYear.value++; } else { viewMonth.value++; } }}\"\n >\n <span class=\"nav-btn-icon\" aria-hidden=\"true\">chevron_right</span>\n </button>\n </div>\n </div>\n <div class=\"cal-body\">\n ${when(view.value === 'year', () => html`\n <div class=\"year-list\" role=\"listbox\" aria-label=\"Year selection\">\n ${each(yearList.value.map((y) => ({ key: String(y), year: y })), (item: {key:string;year:number}) => html`\n <button\n :class=\"${{ 'year-item': true, selected: item.year === viewYear.value }}\"\n role=\"option\"\n aria-selected=\"${item.year === viewYear.value}\"\n @click=\"${() => selectYear(item.year)}\"\n >${String(item.year)}</button>\n `)}\n </div>\n `)}\n ${when(view.value === 'month', () => html`\n <div class=\"month-list\" role=\"listbox\" aria-label=\"Month selection\">\n ${each(MONTH_NAMES.map((m, i) => ({ key: String(i), name: m, index: i })), (item: {key:string;name:string;index:number}) => html`\n <button\n :class=\"${{ 'month-item': true, selected: item.index === viewMonth.value }}\"\n role=\"option\"\n aria-selected=\"${item.index === viewMonth.value}\"\n @click=\"${() => { viewMonth.value = item.index; view.value = 'day'; }}\"\n >${item.name.slice(0, 3)}</button>\n `)}\n </div>\n `)}\n ${when(view.value === 'day', () => html`\n <div class=\"cal-weekdays\" role=\"row\">\n ${each(DAYS_OF_WEEK.map((d, i) => ({ key: String(i), label: d })), (item: {key:string;label:string}) => html`\n <div class=\"cal-weekday\" role=\"columnheader\" aria-label=\"${item.label}\">${item.label}</div>\n `)}\n </div>\n <div\n class=\"cal-grid\"\n role=\"grid\"\n aria-label=\"${monthLabel.value}\"\n @keydown=\"${(e: KeyboardEvent) => {\n const focused = document.activeElement;\n // find focused index in grid\n const cells = (e.currentTarget as HTMLElement).querySelectorAll('[role=gridcell]');\n let idx = Array.from(cells).findIndex(c => c === focused);\n if (idx < 0) return;\n let next = idx;\n if (e.key === 'ArrowRight') next = Math.min(idx + 1, cells.length - 1);\n else if (e.key === 'ArrowLeft') next = Math.max(idx - 1, 0);\n else if (e.key === 'ArrowDown') next = Math.min(idx + 7, cells.length - 1);\n else if (e.key === 'ArrowUp') next = Math.max(idx - 7, 0);\n else if (e.key === 'PageDown') nextMonth();\n else if (e.key === 'PageUp') prevMonth();\n else return;\n e.preventDefault();\n (cells[next] as HTMLElement).focus();\n }}\"\n >\n ${each(calendarDays.value, (day: CalendarDay) => html`\n <button\n :class=\"${{ 'cal-day': true, outside: !day.inMonth, today: day.isToday, selected: day.isSelected, 'range-start': day.isRangeStart, 'range-end': day.isRangeEnd, 'in-range': day.isInRange, disabled: day.disabled }}\"\n role=\"gridcell\"\n aria-label=\"${day.date.toLocaleDateString(undefined, { weekday:'long', year:'numeric', month:'long', day:'numeric' })}\"\n aria-selected=\"${day.isSelected || day.isRangeStart || day.isRangeEnd}\"\n aria-disabled=\"${day.disabled}\"\n tabindex=\"${day.isSelected ? '0' : '-1'}\"\n @click=\"${() => selectDay(day)}\"\n >${day.label}</button>\n `)}\n </div>\n `)}\n </div>\n `;\n\n const renderActions = () => html`\n <div class=\"picker-actions\">\n <md-button variant=\"text\" @click=\"${() => { open.value = false; emit('update:open', false); emit('close'); }}\">Cancel</md-button>\n <md-button variant=\"text\" @click=\"${() => { if (props.variant === 'dialog' && pendingValue.value) { emit('change', pendingValue.value); modelValue.value = pendingValue.value; } open.value = false; emit('update:open', false); emit('close'); }}\">OK</md-button>\n </div>\n `;\n\n const renderPicker = () => html`\n <div class=\"picker\" role=\"dialog\" aria-modal=\"true\" aria-label=\"${props.ariaLabel}\">\n <div class=\"picker-headline\">\n <p class=\"picker-headline-label\">Select date</p>\n <p class=\"picker-headline-value\">${headlineValue.value}</p>\n </div>\n <div class=\"picker-divider\"></div>\n ${renderCalendar()}\n ${renderActions()}\n </div>\n `;\n\n return html`\n ${Transition({ show: open.value && props.variant === 'dialog',\n enterFrom: 'scrim-enter-from', enterActive: 'scrim-enter-active',\n leaveActive: 'scrim-leave-active', leaveTo: 'scrim-leave-to',\n onBeforeEnter: scrollLock.lock,\n onAfterEnter: trap.onAfterEnter,\n onAfterLeave: () => { trap.onAfterLeave(); scrollLock.unlock(); },\n }, html`\n <div\n class=\"scrim\"\n @click=\"${(e: Event) => { if (e.target === e.currentTarget) { emit('close'); open.value = false; emit('update:open', false); } }}\"\n >\n ${renderPicker()}\n </div>\n `)}\n ${when(props.variant === 'docked', () => html`\n <div class=\"docked-wrapper\">\n <div class=\"docked-field\" @click=\"${() => toggleDocked()}\">\n <span class=\"docked-field-label\">${props.label}</span>\n <input\n class=\"docked-field-input\"\n type=\"text\"\n readonly\n :value=\"${modelValue.value ? formatHeadline(modelValue.value) : ''}\"\n placeholder=\"mm/dd/yyyy\"\n aria-label=\"${props.label}\"\n />\n <span class=\"docked-field-icon\" aria-hidden=\"true\">calendar_today</span>\n </div>\n ${Transition({ show: open.value,\n enterFrom: 'docked-enter-from', enterActive: 'docked-enter-active',\n leaveActive: 'docked-leave-active', leaveTo: 'docked-leave-to',\n }, html`\n <div class=\"docked-picker\">\n <div class=\"picker\" role=\"dialog\" aria-label=\"${props.ariaLabel}\">\n ${renderCalendar()}\n ${renderActions()}\n </div>\n </div>\n `)}\n </div>\n `)}\n `;\n});\n","import { component, html, css, defineModel, useProps, useEmit, useStyle, useOnDisconnected } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { createFocusTrap } from '../composables/useFocusTrap';\nimport { useScrollLock } from '../composables/useScrollLock';\n\ncomponent('md-dialog', () => {\n const props = useProps({\n headline: '',\n icon: '',\n });\n const emit = useEmit();\n const open = defineModel('open', false);\n\n useEscapeKey(() => open.value, () => { emit('close'); open.value = false; })();\n const trap = createFocusTrap();\n useOnDisconnected(() => trap.cleanup());\n const scrollLock = useScrollLock();\n\n useStyle(() => css`\n :host { display: contents; }\n\n .scrim {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.32);\n z-index: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n /* Base = fully visible; opacity: 1 and pointer-events: auto are defaults */\n }\n\n /* Scrim enters: fade in; dialog enters: scale up */\n .scrim-enter-from {\n opacity: 0;\n }\n .scrim-enter-from .dialog {\n transform: scale(0.92);\n opacity: 0;\n }\n .scrim-enter-active {\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .scrim-enter-active .dialog {\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1),\n transform 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* Scrim leaves: fade out; dialog leaves: scale down */\n .scrim-leave-to {\n opacity: 0;\n pointer-events: none;\n }\n .scrim-leave-to .dialog {\n transform: scale(0.92);\n opacity: 0;\n }\n .scrim-leave-active {\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .scrim-leave-active .dialog {\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1),\n transform 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .dialog {\n background: var(--md-sys-color-surface-container-high, #ECE6F0);\n border-radius: 28px;\n min-width: 280px;\n max-width: 560px;\n width: calc(100% - 48px);\n max-height: calc(100% - 48px);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: var(--md-sys-elevation-3);\n /* Base = fully open; transform: none and opacity: 1 are defaults */\n }\n .dialog-header {\n padding: 24px 24px 0;\n text-align: center;\n }\n .dialog-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n display: block;\n color: var(--md-sys-color-secondary, #625B71);\n margin-bottom: 16px;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .dialog-headline {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 24px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n margin: 0 0 16px;\n }\n\n .dialog-content {\n padding: 0 24px 24px;\n overflow-y: auto;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n line-height: 20px;\n }\n\n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 0 24px 24px;\n flex-shrink: 0;\n }\n `);\n\n// Scrim + dialog are conditionally mounted via Transition. The scrim fades\n // and the inner dialog scales via CSS descendant selectors on the scrim's\n // transition state classes.\n return html`\n ${Transition({\n show: open.value,\n name: 'md-dialog-scrim',\n enterFrom: 'scrim-enter-from',\n enterActive: 'scrim-enter-active',\n leaveActive: 'scrim-leave-active',\n leaveTo: 'scrim-leave-to',\n onBeforeEnter: scrollLock.lock,\n onAfterEnter: trap.onAfterEnter,\n onAfterLeave: () => { trap.onAfterLeave(); scrollLock.unlock(); },\n }, html`\n <div\n class=\"scrim\"\n @click=\"${(e: Event) => { if (e.target === e.currentTarget) { emit('close'); open.value = false; } }}\"\n >\n <div class=\"dialog\" role=\"dialog\" aria-modal=\"true\" :bind=\"${{ 'aria-labelledby': props.headline ? 'dialog-headline' : null }}\">\n <div class=\"dialog-header\">\n ${when(!!props.icon, () => html`<span class=\"dialog-icon\">${props.icon}</span>`)}\n ${when(!!props.headline, () => html`<h2 class=\"dialog-headline\" id=\"dialog-headline\">${props.headline}</h2>`)}\n </div>\n <div class=\"dialog-content\">\n <slot></slot>\n </div>\n <div class=\"dialog-actions\">\n <slot name=\"actions\"></slot>\n </div>\n </div>\n </div>\n `)}\n `;\n});\n","import { component, html, css, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\n\ncomponent('md-divider', () => {\n const props = useProps({\n inset: false,\n insetStart: false,\n insetEnd: false,\n vertical: false,\n });\n\n useStyle(() => css`\n :host { display: block; }\n\n .divider {\n background: var(--md-sys-color-outline-variant, #CAC4D0);\n }\n .horizontal {\n width: 100%;\n height: 1px;\n }\n .vertical {\n width: 1px;\n height: 100%;\n align-self: stretch;\n }\n .inset { margin-left: 16px; margin-right: 16px; }\n .inset-start { margin-left: 16px; }\n .inset-end { margin-right: 16px; }\n .vertical.inset { margin-top: 8px; margin-bottom: 8px; }\n `);\n\n return html`<div :class=\"${{\n divider: true,\n vertical: props.vertical,\n horizontal: !props.vertical,\n inset: props.inset,\n 'inset-start': props.insetStart,\n 'inset-end': props.insetEnd,\n }}\" role=\"separator\" :bind=\"${{ 'aria-orientation': props.vertical ? 'vertical' : null }}\"></div>`;\n});\n","import { component, html, css, ref, watch, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when, each } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\n\n/**\n * md-fab-menu\n *\n * MD3 FAB menu — a FAB that expands to reveal a list of related actions.\n * Spec: https://m3.material.io/components/fab-menu\n *\n * Props:\n * icon — icon of the main FAB (shown when closed)\n * closeIcon — icon shown when menu is open (default: close)\n * variant — 'primary' | 'secondary' | 'tertiary'\n * open — controlled open state\n * items — array of { id, icon, label }\n * ariaLabel — accessible label for the trigger FAB\n *\n * Emits:\n * open — menu opened\n * close — menu closed\n * select — { id } — an action item was clicked\n */\n\ninterface FabMenuItem {\n id: string;\n icon: string;\n label: string;\n disabled?: boolean;\n}\n\n// Singleton: only one FAB menu may be open at a time across the whole page.\n// When a new FAB opens it calls this to close the previously open one.\nlet _activeFabClose: (() => void) | null = null;\n\ncomponent('md-fab-menu', () => {\n const props = useProps({\n icon: 'add',\n closeIcon: 'close',\n variant: 'primary' as 'primary' | 'secondary' | 'tertiary',\n items: [] as FabMenuItem[],\n ariaLabel: 'Speed dial',\n open: false,\n });\n const emit = useEmit();\n const open = ref(props.open);\n watch(() => props.open, v => { open.value = v; });\n\n const closeMenu = () => {\n if (_activeFabClose === closeMenu) _activeFabClose = null;\n open.value = false;\n emit('update:open', false);\n emit('close');\n };\n\n const toggle = () => {\n if (open.value) {\n closeMenu();\n } else {\n // Close any other open FAB menu before opening this one.\n if (_activeFabClose) _activeFabClose();\n open.value = true;\n emit('update:open', true);\n _activeFabClose = closeMenu;\n emit('open');\n }\n };\n\n const selectItem = (item: FabMenuItem) => {\n if (item.disabled) return;\n emit('select', { id: item.id });\n closeMenu();\n };\n\n useEscapeKey(() => open.value, closeMenu)();\n\n useStyle(() => css`\n :host { display: inline-flex; }\n\n /* ── Outside-click scrim ── */\n .fab-scrim {\n position: fixed;\n inset: 0;\n z-index: 998;\n cursor: default;\n }\n\n /* ── Wrapper: anchor for absolutely positioned items ── */\n /* z-index 999 so the active FAB's trigger and items sit above its own scrim */\n .fab-wrap {\n position: relative;\n z-index: 999;\n display: inline-flex;\n width: 56px;\n height: 56px;\n }\n\n /* ── Items list: absolutely positioned above the trigger ── */\n .items-list {\n position: absolute;\n bottom: calc(100% + 16px);\n right: 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n /* ── Each menu item (M3 list item — 56dp, icon + label) ── */\n .menu-item {\n height: 56px;\n border-radius: 16px;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 0 16px;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n box-shadow: var(--md-sys-elevation-3);\n position: relative;\n overflow: hidden;\n outline: none;\n white-space: nowrap;\n transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n }\n .menu-item::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .menu-item:hover::before { opacity: 0.08; }\n .menu-item:focus::before { opacity: 0.12; }\n .menu-item:active::before { opacity: 0.12; }\n .menu-item:hover { box-shadow: var(--md-sys-elevation-4); }\n .menu-item:focus-visible {\n outline: 2px solid var(--md-sys-color-primary, #6750A4);\n outline-offset: 2px;\n }\n .menu-item:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .menu-item-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n line-height: 1;\n }\n\n .menu-item-label {\n font-size: 14px;\n font-weight: 500;\n }\n\n /* ── Trigger button (56dp close button) ── */\n .fab-trigger {\n width: 56px;\n height: 56px;\n border-radius: 16px;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n outline: none;\n transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);\n z-index: 1;\n user-select: none;\n }\n .fab-trigger::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .fab-trigger:hover::before { opacity: 0.08; }\n .fab-trigger:focus::before { opacity: 0.12; }\n .fab-trigger:active::before { opacity: 0.12; }\n .fab-trigger:focus-visible {\n outline: 2px solid var(--md-sys-color-primary, #6750A4);\n outline-offset: 2px;\n }\n\n .fab-trigger-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* ── Color variants: close button uses container colors, items use full colors ── */\n /* Primary */\n .primary .fab-trigger {\n background: var(--md-sys-color-primary-container, #EADDFF);\n color: var(--md-sys-color-on-primary-container, #21005D);\n box-shadow: var(--md-sys-elevation-3);\n }\n .primary .fab-trigger::before { background: var(--md-sys-color-on-primary-container, #21005D); }\n .primary .menu-item {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n .primary .menu-item::before { background: var(--md-sys-color-on-primary, #FFFFFF); }\n\n /* Secondary */\n .secondary .fab-trigger {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n box-shadow: var(--md-sys-elevation-3);\n }\n .secondary .fab-trigger::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n .secondary .menu-item {\n background: var(--md-sys-color-secondary, #625B71);\n color: var(--md-sys-color-on-secondary, #FFFFFF);\n }\n .secondary .menu-item::before { background: var(--md-sys-color-on-secondary, #FFFFFF); }\n\n /* Tertiary */\n .tertiary .fab-trigger {\n background: var(--md-sys-color-tertiary-container, #FFD8E4);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n box-shadow: var(--md-sys-elevation-3);\n }\n .tertiary .fab-trigger::before { background: var(--md-sys-color-on-tertiary-container, #31111D); }\n .tertiary .menu-item {\n background: var(--md-sys-color-tertiary, #7D5260);\n color: var(--md-sys-color-on-tertiary, #FFFFFF);\n }\n .tertiary .menu-item::before { background: var(--md-sys-color-on-tertiary, #FFFFFF); }\n\n /* ── Transition classes (slide up from trigger direction) ── */\n .items-enter-from { opacity: 0; transform: translateY(16px); }\n .items-enter-active { transition: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1); }\n .items-leave-to { opacity: 0; transform: translateY(16px); }\n .items-leave-active { transition: opacity 100ms cubic-bezier(0.4, 0, 0.2, 1), transform 100ms cubic-bezier(0.4, 0, 0.2, 1); }\n `);\n\n return html`\n ${when(open.value, () => html`\n <div class=\"fab-scrim\" @click=\"${() => closeMenu()}\"></div>\n `)}\n <div :class=\"${{ 'fab-wrap': true, [props.variant]: true }}\">\n ${Transition({ show: open.value,\n enterFrom: 'items-enter-from', enterActive: 'items-enter-active',\n leaveActive: 'items-leave-active', leaveTo: 'items-leave-to',\n }, html`\n <div class=\"items-list\" role=\"menu\">\n ${each(props.items, (item) => html`\n <button\n type=\"button\"\n class=\"menu-item\"\n role=\"menuitem\"\n aria-label=\"${item.label}\"\n ?disabled=\"${item.disabled}\"\n @click=\"${(e: Event) => { e.stopPropagation(); selectItem(item); }}\"\n >\n <span class=\"menu-item-icon\" aria-hidden=\"true\">${item.icon}</span>\n <span class=\"menu-item-label\">${item.label}</span>\n </button>\n `)}\n </div>\n `)}\n <button\n type=\"button\"\n :class=\"${{ 'fab-trigger': true, open: open.value }}\"\n aria-label=\"${props.ariaLabel}\"\n aria-expanded=\"${open.value}\"\n aria-haspopup=\"true\"\n @click=\"${() => toggle()}\"\n >\n <span class=\"fab-trigger-icon\" aria-hidden=\"true\">\n ${open.value ? props.closeIcon : props.icon}\n </span>\n </button>\n </div>\n `;\n});\n","import { component, html, css, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-fab', () => {\n const props = useProps({\n variant: 'primary' as 'primary' | 'secondary' | 'tertiary' | 'surface',\n size: 'regular' as 'small' | 'regular' | 'medium' | 'large',\n icon: 'add',\n label: '',\n lowered: false,\n ariaLabel: '',\n });\n const emit = useEmit();\n\n useStyle(() => css`\n :host { display: inline-flex; }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n border: none;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n outline: none;\n position: relative;\n overflow: hidden;\n transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n -webkit-font-smoothing: antialiased;\n }\n\n /* state layer */\n button::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n button:hover::before { opacity: 0.08; }\n button:focus::before { opacity: 0.12; }\n button:active::before { opacity: 0.12; }\n\n /* ── Sizes ── */\n .small { width: 40px; height: 40px; border-radius: 12px; }\n .regular { width: 56px; height: 56px; border-radius: 16px; }\n .medium { width: 80px; height: 80px; border-radius: 20px; }\n .large { width: 96px; height: 96px; border-radius: 28px; }\n .extended { height: 56px; border-radius: 16px; padding: 0 20px 0 16px; }\n\n /* ── Color variants ── */\n .primary {\n background: var(--md-sys-color-primary-container, #EADDFF);\n color: var(--md-sys-color-on-primary-container, #21005D);\n box-shadow: var(--md-sys-elevation-3);\n }\n .primary::before { background: var(--md-sys-color-on-primary-container, #21005D); }\n\n .secondary {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n box-shadow: var(--md-sys-elevation-3);\n }\n .secondary::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n\n .tertiary {\n background: var(--md-sys-color-tertiary-container, #FFD8E4);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n box-shadow: var(--md-sys-elevation-3);\n }\n .tertiary::before { background: var(--md-sys-color-on-tertiary-container, #31111D); }\n\n .surface-variant {\n background: var(--md-sys-color-surface-container-high, #ECE6F0);\n color: var(--md-sys-color-primary, #6750A4);\n box-shadow: var(--md-sys-elevation-3);\n }\n .surface-variant::before { background: var(--md-sys-color-primary, #6750A4); }\n\n button:hover { box-shadow: var(--md-sys-elevation-4); }\n .lowered { box-shadow: var(--md-sys-elevation-1) !important; }\n .lowered:hover { box-shadow: var(--md-sys-elevation-2) !important; }\n\n .icon {\n font-family: 'Material Symbols Outlined';\n font-weight: normal;\n font-style: normal;\n display: inline-block;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .small .icon { font-size: 24px; }\n .regular .icon { font-size: 24px; }\n .medium .icon { font-size: 28px; }\n .large .icon { font-size: 36px; }\n .extended .icon { font-size: 24px; }\n\n .label { font-size: 14px; font-weight: 500; }\n `);\n\n const colorClass = props.variant === 'surface' ? 'surface-variant' : props.variant;\n const sizeClass = props.label ? 'extended' : props.size;\n\n return html`\n <button\n :class=\"${{\n [colorClass]: true,\n [sizeClass]: true,\n lowered: props.lowered,\n }}\"\n :bind=\"${{ 'aria-label': props.ariaLabel || props.label || props.icon }}\"\n type=\"button\"\n @click=\"${() => emit('click')}\"\n >\n <span class=\"icon\" aria-hidden=\"true\">${props.icon}</span>\n ${when(!!props.label, () => html`<span class=\"label\">${props.label}</span>`)}\n </button>\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\n\ncomponent('md-icon-button', () => {\n const props = useProps({\n variant: 'standard' as 'standard' | 'filled' | 'tonal' | 'outlined',\n icon: 'more_vert',\n disabled: false,\n toggle: false,\n selectedIcon: '',\n ariaLabel: '',\n });\n const emit = useEmit();\n const selected = defineModel('selected', false);\n\n useStyle(() => css`\n :host { display: inline-flex; vertical-align: middle; }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 20px;\n border: none;\n cursor: pointer;\n outline: none;\n position: relative;\n overflow: hidden;\n transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);\n user-select: none;\n background: transparent;\n }\n button:disabled { cursor: not-allowed; opacity: 0.38; pointer-events: none; }\n\n button::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n button:hover::before { opacity: 0.08; }\n button:focus::before { opacity: 0.12; }\n button:active::before { opacity: 0.12; }\n\n /* ── Standard ── */\n .standard { color: var(--md-sys-color-on-surface-variant, #49454F); }\n .standard.selected { color: var(--md-sys-color-primary, #6750A4); }\n .standard::before { background: var(--md-sys-color-on-surface-variant, #49454F); }\n .standard.selected::before { background: var(--md-sys-color-primary, #6750A4); }\n\n /* ── Filled (non-toggle: always primary) ── */\n .filled {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #fff);\n }\n .filled::before { background: var(--md-sys-color-on-primary, #fff); }\n\n /* ── Filled toggle: unselected ── */\n .filled.toggle {\n background: var(--md-sys-color-surface-container-high, #ECE6F0);\n color: var(--md-sys-color-primary, #6750A4);\n }\n .filled.toggle::before { background: var(--md-sys-color-primary, #6750A4); }\n\n /* ── Filled toggle: selected ── */\n .filled.toggle.selected {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #fff);\n }\n .filled.toggle.selected::before { background: var(--md-sys-color-on-primary, #fff); }\n\n /* ── Tonal (non-toggle: always secondary-container) ── */\n .tonal {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n .tonal::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n\n /* ── Tonal toggle: unselected ── */\n .tonal.toggle {\n background: var(--md-sys-color-surface-container-high, #ECE6F0);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .tonal.toggle::before { background: var(--md-sys-color-on-surface-variant, #49454F); }\n\n /* ── Tonal toggle: selected ── */\n .tonal.toggle.selected {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n .tonal.toggle.selected::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n\n /* ── Outlined ── */\n .outlined {\n border: 1px solid var(--md-sys-color-outline, #79747E);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .outlined.selected {\n background: var(--md-sys-color-inverse-surface, #313033);\n color: var(--md-sys-color-inverse-on-surface, #F4EFF4);\n border-color: transparent;\n }\n .outlined::before { background: var(--md-sys-color-on-surface-variant, #49454F); }\n .outlined.selected::before { background: var(--md-sys-color-inverse-on-surface, #F4EFF4); }\n\n .icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n display: inline-block;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .selected .icon {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n `);\n\n const displayIcon = props.toggle && selected.value && props.selectedIcon\n ? props.selectedIcon\n : props.icon;\n\n return html`\n <button\n :class=\"${{\n [props.variant]: true,\n selected: selected.value,\n toggle: props.toggle,\n }}\"\n :disabled=\"${props.disabled}\"\n :bind=\"${{ 'aria-label': props.ariaLabel || props.icon, 'aria-pressed': props.toggle ? String(selected.value) : null }}\"\n type=\"button\"\n @click=\"${() => {\n if (props.toggle) { emit('change', !selected.value); selected.value = !selected.value; }\n emit('click');\n }}\"\n >\n <span class=\"icon\" aria-hidden=\"true\">${displayIcon}</span>\n </button>\n `;\n});\n","import { component, html, css, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-list', () => {\n const props = useProps({\n role: 'list',\n });\n\n useStyle(() => css`\n :host { display: block; }\n\n .list {\n background: var(--md-sys-color-surface, #FFFBFE);\n }\n `);\n\n return html`\n <div class=\"list\" role=\"${props.role}\">\n <slot></slot>\n </div>\n `;\n});\n\ncomponent('md-list-item', () => {\n const props = useProps({\n headline: '',\n supportingText: '',\n leadingIcon: '',\n trailingIcon: '',\n trailingSupportingText: '',\n disabled: false,\n selected: false,\n type: 'text' as 'text' | 'link' | 'checkbox' | 'radio',\n });\n const emit = useEmit();\n\n useStyle(() => css`\n :host { display: block; }\n\n .list-item {\n display: flex;\n align-items: center;\n gap: 16px;\n min-height: 56px;\n padding: 8px 16px;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n position: relative;\n overflow: hidden;\n transition: background-color 200ms;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n }\n .list-item::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .list-item:hover::before { opacity: 0.08; }\n .list-item:focus::before { opacity: 0.12; }\n .list-item:active::before { opacity: 0.12; }\n .list-item.selected::before { opacity: 0.12; background: var(--md-sys-color-primary, #6750A4); }\n .list-item.selected { color: var(--md-sys-color-primary, #6750A4); }\n .list-item.disabled { opacity: 0.38; pointer-events: none; }\n\n .leading-slot {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n }\n .leading-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .selected .leading-icon { color: var(--md-sys-color-primary, #6750A4); }\n\n .content { flex: 1; min-width: 0; }\n .headline {\n font-size: 16px;\n font-weight: 400;\n line-height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .supporting-text {\n font-size: 14px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n line-height: 20px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .trailing-slot {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n .trailing-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .trailing-text {\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n `);\n\n return html`\n <div\n :class=\"${{\n 'list-item': true,\n selected: props.selected,\n disabled: props.disabled,\n }}\"\n role=\"listitem\"\n tabindex=\"${props.disabled ? -1 : 0}\"\n @click=\"${() => !props.disabled && emit('click')}\"\n @keydown=\"${(e: KeyboardEvent) => { if (!props.disabled && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); emit('click'); } }}\"\n >\n ${when(!!props.leadingIcon, () => html`\n <div class=\"leading-slot\">\n <span class=\"leading-icon\">${props.leadingIcon}</span>\n </div>\n `)}\n ${when(!props.leadingIcon, () => html`<slot name=\"leading\" class=\"leading-slot\"></slot>`)}\n\n <div class=\"content\">\n <div class=\"headline\">${props.headline}<slot></slot></div>\n ${when(!!props.supportingText, () => html`\n <div class=\"supporting-text\">${props.supportingText}</div>\n `)}\n </div>\n\n <div class=\"trailing-slot\">\n ${when(!!props.trailingSupportingText, () => html`\n <span class=\"trailing-text\">${props.trailingSupportingText}</span>\n `)}\n ${when(!!props.trailingIcon, () => html`\n <span class=\"trailing-icon\">${props.trailingIcon}</span>\n `)}\n <slot name=\"trailing\"></slot>\n </div>\n </div>\n `;\n});\n","import { component, html, css, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\n\n/**\n * md-loading-indicator\n *\n * The MD3 four-colored indeterminate circular loading indicator.\n * Distinct from md-progress (which covers determinate/indeterminate\n * single-color progress indicators).\n *\n * Props:\n * size — 'small' | 'medium' | 'large' (36px / 48px / 64px)\n * ariaLabel — accessible description (default \"Loading\")\n */\ncomponent('md-loading-indicator', () => {\n const props = useProps({\n size: 'medium' as 'small' | 'medium' | 'large',\n ariaLabel: 'Loading',\n });\n\n useStyle(() => css`\n :host { display: inline-flex; align-items: center; justify-content: center; }\n\n .loader {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .loader.small { width: 36px; height: 36px; }\n .loader.medium { width: 48px; height: 48px; }\n .loader.large { width: 64px; height: 64px; }\n\n svg {\n width: 100%;\n height: 100%;\n animation: md-rotate 1.4s linear infinite;\n }\n\n /* Four colored arcs use stroke-dashoffset animation */\n .track {\n fill: none;\n stroke-width: 4;\n stroke-linecap: round;\n }\n\n .arc1 { stroke: var(--md-sys-color-primary, #6750A4); animation: md-arc 1.4s ease-in-out infinite; }\n .arc2 { stroke: var(--md-sys-color-tertiary, #7D5260); animation: md-arc 1.4s ease-in-out infinite -0.35s; }\n .arc3 { stroke: var(--md-sys-color-secondary, #625B71); animation: md-arc 1.4s ease-in-out infinite -0.7s; }\n .arc4 { stroke: var(--md-sys-color-error, #B3261E); animation: md-arc 1.4s ease-in-out infinite -1.05s; }\n\n @keyframes md-rotate {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n /* Animate stroke-dashoffset to produce the arc-grow / shrink effect */\n @keyframes md-arc {\n 0% { stroke-dasharray: 1px, 200px; stroke-dashoffset: 0; }\n 50% { stroke-dasharray: 100px, 200px; stroke-dashoffset: -15px; }\n 100% { stroke-dasharray: 100px, 200px; stroke-dashoffset: -125px; }\n }\n `);\n\n // Circle radius=20, circumference≈125.7\n // viewBox = 0 0 50 50 → centre 25,25 r=20\n return html`\n <div\n :class=\"${{ loader: true, [props.size]: true }}\"\n role=\"progressbar\"\n aria-label=\"${props.ariaLabel}\"\n aria-busy=\"true\"\n >\n <svg viewBox=\"0 0 50 50\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle class=\"track arc1\" cx=\"25\" cy=\"25\" r=\"20\"\n stroke-dasharray=\"125\" stroke-dashoffset=\"0\" />\n <circle class=\"track arc2\" cx=\"25\" cy=\"25\" r=\"20\"\n stroke-dasharray=\"125\" stroke-dashoffset=\"0\" />\n <circle class=\"track arc3\" cx=\"25\" cy=\"25\" r=\"20\"\n stroke-dasharray=\"125\" stroke-dashoffset=\"0\" />\n <circle class=\"track arc4\" cx=\"25\" cy=\"25\" r=\"20\"\n stroke-dasharray=\"125\" stroke-dashoffset=\"0\" />\n </svg>\n </div>\n `;\n});\n","/**\n * Options for useListKeyNav.\n */\nexport interface ListKeyNavOptions {\n /** Whether arrow keys navigate left/right or up/down. */\n orientation: 'horizontal' | 'vertical';\n /**\n * CSS selector (relative to the container) used to find navigable items.\n * Disabled items should be excluded, e.g. `'[role=\"menuitem\"]:not([disabled])'`.\n */\n itemSelector: string;\n /**\n * Optional callback invoked after focus moves to the new item.\n * Use this to update component state in addition to focus movement,\n * e.g. activating a tab or selecting a radio segment.\n */\n onNavigate?: (item: HTMLElement, index: number) => void;\n}\n\n/**\n * Returns a `keydown` event handler that implements arrow-key, Home, and End\n * navigation within a container element. Attach the handler to the container\n * element via `@keydown`.\n *\n * The handler queries `:focus` within the container to determine the current\n * item. This correctly resolves focus inside shadow DOM where\n * `document.activeElement` would only return the host element.\n *\n * @example\n * // Vertical list (menu):\n * const handleKeyDown = useListKeyNav({\n * orientation: 'vertical',\n * itemSelector: '[role=\"menuitem\"]:not([disabled])',\n * });\n *\n * // Horizontal list with activation callback (tabs):\n * const handleKeyDown = useListKeyNav({\n * orientation: 'horizontal',\n * itemSelector: '[role=\"tab\"]',\n * onNavigate: (_, idx) => { active.value = tabs[idx].id; emit('tab-change', tabs[idx].id); },\n * });\n */\nexport function useListKeyNav(options: ListKeyNavOptions): (e: KeyboardEvent) => void {\n const prevKey = options.orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n const nextKey = options.orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n\n return (e: KeyboardEvent) => {\n const container = e.currentTarget as HTMLElement;\n const items = Array.from(container.querySelectorAll<HTMLElement>(options.itemSelector));\n if (!items.length) return;\n\n const focused = container.querySelector<HTMLElement>(':focus');\n const focusedItem = focused ? (items.find(i => i === focused || i.contains(focused)) ?? null) : null;\n const currentIdx = focusedItem ? items.indexOf(focusedItem) : -1;\n let newIdx = currentIdx;\n\n if (e.key === nextKey) { newIdx = currentIdx < 0 ? 0 : (currentIdx + 1) % items.length; }\n else if (e.key === prevKey) { newIdx = currentIdx < 0 ? items.length - 1 : (currentIdx - 1 + items.length) % items.length; }\n else if (e.key === 'Home') { newIdx = 0; }\n else if (e.key === 'End') { newIdx = items.length - 1; }\n else { return; }\n\n e.preventDefault();\n const item = items[newIdx];\n item?.focus();\n if (item) options.onNavigate?.(item, newIdx);\n };\n}\n","import { getCurrentComponentContext } from '@jasonshimmy/custom-elements-runtime';\n\nfunction getDeepActiveElement(): HTMLElement | null {\n let el: Element | null = document.activeElement;\n while (el?.shadowRoot?.activeElement) el = el.shadowRoot.activeElement;\n return el as HTMLElement | null;\n}\n\n/**\n * Creates a lightweight focus-return handler (no Tab trapping) for overlays\n * that don't need full keyboard confinement — e.g. side sheets, drawers, menus.\n *\n * Wire the returned callbacks into a CER `Transition`:\n * `onAfterEnter: focusReturn.onAfterEnter, onAfterLeave: focusReturn.onAfterLeave`\n *\n * State is stored on the component context so it survives re-renders.\n *\n * @example\n * const focusReturn = createFocusReturn();\n * // In template:\n * Transition({ show: props.open, onAfterEnter: focusReturn.onAfterEnter, onAfterLeave: focusReturn.onAfterLeave }, html`...`)\n */\nexport function createFocusReturn() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctx = getCurrentComponentContext() as any;\n\n if (!ctx.__mdFocusReturn) {\n const state = { previousFocus: null as HTMLElement | null };\n\n ctx.__mdFocusReturn = {\n onAfterEnter(_el?: HTMLElement) {\n state.previousFocus = getDeepActiveElement();\n },\n onAfterLeave(_el?: HTMLElement) {\n state.previousFocus?.focus();\n state.previousFocus = null;\n },\n };\n }\n\n return ctx.__mdFocusReturn as {\n onAfterEnter: (el?: HTMLElement) => void;\n onAfterLeave: (el?: HTMLElement) => void;\n };\n}\n\n","import { component, html, css, defineModel, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when, each } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { useListKeyNav } from '../composables/useListKeyNav';\nimport { createFocusReturn } from '../composables/useFocusReturn';\n\ninterface MenuItem {\n id: string;\n label: string;\n icon?: string;\n disabled?: boolean;\n divider?: boolean;\n}\n\ncomponent('md-menu', () => {\n const props = useProps({\n items: [] as MenuItem[],\n anchor: 'bottom-start' as 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end',\n });\n const emit = useEmit();\n const open = defineModel('open', false);\n\n useStyle(() => css`\n :host { display: inline-block; position: relative; }\n\n .menu-wrapper { position: relative; display: inline-flex; }\n\n .menu {\n position: absolute;\n background: var(--md-sys-color-surface-container, #F3EDF7);\n border-radius: 4px;\n min-width: 112px;\n max-width: 280px;\n box-shadow: var(--md-sys-elevation-2);\n z-index: 500;\n overflow: hidden;\n transform-origin: top left;\n animation: menu-in 120ms cubic-bezier(0, 0, 0.2, 1);\n padding: 8px 0;\n }\n @keyframes menu-in {\n from { opacity: 0; transform: scale(0.8); }\n to { opacity: 1; transform: scale(1); }\n }\n\n .menu.bottom-start { top: 100%; left: 0; }\n .menu.bottom-end { top: 100%; right: 0; }\n .menu.top-start { bottom: 100%; left: 0; }\n .menu.top-end { bottom: 100%; right: 0; }\n\n .menu-item {\n display: flex;\n align-items: center;\n gap: 12px;\n height: 48px;\n padding: 0 12px;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n border: none;\n background: transparent;\n width: 100%;\n text-align: left;\n outline: none;\n position: relative;\n overflow: hidden;\n white-space: nowrap;\n }\n .menu-item::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .menu-item:hover::before { opacity: 0.08; }\n .menu-item:focus::before { opacity: 0.12; }\n .menu-item:active::before { opacity: 0.12; }\n .menu-item:disabled { opacity: 0.38; cursor: not-allowed; pointer-events: none; }\n\n .item-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n flex-shrink: 0;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n\n .menu-divider {\n height: 1px;\n background: var(--md-sys-color-outline-variant, #CAC4D0);\n margin: 8px 0;\n }\n\n .scrim {\n position: fixed;\n inset: 0;\n z-index: 499;\n }\n `);\n\n const handleMenuKeyDown = useListKeyNav({\n orientation: 'vertical',\n itemSelector: '[role=\"menuitem\"]:not([disabled])',\n });\n\n // Auto-focus the first menu item and restore focus on close via Transition callbacks.\n const focusReturn = createFocusReturn();\n\n // Escape key: document-level listener so it fires regardless of focus.\n useEscapeKey(() => open.value, () => { emit('close'); open.value = false; })();\n\n return html`\n <div class=\"menu-wrapper\">\n <slot name=\"trigger\"></slot>\n\n ${when(open.value, () => html`\n <div class=\"scrim\" @click=\"${() => { emit('close'); open.value = false; }}\"></div>`)} \n ${Transition({\n show: open.value,\n css: false,\n onEnter: (_el: HTMLElement, done: () => void) => done(),\n onLeave: (_el: HTMLElement, done: () => void) => done(),\n onAfterEnter(el: HTMLElement) {\n focusReturn.onAfterEnter(el);\n el.querySelector<HTMLElement>('[role=\"menuitem\"]:not([disabled])')?.focus();\n },\n onAfterLeave: focusReturn.onAfterLeave,\n }, html`\n <div :class=\"${{ menu: true, [props.anchor]: !!props.anchor }}\" role=\"menu\" tabindex=\"-1\" @keydown=\"${handleMenuKeyDown}\">\n ${each(\n Array.isArray(props.items) ? props.items : [],\n (item: MenuItem) => item.divider\n ? html`<div key=\"${item.id}\" class=\"menu-divider\"></div>`\n : html`\n <button\n key=\"${item.id}\"\n class=\"menu-item\"\n role=\"menuitem\"\n :disabled=\"${item.disabled || false}\"\n @click=\"${() => { emit('select', item.id); emit('close'); open.value = false; }}\"\n >\n ${when(!!item.icon, () => html`<span class=\"item-icon\" aria-hidden=\"true\">${item.icon}</span>`)}\n ${item.label}\n </button>\n `,\n )}\n </div>\n `)}\n </div>\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { each, when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { useListKeyNav } from '../composables/useListKeyNav';\n\ninterface NavItem {\n id: string;\n label: string;\n icon: string;\n badge?: string | number;\n}\n\ncomponent('md-navigation-bar', () => {\n const props = useProps({\n items: [] as NavItem[],\n });\n const emit = useEmit();\n const active = defineModel('active', '');\n\n const handleNavKeyDown = useListKeyNav({\n orientation: 'horizontal',\n itemSelector: '.nav-item',\n });\n\n useStyle(() => css`\n :host { display: block; }\n\n .nav-bar {\n display: flex;\n background: var(--md-sys-color-surface-container, #F3EDF7);\n height: 80px;\n align-items: stretch;\n box-shadow: 0 -1px 0 var(--md-sys-color-surface-variant, #E7E0EC);\n }\n\n .nav-item {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n outline: none;\n position: relative;\n overflow: hidden;\n padding: 0;\n transition: color 200ms;\n }\n .nav-item::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .nav-item:hover::before { opacity: 0.08; }\n .nav-item:focus::before { opacity: 0.12; }\n .nav-item:active::before { opacity: 0.12; }\n\n .nav-item.active { color: var(--md-sys-color-on-secondary-container, #1D192B); }\n .nav-item.active::before { background: var(--md-sys-color-on-secondary-container, #1D192B); }\n\n .indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 64px;\n height: 32px;\n border-radius: 16px;\n position: relative;\n transition: background-color 200ms;\n }\n .active .indicator {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n }\n\n .nav-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .active .nav-icon {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n\n .nav-label {\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n letter-spacing: 0.5px;\n }\n .active .nav-label { color: var(--md-sys-color-on-secondary-container, #1D192B); }\n\n .badge {\n position: absolute;\n top: 0;\n right: 8px;\n min-width: 16px;\n height: 16px;\n background: var(--md-sys-color-error, #B3261E);\n color: var(--md-sys-color-on-error, #fff);\n border-radius: 8px;\n font-size: 11px;\n font-weight: 700;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n }\n .badge-dot {\n position: absolute;\n top: 2px;\n right: 12px;\n width: 6px;\n height: 6px;\n background: var(--md-sys-color-error, #B3261E);\n border-radius: 50%;\n }\n `);\n\n return html`\n <div class=\"nav-bar\" role=\"navigation\" aria-label=\"Navigation bar\" @keydown=\"${handleNavKeyDown}\">\n ${each(\n Array.isArray(props.items) ? props.items : [],\n (item: NavItem) => html`\n <button\n type=\"button\"\n key=\"${item.id}\"\n :class=\"${{ 'nav-item': true, active: active.value === item.id }}\"\n aria-label=\"${item.label}\"\n :bind=\"${{ 'aria-current': active.value === item.id ? 'page' : null }}\"\n @click=\"${() => { emit('change', item.id); active.value = item.id; }}\"\n >\n <div class=\"indicator\">\n <span class=\"nav-icon\" aria-hidden=\"true\">${item.icon}</span>\n ${when(!!item.badge, () => html`\n <span :class=\"${{ 'badge-dot': typeof item.badge === 'boolean', badge: typeof item.badge !== 'boolean' }}\" aria-hidden=\"true\">\n ${typeof item.badge === 'boolean' ? '' : String(item.badge)}\n </span>\n `)}\n </div>\n <span class=\"nav-label\">${item.label}</span>\n </button>\n `,\n )}\n </div>\n `;\n});\n","import { component, html, css, defineModel, useProps, useEmit, useStyle, useOnDisconnected } from '@jasonshimmy/custom-elements-runtime';\nimport { each, when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { createFocusTrap } from '../composables/useFocusTrap';\nimport { useScrollLock } from '../composables/useScrollLock';\n\ninterface DrawerItem {\n id?: string;\n label?: string;\n icon?: string;\n section?: string;\n divider?: boolean;\n disabled?: boolean;\n}\n\ncomponent('md-navigation-drawer', () => {\n const props = useProps({\n headline: '',\n variant: 'standard' as 'standard' | 'modal',\n items: [] as DrawerItem[],\n });\n const emit = useEmit();\n const open = defineModel('open', false);\n const active = defineModel('active', '');\n\n useEscapeKey(() => open.value && props.variant === 'modal', () => { emit('close'); open.value = false; })();\n const trap = createFocusTrap();\n useOnDisconnected(() => trap.cleanup());\n const scrollLock = useScrollLock();\n\n useStyle(() => css`\n :host { display: contents; }\n\n /* ── Scrim ─────────────────────────────────────────────────────────── */\n .scrim {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.32);\n z-index: 400;\n /* Base = fully visible; opacity: 1 and pointer-events: auto are defaults */\n }\n .scrim-enter-from, .scrim-leave-to {\n opacity: 0;\n pointer-events: none;\n }\n .scrim-enter-active, .scrim-leave-active {\n transition: opacity 250ms ease-out;\n }\n\n /* ── Modal drawer (position: fixed overlay) ─────────────────────────── */\n .drawer {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: 360px;\n max-width: 85vw;\n background: var(--md-sys-color-surface, #FFFBFE);\n z-index: 401;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* Base = fully open; transform: none and pointer-events: auto are defaults */\n }\n .drawer-enter-from, .drawer-leave-to {\n transform: translateX(-100%);\n pointer-events: none;\n }\n .drawer-enter-active, .drawer-leave-active {\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* ── Standard drawer: in-layout, body shrinks to accommodate ───── */\n .standard-drawer {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n width: 360px;\n height: 100%;\n background: var(--md-sys-color-surface, #FFFBFE);\n flex-shrink: 0;\n }\n .standard-enter-from, .standard-leave-to {\n width: 0;\n }\n .standard-enter-active, .standard-leave-active {\n transition: width 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* ── Inner content ──────────────────────────────────────────────────── */\n .drawer-header {\n padding: 12px 28px;\n min-height: 56px;\n display: flex;\n align-items: center;\n }\n .drawer-headline {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n\n .drawer-content {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n }\n\n .drawer-item {\n display: flex;\n align-items: center;\n gap: 12px;\n height: 56px;\n padding: 0 16px;\n border-radius: 28px;\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n outline: none;\n width: 100%;\n text-align: left;\n position: relative;\n overflow: hidden;\n box-sizing: border-box;\n }\n .drawer-item::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .drawer-item:hover::before { opacity: 0.08; }\n .drawer-item:focus::before { opacity: 0.12; }\n .drawer-item:active::before { opacity: 0.12; }\n .drawer-item:disabled { opacity: 0.38; pointer-events: none; }\n\n .drawer-item.active {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n .drawer-item.active::before {\n background: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n\n .drawer-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n flex-shrink: 0;\n position: relative;\n z-index: 1;\n }\n .drawer-item.active .drawer-icon {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n\n .drawer-label {\n position: relative;\n z-index: 1;\n }\n\n .section-label {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n padding: 18px 16px 8px;\n letter-spacing: 0.1px;\n }\n\n .divider {\n height: 1px;\n background: var(--md-sys-color-outline-variant, #CAC4D0);\n margin: 8px 12px;\n }\n `);\n\n return html`\n ${Transition({\n show: open.value && props.variant === 'modal',\n name: 'md-scrim',\n enterFrom: 'scrim-enter-from',\n enterActive: 'scrim-enter-active',\n leaveActive: 'scrim-leave-active',\n leaveTo: 'scrim-leave-to',\n }, html`\n <div class=\"scrim\" @click=\"${() => { emit('close'); open.value = false; }}\"></div>\n `)}\n\n ${props.variant === 'modal'\n ? Transition({\n show: open.value,\n name: 'md-modal-drawer',\n enterFrom: 'drawer-enter-from',\n enterActive: 'drawer-enter-active',\n leaveActive: 'drawer-leave-active',\n leaveTo: 'drawer-leave-to',\n onBeforeEnter: scrollLock.lock,\n onAfterEnter: trap.onAfterEnter,\n onAfterLeave: () => { trap.onAfterLeave(); scrollLock.unlock(); },\n }, html`\n <div\n class=\"drawer\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"${props.headline || 'Navigation drawer'}\"\n >\n ${when(!!props.headline, () => html`\n <div class=\"drawer-header\">\n <span class=\"drawer-headline\">${props.headline}</span>\n </div>\n `)}\n <div class=\"drawer-content\">\n ${each(\n Array.isArray(props.items) ? props.items : [],\n (item: DrawerItem) =>\n item.divider\n ? html`<div class=\"divider\"></div>`\n : item.section\n ? html`<div class=\"section-label\">${item.section}</div>`\n : html`\n <button\n key=\"${item.id}\"\n :class=\"${{ 'drawer-item': true, active: active.value === item.id }}\"\n :disabled=\"${item.disabled || false}\"\n :bind=\"${{ 'aria-current': active.value === item.id ? 'page' : null }}\"\n @click=\"${() => { if (item.id) { emit('change', item.id); active.value = item.id; emit('close'); open.value = false; } }}\"\n >\n ${when(!!item.icon, () => html`<span class=\"drawer-icon\" aria-hidden=\"true\">${item.icon}</span>`)}\n <span class=\"drawer-label\">${item.label}</span>\n </button>\n `,\n )}\n <slot></slot>\n </div>\n </div>\n `)\n : Transition({\n show: open.value,\n name: 'md-standard-drawer',\n enterFrom: 'standard-enter-from',\n enterActive: 'standard-enter-active',\n leaveActive: 'standard-leave-active',\n leaveTo: 'standard-leave-to',\n }, html`\n <div\n class=\"standard-drawer\"\n role=\"navigation\"\n aria-label=\"${props.headline || 'Navigation drawer'}\"\n >\n ${when(!!props.headline, () => html`\n <div class=\"drawer-header\">\n <span class=\"drawer-headline\">${props.headline}</span>\n </div>\n `)}\n <div class=\"drawer-content\">\n ${each(\n Array.isArray(props.items) ? props.items : [],\n (item: DrawerItem) =>\n item.divider\n ? html`<div class=\"divider\"></div>`\n : item.section\n ? html`<div class=\"section-label\">${item.section}</div>`\n : html`\n <button\n key=\"${item.id}\"\n :class=\"${{ 'drawer-item': true, active: active.value === item.id }}\"\n :disabled=\"${item.disabled || false}\"\n :bind=\"${{ 'aria-current': active.value === item.id ? 'page' : null }}\"\n @click=\"${() => { if (item.id) { emit('change', item.id); active.value = item.id; } }}\"\n >\n ${when(!!item.icon, () => html`<span class=\"drawer-icon\" aria-hidden=\"true\">${item.icon}</span>`)}\n <span class=\"drawer-label\">${item.label}</span>\n </button>\n `,\n )}\n <slot></slot>\n </div>\n </div>\n `)\n }\n `;\n});\n\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { each, when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { useListKeyNav } from '../composables/useListKeyNav';\n\ninterface NavItem {\n id: string;\n label: string;\n icon: string;\n badge?: string | number;\n}\n\ncomponent('md-navigation-rail', () => {\n const props = useProps({\n items: [] as NavItem[],\n fab: false,\n fabIcon: 'add',\n menuIcon: false,\n });\n const emit = useEmit();\n const active = defineModel('active', '');\n\n const handleNavKeyDown = useListKeyNav({\n orientation: 'vertical',\n itemSelector: '.nav-item',\n });\n\n useStyle(() => css`\n :host { display: block; height: 100%; }\n\n .nav-rail {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 80px;\n min-height: 100%;\n background: var(--md-sys-color-surface, #FFFBFE);\n padding: 12px 0;\n gap: 4px;\n box-sizing: border-box;\n }\n\n /* ── Menu icon ── */\n .menu-btn {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n outline: none;\n position: relative;\n overflow: hidden;\n margin-bottom: 4px;\n flex-shrink: 0;\n }\n .menu-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n transition: opacity 200ms;\n }\n .menu-btn:hover::before { opacity: 0.08; }\n .menu-btn:focus::before { opacity: 0.12; }\n\n /* ── FAB ── */\n .fab {\n width: 56px;\n height: 56px;\n border-radius: 16px;\n border: none;\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n outline: none;\n position: relative;\n overflow: hidden;\n margin-bottom: 8px;\n box-shadow: var(--md-sys-elevation-1, 0 1px 2px rgba(0,0,0,0.3));\n flex-shrink: 0;\n transition: box-shadow 200ms;\n }\n .fab::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: var(--md-sys-color-on-secondary-container, #1D192B);\n opacity: 0;\n transition: opacity 200ms;\n }\n .fab:hover { box-shadow: var(--md-sys-elevation-2, 0 2px 6px rgba(0,0,0,0.2)); }\n .fab:hover::before { opacity: 0.08; }\n .fab:focus::before { opacity: 0.12; }\n\n /* ── Nav item ── */\n .nav-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n padding: 4px 0;\n cursor: pointer;\n border: none;\n background: transparent;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n outline: none;\n gap: 4px;\n }\n\n .indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 32px;\n border-radius: 16px;\n position: relative;\n /* no overflow:hidden — allows badge to extend outside the pill */\n transition: background-color 200ms;\n }\n .indicator::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n pointer-events: none;\n }\n .nav-item:hover .indicator::before { opacity: 0.08; }\n .nav-item:focus .indicator::before { opacity: 0.12; }\n .nav-item:active .indicator::before { opacity: 0.12; }\n\n .nav-item.active .indicator {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n }\n .nav-item.active .indicator::before {\n background: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n .nav-item.active { color: var(--md-sys-color-on-secondary-container, #1D192B); }\n\n .nav-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n position: relative;\n z-index: 1;\n }\n .nav-item.active .nav-icon {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n\n .nav-label {\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n letter-spacing: 0.5px;\n }\n\n .badge {\n position: absolute;\n top: -4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n background: var(--md-sys-color-error, #B3261E);\n color: var(--md-sys-color-on-error, #fff);\n border-radius: 8px;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n z-index: 2;\n }\n .badge-dot {\n position: absolute;\n top: -2px;\n right: 8px;\n width: 6px;\n height: 6px;\n background: var(--md-sys-color-error, #B3261E);\n border-radius: 50%;\n z-index: 2;\n }\n\n .mat-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n `);\n\n return html`\n <nav class=\"nav-rail\" aria-label=\"Navigation rail\" @keydown=\"${handleNavKeyDown}\">\n ${when(props.menuIcon, () => html`\n <button type=\"button\" class=\"menu-btn\" aria-label=\"Open navigation menu\" @click=\"${() => emit('menu-click')}\">\n <span class=\"mat-icon\" aria-hidden=\"true\">menu</span>\n </button>\n `)}\n ${when(props.fab, () => html`\n <button type=\"button\" class=\"fab\" aria-label=\"Create\" @click=\"${() => emit('fab-click')}\">\n <span class=\"mat-icon\" aria-hidden=\"true\">${props.fabIcon}</span>\n </button>\n `)}\n ${each(\n Array.isArray(props.items) ? props.items : [],\n (item: NavItem) => html`\n <button\n key=\"${item.id}\"\n :class=\"${{ 'nav-item': true, active: active.value === item.id }}\"\n aria-label=\"${item.label}\"\n :bind=\"${{ 'aria-current': active.value === item.id ? 'page' : null }}\"\n @click=\"${() => { emit('change', item.id); active.value = item.id; }}\"\n >\n <div class=\"indicator\">\n <span class=\"nav-icon\" aria-hidden=\"true\">${item.icon}</span>\n ${when(!!item.badge, () => html`\n <span :class=\"${{ 'badge-dot': typeof item.badge === 'boolean', badge: typeof item.badge !== 'boolean' }}\" aria-hidden=\"true\">\n ${typeof item.badge === 'boolean' ? '' : String(item.badge)}\n </span>\n `)}\n </div>\n <span class=\"nav-label\">${item.label}</span>\n </button>\n `,\n )}\n </nav>\n `;\n});\n","import { component, html, css, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-progress', () => {\n const props = useProps({\n variant: 'linear' as 'linear' | 'circular',\n value: 0,\n indeterminate: false,\n buffer: 100,\n ariaLabel: 'Loading',\n });\n\n useStyle(() => css`\n :host { display: block; }\n\n /* ── Linear ── */\n .linear {\n width: 100%;\n height: 4px;\n border-radius: 2px;\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n overflow: hidden;\n position: relative;\n }\n\n .linear-buffer {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n border-radius: 2px;\n background: var(--md-sys-color-primary-container, #EADDFF);\n transition: width 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .linear-indicator {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n border-radius: 2px;\n background: var(--md-sys-color-primary, #6750A4);\n transition: width 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes linear-indeterminate {\n 0% { transform: translateX(-100%) scaleX(0.5); }\n 40% { transform: translateX(0%) scaleX(0.5); }\n 60% { transform: translateX(50%) scaleX(1); }\n 100% { transform: translateX(150%) scaleX(0.5); }\n }\n .linear.indeterminate .linear-indicator {\n width: 50% !important;\n animation: linear-indeterminate 1.5s ease-in-out infinite;\n transform-origin: center left;\n }\n\n /* ── Circular ── */\n .circular {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n .circular svg {\n transform: rotate(-90deg);\n }\n\n .circular circle {\n fill: none;\n stroke-width: 4;\n stroke-linecap: round;\n transition: stroke-dashoffset 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .track-circle { stroke: var(--md-sys-color-secondary-container, #E8DEF8); }\n .indicator-circle { stroke: var(--md-sys-color-primary, #6750A4); }\n\n @keyframes circular-indeterminate {\n 0% { stroke-dashoffset: 150; }\n 50% { stroke-dashoffset: 40; }\n 100% { stroke-dashoffset: 150; }\n }\n @keyframes circular-rotate {\n 100% { transform: rotate(270deg); }\n }\n .circular.indeterminate svg {\n animation: circular-rotate 1.5s linear infinite;\n }\n .circular.indeterminate .indicator-circle {\n animation: circular-indeterminate 1.5s ease-in-out infinite;\n }\n `);\n\n const RADIUS = 18;\n const CIRCUMFERENCE = 2 * Math.PI * RADIUS;\n const dashoffset = CIRCUMFERENCE - (props.value / 100) * CIRCUMFERENCE;\n\n return html`\n ${when(\n props.variant === 'linear',\n () => html`\n <div\n :class=\"${{ linear: true, indeterminate: props.indeterminate }}\"\n role=\"progressbar\"\n aria-label=\"${props.ariaLabel}\"\n :bind=\"${{\n 'aria-valuenow': props.indeterminate ? null : String(props.value),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n }}\"\n >\n ${when(!props.indeterminate && props.buffer < 100, () => html`\n <div class=\"linear-buffer\" :style=\"${{ width: `${props.buffer}%` }}\"></div>\n `)}\n <div\n class=\"linear-indicator\"\n :style=\"${{ width: props.indeterminate ? '50%' : `${props.value}%` }}\"\n ></div>\n </div>\n `,\n )}\n ${when(\n props.variant === 'circular',\n () => html`\n <div\n :class=\"${{ circular: true, indeterminate: props.indeterminate }}\"\n role=\"progressbar\"\n aria-label=\"${props.ariaLabel}\"\n :bind=\"${{\n 'aria-valuenow': props.indeterminate ? null : String(props.value),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n }}\"\n >\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 48 48\">\n <circle class=\"track-circle\" cx=\"24\" cy=\"24\" r=\"${RADIUS}\" />\n <circle\n class=\"indicator-circle\"\n cx=\"24\"\n cy=\"24\"\n r=\"${RADIUS}\"\n :style=\"${{\n strokeDasharray: String(CIRCUMFERENCE),\n strokeDashoffset: props.indeterminate ? undefined : String(dashoffset),\n }}\"\n />\n </svg>\n </div>\n `,\n )}\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\n\ncomponent('md-radio', () => {\n const props = useProps({\n disabled: false,\n name: '',\n value: '',\n label: '',\n });\n const emit = useEmit();\n const checked = defineModel('checked', false);\n\n useStyle(() => css`\n :host { display: inline-flex; align-items: center; vertical-align: middle; }\n\n label {\n display: inline-flex;\n align-items: center;\n gap: 12px;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n user-select: none;\n }\n label.disabled { opacity: 0.38; cursor: not-allowed; }\n\n .radio-container {\n width: 40px;\n height: 40px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n position: relative;\n flex-shrink: 0;\n }\n .radio-container::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .radio-container.checked::before {\n background: var(--md-sys-color-primary, #6750A4);\n }\n label:hover .radio-container::before { opacity: 0.08; }\n label:focus-within .radio-container::before { opacity: 0.12; }\n label:active .radio-container::before { opacity: 0.12; }\n\n input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 40px;\n height: 40px;\n margin: 0;\n cursor: pointer;\n }\n input[type=\"radio\"]:disabled { cursor: not-allowed; }\n\n .circle {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n border: 2px solid var(--md-sys-color-on-surface-variant, #49454F);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 200ms;\n flex-shrink: 0;\n }\n .checked .circle { border-color: var(--md-sys-color-primary, #6750A4); }\n\n .inner {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--md-sys-color-primary, #6750A4);\n transform: scale(0);\n transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n .checked .inner { transform: scale(1); }\n `);\n\n return html`\n <label :class=\"${{ disabled: props.disabled }}\">\n <div :class=\"${{\n 'radio-container': true,\n checked: checked.value,\n }}\">\n <input\n type=\"radio\"\n :checked=\"${checked.value}\"\n :disabled=\"${props.disabled}\"\n :name=\"${props.name}\"\n :value=\"${props.value}\"\n @change=\"${() => { emit('change', props.value); checked.value = props.value as unknown as boolean; }}\"\n />\n <div class=\"circle\">\n <div class=\"inner\"></div>\n </div>\n </div>\n ${props.label}\n </label>\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-search', () => {\n const props = useProps({\n placeholder: 'Search',\n leadingIcon: 'search',\n showAvatar: false,\n });\n const emit = useEmit();\n const modelValue = defineModel('');\n\n const handleClear = () => {\n modelValue.value = '';\n emit('clear');\n };\n\n useStyle(() => css`\n :host { display: block; }\n\n .search-bar {\n display: flex;\n align-items: center;\n height: 56px;\n background: var(--md-sys-color-surface-container-high, #ECE6F0);\n border-radius: 28px;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--md-sys-elevation-1, 0 1px 2px rgba(0,0,0,0.3));\n transition: box-shadow 200ms;\n }\n .search-bar:focus-within {\n background: var(--md-sys-color-surface-container-highest, #E6E0E9);\n box-shadow: var(--md-sys-elevation-2, 0 2px 6px rgba(0,0,0,0.15));\n }\n\n .lead-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n flex-shrink: 0;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n\n .search-input {\n flex: 1;\n border: none;\n background: transparent;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 16px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n outline: none;\n caret-color: var(--md-sys-color-primary, #6750A4);\n min-width: 0;\n }\n .search-input::placeholder {\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n /* Remove native search cancel button */\n .search-input::-webkit-search-cancel-button { display: none; }\n\n .clear-btn {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n outline: none;\n position: relative;\n overflow: hidden;\n flex-shrink: 0;\n }\n .clear-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n transition: opacity 200ms;\n }\n .clear-btn:hover::before { opacity: 0.08; }\n .clear-btn:focus::before { opacity: 0.12; }\n\n .clear-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n position: relative;\n z-index: 1;\n }\n\n .avatar {\n width: 30px;\n height: 30px;\n border-radius: 50%;\n background: var(--md-sys-color-primary-container, #EADDFF);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: hidden;\n }\n .avatar-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 20px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n color: var(--md-sys-color-on-primary-container, #21005D);\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n }\n `);\n\n return html`\n <div class=\"search-bar\" role=\"search\">\n <span class=\"lead-icon\" aria-hidden=\"true\">${props.leadingIcon}</span>\n <input\n type=\"search\"\n class=\"search-input\"\n placeholder=\"${props.placeholder}\"\n :model=\"${modelValue}\"\n aria-label=\"${props.placeholder}\"\n @keydown=\"${(e: KeyboardEvent) => { if (e.key === 'Enter') emit('search', modelValue.value); }}\"\n >\n ${when(!!modelValue.value, () => html`\n <button type=\"button\" class=\"clear-btn\" aria-label=\"Clear search\" @click=\"${handleClear}\">\n <span class=\"clear-icon\" aria-hidden=\"true\">close</span>\n </button>\n `)}\n ${when(props.showAvatar, () => html`\n <div class=\"avatar\">\n <span class=\"avatar-icon\">person</span>\n </div>\n `)}\n </div>\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { each, when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { useListKeyNav } from '../composables/useListKeyNav';\n\ninterface Segment {\n id: string;\n label?: string;\n icon?: string;\n disabled?: boolean;\n}\n\ncomponent('md-segmented-button', () => {\n const props = useProps({\n segments: [] as Segment[],\n multiselect: false,\n ariaLabel: '',\n });\n const emit = useEmit();\n const selected = defineModel('selected', '' as string | string[]);\n\n const handleKeyDown = useListKeyNav({\n orientation: 'horizontal',\n itemSelector: 'button:not([disabled])',\n onNavigate: (item) => {\n // For single-select (radio), arrow keys both move focus and activate the item.\n if (!props.multiselect) item.click();\n },\n });\n\n const isSelected = (id: string): boolean => {\n if (Array.isArray(selected.value)) return selected.value.includes(id);\n return selected.value === id;\n };\n\n const handleClick = (id: string) => {\n if (props.multiselect) {\n const current = Array.isArray(selected.value)\n ? [...selected.value]\n : selected.value ? [selected.value as string] : [];\n const idx = current.indexOf(id);\n if (idx >= 0) current.splice(idx, 1);\n else current.push(id);\n emit('change', current);\n selected.value = current;\n } else {\n emit('change', id);\n selected.value = id;\n }\n };\n\n useStyle(() => css`\n :host { display: inline-flex; }\n\n .segmented-btn-group {\n display: inline-flex;\n height: 40px;\n border: 1px solid var(--md-sys-color-outline, #79747E);\n border-radius: 20px;\n overflow: hidden;\n }\n\n .segment {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n min-width: 48px;\n padding: 0 16px;\n border: none;\n border-right: 1px solid var(--md-sys-color-outline, #79747E);\n background: transparent;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n outline: none;\n position: relative;\n overflow: hidden;\n white-space: nowrap;\n }\n .segment:last-child { border-right: none; }\n .segment:disabled { opacity: 0.38; cursor: not-allowed; pointer-events: none; }\n\n .segment::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .segment:hover::before { opacity: 0.08; }\n .segment:focus::before { opacity: 0.12; }\n .segment:active::before { opacity: 0.12; }\n\n .segment.selected {\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n color: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n .segment.selected::before {\n background: var(--md-sys-color-on-secondary-container, #1D192B);\n }\n\n .seg-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n position: relative;\n z-index: 1;\n }\n .segment.selected .seg-icon {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n }\n\n .check-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n position: relative;\n z-index: 1;\n }\n\n .seg-label {\n position: relative;\n z-index: 1;\n }\n `);\n\n return html`\n <div class=\"segmented-btn-group\" role=\"${props.multiselect ? 'group' : 'radiogroup'}\" :bind=\"${{ 'aria-label': props.ariaLabel || null }}\" @keydown=\"${handleKeyDown}\">\n ${each(\n Array.isArray(props.segments) ? props.segments : [],\n (seg: Segment) => html`\n <button\n key=\"${seg.id}\"\n :class=\"${{ segment: true, selected: isSelected(seg.id) }}\"\n :disabled=\"${seg.disabled || false}\"\n role=\"${props.multiselect ? 'checkbox' : 'radio'}\"\n aria-checked=\"${String(isSelected(seg.id))}\"\n @click=\"${() => { if (!seg.disabled) handleClick(seg.id); }}\"\n >\n ${when(isSelected(seg.id), () => html`<span class=\"check-icon\" aria-hidden=\"true\">check</span>`)}\n ${when(!isSelected(seg.id) && !!seg.icon, () => html`<span class=\"seg-icon\" aria-hidden=\"true\">${seg.icon}</span>`)}\n ${when(!!seg.label, () => html`<span class=\"seg-label\">${seg.label}</span>`)}\n </button>\n `,\n )}\n </div>\n `;\n});\n","import { component, html, css, defineModel, useProps, useEmit, useStyle, useOnDisconnected } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { createFocusTrap } from '../composables/useFocusTrap';\nimport { useScrollLock } from '../composables/useScrollLock';\n\ncomponent('md-side-sheet', () => {\n const props = useProps({\n headline: '',\n variant: 'standard' as 'standard' | 'modal',\n divider: true,\n });\n const emit = useEmit();\n const open = defineModel('open', false);\n\n // Only modal variant uses escape key, focus trap, and scroll lock.\n useEscapeKey(() => open.value && props.variant === 'modal', () => { emit('close'); open.value = false; })();\n const trap = createFocusTrap();\n useOnDisconnected(() => trap.cleanup());\n const scrollLock = useScrollLock();\n\n useStyle(() => css`\n :host { display: contents; }\n\n /* ── Scrim (modal only) ─────────────────────────────────────── */\n .scrim {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.32);\n z-index: 500;\n }\n .scrim-enter-from, .scrim-leave-to {\n opacity: 0;\n pointer-events: none;\n }\n .scrim-enter-active, .scrim-leave-active {\n transition: opacity 250ms ease-out;\n }\n\n /* ── Modal side sheet: overlays content, slides in from right ── */\n .modal-side-sheet {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 360px;\n max-width: 85vw;\n background: var(--md-sys-color-surface-container-low, #F7F2FA);\n border-radius: 16px 0 0 16px;\n z-index: 501;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .modal-enter-from, .modal-leave-to {\n transform: translateX(100%);\n pointer-events: none;\n }\n .modal-enter-active, .modal-leave-active {\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n /* ── Standard side sheet: in-layout, body shrinks to accommodate ── */\n .standard-side-sheet {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n width: 400px;\n height: 100%;\n background: var(--md-sys-color-surface, #FFFBFE);\n flex-shrink: 0;\n }\n .standard-side-sheet.with-divider {\n border-left: 1px solid var(--md-sys-color-outline-variant, #CAC4D0);\n }\n\n\n /* ── Shared header & content ─────────────────────────────────── */\n .sheet-header {\n display: flex;\n align-items: center;\n padding: 24px 24px 0;\n gap: 4px;\n flex-shrink: 0;\n }\n .sheet-headline {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 24px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n margin: 0;\n flex: 1;\n }\n\n .icon-btn {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n outline: none;\n position: relative;\n overflow: hidden;\n flex-shrink: 0;\n }\n .icon-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n transition: opacity 200ms;\n }\n .icon-btn:hover::before { opacity: 0.08; }\n .icon-btn:focus::before { opacity: 0.12; }\n\n .icon-btn-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n position: relative;\n z-index: 1;\n }\n\n .sheet-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px 24px 24px;\n }\n `);\n\n return html`\n ${Transition({\n show: open.value && props.variant === 'modal',\n name: 'md-scrim',\n enterFrom: 'scrim-enter-from',\n enterActive: 'scrim-enter-active',\n leaveActive: 'scrim-leave-active',\n leaveTo: 'scrim-leave-to',\n }, html`\n <div class=\"scrim\" @click=\"${() => { emit('close'); open.value = false; }}\"></div>\n `)}\n\n ${props.variant === 'modal'\n ? Transition({\n show: open.value,\n name: 'md-modal-side-sheet',\n enterFrom: 'modal-enter-from',\n enterActive: 'modal-enter-active',\n leaveActive: 'modal-leave-active',\n leaveTo: 'modal-leave-to',\n onBeforeEnter: scrollLock.lock,\n onAfterEnter: trap.onAfterEnter,\n onAfterLeave: () => { trap.onAfterLeave(); scrollLock.unlock(); },\n }, html`\n <div\n class=\"modal-side-sheet\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"${props.headline || 'Side sheet'}\"\n >\n ${when(!!props.headline, () => html`\n <div class=\"sheet-header\">\n <button class=\"icon-btn\" aria-label=\"Go back\" @click=\"${() => emit('back')}\">\n <span class=\"icon-btn-icon\">arrow_back</span>\n </button>\n <h2 class=\"sheet-headline\">${props.headline}</h2>\n <button class=\"icon-btn\" aria-label=\"Close side sheet\" @click=\"${() => { emit('close'); open.value = false; }}\">\n <span class=\"icon-btn-icon\">close</span>\n </button>\n </div>\n `)}\n <div class=\"sheet-content\">\n <slot></slot>\n </div>\n </div>\n `)\n : Transition({\n show: open.value,\n name: 'md-standard-side-sheet',\n css: false,\n onBeforeEnter: (el) => {\n (el as HTMLElement).style.width = '0';\n },\n onEnter: (el, done) => {\n const h = el as HTMLElement;\n h.offsetHeight; // force reflow to commit width: 0\n h.style.transition = 'width 300ms cubic-bezier(0.4, 0, 0.2, 1)';\n h.style.width = '400px';\n h.addEventListener('transitionend', () => done(), { once: true });\n },\n onAfterEnter: (el) => {\n const h = el as HTMLElement;\n h.style.removeProperty('width');\n h.style.removeProperty('transition');\n },\n onBeforeLeave: (el) => {\n const h = el as HTMLElement;\n h.style.width = `${h.offsetWidth}px`;\n },\n onLeave: (el, done) => {\n const h = el as HTMLElement;\n h.style.transition = 'width 300ms cubic-bezier(0.4, 0, 0.2, 1)';\n h.style.width = '0';\n h.addEventListener('transitionend', () => done(), { once: true });\n },\n onAfterLeave: (el) => {\n const h = el as HTMLElement;\n h.style.removeProperty('width');\n h.style.removeProperty('transition');\n },\n }, html`\n <div\n :class=\"${{ 'standard-side-sheet': true, 'with-divider': props.divider }}\"\n role=\"complementary\"\n aria-label=\"${props.headline || 'Side sheet'}\"\n >\n ${when(!!props.headline, () => html`\n <div class=\"sheet-header\">\n <h2 class=\"sheet-headline\">${props.headline}</h2>\n <button class=\"icon-btn\" aria-label=\"Close side sheet\" @click=\"${() => { emit('close'); open.value = false; }}\">\n <span class=\"icon-btn-icon\">close</span>\n </button>\n </div>\n `)}\n <div class=\"sheet-content\">\n <slot></slot>\n </div>\n </div>\n `)\n }\n `;\n});\n","import { component, html, css, computed, defineModel, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { each } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-slider', () => {\n const props = useProps({\n min: 0,\n max: 100,\n step: 1,\n disabled: false,\n labeled: false,\n ticks: false,\n ariaLabel: '',\n });\n const modelValue = defineModel(50);\n const percentage = computed(() =>\n ((modelValue.value - props.min) / (props.max - props.min)) * 100,\n );\n\n useStyle(() => css`\n :host { display: block; }\n\n .slider-wrapper {\n position: relative;\n height: 40px;\n display: flex;\n align-items: center;\n }\n\n input[type=\"range\"] {\n -webkit-appearance: none;\n appearance: none;\n width: 100%;\n height: 4px;\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n background: transparent;\n position: relative;\n z-index: 2;\n }\n input[type=\"range\"]:disabled { opacity: 0.38; cursor: not-allowed; }\n\n input[type=\"range\"]::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--md-sys-color-primary, #6750A4);\n cursor: pointer;\n box-shadow: 0 0 0 0 rgba(103,80,164,0);\n transition: box-shadow 200ms;\n }\n input[type=\"range\"]:not(:disabled)::-webkit-slider-thumb:hover {\n box-shadow: 0 0 0 8px rgba(103,80,164,0.12);\n }\n input[type=\"range\"]:not(:disabled):focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 10px rgba(103,80,164,0.12);\n }\n input[type=\"range\"]::-moz-range-thumb {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: var(--md-sys-color-primary, #6750A4);\n cursor: pointer;\n border: none;\n }\n\n .track-bg {\n position: absolute;\n left: 10px;\n right: 10px;\n height: 4px;\n border-radius: 2px;\n background: var(--md-sys-color-secondary-container, #E8DEF8);\n z-index: 0;\n }\n .track-active {\n position: absolute;\n left: 10px;\n height: 4px;\n border-radius: 2px;\n background: var(--md-sys-color-primary, #6750A4);\n z-index: 1;\n pointer-events: none;\n transition: width 0ms;\n }\n\n .value-label {\n display: none;\n position: absolute;\n top: -36px;\n transform: translateX(-50%);\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #fff);\n padding: 4px 8px;\n border-radius: 20px;\n font-size: 14px;\n font-weight: 500;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n white-space: nowrap;\n pointer-events: none;\n min-width: 28px;\n text-align: center;\n }\n .value-label.visible {\n display: block;\n }\n\n .tick-marks {\n position: absolute;\n left: 10px;\n right: 10px;\n height: 4px;\n z-index: 1;\n pointer-events: none;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n .tick {\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--md-sys-color-on-primary, #fff);\n flex-shrink: 0;\n }\n .tick.inactive {\n background: var(--md-sys-color-primary, #6750A4);\n }\n `);\n\n const tickCount = computed(() => {\n if (!props.ticks || props.step <= 0) return [];\n const count = Math.round((props.max - props.min) / props.step) + 1;\n return Array.from({ length: count }, (_, i) => {\n const tickValue = props.min + i * props.step;\n return tickValue <= modelValue.value ? 'active' : 'inactive';\n });\n });\n\n return html`\n <div class=\"slider-wrapper\">\n <div class=\"track-bg\"></div>\n <div class=\"track-active\" :style=\"${{ width: `calc(${percentage.value / 100} * (100% - 20px))` }}\"></div>\n <div class=\"tick-marks\" :style=\"${{ display: props.ticks && tickCount.value.length > 0 ? 'flex' : 'none' }}\">\n ${each(tickCount.value, (state: string, i: number) => html`\n <div key=\"${String(i)}\" :class=\"${{ tick: true, inactive: state === 'inactive' }}\"></div>\n `)}\n </div>\n <div\n :class=\"${{ 'value-label': true, visible: !!props.labeled }}\"\n :style=\"${{ left: `calc(10px + ${percentage.value / 100} * (100% - 20px))` }}\"\n >\n ${modelValue.value}\n </div>\n <input\n type=\"range\"\n :min=\"${String(props.min)}\"\n :max=\"${String(props.max)}\"\n :step=\"${String(props.step)}\"\n :model=\"${modelValue}\"\n :disabled=\"${props.disabled}\"\n :bind=\"${{ 'aria-label': props.ariaLabel || null }}\"\n />\n </div>\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-snackbar', () => {\n const props = useProps({\n message: '',\n actionLabel: '',\n });\n const emit = useEmit();\n const open = defineModel('open', false);\n\n useStyle(() => css`\n :host { display: contents; }\n\n .bar {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%) translateY(80px);\n min-width: 288px;\n max-width: 568px;\n background: var(--md-sys-color-inverse-surface, #313033);\n color: var(--md-sys-color-inverse-on-surface, #F4EFF4);\n border-radius: 4px;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0 16px;\n min-height: 48px;\n box-shadow: var(--md-sys-elevation-3);\n opacity: 0;\n pointer-events: none;\n visibility: hidden;\n z-index: 700;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n transition:\n transform 300ms cubic-bezier(0.4, 0, 0.2, 1),\n opacity 300ms cubic-bezier(0.4, 0, 0.2, 1),\n visibility 0s linear 300ms;\n }\n .bar.open {\n transform: translateX(-50%) translateY(0);\n opacity: 1;\n pointer-events: auto;\n visibility: visible;\n transition:\n transform 300ms cubic-bezier(0.4, 0, 0.2, 1),\n opacity 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .message {\n flex: 1;\n padding: 12px 0;\n line-height: 20px;\n }\n\n .action {\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--md-sys-color-inverse-primary, #D0BCFF);\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n padding: 8px 12px;\n flex-shrink: 0;\n outline: none;\n position: relative;\n overflow: hidden;\n }\n .action::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: var(--md-sys-color-inverse-primary, #D0BCFF);\n opacity: 0;\n transition: opacity 200ms;\n }\n .action:hover::before { opacity: 0.08; }\n .action:focus::before { opacity: 0.12; }\n .action:active::before { opacity: 0.12; }\n\n .close-btn {\n background: transparent;\n border: none;\n border-radius: 50%;\n cursor: pointer;\n color: var(--md-sys-color-inverse-on-surface, #F4EFF4);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n outline: none;\n flex-shrink: 0;\n position: relative;\n overflow: hidden;\n }\n .close-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: var(--md-sys-color-inverse-on-surface, #F4EFF4);\n opacity: 0;\n transition: opacity 200ms;\n }\n .close-btn:hover::before { opacity: 0.08; }\n .close-btn:focus::before { opacity: 0.12; }\n .close-btn:active::before { opacity: 0.12; }\n\n .close-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n position: relative;\n z-index: 1;\n }\n `);\n\n return html`\n <div\n :class=\"${{ bar: true, open: open.value }}\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n <span class=\"message\">${props.message}</span>\n ${when(!!props.actionLabel, () => html`\n <button type=\"button\" class=\"action\" @click=\"${() => emit('action')}\">\n ${props.actionLabel}\n </button>\n `)}\n <button type=\"button\" class=\"close-btn\" aria-label=\"Dismiss\" @click=\"${() => { emit('close'); open.value = false; }}\">\n <span class=\"close-icon\" aria-hidden=\"true\">close</span>\n </button>\n </div>\n `;\n});\n","import { component, html, css, ref, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when, each } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { useListKeyNav } from '../composables/useListKeyNav';\n\n/**\n * md-split-button\n *\n * MD3 Split button — a primary action button connected to a dropdown arrow\n * that reveals a menu of secondary actions.\n * Spec: https://m3.material.io/components/split-button\n *\n * Props:\n * label — primary button text\n * icon — optional leading icon for the primary button\n * variant — 'filled' | 'outlined' | 'tonal'\n * disabled — disables both parts\n * items — secondary action items: { id, label, icon?, disabled? }\n *\n * Emits:\n * click — primary button clicked\n * select — { id } — a dropdown item was selected\n */\n\ninterface SplitItem {\n id: string;\n label: string;\n icon?: string;\n disabled?: boolean;\n}\n\ncomponent('md-split-button', () => {\n const props = useProps({\n label: 'Action',\n icon: '',\n variant: 'filled' as 'filled' | 'outlined' | 'tonal',\n disabled: false,\n items: [] as SplitItem[],\n });\n const emit = useEmit();\n const menuOpen = ref(false);\n const previousFocus = ref<HTMLElement | null>(null);\n\n useEscapeKey(() => menuOpen.value, () => { menuOpen.value = false; })();\n\n const handleMenuKeyDown = useListKeyNav({\n orientation: 'vertical',\n itemSelector: '[role=\"menuitem\"]:not([disabled])',\n });\n\n useStyle(() => css`\n :host { display: inline-flex; vertical-align: middle; position: relative; }\n\n .split {\n display: inline-flex;\n align-items: stretch;\n }\n\n /* ── Primary button ── */\n .primary-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: 40px;\n padding: 0 16px 0 20px;\n border: none;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n line-height: 20px;\n outline: none;\n position: relative;\n overflow: hidden;\n user-select: none;\n white-space: nowrap;\n border-radius: 20px 0 0 20px;\n transition: box-shadow 280ms cubic-bezier(0.4,0,0.2,1);\n }\n\n /* ── Divider between primary and arrow ── */\n .btn-divider {\n width: 1px;\n align-self: stretch;\n }\n\n /* ── Arrow button ── */\n .arrow-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border: none;\n cursor: pointer;\n outline: none;\n position: relative;\n overflow: hidden;\n border-radius: 0 20px 20px 0;\n transition: box-shadow 280ms cubic-bezier(0.4,0,0.2,1);\n }\n\n /* State layer shared */\n .primary-btn::before,\n .arrow-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n opacity: 0;\n transition: opacity 200ms cubic-bezier(0.4,0,0.2,1);\n pointer-events: none;\n }\n .primary-btn:hover::before,\n .arrow-btn:hover::before { opacity: 0.08; }\n .primary-btn:focus::before,\n .arrow-btn:focus::before { opacity: 0.12; }\n .primary-btn:active::before,\n .arrow-btn:active::before { opacity: 0.12; }\n .primary-btn:focus-visible,\n .arrow-btn:focus-visible { outline: 2px solid var(--md-sys-color-primary,#6750A4); outline-offset: 2px; z-index: 1; }\n\n .primary-btn:disabled,\n .arrow-btn:disabled { cursor: not-allowed; pointer-events: none; }\n\n /* ── Filled variant ── */\n .filled .primary-btn,\n .filled .arrow-btn {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n .filled .primary-btn::before,\n .filled .arrow-btn::before { background: var(--md-sys-color-on-primary,#FFFFFF); }\n .filled .primary-btn:hover,\n .filled .arrow-btn:hover { box-shadow: var(--md-sys-elevation-1); }\n .filled .btn-divider { background: rgba(255,255,255,0.38); }\n .filled .primary-btn:disabled,\n .filled .arrow-btn:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); }\n\n /* ── Outlined variant ── */\n .outlined .primary-btn {\n background: transparent;\n color: var(--md-sys-color-primary,#6750A4);\n border: 1px solid var(--md-sys-color-outline,#79747E);\n border-right: none;\n }\n .outlined .arrow-btn {\n background: transparent;\n color: var(--md-sys-color-primary,#6750A4);\n border: 1px solid var(--md-sys-color-outline,#79747E);\n border-left: none;\n }\n .outlined .primary-btn::before,\n .outlined .arrow-btn::before { background: var(--md-sys-color-primary,#6750A4); }\n .outlined .btn-divider { background: var(--md-sys-color-outline,#79747E); }\n .outlined .primary-btn:disabled,\n .outlined .arrow-btn:disabled { color: rgba(28,27,31,.38); border-color: rgba(28,27,31,.12); }\n\n /* ── Tonal variant ── */\n .tonal .primary-btn,\n .tonal .arrow-btn {\n background: var(--md-sys-color-secondary-container,#E8DEF8);\n color: var(--md-sys-color-on-secondary-container,#1D192B);\n }\n .tonal .primary-btn::before,\n .tonal .arrow-btn::before { background: var(--md-sys-color-on-secondary-container,#1D192B); }\n .tonal .primary-btn:hover,\n .tonal .arrow-btn:hover { box-shadow: var(--md-sys-elevation-1); }\n .tonal .btn-divider { background: rgba(29,25,43,0.3); }\n .tonal .primary-btn:disabled,\n .tonal .arrow-btn:disabled { background: rgba(28,27,31,.12); color: rgba(28,27,31,.38); }\n\n /* ── Icon ── */\n .btn-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 18px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 18;\n }\n .arrow-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 20px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 20;\n transition: transform 200ms cubic-bezier(0.4,0,0.2,1);\n }\n .arrow-icon.open { transform: rotate(180deg); }\n\n /* ── Dropdown menu ── */\n .menu-wrapper {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n z-index: 200;\n min-width: 160px;\n }\n .menu {\n background: var(--md-sys-color-surface-container, #F3EDF7);\n border-radius: 4px;\n box-shadow: var(--md-sys-elevation-2, 0 2px 6px 2px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.3));\n overflow: hidden;\n padding: 8px 0;\n }\n .menu-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 0 16px;\n height: 48px;\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 14px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface,#1C1B1F);\n cursor: pointer;\n border: none;\n background: transparent;\n width: 100%;\n text-align: left;\n outline: none;\n position: relative;\n overflow: hidden;\n }\n .menu-item::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-on-surface,#1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .menu-item:hover::before { opacity: 0.08; }\n .menu-item:focus::before { opacity: 0.12; }\n .menu-item:active::before { opacity: 0.12; }\n .menu-item:focus-visible { outline: 2px solid var(--md-sys-color-primary,#6750A4); outline-offset: -2px; }\n .menu-item:disabled { color: rgba(28,27,31,.38); cursor: not-allowed; pointer-events: none; }\n .menu-item .btn-icon { color: var(--md-sys-color-on-surface-variant,#49454F); }\n\n /* ── Dropdown scrim ── */\n .drop-scrim {\n position: fixed;\n inset: 0;\n z-index: 199;\n cursor: default;\n }\n `);\n\n return html`\n <div :class=\"${{ split: true, [props.variant]: true }}\">\n <!-- Primary action -->\n <button\n class=\"primary-btn\"\n ?disabled=\"${props.disabled}\"\n @click=\"${() => emit('click')}\"\n >\n ${props.icon ? html`<span class=\"btn-icon\" aria-hidden=\"true\">${props.icon}</span>` : null}\n ${props.label}\n </button>\n\n <!-- Vertical divider -->\n <div class=\"btn-divider\" aria-hidden=\"true\"></div>\n\n <!-- Dropdown arrow -->\n <button\n class=\"arrow-btn\"\n aria-haspopup=\"true\"\n aria-expanded=\"${menuOpen.value}\"\n aria-label=\"More actions\"\n ?disabled=\"${props.disabled}\"\n @click=\"${(e: Event) => { e.stopPropagation(); menuOpen.value = !menuOpen.value; }}\"\n >\n <span :class=\"${{ 'arrow-icon': true, open: menuOpen.value }}\" aria-hidden=\"true\">arrow_drop_down</span>\n </button>\n </div>\n\n ${when(menuOpen.value, () => html`\n <div class=\"drop-scrim\" @click=\"${(e: Event) => { e.stopPropagation(); menuOpen.value = false; }}\"></div>\n `)}\n ${Transition({\n show: menuOpen.value,\n css: false,\n onEnter: (_el: HTMLElement, done: () => void) => done(),\n onLeave: (_el: HTMLElement, done: () => void) => done(),\n onAfterEnter(el: HTMLElement) {\n previousFocus.value = document.activeElement as HTMLElement;\n el.querySelector<HTMLElement>('[role=\"menuitem\"]:not([disabled])')?.focus();\n },\n onAfterLeave() {\n previousFocus.value?.focus();\n previousFocus.value = null;\n },\n }, html`\n <div class=\"menu-wrapper\">\n <div class=\"menu\" role=\"menu\" tabindex=\"-1\" @keydown=\"${handleMenuKeyDown}\">\n ${each(props.items, (item) => html`\n <button\n class=\"menu-item\"\n role=\"menuitem\"\n ?disabled=\"${item.disabled}\"\n @click=\"${(e: Event) => { e.stopPropagation(); emit('select', { id: item.id }); menuOpen.value = false; }}\"\n >\n ${when(!!item.icon, () => html`<span class=\"btn-icon\" aria-hidden=\"true\">${item.icon}</span>`)}\n ${item.label}\n </button>\n `)}\n </div>\n </div>\n `)}\n `;\n});\n","import { component, html, css, defineModel, useEmit, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-switch', () => {\n const props = useProps({\n disabled: false,\n icons: false,\n });\n const emit = useEmit();\n const selected = defineModel('selected', false);\n\n useStyle(() => css`\n :host { display: inline-flex; align-items: center; vertical-align: middle; }\n\n .switch {\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n user-select: none;\n position: relative;\n }\n .switch.disabled { opacity: 0.38; cursor: not-allowed; pointer-events: none; }\n\n input[type=\"checkbox\"] {\n position: absolute;\n opacity: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n cursor: pointer;\n }\n\n .track {\n width: 52px;\n height: 32px;\n border-radius: 16px;\n border: 2px solid var(--md-sys-color-outline, #79747E);\n background: var(--md-sys-color-surface-container-highest, #E6E0E9);\n display: flex;\n align-items: center;\n padding: 0 4px;\n transition: background-color 200ms, border-color 200ms;\n position: relative;\n }\n .selected .track {\n background: var(--md-sys-color-primary, #6750A4);\n border-color: var(--md-sys-color-primary, #6750A4);\n }\n\n .thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--md-sys-color-outline, #79747E);\n transform: translateX(0);\n transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1),\n width 200ms cubic-bezier(0.4, 0, 0.2, 1),\n height 200ms cubic-bezier(0.4, 0, 0.2, 1),\n background-color 200ms cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n position: relative;\n }\n .switch:hover .thumb:not(.selected) {\n width: 20px;\n height: 20px;\n background: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .switch:active .thumb:not(.selected) {\n width: 28px;\n height: 28px;\n background: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .selected .thumb {\n width: 24px;\n height: 24px;\n background: var(--md-sys-color-on-primary, #fff);\n transform: translateX(20px);\n }\n /* Selected hover: color → primary-container, size stays 24px */\n .switch.selected:hover .thumb {\n background: var(--md-sys-color-primary-container, #EADDFF);\n }\n /* Selected pressed: 28px, primary-container */\n .switch.selected:active .thumb {\n width: 28px;\n height: 28px;\n background: var(--md-sys-color-primary-container, #EADDFF);\n }\n\n /* state layer */\n .thumb::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n transition: opacity 200ms;\n pointer-events: none;\n }\n .selected .thumb::before {\n background: var(--md-sys-color-primary, #6750A4);\n }\n .switch:hover .thumb::before { opacity: 0.08; }\n .switch:focus-within .thumb::before { opacity: 0.12; }\n .switch:active .thumb::before { opacity: 0.12; }\n\n .thumb-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 14px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 20;\n color: var(--md-sys-color-surface-container-highest, #E6E0E9);\n display: none;\n }\n .selected .thumb-icon { color: var(--md-sys-color-on-primary-container, #21005D); }\n .icons .thumb .thumb-icon { display: block; }\n `);\n\n return html`\n <div\n :class=\"${{\n switch: true,\n selected: selected.value,\n disabled: props.disabled,\n icons: props.icons,\n }}\"\n >\n <input\n role=\"switch\"\n type=\"checkbox\"\n :checked=\"${selected.value}\"\n :disabled=\"${props.disabled}\"\n @change=\"${(e: Event) => { emit('change', (e.target as HTMLInputElement).checked); selected.value = (e.target as HTMLInputElement).checked; }}\"\n />\n <div class=\"track\">\n <div :class=\"${{ thumb: true, selected: selected.value }}\">\n ${when(props.icons, () => html`<span class=\"thumb-icon\" aria-hidden=\"true\">${selected.value ? 'check' : 'close'}</span>`)}\n </div>\n </div>\n </div>\n `;\n});\n","import { component, html, css, defineModel, watch, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { each, when } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { useListKeyNav } from '../composables/useListKeyNav';\n\ninterface Tab {\n id: string;\n label: string;\n icon?: string;\n badge?: string | number;\n}\n\ncomponent('md-tabs', () => {\n const props = useProps({\n variant: 'primary' as 'primary' | 'secondary',\n tabs: [] as Tab[],\n });\n const emit = useEmit();\n const activeTab = defineModel('activeTab', '');\n\n // Initialize to first tab if not set\n watch(() => props.tabs, (newTabs) => {\n if (!activeTab.value && newTabs && newTabs.length > 0) {\n activeTab.value = newTabs[0].id;\n }\n });\n\n const safeTabs = (): Tab[] => Array.isArray(props.tabs) ? props.tabs : [];\n\n useStyle(() => css`\n :host { display: block; }\n\n .tabs-container {\n display: flex;\n border-bottom: 1px solid var(--md-sys-color-outline-variant, #CAC4D0);\n overflow-x: auto;\n scrollbar-width: none;\n position: relative;\n }\n .tabs-container::-webkit-scrollbar { display: none; }\n\n .tab {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n min-width: 80px;\n height: 48px;\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n letter-spacing: 0.1px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n outline: none;\n position: relative;\n overflow: hidden;\n white-space: nowrap;\n flex-shrink: 0;\n transition: color 200ms;\n }\n /* M3: tabs with both icon and label use 72dp container height */\n .tab.has-icon { height: 72px; }\n .tab::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-on-surface-variant, #49454F);\n opacity: 0;\n transition: opacity 200ms;\n }\n .tab:hover::before { opacity: 0.08; }\n .tab:focus::before { opacity: 0.12; }\n .tab:active::before { opacity: 0.12; }\n\n .tab.active {\n color: var(--md-sys-color-primary, #6750A4);\n }\n .tab.active::before { background: var(--md-sys-color-primary, #6750A4); }\n\n .tab-indicator {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n border-radius: 3px 3px 0 0;\n background: var(--md-sys-color-primary, #6750A4);\n }\n\n .tab-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n line-height: 1;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .tab.active .tab-icon {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n\n /* secondary variant: smaller, no indicator height */\n .secondary .tab { height: 48px; font-size: 14px; }\n .secondary .tab-indicator { height: 2px; }\n\n .tab-badge {\n position: absolute;\n top: 6px;\n right: 8px;\n min-width: 16px;\n height: 16px;\n background: var(--md-sys-color-error, #B3261E);\n color: var(--md-sys-color-on-error, #fff);\n border-radius: 8px;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n }\n\n .content {\n padding: 16px 0;\n }\n `);\n\n const handleTabKeyDown = useListKeyNav({\n orientation: 'horizontal',\n itemSelector: '[role=\"tab\"]',\n onNavigate: (_, newIdx) => {\n const tabs = safeTabs();\n if (tabs[newIdx]) {\n activeTab.value = tabs[newIdx].id;\n emit('tab-change', tabs[newIdx].id);\n }\n },\n });\n\n return html`\n <div>\n <div :class=\"${{ 'tabs-container': true, [props.variant]: true }}\" role=\"tablist\" @keydown=\"${handleTabKeyDown}\">\n ${each(\n safeTabs(),\n (tab: Tab) => html`\n <button\n type=\"button\"\n key=\"${tab.id}\"\n id=\"tab-${tab.id}\"\n :class=\"${{ tab: true, active: activeTab.value === tab.id, 'has-icon': !!tab.icon }}\"\n role=\"tab\"\n aria-selected=\"${String(activeTab.value === tab.id)}\"\n aria-controls=\"tabpanel\"\n tabindex=\"${activeTab.value === tab.id ? '0' : '-1'}\"\n @click=\"${() => { activeTab.value = tab.id; emit('tab-change', tab.id); }}\"\n >\n ${when(!!tab.icon, () => html`<span class=\"tab-icon\" aria-hidden=\"true\">${tab.icon}</span>`)}\n ${tab.label}\n ${when(activeTab.value === tab.id, () => html`<div class=\"tab-indicator\"></div>`)}\n ${when(!!tab.badge, () => html`<span class=\"tab-badge\">${tab.badge}</span>`)}\n </button>\n `,\n )}\n </div>\n <div class=\"content\" role=\"tabpanel\" id=\"tabpanel\" :bind=\"${{ 'aria-labelledby': activeTab.value ? 'tab-' + activeTab.value : null }}\">\n <slot></slot>\n </div>\n </div>\n `;\n});\n","import { component, html, css, ref, defineModel, useProps, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-text-field', () => {\n const fieldId = `md-field`;\n const props = useProps({\n variant: 'filled' as 'filled' | 'outlined',\n label: 'Label',\n type: 'text',\n placeholder: '',\n disabled: false,\n error: false,\n errorText: '',\n supportingText: '',\n leadingIcon: '',\n trailingIcon: '',\n required: false,\n readonly: false,\n });\n const modelValue = defineModel('');\n const focused = ref(false);\n\n useStyle(() => css`\n :host { display: block; }\n\n .field-wrapper {\n position: relative;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n }\n\n /* ── Filled ── */\n .filled {\n background: var(--md-sys-color-surface-container-highest, #E6E0E9);\n border-radius: 4px 4px 0 0;\n padding: 0 16px;\n min-height: 56px;\n display: flex;\n align-items: flex-end;\n position: relative;\n }\n .filled.has-leading { padding-left: 12px; }\n\n .filled-border {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: var(--md-sys-color-on-surface-variant, #49454F);\n transition: height 200ms;\n }\n .filled:focus-within .filled-border {\n height: 2px;\n background: var(--md-sys-color-primary, #6750A4);\n }\n .error .filled-border,\n .filled.error .filled-border { background: var(--md-sys-color-error, #B3261E) !important; }\n\n /* ── Outlined ── */\n .outlined {\n border-radius: 4px;\n padding: 0 16px;\n min-height: 56px;\n display: flex;\n align-items: center;\n position: relative;\n }\n .outlined.has-leading { padding-left: 12px; }\n\n .outlined-border {\n position: absolute;\n inset: 0;\n border: 1px solid var(--md-sys-color-outline, #79747E);\n border-radius: 4px;\n pointer-events: none;\n transition: border-color 200ms, border-width 200ms;\n }\n .outlined:focus-within .outlined-border {\n border-width: 2px;\n border-color: var(--md-sys-color-primary, #6750A4);\n }\n .error .outlined-border { border-color: var(--md-sys-color-error, #B3261E) !important; }\n\n /* ── Shared input ── */\n input {\n border: none;\n background: transparent;\n outline: none;\n font-family: inherit;\n font-size: 16px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n width: 100%;\n padding: 12px 0 0 0;\n caret-color: var(--md-sys-color-primary, #6750A4);\n }\n input:disabled { color: rgba(28,27,31,.38); cursor: not-allowed; }\n .outlined input { padding: 0; }\n\n input::placeholder { color: transparent; }\n input:focus::placeholder { color: var(--md-sys-color-on-surface-variant, #49454F); opacity: 0.5; }\n\n /* ── Label ── */\n label {\n position: absolute;\n font-family: inherit;\n font-size: 16px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n pointer-events: none;\n transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1),\n font-size 150ms cubic-bezier(0.4, 0, 0.2, 1),\n color 150ms cubic-bezier(0.4, 0, 0.2, 1);\n transform-origin: left top;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: calc(100% - 16px);\n }\n\n /* filled label */\n .filled label {\n top: 16px;\n left: 16px;\n }\n .filled.has-leading label { left: 52px; }\n .filled.is-active label,\n .filled:focus-within label {\n transform: translateY(-8px) scale(0.75);\n color: var(--md-sys-color-primary, #6750A4);\n }\n .filled.error label,\n .filled.error:focus-within label { color: var(--md-sys-color-error, #B3261E); }\n\n /* outlined label */\n .outlined label {\n top: 50%;\n left: 16px;\n transform: translateY(-50%);\n background: transparent;\n }\n .outlined.has-leading label { left: 52px; }\n .outlined.is-active label,\n .outlined:focus-within label {\n transform: translateY(-150%) scale(0.75);\n background: var(--md-sys-color-surface, #FFFBFE);\n padding: 0 4px;\n color: var(--md-sys-color-primary, #6750A4);\n left: 12px;\n }\n .outlined.error label { color: var(--md-sys-color-error, #B3261E); }\n\n /* ── Icons ── */\n .field-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 24px;\n font-weight: normal;\n font-style: normal;\n display: inline-flex;\n align-items: center;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n line-height: 1;\n flex-shrink: 0;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n }\n .leading-icon { margin-right: 12px; }\n .trailing-icon { margin-left: 8px; }\n .error-icon { color: var(--md-sys-color-error, #B3261E); }\n\n /* input row inside filled */\n .filled .input-row {\n display: flex;\n align-items: center;\n width: 100%;\n padding-bottom: 8px;\n }\n .outlined .input-row {\n display: flex;\n align-items: center;\n width: 100%;\n }\n\n /* ── Support text ── */\n .support {\n font-size: 12px;\n padding: 4px 16px 0;\n line-height: 16px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .support.error-text { color: var(--md-sys-color-error, #B3261E); }\n\n /* ── Disabled ── */\n .disabled .filled { opacity: 0.38; }\n .disabled .outlined { opacity: 0.38; }\n `);\n\n const showError = props.error;\n\n return html`\n <div :class=\"${{ 'field-wrapper': true, disabled: props.disabled }}\">\n <div\n :class=\"${{\n [props.variant]: true,\n 'has-leading': !!props.leadingIcon,\n 'is-active': modelValue.value !== '' || focused.value,\n error: !!showError,\n }}\"\n >\n ${when(props.variant === 'filled', () => html`<div class=\"filled-border\"></div>`)}\n ${when(props.variant === 'outlined', () => html`<div class=\"outlined-border\"></div>`)}\n\n <label :for=\"${fieldId}\">${props.label}${props.required ? html`<span aria-hidden=\"true\"> *</span>` : ''}</label>\n\n <div class=\"input-row\">\n ${when(!!props.leadingIcon, () => html`<span class=\"field-icon leading-icon\" aria-hidden=\"true\">${props.leadingIcon}</span>`)}\n <input\n :id=\"${fieldId}\"\n :type=\"${props.type}\"\n :model=\"${modelValue}\"\n :disabled=\"${props.disabled}\"\n :readonly=\"${props.readonly}\"\n :required=\"${props.required}\"\n :placeholder=\"${props.placeholder}\"\n :bind=\"${{\n 'aria-required': props.required ? 'true' : null,\n 'aria-invalid': props.error ? 'true' : null,\n 'aria-describedby': (props.error && props.errorText) || props.supportingText ? `${fieldId}-supporting` : null,\n }}\"\n class=\"focus:outline-none\"\n @focus=\"${() => { focused.value = true; }}\"\n @blur=\"${() => { focused.value = false; }}\"\n />\n ${when(!!props.trailingIcon, () => html`<span :class=\"${{ 'field-icon': true, 'trailing-icon': true, 'error-icon': !!showError }}\" aria-hidden=\"true\">${props.trailingIcon}</span>`)}\n ${when(!props.trailingIcon && showError, () => html`<span class=\"field-icon trailing-icon error-icon\" aria-hidden=\"true\">error</span>`)}\n </div>\n </div>\n\n ${when(!!(showError && props.errorText), () => html`<div :id=\"${fieldId}-supporting\" class=\"support error-text\">${props.errorText}</div>`)}\n ${when(!!((!showError) && props.supportingText), () => html`<div :id=\"${fieldId}-supporting\" class=\"support\">${props.supportingText}</div>`)}\n </div>\n `;\n});\n","import { component, html, css, ref, watch, computed, defineModel, useProps, useEmit, useStyle, useOnDisconnected } from '@jasonshimmy/custom-elements-runtime';\nimport { when, each } from '@jasonshimmy/custom-elements-runtime/directives';\nimport { Transition } from '@jasonshimmy/custom-elements-runtime/transitions';\nimport { useEscapeKey } from '../composables/useEscapeKey';\nimport { createFocusTrap } from '../composables/useFocusTrap';\nimport { useScrollLock } from '../composables/useScrollLock';\n\n// ── helpers ────────────────────────────────────────────────────────────────\n\n/** Parse \"HH:MM\" → {hours, minutes}. Returns null on failure. */\nfunction parseTime(value: string): { hours: number; minutes: number } | null {\n if (!value) return null;\n const m = value.match(/^(\\d{1,2}):(\\d{2})$/);\n if (!m) return null;\n const h = parseInt(m[1], 10);\n const min = parseInt(m[2], 10);\n if (h < 0 || h > 23 || min < 0 || min > 59) return null;\n return { hours: h, minutes: min };\n}\n\nfunction pad2(n: number): string { return String(n).padStart(2, '0'); }\n\n/**\n * Convert polar angle (0 = top, clockwise) to {x, y} coordinates on a circle\n * of given radius, centred at cx/cy.\n */\nfunction polarToCartesian(\n cx: number, cy: number, r: number, angleDeg: number\n): { x: number; y: number } {\n const rad = ((angleDeg - 90) * Math.PI) / 180;\n return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };\n}\n\n// ── constants ──────────────────────────────────────────────────────────────\nconst DIAL_SIZE = 256; // px (MD3 spec: 256dp clock dial container)\nconst DIAL_CENTER = DIAL_SIZE / 2;\nconst DIAL_RADIUS = 100; // radius of number ring\n\n// ── component ──────────────────────────────────────────────────────────────\ncomponent('md-time-picker', () => {\n const props = useProps({\n /** 'dial' | 'input' */\n variant: 'dial' as 'dial' | 'input',\n /** 12 or 24-hour format */\n hour24: false,\n ariaLabel: 'Time picker',\n });\n const emit = useEmit();\n const modelValue = defineModel('');\n const open = defineModel('open', false);\n\n // ── internal state ────────────────────────────────────────────────────\n const parsed = computed(() => parseTime(modelValue.value));\n\n // Local mutable copies\n const hours = ref(parsed.value?.hours ?? 12);\n const minutes = ref(parsed.value?.minutes ?? 0);\n const period = ref<'AM' | 'PM'>(\n (parsed.value?.hours ?? 12) < 12 ? 'AM' : 'PM'\n );\n\n // Which part of the dial we're editing: 'hours' | 'minutes'\n const dialMode = ref<'hours' | 'minutes'>('hours');\n\n // Input-mode typed strings\n const inputH = ref(pad2(hours.value));\n const inputM = ref(pad2(minutes.value));\n\n // Sync when prop changes externally\n watch(() => modelValue.value, (v) => {\n const p = parseTime(v);\n if (p) {\n hours.value = p.hours;\n minutes.value = p.minutes;\n period.value = p.hours < 12 ? 'AM' : 'PM';\n inputH.value = pad2(p.hours);\n inputM.value = pad2(p.minutes);\n }\n });\n\n // ── keyboard / dial interaction ───────────────────────────────────────\n /**\n * Given a mouse/touch clientX/Y over the dial SVG, map to the nearest\n * hour (1-12 or 0-23) or minute (0-55 in steps of 5).\n */\n const dialDragging = ref(false);\n\n const hitTestDial = (e: MouseEvent, el: HTMLElement) => {\n const rect = el.getBoundingClientRect();\n const x = e.clientX - rect.left - DIAL_CENTER;\n const y = e.clientY - rect.top - DIAL_CENTER;\n // angle in degrees, 0 at top, clockwise\n let angle = (Math.atan2(y, x) * 180) / Math.PI + 90;\n if (angle < 0) angle += 360;\n\n if (dialMode.value === 'hours') {\n const total = props.hour24 ? 24 : 12;\n const step = 360 / total;\n let val = Math.round(angle / step) % total;\n if (!props.hour24 && val === 0) val = 12;\n if (props.hour24 && period.value === 'PM' && val < 12) val += 12;\n hours.value = val;\n } else {\n const step = 360 / 60;\n const val = Math.round(angle / step) % 60;\n minutes.value = val;\n }\n };\n\n const onDialPointerDown = (e: PointerEvent) => {\n dialDragging.value = true;\n hitTestDial(e as unknown as MouseEvent, e.currentTarget as HTMLElement);\n (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);\n };\n const onDialPointerMove = (e: PointerEvent) => {\n if (!dialDragging.value) return;\n hitTestDial(e as unknown as MouseEvent, e.currentTarget as HTMLElement);\n };\n const onDialPointerUp = (_e: PointerEvent) => {\n dialDragging.value = false;\n // After setting hours, auto-switch to minutes\n if (dialMode.value === 'hours') dialMode.value = 'minutes';\n };\n\n // ── computed display values ───────────────────────────────────────────\n const displayHours = computed(() => {\n if (props.hour24) return pad2(hours.value);\n const h = hours.value % 12 || 12;\n return pad2(h);\n });\n\n const dialAngle = computed(() => {\n if (dialMode.value === 'hours') {\n const total = props.hour24 ? 24 : 12;\n const h = props.hour24 ? hours.value : (hours.value % 12 || 12);\n return (h / total) * 360;\n }\n return (minutes.value / 60) * 360;\n });\n\n // Dial numbers to render\n const dialNumbers = computed(() => {\n if (dialMode.value === 'hours') {\n const count = props.hour24 ? 24 : 12;\n return Array.from({ length: count }, (_, i) => {\n const n = props.hour24 ? i : (i === 0 ? 12 : i);\n const angle = (n / count) * 360;\n const pos = polarToCartesian(DIAL_CENTER, DIAL_CENTER, DIAL_RADIUS, angle);\n const isSelected = hours.value === (props.hour24 ? i : n);\n return { key: String(n), n, pos, isSelected };\n });\n } else {\n // minutes: show 0 5 10 … 55\n return Array.from({ length: 12 }, (_, i) => {\n const n = i * 5;\n const angle = (n / 60) * 360;\n const pos = polarToCartesian(DIAL_CENTER, DIAL_CENTER, DIAL_RADIUS, angle);\n const isSelected = minutes.value === n;\n return { key: String(n), n, pos, isSelected };\n });\n }\n });\n\n // Hand end position (kept for potential future use)\n // const handEnd = computed(() => {\n // return polarToCartesian(DIAL_CENTER, DIAL_CENTER, DIAL_RADIUS, dialAngle.value);\n // });\n\n // ── input validation ──────────────────────────────────────────────────\n const hoursError = computed(() => {\n const h = parseInt(inputH.value, 10);\n return isNaN(h) || (props.hour24 ? h < 0 || h > 23 : h < 1 || h > 12);\n });\n const minutesError = computed(() => {\n const m = parseInt(inputM.value, 10);\n return isNaN(m) || m < 0 || m > 59;\n });\n\n // ── input mode handlers ───────────────────────────────────────────────\n const commitInputH = () => {\n const h = parseInt(inputH.value, 10);\n if (!isNaN(h)) hours.value = Math.max(props.hour24 ? 0 : 1, Math.min(props.hour24 ? 23 : 12, h));\n inputH.value = pad2(hours.value);\n };\n const commitInputM = () => {\n const m = parseInt(inputM.value, 10);\n if (!isNaN(m)) minutes.value = Math.max(0, Math.min(59, m));\n inputM.value = pad2(minutes.value);\n };\n\n // ── confirm / cancel ──────────────────────────────────────────────────\n const handleOK = () => {\n if (currentVariant.value === 'input') { commitInputH(); commitInputM(); }\n let h = hours.value;\n if (!props.hour24) {\n if (period.value === 'AM' && h === 12) h = 0;\n if (period.value === 'PM' && h !== 12) h = h + 12;\n }\n emit('change', `${pad2(h)}:${pad2(minutes.value)}`);\n modelValue.value = `${pad2(h)}:${pad2(minutes.value)}`;\n emit('close');\n open.value = false;\n };\n\n // ── focus/scroll management ───────────────────────────────────────────\n useEscapeKey(() => open.value, () => { emit('close'); open.value = false; })();\n const trap = createFocusTrap();\n useOnDisconnected(() => trap.cleanup());\n const scrollLock = useScrollLock();\n\n // ── styles ────────────────────────────────────────────────────────────\n useStyle(() => css`\n :host { display: contents; }\n\n /* ── Scrim ── */\n .scrim {\n position: fixed;\n inset: 0;\n background: rgba(0,0,0,0.32);\n z-index: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .scrim-enter-from { opacity: 0; }\n .scrim-enter-from .picker { transform: scale(0.92); opacity: 0; }\n .scrim-enter-active { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1); }\n .scrim-enter-active .picker { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1), transform 200ms cubic-bezier(0.4,0,0.2,1); }\n .scrim-leave-to { opacity: 0; pointer-events: none; }\n .scrim-leave-to .picker { transform: scale(0.92); opacity: 0; }\n .scrim-leave-active { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1); }\n .scrim-leave-active .picker { transition: opacity 200ms cubic-bezier(0.4,0,0.2,1), transform 200ms cubic-bezier(0.4,0,0.2,1); }\n\n /* ── Picker container ── */\n .picker {\n background: var(--md-sys-color-surface-container-high, #ECE6F0);\n border-radius: 28px;\n width: 328px;\n max-width: calc(100vw - 48px);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: var(--md-sys-elevation-3, 0 4px 8px 3px rgba(0,0,0,.15), 0 1px 3px rgba(0,0,0,.3));\n }\n\n /* ── Headline ── */\n .picker-headline {\n padding: 24px 24px 20px;\n }\n .picker-headline-label {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 12px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n margin: 0 0 16px;\n }\n\n /* ── Time selector row ── */\n .time-selector {\n display: flex;\n align-items: center;\n gap: 0;\n }\n .time-seg-btn {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 57px;\n font-weight: 400;\n padding: 0 8px;\n border-radius: 8px;\n border: none;\n cursor: pointer;\n background: transparent;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n line-height: 1;\n outline: none;\n min-width: 96px;\n text-align: center;\n transition: background 200ms;\n }\n .time-seg-btn:hover {\n background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent);\n }\n .time-seg-btn.active {\n background: var(--md-sys-color-primary-container, #EADDFF);\n color: var(--md-sys-color-on-primary-container, #21005D);\n }\n .time-seg-btn:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); }\n .time-separator {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 57px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n padding: 0 4px;\n line-height: 1;\n user-select: none;\n }\n\n /* ── Period (AM/PM) ── */\n .period-container {\n display: flex;\n flex-direction: column;\n margin-left: 12px;\n border: 1px solid var(--md-sys-color-outline, #79747E);\n border-radius: 8px;\n overflow: hidden;\n height: 80px;\n }\n .period-btn {\n flex: 1;\n border: none;\n background: transparent;\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 14px;\n font-weight: 500;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n cursor: pointer;\n padding: 0 12px;\n outline: none;\n transition: background 200ms;\n }\n .period-btn:hover {\n background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent);\n }\n .period-btn.active {\n background: var(--md-sys-color-tertiary-container, #FFD8E4);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n }\n .period-btn:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); }\n .period-divider {\n height: 1px;\n background: var(--md-sys-color-outline, #79747E);\n }\n\n /* ── Dial ── */\n .dial-wrapper {\n padding: 0 24px 20px;\n display: flex;\n justify-content: center;\n }\n .dial-ring {\n position: relative;\n width: ${DIAL_SIZE}px;\n height: ${DIAL_SIZE}px;\n border-radius: 50%;\n background: var(--md-sys-color-surface-container-highest, #E6E0E9);\n cursor: pointer;\n touch-action: none;\n flex-shrink: 0;\n }\n .dial-hand-pivot {\n position: absolute;\n width: 0;\n height: 0;\n top: 50%;\n left: 50%;\n transform-origin: 0 0;\n pointer-events: none;\n }\n .dial-hand-bar {\n position: absolute;\n width: 2px;\n background: var(--md-sys-color-primary, #6750A4);\n height: ${DIAL_RADIUS}px;\n top: ${-DIAL_RADIUS}px;\n left: -1px;\n }\n .dial-handle-circle {\n position: absolute;\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: var(--md-sys-color-primary, #6750A4);\n top: ${-(DIAL_RADIUS + 24)}px;\n left: -24px;\n }\n .dial-center-dot {\n position: absolute;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--md-sys-color-primary, #6750A4);\n top: calc(50% - 4px);\n left: calc(50% - 4px);\n pointer-events: none;\n }\n .dial-label {\n position: absolute;\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 13px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n width: 32px;\n height: 32px;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n user-select: none;\n border-radius: 50%;\n }\n .dial-label.active {\n background: var(--md-sys-color-primary, #6750A4);\n color: var(--md-sys-color-on-primary, #FFFFFF);\n }\n\n /* ── Input mode fields ── */\n .input-fields {\n display: flex;\n align-items: center;\n padding: 0 24px;\n gap: 4px;\n margin-bottom: 16px;\n }\n .input-field-wrap {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n .input-field {\n width: 96px;\n height: 72px;\n border-radius: 8px;\n border: none;\n background: var(--md-sys-color-surface-container-highest, #E6E0E9);\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 45px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n text-align: center;\n outline: none;\n caret-color: var(--md-sys-color-primary, #6750A4);\n }\n .input-field:focus { box-shadow: 0 0 0 2px var(--md-sys-color-primary, #6750A4); }\n .input-field.error {\n box-shadow: 0 0 0 2px var(--md-sys-color-error, #B3261E);\n color: var(--md-sys-color-error, #B3261E);\n }\n .input-field.error:focus { box-shadow: 0 0 0 2px var(--md-sys-color-error, #B3261E); }\n .input-error-text {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 11px;\n color: var(--md-sys-color-error, #B3261E);\n display: none;\n margin-top: 2px;\n white-space: nowrap;\n }\n .input-error-text.show { display: block; }\n .input-field-label {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n .input-colon {\n font-family: var(--md-sys-typescale-font,'Roboto',sans-serif);\n font-size: 45px;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n padding: 0 4px;\n user-select: none;\n }\n\n /* ── Mode toggle icon ── */\n .mode-row {\n display: flex;\n justify-content: flex-start;\n padding: 0 12px 8px;\n }\n .mode-btn {\n width: 40px;\n height: 40px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n padding: 0;\n outline: none;\n }\n .mode-btn:hover { background: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) 8%, transparent); }\n .mode-btn:focus-visible { outline: 2px solid var(--md-sys-color-primary, #6750A4); }\n .mode-btn-icon {\n font-family: 'Material Symbols Outlined';\n font-size: 20px;\n font-weight: normal;\n font-variation-settings: 'FILL' 0,'wght' 400,'GRAD' 0,'opsz' 20;\n }\n\n /* ── Divider ── */\n .picker-divider {\n height: 1px;\n background: var(--md-sys-color-outline-variant, #CAC4D0);\n margin: 0;\n }\n\n /* ── Actions ── */\n .picker-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 12px 20px;\n }\n `);\n\n // ── local variant toggle (dial ↔ input) ───────────────────────────────\n // Use a computed so the displayed variant is synchronously derived from props.\n // userVariant stores an explicit in-session toggle; null means “follow props”.\n const userVariant = ref<'dial' | 'input' | null>(null);\n // Clear user override whenever the picker opens so it always starts with props.variant\n watch(() => open.value, (isOpen) => { if (isOpen) userVariant.value = null; });\n const currentVariant = computed(() => userVariant.value ?? props.variant);\n\n // Helper to toggle between dial/input within an open session\n const toggleVariant = () => {\n userVariant.value = currentVariant.value === 'dial' ? 'input' : 'dial';\n };\n\n // ── render ────────────────────────────────────────────────────────────\n const renderContent = () => html`\n <div class=\"picker\" role=\"dialog\" aria-modal=\"true\" aria-label=\"${props.ariaLabel}\">\n\n <!-- Headline: label + time display (dial mode) OR just label (input mode) -->\n <div class=\"picker-headline\">\n <p class=\"picker-headline-label\">${currentVariant.value === 'input' ? 'Enter time' : 'Select time'}</p>\n ${when(currentVariant.value === 'dial', () => html`\n <div class=\"time-selector\" aria-label=\"Current time: ${displayHours.value}:${pad2(minutes.value)} ${props.hour24 ? '' : period.value}\">\n <button\n :class=\"${{ 'time-seg-btn': true, active: dialMode.value === 'hours' }}\"\n aria-label=\"Hours: ${displayHours.value}. Click to edit hours.\"\n @click=\"${() => { dialMode.value = 'hours'; }}\"\n >${displayHours.value}</button>\n <span class=\"time-separator\" aria-hidden=\"true\">:</span>\n <button\n :class=\"${{ 'time-seg-btn': true, active: dialMode.value === 'minutes' }}\"\n aria-label=\"Minutes: ${pad2(minutes.value)}. Click to edit minutes.\"\n @click=\"${() => { dialMode.value = 'minutes'; }}\"\n >${pad2(minutes.value)}</button>\n ${when(!props.hour24, () => html`\n <div class=\"period-container\" role=\"group\" aria-label=\"Period\">\n <button\n :class=\"${{ 'period-btn': true, active: period.value === 'AM' }}\"\n aria-pressed=\"${period.value === 'AM'}\"\n @click=\"${() => { period.value = 'AM'; }}\"\n >AM</button>\n <div class=\"period-divider\" aria-hidden=\"true\"></div>\n <button\n :class=\"${{ 'period-btn': true, active: period.value === 'PM' }}\"\n aria-pressed=\"${period.value === 'PM'}\"\n @click=\"${() => { period.value = 'PM'; }}\"\n >PM</button>\n </div>\n `)}\n </div>\n `)}\n </div>\n\n <!-- Input fields — replaces dial area when in input mode -->\n ${when(currentVariant.value === 'input', () => html`\n <div class=\"input-fields\">\n <div class=\"input-field-wrap\">\n <input\n :class=\"${{ 'input-field': true, error: hoursError.value }}\"\n type=\"text\"\n inputmode=\"numeric\"\n maxlength=\"2\"\n aria-label=\"Hours\"\n :model=\"${inputH}\"\n @input=\"${(e: Event) => e.stopPropagation()}\"\n @blur=\"${commitInputH}\"\n @keydown=\"${(e: KeyboardEvent) => { if (e.key === 'Enter') { commitInputH(); (e.currentTarget as HTMLElement).blur(); } }}\"\n />\n <span class=\"input-field-label\">Hour</span>\n <span :class=\"${{ 'input-error-text': true, show: hoursError.value }}\">${props.hour24 ? '0–23' : '1–12'}</span>\n </div>\n <span class=\"input-colon\" aria-hidden=\"true\">:</span>\n <div class=\"input-field-wrap\">\n <input\n :class=\"${{ 'input-field': true, error: minutesError.value }}\"\n type=\"text\"\n inputmode=\"numeric\"\n maxlength=\"2\"\n aria-label=\"Minutes\"\n :model=\"${inputM}\"\n @input=\"${(e: Event) => e.stopPropagation()}\"\n @blur=\"${commitInputM}\"\n @keydown=\"${(e: KeyboardEvent) => { if (e.key === 'Enter') { commitInputM(); (e.currentTarget as HTMLElement).blur(); } }}\"\n />\n <span class=\"input-field-label\">Minute</span>\n <span :class=\"${{ 'input-error-text': true, show: minutesError.value }}\">0–59</span>\n </div>\n ${when(!props.hour24, () => html`\n <div class=\"period-container\" role=\"group\" aria-label=\"Period\" style=\"margin-left:8px\">\n <button\n :class=\"${{ 'period-btn': true, active: period.value === 'AM' }}\"\n aria-pressed=\"${period.value === 'AM'}\"\n @click=\"${() => { period.value = 'AM'; }}\"\n >AM</button>\n <div class=\"period-divider\" aria-hidden=\"true\"></div>\n <button\n :class=\"${{ 'period-btn': true, active: period.value === 'PM' }}\"\n aria-pressed=\"${period.value === 'PM'}\"\n @click=\"${() => { period.value = 'PM'; }}\"\n >PM</button>\n </div>\n `)}\n </div>\n `)}\n\n <!-- Dial — shown only in dial mode, includes its own divider -->\n ${when(currentVariant.value === 'dial', () => html`\n <div class=\"picker-divider\"></div>\n <div class=\"dial-wrapper\">\n <div\n class=\"dial-ring\"\n role=\"img\"\n aria-label=\"${dialMode.value === 'hours' ? 'Hour selection dial' : 'Minute selection dial'}\"\n @pointerdown=\"${onDialPointerDown}\"\n @pointermove=\"${onDialPointerMove}\"\n @pointerup=\"${onDialPointerUp}\"\n >\n <div class=\"dial-hand-pivot\" :style=\"${{ transform: `rotate(${dialAngle.value}deg)` }}\">\n <div class=\"dial-hand-bar\"></div>\n <div class=\"dial-handle-circle\"></div>\n </div>\n <div class=\"dial-center-dot\"></div>\n ${each(dialNumbers.value, ({ n, pos, isSelected }) => html`\n <span\n :class=\"${{ 'dial-label': true, active: isSelected }}\"\n :style=\"${{ left: pos.x + 'px', top: pos.y + 'px' }}\"\n aria-hidden=\"true\"\n >${n === 0 && dialMode.value === 'minutes' ? '00' : String(n)}</span>\n `)}\n </div>\n </div>\n `)}\n\n <!-- Mode toggle + actions -->\n <div class=\"mode-row\">\n <button\n class=\"mode-btn\"\n aria-label=\"${currentVariant.value === 'dial' ? 'Switch to keyboard input' : 'Switch to dial'}\"\n @click=\"${() => { toggleVariant(); }}\"\n >\n <span class=\"mode-btn-icon\" aria-hidden=\"true\">\n ${currentVariant.value === 'dial' ? 'keyboard' : 'schedule'}\n </span>\n </button>\n </div>\n <div class=\"picker-actions\">\n <md-button variant=\"text\" @click=\"${() => { emit('close'); open.value = false; }}\">Cancel</md-button>\n <md-button variant=\"text\" @click=\"${handleOK}\">OK</md-button>\n </div>\n </div>\n `;\n\n return html`\n ${Transition({ show: open.value,\n enterFrom: 'scrim-enter-from', enterActive: 'scrim-enter-active',\n leaveActive: 'scrim-leave-active', leaveTo: 'scrim-leave-to',\n onBeforeEnter: scrollLock.lock,\n onAfterEnter: trap.onAfterEnter,\n onAfterLeave: () => { trap.onAfterLeave(); scrollLock.unlock(); },\n }, html`\n <div\n class=\"scrim\"\n @click=\"${(e: Event) => { if (e.target === e.currentTarget) { emit('close'); open.value = false; } }}\"\n >\n ${renderContent()}\n </div>\n `)}\n `;\n});\n","import { component, html, css, ref, useProps, useEmit, useStyle } from '@jasonshimmy/custom-elements-runtime';\nimport { when } from '@jasonshimmy/custom-elements-runtime/directives';\n\ncomponent('md-tooltip', () => {\n const props = useProps({\n text: '',\n variant: 'plain' as 'plain' | 'rich',\n title: '',\n action: '',\n });\n const emit = useEmit();\n const visible = ref(false);\n let hideTimer: ReturnType<typeof setTimeout> | null = null;\n\n const show = () => {\n if (hideTimer) { clearTimeout(hideTimer); hideTimer = null; }\n visible.value = true;\n };\n const scheduleHide = () => {\n hideTimer = setTimeout(() => { visible.value = false; }, 100);\n };\n const cancelHide = () => {\n if (hideTimer) { clearTimeout(hideTimer); hideTimer = null; }\n };\n\n useStyle(() => css`\n :host { display: inline-flex; vertical-align: middle; }\n\n .anchor {\n position: relative;\n display: inline-flex;\n }\n\n .tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n z-index: 800;\n animation: tip-in 100ms ease-out;\n }\n @keyframes tip-in {\n from { opacity: 0; transform: translateX(-50%) translateY(4px); }\n to { opacity: 1; transform: translateX(-50%) translateY(0); }\n }\n\n /* ── Plain ── */\n .tooltip.plain {\n background: var(--md-sys-color-inverse-surface, #313033);\n color: var(--md-sys-color-inverse-on-surface, #F4EFF4);\n border-radius: 4px;\n padding: 4px 8px;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 12px;\n line-height: 16px;\n white-space: nowrap;\n pointer-events: none;\n }\n\n /* ── Rich ── */\n .tooltip.rich {\n background: var(--md-sys-color-surface-container, #F3EDF7);\n border-radius: 12px;\n padding: 12px 16px;\n min-width: 120px;\n max-width: 315px;\n box-shadow: var(--md-sys-elevation-2, 0 2px 6px rgba(0,0,0,0.15));\n pointer-events: all;\n }\n\n .tip-title {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n color: var(--md-sys-color-on-surface, #1C1B1F);\n margin-bottom: 4px;\n }\n\n .tip-text {\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 12px;\n line-height: 16px;\n /* color is inherited from .tooltip.plain (light) or set below for rich */\n }\n .tooltip.rich .tip-text {\n color: var(--md-sys-color-on-surface-variant, #49454F);\n }\n\n .tip-actions {\n display: flex;\n justify-content: flex-end;\n margin-top: 8px;\n }\n\n .tip-action-btn {\n border: none;\n background: transparent;\n cursor: pointer;\n font-family: var(--md-sys-typescale-font, 'Roboto', sans-serif);\n font-size: 14px;\n font-weight: 500;\n color: var(--md-sys-color-primary, #6750A4);\n padding: 6px 8px;\n border-radius: 4px;\n outline: none;\n position: relative;\n overflow: hidden;\n }\n .tip-action-btn::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--md-sys-color-primary, #6750A4);\n opacity: 0;\n transition: opacity 200ms;\n }\n .tip-action-btn:hover::before { opacity: 0.08; }\n .tip-action-btn:focus::before { opacity: 0.12; }\n `);\n\n return html`\n <div\n class=\"anchor\"\n @mouseenter=\"${show}\"\n @mouseleave=\"${scheduleHide}\"\n @focusin=\"${show}\"\n @focusout=\"${scheduleHide}\"\n >\n <slot></slot>\n ${when(visible.value, () => html`\n <div\n :class=\"${{ tooltip: true, plain: props.variant === 'plain', rich: props.variant === 'rich' }}\"\n role=\"tooltip\"\n @mouseenter=\"${cancelHide}\"\n @mouseleave=\"${scheduleHide}\"\n >\n ${when(props.variant === 'rich' && !!props.title, () => html`\n <div class=\"tip-title\">${props.title}</div>\n `)}\n ${when(!!props.text, () => html`\n <div class=\"tip-text\">${props.text}</div>\n `)}\n ${when(props.variant === 'rich' && !!props.action, () => html`\n <div class=\"tip-actions\">\n <button type=\"button\" class=\"tip-action-btn\" @click=\"${() => emit('action')}\">${props.action}</button>\n </div>\n `)}\n </div>\n `)}\n </div>\n `;\n});\n","import {\n ref,\n useOnAttributeChanged,\n} from '@jasonshimmy/custom-elements-runtime';\nimport type { ReactiveState } from '@jasonshimmy/custom-elements-runtime';\n\n/**\n * Creates an internal reactive ref that mirrors an external prop value and\n * stays in sync when the prop changes — both via DOM attribute changes and\n * JS property assignment (e.g. `:bind` from a parent component).\n *\n * @param getProp - A getter that returns the current coerced prop value.\n * e.g. `() => props.value || ''`\n *\n * @example\n * const query = useControlledValue(() => props.value || '');\n * query.value = 'typed by user'; // internal mutation works\n */\nexport function useControlledValue<T>(getProp: () => T): ReactiveState<T> {\n const internal = ref<T>(getProp());\n\n // PATH 1 — attribute changes.\n // useOnAttributeChanged fires after _applyProps() but before the scheduled\n // re-render, so getProp() already returns the new coerced value. Assigning\n // here is safe (outside of render) — no \"state modified during render\" warning\n // and no spurious extra render cycle.\n useOnAttributeChanged(() => {\n const next = getProp();\n if (!Object.is(next, internal.value)) {\n internal.value = next;\n }\n });\n\n // PATH 2 — JS property changes (e.g. :bind from a parent component).\n // These do NOT fire attributeChangedCallback, so useOnAttributeChanged never\n // fires. The element's reactive property setter calls _requestRender() directly.\n // On that re-render, ref() returns the same ReactiveState (stable stateIndex key)\n // with the stale value, so we sync here using initSilent(), which:\n // • writes directly to _value without calling makeReactive (safe for primitives)\n // • does NOT call triggerUpdate, avoiding the render warning and an extra render\n const propValue = getProp();\n if (!Object.is(propValue, internal.peek())) {\n internal.initSilent(propValue as T);\n }\n\n return internal;\n}"],"names":["component","props","useProps","emit","useEmit","useStyle","css","isColumn","safeTrailingIcons","html","when","icon","useEscapeKey","guard","onEscape","createComposable","handler","e","useOnConnected","useOnDisconnected","FOCUSABLE","isVisible","el","s","collectDeepTabbables","root","out","child","assigned","getFocusableDeep","container","getDeepActiveElement","createFocusTrap","ctx","getCurrentComponentContext","state","handleKeyDown","focusable","active","idx","lockCount","savedOverflow","savedPaddingRight","useScrollLock","scrollbarWidth","current","open","defineModel","sheetEl","dragStartY","dragStartTime","isDragging","dragDismissed","dismissedEl","DISMISS_RATIO","DISMISS_VELOCITY","onHandlePointerDown","handle","onHandlePointerMove","delta","onHandlePointerUp","elapsed","velocity","shouldDismiss","target","onEnd","trap","scrollLock","Transition","each","item","i","checked","selected","isElevated","checkIcon","DAYS_OF_WEEK","MONTH_NAMES","isoToDate","iso","d","dateToIso","y","m","day","sameDay","a","b","formatHeadline","formatRangeDate","buildCalendar","year","month","rangeStart","rangeEnd","minDate","maxDate","today","startOffset","daysInMonth","prevMonthDays","cells","makeCell","date","remaining","inMonth","t","isSelected","isRangeStart","isRangeEnd","isInRange","disabled","modelValue","ref","watch","v","view","viewYear","viewMonth","initFromValue","pendingValue","isOpen","toggleDocked","selectedDate","computed","rangeStartDt","rangeEndDt","minDt","maxDt","calendarDays","monthLabel","yearList","base","years","prevMonth","nextMonth","selectDay","selectYear","isModal","headlineValue","val","renderCalendar","focused","c","next","renderActions","renderPicker","_activeFabClose","closeMenu","toggle","selectItem","colorClass","sizeClass","displayIcon","useListKeyNav","options","prevKey","nextKey","items","focusedItem","currentIdx","newIdx","createFocusReturn","_el","handleMenuKeyDown","focusReturn","done","handleNavKeyDown","RADIUS","CIRCUMFERENCE","dashoffset","handleClear","id","handleClick","seg","h","percentage","tickCount","count","_","menuOpen","previousFocus","activeTab","newTabs","safeTabs","handleTabKeyDown","tabs","tab","fieldId","showError","parseTime","value","min","pad2","n","polarToCartesian","cx","cy","r","angleDeg","rad","DIAL_SIZE","DIAL_CENTER","DIAL_RADIUS","parsed","hours","minutes","period","dialMode","inputH","inputM","p","dialDragging","hitTestDial","rect","x","angle","total","step","onDialPointerDown","onDialPointerMove","onDialPointerUp","_e","displayHours","dialAngle","dialNumbers","pos","hoursError","minutesError","commitInputH","commitInputM","handleOK","currentVariant","userVariant","toggleVariant","renderContent","visible","hideTimer","show","scheduleHide","cancelHide","useControlledValue","getProp","internal","useOnAttributeChanged","propValue"],"mappings":"6RAGAA,EAAAA,UAAU,aAAc,IAAM,CAC5B,MAAMC,EAAQC,EAAAA,SAAS,CACrB,QAAS,QACT,MAAO,GACP,YAAa,OACb,cAAe,CAAA,EACf,SAAU,EAAA,CACX,EACKC,EAAOC,EAAAA,QAAA,EAEbC,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GAgId,EAED,MAAMC,EAAWN,EAAM,UAAY,UAAYA,EAAM,UAAY,QAC3DO,EAAoB,MAAM,QAAQP,EAAM,aAAa,EAAIA,EAAM,cAAgB,CAAA,EAErF,OAAOQ,EAAAA;AAAAA,sBACa,CAChB,UAAW,GACX,CAACR,EAAM,OAAO,EAAG,GACjB,SAAUA,EAAM,QAAA,CACjB;AAAA;AAAA,UAEKS,EAAAA,KAAK,CAAC,CAACT,EAAM,YAAa,IAAMQ,EAAAA;AAAAA,mFACyC,IAAMN,EAAK,KAAK,CAAC;AAAA,wDAC5CF,EAAM,WAAW;AAAA;AAAA,SAEhE,CAAC;AAAA;AAAA,UAEAS,EAAAA,KAAK,CAACH,EAAU,IAAME,EAAAA;AAAAA;AAAAA,kCAEER,EAAM,KAAK;AAAA;AAAA,SAEpC,CAAC;AAAA;AAAA;AAAA;AAAA,YAIEO,EAAkB,IAAKG,GAAiBF,EAAAA;AAAAA,iEACaE,CAAI,aAAa,IAAMR,EAAK,SAAUQ,CAAI,CAAC;AAAA,6DAC/CA,CAAI;AAAA;AAAA,WAEtD,CAAC;AAAA;AAAA;AAAA;AAAA,QAIJD,EAAAA,KAAKH,EAAU,IAAME,EAAAA;AAAAA;AAAAA,gCAEGR,EAAM,KAAK;AAAA;AAAA,OAEpC,CAAC;AAAA;AAAA,GAGR,CAAC,ECnLDD,EAAAA,UAAU,WAAY,IAAM,CAC1B,MAAMC,EAAQC,EAAAA,SAAS,CACrB,MAAO,GACP,MAAO,EAAA,CACR,EAEDG,OAAAA,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GAiCd,EAEMG,EAAAA;AAAAA;AAAAA;AAAAA,QAGDC,EAAAA,KAAKT,EAAM,OAAS,CAAC,CAACA,EAAM,MAAO,IAAMQ,EAAAA;AAAAA,wBACzB,CAAE,MAAO,GAAM,MAAOR,EAAM,MAAO,MAAO,CAACA,EAAM,MAAO;AAAA,YACpES,OAAK,CAACT,EAAM,MAAO,IAAMQ,EAAAA,OAAO,OAAOR,EAAM,KAAK,CAAC,EAAE,CAAC;AAAA;AAAA,OAE3D,CAAC;AAAA;AAAA,GAGR,CAAC,ECrCM,SAASW,EAAaC,EAAsBC,EAAsB,CACvE,OAAOC,EAAAA,iBAAiB,IAAM,CAC5B,MAAMC,EAAWC,GAAqB,CAChCA,EAAE,MAAQ,UACTJ,MACLI,EAAE,eAAA,EACFH,EAAA,EACF,EAEAI,EAAAA,eAAe,IAAM,CAAE,SAAS,iBAAiB,UAAWF,CAAO,CAAG,CAAC,EACvEG,EAAAA,kBAAkB,IAAM,CAAE,SAAS,oBAAoB,UAAWH,CAAO,CAAG,CAAC,CAC/E,CAAC,CACH,CC3BA,MAAMI,GAAY,CAChB,UACA,yBACA,wBACA,yBACA,2BACA,kCACA,mCACF,EAAE,KAAK,IAAI,EAEX,SAASC,GAAUC,EAA0B,CAC3C,GAAKA,EAAuC,OAAQ,MAAO,GAC3D,MAAMC,EAAI,iBAAiBD,CAAE,EAC7B,OAAOC,EAAE,UAAY,QAAUA,EAAE,aAAe,QAClD,CAUA,SAASC,EAAqBC,EAA4BC,EAA0B,CAClF,UAAWC,KAAS,MAAM,KAAKF,EAAK,QAAQ,EAAG,CAC7C,MAAMH,EAAKK,EACX,GAAIL,EAAG,UAAY,OACjB,UAAWM,KAAaN,EAAuB,iBAAiB,CAAE,QAAS,EAAA,CAAM,EAC/EE,EAAqBI,EAAUF,CAAG,OAE3BJ,EAAG,WAEZE,EAAqBF,EAAG,WAAYI,CAAG,EAC9BJ,EAAG,QAAQF,EAAS,GAAKC,GAAUC,CAAE,EAC9CI,EAAI,KAAKJ,CAAE,EAEXE,EAAqBF,EAAII,CAAG,CAEhC,CACF,CAEA,SAASG,GAAiBC,EAAgD,CACxE,MAAMJ,EAAqB,CAAA,EAC3B,OAAAF,EAAqBM,EAAWJ,CAAG,EAC5BA,CACT,CAEA,SAASK,IAA2C,CAClD,IAAIT,EAAqB,SAAS,cAClC,KAAOA,GAAI,YAAY,eAAeA,EAAKA,EAAG,WAAW,cACzD,OAAOA,CACT,CA4BO,SAASU,GAAkB,CAEhC,MAAMC,EAAMC,EAAAA,2BAAA,EAMZ,GAAI,CAACD,EAAI,cAAe,CACtB,MAAME,EAAQ,CACZ,UAAW,KACX,cAAe,IAAA,EAGXC,EAAiBnB,GAAqB,CAC1C,GAAIA,EAAE,MAAQ,OAAS,CAACkB,EAAM,UAAW,OACzC,MAAME,EAAYR,GAAiBM,EAAM,SAAS,EAClD,GAAI,CAACE,EAAU,OAAQ,OACvB,MAAMC,EAASP,GAAA,EACTQ,EAAMD,EAASD,EAAU,QAAQC,CAAM,EAAI,GAC7CrB,EAAE,SACAsB,GAAO,IAAKtB,EAAE,eAAA,EAAkBoB,EAAUA,EAAU,OAAS,CAAC,EAAE,MAAA,IAEhEE,IAAQF,EAAU,OAAS,GAAKE,EAAM,KAAKtB,EAAE,eAAA,EAAkBoB,EAAU,CAAC,EAAE,MAAA,EAEpF,EAEAJ,EAAI,cAAgB,CAClB,aAAaX,EAAiB,CAC5Ba,EAAM,UAAYb,EAClBa,EAAM,cAAgBJ,GAAA,EACtB,SAAS,iBAAiB,UAAWK,CAAa,EAClDP,GAAiBP,CAAE,EAAE,CAAC,GAAG,MAAA,CAC3B,EACA,cAAe,CACb,SAAS,oBAAoB,UAAWc,CAAa,EACrDD,EAAM,eAAe,MAAA,EACrBA,EAAM,cAAgB,KACtBA,EAAM,UAAY,IACpB,EACA,SAAU,CACR,SAAS,oBAAoB,UAAWC,CAAa,EACrDD,EAAM,UAAY,IACpB,CAAA,CAEJ,CAEA,OAAOF,EAAI,aAKb,CCrIA,IAAIO,EAAY,EACZC,GAAgB,GAChBC,GAAoB,GAEjB,SAASC,GAAgB,CAC9B,MAAO,CACL,MAAO,CACL,GAAIH,IAAc,EAAG,CAGnB,MAAMI,EAAiB,OAAO,WAAa,SAAS,gBAAgB,YAIpE,GAHAH,GAAgB,SAAS,KAAK,MAAM,SACpCC,GAAoB,SAAS,KAAK,MAAM,aACxC,SAAS,KAAK,MAAM,SAAW,SAC3BE,EAAiB,EAAG,CACtB,MAAMC,EAAU,WAAWH,EAAiB,GAAK,EACjD,SAAS,KAAK,MAAM,aAAe,GAAGG,EAAUD,CAAc,IAChE,CACF,CACAJ,GACF,EACA,QAAS,CACHA,GAAa,IACjBA,IACIA,IAAc,IAChB,SAAS,KAAK,MAAM,SAAWC,GAC/B,SAAS,KAAK,MAAM,aAAeC,IAEvC,CAAA,CAEJ,CCxBA1C,EAAAA,UAAU,kBAAmB,IAAM,CACjC,MAAMC,EAAQC,EAAAA,SAAS,CACrB,SAAU,GACV,WAAY,GACZ,QAAS,UAAA,CACV,EACKC,EAAOC,EAAAA,QAAA,EACP0C,EAAOC,EAAAA,YAAY,OAAQ,EAAK,EAGtC,IAAIC,EAA8B,KAC9BC,EAAa,EACbC,EAAgB,EAChBC,EAAa,GAEbC,EAAgB,GAIhBC,EAAkC,KAItC,MAAMC,EAAmB,GACnBC,EAAmB,IAEzB,SAASC,EAAoBvC,EAAiB,CAC5C,GAAI,CAAC6B,EAAK,MAAO,OACjB,MAAMW,EAASxC,EAAE,cACjB+B,EAAWS,EAAO,QAAQ,qBAAqB,GAAKA,EAAO,QAAQ,wBAAwB,EACtFT,IAELG,EAAgB,GAChBF,EAAgBhC,EAAE,QAClBiC,EAAgB,YAAY,IAAA,EAI5BF,EAAQ,MAAM,WAAa,OAG3BS,EAAO,kBAAkBxC,EAAE,SAAS,EACpCA,EAAE,eAAA,EACJ,CAEA,SAASyC,EAAoBzC,EAAiB,CAC5C,GAAI,CAACkC,GAAc,CAACH,EAAS,OAE7B,MAAMW,EAAQ,KAAK,IAAI,EAAG1C,EAAE,QAAUgC,CAAU,EAChDD,EAAQ,MAAM,UAAY,cAAcW,CAAK,KAC/C,CAEA,SAASC,EAAkB3C,EAAiB,CAC1C,GAAI,CAACkC,GAAc,CAACH,EAAS,OAC7BG,EAAa,GAEb,MAAMQ,EAAW,KAAK,IAAI,EAAG1C,EAAE,QAAUgC,CAAU,EAC7CY,GAAY,YAAY,IAAA,EAAQX,GAAiB,IACjDY,EAAWD,EAAU,EAAIF,EAAQE,EAAU,EAE3CE,EACJJ,EAAWX,EAAQ,aAAeM,GAClCQ,EAAWP,EAKb,GAFAP,EAAQ,MAAM,WAAa,GAEvBe,EAAe,CAKjBf,EAAQ,MAAM,WAAa,+CAC3BA,EAAQ,MAAM,UAAY,mBAC1B,MAAMgB,EAAShB,EACTiB,EAAQ,IAAM,CAClBD,EAAO,oBAAoB,gBAAiBC,CAAK,EAKjDb,EAAgB,GAChBC,EAAcW,EACd7D,EAAK,OAAO,EACZ2C,EAAK,MAAQ,EAAY,EAC3BkB,EAAO,iBAAiB,gBAAiBC,CAAK,CAChD,MAEEjB,EAAQ,MAAM,UAAY,GAE5BA,EAAU,IACZ,CAKApC,EAAa,IAAMkC,EAAK,OAAS7C,EAAM,UAAY,QAH9B,IAAM,CAAEE,EAAK,OAAO,EAAG2C,EAAK,MAAQ,EAAO,CAGQ,EAAA,EACxE,MAAMoB,EAAOlC,EAAA,EACbb,oBAAkB,IAAM+C,EAAK,SAAS,EACtC,MAAMC,EAAaxB,EAAA,EAEnBtC,OAAAA,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GA2Gd,EAIMG,EAAAA;AAAAA,MACH2D,aAAW,CACX,KAAMtB,EAAK,OAAS7C,EAAM,UAAY,QACtC,KAAM,WACN,UAAW,mBACX,YAAa,qBACb,YAAa,qBACb,QAAS,gBAAA,EACRQ,EAAAA;AAAAA;AAAAA;AAAAA,kBAGW,IAAM,CAAEN,EAAK,OAAO,EAAG2C,EAAK,MAAQ,EAAO,CAAC;AAAA;AAAA,KAEzD,CAAC;AAAA;AAAA,MAEA7C,EAAM,UAAY,QAChBmE,aAAW,CACT,KAAMtB,EAAK,MACX,KAAM,iBACN,UAAW,mBACX,YAAa,qBACb,YAAa,qBACb,QAAS,iBACT,cAAe,IAAM,CACfM,IACFA,EAAgB,GACZC,IACFA,EAAY,MAAM,WAAa,OAC/BA,EAAc,MAGpB,EACA,cAAec,EAAW,KAC1B,aAAcD,EAAK,aACnB,aAAc,IAAM,CAAEA,EAAK,aAAA,EAAgBC,EAAW,OAAA,CAAU,CAAA,EAC/D1D,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,qBAKU,CAAE,kBAAmBR,EAAM,SAAW,wBAA0B,KAAM;AAAA;AAAA,cAE7ES,OAAKT,EAAM,WAAY,IAAMQ,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,gCAMX+C,CAAmB;AAAA,gCACnBE,CAAmB;AAAA,8BACrBE,CAAiB;AAAA,kCACbA,CAAiB;AAAA,4BACtB3C,GAAqB,EAAMA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAAOA,EAAE,eAAA,EAAkBd,EAAK,OAAO,EAAG2C,EAAK,MAAQ,GAAS,CAAC;AAAA;AAAA;AAAA;AAAA,aAI3I,CAAC;AAAA,cACApC,EAAAA,KAAK,CAAC,CAACT,EAAM,SAAU,IAAMQ,EAAAA;AAAAA;AAAAA,wEAE6BR,EAAM,QAAQ;AAAA;AAAA,aAEzE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,SAKL,EACDmE,EAAAA,WAAW,CACT,KAAMtB,EAAK,MACX,KAAM,oBACN,UAAW,sBACX,YAAa,wBACb,YAAa,wBACb,QAAS,oBACT,cAAe,IAAM,CACfM,IACFA,EAAgB,GACZC,IACFA,EAAY,MAAM,WAAa,OAC/BA,EAAc,MAGpB,CAAA,EACC5C,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA,qBAIU,CAAE,kBAAmBR,EAAM,SAAW,wBAA0B,KAAM;AAAA;AAAA,cAE7ES,OAAKT,EAAM,WAAY,IAAMQ,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,gCAMX+C,CAAmB;AAAA,gCACnBE,CAAmB;AAAA,8BACrBE,CAAiB;AAAA,kCACbA,CAAiB;AAAA,4BACtB3C,GAAqB,EAAMA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAAOA,EAAE,eAAA,EAAkBd,EAAK,OAAO,EAAG2C,EAAK,MAAQ,GAAS,CAAC;AAAA;AAAA;AAAA;AAAA,aAI3I,CAAC;AAAA,cACApC,EAAAA,KAAK,CAAC,CAACT,EAAM,SAAU,IAAMQ,EAAAA;AAAAA;AAAAA,wEAE6BR,EAAM,QAAQ;AAAA;AAAA,aAEzE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,SAKL,CACL;AAAA,GAEJ,CAAC,ECtTDD,EAAAA,UAAU,kBAAmB,IAAM,CACjC,MAAMC,EAAQC,EAAAA,SAAS,CACrB,QAAS,WACT,SAAU,GACV,MAAO,CAAA,CAAC,CACT,EACKC,EAAOC,EAAAA,QAAA,EAEbC,OAAAA,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GA+Hd,EAEMG,EAAAA;AAAAA,mBACU,CAAE,MAAO,GAAM,CAACR,EAAM,OAAO,EAAG,GAAM;AAAA,QACjDoE,EAAAA,KAAKpE,EAAM,MAAO,CAACqE,EAAMC,IAAM9D,EAAAA;AAAAA;AAAAA;AAAAA,wBAGf6D,EAAK,KAAK;AAAA,uBACXrE,EAAM,UAAYqE,EAAK,QAAQ;AAAA,oBACjCrD,GAAa,CAAEA,EAAE,gBAAA,EAAmBd,EAAK,QAAS,CAAE,GAAImE,EAAK,GAAI,MAAOC,EAAG,CAAG,CAAC;AAAA;AAAA,YAExF7D,OAAK,CAAC,CAAC4D,EAAK,KAAM,IAAM7D,mDAAiD6D,EAAK,IAAI,SAAS,CAAC;AAAA,YAC5FA,EAAK,KAAK;AAAA;AAAA,OAEf,CAAC;AAAA;AAAA,GAGR,CAAC,EC9KDtE,EAAAA,UAAU,YAAa,IAAM,CAC3B,MAAMC,EAAQC,EAAAA,SAAS,CACrB,QAAS,SACT,MAAO,GACP,KAAM,GACN,KAAM,SACN,SAAU,EAAA,CACX,EACDG,OAAAA,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GAwGd,EAEMG,EAAAA;AAAAA;AAAAA,eAEMR,EAAM,IAAI;AAAA,gBACT,CACR,CAACA,EAAM,OAAO,EAAG,GACjB,WAAY,CAAC,CAACA,EAAM,IAAA,CACrB;AAAA,mBACYA,EAAM,QAAQ;AAAA;AAAA,QAEzBS,OAAK,CAAC,CAACT,EAAM,KAAM,IAAMQ,+CAA6CR,EAAM,IAAI,SAAS,CAAC;AAAA,QAC1FA,EAAM,KAAK;AAAA;AAAA,GAGnB,CAAC,EChIDD,EAAAA,UAAU,UAAW,IAAM,CACzB,MAAMC,EAAQC,EAAAA,SAAS,CACrB,QAAS,WACT,UAAW,EAAA,CACZ,EACKC,EAAOC,EAAAA,QAAA,EAEbC,OAAAA,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GA8Cd,EAEMG,EAAAA;AAAAA;AAAAA,gBAEO,CACR,KAAM,GACN,CAACR,EAAM,OAAO,EAAG,GACjB,UAAWA,EAAM,SAAA,CAClB;AAAA,kBACWA,EAAM,UAAY,IAAM,MAAS;AAAA,eACpC,CAAE,KAAMA,EAAM,UAAY,SAAW,KAAM;AAAA,gBAC1C,IAAMA,EAAM,WAAaE,EAAK,OAAO,CAAC;AAAA,kBACnCc,GAAqB,CAC5BhB,EAAM,YAAcgB,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OACrDA,EAAE,eAAA,EACFd,EAAK,OAAO,EAEhB,CAAC;AAAA;AAAA;AAAA;AAAA,GAKP,CAAC,EClEDH,EAAAA,UAAU,cAAe,IAAM,CAC7B,MAAMC,EAAQC,EAAAA,SAAS,CACrB,MAAO,CAAA,EACP,QAAS,cAAA,CACV,EACKC,EAAOC,EAAAA,QAAA,EAEbC,OAAAA,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GAkFd,EAEMG,EAAAA;AAAAA,mBACU,CAAE,SAAU,GAAM,CAACR,EAAM,OAAO,EAAG,GAAM;AAAA,QACpDoE,EAAAA,KACA,MAAM,QAAQpE,EAAM,KAAK,EAAIA,EAAM,MAAQ,CAAA,EAC1CqE,GAAuB7D,EAAAA;AAAAA,sBACV6D,EAAK,EAAE,oEAAoEA,EAAK,UAAYA,EAAK,EAAE,aAAa,IAAMnE,EAAK,SAAUmE,EAAK,EAAE,CAAC,eAAgBrD,GAAqB,EAAMA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAAOA,EAAE,eAAA,EAAkBd,EAAK,SAAUmE,EAAK,EAAE,EAAK,CAAC;AAAA,cACtRA,EAAK,MACH7D,mCAAiC6D,EAAK,KAAK,UAAUA,EAAK,UAAY,EAAE,oBACxE7D,EAAAA;AAAAA,uDACuC6D,EAAK,MAAQ,cAAgBA,EAAK,MAAQ,EAAE;AAAA;AAAA;AAAA,eAIvF;AAAA,cACE5D,EAAAA,KAAK,CAAC,EAAE4D,EAAK,UAAYA,EAAK,gBAAiB,IAAM7D,EAAAA;AAAAA;AAAAA,kBAEjDC,OAAK,CAAC,CAAC4D,EAAK,SAAU,IAAM7D,kCAAgC6D,EAAK,QAAQ,MAAM,CAAC;AAAA,kBAChF5D,OAAK,CAAC,CAAC4D,EAAK,eAAgB,IAAM7D,oCAAkC6D,EAAK,cAAc,MAAM,CAAC;AAAA;AAAA,aAEnG,CAAC;AAAA;AAAA,SAAA,CAGP;AAAA;AAAA,GAGP,CAAC,EC7HDtE,EAAAA,UAAU,cAAe,IAAM,CAC7B,MAAMC,EAAQC,EAAAA,SAAS,CACrB,cAAe,GACf,SAAU,GACV,MAAO,EAAA,CACR,EACKC,EAAOC,EAAAA,QAAA,EACPoE,EAAUzB,EAAAA,YAAY,UAAW,EAAK,EAE5C1C,OAAAA,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GAkFd,EAEMG,EAAAA;AAAAA,qBACY,CAAE,SAAUR,EAAM,SAAU;AAAA,qBAC5B,CACb,qBAAsB,GACtB,QAASuE,EAAQ,MACjB,cAAevE,EAAM,aAAA,CACtB;AAAA;AAAA;AAAA,sBAGeuE,EAAQ,KAAK;AAAA,uBACZvE,EAAM,QAAQ;AAAA,mBAClB,CAAE,cAAeA,EAAM,cAAe;AAAA,qBACnCgB,GAAa,CAAEd,EAAK,SAAWc,EAAE,OAA4B,OAAO,EAAGuD,EAAQ,MAASvD,EAAE,OAA4B,OAAS,CAAC;AAAA;AAAA;AAAA,wDAG9FhB,EAAM,cAAgB,SAAW,OAAO;AAAA;AAAA;AAAA,QAGxFA,EAAM,KAAK;AAAA;AAAA,GAGnB,CAAC,ECjHDD,EAAAA,UAAU,UAAW,IAAM,CACzB,MAAMC,EAAQC,EAAAA,SAAS,CACrB,QAAS,SACT,MAAO,GACP,KAAM,GACN,SAAU,EAAA,CACX,EACKC,EAAOC,EAAAA,QAAA,EACPqE,EAAW1B,EAAAA,YAAY,WAAY,EAAK,EAE9C1C,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,GAsGd,EAED,MAAMoE,EAAazE,EAAM,UAAY,UAAYA,EAAM,UAAY,aAC7D0E,EAAYF,EAAS,OAASxE,EAAM,UAAY,SAAW,QAAUA,EAAM,KAEjF,OAAOQ,EAAAA;AAAAA;AAAAA,gBAEO,CACR,KAAM,GACN,SAAUgE,EAAS,MACnB,SAAUC,EACV,WAAY,CAAC,CAACC,CAAA,CACf;AAAA,cACO1E,EAAM,UAAY,SAAW,WAAa,QAAQ;AAAA,eACjD,CAAE,eAAgBA,EAAM,UAAY,SAAW,OAAOwE,EAAS,KAAK,EAAI,KAAM;AAAA,wBACrE,OAAOxE,EAAM,QAAQ,CAAC;AAAA,kBAC5BA,EAAM,SAAW,GAAK,CAAC;AAAA,gBACzB,IAAM,CAAOA,EAAM,WAAYE,EAAK,OAAO,EAAOF,EAAM,UAAY,WAAUwE,EAAS,MAAQ,CAACA,EAAS,OAAS,CAAC;AAAA,kBAChHxD,GAAqB,CAAM,CAAChB,EAAM,WAAagB,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAAQA,EAAE,eAAA,EAAkBd,EAAK,OAAO,EAAOF,EAAM,UAAY,WAAUwE,EAAS,MAAQ,CAACA,EAAS,OAAS,CAAC;AAAA;AAAA,QAEzM/D,EAAAA,KAAK,CAAC,CAACiE,EAAW,IAAMlE,EAAAA,6CAA6CkE,CAAS,SAAS,CAAC;AAAA,QACxF1E,EAAM,KAAK;AAAA,QACXS,EAAAA,KAAKT,EAAM,UAAY,QAAS,IAAMQ,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA,+BAKfR,EAAM,KAAK;AAAA,oBACrBgB,GAAa,CAAEA,EAAE,gBAAA,EAAmBd,EAAK,QAAQ,CAAG,CAAC;AAAA,sBACnDc,GAAqB,EAAMA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAAOA,EAAE,eAAA,EAAkBA,EAAE,gBAAA,EAAmBd,EAAK,QAAQ,EAAK,CAAC;AAAA;AAAA,OAE7I,CAAC;AAAA;AAAA,GAGR,CAAC,EC7ID,MAAMyE,GAAe,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAI,EACxDC,GAAc,CAClB,UAAU,WAAW,QAAQ,QAAQ,MAAM,OAC3C,OAAO,SAAS,YAAY,UAAU,WAAW,UACnD,EAEA,SAASC,EAAUC,EAA0B,CAC3C,GAAI,CAACA,EAAK,OAAO,KACjB,MAAMC,EAAI,IAAI,KAAKD,EAAM,WAAW,EACpC,OAAO,MAAMC,EAAE,QAAA,CAAS,EAAI,KAAOA,CACrC,CAEA,SAASC,GAAUD,EAAiB,CAClC,MAAME,EAAIF,EAAE,YAAA,EACNG,EAAI,OAAOH,EAAE,SAAA,EAAa,CAAC,EAAE,SAAS,EAAG,GAAG,EAC5CI,EAAM,OAAOJ,EAAE,QAAA,CAAS,EAAE,SAAS,EAAG,GAAG,EAC/C,MAAO,GAAGE,CAAC,IAAIC,CAAC,IAAIC,CAAG,EACzB,CAEA,SAASC,EAAQC,EAASC,EAAkB,CAC1C,OAAOD,EAAE,YAAA,IAAkBC,EAAE,YAAA,GACtBD,EAAE,SAAA,IAAkBC,EAAE,YACtBD,EAAE,QAAA,IAAkBC,EAAE,QAAA,CAC/B,CAGA,SAASC,GAAeT,EAAqB,CAC3C,MAAMC,EAAIF,EAAUC,CAAG,EACvB,OAAKC,EACEA,EAAE,mBAAmB,QAAS,CAAE,QAAS,QAAS,MAAO,QAAS,IAAK,UAAW,EAD1E,YAEjB,CAGA,SAASS,GAAgBV,EAAqB,CAC5C,MAAMC,EAAIF,EAAUC,CAAG,EACvB,OAAKC,EACEA,EAAE,mBAAmB,QAAS,CAAE,MAAO,QAAS,IAAK,UAAW,EADxD,GAEjB,CAeA,SAASU,GACPC,EACAC,EACAnB,EACAoB,EACAC,EACAC,EACAC,EACe,CACf,MAAMC,MAAY,KAEZC,EADW,IAAI,KAAKP,EAAMC,EAAO,CAAC,EACX,OAAA,EACvBO,EAAc,IAAI,KAAKR,EAAMC,EAAQ,EAAG,CAAC,EAAE,QAAA,EAC3CQ,EAAgB,IAAI,KAAKT,EAAMC,EAAO,CAAC,EAAE,QAAA,EAEzCS,EAAuB,CAAA,EAG7B,QAAS9B,EAAI2B,EAAc,EAAG3B,GAAK,EAAGA,IAAK,CACzC,MAAMS,EAAI,IAAI,KAAKW,EAAMC,EAAQ,EAAGQ,EAAgB7B,CAAC,EACrD8B,EAAM,KAAKC,GAAStB,EAAG,GAAOiB,EAAOxB,EAAUoB,EAAYC,EAAUC,EAASC,CAAO,CAAC,CACxF,CAGA,QAAShB,EAAI,EAAGA,GAAKmB,EAAanB,IAAK,CACrC,MAAMuB,EAAO,IAAI,KAAKZ,EAAMC,EAAOZ,CAAC,EACpCqB,EAAM,KAAKC,GAASC,EAAM,GAAMN,EAAOxB,EAAUoB,EAAYC,EAAUC,EAASC,CAAO,CAAC,CAC1F,CAGA,MAAMQ,EAAY,GAAKH,EAAM,OAC7B,QAASrB,EAAI,EAAGA,GAAKwB,EAAWxB,IAAK,CACnC,MAAMuB,EAAO,IAAI,KAAKZ,EAAMC,EAAQ,EAAGZ,CAAC,EACxCqB,EAAM,KAAKC,GAASC,EAAM,GAAON,EAAOxB,EAAUoB,EAAYC,EAAUC,EAASC,CAAO,CAAC,CAC3F,CAEA,OAAOK,CACT,CAEA,SAASC,GACPC,EACAE,EACAR,EACAxB,EACAoB,EACAC,EACAC,EACAC,EACa,CACb,MAAMU,EAAIH,EAAK,QAAA,EACTI,EAAalC,EAAWY,EAAQkB,EAAM9B,CAAQ,EAAI,GAClDmC,EAAef,EAAaR,EAAQkB,EAAMV,CAAU,EAAI,GACxDgB,EAAaf,EAAWT,EAAQkB,EAAMT,CAAQ,EAAI,GACxD,IAAIgB,EAAY,GACZjB,GAAcC,IAChBgB,EAAYJ,EAAIb,EAAW,QAAA,GAAaa,EAAIZ,EAAS,QAAA,GAEvD,MAAMiB,GAAYhB,EAAUW,EAAIX,EAAQ,QAAA,EAAY,MAClCC,EAAUU,EAAIV,EAAQ,QAAA,EAAY,IACpD,MAAO,CACL,IAAKf,GAAUsB,CAAI,EACnB,KAAAA,EACA,QAAAE,EACA,QAASpB,EAAQkB,EAAMN,CAAK,EAC5B,WAAAU,EACA,aAAAC,EACA,WAAAC,EACA,UAAAC,EACA,SAAAC,EACA,MAAO,OAAOR,EAAK,QAAA,CAAS,CAAA,CAEhC,CAGAvG,EAAAA,UAAU,iBAAkB,IAAM,CAChC,MAAMC,EAAQC,EAAAA,SAAS,CAErB,QAAS,SAET,WAAY,GAEZ,SAAU,GAEV,IAAK,GAEL,IAAK,GAEL,MAAO,cACP,UAAW,cACX,KAAM,EAAA,CACP,EACKC,EAAOC,EAAAA,QAAA,EACP4G,EAAajE,EAAAA,YAAY,EAAE,EAC3BD,EAAOmE,EAAAA,IAAIhH,EAAM,IAAI,EAC3BiH,EAAAA,MAAM,IAAMjH,EAAM,KAAMkH,GAAK,CAAErE,EAAK,MAAQqE,CAAG,CAAC,EAIhD,MAAMC,EAAOH,EAAAA,IAA8B,KAAK,EAE1CI,EAAYJ,EAAAA,IAAI,IAAI,KAAA,EAAO,aAAa,EACxCK,EAAYL,EAAAA,IAAI,IAAI,KAAA,EAAO,UAAU,EAGrCM,EAAgB,IAAM,CAC1B,MAAM,EAAIzC,EAAUkC,EAAW,KAAK,EAChC,IAAKK,EAAS,MAAQ,EAAE,YAAA,EAAeC,EAAU,MAAQ,EAAE,SAAA,EACjE,EACAC,EAAA,EACAL,EAAAA,MAAM,IAAMF,EAAW,MAAOO,CAAa,EAI3C,MAAMC,EAAeP,EAAAA,IAAID,EAAW,KAAK,EACzCE,EAAAA,MAAM,IAAMF,EAAW,MAAQG,GAAM,CAAEK,EAAa,MAAQL,CAAG,CAAC,EAChED,EAAAA,MAAM,IAAMpE,EAAK,MAAQ2E,GAAW,CAAMA,IAAQD,EAAa,MAAQR,EAAW,MAAO,CAAC,EAG1F,MAAMU,EAAe,IAAM,CAAE,MAAMP,EAAI,CAACrE,EAAK,MAAOA,EAAK,MAAQqE,EAAGhH,EAAK,cAAegH,CAAC,CAAG,EAGtFQ,EAAgBC,EAAAA,SAAS,IAC7B9C,EAAU7E,EAAM,UAAY,SAAWuH,EAAa,MAAQR,EAAW,KAAK,CAAC,EACzEa,EAAgBD,EAAAA,SAAS,IAAM9C,EAAU7E,EAAM,UAAU,CAAC,EAC1D6H,EAAgBF,EAAAA,SAAS,IAAM9C,EAAU7E,EAAM,QAAQ,CAAC,EACxD8H,EAAgBH,EAAAA,SAAS,IAAM9C,EAAU7E,EAAM,GAAG,CAAC,EACnD+H,EAAgBJ,EAAAA,SAAS,IAAM9C,EAAU7E,EAAM,GAAG,CAAC,EAEnDgI,EAAgBL,EAAAA,SAAS,IAC7BlC,GACE2B,EAAS,MAAOC,EAAU,MAC1BK,EAAa,MACbE,EAAa,MAAOC,EAAW,MAC/BC,EAAM,MAAOC,EAAM,KAAA,CACrB,EAGIE,EAAaN,EAAAA,SAAS,IAC1B,GAAG/C,GAAYyC,EAAU,KAAK,CAAC,IAAID,EAAS,KAAK,EAAA,EAI7Cc,EAAWP,EAAAA,SAAS,IAAM,CAC9B,MAAMQ,EAAOf,EAAS,MAChBgB,EAAkB,CAAA,EACxB,QAASnD,EAAIkD,EAAO,GAAIlD,GAAKkD,EAAO,GAAIlD,IAAKmD,EAAM,KAAKnD,CAAC,EACzD,OAAOmD,CACT,CAAC,EAGKC,EAAY,IAAM,CAClBhB,EAAU,QAAU,GAAKA,EAAU,MAAQ,GAAID,EAAS,SACvDC,EAAU,OACjB,EACMiB,EAAY,IAAM,CAClBjB,EAAU,QAAU,IAAMA,EAAU,MAAQ,EAAGD,EAAS,SACvDC,EAAU,OACjB,EAGMkB,EAAapD,GAAqB,CACtC,GAAIA,EAAI,SAAU,OAClB,MAAML,EAAME,GAAUG,EAAI,IAAI,EAC1BnF,EAAM,UAAY,SAEpBuH,EAAa,MAAQzC,GAErB5E,EAAK,SAAU4E,CAAG,EAClBiC,EAAW,MAAQjC,EACnBjC,EAAK,MAAQ,GACb3C,EAAK,cAAe,EAAK,EAE7B,EAEMsI,EAAcvD,GAAc,CAChCmC,EAAS,MAAQnC,EACjBkC,EAAK,MAAQ,KACf,EAGMsB,EAAUd,EAAAA,SAAS,IAAM3H,EAAM,UAAY,QAAQ,EACzDW,EACE,IAAOkC,EAAK,OAAS4F,EAAQ,OAAU5F,EAAK,MAC5C,IAAM,CAAEA,EAAK,MAAQ,GAAO3C,EAAK,cAAe,EAAK,EAAGA,EAAK,OAAO,CAAG,CAAA,EAAC,EAC1E,MAAM+D,EAAOlC,EAAA,EACbb,oBAAkB,IAAM+C,EAAK,SAAS,EACtC,MAAMC,EAAaxB,EAAA,EAGnBtC,EAAAA,SAAS,IAAMC,EAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AA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"}