fernwell 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/js/theme.ts", "../src/js/icon.ts", "../src/js/combobox.ts", "../src/js/modal.ts", "../src/js/nav.ts", "../src/js/loading.ts", "../src/js/toast.ts", "../src/js/table.ts", "../src/js/menu.ts", "../src/js/popover.ts", "../src/js/_position.ts", "../src/js/tooltip.ts", "../src/js/tabs.ts", "../src/js/index.ts"],
4
- "sourcesContent": ["/**\n * Theme \u2014 toggles `data-theme=\"dark\"` on <html>, remembers the choice, and\n * falls back to the OS preference. Also carries the runtime token API\n * (`setTokens` / `resetTokens` / `getToken`) for retheming Fernwell's colour\n * tokens on the fly \u2014 per-tenant branding, a user-picked accent, a live\n * preview \u2014 without touching a stylesheet.\n *\n * <button class=\"fw-btn fw-btn-ghost\" data-fw-theme-toggle\n * data-fw-theme-label-dark=\"\u2600\uFE0F Light\" data-fw-theme-label-light=\"\uD83C\uDF19 Dark\">\uD83C\uDF19 Dark</button>\n *\n * For a real icon instead of an emoji, use `data-fw-theme-icon-dark` /\n * `data-fw-theme-icon-light` (icon names from `icon.ts`) in place of the\n * `-label-` attributes \u2014 optionally alongside a `-label-` pair, which is\n * appended as text after the icon:\n *\n * <button class=\"fw-nav-btn\" data-fw-theme-toggle aria-label=\"Toggle theme\"\n * data-fw-theme-icon-dark=\"sun\" data-fw-theme-icon-light=\"moon\"></button>\n *\n * init() never animates the theme it applies on load (toggling and live OS\n * changes still do) \u2014 but to also avoid a flash of the *wrong* theme's\n * colours before this script runs at all, inline this before your CSS:\n * <script>document.documentElement.dataset.theme=localStorage.getItem('fw-theme')||(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light')</script>\n */\nimport { render as renderIcon } from './icon';\n\nexport type Theme = 'light' | 'dark';\n\nconst STORAGE_KEY = 'fw-theme';\nconst EVENT = 'fw:themechange';\nconst TOKEN_PREFIX = '--fw-';\nconst TOKEN_STYLE_ATTR = 'data-fw-tokens';\nconst INIT_ATTR = 'data-fw-theme-init';\n\nfunction store(): Storage | null {\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\n/** The theme currently applied to <html>, or the system preference if none is set. */\nexport function get(): Theme {\n const attr = document.documentElement.getAttribute('data-theme');\n if (attr === 'dark' || attr === 'light') return attr;\n return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n}\n\n/** Apply a theme, persist it, and update every toggle button on the page. */\nexport function set(theme: Theme, { persist = true }: { persist?: boolean } = {}): void {\n document.documentElement.setAttribute('data-theme', theme);\n if (persist) store()?.setItem(STORAGE_KEY, theme);\n document.querySelectorAll<HTMLElement>('[data-fw-theme-toggle]').forEach((btn) => syncToggle(btn, theme));\n document.dispatchEvent(new CustomEvent<Theme>(EVENT, { detail: theme }));\n}\n\nexport function toggle(): Theme {\n const next: Theme = get() === 'dark' ? 'light' : 'dark';\n set(next);\n return next;\n}\n\nfunction syncToggle(btn: HTMLElement, theme: Theme): void {\n btn.setAttribute('aria-pressed', String(theme === 'dark'));\n const iconName = theme === 'dark' ? btn.dataset.fwThemeIconDark : btn.dataset.fwThemeIconLight;\n const label = theme === 'dark' ? btn.dataset.fwThemeLabelDark : btn.dataset.fwThemeLabelLight;\n if (iconName !== undefined) {\n const icon = `<span class=\"fw-icon\" aria-hidden=\"true\">${renderIcon(iconName)}</span>`;\n btn.innerHTML = label !== undefined ? `${icon} ${label}` : icon;\n } else if (label !== undefined) {\n btn.textContent = label;\n }\n}\n\n/** Wait two animation frames \u2014 long enough for a `transition: none` frame to actually paint. */\nfunction afterPaint(cb: () => void): void {\n const raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : (fn: () => void) => setTimeout(fn, 16);\n raf(() => raf(cb));\n}\n\n/** Apply the stored / system theme and wire every `[data-fw-theme-toggle]` under `root`. */\nexport function init(root: ParentNode = document): void {\n const stored = store()?.getItem(STORAGE_KEY);\n const current: Theme = stored === 'dark' || stored === 'light' ? stored : get();\n\n // Applying the initial theme should never animate \u2014 only a later toggle or\n // OS change should. Suppress transitions for this one set() call.\n const html = document.documentElement;\n html.setAttribute(INIT_ATTR, '');\n set(current, { persist: false });\n afterPaint(() => html.removeAttribute(INIT_ATTR));\n\n root.querySelectorAll<HTMLElement>('[data-fw-theme-toggle]').forEach((btn) => {\n if (btn.dataset.fwBound) return;\n btn.dataset.fwBound = '1';\n syncToggle(btn, current);\n btn.addEventListener('click', () => toggle());\n });\n\n // Follow the OS only while the user hasn't chosen explicitly.\n window.matchMedia?.('(prefers-color-scheme: dark)').addEventListener?.('change', (e) => {\n if (!store()?.getItem(STORAGE_KEY)) set(e.matches ? 'dark' : 'light', { persist: false });\n });\n}\n\n/* ---------------------------------------------------------------------- *\n * Runtime tokens \u2014 override any --fw-* custom property from JS, in both\n * themes or per-theme, scoped to :root or to any selector. Overrides render\n * into one <style data-fw-tokens> appended to <head>: being unlayered and\n * last, it wins over Fernwell's own @layer fw-tokens *and* any earlier\n * static override in the consumer's stylesheet.\n * ---------------------------------------------------------------------- */\n\n/** Token name \u2192 CSS value. Bare names (`primary`) and full names (`--fw-primary`) both work. */\nexport type TokenOverrides = Record<string, string>;\n\n/** Split form: set different values per theme instead of both at once. */\nexport interface TokenThemeOverrides {\n light?: TokenOverrides;\n dark?: TokenOverrides;\n}\n\ninterface ScopeTokens {\n light: TokenOverrides;\n dark: TokenOverrides;\n}\n\nconst tokenScopes = new Map<string, ScopeTokens>();\n\nfunction normalizeTokenName(name: string): string {\n return name.startsWith('--') ? name : `${TOKEN_PREFIX}${name}`;\n}\n\nfunction isThemeSplit(tokens: TokenOverrides | TokenThemeOverrides): tokens is TokenThemeOverrides {\n // A token's own value is always a CSS string \u2014 so any object-valued entry\n // means this is the { light, dark } split form, not a flat token map.\n return Object.values(tokens).some((v) => v !== null && typeof v === 'object');\n}\n\nfunction declBlock(tokens: TokenOverrides): string {\n return Object.entries(tokens)\n .map(([name, value]) => `${normalizeTokenName(name)}:${value};`)\n .join('');\n}\n\nfunction tokenStyleEl(create: boolean): HTMLStyleElement | null {\n const existing = document.head.querySelector<HTMLStyleElement>(`style[${TOKEN_STYLE_ATTR}]`);\n if (existing || !create) return existing;\n const el = document.createElement('style');\n el.setAttribute(TOKEN_STYLE_ATTR, '');\n document.head.appendChild(el);\n return el;\n}\n\nfunction renderTokens(): void {\n if (tokenScopes.size === 0) {\n tokenStyleEl(false)?.remove();\n return;\n }\n const rules: string[] = [];\n tokenScopes.forEach(({ light, dark }, scope) => {\n if (Object.keys(light).length) rules.push(`${scope}{${declBlock(light)}}`);\n if (Object.keys(dark).length) {\n const darkSelector =\n scope === ':root' ? '[data-theme=\"dark\"]' : `[data-theme=\"dark\"] ${scope}, ${scope}[data-theme=\"dark\"]`;\n rules.push(`${darkSelector}{${declBlock(dark)}}`);\n }\n });\n tokenStyleEl(true)!.textContent = rules.join('\\n');\n}\n\n/**\n * Override Fernwell design tokens at runtime \u2014 every derived token (hovers,\n * tints, focus ring, glows) follows automatically, in both themes:\n *\n * theme.setTokens({ primary: '#2266ff' });\n *\n * Pass `{ light, dark }` to set different values per theme, and `scope` to\n * theme a subtree instead of the whole page:\n *\n * theme.setTokens({ light: { primary: '#2266ff' }, dark: { primary: '#5c9dff' } });\n * theme.setTokens({ secondary: '#a33' }, { scope: '.tenant-acme' });\n *\n * Calls accumulate (merge into whatever overrides are already set for that\n * scope) \u2014 call `resetTokens()` to clear them.\n */\nexport function setTokens(tokens: TokenOverrides | TokenThemeOverrides, opts: { scope?: string } = {}): void {\n const scope = opts.scope ?? ':root';\n const entry = tokenScopes.get(scope) ?? { light: {}, dark: {} };\n if (isThemeSplit(tokens)) {\n Object.assign(entry.light, tokens.light);\n Object.assign(entry.dark, tokens.dark);\n } else {\n Object.assign(entry.light, tokens);\n Object.assign(entry.dark, tokens);\n }\n tokenScopes.set(scope, entry);\n renderTokens();\n}\n\n/** Clear runtime token overrides \u2014 for one `scope`, or every scope if omitted. */\nexport function resetTokens(scope?: string): void {\n if (scope) tokenScopes.delete(scope);\n else tokenScopes.clear();\n renderTokens();\n}\n\n/** The live, resolved value of a token (e.g. `getToken('primary')` \u2192 `'#ffc145'`), including runtime overrides. */\nexport function getToken(name: string, el: Element = document.documentElement): string {\n return getComputedStyle(el).getPropertyValue(normalizeTokenName(name)).trim();\n}\n", "/**\n * Icon \u2014 renders a named SVG icon into a `data-fw-icon` element.\n *\n * <span class=\"fw-icon\" data-fw-icon=\"trash\" aria-hidden=\"true\"></span>\n *\n * Icons are decorative by default (the injected <svg> is `aria-hidden` and\n * `focusable=\"false\"`); give the accessible name to a wrapping interactive\n * element instead (e.g. `aria-label` on a button), same as `.fw-icon-btn`.\n * Color and size are not set here \u2014 `.fw-icon` inherits `color` and sizes\n * itself in `em`, so an icon matches whatever text surrounds it.\n */\nconst icons: Record<string, string> = {\n add: '<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>',\n close: '<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>',\n check: '<polyline points=\"5,13 10,18 19,7\"/>',\n edit: '<path d=\"M16.8 3.5a2.1 2.1 0 0 1 3 3L8.5 17.8 4 19l1.2-4.5Z\"/><line x1=\"14.5\" y1=\"5.8\" x2=\"17.7\" y2=\"9\"/>',\n trash:\n '<path d=\"M4 7h16\"/><path d=\"M9 7V4.6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1V7\"/><path d=\"M6.5 7l.8 12.4A2 2 0 0 0 9.3 21h5.4a2 2 0 0 0 2-1.6L18 7\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/>',\n save: '<path d=\"M5 4a1 1 0 0 1 1-1h9.2a1 1 0 0 1 .7.3l2.8 2.8a1 1 0 0 1 .3.7V20a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4Z\"/><path d=\"M8 3v5h7V3\"/><path d=\"M8 21v-6h8v6\"/>',\n search: '<circle cx=\"11\" cy=\"11\" r=\"7\"/><line x1=\"21\" y1=\"21\" x2=\"16.6\" y2=\"16.6\"/>',\n settings:\n '<circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1\"/>',\n download: '<line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/><polyline points=\"7,10 12,15 17,10\"/><line x1=\"5\" y1=\"21\" x2=\"19\" y2=\"21\"/>',\n upload: '<line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"/><polyline points=\"7,8 12,3 17,8\"/><line x1=\"5\" y1=\"21\" x2=\"19\" y2=\"21\"/>',\n share:\n '<circle cx=\"6\" cy=\"12\" r=\"2.3\"/><circle cx=\"18\" cy=\"6\" r=\"2.3\"/><circle cx=\"18\" cy=\"18\" r=\"2.3\"/><line x1=\"8.1\" y1=\"10.8\" x2=\"15.9\" y2=\"7.2\"/><line x1=\"8.1\" y1=\"13.2\" x2=\"15.9\" y2=\"16.8\"/>',\n copy: '<rect x=\"9\" y=\"9\" width=\"12\" height=\"12\" rx=\"2\"/><path d=\"M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1\"/>',\n menu: '<line x1=\"4\" y1=\"6\" x2=\"20\" y2=\"6\"/><line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/>',\n more:\n '<circle cx=\"5\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/>',\n user: '<circle cx=\"12\" cy=\"8\" r=\"4\"/><path d=\"M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8\"/>',\n bell: '<path d=\"M6 8a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6\"/><path d=\"M10 20a2 2 0 0 0 4 0\"/>',\n heart:\n '<path d=\"M12 20s-7-4.4-9.5-8.5C.8 8 2 4.5 5.5 4.5c2 0 3.5 1 6.5 4 3-3 4.5-4 6.5-4 3.5 0 4.7 3.5 3 7-2.5 4.1-9.5 8.5-9.5 8.5Z\"/>',\n star: '<polygon points=\"12,3 14.6,9.1 21.2,9.3 16,13.4 17.8,19.8 12,16.3 6.2,19.8 8,13.4 2.8,9.3 9.4,9.1\"/>',\n calendar: '<rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\"/><line x1=\"8\" y1=\"3\" x2=\"8\" y2=\"7\"/><line x1=\"16\" y1=\"3\" x2=\"16\" y2=\"7\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/>',\n refresh:\n '<path d=\"M20 11A8 8 0 0 0 6.3 6.3L4 8.6\"/><path d=\"M4 4v5h5\"/><path d=\"M4 13a8 8 0 0 0 13.7 4.7L20 15.4\"/><path d=\"M20 20v-5h-5\"/>',\n filter: '<polygon points=\"4,4 20,4 14,12 14,19 10,21 10,12\"/>',\n info: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/><circle cx=\"12\" cy=\"8\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>',\n warning: '<path d=\"M12 3 22 20H2Z\"/><line x1=\"12\" y1=\"9.5\" x2=\"12\" y2=\"14.5\"/><circle cx=\"12\" cy=\"17.3\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>',\n lock: '<rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"/><path d=\"M8 11V7a4 4 0 0 1 8 0v4\"/>',\n eye: '<path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n 'chevron-down': '<polyline points=\"6,9 12,15 18,9\"/>',\n 'arrow-left': '<line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"/><polyline points=\"12,5 5,12 12,19\"/>',\n 'arrow-right': '<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><polyline points=\"12,5 19,12 12,19\"/>',\n folder: '<path d=\"M3.5 6.5a1 1 0 0 1 1-1H10l2 2.2h7.5a1 1 0 0 1 1 1V18a1 1 0 0 1-1 1H4.5a1 1 0 0 1-1-1Z\"/>',\n bookmark: '<path d=\"M6 3h12a1 1 0 0 1 1 1v17l-7-4-7 4V4a1 1 0 0 1 1-1Z\"/>',\n home: '<path d=\"M4 11.5 12 4l8 7.5\"/><path d=\"M6 10v10a1 1 0 0 0 1 1h3.5v-6h2.8v6H17a1 1 0 0 0 1-1V10\"/>',\n logout:\n '<path d=\"M9 4H5.5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1H9\"/><line x1=\"14\" y1=\"12\" x2=\"21\" y2=\"12\"/><polyline points=\"17.5,8.5 21,12 17.5,15.5\"/>',\n paperclip:\n '<path d=\"M21 11.5 12.4 20a4.3 4.3 0 0 1-6-6.1L15 5.3a2.9 2.9 0 0 1 4.1 4.1l-8.6 8.6a1.4 1.4 0 0 1-2-2l7.9-7.9\"/>',\n envelope: '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><path d=\"M4 6.5 12 13l8-6.5\"/>',\n 'chevron-up': '<polyline points=\"6,15 12,9 18,15\"/>',\n 'chevron-left': '<polyline points=\"15,6 9,12 15,18\"/>',\n 'chevron-right': '<polyline points=\"9,6 15,12 9,18\"/>',\n 'arrow-up': '<line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"5\"/><polyline points=\"5,12 12,5 19,12\"/>',\n 'arrow-down': '<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><polyline points=\"5,12 12,19 19,12\"/>',\n unlock: '<rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"/><path d=\"M8 11V7a4 4 0 0 1 7.8-1.3\"/>',\n 'thumbs-up':\n '<path d=\"M7 11v9H4.5a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1H7Z\"/><path d=\"M7 11l4.3-7.3a1.4 1.4 0 0 1 2.6.8L13 9h5.6a2 2 0 0 1 1.9 2.6l-2 6.5A2 2 0 0 1 16.6 19.5H10a3 3 0 0 1-3-3\"/>',\n 'thumbs-down':\n '<path d=\"M7 13V4h2.5a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H7Z\"/><path d=\"M7 13l4.3 7.3a1.4 1.4 0 0 0 2.6-.8L13 15h5.6a2 2 0 0 0 1.9-2.6l-2-6.5A2 2 0 0 0 16.6 4.5H10a3 3 0 0 0-3 3\"/>',\n 'eye-closed':\n '<path d=\"M3.5 12S7 6 12 6s8.5 6 8.5 6-3.5 6-8.5 6-8.5-6-8.5-6Z\"/><line x1=\"4\" y1=\"19\" x2=\"20\" y2=\"5\"/>',\n 'help-circle':\n '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M9.2 9.2a2.8 2.8 0 1 1 4.3 2.4c-.9.6-1.5 1.1-1.5 2.2\"/><circle cx=\"12\" cy=\"17\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>',\n chat: '<path d=\"M4 5.5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H9.5L5 20.5V16.5H5a1 1 0 0 1-1-1Z\"/>',\n kebab:\n '<circle cx=\"12\" cy=\"5\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"19\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"4.5\"/><line x1=\"12\" y1=\"19.5\" x2=\"12\" y2=\"22\"/><line x1=\"2\" y1=\"12\" x2=\"4.5\" y2=\"12\"/><line x1=\"19.5\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"4.9\" y1=\"4.9\" x2=\"6.6\" y2=\"6.6\"/><line x1=\"17.4\" y1=\"17.4\" x2=\"19.1\" y2=\"19.1\"/><line x1=\"4.9\" y1=\"19.1\" x2=\"6.6\" y2=\"17.4\"/><line x1=\"17.4\" y1=\"6.6\" x2=\"19.1\" y2=\"4.9\"/>',\n moon: '<path d=\"M20.5 14.2A8.5 8.5 0 1 1 9.8 3.5a7 7 0 0 0 10.7 10.7Z\"/>',\n};\n\nexport type IconName = keyof typeof icons;\n\nexport function render(name: string): string {\n const inner = icons[name];\n if (!inner) return '';\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">${inner}</svg>`;\n}\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-icon]').forEach((el) => {\n if (el.dataset.fwBound) return;\n el.dataset.fwBound = '1';\n\n const name = el.dataset.fwIcon ?? '';\n const markup = render(name);\n if (!markup) {\n console.warn(`fernwell: unknown icon \"${name}\"`);\n }\n el.innerHTML = markup;\n el.classList.add('fw-icon');\n });\n}\n", "/**\n * Combobox / typeahead \u2014 progressive enhancement over an <input> + <datalist>.\n *\n * <div class=\"fw-combobox\">\n * <input class=\"fw-input\" data-fw-combobox list=\"cities\" placeholder=\"Start typing\u2026\">\n * <datalist id=\"cities\"><option value=\"Seattle\"></option>\u2026</datalist>\n * </div>\n *\n * Or programmatically: combobox(input, { options: ['Seattle', \u2026], onSelect })\n */\nexport interface ComboboxOptions {\n /** Static option list. Defaults to the <datalist> the input's `list` attribute points at. */\n options?: string[];\n /** Filter function; default is case-insensitive substring match. */\n filter?: (option: string, query: string) => boolean;\n /** Text shown when nothing matches. */\n emptyText?: string;\n onSelect?: (value: string) => void;\n}\n\nexport interface ComboboxInstance {\n open(): void;\n close(): void;\n setOptions(options: string[]): void;\n destroy(): void;\n}\n\nlet uid = 0;\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[c] as string);\n}\n\nexport function combobox(input: HTMLInputElement, opts: ComboboxOptions = {}): ComboboxInstance {\n const filter = opts.filter ?? ((o, q) => o.toLowerCase().includes(q));\n const emptyText = opts.emptyText ?? 'No matches';\n let options = opts.options ?? readDatalist(input);\n let current: string[] = [];\n let activeIndex = -1;\n let selecting = false;\n\n // The native datalist would double up with our list \u2014 detach it but keep\n // the options readable for setOptions()/no-JS fallbacks.\n const listId = input.getAttribute('list');\n if (listId) {\n input.dataset.fwList = listId;\n input.removeAttribute('list');\n }\n\n const wrap = input.closest('.fw-combobox') ?? wrapInput(input);\n const list = document.createElement('ul');\n const id = `fw-combobox-${++uid}`;\n list.className = 'fw-combobox-list';\n list.id = id;\n list.setAttribute('role', 'listbox');\n wrap.appendChild(list);\n\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-expanded', 'false');\n input.setAttribute('aria-controls', id);\n input.autocomplete = 'off';\n\n function render(matches: string[]): void {\n current = matches;\n activeIndex = -1;\n const q = input.value.trim().toLowerCase();\n if (matches.length === 0) {\n list.innerHTML = `<li class=\"fw-combobox-empty\">${escapeHtml(emptyText)}</li>`;\n return;\n }\n list.innerHTML = matches\n .map((opt, i) => {\n const idx = q ? opt.toLowerCase().indexOf(q) : -1;\n const label =\n idx > -1\n ? `${escapeHtml(opt.slice(0, idx))}<b>${escapeHtml(opt.slice(idx, idx + q.length))}</b>${escapeHtml(opt.slice(idx + q.length))}`\n : escapeHtml(opt);\n return `<li class=\"fw-combobox-option\" role=\"option\" id=\"${id}-${i}\" data-index=\"${i}\" aria-selected=\"false\">${label}</li>`;\n })\n .join('');\n }\n\n function open(): void {\n const q = input.value.trim().toLowerCase();\n render(q ? options.filter((o) => filter(o, q)) : options);\n list.classList.add('is-open');\n input.setAttribute('aria-expanded', 'true');\n }\n\n function close(): void {\n list.classList.remove('is-open');\n input.setAttribute('aria-expanded', 'false');\n input.removeAttribute('aria-activedescendant');\n activeIndex = -1;\n }\n\n function highlight(i: number): void {\n const items = list.querySelectorAll<HTMLElement>('.fw-combobox-option');\n items.forEach((el) => {\n el.classList.remove('is-active');\n el.setAttribute('aria-selected', 'false');\n });\n const el = items[i];\n if (el) {\n el.classList.add('is-active');\n el.setAttribute('aria-selected', 'true');\n el.scrollIntoView({ block: 'nearest' });\n input.setAttribute('aria-activedescendant', el.id);\n }\n activeIndex = i;\n }\n\n function select(value: string): void {\n input.value = value;\n close();\n // The synthetic events below would re-open the list via onInput/onFocus.\n selecting = true;\n input.focus();\n input.dispatchEvent(new Event('input', { bubbles: true }));\n input.dispatchEvent(new Event('change', { bubbles: true }));\n selecting = false;\n opts.onSelect?.(value);\n }\n\n const onInput = () => {\n if (!selecting) open();\n };\n const onFocus = () => {\n if (!selecting) open();\n };\n const onKeydown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (!list.classList.contains('is-open')) open();\n highlight(Math.min(activeIndex + 1, current.length - 1));\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n highlight(Math.max(activeIndex - 1, 0));\n } else if (e.key === 'Enter') {\n if (activeIndex > -1 && current[activeIndex] !== undefined) {\n e.preventDefault();\n select(current[activeIndex]);\n }\n } else if (e.key === 'Escape') {\n close();\n }\n };\n const onListMousedown = (e: MouseEvent) => {\n const opt = (e.target as HTMLElement).closest<HTMLElement>('.fw-combobox-option');\n if (opt) {\n e.preventDefault(); // keep focus on the input\n select(current[Number(opt.dataset.index)]);\n }\n };\n const onDocClick = (e: MouseEvent) => {\n if (!wrap.contains(e.target as Node)) close();\n };\n\n input.addEventListener('input', onInput);\n input.addEventListener('focus', onFocus);\n input.addEventListener('keydown', onKeydown);\n list.addEventListener('mousedown', onListMousedown);\n document.addEventListener('click', onDocClick);\n\n return {\n open,\n close,\n setOptions(next) {\n options = next;\n if (list.classList.contains('is-open')) open();\n },\n destroy() {\n input.removeEventListener('input', onInput);\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('keydown', onKeydown);\n list.removeEventListener('mousedown', onListMousedown);\n document.removeEventListener('click', onDocClick);\n list.remove();\n if (input.dataset.fwList) input.setAttribute('list', input.dataset.fwList);\n delete input.dataset.fwBound;\n },\n };\n}\n\nfunction readDatalist(input: HTMLInputElement): string[] {\n const id = input.getAttribute('list') ?? input.dataset.fwList;\n const dl = id ? document.getElementById(id) : null;\n return dl ? Array.from(dl.querySelectorAll('option')).map((o) => o.value || o.textContent || '') : [];\n}\n\nfunction wrapInput(input: HTMLInputElement): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'fw-combobox';\n input.parentNode?.insertBefore(wrap, input);\n wrap.appendChild(input);\n return wrap;\n}\n\n/** Enhance every `[data-fw-combobox]` input under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLInputElement>('input[data-fw-combobox]').forEach((input) => {\n if (input.dataset.fwBound) return;\n input.dataset.fwBound = '1';\n combobox(input);\n });\n}\n", "/**\n * Modal & drawer overlays.\n *\n * <button data-fw-open-modal=\"confirm\">\u2026</button>\n * <div class=\"fw-modal-overlay\" id=\"confirm\" role=\"dialog\" aria-modal=\"true\"><div class=\"fw-modal\">\u2026 <button data-fw-close-modal>Cancel</button></div></div>\n *\n * <button data-fw-open-drawer=\"details\">\u2026</button>\n * <div class=\"fw-drawer-overlay\" data-fw-drawer-overlay=\"details\"></div>\n * <aside class=\"fw-drawer\" id=\"details\" role=\"dialog\" aria-modal=\"true\">\u2026 <button data-fw-close-drawer>\u00D7</button></aside>\n *\n * Closes on backdrop click (guarded \u2014 a text-selection drag that ends on the\n * backdrop does NOT close it), on Escape, and returns focus to the opener.\n */\nconst OPEN = 'is-open';\nconst LOCK = 'fw-scroll-lock';\nconst openStack: HTMLElement[] = [];\nconst openers = new WeakMap<HTMLElement, HTMLElement | null>();\n\nconst FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction resolve(target: string | HTMLElement): HTMLElement | null {\n return typeof target === 'string' ? document.getElementById(target) : target;\n}\n\n/** The backdrop element paired with a drawer (via `data-fw-drawer-overlay=\"<id>\"`), if any. */\nfunction backdropFor(el: HTMLElement): HTMLElement | null {\n if (el.classList.contains('fw-modal-overlay')) return el;\n const explicit = el.id ? document.querySelector<HTMLElement>(`[data-fw-drawer-overlay=\"${el.id}\"]`) : null;\n if (explicit) return explicit;\n const prev = el.previousElementSibling;\n return prev instanceof HTMLElement && prev.classList.contains('fw-drawer-overlay') ? prev : null;\n}\n\nexport function open(target: string | HTMLElement, opener: HTMLElement | null = (document.activeElement as HTMLElement) ?? null): void {\n const el = resolve(target);\n if (!el || el.classList.contains(OPEN)) return;\n el.classList.add(OPEN);\n backdropFor(el)?.classList.add(OPEN);\n openers.set(el, opener);\n openStack.push(el);\n document.body.classList.add(LOCK);\n el.dispatchEvent(new CustomEvent('fw:open', { bubbles: true }));\n // Focus the first control inside; fall back to the panel itself.\n const first = el.querySelector<HTMLElement>(FOCUSABLE);\n if (first) first.focus({ preventScroll: true });\n else {\n if (!el.hasAttribute('tabindex')) el.setAttribute('tabindex', '-1');\n el.focus({ preventScroll: true });\n }\n}\n\nexport function close(target: string | HTMLElement): void {\n const el = resolve(target);\n if (!el || !el.classList.contains(OPEN)) return;\n el.classList.remove(OPEN);\n backdropFor(el)?.classList.remove(OPEN);\n const i = openStack.indexOf(el);\n if (i > -1) openStack.splice(i, 1);\n if (openStack.length === 0) document.body.classList.remove(LOCK);\n el.dispatchEvent(new CustomEvent('fw:close', { bubbles: true }));\n openers.get(el)?.focus?.({ preventScroll: true });\n openers.delete(el);\n}\n\nexport function toggle(target: string | HTMLElement): void {\n const el = resolve(target);\n if (el) (el.classList.contains(OPEN) ? close : open)(el);\n}\n\n/**\n * Click-outside-to-close, guarded against a classic false positive: a\n * browser's `click` fires on the nearest common ancestor of mousedown and\n * mouseup. A drag that starts inside the panel and ends on the backdrop has\n * the overlay as that ancestor, so a naive `e.target === overlay` check would\n * close the modal mid-selection. Close only when BOTH landed on the backdrop.\n */\nexport function bindOutsideClickToClose(backdrop: HTMLElement, onClose: () => void): void {\n let downOnBackdrop = false;\n backdrop.addEventListener('mousedown', (e) => {\n downOnBackdrop = e.target === backdrop;\n });\n backdrop.addEventListener('click', (e) => {\n if (e.target === backdrop && downOnBackdrop) onClose();\n });\n}\n\nlet keyBound = false;\n\n/** Wire every trigger, overlay and close button under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-open-modal], [data-fw-open-drawer]').forEach((btn) => {\n if (btn.dataset.fwBound) return;\n btn.dataset.fwBound = '1';\n const id = btn.dataset.fwOpenModal ?? btn.dataset.fwOpenDrawer ?? '';\n btn.addEventListener('click', () => open(id, btn));\n });\n\n root.querySelectorAll<HTMLElement>('.fw-modal-overlay').forEach((overlay) => {\n if (overlay.dataset.fwBound) return;\n overlay.dataset.fwBound = '1';\n bindOutsideClickToClose(overlay, () => close(overlay));\n overlay.querySelectorAll<HTMLElement>('[data-fw-close-modal]').forEach((btn) =>\n btn.addEventListener('click', () => close(overlay)),\n );\n });\n\n root.querySelectorAll<HTMLElement>('.fw-drawer').forEach((drawer) => {\n if (drawer.dataset.fwBound) return;\n drawer.dataset.fwBound = '1';\n const backdrop = backdropFor(drawer);\n if (backdrop) bindOutsideClickToClose(backdrop, () => close(drawer));\n drawer.querySelectorAll<HTMLElement>('[data-fw-close-drawer]').forEach((btn) =>\n btn.addEventListener('click', () => close(drawer)),\n );\n });\n\n if (!keyBound) {\n keyBound = true;\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && openStack.length) close(openStack[openStack.length - 1]);\n });\n }\n}\n", "/**\n * Nav dropdown \u2014 the hamburger toggle in `.fw-nav` (and any other\n * button-controls-panel pair).\n *\n * <button data-fw-nav-toggle aria-controls=\"menu\" aria-expanded=\"false\">\u2026</button>\n * <div class=\"fw-nav-dropdown\" id=\"menu\">\u2026</div>\n *\n * Closes on outside click and Escape.\n */\nconst OPEN = 'is-open';\n\nexport function open(toggle: HTMLElement): void {\n const panel = panelFor(toggle);\n if (!panel) return;\n panel.classList.add(OPEN);\n toggle.setAttribute('aria-expanded', 'true');\n}\n\nexport function close(toggle: HTMLElement): void {\n const panel = panelFor(toggle);\n if (!panel) return;\n panel.classList.remove(OPEN);\n toggle.setAttribute('aria-expanded', 'false');\n}\n\nfunction panelFor(toggle: HTMLElement): HTMLElement | null {\n const id = toggle.getAttribute('aria-controls');\n return id ? document.getElementById(id) : null;\n}\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-nav-toggle]').forEach((toggle) => {\n if (toggle.dataset.fwBound) return;\n toggle.dataset.fwBound = '1';\n const panel = panelFor(toggle);\n if (!panel) return;\n const container = toggle.closest<HTMLElement>('.fw-nav') ?? toggle.parentElement ?? toggle;\n\n toggle.addEventListener('click', (e) => {\n e.stopPropagation();\n (panel.classList.contains(OPEN) ? close : open)(toggle);\n });\n document.addEventListener('click', (e) => {\n if (!container.contains(e.target as Node) && !panel.contains(e.target as Node)) close(toggle);\n });\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') close(toggle);\n });\n });\n}\n", "/**\n * Loading states.\n *\n * loading.setButtonLoading(btn, 'Sending\u2026'); // disables, swaps in a spinner\n * loading.resetButtonLoading(btn); // restores original markup\n *\n * Or declaratively: any <form data-fw-loading> puts its submit button into the\n * loading state on submit (label from `data-fw-loading-text` on the button).\n */\nconst LOADING = 'fw-btn-loading';\n\nexport function setButtonLoading(btn: HTMLButtonElement | null, loadingText?: string): void {\n if (!btn || btn.classList.contains(LOADING)) return;\n btn.dataset.fwOriginalHtml = btn.innerHTML;\n btn.disabled = true;\n btn.setAttribute('aria-busy', 'true');\n btn.classList.add(LOADING);\n const label = loadingText ?? btn.dataset.fwLoadingText ?? btn.textContent ?? '';\n btn.innerHTML = '<span class=\"fw-spinner fw-spinner-sm\" aria-hidden=\"true\"></span>';\n btn.appendChild(document.createTextNode(label));\n}\n\nexport function resetButtonLoading(btn: HTMLButtonElement | null): void {\n if (!btn || !btn.classList.contains(LOADING)) return;\n btn.disabled = false;\n btn.removeAttribute('aria-busy');\n btn.classList.remove(LOADING);\n // Restore markup, not just text, so buttons with an icon keep it.\n if (btn.dataset.fwOriginalHtml !== undefined) {\n btn.innerHTML = btn.dataset.fwOriginalHtml;\n delete btn.dataset.fwOriginalHtml;\n }\n}\n\n/** Reset every loading button \u2014 e.g. after a bfcache restore. */\nexport function resetAll(root: ParentNode = document): void {\n root.querySelectorAll<HTMLButtonElement>(`.${LOADING}`).forEach(resetButtonLoading);\n}\n\nlet pageshowBound = false;\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLFormElement>('form[data-fw-loading]').forEach((form) => {\n if (form.dataset.fwBound) return;\n form.dataset.fwBound = '1';\n form.addEventListener('submit', () => {\n const btn = form.querySelector<HTMLButtonElement>('button[type=\"submit\"], button:not([type])');\n setButtonLoading(btn);\n });\n });\n\n // Browsers restore pages from the back-forward cache without re-running JS,\n // so a spinner painted right before navigating away would come back stuck.\n if (!pageshowBound) {\n pageshowBound = true;\n window.addEventListener('pageshow', (e) => {\n if (e.persisted) resetAll();\n });\n }\n}\n", "/**\n * Toast \u2014 a single, reused, bottom-right notice.\n *\n * toast.show('Invoice sent');\n * toast.show('That card was declined', { variant: 'error', duration: 6000 });\n */\nexport type ToastVariant = 'success' | 'error' | 'info' | 'pending';\n\nexport interface ToastOptions {\n variant?: ToastVariant;\n /** ms before it hides; 0 keeps it until `hide()` or the next `show()`. */\n duration?: number;\n}\n\nlet el: HTMLElement | null = null;\nlet timer: ReturnType<typeof setTimeout> | null = null;\n\nfunction ensure(): HTMLElement {\n if (el && el.isConnected) return el;\n el = document.createElement('div');\n el.className = 'fw-toast';\n el.setAttribute('role', 'status');\n el.setAttribute('aria-live', 'polite');\n el.innerHTML = '<span class=\"fw-toast-dot\" aria-hidden=\"true\"></span><span class=\"fw-toast-text\"></span>';\n document.body.appendChild(el);\n return el;\n}\n\nexport function show(message: string, { variant = 'success', duration = 4000 }: ToastOptions = {}): HTMLElement {\n const node = ensure();\n node.className = `fw-toast${variant === 'success' ? '' : ` fw-toast-${variant}`}`;\n (node.querySelector('.fw-toast-text') as HTMLElement).textContent = message;\n if (timer) clearTimeout(timer);\n // Re-trigger the transition even if it's already showing.\n node.classList.remove('is-show');\n void node.offsetWidth;\n node.classList.add('is-show');\n if (duration > 0) timer = setTimeout(hide, duration);\n return node;\n}\n\nexport function hide(): void {\n el?.classList.remove('is-show');\n if (timer) clearTimeout(timer);\n timer = null;\n}\n", "/**\n * Table \u2014 client-side column sorting and row selection for `.fw-table`.\n *\n * <table class=\"fw-table\" data-fw-table>\n * <thead><tr>\n * <th class=\"fw-table-select\"><label class=\"fw-checkbox\"><input type=\"checkbox\" data-fw-select-all>\u2026</label></th>\n * <th scope=\"col\" aria-sort=\"none\" data-fw-sort><button type=\"button\" class=\"fw-table-sort\">Client</button></th>\n * </tr></thead>\n * <tbody><tr>\n * <td class=\"fw-table-select\"><label class=\"fw-checkbox\"><input type=\"checkbox\" data-fw-select-row>\u2026</label></td>\n * <td data-fw-sort-value=\"1250\">$1,250.00</td>\n * </tr></tbody>\n * </table>\n *\n * Clicking a `th[data-fw-sort]` cycles aria-sort (none \u2192 ascending \u2192 descending \u2192 \u2026)\n * and reorders the first <tbody>. `data-fw-sort-value` on a cell overrides its\n * text for comparison (numbers, ISO dates). Rows without a cell in the sorted\n * column (e.g. a colspan empty row) stay at the bottom.\n *\n * Row checkboxes toggle `.is-selected` / aria-selected on their row and keep the\n * select-all checkbox in sync (checked / indeterminate).\n *\n * Events (bubbling, on the <table>): `fw:sort` { column, direction, th } and\n * `fw:select` { rows, all }.\n */\nexport type SortDirection = 'ascending' | 'descending';\n\nexport interface SortDetail {\n column: number;\n direction: SortDirection;\n th: HTMLTableCellElement;\n}\n\nexport interface SelectDetail {\n rows: HTMLTableRowElement[];\n all: boolean;\n}\n\nconst SELECTED = 'is-selected';\n\nfunction emit(table: HTMLTableElement, name: string, detail: SortDetail | SelectDetail): void {\n table.dispatchEvent(new CustomEvent(name, { bubbles: true, detail }));\n}\n\n/* ---- sorting ---- */\n\nfunction cellValue(row: HTMLTableRowElement, column: number): string {\n const cell = row.cells[column];\n return cell?.dataset.fwSortValue ?? cell?.textContent?.trim() ?? '';\n}\n\nfunction compare(a: string, b: string): number {\n const na = Number(a);\n const nb = Number(b);\n if (a !== '' && b !== '' && Number.isFinite(na) && Number.isFinite(nb)) return na - nb;\n return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' });\n}\n\nfunction sortHeaders(table: HTMLTableElement): HTMLTableCellElement[] {\n return Array.from(table.tHead?.querySelectorAll<HTMLTableCellElement>('th[data-fw-sort]') ?? []);\n}\n\nfunction nextDirection(th: HTMLTableCellElement): SortDirection {\n return th.getAttribute('aria-sort') === 'ascending' ? 'descending' : 'ascending';\n}\n\nexport function sort(table: HTMLTableElement, column: number, direction: SortDirection): void {\n const tbody = table.tBodies[0];\n if (!tbody) return;\n\n const rows = Array.from(tbody.rows);\n // A colspan row (empty / loading) has no cell at `column` \u2014 keep it last.\n const sortable = rows.filter((r) => r.cells.length > column);\n const rest = rows.filter((r) => r.cells.length <= column);\n const sign = direction === 'ascending' ? 1 : -1;\n sortable.sort((a, b) => sign * compare(cellValue(a, column), cellValue(b, column)));\n [...sortable, ...rest].forEach((r) => tbody.appendChild(r));\n\n let active: HTMLTableCellElement | null = null;\n sortHeaders(table).forEach((th) => {\n const isTarget = th.cellIndex === column;\n th.setAttribute('aria-sort', isTarget ? direction : 'none');\n if (isTarget) active = th;\n });\n if (active) emit(table, 'fw:sort', { column, direction, th: active });\n}\n\n/* ---- selection ---- */\n\nfunction rowInputs(table: HTMLTableElement): HTMLInputElement[] {\n return Array.from(table.querySelectorAll<HTMLInputElement>('tbody input[data-fw-select-row]'));\n}\n\nfunction applyRowState(row: HTMLTableRowElement, on: boolean): void {\n row.classList.toggle(SELECTED, on);\n row.setAttribute('aria-selected', on ? 'true' : 'false');\n}\n\nfunction syncSelectAll(table: HTMLTableElement): void {\n const all = table.querySelector<HTMLInputElement>('[data-fw-select-all]');\n if (!all) return;\n const inputs = rowInputs(table);\n const n = inputs.filter((i) => i.checked).length;\n all.checked = n > 0 && n === inputs.length;\n all.indeterminate = n > 0 && n < inputs.length;\n}\n\nexport function getSelected(table: HTMLTableElement): HTMLTableRowElement[] {\n return rowInputs(table)\n .filter((i) => i.checked)\n .map((i) => i.closest('tr'))\n .filter((r): r is HTMLTableRowElement => r !== null);\n}\n\nexport function setRowSelected(row: HTMLTableRowElement, on: boolean): void {\n const input = row.querySelector<HTMLInputElement>('input[data-fw-select-row]');\n if (input) input.checked = on;\n applyRowState(row, on);\n const table = row.closest('table');\n if (!table) return;\n syncSelectAll(table);\n emit(table, 'fw:select', { rows: getSelected(table), all: false });\n}\n\nexport function selectAll(table: HTMLTableElement, on: boolean): void {\n rowInputs(table).forEach((input) => {\n input.checked = on;\n const row = input.closest('tr');\n if (row) applyRowState(row, on);\n });\n syncSelectAll(table);\n emit(table, 'fw:select', { rows: getSelected(table), all: true });\n}\n\n/* ---- init ---- */\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLTableElement>('table[data-fw-table]').forEach((table) => {\n if (table.dataset.fwBound) return;\n table.dataset.fwBound = '1';\n\n sortHeaders(table).forEach((th) => {\n if (!th.hasAttribute('aria-sort')) th.setAttribute('aria-sort', 'none');\n });\n\n table.addEventListener('click', (e) => {\n const th = (e.target as Element).closest<HTMLTableCellElement>('th[data-fw-sort]');\n if (th && table.contains(th)) sort(table, th.cellIndex, nextDirection(th));\n });\n\n // Enter / Space on the sort button (or on a tabindex'd <th> without one).\n // preventDefault stops the button's native activation so it can't sort twice.\n table.addEventListener('keydown', (e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n const target = e.target as Element;\n if (!target.matches('th[data-fw-sort], th[data-fw-sort] .fw-table-sort')) return;\n const th = target.closest<HTMLTableCellElement>('th[data-fw-sort]');\n if (!th) return;\n e.preventDefault();\n sort(table, th.cellIndex, nextDirection(th));\n });\n\n table.addEventListener('change', (e) => {\n const input = e.target as HTMLInputElement;\n if (input.matches('[data-fw-select-all]')) {\n selectAll(table, input.checked);\n } else if (input.matches('[data-fw-select-row]')) {\n const row = input.closest('tr');\n if (row) setRowSelected(row, input.checked);\n }\n });\n\n // Honour server-rendered checked state.\n rowInputs(table).forEach((input) => {\n const row = input.closest('tr');\n if (row && input.checked) applyRowState(row, true);\n });\n syncSelectAll(table);\n });\n}\n", "/**\n * Menu \u2014 a nestable collapsible menu (nav tree or accordion) built on\n * native <details>/<summary>, enhanced for `.fw-menu[data-fw-menu]`.\n *\n * <nav class=\"fw-menu\" aria-label=\"Docs\" data-fw-menu>\n * <ul class=\"fw-menu-list\">\n * <li class=\"fw-menu-item\"><a class=\"fw-menu-link\" href=\"/\" aria-current=\"page\">Overview</a></li>\n * <li class=\"fw-menu-item\">\n * <details class=\"fw-menu-group\">\n * <summary class=\"fw-menu-summary\">Billing</summary>\n * <ul class=\"fw-menu-list\">\n * <li class=\"fw-menu-item fw-menu-split\">\n * <a class=\"fw-menu-link\" href=\"/billing/plans\">Plans</a>\n * <details class=\"fw-menu-group\">\n * <summary class=\"fw-menu-summary fw-menu-summary-icon\"><span class=\"fw-sr-only\">Toggle Plans</span></summary>\n * <ul class=\"fw-menu-list\">\u2026</ul>\n * </details>\n * </li>\n * </ul>\n * </details>\n * </li>\n * </ul>\n * </nav>\n *\n * The `open` attribute on each `.fw-menu-group` is the state \u2014 server-rendered\n * state is honoured, and the menu still expands/collapses without JS.\n *\n * The enhancer adds:\n * - auto-reveal: every ancestor group of an `[aria-current]` link is opened on\n * init, and a collapsed summary whose branch holds the current page gets `.is-current`\n * - `data-fw-menu-exclusive`: opening a group closes its siblings (accordion)\n * - keyboard: ArrowUp/ArrowDown move between visible rows, ArrowRight opens /\n * enters a group, ArrowLeft closes / goes to the parent, Home/End jump.\n * Tab order is untouched \u2014 every row stays natively tabbable.\n *\n * Events (bubbling, from the <details>): `fw:toggle` { group, open }.\n */\nexport interface ToggleDetail {\n group: HTMLDetailsElement;\n open: boolean;\n}\n\nconst GROUP = '.fw-menu-group';\nconst ROW = '.fw-menu-link, .fw-menu-summary';\nconst CURRENT = 'is-current';\n\nfunction emit(group: HTMLDetailsElement, detail: ToggleDetail): void {\n group.dispatchEvent(new CustomEvent('fw:toggle', { bubbles: true, detail }));\n}\n\n/* ---- open / close ---- */\n\nexport function open(group: HTMLDetailsElement): void {\n group.open = true;\n}\n\nexport function close(group: HTMLDetailsElement): void {\n group.open = false;\n}\n\nexport function toggle(group: HTMLDetailsElement, force?: boolean): void {\n group.open = force ?? !group.open;\n}\n\nexport function expandAll(root: ParentNode): void {\n root.querySelectorAll<HTMLDetailsElement>(GROUP).forEach(open);\n}\n\nexport function collapseAll(root: ParentNode): void {\n root.querySelectorAll<HTMLDetailsElement>(GROUP).forEach(close);\n}\n\n/** Open every ancestor group of `el` so it is visible. */\nexport function reveal(el: Element): void {\n let group = el.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null;\n while (group) {\n open(group);\n group = group.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null;\n }\n}\n\n/* ---- current-page hinting ---- */\n\nfunction syncCurrent(menu: HTMLElement): void {\n menu.querySelectorAll<HTMLDetailsElement>(GROUP).forEach((group) => {\n const summary = group.querySelector<HTMLElement>(':scope > .fw-menu-summary');\n if (!summary) return;\n const holdsCurrent = !group.open && group.querySelector('[aria-current]') !== null;\n summary.classList.toggle(CURRENT, holdsCurrent);\n });\n}\n\n/* ---- keyboard ---- */\n\n/** The group this row summarises (a summary), or null for a link. */\nfunction ownGroup(row: HTMLElement): HTMLDetailsElement | null {\n return row.matches('.fw-menu-summary') ? row.closest<HTMLDetailsElement>(GROUP) : null;\n}\n\n/** The group that contains this row (not the one it summarises). */\nfunction parentGroup(row: HTMLElement): HTMLDetailsElement | null {\n const start = ownGroup(row) ?? row;\n return start.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null;\n}\n\nfunction isVisible(row: HTMLElement): boolean {\n for (let g = parentGroup(row); g; g = g.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null) {\n if (!g.open) return false;\n }\n return true;\n}\n\nfunction visibleRows(menu: HTMLElement): HTMLElement[] {\n return Array.from(menu.querySelectorAll<HTMLElement>(ROW)).filter(isVisible);\n}\n\nfunction focusRow(row: HTMLElement | null | undefined): boolean {\n if (!row) return false;\n row.focus();\n return true;\n}\n\n/** The icon-only summary sitting beside a split-row link, if any. */\nfunction splitToggleFor(link: HTMLElement): HTMLElement | null {\n const item = link.closest<HTMLElement>('.fw-menu-split');\n return item?.querySelector<HTMLElement>(':scope > .fw-menu-group > .fw-menu-summary') ?? null;\n}\n\nfunction onKeydown(menu: HTMLElement, e: KeyboardEvent): void {\n if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;\n const row = e.target instanceof HTMLElement && e.target.matches(ROW) ? e.target : null;\n if (!row || !menu.contains(row)) return;\n\n const rows = visibleRows(menu);\n const i = rows.indexOf(row);\n const group = ownGroup(row);\n let handled = true;\n\n switch (e.key) {\n case 'ArrowDown':\n focusRow(rows[i + 1]);\n break;\n case 'ArrowUp':\n focusRow(rows[i - 1]);\n break;\n case 'Home':\n focusRow(rows[0]);\n break;\n case 'End':\n focusRow(rows[rows.length - 1]);\n break;\n case 'ArrowRight':\n if (group) {\n // An open group's first row is simply the next visible one.\n if (!group.open) open(group);\n else if (group.contains(rows[i + 1] ?? menu)) focusRow(rows[i + 1]);\n } else {\n focusRow(splitToggleFor(row));\n }\n break;\n case 'ArrowLeft':\n if (group?.open) {\n close(group);\n } else {\n const parent = parentGroup(row);\n focusRow(parent?.querySelector<HTMLElement>(':scope > .fw-menu-summary'));\n }\n break;\n default:\n handled = false;\n }\n if (handled) e.preventDefault();\n}\n\n/* ---- init ---- */\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-menu]').forEach((menu) => {\n if (menu.dataset.fwBound) return;\n menu.dataset.fwBound = '1';\n const exclusive = menu.hasAttribute('data-fw-menu-exclusive');\n\n // Native `toggle` doesn't bubble \u2014 catch it in the capture phase.\n menu.addEventListener(\n 'toggle',\n (e) => {\n const group = e.target;\n if (!(group instanceof HTMLDetailsElement) || !group.matches(GROUP)) return;\n if (exclusive && group.open && group.parentElement) {\n Array.from(group.parentElement.children).forEach((sibling) => {\n if (sibling !== group && sibling instanceof HTMLDetailsElement && sibling.matches(GROUP)) close(sibling);\n });\n }\n syncCurrent(menu);\n emit(group, { group, open: group.open });\n },\n true,\n );\n\n menu.addEventListener('keydown', (e) => onKeydown(menu, e));\n\n // Honour server-rendered state: make the current page visible on load.\n menu.querySelectorAll('[aria-current]').forEach(reveal);\n syncCurrent(menu);\n });\n}\n", "/**\n * Popover \u2014 a non-modal floating panel anchored to its trigger.\n *\n * <button type=\"button\" data-fw-popover-trigger=\"settings-pop\">Settings</button>\n *\n * <div class=\"fw-popover\" id=\"settings-pop\">\n * <div class=\"fw-popover-head\">\n * <h3 class=\"fw-popover-title\">Settings</h3>\n * <button type=\"button\" class=\"fw-icon-btn\" data-fw-popover-close aria-label=\"Close\">\n * <span data-fw-icon=\"close\" aria-hidden=\"true\"></span>\n * </button>\n * </div>\n * <div class=\"fw-popover-body\">\u2026</div>\n * </div>\n *\n * Optional trigger attributes: `data-fw-popover-placement` (\"top\" | \"bottom\" |\n * \"left\" | \"right\" \u2014 centered on the trigger's cross-axis midpoint \u2014 or a\n * corner variant \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\"\n * that leans the panel toward that corner instead of centering it, e.g. to\n * steer it clear of something else on the page; default \"bottom\"),\n * `data-fw-popover-offset` (px, default 8).\n *\n * While open, the panel is moved to the end of <body> so its `position: fixed`\n * containing block is always the viewport \u2014 not an ancestor with `transform`,\n * `filter` or `contain` (e.g. a card, or another modal) that would otherwise\n * break the positioning math \u2014 and moved back to its authored location on close.\n *\n * This is a non-modal dialog (`aria-modal=\"false\"`), so per WAI-ARIA APG it\n * does NOT trap Tab \u2014 focus is allowed to move naturally out of the panel.\n * Closing on focus leaving the panel/trigger (`focusout`) does the equivalent\n * job without fighting the surrounding page's tab order.\n *\n * Events (bubbling, from the panel): `fw:open`, `fw:close`.\n */\nimport { computePosition, bindOutsideDismiss, type Placement } from './_position';\n\nconst FOCUSABLE =\n 'a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nexport interface PopoverOptions {\n placement?: Placement;\n offset?: number;\n}\n\nexport interface PopoverInstance {\n open(): void;\n close(): void;\n toggle(): void;\n destroy(): void;\n}\n\nexport function popover(trigger: HTMLElement, panel: HTMLElement, opts: PopoverOptions = {}): PopoverInstance {\n const placement = opts.placement ?? 'bottom';\n const offset = opts.offset ?? 8;\n\n trigger.setAttribute('aria-haspopup', 'dialog');\n trigger.setAttribute('aria-controls', panel.id);\n trigger.setAttribute('aria-expanded', 'false');\n panel.setAttribute('role', 'dialog');\n panel.setAttribute('aria-modal', 'false');\n panel.classList.add('fw-popover');\n\n const originalParent = panel.parentNode as ParentNode;\n const originalNextSibling = panel.nextSibling;\n\n let isOpen = false;\n let unbindOutside: (() => void) | null = null;\n let raf = 0;\n\n function reposition(): void {\n const r = computePosition(trigger, panel, { placement, offset });\n panel.style.top = `${r.top}px`;\n panel.style.left = `${r.left}px`;\n panel.setAttribute('data-placement', r.placement);\n }\n\n function scheduleReposition(): void {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(reposition);\n }\n\n function onKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.stopPropagation();\n close();\n }\n }\n\n function onFocusOut(e: FocusEvent): void {\n const next = e.relatedTarget as Node | null;\n if (next && (panel.contains(next) || trigger.contains(next))) return;\n // relatedTarget is null for some mouse-driven blurs \u2014 re-check on the\n // next tick against document.activeElement instead of trusting it.\n setTimeout(() => {\n if (!isOpen) return;\n const active = document.activeElement;\n // A click on non-focusable panel content (plain text, a heading \u2014 not\n // the close button or a link) blurs the previously focused element\n // without moving focus anywhere real: activeElement falls back to\n // <body>. That's not \"focus left the popover\", so it isn't a dismiss\n // signal \u2014 a genuine click outside the popover already closes it via\n // bindOutsideDismiss below.\n if (active === document.body || active === null) return;\n if (!(panel.contains(active) || trigger.contains(active))) close();\n }, 0);\n }\n\n function open(): void {\n if (isOpen) return;\n isOpen = true;\n if (panel.parentNode !== document.body) document.body.appendChild(panel);\n reposition();\n panel.classList.add('is-open');\n trigger.setAttribute('aria-expanded', 'true');\n\n const first = panel.querySelector<HTMLElement>(FOCUSABLE);\n if (first) {\n first.focus({ preventScroll: true });\n } else {\n if (!panel.hasAttribute('tabindex')) panel.setAttribute('tabindex', '-1');\n panel.focus({ preventScroll: true });\n }\n\n unbindOutside = bindOutsideDismiss([trigger, panel], close);\n window.addEventListener('scroll', scheduleReposition, true);\n window.addEventListener('resize', scheduleReposition);\n panel.addEventListener('keydown', onKeydown);\n panel.addEventListener('focusout', onFocusOut);\n panel.dispatchEvent(new CustomEvent('fw:open', { bubbles: true }));\n }\n\n function close(): void {\n if (!isOpen) return;\n isOpen = false;\n panel.classList.remove('is-open');\n trigger.setAttribute('aria-expanded', 'false');\n\n unbindOutside?.();\n unbindOutside = null;\n window.removeEventListener('scroll', scheduleReposition, true);\n window.removeEventListener('resize', scheduleReposition);\n panel.removeEventListener('keydown', onKeydown);\n panel.removeEventListener('focusout', onFocusOut);\n cancelAnimationFrame(raf);\n\n const stillValid = originalNextSibling === null || originalNextSibling.parentNode === originalParent;\n if (stillValid) originalParent.insertBefore(panel, originalNextSibling);\n else originalParent.appendChild(panel);\n\n panel.dispatchEvent(new CustomEvent('fw:close', { bubbles: true }));\n trigger.focus({ preventScroll: true });\n }\n\n function toggle(): void {\n (isOpen ? close : open)();\n }\n\n const onTriggerClick = () => toggle();\n const closeButtons = Array.from(panel.querySelectorAll<HTMLElement>('[data-fw-popover-close]'));\n const onCloseClick = () => close();\n\n trigger.addEventListener('click', onTriggerClick);\n closeButtons.forEach((btn) => btn.addEventListener('click', onCloseClick));\n\n return {\n open,\n close,\n toggle,\n destroy() {\n if (isOpen) close();\n trigger.removeEventListener('click', onTriggerClick);\n closeButtons.forEach((btn) => btn.removeEventListener('click', onCloseClick));\n delete trigger.dataset.fwBound;\n },\n };\n}\n\n/** Wire every `[data-fw-popover-trigger]` under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-popover-trigger]').forEach((trigger) => {\n if (trigger.dataset.fwBound) return;\n const id = trigger.dataset.fwPopoverTrigger ?? '';\n const panel = document.getElementById(id);\n if (!panel) {\n console.warn(`fernwell: popover trigger references missing panel #${id}`);\n return;\n }\n trigger.dataset.fwBound = '1';\n popover(trigger, panel, {\n placement: (trigger.dataset.fwPopoverPlacement as Placement) || undefined,\n offset: trigger.dataset.fwPopoverOffset ? Number(trigger.dataset.fwPopoverOffset) : undefined,\n });\n });\n}\n", "/**\n * Internal positioning helpers shared by popover.ts and tooltip.ts. Not part\n * of the public API \u2014 not re-exported from index.ts.\n *\n * Both callers use `position: fixed`, so all math here is viewport-relative\n * (matching `getBoundingClientRect()`) rather than document-relative.\n */\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * `top` / `bottom` / `left` / `right` center the floating element on the\n * anchor's cross-axis midpoint. `top-left` / `top-right` / `bottom-left` /\n * `bottom-right` keep the anchor above/below but shift the floating element\n * so it leans toward that corner instead of centering \u2014 useful to steer a\n * panel away from something else on the page (another fixed control, a\n * viewport edge) without losing the \"above/below the trigger\" placement.\n *\n * \"Lean right\" means the floating element's LEFT edge lines up with the\n * anchor's left edge, so the (usually wider) box extends further right of\n * the anchor than a centered box would; \"lean left\" mirrors that off the\n * anchor's right edge.\n */\nexport type Placement = Side | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\n/** Which edge of the anchor the floating element's near edge lines up with,\n * on the cross axis \u2014 'start' leans the box toward increasing x/y (right/\n * down), 'end' leans it toward decreasing x/y (left/up). */\ntype Align = 'center' | 'start' | 'end';\n\nexport interface PositionOptions {\n /** Preferred placement. */\n placement?: Placement;\n /** Gap between anchor and floating element, px. */\n offset?: number;\n /** Minimum distance from the viewport edge, px. */\n padding?: number;\n}\n\nexport interface PositionResult {\n /** Final placement, after a possible flip. */\n placement: Placement;\n top: number;\n left: number;\n /**\n * Distance, in px, from the floating element's near edge (left, for a\n * top/bottom placement; top, for a left/right placement) to the anchor's\n * center \u2014 for positioning an optional arrow so it keeps pointing at the\n * anchor even after the cross-axis got clamped to stay in the viewport.\n * Already inset from the floating element's own edges so the arrow never\n * overhangs a rounded corner.\n */\n arrowOffset: number;\n}\n\nconst OPPOSITE_SIDE: Record<Side, Side> = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };\nconst ARROW_INSET = 10; // px \u2014 keeps the arrow clear of the floating box's rounded corners\n\nfunction parsePlacement(p: Placement): { side: Side; align: Align } {\n switch (p) {\n // \"-right\" leans the box right \u2192 its left edge pins to the anchor's\n // left edge (`start`); \"-left\" leans it left \u2192 right edges pin (`end`).\n case 'top-left':\n return { side: 'top', align: 'end' };\n case 'top-right':\n return { side: 'top', align: 'start' };\n case 'bottom-left':\n return { side: 'bottom', align: 'end' };\n case 'bottom-right':\n return { side: 'bottom', align: 'start' };\n default:\n return { side: p, align: 'center' };\n }\n}\n\nconst ALIGN_SUFFIX: Record<Exclude<Align, 'center'>, 'left' | 'right'> = { start: 'right', end: 'left' };\n\nfunction toPlacement(side: Side, align: Align): Placement {\n return align === 'center' ? side : (`${side}-${ALIGN_SUFFIX[align]}` as Placement);\n}\n\nfunction mainAxisSpace(side: Side, anchor: DOMRect, vw: number, vh: number): number {\n switch (side) {\n case 'top':\n return anchor.top;\n case 'bottom':\n return vh - anchor.bottom;\n case 'left':\n return anchor.left;\n case 'right':\n return vw - anchor.right;\n }\n}\n\nfunction mainAxisCoord(side: Side, anchor: DOMRect, floating: DOMRect, offset: number): number {\n switch (side) {\n case 'top':\n return anchor.top - offset - floating.height;\n case 'bottom':\n return anchor.bottom + offset;\n case 'left':\n return anchor.left - offset - floating.width;\n case 'right':\n return anchor.right + offset;\n }\n}\n\n/** Cross-axis coordinate (the floating element's left, for a horizontal\n * anchor span; or top, for a vertical one) implementing `align`. */\nfunction crossAxisCoord(align: Align, anchorStart: number, anchorSize: number, floatingSize: number): number {\n switch (align) {\n case 'start':\n return anchorStart;\n case 'end':\n return anchorStart + anchorSize - floatingSize;\n case 'center':\n return anchorStart + anchorSize / 2 - floatingSize / 2;\n }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max > min ? max : min);\n}\n\n/**\n * Positions `floating` relative to `anchor`: flips to the opposite side when\n * the preferred side doesn't fit and the opposite side has more room (a\n * 2-entry fallback, not a 4-way rotation \u2014 both callers are single-edge\n * anchored, unlike a corner-anchored menu), and clamps the cross-axis into\n * the viewport (\"shift\") rather than flipping it.\n *\n * The cross-axis is centered on the anchor by default (`align: 'center'`,\n * implied by a bare `top`/`bottom`/`left`/`right` placement) \u2014 the corner\n * placements (`top-left`, etc.) opt into edge-alignment instead. Centering\n * is what makes an arrow drawn at the floating element's own midpoint line\n * up with the anchor; `arrowOffset` carries the exact anchor-relative\n * position so the arrow still lines up even when a corner placement or a\n * viewport clamp shifts the box off-center.\n */\nexport function computePosition(anchor: HTMLElement, floating: HTMLElement, opts: PositionOptions = {}): PositionResult {\n const preferred = opts.placement ?? 'bottom';\n const offset = opts.offset ?? 8;\n const padding = opts.padding ?? 8;\n\n const a = anchor.getBoundingClientRect();\n const f = floating.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const { side: preferredSide, align } = parsePlacement(preferred);\n const oppositeSide = OPPOSITE_SIDE[preferredSide];\n const needed = preferredSide === 'top' || preferredSide === 'bottom' ? f.height : f.width;\n\n const side =\n mainAxisSpace(preferredSide, a, vw, vh) - offset < needed &&\n mainAxisSpace(oppositeSide, a, vw, vh) - offset > mainAxisSpace(preferredSide, a, vw, vh) - offset\n ? oppositeSide\n : preferredSide;\n\n let top: number;\n let left: number;\n let arrowOffset: number;\n\n if (side === 'top' || side === 'bottom') {\n top = mainAxisCoord(side, a, f, offset);\n left = clamp(crossAxisCoord(align, a.left, a.width, f.width), padding, vw - f.width - padding);\n arrowOffset = clamp(a.left + a.width / 2 - left, ARROW_INSET, Math.max(f.width - ARROW_INSET, ARROW_INSET));\n } else {\n left = mainAxisCoord(side, a, f, offset);\n top = clamp(crossAxisCoord('center', a.top, a.height, f.height), padding, vh - f.height - padding);\n arrowOffset = clamp(a.top + a.height / 2 - top, ARROW_INSET, Math.max(f.height - ARROW_INSET, ARROW_INSET));\n }\n\n return { placement: toPlacement(side, align), top, left, arrowOffset };\n}\n\n/**\n * Fires `onDismiss` only when a click lands outside every element in\n * `anchors` \u2014 generalizes modal.ts's `bindOutsideClickToClose` (which checks\n * a single backdrop) to an arbitrary set of \"not outside\" elements (e.g. a\n * popover's trigger AND its panel).\n *\n * Guards the same false positive: a browser's `click` fires on the nearest\n * common ancestor of mousedown and mouseup, so a text-selection drag that\n * starts inside an anchor and ends outside it would otherwise look like an\n * outside click. Close only when BOTH mousedown and click landed outside.\n */\nexport function bindOutsideDismiss(anchors: HTMLElement[], onDismiss: () => void): () => void {\n const isOutside = (target: EventTarget | null): boolean => !anchors.some((el) => el.contains(target as Node));\n let downOutside = false;\n\n const onMousedown = (e: MouseEvent) => {\n downOutside = isOutside(e.target);\n };\n const onClick = (e: MouseEvent) => {\n if (downOutside && isOutside(e.target)) onDismiss();\n };\n\n document.addEventListener('mousedown', onMousedown, true);\n document.addEventListener('click', onClick, true);\n\n return () => {\n document.removeEventListener('mousedown', onMousedown, true);\n document.removeEventListener('click', onClick, true);\n };\n}\n", "/**\n * Tooltip \u2014 a short hover/focus annotation, anchored to its trigger.\n *\n * <button type=\"button\" class=\"fw-icon-btn\" title=\"Copy to clipboard\" data-fw-tooltip>\n * <span data-fw-icon=\"copy\" aria-hidden=\"true\"></span>\n * </button>\n *\n * The `title` attribute is the content source \u2014 it's moved into\n * `dataset.fwTooltipText` and removed on init (same detach-and-mirror trick\n * combobox.ts uses for the `list` attribute), which gives a real no-JS\n * fallback (the native OS tooltip) and stops the two tooltips firing at once.\n *\n * Optional trigger attributes: `data-fw-tooltip-placement` (default \"top\";\n * also accepts \"bottom\" | \"left\" | \"right\", or a corner variant \u2014\n * \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\" \u2014 that leans the\n * bubble toward that corner instead of centering it, for triggers near a\n * layout edge), `data-fw-tooltip-offset` (px, default 6),\n * `data-fw-tooltip-delay` (ms, default 400).\n *\n * The bubble is centered on the trigger by default so the arrow (drawn at\n * `computePosition`'s returned `arrowOffset`) always points at the trigger's\n * midpoint \u2014 including when a corner placement or a viewport-edge clamp\n * shifts the bubble off-center.\n *\n * Only one tooltip bubble exists for the whole page (a lazily-created\n * singleton, same pattern as toast.ts) \u2014 a second trigger's hover pre-empts\n * the first. Acceptable for a short annotation; not meant for concurrent\n * multi-tooltip UIs.\n *\n * WCAG 2.1 SC 1.4.13 requires hover/focus-revealed content to be dismissible,\n * *hoverable* (the pointer can move onto it without it disappearing) and\n * persistent. `pointer-events: none` on the bubble would fail \"hoverable\"\n * outright \u2014 the bubble couldn't receive a hover at all \u2014 so this\n * deliberately does NOT set it while open. Instead the bubble gets its own\n * mouseenter/mouseleave, and a short cancelable hide-grace timer covers the\n * gap while the pointer travels from trigger to bubble.\n */\nimport { computePosition, type Placement } from './_position';\n\nconst SHOW_DELAY_DEFAULT = 400;\nconst SKIP_DELAY_WINDOW = 300; // ms \u2014 adjacent-trigger instant-reopen window\nconst HIDE_GRACE = 100; // ms \u2014 covers the trigger\u2192bubble pointer transit gap\n\nexport interface TooltipOptions {\n placement?: Placement;\n offset?: number;\n delay?: number;\n}\n\nexport interface TooltipInstance {\n show(): void;\n hide(): void;\n destroy(): void;\n}\n\ninterface ResolvedOptions {\n placement: Placement;\n offset: number;\n delay: number;\n}\n\nconst optsByTrigger = new WeakMap<HTMLElement, ResolvedOptions>();\n\nlet bubble: HTMLElement | null = null;\nlet activeTrigger: HTMLElement | null = null;\nlet showTimer = 0;\nlet hideTimer = 0;\nlet repositionRaf = 0;\nlet lastHiddenAt = 0;\n\nfunction ensureBubble(): HTMLElement {\n if (bubble && bubble.isConnected) return bubble;\n const el = document.createElement('div');\n el.className = 'fw-tooltip';\n el.id = 'fw-tooltip';\n el.setAttribute('role', 'tooltip');\n document.body.appendChild(el);\n el.addEventListener('mouseenter', cancelHide);\n el.addEventListener('mouseleave', () => requestHide());\n bubble = el;\n return el;\n}\n\nfunction cancelHide(): void {\n clearTimeout(hideTimer);\n}\n\nfunction reposition(): void {\n if (!activeTrigger || !bubble) return;\n const opts = optsByTrigger.get(activeTrigger);\n if (!opts) return;\n const r = computePosition(activeTrigger, bubble, { placement: opts.placement, offset: opts.offset });\n bubble.style.top = `${r.top}px`;\n bubble.style.left = `${r.left}px`;\n bubble.style.setProperty('--fw-tooltip-arrow-pos', `${r.arrowOffset}px`);\n bubble.setAttribute('data-placement', r.placement);\n}\n\nfunction scheduleReposition(): void {\n cancelAnimationFrame(repositionRaf);\n repositionRaf = requestAnimationFrame(reposition);\n}\n\nfunction showNow(trigger: HTMLElement): void {\n clearTimeout(showTimer);\n cancelHide();\n const opts = optsByTrigger.get(trigger);\n if (!opts) return;\n activeTrigger = trigger;\n const el = ensureBubble();\n el.textContent = trigger.dataset.fwTooltipText ?? '';\n reposition();\n el.classList.add('is-open');\n window.addEventListener('scroll', scheduleReposition, true);\n window.addEventListener('resize', scheduleReposition);\n}\n\nfunction hideNow(): void {\n clearTimeout(showTimer);\n clearTimeout(hideTimer);\n if (bubble) bubble.classList.remove('is-open');\n window.removeEventListener('scroll', scheduleReposition, true);\n window.removeEventListener('resize', scheduleReposition);\n cancelAnimationFrame(repositionRaf);\n if (activeTrigger) lastHiddenAt = performance.now();\n activeTrigger = null;\n}\n\nfunction requestShow(trigger: HTMLElement, instant: boolean): void {\n clearTimeout(hideTimer);\n clearTimeout(showTimer);\n const opts = optsByTrigger.get(trigger);\n if (!opts) return;\n if (instant || performance.now() - lastHiddenAt < SKIP_DELAY_WINDOW) {\n showNow(trigger);\n } else {\n showTimer = window.setTimeout(() => showNow(trigger), opts.delay);\n }\n}\n\nfunction requestHide(): void {\n clearTimeout(showTimer);\n clearTimeout(hideTimer);\n hideTimer = window.setTimeout(hideNow, HIDE_GRACE);\n}\n\nexport function tooltip(trigger: HTMLElement, opts: TooltipOptions = {}): TooltipInstance {\n const resolved: ResolvedOptions = {\n placement: opts.placement ?? 'top',\n offset: opts.offset ?? 6,\n delay: opts.delay ?? SHOW_DELAY_DEFAULT,\n };\n optsByTrigger.set(trigger, resolved);\n\n const title = trigger.getAttribute('title');\n if (title !== null) {\n trigger.dataset.fwTooltipText = title;\n trigger.removeAttribute('title');\n }\n trigger.setAttribute('aria-describedby', 'fw-tooltip');\n\n const onMouseenter = () => requestShow(trigger, false);\n const onMouseleave = () => requestHide();\n const onFocus = () => requestShow(trigger, true);\n const onBlur = () => {\n if (activeTrigger === trigger) hideNow();\n };\n const onKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && activeTrigger === trigger) hideNow();\n };\n\n trigger.addEventListener('mouseenter', onMouseenter);\n trigger.addEventListener('mouseleave', onMouseleave);\n trigger.addEventListener('focus', onFocus);\n trigger.addEventListener('blur', onBlur);\n trigger.addEventListener('keydown', onKeydown);\n\n return {\n show: () => requestShow(trigger, true),\n hide: () => {\n if (activeTrigger === trigger) hideNow();\n },\n destroy() {\n if (activeTrigger === trigger) hideNow();\n trigger.removeEventListener('mouseenter', onMouseenter);\n trigger.removeEventListener('mouseleave', onMouseleave);\n trigger.removeEventListener('focus', onFocus);\n trigger.removeEventListener('blur', onBlur);\n trigger.removeEventListener('keydown', onKeydown);\n trigger.removeAttribute('aria-describedby');\n if (trigger.dataset.fwTooltipText !== undefined) {\n trigger.setAttribute('title', trigger.dataset.fwTooltipText);\n delete trigger.dataset.fwTooltipText;\n }\n optsByTrigger.delete(trigger);\n delete trigger.dataset.fwBound;\n },\n };\n}\n\n/** Wire every `[data-fw-tooltip]` under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-tooltip]').forEach((trigger) => {\n if (trigger.dataset.fwBound) return;\n trigger.dataset.fwBound = '1';\n tooltip(trigger, {\n placement: (trigger.dataset.fwTooltipPlacement as Placement) || undefined,\n offset: trigger.dataset.fwTooltipOffset ? Number(trigger.dataset.fwTooltipOffset) : undefined,\n delay: trigger.dataset.fwTooltipDelay ? Number(trigger.dataset.fwTooltipDelay) : undefined,\n });\n });\n}\n", "/**\n * Tabs \u2014 a single-selection tablist that switches between panels.\n *\n * <div class=\"fw-tablist\" role=\"tablist\" aria-label=\"Account settings\" data-fw-tabs>\n * <button type=\"button\" class=\"fw-tab\" id=\"tab-profile\" role=\"tab\" aria-selected=\"true\" aria-controls=\"panel-profile\">Profile</button>\n * <button type=\"button\" class=\"fw-tab\" id=\"tab-billing\" role=\"tab\" aria-selected=\"false\" aria-controls=\"panel-billing\">Billing</button>\n * </div>\n * <div class=\"fw-tabpanel\" id=\"panel-profile\" role=\"tabpanel\" aria-labelledby=\"tab-profile\" tabindex=\"0\">\u2026</div>\n * <div class=\"fw-tabpanel\" id=\"panel-billing\" role=\"tabpanel\" aria-labelledby=\"tab-billing\" tabindex=\"0\" hidden>\u2026</div>\n *\n * Author `aria-selected=\"true\"` on the tab that should start selected (the\n * rest `\"false\"`); `init()` derives roving `tabIndex` (0 on the selected tab,\n * -1 on the rest) and each panel's `hidden` from that. Falls back to the\n * first non-disabled tab if none is marked selected. A tab may carry\n * `aria-disabled=\"true\"` to make it non-interactive \u2014 it is skipped by\n * click, arrow-key, and Home/End navigation.\n *\n * `data-fw-tabs-activation=\"manual\"` on the tablist switches from the\n * default \"automatic\" activation (arrow keys move focus AND select) to\n * \"manual\" (arrow keys only move focus; Space/Enter selects the focused\n * tab) \u2014 use manual when selecting a tab is expensive (e.g. triggers a\n * fetch).\n *\n * `aria-orientation=\"vertical\"` on the tablist swaps the primary arrow keys\n * from Left/Right to Up/Down, per WAI-ARIA APG. Left/Right invert under RTL.\n *\n * Events (bubbling, from the tablist): `fw:tabs-change` { tab, panel }.\n */\nexport type TabsActivation = 'automatic' | 'manual';\n\nexport interface TabsOptions {\n activation?: TabsActivation;\n}\n\nexport interface TabsInstance {\n activate(tab: HTMLElement, focus?: boolean): void;\n destroy(): void;\n}\n\nexport interface TabsChangeDetail {\n tab: HTMLElement;\n panel: HTMLElement;\n}\n\nfunction emit(tablist: HTMLElement, detail: TabsChangeDetail): void {\n tablist.dispatchEvent(new CustomEvent('fw:tabs-change', { bubbles: true, detail }));\n}\n\nfunction isDisabled(tab: HTMLElement): boolean {\n return tab.getAttribute('aria-disabled') === 'true';\n}\n\nfunction panelFor(tab: HTMLElement): HTMLElement | null {\n const id = tab.getAttribute('aria-controls');\n return id ? document.getElementById(id) : null;\n}\n\nfunction closestTab(target: EventTarget | null): HTMLElement | null {\n return target instanceof Element ? target.closest<HTMLElement>('[role=\"tab\"]') : null;\n}\n\n/** The next non-disabled tab `step` positions from `from`, wrapping around. Undefined if every tab is disabled. */\nfunction nextEnabled(list: HTMLElement[], from: number, step: 1 | -1): HTMLElement | undefined {\n for (let n = 1; n <= list.length; n++) {\n const idx = (((from + step * n) % list.length) + list.length) % list.length;\n if (!isDisabled(list[idx])) return list[idx];\n }\n return undefined;\n}\n\nfunction firstEnabled(list: HTMLElement[]): HTMLElement | undefined {\n return list.find((t) => !isDisabled(t));\n}\n\nfunction lastEnabled(list: HTMLElement[]): HTMLElement | undefined {\n for (let i = list.length - 1; i >= 0; i--) {\n if (!isDisabled(list[i])) return list[i];\n }\n return undefined;\n}\n\nexport function tabs(tablist: HTMLElement, opts: TabsOptions = {}): TabsInstance {\n const activation = opts.activation ?? 'automatic';\n\n function allTabs(): HTMLElement[] {\n return Array.from(tablist.querySelectorAll<HTMLElement>('[role=\"tab\"]'));\n }\n\n function activate(tab: HTMLElement, focus = false): void {\n if (isDisabled(tab)) return;\n allTabs().forEach((t) => {\n const selected = t === tab;\n t.setAttribute('aria-selected', String(selected));\n t.tabIndex = selected ? 0 : -1;\n const panel = panelFor(t);\n if (panel) panel.hidden = !selected;\n });\n if (focus) tab.focus();\n const panel = panelFor(tab);\n if (panel) emit(tablist, { tab, panel });\n }\n\n /** Manual-activation arrow move: roving tabindex follows focus, selection is untouched. */\n function focusOnly(tab: HTMLElement): void {\n allTabs().forEach((t) => {\n t.tabIndex = t === tab ? 0 : -1;\n });\n tab.focus();\n }\n\n function syncFromSelected(): void {\n const list = allTabs();\n const selected = list.find((t) => t.getAttribute('aria-selected') === 'true') ?? firstEnabled(list);\n list.forEach((t) => {\n const isSelected = t === selected;\n t.setAttribute('aria-selected', String(isSelected));\n t.tabIndex = isSelected ? 0 : -1;\n const panel = panelFor(t);\n if (panel) panel.hidden = !isSelected;\n });\n }\n\n function onClick(e: MouseEvent): void {\n const tab = closestTab(e.target);\n if (tab && tablist.contains(tab)) activate(tab, false);\n }\n\n function onKeydown(e: KeyboardEvent): void {\n const tab = closestTab(e.target);\n if (!tab) return;\n const list = allTabs();\n const i = list.indexOf(tab);\n if (i === -1) return;\n\n if (e.key === ' ' || e.key === 'Enter') {\n if (activation === 'manual') {\n e.preventDefault();\n activate(tab, false);\n }\n return;\n }\n\n const vertical = tablist.getAttribute('aria-orientation') === 'vertical';\n const rtl = getComputedStyle(tablist).direction === 'rtl';\n const nextKey = vertical ? 'ArrowDown' : rtl ? 'ArrowLeft' : 'ArrowRight';\n const prevKey = vertical ? 'ArrowUp' : rtl ? 'ArrowRight' : 'ArrowLeft';\n\n let dest: HTMLElement | undefined;\n if (e.key === nextKey) dest = nextEnabled(list, i, 1);\n else if (e.key === prevKey) dest = nextEnabled(list, i, -1);\n else if (e.key === 'Home') dest = firstEnabled(list);\n else if (e.key === 'End') dest = lastEnabled(list);\n else return;\n\n if (!dest) return;\n e.preventDefault();\n if (activation === 'manual') focusOnly(dest);\n else activate(dest, true);\n }\n\n tablist.addEventListener('click', onClick);\n tablist.addEventListener('keydown', onKeydown);\n syncFromSelected();\n\n return {\n activate,\n destroy() {\n tablist.removeEventListener('click', onClick);\n tablist.removeEventListener('keydown', onKeydown);\n delete tablist.dataset.fwBound;\n },\n };\n}\n\n/** Wire every `[role=\"tablist\"][data-fw-tabs]` under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[role=\"tablist\"][data-fw-tabs]').forEach((tablist) => {\n if (tablist.dataset.fwBound) return;\n tablist.dataset.fwBound = '1';\n const activation: TabsActivation = tablist.dataset.fwTabsActivation === 'manual' ? 'manual' : 'automatic';\n tabs(tablist, { activation });\n });\n}\n", "/**\n * Fernwell \u2014 vanilla JS enhancers for the Fernwell design system.\n *\n * ESM / CJS: import { init, theme, toast } from 'fernwell'; init();\n * <script>: <script src=\"https://unpkg.com/fernwell/dist/fernwell.iife.js\"></script>\n * \u2192 window.Fernwell, auto-initialised on DOMContentLoaded\n * (add data-fw-no-init to the <script> tag to opt out).\n */\nimport * as theme from './theme';\nimport * as combobox from './combobox';\nimport * as modal from './modal';\nimport * as nav from './nav';\nimport * as loading from './loading';\nimport * as toast from './toast';\nimport * as table from './table';\nimport * as menu from './menu';\nimport * as icon from './icon';\nimport * as popover from './popover';\nimport * as tooltip from './tooltip';\nimport * as tabs from './tabs';\n\nexport { theme, combobox, modal, nav, loading, toast, table, menu, icon, popover, tooltip, tabs };\nexport type { Theme, TokenOverrides, TokenThemeOverrides } from './theme';\nexport type { ComboboxOptions, ComboboxInstance } from './combobox';\nexport type { ToastVariant, ToastOptions } from './toast';\nexport type { SortDirection, SortDetail, SelectDetail } from './table';\nexport type { ToggleDetail } from './menu';\nexport type { IconName } from './icon';\nexport type { PopoverOptions, PopoverInstance } from './popover';\nexport type { TooltipOptions, TooltipInstance } from './tooltip';\nexport type { TabsOptions, TabsInstance, TabsActivation, TabsChangeDetail } from './tabs';\n\nexport const version = \"0.4.0\";\n\n/**\n * Wire every `data-fw-*` hook under `root`. Safe to call more than once \u2014\n * already-bound elements are skipped \u2014 so call it again after injecting\n * markup (e.g. after an HTMX / Turbo swap).\n */\nexport function init(root: ParentNode = document): void {\n theme.init(root);\n combobox.init(root);\n modal.init(root);\n nav.init(root);\n loading.init(root);\n table.init(root);\n menu.init(root);\n icon.init(root);\n popover.init(root);\n tooltip.init(root);\n tabs.init(root);\n}\n\nconst Fernwell = {\n version,\n init,\n theme,\n combobox,\n modal,\n nav,\n loading,\n toast,\n table,\n menu,\n icon,\n popover,\n tooltip,\n tabs,\n};\nexport default Fernwell;\n"],
5
- "mappings": "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",
6
- "names": ["theme_exports", "__export", "get", "getToken", "init", "resetTokens", "set", "setTokens", "toggle", "icon_exports", "__export", "init", "render", "icons", "name", "inner", "root", "el", "_a", "markup", "STORAGE_KEY", "EVENT", "TOKEN_PREFIX", "TOKEN_STYLE_ATTR", "INIT_ATTR", "store", "get", "_a", "attr", "set", "theme", "persist", "btn", "syncToggle", "toggle", "next", "iconName", "label", "icon", "render", "afterPaint", "cb", "raf", "fn", "init", "root", "_b", "_c", "_d", "stored", "current", "html", "e", "tokenScopes", "normalizeTokenName", "name", "isThemeSplit", "tokens", "v", "declBlock", "value", "tokenStyleEl", "create", "existing", "el", "renderTokens", "rules", "light", "dark", "scope", "darkSelector", "setTokens", "opts", "entry", "resetTokens", "getToken", "combobox_exports", "__export", "combobox", "init", "uid", "escapeHtml", "s", "c", "input", "opts", "_a", "_b", "_c", "_d", "filter", "o", "q", "emptyText", "options", "readDatalist", "current", "activeIndex", "selecting", "listId", "wrap", "wrapInput", "list", "id", "render", "matches", "opt", "i", "idx", "label", "open", "close", "highlight", "items", "el", "select", "value", "onInput", "onFocus", "onKeydown", "e", "onListMousedown", "onDocClick", "next", "dl", "root", "modal_exports", "__export", "bindOutsideClickToClose", "close", "init", "open", "toggle", "OPEN", "LOCK", "openStack", "openers", "FOCUSABLE", "resolve", "target", "backdropFor", "el", "explicit", "prev", "opener", "_a", "first", "_b", "_c", "i", "backdrop", "onClose", "downOnBackdrop", "e", "keyBound", "root", "btn", "id", "overlay", "drawer", "nav_exports", "__export", "close", "init", "open", "OPEN", "toggle", "panel", "panelFor", "id", "root", "_a", "_b", "container", "e", "loading_exports", "__export", "init", "resetAll", "resetButtonLoading", "setButtonLoading", "LOADING", "btn", "loadingText", "_a", "_b", "label", "root", "pageshowBound", "form", "e", "toast_exports", "__export", "hide", "show", "el", "timer", "ensure", "message", "variant", "duration", "node", "table_exports", "__export", "getSelected", "init", "selectAll", "setRowSelected", "sort", "SELECTED", "emit", "table", "name", "detail", "cellValue", "row", "column", "_a", "_b", "_c", "cell", "compare", "a", "b", "na", "nb", "sortHeaders", "nextDirection", "th", "direction", "tbody", "rows", "sortable", "r", "rest", "sign", "active", "isTarget", "rowInputs", "applyRowState", "on", "syncSelectAll", "all", "inputs", "n", "i", "input", "root", "e", "target", "menu_exports", "__export", "close", "collapseAll", "expandAll", "init", "open", "reveal", "toggle", "GROUP", "ROW", "CURRENT", "emit", "group", "detail", "force", "root", "el", "_a", "_b", "_c", "_d", "syncCurrent", "menu", "summary", "holdsCurrent", "ownGroup", "row", "parentGroup", "isVisible", "g", "visibleRows", "focusRow", "splitToggleFor", "link", "item", "onKeydown", "e", "rows", "i", "handled", "parent", "exclusive", "sibling", "popover_exports", "__export", "init", "popover", "OPPOSITE_SIDE", "ARROW_INSET", "parsePlacement", "p", "ALIGN_SUFFIX", "toPlacement", "side", "align", "mainAxisSpace", "anchor", "vw", "vh", "mainAxisCoord", "floating", "offset", "crossAxisCoord", "anchorStart", "anchorSize", "floatingSize", "clamp", "value", "min", "max", "computePosition", "opts", "_a", "_b", "_c", "preferred", "padding", "a", "f", "preferredSide", "oppositeSide", "needed", "top", "left", "arrowOffset", "bindOutsideDismiss", "anchors", "onDismiss", "isOutside", "target", "el", "downOutside", "onMousedown", "e", "onClick", "FOCUSABLE", "popover", "trigger", "panel", "opts", "_a", "_b", "placement", "offset", "originalParent", "originalNextSibling", "isOpen", "unbindOutside", "raf", "reposition", "r", "computePosition", "scheduleReposition", "onKeydown", "e", "close", "onFocusOut", "next", "active", "open", "first", "bindOutsideDismiss", "toggle", "onTriggerClick", "closeButtons", "onCloseClick", "btn", "init", "root", "id", "tooltip_exports", "__export", "init", "tooltip", "SHOW_DELAY_DEFAULT", "SKIP_DELAY_WINDOW", "HIDE_GRACE", "optsByTrigger", "bubble", "activeTrigger", "showTimer", "hideTimer", "repositionRaf", "lastHiddenAt", "ensureBubble", "el", "cancelHide", "requestHide", "reposition", "opts", "r", "computePosition", "scheduleReposition", "showNow", "trigger", "_a", "hideNow", "requestShow", "instant", "tooltip", "_b", "_c", "resolved", "title", "onMouseenter", "onMouseleave", "onFocus", "onBlur", "onKeydown", "e", "init", "root", "tabs_exports", "__export", "init", "tabs", "emit", "tablist", "detail", "isDisabled", "tab", "panelFor", "id", "closestTab", "target", "nextEnabled", "list", "from", "step", "n", "idx", "firstEnabled", "lastEnabled", "i", "opts", "_a", "activation", "allTabs", "activate", "focus", "t", "selected", "panel", "focusOnly", "syncFromSelected", "isSelected", "onClick", "e", "onKeydown", "vertical", "rtl", "nextKey", "prevKey", "dest", "root", "version", "init", "root", "Fernwell", "theme_exports", "combobox_exports", "modal_exports", "nav_exports", "loading_exports", "toast_exports", "table_exports", "menu_exports", "icon_exports", "popover_exports", "tooltip_exports", "tabs_exports", "index_default"]
3
+ "sources": ["../src/js/theme.ts", "../src/js/icon.ts", "../src/js/tokens.ts", "../src/js/_tokenData.ts", "../src/js/combobox.ts", "../src/js/modal.ts", "../src/js/nav.ts", "../src/js/loading.ts", "../src/js/toast.ts", "../src/js/table.ts", "../src/js/menu.ts", "../src/js/popover.ts", "../src/js/_position.ts", "../src/js/tooltip.ts", "../src/js/tabs.ts", "../src/js/index.ts"],
4
+ "sourcesContent": ["/**\n * Theme \u2014 toggles `data-theme=\"dark\"` on <html>, remembers the choice, and\n * falls back to the OS preference. The runtime token API (`setTokens` /\n * `resetTokens` / `getToken`) for retheming Fernwell's colour tokens on the\n * fly is implemented in tokens.ts and re-exported here for compatibility.\n *\n * <button class=\"fw-btn fw-btn-ghost\" data-fw-theme-toggle\n * data-fw-theme-label-dark=\"\u2600\uFE0F Light\" data-fw-theme-label-light=\"\uD83C\uDF19 Dark\">\uD83C\uDF19 Dark</button>\n *\n * For a real icon instead of an emoji, use `data-fw-theme-icon-dark` /\n * `data-fw-theme-icon-light` (icon names from `icon.ts`) in place of the\n * `-label-` attributes \u2014 optionally alongside a `-label-` pair, which is\n * appended as text after the icon:\n *\n * <button class=\"fw-nav-btn\" data-fw-theme-toggle aria-label=\"Toggle theme\"\n * data-fw-theme-icon-dark=\"sun\" data-fw-theme-icon-light=\"moon\"></button>\n *\n * init() never animates the theme it applies on load (toggling and live OS\n * changes still do) \u2014 but to also avoid a flash of the *wrong* theme's\n * colours before this script runs at all, inline this before your CSS:\n * <script>document.documentElement.dataset.theme=localStorage.getItem('fw-theme')||(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light')</script>\n * and, if you persist token overrides (see tokens.ts), this too:\n * <script>try{var c=localStorage.getItem('fw-tokens-css');if(c){var s=document.createElement('style');s.setAttribute('data-fw-tokens','');s.textContent=c;document.head.appendChild(s)}}catch(e){}</script>\n */\nimport { render as renderIcon } from './icon.js';\n\nexport type Theme = 'light' | 'dark';\n\nconst STORAGE_KEY = 'fw-theme';\nconst EVENT = 'fw:themechange';\nconst INIT_ATTR = 'data-fw-theme-init';\n\nfunction store(): Storage | null {\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\n/** The theme currently applied to <html>, or the system preference if none is set. */\nexport function get(): Theme {\n const attr = document.documentElement.getAttribute('data-theme');\n if (attr === 'dark' || attr === 'light') return attr;\n return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n}\n\n/** Apply a theme, persist it, and update every toggle button on the page. */\nexport function set(theme: Theme, { persist = true }: { persist?: boolean } = {}): void {\n document.documentElement.setAttribute('data-theme', theme);\n if (persist) store()?.setItem(STORAGE_KEY, theme);\n document.querySelectorAll<HTMLElement>('[data-fw-theme-toggle]').forEach((btn) => syncToggle(btn, theme));\n document.dispatchEvent(new CustomEvent<Theme>(EVENT, { detail: theme }));\n}\n\nexport function toggle(): Theme {\n const next: Theme = get() === 'dark' ? 'light' : 'dark';\n set(next);\n return next;\n}\n\nfunction syncToggle(btn: HTMLElement, theme: Theme): void {\n btn.setAttribute('aria-pressed', String(theme === 'dark'));\n const iconName = theme === 'dark' ? btn.dataset.fwThemeIconDark : btn.dataset.fwThemeIconLight;\n const label = theme === 'dark' ? btn.dataset.fwThemeLabelDark : btn.dataset.fwThemeLabelLight;\n if (iconName !== undefined) {\n const icon = `<span class=\"fw-icon\" aria-hidden=\"true\">${renderIcon(iconName)}</span>`;\n btn.innerHTML = label !== undefined ? `${icon} ${label}` : icon;\n } else if (label !== undefined) {\n btn.textContent = label;\n }\n}\n\n/** Wait two animation frames \u2014 long enough for a `transition: none` frame to actually paint. */\nfunction afterPaint(cb: () => void): void {\n const raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : (fn: () => void) => setTimeout(fn, 16);\n raf(() => raf(cb));\n}\n\n/** Apply the stored / system theme and wire every `[data-fw-theme-toggle]` under `root`. */\nexport function init(root: ParentNode = document): void {\n const stored = store()?.getItem(STORAGE_KEY);\n const current: Theme = stored === 'dark' || stored === 'light' ? stored : get();\n\n // Applying the initial theme should never animate \u2014 only a later toggle or\n // OS change should. Suppress transitions for this one set() call.\n const html = document.documentElement;\n html.setAttribute(INIT_ATTR, '');\n set(current, { persist: false });\n afterPaint(() => html.removeAttribute(INIT_ATTR));\n\n root.querySelectorAll<HTMLElement>('[data-fw-theme-toggle]').forEach((btn) => {\n if (btn.dataset.fwBound) return;\n btn.dataset.fwBound = '1';\n syncToggle(btn, current);\n btn.addEventListener('click', () => toggle());\n });\n\n // Follow the OS only while the user hasn't chosen explicitly.\n window.matchMedia?.('(prefers-color-scheme: dark)').addEventListener?.('change', (e) => {\n if (!store()?.getItem(STORAGE_KEY)) set(e.matches ? 'dark' : 'light', { persist: false });\n });\n}\n\n/*\n * Runtime token overrides live in tokens.ts; they stay reachable here\n * (`theme.setTokens` / `resetTokens` / `getToken`) so existing code keeps working.\n */\nexport { setTokens, resetTokens, getToken } from './tokens.js';\nexport type { TokenOverrides, TokenThemeOverrides, SetTokensOptions } from './tokens.js';\n", "/**\n * Icon \u2014 renders a named SVG icon into a `data-fw-icon` element.\n *\n * <span class=\"fw-icon\" data-fw-icon=\"trash\" aria-hidden=\"true\"></span>\n *\n * Icons are decorative by default (the injected <svg> is `aria-hidden` and\n * `focusable=\"false\"`); give the accessible name to a wrapping interactive\n * element instead (e.g. `aria-label` on a button), same as `.fw-icon-btn`.\n * Color and size are not set here \u2014 `.fw-icon` inherits `color` and sizes\n * itself in `em`, so an icon matches whatever text surrounds it.\n */\nconst icons: Record<string, string> = {\n add: '<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/>',\n close: '<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>',\n check: '<polyline points=\"5,13 10,18 19,7\"/>',\n edit: '<path d=\"M16.8 3.5a2.1 2.1 0 0 1 3 3L8.5 17.8 4 19l1.2-4.5Z\"/><line x1=\"14.5\" y1=\"5.8\" x2=\"17.7\" y2=\"9\"/>',\n trash:\n '<path d=\"M4 7h16\"/><path d=\"M9 7V4.6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1V7\"/><path d=\"M6.5 7l.8 12.4A2 2 0 0 0 9.3 21h5.4a2 2 0 0 0 2-1.6L18 7\"/><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"/><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"/>',\n save: '<path d=\"M5 4a1 1 0 0 1 1-1h9.2a1 1 0 0 1 .7.3l2.8 2.8a1 1 0 0 1 .3.7V20a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4Z\"/><path d=\"M8 3v5h7V3\"/><path d=\"M8 21v-6h8v6\"/>',\n search: '<circle cx=\"11\" cy=\"11\" r=\"7\"/><line x1=\"21\" y1=\"21\" x2=\"16.6\" y2=\"16.6\"/>',\n settings:\n '<circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1\"/>',\n download: '<line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/><polyline points=\"7,10 12,15 17,10\"/><line x1=\"5\" y1=\"21\" x2=\"19\" y2=\"21\"/>',\n upload: '<line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"/><polyline points=\"7,8 12,3 17,8\"/><line x1=\"5\" y1=\"21\" x2=\"19\" y2=\"21\"/>',\n share:\n '<circle cx=\"6\" cy=\"12\" r=\"2.3\"/><circle cx=\"18\" cy=\"6\" r=\"2.3\"/><circle cx=\"18\" cy=\"18\" r=\"2.3\"/><line x1=\"8.1\" y1=\"10.8\" x2=\"15.9\" y2=\"7.2\"/><line x1=\"8.1\" y1=\"13.2\" x2=\"15.9\" y2=\"16.8\"/>',\n copy: '<rect x=\"9\" y=\"9\" width=\"12\" height=\"12\" rx=\"2\"/><path d=\"M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1\"/>',\n menu: '<line x1=\"4\" y1=\"6\" x2=\"20\" y2=\"6\"/><line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/>',\n more:\n '<circle cx=\"5\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/>',\n user: '<circle cx=\"12\" cy=\"8\" r=\"4\"/><path d=\"M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8\"/>',\n bell: '<path d=\"M6 8a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6\"/><path d=\"M10 20a2 2 0 0 0 4 0\"/>',\n heart:\n '<path d=\"M12 20s-7-4.4-9.5-8.5C.8 8 2 4.5 5.5 4.5c2 0 3.5 1 6.5 4 3-3 4.5-4 6.5-4 3.5 0 4.7 3.5 3 7-2.5 4.1-9.5 8.5-9.5 8.5Z\"/>',\n star: '<polygon points=\"12,3 14.6,9.1 21.2,9.3 16,13.4 17.8,19.8 12,16.3 6.2,19.8 8,13.4 2.8,9.3 9.4,9.1\"/>',\n calendar: '<rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\"/><line x1=\"8\" y1=\"3\" x2=\"8\" y2=\"7\"/><line x1=\"16\" y1=\"3\" x2=\"16\" y2=\"7\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/>',\n refresh:\n '<path d=\"M20 11A8 8 0 0 0 6.3 6.3L4 8.6\"/><path d=\"M4 4v5h5\"/><path d=\"M4 13a8 8 0 0 0 13.7 4.7L20 15.4\"/><path d=\"M20 20v-5h-5\"/>',\n filter: '<polygon points=\"4,4 20,4 14,12 14,19 10,21 10,12\"/>',\n info: '<circle cx=\"12\" cy=\"12\" r=\"9\"/><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"16\"/><circle cx=\"12\" cy=\"8\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>',\n warning: '<path d=\"M12 3 22 20H2Z\"/><line x1=\"12\" y1=\"9.5\" x2=\"12\" y2=\"14.5\"/><circle cx=\"12\" cy=\"17.3\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>',\n lock: '<rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"/><path d=\"M8 11V7a4 4 0 0 1 8 0v4\"/>',\n eye: '<path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n 'chevron-down': '<polyline points=\"6,9 12,15 18,9\"/>',\n 'arrow-left': '<line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"/><polyline points=\"12,5 5,12 12,19\"/>',\n 'arrow-right': '<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><polyline points=\"12,5 19,12 12,19\"/>',\n folder: '<path d=\"M3.5 6.5a1 1 0 0 1 1-1H10l2 2.2h7.5a1 1 0 0 1 1 1V18a1 1 0 0 1-1 1H4.5a1 1 0 0 1-1-1Z\"/>',\n bookmark: '<path d=\"M6 3h12a1 1 0 0 1 1 1v17l-7-4-7 4V4a1 1 0 0 1 1-1Z\"/>',\n home: '<path d=\"M4 11.5 12 4l8 7.5\"/><path d=\"M6 10v10a1 1 0 0 0 1 1h3.5v-6h2.8v6H17a1 1 0 0 0 1-1V10\"/>',\n logout:\n '<path d=\"M9 4H5.5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1H9\"/><line x1=\"14\" y1=\"12\" x2=\"21\" y2=\"12\"/><polyline points=\"17.5,8.5 21,12 17.5,15.5\"/>',\n paperclip:\n '<path d=\"M21 11.5 12.4 20a4.3 4.3 0 0 1-6-6.1L15 5.3a2.9 2.9 0 0 1 4.1 4.1l-8.6 8.6a1.4 1.4 0 0 1-2-2l7.9-7.9\"/>',\n envelope: '<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><path d=\"M4 6.5 12 13l8-6.5\"/>',\n 'chevron-up': '<polyline points=\"6,15 12,9 18,15\"/>',\n 'chevron-left': '<polyline points=\"15,6 9,12 15,18\"/>',\n 'chevron-right': '<polyline points=\"9,6 15,12 9,18\"/>',\n 'arrow-up': '<line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"5\"/><polyline points=\"5,12 12,5 19,12\"/>',\n 'arrow-down': '<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><polyline points=\"5,12 12,19 19,12\"/>',\n unlock: '<rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"/><path d=\"M8 11V7a4 4 0 0 1 7.8-1.3\"/>',\n 'thumbs-up':\n '<path d=\"M7 11v9H4.5a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1H7Z\"/><path d=\"M7 11l4.3-7.3a1.4 1.4 0 0 1 2.6.8L13 9h5.6a2 2 0 0 1 1.9 2.6l-2 6.5A2 2 0 0 1 16.6 19.5H10a3 3 0 0 1-3-3\"/>',\n 'thumbs-down':\n '<path d=\"M7 13V4h2.5a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H7Z\"/><path d=\"M7 13l4.3 7.3a1.4 1.4 0 0 0 2.6-.8L13 15h5.6a2 2 0 0 0 1.9-2.6l-2-6.5A2 2 0 0 0 16.6 4.5H10a3 3 0 0 0-3 3\"/>',\n 'eye-closed':\n '<path d=\"M3.5 12S7 6 12 6s8.5 6 8.5 6-3.5 6-8.5 6-8.5-6-8.5-6Z\"/><line x1=\"4\" y1=\"19\" x2=\"20\" y2=\"5\"/>',\n 'help-circle':\n '<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M9.2 9.2a2.8 2.8 0 1 1 4.3 2.4c-.9.6-1.5 1.1-1.5 2.2\"/><circle cx=\"12\" cy=\"17\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>',\n chat: '<path d=\"M4 5.5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H9.5L5 20.5V16.5H5a1 1 0 0 1-1-1Z\"/>',\n kebab:\n '<circle cx=\"12\" cy=\"5\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"19\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\"/>',\n sun: '<circle cx=\"12\" cy=\"12\" r=\"4\"/><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"4.5\"/><line x1=\"12\" y1=\"19.5\" x2=\"12\" y2=\"22\"/><line x1=\"2\" y1=\"12\" x2=\"4.5\" y2=\"12\"/><line x1=\"19.5\" y1=\"12\" x2=\"22\" y2=\"12\"/><line x1=\"4.9\" y1=\"4.9\" x2=\"6.6\" y2=\"6.6\"/><line x1=\"17.4\" y1=\"17.4\" x2=\"19.1\" y2=\"19.1\"/><line x1=\"4.9\" y1=\"19.1\" x2=\"6.6\" y2=\"17.4\"/><line x1=\"17.4\" y1=\"6.6\" x2=\"19.1\" y2=\"4.9\"/>',\n moon: '<path d=\"M20.5 14.2A8.5 8.5 0 1 1 9.8 3.5a7 7 0 0 0 10.7 10.7Z\"/>',\n};\n\nexport type IconName = keyof typeof icons;\n\nexport function render(name: string): string {\n const inner = icons[name];\n if (!inner) return '';\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">${inner}</svg>`;\n}\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-icon]').forEach((el) => {\n if (el.dataset.fwBound) return;\n el.dataset.fwBound = '1';\n\n const name = el.dataset.fwIcon ?? '';\n const markup = render(name);\n if (!markup) {\n console.warn(`fernwell: unknown icon \"${name}\"`);\n }\n el.innerHTML = markup;\n el.classList.add('fw-icon');\n });\n}\n", "/**\n * Tokens \u2014 override any `--fw-*` design token from JS, for the whole app or\n * for one page or subtree, in both themes or per-theme. Every derived token\n * (hovers, tints, focus ring, glows) follows the seed it is built from.\n *\n * tokens.setTokens({ primary: '#2266ff' }); // both themes\n * tokens.setTokens({ light: { primary: '#2266ff' }, dark: { primary: '#5c9dff' } });\n * tokens.setTokens({ secondary: '#a33' }, { scope: '.tenant-acme' }); // one subtree\n * const undo = tokens.setTokens({ primary: '#a33' }); undo(); // route-scoped\n * tokens.setTokens({ primary: '#2266ff' }, { persist: true }); // app-wide\n *\n * Overrides render into one `<style data-fw-tokens>` appended to `<head>`:\n * being unlayered and last, it wins over Fernwell's own `@layer fw-tokens`\n * *and* any earlier static override in the consumer's stylesheet.\n *\n * Persistence \u2014 `persist: true` saves the scope to localStorage so every page\n * of the app (and every reload) gets it. Without it an override lives only\n * for the current page load, which is what \"this page only\" means in a\n * multi-page app. Persisted overrides sit *below* page-level ones, so a page\n * can still tweak an app-wide value. To apply them before first paint, inline\n * this ahead of your CSS (next to the theme snippet \u2014 see theme.ts):\n * <script>try{var c=localStorage.getItem('fw-tokens-css');if(c){var s=document.createElement('style');s.setAttribute('data-fw-tokens','');s.textContent=c;document.head.appendChild(s)}}catch(e){}</script>\n *\n * Declarative hooks (wired by `init()`):\n *\n * <script type=\"application/json\" data-fw-theme-tokens>{\"primary\":\"#2266ff\"}</script>\n * <script type=\"application/json\" data-fw-theme-tokens data-fw-scope=\".tenant-acme\" data-fw-persist>{\u2026}</script>\n * <section data-fw-theme-scope='{\"secondary\":\"#a33\"}'>\u2026</section>\n *\n * The `<script>` form takes the same shapes as `setTokens()` (flat map or\n * `{ light, dark }`); `data-fw-scope` and `data-fw-persist` are optional. The\n * element form themes that element's subtree only, and is never persisted.\n * Both are undone on the next `init()` after their element is removed from\n * the page; call the function `setTokens()` returns, or `resetTokens(scope)`,\n * to undo one sooner.\n *\n * Events (on `document`): `fw:tokenschange` { scope } \u2014 `scope` is absent\n * when every scope changed (a reset or a restore).\n */\nimport { DERIVED, type TokenName } from './_tokenData.js';\n\n/** A token to override: a known name (autocompletes), a bare custom name, or a full `--fw-*` / `--custom` property. */\nexport type TokenKey = TokenName | (string & {});\n\n/** Token name \u2192 CSS value. Bare names (`primary`) and full names (`--fw-primary`) both work. */\nexport type TokenOverrides = Partial<Record<TokenName, string>> & Record<string, string>;\n\n/** Split form: set different values per theme instead of both at once. */\nexport interface TokenThemeOverrides {\n light?: TokenOverrides;\n dark?: TokenOverrides;\n}\n\nexport interface SetTokensOptions {\n /** A CSS selector to theme a subtree instead of the whole page. Default `:root`. */\n scope?: string;\n /** Save this scope to localStorage so it applies on every page and reload. Default `false`. */\n persist?: boolean;\n}\n\nexport interface TokensChangeDetail {\n scope?: string;\n}\n\nconst TOKEN_PREFIX = '--fw-';\nconst STYLE_ATTR = 'data-fw-tokens';\nconst STORE_TOKENS = 'fw-tokens';\nconst STORE_CSS = 'fw-tokens-css';\nconst EVENT = 'fw:tokenschange';\nconst ROOT = ':root';\n\ntype Theme = 'light' | 'dark';\ntype Flat = Record<string, string>;\ninterface ScopeTokens {\n light: Flat;\n dark: Flat;\n}\ntype Layer = Map<string, ScopeTokens>;\n\n// Two layers, rendered in this order so equal-specificity rules resolve\n// persisted \u2192 page: `saved` is what goes to localStorage, `live` is this page only.\nconst saved: Layer = new Map();\nconst live: Layer = new Map();\nlet hydrated = false;\nlet scopeSeq = 0;\n\n// Declarative hooks that applied non-persisted tokens, so they can be undone\n// when their element leaves the page. `swept` remembers elements that were\n// undone that way, so putting the same node back re-applies its hook.\ninterface Hook {\n scope: string;\n undo: () => void;\n}\nconst hooks = new Map<Element, Hook>();\nconst swept = new WeakSet<Element>();\n\nfunction store(): Storage | null {\n try {\n return window.localStorage;\n } catch {\n return null;\n }\n}\n\nfunction normalizeTokenName(name: string): string {\n return name.startsWith('--') ? name : `${TOKEN_PREFIX}${name}`;\n}\n\n/** `--fw-primary` \u2192 `primary`; anything else (a custom property) is returned as-is. */\nfunction bareName(name: string): string {\n return name.startsWith(TOKEN_PREFIX) ? name.slice(TOKEN_PREFIX.length) : name;\n}\n\nfunction warn(message: string): void {\n console.warn(`fernwell: ${message}`);\n}\n\n/** Is this a selector the browser accepts? Guards the rule we build from it. */\nfunction validScope(scope: string): boolean {\n try {\n document.querySelector(scope);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Are every `(` and quote in this value closed? An unclosed one is not a\n * syntax error CSS recovers from at `;` \u2014 it swallows the rules that follow.\n */\nfunction balanced(value: string): boolean {\n let depth = 0;\n let quote = '';\n for (let i = 0; i < value.length; i++) {\n const c = value[i];\n if (c === '\\\\') i++;\n else if (quote) {\n if (c === quote) quote = '';\n else if (c === '\\n') return false;\n } else if (c === '\"' || c === \"'\") quote = c;\n else if (c === '(') depth++;\n else if (c === ')' && --depth < 0) return false;\n }\n return depth === 0 && !quote;\n}\n\n/** Keep only `name \u2192 string` pairs that can't break out of a declaration; names are normalised. */\nfunction sanitize(tokens: unknown): Flat {\n const out: Flat = {};\n if (tokens === null || typeof tokens !== 'object') return out;\n for (const [name, value] of Object.entries(tokens)) {\n if (!/^(--)?[\\w-]+$/.test(name)) {\n warn(`ignoring token with invalid name \"${name}\"`);\n } else if (typeof value !== 'string' || /[{};]|\\/\\*/.test(value) || !balanced(value)) {\n warn(`ignoring invalid value for token \"${name}\"`);\n } else {\n out[normalizeTokenName(name)] = value.trim();\n }\n }\n return out;\n}\n\nfunction isThemeSplit(tokens: TokenOverrides | TokenThemeOverrides): tokens is TokenThemeOverrides {\n // A token's own value is always a CSS string \u2014 so any object-valued entry\n // means this is the { light, dark } split form, not a flat token map.\n return Object.values(tokens).some((v) => v !== null && typeof v === 'object');\n}\n\n/** Split a selector list on its top-level commas \u2014 not those inside `:is(a, b)`, `[x=\"a,b\"]` or a string. */\nfunction splitSelectors(list: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let quote = '';\n let start = 0;\n for (let i = 0; i < list.length; i++) {\n const c = list[i];\n if (c === '\\\\') i++;\n else if (quote) {\n if (c === quote) quote = '';\n } else if (c === '\"' || c === \"'\") quote = c;\n else if (c === '(' || c === '[') depth++;\n else if (c === ')' || c === ']') depth--;\n else if (c === ',' && depth === 0) {\n parts.push(list.slice(start, i).trim());\n start = i + 1;\n }\n }\n parts.push(list.slice(start).trim());\n return parts.filter(Boolean);\n}\n\n/** The dark-theme selector for `scope`: the scope inside a dark root, or itself marked dark \u2014 per list item. */\nfunction darkSelector(scope: string): string {\n if (scope === ROOT) return '[data-theme=\"dark\"]';\n return splitSelectors(scope)\n .map((part) => `[data-theme=\"dark\"] ${part}, ${part}[data-theme=\"dark\"]`)\n .join(', ');\n}\n\nfunction declBlock(tokens: Flat): string {\n return Object.entries(tokens)\n .map(([name, value]) => `${name}:${value};`)\n .join('');\n}\n\n/**\n * Derived tokens are declared on :root, and `var()` resolves where it is\n * declared \u2014 so a seed overridden on a *scoped* selector would leave every\n * token computed from it (hover, tint, focus ring\u2026) stuck on the root value.\n * Re-declare, at the scope, each derived token that reads an overridden one\n * (directly or through another derived token). Anything the caller set\n * explicitly is left alone.\n */\nfunction derivedAt(overrides: Flat, theme: Theme): Flat {\n const explicit = new Set(Object.keys(overrides).map(bareName));\n const affected = new Set(explicit);\n const out: Flat = {};\n for (let grew = true; grew; ) {\n grew = false;\n for (const d of DERIVED) {\n if (explicit.has(d.name) || `${TOKEN_PREFIX}${d.name}` in out) continue;\n if (d.deps.some((dep) => affected.has(dep))) {\n out[`${TOKEN_PREFIX}${d.name}`] = d[theme];\n affected.add(d.name);\n grew = true;\n }\n }\n }\n return out;\n}\n\nfunction rulesFor(layer: Layer): string[] {\n const rules: string[] = [];\n layer.forEach(({ light, dark }, scope) => {\n const root = scope === ROOT;\n const l = root ? light : { ...derivedAt(light, 'light'), ...light };\n const d = root ? dark : { ...derivedAt(dark, 'dark'), ...dark };\n if (Object.keys(l).length) rules.push(`${scope}{${declBlock(l)}}`);\n if (Object.keys(d).length) {\n rules.push(`${darkSelector(scope)}{${declBlock(d)}}`);\n }\n });\n return rules;\n}\n\nfunction styleEl(create: boolean): HTMLStyleElement | null {\n const existing = document.head.querySelector<HTMLStyleElement>(`style[${STYLE_ATTR}]`);\n if (existing) {\n // A pre-paint snippet inserts this element *ahead of* the consumer's\n // stylesheet; move it to the end so it wins, as documented.\n if (create && existing !== document.head.lastElementChild) document.head.appendChild(existing);\n return existing;\n }\n if (!create) return null;\n const el = document.createElement('style');\n el.setAttribute(STYLE_ATTR, '');\n document.head.appendChild(el);\n return el;\n}\n\n/** Write the persisted layer (state + pre-paint CSS) to localStorage, or clear it when empty. */\nfunction persist(): void {\n const s = store();\n if (!s) return;\n try {\n if (saved.size === 0) {\n s.removeItem(STORE_TOKENS);\n s.removeItem(STORE_CSS);\n return;\n }\n const scopes: Record<string, ScopeTokens> = {};\n saved.forEach((entry, scope) => (scopes[scope] = entry));\n s.setItem(STORE_TOKENS, JSON.stringify({ v: 1, scopes }));\n s.setItem(STORE_CSS, rulesFor(saved).join('\\n'));\n } catch {\n // Quota exceeded / storage blocked \u2014 the overrides still apply for this page.\n }\n}\n\nfunction render(scope?: string): void {\n const rules = [...rulesFor(saved), ...rulesFor(live)];\n if (rules.length === 0) styleEl(false)?.remove();\n else styleEl(true)!.textContent = rules.join('\\n');\n document.dispatchEvent(new CustomEvent<TokensChangeDetail>(EVENT, { detail: { scope } }));\n}\n\n/** Set `values` on `target`, returning a function that puts back what it replaced. */\nfunction assign(target: Flat, values: Flat): () => void {\n const previous = new Map(Object.keys(values).map((k) => [k, k in target ? target[k] : undefined]));\n Object.assign(target, values);\n return () =>\n previous.forEach((old, k) => {\n // Skip keys a later call has since changed \u2014 that call owns them now.\n if (target[k] !== values[k]) return;\n if (old === undefined) delete target[k];\n else target[k] = old;\n });\n}\n\n/**\n * Override Fernwell design tokens at runtime \u2014 every derived token (hovers,\n * tints, focus ring, glows) follows automatically, in both themes:\n *\n * tokens.setTokens({ primary: '#2266ff' });\n *\n * Pass `{ light, dark }` to set different values per theme, `scope` to theme\n * a subtree instead of the whole page, and `persist` to keep the scope for\n * every page of the app:\n *\n * tokens.setTokens({ light: { primary: '#2266ff' }, dark: { primary: '#5c9dff' } });\n * tokens.setTokens({ secondary: '#a33' }, { scope: '.tenant-acme' });\n * tokens.setTokens({ primary: '#2266ff' }, { persist: true });\n *\n * Calls accumulate (merge into whatever overrides are already set for that\n * scope) \u2014 call `resetTokens()` to clear them. The returned function undoes\n * just this call, e.g. when a route unmounts; call it in reverse order if\n * several calls touched the same token.\n */\nexport function setTokens(tokens: TokenOverrides | TokenThemeOverrides, opts: SetTokensOptions = {}): () => void {\n const scope = opts.scope ?? ROOT;\n if (!validScope(scope)) {\n warn(`ignoring tokens for invalid scope \"${scope}\"`);\n return () => {};\n }\n if (!hydrated) load();\n\n let light: Flat;\n let dark: Flat;\n if (isThemeSplit(tokens)) {\n light = sanitize(tokens.light);\n dark = sanitize(tokens.dark);\n } else {\n light = sanitize(tokens);\n dark = { ...light };\n }\n\n const layer = opts.persist ? saved : live;\n const entry = layer.get(scope) ?? { light: {}, dark: {} };\n const undoLight = assign(entry.light, light);\n const undoDark = assign(entry.dark, dark);\n layer.set(scope, entry);\n if (opts.persist) persist();\n render(scope);\n\n let done = false;\n return () => {\n if (done) return;\n done = true;\n undoLight();\n undoDark();\n if (!Object.keys(entry.light).length && !Object.keys(entry.dark).length && layer.get(scope) === entry) {\n layer.delete(scope);\n }\n if (layer === saved) persist();\n render(scope);\n };\n}\n\n/**\n * Clear runtime token overrides \u2014 for one `scope`, or every scope if\n * omitted. Persisted overrides are removed from localStorage too.\n */\nexport function resetTokens(scope?: string): void {\n if (!hydrated) load();\n hooks.forEach((hook, el) => {\n if (!scope || hook.scope === scope) hooks.delete(el);\n });\n const hadSaved = scope ? saved.delete(scope) : saved.size > 0;\n if (scope) live.delete(scope);\n else {\n saved.clear();\n live.clear();\n }\n if (hadSaved) persist();\n render(scope);\n}\n\n/**\n * Reload persisted overrides from localStorage, replacing whatever persisted\n * scopes are in memory. `init()` does this once for you; call it yourself\n * only if something else rewrote storage.\n */\nexport function restoreTokens(): void {\n load();\n render();\n}\n\n/** Read persisted overrides into `saved` without rendering \u2014 callers render once they've made their own changes. */\nfunction load(): void {\n hydrated = true;\n saved.clear();\n let parsed: unknown = null;\n try {\n const raw = store()?.getItem(STORE_TOKENS);\n if (raw) parsed = JSON.parse(raw);\n } catch {\n // Malformed JSON \u2014 treat as nothing persisted.\n }\n const scopes = (parsed as { v?: unknown; scopes?: Record<string, Partial<ScopeTokens>> } | null)?.scopes;\n if ((parsed as { v?: unknown } | null)?.v === 1 && scopes && typeof scopes === 'object') {\n for (const [scope, entry] of Object.entries(scopes)) {\n if (!validScope(scope)) continue;\n const light = sanitize(entry?.light);\n const dark = sanitize(entry?.dark);\n if (Object.keys(light).length || Object.keys(dark).length) saved.set(scope, { light, dark });\n }\n }\n}\n\n/** The live, resolved value of a token (e.g. `getToken('primary')` \u2192 `'#ffc145'`), including runtime overrides. */\nexport function getToken(name: TokenKey, el: Element = document.documentElement): string {\n return getComputedStyle(el).getPropertyValue(normalizeTokenName(name)).trim();\n}\n\nfunction parseJSON(source: string | null | undefined, what: string): TokenOverrides | TokenThemeOverrides | null {\n try {\n const value: unknown = JSON.parse(source ?? '');\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) return value as TokenOverrides;\n } catch {\n // fall through to the warning\n }\n warn(`${what} must be a JSON object of tokens`);\n return null;\n}\n\n/** Undo the hooks whose element has left the page \u2014 so route-scoped markup doesn't pile up rules. */\nfunction sweep(): void {\n hooks.forEach((hook, el) => {\n if (el.isConnected) return;\n hooks.delete(el);\n swept.add(el);\n hook.undo();\n });\n}\n\nfunction isBound(el: HTMLElement): boolean {\n return !!el.dataset.fwTokensBound && !swept.has(el);\n}\n\nfunction bind(el: HTMLElement, scope: string, undo: () => void): void {\n el.dataset.fwTokensBound = '1';\n swept.delete(el);\n // A detached root (`init(fragment)`) has nothing to leave yet \u2014 don't track it.\n if (el.isConnected) hooks.set(el, { scope, undo });\n}\n\n/**\n * Restore persisted overrides (once), then apply every declarative hook\n * under `root` \u2014 `<script type=\"application/json\" data-fw-theme-tokens>` and\n * `data-fw-theme-scope=\"{\u2026}\"`. Safe to call again after injecting markup.\n *\n * Bound elements are marked `data-fw-tokens-bound`, not the shared `fwBound`\n * the other enhancers use \u2014 a themed element is often also a table, modal or\n * menu root, and must still be picked up by that component's own `init()`.\n *\n * A hook that isn't persisted is undone on the next `init()` after its element\n * has been removed from the page, so route-scoped markup doesn't accumulate\n * rules. (`data-fw-persist` hooks are app-wide and stay until `resetTokens()`.)\n */\nexport function init(root: ParentNode = document): void {\n if (!hydrated) restoreTokens();\n sweep();\n\n root.querySelectorAll<HTMLElement>('script[type=\"application/json\"][data-fw-theme-tokens]').forEach((el) => {\n if (isBound(el)) return;\n const tokens = parseJSON(el.textContent, 'data-fw-theme-tokens');\n el.dataset.fwTokensBound = '1';\n if (!tokens) return;\n const persist = el.hasAttribute('data-fw-persist');\n const scope = el.dataset.fwScope ?? ROOT;\n const undo = setTokens(tokens, { scope, persist });\n if (!persist) bind(el, scope, undo);\n });\n\n root.querySelectorAll<HTMLElement>('[data-fw-theme-scope]').forEach((el) => {\n if (isBound(el)) return;\n const tokens = parseJSON(el.getAttribute('data-fw-theme-scope'), 'data-fw-theme-scope');\n el.dataset.fwTokensBound = '1';\n if (!tokens) return;\n const id = el.getAttribute('data-fw-scope-id') ?? `fw-s${++scopeSeq}`;\n el.setAttribute('data-fw-scope-id', id);\n const scope = `[data-fw-scope-id=\"${id}\"]`;\n bind(el, scope, setTokens(tokens, { scope }));\n });\n}\n", "/*\n * GENERATED from src/tokens/tokens.json by scripts/gen-tokens.mjs. Do not edit by hand.\n */\n\n/** Every token name, without the `--fw-` prefix. */\nexport type TokenName =\n | 'text'\n | 'text-soft'\n | 'bg'\n | 'bg-dim'\n | 'surface'\n | 'primary'\n | 'primary-hover'\n | 'primary-soft'\n | 'secondary'\n | 'secondary-hover'\n | 'secondary-bg'\n | 'success'\n | 'success-bg'\n | 'warning'\n | 'warning-bg'\n | 'danger'\n | 'danger-bg'\n | 'info'\n | 'info-bg'\n | 'on-primary'\n | 'on-secondary'\n | 'on-secondary-soft'\n | 'on-secondary-fill'\n | 'on-secondary-line'\n | 'overlay'\n | 'overlay-soft'\n | 'focus-ring'\n | 'scrollbar-thumb'\n | 'scrollbar-thumb-hover'\n | 'scrollbar-track'\n | 'font-display'\n | 'font-body'\n | 'font-mono'\n | 'sp-1'\n | 'sp-2'\n | 'sp-3'\n | 'sp-4'\n | 'sp-5'\n | 'sp-6'\n | 'sp-7'\n | 'sp-8'\n | 'sp-9'\n | 'r-sm'\n | 'r-md'\n | 'r-lg'\n | 'r-xl'\n | 'r-full'\n | 'shadow-sm'\n | 'shadow-md'\n | 'shadow-lg'\n | 'shadow-primary'\n | 'shadow-success'\n | 'border-w'\n | 'motion-fast'\n | 'motion-base'\n | 'motion-ease';\n\n/** A token whose value is computed from other tokens (hovers, tints, focus ring, glows). */\nexport interface DerivedToken {\n readonly name: TokenName;\n /** The CSS value in the light theme, with `{ref}`s already resolved to `var(--fw-\u2026)`. */\n readonly light: string;\n readonly dark: string;\n /** Names of the tokens this one is computed from (either theme). */\n readonly deps: readonly string[];\n}\n\nexport const DERIVED: readonly DerivedToken[] = [\n { name: 'primary-hover', light: 'color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%)', dark: 'color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%)', deps: ['primary', 'text'] },\n { name: 'primary-soft', light: 'color-mix(in srgb, var(--fw-primary), white 35%)', dark: 'color-mix(in srgb, var(--fw-primary), white 35%)', deps: ['primary'] },\n { name: 'secondary-hover', light: 'color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%)', dark: 'color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%)', deps: ['secondary', 'text'] },\n { name: 'secondary-bg', light: 'color-mix(in srgb, var(--fw-secondary) 10%, var(--fw-surface))', dark: 'color-mix(in srgb, var(--fw-secondary) 16%, transparent)', deps: ['secondary', 'surface'] },\n { name: 'success-bg', light: 'color-mix(in srgb, var(--fw-success) 12%, var(--fw-surface))', dark: 'color-mix(in srgb, var(--fw-success) 14%, transparent)', deps: ['success', 'surface'] },\n { name: 'warning-bg', light: 'color-mix(in srgb, var(--fw-warning) 14%, var(--fw-surface))', dark: 'color-mix(in srgb, var(--fw-warning) 16%, transparent)', deps: ['warning', 'surface'] },\n { name: 'danger-bg', light: 'color-mix(in srgb, var(--fw-danger) 13%, var(--fw-surface))', dark: 'color-mix(in srgb, var(--fw-danger) 14%, transparent)', deps: ['danger', 'surface'] },\n { name: 'info-bg', light: 'color-mix(in srgb, var(--fw-info) 12%, var(--fw-surface))', dark: 'color-mix(in srgb, var(--fw-info) 14%, transparent)', deps: ['info', 'surface'] },\n { name: 'on-secondary-soft', light: 'color-mix(in srgb, var(--fw-on-secondary) 72%, transparent)', dark: 'color-mix(in srgb, var(--fw-on-secondary) 72%, transparent)', deps: ['on-secondary'] },\n { name: 'on-secondary-fill', light: 'color-mix(in srgb, var(--fw-on-secondary) 10%, transparent)', dark: 'color-mix(in srgb, var(--fw-on-secondary) 10%, transparent)', deps: ['on-secondary'] },\n { name: 'on-secondary-line', light: 'color-mix(in srgb, var(--fw-on-secondary) 16%, transparent)', dark: 'color-mix(in srgb, var(--fw-on-secondary) 16%, transparent)', deps: ['on-secondary'] },\n { name: 'focus-ring', light: '0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent)', dark: '0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent)', deps: ['primary'] },\n { name: 'scrollbar-thumb', light: 'var(--fw-text-soft)', dark: 'var(--fw-text-soft)', deps: ['text-soft'] },\n { name: 'scrollbar-thumb-hover', light: 'color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%)', dark: 'color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%)', deps: ['text-soft', 'text'] },\n { name: 'shadow-primary', light: '0 6px 16px color-mix(in srgb, var(--fw-primary) 35%, transparent)', dark: '0 6px 16px color-mix(in srgb, var(--fw-primary) 22%, transparent)', deps: ['primary'] },\n { name: 'shadow-success', light: '0 6px 16px color-mix(in srgb, var(--fw-success) 28%, transparent)', dark: '0 6px 16px color-mix(in srgb, var(--fw-success) 22%, transparent)', deps: ['success'] },\n];\n", "/**\n * Combobox / typeahead \u2014 progressive enhancement over an <input> + <datalist>.\n *\n * <div class=\"fw-combobox\">\n * <input class=\"fw-input\" data-fw-combobox list=\"cities\" placeholder=\"Start typing\u2026\">\n * <datalist id=\"cities\"><option value=\"Seattle\"></option>\u2026</datalist>\n * </div>\n *\n * Or programmatically: combobox(input, { options: ['Seattle', \u2026], onSelect })\n */\nexport interface ComboboxOptions {\n /** Static option list. Defaults to the <datalist> the input's `list` attribute points at. */\n options?: string[];\n /** Filter function; default is case-insensitive substring match. */\n filter?: (option: string, query: string) => boolean;\n /** Text shown when nothing matches. */\n emptyText?: string;\n onSelect?: (value: string) => void;\n}\n\nexport interface ComboboxInstance {\n open(): void;\n close(): void;\n setOptions(options: string[]): void;\n destroy(): void;\n}\n\nlet uid = 0;\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>\"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[c] as string);\n}\n\nexport function combobox(input: HTMLInputElement, opts: ComboboxOptions = {}): ComboboxInstance {\n const filter = opts.filter ?? ((o, q) => o.toLowerCase().includes(q));\n const emptyText = opts.emptyText ?? 'No matches';\n let options = opts.options ?? readDatalist(input);\n let current: string[] = [];\n let activeIndex = -1;\n let selecting = false;\n\n // The native datalist would double up with our list \u2014 detach it but keep\n // the options readable for setOptions()/no-JS fallbacks.\n const listId = input.getAttribute('list');\n if (listId) {\n input.dataset.fwList = listId;\n input.removeAttribute('list');\n }\n\n const wrap = input.closest('.fw-combobox') ?? wrapInput(input);\n const list = document.createElement('ul');\n const id = `fw-combobox-${++uid}`;\n list.className = 'fw-combobox-list';\n list.id = id;\n list.setAttribute('role', 'listbox');\n wrap.appendChild(list);\n\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-expanded', 'false');\n input.setAttribute('aria-controls', id);\n input.autocomplete = 'off';\n\n function render(matches: string[]): void {\n current = matches;\n activeIndex = -1;\n const q = input.value.trim().toLowerCase();\n if (matches.length === 0) {\n list.innerHTML = `<li class=\"fw-combobox-empty\">${escapeHtml(emptyText)}</li>`;\n return;\n }\n list.innerHTML = matches\n .map((opt, i) => {\n const idx = q ? opt.toLowerCase().indexOf(q) : -1;\n const label =\n idx > -1\n ? `${escapeHtml(opt.slice(0, idx))}<b>${escapeHtml(opt.slice(idx, idx + q.length))}</b>${escapeHtml(opt.slice(idx + q.length))}`\n : escapeHtml(opt);\n return `<li class=\"fw-combobox-option\" role=\"option\" id=\"${id}-${i}\" data-index=\"${i}\" aria-selected=\"false\">${label}</li>`;\n })\n .join('');\n }\n\n function open(): void {\n const q = input.value.trim().toLowerCase();\n render(q ? options.filter((o) => filter(o, q)) : options);\n list.classList.add('is-open');\n input.setAttribute('aria-expanded', 'true');\n }\n\n function close(): void {\n list.classList.remove('is-open');\n input.setAttribute('aria-expanded', 'false');\n input.removeAttribute('aria-activedescendant');\n activeIndex = -1;\n }\n\n function highlight(i: number): void {\n const items = list.querySelectorAll<HTMLElement>('.fw-combobox-option');\n items.forEach((el) => {\n el.classList.remove('is-active');\n el.setAttribute('aria-selected', 'false');\n });\n const el = items[i];\n if (el) {\n el.classList.add('is-active');\n el.setAttribute('aria-selected', 'true');\n el.scrollIntoView({ block: 'nearest' });\n input.setAttribute('aria-activedescendant', el.id);\n }\n activeIndex = i;\n }\n\n function select(value: string): void {\n input.value = value;\n close();\n // The synthetic events below would re-open the list via onInput/onFocus.\n selecting = true;\n input.focus();\n input.dispatchEvent(new Event('input', { bubbles: true }));\n input.dispatchEvent(new Event('change', { bubbles: true }));\n selecting = false;\n opts.onSelect?.(value);\n }\n\n const onInput = () => {\n if (!selecting) open();\n };\n const onFocus = () => {\n if (!selecting) open();\n };\n const onKeydown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (!list.classList.contains('is-open')) open();\n highlight(Math.min(activeIndex + 1, current.length - 1));\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n highlight(Math.max(activeIndex - 1, 0));\n } else if (e.key === 'Enter') {\n if (activeIndex > -1 && current[activeIndex] !== undefined) {\n e.preventDefault();\n select(current[activeIndex]);\n }\n } else if (e.key === 'Escape') {\n close();\n }\n };\n const onListMousedown = (e: MouseEvent) => {\n const opt = (e.target as HTMLElement).closest<HTMLElement>('.fw-combobox-option');\n if (opt) {\n e.preventDefault(); // keep focus on the input\n select(current[Number(opt.dataset.index)]);\n }\n };\n const onDocClick = (e: MouseEvent) => {\n if (!wrap.contains(e.target as Node)) close();\n };\n\n input.addEventListener('input', onInput);\n input.addEventListener('focus', onFocus);\n input.addEventListener('keydown', onKeydown);\n list.addEventListener('mousedown', onListMousedown);\n document.addEventListener('click', onDocClick);\n\n return {\n open,\n close,\n setOptions(next) {\n options = next;\n if (list.classList.contains('is-open')) open();\n },\n destroy() {\n input.removeEventListener('input', onInput);\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('keydown', onKeydown);\n list.removeEventListener('mousedown', onListMousedown);\n document.removeEventListener('click', onDocClick);\n list.remove();\n if (input.dataset.fwList) input.setAttribute('list', input.dataset.fwList);\n delete input.dataset.fwBound;\n },\n };\n}\n\nfunction readDatalist(input: HTMLInputElement): string[] {\n const id = input.getAttribute('list') ?? input.dataset.fwList;\n const dl = id ? document.getElementById(id) : null;\n return dl ? Array.from(dl.querySelectorAll('option')).map((o) => o.value || o.textContent || '') : [];\n}\n\nfunction wrapInput(input: HTMLInputElement): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'fw-combobox';\n input.parentNode?.insertBefore(wrap, input);\n wrap.appendChild(input);\n return wrap;\n}\n\n/** Enhance every `[data-fw-combobox]` input under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLInputElement>('input[data-fw-combobox]').forEach((input) => {\n if (input.dataset.fwBound) return;\n input.dataset.fwBound = '1';\n combobox(input);\n });\n}\n", "/**\n * Modal & drawer overlays.\n *\n * <button data-fw-open-modal=\"confirm\">\u2026</button>\n * <div class=\"fw-modal-overlay\" id=\"confirm\" role=\"dialog\" aria-modal=\"true\"><div class=\"fw-modal\">\u2026 <button data-fw-close-modal>Cancel</button></div></div>\n *\n * <button data-fw-open-drawer=\"details\">\u2026</button>\n * <div class=\"fw-drawer-overlay\" data-fw-drawer-overlay=\"details\"></div>\n * <aside class=\"fw-drawer\" id=\"details\" role=\"dialog\" aria-modal=\"true\">\u2026 <button data-fw-close-drawer>\u00D7</button></aside>\n *\n * Closes on backdrop click (guarded \u2014 a text-selection drag that ends on the\n * backdrop does NOT close it), on Escape, and returns focus to the opener.\n */\nconst OPEN = 'is-open';\nconst LOCK = 'fw-scroll-lock';\nconst openStack: HTMLElement[] = [];\nconst openers = new WeakMap<HTMLElement, HTMLElement | null>();\n\nconst FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction resolve(target: string | HTMLElement): HTMLElement | null {\n return typeof target === 'string' ? document.getElementById(target) : target;\n}\n\n/** The backdrop element paired with a drawer (via `data-fw-drawer-overlay=\"<id>\"`), if any. */\nfunction backdropFor(el: HTMLElement): HTMLElement | null {\n if (el.classList.contains('fw-modal-overlay')) return el;\n const explicit = el.id ? document.querySelector<HTMLElement>(`[data-fw-drawer-overlay=\"${el.id}\"]`) : null;\n if (explicit) return explicit;\n const prev = el.previousElementSibling;\n return prev instanceof HTMLElement && prev.classList.contains('fw-drawer-overlay') ? prev : null;\n}\n\nexport function open(target: string | HTMLElement, opener: HTMLElement | null = (document.activeElement as HTMLElement) ?? null): void {\n const el = resolve(target);\n if (!el || el.classList.contains(OPEN)) return;\n el.classList.add(OPEN);\n backdropFor(el)?.classList.add(OPEN);\n openers.set(el, opener);\n openStack.push(el);\n document.body.classList.add(LOCK);\n el.dispatchEvent(new CustomEvent('fw:open', { bubbles: true }));\n // Focus the first control inside; fall back to the panel itself.\n const first = el.querySelector<HTMLElement>(FOCUSABLE);\n if (first) first.focus({ preventScroll: true });\n else {\n if (!el.hasAttribute('tabindex')) el.setAttribute('tabindex', '-1');\n el.focus({ preventScroll: true });\n }\n}\n\nexport function close(target: string | HTMLElement): void {\n const el = resolve(target);\n if (!el || !el.classList.contains(OPEN)) return;\n el.classList.remove(OPEN);\n backdropFor(el)?.classList.remove(OPEN);\n const i = openStack.indexOf(el);\n if (i > -1) openStack.splice(i, 1);\n if (openStack.length === 0) document.body.classList.remove(LOCK);\n el.dispatchEvent(new CustomEvent('fw:close', { bubbles: true }));\n openers.get(el)?.focus?.({ preventScroll: true });\n openers.delete(el);\n}\n\nexport function toggle(target: string | HTMLElement): void {\n const el = resolve(target);\n if (el) (el.classList.contains(OPEN) ? close : open)(el);\n}\n\n/**\n * Click-outside-to-close, guarded against a classic false positive: a\n * browser's `click` fires on the nearest common ancestor of mousedown and\n * mouseup. A drag that starts inside the panel and ends on the backdrop has\n * the overlay as that ancestor, so a naive `e.target === overlay` check would\n * close the modal mid-selection. Close only when BOTH landed on the backdrop.\n */\nexport function bindOutsideClickToClose(backdrop: HTMLElement, onClose: () => void): void {\n let downOnBackdrop = false;\n backdrop.addEventListener('mousedown', (e) => {\n downOnBackdrop = e.target === backdrop;\n });\n backdrop.addEventListener('click', (e) => {\n if (e.target === backdrop && downOnBackdrop) onClose();\n });\n}\n\nlet keyBound = false;\n\n/** Wire every trigger, overlay and close button under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-open-modal], [data-fw-open-drawer]').forEach((btn) => {\n if (btn.dataset.fwBound) return;\n btn.dataset.fwBound = '1';\n const id = btn.dataset.fwOpenModal ?? btn.dataset.fwOpenDrawer ?? '';\n btn.addEventListener('click', () => open(id, btn));\n });\n\n root.querySelectorAll<HTMLElement>('.fw-modal-overlay').forEach((overlay) => {\n if (overlay.dataset.fwBound) return;\n overlay.dataset.fwBound = '1';\n bindOutsideClickToClose(overlay, () => close(overlay));\n overlay.querySelectorAll<HTMLElement>('[data-fw-close-modal]').forEach((btn) =>\n btn.addEventListener('click', () => close(overlay)),\n );\n });\n\n root.querySelectorAll<HTMLElement>('.fw-drawer').forEach((drawer) => {\n if (drawer.dataset.fwBound) return;\n drawer.dataset.fwBound = '1';\n const backdrop = backdropFor(drawer);\n if (backdrop) bindOutsideClickToClose(backdrop, () => close(drawer));\n drawer.querySelectorAll<HTMLElement>('[data-fw-close-drawer]').forEach((btn) =>\n btn.addEventListener('click', () => close(drawer)),\n );\n });\n\n if (!keyBound) {\n keyBound = true;\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && openStack.length) close(openStack[openStack.length - 1]);\n });\n }\n}\n", "/**\n * Nav dropdown \u2014 the hamburger toggle in `.fw-nav` (and any other\n * button-controls-panel pair).\n *\n * <button data-fw-nav-toggle aria-controls=\"menu\" aria-expanded=\"false\">\u2026</button>\n * <div class=\"fw-nav-dropdown\" id=\"menu\">\u2026</div>\n *\n * Closes on outside click and Escape.\n */\nconst OPEN = 'is-open';\n\nexport function open(toggle: HTMLElement): void {\n const panel = panelFor(toggle);\n if (!panel) return;\n panel.classList.add(OPEN);\n toggle.setAttribute('aria-expanded', 'true');\n}\n\nexport function close(toggle: HTMLElement): void {\n const panel = panelFor(toggle);\n if (!panel) return;\n panel.classList.remove(OPEN);\n toggle.setAttribute('aria-expanded', 'false');\n}\n\nfunction panelFor(toggle: HTMLElement): HTMLElement | null {\n const id = toggle.getAttribute('aria-controls');\n return id ? document.getElementById(id) : null;\n}\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-nav-toggle]').forEach((toggle) => {\n if (toggle.dataset.fwBound) return;\n toggle.dataset.fwBound = '1';\n const panel = panelFor(toggle);\n if (!panel) return;\n const container = toggle.closest<HTMLElement>('.fw-nav') ?? toggle.parentElement ?? toggle;\n\n toggle.addEventListener('click', (e) => {\n e.stopPropagation();\n (panel.classList.contains(OPEN) ? close : open)(toggle);\n });\n document.addEventListener('click', (e) => {\n if (!container.contains(e.target as Node) && !panel.contains(e.target as Node)) close(toggle);\n });\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') close(toggle);\n });\n });\n}\n", "/**\n * Loading states.\n *\n * loading.setButtonLoading(btn, 'Sending\u2026'); // disables, swaps in a spinner\n * loading.resetButtonLoading(btn); // restores original markup\n *\n * Or declaratively: any <form data-fw-loading> puts its submit button into the\n * loading state on submit (label from `data-fw-loading-text` on the button).\n */\nconst LOADING = 'fw-btn-loading';\n\nexport function setButtonLoading(btn: HTMLButtonElement | null, loadingText?: string): void {\n if (!btn || btn.classList.contains(LOADING)) return;\n btn.dataset.fwOriginalHtml = btn.innerHTML;\n btn.disabled = true;\n btn.setAttribute('aria-busy', 'true');\n btn.classList.add(LOADING);\n const label = loadingText ?? btn.dataset.fwLoadingText ?? btn.textContent ?? '';\n btn.innerHTML = '<span class=\"fw-spinner fw-spinner-sm\" aria-hidden=\"true\"></span>';\n btn.appendChild(document.createTextNode(label));\n}\n\nexport function resetButtonLoading(btn: HTMLButtonElement | null): void {\n if (!btn || !btn.classList.contains(LOADING)) return;\n btn.disabled = false;\n btn.removeAttribute('aria-busy');\n btn.classList.remove(LOADING);\n // Restore markup, not just text, so buttons with an icon keep it.\n if (btn.dataset.fwOriginalHtml !== undefined) {\n btn.innerHTML = btn.dataset.fwOriginalHtml;\n delete btn.dataset.fwOriginalHtml;\n }\n}\n\n/** Reset every loading button \u2014 e.g. after a bfcache restore. */\nexport function resetAll(root: ParentNode = document): void {\n root.querySelectorAll<HTMLButtonElement>(`.${LOADING}`).forEach(resetButtonLoading);\n}\n\nlet pageshowBound = false;\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLFormElement>('form[data-fw-loading]').forEach((form) => {\n if (form.dataset.fwBound) return;\n form.dataset.fwBound = '1';\n form.addEventListener('submit', () => {\n const btn = form.querySelector<HTMLButtonElement>('button[type=\"submit\"], button:not([type])');\n setButtonLoading(btn);\n });\n });\n\n // Browsers restore pages from the back-forward cache without re-running JS,\n // so a spinner painted right before navigating away would come back stuck.\n if (!pageshowBound) {\n pageshowBound = true;\n window.addEventListener('pageshow', (e) => {\n if (e.persisted) resetAll();\n });\n }\n}\n", "/**\n * Toast \u2014 a single, reused, bottom-right notice.\n *\n * toast.show('Invoice sent');\n * toast.show('That card was declined', { variant: 'error', duration: 6000 });\n */\nexport type ToastVariant = 'success' | 'error' | 'info' | 'pending';\n\nexport interface ToastOptions {\n variant?: ToastVariant;\n /** ms before it hides; 0 keeps it until `hide()` or the next `show()`. */\n duration?: number;\n}\n\nlet el: HTMLElement | null = null;\nlet timer: ReturnType<typeof setTimeout> | null = null;\n\nfunction ensure(): HTMLElement {\n if (el && el.isConnected) return el;\n el = document.createElement('div');\n el.className = 'fw-toast';\n el.setAttribute('role', 'status');\n el.setAttribute('aria-live', 'polite');\n el.innerHTML = '<span class=\"fw-toast-dot\" aria-hidden=\"true\"></span><span class=\"fw-toast-text\"></span>';\n document.body.appendChild(el);\n return el;\n}\n\nexport function show(message: string, { variant = 'success', duration = 4000 }: ToastOptions = {}): HTMLElement {\n const node = ensure();\n node.className = `fw-toast${variant === 'success' ? '' : ` fw-toast-${variant}`}`;\n (node.querySelector('.fw-toast-text') as HTMLElement).textContent = message;\n if (timer) clearTimeout(timer);\n // Re-trigger the transition even if it's already showing.\n node.classList.remove('is-show');\n void node.offsetWidth;\n node.classList.add('is-show');\n if (duration > 0) timer = setTimeout(hide, duration);\n return node;\n}\n\nexport function hide(): void {\n el?.classList.remove('is-show');\n if (timer) clearTimeout(timer);\n timer = null;\n}\n", "/**\n * Table \u2014 client-side column sorting and row selection for `.fw-table`.\n *\n * <table class=\"fw-table\" data-fw-table>\n * <thead><tr>\n * <th class=\"fw-table-select\"><label class=\"fw-checkbox\"><input type=\"checkbox\" data-fw-select-all>\u2026</label></th>\n * <th scope=\"col\" aria-sort=\"none\" data-fw-sort><button type=\"button\" class=\"fw-table-sort\">Client</button></th>\n * </tr></thead>\n * <tbody><tr>\n * <td class=\"fw-table-select\"><label class=\"fw-checkbox\"><input type=\"checkbox\" data-fw-select-row>\u2026</label></td>\n * <td data-fw-sort-value=\"1250\">$1,250.00</td>\n * </tr></tbody>\n * </table>\n *\n * Clicking a `th[data-fw-sort]` cycles aria-sort (none \u2192 ascending \u2192 descending \u2192 \u2026)\n * and reorders the first <tbody>. `data-fw-sort-value` on a cell overrides its\n * text for comparison (numbers, ISO dates). Rows without a cell in the sorted\n * column (e.g. a colspan empty row) stay at the bottom.\n *\n * Row checkboxes toggle `.is-selected` / aria-selected on their row and keep the\n * select-all checkbox in sync (checked / indeterminate).\n *\n * Events (bubbling, on the <table>): `fw:sort` { column, direction, th } and\n * `fw:select` { rows, all }.\n */\nexport type SortDirection = 'ascending' | 'descending';\n\nexport interface SortDetail {\n column: number;\n direction: SortDirection;\n th: HTMLTableCellElement;\n}\n\nexport interface SelectDetail {\n rows: HTMLTableRowElement[];\n all: boolean;\n}\n\nconst SELECTED = 'is-selected';\n\nfunction emit(table: HTMLTableElement, name: string, detail: SortDetail | SelectDetail): void {\n table.dispatchEvent(new CustomEvent(name, { bubbles: true, detail }));\n}\n\n/* ---- sorting ---- */\n\nfunction cellValue(row: HTMLTableRowElement, column: number): string {\n const cell = row.cells[column];\n return cell?.dataset.fwSortValue ?? cell?.textContent?.trim() ?? '';\n}\n\nfunction compare(a: string, b: string): number {\n const na = Number(a);\n const nb = Number(b);\n if (a !== '' && b !== '' && Number.isFinite(na) && Number.isFinite(nb)) return na - nb;\n return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' });\n}\n\nfunction sortHeaders(table: HTMLTableElement): HTMLTableCellElement[] {\n return Array.from(table.tHead?.querySelectorAll<HTMLTableCellElement>('th[data-fw-sort]') ?? []);\n}\n\nfunction nextDirection(th: HTMLTableCellElement): SortDirection {\n return th.getAttribute('aria-sort') === 'ascending' ? 'descending' : 'ascending';\n}\n\nexport function sort(table: HTMLTableElement, column: number, direction: SortDirection): void {\n const tbody = table.tBodies[0];\n if (!tbody) return;\n\n const rows = Array.from(tbody.rows);\n // A colspan row (empty / loading) has no cell at `column` \u2014 keep it last.\n const sortable = rows.filter((r) => r.cells.length > column);\n const rest = rows.filter((r) => r.cells.length <= column);\n const sign = direction === 'ascending' ? 1 : -1;\n sortable.sort((a, b) => sign * compare(cellValue(a, column), cellValue(b, column)));\n [...sortable, ...rest].forEach((r) => tbody.appendChild(r));\n\n let active: HTMLTableCellElement | null = null;\n sortHeaders(table).forEach((th) => {\n const isTarget = th.cellIndex === column;\n th.setAttribute('aria-sort', isTarget ? direction : 'none');\n if (isTarget) active = th;\n });\n if (active) emit(table, 'fw:sort', { column, direction, th: active });\n}\n\n/* ---- selection ---- */\n\nfunction rowInputs(table: HTMLTableElement): HTMLInputElement[] {\n return Array.from(table.querySelectorAll<HTMLInputElement>('tbody input[data-fw-select-row]'));\n}\n\nfunction applyRowState(row: HTMLTableRowElement, on: boolean): void {\n row.classList.toggle(SELECTED, on);\n row.setAttribute('aria-selected', on ? 'true' : 'false');\n}\n\nfunction syncSelectAll(table: HTMLTableElement): void {\n const all = table.querySelector<HTMLInputElement>('[data-fw-select-all]');\n if (!all) return;\n const inputs = rowInputs(table);\n const n = inputs.filter((i) => i.checked).length;\n all.checked = n > 0 && n === inputs.length;\n all.indeterminate = n > 0 && n < inputs.length;\n}\n\nexport function getSelected(table: HTMLTableElement): HTMLTableRowElement[] {\n return rowInputs(table)\n .filter((i) => i.checked)\n .map((i) => i.closest('tr'))\n .filter((r): r is HTMLTableRowElement => r !== null);\n}\n\nexport function setRowSelected(row: HTMLTableRowElement, on: boolean): void {\n const input = row.querySelector<HTMLInputElement>('input[data-fw-select-row]');\n if (input) input.checked = on;\n applyRowState(row, on);\n const table = row.closest('table');\n if (!table) return;\n syncSelectAll(table);\n emit(table, 'fw:select', { rows: getSelected(table), all: false });\n}\n\nexport function selectAll(table: HTMLTableElement, on: boolean): void {\n rowInputs(table).forEach((input) => {\n input.checked = on;\n const row = input.closest('tr');\n if (row) applyRowState(row, on);\n });\n syncSelectAll(table);\n emit(table, 'fw:select', { rows: getSelected(table), all: true });\n}\n\n/* ---- init ---- */\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLTableElement>('table[data-fw-table]').forEach((table) => {\n if (table.dataset.fwBound) return;\n table.dataset.fwBound = '1';\n\n sortHeaders(table).forEach((th) => {\n if (!th.hasAttribute('aria-sort')) th.setAttribute('aria-sort', 'none');\n });\n\n table.addEventListener('click', (e) => {\n const th = (e.target as Element).closest<HTMLTableCellElement>('th[data-fw-sort]');\n if (th && table.contains(th)) sort(table, th.cellIndex, nextDirection(th));\n });\n\n // Enter / Space on the sort button (or on a tabindex'd <th> without one).\n // preventDefault stops the button's native activation so it can't sort twice.\n table.addEventListener('keydown', (e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n const target = e.target as Element;\n if (!target.matches('th[data-fw-sort], th[data-fw-sort] .fw-table-sort')) return;\n const th = target.closest<HTMLTableCellElement>('th[data-fw-sort]');\n if (!th) return;\n e.preventDefault();\n sort(table, th.cellIndex, nextDirection(th));\n });\n\n table.addEventListener('change', (e) => {\n const input = e.target as HTMLInputElement;\n if (input.matches('[data-fw-select-all]')) {\n selectAll(table, input.checked);\n } else if (input.matches('[data-fw-select-row]')) {\n const row = input.closest('tr');\n if (row) setRowSelected(row, input.checked);\n }\n });\n\n // Honour server-rendered checked state.\n rowInputs(table).forEach((input) => {\n const row = input.closest('tr');\n if (row && input.checked) applyRowState(row, true);\n });\n syncSelectAll(table);\n });\n}\n", "/**\n * Menu \u2014 a nestable collapsible menu (nav tree or accordion) built on\n * native <details>/<summary>, enhanced for `.fw-menu[data-fw-menu]`.\n *\n * <nav class=\"fw-menu\" aria-label=\"Docs\" data-fw-menu>\n * <ul class=\"fw-menu-list\">\n * <li class=\"fw-menu-item\"><a class=\"fw-menu-link\" href=\"/\" aria-current=\"page\">Overview</a></li>\n * <li class=\"fw-menu-item\">\n * <details class=\"fw-menu-group\">\n * <summary class=\"fw-menu-summary\">Billing</summary>\n * <ul class=\"fw-menu-list\">\n * <li class=\"fw-menu-item fw-menu-split\">\n * <a class=\"fw-menu-link\" href=\"/billing/plans\">Plans</a>\n * <details class=\"fw-menu-group\">\n * <summary class=\"fw-menu-summary fw-menu-summary-icon\"><span class=\"fw-sr-only\">Toggle Plans</span></summary>\n * <ul class=\"fw-menu-list\">\u2026</ul>\n * </details>\n * </li>\n * </ul>\n * </details>\n * </li>\n * </ul>\n * </nav>\n *\n * The `open` attribute on each `.fw-menu-group` is the state \u2014 server-rendered\n * state is honoured, and the menu still expands/collapses without JS.\n *\n * The enhancer adds:\n * - auto-reveal: every ancestor group of an `[aria-current]` link is opened on\n * init, and a collapsed summary whose branch holds the current page gets `.is-current`\n * - `data-fw-menu-exclusive`: opening a group closes its siblings (accordion)\n * - keyboard: ArrowUp/ArrowDown move between visible rows, ArrowRight opens /\n * enters a group, ArrowLeft closes / goes to the parent, Home/End jump.\n * Tab order is untouched \u2014 every row stays natively tabbable.\n *\n * Events (bubbling, from the <details>): `fw:toggle` { group, open }.\n */\nexport interface ToggleDetail {\n group: HTMLDetailsElement;\n open: boolean;\n}\n\nconst GROUP = '.fw-menu-group';\nconst ROW = '.fw-menu-link, .fw-menu-summary';\nconst CURRENT = 'is-current';\n\nfunction emit(group: HTMLDetailsElement, detail: ToggleDetail): void {\n group.dispatchEvent(new CustomEvent('fw:toggle', { bubbles: true, detail }));\n}\n\n/* ---- open / close ---- */\n\nexport function open(group: HTMLDetailsElement): void {\n group.open = true;\n}\n\nexport function close(group: HTMLDetailsElement): void {\n group.open = false;\n}\n\nexport function toggle(group: HTMLDetailsElement, force?: boolean): void {\n group.open = force ?? !group.open;\n}\n\nexport function expandAll(root: ParentNode): void {\n root.querySelectorAll<HTMLDetailsElement>(GROUP).forEach(open);\n}\n\nexport function collapseAll(root: ParentNode): void {\n root.querySelectorAll<HTMLDetailsElement>(GROUP).forEach(close);\n}\n\n/** Open every ancestor group of `el` so it is visible. */\nexport function reveal(el: Element): void {\n let group = el.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null;\n while (group) {\n open(group);\n group = group.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null;\n }\n}\n\n/* ---- current-page hinting ---- */\n\nfunction syncCurrent(menu: HTMLElement): void {\n menu.querySelectorAll<HTMLDetailsElement>(GROUP).forEach((group) => {\n const summary = group.querySelector<HTMLElement>(':scope > .fw-menu-summary');\n if (!summary) return;\n const holdsCurrent = !group.open && group.querySelector('[aria-current]') !== null;\n summary.classList.toggle(CURRENT, holdsCurrent);\n });\n}\n\n/* ---- keyboard ---- */\n\n/** The group this row summarises (a summary), or null for a link. */\nfunction ownGroup(row: HTMLElement): HTMLDetailsElement | null {\n return row.matches('.fw-menu-summary') ? row.closest<HTMLDetailsElement>(GROUP) : null;\n}\n\n/** The group that contains this row (not the one it summarises). */\nfunction parentGroup(row: HTMLElement): HTMLDetailsElement | null {\n const start = ownGroup(row) ?? row;\n return start.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null;\n}\n\nfunction isVisible(row: HTMLElement): boolean {\n for (let g = parentGroup(row); g; g = g.parentElement?.closest<HTMLDetailsElement>(GROUP) ?? null) {\n if (!g.open) return false;\n }\n return true;\n}\n\nfunction visibleRows(menu: HTMLElement): HTMLElement[] {\n return Array.from(menu.querySelectorAll<HTMLElement>(ROW)).filter(isVisible);\n}\n\nfunction focusRow(row: HTMLElement | null | undefined): boolean {\n if (!row) return false;\n row.focus();\n return true;\n}\n\n/** The icon-only summary sitting beside a split-row link, if any. */\nfunction splitToggleFor(link: HTMLElement): HTMLElement | null {\n const item = link.closest<HTMLElement>('.fw-menu-split');\n return item?.querySelector<HTMLElement>(':scope > .fw-menu-group > .fw-menu-summary') ?? null;\n}\n\nfunction onKeydown(menu: HTMLElement, e: KeyboardEvent): void {\n if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;\n const row = e.target instanceof HTMLElement && e.target.matches(ROW) ? e.target : null;\n if (!row || !menu.contains(row)) return;\n\n const rows = visibleRows(menu);\n const i = rows.indexOf(row);\n const group = ownGroup(row);\n let handled = true;\n\n switch (e.key) {\n case 'ArrowDown':\n focusRow(rows[i + 1]);\n break;\n case 'ArrowUp':\n focusRow(rows[i - 1]);\n break;\n case 'Home':\n focusRow(rows[0]);\n break;\n case 'End':\n focusRow(rows[rows.length - 1]);\n break;\n case 'ArrowRight':\n if (group) {\n // An open group's first row is simply the next visible one.\n if (!group.open) open(group);\n else if (group.contains(rows[i + 1] ?? menu)) focusRow(rows[i + 1]);\n } else {\n focusRow(splitToggleFor(row));\n }\n break;\n case 'ArrowLeft':\n if (group?.open) {\n close(group);\n } else {\n const parent = parentGroup(row);\n focusRow(parent?.querySelector<HTMLElement>(':scope > .fw-menu-summary'));\n }\n break;\n default:\n handled = false;\n }\n if (handled) e.preventDefault();\n}\n\n/* ---- init ---- */\n\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-menu]').forEach((menu) => {\n if (menu.dataset.fwBound) return;\n menu.dataset.fwBound = '1';\n const exclusive = menu.hasAttribute('data-fw-menu-exclusive');\n\n // Native `toggle` doesn't bubble \u2014 catch it in the capture phase.\n menu.addEventListener(\n 'toggle',\n (e) => {\n const group = e.target;\n if (!(group instanceof HTMLDetailsElement) || !group.matches(GROUP)) return;\n if (exclusive && group.open && group.parentElement) {\n Array.from(group.parentElement.children).forEach((sibling) => {\n if (sibling !== group && sibling instanceof HTMLDetailsElement && sibling.matches(GROUP)) close(sibling);\n });\n }\n syncCurrent(menu);\n emit(group, { group, open: group.open });\n },\n true,\n );\n\n menu.addEventListener('keydown', (e) => onKeydown(menu, e));\n\n // Honour server-rendered state: make the current page visible on load.\n menu.querySelectorAll('[aria-current]').forEach(reveal);\n syncCurrent(menu);\n });\n}\n", "/**\n * Popover \u2014 a non-modal floating panel anchored to its trigger.\n *\n * <button type=\"button\" data-fw-popover-trigger=\"settings-pop\">Settings</button>\n *\n * <div class=\"fw-popover\" id=\"settings-pop\">\n * <div class=\"fw-popover-head\">\n * <h3 class=\"fw-popover-title\">Settings</h3>\n * <button type=\"button\" class=\"fw-icon-btn\" data-fw-popover-close aria-label=\"Close\">\n * <span data-fw-icon=\"close\" aria-hidden=\"true\"></span>\n * </button>\n * </div>\n * <div class=\"fw-popover-body\">\u2026</div>\n * </div>\n *\n * Optional trigger attributes: `data-fw-popover-placement` (\"top\" | \"bottom\" |\n * \"left\" | \"right\" \u2014 centered on the trigger's cross-axis midpoint \u2014 or a\n * corner variant \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\"\n * that leans the panel toward that corner instead of centering it, e.g. to\n * steer it clear of something else on the page; default \"bottom\"),\n * `data-fw-popover-offset` (px, default 8).\n *\n * While open, the panel is moved to the end of <body> so its `position: fixed`\n * containing block is always the viewport \u2014 not an ancestor with `transform`,\n * `filter` or `contain` (e.g. a card, or another modal) that would otherwise\n * break the positioning math \u2014 and moved back to its authored location on close.\n *\n * This is a non-modal dialog (`aria-modal=\"false\"`), so per WAI-ARIA APG it\n * does NOT trap Tab \u2014 focus is allowed to move naturally out of the panel.\n * Closing on focus leaving the panel/trigger (`focusout`) does the equivalent\n * job without fighting the surrounding page's tab order.\n *\n * Events (bubbling, from the panel): `fw:open`, `fw:close`.\n */\nimport { computePosition, bindOutsideDismiss, type Placement } from './_position.js';\n\nconst FOCUSABLE =\n 'a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nexport interface PopoverOptions {\n placement?: Placement;\n offset?: number;\n}\n\nexport interface PopoverInstance {\n open(): void;\n close(): void;\n toggle(): void;\n destroy(): void;\n}\n\nexport function popover(trigger: HTMLElement, panel: HTMLElement, opts: PopoverOptions = {}): PopoverInstance {\n const placement = opts.placement ?? 'bottom';\n const offset = opts.offset ?? 8;\n\n trigger.setAttribute('aria-haspopup', 'dialog');\n trigger.setAttribute('aria-controls', panel.id);\n trigger.setAttribute('aria-expanded', 'false');\n panel.setAttribute('role', 'dialog');\n panel.setAttribute('aria-modal', 'false');\n panel.classList.add('fw-popover');\n\n const originalParent = panel.parentNode as ParentNode;\n const originalNextSibling = panel.nextSibling;\n\n let isOpen = false;\n let unbindOutside: (() => void) | null = null;\n let raf = 0;\n\n function reposition(): void {\n const r = computePosition(trigger, panel, { placement, offset });\n panel.style.top = `${r.top}px`;\n panel.style.left = `${r.left}px`;\n panel.setAttribute('data-placement', r.placement);\n }\n\n function scheduleReposition(): void {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(reposition);\n }\n\n function onKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.stopPropagation();\n close();\n }\n }\n\n function onFocusOut(e: FocusEvent): void {\n const next = e.relatedTarget as Node | null;\n if (next && (panel.contains(next) || trigger.contains(next))) return;\n // relatedTarget is null for some mouse-driven blurs \u2014 re-check on the\n // next tick against document.activeElement instead of trusting it.\n setTimeout(() => {\n if (!isOpen) return;\n const active = document.activeElement;\n // A click on non-focusable panel content (plain text, a heading \u2014 not\n // the close button or a link) blurs the previously focused element\n // without moving focus anywhere real: activeElement falls back to\n // <body>. That's not \"focus left the popover\", so it isn't a dismiss\n // signal \u2014 a genuine click outside the popover already closes it via\n // bindOutsideDismiss below.\n if (active === document.body || active === null) return;\n if (!(panel.contains(active) || trigger.contains(active))) close();\n }, 0);\n }\n\n function open(): void {\n if (isOpen) return;\n isOpen = true;\n if (panel.parentNode !== document.body) document.body.appendChild(panel);\n reposition();\n panel.classList.add('is-open');\n trigger.setAttribute('aria-expanded', 'true');\n\n const first = panel.querySelector<HTMLElement>(FOCUSABLE);\n if (first) {\n first.focus({ preventScroll: true });\n } else {\n if (!panel.hasAttribute('tabindex')) panel.setAttribute('tabindex', '-1');\n panel.focus({ preventScroll: true });\n }\n\n unbindOutside = bindOutsideDismiss([trigger, panel], close);\n window.addEventListener('scroll', scheduleReposition, true);\n window.addEventListener('resize', scheduleReposition);\n panel.addEventListener('keydown', onKeydown);\n panel.addEventListener('focusout', onFocusOut);\n panel.dispatchEvent(new CustomEvent('fw:open', { bubbles: true }));\n }\n\n function close(): void {\n if (!isOpen) return;\n isOpen = false;\n panel.classList.remove('is-open');\n trigger.setAttribute('aria-expanded', 'false');\n\n unbindOutside?.();\n unbindOutside = null;\n window.removeEventListener('scroll', scheduleReposition, true);\n window.removeEventListener('resize', scheduleReposition);\n panel.removeEventListener('keydown', onKeydown);\n panel.removeEventListener('focusout', onFocusOut);\n cancelAnimationFrame(raf);\n\n const stillValid = originalNextSibling === null || originalNextSibling.parentNode === originalParent;\n if (stillValid) originalParent.insertBefore(panel, originalNextSibling);\n else originalParent.appendChild(panel);\n\n panel.dispatchEvent(new CustomEvent('fw:close', { bubbles: true }));\n trigger.focus({ preventScroll: true });\n }\n\n function toggle(): void {\n (isOpen ? close : open)();\n }\n\n const onTriggerClick = () => toggle();\n const closeButtons = Array.from(panel.querySelectorAll<HTMLElement>('[data-fw-popover-close]'));\n const onCloseClick = () => close();\n\n trigger.addEventListener('click', onTriggerClick);\n closeButtons.forEach((btn) => btn.addEventListener('click', onCloseClick));\n\n return {\n open,\n close,\n toggle,\n destroy() {\n if (isOpen) close();\n trigger.removeEventListener('click', onTriggerClick);\n closeButtons.forEach((btn) => btn.removeEventListener('click', onCloseClick));\n delete trigger.dataset.fwBound;\n },\n };\n}\n\n/** Wire every `[data-fw-popover-trigger]` under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-popover-trigger]').forEach((trigger) => {\n if (trigger.dataset.fwBound) return;\n const id = trigger.dataset.fwPopoverTrigger ?? '';\n const panel = document.getElementById(id);\n if (!panel) {\n console.warn(`fernwell: popover trigger references missing panel #${id}`);\n return;\n }\n trigger.dataset.fwBound = '1';\n popover(trigger, panel, {\n placement: (trigger.dataset.fwPopoverPlacement as Placement) || undefined,\n offset: trigger.dataset.fwPopoverOffset ? Number(trigger.dataset.fwPopoverOffset) : undefined,\n });\n });\n}\n", "/**\n * Internal positioning helpers shared by popover.ts and tooltip.ts. Not part\n * of the public API \u2014 not re-exported from index.ts.\n *\n * Both callers use `position: fixed`, so all math here is viewport-relative\n * (matching `getBoundingClientRect()`) rather than document-relative.\n */\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * `top` / `bottom` / `left` / `right` center the floating element on the\n * anchor's cross-axis midpoint. `top-left` / `top-right` / `bottom-left` /\n * `bottom-right` keep the anchor above/below but shift the floating element\n * so it leans toward that corner instead of centering \u2014 useful to steer a\n * panel away from something else on the page (another fixed control, a\n * viewport edge) without losing the \"above/below the trigger\" placement.\n *\n * \"Lean right\" means the floating element's LEFT edge lines up with the\n * anchor's left edge, so the (usually wider) box extends further right of\n * the anchor than a centered box would; \"lean left\" mirrors that off the\n * anchor's right edge.\n */\nexport type Placement = Side | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\n/** Which edge of the anchor the floating element's near edge lines up with,\n * on the cross axis \u2014 'start' leans the box toward increasing x/y (right/\n * down), 'end' leans it toward decreasing x/y (left/up). */\ntype Align = 'center' | 'start' | 'end';\n\nexport interface PositionOptions {\n /** Preferred placement. */\n placement?: Placement;\n /** Gap between anchor and floating element, px. */\n offset?: number;\n /** Minimum distance from the viewport edge, px. */\n padding?: number;\n}\n\nexport interface PositionResult {\n /** Final placement, after a possible flip. */\n placement: Placement;\n top: number;\n left: number;\n /**\n * Distance, in px, from the floating element's near edge (left, for a\n * top/bottom placement; top, for a left/right placement) to the anchor's\n * center \u2014 for positioning an optional arrow so it keeps pointing at the\n * anchor even after the cross-axis got clamped to stay in the viewport.\n * Already inset from the floating element's own edges so the arrow never\n * overhangs a rounded corner.\n */\n arrowOffset: number;\n}\n\nconst OPPOSITE_SIDE: Record<Side, Side> = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };\nconst ARROW_INSET = 10; // px \u2014 keeps the arrow clear of the floating box's rounded corners\n\nfunction parsePlacement(p: Placement): { side: Side; align: Align } {\n switch (p) {\n // \"-right\" leans the box right \u2192 its left edge pins to the anchor's\n // left edge (`start`); \"-left\" leans it left \u2192 right edges pin (`end`).\n case 'top-left':\n return { side: 'top', align: 'end' };\n case 'top-right':\n return { side: 'top', align: 'start' };\n case 'bottom-left':\n return { side: 'bottom', align: 'end' };\n case 'bottom-right':\n return { side: 'bottom', align: 'start' };\n default:\n return { side: p, align: 'center' };\n }\n}\n\nconst ALIGN_SUFFIX: Record<Exclude<Align, 'center'>, 'left' | 'right'> = { start: 'right', end: 'left' };\n\nfunction toPlacement(side: Side, align: Align): Placement {\n return align === 'center' ? side : (`${side}-${ALIGN_SUFFIX[align]}` as Placement);\n}\n\nfunction mainAxisSpace(side: Side, anchor: DOMRect, vw: number, vh: number): number {\n switch (side) {\n case 'top':\n return anchor.top;\n case 'bottom':\n return vh - anchor.bottom;\n case 'left':\n return anchor.left;\n case 'right':\n return vw - anchor.right;\n }\n}\n\nfunction mainAxisCoord(side: Side, anchor: DOMRect, floating: DOMRect, offset: number): number {\n switch (side) {\n case 'top':\n return anchor.top - offset - floating.height;\n case 'bottom':\n return anchor.bottom + offset;\n case 'left':\n return anchor.left - offset - floating.width;\n case 'right':\n return anchor.right + offset;\n }\n}\n\n/** Cross-axis coordinate (the floating element's left, for a horizontal\n * anchor span; or top, for a vertical one) implementing `align`. */\nfunction crossAxisCoord(align: Align, anchorStart: number, anchorSize: number, floatingSize: number): number {\n switch (align) {\n case 'start':\n return anchorStart;\n case 'end':\n return anchorStart + anchorSize - floatingSize;\n case 'center':\n return anchorStart + anchorSize / 2 - floatingSize / 2;\n }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max > min ? max : min);\n}\n\n/**\n * Positions `floating` relative to `anchor`: flips to the opposite side when\n * the preferred side doesn't fit and the opposite side has more room (a\n * 2-entry fallback, not a 4-way rotation \u2014 both callers are single-edge\n * anchored, unlike a corner-anchored menu), and clamps the cross-axis into\n * the viewport (\"shift\") rather than flipping it.\n *\n * The cross-axis is centered on the anchor by default (`align: 'center'`,\n * implied by a bare `top`/`bottom`/`left`/`right` placement) \u2014 the corner\n * placements (`top-left`, etc.) opt into edge-alignment instead. Centering\n * is what makes an arrow drawn at the floating element's own midpoint line\n * up with the anchor; `arrowOffset` carries the exact anchor-relative\n * position so the arrow still lines up even when a corner placement or a\n * viewport clamp shifts the box off-center.\n */\nexport function computePosition(anchor: HTMLElement, floating: HTMLElement, opts: PositionOptions = {}): PositionResult {\n const preferred = opts.placement ?? 'bottom';\n const offset = opts.offset ?? 8;\n const padding = opts.padding ?? 8;\n\n const a = anchor.getBoundingClientRect();\n const f = floating.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const { side: preferredSide, align } = parsePlacement(preferred);\n const oppositeSide = OPPOSITE_SIDE[preferredSide];\n const needed = preferredSide === 'top' || preferredSide === 'bottom' ? f.height : f.width;\n\n const side =\n mainAxisSpace(preferredSide, a, vw, vh) - offset < needed &&\n mainAxisSpace(oppositeSide, a, vw, vh) - offset > mainAxisSpace(preferredSide, a, vw, vh) - offset\n ? oppositeSide\n : preferredSide;\n\n let top: number;\n let left: number;\n let arrowOffset: number;\n\n if (side === 'top' || side === 'bottom') {\n top = mainAxisCoord(side, a, f, offset);\n left = clamp(crossAxisCoord(align, a.left, a.width, f.width), padding, vw - f.width - padding);\n arrowOffset = clamp(a.left + a.width / 2 - left, ARROW_INSET, Math.max(f.width - ARROW_INSET, ARROW_INSET));\n } else {\n left = mainAxisCoord(side, a, f, offset);\n top = clamp(crossAxisCoord('center', a.top, a.height, f.height), padding, vh - f.height - padding);\n arrowOffset = clamp(a.top + a.height / 2 - top, ARROW_INSET, Math.max(f.height - ARROW_INSET, ARROW_INSET));\n }\n\n return { placement: toPlacement(side, align), top, left, arrowOffset };\n}\n\n/**\n * Fires `onDismiss` only when a click lands outside every element in\n * `anchors` \u2014 generalizes modal.ts's `bindOutsideClickToClose` (which checks\n * a single backdrop) to an arbitrary set of \"not outside\" elements (e.g. a\n * popover's trigger AND its panel).\n *\n * Guards the same false positive: a browser's `click` fires on the nearest\n * common ancestor of mousedown and mouseup, so a text-selection drag that\n * starts inside an anchor and ends outside it would otherwise look like an\n * outside click. Close only when BOTH mousedown and click landed outside.\n */\nexport function bindOutsideDismiss(anchors: HTMLElement[], onDismiss: () => void): () => void {\n const isOutside = (target: EventTarget | null): boolean => !anchors.some((el) => el.contains(target as Node));\n let downOutside = false;\n\n const onMousedown = (e: MouseEvent) => {\n downOutside = isOutside(e.target);\n };\n const onClick = (e: MouseEvent) => {\n if (downOutside && isOutside(e.target)) onDismiss();\n };\n\n document.addEventListener('mousedown', onMousedown, true);\n document.addEventListener('click', onClick, true);\n\n return () => {\n document.removeEventListener('mousedown', onMousedown, true);\n document.removeEventListener('click', onClick, true);\n };\n}\n", "/**\n * Tooltip \u2014 a short hover/focus annotation, anchored to its trigger.\n *\n * <button type=\"button\" class=\"fw-icon-btn\" title=\"Copy to clipboard\" data-fw-tooltip>\n * <span data-fw-icon=\"copy\" aria-hidden=\"true\"></span>\n * </button>\n *\n * The `title` attribute is the content source \u2014 it's moved into\n * `dataset.fwTooltipText` and removed on init (same detach-and-mirror trick\n * combobox.ts uses for the `list` attribute), which gives a real no-JS\n * fallback (the native OS tooltip) and stops the two tooltips firing at once.\n *\n * Optional trigger attributes: `data-fw-tooltip-placement` (default \"top\";\n * also accepts \"bottom\" | \"left\" | \"right\", or a corner variant \u2014\n * \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\" \u2014 that leans the\n * bubble toward that corner instead of centering it, for triggers near a\n * layout edge), `data-fw-tooltip-offset` (px, default 6),\n * `data-fw-tooltip-delay` (ms, default 400).\n *\n * The bubble is centered on the trigger by default so the arrow (drawn at\n * `computePosition`'s returned `arrowOffset`) always points at the trigger's\n * midpoint \u2014 including when a corner placement or a viewport-edge clamp\n * shifts the bubble off-center.\n *\n * Only one tooltip bubble exists for the whole page (a lazily-created\n * singleton, same pattern as toast.ts) \u2014 a second trigger's hover pre-empts\n * the first. Acceptable for a short annotation; not meant for concurrent\n * multi-tooltip UIs.\n *\n * WCAG 2.1 SC 1.4.13 requires hover/focus-revealed content to be dismissible,\n * *hoverable* (the pointer can move onto it without it disappearing) and\n * persistent. `pointer-events: none` on the bubble would fail \"hoverable\"\n * outright \u2014 the bubble couldn't receive a hover at all \u2014 so this\n * deliberately does NOT set it while open. Instead the bubble gets its own\n * mouseenter/mouseleave, and a short cancelable hide-grace timer covers the\n * gap while the pointer travels from trigger to bubble.\n */\nimport { computePosition, type Placement } from './_position.js';\n\nconst SHOW_DELAY_DEFAULT = 400;\nconst SKIP_DELAY_WINDOW = 300; // ms \u2014 adjacent-trigger instant-reopen window\nconst HIDE_GRACE = 100; // ms \u2014 covers the trigger\u2192bubble pointer transit gap\n\nexport interface TooltipOptions {\n placement?: Placement;\n offset?: number;\n delay?: number;\n}\n\nexport interface TooltipInstance {\n show(): void;\n hide(): void;\n destroy(): void;\n}\n\ninterface ResolvedOptions {\n placement: Placement;\n offset: number;\n delay: number;\n}\n\nconst optsByTrigger = new WeakMap<HTMLElement, ResolvedOptions>();\n\nlet bubble: HTMLElement | null = null;\nlet activeTrigger: HTMLElement | null = null;\nlet showTimer = 0;\nlet hideTimer = 0;\nlet repositionRaf = 0;\nlet lastHiddenAt = 0;\n\nfunction ensureBubble(): HTMLElement {\n if (bubble && bubble.isConnected) return bubble;\n const el = document.createElement('div');\n el.className = 'fw-tooltip';\n el.id = 'fw-tooltip';\n el.setAttribute('role', 'tooltip');\n document.body.appendChild(el);\n el.addEventListener('mouseenter', cancelHide);\n el.addEventListener('mouseleave', () => requestHide());\n bubble = el;\n return el;\n}\n\nfunction cancelHide(): void {\n clearTimeout(hideTimer);\n}\n\nfunction reposition(): void {\n if (!activeTrigger || !bubble) return;\n const opts = optsByTrigger.get(activeTrigger);\n if (!opts) return;\n const r = computePosition(activeTrigger, bubble, { placement: opts.placement, offset: opts.offset });\n bubble.style.top = `${r.top}px`;\n bubble.style.left = `${r.left}px`;\n bubble.style.setProperty('--fw-tooltip-arrow-pos', `${r.arrowOffset}px`);\n bubble.setAttribute('data-placement', r.placement);\n}\n\nfunction scheduleReposition(): void {\n cancelAnimationFrame(repositionRaf);\n repositionRaf = requestAnimationFrame(reposition);\n}\n\nfunction showNow(trigger: HTMLElement): void {\n clearTimeout(showTimer);\n cancelHide();\n const opts = optsByTrigger.get(trigger);\n if (!opts) return;\n activeTrigger = trigger;\n const el = ensureBubble();\n el.textContent = trigger.dataset.fwTooltipText ?? '';\n reposition();\n el.classList.add('is-open');\n window.addEventListener('scroll', scheduleReposition, true);\n window.addEventListener('resize', scheduleReposition);\n}\n\nfunction hideNow(): void {\n clearTimeout(showTimer);\n clearTimeout(hideTimer);\n if (bubble) bubble.classList.remove('is-open');\n window.removeEventListener('scroll', scheduleReposition, true);\n window.removeEventListener('resize', scheduleReposition);\n cancelAnimationFrame(repositionRaf);\n if (activeTrigger) lastHiddenAt = performance.now();\n activeTrigger = null;\n}\n\nfunction requestShow(trigger: HTMLElement, instant: boolean): void {\n clearTimeout(hideTimer);\n clearTimeout(showTimer);\n const opts = optsByTrigger.get(trigger);\n if (!opts) return;\n if (instant || performance.now() - lastHiddenAt < SKIP_DELAY_WINDOW) {\n showNow(trigger);\n } else {\n showTimer = window.setTimeout(() => showNow(trigger), opts.delay);\n }\n}\n\nfunction requestHide(): void {\n clearTimeout(showTimer);\n clearTimeout(hideTimer);\n hideTimer = window.setTimeout(hideNow, HIDE_GRACE);\n}\n\nexport function tooltip(trigger: HTMLElement, opts: TooltipOptions = {}): TooltipInstance {\n const resolved: ResolvedOptions = {\n placement: opts.placement ?? 'top',\n offset: opts.offset ?? 6,\n delay: opts.delay ?? SHOW_DELAY_DEFAULT,\n };\n optsByTrigger.set(trigger, resolved);\n\n const title = trigger.getAttribute('title');\n if (title !== null) {\n trigger.dataset.fwTooltipText = title;\n trigger.removeAttribute('title');\n }\n trigger.setAttribute('aria-describedby', 'fw-tooltip');\n\n const onMouseenter = () => requestShow(trigger, false);\n const onMouseleave = () => requestHide();\n const onFocus = () => requestShow(trigger, true);\n const onBlur = () => {\n if (activeTrigger === trigger) hideNow();\n };\n const onKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && activeTrigger === trigger) hideNow();\n };\n\n trigger.addEventListener('mouseenter', onMouseenter);\n trigger.addEventListener('mouseleave', onMouseleave);\n trigger.addEventListener('focus', onFocus);\n trigger.addEventListener('blur', onBlur);\n trigger.addEventListener('keydown', onKeydown);\n\n return {\n show: () => requestShow(trigger, true),\n hide: () => {\n if (activeTrigger === trigger) hideNow();\n },\n destroy() {\n if (activeTrigger === trigger) hideNow();\n trigger.removeEventListener('mouseenter', onMouseenter);\n trigger.removeEventListener('mouseleave', onMouseleave);\n trigger.removeEventListener('focus', onFocus);\n trigger.removeEventListener('blur', onBlur);\n trigger.removeEventListener('keydown', onKeydown);\n trigger.removeAttribute('aria-describedby');\n if (trigger.dataset.fwTooltipText !== undefined) {\n trigger.setAttribute('title', trigger.dataset.fwTooltipText);\n delete trigger.dataset.fwTooltipText;\n }\n optsByTrigger.delete(trigger);\n delete trigger.dataset.fwBound;\n },\n };\n}\n\n/** Wire every `[data-fw-tooltip]` under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[data-fw-tooltip]').forEach((trigger) => {\n if (trigger.dataset.fwBound) return;\n trigger.dataset.fwBound = '1';\n tooltip(trigger, {\n placement: (trigger.dataset.fwTooltipPlacement as Placement) || undefined,\n offset: trigger.dataset.fwTooltipOffset ? Number(trigger.dataset.fwTooltipOffset) : undefined,\n delay: trigger.dataset.fwTooltipDelay ? Number(trigger.dataset.fwTooltipDelay) : undefined,\n });\n });\n}\n", "/**\n * Tabs \u2014 a single-selection tablist that switches between panels.\n *\n * <div class=\"fw-tablist\" role=\"tablist\" aria-label=\"Account settings\" data-fw-tabs>\n * <button type=\"button\" class=\"fw-tab\" id=\"tab-profile\" role=\"tab\" aria-selected=\"true\" aria-controls=\"panel-profile\">Profile</button>\n * <button type=\"button\" class=\"fw-tab\" id=\"tab-billing\" role=\"tab\" aria-selected=\"false\" aria-controls=\"panel-billing\">Billing</button>\n * </div>\n * <div class=\"fw-tabpanel\" id=\"panel-profile\" role=\"tabpanel\" aria-labelledby=\"tab-profile\" tabindex=\"0\">\u2026</div>\n * <div class=\"fw-tabpanel\" id=\"panel-billing\" role=\"tabpanel\" aria-labelledby=\"tab-billing\" tabindex=\"0\" hidden>\u2026</div>\n *\n * Author `aria-selected=\"true\"` on the tab that should start selected (the\n * rest `\"false\"`); `init()` derives roving `tabIndex` (0 on the selected tab,\n * -1 on the rest) and each panel's `hidden` from that. Falls back to the\n * first non-disabled tab if none is marked selected. A tab may carry\n * `aria-disabled=\"true\"` to make it non-interactive \u2014 it is skipped by\n * click, arrow-key, and Home/End navigation.\n *\n * `data-fw-tabs-activation=\"manual\"` on the tablist switches from the\n * default \"automatic\" activation (arrow keys move focus AND select) to\n * \"manual\" (arrow keys only move focus; Space/Enter selects the focused\n * tab) \u2014 use manual when selecting a tab is expensive (e.g. triggers a\n * fetch).\n *\n * `aria-orientation=\"vertical\"` on the tablist swaps the primary arrow keys\n * from Left/Right to Up/Down, per WAI-ARIA APG. Left/Right invert under RTL.\n *\n * Events (bubbling, from the tablist): `fw:tabs-change` { tab, panel }.\n */\nexport type TabsActivation = 'automatic' | 'manual';\n\nexport interface TabsOptions {\n activation?: TabsActivation;\n}\n\nexport interface TabsInstance {\n activate(tab: HTMLElement, focus?: boolean): void;\n destroy(): void;\n}\n\nexport interface TabsChangeDetail {\n tab: HTMLElement;\n panel: HTMLElement;\n}\n\nfunction emit(tablist: HTMLElement, detail: TabsChangeDetail): void {\n tablist.dispatchEvent(new CustomEvent('fw:tabs-change', { bubbles: true, detail }));\n}\n\nfunction isDisabled(tab: HTMLElement): boolean {\n return tab.getAttribute('aria-disabled') === 'true';\n}\n\nfunction panelFor(tab: HTMLElement): HTMLElement | null {\n const id = tab.getAttribute('aria-controls');\n return id ? document.getElementById(id) : null;\n}\n\nfunction closestTab(target: EventTarget | null): HTMLElement | null {\n return target instanceof Element ? target.closest<HTMLElement>('[role=\"tab\"]') : null;\n}\n\n/** The next non-disabled tab `step` positions from `from`, wrapping around. Undefined if every tab is disabled. */\nfunction nextEnabled(list: HTMLElement[], from: number, step: 1 | -1): HTMLElement | undefined {\n for (let n = 1; n <= list.length; n++) {\n const idx = (((from + step * n) % list.length) + list.length) % list.length;\n if (!isDisabled(list[idx])) return list[idx];\n }\n return undefined;\n}\n\nfunction firstEnabled(list: HTMLElement[]): HTMLElement | undefined {\n return list.find((t) => !isDisabled(t));\n}\n\nfunction lastEnabled(list: HTMLElement[]): HTMLElement | undefined {\n for (let i = list.length - 1; i >= 0; i--) {\n if (!isDisabled(list[i])) return list[i];\n }\n return undefined;\n}\n\nexport function tabs(tablist: HTMLElement, opts: TabsOptions = {}): TabsInstance {\n const activation = opts.activation ?? 'automatic';\n\n function allTabs(): HTMLElement[] {\n return Array.from(tablist.querySelectorAll<HTMLElement>('[role=\"tab\"]'));\n }\n\n function activate(tab: HTMLElement, focus = false): void {\n if (isDisabled(tab)) return;\n allTabs().forEach((t) => {\n const selected = t === tab;\n t.setAttribute('aria-selected', String(selected));\n t.tabIndex = selected ? 0 : -1;\n const panel = panelFor(t);\n if (panel) panel.hidden = !selected;\n });\n if (focus) tab.focus();\n const panel = panelFor(tab);\n if (panel) emit(tablist, { tab, panel });\n }\n\n /** Manual-activation arrow move: roving tabindex follows focus, selection is untouched. */\n function focusOnly(tab: HTMLElement): void {\n allTabs().forEach((t) => {\n t.tabIndex = t === tab ? 0 : -1;\n });\n tab.focus();\n }\n\n function syncFromSelected(): void {\n const list = allTabs();\n const selected = list.find((t) => t.getAttribute('aria-selected') === 'true') ?? firstEnabled(list);\n list.forEach((t) => {\n const isSelected = t === selected;\n t.setAttribute('aria-selected', String(isSelected));\n t.tabIndex = isSelected ? 0 : -1;\n const panel = panelFor(t);\n if (panel) panel.hidden = !isSelected;\n });\n }\n\n function onClick(e: MouseEvent): void {\n const tab = closestTab(e.target);\n if (tab && tablist.contains(tab)) activate(tab, false);\n }\n\n function onKeydown(e: KeyboardEvent): void {\n const tab = closestTab(e.target);\n if (!tab) return;\n const list = allTabs();\n const i = list.indexOf(tab);\n if (i === -1) return;\n\n if (e.key === ' ' || e.key === 'Enter') {\n if (activation === 'manual') {\n e.preventDefault();\n activate(tab, false);\n }\n return;\n }\n\n const vertical = tablist.getAttribute('aria-orientation') === 'vertical';\n const rtl = getComputedStyle(tablist).direction === 'rtl';\n const nextKey = vertical ? 'ArrowDown' : rtl ? 'ArrowLeft' : 'ArrowRight';\n const prevKey = vertical ? 'ArrowUp' : rtl ? 'ArrowRight' : 'ArrowLeft';\n\n let dest: HTMLElement | undefined;\n if (e.key === nextKey) dest = nextEnabled(list, i, 1);\n else if (e.key === prevKey) dest = nextEnabled(list, i, -1);\n else if (e.key === 'Home') dest = firstEnabled(list);\n else if (e.key === 'End') dest = lastEnabled(list);\n else return;\n\n if (!dest) return;\n e.preventDefault();\n if (activation === 'manual') focusOnly(dest);\n else activate(dest, true);\n }\n\n tablist.addEventListener('click', onClick);\n tablist.addEventListener('keydown', onKeydown);\n syncFromSelected();\n\n return {\n activate,\n destroy() {\n tablist.removeEventListener('click', onClick);\n tablist.removeEventListener('keydown', onKeydown);\n delete tablist.dataset.fwBound;\n },\n };\n}\n\n/** Wire every `[role=\"tablist\"][data-fw-tabs]` under `root`. */\nexport function init(root: ParentNode = document): void {\n root.querySelectorAll<HTMLElement>('[role=\"tablist\"][data-fw-tabs]').forEach((tablist) => {\n if (tablist.dataset.fwBound) return;\n tablist.dataset.fwBound = '1';\n const activation: TabsActivation = tablist.dataset.fwTabsActivation === 'manual' ? 'manual' : 'automatic';\n tabs(tablist, { activation });\n });\n}\n", "/**\n * Fernwell \u2014 vanilla JS enhancers for the Fernwell design system.\n *\n * ESM / CJS: import { init, theme, toast } from 'fernwell'; init();\n * <script>: <script src=\"https://unpkg.com/fernwell/dist/fernwell.iife.js\"></script>\n * \u2192 window.Fernwell, auto-initialised on DOMContentLoaded\n * (add data-fw-no-init to the <script> tag to opt out).\n */\nimport * as theme from './theme.js';\nimport * as tokens from './tokens.js';\nimport * as combobox from './combobox.js';\nimport * as modal from './modal.js';\nimport * as nav from './nav.js';\nimport * as loading from './loading.js';\nimport * as toast from './toast.js';\nimport * as table from './table.js';\nimport * as menu from './menu.js';\nimport * as icon from './icon.js';\nimport * as popover from './popover.js';\nimport * as tooltip from './tooltip.js';\nimport * as tabs from './tabs.js';\n\nexport { theme, tokens, combobox, modal, nav, loading, toast, table, menu, icon, popover, tooltip, tabs };\nexport type { Theme } from './theme.js';\nexport type { TokenName } from './_tokenData.js';\nexport type {\n TokenKey,\n TokenOverrides,\n TokenThemeOverrides,\n SetTokensOptions,\n TokensChangeDetail,\n} from './tokens.js';\nexport type { ComboboxOptions, ComboboxInstance } from './combobox.js';\nexport type { ToastVariant, ToastOptions } from './toast.js';\nexport type { SortDirection, SortDetail, SelectDetail } from './table.js';\nexport type { ToggleDetail } from './menu.js';\nexport type { IconName } from './icon.js';\nexport type { PopoverOptions, PopoverInstance } from './popover.js';\nexport type { TooltipOptions, TooltipInstance } from './tooltip.js';\nexport type { TabsOptions, TabsInstance, TabsActivation, TabsChangeDetail } from './tabs.js';\n\nexport const version: string = \"0.5.0\";\n\n/**\n * Wire every `data-fw-*` hook under `root`. Safe to call more than once \u2014\n * already-bound elements are skipped \u2014 so call it again after injecting\n * markup (e.g. after an HTMX / Turbo swap).\n */\nexport function init(root: ParentNode = document): void {\n theme.init(root);\n tokens.init(root);\n combobox.init(root);\n modal.init(root);\n nav.init(root);\n loading.init(root);\n table.init(root);\n menu.init(root);\n icon.init(root);\n popover.init(root);\n tooltip.init(root);\n tabs.init(root);\n}\n\nconst Fernwell = {\n version,\n init,\n theme,\n tokens,\n combobox,\n modal,\n nav,\n loading,\n toast,\n table,\n menu,\n icon,\n popover,\n tooltip,\n tabs,\n};\nexport default Fernwell;\n"],
5
+ "mappings": "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",
6
+ "names": ["theme_exports", "__export", "get", "getToken", "init", "resetTokens", "set", "setTokens", "toggle", "icon_exports", "__export", "init", "render", "icons", "name", "inner", "root", "el", "_a", "markup", "tokens_exports", "__export", "getToken", "init", "resetTokens", "restoreTokens", "setTokens", "DERIVED", "TOKEN_PREFIX", "STYLE_ATTR", "STORE_TOKENS", "STORE_CSS", "EVENT", "ROOT", "saved", "live", "hydrated", "scopeSeq", "hooks", "swept", "store", "normalizeTokenName", "name", "bareName", "warn", "message", "validScope", "scope", "balanced", "value", "depth", "quote", "i", "c", "sanitize", "tokens", "out", "isThemeSplit", "v", "splitSelectors", "list", "parts", "start", "darkSelector", "part", "declBlock", "derivedAt", "overrides", "theme", "explicit", "affected", "grew", "d", "DERIVED", "dep", "rulesFor", "layer", "rules", "light", "dark", "root", "l", "styleEl", "create", "existing", "el", "persist", "s", "scopes", "entry", "render", "_a", "assign", "target", "values", "previous", "k", "old", "setTokens", "opts", "_b", "load", "undoLight", "undoDark", "done", "resetTokens", "hook", "hadSaved", "restoreTokens", "parsed", "raw", "getToken", "parseJSON", "source", "what", "sweep", "isBound", "bind", "undo", "init", "id", "STORAGE_KEY", "EVENT", "INIT_ATTR", "store", "get", "_a", "attr", "set", "theme", "persist", "btn", "syncToggle", "toggle", "next", "iconName", "label", "icon", "render", "afterPaint", "cb", "raf", "fn", "init", "root", "_b", "_c", "_d", "stored", "current", "html", "e", "combobox_exports", "__export", "combobox", "init", "uid", "escapeHtml", "s", "c", "input", "opts", "_a", "_b", "_c", "_d", "filter", "o", "q", "emptyText", "options", "readDatalist", "current", "activeIndex", "selecting", "listId", "wrap", "wrapInput", "list", "id", "render", "matches", "opt", "i", "idx", "label", "open", "close", "highlight", "items", "el", "select", "value", "onInput", "onFocus", "onKeydown", "e", "onListMousedown", "onDocClick", "next", "dl", "root", "modal_exports", "__export", "bindOutsideClickToClose", "close", "init", "open", "toggle", "OPEN", "LOCK", "openStack", "openers", "FOCUSABLE", "resolve", "target", "backdropFor", "el", "explicit", "prev", "opener", "_a", "first", "_b", "_c", "i", "backdrop", "onClose", "downOnBackdrop", "e", "keyBound", "root", "btn", "id", "overlay", "drawer", "nav_exports", "__export", "close", "init", "open", "OPEN", "toggle", "panel", "panelFor", "id", "root", "_a", "_b", "container", "e", "loading_exports", "__export", "init", "resetAll", "resetButtonLoading", "setButtonLoading", "LOADING", "btn", "loadingText", "_a", "_b", "label", "root", "pageshowBound", "form", "e", "toast_exports", "__export", "hide", "show", "el", "timer", "ensure", "message", "variant", "duration", "node", "table_exports", "__export", "getSelected", "init", "selectAll", "setRowSelected", "sort", "SELECTED", "emit", "table", "name", "detail", "cellValue", "row", "column", "_a", "_b", "_c", "cell", "compare", "a", "b", "na", "nb", "sortHeaders", "nextDirection", "th", "direction", "tbody", "rows", "sortable", "r", "rest", "sign", "active", "isTarget", "rowInputs", "applyRowState", "on", "syncSelectAll", "all", "inputs", "n", "i", "input", "root", "e", "target", "menu_exports", "__export", "close", "collapseAll", "expandAll", "init", "open", "reveal", "toggle", "GROUP", "ROW", "CURRENT", "emit", "group", "detail", "force", "root", "el", "_a", "_b", "_c", "_d", "syncCurrent", "menu", "summary", "holdsCurrent", "ownGroup", "row", "parentGroup", "isVisible", "g", "visibleRows", "focusRow", "splitToggleFor", "link", "item", "onKeydown", "e", "rows", "i", "handled", "parent", "exclusive", "sibling", "popover_exports", "__export", "init", "popover", "OPPOSITE_SIDE", "ARROW_INSET", "parsePlacement", "p", "ALIGN_SUFFIX", "toPlacement", "side", "align", "mainAxisSpace", "anchor", "vw", "vh", "mainAxisCoord", "floating", "offset", "crossAxisCoord", "anchorStart", "anchorSize", "floatingSize", "clamp", "value", "min", "max", "computePosition", "opts", "_a", "_b", "_c", "preferred", "padding", "a", "f", "preferredSide", "oppositeSide", "needed", "top", "left", "arrowOffset", "bindOutsideDismiss", "anchors", "onDismiss", "isOutside", "target", "el", "downOutside", "onMousedown", "e", "onClick", "FOCUSABLE", "popover", "trigger", "panel", "opts", "_a", "_b", "placement", "offset", "originalParent", "originalNextSibling", "isOpen", "unbindOutside", "raf", "reposition", "r", "computePosition", "scheduleReposition", "onKeydown", "e", "close", "onFocusOut", "next", "active", "open", "first", "bindOutsideDismiss", "toggle", "onTriggerClick", "closeButtons", "onCloseClick", "btn", "init", "root", "id", "tooltip_exports", "__export", "init", "tooltip", "SHOW_DELAY_DEFAULT", "SKIP_DELAY_WINDOW", "HIDE_GRACE", "optsByTrigger", "bubble", "activeTrigger", "showTimer", "hideTimer", "repositionRaf", "lastHiddenAt", "ensureBubble", "el", "cancelHide", "requestHide", "reposition", "opts", "r", "computePosition", "scheduleReposition", "showNow", "trigger", "_a", "hideNow", "requestShow", "instant", "tooltip", "_b", "_c", "resolved", "title", "onMouseenter", "onMouseleave", "onFocus", "onBlur", "onKeydown", "e", "init", "root", "tabs_exports", "__export", "init", "tabs", "emit", "tablist", "detail", "isDisabled", "tab", "panelFor", "id", "closestTab", "target", "nextEnabled", "list", "from", "step", "n", "idx", "firstEnabled", "lastEnabled", "i", "opts", "_a", "activation", "allTabs", "activate", "focus", "t", "selected", "panel", "focusOnly", "syncFromSelected", "isSelected", "onClick", "e", "onKeydown", "vertical", "rtl", "nextKey", "prevKey", "dest", "root", "version", "init", "root", "Fernwell", "theme_exports", "tokens_exports", "combobox_exports", "modal_exports", "nav_exports", "loading_exports", "toast_exports", "table_exports", "menu_exports", "icon_exports", "popover_exports", "tooltip_exports", "tabs_exports", "index_default"]
7
7
  }