fernwell 0.3.0 → 0.4.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,28 @@ All notable changes to this project are documented here. The format follows [Kee
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.4.0] — 2026-09-16
8
+
9
+ ### Changed (breaking)
10
+
11
+ - **`.fw-modal` markup requires a new `.fw-modal-scroll` wrapper around its head/body/foot.** `.fw-modal` itself now only holds the rounded shape (radius, shadow, clip); `.fw-modal-scroll` is the actual scrolling region (`max-height`, `overflow-y: auto`, padding). Splitting them keeps the custom scrollbar clipped to the panel's rounded corners instead of cutting through them — `overflow` on an element doesn't clip that same element's own scrollbar decoration.
12
+ - **`.fw-table-wrap` markup requires a new `.fw-table-scroll` wrapper around the `<table>`.** `.fw-table-wrap` now only holds the rounded card shape (border, radius, shadow, clip); `.fw-table-scroll` is the scrolling region and carries what used to live on `.fw-table-wrap` — `tabindex="0"`, `role="region"`, the horizontal `overflow-x: auto`, and (with `.fw-table-sticky`) `--fw-table-max-height`. Same clipping rationale as the Modal change above.
13
+
14
+ ### Added
15
+
16
+ - **Icon component** (`src/css/components/icon.css`, `src/js/icon.ts`): a built-in set of ~45 SVG icons rendered into `[data-fw-icon="name"]` elements (`<span class="fw-icon" data-fw-icon="trash" aria-hidden="true">`), sized in `em` and colored via inherited `color` so an icon always matches the surrounding text. Decorative by default — give the accessible name to a wrapping interactive element (e.g. `aria-label` on a button). Exports `render(name)` and the `IconName` type; docs and other components (nav toggle, theme toggle, table actions, popover close button) now use it in place of emoji.
17
+ - **Popover component** (`src/css/components/popover.css`, `src/js/popover.ts`): a non-modal floating panel anchored to a trigger via `data-fw-popover-trigger="id"`, with `-placement` (`top`/`bottom`/`left`/`right` or a corner variant) and `-offset` options. Flips/shifts to stay in the viewport, closes on Escape, outside-click, focus-out, or `[data-fw-popover-close]`, and returns focus to the trigger. Renders `aria-modal="false"` per WAI-ARIA APG, so it does not trap Tab. Moves to the end of `<body>` while open so its `position: fixed` isn't broken by an ancestor with `transform`/`filter`/`contain`. Emits `fw:open` / `fw:close`. Exports `popover()`, `PopoverOptions`, `PopoverInstance`.
18
+ - **Tooltip component** (`src/css/components/tooltip.css`, `src/js/tooltip.ts`): a short hover/focus annotation sourced from the trigger's `title` attribute (`data-fw-tooltip`), with `-placement`, `-offset`, and `-delay` options. A single shared bubble instance (like `toast.ts`) is hoverable and dismissible per WCAG 2.1 SC 1.4.13, and closes on Escape. Exports `tooltip()`, `TooltipOptions`, `TooltipInstance`.
19
+ - **Tabs component** (`src/css/components/tabs.css`, `src/js/tabs.ts`): a single-selection `role="tablist"` that switches `role="tabpanel"` visibility, authored via `aria-selected` and wired up by `data-fw-tabs`. Arrow-key, Home/End navigation with roving `tabindex`; `aria-orientation="vertical"` swaps to Up/Down; `data-fw-tabs-activation="manual"` switches from automatic (arrow keys select) to manual (arrow keys move focus, Space/Enter selects) activation. A tab may carry `aria-disabled="true"` to be skipped by navigation. Emits `fw:tabs-change`. Exports `TabsOptions`, `TabsInstance`, `TabsActivation`, `TabsChangeDetail`.
20
+ - **Divider component** (`src/css/components/divider.css`): `.fw-divider` (default `<hr>`), horizontal or vertical via `aria-orientation="vertical"` (both the semantic and visual trigger — no separate modifier class), `-dashed` / `-dotted` style variants, and a labeled variant (`.fw-divider-labeled`, with `-start` / `-end` alignment) for "── text ──" section breaks.
21
+ - **Spacer component** (`src/css/components/spacer.css`): `.fw-spacer`, a fixed-size empty box for manual gap control where `gap` on `.fw-row`/`.fw-grid-2` isn't applicable. `data-fw-axis` (`horizontal` / `both`, default vertical) and `data-fw-size` (`1`–`9`, or `auto` for a flex filler that absorbs remaining space) control direction and size via `--fw-sp-*` tokens.
22
+ - **Aspect-ratio component** (`src/css/components/aspect-ratio.css`): `.fw-aspect-ratio` crops a wrapped `<img>`/`<video>`/`<iframe>` (or `.fw-aspect-ratio-media`) to a fixed ratio via `object-fit: cover`. `data-fw-ratio` presets (`1:1`, `4:3`, `16:9`, `21:9`) or an inline `--fw-aspect-ratio` for arbitrary ratios; `data-fw-fit="contain"` switches the fit mode.
23
+ - **Token-colored custom scrollbars** (`src/css/components/scrollbar.css`): `.fw-root` and Fernwell's own internal scroll regions (`.fw-modal-scroll`, `.fw-drawer-body`, `.fw-table-scroll`) now render a thin, theme-aware scrollbar (`scrollbar-width`/`scrollbar-color`, with a `::-webkit-scrollbar-*` fallback for older WebKit/Chromium) instead of the browser default. New tokens: `--fw-scrollbar-thumb`, `--fw-scrollbar-thumb-hover`, `--fw-scrollbar-track` (Table overrides the track to `--fw-bg-dim` so its scrollbar reads as clearly present, since tabular data needs an obvious "more to scroll" cue). `.fw-tablist` also gets a static two-edge fade mask on its scroll axis as a discoverability cue for overflow tabs.
24
+ - Theme toggle (`theme.ts`) now supports a real icon instead of an emoji via `data-fw-theme-icon-dark` / `data-fw-theme-icon-light` (icon names from the new icon component), optionally alongside a `-label-` pair which is appended as text after the icon.
25
+ - `theme.init()` no longer animates the theme it applies on page load — only a later toggle or live OS change animates — so a themed page never flashes a cross-fade of its own initial colors.
26
+ - Docs: new **Popover**, **Tooltip**, and **Tabs** sections with live demos on the Components page; icon usage throughout the docs replaces the previous emoji placeholders.
27
+ - Dev workflow: `npm run dev` now runs `scripts/dev.mjs`, a hot-reloading dev server (previously a one-shot `build && docs`), watching source files and rebuilding/reloading automatically.
28
+
7
29
  ## [0.3.0] — 2026-09-15
8
30
 
9
31
  ### Added
package/README.md CHANGED
@@ -69,7 +69,7 @@ Set `data-theme="dark"` on `<html>` (or any ancestor) and every token flips. A `
69
69
  data-fw-theme-label-light="🌙 Dark" data-fw-theme-label-dark="☀️ Light">🌙 Dark</button>
70
70
  ```
71
71
 
72
- To avoid a flash of the wrong theme, inline this in `<head>` before the stylesheet:
72
+ `init()` never animates the theme it applies on load (toggling and live OS changes still do), but to also avoid a flash of the *wrong* theme's colours before that script runs at all, inline this in `<head>` before the stylesheet:
73
73
 
