@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.js","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":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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"}