@beweco/aurora-ui 1.0.0-beta.147 → 1.0.0-beta.149

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.
Files changed (29) hide show
  1. package/dist/assets/css/styles.css +1 -1
  2. package/dist/index.cjs.js +1007 -307
  3. package/dist/index.esm.js +1005 -309
  4. package/dist/types/components/beta-badge/BetaBadge.d.ts +9 -0
  5. package/dist/types/components/beta-badge/BetaBadge.d.ts.map +1 -0
  6. package/dist/types/components/beta-badge/BetaBadge.types.d.ts +31 -0
  7. package/dist/types/components/beta-badge/BetaBadge.types.d.ts.map +1 -0
  8. package/dist/types/components/beta-badge/beta-badge.styles.d.ts +2 -0
  9. package/dist/types/components/beta-badge/beta-badge.styles.d.ts.map +1 -0
  10. package/dist/types/components/beta-badge/index.d.ts +3 -0
  11. package/dist/types/components/beta-badge/index.d.ts.map +1 -0
  12. package/dist/types/components/linda-mascot/LindaMascot.d.ts +17 -0
  13. package/dist/types/components/linda-mascot/LindaMascot.d.ts.map +1 -0
  14. package/dist/types/components/linda-mascot/LindaMascot.types.d.ts +58 -0
  15. package/dist/types/components/linda-mascot/LindaMascot.types.d.ts.map +1 -0
  16. package/dist/types/components/linda-mascot/index.d.ts +4 -0
  17. package/dist/types/components/linda-mascot/index.d.ts.map +1 -0
  18. package/dist/types/components/linda-mascot/linda-mascot.constants.d.ts +55 -0
  19. package/dist/types/components/linda-mascot/linda-mascot.constants.d.ts.map +1 -0
  20. package/dist/types/components/linda-mascot/linda-mascot.styles.d.ts +2 -0
  21. package/dist/types/components/linda-mascot/linda-mascot.styles.d.ts.map +1 -0
  22. package/dist/types/components/toast/GlobalToast.d.ts.map +1 -1
  23. package/dist/types/index.d.ts +2 -0
  24. package/dist/types/index.d.ts.map +1 -1
  25. package/dist/types/utils/theme-scope.d.ts +18 -0
  26. package/dist/types/utils/theme-scope.d.ts.map +1 -0
  27. package/dist/types/utils/use-injected-style.d.ts +25 -0
  28. package/dist/types/utils/use-injected-style.d.ts.map +1 -0
  29. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -2,7 +2,7 @@ import { Card as Card$1, Breadcrumbs, ProgressBar, Label, ListBoxSection, ListBo
2
2
  export { Accordion, AccordionItem, Avatar, Breadcrumbs, CardFooter, CardHeader, CheckboxGroup, CloseButton, DropdownItem, DropdownMenu, DropdownTrigger, Link, Popover, PopoverContent, PopoverTrigger, Radio, RadioGroup, Skeleton, Slider, Spinner, TableBody, TableCell, TableColumn, TableHeader, TableRow } from '@heroui/react';
3
3
  import { cnMerge } from 'tailwind-variants';
4
4
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
5
- import $8WNJc$react, { Children, isValidElement, Fragment, useState, useRef, useCallback, useEffect, createElement, useId, forwardRef, useMemo, cloneElement, useImperativeHandle, createContext, useContext, useLayoutEffect, memo, useReducer, version } from 'react';
5
+ import $8WNJc$react, { Children, isValidElement, Fragment, useState, useRef, useCallback, useEffect, createElement, useId, forwardRef, useMemo, cloneElement, useInsertionEffect, useImperativeHandle, createContext, useContext, useLayoutEffect, memo, useReducer, version } from 'react';
6
6
  import { Icon } from '@iconify/react';
7
7
  export { loadIcons } from '@iconify/react';
8
8
  import { ResponsiveContainer, AreaChart, CartesianGrid, XAxis, Tooltip as Tooltip$1, Area, LineChart, YAxis, Line, PieChart, Pie, Cell } from 'recharts';
@@ -1406,7 +1406,7 @@ const ACTIVE_SHADOW_CLASS = {
1406
1406
  * Traducciones por defecto en español. Todas son `aria-label`: este componente no tiene más
1407
1407
  * texto visible que los números de página.
1408
1408
  */
1409
- const DEFAULT_TRANSLATIONS$g = {
1409
+ const DEFAULT_TRANSLATIONS$h = {
1410
1410
  previousPageAriaLabel: "Página anterior",
1411
1411
  nextPageAriaLabel: "Página siguiente",
1412
1412
  jumpBackwardAriaLabel: "Retroceder {count} páginas",
@@ -1437,7 +1437,7 @@ const EN_TRANSLATIONS = {
1437
1437
  function baseTranslations(locale) {
1438
1438
  return locale.toLowerCase().startsWith("en")
1439
1439
  ? EN_TRANSLATIONS
1440
- : DEFAULT_TRANSLATIONS$g;
1440
+ : DEFAULT_TRANSLATIONS$h;
1441
1441
  }
1442
1442
  /**
1443
1443
  * TECH-2459 · elipsis navegable — páginas que salta la elipsis. Literal de v2:
@@ -3201,7 +3201,7 @@ function withV2ItemContent(children) {
3201
3201
  }
3202
3202
 
3203
3203
  /** Traducciones por defecto en español (mismo literal que la ✕ de la fachada `Input`). */
3204
- const DEFAULT_TRANSLATIONS$f = {
3204
+ const DEFAULT_TRANSLATIONS$g = {
3205
3205
  clearButtonAriaLabel: "Limpiar",
3206
3206
  emptyContent: "No se encontraron resultados",
3207
3207
  };
@@ -3559,7 +3559,7 @@ labelPlacement: _labelPlacement, scrollShadowProps, ...props }) => {
3559
3559
  : icon === undefined
3560
3560
  ? DEFAULT_ICON
3561
3561
  : icon;
3562
- const t = { ...DEFAULT_TRANSLATIONS$f, ...translations };
3562
+ const t = { ...DEFAULT_TRANSLATIONS$g, ...translations };
3563
3563
  // La regla de v2 para la lista vacía (ver `EMPTY_CONTENT_CLASS`).
3564
3564
  const hideEmptyContent = Boolean(allowsCustomValue) && listboxProps?.emptyContent == null;
3565
3565
  const emptyContent = listboxProps?.emptyContent ?? t.emptyContent;
@@ -3697,274 +3697,49 @@ labelPlacement: _labelPlacement, scrollShadowProps, ...props }) => {
3697
3697
  };
3698
3698
 
3699
3699
  /**
3700
- * ColorPicker Types
3701
- *
3702
- * Defines the type system for the ColorPicker component used for brand configuration.
3703
- */
3704
- /**
3705
- * Default predefined colors (Brand-safe palette)
3706
- */
3707
- const DEFAULT_PREDEFINED_COLORS = [
3708
- // Primary colors
3709
- { key: "blue", name: "Azul", value: "#3B82F6" },
3710
- { key: "violet", name: "Violeta", value: "#8B5CF6" },
3711
- { key: "purple", name: "Púrpura", value: "#A855F7" },
3712
- // Secondary colors
3713
- { key: "green", name: "Verde", value: "#10B981" },
3714
- { key: "teal", name: "Turquesa", value: "#14B8A6" },
3715
- { key: "cyan", name: "Cian", value: "#06B6D4" },
3716
- // Accent colors
3717
- { key: "pink", name: "Rosa", value: "#EC4899" },
3718
- { key: "rose", name: "Rosa claro", value: "#F43F5E" },
3719
- { key: "orange", name: "Naranja", value: "#F97316" },
3720
- // Neutral colors
3721
- { key: "red", name: "Rojo", value: "#EF4444" },
3722
- { key: "amber", name: "Ámbar", value: "#F59E0B" },
3723
- { key: "yellow", name: "Amarillo", value: "#EAB308" },
3724
- // Gray scale (useful for text/backgrounds)
3725
- { key: "gray-dark", name: "Gris oscuro", value: "#374151" },
3726
- { key: "gray", name: "Gris", value: "#6B7280" },
3727
- { key: "gray-light", name: "Gris claro", value: "#9CA3AF" },
3728
- ];
3729
-
3730
- /**
3731
- * Default translations (Spanish)
3732
- */
3733
- const defaultTranslations$e = {
3734
- label: "Color",
3735
- placeholder: "Ingresa código hex",
3736
- customColorLabel: "Color personalizado",
3737
- predefinedColorsLabel: "Colores predefinidos",
3738
- recentColorsLabel: "Colores recientes",
3739
- noRecentColors: "No hay colores recientes",
3740
- invalidColorFormat: "El código de color no es un formato HEX válido (Ej: #FF5733 o FFA07A)",
3741
- colorPreview: "Vista previa del color",
3742
- };
3743
- /**
3744
- * Validates hex color format (#RRGGBB or #RGB)
3745
- */
3746
- const isValidHexColor = (color) => {
3747
- const hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
3748
- return hexRegex.test(color);
3749
- };
3750
- /**
3751
- * Normalizes hex color to 6-digit format (#RGB -> #RRGGBB)
3752
- */
3753
- const normalizeHexColor = (color) => {
3754
- if (!color.startsWith("#")) {
3755
- color = `#${color}`;
3700
+ * Deja una `<style id>` en el `<head>` con las reglas de un componente, una sola vez.
3701
+ *
3702
+ * Existe para los componentes que no pueden depender de `@beweco/aurora-ui/styles`: los
3703
+ * que llegan a un microfrontend por Module Federation (chatbot-claw recibe aurora-ui del
3704
+ * host con `import: false`) o se montan sueltos. Si sus reglas vivieran en `styles.css`,
3705
+ * funcionarían solo cuando el host carga ese CSS y además en la misma versión que el JS
3706
+ * que viaja por MF; cuando no, el componente sale sin animación ni tema y nadie se entera.
3707
+ * Aquí la regla viaja con el componente, como ya hace `SocialMediaCarousel`.
3708
+ *
3709
+ * Idempotente por `id`: cien mascotas en un hilo dejan una sola `<style>`. Nunca reescribe
3710
+ * una `<style>` existente: si en la página conviven dos copias del paquete, se pisarían en
3711
+ * cada montaje. Para que una versión nueva del CSS entre, el id lleva su huella
3712
+ * (`styleIdFor`).
3713
+ */
3714
+ const injectStyle = (doc, id, css) => {
3715
+ if (!doc?.head) {
3716
+ return;
3756
3717
  }
3757
- // Convert 3-digit to 6-digit
3758
- if (color.length === 4) {
3759
- const r = color[1];
3760
- const g = color[2];
3761
- const b = color[3];
3762
- return `#${r}${r}${g}${g}${b}${b}`.toUpperCase();
3718
+ if (doc.getElementById(id)) {
3719
+ return;
3763
3720
  }
3764
- return color.toUpperCase();
3721
+ const style = doc.createElement("style");
3722
+ style.id = id;
3723
+ style.textContent = css;
3724
+ doc.head.appendChild(style);
3725
+ };
3726
+ /** `<base>-<huella del css>`: estable para el mismo CSS, distinto si cambia. */
3727
+ const styleIdFor = (base, css) => {
3728
+ let hash = 5381;
3729
+ for (let i = 0; i < css.length; i++) {
3730
+ hash = ((hash << 5) + hash + css.charCodeAt(i)) | 0;
3731
+ }
3732
+ return `${base}-${(hash >>> 0).toString(36)}`;
3765
3733
  };
3766
3734
  /**
3767
- * Strips leading "#" characters so the text input shows only the hex digits.
3768
- * The "#" prefix is rendered as a fixed startContent in the Input.
3735
+ * `useInsertionEffect` corre antes de pintar y antes que los efectos de layout: las reglas
3736
+ * están en el documento cuando el SVG aparece por primera vez, sin parpadeo sin estilo.
3737
+ * En servidor no corre (y `renderToStaticMarkup` en los tests tampoco lo ejecuta).
3769
3738
  */
3770
- const stripHash = (color) => color.replace(/^#+/, "");
3771
- /**
3772
- * ColorPicker - Advanced color selection component
3773
- *
3774
- * Features:
3775
- * - Native color picker input
3776
- * - Text input for hex codes
3777
- * - Predefined color palette
3778
- * - Recent colors with localStorage persistence
3779
- * - Full i18n support
3780
- * - Dark mode compatible
3781
- * - Accessible
3782
- *
3783
- * @component
3784
- * @example
3785
- * ```tsx
3786
- * <ColorPicker
3787
- * value={brandColor}
3788
- * onChange={setBrandColor}
3789
- * label="Color de marca"
3790
- * enableRecentColors
3791
- * />
3792
- * ```
3793
- */
3794
- const ColorPicker = forwardRef(({ value, onChange, label, required = false, disabled = false, error = false, errorText, predefinedColors = DEFAULT_PREDEFINED_COLORS, enableRecentColors = true, maxRecentColors = 6, recentColorsStorageKey = "aurora-ui-recent-colors", showPredefinedColors = true, translations = {}, className = "", id, name, }, ref) => {
3795
- const generatedId = useId();
3796
- const inputId = id || generatedId;
3797
- const t = { ...defaultTranslations$e, ...translations };
3798
- // Local state for text input — holds the hex digits WITHOUT the leading "#".
3799
- // The "#" is rendered as a fixed startContent prefix.
3800
- const [textValue, setTextValue] = useState(stripHash(value));
3801
- const [isInvalidFormat, setIsInvalidFormat] = useState(false);
3802
- // Recent colors state
3803
- const [recentColors, setRecentColors] = useState([]);
3804
- // Load recent colors from localStorage on mount
3805
- useEffect(() => {
3806
- if (!enableRecentColors)
3807
- return;
3808
- try {
3809
- const stored = localStorage.getItem(recentColorsStorageKey);
3810
- if (stored) {
3811
- const colors = JSON.parse(stored);
3812
- setRecentColors(colors);
3813
- }
3814
- }
3815
- catch (error) {
3816
- console.error("Error loading recent colors:", error);
3817
- }
3818
- }, [enableRecentColors, recentColorsStorageKey]);
3819
- // Save to recent colors when value changes
3820
- useEffect(() => {
3821
- if (!enableRecentColors || !value || !isValidHexColor(value))
3822
- return;
3823
- const normalizedValue = normalizeHexColor(value);
3824
- // Add to recent colors if not already present
3825
- setRecentColors((prev) => {
3826
- // Remove if already exists
3827
- const filtered = prev.filter((c) => c !== normalizedValue);
3828
- // Add to beginning
3829
- const updated = [normalizedValue, ...filtered].slice(0, maxRecentColors);
3830
- // Save to localStorage
3831
- try {
3832
- localStorage.setItem(recentColorsStorageKey, JSON.stringify(updated));
3833
- }
3834
- catch (error) {
3835
- console.error("Error saving recent colors:", error);
3836
- }
3837
- return updated;
3838
- });
3839
- }, [value, enableRecentColors, maxRecentColors, recentColorsStorageKey]);
3840
- // Sync text value when prop value changes
3841
- useEffect(() => {
3842
- setTextValue(stripHash(value));
3843
- setIsInvalidFormat(false);
3844
- }, [value]);
3845
- /**
3846
- * Handle color picker (native input) change
3847
- */
3848
- const handleColorPickerChange = (e) => {
3849
- const newColor = normalizeHexColor(e.target.value);
3850
- setTextValue(stripHash(newColor));
3851
- setIsInvalidFormat(false);
3852
- onChange(newColor);
3853
- };
3854
- /**
3855
- * Handle text input change — passive: no validation, normalization, or
3856
- * onChange propagation while typing. We only update local state and clear
3857
- * any stale error so the user can correct an invalid value without the
3858
- * red border lingering. Validation (and stripping of the leading "#")
3859
- * runs on blur.
3860
- *
3861
- * While typing we let the user see whatever they pressed — including a
3862
- * leading "#" — so the input feels responsive. To prevent a double "#"
3863
- * on screen, the fixed prefix in `startContent` is hidden while
3864
- * `textValue` already starts with "#". The cap is `7` (1 "#" + 6 hex)
3865
- * when the user opted into a leading "#", otherwise `6`.
3866
- */
3867
- const handleTextChange = (newValue) => {
3868
- const max = newValue.startsWith("#") ? 7 : 6;
3869
- setTextValue(newValue.slice(0, max));
3870
- setIsInvalidFormat(false);
3871
- };
3872
- /**
3873
- * Validate the current hex input. Updates `isInvalidFormat` and, when
3874
- * the input is a valid hex, normalizes the display and propagates via
3875
- * `onChange`. Returns whether the input is acceptable so a caller can
3876
- * decide to block submission.
3877
- *
3878
- * Empty + not required → valid (no error, no propagation).
3879
- * Empty + required → invalid (error).
3880
- * Valid (3 or 6 hex chars, with or without leading "#") → normalize, sync
3881
- * display to canonical form, propagate, valid.
3882
- * Otherwise → invalid (error, no propagation).
3883
- */
3884
- const validate = useCallback(() => {
3885
- // User may have typed a leading "#" — strip it so it doesn't end up
3886
- // as "##" once we prepend "#" for the regex check.
3887
- const trimmed = stripHash(textValue.trim());
3888
- if (trimmed === "") {
3889
- const valid = !required;
3890
- setIsInvalidFormat(!valid);
3891
- // Drop any residual "#" the user typed but never followed up on,
3892
- // so the field reads as truly empty after blur.
3893
- setTextValue("");
3894
- return valid;
3895
- }
3896
- const candidate = `#${trimmed}`;
3897
- if (!isValidHexColor(candidate)) {
3898
- setIsInvalidFormat(true);
3899
- return false;
3900
- }
3901
- const normalized = normalizeHexColor(candidate);
3902
- setIsInvalidFormat(false);
3903
- setTextValue(stripHash(normalized));
3904
- onChange(normalized);
3905
- return true;
3906
- }, [textValue, required, onChange]);
3907
- useImperativeHandle(ref, () => ({ validate }), [validate]);
3908
- const handleTextBlur = () => {
3909
- validate();
3910
- };
3911
- /**
3912
- * Handle predefined color selection
3913
- */
3914
- const handlePredefinedColorClick = (colorValue) => {
3915
- if (disabled)
3916
- return;
3917
- const normalized = normalizeHexColor(colorValue);
3918
- setTextValue(stripHash(normalized));
3919
- setIsInvalidFormat(false);
3920
- onChange(normalized);
3921
- };
3922
- /**
3923
- * Render a color circle button
3924
- */
3925
- const renderColorCircle = (colorValue, colorName, isSelected) => (jsx("button", { type: "button", disabled: disabled, onClick: () => handlePredefinedColorClick(colorValue), className: `
3926
- w-8 h-8 rounded-full border-2 cursor-pointer transition-all
3927
- focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-1
3928
- ${disabled ? "opacity-50 cursor-not-allowed" : "hover:scale-110"}
3929
- ${isSelected
3930
- ? "border-primary-500 scale-110 ring-2 ring-primary-500 ring-offset-1"
3931
- : "border-default-700"}
3932
- `, style: { backgroundColor: colorValue }, title: colorName, "aria-label": colorName }, colorValue));
3933
- return (jsxs("div", { className: `flex flex-col gap-3 ${className}`, children: [label && (jsxs("label", { htmlFor: inputId, className: "block text-sm font-medium text-foreground", children: [label, required && jsx("span", { className: "text-danger ml-1", children: "*" })] })), jsxs("div", { className: "flex flex-col gap-1", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("input", { type: "color", id: inputId, name: name, value: `#${stripHash(textValue)}`, onChange: handleColorPickerChange, disabled: disabled, className: `
3934
- w-10 h-10 rounded-lg cursor-pointer border-2 flex-shrink-0
3935
- transition-colors appearance-none bg-transparent p-0.5
3936
- focus:border-primary-500
3937
- ${disabled ? "opacity-50 cursor-not-allowed" : "hover:border-default-400"}
3938
- ${error
3939
- ? "border-danger dark:border-danger-400"
3940
- : "border-default-300 dark:border-default-700"}
3941
- `, "aria-label": t.customColorLabel, title: t.customColorLabel }), jsx(Input, { type: "text", value: textValue, onValueChange: handleTextChange, onBlur: handleTextBlur, placeholder: t.placeholder, disabled: disabled, isDisabled: disabled, isInvalid: error || isInvalidFormat, size: "sm", variant: "bordered",
3942
- // `min-w-0` (TECH-2459, beweossmbs QA 24-sep): el campo es un ítem de la fila
3943
- // flex de la muestra de color y tiene que poder encoger en huecos estrechos
3944
- // (Agenda → Colors: 180px). El `w-full min-w-0` del `<input>` en la fachada
3945
- // ya lo arregla; esto es el suelo explícito en la raíz del campo.
3946
- className: "min-w-0", classNames: {
3947
- input: "uppercase font-mono text-sm",
3948
- inputWrapper: "min-h-8 h-8 focus-within:!border-primary-500",
3949
- }, startContent: textValue.startsWith("#") ? null : (jsx("span", { className: "text-default-400 text-sm", children: "#" })) })] }), (error || isInvalidFormat) && (jsx("p", { className: "text-xs text-danger", children: isInvalidFormat ? t.invalidColorFormat : errorText }))] }), showPredefinedColors && predefinedColors.length > 0 && (jsxs("div", { children: [jsx("p", { className: "text-xs font-medium text-default-600 mb-2", children: t.predefinedColorsLabel }), jsx("div", { className: "flex flex-wrap gap-2", children: predefinedColors.map((color) => renderColorCircle(color.value, color.name, normalizeHexColor(value) === normalizeHexColor(color.value))) })] })), enableRecentColors && recentColors.length > 0 && (jsxs("div", { children: [jsx("p", { className: "text-xs font-medium text-default-600 mb-2", children: t.recentColorsLabel }), jsx("div", { className: "flex flex-wrap gap-2", children: recentColors.map((color) => renderColorCircle(color, color, normalizeHexColor(value) === color)) })] }))] }));
3950
- });
3951
- ColorPicker.displayName = "ColorPicker";
3952
-
3953
- const ThemeContext = createContext({
3954
- mode: "light",
3955
- color: "blue",
3956
- customHex: null,
3957
- // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
3958
- setMode: () => { },
3959
- // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
3960
- setColor: () => { },
3961
- });
3962
- const useThemeContext = () => {
3963
- const context = useContext(ThemeContext);
3964
- if (!context) {
3965
- throw new Error("useThemeContext debe ser usado dentro de un ThemeProvider");
3966
- }
3967
- return context;
3739
+ const useInjectedStyle = (id, css) => {
3740
+ useInsertionEffect(() => {
3741
+ injectStyle(typeof document === "undefined" ? undefined : document, id, css);
3742
+ }, [id, css]);
3968
3743
  };
3969
3744
 
3970
3745
  const themeColors = {
@@ -4765,6 +4540,406 @@ const themeColors = {
4765
4540
  },
4766
4541
  };
4767
4542
 
4543
+ /**
4544
+ * Los mismos nombres de tema que resuelve HeroUI v3 (`@heroui/styles`):
4545
+ * `:root, .light, .default, [data-theme=light], [data-theme=default]` para el claro y
4546
+ * `.dark, [data-theme=dark]` para el oscuro. `default` es un alias del claro en v3; en v2 no
4547
+ * existía. Más los 14 packs de aurora, cada uno en el lado de su `extend`, que son las clases
4548
+ * que `theme-packs.generated.css` declara y `applyThemeClass` pone en `<html>`.
4549
+ */
4550
+ const V3_ALIASES = {
4551
+ light: [".default", '[data-theme="default"]'],
4552
+ dark: [],
4553
+ };
4554
+ const namesOf = (mode) => [
4555
+ `.${mode}`,
4556
+ `[data-theme="${mode}"]`,
4557
+ ...V3_ALIASES[mode],
4558
+ ...Object.entries(themeColors)
4559
+ .filter(([, theme]) => theme.extend === mode)
4560
+ .map(([name]) => `.${name}`),
4561
+ ];
4562
+ /**
4563
+ * Selectores para que un componente con `appearance="auto"` siga al tema del ancestro MÁS
4564
+ * CERCANO.
4565
+ *
4566
+ * Los temas no solo se llaman `dark`/`light`: el `ThemeProvider` de esta librería pone en
4567
+ * `<html>` el tema completo (`blue-dark`, `purple-light`…) y nunca la clase `dark` suelta,
4568
+ * así que mirar solo `.dark` dejaría la pieza en claro sobre un tema oscuro de aurora.
4569
+ *
4570
+ * - `dark`: cualquier ancestro oscuro, o uno oscuro dentro de uno claro.
4571
+ * - `light`: uno claro dentro de uno oscuro (un panel claro en una página oscura). Tiene
4572
+ * una clase más que el oscuro simple, así que gana; va después en la hoja para ganar
4573
+ * también al «oscuro dentro de claro» cuando hay tres niveles.
4574
+ */
4575
+ const themeScopeSelectors = (target) => {
4576
+ const dark = namesOf("dark");
4577
+ const light = namesOf("light");
4578
+ const pairs = (outer, inner) => outer.flatMap((o) => inner.map((i) => `${o} ${i} ${target}`));
4579
+ return {
4580
+ dark: [...dark.map((d) => `${d} ${target}`), ...pairs(light, dark)].join(",\n"),
4581
+ light: pairs(dark, light).join(",\n"),
4582
+ };
4583
+ };
4584
+
4585
+ /**
4586
+ * Reglas del sello Beta. Viajan con el componente (se inyectan en `<head>`), igual que las
4587
+ * de `LindaMascot`: el sello también se pinta dentro del microfrontend del chat.
4588
+ *
4589
+ * Borde de 1 px con el gradiente iridiscente de la mascota muy atenuado: dos fondos, el
4590
+ * neutro recortado al `padding-box` y el gradiente al `border-box`, con el borde
4591
+ * transparente para que se vea el de debajo. Es neutral de marca: lo verá también Luna.
4592
+ */
4593
+ const AUTO_THEME$1 = themeScopeSelectors('.aurora-beta-badge[data-appearance="auto"]');
4594
+ const BETA_BADGE_CSS = `
4595
+ .aurora-beta-badge {
4596
+ --bb-bg: #F6F5FB;
4597
+ --bb-fg: #4B4F6E;
4598
+ --bb-edge: 52%;
4599
+ display: inline-flex;
4600
+ align-items: center;
4601
+ justify-content: center;
4602
+ box-sizing: border-box;
4603
+ border: 1px solid transparent;
4604
+ border-radius: 999px;
4605
+ background:
4606
+ linear-gradient(var(--bb-bg), var(--bb-bg)) padding-box,
4607
+ linear-gradient(
4608
+ 100deg,
4609
+ color-mix(in srgb, #FF8AD8 var(--bb-edge), var(--bb-bg)),
4610
+ color-mix(in srgb, #A48BFF var(--bb-edge), var(--bb-bg)) 38%,
4611
+ color-mix(in srgb, #6FE3FF var(--bb-edge), var(--bb-bg)) 70%,
4612
+ color-mix(in srgb, #FFD08A var(--bb-edge), var(--bb-bg))
4613
+ ) border-box;
4614
+ color: var(--bb-fg);
4615
+ font-family: inherit;
4616
+ font-weight: 600;
4617
+ line-height: 1;
4618
+ letter-spacing: 0.06em;
4619
+ text-transform: uppercase;
4620
+ white-space: nowrap;
4621
+ vertical-align: middle;
4622
+ user-select: none;
4623
+ flex-shrink: 0;
4624
+ }
4625
+ /* Tema: sigue al ancestro claro/oscuro más cercano (ver \`themeScopeSelectors\`). */
4626
+ ${AUTO_THEME$1.dark},
4627
+ .aurora-beta-badge[data-appearance="dark"] {
4628
+ --bb-bg: #1C1D30;
4629
+ --bb-fg: #D5D8F0;
4630
+ --bb-edge: 58%;
4631
+ }
4632
+ ${AUTO_THEME$1.light} {
4633
+ --bb-bg: #F6F5FB;
4634
+ --bb-fg: #4B4F6E;
4635
+ --bb-edge: 52%;
4636
+ }
4637
+ .aurora-beta-badge--sm {
4638
+ font-size: 10px;
4639
+ height: 16px;
4640
+ padding: 0 6px 0 calc(6px + 0.06em);
4641
+ }
4642
+ .aurora-beta-badge--md {
4643
+ font-size: 11px;
4644
+ height: 18px;
4645
+ padding: 0 7px 0 calc(7px + 0.06em);
4646
+ }
4647
+ `;
4648
+
4649
+ const DEFAULT_TRANSLATIONS$f = {
4650
+ label: "Beta",
4651
+ title: "Funcionalidad en pruebas: puede cambiar",
4652
+ };
4653
+ const BETA_BADGE_STYLE_ID = styleIdFor("aurora-beta-badge-styles", BETA_BADGE_CSS);
4654
+ /**
4655
+ * BetaBadge — sello «Beta» para lo que está en pruebas con clientes reales (Linda Claw).
4656
+ * Píldora pequeña en mayúsculas con el borde iridiscente de la mascota muy atenuado.
4657
+ * Ver README.
4658
+ */
4659
+ const BetaBadge = forwardRef(function BetaBadge({ size = "sm", title, appearance = "auto", translations, className, ...spanProps }, ref) {
4660
+ useInjectedStyle(BETA_BADGE_STYLE_ID, BETA_BADGE_CSS);
4661
+ const t = { ...DEFAULT_TRANSLATIONS$f, ...translations };
4662
+ const tooltip = title === true ? t.title : title || undefined;
4663
+ return (jsx("span", { ref: ref, className: [
4664
+ "aurora-beta-badge",
4665
+ `aurora-beta-badge--${size}`,
4666
+ className,
4667
+ ]
4668
+ .filter(Boolean)
4669
+ .join(" "), "data-appearance": appearance, title: tooltip, ...spanProps, children: t.label }));
4670
+ });
4671
+
4672
+ /**
4673
+ * ColorPicker Types
4674
+ *
4675
+ * Defines the type system for the ColorPicker component used for brand configuration.
4676
+ */
4677
+ /**
4678
+ * Default predefined colors (Brand-safe palette)
4679
+ */
4680
+ const DEFAULT_PREDEFINED_COLORS = [
4681
+ // Primary colors
4682
+ { key: "blue", name: "Azul", value: "#3B82F6" },
4683
+ { key: "violet", name: "Violeta", value: "#8B5CF6" },
4684
+ { key: "purple", name: "Púrpura", value: "#A855F7" },
4685
+ // Secondary colors
4686
+ { key: "green", name: "Verde", value: "#10B981" },
4687
+ { key: "teal", name: "Turquesa", value: "#14B8A6" },
4688
+ { key: "cyan", name: "Cian", value: "#06B6D4" },
4689
+ // Accent colors
4690
+ { key: "pink", name: "Rosa", value: "#EC4899" },
4691
+ { key: "rose", name: "Rosa claro", value: "#F43F5E" },
4692
+ { key: "orange", name: "Naranja", value: "#F97316" },
4693
+ // Neutral colors
4694
+ { key: "red", name: "Rojo", value: "#EF4444" },
4695
+ { key: "amber", name: "Ámbar", value: "#F59E0B" },
4696
+ { key: "yellow", name: "Amarillo", value: "#EAB308" },
4697
+ // Gray scale (useful for text/backgrounds)
4698
+ { key: "gray-dark", name: "Gris oscuro", value: "#374151" },
4699
+ { key: "gray", name: "Gris", value: "#6B7280" },
4700
+ { key: "gray-light", name: "Gris claro", value: "#9CA3AF" },
4701
+ ];
4702
+
4703
+ /**
4704
+ * Default translations (Spanish)
4705
+ */
4706
+ const defaultTranslations$e = {
4707
+ label: "Color",
4708
+ placeholder: "Ingresa código hex",
4709
+ customColorLabel: "Color personalizado",
4710
+ predefinedColorsLabel: "Colores predefinidos",
4711
+ recentColorsLabel: "Colores recientes",
4712
+ noRecentColors: "No hay colores recientes",
4713
+ invalidColorFormat: "El código de color no es un formato HEX válido (Ej: #FF5733 o FFA07A)",
4714
+ colorPreview: "Vista previa del color",
4715
+ };
4716
+ /**
4717
+ * Validates hex color format (#RRGGBB or #RGB)
4718
+ */
4719
+ const isValidHexColor = (color) => {
4720
+ const hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
4721
+ return hexRegex.test(color);
4722
+ };
4723
+ /**
4724
+ * Normalizes hex color to 6-digit format (#RGB -> #RRGGBB)
4725
+ */
4726
+ const normalizeHexColor = (color) => {
4727
+ if (!color.startsWith("#")) {
4728
+ color = `#${color}`;
4729
+ }
4730
+ // Convert 3-digit to 6-digit
4731
+ if (color.length === 4) {
4732
+ const r = color[1];
4733
+ const g = color[2];
4734
+ const b = color[3];
4735
+ return `#${r}${r}${g}${g}${b}${b}`.toUpperCase();
4736
+ }
4737
+ return color.toUpperCase();
4738
+ };
4739
+ /**
4740
+ * Strips leading "#" characters so the text input shows only the hex digits.
4741
+ * The "#" prefix is rendered as a fixed startContent in the Input.
4742
+ */
4743
+ const stripHash = (color) => color.replace(/^#+/, "");
4744
+ /**
4745
+ * ColorPicker - Advanced color selection component
4746
+ *
4747
+ * Features:
4748
+ * - Native color picker input
4749
+ * - Text input for hex codes
4750
+ * - Predefined color palette
4751
+ * - Recent colors with localStorage persistence
4752
+ * - Full i18n support
4753
+ * - Dark mode compatible
4754
+ * - Accessible
4755
+ *
4756
+ * @component
4757
+ * @example
4758
+ * ```tsx
4759
+ * <ColorPicker
4760
+ * value={brandColor}
4761
+ * onChange={setBrandColor}
4762
+ * label="Color de marca"
4763
+ * enableRecentColors
4764
+ * />
4765
+ * ```
4766
+ */
4767
+ const ColorPicker = forwardRef(({ value, onChange, label, required = false, disabled = false, error = false, errorText, predefinedColors = DEFAULT_PREDEFINED_COLORS, enableRecentColors = true, maxRecentColors = 6, recentColorsStorageKey = "aurora-ui-recent-colors", showPredefinedColors = true, translations = {}, className = "", id, name, }, ref) => {
4768
+ const generatedId = useId();
4769
+ const inputId = id || generatedId;
4770
+ const t = { ...defaultTranslations$e, ...translations };
4771
+ // Local state for text input — holds the hex digits WITHOUT the leading "#".
4772
+ // The "#" is rendered as a fixed startContent prefix.
4773
+ const [textValue, setTextValue] = useState(stripHash(value));
4774
+ const [isInvalidFormat, setIsInvalidFormat] = useState(false);
4775
+ // Recent colors state
4776
+ const [recentColors, setRecentColors] = useState([]);
4777
+ // Load recent colors from localStorage on mount
4778
+ useEffect(() => {
4779
+ if (!enableRecentColors)
4780
+ return;
4781
+ try {
4782
+ const stored = localStorage.getItem(recentColorsStorageKey);
4783
+ if (stored) {
4784
+ const colors = JSON.parse(stored);
4785
+ setRecentColors(colors);
4786
+ }
4787
+ }
4788
+ catch (error) {
4789
+ console.error("Error loading recent colors:", error);
4790
+ }
4791
+ }, [enableRecentColors, recentColorsStorageKey]);
4792
+ // Save to recent colors when value changes
4793
+ useEffect(() => {
4794
+ if (!enableRecentColors || !value || !isValidHexColor(value))
4795
+ return;
4796
+ const normalizedValue = normalizeHexColor(value);
4797
+ // Add to recent colors if not already present
4798
+ setRecentColors((prev) => {
4799
+ // Remove if already exists
4800
+ const filtered = prev.filter((c) => c !== normalizedValue);
4801
+ // Add to beginning
4802
+ const updated = [normalizedValue, ...filtered].slice(0, maxRecentColors);
4803
+ // Save to localStorage
4804
+ try {
4805
+ localStorage.setItem(recentColorsStorageKey, JSON.stringify(updated));
4806
+ }
4807
+ catch (error) {
4808
+ console.error("Error saving recent colors:", error);
4809
+ }
4810
+ return updated;
4811
+ });
4812
+ }, [value, enableRecentColors, maxRecentColors, recentColorsStorageKey]);
4813
+ // Sync text value when prop value changes
4814
+ useEffect(() => {
4815
+ setTextValue(stripHash(value));
4816
+ setIsInvalidFormat(false);
4817
+ }, [value]);
4818
+ /**
4819
+ * Handle color picker (native input) change
4820
+ */
4821
+ const handleColorPickerChange = (e) => {
4822
+ const newColor = normalizeHexColor(e.target.value);
4823
+ setTextValue(stripHash(newColor));
4824
+ setIsInvalidFormat(false);
4825
+ onChange(newColor);
4826
+ };
4827
+ /**
4828
+ * Handle text input change — passive: no validation, normalization, or
4829
+ * onChange propagation while typing. We only update local state and clear
4830
+ * any stale error so the user can correct an invalid value without the
4831
+ * red border lingering. Validation (and stripping of the leading "#")
4832
+ * runs on blur.
4833
+ *
4834
+ * While typing we let the user see whatever they pressed — including a
4835
+ * leading "#" — so the input feels responsive. To prevent a double "#"
4836
+ * on screen, the fixed prefix in `startContent` is hidden while
4837
+ * `textValue` already starts with "#". The cap is `7` (1 "#" + 6 hex)
4838
+ * when the user opted into a leading "#", otherwise `6`.
4839
+ */
4840
+ const handleTextChange = (newValue) => {
4841
+ const max = newValue.startsWith("#") ? 7 : 6;
4842
+ setTextValue(newValue.slice(0, max));
4843
+ setIsInvalidFormat(false);
4844
+ };
4845
+ /**
4846
+ * Validate the current hex input. Updates `isInvalidFormat` and, when
4847
+ * the input is a valid hex, normalizes the display and propagates via
4848
+ * `onChange`. Returns whether the input is acceptable so a caller can
4849
+ * decide to block submission.
4850
+ *
4851
+ * Empty + not required → valid (no error, no propagation).
4852
+ * Empty + required → invalid (error).
4853
+ * Valid (3 or 6 hex chars, with or without leading "#") → normalize, sync
4854
+ * display to canonical form, propagate, valid.
4855
+ * Otherwise → invalid (error, no propagation).
4856
+ */
4857
+ const validate = useCallback(() => {
4858
+ // User may have typed a leading "#" — strip it so it doesn't end up
4859
+ // as "##" once we prepend "#" for the regex check.
4860
+ const trimmed = stripHash(textValue.trim());
4861
+ if (trimmed === "") {
4862
+ const valid = !required;
4863
+ setIsInvalidFormat(!valid);
4864
+ // Drop any residual "#" the user typed but never followed up on,
4865
+ // so the field reads as truly empty after blur.
4866
+ setTextValue("");
4867
+ return valid;
4868
+ }
4869
+ const candidate = `#${trimmed}`;
4870
+ if (!isValidHexColor(candidate)) {
4871
+ setIsInvalidFormat(true);
4872
+ return false;
4873
+ }
4874
+ const normalized = normalizeHexColor(candidate);
4875
+ setIsInvalidFormat(false);
4876
+ setTextValue(stripHash(normalized));
4877
+ onChange(normalized);
4878
+ return true;
4879
+ }, [textValue, required, onChange]);
4880
+ useImperativeHandle(ref, () => ({ validate }), [validate]);
4881
+ const handleTextBlur = () => {
4882
+ validate();
4883
+ };
4884
+ /**
4885
+ * Handle predefined color selection
4886
+ */
4887
+ const handlePredefinedColorClick = (colorValue) => {
4888
+ if (disabled)
4889
+ return;
4890
+ const normalized = normalizeHexColor(colorValue);
4891
+ setTextValue(stripHash(normalized));
4892
+ setIsInvalidFormat(false);
4893
+ onChange(normalized);
4894
+ };
4895
+ /**
4896
+ * Render a color circle button
4897
+ */
4898
+ const renderColorCircle = (colorValue, colorName, isSelected) => (jsx("button", { type: "button", disabled: disabled, onClick: () => handlePredefinedColorClick(colorValue), className: `
4899
+ w-8 h-8 rounded-full border-2 cursor-pointer transition-all
4900
+ focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-1
4901
+ ${disabled ? "opacity-50 cursor-not-allowed" : "hover:scale-110"}
4902
+ ${isSelected
4903
+ ? "border-primary-500 scale-110 ring-2 ring-primary-500 ring-offset-1"
4904
+ : "border-default-700"}
4905
+ `, style: { backgroundColor: colorValue }, title: colorName, "aria-label": colorName }, colorValue));
4906
+ return (jsxs("div", { className: `flex flex-col gap-3 ${className}`, children: [label && (jsxs("label", { htmlFor: inputId, className: "block text-sm font-medium text-foreground", children: [label, required && jsx("span", { className: "text-danger ml-1", children: "*" })] })), jsxs("div", { className: "flex flex-col gap-1", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("input", { type: "color", id: inputId, name: name, value: `#${stripHash(textValue)}`, onChange: handleColorPickerChange, disabled: disabled, className: `
4907
+ w-10 h-10 rounded-lg cursor-pointer border-2 flex-shrink-0
4908
+ transition-colors appearance-none bg-transparent p-0.5
4909
+ focus:border-primary-500
4910
+ ${disabled ? "opacity-50 cursor-not-allowed" : "hover:border-default-400"}
4911
+ ${error
4912
+ ? "border-danger dark:border-danger-400"
4913
+ : "border-default-300 dark:border-default-700"}
4914
+ `, "aria-label": t.customColorLabel, title: t.customColorLabel }), jsx(Input, { type: "text", value: textValue, onValueChange: handleTextChange, onBlur: handleTextBlur, placeholder: t.placeholder, disabled: disabled, isDisabled: disabled, isInvalid: error || isInvalidFormat, size: "sm", variant: "bordered",
4915
+ // `min-w-0` (TECH-2459, beweossmbs QA 24-sep): el campo es un ítem de la fila
4916
+ // flex de la muestra de color y tiene que poder encoger en huecos estrechos
4917
+ // (Agenda → Colors: 180px). El `w-full min-w-0` del `<input>` en la fachada
4918
+ // ya lo arregla; esto es el suelo explícito en la raíz del campo.
4919
+ className: "min-w-0", classNames: {
4920
+ input: "uppercase font-mono text-sm",
4921
+ inputWrapper: "min-h-8 h-8 focus-within:!border-primary-500",
4922
+ }, startContent: textValue.startsWith("#") ? null : (jsx("span", { className: "text-default-400 text-sm", children: "#" })) })] }), (error || isInvalidFormat) && (jsx("p", { className: "text-xs text-danger", children: isInvalidFormat ? t.invalidColorFormat : errorText }))] }), showPredefinedColors && predefinedColors.length > 0 && (jsxs("div", { children: [jsx("p", { className: "text-xs font-medium text-default-600 mb-2", children: t.predefinedColorsLabel }), jsx("div", { className: "flex flex-wrap gap-2", children: predefinedColors.map((color) => renderColorCircle(color.value, color.name, normalizeHexColor(value) === normalizeHexColor(color.value))) })] })), enableRecentColors && recentColors.length > 0 && (jsxs("div", { children: [jsx("p", { className: "text-xs font-medium text-default-600 mb-2", children: t.recentColorsLabel }), jsx("div", { className: "flex flex-wrap gap-2", children: recentColors.map((color) => renderColorCircle(color, color, normalizeHexColor(value) === color)) })] }))] }));
4923
+ });
4924
+ ColorPicker.displayName = "ColorPicker";
4925
+
4926
+ const ThemeContext = createContext({
4927
+ mode: "light",
4928
+ color: "blue",
4929
+ customHex: null,
4930
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
4931
+ setMode: () => { },
4932
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
4933
+ setColor: () => { },
4934
+ });
4935
+ const useThemeContext = () => {
4936
+ const context = useContext(ThemeContext);
4937
+ if (!context) {
4938
+ throw new Error("useThemeContext debe ser usado dentro de un ThemeProvider");
4939
+ }
4940
+ return context;
4941
+ };
4942
+
4768
4943
  /**
4769
4944
  * @file This file contains the theme configurations for the application.
4770
4945
  */
@@ -6766,6 +6941,535 @@ const LindaIcon = ({ size = 24, className, ...nativeProps }) => {
6766
6941
  return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size, viewBox: "0 0 24 24", className: className, role: "img", "aria-hidden": "true", ...nativeProps, children: jsxs("g", { fill: "currentColor", children: [jsx("path", { d: "M3.84453 3.84453C2.71849 4.97056 2.71849 6.79623 3.84453 7.92226L5.43227 9.51C5.44419 9.49622 5.45669 9.48276 5.46978 9.46967L9.46978 5.46967C9.48284 5.45662 9.49625 5.44415 9.50999 5.43226L7.92226 3.84453C6.79623 2.71849 4.97056 2.71849 3.84453 3.84453Z" }), jsx("path", { d: "M10.5679 6.49012C10.556 6.50386 10.5435 6.51728 10.5304 6.53033L6.53044 10.5303C6.51735 10.5434 6.5039 10.5559 6.49011 10.5678L16.0777 20.1555C17.2038 21.2815 19.0294 21.2815 20.1555 20.1555C21.2815 19.0294 21.2815 17.2038 20.1555 16.0777L10.5679 6.49012Z" }), jsx("path", { d: "M16.1 2.30719C16.261 1.8976 16.8385 1.8976 16.9994 2.30719L17.4298 3.40247C17.479 3.52752 17.5776 3.62651 17.7022 3.67583L18.7934 4.1078C19.2015 4.26934 19.2015 4.849 18.7934 5.01054L17.7022 5.44252C17.5776 5.49184 17.479 5.59082 17.4298 5.71587L16.9995 6.81115C16.8385 7.22074 16.261 7.22074 16.1 6.81116L15.6697 5.71587C15.6205 5.59082 15.5219 5.49184 15.3973 5.44252L14.3061 5.01054C13.898 4.849 13.898 4.26934 14.3061 4.1078L15.3973 3.67583C15.5219 3.62651 15.6205 3.52752 15.6697 3.40247L16.1 2.30719Z" }), jsx("path", { d: "M19.9672 9.12945C20.1281 8.71987 20.7057 8.71987 20.8666 9.12945L21.0235 9.5288C21.0727 9.65385 21.1713 9.75284 21.2959 9.80215L21.6937 9.95965C22.1018 10.1212 22.1018 10.7009 21.6937 10.8624L21.2959 11.0199C21.1713 11.0692 21.0727 11.1682 21.0235 11.2932L20.8666 11.6926C20.7057 12.1022 20.1281 12.1022 19.9672 11.6926L19.8103 11.2932C19.7611 11.1682 19.6625 11.0692 19.5379 11.0199L19.14 10.8624C18.732 10.7009 18.732 10.1212 19.14 9.95965L19.5379 9.80215C19.6625 9.75284 19.7611 9.65385 19.8103 9.5288L19.9672 9.12945Z" }), jsx("path", { d: "M5.1332 15.3072C5.29414 14.8976 5.87167 14.8976 6.03261 15.3072L6.18953 15.7065C6.23867 15.8316 6.33729 15.9306 6.46188 15.9799L6.85975 16.1374C7.26783 16.2989 7.26783 16.8786 6.85975 17.0401L6.46188 17.1976C6.33729 17.2469 6.23867 17.3459 6.18953 17.471L6.03261 17.8703C5.87167 18.2799 5.29414 18.2799 5.1332 17.8703L4.97628 17.471C4.92714 17.3459 4.82852 17.2469 4.70393 17.1976L4.30606 17.0401C3.89798 16.8786 3.89798 16.2989 4.30606 16.1374L4.70393 15.9799C4.82852 15.9306 4.92714 15.8316 4.97628 15.7065L5.1332 15.3072Z" })] }) }));