74
74
  ```html
75
75
  <script>document.documentElement.dataset.theme=localStorage.getItem('fw-theme')||(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light')</script>
@@ -175,13 +175,15 @@ All class names are prefixed `fw-`; state classes are `is-*`. Each stylesheet in
175
175
  | Nav | `.fw-nav` (`-sticky`), `-brand`, `-dot` / `-hex`, `-links`, `-right`, `-avatar`, `-btn`, `-toggle`, `-dropdown` (`-menu`) |
176
176
  | Stat | `.fw-stat-label` `-value` (`-unit`) `-delta` (`.is-up` / `.is-down`) |
177
177
  | Empty state | `.fw-empty`, `-blob`, `-title`, `-body` |
178
- | Modal | `.fw-modal-overlay` > `.fw-modal` (`-wide`); `-head`, `-title`, `-sub`, `-foot` |
178
+ | Modal | `.fw-modal-overlay` > `.fw-modal` (`-wide`) > `.fw-modal-scroll` (the scrolling region — keeps the scrollbar clipped to the panel's rounded corners) > `-head`, `-title`, `-sub`, `-foot` |
179
179
  | Drawer | `.fw-drawer-overlay` + `.fw-drawer`; `-head`, `-eyebrow`, `-title`, `-body`, `-foot` |
180
+ | Popover | `.fw-popover` (`role="dialog"`, non-modal); `-head`, `-title`, `-body` |
181
+ | Tooltip | `.fw-tooltip` (`role="tooltip"`, singleton, created on first show) |
180
182
  | Toast | `.fw-toast` + `-error` `-info` `-pending` (created by `toast.show`) |
181
183
  | List row | `.fw-list-row` (`.is-locked`), `-main`, `-title`, `-meta`; `.fw-sub-list` |
182
184
  | Disclosure | `details.fw-disclosure`, `-chevron`, `-count`, `-body` |
183
185
  | Pagination | `.fw-pagination`, `.fw-pag-info`, `.fw-pag-controls`, `.fw-pag-label`, `.fw-btn-page` |
184
- | Table | `.fw-table-wrap` (`.fw-table-sticky` + `--fw-table-max-height`) > `.fw-table` (`-striped`, `-compact`); cells `.fw-table-num`, `.fw-table-actions`, `.fw-table-select`; `th[aria-sort] > .fw-table-sort`; rows `.fw-table-empty`, `.fw-table-loading`, `.is-selected`; `[aria-busy="true"]` dims the body |
186
+ | Table | `.fw-table-wrap` (`.fw-table-sticky`) > `.fw-table-scroll` (the scrolling region — carries `tabindex="0" role="region"`, bounded by `--fw-table-max-height` when sticky, kept separate from `.fw-table-wrap` so the scrollbar stays clipped to the card's rounded corners) > `.fw-table` (`-striped`, `-compact`); cells `.fw-table-num`, `.fw-table-actions`, `.fw-table-select`; `th[aria-sort] > .fw-table-sort`; rows `.fw-table-empty`, `.fw-table-loading`, `.is-selected`; `[aria-busy="true"]` dims the body |
185
187
  | Collapsible menu | `.fw-menu` (`-accordion`) > `.fw-menu-list` > `.fw-menu-item` (`.fw-menu-split`) > `.fw-menu-link` or `details.fw-menu-group` > `.fw-menu-summary` (`-icon`, `.is-current`) + nested `.fw-menu-list` or `.fw-menu-panel`; `[aria-current="page"]` marks the current link; `--fw-menu-indent`, `--fw-menu-row-h` |
186
188
  | Layout | `.fw-wrap`, `.fw-row`, `.fw-grid-2`, `.fw-sr-only` |
187
189
 
@@ -195,6 +197,8 @@ Everything is progressive enhancement over plain HTML. `init(root?)` is idempote
195
197
  | `input[data-fw-combobox]` | typeahead over the `<datalist>` in `list=` (↑ ↓ Enter Esc, `aria-activedescendant`) |
196
198
  | `[data-fw-open-modal="id"]` / `[data-fw-close-modal]` | modal with backdrop-click (drag-safe), Escape, focus return, scroll lock |
197
199
  | `[data-fw-open-drawer="id"]` / `[data-fw-close-drawer]` / `[data-fw-drawer-overlay="id"]` | same for drawers |
200
+ | `[data-fw-popover-trigger="id"]` (+ `-placement`, `-offset`) / `[data-fw-popover-close]` | non-modal floating panel: flip/shift to stay in the viewport, Escape, outside-click, focus-out, and close-button dismissal, focus return to trigger |
201
+ | `[data-fw-tooltip]` (+ `-placement`, `-offset`, `-delay`) | hover (with delay) or focus (instant) tooltip sourced from the trigger's `title`; hoverable per WCAG 1.4.13, dismisses on Escape |
198
202
  | `[data-fw-nav-toggle][aria-controls]` | dropdown open/close, outside-click and Escape |
199
203
  | `form[data-fw-loading]` | submit button gets a spinner + `data-fw-loading-text` label on submit |
200
204
  | `table[data-fw-table]` with `th[data-fw-sort]`, `input[data-fw-select-all]` / `[data-fw-select-row]` | client-side column sort (cycles `aria-sort`, honours `td[data-fw-sort-value]`), row selection with select-all + indeterminate, `.is-selected` / `aria-selected` on rows |
@@ -203,7 +207,7 @@ Everything is progressive enhancement over plain HTML. `init(root?)` is idempote
203
207
  Programmatic API:
204
208
 
205
209
  ```js
206
- import { theme, combobox, modal, nav, loading, toast, table, menu } from 'fernwell';
210
+ import { theme, combobox, modal, nav, loading, toast, table, menu, popover, tooltip } from 'fernwell';
207
211
 
208
212
  theme.get();
209
213
  theme.set('dark');
@@ -229,9 +233,13 @@ table.selectAll(tableEl, false);
229
233
  menu.open(groupEl); menu.close(groupEl); menu.toggle(groupEl); // groupEl = details.fw-menu-group
230
234
  menu.reveal(linkEl); // open every ancestor group of an element
231
235
  menu.expandAll(menuEl); menu.collapseAll(menuEl);
