@scinverse/ui 0.1.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/LICENSE +21 -0
- package/README.md +63 -0
- package/dist/components/Badge/Badge.d.ts +16 -0
- package/dist/components/Badge/index.d.ts +1 -0
- package/dist/components/Button/Button.d.ts +19 -0
- package/dist/components/Button/index.d.ts +1 -0
- package/dist/components/Card/Card.d.ts +17 -0
- package/dist/components/Card/index.d.ts +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +15 -0
- package/dist/components/Checkbox/index.d.ts +1 -0
- package/dist/components/Dropdown/Dropdown.d.ts +46 -0
- package/dist/components/Dropdown/index.d.ts +1 -0
- package/dist/components/Filter/Filter.d.ts +22 -0
- package/dist/components/Filter/filterModel.d.ts +68 -0
- package/dist/components/Filter/index.d.ts +2 -0
- package/dist/components/Input/FieldCaption.d.ts +9 -0
- package/dist/components/Input/Input.d.ts +16 -0
- package/dist/components/Input/SearchBar.d.ts +15 -0
- package/dist/components/Input/TextArea.d.ts +13 -0
- package/dist/components/Input/index.d.ts +3 -0
- package/dist/components/Panel/Panel.d.ts +6 -0
- package/dist/components/Panel/index.d.ts +1 -0
- package/dist/components/RadioGroup/Radio.d.ts +13 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts +19 -0
- package/dist/components/RadioGroup/RadioGroupContext.d.ts +11 -0
- package/dist/components/RadioGroup/index.d.ts +2 -0
- package/dist/components/Switcher/Switcher.d.ts +16 -0
- package/dist/components/Switcher/index.d.ts +1 -0
- package/dist/components/Tip/Tip.d.ts +21 -0
- package/dist/components/Tip/index.d.ts +1 -0
- package/dist/icons/SvgIcon.d.ts +38 -0
- package/dist/icons/branding.d.ts +20 -0
- package/dist/icons/buttonIcons.d.ts +32 -0
- package/dist/icons/createSvgIcon.d.ts +10 -0
- package/dist/icons/flagIcons.d.ts +20 -0
- package/dist/icons/index.d.ts +7 -0
- package/dist/icons/labels.d.ts +4 -0
- package/dist/icons/railIcons.d.ts +16 -0
- package/dist/index.cjs +200 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1605 -0
- package/dist/index.js.map +1 -0
- package/dist/placeFixedMenu.d.ts +10 -0
- package/dist/styles.cjs +0 -0
- package/dist/styles.css +2 -0
- package/dist/styles.js +0 -0
- package/dist/svg/flags/de.svg +1 -0
- package/dist/svg/flags/en.svg +23 -0
- package/dist/svg/flags/es.svg +1 -0
- package/dist/svg/flags/fr.svg +1 -0
- package/dist/svg/flags/it.svg +1 -0
- package/dist/svg/flags/nl.svg +1 -0
- package/dist/svg/flags/pt.svg +1 -0
- package/dist/svg/flags/ru.svg +1 -0
- package/dist/svg/flags/zh.svg +15 -0
- package/dist/svg/marks/nc-icon.svg +9 -0
- package/dist/svg/marks/nc-scinverse-icon.svg +34 -0
- package/dist/svg/marks/ohs-icon.svg +3 -0
- package/dist/svg/marks/ohs-scinverse-icon.svg +37 -0
- package/dist/svg/marks/scinverse-avatar.svg +13 -0
- package/dist/svg/marks/scinverse-icon.svg +20 -0
- package/dist/svg/marks/scinverse-logo.svg +4 -0
- package/dist/svg/marks/ui-kit-icon.svg +6 -0
- package/dist/svg/marks/ui-kit-scinverse-icon.svg +34 -0
- package/dist/svg/set/arrow-drop-down.svg +3 -0
- package/dist/svg/set/arrow-drop-up.svg +3 -0
- package/dist/svg/set/bell.svg +4 -0
- package/dist/svg/set/check.svg +3 -0
- package/dist/svg/set/chevron-down.svg +3 -0
- package/dist/svg/set/close.svg +3 -0
- package/dist/svg/set/exchange.svg +6 -0
- package/dist/svg/set/eye-slash.svg +3 -0
- package/dist/svg/set/eye.svg +3 -0
- package/dist/svg/set/help.svg +5 -0
- package/dist/svg/set/integration.svg +5 -0
- package/dist/svg/set/loading.svg +11 -0
- package/dist/svg/set/logout.svg +5 -0
- package/dist/svg/set/messages.svg +4 -0
- package/dist/svg/set/moon.svg +6 -0
- package/dist/svg/set/news.svg +3 -0
- package/dist/svg/set/pencil.svg +4 -0
- package/dist/svg/set/plus.svg +3 -0
- package/dist/svg/set/power.svg +3 -0
- package/dist/svg/set/refresh.svg +3 -0
- package/dist/svg/set/search.svg +3 -0
- package/dist/svg/set/settings.svg +4 -0
- package/dist/svg/set/sun.svg +4 -0
- package/dist/svg/set/system.svg +5 -0
- package/dist/svg/set/user.svg +4 -0
- package/dist/theme/ThemeProvider.d.ts +15 -0
- package/package.json +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/theme/ThemeProvider.tsx","../src/icons/SvgIcon.tsx","../src/components/Button/Button.module.css","../src/components/Button/Button.tsx","../src/components/Panel/Panel.module.css","../src/components/Panel/Panel.tsx","../src/components/Card/Card.module.css","../src/components/Card/Card.tsx","../src/components/Badge/Badge.module.css","../src/components/Badge/Badge.tsx","../src/icons/createSvgIcon.tsx","../src/icons/buttonIcons.tsx","../src/components/Checkbox/Checkbox.module.css","../src/components/Checkbox/Checkbox.tsx","../src/components/Tip/Tip.module.css","../src/components/Tip/Tip.tsx","../src/components/RadioGroup/RadioGroupContext.ts","../src/components/RadioGroup/Radio.module.css","../src/components/RadioGroup/Radio.tsx","../src/components/RadioGroup/RadioGroup.module.css","../src/components/RadioGroup/RadioGroup.tsx","../src/components/Input/Input.module.css","../src/components/Input/FieldCaption.tsx","../src/components/Input/Input.tsx","../src/components/Input/SearchBar.module.css","../src/components/Input/SearchBar.tsx","../src/components/Input/TextArea.tsx","../src/components/Switcher/Switcher.module.css","../src/components/Switcher/Switcher.tsx","../src/placeFixedMenu.ts","../src/components/Dropdown/Dropdown.module.css","../src/components/Dropdown/Dropdown.tsx","../src/components/Filter/filterModel.ts","../src/components/Filter/Filter.module.css","../src/components/Filter/Filter.tsx","../src/icons/branding.tsx","../src/icons/flagIcons.tsx","../src/icons/railIcons.tsx","../src/icons/labels.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\n\nexport type Theme = 'dark' | 'light';\n\nconst THEME_KEY = 'scinverse-ui:theme';\n\ninterface ThemeContextValue {\n theme: Theme;\n setTheme: (theme: Theme) => void;\n toggleTheme: () => void;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null);\n\nfunction readStoredTheme(): Theme {\n try {\n const raw = localStorage.getItem(THEME_KEY);\n if (raw === 'light' || raw === 'dark') return raw;\n } catch {\n /* ignore */\n }\n return 'dark';\n}\n\nfunction applyTheme(theme: Theme, root: HTMLElement) {\n root.dataset.theme = theme;\n try {\n localStorage.setItem(THEME_KEY, theme);\n } catch {\n /* ignore */\n }\n}\n\nexport function ThemeProvider({\n children,\n defaultTheme,\n target = 'document',\n}: {\n children: ReactNode;\n defaultTheme?: Theme;\n /** Apply data-theme on documentElement (default) or a local wrapper. */\n target?: 'document' | 'local';\n}) {\n const [theme, setThemeState] = useState<Theme>(() => defaultTheme ?? readStoredTheme());\n\n const setTheme = useCallback(\n (next: Theme) => {\n setThemeState(next);\n if (target === 'document') applyTheme(next, document.documentElement);\n },\n [target],\n );\n\n const toggleTheme = useCallback(() => {\n setTheme(theme === 'dark' ? 'light' : 'dark');\n }, [setTheme, theme]);\n\n useEffect(() => {\n if (target === 'document') applyTheme(theme, document.documentElement);\n }, [theme, target]);\n\n const value = useMemo(\n () => ({ theme, setTheme, toggleTheme }),\n [theme, setTheme, toggleTheme],\n );\n\n if (target === 'local') {\n return (\n <ThemeContext.Provider value={value}>\n <div className=\"sci-root\" data-theme={theme}>\n {children}\n </div>\n </ThemeContext.Provider>\n );\n }\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;\n}\n\nexport function useTheme(): ThemeContextValue {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error('useTheme must be used within ThemeProvider');\n return ctx;\n}\n","import type { ElementType, ReactNode, SVGProps } from 'react';\n\n/** Token names only — raw CSS colors go through the `(string & {})` branch. */\nexport type IconColor =\n | 'inherit'\n | 'accent'\n | 'focus'\n | 'success'\n | 'warning'\n | 'error'\n | 'ink'\n | 'text'\n | 'text-secondary'\n | 'muted';\n\nexport type IconSizeToken = 'sm' | 'md' | 'lg';\n\nexport type SvgIconProps = {\n color?: IconColor | (string & {});\n /** Token or px. Omit = md (24). */\n size?: IconSizeToken | number;\n /**\n * Outline stroke thickness → `strokeWidth`.\n * Meaningful for stroke glyphs; ignored by filled marks that do not stroke.\n */\n weight?: number;\n /** Accessible name → `<title>` + role=\"img\". Without it: aria-hidden. */\n title?: string;\n /** Render as another element/component (SVGR mark, custom svg root). */\n component?: ElementType;\n /** Take viewBox from `component` instead of forcing the default. */\n inheritViewBox?: boolean;\n /** Default viewBox when not inheriting. */\n viewBox?: string;\n children?: ReactNode;\n} & Omit<SVGProps<SVGSVGElement>, 'color' | 'width' | 'height'>;\n\n/** Size tokens → px. Numbers pass through. */\nexport const ICON_SIZE_PX = {\n sm: 16,\n md: 24,\n lg: 32,\n} as const satisfies Record<IconSizeToken, number>;\n\n/**\n * Token → CSS color value.\n * `inherit` = no override (currentColor from parent).\n * Raw strings (`#hex`, `rgb()`, `var(...)`) are used as-is.\n */\nexport const ICON_COLOR_CSS: Record<Exclude<IconColor, 'inherit'>, string> = {\n accent: 'var(--sci-color-accent)',\n focus: 'var(--sci-color-border-focus)',\n success: 'var(--sci-color-success)',\n warning: 'var(--sci-color-warning)',\n error: 'var(--sci-color-error)',\n ink: 'var(--sci-color-ink)',\n text: 'var(--sci-color-text)',\n 'text-secondary': 'var(--sci-color-text-secondary)',\n muted: 'var(--sci-color-text-muted)',\n};\n\nconst DEFAULT_VIEWBOX = '0 0 24 24';\n\nexport function resolveIconSize(size?: IconSizeToken | number): number {\n if (typeof size === 'number') return size;\n return ICON_SIZE_PX[size ?? 'md'];\n}\n\nexport function resolveIconColor(color?: IconColor | (string & {})): string | undefined {\n if (!color || color === 'inherit') return undefined;\n if (Object.prototype.hasOwnProperty.call(ICON_COLOR_CSS, color)) {\n return ICON_COLOR_CSS[color as Exclude<IconColor, 'inherit'>];\n }\n return color;\n}\n\nexport function SvgIcon({\n color = 'inherit',\n size,\n weight,\n title,\n component: Component = 'svg',\n inheritViewBox = false,\n viewBox = DEFAULT_VIEWBOX,\n className,\n style,\n strokeWidth,\n children,\n ...rest\n}: SvgIconProps) {\n const px = resolveIconSize(size);\n const cssColor = resolveIconColor(color);\n const boxProps = inheritViewBox ? {} : { viewBox };\n\n return (\n <Component\n {...boxProps}\n width={px}\n height={px}\n strokeWidth={weight ?? strokeWidth}\n className={['sci-SvgIcon', className].filter(Boolean).join(' ')}\n style={{ color: cssColor, ...style }}\n aria-hidden={title ? undefined : true}\n role={title ? 'img' : undefined}\n {...rest}\n >\n {title ? <title>{title}</title> : null}\n {children}\n </Component>\n );\n}\n",".root {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--sci-spacing-sm);\n min-height: 32px;\n padding: 0.4rem 0.85rem;\n border: 1px solid transparent;\n border-radius: var(--sci-radius-sm);\n font-family: var(--sci-font-family);\n font-size: var(--sci-font-size-sm);\n font-weight: 600;\n line-height: 1.2;\n cursor: pointer;\n transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;\n}\n\n.root:focus,\n.root:focus-visible {\n outline: none;\n}\n\n.root:disabled {\n opacity: 0.45;\n cursor: default;\n}\n\n.small {\n min-height: 28px;\n padding: 0.22rem 0.65rem;\n font-size: 0.8125rem;\n}\n\n.large {\n min-height: 40px;\n padding: 0.55rem 1.1rem;\n font-size: 1rem;\n}\n\n.primary {\n background: var(--sci-color-accent);\n border-color: var(--sci-color-accent);\n color: #fff;\n}\n\n.primary:hover:not(:disabled) {\n background: var(--sci-color-accent-hover);\n border-color: var(--sci-color-accent-hover);\n}\n\n.secondary {\n background: var(--sci-color-bg-input);\n border-color: var(--sci-color-border);\n color: var(--sci-color-text);\n}\n\n.secondary:hover:not(:disabled) {\n border-color: var(--sci-color-border-focus);\n background: var(--sci-color-bg-hover);\n}\n\n.ghost {\n background: transparent;\n border-color: var(--sci-color-border);\n color: var(--sci-color-text-secondary);\n}\n\n.ghost:hover:not(:disabled) {\n color: var(--sci-color-text);\n background: var(--sci-color-bg-hover);\n}\n\n/* Header / panel chrome — 30×30 icon control. */\n.panel {\n width: 30px;\n height: 30px;\n min-height: 30px;\n padding: 0;\n font-size: 15px;\n font-weight: 400;\n line-height: 1;\n background: var(--sci-color-bg-input);\n border-color: var(--sci-color-border);\n color: var(--sci-color-text-secondary);\n}\n\n.panel:hover:not(:disabled) {\n border-color: var(--sci-color-border-focus);\n background: var(--sci-color-bg-hover);\n color: var(--sci-color-text);\n}\n\n.panel.small {\n width: 26px;\n height: 26px;\n min-height: 26px;\n padding: 0;\n}\n\n.panel.large {\n width: 36px;\n height: 36px;\n min-height: 36px;\n padding: 0;\n}\n\n/* Token / raw color via --sci-button-color (same tokens as Icon). */\n.colored.primary {\n background: var(--sci-button-color);\n border-color: var(--sci-button-color);\n color: #fff;\n}\n\n.colored.primary:hover:not(:disabled) {\n background: color-mix(in srgb, var(--sci-button-color) 82%, #000);\n border-color: color-mix(in srgb, var(--sci-button-color) 82%, #000);\n}\n\n.colored.secondary {\n color: var(--sci-button-color);\n border-color: var(--sci-button-color);\n}\n\n.colored.secondary:hover:not(:disabled) {\n border-color: var(--sci-button-color);\n background: color-mix(in srgb, var(--sci-button-color) 12%, transparent);\n color: var(--sci-button-color);\n}\n\n.colored.ghost {\n color: var(--sci-button-color);\n}\n\n.colored.ghost:hover:not(:disabled) {\n color: var(--sci-button-color);\n background: color-mix(in srgb, var(--sci-button-color) 12%, transparent);\n}\n\n.colored.panel {\n color: var(--sci-button-color);\n}\n\n.colored.panel:hover:not(:disabled) {\n color: var(--sci-button-color);\n border-color: var(--sci-button-color);\n background: color-mix(in srgb, var(--sci-button-color) 12%, transparent);\n}\n\n/* Recording / view-toggle on — accent wash (OHS RecordingToggle). */\n.toggledAccent,\n.toggledAccent.primary,\n.toggledAccent.secondary,\n.toggledAccent.ghost,\n.toggledAccent.panel,\n.toggledAccent.colored {\n color: var(--sci-color-accent);\n border-color: color-mix(in srgb, var(--sci-color-accent) 55%, transparent);\n background: color-mix(in srgb, var(--sci-color-accent) 14%, transparent);\n}\n\n.toggledAccent:hover:not(:disabled),\n.toggledAccent.primary:hover:not(:disabled),\n.toggledAccent.secondary:hover:not(:disabled),\n.toggledAccent.ghost:hover:not(:disabled),\n.toggledAccent.panel:hover:not(:disabled),\n.toggledAccent.colored:hover:not(:disabled) {\n color: var(--sci-color-accent);\n border-color: color-mix(in srgb, var(--sci-color-accent) 55%, transparent);\n background: color-mix(in srgb, var(--sci-color-accent) 20%, transparent);\n}\n\n.toggledAccent svg {\n filter: drop-shadow(0 0 5px color-mix(in srgb, var(--sci-color-accent) 85%, transparent));\n}\n\n/* R5 on — accent border and ink, dark surface (ConnectionRetryPopover .btnOn). */\n.toggledDark,\n.toggledDark.primary,\n.toggledDark.secondary,\n.toggledDark.ghost,\n.toggledDark.panel,\n.toggledDark.colored {\n color: var(--sci-color-accent);\n border-color: var(--sci-color-accent);\n background: var(--sci-color-bg-input);\n}\n\n.toggledDark:hover:not(:disabled),\n.toggledDark:focus,\n.toggledDark:focus-visible,\n.toggledDark.primary:hover:not(:disabled),\n.toggledDark.secondary:hover:not(:disabled),\n.toggledDark.ghost:hover:not(:disabled),\n.toggledDark.panel:hover:not(:disabled),\n.toggledDark.colored:hover:not(:disabled) {\n color: var(--sci-color-accent);\n border-color: var(--sci-color-accent);\n background: var(--sci-color-bg-input);\n}\n","import type { ButtonHTMLAttributes, CSSProperties, ReactNode } from 'react';\nimport { resolveIconColor, type IconColor } from '../../icons/SvgIcon';\nimport styles from './Button.module.css';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'panel';\nexport type ButtonSize = 'small' | 'medium' | 'large';\n/** Same token names as SvgIcon `color`. */\nexport type ButtonColor = IconColor;\n/** Pressed look: `true` / `accent` = recording wash; `dark` = R5 fill. */\nexport type ButtonToggled = boolean | 'accent' | 'dark';\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'color'> {\n variant?: ButtonVariant;\n /** Default medium — same footprint as Basic. */\n size?: ButtonSize;\n /** Palette token or raw CSS color. Omit = variant defaults. */\n color?: ButtonColor | (string & {});\n /** Pressed / on. `true` is the accent wash; `dark` is the R5 fill. */\n toggled?: ButtonToggled;\n children?: ReactNode;\n}\n\nfunction toggledOn(toggled: ButtonToggled | undefined): boolean {\n return toggled === true || toggled === 'accent' || toggled === 'dark';\n}\n\nexport function Button({\n variant = 'primary',\n size = 'medium',\n color,\n toggled,\n className,\n type = 'button',\n style,\n children,\n ...rest\n}: ButtonProps) {\n const variantClass =\n variant === 'secondary'\n ? styles.secondary\n : variant === 'ghost'\n ? styles.ghost\n : variant === 'panel'\n ? styles.panel\n : styles.primary;\n const sizeClass = size === 'small' ? styles.small : size === 'large' ? styles.large : null;\n const tint = resolveIconColor(color);\n const tinted = Boolean(tint);\n const pressed = toggledOn(toggled);\n const dark = toggled === 'dark';\n const mergedStyle = (\n tinted ? { ...style, ['--sci-button-color' as string]: tint } : style\n ) as CSSProperties | undefined;\n\n return (\n <button\n type={type}\n className={[\n styles.root,\n variantClass,\n sizeClass,\n tinted ? styles.colored : null,\n pressed ? (dark ? styles.toggledDark : styles.toggledAccent) : null,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={mergedStyle}\n {...rest}\n aria-pressed={rest['aria-pressed'] ?? (toggled !== undefined ? pressed : undefined)}\n >\n {children}\n </button>\n );\n}\n",".root {\n background: var(--sci-color-bg-panel);\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-lg);\n padding: var(--sci-spacing-lg);\n}\n\n.title {\n margin: 0 0 var(--sci-spacing-md);\n color: var(--sci-color-accent);\n font-family: var(--sci-font-family-mono);\n font-size: 0.7rem;\n font-weight: 500;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n","import type { HTMLAttributes, ReactNode } from 'react';\nimport styles from './Panel.module.css';\n\nexport interface PanelProps extends HTMLAttributes<HTMLDivElement> {\n title?: string;\n children?: ReactNode;\n}\n\nexport function Panel({ title, children, className, ...rest }: PanelProps) {\n return (\n <div className={[styles.root, className].filter(Boolean).join(' ')} {...rest}>\n {title ? <h3 className={styles.title}>{title}</h3> : null}\n {children}\n </div>\n );\n}\n",".root {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n width: 100%;\n padding: 8px 10px;\n border: 1px solid transparent;\n border-radius: var(--sci-radius-sm);\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.root:hover {\n background: var(--sci-color-bg-hover);\n}\n\n.selected {\n border-color: var(--sci-color-border-focus);\n background: var(--sci-color-bg-hover);\n}\n\n.info {\n display: flex;\n min-width: 0;\n flex-direction: column;\n}\n\n.name {\n font-weight: 600;\n color: var(--sci-color-text);\n}\n\n.kind {\n color: var(--sci-color-text-muted);\n font-size: 11px;\n}\n\n.end {\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n}\n\n.dot {\n display: inline-block;\n flex-shrink: 0;\n width: 9px;\n height: 9px;\n border-radius: 50%;\n background: currentColor;\n box-shadow: 0 0 6px currentColor;\n}\n","import type { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { ICON_COLOR_CSS, type IconColor } from '../../icons/SvgIcon';\nimport styles from './Card.module.css';\n\nexport interface CardProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'name'> {\n name: ReactNode;\n kind?: ReactNode;\n selected?: boolean;\n /** Status dot, soon badge, anything. */\n end?: ReactNode;\n}\n\nexport type CardDotTone = Extract<\n IconColor,\n 'accent' | 'success' | 'warning' | 'error' | 'muted'\n>;\n\nexport interface CardDotProps {\n tone?: CardDotTone;\n label?: string;\n}\n\n/** Selectable rail row: name, kind, trailing mark. */\nexport function Card({\n name,\n kind,\n selected = false,\n end,\n className,\n type = 'button',\n ...rest\n}: CardProps) {\n return (\n <button\n type={type}\n className={[styles.root, selected ? styles.selected : '', className].filter(Boolean).join(' ')}\n aria-current={selected ? 'true' : undefined}\n {...rest}\n >\n <span className={styles.info}>\n <span className={styles.name}>{name}</span>\n {kind != null ? <span className={styles.kind}>{kind}</span> : null}\n </span>\n {end != null ? <span className={styles.end}>{end}</span> : null}\n </button>\n );\n}\n\nexport function CardDot({ tone = 'muted', label }: CardDotProps) {\n return (\n <span\n className={styles.dot}\n style={{ color: ICON_COLOR_CSS[tone] }}\n aria-label={label}\n title={label}\n />\n );\n}\n",".root {\n display: inline-flex;\n align-items: center;\n box-sizing: border-box;\n font-family: var(--sci-font-family);\n font-weight: 600;\n letter-spacing: 0.04em;\n line-height: 1.2;\n text-transform: uppercase;\n color: var(--sci-color-text-muted);\n background: var(--sci-color-bg-input);\n white-space: nowrap;\n}\n\n.basic {\n border-radius: var(--sci-radius-sm);\n}\n\n.rounded {\n border-radius: var(--sci-radius-lg);\n}\n\n.small {\n padding: 2px 5px;\n font-size: 9px;\n}\n\n.medium {\n padding: 3px 6px;\n font-size: 10px;\n}\n\n.large {\n padding: 3px 8px;\n font-size: 12px;\n}\n\n.colored {\n color: var(--sci-badge-color);\n background: color-mix(in srgb, var(--sci-badge-color) 16%, var(--sci-color-bg-input));\n}\n","import type { HTMLAttributes, ReactNode } from 'react';\nimport { resolveIconColor, type IconColor } from '../../icons/SvgIcon';\nimport styles from './Badge.module.css';\n\nexport type BadgeSize = 'small' | 'medium' | 'large';\n/** Same token names as SvgIcon `color`. */\nexport type BadgeColor = IconColor;\nexport type BadgeRound = 'rounded' | 'basic' | number;\n\nexport interface BadgeProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'color'> {\n children: ReactNode;\n /** Default medium. */\n size?: BadgeSize;\n /** Palette token or raw CSS. Omit = muted. */\n color?: BadgeColor | (string & {});\n /** `basic` (default) — 4px. `rounded` — 12px. A number is px. */\n round?: BadgeRound;\n}\n\nexport function Badge({\n children,\n size = 'medium',\n color,\n round = 'basic',\n className,\n style,\n ...rest\n}: BadgeProps) {\n const sizeClass = size === 'small' ? styles.small : size === 'large' ? styles.large : styles.medium;\n const tint = resolveIconColor(color);\n const customRound = typeof round === 'number';\n const roundClass = customRound ? '' : round === 'rounded' ? styles.rounded : styles.basic;\n return (\n <span\n className={[styles.root, sizeClass, roundClass, tint ? styles.colored : '', className]\n .filter(Boolean)\n .join(' ')}\n style={{\n ...style,\n ...(tint ? { ['--sci-badge-color' as string]: tint } : {}),\n ...(customRound ? { borderRadius: round } : {}),\n }}\n {...rest}\n >\n {children}\n </span>\n );\n}\n","import type { ReactElement, ReactNode } from 'react';\nimport { SvgIcon, type SvgIconProps } from './SvgIcon';\n\nexport type CreateSvgIconOptions = {\n viewBox?: string;\n /** `stroke` = outline defaults (action glyphs). `fill` = filled path. */\n kind?: 'stroke' | 'fill';\n /** Default outline thickness for `kind: 'stroke'`. Maps to `strokeWidth`. Default 1.7. */\n weight?: number;\n};\n\nexport function createSvgIcon(\n path: ReactNode,\n displayName: string,\n options: CreateSvgIconOptions = {},\n): (props: SvgIconProps) => ReactElement {\n const { viewBox = '0 0 24 24', kind = 'stroke', weight = 1.7 } = options;\n\n function Component(props: SvgIconProps) {\n const kindDefaults =\n kind === 'stroke'\n ? {\n fill: 'none' as const,\n stroke: 'currentColor',\n weight,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n }\n : { fill: 'currentColor' as const };\n\n return (\n <SvgIcon viewBox={viewBox} {...kindDefaults} {...props}>\n {path}\n </SvgIcon>\n );\n }\n\n Component.displayName = `${displayName}Icon`;\n return Component;\n}\n","import { createSvgIcon } from './createSvgIcon';\n\n/** 16-grid — at `sm` / 16px the bars sit on the pixel grid. Stroke is the kit default 1.7. */\nexport const PlusIcon = createSvgIcon(\n <path d=\"M8 3v10M3 8h10\" />,\n 'Plus',\n { viewBox: '0 0 16 16' },\n);\n\nexport const MinusIcon = createSvgIcon(\n <path d=\"M3 8h10\" />,\n 'Minus',\n { viewBox: '0 0 16 16' },\n);\n\n/** Recording start/stop — OHS power/standby (filled). */\nexport const PowerIcon = createSvgIcon(\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M7.25 7.25a.75.75 0 0 0 1.5 0V.75a.75.75 0 0 0-1.5 0zm4.04 5.157A5.5 5.5 0 1 1 5 3.39a.75.75 0 1 0-.818-1.257a7 7 0 1 0 7.635 0A.75.75 0 0 0 11 3.39a5.5 5.5 0 0 1 .291 9.017Z\"\n />,\n 'Power',\n { kind: 'fill', viewBox: '0 0 16 16' },\n);\n\nexport const CloseIcon = createSvgIcon(<path d=\"M6 6l12 12M18 6L6 18\" />, 'Close');\n\n/** Magnifier — FilterSearch / SearchBar (same path as OHS Console toolbar). */\nexport const SearchIcon = createSvgIcon(\n <path d=\"M7 2a5 5 0 1 1 0 10A5 5 0 0 1 7 2Zm3.5 8.5L14 14\" />,\n 'Search',\n { viewBox: '0 0 16 16', weight: 1.5 },\n);\n\n/** Login form password reveal — Font Awesome `fa-eye`. */\nexport const EyeIcon = createSvgIcon(\n <path d=\"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\" />,\n 'Eye',\n { kind: 'fill', viewBox: '0 0 576 512' },\n);\n\n/** Login form password hide — Font Awesome `fa-eye-slash`. */\nexport const EyeSlashIcon = createSvgIcon(\n <path d=\"M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C557.29 135.59 449.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z\" />,\n 'EyeSlash',\n { kind: 'fill', viewBox: '0 0 640 512' },\n);\n\nexport const CheckIcon = createSvgIcon(<path d=\"M5 12.5l4.2 4.2L19 7.5\" />, 'Check');\n\nexport const ChevronDownIcon = createSvgIcon(<path d=\"M6 9l6 6 6-6\" />, 'ChevronDown');\n\n/** Material arrow_drop_down — closed Dropdown caret. */\nexport const ArrowDropDownIcon = createSvgIcon(\n <path d=\"m7 10l5 5l5-5z\" />,\n 'ArrowDropDown',\n { kind: 'fill' },\n);\n\n/** Material arrow_drop_up — open Dropdown caret. */\nexport const ArrowDropUpIcon = createSvgIcon(\n <path d=\"m7 14l5-5l5 5z\" />,\n 'ArrowDropUp',\n { kind: 'fill' },\n);\n\n/** Theme toggle — light side (shown while dark is active). */\nexport const SunIcon = createSvgIcon(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"3.5\" />\n <path d=\"M12 3v2M12 19v2M3 12h2M19 12h2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M18.4 5.6L17 7M7 17l-1.4 1.4\" />\n </>,\n 'Sun',\n);\n\n/** Theme toggle — dark side (shown while light is active). */\nexport const MoonIcon = createSvgIcon(\n <g transform=\"translate(256 256) scale(0.875) translate(-256 -256)\">\n <path d=\"M268.279 496c-67.574 0-130.978-26.191-178.534-73.745S16 311.293 16 243.718A252.25 252.25 0 0 1 154.183 18.676a24.44 24.44 0 0 1 34.46 28.958a220.12 220.12 0 0 0 54.8 220.923A218.75 218.75 0 0 0 399.085 333.2a220.2 220.2 0 0 0 65.277-9.846a24.439 24.439 0 0 1 28.959 34.461A252.26 252.26 0 0 1 268.279 496M153.31 55.781A219.3 219.3 0 0 0 48 243.718C48 365.181 146.816 464 268.279 464a219.3 219.3 0 0 0 187.938-105.31a253 253 0 0 1-57.13 6.513a250.54 250.54 0 0 1-178.268-74.016a252.15 252.15 0 0 1-67.509-235.4Z\" />\n </g>,\n 'Moon',\n { kind: 'fill', viewBox: '0 0 512 512' },\n);\n\n/** Header / rail — sign out. */\nexport const LogoutIcon = createSvgIcon(\n <>\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\" />\n </>,\n 'Logout',\n);\n\n/** Edit action — same pencil as the console context menu. */\nexport const PencilIcon = createSvgIcon(\n <>\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z\" />\n </>,\n 'Pencil',\n);\n\n/** Header / rail — system settings gear. */\nexport const SettingsIcon = createSvgIcon(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\" />\n </>,\n 'Settings',\n);\n\n/** Reload / refresh action — two circular arrows. */\nexport const RefreshIcon = createSvgIcon(\n <path d=\"M6.34 6.34c.73-.73 1.59-1.31 2.54-1.71c.99-.42 2.03-.63 3.11-.63V2c-1.35 0-2.66.26-3.89.79c-1.19.5-2.26 1.23-3.18 2.14c-.92.92-1.64 1.99-2.14 3.18c-.52 1.23-.79 2.54-.79 3.89s.26 2.66.79 3.89c.5 1.19 1.22 2.26 2.14 3.18c.17.17.35.32.52.48L2.99 22h6v-6l-2.13 2.13c-.18-.15-.36-.31-.52-.48a8.1 8.1 0 0 1-1.72-2.54c-.42-.99-.63-2.03-.63-3.11s.21-2.13.63-3.11c.4-.95.98-1.81 1.72-2.54Zm12.73-1.41c-.17-.17-.35-.32-.52-.48L21 2h-6v6l2.13-2.13c.18.15.36.31.52.48c.74.74 1.31 1.59 1.72 2.54c.42.99.63 2.03.63 3.11s-.21 2.13-.63 3.11c-.4.95-.98 1.81-1.72 2.54c-.73.73-1.59 1.31-2.54 1.71c-.99.42-2.03.63-3.11.63v2c1.35 0 2.66-.26 3.89-.79c1.19-.5 2.26-1.23 3.18-2.14c.92-.92 1.64-1.99 2.14-3.18c.52-1.23.79-2.54.79-3.89s-.26-2.66-.79-3.89a9.9 9.9 0 0 0-2.14-3.18Z\" />,\n 'Refresh',\n { kind: 'fill' },\n);\n\n/** Indeterminate loading — arc spinner (SMIL). */\nexport const LoadingIcon = createSvgIcon(\n <>\n <path strokeDasharray=\"19\" d=\"M12 2c5.52 0 10 4.48 10 10\">\n <animate fill=\"freeze\" attributeName=\"stroke-dashoffset\" dur=\"0.3s\" values=\"19;0\" />\n <animateTransform\n attributeName=\"transform\"\n dur=\"1.5s\"\n repeatCount=\"indefinite\"\n type=\"rotate\"\n values=\"0 12 12;360 12 12\"\n />\n </path>\n <path\n strokeDasharray=\"63\"\n d=\"M12 2c5.52 0 10 4.48 10 10c0 5.52-4.48 10-10 10c-5.52 0-10-4.48-10-10c0-5.52 4.48-10 10-10Z\"\n opacity={0.3}\n >\n <animate fill=\"freeze\" attributeName=\"stroke-dashoffset\" dur=\"1.2s\" values=\"63;0\" />\n </path>\n </>,\n 'Loading',\n { kind: 'stroke', weight: 2.15 },\n);\n",".root {\n --sci-checkbox-size: 16px;\n --sci-checkbox-mark: 100%;\n display: inline-flex;\n align-items: baseline;\n gap: var(--sci-spacing-sm);\n cursor: pointer;\n user-select: none;\n color: var(--sci-color-text);\n font-size: var(--sci-font-size-sm);\n line-height: 1;\n}\n\n.root:has(.input:disabled) {\n opacity: 0.45;\n cursor: default;\n}\n\n.small {\n --sci-checkbox-size: 14px;\n font-size: 0.8125rem;\n}\n\n.large {\n --sci-checkbox-size: 20px;\n font-size: 1rem;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 1px;\n height: 1px;\n pointer-events: none;\n}\n\n.box {\n position: relative;\n box-sizing: border-box;\n flex-shrink: 0;\n /* Absolute mark stays out of flow — baseline stays the box bottom. */\n width: var(--sci-checkbox-size);\n height: var(--sci-checkbox-size);\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-input);\n transition: border-color 0.12s ease, background 0.12s ease;\n}\n\n.input:focus-visible + .box {\n outline: 2px solid var(--sci-color-border-focus);\n outline-offset: 2px;\n}\n\n.input:checked + .box {\n background: var(--sci-color-accent);\n border-color: var(--sci-color-accent);\n}\n\n.mark {\n position: absolute;\n top: 50%;\n left: 50%;\n width: var(--sci-checkbox-mark) !important;\n height: var(--sci-checkbox-mark) !important;\n color: #fff;\n transform: translate(-50%, -50%);\n visibility: hidden;\n}\n\n.input:checked + .box .mark {\n visibility: visible;\n}\n\n.colored .input:checked + .box {\n background: var(--sci-checkbox-color);\n border-color: var(--sci-checkbox-color);\n}\n\n.label {\n line-height: 1;\n /* Baseline sits on the box bottom; lift so the ink matches the square. */\n translate: 0 -0.12em;\n}\n","import { useEffect, useRef, type CSSProperties, type InputHTMLAttributes, type ReactNode } from 'react';\nimport { CheckIcon } from '../../icons/buttonIcons';\nimport { resolveIconColor, type IconColor } from '../../icons/SvgIcon';\nimport styles from './Checkbox.module.css';\n\nexport type CheckboxSize = 'small' | 'medium' | 'large';\n/** Same token names as SvgIcon `color`. */\nexport type CheckboxColor = IconColor;\n\nexport interface CheckboxProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'color'> {\n label?: ReactNode;\n /** Default medium. */\n size?: CheckboxSize;\n /** Palette token or raw CSS color. Omit = accent when checked. */\n color?: CheckboxColor | (string & {});\n /** Visual mixed state. Set on the DOM node — not a native React attribute. */\n indeterminate?: boolean;\n}\n\nexport function Checkbox({\n label,\n size = 'medium',\n color,\n className,\n id,\n style,\n indeterminate = false,\n ...rest\n}: CheckboxProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const inputId = id ?? (typeof label === 'string' ? `sci-cb-${label}` : undefined);\n const sizeClass = size === 'small' ? styles.small : size === 'large' ? styles.large : null;\n const tint = resolveIconColor(color);\n const tinted = Boolean(tint);\n const mergedStyle = (\n tinted ? { ...style, ['--sci-checkbox-color' as string]: tint } : style\n ) as CSSProperties | undefined;\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n return (\n <label\n className={[styles.root, sizeClass, tinted ? styles.colored : null, className]\n .filter(Boolean)\n .join(' ')}\n htmlFor={inputId}\n style={mergedStyle}\n >\n <input ref={inputRef} id={inputId} type=\"checkbox\" className={styles.input} {...rest} />\n <span className={styles.box} aria-hidden=\"true\">\n <CheckIcon className={styles.mark} weight={2.4} />\n </span>\n {label != null ? <span className={styles.label}>{label}</span> : null}\n </label>\n );\n}\n",".tip {\n position: fixed;\n z-index: 10000;\n max-width: 260px;\n /* Light: 1px less on top — light tips read visually higher. Dark: even padding below. */\n padding: 3px 8px 4px;\n border-radius: var(--sci-radius-sm, 4px);\n border: 1px solid var(--sci-color-text-secondary, var(--color-text-secondary, #adb5bd));\n background: var(--sci-color-bg, var(--color-bg, #f2f4fa));\n /* Light: primary text (approved). Dark: softer — see override below. */\n color: var(--sci-color-text, var(--color-text, #1c2433));\n font-size: 12px;\n font-family: var(--sci-font-family, var(--font-family, system-ui, sans-serif));\n line-height: 1.35;\n white-space: pre-wrap;\n box-shadow: var(--sci-shadow-md, 0 4px 14px rgba(0, 0, 0, 0.35));\n pointer-events: none;\n animation: sciTipIn 0.12s ease-out;\n}\n\n:global([data-theme='dark']) .tip {\n padding: 4px 8px;\n border-color: var(--sci-color-border, var(--color-border, #373a40));\n color: var(--sci-color-text-secondary, var(--color-text-secondary, #adb5bd));\n}\n\n.host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n max-width: 100%;\n}\n\n.hostBlock {\n display: block;\n width: 100%;\n height: 100%;\n max-width: none;\n}\n\n.hostBlock > * {\n width: 100%;\n}\n\n@keyframes sciTipIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n","import {\n useCallback,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport styles from './Tip.module.css';\n\ntype Side = 'bottom' | 'top';\n\nexport interface TipProps {\n /** Tooltip text. Empty / undefined — no tip. */\n content?: string;\n /** Preferred side (default bottom-center; flips near the edge). */\n side?: Side;\n /** Stretch host to 100% (grid cells / full-width buttons). */\n block?: boolean;\n /** Clamp position to this element (otherwise the viewport). */\n boundaryRef?: RefObject<HTMLElement | null>;\n className?: string;\n children: ReactNode;\n}\n\ninterface Pos {\n /** Left / top edges in CSS px (integers — avoids AA blur on borders). */\n left: number;\n top: number;\n side: Side;\n /** Anchor center X — used to re-clamp after measure. */\n centerX: number;\n /** Anchor top (or bottom for side bottom) used to recompute top after measure. */\n anchorY: number;\n gap: number;\n}\n\nconst VIEW_PAD = 8;\n\nfunction isDisabledControl(root: HTMLElement): boolean {\n if (root instanceof HTMLButtonElement && root.disabled) return true;\n if (root.getAttribute('aria-disabled') === 'true') return true;\n const control = root.querySelector('button, input, select, textarea');\n if (control instanceof HTMLButtonElement && control.disabled) return true;\n if (control?.getAttribute('aria-disabled') === 'true') return true;\n if (control instanceof HTMLInputElement && control.disabled) return true;\n return false;\n}\n\nfunction clampCenterX(centerX: number, tipWidth: number, bound: DOMRect): number {\n const half = tipWidth / 2;\n const min = bound.left + VIEW_PAD + half;\n const max = bound.right - VIEW_PAD - half;\n if (min > max) return (bound.left + bound.right) / 2;\n return Math.min(Math.max(centerX, min), max);\n}\n\nfunction leftEdgeFor(centerX: number, tipWidth: number, bound: DOMRect): number {\n return Math.round(clampCenterX(centerX, tipWidth, bound) - tipWidth / 2);\n}\n\n/** Top CSS edge (integer). For side `top`, pass measured tip height so we skip translateY blur. */\nfunction topEdgeFor(anchorTop: number, gap: number, side: Side, tipHeight = 0): number {\n if (side === 'bottom') return Math.round(anchorTop + gap);\n return Math.round(anchorTop - gap - tipHeight);\n}\n\nfunction viewportBound(): DOMRect {\n return {\n left: 0,\n right: window.innerWidth,\n top: 0,\n bottom: window.innerHeight,\n width: window.innerWidth,\n height: window.innerHeight,\n x: 0,\n y: 0,\n toJSON: () => ({}),\n } as DOMRect;\n}\n\n/**\n * Custom tooltip used by NC and OHS Console (portal → not clipped by overflow).\n * Same props as those copies (`delivery/spec.md` §4): hosts swap the import, not call sites.\n * Do not pair with native `title` — you would get a double tip.\n */\nexport function Tip({ content, side = 'bottom', block = false, boundaryRef, className, children }: TipProps) {\n const tipId = useId();\n const tipRef = useRef<HTMLSpanElement>(null);\n const [pos, setPos] = useState<Pos | null>(null);\n\n const hide = useCallback(() => setPos(null), []);\n\n const showFrom = useCallback(\n (el: HTMLElement) => {\n if (!content || isDisabledControl(el)) {\n return;\n }\n const rect = el.getBoundingClientRect();\n const gap = 8;\n const tipEstimate = 36;\n const bound = boundaryRef?.current?.getBoundingClientRect() ?? viewportBound();\n\n let nextSide = side;\n let anchorY = side === 'bottom' ? rect.bottom : rect.top;\n\n if (side === 'bottom' && bound.bottom - rect.bottom < tipEstimate) {\n nextSide = 'top';\n anchorY = rect.top;\n } else if (side === 'top' && rect.top - bound.top < tipEstimate) {\n nextSide = 'bottom';\n anchorY = rect.bottom;\n }\n\n const centerX = rect.left + rect.width / 2;\n const roughW = Math.min(260, Math.max(80, content.length * 7));\n\n setPos({\n left: leftEdgeFor(centerX, roughW, bound),\n // Estimate before measure; layout effect snaps with real tipHeight.\n top: topEdgeFor(anchorY, gap, nextSide, nextSide === 'top' ? tipEstimate : 0),\n side: nextSide,\n centerX,\n anchorY,\n gap,\n });\n },\n [boundaryRef, content, side],\n );\n\n useLayoutEffect(() => {\n if (!pos || !tipRef.current) return;\n const tipW = tipRef.current.offsetWidth;\n const tipH = tipRef.current.offsetHeight;\n const bound = boundaryRef?.current?.getBoundingClientRect() ?? viewportBound();\n const nextLeft = leftEdgeFor(pos.centerX, tipW, bound);\n const nextTop = topEdgeFor(pos.anchorY, pos.gap, pos.side, tipH);\n if (nextLeft !== pos.left || nextTop !== pos.top) {\n setPos((p) => (p ? { ...p, left: nextLeft, top: nextTop } : p));\n }\n }, [boundaryRef, pos]);\n\n if (!content) {\n return <>{children}</>;\n }\n\n return (\n <span\n className={[styles.host, block ? styles.hostBlock : '', className].filter(Boolean).join(' ')}\n aria-describedby={pos ? tipId : undefined}\n onMouseEnter={(e) => showFrom(e.currentTarget)}\n onMouseLeave={hide}\n onFocus={(e) => showFrom(e.currentTarget)}\n onBlur={hide}\n >\n {children}\n {pos &&\n createPortal(\n <span\n ref={tipRef}\n id={tipId}\n role=\"tooltip\"\n className={styles.tip}\n style={{ left: pos.left, top: pos.top } as CSSProperties}\n >\n {content}\n </span>,\n document.body,\n )}\n </span>\n );\n}\n","import { createContext, type ChangeEvent } from 'react';\nimport type { RadioColor, RadioSize } from './Radio';\n\nexport type RadioGroupContextValue = {\n name: string;\n value?: string;\n disabled?: boolean;\n size?: RadioSize;\n color?: RadioColor | (string & {});\n onSelect: (event: ChangeEvent<HTMLInputElement>) => void;\n};\n\nexport const RadioGroupContext = createContext<RadioGroupContextValue | null>(null);\n",".root {\n --sci-radio-size: 16px;\n --sci-radio-label-nudge: -3px;\n position: relative;\n display: inline-flex;\n align-items: baseline;\n gap: var(--sci-spacing-sm);\n cursor: pointer;\n user-select: none;\n color: var(--sci-color-text);\n font-size: var(--sci-font-size-sm);\n line-height: 1;\n}\n\n.root:has(.input:disabled) {\n opacity: 0.45;\n cursor: default;\n}\n\n.small {\n --sci-radio-size: 14px;\n --sci-radio-label-nudge: -2px;\n font-size: 0.8125rem;\n}\n\n.large {\n --sci-radio-size: 20px;\n --sci-radio-label-nudge: -5px;\n font-size: 1rem;\n}\n\n.input {\n position: absolute;\n opacity: 0;\n width: 1px;\n height: 1px;\n pointer-events: none;\n}\n\n.box {\n display: block;\n flex-shrink: 0;\n width: var(--sci-radio-size);\n height: var(--sci-radio-size);\n overflow: hidden;\n}\n\n.glyph {\n display: block;\n width: var(--sci-radio-size);\n height: var(--sci-radio-size);\n}\n\n.ring {\n fill: var(--sci-color-bg-input);\n stroke: var(--sci-color-border);\n stroke-width: 1.5;\n}\n\n.dot {\n fill: var(--sci-color-accent);\n opacity: 0;\n transition: opacity 0.12s ease;\n}\n\n.input:focus-visible + .box .ring {\n stroke: var(--sci-color-border-focus);\n}\n\n.input:checked + .box .ring {\n stroke: var(--sci-color-accent);\n}\n\n.input:checked + .box .dot {\n opacity: 1;\n}\n\n.colored .input:checked + .box .ring {\n stroke: var(--sci-radio-color);\n}\n\n.colored .dot {\n fill: var(--sci-radio-color);\n}\n\n.label {\n line-height: 1;\n translate: 0 var(--sci-radio-label-nudge);\n}\n","import type { CSSProperties, InputHTMLAttributes, ReactNode } from 'react';\nimport { useContext } from 'react';\nimport { resolveIconColor, type IconColor } from '../../icons/SvgIcon';\nimport { RadioGroupContext } from './RadioGroupContext';\nimport styles from './Radio.module.css';\n\nexport type RadioSize = 'small' | 'medium' | 'large';\n/** Same token names as SvgIcon `color`. */\nexport type RadioColor = IconColor;\n\nexport interface RadioProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'color'> {\n label?: ReactNode;\n /** Default medium. Group value wins if the radio omits size. */\n size?: RadioSize;\n /** Palette token or raw CSS color. Omit = accent when selected. */\n color?: RadioColor | (string & {});\n}\n\nexport function Radio({\n label,\n size: sizeProp,\n color: colorProp,\n className,\n id,\n style,\n name: nameProp,\n disabled: disabledProp,\n checked: checkedProp,\n value,\n onChange,\n ...rest\n}: RadioProps) {\n const group = useContext(RadioGroupContext);\n const size = sizeProp ?? group?.size ?? 'medium';\n const color = colorProp ?? group?.color;\n const disabled = disabledProp ?? group?.disabled;\n const name = group?.name ?? nameProp;\n const checked = group ? group.value === String(value ?? '') : checkedProp;\n const sizeClass = size === 'small' ? styles.small : size === 'large' ? styles.large : null;\n const tint = resolveIconColor(color);\n const tinted = Boolean(tint);\n const mergedStyle = (\n tinted ? { ...style, ['--sci-radio-color' as string]: tint } : style\n ) as CSSProperties | undefined;\n const inputId = id ?? (typeof label === 'string' ? `sci-radio-${name ?? 'x'}-${label}` : undefined);\n\n return (\n <label\n className={[styles.root, sizeClass, tinted ? styles.colored : null, className]\n .filter(Boolean)\n .join(' ')}\n htmlFor={inputId}\n style={mergedStyle}\n >\n <input\n id={inputId}\n type=\"radio\"\n className={styles.input}\n name={name}\n value={value}\n checked={checked}\n disabled={disabled}\n onChange={group ? group.onSelect : onChange}\n {...rest}\n />\n <span className={styles.box} aria-hidden=\"true\">\n <svg className={styles.glyph} viewBox=\"0 0 24 24\" focusable=\"false\">\n <circle className={styles.ring} cx=\"12\" cy=\"12\" r=\"10\" />\n <circle className={styles.dot} cx=\"12\" cy=\"12\" r=\"5.5\" />\n </svg>\n </span>\n {label != null ? <span className={styles.label}>{label}</span> : null}\n </label>\n );\n}\n",".root {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.15rem;\n}\n\n.legend {\n color: var(--sci-color-text-secondary);\n font-size: var(--sci-font-size-sm);\n line-height: 1.3;\n}\n\n.optionsV,\n.optionsH {\n display: flex;\n gap: var(--sci-spacing-sm);\n}\n\n.optionsV {\n flex-direction: column;\n align-items: flex-start;\n}\n\n.optionsH {\n flex-direction: row;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--sci-spacing-md);\n}\n","import {\n useCallback,\n useId,\n useState,\n type ChangeEvent,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport type { RadioColor, RadioSize } from './Radio';\nimport { RadioGroupContext } from './RadioGroupContext';\nimport styles from './RadioGroup.module.css';\n\nexport type RadioGroupOrientation = 'vertical' | 'horizontal';\n\nexport interface RadioGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'color'> {\n /** Shared `name` for the radios. Auto-generated when omitted. */\n name?: string;\n value?: string;\n defaultValue?: string;\n onChange?: (event: ChangeEvent<HTMLInputElement>, value: string) => void;\n /** Default vertical. */\n orientation?: RadioGroupOrientation;\n disabled?: boolean;\n size?: RadioSize;\n color?: RadioColor | (string & {});\n /** Visible group title; also used as `aria-label` when that is omitted. */\n label?: ReactNode;\n children?: ReactNode;\n}\n\nexport function RadioGroup({\n name: nameProp,\n value: valueProp,\n defaultValue,\n onChange,\n orientation = 'vertical',\n disabled,\n size,\n color,\n label,\n className,\n children,\n 'aria-label': ariaLabel,\n ...rest\n}: RadioGroupProps) {\n const autoName = useId();\n const name = nameProp ?? autoName;\n const [uncontrolled, setUncontrolled] = useState(defaultValue);\n const value = valueProp !== undefined ? valueProp : uncontrolled;\n\n const onSelect = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n if (valueProp === undefined) setUncontrolled(event.target.value);\n onChange?.(event, event.target.value);\n },\n [onChange, valueProp],\n );\n\n return (\n <RadioGroupContext.Provider value={{ name, value, disabled, size, color, onSelect }}>\n <div\n role=\"radiogroup\"\n aria-orientation={orientation}\n aria-label={ariaLabel ?? (typeof label === 'string' ? label : undefined)}\n className={[styles.root, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {label != null ? <div className={styles.legend}>{label}</div> : null}\n <div className={orientation === 'horizontal' ? styles.optionsH : styles.optionsV}>\n {children}\n </div>\n </div>\n </RadioGroupContext.Provider>\n );\n}\n",".labeled {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 0.25rem;\n width: max-content;\n max-width: 100%;\n min-width: 0;\n}\n\n.labeled.fill {\n width: 100%;\n}\n\n.caption {\n font-size: 11px;\n line-height: 1.3;\n color: var(--sci-color-text-muted);\n}\n\n.field {\n display: block;\n width: auto;\n max-width: 100%;\n min-width: 0;\n box-sizing: border-box;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-input);\n color: var(--sci-color-text);\n font: inherit;\n font-size: var(--sci-font-size-sm);\n}\n\n.field:focus,\n.field:focus-visible {\n outline: none;\n border-color: var(--sci-color-border-focus);\n}\n\n.invalid,\n.invalid:focus,\n.invalid:focus-visible {\n border-color: var(--sci-color-error);\n}\n\n.field:disabled {\n color: var(--sci-color-text-muted);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.field:disabled::placeholder {\n color: var(--sci-color-text-muted);\n}\n\n.input {\n height: 32px;\n padding: 0 8px;\n}\n\n.fill.field,\n.fill .field {\n width: 100%;\n}\n\n.passwordWrap {\n position: relative;\n display: block;\n width: max-content;\n max-width: 100%;\n min-width: 0;\n}\n\n.passwordWrap.fill {\n width: 100%;\n}\n\n.passwordInput {\n padding-right: 28px;\n}\n\n.reveal {\n position: absolute;\n top: 50%;\n right: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: 0;\n background: transparent;\n color: var(--sci-color-text-muted);\n line-height: 1;\n cursor: pointer;\n transform: translateY(-50%);\n}\n\n.reveal:focus,\n.reveal:focus-visible {\n outline: none;\n}\n\n.reveal:hover:not(:disabled) {\n color: var(--sci-color-text);\n}\n\n.passwordWrap:has(.field:disabled) {\n user-select: none;\n -webkit-user-select: none;\n}\n\n.passwordWrap:has(.field:disabled) .reveal {\n opacity: 0.55;\n}\n\n.reveal:disabled {\n color: var(--sci-color-text-muted);\n}\n\n.textarea {\n min-height: 64px;\n padding: 6px 8px;\n resize: vertical;\n line-height: 1.4;\n}\n\n.mono {\n font-family: var(--sci-font-family-mono);\n}\n","import type { ReactNode } from 'react';\nimport styles from './Input.module.css';\n\n/** Caption above Input / TextArea / Dropdown. Bare control when `label` is omitted. */\nexport function FieldCaption({\n label,\n htmlFor,\n fullWidth = false,\n children,\n}: {\n label?: ReactNode;\n htmlFor?: string;\n /** Stretch to the parent. Default hugs the control. */\n fullWidth?: boolean;\n children: ReactNode;\n}) {\n if (label == null) return children;\n return (\n <label\n className={[styles.labeled, fullWidth ? styles.fill : ''].filter(Boolean).join(' ')}\n htmlFor={htmlFor}\n >\n <span className={styles.caption}>{label}</span>\n {children}\n </label>\n );\n}\n","import { useId, useState, type InputHTMLAttributes, type ReactNode } from 'react';\nimport { EyeIcon, EyeSlashIcon } from '../../icons/buttonIcons';\nimport { FieldCaption } from './FieldCaption';\nimport styles from './Input.module.css';\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\n type?: 'text' | 'search' | 'email' | 'url' | 'password' | 'number';\n /** Caption above the field. Omit for a bare input. */\n label?: ReactNode;\n /** Stretch to the parent. Default hugs the content. */\n fullWidth?: boolean;\n /** Red border after a failed validation. */\n invalid?: boolean;\n /** Password reveal — shown. Default matches the login form. */\n showPasswordLabel?: string;\n /** Password reveal — hidden. */\n hidePasswordLabel?: string;\n}\n\n/** Single-line field. Same chrome as SearchBar / Dropdown — no system focus ring. */\nexport function Input({\n className,\n type = 'text',\n label,\n fullWidth = false,\n invalid = false,\n disabled,\n id,\n showPasswordLabel = 'Show password',\n hidePasswordLabel = 'Hide password',\n ...rest\n}: InputProps) {\n const [revealed, setRevealed] = useState(false);\n const generatedId = useId();\n const isPassword = type === 'password';\n const inputId = id ?? (label != null || isPassword ? generatedId : undefined);\n const inputType = isPassword && revealed ? 'text' : type;\n\n const field = (\n <input\n id={inputId}\n type={inputType}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n className={[\n styles.field,\n styles.input,\n isPassword ? styles.passwordInput : '',\n fullWidth ? styles.fill : '',\n invalid ? styles.invalid : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n />\n );\n\n const control = !isPassword ? (\n field\n ) : (\n <div className={[styles.passwordWrap, fullWidth ? styles.fill : ''].filter(Boolean).join(' ')}>\n {field}\n <button\n type=\"button\"\n className={styles.reveal}\n aria-label={revealed ? hidePasswordLabel : showPasswordLabel}\n aria-controls={inputId}\n aria-pressed={revealed}\n disabled={disabled}\n onClick={() => setRevealed((open) => !open)}\n >\n {revealed ? <EyeSlashIcon size={14} /> : <EyeIcon size={14} />}\n </button>\n </div>\n );\n\n return (\n <FieldCaption label={label} htmlFor={inputId} fullWidth={fullWidth}>\n {control}\n </FieldCaption>\n );\n}\n",".wrap {\n position: relative;\n display: inline-flex;\n align-items: center;\n /* Flex parents stretch children on the cross axis — wrap must stay input-wide\n or `right: 4px` on clear lands at the far edge of the row. */\n width: max-content;\n max-width: 100%;\n align-self: flex-start;\n}\n\n.fill {\n display: flex;\n width: 100%;\n}\n\n.icon {\n position: absolute;\n left: 8px;\n color: var(--sci-color-text-muted);\n pointer-events: none;\n}\n\n.input {\n width: 200px;\n max-width: 240px;\n height: 32px;\n box-sizing: border-box;\n padding: 6px 10px 6px 28px;\n border-radius: var(--sci-radius-sm);\n border: 1px solid var(--sci-color-border);\n background: var(--sci-color-bg-input);\n color: var(--sci-color-text);\n font: inherit;\n font-size: var(--sci-font-size-sm);\n}\n\n.fill .input {\n width: 100%;\n max-width: none;\n flex: 1;\n min-width: 0;\n}\n\n.withClear {\n padding-right: 26px;\n}\n\n.input:focus,\n.input:focus-visible {\n outline: none;\n border-color: var(--sci-color-border-focus);\n}\n\n.wrap:has(.input:disabled) {\n user-select: none;\n -webkit-user-select: none;\n}\n\n.wrap:has(.input:disabled) .icon {\n opacity: 0.55;\n}\n\n.input:disabled {\n color: var(--sci-color-text-muted);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.input:disabled::placeholder {\n color: var(--sci-color-text-muted);\n}\n\n.clear {\n position: absolute;\n right: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: 0;\n background: transparent;\n color: var(--sci-color-text-muted);\n line-height: 1;\n cursor: pointer;\n}\n\n.clear:hover:not(:disabled) {\n color: var(--sci-color-text);\n background: transparent;\n}\n\n.clear:disabled {\n color: var(--sci-color-text-muted);\n}\n","import {\n useEffect,\n useRef,\n useState,\n type ChangeEvent,\n type InputHTMLAttributes,\n} from 'react';\nimport { CloseIcon, SearchIcon } from '../../icons/buttonIcons';\nimport styles from './SearchBar.module.css';\n\nexport interface SearchBarProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {\n /** Stretch to the parent. Default is the compact width. */\n fullWidth?: boolean;\n /**\n * Debounced value. First emit is skipped when it matches the starting value.\n */\n onSearch?: (query: string) => void;\n /** Delay before `onSearch`, in ms. Default 300. Use 500+ for a large catalog. */\n debounce?: number;\n /** aria-label on the clear control. */\n clearLabel?: string;\n}\n\nfunction useDebouncedValue(value: string, ms: number): string {\n const [debounced, setDebounced] = useState(value);\n useEffect(() => {\n if (ms <= 0) return;\n const id = window.setTimeout(() => setDebounced(value), ms);\n return () => window.clearTimeout(id);\n }, [value, ms]);\n // No delay means no state to hold: read through and skip the extra render.\n return ms <= 0 ? value : debounced;\n}\n\n/** Text query field: icon, optional clear, optional debounce. */\nexport function SearchBar({\n className,\n fullWidth = false,\n onSearch,\n debounce = 300,\n clearLabel = 'Clear search',\n value,\n defaultValue,\n onChange,\n disabled,\n ...rest\n}: SearchBarProps) {\n const controlled = value !== undefined;\n const [inner, setInner] = useState(() => String(defaultValue ?? ''));\n const text = controlled ? String(value ?? '') : inner;\n const debounced = useDebouncedValue(text, debounce);\n\n const onSearchRef = useRef(onSearch);\n // Declared before the emit effect below, so `current` is fresh by the time it fires.\n useEffect(() => {\n onSearchRef.current = onSearch;\n });\n const lastSent = useRef(String(defaultValue ?? value ?? ''));\n\n useEffect(() => {\n if (!onSearchRef.current) return;\n if (debounced === lastSent.current) return;\n lastSent.current = debounced;\n onSearchRef.current(debounced);\n }, [debounced]);\n\n const emitChange = (next: string, event?: ChangeEvent<HTMLInputElement>) => {\n if (!controlled) setInner(next);\n if (event) {\n onChange?.(event);\n return;\n }\n onChange?.({\n target: { value: next },\n currentTarget: { value: next },\n } as ChangeEvent<HTMLInputElement>);\n };\n\n const clear = () => {\n emitChange('');\n lastSent.current = '';\n onSearchRef.current?.('');\n };\n\n return (\n <div className={[styles.wrap, fullWidth ? styles.fill : '', className].filter(Boolean).join(' ')}>\n <SearchIcon className={styles.icon} size={14} />\n <input\n type=\"text\"\n className={[styles.input, text && !disabled ? styles.withClear : ''].filter(Boolean).join(' ')}\n value={text}\n disabled={disabled}\n onChange={(event) => {\n if (!controlled) setInner(event.target.value);\n onChange?.(event);\n }}\n {...rest}\n />\n {text && !disabled ? (\n <button\n type=\"button\"\n className={styles.clear}\n aria-label={clearLabel}\n onClick={clear}\n >\n <CloseIcon size={12} />\n </button>\n ) : null}\n </div>\n );\n}\n","import { useId, type ReactNode, type TextareaHTMLAttributes } from 'react';\nimport { FieldCaption } from './FieldCaption';\nimport styles from './Input.module.css';\n\nexport interface TextAreaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** Caption above the field. Omit for a bare textarea. */\n label?: ReactNode;\n /** Stretch to the parent. Default hugs the content. */\n fullWidth?: boolean;\n /** Monospace (glob, code). */\n mono?: boolean;\n /** Red border after a failed validation. */\n invalid?: boolean;\n}\n\n/** Multiline field. Same chrome as Input. */\nexport function TextArea({\n className,\n label,\n fullWidth = false,\n mono = false,\n invalid = false,\n id,\n ...rest\n}: TextAreaProps) {\n const generatedId = useId();\n const inputId = id ?? (label != null ? generatedId : undefined);\n\n return (\n <FieldCaption label={label} htmlFor={inputId} fullWidth={fullWidth}>\n <textarea\n id={inputId}\n aria-invalid={invalid || undefined}\n className={[\n styles.field,\n styles.textarea,\n fullWidth ? styles.fill : '',\n mono ? styles.mono : '',\n invalid ? styles.invalid : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n />\n </FieldCaption>\n );\n}\n",".wrap {\n display: inline-flex;\n align-items: center;\n gap: var(--sci-spacing-sm);\n}\n\n.track {\n position: relative;\n box-sizing: border-box;\n width: 52px;\n height: 28px;\n padding: 0;\n margin: 0;\n border: 1px solid var(--sci-color-border);\n border-radius: 999px;\n background: var(--sci-color-bg-input);\n line-height: 0;\n cursor: pointer;\n transition:\n background 0.18s ease,\n border-color 0.18s ease;\n}\n\n.track:focus,\n.track:focus-visible {\n outline: none;\n}\n\n.wrap:has(.track:disabled) {\n opacity: 0.45;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.track:disabled {\n cursor: default;\n}\n\n.track:disabled .knob {\n animation: none;\n}\n\n.knob {\n position: absolute;\n top: 50%;\n left: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: #fff;\n color: var(--sci-color-text-muted);\n font-size: 13px;\n line-height: 1;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);\n transform: translateY(-50%);\n transition:\n transform 0.18s ease,\n background 0.18s ease;\n}\n\n.off {\n background: var(--sci-color-bg-input);\n border-color: var(--sci-color-border);\n}\n\n.off .knob {\n background-color: var(--sci-color-text-muted);\n}\n\n.connecting {\n background: var(--sci-color-warning);\n border-color: var(--sci-color-warning);\n}\n\n.connecting .knob {\n transform: translate(13px, -50%);\n background-color: color-mix(in srgb, var(--sci-color-warning) 40%, white);\n animation: pulse 0.9s ease-in-out infinite;\n}\n\n.active {\n background: var(--sci-color-accent);\n border-color: var(--sci-color-accent);\n}\n\n.active .knob {\n transform: translate(24px, -50%);\n background-color: color-mix(in srgb, var(--sci-color-accent) 25%, white);\n}\n\n.waiting {\n background: var(--sci-color-success);\n border-color: var(--sci-color-success);\n}\n\n.waiting .knob {\n transform: translate(24px, -50%);\n background-color: color-mix(in srgb, var(--sci-color-success) 25%, white);\n}\n\n.degraded {\n background: var(--sci-color-warning);\n border-color: var(--sci-color-warning);\n}\n\n.degraded .knob {\n transform: translate(24px, -50%);\n background-color: color-mix(in srgb, var(--sci-color-warning) 35%, white);\n animation: pulse 0.9s ease-in-out infinite;\n}\n\n.unreachable {\n background: var(--sci-color-warning);\n border-color: var(--sci-color-warning);\n}\n\n.unreachable .knob {\n transform: translate(13px, -50%);\n background-color: color-mix(in srgb, var(--sci-color-warning) 40%, white);\n animation: pulse 0.9s ease-in-out infinite;\n}\n\n.error {\n background: var(--sci-color-error);\n border-color: var(--sci-color-error);\n}\n\n.error .knob {\n background-color: color-mix(in srgb, var(--sci-color-error) 40%, white);\n}\n\n.label {\n font-size: var(--sci-font-size-sm);\n color: var(--sci-color-text-secondary);\n}\n\n.small {\n flex-direction: column;\n gap: 2px;\n align-items: center;\n justify-content: center;\n}\n\n.small .label {\n font-size: 8px;\n line-height: 1;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n opacity: 0.8;\n}\n\n.small .track {\n width: 39px;\n height: 20px;\n}\n\n.small .knob {\n left: 2px;\n width: 16px;\n height: 16px;\n font-size: 9px;\n}\n\n.small .connecting .knob,\n.small .unreachable .knob {\n transform: translate(9px, -50%);\n}\n\n.small .active .knob,\n.small .waiting .knob,\n.small .degraded .knob {\n transform: translate(18px, -50%);\n}\n\n@keyframes pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n","import type { ButtonHTMLAttributes, ReactNode } from 'react';\nimport styles from './Switcher.module.css';\n\nexport type SwitcherPhase =\n | 'off'\n | 'connecting'\n | 'active'\n | 'waiting'\n | 'degraded'\n | 'error'\n | 'unreachable';\n\n/** `medium` — Connection track. `small` — Auto. */\nexport type SwitcherSize = 'medium' | 'small';\n\nexport interface SwitcherProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onToggle'> {\n /** Track color and knob position. Default `off`. */\n phase?: SwitcherPhase;\n /** When `phase` is omitted: `true` → `active`, `false` → `off`. */\n checked?: boolean;\n label?: ReactNode;\n /** Default medium (Connection). Small is Auto. */\n size?: SwitcherSize;\n onToggle?: () => void;\n}\n\nfunction resolvePhase(phase: SwitcherPhase | undefined, checked: boolean | undefined): SwitcherPhase {\n if (phase) return phase;\n if (checked) return 'active';\n return 'off';\n}\n\n/** Colored track switch — Connection (medium) and Auto (small). */\nexport function Switcher({\n phase: phaseProp,\n checked,\n label,\n size = 'medium',\n disabled,\n onToggle,\n className,\n ...rest\n}: SwitcherProps) {\n const phase = resolvePhase(phaseProp, checked);\n const on = phase === 'active' || phase === 'waiting' || phase === 'degraded';\n const busy = phase === 'connecting' || phase === 'unreachable';\n const locked = disabled || phase === 'unreachable';\n\n return (\n <div\n className={[styles.wrap, size === 'small' ? styles.small : '', className].filter(Boolean).join(' ')}\n >\n {label != null ? <span className={styles.label}>{label}</span> : null}\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={on || busy}\n aria-busy={busy || undefined}\n disabled={disabled}\n className={[styles.track, styles[phase]].join(' ')}\n {...rest}\n onClick={() => {\n if (locked) return;\n onToggle?.();\n }}\n >\n <span className={styles.knob}>{on || busy ? '' : '×'}</span>\n </button>\n </div>\n );\n}\n","/** Viewport-fixed menu at a pointer, flipped above when it would overflow. */\nexport function placeFixedPoint(\n x: number,\n y: number,\n menu: HTMLElement | null,\n): { top: number; left: number } {\n return placeFixedMenu(new DOMRect(x, y, 0, 0), menu, 0);\n}\n\n/** Viewport-fixed menu under `anchor`, flipped above when it would overflow. */\nexport function placeFixedMenu(\n anchor: DOMRect,\n menu: HTMLElement | null,\n gap: number,\n): { top: number; left: number } {\n const pad = 8;\n const vh = window.innerHeight;\n const vw = window.innerWidth;\n const menuH = menu?.offsetHeight ?? 0;\n const menuW = menu?.offsetWidth ?? 0;\n\n let top = anchor.bottom + gap;\n const spaceBelow = vh - pad - top;\n const spaceAbove = anchor.top - gap - pad;\n if (menuH > 0 && spaceBelow < menuH && spaceAbove > spaceBelow) {\n top = Math.max(pad, anchor.top - gap - menuH);\n } else if (menuH > 0 && top + menuH > vh - pad) {\n top = Math.max(pad, vh - pad - menuH);\n }\n\n let left = anchor.left;\n if (menuW > 0 && left + menuW > vw - pad) {\n left = Math.max(pad, vw - pad - menuW);\n }\n return { top, left };\n}\n",".root {\n position: relative;\n display: block;\n width: max-content;\n max-width: 100%;\n min-width: 0;\n}\n\n.root.fill {\n width: 100%;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n width: max-content;\n max-width: 100%;\n height: 32px;\n padding: 0 4px 0 12px;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-input);\n color: var(--sci-color-text);\n font: inherit;\n font-size: var(--sci-font-size-sm);\n text-align: left;\n cursor: pointer;\n}\n\n.fill .trigger {\n width: 100%;\n}\n\n.trigger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--sci-color-text) 4%, var(--sci-color-bg-input));\n}\n\n.trigger:focus,\n.trigger:focus-visible {\n outline: none;\n border-color: var(--sci-color-border-focus);\n}\n\n.triggerOpen {\n border-color: var(--sci-color-border-focus);\n}\n\n.root:has(.trigger:disabled) {\n opacity: 0.45;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.trigger:disabled {\n color: var(--sci-color-text-muted);\n cursor: default;\n}\n\n.value {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.caret {\n flex-shrink: 0;\n color: var(--sci-color-text-muted);\n}\n\n.menu {\n z-index: 60;\n box-sizing: border-box;\n margin: 0;\n padding: 4px 0;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-panel);\n color: var(--sci-color-text);\n list-style: none;\n max-height: min(280px, 50vh);\n overflow: auto;\n box-shadow:\n 0 5px 5px -3px rgba(0, 0, 0, 0.2),\n 0 8px 10px 1px rgba(0, 0, 0, 0.14),\n 0 3px 14px 2px rgba(0, 0, 0, 0.12);\n opacity: 0;\n transform: translateY(-6px);\n transform-origin: top center;\n transition:\n opacity 0.16s ease,\n transform 0.16s ease;\n pointer-events: none;\n}\n\n.menuOpen {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n.option {\n display: block;\n width: 100%;\n padding: 7px 12px;\n border: none;\n border-radius: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: var(--sci-font-size-sm);\n text-align: left;\n cursor: pointer;\n}\n\n.option:hover,\n.optionActive {\n background: var(--sci-color-bg-hover);\n}\n\n.optionSelected {\n background: color-mix(in srgb, var(--sci-color-accent) 22%, transparent);\n}\n\n.optionSelected:hover,\n.optionSelected.optionActive {\n background: color-mix(in srgb, var(--sci-color-accent) 30%, transparent);\n}\n\n.option:focus,\n.option:focus-visible {\n outline: none;\n}\n\n/* Header language control — PlatformHeader .iconBtn / .localeMenu */\n.iconRoot {\n width: max-content;\n}\n\n.iconTrigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-input);\n color: var(--sci-color-text-secondary);\n font-size: 15px;\n line-height: 1;\n cursor: pointer;\n transition:\n border-color 0.12s ease,\n background 0.12s ease,\n color 0.12s ease;\n}\n\n.iconTrigger:hover:not(:disabled) {\n border-color: var(--sci-color-border-focus);\n background: var(--sci-color-bg-hover);\n color: var(--sci-color-text);\n}\n\n.iconTrigger:disabled {\n opacity: 0.45;\n cursor: default;\n}\n\n.iconTrigger:focus,\n.iconTrigger:focus-visible {\n outline: none;\n}\n\n.flagIcon {\n display: block;\n flex-shrink: 0;\n line-height: 0;\n shape-rendering: geometricPrecision;\n}\n\n.iconMenu {\n z-index: 60;\n box-sizing: border-box;\n margin: 0;\n padding: var(--sci-spacing-xs);\n list-style: none;\n min-width: 11.5rem;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-md);\n background: var(--sci-color-bg-panel);\n box-shadow: var(--sci-shadow-md);\n}\n\n.iconOption {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n text-align: left;\n padding: 0.45rem 0.65rem;\n border: 0;\n border-radius: var(--sci-radius-sm);\n background: transparent;\n color: var(--sci-color-text-secondary);\n font-family: inherit;\n font-size: var(--sci-font-size-sm);\n cursor: pointer;\n}\n\n.iconOption:hover,\n.iconOptionActive:not(.iconOptionSelected) {\n background: var(--sci-color-bg-hover);\n color: var(--sci-color-text);\n}\n\n.iconOptionSelected {\n color: var(--sci-color-accent);\n background: color-mix(in srgb, var(--sci-color-accent) 12%, transparent);\n}\n\n.iconLabel {\n line-height: 1.25;\n color: inherit;\n}\n\n.iconOption:focus,\n.iconOption:focus-visible {\n outline: none;\n}\n\n/* Filter [+] — FilterChips .iconBtn / .popover */\n.selectorTrigger {\n color: var(--sci-color-accent);\n}\n\n.selectorTrigger:hover:not(:disabled) {\n color: var(--sci-color-accent);\n}\n\n.selectorTriggerOpen {\n border-color: var(--sci-color-accent);\n background: color-mix(in srgb, var(--sci-color-accent) 16%, transparent);\n}\n\n.selectorMenu {\n z-index: 60;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n min-width: 200px;\n max-height: 60vh;\n overflow-y: auto;\n margin: 0;\n padding: var(--sci-spacing-xs);\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-md);\n background: var(--sci-color-bg-panel);\n box-shadow: var(--sci-shadow-md);\n}\n\n.selectorList {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.selectorOption {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border-radius: var(--sci-radius-sm);\n white-space: nowrap;\n}\n\n.selectorOption:hover,\n.selectorOptionActive {\n background: var(--sci-color-bg-hover);\n}\n\n.selectorFooter {\n display: flex;\n justify-content: flex-end;\n margin-top: 4px;\n padding: 4px 4px 2px;\n border-top: 1px solid var(--sci-color-border);\n}\n\n.selectorOk {\n height: 26px;\n padding: 0 12px;\n border-radius: var(--sci-radius-sm);\n border: 1px solid var(--sci-color-accent);\n background: var(--sci-color-accent);\n color: #fff;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.selectorOk:hover {\n background: color-mix(in srgb, var(--sci-color-accent) 85%, #000);\n border-color: color-mix(in srgb, var(--sci-color-accent) 85%, #000);\n}\n\n/* Right-click menu — console connection / integration card */\n.contextBackdrop {\n position: fixed;\n inset: 0;\n z-index: 59;\n}\n\n.contextMenu {\n z-index: 60;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 168px;\n margin: 0;\n padding: 4px;\n list-style: none;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-panel);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);\n}\n\n.contextOption {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 10px;\n border: none;\n border-radius: var(--sci-radius-sm);\n background: transparent;\n color: var(--sci-color-text);\n font: inherit;\n font-size: var(--sci-font-size-sm);\n text-align: left;\n cursor: pointer;\n}\n\n.contextOption:hover,\n.contextOptionActive {\n background: var(--sci-color-bg-hover);\n}\n\n.contextIcon {\n display: inline-flex;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n color: var(--sci-color-text-muted);\n}\n\n.contextDanger:hover,\n.contextDanger.contextOptionActive {\n color: var(--sci-color-error);\n}\n\n.contextDanger:hover .contextIcon,\n.contextDanger.contextOptionActive .contextIcon {\n color: var(--sci-color-error);\n}\n\n.contextOption:focus,\n.contextOption:focus-visible {\n outline: none;\n}\n","import {\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { ArrowDropDownIcon, ArrowDropUpIcon, PlusIcon } from '../../icons/buttonIcons';\nimport { placeFixedMenu, placeFixedPoint } from '../../placeFixedMenu';\nimport { Checkbox } from '../Checkbox/Checkbox';\nimport { FieldCaption } from '../Input/FieldCaption';\nimport { Tip } from '../Tip/Tip';\nimport styles from './Dropdown.module.css';\n\nconst CLOSE_MS = 160;\n\nexport type DropdownVariant = 'field' | 'icon' | 'selector' | 'context';\n\nexport interface DropdownOption<T extends string = string> {\n value: T;\n label: string;\n /** Glyph in the icon / context variants. */\n icon?: ReactNode;\n /** Context row — error color on hover. */\n danger?: boolean;\n}\n\nexport interface DropdownProps<T extends string = string> {\n options: readonly DropdownOption<T>[];\n value?: T;\n defaultValue?: T;\n onChange?: (value: T) => void;\n /**\n * `field` — form select (Input chrome).\n * `icon` — header language control: 30×30 panel button + flag menu.\n * `selector` — filter [+] : multi-select, kit Checkbox, OK.\n * `context` — portal at `anchor`. Host opens it from `onContextMenu`.\n */\n variant?: DropdownVariant;\n /** Checked keys (`selector`). */\n selected?: readonly T[];\n defaultSelected?: readonly T[];\n onSelectedChange?: (selected: T[]) => void;\n /** Caption above the field. Omit for a bare trigger. */\n label?: ReactNode;\n /** Stretch to the parent. Default hugs the selected label. */\n fullWidth?: boolean;\n /** Fixed width (px if number). Omit for content width. */\n width?: number | string;\n disabled?: boolean;\n className?: string;\n id?: string;\n 'aria-label'?: string;\n /** Pointer (`variant=\"context\"`). `null` / omit — closed. */\n anchor?: { x: number; y: number } | null;\n /** Backdrop, Escape, pick (`variant=\"context\"`). */\n onClose?: () => void;\n}\n\n/** Form select, header language icon, filter [+], or a right-click menu. */\nexport function Dropdown<T extends string = string>({\n options,\n value,\n defaultValue,\n onChange,\n variant = 'field',\n selected,\n defaultSelected,\n onSelectedChange,\n label,\n fullWidth = false,\n width,\n disabled = false,\n className,\n id,\n 'aria-label': ariaLabel,\n anchor,\n onClose,\n}: DropdownProps<T>) {\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const listId = `${inputId}-list`;\n const controlled = value !== undefined;\n const [inner, setInner] = useState<T>(\n () => (defaultValue ?? options[0]?.value ?? ('' as T)),\n );\n const current = controlled ? value : inner;\n\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLElement>(null);\n const closeTimer = useRef<number | null>(null);\n\n const [present, setPresent] = useState(false);\n const [open, setOpen] = useState(false);\n const [activeIdx, setActiveIdx] = useState(-1);\n const [menuBox, setMenuBox] = useState<{ top: number; left: number; width: number } | null>(\n null,\n );\n\n const isIcon = variant === 'icon';\n const isSelector = variant === 'selector';\n const isContext = variant === 'context';\n const isFlyout = isIcon || isSelector;\n const pointRef = useRef<{ x: number; y: number } | null>(null);\n const currentOpt = options.find((opt) => opt.value === current) ?? options[0];\n const selectedIdx = Math.max(\n 0,\n options.findIndex((opt) => opt.value === current),\n );\n const selectedCtrl = selected !== undefined;\n const [innerSelected, setInnerSelected] = useState<T[]>(() => [...(defaultSelected ?? [])]);\n const picked = new Set(selectedCtrl ? selected : innerSelected);\n\n const placeMenu = (menu?: HTMLElement | null) => {\n const node = menu === undefined ? menuRef.current : menu;\n if (isContext) {\n const p = pointRef.current;\n if (!p) return;\n const pos = placeFixedPoint(p.x, p.y, node);\n setMenuBox((cur) => {\n const next = { ...pos, width: 0 };\n if (cur && cur.top === next.top && cur.left === next.left && cur.width === next.width) {\n return cur;\n }\n return next;\n });\n return;\n }\n const el = triggerRef.current;\n if (!el) return;\n const r = el.getBoundingClientRect();\n const pos = placeFixedMenu(r, node, isIcon ? 6 : 4);\n setMenuBox((cur) => {\n const next = { ...pos, width: r.width };\n if (cur && cur.top === next.top && cur.left === next.left && cur.width === next.width) {\n return cur;\n }\n return next;\n });\n };\n\n const menuCallbackRef = (node: HTMLElement | null) => {\n menuRef.current = node;\n if (node) placeMenu(node);\n };\n\n const openMenu = () => {\n if (disabled) return;\n if (closeTimer.current != null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n placeMenu();\n setPresent(true);\n setActiveIdx(isContext ? 0 : selectedIdx);\n if (isFlyout) {\n setOpen(true);\n return;\n }\n requestAnimationFrame(() => setOpen(true));\n };\n\n const closeMenu = () => {\n if (isContext) {\n onClose?.();\n return;\n }\n setOpen(false);\n if (isFlyout) {\n setPresent(false);\n setMenuBox(null);\n return;\n }\n if (closeTimer.current != null) window.clearTimeout(closeTimer.current);\n closeTimer.current = window.setTimeout(() => {\n setPresent(false);\n setMenuBox(null);\n closeTimer.current = null;\n }, CLOSE_MS);\n };\n\n // TODO: `variant=\"context\"` mirrors the `anchor` prop into open/present/position state so the\n // CLOSE_MS exit animation can outlive the prop. Deriving it instead means lifting that timer\n // out of the component — tracked separately; suppressed here rather than half-refactored.\n /* eslint-disable react-hooks/set-state-in-effect */\n useLayoutEffect(() => {\n if (!isContext) return;\n if (anchor) {\n pointRef.current = { x: anchor.x, y: anchor.y };\n if (closeTimer.current != null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n setActiveIdx(0);\n setPresent(true);\n setOpen(true);\n placeMenu();\n return;\n }\n setOpen(false);\n setPresent(false);\n setMenuBox(null);\n pointRef.current = null;\n }, [isContext, anchor]);\n /* eslint-enable react-hooks/set-state-in-effect */\n\n useLayoutEffect(() => {\n if (!present || isContext) return;\n placeMenu();\n }, [present, isIcon, isSelector]);\n\n useEffect(() => {\n if (!present) return;\n const onDoc = (e: MouseEvent) => {\n const t = e.target as Node;\n if (rootRef.current?.contains(t)) return;\n if (menuRef.current?.contains(t)) return;\n closeMenu();\n };\n const onReposition = () => placeMenu();\n document.addEventListener('mousedown', onDoc);\n window.addEventListener('resize', onReposition);\n window.addEventListener('scroll', onReposition, true);\n return () => {\n document.removeEventListener('mousedown', onDoc);\n window.removeEventListener('resize', onReposition);\n window.removeEventListener('scroll', onReposition, true);\n };\n }, [present]);\n\n useEffect(\n () => () => {\n if (closeTimer.current != null) window.clearTimeout(closeTimer.current);\n },\n [],\n );\n\n const pick = (next: T) => {\n if (!isContext && !controlled) setInner(next);\n onChange?.(next);\n closeMenu();\n if (!isContext) triggerRef.current?.focus();\n };\n\n const toggle = (key: T) => {\n const cur = [...(selected ?? innerSelected)];\n const next = picked.has(key) ? cur.filter((v) => v !== key) : [...cur, key];\n if (!selectedCtrl) setInnerSelected(next);\n onSelectedChange?.(next);\n };\n\n const onTriggerKey = (e: ReactKeyboardEvent<HTMLButtonElement>) => {\n if (disabled) return;\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!open) {\n openMenu();\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n const opt = options[activeIdx];\n if (!opt) return;\n if (isSelector) toggle(opt.value);\n else pick(opt.value);\n } else {\n setActiveIdx((i) => Math.min(options.length - 1, (i < 0 ? selectedIdx : i) + 1));\n }\n } else if (e.key === 'Escape' && present) {\n e.preventDefault();\n closeMenu();\n } else if (open && e.key === 'ArrowUp') {\n e.preventDefault();\n setActiveIdx((i) => Math.max(0, (i < 0 ? selectedIdx : i) - 1));\n }\n };\n\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n closeMenu();\n return;\n }\n if (!isContext) return;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActiveIdx((i) => Math.min(options.length - 1, (i < 0 ? 0 : i) + 1));\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActiveIdx((i) => Math.max(0, (i < 0 ? 0 : i) - 1));\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const opt = options[activeIdx];\n if (opt) pick(opt.value);\n }\n };\n document.addEventListener('keydown', onKey, true);\n return () => document.removeEventListener('keydown', onKey, true);\n }, [open, isContext, activeIdx, options]);\n\n const optionRows = options.map((opt, i) => {\n const isOn = isSelector ? picked.has(opt.value) : !isContext && opt.value === current;\n const isActive = i === activeIdx;\n const optId = `${listId}-opt-${i}`;\n if (isSelector) {\n return (\n <li\n key={opt.value === '' ? `__empty-${i}` : opt.value}\n role=\"option\"\n aria-selected={isOn}\n onMouseEnter={() => setActiveIdx(i)}\n >\n <Checkbox\n id={optId}\n checked={isOn}\n label={opt.label}\n className={[styles.selectorOption, isActive ? styles.selectorOptionActive : '']\n .filter(Boolean)\n .join(' ')}\n onChange={() => toggle(opt.value)}\n />\n </li>\n );\n }\n if (isContext) {\n return (\n <li key={opt.value === '' ? `__empty-${i}` : opt.value} role=\"presentation\">\n <button\n type=\"button\"\n id={optId}\n role=\"menuitem\"\n className={[\n styles.contextOption,\n opt.danger ? styles.contextDanger : '',\n isActive ? styles.contextOptionActive : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseEnter={() => setActiveIdx(i)}\n onClick={() => pick(opt.value)}\n >\n {opt.icon ? <span className={styles.contextIcon}>{opt.icon}</span> : null}\n {opt.label}\n </button>\n </li>\n );\n }\n return (\n <li key={opt.value === '' ? `__empty-${i}` : opt.value} role=\"presentation\">\n <button\n type=\"button\"\n id={optId}\n role=\"option\"\n aria-selected={isOn}\n className={[\n isIcon ? styles.iconOption : styles.option,\n isOn ? (isIcon ? styles.iconOptionSelected : styles.optionSelected) : '',\n isActive ? (isIcon ? styles.iconOptionActive : styles.optionActive) : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onMouseEnter={() => setActiveIdx(i)}\n onClick={() => pick(opt.value)}\n >\n {isIcon ? (\n <>\n {opt.icon ? <span className={styles.flagIcon}>{opt.icon}</span> : null}\n <span className={styles.iconLabel}>{opt.label}</span>\n </>\n ) : (\n opt.label\n )}\n </button>\n </li>\n );\n });\n\n const trigger = (\n <button\n ref={triggerRef}\n type=\"button\"\n id={inputId}\n className={\n isSelector\n ? [\n styles.iconTrigger,\n styles.selectorTrigger,\n open ? styles.selectorTriggerOpen : '',\n ]\n .filter(Boolean)\n .join(' ')\n : isIcon\n ? styles.iconTrigger\n : [styles.trigger, open ? styles.triggerOpen : ''].filter(Boolean).join(' ')\n }\n disabled={disabled}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={present ? listId : undefined}\n aria-label={ariaLabel}\n onClick={() => (open ? closeMenu() : openMenu())}\n onKeyDown={onTriggerKey}\n >\n {isSelector ? (\n <PlusIcon size={16} />\n ) : isIcon ? (\n currentOpt?.icon ? <span className={styles.flagIcon}>{currentOpt.icon}</span> : null\n ) : (\n <>\n <span className={styles.value}>{currentOpt?.label ?? ''}</span>\n {open ? (\n <ArrowDropUpIcon className={styles.caret} size={18} />\n ) : (\n <ArrowDropDownIcon className={styles.caret} size={18} />\n )}\n </>\n )}\n </button>\n );\n\n const listProps = {\n id: listId,\n role: (isContext ? 'menu' : 'listbox') as 'menu' | 'listbox',\n 'aria-activedescendant': activeIdx >= 0 ? `${listId}-opt-${activeIdx}` : undefined,\n };\n\n const menu =\n present &&\n menuBox &&\n createPortal(\n isSelector ? (\n <div\n ref={menuCallbackRef}\n className={styles.selectorMenu}\n style={{ position: 'fixed', top: menuBox.top, left: menuBox.left }}\n >\n <ul className={styles.selectorList} {...listProps}>\n {optionRows}\n </ul>\n <div className={styles.selectorFooter}>\n <button type=\"button\" className={styles.selectorOk} onClick={closeMenu}>\n OK\n </button>\n </div>\n </div>\n ) : (\n <ul\n ref={menuCallbackRef}\n className={\n isContext\n ? styles.contextMenu\n : isIcon\n ? styles.iconMenu\n : [styles.menu, open ? styles.menuOpen : ''].filter(Boolean).join(' ')\n }\n style={\n isContext || isIcon\n ? { position: 'fixed', top: menuBox.top, left: menuBox.left }\n : {\n position: 'fixed',\n top: menuBox.top,\n left: menuBox.left,\n minWidth: menuBox.width,\n width: fullWidth || width != null ? menuBox.width : 'max-content',\n }\n }\n {...listProps}\n >\n {optionRows}\n </ul>\n ),\n document.body,\n );\n\n const tip = isSelector ? ariaLabel : isIcon ? currentOpt?.label : undefined;\n\n const backdrop =\n isContext &&\n present &&\n createPortal(\n <div\n // Pointer-only dismiss surface; keyboard users close with Escape, so keep it\n // out of the accessibility tree instead of giving it a role and tab stop.\n role=\"presentation\"\n className={styles.contextBackdrop}\n onClick={closeMenu}\n onContextMenu={(e) => {\n e.preventDefault();\n closeMenu();\n }}\n />,\n document.body,\n );\n\n if (isContext) {\n if (!anchor) return null;\n return (\n <>\n {backdrop}\n {menu}\n </>\n );\n }\n\n return (\n <FieldCaption label={label} htmlFor={inputId} fullWidth={!isFlyout && fullWidth}>\n <div\n ref={rootRef}\n className={[\n styles.root,\n isFlyout ? styles.iconRoot : '',\n !isFlyout && (fullWidth || width != null) ? styles.fill : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={\n isFlyout || width == null\n ? undefined\n : { width: typeof width === 'number' ? `${width}px` : width }\n }\n >\n {tip ? <Tip content={tip}>{trigger}</Tip> : trigger}\n {menu}\n </div>\n </FieldCaption>\n );\n}\n","import type { ReactNode } from 'react';\n\n/** Option in a chip popover. */\nexport interface FilterOption {\n id: string;\n label: string;\n /** Extra count on the right (selected instruments, members). */\n count?: number;\n disabled?: boolean;\n /** Tip — why disabled, etc. */\n title?: string;\n /** Leading glyph. */\n icon?: ReactNode;\n}\n\n/** Radio group under the options. */\nexport interface FilterRadioGroup {\n label: string;\n options: FilterOption[];\n selected: string;\n onChange: (id: string) => void;\n}\n\n/**\n * One chip. The bar does not know about stores or hosts — bind through this spec.\n */\nexport interface FilterSpec {\n key: string;\n name: string;\n /** `single` — radio, closes on pick. `multi` — checkboxes. */\n mode: 'single' | 'multi';\n options: FilterOption[];\n /** Selected ids. Empty id `''` is neutral (no chip value). */\n selected: string[];\n onChange: (selected: string[]) => void;\n /** Multi: master «All» + divider. */\n masterAll?: boolean;\n applyScope?: FilterRadioGroup;\n /**\n * × removes the chip immediately.\n * Empty `options` and no `content` — tag chip, no popover.\n */\n removeOnly?: boolean;\n /** Always shown; × only resets. */\n pinned?: boolean;\n /** Override chip value text. */\n summary?: string;\n /** When set, first × uses this instead of «no summary». */\n atDefault?: boolean;\n onReset?: () => void;\n /** Custom popover body. */\n content?: ReactNode;\n footerActions?: { label: string; onClick: () => void }[];\n optionActions?: Record<string, { label: string; title?: string; onClick: () => void }>;\n}\n\n/** Row in the [+] menu. */\nexport interface FilterMenuItem {\n key: string;\n name: string;\n}\n\nexport function isTagChip(spec: FilterSpec): boolean {\n return Boolean(spec.removeOnly && spec.options.length === 0 && spec.content == null);\n}\n\nexport function summarize(spec: FilterSpec): string | undefined {\n if (spec.summary !== undefined) {\n return spec.summary === '' ? undefined : spec.summary;\n }\n const labels = spec.selected\n .filter((id) => id !== '')\n .map((id) => spec.options.find((o) => o.id === id)?.label ?? id);\n const scope = spec.applyScope;\n if (scope && scope.selected !== scope.options[0]?.id) {\n const scopeLabel = scope.options.find((o) => o.id === scope.selected)?.label;\n if (scopeLabel) labels.push(scopeLabel);\n }\n return labels.length > 0 ? labels.join(', ') : undefined;\n}\n\nexport function isSpecAtDefault(spec: FilterSpec): boolean {\n if (spec.atDefault !== undefined) return spec.atDefault;\n return summarize(spec) === undefined;\n}\n\nexport function resetSpec(spec: FilterSpec): void {\n if (spec.onReset) {\n spec.onReset();\n return;\n }\n spec.onChange([]);\n if (spec.applyScope) {\n const first = spec.applyScope.options[0]?.id;\n if (first !== undefined && spec.applyScope.selected !== first) {\n spec.applyScope.onChange(first);\n }\n }\n}\n",".root {\n display: flex;\n align-items: center;\n gap: var(--sci-spacing-sm);\n flex-wrap: wrap;\n}\n\n.chipWrap {\n position: relative;\n display: inline-flex;\n}\n\n.chip {\n display: inline-flex;\n align-items: center;\n height: 30px;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-input);\n color: var(--sci-color-text);\n overflow: hidden;\n}\n\n.chipActive {\n border-color: var(--sci-color-accent);\n background: color-mix(in srgb, var(--sci-color-accent) 16%, transparent);\n}\n\n.chipBody {\n display: inline-flex;\n align-items: center;\n align-self: stretch;\n gap: 4px;\n padding: 0 8px 0 10px;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: var(--sci-font-size-sm);\n font-weight: 600;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.chipBody:hover {\n background: var(--sci-color-bg-hover);\n}\n\n.chipBodyStatic {\n cursor: default;\n}\n\n.chipBodyStatic:hover {\n background: transparent;\n}\n\n.chipName {\n color: inherit;\n}\n\n.chipValue {\n color: var(--sci-color-text-secondary);\n font-weight: 400;\n max-width: 220px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.caret {\n flex-shrink: 0;\n color: var(--sci-color-text-secondary);\n}\n\n.chipCloseHost {\n align-self: stretch;\n align-items: stretch;\n}\n\n.chipClose {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n height: 100%;\n padding: 0 8px;\n border: 0;\n background: transparent;\n color: var(--sci-color-text-muted);\n cursor: pointer;\n}\n\n.chipClose:hover {\n background: var(--sci-color-bg-hover);\n color: var(--sci-color-text);\n}\n\n.iconBtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-sm);\n background: var(--sci-color-bg-input);\n color: var(--sci-color-accent);\n cursor: pointer;\n}\n\n.iconBtn:hover:not(:disabled) {\n border-color: var(--sci-color-border-focus);\n background: var(--sci-color-bg-hover);\n}\n\n.iconBtn:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n.popover {\n z-index: 60;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n min-width: 200px;\n max-height: 60vh;\n overflow-y: auto;\n margin: 0;\n padding: var(--sci-spacing-xs);\n border: 1px solid var(--sci-color-border);\n border-radius: var(--sci-radius-md);\n background: var(--sci-color-bg-panel);\n box-shadow: var(--sci-shadow-md);\n}\n\n.row {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border-radius: var(--sci-radius-sm);\n white-space: nowrap;\n}\n\n.row:hover {\n background: var(--sci-color-bg-hover);\n}\n\n.rowAll {\n font-weight: 600;\n}\n\n.optionRow {\n display: flex;\n align-items: center;\n gap: 4px;\n width: 100%;\n}\n\n.optionRow .row {\n flex: 1;\n min-width: 0;\n}\n\n.optionLabel {\n display: inline-flex;\n align-items: baseline;\n gap: 0.4em;\n min-width: 0;\n}\n\n.optionText {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.count {\n margin-left: auto;\n padding-left: 10px;\n color: var(--sci-color-text-muted);\n font-variant-numeric: tabular-nums;\n}\n\n.divider {\n height: 1px;\n margin: 2px 6px;\n background: var(--sci-color-border);\n}\n\n.optionAction {\n flex: none;\n width: 22px;\n height: 22px;\n padding: 0;\n border: 0;\n border-radius: var(--sci-radius-sm);\n background: transparent;\n color: var(--sci-color-text-muted);\n cursor: pointer;\n}\n\n.optionAction:hover {\n color: var(--sci-color-accent);\n background: color-mix(in srgb, var(--sci-color-accent) 14%, transparent);\n}\n\n.applyScope {\n display: flex;\n flex-direction: column;\n margin-top: var(--sci-spacing-xs);\n padding-top: var(--sci-spacing-xs);\n border-top: 1px solid var(--sci-color-border);\n}\n\n.scopeLabel {\n padding: 4px 10px 2px;\n color: var(--sci-color-text-muted);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n.footer {\n display: flex;\n justify-content: flex-end;\n margin-top: 4px;\n padding: 4px 4px 2px;\n border-top: 1px solid var(--sci-color-border);\n}\n\n.footerOk {\n height: 26px;\n padding: 0 12px;\n border-radius: var(--sci-radius-sm);\n border: 1px solid var(--sci-color-accent);\n background: var(--sci-color-accent);\n color: #fff;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.footerOk:hover {\n background: color-mix(in srgb, var(--sci-color-accent) 85%, #000);\n border-color: color-mix(in srgb, var(--sci-color-accent) 85%, #000);\n}\n\n.empty {\n padding: 7px 10px;\n color: var(--sci-color-text-muted);\n font-size: var(--sci-font-size-sm);\n}\n","import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n ArrowDropDownIcon,\n ArrowDropUpIcon,\n CloseIcon,\n SettingsIcon,\n} from '../../icons/buttonIcons';\nimport { Checkbox } from '../Checkbox/Checkbox';\nimport { Dropdown } from '../Dropdown/Dropdown';\nimport { Radio } from '../RadioGroup/Radio';\nimport { RadioGroup } from '../RadioGroup/RadioGroup';\nimport { Tip } from '../Tip/Tip';\nimport { placeFixedMenu } from '../../placeFixedMenu';\nimport {\n isSpecAtDefault,\n isTagChip,\n resetSpec,\n summarize,\n type FilterMenuItem,\n type FilterSpec,\n} from './filterModel';\nimport styles from './Filter.module.css';\n\nexport type { FilterMenuItem, FilterOption, FilterRadioGroup, FilterSpec } from './filterModel';\n\nexport interface FilterProps {\n available: readonly FilterMenuItem[];\n /** Keys added via [+], in add order. */\n active: readonly string[];\n specs: Record<string, FilterSpec>;\n /** Always-visible chips. Not cleared by [×]. */\n pinned?: readonly string[];\n onAdd: (key: string) => void;\n onRemove: (key: string) => void;\n onClear: () => void;\n addLabel?: string;\n clearLabel?: string;\n className?: string;\n}\n\n/**\n * Dynamic filter bar: [+] chips [×].\n * First × on a chip resets to default; second × removes it.\n * [×] drops every chip added through [+].\n */\nexport function Filter({\n available,\n active,\n specs,\n pinned = [],\n onAdd,\n onRemove,\n onClear,\n addLabel = 'Add filter',\n clearLabel = 'Clear filters',\n className,\n}: FilterProps) {\n const [openKey, setOpenKey] = useState<string | null>(null);\n const wrapRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const [menuBox, setMenuBox] = useState<{ top: number; left: number } | null>(null);\n\n const placeMenu = (menu?: HTMLElement | null) => {\n const el = wrapRef.current;\n const node = menu === undefined ? menuRef.current : menu;\n if (!el) return;\n const next = placeFixedMenu(el.getBoundingClientRect(), node, 4);\n setMenuBox((cur) => (cur && cur.top === next.top && cur.left === next.left ? cur : next));\n };\n\n const menuCallbackRef = (node: HTMLDivElement | null) => {\n menuRef.current = node;\n if (node) placeMenu(node);\n };\n\n // The popover only renders under `openKey`, so a stale box is never visible: on reopen\n // `menuCallbackRef` repositions it with real dimensions before paint.\n useLayoutEffect(() => {\n if (openKey) placeMenu();\n }, [openKey]);\n\n useEffect(() => {\n if (!openKey) return;\n const onDoc = (e: MouseEvent) => {\n const t = e.target as Node;\n if (wrapRef.current?.contains(t)) return;\n if (menuRef.current?.contains(t)) return;\n setOpenKey(null);\n };\n const onReposition = () => placeMenu();\n document.addEventListener('mousedown', onDoc);\n window.addEventListener('resize', onReposition);\n window.addEventListener('scroll', onReposition, true);\n return () => {\n document.removeEventListener('mousedown', onDoc);\n window.removeEventListener('resize', onReposition);\n window.removeEventListener('scroll', onReposition, true);\n };\n }, [openKey]);\n\n const toggleChip = (key: string) => setOpenKey((cur) => (cur === key ? null : key));\n\n const handleClose = (spec: FilterSpec) => {\n if (spec.removeOnly) {\n if (!spec.pinned) onRemove(spec.key);\n setOpenKey(null);\n return;\n }\n if (!isSpecAtDefault(spec)) {\n resetSpec(spec);\n return;\n }\n if (spec.pinned) return;\n onRemove(spec.key);\n setOpenKey(null);\n };\n\n const chips = [...pinned, ...active.filter((k) => !pinned.includes(k))];\n\n const addOptions = available.map((item) => ({ value: item.key, label: item.name }));\n\n return (\n <div className={[styles.root, className].filter(Boolean).join(' ')}>\n <Dropdown\n variant=\"selector\"\n options={addOptions}\n selected={[...active]}\n onSelectedChange={(next) => {\n for (const key of next) if (!active.includes(key)) onAdd(key);\n for (const key of active) if (!next.includes(key)) onRemove(key);\n }}\n aria-label={addLabel}\n />\n\n {chips.map((key) => {\n const spec = specs[key];\n if (!spec) return null;\n const value = summarize(spec);\n const tagOnly = isTagChip(spec);\n const isOpen = openKey === key;\n const atDefault = isSpecAtDefault(spec);\n const on = Boolean(value) || isOpen || tagOnly;\n const closeTip = spec.pinned\n ? 'Reset filter'\n : spec.removeOnly || tagOnly || atDefault\n ? 'Remove filter'\n : 'Reset filter';\n return (\n <div\n key={key}\n className={styles.chipWrap}\n ref={isOpen ? wrapRef : undefined}\n >\n <div className={[styles.chip, on ? styles.chipActive : ''].filter(Boolean).join(' ')}>\n {tagOnly ? (\n <span className={[styles.chipBody, styles.chipBodyStatic].join(' ')}>\n <span className={styles.chipName}>{spec.name}</span>\n </span>\n ) : (\n <button\n type=\"button\"\n className={styles.chipBody}\n aria-expanded={isOpen}\n onClick={() => toggleChip(key)}\n >\n <span className={styles.chipName}>{spec.name}</span>\n {value ? <span className={styles.chipValue}>: {value}</span> : null}\n {isOpen ? (\n <ArrowDropUpIcon className={styles.caret} size={16} />\n ) : (\n <ArrowDropDownIcon className={styles.caret} size={16} />\n )}\n </button>\n )}\n <Tip content={closeTip} className={styles.chipCloseHost}>\n <button\n type=\"button\"\n className={styles.chipClose}\n aria-label={`${closeTip} «${spec.name}»`}\n onClick={() => handleClose(spec)}\n >\n <CloseIcon size={12} />\n </button>\n </Tip>\n </div>\n </div>\n );\n })}\n\n <Tip content={clearLabel}>\n <button\n type=\"button\"\n className={styles.iconBtn}\n disabled={active.length === 0}\n aria-label={clearLabel}\n onClick={() => {\n onClear();\n setOpenKey(null);\n }}\n >\n <CloseIcon size={16} />\n </button>\n </Tip>\n\n {openKey &&\n menuBox &&\n specs[openKey] &&\n !isTagChip(specs[openKey]) &&\n createPortal(\n <div\n ref={menuCallbackRef}\n className={styles.popover}\n style={{ position: 'fixed', top: menuBox.top, left: menuBox.left }}\n >\n <ChipPopover spec={specs[openKey]} onClose={() => setOpenKey(null)} />\n </div>,\n document.body,\n )}\n </div>\n );\n}\n\nfunction ChipPopover({ spec, onClose }: { spec: FilterSpec; onClose: () => void }) {\n return (\n <>\n {spec.content != null ? (\n spec.content\n ) : spec.mode === 'single' ? (\n <SingleOptions spec={spec} onPick={onClose} />\n ) : (\n <MultiOptions spec={spec} />\n )}\n {spec.applyScope ? <ApplyScope group={spec.applyScope} /> : null}\n {spec.footerActions && spec.footerActions.length > 0 ? (\n <div className={styles.footer}>\n {spec.footerActions.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n className={styles.footerOk}\n onClick={() => {\n onClose();\n action.onClick();\n }}\n >\n {action.label}\n </button>\n ))}\n </div>\n ) : null}\n </>\n );\n}\n\nfunction optionLabel(o: FilterSpec['options'][number]): ReactNode {\n return (\n <span className={styles.optionLabel}>\n {o.icon}\n <span className={styles.optionText}>{o.label}</span>\n {o.count !== undefined ? <span className={styles.count}>{o.count}</span> : null}\n </span>\n );\n}\n\nfunction SingleOptions({ spec, onPick }: { spec: FilterSpec; onPick: () => void }) {\n const current = spec.selected[0] ?? '';\n return (\n <RadioGroup\n value={current}\n onChange={(_, id) => {\n spec.onChange([id]);\n onPick();\n }}\n >\n {spec.options.map((o) => (\n <Tip key={o.id} content={o.title} block>\n <Radio\n value={o.id}\n label={optionLabel(o)}\n disabled={o.disabled}\n className={styles.row}\n />\n </Tip>\n ))}\n </RadioGroup>\n );\n}\n\nfunction MultiOptions({ spec }: { spec: FilterSpec }) {\n const selected = new Set(spec.selected);\n const enabledIds = spec.options.filter((o) => !o.disabled).map((o) => o.id);\n const allChecked = enabledIds.length > 0 && enabledIds.every((id) => selected.has(id));\n const someChecked = enabledIds.some((id) => selected.has(id)) && !allChecked;\n\n return (\n <>\n {spec.masterAll ? (\n <>\n <Checkbox\n checked={allChecked}\n indeterminate={someChecked}\n label=\"All\"\n className={[styles.row, styles.rowAll].join(' ')}\n onChange={() => {\n if (allChecked) {\n spec.onChange(spec.selected.filter((id) => !enabledIds.includes(id)));\n } else {\n const next = new Set(spec.selected);\n for (const id of enabledIds) next.add(id);\n spec.onChange([...next]);\n }\n }}\n />\n <div className={styles.divider} aria-hidden=\"true\" />\n </>\n ) : null}\n {spec.options.map((o) => {\n const action = spec.optionActions?.[o.id];\n return (\n <Tip key={o.id} content={o.title} block>\n <div className={styles.optionRow}>\n <Checkbox\n checked={selected.has(o.id)}\n disabled={o.disabled}\n label={optionLabel(o)}\n className={styles.row}\n onChange={(e) => {\n const next = new Set(selected);\n if (e.target.checked) next.add(o.id);\n else next.delete(o.id);\n spec.onChange([...next]);\n }}\n />\n {action ? (\n <Tip content={action.title ?? action.label}>\n <button\n type=\"button\"\n className={styles.optionAction}\n aria-label={action.label}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n action.onClick();\n }}\n >\n <SettingsIcon size={12} />\n </button>\n </Tip>\n ) : null}\n </div>\n </Tip>\n );\n })}\n </>\n );\n}\n\nfunction ApplyScope({ group }: { group: NonNullable<FilterSpec['applyScope']> }) {\n return (\n <div className={styles.applyScope}>\n <div className={styles.scopeLabel}>{group.label}</div>\n <RadioGroup value={group.selected} onChange={(_, id) => group.onChange(id)}>\n {group.options.map((o) => (\n <Radio key={o.id} value={o.id} label={o.label} className={styles.row} />\n ))}\n </RadioGroup>\n </div>\n );\n}\n","import { useId, useMemo } from 'react';\nimport avatarSvg from './marks/scinverse-avatar.svg?raw';\nimport iconSvg from './marks/scinverse-icon.svg?raw';\nimport logoSvg from './marks/scinverse-logo.svg?raw';\nimport ncSvg from './marks/nc-icon.svg?raw';\nimport ncConnectionSvg from './marks/nc-scinverse-icon.svg?raw';\nimport ohsSvg from './marks/ohs-icon.svg?raw';\nimport ohsConnectionSvg from './marks/ohs-scinverse-icon.svg?raw';\nimport uiKitSvg from './marks/ui-kit-icon.svg?raw';\nimport uiKitConnectionSvg from './marks/ui-kit-scinverse-icon.svg?raw';\nimport { SvgIcon, type SvgIconProps } from './SvgIcon';\n\nexport type BrandMarkProps = Omit<SvgIconProps, 'component' | 'inheritViewBox' | 'children'>;\n\nfunction prefixIds(svg: string, prefix: string): string {\n return svg\n .replace(/id=\"([^\"]+)\"/g, `id=\"${prefix}-$1\"`)\n .replace(/url\\(#([^)]+)\\)/g, `url(#${prefix}-$1)`);\n}\n\nfunction paintCurrentColor(svg: string): string {\n return svg.replace(/(fill|stroke)=\"#000(?:000)?\"/gi, '$1=\"currentColor\"');\n}\n\nfunction markParts(source: string): { viewBox: string; inner: string } {\n const viewBox = source.match(/viewBox=\"([^\"]+)\"/)?.[1] ?? '0 0 64 64';\n const inner = source.replace(/^[\\s\\S]*?<svg[^>]*>/, '').replace(/<\\/svg>\\s*$/, '');\n return { viewBox, inner };\n}\n\n/** Canonical brand SVG. Ink is currentColor; clip and mask ids are unique per instance. */\nfunction BrandMark({ source, title, ...rest }: BrandMarkProps & { source: string }) {\n const prefix = useId().replace(/[^a-zA-Z0-9]/g, '');\n const { viewBox, inner } = useMemo(() => {\n const painted = paintCurrentColor(prefixIds(source, prefix));\n return markParts(painted);\n }, [source, prefix]);\n\n return (\n <SvgIcon viewBox={viewBox} fill=\"currentColor\" title={title} {...rest}>\n <g dangerouslySetInnerHTML={{ __html: inner }} />\n </SvgIcon>\n );\n}\n\n/** Geometric globe. Favicon, tab, small chrome. */\nexport function ScinverseIcon(props: BrandMarkProps) {\n return <BrandMark source={iconSvg} {...props} />;\n}\n\n/** Spatial globe. Header, README, lockup. */\nexport function ScinverseLogo(props: BrandMarkProps) {\n return <BrandMark source={logoSvg} {...props} />;\n}\n\n/** Detailed globe. Org avatar, profile, large circles. No outer ring. */\nexport function ScinverseAvatar(props: BrandMarkProps) {\n return <BrandMark source={avatarSvg} {...props} />;\n}\n\n/** OHS on the Scinverse globe — product lockup in headers. */\nexport function ConnectionOhsIcon(props: BrandMarkProps) {\n return <BrandMark source={ohsConnectionSvg} {...props} />;\n}\n\n/** NC on the Scinverse globe — product lockup in headers. */\nexport function ConnectionNcIcon(props: BrandMarkProps) {\n return <BrandMark source={ncConnectionSvg} {...props} />;\n}\n\n/** UI kit on the Scinverse globe — product lockup in headers. */\nexport function ConnectionUiKitIcon(props: BrandMarkProps) {\n return <BrandMark source={uiKitConnectionSvg} {...props} />;\n}\n\n/** OHS — ring with segment cuts and a bar chart. */\nexport function ServiceOhsIcon(props: BrandMarkProps) {\n return <BrandMark source={ohsSvg} {...props} />;\n}\n\n/** NC — bell in a ring. */\nexport function ServiceNcIcon(props: BrandMarkProps) {\n return <BrandMark source={ncSvg} {...props} />;\n}\n\n/** UI kit — palette. */\nexport function ServiceUiKitIcon(props: BrandMarkProps) {\n return <BrandMark source={uiKitSvg} {...props} />;\n}\n","import { useId, useMemo } from 'react';\nimport deSvg from './flags/de.svg?raw';\nimport enSvg from './flags/en.svg?raw';\nimport esSvg from './flags/es.svg?raw';\nimport frSvg from './flags/fr.svg?raw';\nimport itSvg from './flags/it.svg?raw';\nimport nlSvg from './flags/nl.svg?raw';\nimport ptSvg from './flags/pt.svg?raw';\nimport ruSvg from './flags/ru.svg?raw';\nimport zhSvg from './flags/zh.svg?raw';\nimport { SvgIcon, type SvgIconProps } from './SvgIcon';\n\nexport type FlagIconProps = Omit<SvgIconProps, 'component' | 'inheritViewBox' | 'children'>;\n\nfunction prefixIds(svg: string, prefix: string): string {\n return svg\n .replace(/id=\"([^\"]+)\"/g, `id=\"${prefix}-$1\"`)\n .replace(/url\\(#([^)]+)\\)/g, `url(#${prefix}-$1)`);\n}\n\nfunction markParts(source: string): { viewBox: string; inner: string } {\n const viewBox = source.match(/viewBox=\"([^\"]+)\"/)?.[1] ?? '0 0 512 512';\n const inner = source.replace(/^[\\s\\S]*?<svg[^>]*>/, '').replace(/<\\/svg>\\s*$/, '');\n return { viewBox, inner };\n}\n\n/**\n * Circular Language Icons (country glyphs for locale).\n * Multicolor — keep native fills; mask ids are unique per instance.\n */\nfunction FlagIcon({ source, title, ...rest }: FlagIconProps & { source: string }) {\n const prefix = useId().replace(/[^a-zA-Z0-9]/g, '');\n const { viewBox, inner } = useMemo(() => markParts(prefixIds(source, prefix)), [source, prefix]);\n\n return (\n <SvgIcon viewBox={viewBox} title={title} {...rest}>\n <g dangerouslySetInnerHTML={{ __html: inner }} />\n </SvgIcon>\n );\n}\n\n/** English — circle-flags:gb */\nexport function FlagEnIcon(props: FlagIconProps) {\n return <FlagIcon source={enSvg} {...props} />;\n}\n\n/** French — circle-flags:fr */\nexport function FlagFrIcon(props: FlagIconProps) {\n return <FlagIcon source={frSvg} {...props} />;\n}\n\n/** Russian — circle-flags:ru */\nexport function FlagRuIcon(props: FlagIconProps) {\n return <FlagIcon source={ruSvg} {...props} />;\n}\n\n/** German — circle-flags:de */\nexport function FlagDeIcon(props: FlagIconProps) {\n return <FlagIcon source={deSvg} {...props} />;\n}\n\n/** Italian — circle-flags:it */\nexport function FlagItIcon(props: FlagIconProps) {\n return <FlagIcon source={itSvg} {...props} />;\n}\n\n/** Spanish — circle-flags:es */\nexport function FlagEsIcon(props: FlagIconProps) {\n return <FlagIcon source={esSvg} {...props} />;\n}\n\n/** Portuguese — circle-flags:pt */\nexport function FlagPtIcon(props: FlagIconProps) {\n return <FlagIcon source={ptSvg} {...props} />;\n}\n\n/** Dutch — circle-flags:nl */\nexport function FlagNlIcon(props: FlagIconProps) {\n return <FlagIcon source={nlSvg} {...props} />;\n}\n\n/** Chinese */\nexport function FlagZhIcon(props: FlagIconProps) {\n return <FlagIcon source={zhSvg} {...props} />;\n}\n","import { createSvgIcon } from './createSvgIcon';\n\n/** Venue / exchange — building with columns. */\nexport const ExchangeIcon = createSvgIcon(\n <>\n <path d=\"M3 9.5 12 4l9 5.5\" />\n <path d=\"M4 9.5h16\" />\n <path d=\"M6 9.5v8M10 9.5v8M14 9.5v8M18 9.5v8\" />\n <path d=\"M3.5 20.5h17\" />\n </>,\n 'Exchange',\n);\n\n/** Plug — external integration. */\nexport const IntegrationIcon = createSvgIcon(\n <>\n <path d=\"M9 3v5M15 3v5\" />\n <path d=\"M6 8h12v3a6 6 0 0 1-12 0z\" />\n <path d=\"M12 17v4\" />\n </>,\n 'Integration',\n);\n\n/** Broadcast waves — news. */\nexport const NewsIcon = createSvgIcon(\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.472 6L2 12l3.472 6H7.5l-3.472-6L7.5 6zM12 13.5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3M22 12l-3.472-6H16.5l3.472 6l-3.472 6h2.028zM8.315 8L6 12l2.315 4h2.028l-2.315-4l2.314-4zm10.028 4l-2.315-4H14l2.315 4L14 16h2.028z\"\n />,\n 'News',\n { kind: 'fill' },\n);\n\n/** Stacked hosts — system / infrastructure. */\nexport const SystemIcon = createSvgIcon(\n <>\n <rect x=\"3.5\" y=\"4\" width=\"17\" height=\"7\" rx=\"1.5\" />\n <rect x=\"3.5\" y=\"13\" width=\"17\" height=\"7\" rx=\"1.5\" />\n <path d=\"M7 7.5h.01M7 16.5h.01\" />\n </>,\n 'System',\n);\n\n/** Envelope — messages / incident log. */\nexport const MessagesIcon = createSvgIcon(\n <>\n <rect x=\"3\" y=\"5.5\" width=\"18\" height=\"13\" rx=\"2\" />\n <path d=\"m4 7 8 5.5L20 7\" />\n </>,\n 'Messages',\n);\n\n/** Question in a circle — help. */\nexport const HelpIcon = createSvgIcon(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M9.2 9.3a2.8 2.8 0 0 1 5.4 1c0 1.9-2.6 2.2-2.6 3.7\" />\n <path d=\"M12 17.3h.01\" />\n </>,\n 'Help',\n);\n\n/** Bell — notifications. */\nexport const BellIcon = createSvgIcon(\n <>\n <path d=\"M18 8.5a6 6 0 0 0-12 0c0 6.5-2.5 8.5-2.5 8.5h17S18 15 18 8.5\" />\n <path d=\"M13.7 20.5a2 2 0 0 1-3.4 0\" />\n </>,\n 'Bell',\n);\n\n/** User avatar. */\nexport const UserIcon = createSvgIcon(\n <>\n <path d=\"M19 20.5v-1.8a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v1.8\" />\n <circle cx=\"12\" cy=\"7.5\" r=\"3.8\" />\n </>,\n 'User',\n);\n","import { createSvgIcon } from './createSvgIcon';\n\nexport const InfoLabelIcon = createSvgIcon(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"8.5\" />\n <path d=\"M12 11v5M12 8h.01\" />\n </>,\n 'InfoLabel',\n);\n\nexport const OkLabelIcon = createSvgIcon(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"8.5\" />\n <path d=\"M8.2 12.3l2.6 2.6 5-5.2\" />\n </>,\n 'OkLabel',\n);\n\nexport const WarnLabelIcon = createSvgIcon(\n <>\n <path d=\"M12 4.2l8.2 14.6H3.8L12 4.2z\" />\n <path d=\"M12 10v4M12 16.6h.01\" />\n </>,\n 'WarnLabel',\n);\n\nexport const ErrorLabelIcon = createSvgIcon(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"8.5\" />\n <path d=\"M9 9l6 6M15 9l-6 6\" />\n </>,\n 'ErrorLabel',\n);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Viewport-fixed menu at a pointer, flipped above when it would overflow. */
|
|
2
|
+
export declare function placeFixedPoint(x: number, y: number, menu: HTMLElement | null): {
|
|
3
|
+
top: number;
|
|
4
|
+
left: number;
|
|
5
|
+
};
|
|
6
|
+
/** Viewport-fixed menu under `anchor`, flipped above when it would overflow. */
|
|
7
|
+
export declare function placeFixedMenu(anchor: DOMRect, menu: HTMLElement | null, gap: number): {
|
|
8
|
+
top: number;
|
|
9
|
+
left: number;
|
|
10
|
+
};
|
package/dist/styles.cjs
ADDED
|
File without changes
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
._root_12w6a_1{justify-content:center;align-items:center;gap:var(--sci-spacing-sm);border-radius:var(--sci-radius-sm);min-height:32px;font-family:var(--sci-font-family);font-size:var(--sci-font-size-sm);cursor:pointer;border:1px solid #0000;padding:.4rem .85rem;font-weight:600;line-height:1.2;transition:background .12s,border-color .12s,color .12s;display:inline-flex}._root_12w6a_1:focus,._root_12w6a_1:focus-visible{outline:none}._root_12w6a_1:disabled{opacity:.45;cursor:default}._small_12w6a_28{min-height:28px;padding:.22rem .65rem;font-size:.8125rem}._large_12w6a_34{min-height:40px;padding:.55rem 1.1rem;font-size:1rem}._primary_12w6a_40{background:var(--sci-color-accent);border-color:var(--sci-color-accent);color:#fff}._primary_12w6a_40:hover:not(:disabled){background:var(--sci-color-accent-hover);border-color:var(--sci-color-accent-hover)}._secondary_12w6a_51{background:var(--sci-color-bg-input);border-color:var(--sci-color-border);color:var(--sci-color-text)}._secondary_12w6a_51:hover:not(:disabled){border-color:var(--sci-color-border-focus);background:var(--sci-color-bg-hover)}._ghost_12w6a_62{border-color:var(--sci-color-border);color:var(--sci-color-text-secondary);background:0 0}._ghost_12w6a_62:hover:not(:disabled){color:var(--sci-color-text);background:var(--sci-color-bg-hover)}._panel_12w6a_74{background:var(--sci-color-bg-input);border-color:var(--sci-color-border);width:30px;height:30px;min-height:30px;color:var(--sci-color-text-secondary);padding:0;font-size:15px;font-weight:400;line-height:1}._panel_12w6a_74:hover:not(:disabled){border-color:var(--sci-color-border-focus);background:var(--sci-color-bg-hover);color:var(--sci-color-text)}._panel_12w6a_74._small_12w6a_28{width:26px;height:26px;min-height:26px;padding:0}._panel_12w6a_74._large_12w6a_34{width:36px;height:36px;min-height:36px;padding:0}._colored_12w6a_108._primary_12w6a_40{background:var(--sci-button-color);border-color:var(--sci-button-color);color:#fff}._colored_12w6a_108._primary_12w6a_40:hover:not(:disabled){background:color-mix(in srgb, var(--sci-button-color) 82%, #000);border-color:color-mix(in srgb, var(--sci-button-color) 82%, #000)}._colored_12w6a_108._secondary_12w6a_51{color:var(--sci-button-color);border-color:var(--sci-button-color)}._colored_12w6a_108._secondary_12w6a_51:hover:not(:disabled){border-color:var(--sci-button-color);background:color-mix(in srgb, var(--sci-button-color) 12%, transparent);color:var(--sci-button-color)}._colored_12w6a_108._ghost_12w6a_62{color:var(--sci-button-color)}._colored_12w6a_108._ghost_12w6a_62:hover:not(:disabled){color:var(--sci-button-color);background:color-mix(in srgb, var(--sci-button-color) 12%, transparent)}._colored_12w6a_108._panel_12w6a_74{color:var(--sci-button-color)}._colored_12w6a_108._panel_12w6a_74:hover:not(:disabled){color:var(--sci-button-color);border-color:var(--sci-button-color);background:color-mix(in srgb, var(--sci-button-color) 12%, transparent)}._toggledAccent_12w6a_150,._toggledAccent_12w6a_150._primary_12w6a_40,._toggledAccent_12w6a_150._secondary_12w6a_51,._toggledAccent_12w6a_150._ghost_12w6a_62,._toggledAccent_12w6a_150._panel_12w6a_74,._toggledAccent_12w6a_150._colored_12w6a_108{color:var(--sci-color-accent);border-color:color-mix(in srgb, var(--sci-color-accent) 55%, transparent);background:color-mix(in srgb, var(--sci-color-accent) 14%, transparent)}._toggledAccent_12w6a_150:hover:not(:disabled),._toggledAccent_12w6a_150._primary_12w6a_40:hover:not(:disabled),._toggledAccent_12w6a_150._secondary_12w6a_51:hover:not(:disabled),._toggledAccent_12w6a_150._ghost_12w6a_62:hover:not(:disabled),._toggledAccent_12w6a_150._panel_12w6a_74:hover:not(:disabled),._toggledAccent_12w6a_150._colored_12w6a_108:hover:not(:disabled){color:var(--sci-color-accent);border-color:color-mix(in srgb, var(--sci-color-accent) 55%, transparent);background:color-mix(in srgb, var(--sci-color-accent) 20%, transparent)}._toggledAccent_12w6a_150 svg{filter:drop-shadow(0 0 5px color-mix(in srgb, var(--sci-color-accent) 85%, transparent))}._toggledDark_12w6a_177,._toggledDark_12w6a_177._primary_12w6a_40,._toggledDark_12w6a_177._secondary_12w6a_51,._toggledDark_12w6a_177._ghost_12w6a_62,._toggledDark_12w6a_177._panel_12w6a_74,._toggledDark_12w6a_177._colored_12w6a_108,._toggledDark_12w6a_177:hover:not(:disabled),._toggledDark_12w6a_177:focus,._toggledDark_12w6a_177:focus-visible,._toggledDark_12w6a_177._primary_12w6a_40:hover:not(:disabled),._toggledDark_12w6a_177._secondary_12w6a_51:hover:not(:disabled),._toggledDark_12w6a_177._ghost_12w6a_62:hover:not(:disabled),._toggledDark_12w6a_177._panel_12w6a_74:hover:not(:disabled),._toggledDark_12w6a_177._colored_12w6a_108:hover:not(:disabled){color:var(--sci-color-accent);border-color:var(--sci-color-accent);background:var(--sci-color-bg-input)}._root_z6xc1_1{background:var(--sci-color-bg-panel);border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-lg);padding:var(--sci-spacing-lg)}._title_z6xc1_8{margin:0 0 var(--sci-spacing-md);color:var(--sci-color-accent);font-family:var(--sci-font-family-mono);letter-spacing:.08em;text-transform:uppercase;font-size:.7rem;font-weight:500}._root_1oxl8_1{border-radius:var(--sci-radius-sm);width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:1px solid #0000;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px;display:flex}._root_1oxl8_1:hover{background:var(--sci-color-bg-hover)}._selected_1oxl8_21{border-color:var(--sci-color-border-focus);background:var(--sci-color-bg-hover)}._info_1oxl8_26{flex-direction:column;min-width:0;display:flex}._name_1oxl8_32{color:var(--sci-color-text);font-weight:600}._kind_1oxl8_37{color:var(--sci-color-text-muted);font-size:11px}._end_1oxl8_42{flex-shrink:0;align-items:center;display:inline-flex}._dot_1oxl8_48{background:currentColor;border-radius:50%;flex-shrink:0;width:9px;height:9px;display:inline-block;box-shadow:0 0 6px}._root_8pbpz_1{box-sizing:border-box;font-family:var(--sci-font-family);letter-spacing:.04em;text-transform:uppercase;color:var(--sci-color-text-muted);background:var(--sci-color-bg-input);white-space:nowrap;align-items:center;font-weight:600;line-height:1.2;display:inline-flex}._basic_8pbpz_15{border-radius:var(--sci-radius-sm)}._rounded_8pbpz_19{border-radius:var(--sci-radius-lg)}._small_8pbpz_23{padding:2px 5px;font-size:9px}._medium_8pbpz_28{padding:3px 6px;font-size:10px}._large_8pbpz_33{padding:3px 8px;font-size:12px}._colored_8pbpz_38{color:var(--sci-badge-color);background:color-mix(in srgb, var(--sci-badge-color) 16%, var(--sci-color-bg-input))}._root_jienc_1{--sci-checkbox-size:16px;--sci-checkbox-mark:100%;align-items:baseline;gap:var(--sci-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--sci-color-text);font-size:var(--sci-font-size-sm);line-height:1;display:inline-flex}._root_jienc_1:has(._input_jienc_14:disabled){opacity:.45;cursor:default}._small_jienc_19{--sci-checkbox-size:14px;font-size:.8125rem}._large_jienc_24{--sci-checkbox-size:20px;font-size:1rem}._input_jienc_14{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute}._box_jienc_37{box-sizing:border-box;width:var(--sci-checkbox-size);height:var(--sci-checkbox-size);border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-input);flex-shrink:0;transition:border-color .12s,background .12s;position:relative}._input_jienc_14:focus-visible+._box_jienc_37{outline:2px solid var(--sci-color-border-focus);outline-offset:2px}._input_jienc_14:checked+._box_jienc_37{background:var(--sci-color-accent);border-color:var(--sci-color-accent)}._mark_jienc_60{color:#fff;visibility:hidden;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:var(--sci-checkbox-mark)!important;height:var(--sci-checkbox-mark)!important}._input_jienc_14:checked+._box_jienc_37 ._mark_jienc_60{visibility:visible}._colored_jienc_75 ._input_jienc_14:checked+._box_jienc_37{background:var(--sci-checkbox-color);border-color:var(--sci-checkbox-color)}._label_jienc_80{line-height:1;translate:0 -.12em}._tip_1rreb_1{z-index:10000;border-radius:var(--sci-radius-sm,4px);border:1px solid var(--sci-color-text-secondary,var(--color-text-secondary,#adb5bd));background:var(--sci-color-bg,var(--color-bg,#f2f4fa));max-width:260px;color:var(--sci-color-text,var(--color-text,#1c2433));font-size:12px;font-family:var(--sci-font-family,var(--font-family,system-ui, sans-serif));white-space:pre-wrap;box-shadow:var(--sci-shadow-md,0 4px 14px #00000059);pointer-events:none;padding:3px 8px 4px;line-height:1.35;animation:.12s ease-out _sciTipIn_1rreb_1;position:fixed}[data-theme=dark] ._tip_1rreb_1{border-color:var(--sci-color-border,var(--color-border,#373a40));color:var(--sci-color-text-secondary,var(--color-text-secondary,#adb5bd));padding:4px 8px}._host_1rreb_27{justify-content:center;align-items:center;max-width:100%;display:inline-flex}._hostBlock_1rreb_34{width:100%;max-width:none;height:100%;display:block}._hostBlock_1rreb_34>*{width:100%}@keyframes _sciTipIn_1rreb_1{0%{opacity:0}to{opacity:1}}._root_leo0p_1{--sci-radio-size:16px;--sci-radio-label-nudge:-3px;align-items:baseline;gap:var(--sci-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--sci-color-text);font-size:var(--sci-font-size-sm);line-height:1;display:inline-flex;position:relative}._root_leo0p_1:has(._input_leo0p_15:disabled){opacity:.45;cursor:default}._small_leo0p_20{--sci-radio-size:14px;--sci-radio-label-nudge:-2px;font-size:.8125rem}._large_leo0p_26{--sci-radio-size:20px;--sci-radio-label-nudge:-5px;font-size:1rem}._input_leo0p_15{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute}._box_leo0p_40{width:var(--sci-radio-size);height:var(--sci-radio-size);flex-shrink:0;display:block;overflow:hidden}._glyph_leo0p_48{width:var(--sci-radio-size);height:var(--sci-radio-size);display:block}._ring_leo0p_54{fill:var(--sci-color-bg-input);stroke:var(--sci-color-border);stroke-width:1.5px}._dot_leo0p_60{fill:var(--sci-color-accent);opacity:0;transition:opacity .12s}._input_leo0p_15:focus-visible+._box_leo0p_40 ._ring_leo0p_54{stroke:var(--sci-color-border-focus)}._input_leo0p_15:checked+._box_leo0p_40 ._ring_leo0p_54{stroke:var(--sci-color-accent)}._input_leo0p_15:checked+._box_leo0p_40 ._dot_leo0p_60{opacity:1}._colored_leo0p_78 ._input_leo0p_15:checked+._box_leo0p_40 ._ring_leo0p_54{stroke:var(--sci-radio-color)}._colored_leo0p_78 ._dot_leo0p_60{fill:var(--sci-radio-color)}._label_leo0p_86{translate:0 var(--sci-radio-label-nudge);line-height:1}._root_1x8jf_1{flex-direction:column;align-items:flex-start;gap:.15rem;display:flex}._legend_1x8jf_8{color:var(--sci-color-text-secondary);font-size:var(--sci-font-size-sm);line-height:1.3}._optionsV_1x8jf_14,._optionsH_1x8jf_15{gap:var(--sci-spacing-sm);display:flex}._optionsV_1x8jf_14{flex-direction:column;align-items:flex-start}._optionsH_1x8jf_15{align-items:baseline;gap:var(--sci-spacing-md);flex-flow:wrap}._labeled_lc52b_1{flex-direction:column;align-items:stretch;gap:.25rem;width:max-content;min-width:0;max-width:100%;display:flex}._labeled_lc52b_1._fill_lc52b_11{width:100%}._caption_lc52b_15{color:var(--sci-color-text-muted);font-size:11px;line-height:1.3}._field_lc52b_21{box-sizing:border-box;border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-input);width:auto;min-width:0;max-width:100%;color:var(--sci-color-text);font:inherit;font-size:var(--sci-font-size-sm);display:block}._field_lc52b_21:focus,._field_lc52b_21:focus-visible{border-color:var(--sci-color-border-focus);outline:none}._invalid_lc52b_41,._invalid_lc52b_41:focus,._invalid_lc52b_41:focus-visible{border-color:var(--sci-color-error)}._field_lc52b_21:disabled{color:var(--sci-color-text-muted);-webkit-user-select:none;user-select:none}._field_lc52b_21:disabled::placeholder{color:var(--sci-color-text-muted)}._input_lc52b_57{height:32px;padding:0 8px}._fill_lc52b_11._field_lc52b_21,._fill_lc52b_11 ._field_lc52b_21{width:100%}._passwordWrap_lc52b_67{width:max-content;min-width:0;max-width:100%;display:block;position:relative}._passwordWrap_lc52b_67._fill_lc52b_11{width:100%}._passwordInput_lc52b_79{padding-right:28px}._reveal_lc52b_83{width:20px;height:20px;color:var(--sci-color-text-muted);cursor:pointer;background:0 0;border:none;border-radius:0;justify-content:center;align-items:center;padding:0;line-height:1;display:inline-flex;position:absolute;top:50%;right:4px;transform:translateY(-50%)}._reveal_lc52b_83:focus,._reveal_lc52b_83:focus-visible{outline:none}._reveal_lc52b_83:hover:not(:disabled){color:var(--sci-color-text)}._passwordWrap_lc52b_67:has(._field_lc52b_21:disabled){-webkit-user-select:none;user-select:none}._passwordWrap_lc52b_67:has(._field_lc52b_21:disabled) ._reveal_lc52b_83{opacity:.55}._reveal_lc52b_83:disabled{color:var(--sci-color-text-muted)}._textarea_lc52b_124{resize:vertical;min-height:64px;padding:6px 8px;line-height:1.4}._mono_lc52b_131{font-family:var(--sci-font-family-mono)}._wrap_15qkt_1{align-self:flex-start;align-items:center;width:max-content;max-width:100%;display:inline-flex;position:relative}._fill_15qkt_12{width:100%;display:flex}._icon_15qkt_17{color:var(--sci-color-text-muted);pointer-events:none;position:absolute;left:8px}._input_15qkt_24{box-sizing:border-box;border-radius:var(--sci-radius-sm);border:1px solid var(--sci-color-border);background:var(--sci-color-bg-input);width:200px;max-width:240px;height:32px;color:var(--sci-color-text);font:inherit;font-size:var(--sci-font-size-sm);padding:6px 10px 6px 28px}._fill_15qkt_12 ._input_15qkt_24{flex:1;width:100%;min-width:0;max-width:none}._withClear_15qkt_45{padding-right:26px}._input_15qkt_24:focus,._input_15qkt_24:focus-visible{border-color:var(--sci-color-border-focus);outline:none}._wrap_15qkt_1:has(._input_15qkt_24:disabled){-webkit-user-select:none;user-select:none}._wrap_15qkt_1:has(._input_15qkt_24:disabled) ._icon_15qkt_17{opacity:.55}._input_15qkt_24:disabled{color:var(--sci-color-text-muted);-webkit-user-select:none;user-select:none}._input_15qkt_24:disabled::placeholder{color:var(--sci-color-text-muted)}._clear_15qkt_74{width:20px;height:20px;color:var(--sci-color-text-muted);cursor:pointer;background:0 0;border:none;border-radius:0;justify-content:center;align-items:center;padding:0;line-height:1;display:inline-flex;position:absolute;right:4px}._clear_15qkt_74:hover:not(:disabled){color:var(--sci-color-text);background:0 0}._clear_15qkt_74:disabled{color:var(--sci-color-text-muted)}._wrap_1vrao_1{align-items:center;gap:var(--sci-spacing-sm);display:inline-flex}._track_1vrao_7{box-sizing:border-box;border:1px solid var(--sci-color-border);background:var(--sci-color-bg-input);cursor:pointer;border-radius:999px;width:52px;height:28px;margin:0;padding:0;line-height:0;transition:background .18s,border-color .18s;position:relative}._track_1vrao_7:focus,._track_1vrao_7:focus-visible{outline:none}._wrap_1vrao_1:has(._track_1vrao_7:disabled){opacity:.45;-webkit-user-select:none;user-select:none}._track_1vrao_7:disabled{cursor:default}._track_1vrao_7:disabled ._knob_1vrao_39{animation:none}._knob_1vrao_39{box-sizing:border-box;width:22px;height:22px;color:var(--sci-color-text-muted);background:#fff;border-radius:50%;justify-content:center;align-items:center;font-size:13px;line-height:1;transition:transform .18s,background .18s;display:flex;position:absolute;top:50%;left:2px;transform:translateY(-50%);box-shadow:0 1px 2px #00000059}._off_1vrao_65{background:var(--sci-color-bg-input);border-color:var(--sci-color-border)}._off_1vrao_65 ._knob_1vrao_39{background-color:var(--sci-color-text-muted)}._connecting_1vrao_74{background:var(--sci-color-warning);border-color:var(--sci-color-warning)}._connecting_1vrao_74 ._knob_1vrao_39{background-color:color-mix(in srgb, var(--sci-color-warning) 40%, white);animation:.9s ease-in-out infinite _pulse_1vrao_1;transform:translate(13px,-50%)}._active_1vrao_85{background:var(--sci-color-accent);border-color:var(--sci-color-accent)}._active_1vrao_85 ._knob_1vrao_39{background-color:color-mix(in srgb, var(--sci-color-accent) 25%, white);transform:translate(24px,-50%)}._waiting_1vrao_95{background:var(--sci-color-success);border-color:var(--sci-color-success)}._waiting_1vrao_95 ._knob_1vrao_39{background-color:color-mix(in srgb, var(--sci-color-success) 25%, white);transform:translate(24px,-50%)}._degraded_1vrao_105{background:var(--sci-color-warning);border-color:var(--sci-color-warning)}._degraded_1vrao_105 ._knob_1vrao_39{background-color:color-mix(in srgb, var(--sci-color-warning) 35%, white);animation:.9s ease-in-out infinite _pulse_1vrao_1;transform:translate(24px,-50%)}._unreachable_1vrao_116{background:var(--sci-color-warning);border-color:var(--sci-color-warning)}._unreachable_1vrao_116 ._knob_1vrao_39{background-color:color-mix(in srgb, var(--sci-color-warning) 40%, white);animation:.9s ease-in-out infinite _pulse_1vrao_1;transform:translate(13px,-50%)}._error_1vrao_127{background:var(--sci-color-error);border-color:var(--sci-color-error)}._error_1vrao_127 ._knob_1vrao_39{background-color:color-mix(in srgb, var(--sci-color-error) 40%, white)}._label_1vrao_136{font-size:var(--sci-font-size-sm);color:var(--sci-color-text-secondary)}._small_1vrao_141{flex-direction:column;justify-content:center;align-items:center;gap:2px}._small_1vrao_141 ._label_1vrao_136{letter-spacing:.02em;text-transform:uppercase;opacity:.8;font-size:8px;line-height:1}._small_1vrao_141 ._track_1vrao_7{width:39px;height:20px}._small_1vrao_141 ._knob_1vrao_39{width:16px;height:16px;font-size:9px;left:2px}._small_1vrao_141 ._connecting_1vrao_74 ._knob_1vrao_39,._small_1vrao_141 ._unreachable_1vrao_116 ._knob_1vrao_39{transform:translate(9px,-50%)}._small_1vrao_141 ._active_1vrao_85 ._knob_1vrao_39,._small_1vrao_141 ._waiting_1vrao_95 ._knob_1vrao_39,._small_1vrao_141 ._degraded_1vrao_105 ._knob_1vrao_39{transform:translate(18px,-50%)}@keyframes _pulse_1vrao_1{0%,to{opacity:1}50%{opacity:.5}}._root_16vao_1{width:max-content;min-width:0;max-width:100%;display:block;position:relative}._root_16vao_1._fill_16vao_9{width:100%}._trigger_16vao_13{border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-input);width:max-content;max-width:100%;height:32px;color:var(--sci-color-text);font:inherit;font-size:var(--sci-font-size-sm);text-align:left;cursor:pointer;align-items:center;gap:6px;padding:0 4px 0 12px;display:inline-flex}._fill_16vao_9 ._trigger_16vao_13{width:100%}._trigger_16vao_13:hover:not(:disabled){background:color-mix(in srgb, var(--sci-color-text) 4%, var(--sci-color-bg-input))}._trigger_16vao_13:focus,._trigger_16vao_13:focus-visible{border-color:var(--sci-color-border-focus);outline:none}._triggerOpen_16vao_45{border-color:var(--sci-color-border-focus)}._root_16vao_1:has(._trigger_16vao_13:disabled){opacity:.45;-webkit-user-select:none;user-select:none}._trigger_16vao_13:disabled{color:var(--sci-color-text-muted);cursor:default}._value_16vao_60{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}._caret_16vao_68{color:var(--sci-color-text-muted);flex-shrink:0}._menu_16vao_73{z-index:60;box-sizing:border-box;border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-panel);color:var(--sci-color-text);opacity:0;transform-origin:top;pointer-events:none;max-height:min(280px,50vh);margin:0;padding:4px 0;list-style:none;transition:opacity .16s,transform .16s;overflow:auto;transform:translateY(-6px);box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}._menuOpen_16vao_98{opacity:1;pointer-events:auto;transform:translateY(0)}._option_16vao_104{width:100%;color:inherit;font:inherit;font-size:var(--sci-font-size-sm);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:0;padding:7px 12px;display:block}._option_16vao_104:hover,._optionActive_16vao_119{background:var(--sci-color-bg-hover)}._optionSelected_16vao_123{background:color-mix(in srgb, var(--sci-color-accent) 22%, transparent)}._optionSelected_16vao_123:hover,._optionSelected_16vao_123._optionActive_16vao_119{background:color-mix(in srgb, var(--sci-color-accent) 30%, transparent)}._option_16vao_104:focus,._option_16vao_104:focus-visible{outline:none}._iconRoot_16vao_138{width:max-content}._iconTrigger_16vao_142{border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-input);width:30px;height:30px;color:var(--sci-color-text-secondary);cursor:pointer;justify-content:center;align-items:center;padding:0;font-size:15px;line-height:1;transition:border-color .12s,background .12s,color .12s;display:inline-flex}._iconTrigger_16vao_142:hover:not(:disabled){border-color:var(--sci-color-border-focus);background:var(--sci-color-bg-hover);color:var(--sci-color-text)}._iconTrigger_16vao_142:disabled{opacity:.45;cursor:default}._iconTrigger_16vao_142:focus,._iconTrigger_16vao_142:focus-visible{outline:none}._flagIcon_16vao_178{shape-rendering:geometricprecision;flex-shrink:0;line-height:0;display:block}._iconMenu_16vao_185{z-index:60;box-sizing:border-box;padding:var(--sci-spacing-xs);border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-md);background:var(--sci-color-bg-panel);min-width:11.5rem;box-shadow:var(--sci-shadow-md);margin:0;list-style:none}._iconOption_16vao_198{text-align:left;border-radius:var(--sci-radius-sm);width:100%;color:var(--sci-color-text-secondary);font-family:inherit;font-size:var(--sci-font-size-sm);cursor:pointer;background:0 0;border:0;align-items:center;gap:.5rem;padding:.45rem .65rem;display:flex}._iconOption_16vao_198:hover,._iconOptionActive_16vao_215:not(._iconOptionSelected_16vao_215){background:var(--sci-color-bg-hover);color:var(--sci-color-text)}._iconOptionSelected_16vao_215{color:var(--sci-color-accent);background:color-mix(in srgb, var(--sci-color-accent) 12%, transparent)}._iconLabel_16vao_225{color:inherit;line-height:1.25}._iconOption_16vao_198:focus,._iconOption_16vao_198:focus-visible{outline:none}._selectorTrigger_16vao_236,._selectorTrigger_16vao_236:hover:not(:disabled){color:var(--sci-color-accent)}._selectorTriggerOpen_16vao_244{border-color:var(--sci-color-accent);background:color-mix(in srgb, var(--sci-color-accent) 16%, transparent)}._selectorMenu_16vao_249{z-index:60;box-sizing:border-box;min-width:200px;max-height:60vh;padding:var(--sci-spacing-xs);border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-md);background:var(--sci-color-bg-panel);box-shadow:var(--sci-shadow-md);flex-direction:column;margin:0;display:flex;overflow-y:auto}._selectorList_16vao_265{margin:0;padding:0;list-style:none}._selectorOption_16vao_271{box-sizing:border-box;border-radius:var(--sci-radius-sm);white-space:nowrap;width:100%;padding:7px 10px}._selectorOption_16vao_271:hover,._selectorOptionActive_16vao_280{background:var(--sci-color-bg-hover)}._selectorFooter_16vao_284{border-top:1px solid var(--sci-color-border);justify-content:flex-end;margin-top:4px;padding:4px 4px 2px;display:flex}._selectorOk_16vao_292{border-radius:var(--sci-radius-sm);border:1px solid var(--sci-color-accent);background:var(--sci-color-accent);color:#fff;cursor:pointer;height:26px;padding:0 12px;font-size:12px;font-weight:600}._selectorOk_16vao_292:hover{background:color-mix(in srgb, var(--sci-color-accent) 85%, #000);border-color:color-mix(in srgb, var(--sci-color-accent) 85%, #000)}._contextBackdrop_16vao_310{z-index:59;position:fixed;inset:0}._contextMenu_16vao_316{z-index:60;box-sizing:border-box;border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-panel);flex-direction:column;gap:2px;min-width:168px;margin:0;padding:4px;list-style:none;display:flex;box-shadow:0 6px 20px #0006}._contextOption_16vao_332{border-radius:var(--sci-radius-sm);width:100%;color:var(--sci-color-text);font:inherit;font-size:var(--sci-font-size-sm);text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:7px 10px;display:flex}._contextOption_16vao_332:hover,._contextOptionActive_16vao_349{background:var(--sci-color-bg-hover)}._contextIcon_16vao_353{width:16px;height:16px;color:var(--sci-color-text-muted);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}._contextDanger_16vao_363:hover,._contextDanger_16vao_363._contextOptionActive_16vao_349,._contextDanger_16vao_363:hover ._contextIcon_16vao_353,._contextDanger_16vao_363._contextOptionActive_16vao_349 ._contextIcon_16vao_353{color:var(--sci-color-error)}._contextOption_16vao_332:focus,._contextOption_16vao_332:focus-visible{outline:none}._root_1pz4u_1{align-items:center;gap:var(--sci-spacing-sm);flex-wrap:wrap;display:flex}._chipWrap_1pz4u_8{display:inline-flex;position:relative}._chip_1pz4u_8{border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-input);height:30px;color:var(--sci-color-text);align-items:center;display:inline-flex;overflow:hidden}._chipActive_1pz4u_24{border-color:var(--sci-color-accent);background:color-mix(in srgb, var(--sci-color-accent) 16%, transparent)}._chipBody_1pz4u_29{color:inherit;font:inherit;font-size:var(--sci-font-size-sm);white-space:nowrap;cursor:pointer;background:0 0;border:0;align-self:stretch;align-items:center;gap:4px;padding:0 8px 0 10px;font-weight:600;display:inline-flex}._chipBody_1pz4u_29:hover{background:var(--sci-color-bg-hover)}._chipBodyStatic_1pz4u_49{cursor:default}._chipBodyStatic_1pz4u_49:hover{background:0 0}._chipName_1pz4u_57{color:inherit}._chipValue_1pz4u_61{color:var(--sci-color-text-secondary);text-overflow:ellipsis;white-space:nowrap;max-width:220px;font-weight:400;overflow:hidden}._caret_1pz4u_70{color:var(--sci-color-text-secondary);flex-shrink:0}._chipCloseHost_1pz4u_75{align-self:stretch;align-items:stretch}._chipClose_1pz4u_75{box-sizing:border-box;height:100%;color:var(--sci-color-text-muted);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:0 8px;display:inline-flex}._chipClose_1pz4u_75:hover{background:var(--sci-color-bg-hover);color:var(--sci-color-text)}._iconBtn_1pz4u_98{border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-sm);background:var(--sci-color-bg-input);width:30px;height:30px;color:var(--sci-color-accent);cursor:pointer;justify-content:center;align-items:center;padding:0;display:inline-flex}._iconBtn_1pz4u_98:hover:not(:disabled){border-color:var(--sci-color-border-focus);background:var(--sci-color-bg-hover)}._iconBtn_1pz4u_98:disabled{opacity:.4;cursor:default}._popover_1pz4u_122{z-index:60;box-sizing:border-box;min-width:200px;max-height:60vh;padding:var(--sci-spacing-xs);border:1px solid var(--sci-color-border);border-radius:var(--sci-radius-md);background:var(--sci-color-bg-panel);box-shadow:var(--sci-shadow-md);flex-direction:column;margin:0;display:flex;overflow-y:auto}._row_1pz4u_138{box-sizing:border-box;border-radius:var(--sci-radius-sm);white-space:nowrap;width:100%;padding:7px 10px}._row_1pz4u_138:hover{background:var(--sci-color-bg-hover)}._rowAll_1pz4u_150{font-weight:600}._optionRow_1pz4u_154{align-items:center;gap:4px;width:100%;display:flex}._optionRow_1pz4u_154 ._row_1pz4u_138{flex:1;min-width:0}._optionLabel_1pz4u_166{align-items:baseline;gap:.4em;min-width:0;display:inline-flex}._optionText_1pz4u_173{text-overflow:ellipsis;min-width:0;overflow:hidden}._count_1pz4u_179{color:var(--sci-color-text-muted);font-variant-numeric:tabular-nums;margin-left:auto;padding-left:10px}._divider_1pz4u_186{background:var(--sci-color-border);height:1px;margin:2px 6px}._optionAction_1pz4u_192{border-radius:var(--sci-radius-sm);width:22px;height:22px;color:var(--sci-color-text-muted);cursor:pointer;background:0 0;border:0;flex:none;padding:0}._optionAction_1pz4u_192:hover{color:var(--sci-color-accent);background:color-mix(in srgb, var(--sci-color-accent) 14%, transparent)}._applyScope_1pz4u_209{margin-top:var(--sci-spacing-xs);padding-top:var(--sci-spacing-xs);border-top:1px solid var(--sci-color-border);flex-direction:column;display:flex}._scopeLabel_1pz4u_217{color:var(--sci-color-text-muted);letter-spacing:.04em;text-transform:uppercase;padding:4px 10px 2px;font-size:11px;font-weight:600}._footer_1pz4u_226{border-top:1px solid var(--sci-color-border);justify-content:flex-end;margin-top:4px;padding:4px 4px 2px;display:flex}._footerOk_1pz4u_234{border-radius:var(--sci-radius-sm);border:1px solid var(--sci-color-accent);background:var(--sci-color-accent);color:#fff;cursor:pointer;height:26px;padding:0 12px;font-size:12px;font-weight:600}._footerOk_1pz4u_234:hover{background:color-mix(in srgb, var(--sci-color-accent) 85%, #000);border-color:color-mix(in srgb, var(--sci-color-accent) 85%, #000)}._empty_1pz4u_251{color:var(--sci-color-text-muted);font-size:var(--sci-font-size-sm);padding:7px 10px}:root{--sci-color-bg-hero:#e6e9f3;--sci-color-bg:#f2f4fa;--sci-color-bg-panel:#f7f9ff;--sci-color-bg-input:#f9fbff;--sci-color-bg-hover:#f1f5ff;--sci-color-text:#1c2433;--sci-color-text-secondary:#4c576a;--sci-color-text-muted:#8a96ab;--sci-color-border:#c8d0e0;--sci-color-border-focus:#54a1ff;--sci-color-accent:#008dff;--sci-color-accent-hover:#0b83f5;--sci-color-success:#2f9e6b;--sci-color-warning:#b8860b;--sci-color-error:#d64545;--sci-color-ink:#0d0f12;--sci-shadow-sm:0 1px 2px #1c30500f;--sci-shadow-md:0 4px 12px #1c305014;--sci-spacing-xs:4px;--sci-spacing-sm:8px;--sci-spacing-md:16px;--sci-spacing-lg:24px;--sci-spacing-xl:32px;--sci-radius-sm:4px;--sci-radius-md:8px;--sci-radius-lg:12px;--sci-font-family:"Segoe UI", system-ui, -apple-system, sans-serif;--sci-font-family-mono:"Cascadia Code", "Fira Code", "Consolas", monospace;--sci-font-size-sm:.875rem;--sci-font-size-base:1rem;--sci-font-size-lg:1.125rem;--color-bg:var(--sci-color-bg);--color-bg-hero:var(--sci-color-bg-hero);--color-bg-panel:var(--sci-color-bg-panel);--color-bg-input:var(--sci-color-bg-input);--color-bg-hover:var(--sci-color-bg-hover);--color-text:var(--sci-color-text);--color-text-secondary:var(--sci-color-text-secondary);--color-text-muted:var(--sci-color-text-muted);--color-border:var(--sci-color-border);--color-border-focus:var(--sci-color-border-focus);--color-accent:var(--sci-color-accent);--color-accent-hover:var(--sci-color-accent-hover);--color-success:var(--sci-color-success);--color-warning:var(--sci-color-warning);--color-error:var(--sci-color-error);--color-ink:var(--sci-color-ink);--shadow-sm:var(--sci-shadow-sm);--shadow-md:var(--sci-shadow-md);--spacing-xs:var(--sci-spacing-xs);--spacing-sm:var(--sci-spacing-sm);--spacing-md:var(--sci-spacing-md);--spacing-lg:var(--sci-spacing-lg);--spacing-xl:var(--sci-spacing-xl);--radius-sm:var(--sci-radius-sm);--radius-md:var(--sci-radius-md);--radius-lg:var(--sci-radius-lg);--font-family:var(--sci-font-family);--font-family-mono:var(--sci-font-family-mono);--font-size-sm:var(--sci-font-size-sm);--font-size-base:var(--sci-font-size-base);--font-size-lg:var(--sci-font-size-lg)}[data-theme=dark]{--sci-color-bg-hero:#202125;--sci-color-bg:#1a1b1e;--sci-color-bg-panel:#25262b;--sci-color-bg-input:#2c2e33;--sci-color-bg-hover:#272a2e;--sci-color-text:#e9ecef;--sci-color-text-secondary:#adb5bd;--sci-color-text-muted:#6c757d;--sci-color-border:#373a40;--sci-color-border-focus:#3fa5f8;--sci-color-accent:#4dabf7;--sci-color-accent-hover:#1f9aff;--sci-color-success:#51cf66;--sci-color-warning:#d29922;--sci-color-error:#ff6b6b;--sci-shadow-sm:0 1px 2px #0003;--sci-shadow-md:0 4px 6px #0000004d}*,:before,:after{box-sizing:border-box}.sci-root{font-family:var(--sci-font-family);font-size:var(--sci-font-size-base);color:var(--sci-color-text);background:var(--sci-color-bg-hero);line-height:1.5}
|
|
2
|
+
/*$vite$:1*/
|
package/dist/styles.js
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><mask id="SVGuywqVbel"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#SVGuywqVbel)"><path fill="#ffda44" d="m0 345l256.7-25.5L512 345v167H0z"/><path fill="#d80027" d="m0 167l255-23l257 23v178H0z"/><path fill="#333" d="M0 0h512v167H0z"/></g></svg>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="1em" height="1em">
|
|
2
|
+
<g fill="none" fill-rule="evenodd">
|
|
3
|
+
<g fill-rule="nonzero">
|
|
4
|
+
<circle fill="#F0F0F0" cx="60" cy="60" r="60"/>
|
|
5
|
+
<g transform="translate(1.875 1.875)" fill="#0052B4">
|
|
6
|
+
<path d="M10.528125,21.5957812 C5.81507813,27.7277344 2.26125,34.7953125 0.191953125,42.4732031 L31.4055469,42.4732031 L10.528125,21.5957812 Z"/>
|
|
7
|
+
<path d="M116.058047,42.4732031 C113.98875,34.7955469 110.434687,27.7279687 105.721875,21.5960156 L84.8449219,42.4732031 L116.058047,42.4732031 Z"/>
|
|
8
|
+
<path d="M0.191953125,73.7775 C2.26148438,81.4551563 5.8153125,88.5227344 10.528125,94.6544531 L31.4048438,73.7775 L0.191953125,73.7775 Z"/>
|
|
9
|
+
<path d="M94.6542187,10.5283594 C88.5222656,5.8153125 81.4549219,2.26148438 73.7770313,0.191953125 L73.7770313,31.4053125 L94.6542187,10.5283594 Z"/>
|
|
10
|
+
<path d="M21.5957812,105.721641 C27.7277344,110.434687 34.7953125,113.988516 42.4729687,116.058047 L42.4729687,84.8449219 L21.5957812,105.721641 Z"/>
|
|
11
|
+
<path d="M42.4727344,0.191953125 C34.7950781,2.26148438 27.7275,5.8153125 21.5957813,10.528125 L42.4727344,31.4050781 L42.4727344,0.191953125 Z"/>
|
|
12
|
+
<path d="M73.7772656,116.058047 C81.4549219,113.988516 88.5225,110.434687 94.6542187,105.721875 L73.7772656,84.8449219 L73.7772656,116.058047 Z"/>
|
|
13
|
+
<path d="M84.8449219,73.7775 L105.721875,94.6546875 C110.434687,88.5229688 113.98875,81.4551563 116.058047,73.7775 L84.8449219,73.7775 Z"/>
|
|
14
|
+
</g>
|
|
15
|
+
<path d="M119.492109,52.1739844 L67.8264844,52.1739844 L67.82625,52.1739844 L67.82625,0.507890625 C65.2642969,0.174375 62.6524219,0 60,0 C57.3471094,0 54.7357031,0.174375 52.1739844,0.507890625 L52.1739844,52.1735156 L52.1739844,52.17375 L0.507890625,52.17375 C0.174375,54.7357031 5.68434189e-14,57.3475781 5.68434189e-14,60 C5.68434189e-14,62.6528906 0.174375,65.2642969 0.507890625,67.8260156 L52.1735156,67.8260156 L52.17375,67.8260156 L52.17375,119.492109 C54.7357031,119.825625 57.3471094,120 60,120 C62.6524219,120 65.2642969,119.825859 67.8260156,119.492109 L67.8260156,67.8264844 L67.8260156,67.82625 L119.492109,67.82625 C119.825625,65.2642969 120,62.6528906 120,60 C120,57.3475781 119.825625,54.7357031 119.492109,52.1739844 Z" fill="#D80027"/>
|
|
16
|
+
<path d="M75.6522656,75.6522656 L102.426328,102.426562 C103.657734,101.195625 104.832422,99.9086719 105.953203,98.5746094 L83.0308594,75.6522656 L75.6522656,75.6522656 Z" fill="#D80027"/>
|
|
17
|
+
<path d="M44.3477344,75.6525 L44.3472656,75.6525 L17.5734375,102.426328 C18.804375,103.657734 20.0913281,104.832422 21.4253906,105.953203 L44.3477344,83.0303906 L44.3477344,75.6525 Z" fill="#D80027"/>
|
|
18
|
+
<path d="M44.3477344,44.3482031 L44.3477344,44.3477344 L17.5736719,17.5734375 C16.3422656,18.804375 15.1675781,20.0913281 14.0467969,21.4253906 L36.969375,44.3479687 L44.3477344,44.3482031 Z" fill="#D80027"/>
|
|
19
|
+
<path d="M75.6522656,44.3482031 L102.426562,17.5736719 C101.195625,16.3422656 99.9086719,15.1675781 98.5746094,14.0470312 L75.6522656,36.9696094 L75.6522656,44.3482031 Z" fill="#D80027"/>
|
|
20
|
+
</g>
|
|
21
|
+
<circle stroke-opacity="0.1" stroke="#000" cx="60" cy="60" r="60"/>
|
|
22
|
+
</g>
|
|
23
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><mask id="SVGuywqVbel"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#SVGuywqVbel)"><path fill="#ffda44" d="m0 128l256-32l256 32v256l-256 32L0 384Z"/><path fill="#d80027" d="M0 0h512v128H0zm0 384h512v128H0z"/><g fill="#eee"><path d="M144 304h-16v-80h16zm128 0h16v-80h-16z"/><ellipse cx="208" cy="296" rx="48" ry="32"/></g><g fill="#d80027"><rect width="16" height="24" x="128" y="192" rx="8"/><rect width="16" height="24" x="272" y="192" rx="8"/><path d="M208 272v24a24 24 0 0 0 24 24a24 24 0 0 0 24-24v-24h-24z"/></g><rect width="32" height="16" x="120" y="208" fill="#ff9811" ry="8"/><rect width="32" height="16" x="264" y="208" fill="#ff9811" ry="8"/><rect width="32" height="16" x="120" y="304" fill="#ff9811" rx="8"/><rect width="32" height="16" x="264" y="304" fill="#ff9811" rx="8"/><path fill="#ff9811" d="M160 272v24c0 8 4 14 9 19l5-6l5 10a21 21 0 0 0 10 0l5-10l5 6c6-5 9-11 9-19v-24h-9l-5 8l-5-8h-10l-5 8l-5-8z"/><path fill="#d80027" d="M122 248a4 4 0 0 0-4 4a4 4 0 0 0 4 4h172a4 4 0 0 0 4-4a4 4 0 0 0-4-4zm0 24a4 4 0 0 0-4 4a4 4 0 0 0 4 4h28a4 4 0 0 0 4-4a4 4 0 0 0-4-4zm144 0a4 4 0 0 0-4 4a4 4 0 0 0 4 4h28a4 4 0 0 0 4-4a4 4 0 0 0-4-4z"/><path fill="#eee" d="M196 168c-7 0-13 5-15 11l-5-1c-9 0-16 7-16 16s7 16 16 16c7 0 13-4 15-11a16 16 0 0 0 17-4a16 16 0 0 0 17 4a16 16 0 1 0 10-20a16 16 0 0 0-27-5q-4.5-6-12-6m0 8c5 0 8 4 8 8c0 5-3 8-8 8c-4 0-8-3-8-8c0-4 4-8 8-8m24 0c5 0 8 4 8 8c0 5-3 8-8 8c-4 0-8-3-8-8c0-4 4-8 8-8m-44 10l4 1l4 8c0 4-4 7-8 7s-8-3-8-8c0-4 4-8 8-8m64 0c5 0 8 4 8 8c0 5-3 8-8 8c-4 0-8-3-8-7l4-8z"/><path fill="none" d="M220 284v12c0 7 5 12 12 12s12-5 12-12v-12z"/><path fill="#ff9811" d="M200 160h16v32h-16z"/><path fill="#eee" d="M208 224h48v48h-48z"/><path fill="#d80027" d="m248 208l-8 8h-64l-8-8c0-13 18-24 40-24s40 11 40 24m-88 16h48v48h-48z"/><rect width="20" height="32" x="222" y="232" fill="#d80027" rx="10" ry="10"/><path fill="#ff9811" d="M168 232v8h8v16h-8v8h32v-8h-8v-16h8v-8zm8-16h64v8h-64z"/><g fill="#ffda44"><circle cx="186" cy="202" r="6"/><circle cx="208" cy="202" r="6"/><circle cx="230" cy="202" r="6"/></g><path fill="#d80027" d="M169 272v43a24 24 0 0 0 10 4v-47zm20 0v47a24 24 0 0 0 10-4v-43z"/><g fill="#338af3"><circle cx="208" cy="272" r="16"/><rect width="32" height="16" x="264" y="320" ry="8"/><rect width="32" height="16" x="120" y="320" ry="8"/></g></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><mask id="SVGuywqVbel"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#SVGuywqVbel)"><path fill="#eee" d="M167 0h178l25.9 252.3L345 512H167l-29.8-253.4z"/><path fill="#0052b4" d="M0 0h167v512H0z"/><path fill="#d80027" d="M345 0h167v512H345z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><mask id="SVGuywqVbel"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#SVGuywqVbel)"><path fill="#eee" d="M167 0h178l25.9 252.3L345 512H167l-29.8-253.4z"/><path fill="#6da544" d="M0 0h167v512H0z"/><path fill="#d80027" d="M345 0h167v512H345z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><mask id="SVGuywqVbel"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#SVGuywqVbel)"><path fill="#eee" d="m0 167l253.8-19.3L512 167v178l-254.9 32.3L0 345z"/><path fill="#a2001d" d="M0 0h512v167H0z"/><path fill="#0052b4" d="M0 345h512v167H0z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><mask id="SVGuywqVbel"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#SVGuywqVbel)"><path fill="#6da544" d="M0 512h167l37.9-260.3L167 0H0z"/><path fill="#d80027" d="M512 0H167v512h345z"/><circle cx="167" cy="256" r="89" fill="#ffda44"/><path fill="#d80027" d="M116.9 211.5V267a50 50 0 1 0 100.1 0v-55.6H117z"/><path fill="#eee" d="M167 283.8c-9.2 0-16.7-7.5-16.7-16.7V245h33.4v22c0 9.2-7.5 16.7-16.7 16.7z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><mask id="SVGuywqVbel"><circle cx="256" cy="256" r="256" fill="#fff"/></mask><g mask="url(#SVGuywqVbel)"><path fill="#0052b4" d="M512 170v172l-256 32L0 342V170l256-32z"/><path fill="#eee" d="M512 0v170H0V0Z"/><path fill="#d80027" d="M512 342v170H0V342Z"/></g></svg>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 120 120">
|
|
2
|
+
<g id="ZH" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
3
|
+
<g id="china" fill-rule="nonzero">
|
|
4
|
+
<circle id="Oval" fill="#D80027" cx="60" cy="60" r="60"/>
|
|
5
|
+
<g id="stars" transform="translate(10.781250, 26.718750)" fill="#FFDA44">
|
|
6
|
+
<polygon points="22.0546875 9.796875 27.234375 25.734375 43.9921875 25.734375 30.4453125 35.6015625 35.625 51.5390625 22.0546875 41.6953125 8.484375 51.5390625 13.6875 35.6015625 0.1171875 25.734375 16.875 25.734375"/>
|
|
7
|
+
<polygon points="60.3515625 66.2109375 56.390625 61.3359375 50.53125 63.609375 53.9296875 58.3359375 49.96875 53.4375 56.0390625 55.0546875 59.4609375 49.78125 59.7890625 56.0625 65.8828125 57.6796875 60 59.9296875"/>
|
|
8
|
+
<polygon points="68.2265625 51.9140625 70.1015625 45.9140625 64.96875 42.28125 71.25 42.1875 73.1015625 36.1875 75.140625 42.140625 81.421875 42.0703125 76.3828125 45.8203125 78.3984375 51.7734375 73.265625 48.140625"/>
|
|
9
|
+
<polygon points="78.84375 17.3203125 76.078125 22.96875 80.578125 27.3515625 74.3671875 26.4609375 71.6015625 32.0859375 70.5234375 25.8984375 64.2890625 25.0078125 69.8671875 22.078125 68.7890625 15.8671875 73.2890625 20.25"/>
|
|
10
|
+
<polygon points="60.515625 0.2109375 60.046875 6.46875 65.8828125 8.8359375 59.765625 10.3359375 59.3203125 16.6171875 56.015625 11.2734375 49.8984375 12.7734375 53.953125 7.96875 50.625 2.6484375 56.4609375 5.015625"/>
|
|
11
|
+
</g>
|
|
12
|
+
</g>
|
|
13
|
+
<circle stroke-opacity="0.1" stroke="#000000" cx="60" cy="60" r="60"/>
|
|
14
|
+
</g>
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="7 5 128 128" width="128" height="128">
|
|
2
|
+
<circle cx="71" cy="69" r="44" fill="none" stroke="#000" stroke-width="5"/>
|
|
3
|
+
<g fill="#000" transform="translate(71 69) scale(0.9) translate(-71 -69)">
|
|
4
|
+
<path d="m60.637 42.535c0.66797 1.5898-0.074219 3.4219-1.6641 4.0938-4.0312 1.6992-7.3867 5.1758-9.1992 9.6875-0.64453 1.6016-2.4609 2.3789-4.0625 1.7344-1.6016-0.64062-2.3789-2.4609-1.7383-4.0625 2.3828-5.9336 6.8789-10.719 12.57-13.117 1.5898-0.67188 3.4219 0.074218 4.0938 1.6641z"/>
|
|
5
|
+
<path d="m79.988 42.535c0.67188-1.5898 2.5039-2.3359 4.0938-1.6641 5.6875 2.3984 10.184 7.1836 12.566 13.117 0.64453 1.6016-0.13281 3.4219-1.7344 4.0625-1.6016 0.64453-3.4219-0.13281-4.0664-1.7344-1.8125-4.5117-5.168-7.9883-9.1953-9.6875-1.5898-0.67188-2.3359-2.5039-1.6641-4.0938z"/>
|
|
6
|
+
<path d="m70.312 40.625c1.7266 0 3.125 1.3984 3.125 3.125v0.36328c9.8945 1.4688 17.578 9.7969 17.578 19.996v17.594c0.99609 0.52344 1.6719 1.5664 1.6719 2.7695 0 1.7266-1.3984 3.125-3.125 3.125h-38.504c-1.7266 0-3.125-1.3984-3.125-3.125 0-1.2031 0.67969-2.2461 1.6758-2.7695v-17.594c0-10.199 7.6836-18.527 17.578-19.996v-0.36328c0-1.7266 1.3984-3.125 3.125-3.125z"/>
|
|
7
|
+
<path d="m62.164 93.75c0-1.7266 1.3984-3.125 3.125-3.125h10.047c1.7227 0 3.125 1.3984 3.125 3.125s-1.4023 3.125-3.125 3.125h-10.047c-1.7266 0-3.125-1.3984-3.125-3.125z"/>
|
|
8
|
+
</g>
|
|
9
|
+
</svg>
|