@kanyun-ai-infra/band-plugin-react 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, Ref, MouseEvent } from 'react';
3
- import { MemberView } from '@kanyun-ai-infra/band-plugin-sdk';
3
+ import { MemberView, PeopleApi } from '@kanyun-ai-infra/band-plugin-sdk';
4
4
 
5
5
  /**
6
6
  * 一行错误提示:操作失败时显示在面板里。`children` 为空(null、undefined、空串、false)时什么也不渲染。
@@ -209,6 +209,24 @@ declare function SettingsSingle({ label, children }: {
209
209
  declare function SettingsChoices({ children }: {
210
210
  children: ReactNode;
211
211
  }): react.JSX.Element;
212
+ /** 起点选项块的一项:标题加一句说明。 */
213
+ interface SettingsPick<T extends string> {
214
+ value: T;
215
+ label: ReactNode;
216
+ line?: ReactNode;
217
+ }
218
+ /**
219
+ * 选项块(单选):一排块,每块一句标题、一句说明,选中的块 `--accent-soft` 底加 2px `--accent` 内描边;
220
+ * 用在「先选类型,下面再填该填的字段」的表单最前面(设置体系 §4.1;新建工坊的「从哪开始」)。
221
+ * 单选按钮藏起来(`.sr-only`),块本身是 `label`,键盘方向键照原生单选走。≤599 宽一列。
222
+ */
223
+ declare function SettingsPicks<T extends string>({ label, value, onChange, options, disabled, }: {
224
+ label: ReactNode;
225
+ value: T;
226
+ onChange: (value: T) => void;
227
+ options: readonly SettingsPick<T>[];
228
+ disabled?: boolean;
229
+ }): react.JSX.Element;
212
230
  /** 危险操作区:只在详情页最下面,每项一行(动作 + 后果一句 + 按钮),按钮是 `.btn.danger`(稿 §3.6)。 */