236
+ const pop = popover(triggerEl, panelEl, { placement: 'bottom', offset: 8 });
237
+ pop.open(); pop.close(); pop.toggle(); pop.destroy();
238
+ const tip = tooltip(triggerEl, { placement: 'top', delay: 400 });
239
+ tip.show(); tip.hide(); tip.destroy();
232
240
  ```
233
241
 
234
- Events: `fw:themechange` on `document` (detail: `'light' | 'dark'`), `fw:open` / `fw:close` bubbling from the modal or drawer, `fw:sort` (detail: `{ column, direction, th }`) and `fw:select` (detail: `{ rows, all }`) bubbling from the table, `fw:toggle` (detail: `{ group, open }`) bubbling from a `.fw-menu-group`.
242
+ Events: `fw:themechange` on `document` (detail: `'light' | 'dark'`), `fw:open` / `fw:close` bubbling from the modal, drawer, or popover, `fw:sort` (detail: `{ column, direction, th }`) and `fw:select` (detail: `{ rows, all }`) bubbling from the table, `fw:toggle` (detail: `{ group, open }`) bubbling from a `.fw-menu-group`.
235
243
 
236
244
  ## Principles
237
245
 
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Internal positioning helpers shared by popover.ts and tooltip.ts. Not part
3
+ * of the public API — not re-exported from index.ts.
4
+ *
5
+ * Both callers use `position: fixed`, so all math here is viewport-relative
6
+ * (matching `getBoundingClientRect()`) rather than document-relative.
7
+ */
8
+ export type Side = 'top' | 'bottom' | 'left' | 'right';
9
+ /**
10
+ * `top` / `bottom` / `left` / `right` center the floating element on the
11
+ * anchor's cross-axis midpoint. `top-left` / `top-right` / `bottom-left` /
12
+ * `bottom-right` keep the anchor above/below but shift the floating element
13
+ * so it leans toward that corner instead of centering — useful to steer a
14
+ * panel away from something else on the page (another fixed control, a
15
+ * viewport edge) without losing the "above/below the trigger" placement.
16
+ *
17
+ * "Lean right" means the floating element's LEFT edge lines up with the
18
+ * anchor's left edge, so the (usually wider) box extends further right of
19
+ * the anchor than a centered box would; "lean left" mirrors that off the
20
+ * anchor's right edge.
21
+ */
22
+ export type Placement = Side | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
23
+ export interface PositionOptions {
24
+ /** Preferred placement. */
25
+ placement?: Placement;
26
+ /** Gap between anchor and floating element, px. */
27
+ offset?: number;
28
+ /** Minimum distance from the viewport edge, px. */
29
+ padding?: number;
30
+ }
31
+ export interface PositionResult {
32
+ /** Final placement, after a possible flip. */
33
+ placement: Placement;
34
+ top: number;
35
+ left: number;
36
+ /**
37
+ * Distance, in px, from the floating element's near edge (left, for a
38
+ * top/bottom placement; top, for a left/right placement) to the anchor's
39
+ * center — for positioning an optional arrow so it keeps pointing at the
40
+ * anchor even after the cross-axis got clamped to stay in the viewport.
41
+ * Already inset from the floating element's own edges so the arrow never
42
+ * overhangs a rounded corner.
43
+ */
44
+ arrowOffset: number;
45
+ }
46
+ /**
47
+ * Positions `floating` relative to `anchor`: flips to the opposite side when
48
+ * the preferred side doesn't fit and the opposite side has more room (a
49
+ * 2-entry fallback, not a 4-way rotation — both callers are single-edge
50
+ * anchored, unlike a corner-anchored menu), and clamps the cross-axis into
51
+ * the viewport ("shift") rather than flipping it.
52
+ *
53
+ * The cross-axis is centered on the anchor by default (`align: 'center'`,
54
+ * implied by a bare `top`/`bottom`/`left`/`right` placement) — the corner
55
+ * placements (`top-left`, etc.) opt into edge-alignment instead. Centering
56
+ * is what makes an arrow drawn at the floating element's own midpoint line
57
+ * up with the anchor; `arrowOffset` carries the exact anchor-relative
58
+ * position so the arrow still lines up even when a corner placement or a
59
+ * viewport clamp shifts the box off-center.
60
+ */
61
+ export declare function computePosition(anchor: HTMLElement, floating: HTMLElement, opts?: PositionOptions): PositionResult;
62
+ /**
63
+ * Fires `onDismiss` only when a click lands outside every element in
64
+ * `anchors` — generalizes modal.ts's `bindOutsideClickToClose` (which checks
65
+ * a single backdrop) to an arbitrary set of "not outside" elements (e.g. a
66
+ * popover's trigger AND its panel).
67
+ *
68
+ * Guards the same false positive: a browser's `click` fires on the nearest
69
+ * common ancestor of mousedown and mouseup, so a text-selection drag that
70
+ * starts inside an anchor and ends outside it would otherwise look like an
71
+ * outside click. Close only when BOTH mousedown and click landed outside.
72
+ */
73
+ export declare function bindOutsideDismiss(anchors: HTMLElement[], onDismiss: () => void): () => void;
package/dist/fernwell.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! fernwell v0.3.0 | MIT | https://github.com/JacobKnaack/fernwell */
2
- "use strict";var V=Object.defineProperty;var Ze=Object.getOwnPropertyDescriptor;var et=Object.getOwnPropertyNames;var tt=Object.prototype.hasOwnProperty;var T=(e,t)=>{for(var n in t)V(e,n,{get:t[n],enumerable:!0})},nt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of et(t))!tt.call(e,r)&&r!==n&&V(e,r,{get:()=>t[r],enumerable:!(o=Ze(t,r))||o.enumerable});return e};var ot=e=>nt(V({},"__esModule",{value:!0}),e);var Ot={};T(Ot,{combobox:()=>C,default:()=>St,init:()=>Xe,loading:()=>N,menu:()=>K,modal:()=>D,nav:()=>B,table:()=>R,theme:()=>O,toast:()=>I,version:()=>Ye});module.exports=ot(Ot);var O={};T(O,{get:()=>W,getToken:()=>ct,init:()=>_,resetTokens:()=>at,set:()=>S,setTokens:()=>lt,toggle:()=>xe});var G="fw-theme",rt="fw:themechange",st="--fw-",Me="data-fw-tokens";function U(){try{return window.localStorage}catch{return null}}function W(){var t;let e=document.documentElement.getAttribute("data-theme");return e==="dark"||e==="light"?e:(t=window.matchMedia)!=null&&t.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}function S(e,{persist:t=!0}={}){var n;document.documentElement.setAttribute("data-theme",e),t&&((n=U())==null||n.setItem(G,e)),document.querySelectorAll("[data-fw-theme-toggle]").forEach(o=>ke(o,e)),document.dispatchEvent(new CustomEvent(rt,{detail:e}))}function xe(){let e=W()==="dark"?"light":"dark";return S(e),e}function ke(e,t){e.setAttribute("aria-pressed",String(t==="dark"));let n=t==="dark"?e.dataset.fwThemeLabelDark:e.dataset.fwThemeLabelLight;n!==void 0&&(e.textContent=n)}function _(e=document){var o,r,s,l;let t=(o=U())==null?void 0:o.getItem(G),n=t==="dark"||t==="light"?t:W();S(n,{persist:!1}),e.querySelectorAll("[data-fw-theme-toggle]").forEach(d=>{d.dataset.fwBound||(d.dataset.fwBound="1",ke(d,n),d.addEventListener("click",()=>xe()))}),(l=(r=window.matchMedia)==null?void 0:(s=r.call(window,"(prefers-color-scheme: dark)")).addEventListener)==null||l.call(s,"change",d=>{var f;(f=U())!=null&&f.getItem(G)||S(d.matches?"dark":"light",{persist:!1})})}var b=new Map;function Ae(e){return e.startsWith("--")?e:`${st}${e}`}function it(e){return Object.values(e).some(t=>t!==null&&typeof t=="object")}function He(e){return Object.entries(e).map(([t,n])=>`${Ae(t)}:${n};`).join("")}function ye(e){let t=document.head.querySelector(`style[${Me}]`);if(t||!e)return t;let n=document.createElement("style");return n.setAttribute(Me,""),document.head.appendChild(n),n}function Se(){var t;if(b.size===0){(t=ye(!1))==null||t.remove();return}let e=[];b.forEach(({light:n,dark:o},r)=>{if(Object.keys(n).length&&e.push(`${r}{${He(n)}}`),Object.keys(o).length){let s=r===":root"?'[data-theme="dark"]':`[data-theme="dark"] ${r}, ${r}[data-theme="dark"]`;e.push(`${s}{${He(o)}}`)}}),ye(!0).textContent=e.join(`
3
- `)}function lt(e,t={}){var r,s;let n=(r=t.scope)!=null?r:":root",o=(s=b.get(n))!=null?s:{light:{},dark:{}};it(e)?(Object.assign(o.light,e.light),Object.assign(o.dark,e.dark)):(Object.assign(o.light,e),Object.assign(o.dark,e)),b.set(n,o),Se()}function at(e){e?b.delete(e):b.clear(),Se()}function ct(e,t=document.documentElement){return getComputedStyle(t).getPropertyValue(Ae(e)).trim()}var C={};T(C,{combobox:()=>Oe,init:()=>z});var dt=0;function x(e){return e.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}function Oe(e,t={}){var ve,he,be,ge;let n=(ve=t.filter)!=null?ve:((i,c)=>i.toLowerCase().includes(c)),o=(he=t.emptyText)!=null?he:"No matches",r=(be=t.options)!=null?be:ut(e),s=[],l=-1,d=!1,f=e.getAttribute("list");f&&(e.dataset.fwList=f,e.removeAttribute("list"));let u=(ge=e.closest(".fw-combobox"))!=null?ge:ft(e),a=document.createElement("ul"),F=`fw-combobox-${++dt}`;a.className="fw-combobox-list",a.id=F,a.setAttribute("role","listbox"),u.appendChild(a),e.setAttribute("role","combobox"),e.setAttribute("aria-autocomplete","list"),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-controls",F),e.autocomplete="off";function Je(i){s=i,l=-1;let c=e.value.trim().toLowerCase();if(i.length===0){a.innerHTML=`<li class="fw-combobox-empty">${x(o)}</li>`;return}a.innerHTML=i.map((E,H)=>{let y=c?E.toLowerCase().indexOf(c):-1,Qe=y>-1?`${x(E.slice(0,y))}<b>${x(E.slice(y,y+c.length))}</b>${x(E.slice(y+c.length))}`:x(E);return`<li class="fw-combobox-option" role="option" id="${F}-${H}" data-index="${H}" aria-selected="false">${Qe}</li>`}).join("")}function M(){let i=e.value.trim().toLowerCase();Je(i?r.filter(c=>n(c,i)):r),a.classList.add("is-open"),e.setAttribute("aria-expanded","true")}function A(){a.classList.remove("is-open"),e.setAttribute("aria-expanded","false"),e.removeAttribute("aria-activedescendant"),l=-1}function fe(i){let c=a.querySelectorAll(".fw-combobox-option");c.forEach(H=>{H.classList.remove("is-active"),H.setAttribute("aria-selected","false")});let E=c[i];E&&(E.classList.add("is-active"),E.setAttribute("aria-selected","true"),E.scrollIntoView({block:"nearest"}),e.setAttribute("aria-activedescendant",E.id)),l=i}function me(i){var c;e.value=i,A(),d=!0,e.focus(),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})),d=!1,(c=t.onSelect)==null||c.call(t,i)}let Ee=()=>{d||M()},pe=()=>{d||M()},Te=i=>{i.key==="ArrowDown"?(i.preventDefault(),a.classList.contains("is-open")||M(),fe(Math.min(l+1,s.length-1))):i.key==="ArrowUp"?(i.preventDefault(),fe(Math.max(l-1,0))):i.key==="Enter"?l>-1&&s[l]!==void 0&&(i.preventDefault(),me(s[l])):i.key==="Escape"&&A()},Le=i=>{let c=i.target.closest(".fw-combobox-option");c&&(i.preventDefault(),me(s[Number(c.dataset.index)]))},we=i=>{u.contains(i.target)||A()};return e.addEventListener("input",Ee),e.addEventListener("focus",pe),e.addEventListener("keydown",Te),a.addEventListener("mousedown",Le),document.addEventListener("click",we),{open:M,close:A,setOptions(i){r=i,a.classList.contains("is-open")&&M()},destroy(){e.removeEventListener("input",Ee),e.removeEventListener("focus",pe),e.removeEventListener("keydown",Te),a.removeEventListener("mousedown",Le),document.removeEventListener("click",we),a.remove(),e.dataset.fwList&&e.setAttribute("list",e.dataset.fwList),delete e.dataset.fwBound}}}function ut(e){var o;let t=(o=e.getAttribute("list"))!=null?o:e.dataset.fwList,n=t?document.getElementById(t):null;return n?Array.from(n.querySelectorAll("option")).map(r=>r.value||r.textContent||""):[]}function ft(e){var n;let t=document.createElement("div");return t.className="fw-combobox",(n=e.parentNode)==null||n.insertBefore(t,e),t.appendChild(e),t}function z(e=document){e.querySelectorAll("input[data-fw-combobox]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Oe(t))})}var D={};T(D,{bindOutsideClickToClose:()=>X,close:()=>L,init:()=>ee,open:()=>Z,toggle:()=>Et});var w="is-open",De="fw-scroll-lock",v=[],Y=new WeakMap,mt='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function J(e){return typeof e=="string"?document.getElementById(e):e}function Q(e){if(e.classList.contains("fw-modal-overlay"))return e;let t=e.id?document.querySelector(`[data-fw-drawer-overlay="${e.id}"]`):null;if(t)return t;let n=e.previousElementSibling;return n instanceof HTMLElement&&n.classList.contains("fw-drawer-overlay")?n:null}function Z(e,t=(n=>(n=document.activeElement)!=null?n:null)()){var s;let o=J(e);if(!o||o.classList.contains(w))return;o.classList.add(w),(s=Q(o))==null||s.classList.add(w),Y.set(o,t),v.push(o),document.body.classList.add(De),o.dispatchEvent(new CustomEvent("fw:open",{bubbles:!0}));let r=o.querySelector(mt);r?r.focus({preventScroll:!0}):(o.hasAttribute("tabindex")||o.setAttribute("tabindex","-1"),o.focus({preventScroll:!0}))}function L(e){var o,r,s;let t=J(e);if(!t||!t.classList.contains(w))return;t.classList.remove(w),(o=Q(t))==null||o.classList.remove(w);let n=v.indexOf(t);n>-1&&v.splice(n,1),v.length===0&&document.body.classList.remove(De),t.dispatchEvent(new CustomEvent("fw:close",{bubbles:!0})),(s=(r=Y.get(t))==null?void 0:r.focus)==null||s.call(r,{preventScroll:!0}),Y.delete(t)}function Et(e){let t=J(e);t&&(t.classList.contains(w)?L:Z)(t)}function X(e,t){let n=!1;e.addEventListener("mousedown",o=>{n=o.target===e}),e.addEventListener("click",o=>{o.target===e&&n&&t()})}var Ce=!1;function ee(e=document){e.querySelectorAll("[data-fw-open-modal], [data-fw-open-drawer]").forEach(t=>{var o,r;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=(r=(o=t.dataset.fwOpenModal)!=null?o:t.dataset.fwOpenDrawer)!=null?r:"";t.addEventListener("click",()=>Z(n,t))}),e.querySelectorAll(".fw-modal-overlay").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",X(t,()=>L(t)),t.querySelectorAll("[data-fw-close-modal]").forEach(n=>n.addEventListener("click",()=>L(t))))}),e.querySelectorAll(".fw-drawer").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=Q(t);n&&X(n,()=>L(t)),t.querySelectorAll("[data-fw-close-drawer]").forEach(o=>o.addEventListener("click",()=>L(t)))}),Ce||(Ce=!0,document.addEventListener("keydown",t=>{t.key==="Escape"&&v.length&&L(v[v.length-1])}))}var B={};T(B,{close:()=>q,init:()=>oe,open:()=>qe});var te="is-open";function qe(e){let t=ne(e);t&&(t.classList.add(te),e.setAttribute("aria-expanded","true"))}function q(e){let t=ne(e);t&&(t.classList.remove(te),e.setAttribute("aria-expanded","false"))}function ne(e){let t=e.getAttribute("aria-controls");return t?document.getElementById(t):null}function oe(e=document){e.querySelectorAll("[data-fw-nav-toggle]").forEach(t=>{var r,s;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=ne(t);if(!n)return;let o=(s=(r=t.closest(".fw-nav"))!=null?r:t.parentElement)!=null?s:t;t.addEventListener("click",l=>{l.stopPropagation(),(n.classList.contains(te)?q:qe)(t)}),document.addEventListener("click",l=>{!o.contains(l.target)&&!n.contains(l.target)&&q(t)}),document.addEventListener("keydown",l=>{l.key==="Escape"&&q(t)})})}var N={};T(N,{init:()=>re,resetAll:()=>$e,resetButtonLoading:()=>Ie,setButtonLoading:()=>Ne});var k="fw-btn-loading";function Ne(e,t){var o,r;if(!e||e.classList.contains(k))return;e.dataset.fwOriginalHtml=e.innerHTML,e.disabled=!0,e.setAttribute("aria-busy","true"),e.classList.add(k);let n=(r=(o=t!=null?t:e.dataset.fwLoadingText)!=null?o:e.textContent)!=null?r:"";e.innerHTML='<span class="fw-spinner fw-spinner-sm" aria-hidden="true"></span>',e.appendChild(document.createTextNode(n))}function Ie(e){!e||!e.classList.contains(k)||(e.disabled=!1,e.removeAttribute("aria-busy"),e.classList.remove(k),e.dataset.fwOriginalHtml!==void 0&&(e.innerHTML=e.dataset.fwOriginalHtml,delete e.dataset.fwOriginalHtml))}function $e(e=document){e.querySelectorAll(`.${k}`).forEach(Ie)}var Be=!1;function re(e=document){e.querySelectorAll("form[data-fw-loading]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",t.addEventListener("submit",()=>{let n=t.querySelector('button[type="submit"], button:not([type])');Ne(n)}))}),Be||(Be=!0,window.addEventListener("pageshow",t=>{t.persisted&&$e()}))}var I={};T(I,{hide:()=>Re,show:()=>Tt});var m=null,g=null;function pt(){return m&&m.isConnected||(m=document.createElement("div"),m.className="fw-toast",m.setAttribute("role","status"),m.setAttribute("aria-live","polite"),m.innerHTML='<span class="fw-toast-dot" aria-hidden="true"></span><span class="fw-toast-text"></span>',document.body.appendChild(m)),m}function Tt(e,{variant:t="success",duration:n=4e3}={}){let o=pt();return o.className=`fw-toast${t==="success"?"":` fw-toast-${t}`}`,o.querySelector(".fw-toast-text").textContent=e,g&&clearTimeout(g),o.classList.remove("is-show"),o.offsetWidth,o.classList.add("is-show"),n>0&&(g=setTimeout(Re,n)),o}function Re(){m==null||m.classList.remove("is-show"),g&&clearTimeout(g),g=null}var R={};T(R,{getSelected:()=>ce,init:()=>de,selectAll:()=>Ve,setRowSelected:()=>Fe,sort:()=>se});var Lt="is-selected";function ie(e,t,n){e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n}))}function Pe(e,t){var o,r,s;let n=e.cells[t];return(s=(r=n==null?void 0:n.dataset.fwSortValue)!=null?r:(o=n==null?void 0:n.textContent)==null?void 0:o.trim())!=null?s:""}function wt(e,t){let n=Number(e),o=Number(t);return e!==""&&t!==""&&Number.isFinite(n)&&Number.isFinite(o)?n-o:e.localeCompare(t,void 0,{numeric:!0,sensitivity:"base"})}function Ke(e){var t,n;return Array.from((n=(t=e.tHead)==null?void 0:t.querySelectorAll("th[data-fw-sort]"))!=null?n:[])}function je(e){return e.getAttribute("aria-sort")==="ascending"?"descending":"ascending"}function se(e,t,n){let o=e.tBodies[0];if(!o)return;let r=Array.from(o.rows),s=r.filter(u=>u.cells.length>t),l=r.filter(u=>u.cells.length<=t),d=n==="ascending"?1:-1;s.sort((u,a)=>d*wt(Pe(u,t),Pe(a,t))),[...s,...l].forEach(u=>o.appendChild(u));let f=null;Ke(e).forEach(u=>{let a=u.cellIndex===t;u.setAttribute("aria-sort",a?n:"none"),a&&(f=u)}),f&&ie(e,"fw:sort",{column:t,direction:n,th:f})}function $(e){return Array.from(e.querySelectorAll("tbody input[data-fw-select-row]"))}function le(e,t){e.classList.toggle(Lt,t),e.setAttribute("aria-selected",t?"true":"false")}function ae(e){let t=e.querySelector("[data-fw-select-all]");if(!t)return;let n=$(e),o=n.filter(r=>r.checked).length;t.checked=o>0&&o===n.length,t.indeterminate=o>0&&o<n.length}function ce(e){return $(e).filter(t=>t.checked).map(t=>t.closest("tr")).filter(t=>t!==null)}function Fe(e,t){let n=e.querySelector("input[data-fw-select-row]");n&&(n.checked=t),le(e,t);let o=e.closest("table");o&&(ae(o),ie(o,"fw:select",{rows:ce(o),all:!1}))}function Ve(e,t){$(e).forEach(n=>{n.checked=t;let o=n.closest("tr");o&&le(o,t)}),ae(e),ie(e,"fw:select",{rows:ce(e),all:!0})}function de(e=document){e.querySelectorAll("table[data-fw-table]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Ke(t).forEach(n=>{n.hasAttribute("aria-sort")||n.setAttribute("aria-sort","none")}),t.addEventListener("click",n=>{let o=n.target.closest("th[data-fw-sort]");o&&t.contains(o)&&se(t,o.cellIndex,je(o))}),t.addEventListener("keydown",n=>{if(n.key!=="Enter"&&n.key!==" ")return;let o=n.target;if(!o.matches("th[data-fw-sort], th[data-fw-sort] .fw-table-sort"))return;let r=o.closest("th[data-fw-sort]");r&&(n.preventDefault(),se(t,r.cellIndex,je(r)))}),t.addEventListener("change",n=>{let o=n.target;if(o.matches("[data-fw-select-all]"))Ve(t,o.checked);else if(o.matches("[data-fw-select-row]")){let r=o.closest("tr");r&&Fe(r,o.checked)}}),$(t).forEach(n=>{let o=n.closest("tr");o&&n.checked&&le(o,!0)}),ae(t))})}var K={};T(K,{close:()=>j,collapseAll:()=>Mt,expandAll:()=>gt,init:()=>ue,open:()=>P,reveal:()=>We,toggle:()=>bt});var p=".fw-menu-group",Ue=".fw-menu-link, .fw-menu-summary",vt="is-current";function ht(e,t){e.dispatchEvent(new CustomEvent("fw:toggle",{bubbles:!0,detail:t}))}function P(e){e.open=!0}function j(e){e.open=!1}function bt(e,t){e.open=t!=null?t:!e.open}function gt(e){e.querySelectorAll(p).forEach(P)}function Mt(e){e.querySelectorAll(p).forEach(j)}function We(e){var n,o,r,s;let t=(o=(n=e.parentElement)==null?void 0:n.closest(p))!=null?o:null;for(;t;)P(t),t=(s=(r=t.parentElement)==null?void 0:r.closest(p))!=null?s:null}function Ge(e){e.querySelectorAll(p).forEach(t=>{let n=t.querySelector(":scope > .fw-menu-summary");if(!n)return;let o=!t.open&&t.querySelector("[aria-current]")!==null;n.classList.toggle(vt,o)})}function _e(e){return e.matches(".fw-menu-summary")?e.closest(p):null}function ze(e){var n,o,r;return(r=(o=((n=_e(e))!=null?n:e).parentElement)==null?void 0:o.closest(p))!=null?r:null}function Ht(e){var t,n;for(let o=ze(e);o;o=(n=(t=o.parentElement)==null?void 0:t.closest(p))!=null?n:null)if(!o.open)return!1;return!0}function yt(e){return Array.from(e.querySelectorAll(Ue)).filter(Ht)}function h(e){return e?(e.focus(),!0):!1}function xt(e){var n;let t=e.closest(".fw-menu-split");return(n=t==null?void 0:t.querySelector(":scope > .fw-menu-group > .fw-menu-summary"))!=null?n:null}function kt(e,t){var d;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)return;let n=t.target instanceof HTMLElement&&t.target.matches(Ue)?t.target:null;if(!n||!e.contains(n))return;let o=yt(e),r=o.indexOf(n),s=_e(n),l=!0;switch(t.key){case"ArrowDown":h(o[r+1]);break;case"ArrowUp":h(o[r-1]);break;case"Home":h(o[0]);break;case"End":h(o[o.length-1]);break;case"ArrowRight":s?s.open?s.contains((d=o[r+1])!=null?d:e)&&h(o[r+1]):P(s):h(xt(n));break;case"ArrowLeft":if(s!=null&&s.open)j(s);else{let f=ze(n);h(f==null?void 0:f.querySelector(":scope > .fw-menu-summary"))}break;default:l=!1}l&&t.preventDefault()}function ue(e=document){e.querySelectorAll("[data-fw-menu]").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.hasAttribute("data-fw-menu-exclusive");t.addEventListener("toggle",o=>{let r=o.target;!(r instanceof HTMLDetailsElement)||!r.matches(p)||(n&&r.open&&r.parentElement&&Array.from(r.parentElement.children).forEach(s=>{s!==r&&s instanceof HTMLDetailsElement&&s.matches(p)&&j(s)}),Ge(t),ht(r,{group:r,open:r.open}))},!0),t.addEventListener("keydown",o=>kt(t,o)),t.querySelectorAll("[aria-current]").forEach(We),Ge(t)})}var Ye="0.3.0";function Xe(e=document){_(e),z(e),ee(e),oe(e),re(e),de(e),ue(e)}var At={version:Ye,init:Xe,theme:O,combobox:C,modal:D,nav:B,loading:N,toast:I,table:R,menu:K},St=At;
1
+ /*! fernwell v0.4.0 | MIT | https://github.com/JacobKnaack/fernwell */
2
+ "use strict";var Ee=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var $t=Object.getOwnPropertyNames;var Ft=Object.prototype.hasOwnProperty;var y=(e,t)=>{for(var n in t)Ee(e,n,{get:t[n],enumerable:!0})},Vt=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of $t(t))!Ft.call(e,r)&&r!==n&&Ee(e,r,{get:()=>t[r],enumerable:!(o=Rt(t,r))||o.enumerable});return e};var Kt=e=>Vt(Ee({},"__esModule",{value:!0}),e);var Sn={};y(Sn,{combobox:()=>J,default:()=>gn,icon:()=>z,init:()=>Bt,loading:()=>ne,menu:()=>ae,modal:()=>Q,nav:()=>te,popover:()=>ue,table:()=>ie,tabs:()=>ve,theme:()=>X,toast:()=>oe,tooltip:()=>me,version:()=>Nt});module.exports=Kt(Sn);var X={};y(X,{get:()=>ye,getToken:()=>Yt,init:()=>Le,resetTokens:()=>zt,set:()=>Y,setTokens:()=>Gt,toggle:()=>Je});var z={};y(z,{init:()=>he,render:()=>G});var jt={add:'<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>',close:'<line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/>',check:'<polyline points="5,13 10,18 19,7"/>',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"/>',trash:'<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"/>',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"/>',search:'<circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.6" y2="16.6"/>',settings:'<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"/>',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"/>',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"/>',share:'<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"/>',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"/>',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"/>',more:'<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"/>',user:'<circle cx="12" cy="8" r="4"/><path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/>',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"/>',heart:'<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"/>',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"/>',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"/>',refresh:'<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"/>',filter:'<polygon points="4,4 20,4 14,12 14,19 10,21 10,12"/>',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"/>',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"/>',lock:'<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>',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"/>',"chevron-down":'<polyline points="6,9 12,15 18,9"/>',"arrow-left":'<line x1="19" y1="12" x2="5" y2="12"/><polyline points="12,5 5,12 12,19"/>',"arrow-right":'<line x1="5" y1="12" x2="19" y2="12"/><polyline points="12,5 19,12 12,19"/>',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"/>',bookmark:'<path d="M6 3h12a1 1 0 0 1 1 1v17l-7-4-7 4V4a1 1 0 0 1 1-1Z"/>',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"/>',logout:'<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"/>',paperclip:'<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"/>',envelope:'<rect x="3" y="5" width="18" height="14" rx="2"/><path d="M4 6.5 12 13l8-6.5"/>',"chevron-up":'<polyline points="6,15 12,9 18,15"/>',"chevron-left":'<polyline points="15,6 9,12 15,18"/>',"chevron-right":'<polyline points="9,6 15,12 9,18"/>',"arrow-up":'<line x1="12" y1="19" x2="12" y2="5"/><polyline points="5,12 12,5 19,12"/>',"arrow-down":'<line x1="12" y1="5" x2="12" y2="19"/><polyline points="5,12 12,19 19,12"/>',unlock:'<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 7.8-1.3"/>',"thumbs-up":'<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"/>',"thumbs-down":'<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"/>',"eye-closed":'<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"/>',"help-circle":'<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"/>',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"/>',kebab:'<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"/>',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"/>',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"/>'};function G(e){let t=jt[e];return t?`<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">${t}</svg>`:""}function he(e=document){e.querySelectorAll("[data-fw-icon]").forEach(t=>{var r;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=(r=t.dataset.fwIcon)!=null?r:"",o=G(n);o||console.warn(`fernwell: unknown icon "${n}"`),t.innerHTML=o,t.classList.add("fw-icon")})}var we="fw-theme",_t="fw:themechange",Zt="--fw-",Ge="data-fw-tokens",ze="data-fw-theme-init";function Te(){try{return window.localStorage}catch{return null}}function ye(){var t;let e=document.documentElement.getAttribute("data-theme");return e==="dark"||e==="light"?e:(t=window.matchMedia)!=null&&t.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}function Y(e,{persist:t=!0}={}){var n;document.documentElement.setAttribute("data-theme",e),t&&((n=Te())==null||n.setItem(we,e)),document.querySelectorAll("[data-fw-theme-toggle]").forEach(o=>Qe(o,e)),document.dispatchEvent(new CustomEvent(_t,{detail:e}))}function Je(){let e=ye()==="dark"?"light":"dark";return Y(e),e}function Qe(e,t){e.setAttribute("aria-pressed",String(t==="dark"));let n=t==="dark"?e.dataset.fwThemeIconDark:e.dataset.fwThemeIconLight,o=t==="dark"?e.dataset.fwThemeLabelDark:e.dataset.fwThemeLabelLight;if(n!==void 0){let r=`<span class="fw-icon" aria-hidden="true">${G(n)}</span>`;e.innerHTML=o!==void 0?`${r} ${o}`:r}else o!==void 0&&(e.textContent=o)}function Wt(e){let t=typeof requestAnimationFrame=="function"?requestAnimationFrame:n=>setTimeout(n,16);t(()=>t(e))}function Le(e=document){var r,i,l,a;let t=(r=Te())==null?void 0:r.getItem(we),n=t==="dark"||t==="light"?t:ye(),o=document.documentElement;o.setAttribute(ze,""),Y(n,{persist:!1}),Wt(()=>o.removeAttribute(ze)),e.querySelectorAll("[data-fw-theme-toggle]").forEach(c=>{c.dataset.fwBound||(c.dataset.fwBound="1",Qe(c,n),c.addEventListener("click",()=>Je()))}),(a=(i=window.matchMedia)==null?void 0:(l=i.call(window,"(prefers-color-scheme: dark)")).addEventListener)==null||a.call(l,"change",c=>{var d;(d=Te())!=null&&d.getItem(we)||Y(c.matches?"dark":"light",{persist:!1})})}var B=new Map;function et(e){return e.startsWith("--")?e:`${Zt}${e}`}function Ut(e){return Object.values(e).some(t=>t!==null&&typeof t=="object")}function Ye(e){return Object.entries(e).map(([t,n])=>`${et(t)}:${n};`).join("")}function Xe(e){let t=document.head.querySelector(`style[${Ge}]`);if(t||!e)return t;let n=document.createElement("style");return n.setAttribute(Ge,""),document.head.appendChild(n),n}function tt(){var t;if(B.size===0){(t=Xe(!1))==null||t.remove();return}let e=[];B.forEach(({light:n,dark:o},r)=>{if(Object.keys(n).length&&e.push(`${r}{${Ye(n)}}`),Object.keys(o).length){let i=r===":root"?'[data-theme="dark"]':`[data-theme="dark"] ${r}, ${r}[data-theme="dark"]`;e.push(`${i}{${Ye(o)}}`)}}),Xe(!0).textContent=e.join(`
3
+ `)}function Gt(e,t={}){var r,i;let n=(r=t.scope)!=null?r:":root",o=(i=B.get(n))!=null?i:{light:{},dark:{}};Ut(e)?(Object.assign(o.light,e.light),Object.assign(o.dark,e.dark)):(Object.assign(o.light,e),Object.assign(o.dark,e)),B.set(n,o),tt()}function zt(e){e?B.delete(e):B.clear(),tt()}function Yt(e,t=document.documentElement){return getComputedStyle(t).getPropertyValue(et(e)).trim()}var J={};y(J,{combobox:()=>nt,init:()=>be});var Xt=0;function K(e){return e.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}function nt(e,t={}){var h,N,O,Ue;let n=(h=t.filter)!=null?h:((f,w)=>f.toLowerCase().includes(w)),o=(N=t.emptyText)!=null?N:"No matches",r=(O=t.options)!=null?O:Jt(e),i=[],l=-1,a=!1,c=e.getAttribute("list");c&&(e.dataset.fwList=c,e.removeAttribute("list"));let d=(Ue=e.closest(".fw-combobox"))!=null?Ue:Qt(e),s=document.createElement("ul"),u=`fw-combobox-${++Xt}`;s.className="fw-combobox-list",s.id=u,s.setAttribute("role","listbox"),d.appendChild(s),e.setAttribute("role","combobox"),e.setAttribute("aria-autocomplete","list"),e.setAttribute("aria-expanded","false"),e.setAttribute("aria-controls",u),e.autocomplete="off";function E(f){i=f,l=-1;let w=e.value.trim().toLowerCase();if(f.length===0){s.innerHTML=`<li class="fw-combobox-empty">${K(o)}</li>`;return}s.innerHTML=f.map((H,F)=>{let V=w?H.toLowerCase().indexOf(w):-1,qt=V>-1?`${K(H.slice(0,V))}<b>${K(H.slice(V,V+w.length))}</b>${K(H.slice(V+w.length))}`:K(H);return`<li class="fw-combobox-option" role="option" id="${u}-${F}" data-index="${F}" aria-selected="false">${qt}</li>`}).join("")}function m(){let f=e.value.trim().toLowerCase();E(f?r.filter(w=>n(w,f)):r),s.classList.add("is-open"),e.setAttribute("aria-expanded","true")}function p(){s.classList.remove("is-open"),e.setAttribute("aria-expanded","false"),e.removeAttribute("aria-activedescendant"),l=-1}function v(f){let w=s.querySelectorAll(".fw-combobox-option");w.forEach(F=>{F.classList.remove("is-active"),F.setAttribute("aria-selected","false")});let H=w[f];H&&(H.classList.add("is-active"),H.setAttribute("aria-selected","true"),H.scrollIntoView({block:"nearest"}),e.setAttribute("aria-activedescendant",H.id)),l=f}function b(f){var w;e.value=f,p(),a=!0,e.focus(),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})),a=!1,(w=t.onSelect)==null||w.call(t,f)}let M=()=>{a||m()},T=()=>{a||m()},g=f=>{f.key==="ArrowDown"?(f.preventDefault(),s.classList.contains("is-open")||m(),v(Math.min(l+1,i.length-1))):f.key==="ArrowUp"?(f.preventDefault(),v(Math.max(l-1,0))):f.key==="Enter"?l>-1&&i[l]!==void 0&&(f.preventDefault(),b(i[l])):f.key==="Escape"&&p()},S=f=>{let w=f.target.closest(".fw-combobox-option");w&&(f.preventDefault(),b(i[Number(w.dataset.index)]))},$=f=>{d.contains(f.target)||p()};return e.addEventListener("input",M),e.addEventListener("focus",T),e.addEventListener("keydown",g),s.addEventListener("mousedown",S),document.addEventListener("click",$),{open:m,close:p,setOptions(f){r=f,s.classList.contains("is-open")&&m()},destroy(){e.removeEventListener("input",M),e.removeEventListener("focus",T),e.removeEventListener("keydown",g),s.removeEventListener("mousedown",S),document.removeEventListener("click",$),s.remove(),e.dataset.fwList&&e.setAttribute("list",e.dataset.fwList),delete e.dataset.fwBound}}}function Jt(e){var o;let t=(o=e.getAttribute("list"))!=null?o:e.dataset.fwList,n=t?document.getElementById(t):null;return n?Array.from(n.querySelectorAll("option")).map(r=>r.value||r.textContent||""):[]}function Qt(e){var n;let t=document.createElement("div");return t.className="fw-combobox",(n=e.parentNode)==null||n.insertBefore(t,e),t.appendChild(e),t}function be(e=document){e.querySelectorAll("input[data-fw-combobox]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",nt(t))})}var Q={};y(Q,{bindOutsideClickToClose:()=>Me,close:()=>C,init:()=>ge,open:()=>ke,toggle:()=>tn});var D="is-open",rt="fw-scroll-lock",P=[],xe=new WeakMap,en='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function He(e){return typeof e=="string"?document.getElementById(e):e}function Ae(e){if(e.classList.contains("fw-modal-overlay"))return e;let t=e.id?document.querySelector(`[data-fw-drawer-overlay="${e.id}"]`):null;if(t)return t;let n=e.previousElementSibling;return n instanceof HTMLElement&&n.classList.contains("fw-drawer-overlay")?n:null}function ke(e,t=(n=>(n=document.activeElement)!=null?n:null)()){var i;let o=He(e);if(!o||o.classList.contains(D))return;o.classList.add(D),(i=Ae(o))==null||i.classList.add(D),xe.set(o,t),P.push(o),document.body.classList.add(rt),o.dispatchEvent(new CustomEvent("fw:open",{bubbles:!0}));let r=o.querySelector(en);r?r.focus({preventScroll:!0}):(o.hasAttribute("tabindex")||o.setAttribute("tabindex","-1"),o.focus({preventScroll:!0}))}function C(e){var o,r,i;let t=He(e);if(!t||!t.classList.contains(D))return;t.classList.remove(D),(o=Ae(t))==null||o.classList.remove(D);let n=P.indexOf(t);n>-1&&P.splice(n,1),P.length===0&&document.body.classList.remove(rt),t.dispatchEvent(new CustomEvent("fw:close",{bubbles:!0})),(i=(r=xe.get(t))==null?void 0:r.focus)==null||i.call(r,{preventScroll:!0}),xe.delete(t)}function tn(e){let t=He(e);t&&(t.classList.contains(D)?C:ke)(t)}function Me(e,t){let n=!1;e.addEventListener("mousedown",o=>{n=o.target===e}),e.addEventListener("click",o=>{o.target===e&&n&&t()})}var ot=!1;function ge(e=document){e.querySelectorAll("[data-fw-open-modal], [data-fw-open-drawer]").forEach(t=>{var o,r;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=(r=(o=t.dataset.fwOpenModal)!=null?o:t.dataset.fwOpenDrawer)!=null?r:"";t.addEventListener("click",()=>ke(n,t))}),e.querySelectorAll(".fw-modal-overlay").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Me(t,()=>C(t)),t.querySelectorAll("[data-fw-close-modal]").forEach(n=>n.addEventListener("click",()=>C(t))))}),e.querySelectorAll(".fw-drawer").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=Ae(t);n&&Me(n,()=>C(t)),t.querySelectorAll("[data-fw-close-drawer]").forEach(o=>o.addEventListener("click",()=>C(t)))}),ot||(ot=!0,document.addEventListener("keydown",t=>{t.key==="Escape"&&P.length&&C(P[P.length-1])}))}var te={};y(te,{close:()=>ee,init:()=>Ce,open:()=>it});var Se="is-open";function it(e){let t=Oe(e);t&&(t.classList.add(Se),e.setAttribute("aria-expanded","true"))}function ee(e){let t=Oe(e);t&&(t.classList.remove(Se),e.setAttribute("aria-expanded","false"))}function Oe(e){let t=e.getAttribute("aria-controls");return t?document.getElementById(t):null}function Ce(e=document){e.querySelectorAll("[data-fw-nav-toggle]").forEach(t=>{var r,i;if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=Oe(t);if(!n)return;let o=(i=(r=t.closest(".fw-nav"))!=null?r:t.parentElement)!=null?i:t;t.addEventListener("click",l=>{l.stopPropagation(),(n.classList.contains(Se)?ee:it)(t)}),document.addEventListener("click",l=>{!o.contains(l.target)&&!n.contains(l.target)&&ee(t)}),document.addEventListener("keydown",l=>{l.key==="Escape"&&ee(t)})})}var ne={};y(ne,{init:()=>De,resetAll:()=>ct,resetButtonLoading:()=>at,setButtonLoading:()=>lt});var j="fw-btn-loading";function lt(e,t){var o,r;if(!e||e.classList.contains(j))return;e.dataset.fwOriginalHtml=e.innerHTML,e.disabled=!0,e.setAttribute("aria-busy","true"),e.classList.add(j);let n=(r=(o=t!=null?t:e.dataset.fwLoadingText)!=null?o:e.textContent)!=null?r:"";e.innerHTML='<span class="fw-spinner fw-spinner-sm" aria-hidden="true"></span>',e.appendChild(document.createTextNode(n))}function at(e){!e||!e.classList.contains(j)||(e.disabled=!1,e.removeAttribute("aria-busy"),e.classList.remove(j),e.dataset.fwOriginalHtml!==void 0&&(e.innerHTML=e.dataset.fwOriginalHtml,delete e.dataset.fwOriginalHtml))}function ct(e=document){e.querySelectorAll(`.${j}`).forEach(at)}var st=!1;function De(e=document){e.querySelectorAll("form[data-fw-loading]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",t.addEventListener("submit",()=>{let n=t.querySelector('button[type="submit"], button:not([type])');lt(n)}))}),st||(st=!0,window.addEventListener("pageshow",t=>{t.persisted&&ct()}))}var oe={};y(oe,{hide:()=>dt,show:()=>on});var L=null,q=null;function nn(){return L&&L.isConnected||(L=document.createElement("div"),L.className="fw-toast",L.setAttribute("role","status"),L.setAttribute("aria-live","polite"),L.innerHTML='<span class="fw-toast-dot" aria-hidden="true"></span><span class="fw-toast-text"></span>',document.body.appendChild(L)),L}function on(e,{variant:t="success",duration:n=4e3}={}){let o=nn();return o.className=`fw-toast${t==="success"?"":` fw-toast-${t}`}`,o.querySelector(".fw-toast-text").textContent=e,q&&clearTimeout(q),o.classList.remove("is-show"),o.offsetWidth,o.classList.add("is-show"),n>0&&(q=setTimeout(dt,n)),o}function dt(){L==null||L.classList.remove("is-show"),q&&clearTimeout(q),q=null}var ie={};y(ie,{getSelected:()=>qe,init:()=>Re,selectAll:()=>vt,setRowSelected:()=>pt,sort:()=>Pe});var rn="is-selected";function Ie(e,t,n){e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:n}))}function ut(e,t){var o,r,i;let n=e.cells[t];return(i=(r=n==null?void 0:n.dataset.fwSortValue)!=null?r:(o=n==null?void 0:n.textContent)==null?void 0:o.trim())!=null?i:""}function sn(e,t){let n=Number(e),o=Number(t);return e!==""&&t!==""&&Number.isFinite(n)&&Number.isFinite(o)?n-o:e.localeCompare(t,void 0,{numeric:!0,sensitivity:"base"})}function mt(e){var t,n;return Array.from((n=(t=e.tHead)==null?void 0:t.querySelectorAll("th[data-fw-sort]"))!=null?n:[])}function ft(e){return e.getAttribute("aria-sort")==="ascending"?"descending":"ascending"}function Pe(e,t,n){let o=e.tBodies[0];if(!o)return;let r=Array.from(o.rows),i=r.filter(d=>d.cells.length>t),l=r.filter(d=>d.cells.length<=t),a=n==="ascending"?1:-1;i.sort((d,s)=>a*sn(ut(d,t),ut(s,t))),[...i,...l].forEach(d=>o.appendChild(d));let c=null;mt(e).forEach(d=>{let s=d.cellIndex===t;d.setAttribute("aria-sort",s?n:"none"),s&&(c=d)}),c&&Ie(e,"fw:sort",{column:t,direction:n,th:c})}function re(e){return Array.from(e.querySelectorAll("tbody input[data-fw-select-row]"))}function Ne(e,t){e.classList.toggle(rn,t),e.setAttribute("aria-selected",t?"true":"false")}function Be(e){let t=e.querySelector("[data-fw-select-all]");if(!t)return;let n=re(e),o=n.filter(r=>r.checked).length;t.checked=o>0&&o===n.length,t.indeterminate=o>0&&o<n.length}function qe(e){return re(e).filter(t=>t.checked).map(t=>t.closest("tr")).filter(t=>t!==null)}function pt(e,t){let n=e.querySelector("input[data-fw-select-row]");n&&(n.checked=t),Ne(e,t);let o=e.closest("table");o&&(Be(o),Ie(o,"fw:select",{rows:qe(o),all:!1}))}function vt(e,t){re(e).forEach(n=>{n.checked=t;let o=n.closest("tr");o&&Ne(o,t)}),Be(e),Ie(e,"fw:select",{rows:qe(e),all:!0})}function Re(e=document){e.querySelectorAll("table[data-fw-table]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",mt(t).forEach(n=>{n.hasAttribute("aria-sort")||n.setAttribute("aria-sort","none")}),t.addEventListener("click",n=>{let o=n.target.closest("th[data-fw-sort]");o&&t.contains(o)&&Pe(t,o.cellIndex,ft(o))}),t.addEventListener("keydown",n=>{if(n.key!=="Enter"&&n.key!==" ")return;let o=n.target;if(!o.matches("th[data-fw-sort], th[data-fw-sort] .fw-table-sort"))return;let r=o.closest("th[data-fw-sort]");r&&(n.preventDefault(),Pe(t,r.cellIndex,ft(r)))}),t.addEventListener("change",n=>{let o=n.target;if(o.matches("[data-fw-select-all]"))vt(t,o.checked);else if(o.matches("[data-fw-select-row]")){let r=o.closest("tr");r&&pt(r,o.checked)}}),re(t).forEach(n=>{let o=n.closest("tr");o&&n.checked&&Ne(o,!0)}),Be(t))})}var ae={};y(ae,{close:()=>le,collapseAll:()=>un,expandAll:()=>dn,init:()=>$e,open:()=>se,reveal:()=>wt,toggle:()=>cn});var A=".fw-menu-group",ht=".fw-menu-link, .fw-menu-summary",ln="is-current";function an(e,t){e.dispatchEvent(new CustomEvent("fw:toggle",{bubbles:!0,detail:t}))}function se(e){e.open=!0}function le(e){e.open=!1}function cn(e,t){e.open=t!=null?t:!e.open}function dn(e){e.querySelectorAll(A).forEach(se)}function un(e){e.querySelectorAll(A).forEach(le)}function wt(e){var n,o,r,i;let t=(o=(n=e.parentElement)==null?void 0:n.closest(A))!=null?o:null;for(;t;)se(t),t=(i=(r=t.parentElement)==null?void 0:r.closest(A))!=null?i:null}function Et(e){e.querySelectorAll(A).forEach(t=>{let n=t.querySelector(":scope > .fw-menu-summary");if(!n)return;let o=!t.open&&t.querySelector("[aria-current]")!==null;n.classList.toggle(ln,o)})}function Tt(e){return e.matches(".fw-menu-summary")?e.closest(A):null}function yt(e){var n,o,r;return(r=(o=((n=Tt(e))!=null?n:e).parentElement)==null?void 0:o.closest(A))!=null?r:null}function fn(e){var t,n;for(let o=yt(e);o;o=(n=(t=o.parentElement)==null?void 0:t.closest(A))!=null?n:null)if(!o.open)return!1;return!0}function mn(e){return Array.from(e.querySelectorAll(ht)).filter(fn)}function I(e){return e?(e.focus(),!0):!1}function pn(e){var n;let t=e.closest(".fw-menu-split");return(n=t==null?void 0:t.querySelector(":scope > .fw-menu-group > .fw-menu-summary"))!=null?n:null}function vn(e,t){var a;if(t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)return;let n=t.target instanceof HTMLElement&&t.target.matches(ht)?t.target:null;if(!n||!e.contains(n))return;let o=mn(e),r=o.indexOf(n),i=Tt(n),l=!0;switch(t.key){case"ArrowDown":I(o[r+1]);break;case"ArrowUp":I(o[r-1]);break;case"Home":I(o[0]);break;case"End":I(o[o.length-1]);break;case"ArrowRight":i?i.open?i.contains((a=o[r+1])!=null?a:e)&&I(o[r+1]):se(i):I(pn(n));break;case"ArrowLeft":if(i!=null&&i.open)le(i);else{let c=yt(n);I(c==null?void 0:c.querySelector(":scope > .fw-menu-summary"))}break;default:l=!1}l&&t.preventDefault()}function $e(e=document){e.querySelectorAll("[data-fw-menu]").forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.hasAttribute("data-fw-menu-exclusive");t.addEventListener("toggle",o=>{let r=o.target;!(r instanceof HTMLDetailsElement)||!r.matches(A)||(n&&r.open&&r.parentElement&&Array.from(r.parentElement.children).forEach(i=>{i!==r&&i instanceof HTMLDetailsElement&&i.matches(A)&&le(i)}),Et(t),an(r,{group:r,open:r.open}))},!0),t.addEventListener("keydown",o=>vn(t,o)),t.querySelectorAll("[aria-current]").forEach(wt),Et(t)})}var ue={};y(ue,{init:()=>Ve,popover:()=>Mt});var En={top:"bottom",bottom:"top",left:"right",right:"left"},R=10;function hn(e){switch(e){case"top-left":return{side:"top",align:"end"};case"top-right":return{side:"top",align:"start"};case"bottom-left":return{side:"bottom",align:"end"};case"bottom-right":return{side:"bottom",align:"start"};default:return{side:e,align:"center"}}}var wn={start:"right",end:"left"};function Tn(e,t){return t==="center"?e:`${e}-${wn[t]}`}function Fe(e,t,n,o){switch(e){case"top":return t.top;case"bottom":return o-t.bottom;case"left":return t.left;case"right":return n-t.right}}function Lt(e,t,n,o){switch(e){case"top":return t.top-o-n.height;case"bottom":return t.bottom+o;case"left":return t.left-o-n.width;case"right":return t.right+o}}function bt(e,t,n,o){switch(e){case"start":return t;case"end":return t+n-o;case"center":return t+n/2-o/2}}function ce(e,t,n){return Math.min(Math.max(e,t),n>t?n:t)}function de(e,t,n={}){var T,g,S;let o=(T=n.placement)!=null?T:"bottom",r=(g=n.offset)!=null?g:8,i=(S=n.padding)!=null?S:8,l=e.getBoundingClientRect(),a=t.getBoundingClientRect(),c=window.innerWidth,d=window.innerHeight,{side:s,align:u}=hn(o),E=En[s],m=s==="top"||s==="bottom"?a.height:a.width,p=Fe(s,l,c,d)-r<m&&Fe(E,l,c,d)-r>Fe(s,l,c,d)-r?E:s,v,b,M;return p==="top"||p==="bottom"?(v=Lt(p,l,a,r),b=ce(bt(u,l.left,l.width,a.width),i,c-a.width-i),M=ce(l.left+l.width/2-b,R,Math.max(a.width-R,R))):(b=Lt(p,l,a,r),v=ce(bt("center",l.top,l.height,a.height),i,d-a.height-i),M=ce(l.top+l.height/2-v,R,Math.max(a.height-R,R))),{placement:Tn(p,u),top:v,left:b,arrowOffset:M}}function xt(e,t){let n=l=>!e.some(a=>a.contains(l)),o=!1,r=l=>{o=n(l.target)},i=l=>{o&&n(l.target)&&t()};return document.addEventListener("mousedown",r,!0),document.addEventListener("click",i,!0),()=>{document.removeEventListener("mousedown",r,!0),document.removeEventListener("click",i,!0)}}var yn='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Mt(e,t,n={}){var S,$;let o=(S=n.placement)!=null?S:"bottom",r=($=n.offset)!=null?$:8;e.setAttribute("aria-haspopup","dialog"),e.setAttribute("aria-controls",t.id),e.setAttribute("aria-expanded","false"),t.setAttribute("role","dialog"),t.setAttribute("aria-modal","false"),t.classList.add("fw-popover");let i=t.parentNode,l=t.nextSibling,a=!1,c=null,d=0;function s(){let h=de(e,t,{placement:o,offset:r});t.style.top=`${h.top}px`,t.style.left=`${h.left}px`,t.setAttribute("data-placement",h.placement)}function u(){cancelAnimationFrame(d),d=requestAnimationFrame(s)}function E(h){h.key==="Escape"&&(h.stopPropagation(),v())}function m(h){let N=h.relatedTarget;N&&(t.contains(N)||e.contains(N))||setTimeout(()=>{if(!a)return;let O=document.activeElement;O===document.body||O===null||t.contains(O)||e.contains(O)||v()},0)}function p(){if(a)return;a=!0,t.parentNode!==document.body&&document.body.appendChild(t),s(),t.classList.add("is-open"),e.setAttribute("aria-expanded","true");let h=t.querySelector(yn);h?h.focus({preventScroll:!0}):(t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1"),t.focus({preventScroll:!0})),c=xt([e,t],v),window.addEventListener("scroll",u,!0),window.addEventListener("resize",u),t.addEventListener("keydown",E),t.addEventListener("focusout",m),t.dispatchEvent(new CustomEvent("fw:open",{bubbles:!0}))}function v(){if(!a)return;a=!1,t.classList.remove("is-open"),e.setAttribute("aria-expanded","false"),c==null||c(),c=null,window.removeEventListener("scroll",u,!0),window.removeEventListener("resize",u),t.removeEventListener("keydown",E),t.removeEventListener("focusout",m),cancelAnimationFrame(d),l===null||l.parentNode===i?i.insertBefore(t,l):i.appendChild(t),t.dispatchEvent(new CustomEvent("fw:close",{bubbles:!0})),e.focus({preventScroll:!0})}function b(){(a?v:p)()}let M=()=>b(),T=Array.from(t.querySelectorAll("[data-fw-popover-close]")),g=()=>v();return e.addEventListener("click",M),T.forEach(h=>h.addEventListener("click",g)),{open:p,close:v,toggle:b,destroy(){a&&v(),e.removeEventListener("click",M),T.forEach(h=>h.removeEventListener("click",g)),delete e.dataset.fwBound}}}function Ve(e=document){e.querySelectorAll("[data-fw-popover-trigger]").forEach(t=>{var r;if(t.dataset.fwBound)return;let n=(r=t.dataset.fwPopoverTrigger)!=null?r:"",o=document.getElementById(n);if(!o){console.warn(`fernwell: popover trigger references missing panel #${n}`);return}t.dataset.fwBound="1",Mt(t,o,{placement:t.dataset.fwPopoverPlacement||void 0,offset:t.dataset.fwPopoverOffset?Number(t.dataset.fwPopoverOffset):void 0})})}var me={};y(me,{init:()=>_e,tooltip:()=>Ot});var Ln=400,bn=300,xn=100,Z=new WeakMap,x=null,k=null,W=0,U=0,je=0,At=0;function Mn(){if(x&&x.isConnected)return x;let e=document.createElement("div");return e.className="fw-tooltip",e.id="fw-tooltip",e.setAttribute("role","tooltip"),document.body.appendChild(e),e.addEventListener("mouseenter",kt),e.addEventListener("mouseleave",()=>St()),x=e,e}function kt(){clearTimeout(U)}function gt(){if(!k||!x)return;let e=Z.get(k);if(!e)return;let t=de(k,x,{placement:e.placement,offset:e.offset});x.style.top=`${t.top}px`,x.style.left=`${t.left}px`,x.style.setProperty("--fw-tooltip-arrow-pos",`${t.arrowOffset}px`),x.setAttribute("data-placement",t.placement)}function fe(){cancelAnimationFrame(je),je=requestAnimationFrame(gt)}function Ht(e){var o;if(clearTimeout(W),kt(),!Z.get(e))return;k=e;let n=Mn();n.textContent=(o=e.dataset.fwTooltipText)!=null?o:"",gt(),n.classList.add("is-open"),window.addEventListener("scroll",fe,!0),window.addEventListener("resize",fe)}function _(){clearTimeout(W),clearTimeout(U),x&&x.classList.remove("is-open"),window.removeEventListener("scroll",fe,!0),window.removeEventListener("resize",fe),cancelAnimationFrame(je),k&&(At=performance.now()),k=null}function Ke(e,t){clearTimeout(U),clearTimeout(W);let n=Z.get(e);n&&(t||performance.now()-At<bn?Ht(e):W=window.setTimeout(()=>Ht(e),n.delay))}function St(){clearTimeout(W),clearTimeout(U),U=window.setTimeout(_,xn)}function Ot(e,t={}){var d,s,u;let n={placement:(d=t.placement)!=null?d:"top",offset:(s=t.offset)!=null?s:6,delay:(u=t.delay)!=null?u:Ln};Z.set(e,n);let o=e.getAttribute("title");o!==null&&(e.dataset.fwTooltipText=o,e.removeAttribute("title")),e.setAttribute("aria-describedby","fw-tooltip");let r=()=>Ke(e,!1),i=()=>St(),l=()=>Ke(e,!0),a=()=>{k===e&&_()},c=E=>{E.key==="Escape"&&k===e&&_()};return e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",i),e.addEventListener("focus",l),e.addEventListener("blur",a),e.addEventListener("keydown",c),{show:()=>Ke(e,!0),hide:()=>{k===e&&_()},destroy(){k===e&&_(),e.removeEventListener("mouseenter",r),e.removeEventListener("mouseleave",i),e.removeEventListener("focus",l),e.removeEventListener("blur",a),e.removeEventListener("keydown",c),e.removeAttribute("aria-describedby"),e.dataset.fwTooltipText!==void 0&&(e.setAttribute("title",e.dataset.fwTooltipText),delete e.dataset.fwTooltipText),Z.delete(e),delete e.dataset.fwBound}}}function _e(e=document){e.querySelectorAll("[data-fw-tooltip]").forEach(t=>{t.dataset.fwBound||(t.dataset.fwBound="1",Ot(t,{placement:t.dataset.fwTooltipPlacement||void 0,offset:t.dataset.fwTooltipOffset?Number(t.dataset.fwTooltipOffset):void 0,delay:t.dataset.fwTooltipDelay?Number(t.dataset.fwTooltipDelay):void 0}))})}var ve={};y(ve,{init:()=>We,tabs:()=>It});function Hn(e,t){e.dispatchEvent(new CustomEvent("fw:tabs-change",{bubbles:!0,detail:t}))}function pe(e){return e.getAttribute("aria-disabled")==="true"}function Ze(e){let t=e.getAttribute("aria-controls");return t?document.getElementById(t):null}function Ct(e){return e instanceof Element?e.closest('[role="tab"]'):null}function Dt(e,t,n){for(let o=1;o<=e.length;o++){let r=((t+n*o)%e.length+e.length)%e.length;if(!pe(e[r]))return e[r]}}function Pt(e){return e.find(t=>!pe(t))}function An(e){for(let t=e.length-1;t>=0;t--)if(!pe(e[t]))return e[t]}function It(e,t={}){var d;let n=(d=t.activation)!=null?d:"automatic";function o(){return Array.from(e.querySelectorAll('[role="tab"]'))}function r(s,u=!1){if(pe(s))return;o().forEach(m=>{let p=m===s;m.setAttribute("aria-selected",String(p)),m.tabIndex=p?0:-1;let v=Ze(m);v&&(v.hidden=!p)}),u&&s.focus();let E=Ze(s);E&&Hn(e,{tab:s,panel:E})}function i(s){o().forEach(u=>{u.tabIndex=u===s?0:-1}),s.focus()}function l(){var E;let s=o(),u=(E=s.find(m=>m.getAttribute("aria-selected")==="true"))!=null?E:Pt(s);s.forEach(m=>{let p=m===u;m.setAttribute("aria-selected",String(p)),m.tabIndex=p?0:-1;let v=Ze(m);v&&(v.hidden=!p)})}function a(s){let u=Ct(s.target);u&&e.contains(u)&&r(u,!1)}function c(s){let u=Ct(s.target);if(!u)return;let E=o(),m=E.indexOf(u);if(m===-1)return;if(s.key===" "||s.key==="Enter"){n==="manual"&&(s.preventDefault(),r(u,!1));return}let p=e.getAttribute("aria-orientation")==="vertical",v=getComputedStyle(e).direction==="rtl",b=p?"ArrowDown":v?"ArrowLeft":"ArrowRight",M=p?"ArrowUp":v?"ArrowRight":"ArrowLeft",T;if(s.key===b)T=Dt(E,m,1);else if(s.key===M)T=Dt(E,m,-1);else if(s.key==="Home")T=Pt(E);else if(s.key==="End")T=An(E);else return;T&&(s.preventDefault(),n==="manual"?i(T):r(T,!0))}return e.addEventListener("click",a),e.addEventListener("keydown",c),l(),{activate:r,destroy(){e.removeEventListener("click",a),e.removeEventListener("keydown",c),delete e.dataset.fwBound}}}function We(e=document){e.querySelectorAll('[role="tablist"][data-fw-tabs]').forEach(t=>{if(t.dataset.fwBound)return;t.dataset.fwBound="1";let n=t.dataset.fwTabsActivation==="manual"?"manual":"automatic";It(t,{activation:n})})}var Nt="0.4.0";function Bt(e=document){Le(e),be(e),ge(e),Ce(e),De(e),Re(e),$e(e),he(e),Ve(e),_e(e),We(e)}var kn={version:Nt,init:Bt,theme:X,combobox:J,modal:Q,nav:te,loading:ne,toast:oe,table:ie,menu:ae,icon:z,popover:ue,tooltip:me,tabs:ve},gn=kn;
4
4
  //# sourceMappingURL=fernwell.cjs.map