staffa 0.12.1 → 0.13.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/README.md CHANGED
@@ -180,17 +180,19 @@ Navigations settle asynchronously (closes travel through the browser's history),
180
180
 
181
181
  Navigating faster than the shell can settle is fine: closing travels through the browser's history, so it takes a moment to land, and anything asked for in the meantime waits for it rather than being dropped. Two quick Escapes (or back gestures) peel two panels, each aimed at the stack the one before it was heading for.
182
182
 
183
- **Every panel must work at 360–540px**, because that is what it gets whenever two columns fit. `$panel.maxWidth` says how much *more* it can usefully take. The content area is the page, at most 1280px wide, minus the nav sidebar:
183
+ **Every panel must work at 360–540px**, because that is what it gets whenever two columns fit. `$panel.maxWidth` says how much *more* it can usefully take. The content area is what `S.main()`'s `fullWidth` says it is 1080px by default:
184
184
 
185
185
  | `maxWidth` | How wide the panel gets | Good for |
186
186
  | --- | --- | --- |
187
187
  | `"half"` | Half the content area: 360 to 540px. | lists, detail forms — anything that reads well at phone width |
188
- | `"full"` (default) | The whole content area: up to ~1100px. | ordinary screens; the safe default |
189
- | `"screen"` | The whole window, no upper limit: ~1750px on a 1920px screen. | boards, wide tables, dense dashboards |
188
+ | `"full"` (default) | The whole content area: up to 1080px. | ordinary screens; the safe default |
189
+ | `"screen"` | The whole window, no upper limit: ~1720px on a 1920px screen. | boards, wide tables, dense dashboards |
190
190
 
191
- Below the width two columns need, everything takes the whole content area whatever it asked for. Those numbers assume a nav sidebar of around 170px; without one, add that back. Nothing fits beside a `"full"` on a standard 1280px page, but on a wide enough window a `"half"` still can, and the page grows past 1280px to hold both.
191
+ Below the width two columns need, everything takes the whole content area whatever it asked for. Nothing fits beside a `"full"` on a standard page, but on a wide enough window a `"half"` still can, and the page grows to hold both.
192
192
 
193
- A column's width depends only on the size of the window, never on what else is open. So opening or closing a panel never resizes the ones already on screen, and never reflows what someone was reading. A lone `"half"` leaves its other half empty, and that is exactly where the next one lands. When more columns fit than the standard 1280px page holds (three halves, say), the page itself grows, staying centred, to hold them — though the top bar and footer keep to the standard width, so the chrome holds still while the columns come and go.
193
+ The standard page is those 1080px plus the nav sidebar's 200 the 1280px an app is usually seen at, though neither figure is fixed: `S.main({ navWidth, fullWidth })` sets both, and everything above follows from them.
194
+
195
+ A column's width depends only on the size of the window, never on what else is open. So opening or closing a panel never resizes the ones already on screen, and never reflows what someone was reading. A lone `"half"` leaves its other half empty, and that is exactly where the next one lands. When more columns fit than the standard page holds (three halves, say), the page itself grows, staying centred, to hold them — though the top bar and footer keep to the standard width, so the chrome holds still while the columns come and go.
194
196
 
195
197
  Columns tile that area, separated by a hairline and no gutter — a column brings its own padding, so their contents stay comfortably apart regardless.
196
198
 
@@ -217,6 +217,20 @@ export interface MainOptions<R = Routes> {
217
217
  * themselves up with them.
218
218
  */
219
219
  maxWidth?: string;
220
+ /**
221
+ * How wide a `"full"` panel gets, in pixels — and with it the whole content
222
+ * area, since a `"full"` fills it exactly. A `"half"` gets half of this, and
223
+ * a `"screen"` ignores it and takes the window. Defaults to 1080; the window
224
+ * caps it when there is less room than that. Routed mode only.
225
+ *
226
+ * This plus {@link MainOptions.navWidth} is the app's standard page — see
227
+ * there.
228
+ *
229
+ * Live, like {@link MainOptions.columns}: pass a proxied options object (or
230
+ * make this field a getter) and a change is adopted in one layout pass,
231
+ * every panel keeping its state.
232
+ */
233
+ fullWidth?: number;
220
234
  /** Aberdeen attr/style string applied to the content area. */
221
235
  contentAttrs?: Attributes;
222
236
  /** Aberdeen attr/style string applied to the top bar. */
@@ -243,6 +257,17 @@ export interface MainOptions<R = Routes> {
243
257
  * chrome goes assumes they are one.
244
258
  */
245
259
  navPosition?: "left" | "right";
260
+ /**
261
+ * How wide the nav sidebar column is, in pixels — its hairline included.
262
+ * Defaults to 200.
263
+ *
264
+ * Together with {@link MainOptions.fullWidth} this is the app's *standard
265
+ * page*: the width the top bar and footer keep to, and the width the
266
+ * columns settle back to. The defaults come to the familiar 1280px.
267
+ *
268
+ * Live, like {@link MainOptions.fullWidth}.
269
+ */
270
+ navWidth?: number;
246
271
  /** Aberdeen attr/style string applied to the sidebar nav panel. */
247
272
  navAttrs?: Attributes;
248
273
  /** Aberdeen attr/style string applied to the narrow-screen full-page nav. */
@@ -8,7 +8,16 @@ import { drawMenu, isFloatingMenuOpen, consumeBranchNav, anyCurrent } from "./me
8
8
  import { menu as menuIcon, x as closeIcon } from "../icons.js";
9
9
  import { iconButton } from "./button.js";
10
10
  import { isDialogOpen } from "./dialog.js";
11
- import { PanelStackController, SHELL_PX } from "./panels.js";
11
+ import { PanelStackController } from "./panels.js";
12
+ /**
13
+ * The default nav column (hairline included) and the default width of a
14
+ * `"full"` panel — see {@link MainOptions.navWidth} and
15
+ * {@link MainOptions.fullWidth}. Side by side they come to the 1280px page the
16
+ * shell is usually seen as, but that figure lives nowhere: the browser adds
17
+ * these two up, and an app that changes either simply gets a different page.
18
+ */
19
+ const NAV_W = 200;
20
+ const FULL_W = 1080;
12
21
  A.insertGlobalCss({
13
22
  ".s-main": {
14
23
  // container-type so @container queries below can respond to shell width.
@@ -89,7 +98,7 @@ A.insertGlobalCss({
89
98
  ".s-body main.s-scroll-y": "margin-right:$3",
90
99
  // Routed mode takes its width from the stack instead of from
91
100
  // `maxWidth`: the layout engine publishes the ensemble width (sidebar +
92
- // separator + content area) as --s-shell-w — the standard 1280px page
101
+ // separator + content area) as --s-shell-w — the standard page
93
102
  // normally, wider while the columns outgrow it (a "screen" page, or
94
103
  // extra columns fitting a wide window) — and the body row caps itself
95
104
  // to it, staying centred around the columns. Changing the custom
@@ -107,7 +116,7 @@ A.insertGlobalCss({
107
116
  // the columns grow. (Below the standard width the ensemble is simply
108
117
  // the window, which only a resize changes — so the bars never animate,
109
118
  // and take no part in the transition above.)
110
- [`&.s-routed > header > .s-bar, &.s-routed > footer > .s-bar`]: `max-width:${SHELL_PX}px`,
119
+ "&.s-routed > header > .s-bar, &.s-routed > footer > .s-bar": "max-width: calc(var(--s-nav-w) + var(--s-full-w))",
111
120
  },
112
121
  // Sidebar nav panel. Items reuse the shared `.s-menu-item` /
113
122
  // `.s-menu-sep` styles from menu.ts, so the sidebar and the floating
@@ -118,7 +127,10 @@ A.insertGlobalCss({
118
127
  // The generous horizontal padding is what keeps the rows clear of the content
119
128
  // separator on one side and the shell edge on the other; the vertical scroll
120
129
  // (overflow-y:auto, which also clips overflow-x) leaves no room to bleed past it.
121
- "&": "display:flex flex-direction:column overflow-y:auto flex-shrink:0 max-width:228px padding:$3 gap:$1",
130
+ // `--s-nav-w` measures the whole column, hairline included, so the panel
131
+ // itself gives that 1px back — and the app's two widths then add up to
132
+ // exactly the page the bars above and below keep to.
133
+ "&": "display:flex flex-direction:column overflow-y:auto flex-shrink:0 width: calc(var(--s-nav-w) - 1px); padding:$3 gap:$1",
122
134
  },
123
135
  // The narrow-screen nav: a full "panel" that slides in over the content from the
124
136
  // left, rather than a dropdown — on a phone a nav is a screenful of UI, not a
@@ -196,6 +208,9 @@ export function main(opts = {}) {
196
208
  notFound: opts.notFound,
197
209
  ancestors: opts.ancestors,
198
210
  title: opts.title,
211
+ // Corrected below, and on every change, from the app's own option:
212
+ // read here it would subscribe the whole shell to it.
213
+ fullWidth: FULL_W,
199
214
  $shell,
200
215
  })
201
216
  : null;
@@ -207,6 +222,7 @@ export function main(opts = {}) {
207
222
  // the new link default. Nothing else of the shell is touched.
208
223
  A(() => ctl.setColumns(opts.columns));
209
224
  A(() => ctl.setLinkNavigation(opts.linkNavigation));
225
+ A(() => ctl.setFullWidth(opts.fullWidth ?? FULL_W));
210
226
  }
211
227
  // Where the brand mark and the app's name link — or nowhere, when the app
212
228
  // said `home: null` (a title slot holding a control of its own, say).
@@ -215,13 +231,22 @@ export function main(opts = {}) {
215
231
  // rather than to `maxWidth`.
216
232
  const capWidth = ctl ? null : opts.maxWidth;
217
233
  const root = A(`div.s-main${ctl ? ".s-routed" : ""}`, opts.attrs, () => {
218
- // Which side the sidebar is on, as a class on the shell for the CSS above to
219
- // hang off. Its own scope (see `nav` above), so a nav appearing or emptying
220
- // out only retags the shell rather than redrawing it.
234
+ // The two widths the CSS above works from, and with them the standard page
235
+ // the bars keep to. Each sits in a scope of its own one that draws
236
+ // nothing, so re-running it is a single style write: an app that changes
237
+ // either on a proxied options object resizes the shell in place, panels
238
+ // and their state untouched.
239
+ A(() => A(`--s-full-w: ${opts.fullWidth ?? FULL_W}px`));
240
+ // `--s-nav-w` is the sidebar's whole column, and nothing at all when there
241
+ // is no sidebar to give it to — a shell without one lines its bars up with
242
+ // the content. This scope also tags the shell with the side the sidebar is
243
+ // on, for the CSS above to hang off (see `nav` above: reading `nav.items`
244
+ // here subscribes this scope alone, never the shell entire).
221
245
  A(() => {
222
246
  if (nav == null || !nav.items.length)
223
- return;
224
- A(`.s-nav-${navPos}`);
247
+ A("--s-nav-w: 0px");
248
+ else
249
+ A(`.s-nav-${navPos}`, `--s-nav-w: ${opts.navWidth ?? NAV_W}px`);
225
250
  });
226
251
  // Top bar: `[leading] [identity] …spacer… [trailing]`, where each slot's
227
252
  // contents depend on how much room the shell has and — in routed mode — on
@@ -157,13 +157,15 @@ export interface Panel<P = Record<string, string | number | string[]>> {
157
157
  * because that is what it gets when two columns fit; this says how much
158
158
  * *more* it can take.
159
159
  *
160
- * - `"half"` — nothing more. Half the content area (360–540px), so a second
161
- * column fits beside it. For lists and detail forms.
162
- * - `"full"` (the default) — the whole content area, up to ~1100px.
160
+ * - `"half"` — nothing more. Half the content area (360px up to half of
161
+ * {@link MainOptions.fullWidth}), so a second column fits beside it. For
162
+ * lists and detail forms.
163
+ * - `"full"` (the default) — the whole content area, which is exactly
164
+ * {@link MainOptions.fullWidth}: 1080px unless the app says otherwise.
163
165
  * - `"screen"` — the whole window, unbounded: boards, wide tables, dense
164
166
  * dashboards. While one is open the columns stretch to the screen edges
165
- * instead of stopping at the standard 1280px page; the top bar and
166
- * footer hold the standard width throughout.
167
+ * instead of stopping at the standard page; the top bar and footer hold
168
+ * the standard width throughout.
167
169
  *
168
170
  * Below the width two columns need, everything takes the content area
169
171
  * whatever it asked for. Widths depend only on the window, never on what
@@ -275,14 +277,6 @@ export interface Panel<P = Record<string, string | number | string[]>> {
275
277
  */
276
278
  open(href: string, how?: "push" | "replace" | "open"): Promise<boolean>;
277
279
  }
278
- /**
279
- * The standard page width: sidebar plus content area, capped by the window.
280
- * `"full"` fills the content-area part of this exactly; only a `"screen"`
281
- * page makes the shell grow past it. The top bar and footer keep to this
282
- * width even then (see main.ts), so the chrome holds still while the
283
- * columns stretch.
284
- */
285
- export declare const SHELL_PX = 1280;
286
280
  /** Options the stack needs from its shell. */
287
281
  export interface PanelStackOptions {
288
282
  routes: Routes;
@@ -293,6 +287,8 @@ export interface PanelStackOptions {
293
287
  columns?: "auto" | "single";
294
288
  /** What a bare link does. See {@link MainOptions.linkNavigation}. */
295
289
  linkNavigation?: "push" | "replace" | "open";
290
+ /** How wide a `"full"` panel gets, in px. See {@link MainOptions.fullWidth}. */
291
+ fullWidth: number;
296
292
  /** The shell's own title, used as the suffix of `document.title`. */
297
293
  title?: unknown;
298
294
  /**
@@ -455,8 +451,8 @@ export declare class PanelStackController implements PanelStack {
455
451
  private containerEl?;
456
452
  /** The shell's measurements, shared by everything drawn since they were taken. */
457
453
  private geom?;
458
- /** The body width at the last layout; a change means a window resize → snap. */
459
- private lastBodyW;
454
+ /** The measurements the last layout ran on; a change in them → snap. */
455
+ private lastGeom?;
460
456
  private layoutQueued;
461
457
  private timers;
462
458
  /** The arrangement the navigation in flight is heading for; see {@link intended}. */
@@ -673,6 +669,12 @@ export declare class PanelStackController implements PanelStack {
673
669
  setColumns(columns: "auto" | "single" | undefined): void;
674
670
  /** Adopt a changed `linkNavigation` default; the next click reads it. */
675
671
  setLinkNavigation(mode: "push" | "replace" | "open" | undefined): void;
672
+ /**
673
+ * Adopt a changed `fullWidth`: one layout pass, nothing redrawn. A changed
674
+ * `navWidth` needs no counterpart — resizing the sidebar resizes the column
675
+ * region, which the layout engine is already observing.
676
+ */
677
+ setFullWidth(px: number): void;
676
678
  /**
677
679
  * The breadcrumb stack, drawn by `main()` into the top bar: every open
678
680
  * panel, oldest first, the ones on screen right now in bold, pinned ones
@@ -123,14 +123,6 @@ function matchRoute(r, segments) {
123
123
  const PAGE_MS = 250;
124
124
  /** How long a freshly pushed `loading` panel holds its enter animation. */
125
125
  const LOADING_HOLD_MS = 300;
126
- /**
127
- * The standard page width: sidebar plus content area, capped by the window.
128
- * `"full"` fills the content-area part of this exactly; only a `"screen"`
129
- * page makes the shell grow past it. The top bar and footer keep to this
130
- * width even then (see main.ts), so the chrome holds still while the
131
- * columns stretch.
132
- */
133
- export const SHELL_PX = 1280;
134
126
  /** Don't pair smalls when half the content area would be narrower than this. */
135
127
  const PAIR_MIN_PX = 360;
136
128
  /**
@@ -361,8 +353,8 @@ export class PanelStackController {
361
353
  containerEl;
362
354
  /** The shell's measurements, shared by everything drawn since they were taken. */
363
355
  geom;
364
- /** The body width at the last layout; a change means a window resize → snap. */
365
- lastBodyW = -1;
356
+ /** The measurements the last layout ran on; a change in them → snap. */
357
+ lastGeom;
366
358
  layoutQueued = false;
367
359
  timers = new Set();
368
360
  /** The arrangement the navigation in flight is heading for; see {@link intended}. */
@@ -1041,6 +1033,17 @@ export class PanelStackController {
1041
1033
  setLinkNavigation(mode) {
1042
1034
  this.opts.linkNavigation = mode;
1043
1035
  }
1036
+ /**
1037
+ * Adopt a changed `fullWidth`: one layout pass, nothing redrawn. A changed
1038
+ * `navWidth` needs no counterpart — resizing the sidebar resizes the column
1039
+ * region, which the layout engine is already observing.
1040
+ */
1041
+ setFullWidth(px) {
1042
+ if (this.opts.fullWidth === px)
1043
+ return;
1044
+ this.opts.fullWidth = px;
1045
+ this.scheduleLayout();
1046
+ }
1044
1047
  /**
1045
1048
  * The breadcrumb stack, drawn by `main()` into the top bar: every open
1046
1049
  * panel, oldest first, the ones on screen right now in bold, pinned ones
@@ -1368,25 +1371,21 @@ export class PanelStackController {
1368
1371
  if (child !== container)
1369
1372
  chrome += child.getBoundingClientRect().width;
1370
1373
  }
1371
- // The standard panel is SHELL_PX wide, capped by the window; what it leaves
1372
- // beside the sidebar is the *standard* content area. Widths are a pure
1373
- // function of the window never of what else is open so a panel NEVER
1374
- // resizes because a neighbour came or went; only a window resize (the
1375
- // snap pass in `layout`) changes them:
1374
+ // What the window has beside the sidebar, and within that the *standard*
1375
+ // content area: the width the app gave a "full" panel, or all there is
1376
+ // when the window has less. Widths are a pure function of the window
1377
+ // never of what else is open so a panel NEVER resizes because a
1378
+ // neighbour came or went; only a window resize (the snap pass in
1379
+ // `layout`) changes them:
1376
1380
  // - "full" fills the standard content area exactly;
1377
1381
  // - "half" is half of it whenever that half is still a usable column, and
1378
1382
  // the whole of it on narrower screens;
1379
1383
  // - "screen" ignores the standard width and takes everything the window
1380
1384
  // has — which also means nothing ever fits beside it.
1381
- const full = Math.max(0, Math.min(SHELL_PX, total) - chrome);
1385
+ const screen = Math.max(0, total - chrome);
1386
+ const full = Math.min(this.opts.fullWidth, screen);
1382
1387
  const halved = full / 2;
1383
- return {
1384
- total,
1385
- chrome,
1386
- half: halved >= PAIR_MIN_PX ? halved : full,
1387
- full,
1388
- screen: Math.max(0, total - chrome),
1389
- };
1388
+ return { total, chrome, half: halved >= PAIR_MIN_PX ? halved : full, full, screen };
1390
1389
  }
1391
1390
  /**
1392
1391
  * The measurements this pass runs on. Taken once per layout pass and per
@@ -1430,13 +1429,16 @@ export class PanelStackController {
1430
1429
  if (!geom)
1431
1430
  return;
1432
1431
  const stacking = this.opts.columns !== "single";
1433
- // A window resize (or the very first pass) must be adopted instantly —
1434
- // geometry tracking the window through a 450ms transition reads as lag,
1435
- // and a shell animating itself into place on load reads as a glitch.
1432
+ // A window resize or the app resizing the shell itself, by changing
1433
+ // `navWidth` or `fullWidth` must be adopted instantly: geometry tracking
1434
+ // the window through a 450ms transition reads as lag, and a shell
1435
+ // animating itself into place on its first pass reads as a glitch. Only
1436
+ // what a *panel* did is worth animating, and none of those three are.
1436
1437
  // `.s-shell-snap` suppresses every standing transition for this one pass.
1437
- const snap = this.lastBodyW !== geom.total;
1438
+ const was = this.lastGeom;
1439
+ const snap = was == null || was.total !== geom.total || was.chrome !== geom.chrome || was.full !== geom.full;
1438
1440
  if (snap) {
1439
- this.lastBodyW = geom.total;
1441
+ this.lastGeom = geom;
1440
1442
  shell.classList.add("s-shell-snap");
1441
1443
  }
1442
1444
  const width = (entry) => geom[entry.maxWidth];
@@ -1458,7 +1460,7 @@ export class PanelStackController {
1458
1460
  // The content area holds the run, but is never smaller than the standard
1459
1461
  // panel (a lone small leaves its other half open — which is exactly where
1460
1462
  // the next small lands, without anything on screen moving) and never
1461
- // wider than the window. So the panel is the familiar 1280px until extra
1463
+ // wider than the window. So the page holds its standard width until extra
1462
1464
  // columns genuinely fit, and stretches — centred — to hold the ones that
1463
1465
  // do; with a "screen" up that's the window's edges.
1464
1466
  const area = Math.min(geom.screen, Math.max(geom.full, runSum));
@@ -1 +1 @@
1
- import E from"aberdeen";var Y="background: linear-gradient(170deg, color-mix(in oklab, $s-bg, white 9%), color-mix(in oklab, $s-bg, black 9%));",u1="staffa:darkMode",T1=E.proxy({value:d2()});function d2(){try{let t=localStorage.getItem(u1);if(t==="dark")return!0;if(t==="light")return!1}catch{}}function o2(t){T1.value=t;try{t===void 0?localStorage.removeItem(u1):localStorage.setItem(u1,t?"dark":"light")}catch{}}function D1(t=!1){let a=T1.value;return a===void 0&&!t?E.darkMode():a}E(()=>{D1()?E.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#0e0f12 --s-text:#e9eaec",".s-s.neutral":"--s-bg:#191b1f --s-text:#e9eaec",".s-s.neutral .s-s.neutral":"--s-bg:#23262b"}):E.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#eef0f3 --s-text:#1d1f24",".s-s.neutral, .s-s.neutral":"--s-bg:#ffffff --s-text:#1d1f24",".s-s.neutral .s-s.neutral":"--s-bg:#f6f7f9"})});E.setSpacingCssVars(1.1);E.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 p:$3 line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased background-color:$s-bg text:$s-text",a:"color: $s-link-fg; text-decoration:underline text-underline-offset:2px; transition: color 0.12s, filter 0.12s;","a:hover":"filter: brightness(1.15)","input, button, textarea, select, optgroup":"font:inherit color:inherit","input:where(:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=image],[type=submit],[type=button],[type=reset],[type=hidden])), textarea, select":"background:$s-bg border: 1px solid $s-faint; r:$s-radius-sm padding: 0.45em 0.65em; max-width:100%","input:where([type=checkbox],[type=radio])":"width:1.15em height:1.15em cursor:pointer","input[type=range]":"appearance:none background:transparent cursor:pointer vertical-align:middle","input[type=range]::-webkit-slider-runnable-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-progress":"height:4px r:99px background:$s-accent","input[type=range]::-webkit-slider-thumb":"appearance:none width:16px height:16px margin-top:-6px r:50% background:$s-accent","input[type=range]::-moz-range-thumb":"width:16px height:16px border:0 r:50% background:$s-accent","input[type=file]":"cursor:pointer",progress:"appearance:none border:0 height:6px r:99px background:$s-faint overflow:hidden vertical-align:middle","progress::-webkit-progress-bar":"background:$s-faint r:99px","progress::-webkit-progress-value":"background:$s-accent r:99px","progress::-moz-progress-bar":"background:$s-accent r:99px",meter:"vertical-align:middle",fieldset:"border: 1px solid $s-faint; r:$s-radius-sm padding:$2 min-width:0",legend:"padding: 0 $1; font-weight:600","code, kbd, samp, pre":"font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;",code:"background: color-mix(in oklab, $s-text, $s-bg 86%); padding: 0.12em 0.34em; r:4px font-size:0.9em",pre:"background: color-mix(in oklab, $s-text, $s-bg 92%); p:$3 r: $s-radius; overflow:auto","pre code":"background:transparent p:0","img, svg, video, canvas":"max-width:100% h:auto",hr:"border:0 border-top: 1px solid $s-faint;","::placeholder":"color: $s-muted; opacity:1",":focus-visible":"outline: 2px solid $s-focus; outline-offset:2px",small:"color:$s-muted font-size:0.9em","@media (prefers-reduced-motion: reduce)":{"*, *::before, *::after":"transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important;"},":root":"--s-primary:#00a884 --s-danger:#dc5b41 --s-success:#00a884 --s-warning:#ef6b00 --s-link:#3f8cd8 --s-radius-sm:6px --s-radius:12px --s-radius-lg:18px --s-focus: color-mix(in srgb, $s-primary 38%, transparent); --s-gradient: linear-gradient(135deg, color-mix(in oklab, $s-primary, white 16%), color-mix(in oklab, $s-primary, black 14%));",":root, .s-s.neutral":"--s-accent:$s-primary --s-link-fg:$s-link",".s-s:not(.neutral)":"--s-bg:$s-primary border:0 --s-text:#eee --s-accent:#fff --s-link-fg:#eef --s-muted: color-mix(in srgb, #fff 70%, transparent); --s-faint: color-mix(in srgb, #fff 30%, transparent);",".s-s.danger":"--s-bg:$s-danger",".s-s.success":"--s-bg:$s-success",".s-s.warning":"--s-bg:$s-warning",".s-s.link":"--s-bg:$s-link",".s-s.primary":"--s-bg:$s-primary",":root, .s-s":"--s-muted: color-mix(in oklab, $s-text, $s-bg 42%); --s-faint: color-mix(in oklab, $s-text, $s-bg 80%); color:$s-text accent-color:$s-accent scrollbar-width:thin scrollbar-color: $s-faint transparent;",".s-s, body":Y,".s-s":"r:$s-radius",":where(.s-s.neutral)":"border: 1px solid $s-faint;",".s-s::-webkit-scrollbar, .s-s ::-webkit-scrollbar":"width:10px height:10px",".s-s::-webkit-scrollbar-track, .s-s ::-webkit-scrollbar-track":"background:transparent",".s-s::-webkit-scrollbar-thumb, .s-s ::-webkit-scrollbar-thumb":"background:$s-faint border-radius:99px border: 2px solid transparent; background-clip:padding-box",".s-s.shadow.neutral:not(.s-btn)":"box-shadow: 0 4px 14px rgba(0,0,0,0.13);",".s-s.extra-shadow.neutral:not(.s-btn)":"box-shadow: 0 18px 50px rgba(0,0,0,0.28);",".s-s.shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 4px 14px color-mix(in srgb, $s-bg 30%, transparent);",".s-s.extra-shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 14px 40px color-mix(in srgb, $s-bg 40%, transparent);",".s-s.no-shadow":"box-shadow: none !important;",".s-s:not(.neutral).tonal, .s-s:not(.neutral).outlined":"--s-text:$s-bg --s-accent:$s-bg --s-link-fg:$s-bg --s-faint: color-mix(in srgb, $s-bg 30%, transparent); --s-muted: color-mix(in srgb, $s-bg 70%, transparent);",".s-s:not(.neutral).tonal":"background: color-mix(in srgb, $s-bg 15%, transparent); border: 1px solid $s-faint;",".s-s:not(.neutral).outlined":"background: transparent; border: 1px solid color-mix(in srgb, $s-bg 45%, transparent);",".s-s:not(.neutral) .s-s.tonal, .s-s:not(.neutral) .s-s.outlined":"--s-text:#fff --s-accent:#fff --s-link-fg:#fff "+Y+" border-color: transparent;"});E.insertGlobalCss({".s-preload, .s-preload *, .s-preload *::before, .s-preload *::after":"transition: none !important; animation: none !important;"});if(typeof document<"u"&&typeof requestAnimationFrame=="function"){let t=document.documentElement;t.classList.add("s-preload"),requestAnimationFrame(()=>requestAnimationFrame(()=>t.classList.remove("s-preload")))}E.insertGlobalCss({":disabled, [aria-disabled=true]":"opacity:0.45 filter:saturate(0.6) user-select:none",":disabled, [aria-disabled=true], :disabled *, [aria-disabled=true] *":"pointer-events:none cursor:not-allowed"});var c2="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";E.insertGlobalCss({[`${c2}`]:{"&":"margin:0","&:not(:first-child)":"margin-top:$3"},"h1, h2, h3, h4, h5, h6":{"&":"line-height:1.15 font-weight:700 text-wrap:balance","&:not(:first-child)":"margin-top:1.4em"},h1:"font-size:2em font-weight:800 letter-spacing:-0.022em",h2:"font-size:1.55em letter-spacing:-0.018em",h3:"font-size:1.3em letter-spacing:-0.011em",h4:"font-size:1.1em",h5:"font-size:0.95em letter-spacing:0.005em",h6:"font-size:0.8em fg:$s-muted text-transform:uppercase letter-spacing:0.07em","ul, ol":{"&":"padding-left:1.5em","> li:not(:first-child), li > &:not(:first-child)":"margin-top:$1"},blockquote:"border-left: 3px solid $s-faint; padding-left: $3; fg: $s-muted",table:"border-collapse:collapse","th, td":"text-align:left padding: $1 $2; border-bottom: 1px solid $s-faint; vertical-align:top",th:"font-weight:600","thead th":"border-bottom: 2px solid $s-faint;",dt:"font-weight:600",dd:"margin-left: 1.5em",figcaption:"fg:$s-muted font-size:0.9em margin-top:$1 text-align:center"});import M from"aberdeen";import R1 from"aberdeen";var r1=640,n2=0;function B(t="s"){return`${t}-${++n2}`}function v(t,...a){t!=null&&(typeof t=="function"?t(...a):R1("rich=",t))}var i2="a[href], button, input, select, textarea, [tabindex]";function j(t,a){let h=p=>p instanceof HTMLElement&&!p.hasAttribute("disabled")&&p.getAttribute("aria-disabled")!=="true"&&p.tabIndex>=0&&p.getClientRects().length>0,e=(a?[...t.querySelectorAll(a)].find(h):void 0)??[...t.querySelectorAll(i2)].find(h);return e?.focus(),e!=null}function F(t){queueMicrotask(()=>R1(t))}import L from"aberdeen";L.insertGlobalCss({".s-field":{"&":"display:flex flex-direction:column gap:$1","> label":"font-weight:600 font-size:0.9em fg:$s-text user-select:none"},".s-req":"fg:$s-danger margin-left:2px",".s-help":"font-size:0.82em fg:$s-muted",".s-error":"font-size:0.82em fg:$s-danger",".s-input":{"&":"w:100% background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.55em 0.7em; transition: border-color 0.15s, box-shadow 0.15s;","&:hover:not(:disabled)":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","&:focus-visible":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus; outline:none","&[aria-invalid=true]":"border-color:$s-danger"}});function I(t,a){let h=t.id??B("field"),e=()=>!!t.error;L("div.s-field",t.attrs,()=>{L(()=>{t.label!=null&&L("label for=",h,()=>{v(t.label),t.required&&L("span.s-req aria-hidden=true #*")})}),a(h,e),L(()=>{t.help!=null&&!t.error&&L("div.s-help",()=>v(t.help))}),L(()=>{t.error&&L("div.s-error role=alert #",t.error)})})}function _(t,a,h,e){L("id=",a),t.name&&L("name=",t.name),L(()=>{t.disabled&&L("disabled=true")}),L(()=>{t.required&&L("aria-required=true")}),L(()=>L("aria-invalid=",h()?"true":"false")),e&&L("bind=",e)}M.insertGlobalCss({".s-ac":{"&":"position:relative","> .s-control":"display:flex flex-wrap:wrap align-items:center gap:$1 background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.3em 0.4em; cursor:text; transition: border-color 0.15s, box-shadow 0.15s;","> .s-control:hover":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","> .s-control:focus-within":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus;","&[aria-invalid=true] > .s-control":"border-color:$s-danger",".s-chip":"display:inline-flex align-items:center gap:$1 font-size:0.85em background: color-mix(in oklab, $s-bg, $s-text 10%); border: 1px solid $s-faint; r:$s-radius padding: 0.1em 0.2em 0.1em 0.5em;",".s-chip > button":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.2em; r:4px",".s-chip > button:hover":"fg:$s-text background:$s-faint",input:"flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em","> .s-menu":"position:absolute top:100% left:0 right:0 z-index:20 margin-top:4px max-height:15rem overflow-y:auto list-style:none p:$1 margin-bottom:0","> .s-menu li":"margin:0",".s-option":"padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",".s-option[aria-selected=true]":"background: color-mix(in srgb, $s-text 10%, transparent);",".s-add":"fg:$s-accent font-style:italic",".s-empty":"padding: 0.45em 0.6em; fg:$s-muted"}});function s2(t){return typeof t=="string"?{value:t,label:t}:{value:t.value,label:t.label??t.value}}function l2(t){let a=B("ac-menu"),h=M.proxy({query:"",open:!1,active:0}),e=()=>(typeof t.options=="function"?t.options():t.options).map(s2),p=()=>{let n=t.bind?.value;return n==null||n===""?[]:Array.isArray(n)?n:[n]},r=n=>e().find(m=>m.value===n)?.label??n;if(!t.multi){let n=t.bind?M.peek(t.bind,"value"):void 0;typeof n=="string"&&n&&(h.query=M.peek(()=>r(n)))}let d=()=>{let n=new Set(p()),m=e();t.multi&&(m=m.filter(g=>!n.has(g.value)));let u=h.query.trim().toLowerCase();return u&&(m=m.filter(g=>g.label.toLowerCase().includes(u))),m},o=(n,m)=>{if(t.multi){let u=Array.isArray(t.bind?.value)?[...t.bind.value]:[];u.includes(n)||u.push(n),t.bind&&(t.bind.value=u),h.query=""}else t.bind&&(t.bind.value=n),h.query=r(n),h.open=!1;h.active=0,m?.focus()},c=n=>{if(!t.bind)return;let m=t.bind.value??[];t.bind.value=m.filter(u=>u!==n)};I(t,(n,m)=>{M("div.s-ac",t.inputAttrs,()=>{M(()=>M("aria-invalid=",m()?"true":"false"));let u;M("div.s-control",()=>{M("click=",()=>u?.focus()),M(()=>{if(t.multi)for(let g of p())M("span.s-chip",()=>{M("span #",M.peek(()=>r(g))),M("button type=button aria-label=",`Remove ${g}`,()=>{M("#\xD7"),M("click=",s=>{s.stopPropagation(),c(g),u?.focus()})})})}),u=M("input type=text role=combobox autocomplete=off",()=>{M("id=",n,`aria-controls=${a} aria-autocomplete=list`),t.placeholder!=null&&M("placeholder=",t.placeholder),t.disabled&&M("disabled=true"),t.required&&M("aria-required=true"),M("bind=",M.ref(h,"query")),M(()=>M("aria-expanded=",h.open?"true":"false")),M(()=>{let s=d()[h.active];M("aria-activedescendant=",h.open&&s?`${a}-opt-${h.active}`:"")}),M("input=",()=>{h.open=!0,h.active=0}),M("focus=",()=>{h.open=!0}),M("blur=",()=>{setTimeout(()=>f(),150)}),M("keydown=",g=>i(g,u))})}),M(()=>{if(!h.open)return;let g=d(),s=h.query.trim(),b=t.allowCustom!==!1&&s!==""&&!g.some(C=>C.label.toLowerCase()===s.toLowerCase());M("ul.s-menu.s-s.neutral.shadow role=listbox",`id=${a}`,()=>{g.forEach((C,z)=>{M("li.s-option role=option",`id=${a}-opt-${z}`,()=>{M(()=>M("aria-selected=",h.active===z?"true":"false")),M("#",C.label),M("mousedown=",m1=>m1.preventDefault()),M("click=",()=>o(C.value,u)),M("mousemove=",()=>{h.active=z})})}),b&&M("li.s-option.s-add role=option",()=>{M("#",`Add "${s}"`),M("mousedown=",C=>C.preventDefault()),M("click=",()=>o(s,u))}),g.length===0&&!b&&M("li.s-empty #No matches")})}),M(()=>{if(t.name)if(t.multi)for(let g of p())M("input type=hidden",()=>{M("name=",t.name),M("value=",g)});else M("input type=hidden",()=>{M("name=",t.name),M("value=",p()[0]??"")})})})});function i(n,m){let u=d(),g=u.length-1;if(n.key==="ArrowDown")n.preventDefault(),h.open=!0,h.active=Math.min(g,h.active+1);else if(n.key==="ArrowUp")n.preventDefault(),h.active=Math.max(0,h.active-1);else if(n.key==="Enter"){n.preventDefault();let s=u[h.active];s?o(s.value,m):t.allowCustom!==!1&&h.query.trim()?o(h.query.trim(),m):h.open&&(h.open=!1)}else if(n.key==="Escape")h.open&&(n.preventDefault(),h.open=!1,t.multi||(h.query=r(p()[0]??"")));else if(n.key==="Backspace"&&t.multi&&h.query===""){let s=p();s.length&&c(s[s.length-1])}}function f(){h.open=!1,t.multi?h.query="":t.allowCustom!==!1&&h.query.trim()?o(h.query.trim()):h.query=r(p()[0]??"")}}import N from"aberdeen";import M2 from"aberdeen";var t1={size:24,color:"currentColor",strokeWidth:2,cap:"round",join:"round"};function x2(t,a){let h=a.size??t1.size,e=M2('svg.s-icon aria-hidden=true viewBox="0 0 24 24" fill=none',"width=",h,"height=",h,"stroke=",a.color??t1.color,"stroke-width=",a.strokeWidth??t1.strokeWidth,"stroke-linecap=",a.cap??t1.cap,"stroke-linejoin=",a.join??t1.join,a.attrs);e.innerHTML=t}function $(t){return(a={})=>x2(t,a)}var Z1=$('<path d="m9 18 6-6-6-6" />');var B1=$('<circle cx="12" cy="12" r="10" />');var F1=$('<path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />');var I1=$('<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />');var d1=$('<path d="M4 5h16" /><path d="M4 12h16" /><path d="M4 19h16" />');var U1=$('<path d="M12 17v5" /><path d="M15 9.34V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H7.89" /><path d="m2 2 20 20" /><path d="M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h11" />'),y1=$('<path d="M12 17v5" /><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" />');var N1=$('<path d="M22 2 2 22" />');var Q=$('<path d="M18 6 6 18" /><path d="m6 6 12 12" />');import P from"aberdeen";P.insertGlobalCss({".s-btn":{"&":"display:inline-flex align-items:center justify-content:center gap:$2 font-weight:450 line-height:1.1 white-space:nowrap cursor:pointer text-decoration:none padding: $m2 $m3; transition: background 0.15s, border-color 0.15s, color 0.15s, filter 0.15s, box-shadow 0.15s, transform 0.08s;","&:focus-visible":"outline: 3px solid $s-focus; outline-offset: 1px;","&:hover":"filter: brightness(1.06)","&.tonal:hover, &.outlined:hover":"background: color-mix(in srgb, $s-bg 24%, transparent);","&.neutral:hover":"filter:none background: color-mix(in srgb, $s-text 8%, $s-bg);","> svg":"width:1.25em height:1.25em","&:active:not(:disabled)":"transform: translateY(1px)","&.small, .small > &":"padding: $m1 $m2; font-size:0.85em border-radius:$s-radius-sm","&.large, .large > &":"font-size:1.4em border-radius:$s-radius-lg"},".s-icon-btn":{"&":"display:inline-flex align-items:center justify-content:center flex-shrink:0 width:2rem height:2rem p:0 border:0 background:transparent cursor:pointer fg:$s-muted r:$s-radius-sm line-height:1 font-size:1rem text-decoration:none transition: color 0.12s, background 0.12s;","> svg":"width:1.25em height:1.25em","&:hover:not(:disabled):not([aria-disabled=true])":"fg:$s-text background: color-mix(in srgb, $s-text 10%, transparent);","&:focus-visible":"outline: 3px solid $s-focus; outline-offset:1px","&.small, .small > &":"width:1.6rem height:1.6rem font-size:0.8rem","&.large, .large > &":"width:2.4rem height:2.4rem font-size:1.2rem"}});function a1(t){let a=t.href!=null?"a":"button";P(`${a}.s-icon-btn`,t.attrs,()=>{W1(t),P("aria-label=",t.ariaLabel),v(t.icon)})}function W1(t){t.href!=null?(P("role=button"),t.disabled?P("aria-disabled=true"):P("href=",t.href)):(P("type=",t.type??"button"),t.disabled&&P("disabled=true")),t.click&&!t.disabled&&P("click=",t.click)}function O(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t,h=a.href!=null?"a":"button";P(`${h}.s-btn.s-s.shadow`,a.attrs,()=>{W1(a),a.ariaLabel&&P("aria-label=",a.ariaLabel),v(a.icon),v(a.content)})}N.insertGlobalCss({".s-box":{"&":"display:flex flex-direction:column overflow:hidden r: $s-radius-lg; position:relative","&:not(:first-child)":"margin-top: $3","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0","> div":"p:$3 gap:$3","> header > .s-box-close":"margin-left:auto","> .s-box-close":"position:absolute top:$2 right:$2 z-index:1"}});function v2(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;N("section.s-box.s-s.neutral.shadow",a.attrs,()=>{N(()=>{a.header!=null?N("header.s-s.neutral",a.headerAttrs,()=>{v(a.header),typeof a.close=="function"&&X1(a.close)}):typeof a.close=="function"&&X1(a.close)}),N("div",a.contentAttrs,()=>{v(a.content)}),N(()=>{a.footer!=null&&N("footer.s-s.neutral",a.footerAttrs,()=>v(a.footer))})})}function X1(t){a1({icon:Q,ariaLabel:"Close",click:t,attrs:".s-box-close"})}import f1 from"aberdeen";import G1 from"aberdeen";G1.insertGlobalCss({".s-bgroup":{"&":"display:inline-flex align-items:stretch","&.s-spaced":"gap:$2 flex-wrap:wrap","&.s-vertical":"flex-direction:column","&.s-attached":"gap:0","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child)":"margin-left:-1px","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached:not(.s-vertical) > .s-btn:first-child:not(:last-child)":"border-top-right-radius:0 border-bottom-right-radius:0","&.s-attached:not(.s-vertical) > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-bottom-left-radius:0","&.s-attached.s-vertical > .s-btn:not(:first-child)":"margin-top:-1px","&.s-attached.s-vertical > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached.s-vertical > .s-btn:first-child:not(:last-child)":"border-bottom-left-radius:0 border-bottom-right-radius:0","&.s-attached.s-vertical > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-top-right-radius:0","&.s-attached > .s-btn:hover, &.s-attached > .s-btn:focus-visible":"z-index:1"}});function W(t={}){let h=`.s-${t.layout??"attached"}${t.vertical?".s-vertical":""}`;G1(`div.s-bgroup${h} role=group`,t.attrs,()=>{if(t.buttons)for(let e of t.buttons)O(e);v(t.content)})}function m2(t){f1(()=>{let a=t.bind.value;W({attrs:t.attrs,buttons:Object.entries(t.options).map(([h,e])=>({content:e,ariaLabel:typeof e=="function"?h:void 0,attrs:a===h?".primary":".neutral",click:()=>{t.bind.value=t.allowDeselect&&a===h?void 0:h}}))})}),t.name&&f1(()=>f1("input type=hidden name=",t.name,"value=",t.bind.value??""))}import k from"aberdeen";k.insertGlobalCss({".s-check":{"&":"display:flex flex-direction:column gap:$1","> label":"display:flex align-items:center gap:$2 cursor:pointer user-select:none","> label:has(input:disabled)":"cursor:not-allowed opacity:0.45 filter:saturate(0.6)",input:"cursor:inherit m:0"}});function u2(t={}){let a=t.id??B("check");k("div.s-check",t.attrs,()=>{k("label for=",a,()=>{k("input type=checkbox",t.inputAttrs,()=>{k("id=",a),t.name&&k("name=",t.name),t.checked&&!t.bind&&k("checked=true"),t.change&&k("change=",t.change),k(()=>{t.disabled&&k("disabled=true")}),k(()=>{t.required&&k("aria-required=true")}),t.bind&&k("bind=",t.bind)}),k(()=>{t.label!=null&&v(t.label),t.required&&k("span.s-req aria-hidden=true #*")})}),k(()=>{t.help!=null&&!t.error&&k("div.s-help",()=>v(t.help))}),k(()=>{t.error&&k("div.s-error role=alert #",t.error)})})}import X from"aberdeen";X.insertGlobalCss({".s-form":{"&":"display:flex flex-direction:column gap:$3","&.grid":"display:grid grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap:$3","&.grid > .s-wide, &.grid > footer":"grid-column: 1 / -1;","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 flex-wrap:wrap margin-top:$1"}});function y2(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;X("form.s-form",a.attrs,()=>{X(()=>{X(".grid=",a.layout==="grid")}),X("submit=",h=>{if(h.preventDefault(),a.submit){let e=new FormData(h.target),p={};for(let r of new Set(e.keys())){let d=e.getAll(r);p[r]=d.length===1?d[0]:d}a.submit(p,h)}}),v(a.content),X(()=>{a.actions&&X("footer",a.actionsAttrs,()=>v(a.actions))})})}import x from"aberdeen";import{current as E1}from"aberdeen/route";import y from"aberdeen";import{matchCurrent as f2,current as o1,go as g2}from"aberdeen/route";y.insertGlobalCss({".s-menu-list":"position:fixed z-index:350 min-width:10rem display:flex flex-direction:column p:$1 r:$s-radius-lg overflow-y:auto max-height:min(80vh,28rem) transition: opacity 0.15s, transform 0.15s, visibility 0.15s;",".s-menu-list.hidden":"opacity:0 pointer-events:none transform:translateY(-6px) visibility:hidden",".s-menu-item":"display:flex align-items:center gap:$2 w:100% outline:0 scroll-margin:$2 padding: $m2 0; line-height:1.1 r:$s-radius cursor:pointer text-align:left font-weight:450 font-size:0.9em border:0 background:transparent fg:$s-text text-decoration:none transition: color 0.12s, transform 0.12s, text-shadow 0.12s;",".s-menu-item:focus-visible:not([aria-current=page]), .s-menu-item:hover:not([aria-disabled=true]):not([aria-current=page])":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);",".s-menu-item[aria-current=page]":"color:$s-accent filter:none",".s-menu-list .s-menu-item":"padding-inline:$2",".s-menu-item[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none",".s-menu-icon":"flex-shrink:0",".s-menu-list .s-menu-icon":"display:flex",".s-menu-list .s-menu-icon > svg":"width:1.25em height:1.25em","hr.s-menu-sep":"border:0 height:1px margin: $1 0.6rem; background: linear-gradient(to right, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-menu-chevron":"margin-left:auto flex-shrink:0 display:flex transition: transform 0.15s ease;",".s-menu-chevron > svg":"width:1em height:1em",".s-menu-details":{"> summary":"list-style:none","> summary::-webkit-details-marker":"display:none","&::details-content":"interpolate-size:allow-keywords block-size:0 overflow-y:clip transition: block-size 0.15s ease, content-visibility 0.15s allow-discrete;","&[open]::details-content":"block-size:auto","&[open] > summary .s-menu-chevron":"transform:rotate(90deg)"},".s-menu-sub":"display:flex flex-direction:column gap:$1 padding-left:$3",".s-menu-inline":"display:flex flex-direction:column gap:$1"});function h1(t,a){y("keydown=",e=>{if(e.key==="Enter"&&e.target.tagName==="A"){queueMicrotask(()=>a?.());return}if(e.key!=="ArrowDown"&&e.key!=="ArrowUp"&&e.key!=="Home"&&e.key!=="End")return;e.preventDefault();let r=[...e.currentTarget.querySelectorAll(".s-menu-item")].filter(i=>i.getAttribute("aria-disabled")!=="true"&&!H2(i));if(!r.length)return;let d=r.indexOf(document.activeElement),o=e.key==="ArrowUp"?-1:1,c=e.key==="Home"?0:e.key==="End"?r.length-1:d<0?o>0?0:r.length-1:(d+o+r.length)%r.length;r[c].focus()});let h=y.derive(()=>g1(t));j1(t,a,h)}function j1(t,a,h){for(let e of t){if(typeof e=="string"||typeof e=="function"){v(e);continue}if("separator"in e){y("hr.s-menu-sep");continue}e.items?w2(e,a,h):b2(e,a)}}function b2(t,a){let h=!1,e=y(t.href?"a.s-menu-item data-panel=open":"button.s-menu-item type=button",t.attrs,()=>{t.href&&(y("href=",t.href),t.target&&y("target=",t.target),y(()=>{let p=!h;h=!0,b1(t)&&(y("aria-current=page"),requestAnimationFrame(()=>e.scrollIntoView({block:"nearest",behavior:p?"instant":"smooth"})))})),t.disabled&&y("aria-disabled=true"),y("click=",p=>{if(t.disabled){p.preventDefault();return}a?.(),t.click?.(p)}),t.icon&&y("span.s-menu-icon",()=>v(t.icon)),v(t.label)})}var _1=new Map;function K1(t,a){return _1.set(t,a),a}function w2(t,a,h){let e=t.href??Q1(t.items),p=e!=null?y.derive(()=>w1(t)?K1(e,!0):h==null||h.value?K1(e,!1):_1.get(e)??!1):null;y("details.s-menu-details",()=>{p&&y(()=>{p.value&&y("open=true")}),y("summary.s-menu-item.s-menu-branch",t.attrs,()=>{t.disabled&&y("aria-disabled=true"),y(()=>{b1(t)&&y("aria-current=page")}),y("click=",r=>{if(t.disabled){r.preventDefault();return}e!=null&&(r.preventDefault(),A2(e),g2(e)),t.click?.(r)}),t.icon&&y("span.s-menu-icon",()=>v(t.icon)),v(t.label),y("span.s-menu-chevron aria-hidden=true",()=>Z1())}),y("div.s-menu-sub",()=>j1(t.items,a,h))})}function H2(t){for(let a=t.closest("details");a;a=a.parentElement&&a.parentElement.closest("details"))if(!a.open&&t.closest("summary")?.parentElement!==a)return!0;return!1}function g1(t){return t.some(a=>typeof a!="string"&&typeof a!="function"&&!("separator"in a)&&w1(a))}function b1(t){if(t.href!=null&&f2(t.href))return!0;let a=t.match;if(a==null)return!1;let h=o1.path;if(typeof a=="function")return a(h);let e=a.replace(/\/+$/,"")||"/";return h===e||h.startsWith(e==="/"?"/":e+"/")}function w1(t){if(b1(t))return!0;for(let a of t.items??[])if(!(typeof a=="string"||typeof a=="function"||"separator"in a)&&w1(a))return!0;return!1}function Q1(t){for(let a of t){if(typeof a=="string"||typeof a=="function"||"separator"in a)continue;let h=a.href??(a.items?Q1(a.items):void 0);if(h!=null)return h}}var c1=null;function A2(t){try{c1=new URL(t,location.href).pathname.replace(/\/+$/,"")||"/"}catch{c1=null}}function H1(t){return c1!==t?!1:(c1=null,!0)}var U=y.proxy({opts:null});function Z(){let t=U.opts?.anchor;U.opts=null,t?.focus()}function n1(t){let a=U.opts;return a!=null&&(t==null||a.anchor===t)}function V2(t){n1(t)&&Z()}function k2(t,a){let h=t.offsetWidth,e=t.offsetHeight,p=window.innerWidth,r=window.innerHeight,d=4,o=a.left;o+h>p-8&&(o=Math.max(8,a.right-h));let c=a.bottom+d;c+e>r-8&&a.top-e-d>=8&&(c=a.top-e-d),t.style.left=Math.max(8,o)+"px",t.style.top=Math.max(8,c)+"px"}F(()=>{let t=U.opts;if(!t)return;let a=y("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden",t.dropdownAttrs,()=>{h1(t.items,Z)}),h=r=>{let d=r.target;!a.contains(d)&&(t.closeOnAnchorClick||!t.anchor.contains(d))&&Z()},e=r=>{(r.key==="Escape"||r.key==="Tab")&&(r.preventDefault(),Z())},p=y.peek(o1,"path");y(()=>{o1.path!==p&&!H1(o1.path)&&Z()}),document.addEventListener("click",h,!0),document.addEventListener("keydown",e,!0),y.clean(()=>{document.removeEventListener("click",h,!0),document.removeEventListener("keydown",e,!0)}),requestAnimationFrame(()=>{if(!document.body.contains(a))return;let r=t.at?{left:t.at.x,right:t.at.x,top:t.at.y,bottom:t.at.y}:t.anchor.getBoundingClientRect();k2(a,r),j(a,".s-menu-item[aria-current=page]")})});function L2(t){y("nav.s-menu-inline",t.attrs,()=>h1(t.items,t.onLeafSelect))}function A1(t){return U.opts=t,Z}function V1(t){let a=null;y.clean(()=>{U.opts?.anchor===a&&Z()}),y("contextmenu=",h=>{h.preventDefault(),a=h.currentTarget,A1({items:t.items,anchor:a,at:{x:h.clientX,y:h.clientY},closeOnAnchorClick:!0,dropdownAttrs:t.dropdownAttrs})})}function C2(t){let a=null;y.clean(()=>{U.opts?.anchor===a&&Z()}),O({icon:d1,...t.button?.content==null?{ariaLabel:"Open menu"}:null,attrs:".neutral",...t.button,click:h=>{if(a=h.currentTarget,U.opts?.anchor===a){Z();return}A1({items:t.items,anchor:a,dropdownAttrs:t.dropdownAttrs})}})}import H from"aberdeen";import G from"aberdeen";function k1(t={}){I(t,(a,h)=>{G("input.s-input",t.inputAttrs,()=>{G("type=",t.type??"text"),t.placeholder!=null&&G("placeholder=",t.placeholder),t.autocomplete!=null&&G("autocomplete=",t.autocomplete),t.value!=null&&!t.bind&&G("value=",t.value),t.input&&G("input=",t.input),t.change&&G("change=",t.change),_(t,a,h,t.bind)})})}H.insertGlobalCss({".s-backdrop":{"&":"position:fixed inset:0 z-index:200 display:block background: rgba(0,0,0,0.55); transition: opacity 0.4s ease-in-out;","&.hidden":"opacity:0 pointer-events:none"},".s-dialog":{"&":"position:fixed z-index:200 top:50% left:50% display:flex flex-direction:column transform:translate(-50%,-50%) min-width:20rem max-width:min(90vw,44rem) max-height:min(88vh,800px) r: $s-radius-lg; overflow:hidden transition: opacity 0.2s ease-out, transform 0.2s ease-out;","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600 flex-shrink:0","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0 flex-shrink:0","> div":"p:$3 gap:$3 display:flex flex-direction:column overflow-y:auto flex:1 min-height:0","&.hidden":"opacity:0 pointer-events:none transform: translate(-50%, calc(-50% + 20px)); pointer-events:none"}});var K=H.proxy({}),L1=0,J1=H.derive(()=>{let t=Object.keys(K);if(t.length)return t[t.length-1]});function C1(){return J1.value!=null}F(()=>{H.onEach(K,({resolve:t,opts:a},h)=>{let e=()=>{delete K[h]};H.clean(()=>{a.onClose?.(),t()});let p=H.derive(()=>J1.value!=h);H("div.s-backdrop create=hidden destroy=hidden .hidden=",p,"click=",()=>{a.allowCancel!==!1&&e()});let r=H("div.s-dialog.neutral.s-s.extra-shadow create=hidden destroy=hidden",a.attrs,()=>{H(()=>{a.header!=null&&H("header.s-s.neutral",a.headerAttrs,()=>v(a.header))}),H("div",a.contentAttrs,()=>{v(a.content,e)}),H(()=>{a.footer!=null&&H("footer.s-s.neutral",a.footerAttrs,()=>v(a.footer))})});requestAnimationFrame(()=>{document.body.contains(r)&&j(r)})})});function i1(t){L1||document.addEventListener("keydown",h=>{if(h.key!=="Escape"||h.defaultPrevented)return;let e=H.unproxy(K);for(let p=L1;p>0;p--)if(e[p]){h.preventDefault(),e[p].opts.allowCancel!==!1&&delete K[p];break}});let a=++L1;return t.cancelWithScope!==!1&&H.clean(()=>{delete K[a]}),new Promise(h=>{K[a]={resolve:h,opts:t}})}function z2(t,a={}){return i1({header:"Alert",allowCancel:!0,content:h=>{H("p",()=>{H("#",t)}),W({layout:"spaced",attrs:"align-self:flex-end",content:()=>{O({content:"OK",click:h})}})},...a})}function $2(t,a={}){return new Promise(h=>{let e=!1;i1({header:"Confirm",allowCancel:!0,content:p=>{H("p",()=>{H("#",t)}),W({layout:"spaced",attrs:"align-self:flex-end",content:()=>{O({content:"Cancel",attrs:".neutral",click:p}),O({content:"OK",click:()=>{e=!0,p()}})}})},...a,onClose:()=>{h(e),a.onClose?.()}})})}function S2(t,a="",h={}){return new Promise(e=>{let p=null;i1({header:"Input",allowCancel:!0,content:r=>{H("p",()=>{H("#",t)});let d=H.proxy({value:a});H("form display:contents",()=>{H("submit=",o=>{o.preventDefault(),p=d.value,r()}),k1({bind:H.ref(d,"value")}),W({layout:"spaced",attrs:"align-self:flex-end",content:()=>{O({content:"Cancel",attrs:".neutral",type:"button",click:r}),O({content:"OK",type:"submit"})}})})},...h,onClose:()=>{e(p),h.onClose?.()}})})}import l,{OPAQUE as t2}from"aberdeen";import*as w from"aberdeen/route";import A from"aberdeen";var P2=$('<path d="m15 18-6-6 6-6"/>'),O2=$('<path d="m9 18 6-6-6-6"/>');A.insertGlobalCss({".s-strip":{"&":"position:relative display:flex min-width:0","> .s-strip-row":"display:flex align-items:center flex:1 min-width:0 overflow-x:auto overflow-y:hidden scrollbar-width:none scroll-behavior:smooth","> .s-strip-row::-webkit-scrollbar":"display:none","> .s-strip-btn":"position:absolute top:0 bottom:0 z-index:1 display:none align-items:center justify-content:center width:2.4em border:0 padding:0 cursor:pointer fg:$s-muted transition: color 0.15s;","> .s-strip-btn:hover":"fg:$s-text","> .s-strip-btn-left":"left:0 justify-content:flex-start background: linear-gradient(to right, $s-bg 45%, transparent)","> .s-strip-btn-right":"right:0 justify-content:flex-end background: linear-gradient(to left, $s-bg 45%, transparent)","&.s-can-left > .s-strip-btn-left, &.s-can-right > .s-strip-btn-right":"display:flex"},".s-tabs":{"&":"display:flex flex-direction:column gap:$3",".s-tabbar":"border-bottom: 1px solid $s-faint;",".s-tablist":"gap:$1 align-items:stretch margin-bottom:-1px",".s-tab":"display:inline-flex align-items:center gap:$2 cursor:pointer background:transparent border:0 color: $s-muted; font-weight:600 padding: 0.6em 0.9em; white-space:nowrap border-bottom: 3px solid transparent; transition: color 0.15s, background 0.15s, border-color 0.15s;",".s-tab:hover:not(:disabled), .s-tab[aria-selected=true]":"color: $s-text;",".s-tab:focus-visible":"outline:none box-shadow: inset 0 0 0 2px $s-focus; r: $s-radius;",".s-tab[aria-selected=true]":"border-image: $s-gradient 1;",".s-tabpanel":"display:block"}});function s1(t){A("div.s-strip",t.attrs,()=>{let a=A("div.s-strip-row",t.stripAttrs,()=>v(t.content));Y1(a,-1),Y1(a,1),q2(a)})}function l1(t){let a=t.parentElement;if(!a||!t.isConnected)return;let h=parseFloat(getComputedStyle(a).fontSize)*2.6,e=t.getBoundingClientRect(),p=a.getBoundingClientRect();e.left<p.left+h?a.scrollBy({left:e.left-p.left-h,behavior:"smooth"}):e.right>p.right-h&&a.scrollBy({left:e.right-p.right+h,behavior:"smooth"})}function E2(t){let a=B("tabs"),h=(r,d)=>r.id??String(d),e=t.bind??A.proxy(h(t.tabs[0]??{label:""},0));t.tabs.length>0&&!t.tabs.some((r,d)=>h(r,d)===A.peek(()=>e.value))&&(e.value=h(t.tabs[0],0));let p=(r,d)=>{r.disabled||(e.value=h(r,d))};A("div.s-tabs",t.attrs,()=>{s1({attrs:".s-tabbar",stripAttrs:".s-tablist role=tablist",content:()=>{t.tabs.forEach((r,d)=>{let o=h(r,d),c=A("button.s-tab type=button role=tab",()=>{A("id=",`${a}-tab-${o}`,"aria-controls=",`${a}-panel-${o}`),A(()=>{let i=e.value===o;A("aria-selected=",i?"true":"false"),A("tabindex=",i?"0":"-1"),i&&requestAnimationFrame(()=>l1(c))}),r.disabled&&A("disabled=true"),A("click=",()=>p(r,d)),A("keydown=",i=>T2(i,t.tabs,d,p)),v(r.icon),v(r.label)})})}}),A("div.s-tabpanel role=tabpanel",t.contentAttrs,()=>{A(()=>{let r=e.value,d=t.tabs.findIndex((c,i)=>h(c,i)===r),o=t.tabs[d]??t.tabs[0];o&&(A("id=",`${a}-panel-${h(o,d)}`,"aria-labelledby=",`${a}-tab-${h(o,d)}`),v(o.content))})})})}function Y1(t,a){A(`button.s-strip-btn.s-strip-btn-${a<0?"left":"right"} type=button`,()=>{A("tabindex=-1 aria-hidden=true"),A("click=",()=>t.scrollBy({left:a*t.clientWidth*.8,behavior:"smooth"})),(a<0?P2:O2)({size:"1.1em"})})}function q2(t){let a=t.parentElement;if(!a||typeof ResizeObserver>"u")return;let h=()=>{let r=t.scrollWidth-t.clientWidth;a.classList.toggle("s-can-left",t.scrollLeft>1),a.classList.toggle("s-can-right",t.scrollLeft<r-1)};t.addEventListener("scroll",h,{passive:!0});let e=new ResizeObserver(h);e.observe(t);let p=typeof MutationObserver>"u"?void 0:new MutationObserver(r=>{for(let d of r){for(let o of d.addedNodes)o instanceof Element&&e.observe(o);for(let o of d.removedNodes)o instanceof Element&&e.unobserve(o)}h()});p?.observe(t,{childList:!0});for(let r of Array.from(t.children))e.observe(r);h(),A.clean(()=>{t.removeEventListener("scroll",h),e.disconnect(),p?.disconnect()})}function T2(t,a,h,e){let p=h;if(t.key==="ArrowRight"||t.key==="ArrowDown")p=(h+1)%a.length;else if(t.key==="ArrowLeft"||t.key==="ArrowUp")p=(h-1+a.length)%a.length;else if(t.key==="Home")p=0;else if(t.key==="End")p=a.length-1;else return;t.preventDefault();let r=p>=h?1:-1;for(let d=0;d<a.length;d++){let o=a[p];if(o&&!o.disabled){e(o,p),t.currentTarget?.parentElement?.children[p]?.focus();return}p=(p+r+a.length)%a.length}}import V from"aberdeen";import{grow as D2,shrink as R2}from"aberdeen/transitions";V.insertGlobalCss({".s-toasts":"position:fixed bottom:$3 right:$3 z-index:400 display:flex flex-direction:column gap:$2 pointer-events:none max-width:min(90vw,24rem) w:24rem",".s-toast":{"&":"display:flex align-items:flex-start gap:$2 padding: $3; pointer-events:auto position:relative overflow:hidden",".s-toast-body":"display:flex flex-direction:column gap:$1 flex:1 min-width:0",".s-toast-title":"font-weight:700 line-height:1.3",".s-toast-close":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.15em; r:4px flex-shrink:0 align-self:flex-start",".s-toast-close:hover":"fg:$s-text",".s-toast-close:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; fg:$s-text",".s-toast-progress":"position:absolute bottom:0 left:0 right:0 height:2px background:$s-accent width:100%"}});var Z2=0,e1=V.proxy({});F(()=>{V.peek(()=>V.isEmpty(e1))&&V.isEmpty(e1)||V("div.s-toasts",()=>{V.onEach(e1,t=>{let{opts:a,id:h}=t,e=a.type==="danger"||a.type==="warning"?"alert":"status",p=a.type==null||a.type==="neutral"?"neutral":a.type,r=a.duration??6e3,d,o=null,c=()=>{clearTimeout(d),o&&(o.style.transition="none",o.style.width="100%",o.offsetWidth,o.style.transition=`width ${r}ms linear`,o.style.width="0%"),d=setTimeout(()=>z1(h),r)},i=()=>{clearTimeout(d),d=void 0,o&&(o.style.transition="none",o.style.width="100%")};V.clean(()=>clearTimeout(d)),V(`div.s-toast.s-s.${p}.extra-shadow aria-live=polite role=${e}`,"create=",D2,"destroy=",R2,a.attrs,()=>{r>0&&(V("mouseenter=",i),V("mouseleave=",c)),V("div.s-toast-body",()=>{V(()=>{a.title!=null&&V("div.s-toast-title",()=>v(a.title))}),V("div.s-toast-msg",()=>v(a.message))}),V(()=>{a.dismissible!==!1&&V("button.s-toast-close type=button aria-label=Dismiss",()=>{V("#\xD7"),V("click=",()=>z1(h))})}),r>0&&(o=V("div.s-toast-progress"))}),r>0&&requestAnimationFrame(c)})})});function z1(t){delete e1[t]}function M1(t){let a=++Z2;return e1[a]={id:a,opts:t},()=>z1(a)}var P1={integer(t){if(!/^(0|-?[1-9]\d*)$/.test(t))return;let a=Number(t);return Number.isSafeInteger(a)?a:void 0}};function q(t){let a=String(t).replace(/\/+$/,"");return a.startsWith("/")||(a=`/${a}`),a}function p1(t){let a=q(t);return a==="/"?[]:a.slice(1).split("/")}function a2(t){let a=p1(t),h=a.map((e,p)=>{if(!e.startsWith("[")||!e.endsWith("]"))return{kind:"lit",value:e};let r=/^\[\.\.\.([A-Za-z_$][\w$]*)\]$/.exec(e);if(r){if(p!==a.length-1)throw new Error(`Staffa: "${e}" must be the last segment of route "${t}"`);return{kind:"rest",name:r[1]}}let d=/^\[([A-Za-z_$][\w$]*)(?:=([A-Za-z_$][\w$]*))?\]$/.exec(e);if(!d)throw new Error(`Staffa: malformed param "${e}" in route "${t}"`);let[,o,c]=d;if(c&&!(c in P1))throw new Error(`Staffa: unknown matcher "${c}" in route "${t}" (known: ${Object.keys(P1).join(", ")})`);return{kind:"param",name:o,matcher:c}});return{key:t,segs:h}}function B2(t){try{return decodeURIComponent(t)}catch{return t}}function $1(t,a){let h={};for(let e=0;e<t.segs.length;e++){let p=t.segs[e];if(p.kind==="rest")return e>=a.length?null:(h[p.name]=a.slice(e).join("/"),h);if(e>=a.length)return null;let r=a[e];if(p.kind==="lit"){if(r!==p.value)return null}else if(p.matcher){let d=P1[p.matcher](r);if(d===void 0)return null;h[p.name]=d}else h[p.name]=B2(r)}return t.segs.length===a.length?h:null}var e2=250,F2=300,O1=1280,I2=360,h2=2;l.insertGlobalCss({":root":`--s-panel-ms:${e2}ms`,".s-panels":"flex:1 min-width:0 min-height:0 position:relative overflow:clip isolation:isolate "+Y,".s-panel":{"&":"position:absolute top:0 bottom:0 left:0 display:flex flex-direction:column "+Y+" visibility:visible transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility 0s;","&.s-panel-sep::before":"content:'' position:absolute left:0 top:0.6rem bottom:0.6rem width:1px z-index:1 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);","&.s-panel-enter":"opacity:0 transition:none transform: translateX(8cqw);","&.s-panel-closing":"opacity:0 pointer-events:none transform: translateX(8cqw);","&.s-panel-hidden, &.s-panel-parked":"opacity:0 visibility:hidden transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility var(--s-panel-ms);","&.s-panel-hidden":"transform: translateX(-8cqw);","&.s-panel-parked":"transform: translateX(8cqw);"},".s-panel > .s-content":"flex:1 min-height:0 overflow-y:auto overflow-x:hidden p:$3",".s-panel-actions":"display:flex align-items:center justify-content:flex-end gap:$1 flex-shrink:0 padding: $3 $3 0;",".s-crumbs > .s-strip-row":"gap:$m1",".s-crumb":{"&":"flex: 1 0 4rem; font-size:0.85em line-height:1.5 fg:$s-muted text-decoration:none white-space:nowrap max-width:max-content overflow:hidden text-overflow:ellipsis transition: color 0.12s;","&.s-crumb-on":"font-weight:600 fg:$s-text","a&:hover":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);","svg.s-crumb-pin":"vertical-align:-0.12em margin-right:0.3em opacity:0.8 fill:currentColor","svg.s-crumb-unsaved":"vertical-align:0.08em margin-right:0.3em fill:currentColor"},"svg.s-crumb-sep":"flex-shrink:0 opacity:0.4",".s-main.s-shell-snap .s-panel":"transition:none",".s-panel-loading":{"&":"position:absolute inset:0 display:flex align-items:center justify-content:center gap:$1 pointer-events:none",i:"width:0.5rem height:0.5rem r:50% background:$s-muted opacity:0.45 animation: s-panel-pulse 1s ease-in-out infinite;","i:nth-child(2)":"animation-delay:0.15s","i:nth-child(3)":"animation-delay:0.3s"},"@keyframes s-panel-pulse":{"0%, 100%":"opacity:0.25 transform:scale(0.8)","50%":"opacity:0.7 transform:scale(1)"}});var S1=!1,x1=class{[t2]=!0;compiled;ancestors;opts;$state=l.proxy({live:[],focus:0});$open=l.proxy({});nextOrder=0;containerEl;geom;lastBodyW=-1;layoutQueued=!1;timers=new Set;intent=null;settling=null;lastSeen=null;queued=null;constructor(a){if(S1)throw new Error("Staffa: only one routed S.main() (one with `routes`) can be active at a time");S1=!0,this.opts=a,this.compiled=Object.entries(a.routes).map(([h,e])=>({...a2(h),draw:e})),this.ancestors=Object.entries(a.ancestors??{}).filter(h=>h[1]!=null).map(([h,e])=>({...a2(h),fn:e})),l(()=>{let h=this.computeTarget(),e={...w.current.search},p=w.current.hash;l.peek(()=>{let r=this.lastSeen;if(r&&r.path!==w.current.path){let d=this.$state.live.find(o=>o.path===r.path);d&&(d.search=r.search,d.hash=r.hash)}this.lastSeen={path:w.current.path,search:e,hash:p},this.propose(h),Array.isArray(w.current.state.panels)||Object.assign(w.current.state,this.stateFor({stack:this.paths(),focus:this.$state.focus}))})}),this.interceptLinks(),this.watchTitle(),this.guardTabClose(),l.clean(()=>{for(let h of this.timers)clearTimeout(h);this.timers.clear(),this.queued?.settle(!1),this.queued=null,S1=!1})}resolve(a){let h=p1(a);for(let e of this.compiled){let p=$1(e,h);if(p)return{draw:e.draw,params:p}}return{draw:this.opts.notFound??G2,params:{}}}matches(a){let h=p1(a);return this.compiled.some(e=>$1(e,h)!=null)}deriveStack(a){let h=q(a),e=this.askAncestors(h),p=e?e.map(q):this.prefixesOf(h),r=[];for(let d of p)d!==h&&!r.includes(d)&&this.matches(d)&&r.push(d);return r.push(h),r}askAncestors(a){let h=p1(a);for(let e of this.ancestors){let p=$1(e,h);if(p)return e.fn(p,a)??void 0}}prefixesOf(a){let h=p1(a),e=[];for(let p=1;p<h.length;p++)e.push("/"+h.slice(0,p).join("/"));return e}pinnedIn(a,h){return a.filter(e=>h.includes(e)?!1:this.$state.live.find(p=>p.path===e)?.$panel.pinned===!0)}unsavedAt(a){return this.$state.live.find(h=>h.path===a)?.$panel.unsaved===!0}targetFor(a,h){let e=Array.isArray(h?.panels)?h.panels.map(String):null;if(e){let p=Array.isArray(h.parked)?h.parked.map(String):[],r=q(a),d=new Set([r]),o=i=>i.map(q).filter(f=>!d.has(f)&&!!d.add(f)),c=o(e);return{stack:[...c,r,...o(p)],focus:c.length}}return l.peek(()=>{let p=this.deriveStack(a).slice(0,-1),r=[...p,...this.pinnedIn(this.paths(),[...p,q(a)]),q(a)];return{stack:r,focus:r.length-1}})}computeTarget(){return this.targetFor(w.current.path,w.current.state)}paths(){return this.$state.live.map(a=>a.path)}propose(a){let h=this.$state.live.filter(e=>!a.stack.includes(e.path)&&e.$panel.unsaved).map(e=>e.path);h.length&&(a={stack:[...a.stack,...h],focus:a.focus}),!(N2(this.paths(),a.stack)&&a.focus===this.$state.focus)&&this.commit(a,w.current.nav)}commit(a,h){this.geom=void 0;let e=w.current.state.pinned,p=new Set(Array.isArray(e)?e.map(String):[]),r=new Map(this.$state.live.map(o=>[o.path,o])),d=[];for(let o of a.stack){let c=r.get(o);if(c){r.delete(o),d.push(c);continue}let i=this.createEntry(o,d.length<=a.focus,p.has(o));h!=="load"&&h!=="back"&&(i.enter=!0),d.push(i),this.$open[o]=i}for(let o of r.values())this.beginClose(o);this.$state.live=d,this.$state.focus=Math.min(a.focus,d.length-1),this.scheduleLayout()}createEntry(a,h,e){let{draw:p,params:r}=this.resolve(a),d={[t2]:!0,order:this.nextOrder++,path:a,draw:p,$ui:l.proxy({holding:!1}),maxWidth:"full",width:0};return d.$panel=l.proxy({stack:this,params:r,path:a,width:0,visible:h,pinned:e||void 0,close:()=>this.closePath(d.path),open:(o,c)=>this.navigate(o,{from:d.path,how:c})}),d}beginClose(a){a.closing=!0,a.$panel.visible=!1,a.el&&(a.el.style.zIndex=String(h2*this.$state.live.indexOf(a))),delete this.$open[a.path]}playExit(a,h){if(!a.closing){h.remove();return}h.classList.add("s-panel-closing"),h.setAttribute("inert","");let e=()=>{clearTimeout(p),this.timers.delete(p),h.remove()};h.addEventListener("transitionend",r=>{r.target===h&&r.propertyName==="opacity"&&e()});let p=setTimeout(e,e2+80);this.timers.add(p)}intended(){return this.intent??{stack:this.paths(),focus:this.$state.focus}}stateFor(a){return{panels:a.stack.slice(0,a.focus),parked:a.stack.slice(a.focus+1),pinned:this.pinnedPaths()}}pinnedPaths(){return this.$state.live.filter(a=>a.$panel.pinned).map(a=>a.path)}issue(a,h){return this.intent=a,this.settling?(this.queued?.settle(!1),new Promise(e=>{this.queued={run:h,settle:e}})):this.start(h)}start(a){let h=p=>{this.settling=null;let r=this.queued;return this.queued=null,p&&r?this.start(r.run).then(r.settle,()=>r.settle(!1)):(this.intent=null,r?.settle(!1)),p},e=Promise.resolve(a()).then(h,p=>(console.error(p),h(!1)));return this.settling=e,e}focusAt(a,h,e){let p=this.intended();if(a<0||a>=p.stack.length||a===p.focus)return Promise.resolve(!1);let r={stack:p.stack,focus:a},d=p.stack[a];return this.issue(r,()=>{let o=this.$state.live.find(c=>c.path===d);return w.go({path:d,search:h??o?.search,hash:e??o?.hash,state:this.stateFor(r)})})}back(){return l.peek(()=>{let a=this.intended();return a.focus===a.stack.length-1&&!this.unsavedAt(a.stack[a.focus])?this.closePath(a.stack[a.focus]??""):a.focus===0?Promise.resolve(!1):this.focusAt(a.focus-1)})}closePath(a){return l.peek(()=>{let h=this.intended(),e=h.stack.indexOf(q(a));if(e<0||h.stack.length<2||this.unsavedAt(h.stack[e]))return Promise.resolve(!1);let p=h.stack.filter((i,f)=>f!==e),r=e===h.focus?Math.max(0,e-1):h.focus-(e<h.focus?1:0),d={stack:p,focus:r};if(e===h.focus&&e===h.stack.length-1){let i=this.$state.live.find(m=>m.path===p[r]),f={};i?.search&&(f.search=i.search),i?.hash&&(f.hash=i.hash);let n=p.filter(m=>this.$state.live.find(u=>u.path===m)?.$panel.pinned===!0);return this.issue(d,()=>Promise.resolve(w.back({path:p[r],state:{panels:p.slice(0,r),parked:[]}},f)).then(m=>(m&&(w.current.state.pinned=n),m)))}let o=p[r],c=o!==h.stack[h.focus];return this.issue(d,()=>{let i=c?this.$state.live.find(f=>f.path===o):void 0;return w.go({path:o,search:c?i?.search:{...w.current.search},hash:c?i?.hash:w.current.hash,state:this.stateFor(d)})})})}navigate(a,{from:h,how:e,beneath:p}={}){let r=e??this.opts.linkNavigation,d=r==="open"?null:h??null,o=r==="replace";return l.peek(()=>{let c;try{c=new URL(a,location.href)}catch{return Promise.resolve(!1)}let i=q(c.pathname),f=Object.fromEntries(new URLSearchParams(c.search)),n=c.hash,m=this.intended(),u=p?-1:m.stack.indexOf(i);if(u>=0&&u!==m.focus)return this.focusAt(u,c.search?f:void 0,n||void 0);if(u>=0)return c.search===location.search&&(c.hash||"")===(location.hash||"")?Promise.resolve(!0):this.issue(m,()=>w.go({path:i,search:f,hash:n,state:this.stateFor(m)}));let g=d==null?-1:m.stack.indexOf(d),s=p?p.map(q).filter((z,m1,r2)=>z!==i&&r2.indexOf(z)===m1):g<0?this.deriveStack(i).slice(0,-1):m.stack.slice(0,o?g:g+1),b=[...s,...this.pinnedIn(m.stack,[...s,i,o?d:null])],C={stack:[...b,i],focus:b.length};return this.issue(C,()=>w.go({path:i,search:f,hash:n,state:this.stateFor(C)}))})}pushPath(a,h){return l.peek(()=>{let e=this.intended();return this.navigate(a,{from:e.stack[e.focus],how:h?"replace":"push"})})}interceptLinks(){w.interceptLinks((a,h)=>{let e=h.getAttribute("data-panel")??void 0,p=h.closest(".s-panel"),r=p?this.$state.live.find(d=>d.el===p):h.closest(".s-panel-origin")?this.$state.live[this.$state.focus]:void 0;return this.navigate(a.href,{from:r?.path,how:e}),!0})}get currentPanel(){return this.$state.live[this.$state.focus]?.$panel}get panels(){return this.$state.live.map(a=>a.$panel)}get currentPanelIndex(){return this.$state.focus}pushPanel(a){return this.pushPath(a,!1)}replacePanel(a){return this.pushPath(a,!0)}openPanelStack(a,h){return this.navigate(a,{how:"open",beneath:h})}closePanel(a){return l.peek(()=>{let h=this.intended();return this.closePath(a??h.stack[h.focus]??"")})}setColumns(a){this.opts.columns!==a&&(this.opts.columns=a,this.scheduleLayout())}setLinkNavigation(a){this.opts.linkNavigation=a}drawCrumbs(){s1({attrs:".s-crumbs role=navigation aria-label=Breadcrumbs",content:()=>{l(()=>{let a=this.panels.map(p=>p.path),h=this.currentPanelIndex,e;for(let p=0;p<a.length;p++){p&&N1({size:"0.85em",attrs:".s-crumb-sep"});let r=this.drawCrumb(a[p],p,p===h);p===h&&(e=r)}requestAnimationFrame(()=>{e&&l1(e)})})}})}drawCrumb(a,h,e){let p=this.$state.live[h];return l(e?"span.s-crumb aria-current=page":"a.s-crumb",()=>{e||l("href=",a),l(()=>{p?.$panel.visible&&l(".s-crumb-on")}),l(()=>{p?.$panel.unsaved&&B1({size:"0.45em",attrs:".s-crumb-unsaved"})}),l(()=>{p?.$panel.pinned&&y1({size:"0.85em",attrs:".s-crumb-pin"})}),l(()=>{l("#",p?.$panel.title??p?.$ui.fallback??(a.split("/").pop()||a))}),V1({items:[{label:"Open in new tab",icon:F1,click:()=>{window.open(a,"_blank","noopener")}},{label:"Copy link",icon:I1,click:()=>{X2(a)}},{separator:!0},{label:()=>{l(()=>{l("#",p?.$panel.pinned?"Unpin":"Pin")})},icon:()=>{l(()=>{(p?.$panel.pinned?U1:y1)()})},click:()=>{p&&this.togglePin(p)}},{label:"Close",icon:Q,disabled:p?.$panel.unsaved===!0,click:()=>{this.closePath(a)}}]})})}togglePin(a){a.$panel.pinned=!a.$panel.pinned||void 0,w.current.state.pinned=this.pinnedPaths()}watchTitle(){let a=document.title;l(()=>{let h=this.$state.live[this.$state.focus],e=h?.$panel.title??h?.$ui.fallback,p=typeof this.opts.title=="string"?this.opts.title:void 0,r=this.$state.live.some(o=>o.$panel.unsaved),d=e&&p?`${e} \xB7 ${p}`:e||p;d&&(document.title=(r?"\u2022 ":"")+d)}),l.clean(()=>{document.title=a})}guardTabClose(){if(typeof window>"u")return;let a=!1,h=()=>{a=!0},e=p=>{a=!1;let r=this.$state.live.find(o=>o.$panel.unsaved);if(!r)return;p.preventDefault(),p.returnValue=!0;let d=r.path;setTimeout(()=>{if(a)return;let o=this.$state.live.find(c=>c.path===d);o&&!o.$panel.visible&&this.focusAt(this.intended().stack.indexOf(d))},0)};l(()=>{this.$state.live.some(p=>p.$panel.unsaved)&&(window.addEventListener("beforeunload",e),window.addEventListener("pagehide",h),l.clean(()=>{window.removeEventListener("beforeunload",e),window.removeEventListener("pagehide",h)}))})}drawColumns(){let a=l("div.s-panels role=main",()=>{this.containerEl=l(),l.onEach(this.$open,h=>this.drawPanel(h),h=>h.order)});if(typeof ResizeObserver<"u"){let h=new ResizeObserver(()=>this.layout());h.observe(a);let e=a.parentElement?.parentElement;e&&h.observe(e),l.clean(()=>h.disconnect())}l.clean(()=>{this.containerEl===a&&(this.containerEl=void 0)}),this.scheduleLayout()}drawPanel(a){let h;l(()=>{let e=a.$panel.maxWidth;a.maxWidth=e==="half"||e==="screen"?e:"full";let p=this.roomFor(a.maxWidth);p&&(a.width=p,l.peek(a.$panel,"width")!==p&&(a.$panel.width=p),h&&(h.style.width=`${p}px`,this.scheduleLayout()))}),h=l(`section.s-panel${a.width?` w:${a.width}px`:""}`,"destroy=",e=>this.playExit(a,e),()=>{l(()=>this.drawActions(a)),l("div.s-content",()=>{if(a.draw(a.$panel),w.persistScroll(a.path),l.peek(a.$panel,"title")==null){let e=W2(l());e&&l.peek(a.$ui,"fallback")!==e&&(a.$ui.fallback=e)}}),l(()=>{!a.$panel.loading||a.$ui.holding||l("div.s-panel-loading aria-hidden=true",()=>{l("i"),l("i"),l("i")})})}),a.el=h,a.placed=!1,h.style.transition="none",l.clean(()=>{a.el===h&&(a.el=void 0)}),l(()=>{a.$panel.loading,this.scheduleLayout()}),this.scheduleLayout()}drawActions(a){this.opts.$shell.narrow||a.$panel.actions==null||l("div.s-panel-actions",()=>v(a.$panel.actions))}scheduleLayout(){this.layoutQueued||(this.layoutQueued=!0,requestAnimationFrame(()=>{this.layoutQueued=!1,this.layout()}))}measure(){let a=this.containerEl,h=a?.parentElement,e=h?.parentElement;if(!a||!h||!e)return;let p=e.getBoundingClientRect().width;if(!p)return;let r=0;for(let c of h.children)c!==a&&(r+=c.getBoundingClientRect().width);let d=Math.max(0,Math.min(O1,p)-r),o=d/2;return{total:p,chrome:r,half:o>=I2?o:d,full:d,screen:Math.max(0,p-r)}}geometry(){return this.geom??=this.measure()}roomFor(a){return this.geometry()?.[a]??0}layout(){let a=this.containerEl,h=a?.closest(".s-main");if(!a||!h)return;let e=this.$state.live,p=e.length;if(!p||e.some(s=>!s.el))return;this.geom=void 0;let r=this.geometry();if(!r)return;let d=this.opts.columns!=="single",o=this.lastBodyW!==r.total;o&&(this.lastBodyW=r.total,h.classList.add("s-shell-snap"));let c=s=>r[s.maxWidth],i=Math.min(this.$state.focus,p-1),f=i,n=c(e[i]);if(d)for(let s=i-1;s>=0;s--){let b=n+c(e[s]);if(b>r.screen)break;n=b,f=s}let m=Math.min(r.screen,Math.max(r.full,n));for(let s=f;s<=i;s++)e[s].width=c(e[s]);for(let s of e)s.width||(s.width=c(s));h.style.setProperty("--s-shell-w",`${r.chrome+m}px`);let u=[],g=0;for(let s=0;s<p;s++){let b=e[s],C=b.el,z=s>=f&&s<=i;U2(C,z?g:s>i?m:0,b.width,h2*s+1),b.$panel.visible!==z&&(b.$panel.visible=z),b.$panel.width!==b.width&&(b.$panel.width=b.width),z&&(g+=b.width),C.classList.toggle("s-panel-sep",z&&s>f),C.classList.toggle("s-panel-hidden",s<f),C.classList.toggle("s-panel-parked",s>i),C.toggleAttribute("inert",!z),!b.placed&&(u.push(b),!b.$panel.loading||b.holdDone?b.$ui.holding=!1:b.$ui.holding||(b.$ui.holding=!0,this.holdEnter(b)),b.enter&&z&&C.classList.add("s-panel-enter"))}(u.length||o)&&a.offsetWidth,o&&h.classList.remove("s-shell-snap");for(let s of u)s.$ui.holding||(s.el.style.transition="",s.el.classList.remove("s-panel-enter"),s.enter=!1,s.placed=!0)}holdEnter(a){let h=setTimeout(()=>{this.timers.delete(h),a.holdDone=!0,a.$ui.holding&&(a.$ui.holding=!1,this.scheduleLayout())},F2);this.timers.add(h)}};function U2(t,a,h,e){t.style.left=`${a}px`,t.style.width=`${h}px`,t.style.zIndex=String(e)}function N2(t,a){return t.length===a.length&&t.every((h,e)=>h===a[e])}function W2(t){let a=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(let h=a.nextNode();h;h=a.nextNode()){let e=h.textContent.trim();if(e)return e.length>48?`${e.slice(0,47).trimEnd()}\u2026`:e}}async function X2(t){let a=new URL(t,location.href).href;try{await navigator.clipboard.writeText(a),M1({message:"Link copied."})}catch{M1({message:"Couldn't copy the link.",type:"danger"})}}function G2(t){l("p fg:$s-muted",()=>l("#",`No panel at ${t.path}`))}x.insertGlobalCss({".s-main":{"&":"display:flex flex-direction:column min-height:100vh max-height:100vh container-type:inline-size","body > &":"margin: calc(-1 * $3)","> header":"border:0 border-bottom: 1px solid $s-faint; r:0 position:sticky top:0 z-index:10","> footer":"border-top: 1px solid $s-faint; fg:$s-muted","> header > .s-bar, > footer > .s-bar":"display:flex align-items:center width:100% margin-inline:auto gap:$3 padding: $2 $3;","> header .s-logo, > header .s-nav-trigger":"display:flex align-items:center flex-shrink:0","> header .s-nav-trigger":"margin-left:-0.375rem","> header .s-logo":"font-size:1.4em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent;","> header .s-titles":"display:flex flex-direction:column min-width:5rem flex: 0 1 auto;","> header .s-subtitle":"fg:$s-muted font-size:0.85em line-height:1.5 overflow:hidden text-overflow:ellipsis white-space:nowrap","> header .s-title":"font-weight:800 font-size:1.1em line-height:1.2 overflow:hidden text-overflow:ellipsis white-space:nowrap letter-spacing:-0.01em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent; width:fit-content max-width:100%","> header a.s-logo, > header a.s-title":"text-decoration:none filter:none cursor:pointer","> header .s-menu":"display:flex align-items:center justify-content:flex-end gap:$2 flex: 1 0.1 auto; min-width:0",".s-body":"flex:1 overflow:clip display:flex flex-direction:row min-height:0 justify-content:center position:relative",".s-body-inner":"flex:1 min-width:0 display:flex flex-direction:row min-height:0","&.s-nav-right .s-body-inner":"flex-direction:row-reverse",".s-nav-sep":"width:1px flex-shrink:0 align-self:stretch margin: 0.6rem 0; border:0 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-body main":"flex:1 min-width:0 min-height:0 overflow-x:hidden overflow-y:auto display:flex flex-direction:column transition: transform var(--s-panel-ms) ease;",".s-body main.s-slide-in":"transform: translateX(100%); transition:none",".s-body main > .s-content":"width:100% flex:1 p:$3",".s-body main.s-scroll-y":"margin-right:$3","&.s-routed > .s-body > .s-body-inner":"max-width: var(--s-shell-w, 100%); transition: max-width var(--s-panel-ms) ease;","&.s-routed.s-shell-snap > .s-body > .s-body-inner":"transition:none","&.s-routed > header > .s-bar, &.s-routed > footer > .s-bar":`max-width:${O1}px`},".s-nav-panel":{"&":"display:flex flex-direction:column overflow-y:auto flex-shrink:0 max-width:228px padding:$3 gap:$1"},".s-nav-page":{"&":"position:absolute inset:0 z-index:5 display:flex flex-direction:column overflow-y:auto overscroll-behavior:contain border:0 r:0 padding:$2 gap:$1 transition: transform var(--s-panel-ms) ease, visibility var(--s-panel-ms);","&.s-nav-page-off":"transform:translateX(-100%) pointer-events:none visibility:hidden",".s-menu-item":"padding: $2 $3; min-height:3rem font-size:1.05em gap:$3"},[`@container (max-width: ${r1}px)`]:{".s-main .s-nav-panel, .s-main .s-nav-sep":"display:none",".s-main > header > .s-bar":"gap:$1 padding: $1 $2;",".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0",".s-main .s-body main.s-scroll-y":"margin-right:0"}});function K2(t={}){let a=t.nav,h=t.navPosition??"left",e=x.proxy({open:!1}),p=x.proxy({narrow:typeof document<"u"&&document.documentElement.clientWidth<=r1}),r=t.routes;if(r!=null&&t.content!=null)throw new Error("Staffa: S.main() takes either `content` or `routes`, not both");let d=r?new x1({routes:r,notFound:t.notFound,ancestors:t.ancestors,title:t.title,$shell:p}):null;d&&(x(()=>d.setColumns(t.columns)),x(()=>d.setLinkNavigation(t.linkNavigation)));let o=d&&t.home!==null?t.home??"/":null,c=d?null:t.maxWidth,i=x(`div.s-main${d?".s-routed":""}`,t.attrs,()=>{x(()=>{a==null||!a.items.length||x(`.s-nav-${h}`)}),x(()=>{(d!=null||t.title!=null||t.subtitle!=null||t.logo!=null||t.menu!=null||a!=null&&a.items.length>0)&&x("header.s-s.neutral",t.topbarAttrs,()=>{x("div.s-bar",()=>{x(()=>{c!=null&&x("max-width:",c)}),x(()=>{if(p.narrow&&a!=null&&a.items.length){x("div.s-nav-trigger",()=>Y2(a,e));return}t.logo!=null&&x(o!=null?"a.s-logo aria-label=Home":"div.s-logo",()=>{o!=null&&x("href=",o),v(t.logo)})}),x("div.s-titles",()=>{x(()=>{t.title!=null&&x(o!=null?"a.s-title":"div.s-title",()=>{o!=null&&x("href=",o),v(t.title)})}),_2(t,d,a,p)}),x(()=>{let n=p.narrow?d?.currentPanel?.actions:void 0,m=n??t.menu;m!=null&&x(`div.s-menu${n!=null?".s-panel-origin":""}`,()=>v(m))})})})}),x("div.s-body",()=>{x("div.s-body-inner",()=>{x(()=>{c!=null&&x("max-width:",c)}),x(()=>{a==null||!a.items.length||(x(`nav.s-nav-panel.s-nav-${h}`,t.navAttrs,()=>{h1(a.items)}),x("div.s-nav-sep aria-hidden=true"))}),h0(t,d)}),x(()=>{a!=null&&a.items.length&&e.open&&t0(a,t.navPageAttrs,e,p)})}),x(()=>{t.footer!=null&&x("footer",()=>{x("div.s-bar",()=>{x(()=>{c!=null&&x("max-width:",c)}),v(t.footer)})})})});if(J2(i,p),a!=null||d){let f=n=>{if(n.key!=="Escape"||n.defaultPrevented||C1()||n1())return;let m=i.querySelector(".s-nav-trigger button");if(e.open){n.preventDefault(),e.open=!1,m?.focus();return}if(d&&d.currentPanelIndex>0){n.preventDefault(),d.back();return}let u=i.querySelector(".s-nav-panel");if(u?.offsetParent!=null){let g=u.querySelector("[aria-current=page]")??u.querySelector(".s-menu-item:not([aria-disabled=true])");g&&(n.preventDefault(),g.focus());return}m&&(n.preventDefault(),m.click())};document.addEventListener("keydown",f),x.clean(()=>document.removeEventListener("keydown",f))}return d??void 0}var v1=null;function j2(){v1?.()}function _2(t,a,h,e){x(()=>{if(t.subtitle!=null&&(a==null||Q2(a,h,e))){x("div.s-subtitle",()=>v(t.subtitle));return}a?.drawCrumbs()})}function Q2(t,a,h){return h.narrow||a==null||t.panels.length>1?!1:g1(a.items)}function J2(t,a){if(typeof ResizeObserver>"u")return;let h=new ResizeObserver(e=>{let p=e[0]?.contentBoxSize?.[0],r=p?p.inlineSize:e[0]?.contentRect.width;r!=null&&(a.narrow=r<=r1)});h.observe(t),x.clean(()=>h.disconnect())}function Y2(t,a){a1({icon:t.button?.icon??(()=>x(()=>(a.open?Q:d1)())),ariaLabel:t.button?.ariaLabel??"Open navigation",attrs:t.button?.attrs,click:()=>{a.open=!a.open}})}function t0(t,a,h,e){let p=!1,r=()=>{p=!0,h.open=!1},d=x("nav.s-nav-page.s-s.neutral aria-label=Navigation create=s-nav-page-off destroy=s-nav-page-off",a,()=>h1(t.items,r));v1=r,x.clean(()=>{v1===r&&(v1=null)});let o=x.peek(E1,"path");x(()=>{E1.path!==o&&!H1(E1.path)&&r()});let c=d.closest(".s-main"),i=d.parentElement?.querySelector(":scope > .s-body-inner"),f=i?.querySelector(":scope > main");i?.setAttribute("inert",""),x(()=>{e.narrow||(h.open=!1)}),x.clean(()=>{i?.removeAttribute("inert"),p&&(f&&a0(f),c?.querySelector(".s-nav-trigger button")?.focus())}),requestAnimationFrame(()=>{document.body.contains(d)&&j(d,".s-menu-item[aria-current=page]")})}function a0(t){t.classList.add("s-slide-in"),t.offsetWidth,t.classList.remove("s-slide-in")}function h0(t,a){if(a){a.drawColumns();return}let h=x("main",()=>{x("div.s-content",t.contentAttrs,()=>{v(t.content)})});e0(h)}function e0(t){if(typeof ResizeObserver>"u")return;let a=()=>t.classList.toggle("s-scroll-y",t.offsetWidth>t.clientWidth),h=new ResizeObserver(a);h.observe(t),t.firstElementChild&&h.observe(t.firstElementChild),a(),x.clean(()=>h.disconnect())}import S from"aberdeen";S.insertGlobalCss({".s-select_wrap":{"&":"position:relative display:block",select:"w:100% cursor:pointer padding-right:2.2em; appearance:none","&::after":"content: '\u25BE'; position:absolute right:0.7em top:50%; transform: translateY(-50%); pointer-events:none fg:$s-muted font-size:0.85em"}});function p0(t){I(t,(a,h)=>{S("div.s-select_wrap",t.inputAttrs,()=>{S("select.s-input",()=>{_(t,a,h),S("change=",e=>{t.bind&&(t.bind.value=e.target.value)}),S(()=>{let e=typeof t.options=="function"?t.options():t.options,p=t.bind?.value??"";t.placeholder!=null&&S("option",()=>{S("value= disabled=true hidden=true"),p||S("selected=true"),S("#",t.placeholder)});for(let r of e){let d=typeof r=="string"?{value:r,label:r}:{value:r.value,label:r.label??r.value};S("option",()=>{S("value=",d.value),d.value===p&&S("selected=true"),S("#",d.label)})}})})})})}import T from"aberdeen";T.insertGlobalCss({"textarea.s-input":"resize:vertical min-height:3em line-height:1.45","textarea.s-input.s-autoGrow":"resize:none min-height:2.5em overflow-y:hidden"});function r0(t={}){let a=t.autoGrow!==!1;I(t,(h,e)=>{let p=T("textarea.s-input",t.inputAttrs,()=>{a?(T(".s-autoGrow"),T("input=",r=>{p2(r.currentTarget),t.input&&t.input(r)})):(T("rows=",t.rows??4),T("resize:",t.resize??"vertical"),t.input&&T("input=",t.input)),t.placeholder!=null&&T("placeholder=",t.placeholder),t.value!=null&&!t.bind&&T("value=",t.value),t.change&&T("change=",t.change),_(t,h,e,t.bind)});a&&requestAnimationFrame(()=>p2(p))})}function p2(t){t.style.height="auto",t.style.height=`${t.scrollHeight}px`}import D from"aberdeen";D.insertGlobalCss({".s-tt-tip":{"&":"position:fixed z-index:500 max-width:20rem w:max-content padding: 0.3em 0.65em; font-size:0.85em line-height:1.4 pointer-events:none"}});var J=D.proxy(void 0),R=null;typeof window<"u"&&window.addEventListener("scroll",()=>{J.value=void 0},{capture:!0,passive:!0});function d0(t,a,h,e){let r=window.innerWidth,d=window.innerHeight,o=0,c=0;return e==="bottom"?(o=t.left+(t.width-a)/2,c=t.bottom+7,c+h>d-8&&(c=t.top-h-7)):e==="left"?(o=t.left-a-7,c=t.top+(t.height-h)/2,o<8&&(o=t.right+7)):e==="right"?(o=t.right+7,c=t.top+(t.height-h)/2,o+a>r-8&&(o=t.left-a-7)):(o=t.left+(t.width-a)/2,c=t.top-h-7,c<8&&(c=t.bottom+7)),{x:Math.max(8,Math.min(o,r-a-8)),y:Math.max(8,Math.min(c,d-h-8))}}function q1(){R&&clearTimeout(R),R=setTimeout(()=>{J.value=void 0,R=null},100)}F(()=>{let t=J.value;if(!t)return;let{opts:a,anchor:h}=t,e=a.placement??"top",p=D("div.s-tt-tip.s-s.neutral.shadow role=tooltip visibility:hidden",a.attrs,()=>{D("mouseenter=",()=>{R&&(clearTimeout(R),R=null)}),D("mouseleave=",q1),v(a.tip)});requestAnimationFrame(()=>{if(!document.body.contains(p))return;let{x:r,y:d}=d0(h.getBoundingClientRect(),p.offsetWidth,p.offsetHeight,e);p.style.left=r+"px",p.style.top=d+"px",p.style.visibility=""})});function o0(t){let a=h=>{R&&(clearTimeout(R),R=null),J.value={opts:t,anchor:h.currentTarget}};D("mouseenter=",a),D("mouseleave=",q1),D("focusin=",a),D("focusout=",q1),D.clean(()=>{J.value?.opts===t&&(J.value=void 0)})}export{V1 as addContextMenu,o0 as addTooltip,z2 as alert,l2 as autocomplete,v2 as box,O as button,m2 as buttonChooser,W as buttonGroup,u2 as checkbox,V2 as closeFloatingMenu,j2 as closeNav,$2 as confirm,i1 as dialog,y2 as form,D1 as getDarkMode,a1 as iconButton,C1 as isDialogOpen,n1 as isFloatingMenuOpen,K2 as main,L2 as menu,C2 as menuButton,S2 as prompt,l1 as revealInStrip,s1 as scrollStrip,p0 as select,o2 as setDarkMode,A1 as showFloatingMenu,E2 as tabs,r0 as textarea,k1 as textline,M1 as toast};
1
+ import q from"aberdeen";var t1="background: linear-gradient(170deg, color-mix(in oklab, $s-bg, white 9%), color-mix(in oklab, $s-bg, black 9%));",u1="staffa:darkMode",T1=q.proxy({value:d2()});function d2(){try{let t=localStorage.getItem(u1);if(t==="dark")return!0;if(t==="light")return!1}catch{}}function o2(t){T1.value=t;try{t===void 0?localStorage.removeItem(u1):localStorage.setItem(u1,t?"dark":"light")}catch{}}function D1(t=!1){let a=T1.value;return a===void 0&&!t?q.darkMode():a}q(()=>{D1()?q.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#0e0f12 --s-text:#e9eaec",".s-s.neutral":"--s-bg:#191b1f --s-text:#e9eaec",".s-s.neutral .s-s.neutral":"--s-bg:#23262b"}):q.insertGlobalCss({":root, .s-s.neutral":"--s-bg:#eef0f3 --s-text:#1d1f24",".s-s.neutral, .s-s.neutral":"--s-bg:#ffffff --s-text:#1d1f24",".s-s.neutral .s-s.neutral":"--s-bg:#f6f7f9"})});q.setSpacingCssVars(1.1);q.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 p:$3 line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased background-color:$s-bg text:$s-text",a:"color: $s-link-fg; text-decoration:underline text-underline-offset:2px; transition: color 0.12s, filter 0.12s;","a:hover":"filter: brightness(1.15)","input, button, textarea, select, optgroup":"font:inherit color:inherit","input:where(:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=image],[type=submit],[type=button],[type=reset],[type=hidden])), textarea, select":"background:$s-bg border: 1px solid $s-faint; r:$s-radius-sm padding: 0.45em 0.65em; max-width:100%","input:where([type=checkbox],[type=radio])":"width:1.15em height:1.15em cursor:pointer","input[type=range]":"appearance:none background:transparent cursor:pointer vertical-align:middle","input[type=range]::-webkit-slider-runnable-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-track":"height:4px r:99px background:$s-faint","input[type=range]::-moz-range-progress":"height:4px r:99px background:$s-accent","input[type=range]::-webkit-slider-thumb":"appearance:none width:16px height:16px margin-top:-6px r:50% background:$s-accent","input[type=range]::-moz-range-thumb":"width:16px height:16px border:0 r:50% background:$s-accent","input[type=file]":"cursor:pointer",progress:"appearance:none border:0 height:6px r:99px background:$s-faint overflow:hidden vertical-align:middle","progress::-webkit-progress-bar":"background:$s-faint r:99px","progress::-webkit-progress-value":"background:$s-accent r:99px","progress::-moz-progress-bar":"background:$s-accent r:99px",meter:"vertical-align:middle",fieldset:"border: 1px solid $s-faint; r:$s-radius-sm padding:$2 min-width:0",legend:"padding: 0 $1; font-weight:600","code, kbd, samp, pre":"font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;",code:"background: color-mix(in oklab, $s-text, $s-bg 86%); padding: 0.12em 0.34em; r:4px font-size:0.9em",pre:"background: color-mix(in oklab, $s-text, $s-bg 92%); p:$3 r: $s-radius; overflow:auto","pre code":"background:transparent p:0","img, svg, video, canvas":"max-width:100% h:auto",hr:"border:0 border-top: 1px solid $s-faint;","::placeholder":"color: $s-muted; opacity:1",":focus-visible":"outline: 2px solid $s-focus; outline-offset:2px",small:"color:$s-muted font-size:0.9em","@media (prefers-reduced-motion: reduce)":{"*, *::before, *::after":"transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important;"},":root":"--s-primary:#00a884 --s-danger:#dc5b41 --s-success:#00a884 --s-warning:#ef6b00 --s-link:#3f8cd8 --s-radius-sm:6px --s-radius:12px --s-radius-lg:18px --s-focus: color-mix(in srgb, $s-primary 38%, transparent); --s-gradient: linear-gradient(135deg, color-mix(in oklab, $s-primary, white 16%), color-mix(in oklab, $s-primary, black 14%));",":root, .s-s.neutral":"--s-accent:$s-primary --s-link-fg:$s-link",".s-s:not(.neutral)":"--s-bg:$s-primary border:0 --s-text:#eee --s-accent:#fff --s-link-fg:#eef --s-muted: color-mix(in srgb, #fff 70%, transparent); --s-faint: color-mix(in srgb, #fff 30%, transparent);",".s-s.danger":"--s-bg:$s-danger",".s-s.success":"--s-bg:$s-success",".s-s.warning":"--s-bg:$s-warning",".s-s.link":"--s-bg:$s-link",".s-s.primary":"--s-bg:$s-primary",":root, .s-s":"--s-muted: color-mix(in oklab, $s-text, $s-bg 42%); --s-faint: color-mix(in oklab, $s-text, $s-bg 80%); color:$s-text accent-color:$s-accent scrollbar-width:thin scrollbar-color: $s-faint transparent;",".s-s, body":t1,".s-s":"r:$s-radius",":where(.s-s.neutral)":"border: 1px solid $s-faint;",".s-s::-webkit-scrollbar, .s-s ::-webkit-scrollbar":"width:10px height:10px",".s-s::-webkit-scrollbar-track, .s-s ::-webkit-scrollbar-track":"background:transparent",".s-s::-webkit-scrollbar-thumb, .s-s ::-webkit-scrollbar-thumb":"background:$s-faint border-radius:99px border: 2px solid transparent; background-clip:padding-box",".s-s.shadow.neutral:not(.s-btn)":"box-shadow: 0 4px 14px rgba(0,0,0,0.13);",".s-s.extra-shadow.neutral:not(.s-btn)":"box-shadow: 0 18px 50px rgba(0,0,0,0.28);",".s-s.shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 4px 14px color-mix(in srgb, $s-bg 30%, transparent);",".s-s.extra-shadow:not(.neutral):not(.tonal):not(.outlined)":"box-shadow: 0 14px 40px color-mix(in srgb, $s-bg 40%, transparent);",".s-s.no-shadow":"box-shadow: none !important;",".s-s:not(.neutral).tonal, .s-s:not(.neutral).outlined":"--s-text:$s-bg --s-accent:$s-bg --s-link-fg:$s-bg --s-faint: color-mix(in srgb, $s-bg 30%, transparent); --s-muted: color-mix(in srgb, $s-bg 70%, transparent);",".s-s:not(.neutral).tonal":"background: color-mix(in srgb, $s-bg 15%, transparent); border: 1px solid $s-faint;",".s-s:not(.neutral).outlined":"background: transparent; border: 1px solid color-mix(in srgb, $s-bg 45%, transparent);",".s-s:not(.neutral) .s-s.tonal, .s-s:not(.neutral) .s-s.outlined":"--s-text:#fff --s-accent:#fff --s-link-fg:#fff "+t1+" border-color: transparent;"});q.insertGlobalCss({".s-preload, .s-preload *, .s-preload *::before, .s-preload *::after":"transition: none !important; animation: none !important;"});if(typeof document<"u"&&typeof requestAnimationFrame=="function"){let t=document.documentElement;t.classList.add("s-preload"),requestAnimationFrame(()=>requestAnimationFrame(()=>t.classList.remove("s-preload")))}q.insertGlobalCss({":disabled, [aria-disabled=true]":"opacity:0.45 filter:saturate(0.6) user-select:none",":disabled, [aria-disabled=true], :disabled *, [aria-disabled=true] *":"pointer-events:none cursor:not-allowed"});var c2="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";q.insertGlobalCss({[`${c2}`]:{"&":"margin:0","&:not(:first-child)":"margin-top:$3"},"h1, h2, h3, h4, h5, h6":{"&":"line-height:1.15 font-weight:700 text-wrap:balance","&:not(:first-child)":"margin-top:1.4em"},h1:"font-size:2em font-weight:800 letter-spacing:-0.022em",h2:"font-size:1.55em letter-spacing:-0.018em",h3:"font-size:1.3em letter-spacing:-0.011em",h4:"font-size:1.1em",h5:"font-size:0.95em letter-spacing:0.005em",h6:"font-size:0.8em fg:$s-muted text-transform:uppercase letter-spacing:0.07em","ul, ol":{"&":"padding-left:1.5em","> li:not(:first-child), li > &:not(:first-child)":"margin-top:$1"},blockquote:"border-left: 3px solid $s-faint; padding-left: $3; fg: $s-muted",table:"border-collapse:collapse","th, td":"text-align:left padding: $1 $2; border-bottom: 1px solid $s-faint; vertical-align:top",th:"font-weight:600","thead th":"border-bottom: 2px solid $s-faint;",dt:"font-weight:600",dd:"margin-left: 1.5em",figcaption:"fg:$s-muted font-size:0.9em margin-top:$1 text-align:center"});import M from"aberdeen";import R1 from"aberdeen";var d1=640,n2=0;function F(t="s"){return`${t}-${++n2}`}function x(t,...a){t!=null&&(typeof t=="function"?t(...a):R1("rich=",t))}var i2="a[href], button, input, select, textarea, [tabindex]";function _(t,a){let h=p=>p instanceof HTMLElement&&!p.hasAttribute("disabled")&&p.getAttribute("aria-disabled")!=="true"&&p.tabIndex>=0&&p.getClientRects().length>0,e=(a?[...t.querySelectorAll(a)].find(h):void 0)??[...t.querySelectorAll(i2)].find(h);return e?.focus(),e!=null}function I(t){queueMicrotask(()=>R1(t))}import C from"aberdeen";C.insertGlobalCss({".s-field":{"&":"display:flex flex-direction:column gap:$1","> label":"font-weight:600 font-size:0.9em fg:$s-text user-select:none"},".s-req":"fg:$s-danger margin-left:2px",".s-help":"font-size:0.82em fg:$s-muted",".s-error":"font-size:0.82em fg:$s-danger",".s-input":{"&":"w:100% background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.55em 0.7em; transition: border-color 0.15s, box-shadow 0.15s;","&:hover:not(:disabled)":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","&:focus-visible":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus; outline:none","&[aria-invalid=true]":"border-color:$s-danger"}});function U(t,a){let h=t.id??F("field"),e=()=>!!t.error;C("div.s-field",t.attrs,()=>{C(()=>{t.label!=null&&C("label for=",h,()=>{x(t.label),t.required&&C("span.s-req aria-hidden=true #*")})}),a(h,e),C(()=>{t.help!=null&&!t.error&&C("div.s-help",()=>x(t.help))}),C(()=>{t.error&&C("div.s-error role=alert #",t.error)})})}function Q(t,a,h,e){C("id=",a),t.name&&C("name=",t.name),C(()=>{t.disabled&&C("disabled=true")}),C(()=>{t.required&&C("aria-required=true")}),C(()=>C("aria-invalid=",h()?"true":"false")),e&&C("bind=",e)}M.insertGlobalCss({".s-ac":{"&":"position:relative","> .s-control":"display:flex flex-wrap:wrap align-items:center gap:$1 background: color-mix(in oklab, $s-bg, $s-text 4%); color:$s-text border: 1px solid $s-faint; r:$s-radius padding: 0.3em 0.4em; cursor:text; transition: border-color 0.15s, box-shadow 0.15s;","> .s-control:hover":"border-color: color-mix(in oklab, $s-text, $s-bg 55%);","> .s-control:focus-within":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus;","&[aria-invalid=true] > .s-control":"border-color:$s-danger",".s-chip":"display:inline-flex align-items:center gap:$1 font-size:0.85em background: color-mix(in oklab, $s-bg, $s-text 10%); border: 1px solid $s-faint; r:$s-radius padding: 0.1em 0.2em 0.1em 0.5em;",".s-chip > button":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.2em; r:4px",".s-chip > button:hover":"fg:$s-text background:$s-faint",input:"flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em","> .s-menu":"position:absolute top:100% left:0 right:0 z-index:20 margin-top:4px max-height:15rem overflow-y:auto list-style:none p:$1 margin-bottom:0","> .s-menu li":"margin:0",".s-option":"padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",".s-option[aria-selected=true]":"background: color-mix(in srgb, $s-text 10%, transparent);",".s-add":"fg:$s-accent font-style:italic",".s-empty":"padding: 0.45em 0.6em; fg:$s-muted"}});function s2(t){return typeof t=="string"?{value:t,label:t}:{value:t.value,label:t.label??t.value}}function l2(t){let a=F("ac-menu"),h=M.proxy({query:"",open:!1,active:0}),e=()=>(typeof t.options=="function"?t.options():t.options).map(s2),p=()=>{let n=t.bind?.value;return n==null||n===""?[]:Array.isArray(n)?n:[n]},r=n=>e().find(v=>v.value===n)?.label??n;if(!t.multi){let n=t.bind?M.peek(t.bind,"value"):void 0;typeof n=="string"&&n&&(h.query=M.peek(()=>r(n)))}let d=()=>{let n=new Set(p()),v=e();t.multi&&(v=v.filter(b=>!n.has(b.value)));let y=h.query.trim().toLowerCase();return y&&(v=v.filter(b=>b.label.toLowerCase().includes(y))),v},o=(n,v)=>{if(t.multi){let y=Array.isArray(t.bind?.value)?[...t.bind.value]:[];y.includes(n)||y.push(n),t.bind&&(t.bind.value=y),h.query=""}else t.bind&&(t.bind.value=n),h.query=r(n),h.open=!1;h.active=0,v?.focus()},c=n=>{if(!t.bind)return;let v=t.bind.value??[];t.bind.value=v.filter(y=>y!==n)};U(t,(n,v)=>{M("div.s-ac",t.inputAttrs,()=>{M(()=>M("aria-invalid=",v()?"true":"false"));let y;M("div.s-control",()=>{M("click=",()=>y?.focus()),M(()=>{if(t.multi)for(let b of p())M("span.s-chip",()=>{M("span #",M.peek(()=>r(b))),M("button type=button aria-label=",`Remove ${b}`,()=>{M("#\xD7"),M("click=",A=>{A.stopPropagation(),c(b),y?.focus()})})})}),y=M("input type=text role=combobox autocomplete=off",()=>{M("id=",n,`aria-controls=${a} aria-autocomplete=list`),t.placeholder!=null&&M("placeholder=",t.placeholder),t.disabled&&M("disabled=true"),t.required&&M("aria-required=true"),M("bind=",M.ref(h,"query")),M(()=>M("aria-expanded=",h.open?"true":"false")),M(()=>{let A=d()[h.active];M("aria-activedescendant=",h.open&&A?`${a}-opt-${h.active}`:"")}),M("input=",()=>{h.open=!0,h.active=0}),M("focus=",()=>{h.open=!0}),M("blur=",()=>{setTimeout(()=>f(),150)}),M("keydown=",b=>s(b,y))})}),M(()=>{if(!h.open)return;let b=d(),A=h.query.trim(),m=t.allowCustom!==!1&&A!==""&&!b.some(g=>g.label.toLowerCase()===A.toLowerCase());M("ul.s-menu.s-s.neutral.shadow role=listbox",`id=${a}`,()=>{b.forEach((g,z)=>{M("li.s-option role=option",`id=${a}-opt-${z}`,()=>{M(()=>M("aria-selected=",h.active===z?"true":"false")),M("#",g.label),M("mousedown=",P=>P.preventDefault()),M("click=",()=>o(g.value,y)),M("mousemove=",()=>{h.active=z})})}),m&&M("li.s-option.s-add role=option",()=>{M("#",`Add "${A}"`),M("mousedown=",g=>g.preventDefault()),M("click=",()=>o(A,y))}),b.length===0&&!m&&M("li.s-empty #No matches")})}),M(()=>{if(t.name)if(t.multi)for(let b of p())M("input type=hidden",()=>{M("name=",t.name),M("value=",b)});else M("input type=hidden",()=>{M("name=",t.name),M("value=",p()[0]??"")})})})});function s(n,v){let y=d(),b=y.length-1;if(n.key==="ArrowDown")n.preventDefault(),h.open=!0,h.active=Math.min(b,h.active+1);else if(n.key==="ArrowUp")n.preventDefault(),h.active=Math.max(0,h.active-1);else if(n.key==="Enter"){n.preventDefault();let A=y[h.active];A?o(A.value,v):t.allowCustom!==!1&&h.query.trim()?o(h.query.trim(),v):h.open&&(h.open=!1)}else if(n.key==="Escape")h.open&&(n.preventDefault(),h.open=!1,t.multi||(h.query=r(p()[0]??"")));else if(n.key==="Backspace"&&t.multi&&h.query===""){let A=p();A.length&&c(A[A.length-1])}}function f(){h.open=!1,t.multi?h.query="":t.allowCustom!==!1&&h.query.trim()?o(h.query.trim()):h.query=r(p()[0]??"")}}import N from"aberdeen";import M2 from"aberdeen";var a1={size:24,color:"currentColor",strokeWidth:2,cap:"round",join:"round"};function x2(t,a){let h=a.size??a1.size,e=M2('svg.s-icon aria-hidden=true viewBox="0 0 24 24" fill=none',"width=",h,"height=",h,"stroke=",a.color??a1.color,"stroke-width=",a.strokeWidth??a1.strokeWidth,"stroke-linecap=",a.cap??a1.cap,"stroke-linejoin=",a.join??a1.join,a.attrs);e.innerHTML=t}function $(t){return(a={})=>x2(t,a)}var Z1=$('<path d="m9 18 6-6-6-6" />');var B1=$('<circle cx="12" cy="12" r="10" />');var F1=$('<path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />');var I1=$('<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />');var o1=$('<path d="M4 5h16" /><path d="M4 12h16" /><path d="M4 19h16" />');var U1=$('<path d="M12 17v5" /><path d="M15 9.34V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H7.89" /><path d="m2 2 20 20" /><path d="M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h11" />'),y1=$('<path d="M12 17v5" /><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" />');var W1=$('<path d="M22 2 2 22" />');var J=$('<path d="M18 6 6 18" /><path d="m6 6 12 12" />');import O from"aberdeen";O.insertGlobalCss({".s-btn":{"&":"display:inline-flex align-items:center justify-content:center gap:$2 font-weight:450 line-height:1.1 white-space:nowrap cursor:pointer text-decoration:none padding: $m2 $m3; transition: background 0.15s, border-color 0.15s, color 0.15s, filter 0.15s, box-shadow 0.15s, transform 0.08s;","&:focus-visible":"outline: 3px solid $s-focus; outline-offset: 1px;","&:hover":"filter: brightness(1.06)","&.tonal:hover, &.outlined:hover":"background: color-mix(in srgb, $s-bg 24%, transparent);","&.neutral:hover":"filter:none background: color-mix(in srgb, $s-text 8%, $s-bg);","> svg":"width:1.25em height:1.25em","&:active:not(:disabled)":"transform: translateY(1px)","&.small, .small > &":"padding: $m1 $m2; font-size:0.85em border-radius:$s-radius-sm","&.large, .large > &":"font-size:1.4em border-radius:$s-radius-lg"},".s-icon-btn":{"&":"display:inline-flex align-items:center justify-content:center flex-shrink:0 width:2rem height:2rem p:0 border:0 background:transparent cursor:pointer fg:$s-muted r:$s-radius-sm line-height:1 font-size:1rem text-decoration:none transition: color 0.12s, background 0.12s;","> svg":"width:1.25em height:1.25em","&:hover:not(:disabled):not([aria-disabled=true])":"fg:$s-text background: color-mix(in srgb, $s-text 10%, transparent);","&:focus-visible":"outline: 3px solid $s-focus; outline-offset:1px","&.small, .small > &":"width:1.6rem height:1.6rem font-size:0.8rem","&.large, .large > &":"width:2.4rem height:2.4rem font-size:1.2rem"}});function h1(t){let a=t.href!=null?"a":"button";O(`${a}.s-icon-btn`,t.attrs,()=>{N1(t),O("aria-label=",t.ariaLabel),x(t.icon)})}function N1(t){t.href!=null?(O("role=button"),t.disabled?O("aria-disabled=true"):O("href=",t.href)):(O("type=",t.type??"button"),t.disabled&&O("disabled=true")),t.click&&!t.disabled&&O("click=",t.click)}function E(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t,h=a.href!=null?"a":"button";O(`${h}.s-btn.s-s.shadow`,a.attrs,()=>{N1(a),a.ariaLabel&&O("aria-label=",a.ariaLabel),x(a.icon),x(a.content)})}N.insertGlobalCss({".s-box":{"&":"display:flex flex-direction:column overflow:hidden r: $s-radius-lg; position:relative","&:not(:first-child)":"margin-top: $3","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0","> div":"p:$3 gap:$3","> header > .s-box-close":"margin-left:auto","> .s-box-close":"position:absolute top:$2 right:$2 z-index:1"}});function v2(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;N("section.s-box.s-s.neutral.shadow",a.attrs,()=>{N(()=>{a.header!=null?N("header.s-s.neutral",a.headerAttrs,()=>{x(a.header),typeof a.close=="function"&&G1(a.close)}):typeof a.close=="function"&&G1(a.close)}),N("div",a.contentAttrs,()=>{x(a.content)}),N(()=>{a.footer!=null&&N("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})})}function G1(t){h1({icon:J,ariaLabel:"Close",click:t,attrs:".s-box-close"})}import f1 from"aberdeen";import X1 from"aberdeen";X1.insertGlobalCss({".s-bgroup":{"&":"display:inline-flex align-items:stretch","&.s-spaced":"gap:$2 flex-wrap:wrap","&.s-vertical":"flex-direction:column","&.s-attached":"gap:0","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child)":"margin-left:-1px","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached:not(.s-vertical) > .s-btn:first-child:not(:last-child)":"border-top-right-radius:0 border-bottom-right-radius:0","&.s-attached:not(.s-vertical) > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-bottom-left-radius:0","&.s-attached.s-vertical > .s-btn:not(:first-child)":"margin-top:-1px","&.s-attached.s-vertical > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached.s-vertical > .s-btn:first-child:not(:last-child)":"border-bottom-left-radius:0 border-bottom-right-radius:0","&.s-attached.s-vertical > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-top-right-radius:0","&.s-attached > .s-btn:hover, &.s-attached > .s-btn:focus-visible":"z-index:1"}});function G(t={}){let h=`.s-${t.layout??"attached"}${t.vertical?".s-vertical":""}`;X1(`div.s-bgroup${h} role=group`,t.attrs,()=>{if(t.buttons)for(let e of t.buttons)E(e);x(t.content)})}function m2(t){f1(()=>{let a=t.bind.value;G({attrs:t.attrs,buttons:Object.entries(t.options).map(([h,e])=>({content:e,ariaLabel:typeof e=="function"?h:void 0,attrs:a===h?".primary":".neutral",click:()=>{t.bind.value=t.allowDeselect&&a===h?void 0:h}}))})}),t.name&&f1(()=>f1("input type=hidden name=",t.name,"value=",t.bind.value??""))}import L from"aberdeen";L.insertGlobalCss({".s-check":{"&":"display:flex flex-direction:column gap:$1","> label":"display:flex align-items:center gap:$2 cursor:pointer user-select:none","> label:has(input:disabled)":"cursor:not-allowed opacity:0.45 filter:saturate(0.6)",input:"cursor:inherit m:0"}});function u2(t={}){let a=t.id??F("check");L("div.s-check",t.attrs,()=>{L("label for=",a,()=>{L("input type=checkbox",t.inputAttrs,()=>{L("id=",a),t.name&&L("name=",t.name),t.checked&&!t.bind&&L("checked=true"),t.change&&L("change=",t.change),L(()=>{t.disabled&&L("disabled=true")}),L(()=>{t.required&&L("aria-required=true")}),t.bind&&L("bind=",t.bind)}),L(()=>{t.label!=null&&x(t.label),t.required&&L("span.s-req aria-hidden=true #*")})}),L(()=>{t.help!=null&&!t.error&&L("div.s-help",()=>x(t.help))}),L(()=>{t.error&&L("div.s-error role=alert #",t.error)})})}import X from"aberdeen";X.insertGlobalCss({".s-form":{"&":"display:flex flex-direction:column gap:$3","&.grid":"display:grid grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap:$3","&.grid > .s-wide, &.grid > footer":"grid-column: 1 / -1;","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 flex-wrap:wrap margin-top:$1"}});function y2(t={}){let a=typeof t=="string"||typeof t=="function"?{content:t}:t;X("form.s-form",a.attrs,()=>{X(()=>{X(".grid=",a.layout==="grid")}),X("submit=",h=>{if(h.preventDefault(),a.submit){let e=new FormData(h.target),p={};for(let r of new Set(e.keys())){let d=e.getAll(r);p[r]=d.length===1?d[0]:d}a.submit(p,h)}}),x(a.content),X(()=>{a.actions&&X("footer",a.actionsAttrs,()=>x(a.actions))})})}import i from"aberdeen";import{current as O1}from"aberdeen/route";import u from"aberdeen";import{matchCurrent as f2,current as c1,go as g2}from"aberdeen/route";u.insertGlobalCss({".s-menu-list":"position:fixed z-index:350 min-width:10rem display:flex flex-direction:column p:$1 r:$s-radius-lg overflow-y:auto max-height:min(80vh,28rem) transition: opacity 0.15s, transform 0.15s, visibility 0.15s;",".s-menu-list.hidden":"opacity:0 pointer-events:none transform:translateY(-6px) visibility:hidden",".s-menu-item":"display:flex align-items:center gap:$2 w:100% outline:0 scroll-margin:$2 padding: $m2 0; line-height:1.1 r:$s-radius cursor:pointer text-align:left font-weight:450 font-size:0.9em border:0 background:transparent fg:$s-text text-decoration:none transition: color 0.12s, transform 0.12s, text-shadow 0.12s;",".s-menu-item:focus-visible:not([aria-current=page]), .s-menu-item:hover:not([aria-disabled=true]):not([aria-current=page])":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);",".s-menu-item[aria-current=page]":"color:$s-accent filter:none",".s-menu-list .s-menu-item":"padding-inline:$2",".s-menu-item[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none",".s-menu-icon":"flex-shrink:0",".s-menu-list .s-menu-icon":"display:flex",".s-menu-list .s-menu-icon > svg":"width:1.25em height:1.25em","hr.s-menu-sep":"border:0 height:1px margin: $1 0.6rem; background: linear-gradient(to right, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-menu-chevron":"margin-left:auto flex-shrink:0 display:flex transition: transform 0.15s ease;",".s-menu-chevron > svg":"width:1em height:1em",".s-menu-details":{"> summary":"list-style:none","> summary::-webkit-details-marker":"display:none","&::details-content":"interpolate-size:allow-keywords block-size:0 overflow-y:clip transition: block-size 0.15s ease, content-visibility 0.15s allow-discrete;","&[open]::details-content":"block-size:auto","&[open] > summary .s-menu-chevron":"transform:rotate(90deg)"},".s-menu-sub":"display:flex flex-direction:column gap:$1 padding-left:$3",".s-menu-inline":"display:flex flex-direction:column gap:$1"});function e1(t,a){u("keydown=",e=>{if(e.key==="Enter"&&e.target.tagName==="A"){queueMicrotask(()=>a?.());return}if(e.key!=="ArrowDown"&&e.key!=="ArrowUp"&&e.key!=="Home"&&e.key!=="End")return;e.preventDefault();let r=[...e.currentTarget.querySelectorAll(".s-menu-item")].filter(s=>s.getAttribute("aria-disabled")!=="true"&&!H2(s));if(!r.length)return;let d=r.indexOf(document.activeElement),o=e.key==="ArrowUp"?-1:1,c=e.key==="Home"?0:e.key==="End"?r.length-1:d<0?o>0?0:r.length-1:(d+o+r.length)%r.length;r[c].focus()});let h=u.derive(()=>g1(t));j1(t,a,h)}function j1(t,a,h){for(let e of t){if(typeof e=="string"||typeof e=="function"){x(e);continue}if("separator"in e){u("hr.s-menu-sep");continue}e.items?w2(e,a,h):b2(e,a)}}function b2(t,a){let h=!1,e=u(t.href?"a.s-menu-item data-panel=open":"button.s-menu-item type=button",t.attrs,()=>{t.href&&(u("href=",t.href),t.target&&u("target=",t.target),u(()=>{let p=!h;h=!0,b1(t)&&(u("aria-current=page"),requestAnimationFrame(()=>e.scrollIntoView({block:"nearest",behavior:p?"instant":"smooth"})))})),t.disabled&&u("aria-disabled=true"),u("click=",p=>{if(t.disabled){p.preventDefault();return}a?.(),t.click?.(p)}),t.icon&&u("span.s-menu-icon",()=>x(t.icon)),x(t.label)})}var _1=new Map;function K1(t,a){return _1.set(t,a),a}function w2(t,a,h){let e=t.href??Q1(t.items),p=e!=null?u.derive(()=>w1(t)?K1(e,!0):h==null||h.value?K1(e,!1):_1.get(e)??!1):null;u("details.s-menu-details",()=>{p&&u(()=>{p.value&&u("open=true")}),u("summary.s-menu-item.s-menu-branch",t.attrs,()=>{t.disabled&&u("aria-disabled=true"),u(()=>{b1(t)&&u("aria-current=page")}),u("click=",r=>{if(t.disabled){r.preventDefault();return}e!=null&&(r.preventDefault(),A2(e),g2(e)),t.click?.(r)}),t.icon&&u("span.s-menu-icon",()=>x(t.icon)),x(t.label),u("span.s-menu-chevron aria-hidden=true",()=>Z1())}),u("div.s-menu-sub",()=>j1(t.items,a,h))})}function H2(t){for(let a=t.closest("details");a;a=a.parentElement&&a.parentElement.closest("details"))if(!a.open&&t.closest("summary")?.parentElement!==a)return!0;return!1}function g1(t){return t.some(a=>typeof a!="string"&&typeof a!="function"&&!("separator"in a)&&w1(a))}function b1(t){if(t.href!=null&&f2(t.href))return!0;let a=t.match;if(a==null)return!1;let h=c1.path;if(typeof a=="function")return a(h);let e=a.replace(/\/+$/,"")||"/";return h===e||h.startsWith(e==="/"?"/":e+"/")}function w1(t){if(b1(t))return!0;for(let a of t.items??[])if(!(typeof a=="string"||typeof a=="function"||"separator"in a)&&w1(a))return!0;return!1}function Q1(t){for(let a of t){if(typeof a=="string"||typeof a=="function"||"separator"in a)continue;let h=a.href??(a.items?Q1(a.items):void 0);if(h!=null)return h}}var n1=null;function A2(t){try{n1=new URL(t,location.href).pathname.replace(/\/+$/,"")||"/"}catch{n1=null}}function H1(t){return n1!==t?!1:(n1=null,!0)}var W=u.proxy({opts:null});function B(){let t=W.opts?.anchor;W.opts=null,t?.focus()}function i1(t){let a=W.opts;return a!=null&&(t==null||a.anchor===t)}function V2(t){i1(t)&&B()}function k2(t,a){let h=t.offsetWidth,e=t.offsetHeight,p=window.innerWidth,r=window.innerHeight,d=4,o=a.left;o+h>p-8&&(o=Math.max(8,a.right-h));let c=a.bottom+d;c+e>r-8&&a.top-e-d>=8&&(c=a.top-e-d),t.style.left=Math.max(8,o)+"px",t.style.top=Math.max(8,c)+"px"}I(()=>{let t=W.opts;if(!t)return;let a=u("div.s-menu-list.s-s.neutral.shadow create=hidden destroy=hidden",t.dropdownAttrs,()=>{e1(t.items,B)}),h=r=>{let d=r.target;!a.contains(d)&&(t.closeOnAnchorClick||!t.anchor.contains(d))&&B()},e=r=>{(r.key==="Escape"||r.key==="Tab")&&(r.preventDefault(),B())},p=u.peek(c1,"path");u(()=>{c1.path!==p&&!H1(c1.path)&&B()}),document.addEventListener("click",h,!0),document.addEventListener("keydown",e,!0),u.clean(()=>{document.removeEventListener("click",h,!0),document.removeEventListener("keydown",e,!0)}),requestAnimationFrame(()=>{if(!document.body.contains(a))return;let r=t.at?{left:t.at.x,right:t.at.x,top:t.at.y,bottom:t.at.y}:t.anchor.getBoundingClientRect();k2(a,r),_(a,".s-menu-item[aria-current=page]")})});function L2(t){u("nav.s-menu-inline",t.attrs,()=>e1(t.items,t.onLeafSelect))}function A1(t){return W.opts=t,B}function V1(t){let a=null;u.clean(()=>{W.opts?.anchor===a&&B()}),u("contextmenu=",h=>{h.preventDefault(),a=h.currentTarget,A1({items:t.items,anchor:a,at:{x:h.clientX,y:h.clientY},closeOnAnchorClick:!0,dropdownAttrs:t.dropdownAttrs})})}function C2(t){let a=null;u.clean(()=>{W.opts?.anchor===a&&B()}),E({icon:o1,...t.button?.content==null?{ariaLabel:"Open menu"}:null,attrs:".neutral",...t.button,click:h=>{if(a=h.currentTarget,W.opts?.anchor===a){B();return}A1({items:t.items,anchor:a,dropdownAttrs:t.dropdownAttrs})}})}import H from"aberdeen";import K from"aberdeen";function k1(t={}){U(t,(a,h)=>{K("input.s-input",t.inputAttrs,()=>{K("type=",t.type??"text"),t.placeholder!=null&&K("placeholder=",t.placeholder),t.autocomplete!=null&&K("autocomplete=",t.autocomplete),t.value!=null&&!t.bind&&K("value=",t.value),t.input&&K("input=",t.input),t.change&&K("change=",t.change),Q(t,a,h,t.bind)})})}H.insertGlobalCss({".s-backdrop":{"&":"position:fixed inset:0 z-index:200 display:block background: rgba(0,0,0,0.55); transition: opacity 0.4s ease-in-out;","&.hidden":"opacity:0 pointer-events:none"},".s-dialog":{"&":"position:fixed z-index:200 top:50% left:50% display:flex flex-direction:column transform:translate(-50%,-50%) min-width:20rem max-width:min(90vw,44rem) max-height:min(88vh,800px) r: $s-radius-lg; overflow:hidden transition: opacity 0.2s ease-out, transform 0.2s ease-out;","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border:0 border-bottom: 1px solid $s-faint; r:0 font-weight:600 flex-shrink:0","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border:0 border-top: 1px solid $s-faint; r:0 flex-shrink:0","> div":"p:$3 gap:$3 display:flex flex-direction:column overflow-y:auto flex:1 min-height:0","&.hidden":"opacity:0 pointer-events:none transform: translate(-50%, calc(-50% + 20px)); pointer-events:none"}});var j=H.proxy({}),L1=0,J1=H.derive(()=>{let t=Object.keys(j);if(t.length)return t[t.length-1]});function C1(){return J1.value!=null}I(()=>{H.onEach(j,({resolve:t,opts:a},h)=>{let e=()=>{delete j[h]};H.clean(()=>{a.onClose?.(),t()});let p=H.derive(()=>J1.value!=h);H("div.s-backdrop create=hidden destroy=hidden .hidden=",p,"click=",()=>{a.allowCancel!==!1&&e()});let r=H("div.s-dialog.neutral.s-s.extra-shadow create=hidden destroy=hidden",a.attrs,()=>{H(()=>{a.header!=null&&H("header.s-s.neutral",a.headerAttrs,()=>x(a.header))}),H("div",a.contentAttrs,()=>{x(a.content,e)}),H(()=>{a.footer!=null&&H("footer.s-s.neutral",a.footerAttrs,()=>x(a.footer))})});requestAnimationFrame(()=>{document.body.contains(r)&&_(r)})})});function s1(t){L1||document.addEventListener("keydown",h=>{if(h.key!=="Escape"||h.defaultPrevented)return;let e=H.unproxy(j);for(let p=L1;p>0;p--)if(e[p]){h.preventDefault(),e[p].opts.allowCancel!==!1&&delete j[p];break}});let a=++L1;return t.cancelWithScope!==!1&&H.clean(()=>{delete j[a]}),new Promise(h=>{j[a]={resolve:h,opts:t}})}function z2(t,a={}){return s1({header:"Alert",allowCancel:!0,content:h=>{H("p",()=>{H("#",t)}),G({layout:"spaced",attrs:"align-self:flex-end",content:()=>{E({content:"OK",click:h})}})},...a})}function $2(t,a={}){return new Promise(h=>{let e=!1;s1({header:"Confirm",allowCancel:!0,content:p=>{H("p",()=>{H("#",t)}),G({layout:"spaced",attrs:"align-self:flex-end",content:()=>{E({content:"Cancel",attrs:".neutral",click:p}),E({content:"OK",click:()=>{e=!0,p()}})}})},...a,onClose:()=>{h(e),a.onClose?.()}})})}function S2(t,a="",h={}){return new Promise(e=>{let p=null;s1({header:"Input",allowCancel:!0,content:r=>{H("p",()=>{H("#",t)});let d=H.proxy({value:a});H("form display:contents",()=>{H("submit=",o=>{o.preventDefault(),p=d.value,r()}),k1({bind:H.ref(d,"value")}),G({layout:"spaced",attrs:"align-self:flex-end",content:()=>{E({content:"Cancel",attrs:".neutral",type:"button",click:r}),E({content:"OK",type:"submit"})}})})},...h,onClose:()=>{e(p),h.onClose?.()}})})}import l,{OPAQUE as t2}from"aberdeen";import*as w from"aberdeen/route";import V from"aberdeen";var P2=$('<path d="m15 18-6-6 6-6"/>'),O2=$('<path d="m9 18 6-6-6-6"/>');V.insertGlobalCss({".s-strip":{"&":"position:relative display:flex min-width:0","> .s-strip-row":"display:flex align-items:center flex:1 min-width:0 overflow-x:auto overflow-y:hidden scrollbar-width:none scroll-behavior:smooth","> .s-strip-row::-webkit-scrollbar":"display:none","> .s-strip-btn":"position:absolute top:0 bottom:0 z-index:1 display:none align-items:center justify-content:center width:2.4em border:0 padding:0 cursor:pointer fg:$s-muted transition: color 0.15s;","> .s-strip-btn:hover":"fg:$s-text","> .s-strip-btn-left":"left:0 justify-content:flex-start background: linear-gradient(to right, $s-bg 45%, transparent)","> .s-strip-btn-right":"right:0 justify-content:flex-end background: linear-gradient(to left, $s-bg 45%, transparent)","&.s-can-left > .s-strip-btn-left, &.s-can-right > .s-strip-btn-right":"display:flex"},".s-tabs":{"&":"display:flex flex-direction:column gap:$3",".s-tabbar":"border-bottom: 1px solid $s-faint;",".s-tablist":"gap:$1 align-items:stretch margin-bottom:-1px",".s-tab":"display:inline-flex align-items:center gap:$2 cursor:pointer background:transparent border:0 color: $s-muted; font-weight:600 padding: 0.6em 0.9em; white-space:nowrap border-bottom: 3px solid transparent; transition: color 0.15s, background 0.15s, border-color 0.15s;",".s-tab:hover:not(:disabled), .s-tab[aria-selected=true]":"color: $s-text;",".s-tab:focus-visible":"outline:none box-shadow: inset 0 0 0 2px $s-focus; r: $s-radius;",".s-tab[aria-selected=true]":"border-image: $s-gradient 1;",".s-tabpanel":"display:block"}});function l1(t){V("div.s-strip",t.attrs,()=>{let a=V("div.s-strip-row",t.stripAttrs,()=>x(t.content));Y1(a,-1),Y1(a,1),q2(a)})}function M1(t){let a=t.parentElement;if(!a||!t.isConnected)return;let h=parseFloat(getComputedStyle(a).fontSize)*2.6,e=t.getBoundingClientRect(),p=a.getBoundingClientRect();e.left<p.left+h?a.scrollBy({left:e.left-p.left-h,behavior:"smooth"}):e.right>p.right-h&&a.scrollBy({left:e.right-p.right+h,behavior:"smooth"})}function E2(t){let a=F("tabs"),h=(r,d)=>r.id??String(d),e=t.bind??V.proxy(h(t.tabs[0]??{label:""},0));t.tabs.length>0&&!t.tabs.some((r,d)=>h(r,d)===V.peek(()=>e.value))&&(e.value=h(t.tabs[0],0));let p=(r,d)=>{r.disabled||(e.value=h(r,d))};V("div.s-tabs",t.attrs,()=>{l1({attrs:".s-tabbar",stripAttrs:".s-tablist role=tablist",content:()=>{t.tabs.forEach((r,d)=>{let o=h(r,d),c=V("button.s-tab type=button role=tab",()=>{V("id=",`${a}-tab-${o}`,"aria-controls=",`${a}-panel-${o}`),V(()=>{let s=e.value===o;V("aria-selected=",s?"true":"false"),V("tabindex=",s?"0":"-1"),s&&requestAnimationFrame(()=>M1(c))}),r.disabled&&V("disabled=true"),V("click=",()=>p(r,d)),V("keydown=",s=>T2(s,t.tabs,d,p)),x(r.icon),x(r.label)})})}}),V("div.s-tabpanel role=tabpanel",t.contentAttrs,()=>{V(()=>{let r=e.value,d=t.tabs.findIndex((c,s)=>h(c,s)===r),o=t.tabs[d]??t.tabs[0];o&&(V("id=",`${a}-panel-${h(o,d)}`,"aria-labelledby=",`${a}-tab-${h(o,d)}`),x(o.content))})})})}function Y1(t,a){V(`button.s-strip-btn.s-strip-btn-${a<0?"left":"right"} type=button`,()=>{V("tabindex=-1 aria-hidden=true"),V("click=",()=>t.scrollBy({left:a*t.clientWidth*.8,behavior:"smooth"})),(a<0?P2:O2)({size:"1.1em"})})}function q2(t){let a=t.parentElement;if(!a||typeof ResizeObserver>"u")return;let h=()=>{let r=t.scrollWidth-t.clientWidth;a.classList.toggle("s-can-left",t.scrollLeft>1),a.classList.toggle("s-can-right",t.scrollLeft<r-1)};t.addEventListener("scroll",h,{passive:!0});let e=new ResizeObserver(h);e.observe(t);let p=typeof MutationObserver>"u"?void 0:new MutationObserver(r=>{for(let d of r){for(let o of d.addedNodes)o instanceof Element&&e.observe(o);for(let o of d.removedNodes)o instanceof Element&&e.unobserve(o)}h()});p?.observe(t,{childList:!0});for(let r of Array.from(t.children))e.observe(r);h(),V.clean(()=>{t.removeEventListener("scroll",h),e.disconnect(),p?.disconnect()})}function T2(t,a,h,e){let p=h;if(t.key==="ArrowRight"||t.key==="ArrowDown")p=(h+1)%a.length;else if(t.key==="ArrowLeft"||t.key==="ArrowUp")p=(h-1+a.length)%a.length;else if(t.key==="Home")p=0;else if(t.key==="End")p=a.length-1;else return;t.preventDefault();let r=p>=h?1:-1;for(let d=0;d<a.length;d++){let o=a[p];if(o&&!o.disabled){e(o,p),t.currentTarget?.parentElement?.children[p]?.focus();return}p=(p+r+a.length)%a.length}}import k from"aberdeen";import{grow as D2,shrink as R2}from"aberdeen/transitions";k.insertGlobalCss({".s-toasts":"position:fixed bottom:$3 right:$3 z-index:400 display:flex flex-direction:column gap:$2 pointer-events:none max-width:min(90vw,24rem) w:24rem",".s-toast":{"&":"display:flex align-items:flex-start gap:$2 padding: $3; pointer-events:auto position:relative overflow:hidden",".s-toast-body":"display:flex flex-direction:column gap:$1 flex:1 min-width:0",".s-toast-title":"font-weight:700 line-height:1.3",".s-toast-close":"cursor:pointer border:0 background:transparent fg:$s-muted font-size:1.1em line-height:1 padding: 0 0.15em; r:4px flex-shrink:0 align-self:flex-start",".s-toast-close:hover":"fg:$s-text",".s-toast-close:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; fg:$s-text",".s-toast-progress":"position:absolute bottom:0 left:0 right:0 height:2px background:$s-accent width:100%"}});var Z2=0,p1=k.proxy({});I(()=>{k.peek(()=>k.isEmpty(p1))&&k.isEmpty(p1)||k("div.s-toasts",()=>{k.onEach(p1,t=>{let{opts:a,id:h}=t,e=a.type==="danger"||a.type==="warning"?"alert":"status",p=a.type==null||a.type==="neutral"?"neutral":a.type,r=a.duration??6e3,d,o=null,c=()=>{clearTimeout(d),o&&(o.style.transition="none",o.style.width="100%",o.offsetWidth,o.style.transition=`width ${r}ms linear`,o.style.width="0%"),d=setTimeout(()=>z1(h),r)},s=()=>{clearTimeout(d),d=void 0,o&&(o.style.transition="none",o.style.width="100%")};k.clean(()=>clearTimeout(d)),k(`div.s-toast.s-s.${p}.extra-shadow aria-live=polite role=${e}`,"create=",D2,"destroy=",R2,a.attrs,()=>{r>0&&(k("mouseenter=",s),k("mouseleave=",c)),k("div.s-toast-body",()=>{k(()=>{a.title!=null&&k("div.s-toast-title",()=>x(a.title))}),k("div.s-toast-msg",()=>x(a.message))}),k(()=>{a.dismissible!==!1&&k("button.s-toast-close type=button aria-label=Dismiss",()=>{k("#\xD7"),k("click=",()=>z1(h))})}),r>0&&(o=k("div.s-toast-progress"))}),r>0&&requestAnimationFrame(c)})})});function z1(t){delete p1[t]}function x1(t){let a=++Z2;return p1[a]={id:a,opts:t},()=>z1(a)}var P1={integer(t){if(!/^(0|-?[1-9]\d*)$/.test(t))return;let a=Number(t);return Number.isSafeInteger(a)?a:void 0}};function T(t){let a=String(t).replace(/\/+$/,"");return a.startsWith("/")||(a=`/${a}`),a}function r1(t){let a=T(t);return a==="/"?[]:a.slice(1).split("/")}function a2(t){let a=r1(t),h=a.map((e,p)=>{if(!e.startsWith("[")||!e.endsWith("]"))return{kind:"lit",value:e};let r=/^\[\.\.\.([A-Za-z_$][\w$]*)\]$/.exec(e);if(r){if(p!==a.length-1)throw new Error(`Staffa: "${e}" must be the last segment of route "${t}"`);return{kind:"rest",name:r[1]}}let d=/^\[([A-Za-z_$][\w$]*)(?:=([A-Za-z_$][\w$]*))?\]$/.exec(e);if(!d)throw new Error(`Staffa: malformed param "${e}" in route "${t}"`);let[,o,c]=d;if(c&&!(c in P1))throw new Error(`Staffa: unknown matcher "${c}" in route "${t}" (known: ${Object.keys(P1).join(", ")})`);return{kind:"param",name:o,matcher:c}});return{key:t,segs:h}}function B2(t){try{return decodeURIComponent(t)}catch{return t}}function $1(t,a){let h={};for(let e=0;e<t.segs.length;e++){let p=t.segs[e];if(p.kind==="rest")return e>=a.length?null:(h[p.name]=a.slice(e).join("/"),h);if(e>=a.length)return null;let r=a[e];if(p.kind==="lit"){if(r!==p.value)return null}else if(p.matcher){let d=P1[p.matcher](r);if(d===void 0)return null;h[p.name]=d}else h[p.name]=B2(r)}return t.segs.length===a.length?h:null}var e2=250,F2=300,I2=360,h2=2;l.insertGlobalCss({":root":`--s-panel-ms:${e2}ms`,".s-panels":"flex:1 min-width:0 min-height:0 position:relative overflow:clip isolation:isolate "+t1,".s-panel":{"&":"position:absolute top:0 bottom:0 left:0 display:flex flex-direction:column "+t1+" visibility:visible transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility 0s;","&.s-panel-sep::before":"content:'' position:absolute left:0 top:0.6rem bottom:0.6rem width:1px z-index:1 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);","&.s-panel-enter":"opacity:0 transition:none transform: translateX(8cqw);","&.s-panel-closing":"opacity:0 pointer-events:none transform: translateX(8cqw);","&.s-panel-hidden, &.s-panel-parked":"opacity:0 visibility:hidden transition: left var(--s-panel-ms) ease, transform var(--s-panel-ms) ease-out, opacity var(--s-panel-ms) linear, visibility var(--s-panel-ms);","&.s-panel-hidden":"transform: translateX(-8cqw);","&.s-panel-parked":"transform: translateX(8cqw);"},".s-panel > .s-content":"flex:1 min-height:0 overflow-y:auto overflow-x:hidden p:$3",".s-panel-actions":"display:flex align-items:center justify-content:flex-end gap:$1 flex-shrink:0 padding: $3 $3 0;",".s-crumbs > .s-strip-row":"gap:$m1",".s-crumb":{"&":"flex: 1 0 4rem; font-size:0.85em line-height:1.5 fg:$s-muted text-decoration:none white-space:nowrap max-width:max-content overflow:hidden text-overflow:ellipsis transition: color 0.12s;","&.s-crumb-on":"font-weight:600 fg:$s-text","a&:hover":"filter:none color: color-mix(in lab, $s-primary 33%, $s-text);","svg.s-crumb-pin":"vertical-align:-0.12em margin-right:0.3em opacity:0.8 fill:currentColor","svg.s-crumb-unsaved":"vertical-align:0.08em margin-right:0.3em fill:currentColor"},"svg.s-crumb-sep":"flex-shrink:0 opacity:0.4",".s-main.s-shell-snap .s-panel":"transition:none",".s-panel-loading":{"&":"position:absolute inset:0 display:flex align-items:center justify-content:center gap:$1 pointer-events:none",i:"width:0.5rem height:0.5rem r:50% background:$s-muted opacity:0.45 animation: s-panel-pulse 1s ease-in-out infinite;","i:nth-child(2)":"animation-delay:0.15s","i:nth-child(3)":"animation-delay:0.3s"},"@keyframes s-panel-pulse":{"0%, 100%":"opacity:0.25 transform:scale(0.8)","50%":"opacity:0.7 transform:scale(1)"}});var S1=!1,v1=class{[t2]=!0;compiled;ancestors;opts;$state=l.proxy({live:[],focus:0});$open=l.proxy({});nextOrder=0;containerEl;geom;lastGeom;layoutQueued=!1;timers=new Set;intent=null;settling=null;lastSeen=null;queued=null;constructor(a){if(S1)throw new Error("Staffa: only one routed S.main() (one with `routes`) can be active at a time");S1=!0,this.opts=a,this.compiled=Object.entries(a.routes).map(([h,e])=>({...a2(h),draw:e})),this.ancestors=Object.entries(a.ancestors??{}).filter(h=>h[1]!=null).map(([h,e])=>({...a2(h),fn:e})),l(()=>{let h=this.computeTarget(),e={...w.current.search},p=w.current.hash;l.peek(()=>{let r=this.lastSeen;if(r&&r.path!==w.current.path){let d=this.$state.live.find(o=>o.path===r.path);d&&(d.search=r.search,d.hash=r.hash)}this.lastSeen={path:w.current.path,search:e,hash:p},this.propose(h),Array.isArray(w.current.state.panels)||Object.assign(w.current.state,this.stateFor({stack:this.paths(),focus:this.$state.focus}))})}),this.interceptLinks(),this.watchTitle(),this.guardTabClose(),l.clean(()=>{for(let h of this.timers)clearTimeout(h);this.timers.clear(),this.queued?.settle(!1),this.queued=null,S1=!1})}resolve(a){let h=r1(a);for(let e of this.compiled){let p=$1(e,h);if(p)return{draw:e.draw,params:p}}return{draw:this.opts.notFound??X2,params:{}}}matches(a){let h=r1(a);return this.compiled.some(e=>$1(e,h)!=null)}deriveStack(a){let h=T(a),e=this.askAncestors(h),p=e?e.map(T):this.prefixesOf(h),r=[];for(let d of p)d!==h&&!r.includes(d)&&this.matches(d)&&r.push(d);return r.push(h),r}askAncestors(a){let h=r1(a);for(let e of this.ancestors){let p=$1(e,h);if(p)return e.fn(p,a)??void 0}}prefixesOf(a){let h=r1(a),e=[];for(let p=1;p<h.length;p++)e.push("/"+h.slice(0,p).join("/"));return e}pinnedIn(a,h){return a.filter(e=>h.includes(e)?!1:this.$state.live.find(p=>p.path===e)?.$panel.pinned===!0)}unsavedAt(a){return this.$state.live.find(h=>h.path===a)?.$panel.unsaved===!0}targetFor(a,h){let e=Array.isArray(h?.panels)?h.panels.map(String):null;if(e){let p=Array.isArray(h.parked)?h.parked.map(String):[],r=T(a),d=new Set([r]),o=s=>s.map(T).filter(f=>!d.has(f)&&!!d.add(f)),c=o(e);return{stack:[...c,r,...o(p)],focus:c.length}}return l.peek(()=>{let p=this.deriveStack(a).slice(0,-1),r=[...p,...this.pinnedIn(this.paths(),[...p,T(a)]),T(a)];return{stack:r,focus:r.length-1}})}computeTarget(){return this.targetFor(w.current.path,w.current.state)}paths(){return this.$state.live.map(a=>a.path)}propose(a){let h=this.$state.live.filter(e=>!a.stack.includes(e.path)&&e.$panel.unsaved).map(e=>e.path);h.length&&(a={stack:[...a.stack,...h],focus:a.focus}),!(W2(this.paths(),a.stack)&&a.focus===this.$state.focus)&&this.commit(a,w.current.nav)}commit(a,h){this.geom=void 0;let e=w.current.state.pinned,p=new Set(Array.isArray(e)?e.map(String):[]),r=new Map(this.$state.live.map(o=>[o.path,o])),d=[];for(let o of a.stack){let c=r.get(o);if(c){r.delete(o),d.push(c);continue}let s=this.createEntry(o,d.length<=a.focus,p.has(o));h!=="load"&&h!=="back"&&(s.enter=!0),d.push(s),this.$open[o]=s}for(let o of r.values())this.beginClose(o);this.$state.live=d,this.$state.focus=Math.min(a.focus,d.length-1),this.scheduleLayout()}createEntry(a,h,e){let{draw:p,params:r}=this.resolve(a),d={[t2]:!0,order:this.nextOrder++,path:a,draw:p,$ui:l.proxy({holding:!1}),maxWidth:"full",width:0};return d.$panel=l.proxy({stack:this,params:r,path:a,width:0,visible:h,pinned:e||void 0,close:()=>this.closePath(d.path),open:(o,c)=>this.navigate(o,{from:d.path,how:c})}),d}beginClose(a){a.closing=!0,a.$panel.visible=!1,a.el&&(a.el.style.zIndex=String(h2*this.$state.live.indexOf(a))),delete this.$open[a.path]}playExit(a,h){if(!a.closing){h.remove();return}h.classList.add("s-panel-closing"),h.setAttribute("inert","");let e=()=>{clearTimeout(p),this.timers.delete(p),h.remove()};h.addEventListener("transitionend",r=>{r.target===h&&r.propertyName==="opacity"&&e()});let p=setTimeout(e,e2+80);this.timers.add(p)}intended(){return this.intent??{stack:this.paths(),focus:this.$state.focus}}stateFor(a){return{panels:a.stack.slice(0,a.focus),parked:a.stack.slice(a.focus+1),pinned:this.pinnedPaths()}}pinnedPaths(){return this.$state.live.filter(a=>a.$panel.pinned).map(a=>a.path)}issue(a,h){return this.intent=a,this.settling?(this.queued?.settle(!1),new Promise(e=>{this.queued={run:h,settle:e}})):this.start(h)}start(a){let h=p=>{this.settling=null;let r=this.queued;return this.queued=null,p&&r?this.start(r.run).then(r.settle,()=>r.settle(!1)):(this.intent=null,r?.settle(!1)),p},e=Promise.resolve(a()).then(h,p=>(console.error(p),h(!1)));return this.settling=e,e}focusAt(a,h,e){let p=this.intended();if(a<0||a>=p.stack.length||a===p.focus)return Promise.resolve(!1);let r={stack:p.stack,focus:a},d=p.stack[a];return this.issue(r,()=>{let o=this.$state.live.find(c=>c.path===d);return w.go({path:d,search:h??o?.search,hash:e??o?.hash,state:this.stateFor(r)})})}back(){return l.peek(()=>{let a=this.intended();return a.focus===a.stack.length-1&&!this.unsavedAt(a.stack[a.focus])?this.closePath(a.stack[a.focus]??""):a.focus===0?Promise.resolve(!1):this.focusAt(a.focus-1)})}closePath(a){return l.peek(()=>{let h=this.intended(),e=h.stack.indexOf(T(a));if(e<0||h.stack.length<2||this.unsavedAt(h.stack[e]))return Promise.resolve(!1);let p=h.stack.filter((s,f)=>f!==e),r=e===h.focus?Math.max(0,e-1):h.focus-(e<h.focus?1:0),d={stack:p,focus:r};if(e===h.focus&&e===h.stack.length-1){let s=this.$state.live.find(v=>v.path===p[r]),f={};s?.search&&(f.search=s.search),s?.hash&&(f.hash=s.hash);let n=p.filter(v=>this.$state.live.find(y=>y.path===v)?.$panel.pinned===!0);return this.issue(d,()=>Promise.resolve(w.back({path:p[r],state:{panels:p.slice(0,r),parked:[]}},f)).then(v=>(v&&(w.current.state.pinned=n),v)))}let o=p[r],c=o!==h.stack[h.focus];return this.issue(d,()=>{let s=c?this.$state.live.find(f=>f.path===o):void 0;return w.go({path:o,search:c?s?.search:{...w.current.search},hash:c?s?.hash:w.current.hash,state:this.stateFor(d)})})})}navigate(a,{from:h,how:e,beneath:p}={}){let r=e??this.opts.linkNavigation,d=r==="open"?null:h??null,o=r==="replace";return l.peek(()=>{let c;try{c=new URL(a,location.href)}catch{return Promise.resolve(!1)}let s=T(c.pathname),f=Object.fromEntries(new URLSearchParams(c.search)),n=c.hash,v=this.intended(),y=p?-1:v.stack.indexOf(s);if(y>=0&&y!==v.focus)return this.focusAt(y,c.search?f:void 0,n||void 0);if(y>=0)return c.search===location.search&&(c.hash||"")===(location.hash||"")?Promise.resolve(!0):this.issue(v,()=>w.go({path:s,search:f,hash:n,state:this.stateFor(v)}));let b=d==null?-1:v.stack.indexOf(d),A=p?p.map(T).filter((z,P,r2)=>z!==s&&r2.indexOf(z)===P):b<0?this.deriveStack(s).slice(0,-1):v.stack.slice(0,o?b:b+1),m=[...A,...this.pinnedIn(v.stack,[...A,s,o?d:null])],g={stack:[...m,s],focus:m.length};return this.issue(g,()=>w.go({path:s,search:f,hash:n,state:this.stateFor(g)}))})}pushPath(a,h){return l.peek(()=>{let e=this.intended();return this.navigate(a,{from:e.stack[e.focus],how:h?"replace":"push"})})}interceptLinks(){w.interceptLinks((a,h)=>{let e=h.getAttribute("data-panel")??void 0,p=h.closest(".s-panel"),r=p?this.$state.live.find(d=>d.el===p):h.closest(".s-panel-origin")?this.$state.live[this.$state.focus]:void 0;return this.navigate(a.href,{from:r?.path,how:e}),!0})}get currentPanel(){return this.$state.live[this.$state.focus]?.$panel}get panels(){return this.$state.live.map(a=>a.$panel)}get currentPanelIndex(){return this.$state.focus}pushPanel(a){return this.pushPath(a,!1)}replacePanel(a){return this.pushPath(a,!0)}openPanelStack(a,h){return this.navigate(a,{how:"open",beneath:h})}closePanel(a){return l.peek(()=>{let h=this.intended();return this.closePath(a??h.stack[h.focus]??"")})}setColumns(a){this.opts.columns!==a&&(this.opts.columns=a,this.scheduleLayout())}setLinkNavigation(a){this.opts.linkNavigation=a}setFullWidth(a){this.opts.fullWidth!==a&&(this.opts.fullWidth=a,this.scheduleLayout())}drawCrumbs(){l1({attrs:".s-crumbs role=navigation aria-label=Breadcrumbs",content:()=>{l(()=>{let a=this.panels.map(p=>p.path),h=this.currentPanelIndex,e;for(let p=0;p<a.length;p++){p&&W1({size:"0.85em",attrs:".s-crumb-sep"});let r=this.drawCrumb(a[p],p,p===h);p===h&&(e=r)}requestAnimationFrame(()=>{e&&M1(e)})})}})}drawCrumb(a,h,e){let p=this.$state.live[h];return l(e?"span.s-crumb aria-current=page":"a.s-crumb",()=>{e||l("href=",a),l(()=>{p?.$panel.visible&&l(".s-crumb-on")}),l(()=>{p?.$panel.unsaved&&B1({size:"0.45em",attrs:".s-crumb-unsaved"})}),l(()=>{p?.$panel.pinned&&y1({size:"0.85em",attrs:".s-crumb-pin"})}),l(()=>{l("#",p?.$panel.title??p?.$ui.fallback??(a.split("/").pop()||a))}),V1({items:[{label:"Open in new tab",icon:F1,click:()=>{window.open(a,"_blank","noopener")}},{label:"Copy link",icon:I1,click:()=>{G2(a)}},{separator:!0},{label:()=>{l(()=>{l("#",p?.$panel.pinned?"Unpin":"Pin")})},icon:()=>{l(()=>{(p?.$panel.pinned?U1:y1)()})},click:()=>{p&&this.togglePin(p)}},{label:"Close",icon:J,disabled:p?.$panel.unsaved===!0,click:()=>{this.closePath(a)}}]})})}togglePin(a){a.$panel.pinned=!a.$panel.pinned||void 0,w.current.state.pinned=this.pinnedPaths()}watchTitle(){let a=document.title;l(()=>{let h=this.$state.live[this.$state.focus],e=h?.$panel.title??h?.$ui.fallback,p=typeof this.opts.title=="string"?this.opts.title:void 0,r=this.$state.live.some(o=>o.$panel.unsaved),d=e&&p?`${e} \xB7 ${p}`:e||p;d&&(document.title=(r?"\u2022 ":"")+d)}),l.clean(()=>{document.title=a})}guardTabClose(){if(typeof window>"u")return;let a=!1,h=()=>{a=!0},e=p=>{a=!1;let r=this.$state.live.find(o=>o.$panel.unsaved);if(!r)return;p.preventDefault(),p.returnValue=!0;let d=r.path;setTimeout(()=>{if(a)return;let o=this.$state.live.find(c=>c.path===d);o&&!o.$panel.visible&&this.focusAt(this.intended().stack.indexOf(d))},0)};l(()=>{this.$state.live.some(p=>p.$panel.unsaved)&&(window.addEventListener("beforeunload",e),window.addEventListener("pagehide",h),l.clean(()=>{window.removeEventListener("beforeunload",e),window.removeEventListener("pagehide",h)}))})}drawColumns(){let a=l("div.s-panels role=main",()=>{this.containerEl=l(),l.onEach(this.$open,h=>this.drawPanel(h),h=>h.order)});if(typeof ResizeObserver<"u"){let h=new ResizeObserver(()=>this.layout());h.observe(a);let e=a.parentElement?.parentElement;e&&h.observe(e),l.clean(()=>h.disconnect())}l.clean(()=>{this.containerEl===a&&(this.containerEl=void 0)}),this.scheduleLayout()}drawPanel(a){let h;l(()=>{let e=a.$panel.maxWidth;a.maxWidth=e==="half"||e==="screen"?e:"full";let p=this.roomFor(a.maxWidth);p&&(a.width=p,l.peek(a.$panel,"width")!==p&&(a.$panel.width=p),h&&(h.style.width=`${p}px`,this.scheduleLayout()))}),h=l(`section.s-panel${a.width?` w:${a.width}px`:""}`,"destroy=",e=>this.playExit(a,e),()=>{l(()=>this.drawActions(a)),l("div.s-content",()=>{if(a.draw(a.$panel),w.persistScroll(a.path),l.peek(a.$panel,"title")==null){let e=N2(l());e&&l.peek(a.$ui,"fallback")!==e&&(a.$ui.fallback=e)}}),l(()=>{!a.$panel.loading||a.$ui.holding||l("div.s-panel-loading aria-hidden=true",()=>{l("i"),l("i"),l("i")})})}),a.el=h,a.placed=!1,h.style.transition="none",l.clean(()=>{a.el===h&&(a.el=void 0)}),l(()=>{a.$panel.loading,this.scheduleLayout()}),this.scheduleLayout()}drawActions(a){this.opts.$shell.narrow||a.$panel.actions==null||l("div.s-panel-actions",()=>x(a.$panel.actions))}scheduleLayout(){this.layoutQueued||(this.layoutQueued=!0,requestAnimationFrame(()=>{this.layoutQueued=!1,this.layout()}))}measure(){let a=this.containerEl,h=a?.parentElement,e=h?.parentElement;if(!a||!h||!e)return;let p=e.getBoundingClientRect().width;if(!p)return;let r=0;for(let s of h.children)s!==a&&(r+=s.getBoundingClientRect().width);let d=Math.max(0,p-r),o=Math.min(this.opts.fullWidth,d),c=o/2;return{total:p,chrome:r,half:c>=I2?c:o,full:o,screen:d}}geometry(){return this.geom??=this.measure()}roomFor(a){return this.geometry()?.[a]??0}layout(){let a=this.containerEl,h=a?.closest(".s-main");if(!a||!h)return;let e=this.$state.live,p=e.length;if(!p||e.some(m=>!m.el))return;this.geom=void 0;let r=this.geometry();if(!r)return;let d=this.opts.columns!=="single",o=this.lastGeom,c=o==null||o.total!==r.total||o.chrome!==r.chrome||o.full!==r.full;c&&(this.lastGeom=r,h.classList.add("s-shell-snap"));let s=m=>r[m.maxWidth],f=Math.min(this.$state.focus,p-1),n=f,v=s(e[f]);if(d)for(let m=f-1;m>=0;m--){let g=v+s(e[m]);if(g>r.screen)break;v=g,n=m}let y=Math.min(r.screen,Math.max(r.full,v));for(let m=n;m<=f;m++)e[m].width=s(e[m]);for(let m of e)m.width||(m.width=s(m));h.style.setProperty("--s-shell-w",`${r.chrome+y}px`);let b=[],A=0;for(let m=0;m<p;m++){let g=e[m],z=g.el,P=m>=n&&m<=f;U2(z,P?A:m>f?y:0,g.width,h2*m+1),g.$panel.visible!==P&&(g.$panel.visible=P),g.$panel.width!==g.width&&(g.$panel.width=g.width),P&&(A+=g.width),z.classList.toggle("s-panel-sep",P&&m>n),z.classList.toggle("s-panel-hidden",m<n),z.classList.toggle("s-panel-parked",m>f),z.toggleAttribute("inert",!P),!g.placed&&(b.push(g),!g.$panel.loading||g.holdDone?g.$ui.holding=!1:g.$ui.holding||(g.$ui.holding=!0,this.holdEnter(g)),g.enter&&P&&z.classList.add("s-panel-enter"))}(b.length||c)&&a.offsetWidth,c&&h.classList.remove("s-shell-snap");for(let m of b)m.$ui.holding||(m.el.style.transition="",m.el.classList.remove("s-panel-enter"),m.enter=!1,m.placed=!0)}holdEnter(a){let h=setTimeout(()=>{this.timers.delete(h),a.holdDone=!0,a.$ui.holding&&(a.$ui.holding=!1,this.scheduleLayout())},F2);this.timers.add(h)}};function U2(t,a,h,e){t.style.left=`${a}px`,t.style.width=`${h}px`,t.style.zIndex=String(e)}function W2(t,a){return t.length===a.length&&t.every((h,e)=>h===a[e])}function N2(t){let a=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(let h=a.nextNode();h;h=a.nextNode()){let e=h.textContent.trim();if(e)return e.length>48?`${e.slice(0,47).trimEnd()}\u2026`:e}}async function G2(t){let a=new URL(t,location.href).href;try{await navigator.clipboard.writeText(a),x1({message:"Link copied."})}catch{x1({message:"Couldn't copy the link.",type:"danger"})}}function X2(t){l("p fg:$s-muted",()=>l("#",`No panel at ${t.path}`))}var K2=200,E1=1080;i.insertGlobalCss({".s-main":{"&":"display:flex flex-direction:column min-height:100vh max-height:100vh container-type:inline-size","body > &":"margin: calc(-1 * $3)","> header":"border:0 border-bottom: 1px solid $s-faint; r:0 position:sticky top:0 z-index:10","> footer":"border-top: 1px solid $s-faint; fg:$s-muted","> header > .s-bar, > footer > .s-bar":"display:flex align-items:center width:100% margin-inline:auto gap:$3 padding: $2 $3;","> header .s-logo, > header .s-nav-trigger":"display:flex align-items:center flex-shrink:0","> header .s-nav-trigger":"margin-left:-0.375rem","> header .s-logo":"font-size:1.4em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent;","> header .s-titles":"display:flex flex-direction:column min-width:5rem flex: 0 1 auto;","> header .s-subtitle":"fg:$s-muted font-size:0.85em line-height:1.5 overflow:hidden text-overflow:ellipsis white-space:nowrap","> header .s-title":"font-weight:800 font-size:1.1em line-height:1.2 overflow:hidden text-overflow:ellipsis white-space:nowrap letter-spacing:-0.01em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent; width:fit-content max-width:100%","> header a.s-logo, > header a.s-title":"text-decoration:none filter:none cursor:pointer","> header .s-menu":"display:flex align-items:center justify-content:flex-end gap:$2 flex: 1 0.1 auto; min-width:0",".s-body":"flex:1 overflow:clip display:flex flex-direction:row min-height:0 justify-content:center position:relative",".s-body-inner":"flex:1 min-width:0 display:flex flex-direction:row min-height:0","&.s-nav-right .s-body-inner":"flex-direction:row-reverse",".s-nav-sep":"width:1px flex-shrink:0 align-self:stretch margin: 0.6rem 0; border:0 background: linear-gradient(to bottom, transparent, $s-faint 18%, $s-faint 82%, transparent);",".s-body main":"flex:1 min-width:0 min-height:0 overflow-x:hidden overflow-y:auto display:flex flex-direction:column transition: transform var(--s-panel-ms) ease;",".s-body main.s-slide-in":"transform: translateX(100%); transition:none",".s-body main > .s-content":"width:100% flex:1 p:$3",".s-body main.s-scroll-y":"margin-right:$3","&.s-routed > .s-body > .s-body-inner":"max-width: var(--s-shell-w, 100%); transition: max-width var(--s-panel-ms) ease;","&.s-routed.s-shell-snap > .s-body > .s-body-inner":"transition:none","&.s-routed > header > .s-bar, &.s-routed > footer > .s-bar":"max-width: calc(var(--s-nav-w) + var(--s-full-w))"},".s-nav-panel":{"&":"display:flex flex-direction:column overflow-y:auto flex-shrink:0 width: calc(var(--s-nav-w) - 1px); padding:$3 gap:$1"},".s-nav-page":{"&":"position:absolute inset:0 z-index:5 display:flex flex-direction:column overflow-y:auto overscroll-behavior:contain border:0 r:0 padding:$2 gap:$1 transition: transform var(--s-panel-ms) ease, visibility var(--s-panel-ms);","&.s-nav-page-off":"transform:translateX(-100%) pointer-events:none visibility:hidden",".s-menu-item":"padding: $2 $3; min-height:3rem font-size:1.05em gap:$3"},[`@container (max-width: ${d1}px)`]:{".s-main .s-nav-panel, .s-main .s-nav-sep":"display:none",".s-main > header > .s-bar":"gap:$1 padding: $1 $2;",".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0",".s-main .s-body main.s-scroll-y":"margin-right:0"}});function j2(t={}){let a=t.nav,h=t.navPosition??"left",e=i.proxy({open:!1}),p=i.proxy({narrow:typeof document<"u"&&document.documentElement.clientWidth<=d1}),r=t.routes;if(r!=null&&t.content!=null)throw new Error("Staffa: S.main() takes either `content` or `routes`, not both");let d=r?new v1({routes:r,notFound:t.notFound,ancestors:t.ancestors,title:t.title,fullWidth:E1,$shell:p}):null;d&&(i(()=>d.setColumns(t.columns)),i(()=>d.setLinkNavigation(t.linkNavigation)),i(()=>d.setFullWidth(t.fullWidth??E1)));let o=d&&t.home!==null?t.home??"/":null,c=d?null:t.maxWidth,s=i(`div.s-main${d?".s-routed":""}`,t.attrs,()=>{i(()=>i(`--s-full-w: ${t.fullWidth??E1}px`)),i(()=>{a==null||!a.items.length?i("--s-nav-w: 0px"):i(`.s-nav-${h}`,`--s-nav-w: ${t.navWidth??K2}px`)}),i(()=>{(d!=null||t.title!=null||t.subtitle!=null||t.logo!=null||t.menu!=null||a!=null&&a.items.length>0)&&i("header.s-s.neutral",t.topbarAttrs,()=>{i("div.s-bar",()=>{i(()=>{c!=null&&i("max-width:",c)}),i(()=>{if(p.narrow&&a!=null&&a.items.length){i("div.s-nav-trigger",()=>t0(a,e));return}t.logo!=null&&i(o!=null?"a.s-logo aria-label=Home":"div.s-logo",()=>{o!=null&&i("href=",o),x(t.logo)})}),i("div.s-titles",()=>{i(()=>{t.title!=null&&i(o!=null?"a.s-title":"div.s-title",()=>{o!=null&&i("href=",o),x(t.title)})}),Q2(t,d,a,p)}),i(()=>{let n=p.narrow?d?.currentPanel?.actions:void 0,v=n??t.menu;v!=null&&i(`div.s-menu${n!=null?".s-panel-origin":""}`,()=>x(v))})})})}),i("div.s-body",()=>{i("div.s-body-inner",()=>{i(()=>{c!=null&&i("max-width:",c)}),i(()=>{a==null||!a.items.length||(i(`nav.s-nav-panel.s-nav-${h}`,t.navAttrs,()=>{e1(a.items)}),i("div.s-nav-sep aria-hidden=true"))}),e0(t,d)}),i(()=>{a!=null&&a.items.length&&e.open&&a0(a,t.navPageAttrs,e,p)})}),i(()=>{t.footer!=null&&i("footer",()=>{i("div.s-bar",()=>{i(()=>{c!=null&&i("max-width:",c)}),x(t.footer)})})})});if(Y2(s,p),a!=null||d){let f=n=>{if(n.key!=="Escape"||n.defaultPrevented||C1()||i1())return;let v=s.querySelector(".s-nav-trigger button");if(e.open){n.preventDefault(),e.open=!1,v?.focus();return}if(d&&d.currentPanelIndex>0){n.preventDefault(),d.back();return}let y=s.querySelector(".s-nav-panel");if(y?.offsetParent!=null){let b=y.querySelector("[aria-current=page]")??y.querySelector(".s-menu-item:not([aria-disabled=true])");b&&(n.preventDefault(),b.focus());return}v&&(n.preventDefault(),v.click())};document.addEventListener("keydown",f),i.clean(()=>document.removeEventListener("keydown",f))}return d??void 0}var m1=null;function _2(){m1?.()}function Q2(t,a,h,e){i(()=>{if(t.subtitle!=null&&(a==null||J2(a,h,e))){i("div.s-subtitle",()=>x(t.subtitle));return}a?.drawCrumbs()})}function J2(t,a,h){return h.narrow||a==null||t.panels.length>1?!1:g1(a.items)}function Y2(t,a){if(typeof ResizeObserver>"u")return;let h=new ResizeObserver(e=>{let p=e[0]?.contentBoxSize?.[0],r=p?p.inlineSize:e[0]?.contentRect.width;r!=null&&(a.narrow=r<=d1)});h.observe(t),i.clean(()=>h.disconnect())}function t0(t,a){h1({icon:t.button?.icon??(()=>i(()=>(a.open?J:o1)())),ariaLabel:t.button?.ariaLabel??"Open navigation",attrs:t.button?.attrs,click:()=>{a.open=!a.open}})}function a0(t,a,h,e){let p=!1,r=()=>{p=!0,h.open=!1},d=i("nav.s-nav-page.s-s.neutral aria-label=Navigation create=s-nav-page-off destroy=s-nav-page-off",a,()=>e1(t.items,r));m1=r,i.clean(()=>{m1===r&&(m1=null)});let o=i.peek(O1,"path");i(()=>{O1.path!==o&&!H1(O1.path)&&r()});let c=d.closest(".s-main"),s=d.parentElement?.querySelector(":scope > .s-body-inner"),f=s?.querySelector(":scope > main");s?.setAttribute("inert",""),i(()=>{e.narrow||(h.open=!1)}),i.clean(()=>{s?.removeAttribute("inert"),p&&(f&&h0(f),c?.querySelector(".s-nav-trigger button")?.focus())}),requestAnimationFrame(()=>{document.body.contains(d)&&_(d,".s-menu-item[aria-current=page]")})}function h0(t){t.classList.add("s-slide-in"),t.offsetWidth,t.classList.remove("s-slide-in")}function e0(t,a){if(a){a.drawColumns();return}let h=i("main",()=>{i("div.s-content",t.contentAttrs,()=>{x(t.content)})});p0(h)}function p0(t){if(typeof ResizeObserver>"u")return;let a=()=>t.classList.toggle("s-scroll-y",t.offsetWidth>t.clientWidth),h=new ResizeObserver(a);h.observe(t),t.firstElementChild&&h.observe(t.firstElementChild),a(),i.clean(()=>h.disconnect())}import S from"aberdeen";S.insertGlobalCss({".s-select_wrap":{"&":"position:relative display:block",select:"w:100% cursor:pointer padding-right:2.2em; appearance:none","&::after":"content: '\u25BE'; position:absolute right:0.7em top:50%; transform: translateY(-50%); pointer-events:none fg:$s-muted font-size:0.85em"}});function r0(t){U(t,(a,h)=>{S("div.s-select_wrap",t.inputAttrs,()=>{S("select.s-input",()=>{Q(t,a,h),S("change=",e=>{t.bind&&(t.bind.value=e.target.value)}),S(()=>{let e=typeof t.options=="function"?t.options():t.options,p=t.bind?.value??"";t.placeholder!=null&&S("option",()=>{S("value= disabled=true hidden=true"),p||S("selected=true"),S("#",t.placeholder)});for(let r of e){let d=typeof r=="string"?{value:r,label:r}:{value:r.value,label:r.label??r.value};S("option",()=>{S("value=",d.value),d.value===p&&S("selected=true"),S("#",d.label)})}})})})})}import D from"aberdeen";D.insertGlobalCss({"textarea.s-input":"resize:vertical min-height:3em line-height:1.45","textarea.s-input.s-autoGrow":"resize:none min-height:2.5em overflow-y:hidden"});function d0(t={}){let a=t.autoGrow!==!1;U(t,(h,e)=>{let p=D("textarea.s-input",t.inputAttrs,()=>{a?(D(".s-autoGrow"),D("input=",r=>{p2(r.currentTarget),t.input&&t.input(r)})):(D("rows=",t.rows??4),D("resize:",t.resize??"vertical"),t.input&&D("input=",t.input)),t.placeholder!=null&&D("placeholder=",t.placeholder),t.value!=null&&!t.bind&&D("value=",t.value),t.change&&D("change=",t.change),Q(t,h,e,t.bind)});a&&requestAnimationFrame(()=>p2(p))})}function p2(t){t.style.height="auto",t.style.height=`${t.scrollHeight}px`}import R from"aberdeen";R.insertGlobalCss({".s-tt-tip":{"&":"position:fixed z-index:500 max-width:20rem w:max-content padding: 0.3em 0.65em; font-size:0.85em line-height:1.4 pointer-events:none"}});var Y=R.proxy(void 0),Z=null;typeof window<"u"&&window.addEventListener("scroll",()=>{Y.value=void 0},{capture:!0,passive:!0});function o0(t,a,h,e){let r=window.innerWidth,d=window.innerHeight,o=0,c=0;return e==="bottom"?(o=t.left+(t.width-a)/2,c=t.bottom+7,c+h>d-8&&(c=t.top-h-7)):e==="left"?(o=t.left-a-7,c=t.top+(t.height-h)/2,o<8&&(o=t.right+7)):e==="right"?(o=t.right+7,c=t.top+(t.height-h)/2,o+a>r-8&&(o=t.left-a-7)):(o=t.left+(t.width-a)/2,c=t.top-h-7,c<8&&(c=t.bottom+7)),{x:Math.max(8,Math.min(o,r-a-8)),y:Math.max(8,Math.min(c,d-h-8))}}function q1(){Z&&clearTimeout(Z),Z=setTimeout(()=>{Y.value=void 0,Z=null},100)}I(()=>{let t=Y.value;if(!t)return;let{opts:a,anchor:h}=t,e=a.placement??"top",p=R("div.s-tt-tip.s-s.neutral.shadow role=tooltip visibility:hidden",a.attrs,()=>{R("mouseenter=",()=>{Z&&(clearTimeout(Z),Z=null)}),R("mouseleave=",q1),x(a.tip)});requestAnimationFrame(()=>{if(!document.body.contains(p))return;let{x:r,y:d}=o0(h.getBoundingClientRect(),p.offsetWidth,p.offsetHeight,e);p.style.left=r+"px",p.style.top=d+"px",p.style.visibility=""})});function c0(t){let a=h=>{Z&&(clearTimeout(Z),Z=null),Y.value={opts:t,anchor:h.currentTarget}};R("mouseenter=",a),R("mouseleave=",q1),R("focusin=",a),R("focusout=",q1),R.clean(()=>{Y.value?.opts===t&&(Y.value=void 0)})}export{V1 as addContextMenu,c0 as addTooltip,z2 as alert,l2 as autocomplete,v2 as box,E as button,m2 as buttonChooser,G as buttonGroup,u2 as checkbox,V2 as closeFloatingMenu,_2 as closeNav,$2 as confirm,s1 as dialog,y2 as form,D1 as getDarkMode,h1 as iconButton,C1 as isDialogOpen,i1 as isFloatingMenuOpen,j2 as main,L2 as menu,C2 as menuButton,S2 as prompt,M1 as revealInStrip,l1 as scrollStrip,r0 as select,o2 as setDarkMode,A1 as showFloatingMenu,E2 as tabs,d0 as textarea,k1 as textline,x1 as toast};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "staffa",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "An opinionated component library for the Aberdeen reactive UI library.",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -253,6 +253,22 @@ themselves up with them.
253
253
 
254
254
  **Type:** `string`
255
255
 
256
+ ### mainOptions.fullWidth · member
257
+
258
+ How wide a `"full"` panel gets, in pixels — and with it the whole content
259
+ area, since a `"full"` fills it exactly. A `"half"` gets half of this, and
260
+ a `"screen"` ignores it and takes the window. Defaults to 1080; the window
261
+ caps it when there is less room than that. Routed mode only.
262
+
263
+ This plus `MainOptions.navWidth` is the app's standard page — see
264
+ there.
265
+
266
+ Live, like `MainOptions.columns`: pass a proxied options object (or
267
+ make this field a getter) and a change is adopted in one layout pass,
268
+ every panel keeping its state.
269
+
270
+ **Type:** `number`
271
+
256
272
  ### mainOptions.contentAttrs · member
257
273
 
258
274
  Aberdeen attr/style string applied to the content area.
@@ -291,6 +307,19 @@ chrome goes assumes they are one.
291
307
 
292
308
  **Type:** `"left" | "right"`
293
309
 
310
+ ### mainOptions.navWidth · member
311
+
312
+ How wide the nav sidebar column is, in pixels — its hairline included.
313
+ Defaults to 200.
314
+
315
+ Together with `MainOptions.fullWidth` this is the app's *standard
316
+ page*: the width the top bar and footer keep to, and the width the
317
+ columns settle back to. The defaults come to the familiar 1280px.
318
+
319
+ Live, like `MainOptions.fullWidth`.
320
+
321
+ **Type:** `number`
322
+
294
323
  ### mainOptions.navAttrs · member
295
324
 
296
325
  Aberdeen attr/style string applied to the sidebar nav panel.
package/skill/Panel.md CHANGED
@@ -93,13 +93,15 @@ The widest this panel can usefully be. Every panel must work at 360–540px,
93
93
  because that is what it gets when two columns fit; this says how much
94
94
  *more* it can take.
95
95
 
96
- - `"half"` — nothing more. Half the content area (360–540px), so a second
97
- column fits beside it. For lists and detail forms.
98
- - `"full"` (the default) — the whole content area, up to ~1100px.
96
+ - `"half"` — nothing more. Half the content area (360px up to half of
97
+ `MainOptions.fullWidth`), so a second column fits beside it. For
98
+ lists and detail forms.
99
+ - `"full"` (the default) — the whole content area, which is exactly
100
+ `MainOptions.fullWidth`: 1080px unless the app says otherwise.
99
101
  - `"screen"` — the whole window, unbounded: boards, wide tables, dense
100
102
  dashboards. While one is open the columns stretch to the screen edges
101
- instead of stopping at the standard 1280px page; the top bar and
102
- footer hold the standard width throughout.
103
+ instead of stopping at the standard page; the top bar and footer hold
104
+ the standard width throughout.
103
105
 
104
106
  Below the width two columns need, everything takes the content area
105
107
  whatever it asked for. Widths depend only on the window, never on what
package/skill/SKILL.md CHANGED
@@ -185,17 +185,19 @@ Navigations settle asynchronously (closes travel through the browser's history),
185
185
 
186
186
  Navigating faster than the shell can settle is fine: closing travels through the browser's history, so it takes a moment to land, and anything asked for in the meantime waits for it rather than being dropped. Two quick Escapes (or back gestures) peel two panels, each aimed at the stack the one before it was heading for.
187
187
 
188
- **Every panel must work at 360–540px**, because that is what it gets whenever two columns fit. `$panel.maxWidth` says how much *more* it can usefully take. The content area is the page, at most 1280px wide, minus the nav sidebar:
188
+ **Every panel must work at 360–540px**, because that is what it gets whenever two columns fit. `$panel.maxWidth` says how much *more* it can usefully take. The content area is what `S.main()`'s `fullWidth` says it is 1080px by default:
189
189
 
190
190
  | `maxWidth` | How wide the panel gets | Good for |
191
191
  | --- | --- | --- |
192
192
  | `"half"` | Half the content area: 360 to 540px. | lists, detail forms — anything that reads well at phone width |
193
- | `"full"` (default) | The whole content area: up to ~1100px. | ordinary screens; the safe default |
194
- | `"screen"` | The whole window, no upper limit: ~1750px on a 1920px screen. | boards, wide tables, dense dashboards |
193
+ | `"full"` (default) | The whole content area: up to 1080px. | ordinary screens; the safe default |
194
+ | `"screen"` | The whole window, no upper limit: ~1720px on a 1920px screen. | boards, wide tables, dense dashboards |
195
195
 
196
- Below the width two columns need, everything takes the whole content area whatever it asked for. Those numbers assume a nav sidebar of around 170px; without one, add that back. Nothing fits beside a `"full"` on a standard 1280px page, but on a wide enough window a `"half"` still can, and the page grows past 1280px to hold both.
196
+ Below the width two columns need, everything takes the whole content area whatever it asked for. Nothing fits beside a `"full"` on a standard page, but on a wide enough window a `"half"` still can, and the page grows to hold both.
197
197
 
198
- A column's width depends only on the size of the window, never on what else is open. So opening or closing a panel never resizes the ones already on screen, and never reflows what someone was reading. A lone `"half"` leaves its other half empty, and that is exactly where the next one lands. When more columns fit than the standard 1280px page holds (three halves, say), the page itself grows, staying centred, to hold them — though the top bar and footer keep to the standard width, so the chrome holds still while the columns come and go.
198
+ The standard page is those 1080px plus the nav sidebar's 200 the 1280px an app is usually seen at, though neither figure is fixed: `S.main({ navWidth, fullWidth })` sets both, and everything above follows from them.
199
+
200
+ A column's width depends only on the size of the window, never on what else is open. So opening or closing a panel never resizes the ones already on screen, and never reflows what someone was reading. A lone `"half"` leaves its other half empty, and that is exactly where the next one lands. When more columns fit than the standard page holds (three halves, say), the page itself grows, staying centred, to hold them — though the top bar and footer keep to the standard width, so the chrome holds still while the columns come and go.
199
201
 
200
202
  Columns tile that area, separated by a hairline and no gutter — a column brings its own padding, so their contents stay comfortably apart regardless.
201
203
 
@@ -8,7 +8,7 @@ import { type MenuOptions, drawMenu, isFloatingMenuOpen, consumeBranchNav, anyCu
8
8
  import { menu as menuIcon, x as closeIcon } from "../icons.js";
9
9
  import { iconButton } from "./button.js";
10
10
  import { isDialogOpen } from "./dialog.js";
11
- import { PanelStackController, SHELL_PX, type PanelStack, type AncestorTable, type Panel, type RouteHandler, type RouteTable, type Routes } from "./panels.js";
11
+ import { PanelStackController, type PanelStack, type AncestorTable, type Panel, type RouteHandler, type RouteTable, type Routes } from "./panels.js";
12
12
 
13
13
  /** Options for {@link main}. */
14
14
  export interface MainOptions<R = Routes> {
@@ -229,6 +229,20 @@ export interface MainOptions<R = Routes> {
229
229
  * themselves up with them.
230
230
  */
231
231
  maxWidth?: string;
232
+ /**
233
+ * How wide a `"full"` panel gets, in pixels — and with it the whole content
234
+ * area, since a `"full"` fills it exactly. A `"half"` gets half of this, and
235
+ * a `"screen"` ignores it and takes the window. Defaults to 1080; the window
236
+ * caps it when there is less room than that. Routed mode only.
237
+ *
238
+ * This plus {@link MainOptions.navWidth} is the app's standard page — see
239
+ * there.
240
+ *
241
+ * Live, like {@link MainOptions.columns}: pass a proxied options object (or
242
+ * make this field a getter) and a change is adopted in one layout pass,
243
+ * every panel keeping its state.
244
+ */
245
+ fullWidth?: number;
232
246
  /** Aberdeen attr/style string applied to the content area. */
233
247
  contentAttrs?: Attributes;
234
248
  /** Aberdeen attr/style string applied to the top bar. */
@@ -255,12 +269,33 @@ export interface MainOptions<R = Routes> {
255
269
  * chrome goes assumes they are one.
256
270
  */
257
271
  navPosition?: "left" | "right";
272
+ /**
273
+ * How wide the nav sidebar column is, in pixels — its hairline included.
274
+ * Defaults to 200.
275
+ *
276
+ * Together with {@link MainOptions.fullWidth} this is the app's *standard
277
+ * page*: the width the top bar and footer keep to, and the width the
278
+ * columns settle back to. The defaults come to the familiar 1280px.
279
+ *
280
+ * Live, like {@link MainOptions.fullWidth}.
281
+ */
282
+ navWidth?: number;
258
283
  /** Aberdeen attr/style string applied to the sidebar nav panel. */
259
284
  navAttrs?: Attributes;
260
285
  /** Aberdeen attr/style string applied to the narrow-screen full-page nav. */
261
286
  navPageAttrs?: Attributes;
262
287
  }
263
288
 
289
+ /**
290
+ * The default nav column (hairline included) and the default width of a
291
+ * `"full"` panel — see {@link MainOptions.navWidth} and
292
+ * {@link MainOptions.fullWidth}. Side by side they come to the 1280px page the
293
+ * shell is usually seen as, but that figure lives nowhere: the browser adds
294
+ * these two up, and an app that changes either simply gets a different page.
295
+ */
296
+ const NAV_W = 200;
297
+ const FULL_W = 1080;
298
+
264
299
  A.insertGlobalCss({
265
300
  ".s-main": {
266
301
  // container-type so @container queries below can respond to shell width.
@@ -342,7 +377,7 @@ A.insertGlobalCss({
342
377
  ".s-body main.s-scroll-y": "margin-right:$3",
343
378
  // Routed mode takes its width from the stack instead of from
344
379
  // `maxWidth`: the layout engine publishes the ensemble width (sidebar +
345
- // separator + content area) as --s-shell-w — the standard 1280px page
380
+ // separator + content area) as --s-shell-w — the standard page
346
381
  // normally, wider while the columns outgrow it (a "screen" page, or
347
382
  // extra columns fitting a wide window) — and the body row caps itself
348
383
  // to it, staying centred around the columns. Changing the custom
@@ -361,7 +396,7 @@ A.insertGlobalCss({
361
396
  // the columns grow. (Below the standard width the ensemble is simply
362
397
  // the window, which only a resize changes — so the bars never animate,
363
398
  // and take no part in the transition above.)
364
- [`&.s-routed > header > .s-bar, &.s-routed > footer > .s-bar`]: `max-width:${SHELL_PX}px`,
399
+ "&.s-routed > header > .s-bar, &.s-routed > footer > .s-bar": "max-width: calc(var(--s-nav-w) + var(--s-full-w))",
365
400
  },
366
401
  // Sidebar nav panel. Items reuse the shared `.s-menu-item` /
367
402
  // `.s-menu-sep` styles from menu.ts, so the sidebar and the floating
@@ -372,7 +407,10 @@ A.insertGlobalCss({
372
407
  // The generous horizontal padding is what keeps the rows clear of the content
373
408
  // separator on one side and the shell edge on the other; the vertical scroll
374
409
  // (overflow-y:auto, which also clips overflow-x) leaves no room to bleed past it.
375
- "&": "display:flex flex-direction:column overflow-y:auto flex-shrink:0 max-width:228px padding:$3 gap:$1",
410
+ // `--s-nav-w` measures the whole column, hairline included, so the panel
411
+ // itself gives that 1px back — and the app's two widths then add up to
412
+ // exactly the page the bars above and below keep to.
413
+ "&": "display:flex flex-direction:column overflow-y:auto flex-shrink:0 width: calc(var(--s-nav-w) - 1px); padding:$3 gap:$1",
376
414
  },
377
415
  // The narrow-screen nav: a full "panel" that slides in over the content from the
378
416
  // left, rather than a dropdown — on a phone a nav is a screenful of UI, not a
@@ -501,6 +539,9 @@ export function main<R extends RouteTable<R>>(opts: MainOptions<R> = {}): PanelS
501
539
  notFound: opts.notFound,
502
540
  ancestors: opts.ancestors,
503
541
  title: opts.title,
542
+ // Corrected below, and on every change, from the app's own option:
543
+ // read here it would subscribe the whole shell to it.
544
+ fullWidth: FULL_W,
504
545
  $shell,
505
546
  })
506
547
  : null;
@@ -512,6 +553,7 @@ export function main<R extends RouteTable<R>>(opts: MainOptions<R> = {}): PanelS
512
553
  // the new link default. Nothing else of the shell is touched.
513
554
  A(() => ctl.setColumns(opts.columns));
514
555
  A(() => ctl.setLinkNavigation(opts.linkNavigation));
556
+ A(() => ctl.setFullWidth(opts.fullWidth ?? FULL_W));
515
557
  }
516
558
  // Where the brand mark and the app's name link — or nowhere, when the app
517
559
  // said `home: null` (a title slot holding a control of its own, say).
@@ -521,12 +563,20 @@ export function main<R extends RouteTable<R>>(opts: MainOptions<R> = {}): PanelS
521
563
  const capWidth = ctl ? null : opts.maxWidth;
522
564
 
523
565
  const root = A(`div.s-main${ctl ? ".s-routed" : ""}`, opts.attrs, () => {
524
- // Which side the sidebar is on, as a class on the shell for the CSS above to
525
- // hang off. Its own scope (see `nav` above), so a nav appearing or emptying
526
- // out only retags the shell rather than redrawing it.
566
+ // The two widths the CSS above works from, and with them the standard page
567
+ // the bars keep to. Each sits in a scope of its own one that draws
568
+ // nothing, so re-running it is a single style write: an app that changes
569
+ // either on a proxied options object resizes the shell in place, panels
570
+ // and their state untouched.
571
+ A(() => A(`--s-full-w: ${opts.fullWidth ?? FULL_W}px`));
572
+ // `--s-nav-w` is the sidebar's whole column, and nothing at all when there
573
+ // is no sidebar to give it to — a shell without one lines its bars up with
574
+ // the content. This scope also tags the shell with the side the sidebar is
575
+ // on, for the CSS above to hang off (see `nav` above: reading `nav.items`
576
+ // here subscribes this scope alone, never the shell entire).
527
577
  A(() => {
528
- if (nav == null || !nav.items.length) return;
529
- A(`.s-nav-${navPos}`);
578
+ if (nav == null || !nav.items.length) A("--s-nav-w: 0px");
579
+ else A(`.s-nav-${navPos}`, `--s-nav-w: ${opts.navWidth ?? NAV_W}px`);
530
580
  });
531
581
 
532
582
  // Top bar: `[leading] [identity] …spacer… [trailing]`, where each slot's
@@ -175,13 +175,15 @@ export interface Panel<P = Record<string, string | number | string[]>> {
175
175
  * because that is what it gets when two columns fit; this says how much
176
176
  * *more* it can take.
177
177
  *
178
- * - `"half"` — nothing more. Half the content area (360–540px), so a second
179
- * column fits beside it. For lists and detail forms.
180
- * - `"full"` (the default) — the whole content area, up to ~1100px.
178
+ * - `"half"` — nothing more. Half the content area (360px up to half of
179
+ * {@link MainOptions.fullWidth}), so a second column fits beside it. For
180
+ * lists and detail forms.
181
+ * - `"full"` (the default) — the whole content area, which is exactly
182
+ * {@link MainOptions.fullWidth}: 1080px unless the app says otherwise.
181
183
  * - `"screen"` — the whole window, unbounded: boards, wide tables, dense
182
184
  * dashboards. While one is open the columns stretch to the screen edges
183
- * instead of stopping at the standard 1280px page; the top bar and
184
- * footer hold the standard width throughout.
185
+ * instead of stopping at the standard page; the top bar and footer hold
186
+ * the standard width throughout.
185
187
  *
186
188
  * Below the width two columns need, everything takes the content area
187
189
  * whatever it asked for. Widths depend only on the window, never on what
@@ -416,14 +418,6 @@ function matchRoute(r: { segs: Seg[] }, segments: string[]): Record<string, any>
416
418
  const PAGE_MS = 250;
417
419
  /** How long a freshly pushed `loading` panel holds its enter animation. */
418
420
  const LOADING_HOLD_MS = 300;
419
- /**
420
- * The standard page width: sidebar plus content area, capped by the window.
421
- * `"full"` fills the content-area part of this exactly; only a `"screen"`
422
- * page makes the shell grow past it. The top bar and footer keep to this
423
- * width even then (see main.ts), so the chrome holds still while the
424
- * columns stretch.
425
- */
426
- export const SHELL_PX = 1280;
427
421
  /** Don't pair smalls when half the content area would be narrower than this. */
428
422
  const PAIR_MIN_PX = 360;
429
423
  /**
@@ -685,7 +679,7 @@ interface Geometry {
685
679
  chrome: number;
686
680
  /** Half the standard content area, or all of it when a half would be too narrow. */
687
681
  half: number;
688
- /** The standard content area: the 1280px page minus the chrome. */
682
+ /** The standard content area: what the app asked a `"full"` panel to be. */
689
683
  full: number;
690
684
  /** Everything the window has beside the chrome, with no upper limit. */
691
685
  screen: number;
@@ -715,6 +709,8 @@ export interface PanelStackOptions {
715
709
  columns?: "auto" | "single";
716
710
  /** What a bare link does. See {@link MainOptions.linkNavigation}. */
717
711
  linkNavigation?: "push" | "replace" | "open";
712
+ /** How wide a `"full"` panel gets, in px. See {@link MainOptions.fullWidth}. */
713
+ fullWidth: number;
718
714
  /** The shell's own title, used as the suffix of `document.title`. */
719
715
  title?: unknown;
720
716
  /**
@@ -884,8 +880,8 @@ export class PanelStackController implements PanelStack {
884
880
  private containerEl?: HTMLElement;
885
881
  /** The shell's measurements, shared by everything drawn since they were taken. */
886
882
  private geom?: Geometry;
887
- /** The body width at the last layout; a change means a window resize → snap. */
888
- private lastBodyW = -1;
883
+ /** The measurements the last layout ran on; a change in them → snap. */
884
+ private lastGeom?: Geometry;
889
885
  private layoutQueued = false;
890
886
  private timers = new Set<ReturnType<typeof setTimeout>>();
891
887
  /** The arrangement the navigation in flight is heading for; see {@link intended}. */
@@ -1588,6 +1584,17 @@ export class PanelStackController implements PanelStack {
1588
1584
  this.opts.linkNavigation = mode;
1589
1585
  }
1590
1586
 
1587
+ /**
1588
+ * Adopt a changed `fullWidth`: one layout pass, nothing redrawn. A changed
1589
+ * `navWidth` needs no counterpart — resizing the sidebar resizes the column
1590
+ * region, which the layout engine is already observing.
1591
+ */
1592
+ setFullWidth(px: number): void {
1593
+ if (this.opts.fullWidth === px) return;
1594
+ this.opts.fullWidth = px;
1595
+ this.scheduleLayout();
1596
+ }
1597
+
1591
1598
  /**
1592
1599
  * The breadcrumb stack, drawn by `main()` into the top bar: every open
1593
1600
  * panel, oldest first, the ones on screen right now in bold, pinned ones
@@ -1914,25 +1921,21 @@ export class PanelStackController implements PanelStack {
1914
1921
  if (child !== container) chrome += child.getBoundingClientRect().width;
1915
1922
  }
1916
1923
 
1917
- // The standard panel is SHELL_PX wide, capped by the window; what it leaves
1918
- // beside the sidebar is the *standard* content area. Widths are a pure
1919
- // function of the window never of what else is open so a panel NEVER
1920
- // resizes because a neighbour came or went; only a window resize (the
1921
- // snap pass in `layout`) changes them:
1924
+ // What the window has beside the sidebar, and within that the *standard*
1925
+ // content area: the width the app gave a "full" panel, or all there is
1926
+ // when the window has less. Widths are a pure function of the window
1927
+ // never of what else is open so a panel NEVER resizes because a
1928
+ // neighbour came or went; only a window resize (the snap pass in
1929
+ // `layout`) changes them:
1922
1930
  // - "full" fills the standard content area exactly;
1923
1931
  // - "half" is half of it whenever that half is still a usable column, and
1924
1932
  // the whole of it on narrower screens;
1925
1933
  // - "screen" ignores the standard width and takes everything the window
1926
1934
  // has — which also means nothing ever fits beside it.
1927
- const full = Math.max(0, Math.min(SHELL_PX, total) - chrome);
1935
+ const screen = Math.max(0, total - chrome);
1936
+ const full = Math.min(this.opts.fullWidth, screen);
1928
1937
  const halved = full / 2;
1929
- return {
1930
- total,
1931
- chrome,
1932
- half: halved >= PAIR_MIN_PX ? halved : full,
1933
- full,
1934
- screen: Math.max(0, total - chrome),
1935
- };
1938
+ return { total, chrome, half: halved >= PAIR_MIN_PX ? halved : full, full, screen };
1936
1939
  }
1937
1940
 
1938
1941
  /**
@@ -1979,13 +1982,16 @@ export class PanelStackController implements PanelStack {
1979
1982
 
1980
1983
  const stacking = this.opts.columns !== "single";
1981
1984
 
1982
- // A window resize (or the very first pass) must be adopted instantly —
1983
- // geometry tracking the window through a 450ms transition reads as lag,
1984
- // and a shell animating itself into place on load reads as a glitch.
1985
+ // A window resize or the app resizing the shell itself, by changing
1986
+ // `navWidth` or `fullWidth` must be adopted instantly: geometry tracking
1987
+ // the window through a 450ms transition reads as lag, and a shell
1988
+ // animating itself into place on its first pass reads as a glitch. Only
1989
+ // what a *panel* did is worth animating, and none of those three are.
1985
1990
  // `.s-shell-snap` suppresses every standing transition for this one pass.
1986
- const snap = this.lastBodyW !== geom.total;
1991
+ const was = this.lastGeom;
1992
+ const snap = was == null || was.total !== geom.total || was.chrome !== geom.chrome || was.full !== geom.full;
1987
1993
  if (snap) {
1988
- this.lastBodyW = geom.total;
1994
+ this.lastGeom = geom;
1989
1995
  shell.classList.add("s-shell-snap");
1990
1996
  }
1991
1997
 
@@ -2009,7 +2015,7 @@ export class PanelStackController implements PanelStack {
2009
2015
  // The content area holds the run, but is never smaller than the standard
2010
2016
  // panel (a lone small leaves its other half open — which is exactly where
2011
2017
  // the next small lands, without anything on screen moving) and never
2012
- // wider than the window. So the panel is the familiar 1280px until extra
2018
+ // wider than the window. So the page holds its standard width until extra
2013
2019
  // columns genuinely fit, and stretches — centred — to hold the ones that
2014
2020
  // do; with a "screen" up that's the window's edges.
2015
2021
  const area = Math.min(geom.screen, Math.max(geom.full, runSum));