213
231
  declare function SettingsDanger({ children }: {
214
232
  children: ReactNode;
@@ -310,4 +328,281 @@ declare function SettingsSaveState({ saving, saved, failed, missing, }: {
310
328
  missing?: ReactNode;
311
329
  }): react.JSX.Element;
312
330
 
313
- export { AgentAvatar, Avatar, BandMark, ErrorNote, Glyph, type GlyphKind, INSTRUMENTS, InfoNote, type Instrument, LogoLockup, PaneHeader, SettingsActions, SettingsBack, type SettingsBackTarget, SettingsChoices, SettingsDanger, SettingsDangerRow, SettingsDialog, SettingsEmpty, type SettingsFact, SettingsFacts, SettingsField, type SettingsFieldProps, SettingsForm, type SettingsGroup, SettingsHead, SettingsLayout, SettingsLoading, type SettingsNavItem, SettingsNoAccess, SettingsNotice, SettingsReadError, SettingsRow, SettingsRows, SettingsSaveState, SettingsSaved, SettingsSection, SettingsSingle, type SettingsTarget, WorkshopEmblem, WorkshopIcon, agentInstrument, avatarInitial, avatarTone, instrumentOf, memberOrder, settingsLinkHandler };
331
+ /** 下拉里的一项。`group` 相同的排在一段,段的顺序按它第一次出现的顺序。 */
332
+ interface ComboboxItem {
333
+ value: string;
334
+ label: string;
335
+ group?: string;
336
+ /** 行尾的补充说明(部门、类型),用等宽字体。 */
337
+ meta?: string;
338
+ /** label 之外用来搜索的文字(部门、拼音备注),不进占位提示。 */
339
+ keywords?: string;
340
+ }
341
+ /**
342
+ * 可搜索的单选 / 多选(样张 §2「Combobox」)。键盘:↑↓ 移动、回车选中、「空格」在多选里切换选中、
343
+ * Esc 关闭、输入过滤;退格在空输入时删掉最后一个已选。
344
+ *
345
+ * 空格只在查询为空时切换选中:查询里带了字时空格照常输入,否则「Wang Min」这种名字搜不了
346
+ * (样张只演示了空查询下的多选,这一点按能打字优先定)。
347
+ */
348
+ declare function Combobox({ label, items, value, onChange, multiple, placeholder, emptyText, onCreate, createLabel, disabled, }: {
349
+ /** 输入框的无障碍名,也是空结果那句「没有匹配的<label>」里的名字。 */
350
+ label: string;
351
+ items: readonly ComboboxItem[];
352
+ /** 受控:已选的值,按选中的先后。 */
353
+ value: readonly string[];
354
+ onChange(next: readonly string[]): void;
355
+ /** 多选:回车与空格切换选中、列表不关;单选:回车选中并关闭。 */
356
+ multiple?: boolean;
357
+ placeholder?: string;
358
+ /** 空结果那一行的整句,缺省「没有匹配的<label>」。 */
359
+ emptyText?: string;
360
+ /**
361
+ * 查询非空、且没有名字正好相同的候选时,列表末尾多一行「新建」。选中它时把这句查询交回调用方
362
+ * (建完由调用方把新值放进 `value`)。
363
+ */
364
+ onCreate?(name: string): void;
365
+ /** 「新建」那行的写法,缺省「新建「<查询>」」。 */
366
+ createLabel?(name: string): string;
367
+ disabled?: boolean;
368
+ }): react.JSX.Element;
369
+ /**
370
+ * 一段文字拆成标签:按逗号(半角、全角)、换行、制表符拆,去掉首尾空白与空串,**不去重**
371
+ * (重复要提示,不能悄悄吃掉)。纯函数,单测与 TagInput 共用。
372
+ */
373
+ declare function splitTags(text: string): string[];
374
+ /**
375
+ * 数组值(样张 §2「Tag Input」):值受控,回车或逗号确认一个,粘贴带分隔符时整段拆开;重复的值不加入,
376
+ * 已有的那个闪一下红底并在下面写一句(「「x」重复了,已跳过」,1.8 秒后退回);输入框空着时退格删最后一个。
377
+ *
378
+ * 输入法:回车、退格都经 `withImeGuard`——组字中选字的回车不能当成「加一个标签」。
379
+ */
380
+ declare function TagInput({ label, value, onChange, placeholder, hint, disabled, id, }: {
381
+ /** 输入框的无障碍名。 */
382
+ label: string;
383
+ /** 受控:标签,按加入的先后。 */
384
+ value: readonly string[];
385
+ onChange(next: readonly string[]): void;
386
+ placeholder?: string;
387
+ /** 常态那句说明(「粘贴「五年级, 分数」会拆成两个」);重复时换成提示,1.8 秒后退回这句。 */
388
+ hint?: string;
389
+ disabled?: boolean;
390
+ id?: string;
391
+ }): react.JSX.Element;
392
+ /** 筛选项:一段里的一个值。 */
393
+ interface FilterOption {
394
+ value: string;
395
+ label: string;
396
+ }
397
+ /** 一段筛选:`key` 是行数据里的字段名。 */
398
+ interface FilterGroup {
399
+ key: string;
400
+ label: string;
401
+ options: readonly FilterOption[];
402
+ }
403
+ /** 一行在各分组上的取值(`row[group.key]`)。 */
404
+ type FilterRow = Readonly<Record<string, string>>;
405
+ /** 已选:分组 key → 选中的值(段内是「或」)。 */
406
+ type FilterSelection = Readonly<Record<string, readonly string[]>>;
407
+ /**
408
+ * 计数(样张 §2「Filter Menu」的 faceted 口径):某个选项的计数 = 在**其他**分组的已选条件下还剩多少行,
409
+ * 也带自己这一段——和产物库的「勾了别的组,这一段的数跟着缩」同一口径。纯函数,单测与 FilterMenu 共用。
410
+ */
411
+ declare function facetedCount(rows: readonly FilterRow[], groups: readonly FilterGroup[], selection: FilterSelection, groupKey: string, value: string): number;
412
+ /** 按已选筛行:每组内是「或」,组之间是「且」。纯函数。 */
413
+ declare function filterRows(rows: readonly FilterRow[], groups: readonly FilterGroup[], selection: FilterSelection): readonly FilterRow[];
414
+ /**
415
+ * 分组筛选(样张 §2「Filter Menu」)。分组可折叠(组标题是按钮,`aria-expanded`),计数按当前其他分组
416
+ * 的已选算(`facetedCount`),已选的做成 chip 可单个移除,右端「清空」。值受控。
417
+ *
418
+ * 键盘:组标题与每个勾选框都在正常的 Tab 顺序里(勾选框是原生 `<input type="checkbox">`),空格切换;
419
+ * 点组标题只折叠/展开,不改筛选。
420
+ */
421
+ declare function FilterMenu({ groups, rows, value, onChange, emptyText, }: {
422
+ groups: readonly FilterGroup[];
423
+ /** 用来算计数的行(通常是未筛选的全量;传筛过的会让计数越筛越小)。 */
424
+ rows: readonly FilterRow[];
425
+ value: FilterSelection;
426
+ onChange(next: FilterSelection): void;
427
+ /** 一段里一个选项都没有时那一行,缺省「没有可筛的」。 */
428
+ emptyText?: string;
429
+ }): react.JSX.Element;
430
+
431
+ /**
432
+ * 页面里的 toast(backlog #5):刚做完一件事的即时回执。宿主(外壳)画唯一一层容器 `ToastHost`,
433
+ * 插件与锁定插件只 import 这里的 `toast()` 入队,不自己画容器——两个插件同时弹也落进同一摞,不会各画一层。
434
+ *
435
+ * 模块级 store 是有意为之:`@kanyun-ai-infra/band-plugin-react` 是宿主提供的共享模块,宿主与每个插件拿到同一个
436
+ * 实例;而每个插件各开一个 React root,React context 跨不过去,ctx 也没有这个能力(加它要改协议)。
437
+ *
438
+ * 规则照样张(docs/design/specimens/band-design-components.html §5,本卡按它实现):
439
+ * - 成功 4 秒自己收;鼠标停在上面时不收,移开后 2 秒再收;
440
+ * - 错误不自己走,要么点「重试」要么关掉(没给动作时容器补一个「关闭」);
441
+ * - 进行中做完在同一条里变成勾(用同一个 id 再调一次 `toast`),不新弹一条;
442
+ * - 同时最多三条,第四条挤掉最早的一条(进行中的先留着)。
443
+ *
444
+ * 模块级状态跟着页面活:测试要清干净用 `dismissAllToasts`。
445
+ */
446
+ type ToastKind = "ok" | "bad" | "busy";
447
+ /** toast 上的一个动作(错误一般是「重试」)。 */
448
+ interface ToastAction {
449
+ label: string;
450
+ onClick: () => void;
451
+ }
452
+ interface ToastOptions {
453
+ /** 缺省 `ok`。 */
454
+ kind?: ToastKind;
455
+ /** 一行说明。 */
456
+ text: string;
457
+ /** 第二行小字。 */
458
+ detail?: string;
459
+ /** 一个动作;错误的「重试」放这里。 */
460
+ action?: ToastAction;
461
+ /** 传已有的 id:改那一条(进行中做完变成勾),不新弹一条。 */
462
+ id?: string;
463
+ }
464
+ interface ToastItem {
465
+ id: string;
466
+ kind: ToastKind;
467
+ text: string;
468
+ detail?: string;
469
+ action?: ToastAction;
470
+ }
471
+ /** 弹一条;传 `id` 就是改那一条。返回它的 id。 */
472
+ declare function toast(opts: ToastOptions): string;
473
+ /** 收起一条(动作、Esc、关掉都走这里)。 */
474
+ declare function dismissToast(id: string): void;
475
+ /** 全部收掉(换身份、测试收尾)。 */
476
+ declare function dismissAllToasts(): void;
477
+
478
+ /** 宿主画的一次性容器;一页只有一个(`band-shell`)。插件调 `toast()`,不自己画。 */
479
+ declare function ToastHost(): react.JSX.Element;
480
+
481
+ interface ChainedPerson {
482
+ id: string;
483
+ /** 这个人所在部门的链;挂在多个部门时任取其一,判定只看是否在某部门之下。 */
484
+ chain?: string;
485
+ }
486
+ interface Blocked extends ChainedPerson {
487
+ reason: string;
488
+ }
489
+
490
+ /** 一个人。`id` 是 ldap;`path` 是部门路径(「研发中心 / 平台组」),只用来看清是谁。 */
491
+ interface PickerPerson {
492
+ id: string;
493
+ name: string;
494
+ path?: string;
495
+ /** 部门 id 链(「/」隔开,`1/5/9`),算部门勾选态用;推不出时没有。 */
496
+ chain?: string;
497
+ /** false:还没登录过 Band(名字从组织架构来)。不影响能不能选(owner 11-14),只在已选名单里标一句。 */
498
+ inBand?: boolean;
499
+ }
500
+ /** 一个部门。`count` 是含下级部门的总人数;`count` 与 `chain` 都有才画勾选框。 */
501
+ interface PickerOrg {
502
+ id: string;
503
+ name: string;
504
+ path?: string;
505
+ chain?: string;
506
+ count?: number;
507
+ }
508
+ /** 不能选的人:原因写在候选行上;带 `chain` 时从部门的可选人数里扣掉。 */
509
+ type BlockedPerson = Blocked;
510
+ /** 目录的一页:一层部门的下级部门与直属的人,或一次搜索的结果。 */
511
+ interface DirectoryPage {
512
+ orgs: readonly PickerOrg[];
513
+ people: readonly PickerPerson[];
514
+ /** 搜索结果被上游截断了:提示换个更准的词。 */
515
+ truncated?: boolean;
516
+ /** 组织架构读不到、退回了 Band 用户目录:写原因,弹层顶上一直显示。 */
517
+ fallback?: string;
518
+ }
519
+ /** 数据口。所有方法收 `signal`:换词、关弹层时取消上一次。 */
520
+ interface PersonDirectory {
521
+ /** 组织架构现在用不了时的原因(退回了 Band 用户目录):没搜之前也在弹层顶上显示。 */
522
+ unavailable?: string;
523
+ search(q: string, opts: {
524
+ signal: AbortSignal;
525
+ }): Promise<DirectoryPage>;
526
+ /** 按部门浏览;`null` 是根。没有这个方法就只能搜。 */
527
+ browse?(orgId: string | null, opts: {
528
+ signal: AbortSignal;
529
+ chain?: string;
530
+ }): Promise<DirectoryPage>;
531
+ /** 一个部门(含下级)的全部人,最多 `limit` 个;`total` 是真实总数。 */
532
+ members?(orgId: string, opts: {
533
+ signal: AbortSignal;
534
+ limit: number;
535
+ chain?: string;
536
+ }): Promise<{
537
+ people: readonly PickerPerson[];
538
+ total: number;
539
+ }>;
540
+ /** 粘贴多个 ldap 时按 ldap 批量解析;找不到的放 `missing`。 */
541
+ resolve?(ids: readonly string[], opts: {
542
+ signal: AbortSignal;
543
+ }): Promise<{
544
+ people: readonly PickerPerson[];
545
+ missing: readonly string[];
546
+ /** 只能认出一部分人的原因(组织架构读不到):写进提示,免得用户以为 ldap 写错了。 */
547
+ fallback?: string;
548
+ }>;
549
+ }
550
+ interface PersonSearchProps {
551
+ /** 输入框的无障碍名(「添加管理员」「加人」)。 */
552
+ label: string;
553
+ directory: PersonDirectory;
554
+ /** 已选的人:在候选里打勾(多选)或显示在输入框里(单选),不再重复加。 */
555
+ picked: readonly PickerPerson[];
556
+ /** 选中的人(单选一个;多选可能是整个部门或一次粘贴的一批,已按 ldap 去重)。 */
557
+ onPick(people: readonly PickerPerson[]): void;
558
+ /** 取消选中(多选里点已勾的人、取消整个部门;单选里点 ×)。 */
559
+ onUnpick?(ids: readonly string[]): void;
560
+ multiple?: boolean;
561
+ /** 还能再加几个人(名单上限减去已选);不给就不限。 */
562
+ room?: number;
563
+ /** 不能选的人与原因(「已经是管理员」)。 */
564
+ disabled?: readonly BlockedPerson[];
565
+ /** 目录里没有的 ldap 也能加(名字先写 ldap)。 */
566
+ allowUnknown?: boolean;
567
+ placeholder?: string;
568
+ /** 整个控件禁用(保存中)。 */
569
+ busy?: boolean;
570
+ /** 根的名字(浏览时路径的第一段)。 */
571
+ rootLabel?: string;
572
+ /**
573
+ * 取到一个部门的全员时,把带部门链的人交给宿主(宿主拿来给名单里已有、还没链的人补链,省一次解析)。
574
+ * 包括已经在名单里、这次没有新加的人。
575
+ */
576
+ onLearn?(people: readonly PickerPerson[]): void;
577
+ /** 一开始就展开(样张、设计站用)。 */
578
+ defaultOpen?: boolean;
579
+ /** 一开始的搜索词(样张用)。 */
580
+ defaultQuery?: string;
581
+ /** 一开始浏览到哪(从根往下的部门,样张用)。 */
582
+ defaultTrail?: readonly PickerOrg[];
583
+ }
584
+ /** 搜索框 + 弹层:搜人、按部门逐级进入、勾整个部门、粘贴多个 ldap。 */
585
+ declare function PersonSearch({ label, directory, picked, onPick, onUnpick, multiple, room, disabled, allowUnknown, placeholder, busy, rootLabel, onLearn, defaultOpen, defaultQuery, defaultTrail, }: PersonSearchProps): react.JSX.Element;
586
+ interface PersonPickerProps extends Omit<PersonSearchProps, "picked" | "onPick" | "onUnpick" | "room" | "multiple"> {
587
+ /** 受控:名单上的人,按加入先后。 */
588
+ value: readonly PickerPerson[];
589
+ onChange(next: readonly PickerPerson[]): void;
590
+ /** 名单上限(同服务端)。 */
591
+ max?: number;
592
+ /** 只读:只列名单,没有加人和移出。 */
593
+ readOnly?: boolean;
594
+ /** 移出前在行内再确认一次(改动即时生效的名单用;有「保存」的表单不用)。 */
595
+ confirmRemove?: boolean;
596
+ /** 名单为空时的一句话。 */
597
+ emptyText?: string;
598
+ /** 这些人不能移出与原因(「创建人」);取消整个部门时也不动他们。 */
599
+ locked?: Readonly<Record<string, string>>;
600
+ /** 换掉下面的加人框(一次加一个、要另填角色再提交的地方:放单选的 `PersonSearch` 和提交按钮)。 */
601
+ addSlot?: ReactNode;
602
+ }
603
+ /** 名单 + 加人:已选的人一行一个(头像、名字、ldap、部门),可移出;下面是多选的 `PersonSearch`。 */
604
+ declare function PersonPicker({ value, onChange, max, readOnly, confirmRemove, emptyText, locked, addSlot, label, ...search }: PersonPickerProps): react.JSX.Element;
605
+ /** 把宿主的人员目录(`ctx.people`)接成选择器的数据口。取消信号不往下传:过期的结果组件自己丢掉。 */
606
+ declare function peopleDirectory(api: PeopleApi): PersonDirectory;
607
+
608
+ export { AgentAvatar, Avatar, BandMark, type BlockedPerson, Combobox, type ComboboxItem, type DirectoryPage, ErrorNote, type FilterGroup, FilterMenu, type FilterOption, type FilterRow, type FilterSelection, Glyph, type GlyphKind, INSTRUMENTS, InfoNote, type Instrument, LogoLockup, PaneHeader, type PersonDirectory, PersonPicker, type PersonPickerProps, PersonSearch, type PersonSearchProps, type PickerOrg, type PickerPerson, SettingsActions, SettingsBack, type SettingsBackTarget, SettingsChoices, SettingsDanger, SettingsDangerRow, SettingsDialog, SettingsEmpty, type SettingsFact, SettingsFacts, SettingsField, type SettingsFieldProps, SettingsForm, type SettingsGroup, SettingsHead, SettingsLayout, SettingsLoading, type SettingsNavItem, SettingsNoAccess, SettingsNotice, type SettingsPick, SettingsPicks, SettingsReadError, SettingsRow, SettingsRows, SettingsSaveState, SettingsSaved, SettingsSection, SettingsSingle, type SettingsTarget, TagInput, type ToastAction, ToastHost, type ToastItem, type ToastKind, type ToastOptions, WorkshopEmblem, WorkshopIcon, agentInstrument, avatarInitial, avatarTone, dismissAllToasts, dismissToast, facetedCount, filterRows, instrumentOf, memberOrder, peopleDirectory, settingsLinkHandler, splitTags, toast };
@@ -1,6 +1,6 @@
1
1
  /* band:inject-css */ /* @kanyun-ai-infra/band-plugin-react/components 的样式(scripts/tsup-inject-css.ts) */
2
2
  if (typeof document !== "undefined" && document.head) {
3
- const css = "/* src/ui.css */\n.band-plugin-react-error {\n font-size: var(--fs-ui);\n padding: 7px 10px;\n border-radius: 8px;\n background: var(--bad-soft);\n color: var(--bad);\n font-family: var(--mono);\n}\n.band-plugin-react-info {\n font-size: var(--fs-ui);\n padding: 7px 10px;\n border-radius: 8px;\n background: var(--panel);\n color: var(--muted);\n}\n.band-plugin-react-retry {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n}\n.band-plugin-react-failed {\n display: grid;\n gap: 6px;\n justify-items: start;\n margin: auto;\n padding: 8px 10px;\n border-radius: var(--r);\n background: var(--bad-soft);\n color: var(--bad);\n font-size: var(--fs-ui);\n}\n.band-plugin-react-failed p {\n margin: 0;\n}\n.band-plugin-react-failed-title {\n font-weight: 600;\n}\n.band-plugin-react-failed-reason {\n overflow-wrap: anywhere;\n}\n.band-plugin-react-pane-head {\n padding: 6px 14px 6px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-height: 36px;\n}\n.band-plugin-react-pane-title {\n margin: 0;\n font-size: var(--fs-dense);\n color: var(--muted);\n font-weight: 500;\n letter-spacing: 0.02em;\n}\n.band-plugin-react-wsicon {\n flex: none;\n display: block;\n}\n.band-plugin-react-wstile {\n --band-wstile: 16px;\n width: var(--band-wstile);\n height: var(--band-wstile);\n display: inline-grid;\n place-items: center;\n flex: none;\n border-radius: calc(var(--band-wstile) * 0.26);\n background: var(--panel);\n box-shadow: var(--shadow-card);\n}\n.band-plugin-react-wstile > :where(.band-plugin-react-wsicon) {\n width: 82%;\n height: 82%;\n}\n.band-plugin-react-wstile:where(.is-large) {\n border-radius: var(--r-xl);\n}\n.band-plugin-react-wstile:where(.is-large) > :where(.band-plugin-react-wsicon) {\n width: 76%;\n height: 76%;\n}\n.band-plugin-react-instrument {\n width: 72%;\n height: 72%;\n background: currentColor;\n -webkit-mask: var(--band-instrument) center / contain no-repeat;\n mask: var(--band-instrument) center / contain no-repeat;\n}\n.band-plugin-react-model-hint {\n margin: 0;\n}\n.band-plugin-react-target-repo {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin: 0;\n font-size: var(--fs-meta);\n line-height: 1.5;\n color: var(--muted);\n}\n.band-plugin-react-target-repo code {\n font-family: var(--mono);\n color: var(--ink);\n}\n.band-plugin-react-target-repo a {\n color: var(--accent-text);\n}\n.band-plugin-react-target-repo-request {\n align-self: flex-start;\n}\n.band-plugin-react-target-repo-err {\n color: var(--bad);\n}\n.band-plugin-react-first-delivery {\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex-basis: 100%;\n padding: 12px;\n border: 1px solid var(--rule);\n border-radius: var(--r-lg);\n background: var(--panel);\n margin: 0;\n min-width: 0;\n}\n.band-plugin-react-first-delivery-slot {\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: var(--fs-meta);\n}\n.band-plugin-react-first-delivery-pick,\n.band-plugin-react-first-delivery-file {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.band-plugin-react-first-delivery-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.band-plugin-react-first-delivery-name {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.band-plugin-react-first-delivery-size {\n color: var(--muted);\n}\n.band-plugin-react-first-delivery-missing {\n margin: 0;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-first-delivery .btn {\n align-self: flex-start;\n}\n.band-plugin-react-no-key {\n margin: 0;\n font-size: var(--fs-ui);\n color: var(--bad);\n}\n\n/* src/settings/settings.css */\n.band-sf {\n display: grid;\n grid-template-columns: 216px minmax(0, 1fr);\n min-height: 0;\n height: 100%;\n}\n.band-sf-nav {\n min-height: 0;\n overflow: auto;\n overscroll-behavior: contain;\n padding: 24px 12px 24px 20px;\n display: grid;\n gap: 16px;\n align-content: start;\n}\n.band-sf-head {\n display: grid;\n gap: 2px;\n min-width: 0;\n padding: 0 8px;\n}\n.band-sf-title {\n font-size: var(--fs-title);\n font-weight: 600;\n line-height: 1.3;\n}\n.band-sf-obj {\n font-size: var(--fs-ui);\n color: var(--muted);\n}\n.band-sf-grp {\n display: grid;\n gap: 1px;\n}\n.band-sf-grp > span {\n padding: 2px 8px;\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-grp a {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 8px;\n border-radius: var(--r);\n color: var(--ink);\n text-decoration: none;\n font-size: var(--fs-row);\n}\n.band-sf-grp a:hover {\n background: var(--fill);\n}\n.band-sf-grp a[aria-current=page] {\n background: var(--fill-2);\n font-weight: 500;\n}\n.band-sf-grp a:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-grp a .band-sf-chev {\n display: none;\n color: var(--muted);\n}\n.band-sf-scroll {\n min-height: 0;\n overflow: auto;\n overscroll-behavior: contain;\n}\n.band-sf-main {\n box-sizing: border-box;\n width: 100%;\n max-width: 824px;\n padding: 32px 32px 64px;\n display: grid;\n gap: 20px;\n align-content: start;\n}\n.band-sf-crumb {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n min-width: 0;\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-crumb-in {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n min-width: 0;\n}\n.band-sf-crumb-ws {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n white-space: nowrap;\n}\n.band-sf-crumb-ws > span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.band-sf-crumb a,\n.band-sf-crumb button {\n min-width: 0;\n border: 0;\n padding: 0;\n background: none;\n color: var(--muted);\n font: inherit;\n text-decoration: none;\n border-radius: 4px;\n overflow-wrap: anywhere;\n cursor: pointer;\n}\n.band-sf-crumb button {\n text-align: start;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.band-sf-crumb a:hover,\n.band-sf-crumb button:hover {\n color: var(--ink);\n}\n.band-sf-crumb a:focus-visible,\n.band-sf-crumb button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--accent);\n}\n.band-sf-back {\n display: inline-flex;\n align-self: start;\n justify-self: start;\n gap: 4px;\n color: var(--muted);\n text-decoration: none;\n font-size: var(--fs-ui);\n border-radius: 4px;\n}\n.band-sf-back-m {\n display: none;\n}\n.band-sf-back:hover {\n color: var(--ink);\n}\n.band-sf-back:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-h {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n}\n.band-sf-h > div {\n display: grid;\n gap: 4px;\n min-width: 0;\n}\n.band-sf-h h1 {\n margin: 0;\n font-size: var(--fs-h2);\n font-weight: 600;\n line-height: 1.3;\n}\n.band-sf-h p {\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-ui);\n max-width: 560px;\n}\n.band-sf-h-a {\n flex: none;\n}\n.band-sf-sec {\n display: grid;\n gap: 10px;\n}\n.band-sf-sec h2 {\n margin: 0;\n font-size: var(--fs-lead);\n font-weight: 600;\n}\n.band-sf-sec > p {\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-ui);\n}\n.band-sf-rows {\n display: grid;\n gap: 2px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.band-sf-row {\n position: relative;\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 2px 12px;\n align-items: center;\n padding: 10px 12px;\n margin: 0 -12px;\n border-radius: var(--r-lg);\n}\n.band-sf-row:hover {\n background: var(--fill);\n}\n.band-sf-row.is-new,\n.band-sf-row.is-new:hover {\n background: var(--ok-soft);\n}\n.band-sf-row-t {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px 8px;\n min-width: 0;\n}\n.band-sf-row-t b {\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n.band-sf-row-link {\n color: inherit;\n text-decoration: none;\n border-radius: 4px;\n}\n.band-sf-row-link::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: var(--r-lg);\n}\n.band-sf-row-a {\n position: relative;\n z-index: 1;\n}\n.band-sf-row-link:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-row-m {\n grid-column: 1;\n display: flex;\n flex-wrap: wrap;\n gap: 2px 14px;\n color: var(--muted);\n font-size: var(--fs-dense);\n min-width: 0;\n}\n.band-sf-row-m > span {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.band-sf-row-a {\n grid-column: 2;\n grid-row: 1 / span 2;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.band-sf-row-a .btn {\n position: relative;\n z-index: 1;\n}\n.band-sf-chev {\n color: var(--muted);\n}\n.band-sf-mono {\n font-family: var(--mono);\n font-size: 0.92em;\n}\n.band-sf-facts {\n display: grid;\n gap: 6px 16px;\n margin: 0;\n font-size: var(--fs-ui);\n}\n.band-sf-fact {\n display: grid;\n grid-template-columns: 112px minmax(0, 1fr);\n gap: 16px;\n}\n.band-sf-facts dt {\n color: var(--muted);\n}\n.band-sf-facts dd {\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.band-sf-dz {\n display: grid;\n gap: 10px;\n padding-top: 8px;\n}\n.band-sf-dz h2 {\n margin: 0;\n font-size: var(--fs-lead);\n font-weight: 600;\n}\n.band-sf-dz-r {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n.band-sf-dz-r > div {\n display: grid;\n gap: 2px;\n min-width: 0;\n}\n.band-sf-dz-r span {\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-dz-r .btn {\n flex: none;\n}\n.band-sf-empty,\n.band-sf .band-sf-empty.rest {\n display: grid;\n justify-items: start;\n text-align: start;\n gap: 10px;\n padding: 24px 0;\n max-width: 480px;\n}\n.band-sf-empty p {\n margin: 0;\n color: var(--muted);\n}\n.band-sf-error {\n min-width: 0;\n}\n.band-sf-load {\n padding: 40px 0;\n display: grid;\n justify-items: start;\n}\n.band-sf-ok {\n margin: 0;\n color: var(--ok);\n font-size: var(--fs-ui);\n}\n.band-sf-muted {\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-ui);\n}\n.band-sf-banner {\n margin: 0;\n padding: 10px 12px;\n border-radius: var(--r-lg);\n background: var(--fill);\n font-size: var(--fs-ui);\n}\n.band-sf-banner.is-warn {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--warn-soft);\n}\n.band-sf-form {\n display: grid;\n gap: 16px;\n max-width: 560px;\n min-width: 0;\n}\n.band-sf-form code {\n overflow-wrap: anywhere;\n}\n.band-sf-fld {\n display: grid;\n gap: 6px;\n min-width: 0;\n}\n.band-sf-fld > label {\n font-size: var(--fs-ui);\n font-weight: 500;\n}\n.band-sf-fld .field {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n}\n.band-sf-fld textarea.field {\n resize: vertical;\n line-height: 1.5;\n}\n.band-sf-req {\n margin-left: 6px;\n color: var(--muted);\n font-weight: 400;\n}\n.band-sf-optional {\n margin-left: 6px;\n color: var(--muted);\n font-weight: 400;\n}\n.band-sf-one {\n display: grid;\n gap: 10px;\n min-width: 0;\n}\n.band-sf-one fieldset {\n margin: 0;\n padding: 0;\n border: 0;\n min-width: 0;\n display: grid;\n gap: 10px;\n}\n.band-sf-choices {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n}\n.band-sf-hint {\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-hint a,\n.band-sf-fld .field-note a,\n.band-sf-muted a {\n color: var(--accent-text);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n.band-sf-err {\n margin: 0;\n color: var(--bad);\n font-size: var(--fs-ui);\n}\n.band-sf-fail {\n grid-column: 1 / -1;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n overflow-wrap: anywhere;\n}\n.band-sf-given {\n margin: 0;\n padding: 10px 12px;\n border-radius: var(--r-lg);\n background: var(--fill);\n font-size: var(--fs-ui);\n}\ndl.band-sf-given {\n display: grid;\n grid-template-columns: 56px minmax(0, 1fr);\n gap: 2px 12px;\n}\ndl.band-sf-given dt {\n color: var(--muted);\n}\ndl.band-sf-given dd {\n margin: 0;\n min-width: 0;\n}\ndl.band-sf-given p {\n grid-column: 1 / -1;\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-stepback {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n align-self: start;\n justify-self: start;\n padding: 0;\n border: 0;\n background: none;\n color: var(--muted);\n font: inherit;\n font-size: var(--fs-ui);\n cursor: pointer;\n border-radius: 4px;\n}\n.band-sf-stepback:hover {\n color: var(--ink);\n}\n.band-sf-stepback:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-acts {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n}\n.band-sf-acts-end {\n justify-content: flex-end;\n}\n.band-sf-state {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--muted);\n font-size: var(--fs-ui);\n}\n.band-settings-no-access {\n display: grid;\n gap: 10px;\n justify-items: start;\n max-width: 560px;\n padding-top: 8px;\n}\n.band-settings-no-access h2 {\n margin: 0;\n font-size: var(--fs-title);\n}\n.band-settings-no-access p {\n margin: 0;\n color: var(--muted);\n}\n.band-sf-dialog {\n box-sizing: border-box;\n width: min(460px, calc(100vw - 32px));\n max-height: calc(100dvh - 32px);\n overflow: auto;\n overscroll-behavior: contain;\n border: 0;\n border-radius: var(--r-xl);\n box-shadow: var(--shadow-pop);\n background: var(--panel);\n color: var(--ink);\n padding: 22px 24px;\n}\n.band-sf-dialog[open] {\n display: grid;\n gap: 14px;\n}\n.band-sf-dialog::backdrop {\n background: var(--scrim);\n}\n.band-sf-dialog h2 {\n margin: 0;\n font-size: var(--fs-title);\n overflow-wrap: anywhere;\n}\n.band-sf-dialog ul {\n margin: 0;\n padding-left: 18px;\n display: grid;\n gap: 4px;\n}\n.band-sf-row-x {\n grid-column: 1 / -1;\n margin-top: 8px;\n min-width: 0;\n}\n.band-sf-row.has-lead {\n grid-template-columns: auto minmax(0, 1fr) auto;\n}\n.band-sf-row-l {\n grid-column: 1;\n grid-row: 1 / span 2;\n display: flex;\n align-items: center;\n}\n.band-sf-row.has-lead .band-sf-row-t,\n.band-sf-row.has-lead .band-sf-row-m {\n grid-column: 2;\n}\n.band-sf-row.has-lead .band-sf-row-a {\n grid-column: 3;\n}\n@media (max-width: 600px) {\n .band-sf {\n grid-template-columns: minmax(0, 1fr);\n }\n .band-sf[data-view=page] .band-sf-nav {\n display: none;\n }\n .band-sf[data-view=index] .band-sf-scroll {\n display: none;\n }\n .band-sf-nav {\n padding: 16px;\n }\n .band-sf-grp a {\n padding: 10px 8px;\n font-size: var(--fs-body);\n }\n .band-sf-grp a .band-sf-chev {\n display: inline;\n }\n .band-sf-grp a[aria-current=page] {\n background: none;\n font-weight: 400;\n }\n .band-sf-main {\n padding: 12px 16px 48px;\n gap: 16px;\n }\n .band-sf-back-m {\n display: inline-flex;\n }\n .band-sf-h {\n display: grid;\n gap: 10px;\n }\n .band-sf-h-a .btn {\n justify-self: start;\n }\n .band-sf-row-a {\n grid-column: 1 / -1;\n grid-row: auto;\n justify-content: flex-start;\n margin-top: 4px;\n }\n .band-sf-row-a .band-sf-chev {\n margin-left: auto;\n }\n .band-sf-row-a:has(.band-sf-chev:only-child) {\n grid-column: 2;\n grid-row: 1 / span 2;\n justify-content: flex-end;\n margin-top: 0;\n }\n .band-sf-row > .band-sf-acts {\n grid-column: 1 / -1;\n justify-content: flex-start;\n margin-top: 4px;\n }\n .band-sf-fact {\n grid-template-columns: 88px minmax(0, 1fr);\n gap: 12px;\n }\n .band-sf-dz-r {\n display: grid;\n gap: 8px;\n }\n .band-sf-dz-r .btn {\n justify-self: start;\n }\n .band-sf-dialog {\n padding: 18px 16px;\n }\n .band-sf-row.has-lead .band-sf-row-a {\n grid-column: 2 / -1;\n }\n}\n";
3
+ const css = "/* src/ui.css */\n.band-plugin-react-error {\n font-size: var(--fs-ui);\n padding: 7px 10px;\n border-radius: 8px;\n background: var(--bad-soft);\n color: var(--bad);\n font-family: var(--mono);\n}\n.band-plugin-react-info {\n font-size: var(--fs-ui);\n padding: 7px 10px;\n border-radius: 8px;\n background: var(--panel);\n color: var(--muted);\n}\n.band-plugin-react-retry {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n}\n.band-plugin-react-failed {\n display: grid;\n gap: 6px;\n justify-items: start;\n margin: auto;\n padding: 8px 10px;\n border-radius: var(--r);\n background: var(--bad-soft);\n color: var(--bad);\n font-size: var(--fs-ui);\n}\n.band-plugin-react-failed p {\n margin: 0;\n}\n.band-plugin-react-failed-title {\n font-weight: 600;\n}\n.band-plugin-react-failed-reason {\n overflow-wrap: anywhere;\n}\n.band-plugin-react-pane-head {\n padding: 6px 14px 6px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-height: 36px;\n}\n.band-plugin-react-pane-title {\n margin: 0;\n font-size: var(--fs-dense);\n color: var(--muted);\n font-weight: 500;\n letter-spacing: 0.02em;\n}\n.band-plugin-react-wsicon {\n flex: none;\n display: block;\n}\n.band-plugin-react-wstile {\n --band-wstile: 16px;\n width: var(--band-wstile);\n height: var(--band-wstile);\n display: inline-grid;\n place-items: center;\n flex: none;\n border-radius: calc(var(--band-wstile) * 0.26);\n background: var(--panel);\n box-shadow: var(--shadow-card);\n}\n.band-plugin-react-wstile > :where(.band-plugin-react-wsicon) {\n width: 82%;\n height: 82%;\n}\n.band-plugin-react-wstile:where(.is-large) {\n border-radius: var(--r-xl);\n}\n.band-plugin-react-wstile:where(.is-large) > :where(.band-plugin-react-wsicon) {\n width: 76%;\n height: 76%;\n}\n.band-plugin-react-instrument {\n width: 72%;\n height: 72%;\n background: currentColor;\n -webkit-mask: var(--band-instrument) center / contain no-repeat;\n mask: var(--band-instrument) center / contain no-repeat;\n}\n.band-plugin-react-model-hint {\n margin: 0;\n}\n.band-plugin-react-target-repo {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin: 0;\n font-size: var(--fs-meta);\n line-height: 1.5;\n color: var(--muted);\n}\n.band-plugin-react-target-repo code {\n font-family: var(--mono);\n color: var(--ink);\n}\n.band-plugin-react-target-repo a {\n color: var(--accent-text);\n}\n.band-plugin-react-target-repo-request {\n align-self: flex-start;\n}\n.band-plugin-react-target-repo-err {\n color: var(--bad);\n}\n.band-plugin-react-first-delivery {\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex-basis: 100%;\n padding: 12px;\n border: 1px solid var(--rule);\n border-radius: var(--r-lg);\n background: var(--panel);\n margin: 0;\n min-width: 0;\n}\n.band-plugin-react-first-delivery-slot {\n display: flex;\n flex-direction: column;\n gap: 4px;\n font-size: var(--fs-meta);\n}\n.band-plugin-react-first-delivery-pick,\n.band-plugin-react-first-delivery-file {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.band-plugin-react-first-delivery-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.band-plugin-react-first-delivery-name {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.band-plugin-react-first-delivery-size {\n color: var(--muted);\n}\n.band-plugin-react-first-delivery-missing {\n margin: 0;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-first-delivery .btn {\n align-self: flex-start;\n}\n.band-plugin-react-no-key {\n margin: 0;\n font-size: var(--fs-ui);\n color: var(--bad);\n}\n\n/* src/settings/settings.css */\n.band-sf {\n display: grid;\n grid-template-columns: 216px minmax(0, 1fr);\n min-height: 0;\n height: 100%;\n}\n.band-sf-nav {\n min-height: 0;\n overflow: auto;\n overscroll-behavior: contain;\n padding: 24px 12px 24px 20px;\n display: grid;\n gap: 16px;\n align-content: start;\n}\n.band-sf-head {\n display: grid;\n gap: 2px;\n min-width: 0;\n padding: 0 8px;\n}\n.band-sf-title {\n font-size: var(--fs-title);\n font-weight: 600;\n line-height: 1.3;\n}\n.band-sf-obj {\n font-size: var(--fs-ui);\n color: var(--muted);\n}\n.band-sf-grp {\n display: grid;\n gap: 1px;\n}\n.band-sf-grp > span {\n padding: 2px 8px;\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-grp a {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 8px;\n border-radius: var(--r);\n color: var(--ink);\n text-decoration: none;\n font-size: var(--fs-row);\n}\n.band-sf-grp a:hover {\n background: var(--fill);\n}\n.band-sf-grp a[aria-current=page] {\n background: var(--fill-2);\n font-weight: 500;\n}\n.band-sf-grp a:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-grp a .band-sf-chev {\n display: none;\n color: var(--muted);\n}\n.band-sf-scroll {\n min-height: 0;\n overflow: auto;\n overscroll-behavior: contain;\n}\n.band-sf-main {\n box-sizing: border-box;\n width: 100%;\n max-width: 824px;\n padding: 32px 32px 64px;\n display: grid;\n gap: 20px;\n align-content: start;\n}\n.band-sf-crumb {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n min-width: 0;\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-crumb-in {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px;\n min-width: 0;\n}\n.band-sf-crumb-ws {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n white-space: nowrap;\n}\n.band-sf-crumb-ws > span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.band-sf-crumb a,\n.band-sf-crumb button {\n min-width: 0;\n border: 0;\n padding: 0;\n background: none;\n color: var(--muted);\n font: inherit;\n text-decoration: none;\n border-radius: 4px;\n overflow-wrap: anywhere;\n cursor: pointer;\n}\n.band-sf-crumb button {\n text-align: start;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.band-sf-crumb a:hover,\n.band-sf-crumb button:hover {\n color: var(--ink);\n}\n.band-sf-crumb a:focus-visible,\n.band-sf-crumb button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--accent);\n}\n.band-sf-back {\n display: inline-flex;\n align-self: start;\n justify-self: start;\n gap: 4px;\n color: var(--muted);\n text-decoration: none;\n font-size: var(--fs-ui);\n border-radius: 4px;\n}\n.band-sf-back-m {\n display: none;\n}\n.band-sf-back:hover {\n color: var(--ink);\n}\n.band-sf-back:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-h {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n}\n.band-sf-h > div {\n display: grid;\n gap: 4px;\n min-width: 0;\n}\n.band-sf-h h1 {\n margin: 0;\n font-size: var(--fs-h2);\n font-weight: 600;\n line-height: 1.3;\n}\n.band-sf-h p {\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-ui);\n max-width: 560px;\n}\n.band-sf-h-a {\n flex: none;\n}\n.band-sf-sec {\n display: grid;\n gap: 10px;\n}\n.band-sf-sec h2 {\n margin: 0;\n font-size: var(--fs-lead);\n font-weight: 600;\n}\n.band-sf-sec > p {\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-ui);\n}\n.band-sf-rows {\n display: grid;\n gap: 2px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.band-sf-row {\n position: relative;\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 2px 12px;\n align-items: center;\n padding: 10px 12px;\n margin: 0 -12px;\n border-radius: var(--r-lg);\n}\n.band-sf-row:hover {\n background: var(--fill);\n}\n.band-sf-row.is-new,\n.band-sf-row.is-new:hover {\n background: var(--ok-soft);\n}\n.band-sf-row-t {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 4px 8px;\n min-width: 0;\n}\n.band-sf-row-t b {\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n.band-sf-row-link {\n color: inherit;\n text-decoration: none;\n border-radius: 4px;\n}\n.band-sf-row-link::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: var(--r-lg);\n}\n.band-sf-row-a {\n position: relative;\n z-index: 1;\n}\n.band-sf-row-link:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-row-m {\n grid-column: 1;\n display: flex;\n flex-wrap: wrap;\n gap: 2px 14px;\n color: var(--muted);\n font-size: var(--fs-dense);\n min-width: 0;\n}\n.band-sf-row-m > span {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.band-sf-row-a {\n grid-column: 2;\n grid-row: 1 / span 2;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.band-sf-row-a .btn {\n position: relative;\n z-index: 1;\n}\n.band-sf-chev {\n color: var(--muted);\n}\n.band-sf-mono {\n font-family: var(--mono);\n font-size: 0.92em;\n}\n.band-sf-facts {\n display: grid;\n gap: 6px 16px;\n margin: 0;\n font-size: var(--fs-ui);\n}\n.band-sf-fact {\n display: grid;\n grid-template-columns: 112px minmax(0, 1fr);\n gap: 16px;\n}\n.band-sf-facts dt {\n color: var(--muted);\n}\n.band-sf-facts dd {\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.band-sf-dz {\n display: grid;\n gap: 10px;\n padding-top: 8px;\n}\n.band-sf-dz h2 {\n margin: 0;\n font-size: var(--fs-lead);\n font-weight: 600;\n}\n.band-sf-dz-r {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n.band-sf-dz-r > div {\n display: grid;\n gap: 2px;\n min-width: 0;\n}\n.band-sf-dz-r span {\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-dz-r .btn {\n flex: none;\n}\n.band-sf-empty,\n.band-sf .band-sf-empty.rest {\n display: grid;\n justify-items: start;\n text-align: start;\n gap: 10px;\n padding: 24px 0;\n max-width: 480px;\n}\n.band-sf-empty p {\n margin: 0;\n color: var(--muted);\n}\n.band-sf-error {\n min-width: 0;\n}\n.band-sf-load {\n padding: 40px 0;\n display: grid;\n justify-items: start;\n}\n.band-sf-ok {\n margin: 0;\n color: var(--ok);\n font-size: var(--fs-ui);\n}\n.band-sf-muted {\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-ui);\n}\n.band-sf-banner {\n margin: 0;\n padding: 10px 12px;\n border-radius: var(--r-lg);\n background: var(--fill);\n font-size: var(--fs-ui);\n}\n.band-sf-banner.is-warn {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--warn-soft);\n}\n.band-sf-form {\n display: grid;\n gap: 16px;\n max-width: 560px;\n min-width: 0;\n}\n.band-sf-form code {\n overflow-wrap: anywhere;\n}\n.band-sf-fld {\n display: grid;\n gap: 6px;\n min-width: 0;\n}\n.band-sf-fld > label {\n font-size: var(--fs-ui);\n font-weight: 500;\n}\n.band-sf-fld .field {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n}\n.band-sf-fld textarea.field {\n resize: vertical;\n line-height: 1.5;\n}\n.band-sf-req {\n margin-left: 6px;\n color: var(--muted);\n font-weight: 400;\n}\n.band-sf-optional {\n margin-left: 6px;\n color: var(--muted);\n font-weight: 400;\n}\n.band-sf-one {\n display: grid;\n gap: 10px;\n min-width: 0;\n}\n.band-sf-one fieldset {\n margin: 0;\n padding: 0;\n border: 0;\n min-width: 0;\n display: grid;\n gap: 10px;\n}\n.band-sf-choices {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n}\n.band-sf-blks-l {\n font-size: var(--fs-ui);\n font-weight: 600;\n}\n.band-sf-blks {\n display: grid;\n gap: 8px;\n}\n.band-sf-blks-3 {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n.band-sf-blks-2 {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n}\n.band-sf-blk {\n display: grid;\n gap: 4px;\n align-content: start;\n padding: 12px 14px;\n border-radius: var(--r-lg);\n background: var(--fill);\n cursor: pointer;\n min-width: 0;\n}\n.band-sf-blk > b {\n font-weight: 600;\n font-size: var(--fs-ui);\n overflow-wrap: anywhere;\n}\n.band-sf-blk > small {\n color: var(--muted);\n font-size: var(--fs-dense);\n overflow-wrap: anywhere;\n}\n.band-sf-blk.is-on {\n background: var(--accent-soft);\n box-shadow: inset 0 0 0 2px var(--accent);\n}\n.band-sf-blk.is-on > b {\n color: var(--accent-text);\n}\n.band-sf-blk:has(:focus-visible) {\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-blk:has(:disabled) {\n cursor: default;\n}\n@media (max-width: 600px) {\n .band-sf-blks-3,\n .band-sf-blks-2 {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n.band-sf-hint {\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-hint a,\n.band-sf-fld .field-note a,\n.band-sf-muted a {\n color: var(--accent-text);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n.band-sf-err {\n margin: 0;\n color: var(--bad);\n font-size: var(--fs-ui);\n}\n.band-sf-fail {\n grid-column: 1 / -1;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n overflow-wrap: anywhere;\n}\n.band-sf-given {\n margin: 0;\n padding: 10px 12px;\n border-radius: var(--r-lg);\n background: var(--fill);\n font-size: var(--fs-ui);\n}\ndl.band-sf-given {\n display: grid;\n grid-template-columns: 56px minmax(0, 1fr);\n gap: 2px 12px;\n}\ndl.band-sf-given dt {\n color: var(--muted);\n}\ndl.band-sf-given dd {\n margin: 0;\n min-width: 0;\n}\ndl.band-sf-given p {\n grid-column: 1 / -1;\n margin: 0;\n color: var(--muted);\n font-size: var(--fs-dense);\n}\n.band-sf-stepback {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n align-self: start;\n justify-self: start;\n padding: 0;\n border: 0;\n background: none;\n color: var(--muted);\n font: inherit;\n font-size: var(--fs-ui);\n cursor: pointer;\n border-radius: 4px;\n}\n.band-sf-stepback:hover {\n color: var(--ink);\n}\n.band-sf-stepback:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-sf-acts {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n}\n.band-sf-acts-end {\n justify-content: flex-end;\n}\n.band-sf-state {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--muted);\n font-size: var(--fs-ui);\n}\n.band-settings-no-access {\n display: grid;\n gap: 10px;\n justify-items: start;\n max-width: 560px;\n padding-top: 8px;\n}\n.band-settings-no-access h2 {\n margin: 0;\n font-size: var(--fs-title);\n}\n.band-settings-no-access p {\n margin: 0;\n color: var(--muted);\n}\n.band-sf-dialog {\n box-sizing: border-box;\n width: min(460px, calc(100vw - 32px));\n max-height: calc(100dvh - 32px);\n overflow: auto;\n overscroll-behavior: contain;\n border: 0;\n border-radius: var(--r-xl);\n box-shadow: var(--shadow-pop);\n background: var(--panel);\n color: var(--ink);\n padding: 22px 24px;\n}\n.band-sf-dialog[open] {\n display: grid;\n gap: 14px;\n}\n.band-sf-dialog::backdrop {\n background: var(--scrim);\n}\n.band-sf-dialog h2 {\n margin: 0;\n font-size: var(--fs-title);\n overflow-wrap: anywhere;\n}\n.band-sf-dialog ul {\n margin: 0;\n padding-left: 18px;\n display: grid;\n gap: 4px;\n}\n.band-sf-row-x {\n grid-column: 1 / -1;\n margin-top: 8px;\n min-width: 0;\n}\n.band-sf-row.has-lead {\n grid-template-columns: auto minmax(0, 1fr) auto;\n}\n.band-sf-row-l {\n grid-column: 1;\n grid-row: 1 / span 2;\n display: flex;\n align-items: center;\n}\n.band-sf-row.has-lead .band-sf-row-t,\n.band-sf-row.has-lead .band-sf-row-m {\n grid-column: 2;\n}\n.band-sf-row.has-lead .band-sf-row-a {\n grid-column: 3;\n}\n@media (max-width: 600px) {\n .band-sf {\n grid-template-columns: minmax(0, 1fr);\n }\n .band-sf[data-view=page] .band-sf-nav {\n display: none;\n }\n .band-sf[data-view=index] .band-sf-scroll {\n display: none;\n }\n .band-sf-nav {\n padding: 16px;\n }\n .band-sf-grp a {\n padding: 10px 8px;\n font-size: var(--fs-body);\n }\n .band-sf-grp a .band-sf-chev {\n display: inline;\n }\n .band-sf-grp a[aria-current=page] {\n background: none;\n font-weight: 400;\n }\n .band-sf-main {\n padding: 12px 16px 48px;\n gap: 16px;\n }\n .band-sf-back-m {\n display: inline-flex;\n }\n .band-sf-h {\n display: grid;\n gap: 10px;\n }\n .band-sf-h-a .btn {\n justify-self: start;\n }\n .band-sf-row-a {\n grid-column: 1 / -1;\n grid-row: auto;\n justify-content: flex-start;\n margin-top: 4px;\n }\n .band-sf-row-a .band-sf-chev {\n margin-left: auto;\n }\n .band-sf-row-a:has(.band-sf-chev:only-child) {\n grid-column: 2;\n grid-row: 1 / span 2;\n justify-content: flex-end;\n margin-top: 0;\n }\n .band-sf-row > .band-sf-acts {\n grid-column: 1 / -1;\n justify-content: flex-start;\n margin-top: 4px;\n }\n .band-sf-fact {\n grid-template-columns: 88px minmax(0, 1fr);\n gap: 12px;\n }\n .band-sf-dz-r {\n display: grid;\n gap: 8px;\n }\n .band-sf-dz-r .btn {\n justify-self: start;\n }\n .band-sf-dialog {\n padding: 18px 16px;\n }\n .band-sf-row.has-lead .band-sf-row-a {\n grid-column: 2 / -1;\n }\n}\n\n/* src/controls.css */\n.band-plugin-react-combo-field,\n.band-plugin-react-tags {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n align-items: center;\n padding: 5px 8px;\n border-radius: var(--r);\n background: var(--panel);\n box-shadow: inset 0 0 0 1px var(--control-edge);\n}\n.band-plugin-react-combo-field > :where(.field),\n.band-plugin-react-tags > :where(.field) {\n flex: 1 1 90px;\n min-width: 90px;\n width: auto;\n}\n.band-plugin-react-combo-picked {\n list-style: none;\n margin: 0 0 7px;\n padding: 0;\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n}\n.band-plugin-react-combo-chip,\n.band-plugin-react-filter-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 22px;\n padding: 0 4px 0 8px;\n border-radius: 999px;\n background: var(--fill-2);\n color: var(--ink);\n font-size: var(--fs-meta);\n white-space: nowrap;\n}\n.band-plugin-react-filter-chip {\n background: var(--accent-soft);\n color: var(--accent-text);\n}\n.band-plugin-react-combo-chip > button,\n.band-plugin-react-filter-chip > button {\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n line-height: 1;\n padding: 0 3px;\n border-radius: 999px;\n opacity: 0.85;\n}\n.band-plugin-react-combo-chip > button:where(:focus-visible),\n.band-plugin-react-filter-chip > button:where(:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n opacity: 1;\n}\n.band-plugin-react-combo-pop {\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 6px);\n z-index: var(--layer-pop);\n display: grid;\n gap: 1px;\n max-height: 236px;\n overflow: auto;\n overscroll-behavior: contain;\n padding: 5px;\n border-radius: var(--r-lg);\n background: var(--panel);\n box-shadow: var(--shadow-pop);\n}\n.band-plugin-react-combo-group {\n padding: 6px 8px 3px;\n font-size: var(--fs-badge);\n color: var(--muted);\n}\n.band-plugin-react-combo-opt {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 8px;\n border: 0;\n border-radius: var(--r-sm);\n background: none;\n color: var(--ink);\n font: inherit;\n font-size: var(--fs-row);\n text-align: left;\n}\n.band-plugin-react-combo-opt:where(.is-active) {\n background: var(--fill-2);\n}\n.band-plugin-react-combo-opt:where(:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-plugin-react-combo-label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.band-plugin-react-combo-label > mark {\n background: var(--accent-soft);\n color: var(--ink);\n border-radius: 2px;\n}\n.band-plugin-react-combo-meta {\n margin-left: auto;\n flex: none;\n font-family: var(--mono);\n font-size: var(--fs-badge);\n color: var(--muted);\n}\n.band-plugin-react-combo-plus {\n display: inline-grid;\n place-items: center;\n width: 20px;\n height: 20px;\n flex: none;\n border-radius: 50%;\n background: var(--fill-3);\n color: var(--muted);\n font-size: var(--fs-badge);\n}\n.band-plugin-react-combo-empty {\n padding: 8px;\n text-align: center;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 22px;\n padding: 0 4px 0 8px;\n border-radius: 999px;\n background: var(--fill-2);\n color: var(--ink);\n font-size: var(--fs-meta);\n white-space: nowrap;\n}\n.band-plugin-react-tag:where([data-dup]) {\n background: var(--bad-soft);\n color: var(--bad);\n}\n.band-plugin-react-tag > button {\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n line-height: 1;\n padding: 0 3px;\n border-radius: 999px;\n opacity: 0.85;\n}\n.band-plugin-react-tag > button:where(:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n opacity: 1;\n}\n.band-plugin-react-tag-hint {\n margin: 5px 0 0;\n min-height: 16px;\n font-size: var(--fs-badge);\n color: var(--muted);\n}\n.band-plugin-react-tag-hint:where([data-err]) {\n color: var(--bad);\n}\n.band-plugin-react-filter {\n display: grid;\n gap: 2px;\n min-width: 0;\n}\n.band-plugin-react-filter-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n margin-bottom: 8px;\n}\n.band-plugin-react-filter-clear {\n margin-left: auto;\n border: 0;\n background: none;\n padding: 0 2px;\n color: var(--muted);\n font: inherit;\n font-size: var(--fs-meta);\n text-decoration: underline;\n}\n.band-plugin-react-filter-clear:where(:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n border-radius: 4px;\n}\n.band-plugin-react-filter-group {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 7px 8px 3px;\n border: 0;\n border-radius: var(--r-sm);\n background: none;\n color: var(--muted);\n font: inherit;\n font-size: var(--fs-badge);\n text-align: left;\n}\n.band-plugin-react-filter-group:where(:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n.band-plugin-react-filter-group::before {\n content: \"\\25b8\";\n width: 11px;\n flex: none;\n font-size: var(--fs-meta);\n line-height: 1;\n}\n.band-plugin-react-filter-group[aria-expanded=true]::before {\n content: \"\\25be\";\n}\n.band-plugin-react-filter-group-count {\n margin-left: auto;\n font-family: var(--mono);\n}\n.band-plugin-react-filter-opt {\n padding: 4px 8px;\n border-radius: var(--r-sm);\n}\n.band-plugin-react-filter-opt:where(:hover) {\n background: var(--fill);\n}\n.band-plugin-react-filter-count {\n margin-left: auto;\n font-family: var(--mono);\n font-size: var(--fs-badge);\n color: var(--muted);\n}\n.band-plugin-react-filter-empty {\n padding: 8px;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n\n/* src/toast/toast.css */\n.band-plugin-react-toast-stack {\n position: fixed;\n right: 20px;\n bottom: calc(60px + env(safe-area-inset-bottom, 0px));\n z-index: var(--layer-pop);\n width: min(340px, calc(100vw - 40px));\n display: grid;\n gap: 8px;\n}\n.band-plugin-react-toast {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr) auto;\n gap: 10px;\n align-items: center;\n padding: 10px 12px;\n border-radius: var(--r-lg);\n background: var(--panel);\n box-shadow: var(--shadow-pop);\n font-size: var(--fs-row);\n color: var(--ink);\n animation: band-plugin-react-toast-in var(--eighth) var(--ease);\n}\n@keyframes band-plugin-react-toast-in {\n from {\n opacity: 0;\n transform: translateY(6px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n}\n.band-plugin-react-toast-again {\n animation: none;\n}\n.band-plugin-react-toast-icon {\n width: 16px;\n height: 16px;\n display: grid;\n place-items: center;\n border-radius: 50%;\n font-size: 10px;\n color: var(--panel);\n}\n.band-plugin-react-toast-icon:where(.ok) {\n background: var(--ok);\n}\n.band-plugin-react-toast-icon:where(.bad) {\n background: var(--bad);\n}\n.band-plugin-react-toast-icon:where(.busy) {\n border: 1.6px solid var(--accent);\n border-top-color: transparent;\n color: transparent;\n background: none;\n animation: band-plugin-react-toast-spin 900ms linear infinite;\n}\n@keyframes band-plugin-react-toast-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.band-plugin-react-toast-text {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.band-plugin-react-toast-detail {\n display: block;\n color: var(--muted);\n font-size: var(--fs-meta);\n overflow-wrap: anywhere;\n}\n.band-plugin-react-toast-act {\n font-size: var(--fs-meta);\n color: var(--ink);\n background: none;\n border: 0;\n font-family: inherit;\n text-decoration: underline;\n padding: 2px 4px;\n border-radius: 4px;\n}\n.band-plugin-react-toast-act:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n@media (prefers-reduced-motion: reduce) {\n .band-plugin-react-toast,\n .band-plugin-react-toast-icon:where(.busy) {\n animation: none;\n }\n}\n\n/* src/person-picker.css */\n.band-plugin-react-pp-picker {\n display: grid;\n gap: 8px;\n min-width: 0;\n}\n.band-plugin-react-pp-people {\n list-style: none;\n margin: 0;\n padding: 0;\n display: grid;\n gap: 2px;\n}\n.band-plugin-react-pp-person {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 44px;\n padding: 4px 6px;\n border-radius: var(--r-sm);\n}\n.band-plugin-react-pp-person:where(:hover) {\n background: var(--fill);\n}\n.band-plugin-react-pp-empty {\n padding: 10px 6px;\n color: var(--muted);\n font-size: var(--fs-row);\n}\n.band-plugin-react-pp-confirm {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: var(--fs-dense);\n color: var(--ink);\n white-space: nowrap;\n}\n.band-plugin-react-pp-count {\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-pp {\n position: relative;\n min-width: 0;\n}\n.band-plugin-react-pp-field {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 3px 8px;\n border-radius: var(--r);\n background: var(--panel);\n box-shadow: inset 0 0 0 1px var(--control-edge);\n}\n.band-plugin-react-pp-field > :where(.field) {\n flex: 1 1 auto;\n min-width: 0;\n}\n.band-plugin-react-pp-icon {\n width: 14px;\n height: 14px;\n flex: none;\n fill: none;\n stroke: var(--muted);\n stroke-width: 1.5;\n stroke-linecap: round;\n}\n.band-plugin-react-pp-notice {\n display: block;\n margin-top: 6px;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-pp-pop {\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 6px);\n z-index: var(--layer-pop);\n display: grid;\n gap: 4px;\n padding: 5px;\n border-radius: var(--r-lg);\n background: var(--panel);\n box-shadow: var(--shadow-pop);\n}\n.band-plugin-react-pp-list {\n display: grid;\n gap: 1px;\n max-height: 320px;\n overflow: auto;\n overscroll-behavior: contain;\n}\n.band-plugin-react-pp-fallback {\n padding: 7px 8px;\n border-radius: var(--r-sm);\n background: var(--sunk);\n color: var(--muted);\n font-size: var(--fs-meta);\n}\n.band-plugin-react-pp-trail {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 2px 4px;\n padding: 4px 6px 2px;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-pp-trail > span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n.band-plugin-react-pp-trail button {\n border: 0;\n background: none;\n padding: 1px 3px;\n border-radius: 5px;\n font: inherit;\n color: var(--muted);\n}\n.band-plugin-react-pp-trail button:where(:hover) {\n background: var(--fill);\n color: var(--ink);\n}\n.band-plugin-react-pp-trail button:where([aria-current]) {\n color: var(--ink);\n font-weight: 500;\n}\n.band-plugin-react-pp-row {\n display: flex;\n align-items: center;\n gap: 9px;\n min-height: 36px;\n padding: 5px 8px;\n border-radius: var(--r-sm);\n color: var(--ink);\n font-size: var(--fs-row);\n cursor: pointer;\n}\n.band-plugin-react-pp-row:where(.is-active) {\n background: var(--fill-2);\n}\n.band-plugin-react-pp-row:where(.is-off) {\n cursor: default;\n}\n.band-plugin-react-pp-row:where(.is-off) > :where(:not(.band-plugin-react-pp-main)) {\n opacity: 0.42;\n}\n.band-plugin-react-pp-main {\n display: grid;\n min-width: 0;\n flex: 1 1 auto;\n}\n.band-plugin-react-pp-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.band-plugin-react-pp-name > :where(mark),\n.band-plugin-react-pp-id > :where(mark) {\n background: var(--accent-soft);\n color: inherit;\n border-radius: 2px;\n}\n.band-plugin-react-pp-id {\n font-family: var(--mono);\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-pp-sub {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-pp-meta {\n flex: none;\n font-size: var(--fs-meta);\n color: var(--muted);\n}\n.band-plugin-react-pp-chev {\n flex: none;\n width: 14px;\n text-align: center;\n color: var(--muted);\n}\n.band-plugin-react-pp-dept,\n.band-plugin-react-pp-all {\n flex: none;\n display: inline-grid;\n place-items: center;\n width: 20px;\n height: 20px;\n border-radius: 6px;\n background: var(--fill-2);\n color: var(--muted);\n font-size: var(--fs-meta);\n}\n.band-plugin-react-pp-dept > svg {\n width: 13px;\n height: 13px;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.4;\n}\n.band-plugin-react-pp-state {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 18px 8px;\n color: var(--muted);\n font-size: var(--fs-row);\n text-align: center;\n}\n.band-plugin-react-pp-tuning > svg {\n width: 40px;\n height: 28px;\n}\n.band-plugin-react-pp-foot {\n padding: 4px 8px 2px;\n}\n@media (pointer: coarse), (max-width: 599px) {\n .band-plugin-react-pp-person {\n flex-wrap: wrap;\n }\n .band-plugin-react-pp-list {\n max-height: min(56vh, 420px);\n }\n}\n.band-plugin-react-pp-row:where(.is-off) .band-plugin-react-pp-name {\n color: var(--muted);\n}\n.band-plugin-react-pp-chosen {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n flex: none;\n max-width: 70%;\n height: 24px;\n padding: 0 4px 0 4px;\n border-radius: 999px;\n background: var(--fill-2);\n font-size: var(--fs-dense);\n white-space: nowrap;\n}\n.band-plugin-react-pp-chosen > button {\n border: 0;\n background: none;\n color: var(--muted);\n font: inherit;\n line-height: 1;\n padding: 0 4px;\n border-radius: 999px;\n}\n.band-plugin-react-pp-chosen > button:where(:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--accent);\n}\n";
4
4
  let el = document.head.querySelector("style[data-band-style=\"@kanyun-ai-infra/band-plugin-react/components\"]");
5
5
  if (!el) {
6
6
  el = document.createElement("style");
@@ -14,12 +14,16 @@ import {
14
14
  AgentAvatar,
15
15
  Avatar,
16
16
  BandMark,
17
+ Combobox,
17
18
  ErrorNote,
19
+ FilterMenu,
18
20
  Glyph,
19
21
  INSTRUMENTS,
20
22
  InfoNote,
21
23
  LogoLockup,
22
24
  PaneHeader,
25
+ PersonPicker,
26
+ PersonSearch,
23
27
  SettingsActions,
24
28
  SettingsBack,
25
29
  SettingsChoices,
@@ -35,6 +39,7 @@ import {
35
39
  SettingsLoading,
36
40
  SettingsNoAccess,
37
41
  SettingsNotice,
42
+ SettingsPicks,
38
43
  SettingsReadError,
39
44
  SettingsRow,
40
45
  SettingsRows,
@@ -42,25 +47,39 @@ import {
42
47
  SettingsSaved,
43
48
  SettingsSection,
44
49
  SettingsSingle,
50
+ TagInput,
51
+ ToastHost,
45
52
  WorkshopEmblem,
46
53
  WorkshopIcon,
47
54
  agentInstrument,
48
55
  avatarInitial,
49
56
  avatarTone,
57
+ dismissAllToasts,
58
+ dismissToast,
59
+ facetedCount,
60
+ filterRows,
50
61
  instrumentOf,
51
62
  memberOrder,
52
- settingsLinkHandler
53
- } from "./chunk-HX653UQN.js";
63
+ peopleDirectory,
64
+ settingsLinkHandler,
65
+ splitTags,
66
+ toast
67
+ } from "./chunk-ER2ITOG5.js";
68
+ import "./chunk-VKASR4EL.js";
54
69
  export {
55
70
  AgentAvatar,
56
71
  Avatar,
57
72
  BandMark,
73
+ Combobox,
58
74
  ErrorNote,
75
+ FilterMenu,
59
76
  Glyph,
60
77
  INSTRUMENTS,
61
78
  InfoNote,
62
79
  LogoLockup,
63
80
  PaneHeader,
81
+ PersonPicker,
82
+ PersonSearch,
64
83
  SettingsActions,
65
84
  SettingsBack,
66
85
  SettingsChoices,
@@ -76,6 +95,7 @@ export {
76
95
  SettingsLoading,
77
96
  SettingsNoAccess,
78
97
  SettingsNotice,
98
+ SettingsPicks,
79
99
  SettingsReadError,
80
100
  SettingsRow,
81
101
  SettingsRows,
@@ -83,12 +103,21 @@ export {
83
103
  SettingsSaved,
84
104
  SettingsSection,
85
105
  SettingsSingle,
106
+ TagInput,
107
+ ToastHost,
86
108
  WorkshopEmblem,
87
109
  WorkshopIcon,
88
110
  agentInstrument,
89
111
  avatarInitial,
90
112
  avatarTone,
113
+ dismissAllToasts,
114
+ dismissToast,
115
+ facetedCount,
116
+ filterRows,
91
117
  instrumentOf,
92
118
  memberOrder,
93
- settingsLinkHandler
119
+ peopleDirectory,
120
+ settingsLinkHandler,
121
+ splitTags,
122
+ toast
94
123
  };