6767
6942
  };
6768
6943
 
6944
+ const LINDA_MASCOT_STATES = [
6945
+ "idle",
6946
+ "processing",
6947
+ "working",
6948
+ "listening",
6949
+ "talking",
6950
+ "ready",
6951
+ ];
6952
+ /** px de cada talla con nombre. Cada una cae en su propio nivel de detalle. */
6953
+ const LINDA_MASCOT_SIZE_PX = {
6954
+ xs: 20,
6955
+ sm: 32,
6956
+ md: 72,
6957
+ lg: 144,
6958
+ };
6959
+ /** Variable CSS que lleva la intensidad de voz (0–1). Parte del contrato público. */
6960
+ const LINDA_MASCOT_LEVEL_VAR = "--linda-mascot-level";
6961
+ /** id de la `<style>` que el componente deja en `<head>`. */
6962
+ const LINDA_MASCOT_STYLE_ID = "aurora-linda-mascot-styles";
6963
+ /** Paleta de la hoja de marca. */
6964
+ const LINDA_MASCOT_PALETTE = {
6965
+ coreLight: "#2A2D4A",
6966
+ coreDark: "#0B0C18",
6967
+ eye: "#EAF2FF",
6968
+ eyeGlow: "#8FB8FF",
6969
+ pink: "#FF8AD8",
6970
+ violet: "#A48BFF",
6971
+ cyan: "#6FE3FF",
6972
+ amber: "#FFD08A",
6973
+ };
6974
+ const resolveMascotPx = (size) => {
6975
+ if (typeof size === "number") {
6976
+ return Number.isFinite(size) && size > 0 ? size : LINDA_MASCOT_SIZE_PX.md;
6977
+ }
6978
+ return LINDA_MASCOT_SIZE_PX[size ?? "md"] ?? LINDA_MASCOT_SIZE_PX.md;
6979
+ };
6980
+ /** ≤20 xs · 21–40 sm · 41–95 md · ≥96 lg. */
6981
+ const resolveMascotTier = (px) => {
6982
+ if (px <= 20) {
6983
+ return "xs";
6984
+ }
6985
+ if (px <= 40) {
6986
+ return "sm";
6987
+ }
6988
+ if (px < 96) {
6989
+ return "md";
6990
+ }
6991
+ return "lg";
6992
+ };
6993
+ const clampLevel = (level) => {
6994
+ if (typeof level !== "number" || Number.isNaN(level)) {
6995
+ return 0;
6996
+ }
6997
+ return Math.min(1, Math.max(0, level));
6998
+ };
6999
+ const LINDA_MASCOT_GEOMETRY = {
7000
+ xs: {
7001
+ coreRx: 40,
7002
+ coreCy: 61,
7003
+ eyeWidth: 17,
7004
+ eyeHeight: 8,
7005
+ eyeStroke: 9,
7006
+ eyeGap: 31,
7007
+ rings: [{ r: 57, squash: 0.3, tilt: -16, strokePx: 1.2, opacity: 0.95 }],
7008
+ halo: false,
7009
+ specular: false,
7010
+ blur: false,
7011
+ ringGlow: "none",
7012
+ },
7013
+ sm: {
7014
+ coreRx: 36,
7015
+ coreCy: 61,
7016
+ eyeWidth: 14,
7017
+ eyeHeight: 6.5,
7018
+ eyeStroke: 6,
7019
+ eyeGap: 28,
7020
+ rings: [
7021
+ { r: 56, squash: 0.3, tilt: -16, strokePx: 1.1, opacity: 0.9 },
7022
+ { r: 52, squash: 0.36, tilt: 20, strokePx: 1, opacity: 0.7 },
7023
+ ],
7024
+ halo: true,
7025
+ specular: false,
7026
+ blur: false,
7027
+ ringGlow: "none",
7028
+ },
7029
+ md: {
7030
+ coreRx: 33,
7031
+ coreCy: 61,
7032
+ eyeWidth: 12.5,
7033
+ eyeHeight: 5.5,
7034
+ eyeStroke: 4.4,
7035
+ eyeGap: 25,
7036
+ rings: [
7037
+ { r: 56, squash: 0.3, tilt: -16, strokePx: 1.5, opacity: 0.85 },
7038
+ { r: 52, squash: 0.38, tilt: 20, strokePx: 1.2, opacity: 0.7 },
7039
+ { r: 58, squash: 0.2, tilt: -3, strokePx: 1, opacity: 0.55 },
7040
+ ],
7041
+ halo: true,
7042
+ specular: true,
7043
+ blur: true,
7044
+ ringGlow: "flat",
7045
+ },
7046
+ lg: {
7047
+ coreRx: 32,
7048
+ coreCy: 61,
7049
+ eyeWidth: 12,
7050
+ eyeHeight: 5.2,
7051
+ eyeStroke: 3.8,
7052
+ eyeGap: 24,
7053
+ rings: [
7054
+ { r: 56, squash: 0.3, tilt: -16, strokePx: 2, opacity: 0.85 },
7055
+ { r: 52, squash: 0.38, tilt: 20, strokePx: 1.6, opacity: 0.72 },
7056
+ { r: 58, squash: 0.2, tilt: -3, strokePx: 1.3, opacity: 0.58 },
7057
+ ],
7058
+ halo: true,
7059
+ specular: true,
7060
+ blur: true,
7061
+ ringGlow: "blur",
7062
+ },
7063
+ };
7064
+
7065
+ const LEVEL = `var(${LINDA_MASCOT_LEVEL_VAR})`;
7066
+ const AUTO_THEME = themeScopeSelectors('.aurora-linda-mascot[data-appearance="auto"]');
7067
+ /** Curva de los movimientos que responden a la voz: sale rápido, llega suave. */
7068
+ const EASE_OUT = "cubic-bezier(0.22, 0.7, 0.3, 1)";
7069
+ /**
7070
+ * Reglas de la mascota. Viajan con el componente (se inyectan en `<head>`, ver
7071
+ * `useInjectedStyle`) para que funcione en un microfrontend que no carga `styles.css`.
7072
+ *
7073
+ * Todo se anima con `transform` u `opacity`. Cada grupo animado es un `<g>` SIN atributo
7074
+ * `transform`: en SVG la propiedad CSS `transform` reemplaza al atributo, así que la
7075
+ * geometría (posición, inclinación, aplastamiento) vive en grupos padres y el movimiento
7076
+ * en grupos hijos. Por la misma razón, lo que sigue a la voz (`--linda-mascot-level`,
7077
+ * con `transition`) y lo que late en bucle (con `animation`) van en grupos distintos: una
7078
+ * animación CSS anula la transición de la misma propiedad.
7079
+ */
7080
+ /** Reglas de movimiento reducido bajo la raíz \`root\` (clase o clase+atributo). */
7081
+ const reducedMotionBody = (root) => `
7082
+ ${root} .aurora-lm-spin,
7083
+ ${root} .aurora-lm-boost,
7084
+ ${root} .aurora-lm-orbit,
7085
+ ${root} .aurora-lm-eyes,
7086
+ ${root} .aurora-lm-breathe,
7087
+ ${root} .aurora-lm-halo,
7088
+ ${root} .aurora-lm-sparkle {
7089
+ animation: none !important;
7090
+ }
7091
+ ${root} .aurora-lm-level-body,
7092
+ ${root} .aurora-lm-level-rings,
7093
+ ${root} .aurora-lm-level-halo {
7094
+ transform: none !important;
7095
+ }
7096
+ ${root}.aurora-linda-mascot--listening .aurora-lm-level-rings,
7097
+ ${root}.aurora-linda-mascot--talking .aurora-lm-level-rings {
7098
+ opacity: calc(0.55 + ${LEVEL} * 0.45);
7099
+ }
7100
+ ${root}.aurora-linda-mascot--processing .aurora-lm-halo {
7101
+ animation: aurora-lm-glow 1.6s ease-in-out infinite !important;
7102
+ }
7103
+ ${root}.aurora-linda-mascot--working .aurora-lm-halo {
7104
+ opacity: 1 !important;
7105
+ }
7106
+ ${root}.aurora-linda-mascot--listening .aurora-lm-level-halo,
7107
+ ${root}.aurora-linda-mascot--talking .aurora-lm-level-halo {
7108
+ opacity: calc(0.4 + ${LEVEL} * 0.6) !important;
7109
+ }
7110
+ ${root}.aurora-linda-mascot--ready .aurora-lm-sparkle {
7111
+ animation: aurora-lm-sparkle-fade 700ms ease-out 1 both !important;
7112
+ }
7113
+ `;
7114
+ const reducedMotionRules = (root) => `
7115
+ @media (prefers-reduced-motion: reduce) {${reducedMotionBody(root)}}
7116
+ ${reducedMotionBody(`${root}[data-motion="reduce"]`)}
7117
+ `;
7118
+ const LINDA_MASCOT_CSS = `
7119
+ .aurora-linda-mascot {
7120
+ ${LINDA_MASCOT_LEVEL_VAR}: 0;
7121
+ --lm-halo: 0.5;
7122
+ --lm-shadow: 1;
7123
+ --lm-rim: 0.85;
7124
+ --lm-sparkle: #F2B441;
7125
+ display: inline-block;
7126
+ flex-shrink: 0;
7127
+ overflow: visible;
7128
+ vertical-align: middle;
7129
+ }
7130
+ /* En lg la mascota es escenario (bienvenida, llamada): más halo, como en la hoja de marca.
7131
+ Multiplicador aparte para no competir en especificidad con las reglas de tema. */
7132
+ .aurora-linda-mascot--tier-lg {
7133
+ --lm-halo-boost: 1.4;
7134
+ }
7135
+ /*
7136
+ * Tema. \`auto\` sigue al ancestro claro/oscuro más cercano, incluidos los temas de aurora
7137
+ * (\`blue-dark\`…); ver \`themeScopeSelectors\`.
7138
+ */
7139
+ ${AUTO_THEME.dark},
7140
+ .aurora-linda-mascot[data-appearance="dark"] {
7141
+ --lm-halo: 0.95;
7142
+ --lm-shadow: 0;
7143
+ --lm-rim: 1;
7144
+ --lm-sparkle: #FFF1C9;
7145
+ }
7146
+ ${AUTO_THEME.light} {
7147
+ --lm-halo: 0.5;
7148
+ --lm-shadow: 1;
7149
+ --lm-rim: 0.85;
7150
+ --lm-sparkle: #F2B441;
7151
+ }
7152
+
7153
+ /* Cuerpo entero: respiración en bucle + escala por voz (grupos distintos). */
7154
+ .aurora-lm-breathe,
7155
+ .aurora-lm-level-body,
7156
+ .aurora-lm-level-rings {
7157
+ transform-box: view-box;
7158
+ transform-origin: 60px 61px;
7159
+ }
7160
+ .aurora-lm-breathe {
7161
+ animation: aurora-lm-breathe 2s ease-in-out infinite alternate;
7162
+ }
7163
+ .aurora-lm-level-body,
7164
+ .aurora-lm-level-rings,
7165
+ .aurora-lm-level-halo {
7166
+ transition: transform 140ms ${EASE_OUT}, opacity 240ms ${EASE_OUT};
7167
+ }
7168
+
7169
+ /* Halo y sombra de contacto. */
7170
+ .aurora-lm-halo,
7171
+ .aurora-lm-level-halo {
7172
+ transform-box: fill-box;
7173
+ transform-origin: center;
7174
+ }
7175
+ .aurora-lm-halo {
7176
+ opacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));
7177
+ transition: opacity 400ms ease;
7178
+ }
7179
+ .aurora-lm-shadow {
7180
+ opacity: var(--lm-shadow);
7181
+ }
7182
+ .aurora-lm-rim {
7183
+ opacity: var(--lm-rim);
7184
+ }
7185
+
7186
+ /*
7187
+ * Anillos. El círculo gira dentro de su grupo aplastado: la elipse no cambia de forma y
7188
+ * lo que recorre el trazo es el color, como un anillo que gira en profundidad.
7189
+ * \`--lm-spin-duration\` y \`--lm-spin-direction\` llegan por anillo desde el marcado.
7190
+ */
7191
+ .aurora-lm-spin {
7192
+ transform-box: view-box;
7193
+ transform-origin: 0 0;
7194
+ animation: aurora-lm-spin var(--lm-spin-duration, 24s) linear infinite
7195
+ var(--lm-spin-direction, normal);
7196
+ }
7197
+ /* Segundo giro encadenado: parado salvo en working, donde dobla la velocidad sin saltos
7198
+ (pausar conserva el ángulo; cambiar la duración lo haría saltar). */
7199
+ .aurora-lm-boost {
7200
+ animation-play-state: paused;
7201
+ }
7202
+ /* Cometa del anillo principal: orbita siempre, se ve solo al pensar o trabajar. */
7203
+ .aurora-lm-orbit {
7204
+ animation-play-state: paused;
7205
+ }
7206
+ .aurora-lm-comet,
7207
+ .aurora-lm-glint {
7208
+ opacity: 0;
7209
+ transition: opacity 320ms ease;
7210
+ }
7211
+
7212
+ /* Ojos: solo parpadean (sin expresiones faciales). Dos parpadeos por ciclo, a 4,8 y 6,2 s. */
7213
+ .aurora-lm-eyes {
7214
+ transform-box: fill-box;
7215
+ transform-origin: center;
7216
+ animation: aurora-lm-blink 11s ease-in-out infinite;
7217
+ }
7218
+
7219
+ /* Chispas de fin de turno. */
7220
+ /* Dorado en claro (el blanco desaparece sobre fondo claro), casi blanco en oscuro. */
7221
+ .aurora-lm-sparkle {
7222
+ transform-box: fill-box;
7223
+ transform-origin: center;
7224
+ opacity: 0;
7225
+ fill: var(--lm-sparkle);
7226
+ }
7227
+
7228
+ /* ── Estados ─────────────────────────────────────────────────────────────── */
7229
+
7230
+ /* idle no añade nada: es el movimiento base de arriba (giro, respiración, parpadeo). */
7231
+
7232
+ .aurora-linda-mascot--processing .aurora-lm-orbit {
7233
+ animation-play-state: running;
7234
+ }
7235
+ .aurora-linda-mascot--processing .aurora-lm-comet {
7236
+ opacity: 1;
7237
+ }
7238
+ .aurora-linda-mascot--processing .aurora-lm-halo {
7239
+ animation: aurora-lm-pulse 1.6s ease-in-out infinite;
7240
+ }
7241
+
7242
+ .aurora-linda-mascot--working .aurora-lm-boost,
7243
+ .aurora-linda-mascot--working .aurora-lm-orbit {
7244
+ animation-play-state: running;
7245
+ }
7246
+ .aurora-linda-mascot--working .aurora-lm-glint {
7247
+ opacity: 1;
7248
+ }
7249
+
7250
+ .aurora-linda-mascot--listening .aurora-lm-level-rings {
7251
+ transform: scale(calc(0.86 + ${LEVEL} * 0.16));
7252
+ }
7253
+ .aurora-linda-mascot--listening .aurora-lm-level-halo {
7254
+ transform: scale(calc(0.92 + ${LEVEL} * 0.2));
7255
+ }
7256
+
7257
+ .aurora-linda-mascot--talking .aurora-lm-level-body {
7258
+ transform: scale(calc(1 + ${LEVEL} * 0.07));
7259
+ }
7260
+ .aurora-linda-mascot--talking .aurora-lm-level-halo {
7261
+ transform: scale(calc(1 + ${LEVEL} * 0.32));
7262
+ opacity: calc(0.75 + ${LEVEL} * 0.25);
7263
+ }
7264
+
7265
+ .aurora-linda-mascot--ready .aurora-lm-sparkle {
7266
+ animation: aurora-lm-sparkle 700ms cubic-bezier(0.2, 0.8, 0.3, 1) 1 both;
7267
+ animation-delay: var(--lm-sparkle-delay, 0ms);
7268
+ }
7269
+
7270
+ /* ── Keyframes ───────────────────────────────────────────────────────────── */
7271
+
7272
+ @keyframes aurora-lm-spin {
7273
+ to {
7274
+ transform: rotate(360deg);
7275
+ }
7276
+ }
7277
+ @keyframes aurora-lm-breathe {
7278
+ from {
7279
+ transform: scale(1);
7280
+ }
7281
+ to {
7282
+ transform: scale(1.03);
7283
+ }
7284
+ }
7285
+ @keyframes aurora-lm-blink {
7286
+ 0%, 42%, 45%, 97.5%, 100% {
7287
+ transform: scaleY(1);
7288
+ }
7289
+ 43.5%, 98.8% {
7290
+ transform: scaleY(0.12);
7291
+ }
7292
+ }
7293
+ @keyframes aurora-lm-pulse {
7294
+ 0%, 100% {
7295
+ transform: scale(1);
7296
+ opacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));
7297
+ }
7298
+ 50% {
7299
+ transform: scale(1.12);
7300
+ opacity: 1;
7301
+ }
7302
+ }
7303
+ @keyframes aurora-lm-glow {
7304
+ 0%, 100% {
7305
+ opacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));
7306
+ }
7307
+ 50% {
7308
+ opacity: 1;
7309
+ }
7310
+ }
7311
+ @keyframes aurora-lm-sparkle {
7312
+ 0% {
7313
+ opacity: 0;
7314
+ transform: scale(0.2) rotate(0deg);
7315
+ }
7316
+ 35% {
7317
+ opacity: 1;
7318
+ transform: scale(1) rotate(45deg);
7319
+ }
7320
+ 100% {
7321
+ opacity: 0;
7322
+ transform: scale(0.5) rotate(90deg);
7323
+ }
7324
+ }
7325
+ @keyframes aurora-lm-sparkle-fade {
7326
+ 0%, 100% {
7327
+ opacity: 0;
7328
+ }
7329
+ 35% {
7330
+ opacity: 1;
7331
+ }
7332
+ }
7333
+
7334
+ /*
7335
+ * Movimiento reducido: nada gira, parpadea, respira ni crece. El estado se sigue leyendo
7336
+ * sin movimiento: al pensar o trabajar el cometa o el destello se quedan quietos sobre el
7337
+ * anillo (así se distingue también en \`xs\`, que no tiene halo) y el halo late en opacidad
7338
+ * o se enciende; con la voz sube la opacidad del halo y de los anillos; las chispas
7339
+ * aparecen y se desvanecen sin moverse.
7340
+ *
7341
+ * Las mismas reglas se aplican con la preferencia del sistema y con \`motion="reduce"\`
7342
+ * (\`data-motion\`), que el consumidor usa para listas largas o para forzarlo. \`!important\`
7343
+ * porque las reglas por estado de arriba tienen más especificidad y \`@media\` no la sube.
7344
+ */
7345
+ ${reducedMotionRules(".aurora-linda-mascot")}
7346
+ `;
7347
+
7348
+ const CX = 60;
7349
+ const STYLE_ID = styleIdFor(LINDA_MASCOT_STYLE_ID, LINDA_MASCOT_CSS);
7350
+ /** Velocidad de giro por anillo (s por vuelta) y sentido. */
7351
+ const RING_MOTION = [
7352
+ { duration: "24s", direction: "normal" },
7353
+ { duration: "30s", direction: "reverse" },
7354
+ { duration: "36s", direction: "normal" },
7355
+ ];
7356
+ /** Chispas de `ready`: posición en el viewBox, tamaño y retardo. */
7357
+ const SPARKLES = [
7358
+ { x: 90, y: 17, s: 9, delay: "0ms" },
7359
+ { x: 104, y: 35, s: 5.5, delay: "90ms" },
7360
+ { x: 73, y: 7, s: 4.5, delay: "170ms" },
7361
+ ];
7362
+ const sparklePath = (s) => {
7363
+ const k = s * 0.18;
7364
+ return `M0 ${-s}C${k} ${-k} ${k} ${-k} ${s} 0C${k} ${k} ${k} ${k} 0 ${s}C${-k} ${k} ${-k} ${k} ${-s} 0C${-k} ${-k} ${-k} ${-k} 0 ${-s}Z`;
7365
+ };
7366
+ /**
7367
+ * Perímetro en px de pantalla de la elipse de un anillo. Con `non-scaling-stroke` los
7368
+ * guiones se miden en px de pantalla (no en unidades del viewBox ni en `pathLength`), así
7369
+ * que el cometa se dimensiona como fracción de este perímetro para medir lo mismo a
7370
+ * cualquier talla.
7371
+ */
7372
+ const ringPerimeterPx = (ring, px) => {
7373
+ const a = (ring.r * px) / 120;
7374
+ const b = a * ring.squash;
7375
+ const h = ((a - b) / (a + b)) ** 2;
7376
+ return Math.PI * (a + b) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)));
7377
+ };
7378
+ /**
7379
+ * Cometa con estela sobre un anillo: cola de `steps` tramos consecutivos con el
7380
+ * iridiscente del anillo, cada uno más opaco y más grueso que el anterior, y una cabeza
7381
+ * redonda y brillante al final. Todo es `stroke-dasharray` sobre el mismo círculo que el
7382
+ * anillo, así que gira con `transform` y se recorta delante/detrás igual que él. El giro
7383
+ * es horario: la cabeza va al final del trazo, por delante de su cola.
7384
+ */
7385
+ const Comet = ({ className, r, perimeter, tail, strokePx, headPx, steps, ringPaint, headPaint, }) => {
7386
+ const tailPx = perimeter * tail;
7387
+ const seg = tailPx / steps;
7388
+ return (jsxs("g", { className: className, "data-part": "comet", children: [Array.from({ length: steps }, (_, i) => {
7389
+ const t = (i + 1) / steps;
7390
+ return (jsx("circle", { r: r, fill: "none", stroke: ringPaint, strokeWidth: strokePx * (0.8 + 1.6 * t), strokeOpacity: t ** 1.5, strokeDasharray: `${(seg + 0.4).toFixed(2)} ${(perimeter - seg - 0.4).toFixed(2)}`, strokeDashoffset: (-seg * i).toFixed(2), vectorEffect: "non-scaling-stroke" }, i));
7391
+ }), jsx("circle", { r: r, fill: "none", stroke: headPaint, strokeWidth: headPx * 1.5, strokeOpacity: 0.3, strokeLinecap: "round", strokeDasharray: `0.01 ${(perimeter - 0.01).toFixed(2)}`, strokeDashoffset: (-tailPx).toFixed(2), vectorEffect: "non-scaling-stroke" }), jsx("circle", { r: r, fill: "none", stroke: "#FFFFFF", strokeWidth: headPx, strokeLinecap: "round", strokeDasharray: `0.01 ${(perimeter - 0.01).toFixed(2)}`, strokeDashoffset: (-tailPx).toFixed(2), vectorEffect: "non-scaling-stroke" })] }));
7392
+ };
7393
+ /** Arco «∩» de un ojo centrado en (x, y): ancho w, alto h. */
7394
+ const eyePath = (x, y, w, h) => {
7395
+ const half = w / 2;
7396
+ const base = y + h / 2;
7397
+ const control = y - h * 0.8333;
7398
+ return `M${x - half} ${base}C${x - half} ${control} ${x + half} ${control} ${x + half} ${base}`;
7399
+ };
7400
+ /**
7401
+ * `useId` devuelve `:r0:` (React 18), `«r0»` o `_r_0_` (19): fuera lo que no vale en un
7402
+ * id referenciado desde `url(#…)`.
7403
+ */
7404
+ const safeId = (raw) => `lm${raw.replace(/[^a-zA-Z0-9_-]/g, "")}`;
7405
+ /**
7406
+ * LindaMascot — la cara de Linda: un orbe de tinta con ojos luminosos y anillos
7407
+ * iridiscentes, en SVG + CSS (sin imágenes, fuentes ni WebGL).
7408
+ *
7409
+ * Se anima según lo que Linda está haciendo (`state`) y, en la llamada de voz, según el
7410
+ * volumen (`level`), sin preguntar nada al modelo. Pinta más o menos detalle según la
7411
+ * talla para leerse igual a 16 px que a 200 px. Ver README.
7412
+ */
7413
+ const LindaMascot = forwardRef(function LindaMascot({ state = "idle", size = "md", level, label, appearance = "auto", motion = "auto", className, style, ...svgProps }, ref) {
7414
+ useInjectedStyle(STYLE_ID, LINDA_MASCOT_CSS);
7415
+ const uid = safeId(useId());
7416
+ const px = resolveMascotPx(size);
7417
+ const tier = resolveMascotTier(px);
7418
+ const g = LINDA_MASCOT_GEOMETRY[tier];
7419
+ const coreRy = g.coreRx * 0.92;
7420
+ const eyeY = g.coreCy - coreRy + coreRy * 2 * 0.45;
7421
+ const eyes = [CX - g.eyeGap / 2, CX + g.eyeGap / 2];
7422
+ // Recorte delante/detrás: en lg los velos desenfocados salen más allá del anillo.
7423
+ const clipHalf = g.ringGlow === "blur" ? 120 : 80;
7424
+ const id = {
7425
+ core: `${uid}-core`,
7426
+ coreClip: `${uid}-core-clip`,
7427
+ rim: `${uid}-rim`,
7428
+ ring: `${uid}-ring`,
7429
+ halo: `${uid}-halo`,
7430
+ shadow: `${uid}-shadow`,
7431
+ specular: `${uid}-specular`,
7432
+ back: `${uid}-back`,
7433
+ front: `${uid}-front`,
7434
+ soft: `${uid}-soft`,
7435
+ eyeGlow: `${uid}-eye-glow`,
7436
+ aura: `${uid}-aura`,
7437
+ veil: `${uid}-veil`,
7438
+ tail: `${uid}-tail`,
7439
+ };
7440
+ const a11y = label
7441
+ ? { role: "img", "aria-label": label }
7442
+ : { "aria-hidden": true };
7443
+ const renderRing = (ring, index, half) => {
7444
+ const motion = RING_MOTION[index];
7445
+ const spinStyle = {
7446
+ "--lm-spin-duration": motion.duration,
7447
+ "--lm-spin-direction": motion.direction,
7448
+ };
7449
+ const isMain = index === 0;
7450
+ const perimeter = ringPerimeterPx(ring, px);
7451
+ return (jsx("g", { "data-ring": index + 1, "data-ring-half": half, transform: `translate(${CX} ${g.coreCy}) rotate(${ring.tilt})`, opacity: half === "back" ? ring.opacity * 0.62 : ring.opacity, children: jsx("g", { clipPath: `url(#${half === "back" ? id.back : id.front})`, children: jsxs("g", { transform: `scale(1 ${ring.squash})`, children: [jsx("g", { className: "aurora-lm-spin", style: spinStyle, children: jsxs("g", { className: "aurora-lm-spin aurora-lm-boost", style: spinStyle, children: [g.ringGlow === "blur" && (jsx("circle", { "data-part": "veil", r: ring.r, fill: "none", stroke: `url(#${id.ring})`, strokeWidth: ring.strokePx * 16, strokeOpacity: 0.3, vectorEffect: "non-scaling-stroke", filter: `url(#${id.veil})` })), g.ringGlow !== "none" && (jsx("circle", { r: ring.r, fill: "none", stroke: `url(#${id.ring})`, strokeWidth: ring.strokePx * (g.ringGlow === "blur" ? 6.5 : 5), strokeOpacity: g.ringGlow === "blur" ? 0.34 : 0.14, vectorEffect: "non-scaling-stroke", filter: g.ringGlow === "blur" ? `url(#${id.soft})` : undefined })), g.ringGlow !== "none" && (jsx("circle", { r: ring.r + 2.2, fill: "none", stroke: `url(#${id.ring})`, strokeWidth: ring.strokePx * 0.55, strokeOpacity: 0.55, vectorEffect: "non-scaling-stroke" })), jsx("circle", { r: ring.r, fill: "none", stroke: `url(#${id.ring})`, strokeWidth: ring.strokePx, vectorEffect: "non-scaling-stroke" })] }) }), isMain && (jsxs("g", { className: "aurora-lm-spin aurora-lm-orbit", style: {
7452
+ "--lm-spin-duration": "1.6s",
7453
+ }, children: [jsx(Comet, { className: "aurora-lm-comet", r: ring.r, perimeter: perimeter, tail: 0.3, strokePx: ring.strokePx, headPx: Math.max(2, ring.strokePx * 2.4), steps: tier === "xs" ? 6 : 12, ringPaint: `url(#${id.tail})`, headPaint: LINDA_MASCOT_PALETTE.eyeGlow }), jsx(Comet, { className: "aurora-lm-glint", r: ring.r, perimeter: perimeter, tail: 0.14, strokePx: ring.strokePx * 1.2, headPx: Math.max(2.4, ring.strokePx * 3), steps: tier === "xs" ? 4 : 8, ringPaint: `url(#${id.tail})`, headPaint: LINDA_MASCOT_PALETTE.eyeGlow })] }))] }) }) }, `${half}-${index}`));
7454
+ };
7455
+ const ringHalves = (half) => g.rings.map((ring, index) => renderRing(ring, index, half));
7456
+ return (
7457
+ // biome-ignore lint/a11y/noSvgWithoutTitle: el nombre llega por aria-label (con `label`) o la mascota es decorativa (aria-hidden); biome no ve el spread de `a11y`.
7458
+ jsxs("svg", { ref: ref, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 120 120", width: px, height: px, focusable: "false", className: [
7459
+ "aurora-linda-mascot",
7460
+ `aurora-linda-mascot--${state}`,
7461
+ `aurora-linda-mascot--tier-${tier}`,
7462
+ className,
7463
+ ]
7464
+ .filter(Boolean)
7465
+ .join(" "), "data-state": state, "data-tier": tier, "data-appearance": appearance, "data-motion": motion, style: {
7466
+ ...style,
7467
+ [LINDA_MASCOT_LEVEL_VAR]: clampLevel(level),
7468
+ }, ...a11y, ...svgProps, children: [jsxs("defs", { children: [jsxs("radialGradient", { id: id.core, cx: "0.4", cy: "0.34", r: "0.72", children: [jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.coreLight }), jsx("stop", { offset: "0.6", stopColor: "#15172B" }), jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.coreDark })] }), jsxs("linearGradient", { id: id.ring, x1: "0", y1: "0", x2: "1", y2: "1", children: [jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.pink }), jsx("stop", { offset: "0.36", stopColor: LINDA_MASCOT_PALETTE.violet }), jsx("stop", { offset: "0.68", stopColor: LINDA_MASCOT_PALETTE.cyan }), jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.amber })] }), jsxs("linearGradient", { id: id.tail, x1: "0", y1: "0", x2: "1", y2: "1", children: [jsx("stop", { offset: "0", stopColor: "#FFC4EC" }), jsx("stop", { offset: "0.36", stopColor: "#D4C8FF" }), jsx("stop", { offset: "0.68", stopColor: "#B8F1FF" }), jsx("stop", { offset: "1", stopColor: "#FFE6BF" })] }), jsxs("linearGradient", { id: id.rim, x1: "0.2", y1: "0", x2: "0.5", y2: "1", children: [jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.violet }), jsx("stop", { offset: "0.42", stopColor: LINDA_MASCOT_PALETTE.cyan }), jsx("stop", { offset: "0.74", stopColor: LINDA_MASCOT_PALETTE.pink }), jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.amber })] }), jsx("clipPath", { id: id.coreClip, children: jsx("ellipse", { cx: CX, cy: g.coreCy, rx: g.coreRx, ry: coreRy }) }), jsx("clipPath", { id: id.back, children: jsx("rect", { x: -clipHalf, y: -clipHalf, width: clipHalf * 2, height: clipHalf }) }), jsx("clipPath", { id: id.front, children: jsx("rect", { x: -clipHalf, y: 0, width: clipHalf * 2, height: clipHalf }) }), g.halo && (jsxs("radialGradient", { id: id.halo, children: [jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.violet, stopOpacity: "0.7" }), jsx("stop", { offset: tier === "lg" ? "0.48" : "0.42", stopColor: LINDA_MASCOT_PALETTE.pink, stopOpacity: tier === "lg" ? "0.36" : "0.28" }), jsx("stop", { offset: tier === "lg" ? "0.78" : "0.7", stopColor: LINDA_MASCOT_PALETTE.cyan, stopOpacity: tier === "lg" ? "0.14" : "0.08" }), jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.cyan, stopOpacity: "0" })] })), g.halo && (jsxs("radialGradient", { id: id.shadow, children: [jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.coreDark, stopOpacity: "0.28" }), jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.coreDark, stopOpacity: "0" })] })), g.specular && (jsxs("radialGradient", { id: id.specular, children: [jsx("stop", { offset: "0", stopColor: "#FFFFFF", stopOpacity: "0.2" }), jsx("stop", { offset: "1", stopColor: "#FFFFFF", stopOpacity: "0" })] })), g.blur && (jsx("filter", { id: id.eyeGlow, filterUnits: "userSpaceOnUse", x: "-20", y: "-20", width: "160", height: "160", children: jsx("feGaussianBlur", { stdDeviation: "2.2" }) })), g.blur && (jsx("filter", { id: id.aura, filterUnits: "userSpaceOnUse", x: "-20", y: "-20", width: "160", height: "160", children: jsx("feGaussianBlur", { stdDeviation: tier === "lg" ? 5.5 : 4 }) })), g.ringGlow === "blur" && (jsx("filter", { id: id.soft, filterUnits: "userSpaceOnUse", x: "-90", y: "-90", width: "180", height: "180", children: jsx("feGaussianBlur", { stdDeviation: "2.6" }) })), g.ringGlow === "blur" && (jsx("filter", { id: id.veil, filterUnits: "userSpaceOnUse", x: "-100", y: "-100", width: "200", height: "200", children: jsx("feGaussianBlur", { stdDeviation: "5" }) }))] }), jsx("g", { className: "aurora-lm-level-body", children: jsxs("g", { className: "aurora-lm-breathe", children: [g.halo && (jsx("g", { className: "aurora-lm-level-halo", children: jsx("circle", { className: "aurora-lm-halo", "data-part": "halo", cx: CX, cy: g.coreCy, r: tier === "lg" ? 61 : 58, fill: `url(#${id.halo})` }) })), g.halo && (jsx("ellipse", { className: "aurora-lm-shadow", "data-part": "shadow", cx: CX, cy: g.coreCy + coreRy + 9, rx: g.coreRx * 0.8, ry: 4.5, fill: `url(#${id.shadow})` })), jsx("g", { className: "aurora-lm-rings aurora-lm-level-rings", children: ringHalves("back") }), tier !== "xs" && (jsx("ellipse", { className: "aurora-lm-rim", "data-part": "aura", cx: CX, cy: g.coreCy, rx: g.coreRx + 1, ry: coreRy + 1, fill: "none", stroke: `url(#${id.rim})`, strokeWidth: tier === "lg" ? 9 : g.blur ? 7 : 3, strokeOpacity: tier === "lg" ? 0.85 : g.blur ? 0.75 : 0.45, filter: g.blur ? `url(#${id.aura})` : undefined })), jsxs("g", { "data-part": "core", children: [jsx("ellipse", { cx: CX, cy: g.coreCy, rx: g.coreRx, ry: coreRy, fill: `url(#${id.core})` }), jsx("g", { clipPath: `url(#${id.coreClip})`, children: jsx("ellipse", { className: "aurora-lm-rim", cx: CX, cy: g.coreCy, rx: g.coreRx, ry: coreRy, fill: "none", stroke: `url(#${id.rim})`, strokeWidth: tier === "xs" ? 5 : g.blur ? 7 : 5, filter: g.blur ? `url(#${id.eyeGlow})` : undefined }) }), g.specular && (jsx("ellipse", { "data-part": "specular", cx: CX - g.coreRx * 0.36, cy: g.coreCy - coreRy * 0.5, rx: g.coreRx * 0.38, ry: g.coreRx * 0.2, transform: `rotate(-28 ${CX - g.coreRx * 0.36} ${g.coreCy - coreRy * 0.5})`, fill: `url(#${id.specular})` }))] }), jsxs("g", { className: "aurora-lm-eyes", "data-part": "eyes", children: [eyes.map((x) => (jsx("path", { d: eyePath(x, eyeY, g.eyeWidth, g.eyeHeight), fill: "none", stroke: LINDA_MASCOT_PALETTE.eyeGlow, strokeWidth: g.eyeStroke * (g.blur ? 2.2 : 1.7), strokeLinecap: "round", strokeOpacity: g.blur ? 0.85 : 0.35, filter: g.blur ? `url(#${id.eyeGlow})` : undefined }, `glow-${x}`))), eyes.map((x) => (jsx("path", { "data-part": "eye", d: eyePath(x, eyeY, g.eyeWidth, g.eyeHeight), fill: "none", stroke: LINDA_MASCOT_PALETTE.eye, strokeWidth: g.eyeStroke, strokeLinecap: "round" }, `eye-${x}`)))] }), jsx("g", { className: "aurora-lm-rings aurora-lm-level-rings", children: ringHalves("front") }), state === "ready" && tier !== "xs" && (jsx("g", { "data-part": "sparkles", children: SPARKLES.map((s) => (jsx("g", { transform: `translate(${s.x} ${s.y})`, children: jsx("path", { className: "aurora-lm-sparkle", d: sparklePath(s.s), style: {
7469
+ "--lm-sparkle-delay": s.delay,
7470
+ } }) }, `${s.x}-${s.y}`))) }))] }) })] }));
7471
+ });
7472
+
6769
7473
  const defaultTranslations$8 = {
6770
7474
  previewAlt: "Vista previa de imagen",
6771
7475
  removeButtonAriaLabel: "Eliminar imagen",
@@ -11987,31 +12691,20 @@ const VARIANT_BY_COLOR = {
11987
12691
  danger: "danger",
11988
12692
  default: "default",
11989
12693
  };
11990
- // TECH-2459 · F5 · P-25 — v2 pintaba el toast con `<Alert variant="flat" color={...}>`, y el
11991
- // `flat` de v2 daba FONDO TEÑIDO por color (`@heroui/theme@2.4.15`, `chunk-BGEKJ4Q5.mjs`,
11992
- // compound `variant: ["flat","faded"]`: `bg-success-50 dark:bg-success-50/50`, etc.). `.toast` de
11993
- // v3 es siempre `bg-surface` (medido: `oklch(1 0 0)`, blanco puro) y solo tiñe el título, así que
11994
- // el fondo de color se había perdido. Se reponen las clases LITERALES de v2 — Aurora emite toda
11995
- // la escala 50-900 en `@theme static`, así que `bg-success-50` sigue siendo una utilidad válida.
11996
- const SURFACE_BY_COLOR = {
11997
- primary: "bg-primary-50 dark:bg-primary-50/50",
11998
- secondary: "bg-secondary-50 dark:bg-secondary-50/50",
11999
- success: "bg-success-50 dark:bg-success-50/50",
12000
- warning: "bg-warning-50 dark:bg-warning-50/50",
12001
- danger: "bg-danger-50 dark:bg-danger-50/50",
12002
- default: "bg-default-100 dark:bg-default-50/50",
12003
- };
12004
- // Color de la `x`, también tomado del slot `closeButton` de v2 (`text-success-500`,
12005
- // `data-[hover]:bg-success-200`, …). `bg-transparent` neutraliza el `bg-default` de
12006
- // `.close-button--default` de v3, que sobre un fondo teñido cantaba como una píldora gris.
12007
- const CLOSE_BY_COLOR = {
12008
- primary: "text-primary-500 hover:bg-primary-200",
12009
- secondary: "text-secondary-500 hover:bg-secondary-200",
12010
- success: "text-success-500 hover:bg-success-200",
12011
- warning: "text-warning-500 hover:bg-warning-200",
12012
- danger: "text-danger-500 hover:bg-danger-200",
12013
- default: "text-default-400 hover:bg-default-200",
12014
- };
12694
+ // TECH-2459 · Aspecto de v3 — DECISIÓN DEL USUARIO del 1-oct-2026, excepción aceptada a v2. v2
12695
+ // pintaba el toast con `<Alert variant="flat" color={...}>`, que daba FONDO TEÑIDO por color, y
12696
+ // P-25 (F5) lo había repuesto con las clases literales de v2 (`bg-success-50`…). Ya no: el toast
12697
+ // se ve como los ejemplos oficiales de v3 (Default/Accent/Success/Warning/Danger). El fondo es el
12698
+ // de `.toast` (`bg-surface`: blanco en claro, la superficie oscura del pack en oscuro) en los seis
12699
+ // colores, y el color del estado va SOLO en el título y en el icono. La descripción es la de v3
12700
+ // (`text-muted`), sin tocar.
12701
+ // La `x`, neutra en los seis colores: `text-muted`, el mismo gris de `.close-button--default` de
12702
+ // v3, que llega solo al no pisarlo. `bg-transparent` quita el `bg-default` de esa clase: en Aurora
12703
+ // `--color-default` es el gris MEDIO de v2 (`#d4d4d8`), no el casi imperceptible que v3 espera, y
12704
+ // sobre el fondo blanco cantaba como una píldora gris permanente. El hover sí lleva el gris suave
12705
+ // de v3 (`bg-default-hover`, que deriva del `--default` PROPIO de v3, no del de Aurora); hay que
12706
+ // declararlo como utilidad porque el `bg-transparent` de arriba también gana al hover de v3.
12707
+ const CLOSE_CLASS = "shrink-0 self-center bg-transparent hover:bg-default-hover data-[hovered=true]:bg-default-hover";
12015
12708
  // TECH-2459 · Indicador de estado — REPUESTO el 8-sep-2026 por decisión del usuario, a partir del
12016
12709
  // finding `app-loginos-toast-v3-visual.md` (smoke de loginos contra QA, beta.114): con el MISMO
12017
12710
  // toast (`color="danger"`, login con credenciales inválidas) v2 pintaba un glifo de estado a la
@@ -12038,22 +12731,25 @@ const ICON_BY_VARIANT = {
12038
12731
  success: SuccessIcon,
12039
12732
  warning: WarningIcon,
12040
12733
  };
12041
- // Color del glifo: los literales del `tv` de v2 (`alert.js`, `colorVariants.flat.<color>`), que
12042
- // son los mismos que ya usa la fachada `Alert` (su mapa `FLAT_BASE`), porque en v2 el icono era
12043
- // `fill-current` y heredaba el color del texto del alert. Hace falta declararlo estado a estado y
12044
- // no vale con dejar que herede de v3: `.toast__indicator` solo tiñe success/warning/danger, y su
12045
- // base es `text-overlay-foreground` (= `--foreground`, medido `oklch(0.9911 0 0)` en oscuro), o
12046
- // sea que un toast `primary`/`secondary`/`default` pintaría un glifo NEUTRO (blanco en oscuro,
12047
- // gris oscuro en claro) en vez del color del estado — se ve, pero no es el icono de v2.
12048
- // `secondary` se trata como en el resto del fichero: v3 no tiene esa variante de marca (se parte
12049
- // de "default"), así que se recolorea con el token propio de Aurora.
12734
+ // Color del glifo: el MISMO que el del título en cada estado (decisión del 1-oct, ver arriba). Los
12735
+ // literales de v2 que había aquí (`text-success-700`…) estaban pensados para el fondo teñido y ya
12736
+ // no aplican. Lo que pinta v3 por su cuenta (`toast.css`, la última regla de cada selector):
12737
+ // - success/warning/danger: `.toast--<x> .toast__indicator` → `text-<x>-soft-foreground`, el mismo
12738
+ // token que su título. Se deja heredar: cadena vacía.
12739
+ // - accent (= `primary`): v3 tiñe el título (`text-accent-soft-foreground`) pero NO el indicador,
12740
+ // que se queda en la base `text-overlay-foreground` (neutro: casi negro en claro, casi blanco en
12741
+ // oscuro). Se le da el token del título para que icono y título digan el mismo estado.
12742
+ // - default: v3 no tiñe ni título ni indicador; los dos quedan en `text-overlay-foreground`, que
12743
+ // es el foreground neutro que toca. Cadena vacía.
12744
+ // - secondary: v3 no tiene esa variante de marca (se parte de "default"), así que se recolorea con
12745
+ // el token propio de Aurora, el mismo que el título (`--color-secondary-600`).
12050
12746
  const ICON_BY_COLOR = {
12051
- primary: "text-primary-600",
12747
+ primary: "text-accent-soft-foreground",
12052
12748
  secondary: "text-secondary-600",
12053
- success: "text-success-700 dark:text-success",
12054
- warning: "text-warning-700 dark:text-warning",
12055
- danger: "text-danger-600 dark:text-danger-500",
12056
- default: "text-default-foreground",
12749
+ success: "",
12750
+ warning: "",
12751
+ danger: "",
12752
+ default: "",
12057
12753
  };
12058
12754
  // Geometría del hueco del icono en v2 (slot `iconWrapper`: `flex-none relative w-9 h-9
12059
12755
  // rounded-full grid place-items-center`, con el glifo a `w-6`). El toast de v2 pasaba
@@ -12078,7 +12774,7 @@ function GlobalToast({ translations = {} } = {}) {
12078
12774
  const slots = toastVariants({ placement: "top end", variant });
12079
12775
  const isSecondary = color === "secondary";
12080
12776
  const StatusIcon = ICON_BY_VARIANT[variant];
12081
- return (jsx("div", { className: "fixed top-4 right-4 z-[2000] w-full max-w-sm", children: jsxs("div", { className: cn(slots.toast(), "gap-x-0 rounded-[12px]", SURFACE_BY_COLOR[color]), "data-frontmost": "true", style: { position: "relative" }, children: [jsx("div", { className: cn(slots.indicator(), INDICATOR_BASE, ICON_BY_COLOR[color]), children: jsx(StatusIcon, {}) }), jsxs("div", { className: cn(slots.content(), "ms-2 box-border min-h-10 justify-center"), children: [jsx("div", { className: slots.title(), style: isSecondary ? { color: "var(--color-secondary-600)" } : undefined, children: toast.title }), toast.description && (jsx("div", { className: slots.description(), children: toast.description }))] }), jsx(CloseButton, { "aria-label": t.closeButtonAriaLabel, className: cn("shrink-0 self-center bg-transparent", CLOSE_BY_COLOR[color]), onPress: hideToast })] }) }));
12777
+ return (jsx("div", { className: "fixed top-4 right-4 z-[2000] w-full max-w-sm", children: jsxs("div", { className: cn(slots.toast(), "gap-x-0 rounded-[12px]"), "data-frontmost": "true", style: { position: "relative" }, children: [jsx("div", { className: cn(slots.indicator(), INDICATOR_BASE, ICON_BY_COLOR[color]), children: jsx(StatusIcon, {}) }), jsxs("div", { className: cn(slots.content(), "ms-2 box-border min-h-10 justify-center"), children: [jsx("div", { className: slots.title(), style: isSecondary ? { color: "var(--color-secondary-600)" } : undefined, children: toast.title }), toast.description && (jsx("div", { className: slots.description(), children: toast.description }))] }), jsx(CloseButton, { "aria-label": t.closeButtonAriaLabel, className: CLOSE_CLASS, onPress: hideToast })] }) }));
12082
12778
  }
12083
12779
 
12084
12780
  /**
@@ -18883,4 +19579,4 @@ const NavigationLoadingProvider = ({ children, }) => {
18883
19579
  return (jsxs(NavigationLoadingContext.Provider, { value: value, children: [children, jsx(NavigationLoadingOverlay, { isVisible: isVisible })] }));
18884
19580
  };
18885
19581
 
18886
- export { ALL_THEMES, AURORA_THEME_FAMILIES, AURORA_THEME_REGISTRY, AccordionList, AddHolidayForm, Alert, AnalyticsCard, AreaLineChart, AuraAutocomplete, AuraTable, AuraToastProvider, AuraAutocomplete as Autocomplete, AutocompleteItem, BEWEOS_THEME_MODE_COOKIE_NAME, Badge, BreadcrumbItem, BreadcrumbsComponent, Button, CONTAINER_ATTRIBUTE, Card, CardBody, Checkbox, Chip, ColorPicker, ColorSelector, ContentCarousel, Currency, DEFAULT_DONUT_COLORS, DEFAULT_PREDEFINED_COLORS, DEFAULT_RANKED_BAR_COLORS, DISMISS_CONTROL_ATTRIBUTE, DatePicker, DateRangePicker, DateSelector, Divider, DonutChart, Drawer, DrawerBody, DrawerContent, DrawerFilters, DrawerFooter, DrawerHeader, Dropdown, DropdownSection, EmailPreview, EnumMenuNavListItem, GlobalToast, H1, H2, H3, H4, HeaderComponent, HeroUIProvider, HolidayType, IconComponent, Image$1 as Image, ImagePreview, Input, InputPassword, Kanban, KanbanCard, KanbanColumn, LINDA_TONE_PROPERTIES, LindaIcon, MenuClaw, MenuComponent, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, MultiStepWizard, NavigationLoadingContext, NavigationLoadingOverlay, NavigationLoadingProvider, P, Pagination, Phone, Progress, PromotionalBanner, REGISTERED_THEME_COLORS, RangeFilter, RankedBarList, RowSteps, DEFAULT_TRANSLATIONS$2 as SEGMENTATION_DEFAULT_TRANSLATIONS, ScheduleRow, SearchInput, SegmentationBuilder, Select, SelectItem, SelectSection, SimpleLineChart, SocialMediaBar, SocialMediaCarousel, SocialMediaPreview, StatTile, StepIndicator, Switch, Switch as SwitchComponent, THEME_COLOR_HEX_MAP, Tab, Table, Tabs, TagsFilter, Textarea, ThemeContext, ThemePicker, ThemeProvider, TimeInput, TimeInputComponent, ToastContext, Tooltip, TwoColumnLayoutAgent, UploadFile, VerticalSteps, ViolinPlot, WhatsAppPreview, Wizard, WizardNavigation, WizardSidebar, applyCustomPrimaryColor, applyLindaTones, cn, computeBars, computeMax, computeSlices, computeTotal, containerProps, createCurrencyFormatter, uniqueCountries as defaultCountries, defaultCurrencyOptions, defaultTranslations$5 as defaultTranslations, deriveLindaTones, dismissControlProps, forceLightOnlyThemeBeforeReact, formatAuroraThemeTooltip, formatDonutPercent, generateThemeColorScale, getContrastForeground, getRegisteredThemeColorBases, getSelectedKeyFromPath, hexToHsl, hexToThemeColor, hslToCssValue, isAuroraFullThemeId, isDismissControl, isDonutEmpty, isExactThemeColor, isGroupState, isHexColor, isRankedBarListEmpty, isSegmentationGroup, parseColorToHsl, removeCustomPrimaryColor, removeLindaTones, shouldClosePopoverOnInteractOutside, sizeMap, themeColors, useAuraToast, useCloseOnAncestorScroll, useDisclosure, useMediaQuery, useNavigationLoading, useThemeContext };
19582
+ export { ALL_THEMES, AURORA_THEME_FAMILIES, AURORA_THEME_REGISTRY, AccordionList, AddHolidayForm, Alert, AnalyticsCard, AreaLineChart, AuraAutocomplete, AuraTable, AuraToastProvider, AuraAutocomplete as Autocomplete, AutocompleteItem, BEWEOS_THEME_MODE_COOKIE_NAME, Badge, BetaBadge, BreadcrumbItem, BreadcrumbsComponent, Button, CONTAINER_ATTRIBUTE, Card, CardBody, Checkbox, Chip, ColorPicker, ColorSelector, ContentCarousel, Currency, DEFAULT_DONUT_COLORS, DEFAULT_PREDEFINED_COLORS, DEFAULT_RANKED_BAR_COLORS, DISMISS_CONTROL_ATTRIBUTE, DatePicker, DateRangePicker, DateSelector, Divider, DonutChart, Drawer, DrawerBody, DrawerContent, DrawerFilters, DrawerFooter, DrawerHeader, Dropdown, DropdownSection, EmailPreview, EnumMenuNavListItem, GlobalToast, H1, H2, H3, H4, HeaderComponent, HeroUIProvider, HolidayType, IconComponent, Image$1 as Image, ImagePreview, Input, InputPassword, Kanban, KanbanCard, KanbanColumn, LINDA_MASCOT_LEVEL_VAR, LINDA_MASCOT_STATES, LINDA_TONE_PROPERTIES, LindaIcon, LindaMascot, MenuClaw, MenuComponent, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, MultiStepWizard, NavigationLoadingContext, NavigationLoadingOverlay, NavigationLoadingProvider, P, Pagination, Phone, Progress, PromotionalBanner, REGISTERED_THEME_COLORS, RangeFilter, RankedBarList, RowSteps, DEFAULT_TRANSLATIONS$2 as SEGMENTATION_DEFAULT_TRANSLATIONS, ScheduleRow, SearchInput, SegmentationBuilder, Select, SelectItem, SelectSection, SimpleLineChart, SocialMediaBar, SocialMediaCarousel, SocialMediaPreview, StatTile, StepIndicator, Switch, Switch as SwitchComponent, THEME_COLOR_HEX_MAP, Tab, Table, Tabs, TagsFilter, Textarea, ThemeContext, ThemePicker, ThemeProvider, TimeInput, TimeInputComponent, ToastContext, Tooltip, TwoColumnLayoutAgent, UploadFile, VerticalSteps, ViolinPlot, WhatsAppPreview, Wizard, WizardNavigation, WizardSidebar, applyCustomPrimaryColor, applyLindaTones, cn, computeBars, computeMax, computeSlices, computeTotal, containerProps, createCurrencyFormatter, uniqueCountries as defaultCountries, defaultCurrencyOptions, defaultTranslations$5 as defaultTranslations, deriveLindaTones, dismissControlProps, forceLightOnlyThemeBeforeReact, formatAuroraThemeTooltip, formatDonutPercent, generateThemeColorScale, getContrastForeground, getRegisteredThemeColorBases, getSelectedKeyFromPath, hexToHsl, hexToThemeColor, hslToCssValue, isAuroraFullThemeId, isDismissControl, isDonutEmpty, isExactThemeColor, isGroupState, isHexColor, isRankedBarListEmpty, isSegmentationGroup, parseColorToHsl, removeCustomPrimaryColor, removeLindaTones, shouldClosePopoverOnInteractOutside, sizeMap, themeColors, useAuraToast, useCloseOnAncestorScroll, useDisclosure, useMediaQuery, useNavigationLoading, useThemeContext };