@beweco/aurora-ui 0.6.86 → 0.6.87

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 (28) hide show
  1. package/dist/assets/css/styles.css +1 -1
  2. package/dist/index.cjs.js +643 -250
  3. package/dist/index.esm.js +641 -252
  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 +27 -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 +56 -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/index.d.ts +2 -0
  23. package/dist/types/index.d.ts.map +1 -1
  24. package/dist/types/utils/theme-scope.d.ts +18 -0
  25. package/dist/types/utils/theme-scope.d.ts.map +1 -0
  26. package/dist/types/utils/use-injected-style.d.ts +25 -0
  27. package/dist/types/utils/use-injected-style.d.ts.map +1 -0
  28. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -4,7 +4,7 @@ export { Slider } from '@heroui/react';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { Icon } from '@iconify/react';
6
6
  export { loadIcons } from '@iconify/react';
7
- import React, { useId, useState, useCallback, useMemo, forwardRef, useEffect, useImperativeHandle, createContext, useContext, useRef, useLayoutEffect, memo, createElement, Fragment as Fragment$1 } from 'react';
7
+ import React, { useId, useState, useCallback, useMemo, useInsertionEffect, forwardRef, useEffect, useImperativeHandle, createContext, useContext, useRef, useLayoutEffect, memo, createElement, Fragment as Fragment$1 } from 'react';
8
8
  import { ResponsiveContainer, AreaChart, CartesianGrid, XAxis, Tooltip as Tooltip$1, Area, LineChart, YAxis, Line, PieChart, Pie, Cell } from 'recharts';
9
9
  import { createPortal } from 'react-dom';
10
10
  import { motion, AnimatePresence } from 'framer-motion';
@@ -795,263 +795,49 @@ var AuraAutocomplete = function (_a) {
795
795
  };
796
796
 
797
797
  /**
798
- * ColorPicker Types
798
+ * Deja una `<style id>` en el `<head>` con las reglas de un componente, una sola vez.
799
799
  *
800
- * Defines the type system for the ColorPicker component used for brand configuration.
801
- */
802
- /**
803
- * Default predefined colors (Brand-safe palette)
804
- */
805
- var DEFAULT_PREDEFINED_COLORS = [
806
- // Primary colors
807
- { key: "blue", name: "Azul", value: "#3B82F6" },
808
- { key: "violet", name: "Violeta", value: "#8B5CF6" },
809
- { key: "purple", name: "Púrpura", value: "#A855F7" },
810
- // Secondary colors
811
- { key: "green", name: "Verde", value: "#10B981" },
812
- { key: "teal", name: "Turquesa", value: "#14B8A6" },
813
- { key: "cyan", name: "Cian", value: "#06B6D4" },
814
- // Accent colors
815
- { key: "pink", name: "Rosa", value: "#EC4899" },
816
- { key: "rose", name: "Rosa claro", value: "#F43F5E" },
817
- { key: "orange", name: "Naranja", value: "#F97316" },
818
- // Neutral colors
819
- { key: "red", name: "Rojo", value: "#EF4444" },
820
- { key: "amber", name: "Ámbar", value: "#F59E0B" },
821
- { key: "yellow", name: "Amarillo", value: "#EAB308" },
822
- // Gray scale (useful for text/backgrounds)
823
- { key: "gray-dark", name: "Gris oscuro", value: "#374151" },
824
- { key: "gray", name: "Gris", value: "#6B7280" },
825
- { key: "gray-light", name: "Gris claro", value: "#9CA3AF" },
826
- ];
827
-
828
- /**
829
- * Default translations (Spanish)
830
- */
831
- var defaultTranslations$e = {
832
- label: "Color",
833
- placeholder: "Ingresa código hex",
834
- customColorLabel: "Color personalizado",
835
- predefinedColorsLabel: "Colores predefinidos",
836
- recentColorsLabel: "Colores recientes",
837
- noRecentColors: "No hay colores recientes",
838
- invalidColorFormat: "El código de color no es un formato HEX válido (Ej: #FF5733 o FFA07A)",
839
- colorPreview: "Vista previa del color",
840
- };
841
- /**
842
- * Validates hex color format (#RRGGBB or #RGB)
843
- */
844
- var isValidHexColor = function (color) {
845
- var hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
846
- return hexRegex.test(color);
847
- };
848
- /**
849
- * Normalizes hex color to 6-digit format (#RGB -> #RRGGBB)
800
+ * Existe para los componentes que no pueden depender de `@beweco/aurora-ui/styles`: los
801
+ * que llegan a un microfrontend por Module Federation (chatbot-claw recibe aurora-ui del
802
+ * host con `import: false`) o se montan sueltos. Si sus reglas vivieran en `styles.css`,
803
+ * funcionarían solo cuando el host carga ese CSS y además en la misma versión que el JS
804
+ * que viaja por MF; cuando no, el componente sale sin animación ni tema y nadie se entera.
805
+ * Aquí la regla viaja con el componente, como ya hace `SocialMediaCarousel`.
806
+ *
807
+ * Idempotente por `id`: cien mascotas en un hilo dejan una sola `<style>`. Nunca reescribe
808
+ * una `<style>` existente: si en la página conviven dos copias del paquete, se pisarían en
809
+ * cada montaje. Para que una versión nueva del CSS entre, el id lleva su huella
810
+ * (`styleIdFor`).
850
811
  */
851
- var normalizeHexColor = function (color) {
852
- if (!color.startsWith("#")) {
853
- color = "#".concat(color);
812
+ var injectStyle = function (doc, id, css) {
813
+ if (!(doc === null || doc === void 0 ? void 0 : doc.head)) {
814
+ return;
854
815
  }
855
- // Convert 3-digit to 6-digit
856
- if (color.length === 4) {
857
- var r = color[1];
858
- var g = color[2];
859
- var b = color[3];
860
- return "#".concat(r).concat(r).concat(g).concat(g).concat(b).concat(b).toUpperCase();
816
+ if (doc.getElementById(id)) {
817
+ return;
861
818
  }
862
- return color.toUpperCase();
819
+ var style = doc.createElement("style");
820
+ style.id = id;
821
+ style.textContent = css;
822
+ doc.head.appendChild(style);
823
+ };
824
+ /** `<base>-<huella del css>`: estable para el mismo CSS, distinto si cambia. */
825
+ var styleIdFor = function (base, css) {
826
+ var hash = 5381;
827
+ for (var i = 0; i < css.length; i++) {
828
+ hash = ((hash << 5) + hash + css.charCodeAt(i)) | 0;
829
+ }
830
+ return "".concat(base, "-").concat((hash >>> 0).toString(36));
863
831
  };
864
832
  /**
865
- * Strips leading "#" characters so the text input shows only the hex digits.
866
- * The "#" prefix is rendered as a fixed startContent in the Input.
867
- */
868
- var stripHash = function (color) { return color.replace(/^#+/, ""); };
869
- /**
870
- * ColorPicker - Advanced color selection component
871
- *
872
- * Features:
873
- * - Native color picker input
874
- * - Text input for hex codes
875
- * - Predefined color palette
876
- * - Recent colors with localStorage persistence
877
- * - Full i18n support
878
- * - Dark mode compatible
879
- * - Accessible
880
- *
881
- * @component
882
- * @example
883
- * ```tsx
884
- * <ColorPicker
885
- * value={brandColor}
886
- * onChange={setBrandColor}
887
- * label="Color de marca"
888
- * enableRecentColors
889
- * />
890
- * ```
833
+ * `useInsertionEffect` corre antes de pintar y antes que los efectos de layout: las reglas
834
+ * están en el documento cuando el SVG aparece por primera vez, sin parpadeo sin estilo.
835
+ * En servidor no corre (y `renderToStaticMarkup` en los tests tampoco lo ejecuta).
891
836
  */
892
- var ColorPicker = forwardRef(function (_a, ref) {
893
- var value = _a.value, onChange = _a.onChange, label = _a.label, _b = _a.required, required = _b === void 0 ? false : _b, _c = _a.disabled, disabled = _c === void 0 ? false : _c, _d = _a.error, error = _d === void 0 ? false : _d, errorText = _a.errorText, _e = _a.predefinedColors, predefinedColors = _e === void 0 ? DEFAULT_PREDEFINED_COLORS : _e, _f = _a.enableRecentColors, enableRecentColors = _f === void 0 ? true : _f, _g = _a.maxRecentColors, maxRecentColors = _g === void 0 ? 6 : _g, _h = _a.recentColorsStorageKey, recentColorsStorageKey = _h === void 0 ? "aurora-ui-recent-colors" : _h, _j = _a.showPredefinedColors, showPredefinedColors = _j === void 0 ? true : _j, _k = _a.translations, translations = _k === void 0 ? {} : _k, _l = _a.className, className = _l === void 0 ? "" : _l, id = _a.id, name = _a.name;
894
- var generatedId = useId();
895
- var inputId = id || generatedId;
896
- var t = __assign(__assign({}, defaultTranslations$e), translations);
897
- // Local state for text input — holds the hex digits WITHOUT the leading "#".
898
- // The "#" is rendered as a fixed startContent prefix.
899
- var _m = useState(stripHash(value)), textValue = _m[0], setTextValue = _m[1];
900
- var _o = useState(false), isInvalidFormat = _o[0], setIsInvalidFormat = _o[1];
901
- // Recent colors state
902
- var _p = useState([]), recentColors = _p[0], setRecentColors = _p[1];
903
- // Load recent colors from localStorage on mount
904
- useEffect(function () {
905
- if (!enableRecentColors)
906
- return;
907
- try {
908
- var stored = localStorage.getItem(recentColorsStorageKey);
909
- if (stored) {
910
- var colors = JSON.parse(stored);
911
- setRecentColors(colors);
912
- }
913
- }
914
- catch (error) {
915
- console.error("Error loading recent colors:", error);
916
- }
917
- }, [enableRecentColors, recentColorsStorageKey]);
918
- // Save to recent colors when value changes
919
- useEffect(function () {
920
- if (!enableRecentColors || !value || !isValidHexColor(value))
921
- return;
922
- var normalizedValue = normalizeHexColor(value);
923
- // Add to recent colors if not already present
924
- setRecentColors(function (prev) {
925
- // Remove if already exists
926
- var filtered = prev.filter(function (c) { return c !== normalizedValue; });
927
- // Add to beginning
928
- var updated = __spreadArray([normalizedValue], filtered, true).slice(0, maxRecentColors);
929
- // Save to localStorage
930
- try {
931
- localStorage.setItem(recentColorsStorageKey, JSON.stringify(updated));
932
- }
933
- catch (error) {
934
- console.error("Error saving recent colors:", error);
935
- }
936
- return updated;
937
- });
938
- }, [value, enableRecentColors, maxRecentColors, recentColorsStorageKey]);
939
- // Sync text value when prop value changes
940
- useEffect(function () {
941
- setTextValue(stripHash(value));
942
- setIsInvalidFormat(false);
943
- }, [value]);
944
- /**
945
- * Handle color picker (native input) change
946
- */
947
- var handleColorPickerChange = function (e) {
948
- var newColor = normalizeHexColor(e.target.value);
949
- setTextValue(stripHash(newColor));
950
- setIsInvalidFormat(false);
951
- onChange(newColor);
952
- };
953
- /**
954
- * Handle text input change — passive: no validation, normalization, or
955
- * onChange propagation while typing. We only update local state and clear
956
- * any stale error so the user can correct an invalid value without the
957
- * red border lingering. Validation (and stripping of the leading "#")
958
- * runs on blur.
959
- *
960
- * While typing we let the user see whatever they pressed — including a
961
- * leading "#" — so the input feels responsive. To prevent a double "#"
962
- * on screen, the fixed prefix in `startContent` is hidden while
963
- * `textValue` already starts with "#". The cap is `7` (1 "#" + 6 hex)
964
- * when the user opted into a leading "#", otherwise `6`.
965
- */
966
- var handleTextChange = function (newValue) {
967
- var max = newValue.startsWith("#") ? 7 : 6;
968
- setTextValue(newValue.slice(0, max));
969
- setIsInvalidFormat(false);
970
- };
971
- /**
972
- * Validate the current hex input. Updates `isInvalidFormat` and, when
973
- * the input is a valid hex, normalizes the display and propagates via
974
- * `onChange`. Returns whether the input is acceptable so a caller can
975
- * decide to block submission.
976
- *
977
- * Empty + not required → valid (no error, no propagation).
978
- * Empty + required → invalid (error).
979
- * Valid (3 or 6 hex chars, with or without leading "#") → normalize, sync
980
- * display to canonical form, propagate, valid.
981
- * Otherwise → invalid (error, no propagation).
982
- */
983
- var validate = useCallback(function () {
984
- // User may have typed a leading "#" — strip it so it doesn't end up
985
- // as "##" once we prepend "#" for the regex check.
986
- var trimmed = stripHash(textValue.trim());
987
- if (trimmed === "") {
988
- var valid = !required;
989
- setIsInvalidFormat(!valid);
990
- // Drop any residual "#" the user typed but never followed up on,
991
- // so the field reads as truly empty after blur.
992
- setTextValue("");
993
- return valid;
994
- }
995
- var candidate = "#".concat(trimmed);
996
- if (!isValidHexColor(candidate)) {
997
- setIsInvalidFormat(true);
998
- return false;
999
- }
1000
- var normalized = normalizeHexColor(candidate);
1001
- setIsInvalidFormat(false);
1002
- setTextValue(stripHash(normalized));
1003
- onChange(normalized);
1004
- return true;
1005
- }, [textValue, required, onChange]);
1006
- useImperativeHandle(ref, function () { return ({ validate: validate }); }, [validate]);
1007
- var handleTextBlur = function () {
1008
- validate();
1009
- };
1010
- /**
1011
- * Handle predefined color selection
1012
- */
1013
- var handlePredefinedColorClick = function (colorValue) {
1014
- if (disabled)
1015
- return;
1016
- var normalized = normalizeHexColor(colorValue);
1017
- setTextValue(stripHash(normalized));
1018
- setIsInvalidFormat(false);
1019
- onChange(normalized);
1020
- };
1021
- /**
1022
- * Render a color circle button
1023
- */
1024
- var renderColorCircle = function (colorValue, colorName, isSelected) { return (jsx("button", { type: "button", disabled: disabled, onClick: function () { return handlePredefinedColorClick(colorValue); }, className: "\n\t\t\t\tw-8 h-8 rounded-full border-2 cursor-pointer transition-all\n\t\t\t\tfocus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-1\n\t\t\t\t".concat(disabled ? "opacity-50 cursor-not-allowed" : "hover:scale-110", "\n\t\t\t\t").concat(isSelected
1025
- ? "border-primary-500 scale-110 ring-2 ring-primary-500 ring-offset-1"
1026
- : "border-default-700", "\n\t\t\t"), style: { backgroundColor: colorValue }, title: colorName, "aria-label": colorName }, colorValue)); };
1027
- return (jsxs("div", { className: "flex flex-col gap-3 ".concat(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: "#".concat(stripHash(textValue)), onChange: handleColorPickerChange, disabled: disabled, className: "\n\t\t\t\t\t\t\tw-10 h-10 rounded-lg cursor-pointer border-2 flex-shrink-0\n\t\t\t\t\t\t\ttransition-colors appearance-none bg-transparent p-0.5\n\t\t\t\t\t\t\tfocus:border-primary-500\n\t\t\t\t\t\t\t".concat(disabled ? "opacity-50 cursor-not-allowed" : "hover:border-default-400", "\n\t\t\t\t\t\t\t").concat(error
1028
- ? "border-danger dark:border-danger-400"
1029
- : "border-default-300 dark:border-default-700", "\n\t\t\t\t\t\t"), "aria-label": t.customColorLabel, title: t.customColorLabel }), jsx(Input$1, { type: "text", value: textValue, onValueChange: handleTextChange, onBlur: handleTextBlur, placeholder: t.placeholder, disabled: disabled, isInvalid: error || isInvalidFormat, size: "sm", variant: "bordered", classNames: {
1030
- input: "uppercase font-mono text-small",
1031
- inputWrapper: "min-h-8 h-8 focus-within:!border-primary-500",
1032
- }, startContent: textValue.startsWith("#") ? null : (jsx("span", { className: "text-default-400 text-sm", children: "#" })) })] }), (error || isInvalidFormat) && (jsx("p", { className: "text-tiny 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(function (color) {
1033
- return renderColorCircle(color.value, color.name, normalizeHexColor(value) === normalizeHexColor(color.value));
1034
- }) })] })), 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(function (color) {
1035
- return renderColorCircle(color, color, normalizeHexColor(value) === color);
1036
- }) })] }))] }));
1037
- });
1038
- ColorPicker.displayName = "ColorPicker";
1039
-
1040
- var ThemeContext = createContext({
1041
- mode: "light",
1042
- color: "blue",
1043
- customHex: null,
1044
- // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
1045
- setMode: function () { },
1046
- // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
1047
- setColor: function () { },
1048
- });
1049
- var useThemeContext = function () {
1050
- var context = useContext(ThemeContext);
1051
- if (!context) {
1052
- throw new Error("useThemeContext debe ser usado dentro de un ThemeProvider");
1053
- }
1054
- return context;
837
+ var useInjectedStyle = function (id, css) {
838
+ useInsertionEffect(function () {
839
+ injectStyle(typeof document === "undefined" ? undefined : document, id, css);
840
+ }, [id, css]);
1055
841
  };
1056
842
 
1057
843
  var themeColors = {
@@ -1852,6 +1638,338 @@ var themeColors = {
1852
1638
  },
1853
1639
  };
1854
1640
 
1641
+ var namesOf = function (mode) { return __spreadArray([
1642
+ ".".concat(mode),
1643
+ "[data-theme=\"".concat(mode, "\"]")
1644
+ ], Object.entries(themeColors)
1645
+ .filter(function (_a) {
1646
+ var theme = _a[1];
1647
+ return theme.extend === mode;
1648
+ })
1649
+ .map(function (_a) {
1650
+ var name = _a[0];
1651
+ return ".".concat(name);
1652
+ }), true); };
1653
+ /**
1654
+ * Selectores para que un componente con `appearance="auto"` siga al tema del ancestro MÁS
1655
+ * CERCANO.
1656
+ *
1657
+ * Los temas no solo se llaman `dark`/`light`: el `ThemeProvider` de esta librería pone en
1658
+ * `<html>` el tema completo (`blue-dark`, `purple-light`…) y nunca la clase `dark` suelta,
1659
+ * así que mirar solo `.dark` dejaría la pieza en claro sobre un tema oscuro de aurora.
1660
+ *
1661
+ * - `dark`: cualquier ancestro oscuro, o uno oscuro dentro de uno claro.
1662
+ * - `light`: uno claro dentro de uno oscuro (un panel claro en una página oscura). Tiene
1663
+ * una clase más que el oscuro simple, así que gana; va después en la hoja para ganar
1664
+ * también al «oscuro dentro de claro» cuando hay tres niveles.
1665
+ */
1666
+ var themeScopeSelectors = function (target) {
1667
+ var dark = namesOf("dark");
1668
+ var light = namesOf("light");
1669
+ var pairs = function (outer, inner) {
1670
+ return outer.flatMap(function (o) { return inner.map(function (i) { return "".concat(o, " ").concat(i, " ").concat(target); }); });
1671
+ };
1672
+ return {
1673
+ dark: __spreadArray(__spreadArray([], dark.map(function (d) { return "".concat(d, " ").concat(target); }), true), pairs(light, dark), true).join(",\n"),
1674
+ light: pairs(dark, light).join(",\n"),
1675
+ };
1676
+ };
1677
+
1678
+ /**
1679
+ * Reglas del sello Beta. Viajan con el componente (se inyectan en `<head>`), igual que las
1680
+ * de `LindaMascot`: el sello también se pinta dentro del microfrontend del chat.
1681
+ *
1682
+ * Borde de 1 px con el gradiente iridiscente de la mascota muy atenuado: dos fondos, el
1683
+ * neutro recortado al `padding-box` y el gradiente al `border-box`, con el borde
1684
+ * transparente para que se vea el de debajo. Es neutral de marca: lo verá también Luna.
1685
+ */
1686
+ var AUTO_THEME$1 = themeScopeSelectors('.aurora-beta-badge[data-appearance="auto"]');
1687
+ var BETA_BADGE_CSS = "\n.aurora-beta-badge {\n\t--bb-bg: #F6F5FB;\n\t--bb-fg: #4B4F6E;\n\t--bb-edge: 52%;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbox-sizing: border-box;\n\tborder: 1px solid transparent;\n\tborder-radius: 999px;\n\tbackground:\n\t\tlinear-gradient(var(--bb-bg), var(--bb-bg)) padding-box,\n\t\tlinear-gradient(\n\t\t\t100deg,\n\t\t\tcolor-mix(in srgb, #FF8AD8 var(--bb-edge), var(--bb-bg)),\n\t\t\tcolor-mix(in srgb, #A48BFF var(--bb-edge), var(--bb-bg)) 38%,\n\t\t\tcolor-mix(in srgb, #6FE3FF var(--bb-edge), var(--bb-bg)) 70%,\n\t\t\tcolor-mix(in srgb, #FFD08A var(--bb-edge), var(--bb-bg))\n\t\t) border-box;\n\tcolor: var(--bb-fg);\n\tfont-family: inherit;\n\tfont-weight: 600;\n\tline-height: 1;\n\tletter-spacing: 0.06em;\n\ttext-transform: uppercase;\n\twhite-space: nowrap;\n\tvertical-align: middle;\n\tuser-select: none;\n\tflex-shrink: 0;\n}\n/* Tema: sigue al ancestro claro/oscuro m\u00E1s cercano (ver `themeScopeSelectors`). */\n".concat(AUTO_THEME$1.dark, ",\n.aurora-beta-badge[data-appearance=\"dark\"] {\n\t--bb-bg: #1C1D30;\n\t--bb-fg: #D5D8F0;\n\t--bb-edge: 58%;\n}\n").concat(AUTO_THEME$1.light, " {\n\t--bb-bg: #F6F5FB;\n\t--bb-fg: #4B4F6E;\n\t--bb-edge: 52%;\n}\n.aurora-beta-badge--sm {\n\tfont-size: 10px;\n\theight: 16px;\n\tpadding: 0 6px 0 calc(6px + 0.06em);\n}\n.aurora-beta-badge--md {\n\tfont-size: 11px;\n\theight: 18px;\n\tpadding: 0 7px 0 calc(7px + 0.06em);\n}\n");
1688
+
1689
+ var DEFAULT_TRANSLATIONS$c = {
1690
+ label: "Beta",
1691
+ title: "Funcionalidad en pruebas: puede cambiar",
1692
+ };
1693
+ var BETA_BADGE_STYLE_ID = styleIdFor("aurora-beta-badge-styles", BETA_BADGE_CSS);
1694
+ /**
1695
+ * BetaBadge — sello «Beta» para lo que está en pruebas con clientes reales (Linda Claw).
1696
+ * Píldora pequeña en mayúsculas con el borde iridiscente de la mascota muy atenuado.
1697
+ * Ver README.
1698
+ */
1699
+ var BetaBadge = forwardRef(function BetaBadge(_a, ref) {
1700
+ var _b = _a.size, size = _b === void 0 ? "sm" : _b, title = _a.title, _c = _a.appearance, appearance = _c === void 0 ? "auto" : _c, translations = _a.translations, className = _a.className, spanProps = __rest(_a, ["size", "title", "appearance", "translations", "className"]);
1701
+ useInjectedStyle(BETA_BADGE_STYLE_ID, BETA_BADGE_CSS);
1702
+ var t = __assign(__assign({}, DEFAULT_TRANSLATIONS$c), translations);
1703
+ var tooltip = title === true ? t.title : title || undefined;
1704
+ return (jsx("span", __assign({ ref: ref, className: [
1705
+ "aurora-beta-badge",
1706
+ "aurora-beta-badge--".concat(size),
1707
+ className,
1708
+ ]
1709
+ .filter(Boolean)
1710
+ .join(" "), "data-appearance": appearance, title: tooltip }, spanProps, { children: t.label })));
1711
+ });
1712
+
1713
+ /**
1714
+ * ColorPicker Types
1715
+ *
1716
+ * Defines the type system for the ColorPicker component used for brand configuration.
1717
+ */
1718
+ /**
1719
+ * Default predefined colors (Brand-safe palette)
1720
+ */
1721
+ var DEFAULT_PREDEFINED_COLORS = [
1722
+ // Primary colors
1723
+ { key: "blue", name: "Azul", value: "#3B82F6" },
1724
+ { key: "violet", name: "Violeta", value: "#8B5CF6" },
1725
+ { key: "purple", name: "Púrpura", value: "#A855F7" },
1726
+ // Secondary colors
1727
+ { key: "green", name: "Verde", value: "#10B981" },
1728
+ { key: "teal", name: "Turquesa", value: "#14B8A6" },
1729
+ { key: "cyan", name: "Cian", value: "#06B6D4" },
1730
+ // Accent colors
1731
+ { key: "pink", name: "Rosa", value: "#EC4899" },
1732
+ { key: "rose", name: "Rosa claro", value: "#F43F5E" },
1733
+ { key: "orange", name: "Naranja", value: "#F97316" },
1734
+ // Neutral colors
1735
+ { key: "red", name: "Rojo", value: "#EF4444" },
1736
+ { key: "amber", name: "Ámbar", value: "#F59E0B" },
1737
+ { key: "yellow", name: "Amarillo", value: "#EAB308" },
1738
+ // Gray scale (useful for text/backgrounds)
1739
+ { key: "gray-dark", name: "Gris oscuro", value: "#374151" },
1740
+ { key: "gray", name: "Gris", value: "#6B7280" },
1741
+ { key: "gray-light", name: "Gris claro", value: "#9CA3AF" },
1742
+ ];
1743
+
1744
+ /**
1745
+ * Default translations (Spanish)
1746
+ */
1747
+ var defaultTranslations$e = {
1748
+ label: "Color",
1749
+ placeholder: "Ingresa código hex",
1750
+ customColorLabel: "Color personalizado",
1751
+ predefinedColorsLabel: "Colores predefinidos",
1752
+ recentColorsLabel: "Colores recientes",
1753
+ noRecentColors: "No hay colores recientes",
1754
+ invalidColorFormat: "El código de color no es un formato HEX válido (Ej: #FF5733 o FFA07A)",
1755
+ colorPreview: "Vista previa del color",
1756
+ };
1757
+ /**
1758
+ * Validates hex color format (#RRGGBB or #RGB)
1759
+ */
1760
+ var isValidHexColor = function (color) {
1761
+ var hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
1762
+ return hexRegex.test(color);
1763
+ };
1764
+ /**
1765
+ * Normalizes hex color to 6-digit format (#RGB -> #RRGGBB)
1766
+ */
1767
+ var normalizeHexColor = function (color) {
1768
+ if (!color.startsWith("#")) {
1769
+ color = "#".concat(color);
1770
+ }
1771
+ // Convert 3-digit to 6-digit
1772
+ if (color.length === 4) {
1773
+ var r = color[1];
1774
+ var g = color[2];
1775
+ var b = color[3];
1776
+ return "#".concat(r).concat(r).concat(g).concat(g).concat(b).concat(b).toUpperCase();
1777
+ }
1778
+ return color.toUpperCase();
1779
+ };
1780
+ /**
1781
+ * Strips leading "#" characters so the text input shows only the hex digits.
1782
+ * The "#" prefix is rendered as a fixed startContent in the Input.
1783
+ */
1784
+ var stripHash = function (color) { return color.replace(/^#+/, ""); };
1785
+ /**
1786
+ * ColorPicker - Advanced color selection component
1787
+ *
1788
+ * Features:
1789
+ * - Native color picker input
1790
+ * - Text input for hex codes
1791
+ * - Predefined color palette
1792
+ * - Recent colors with localStorage persistence
1793
+ * - Full i18n support
1794
+ * - Dark mode compatible
1795
+ * - Accessible
1796
+ *
1797
+ * @component
1798
+ * @example
1799
+ * ```tsx
1800
+ * <ColorPicker
1801
+ * value={brandColor}
1802
+ * onChange={setBrandColor}
1803
+ * label="Color de marca"
1804
+ * enableRecentColors
1805
+ * />
1806
+ * ```
1807
+ */
1808
+ var ColorPicker = forwardRef(function (_a, ref) {
1809
+ var value = _a.value, onChange = _a.onChange, label = _a.label, _b = _a.required, required = _b === void 0 ? false : _b, _c = _a.disabled, disabled = _c === void 0 ? false : _c, _d = _a.error, error = _d === void 0 ? false : _d, errorText = _a.errorText, _e = _a.predefinedColors, predefinedColors = _e === void 0 ? DEFAULT_PREDEFINED_COLORS : _e, _f = _a.enableRecentColors, enableRecentColors = _f === void 0 ? true : _f, _g = _a.maxRecentColors, maxRecentColors = _g === void 0 ? 6 : _g, _h = _a.recentColorsStorageKey, recentColorsStorageKey = _h === void 0 ? "aurora-ui-recent-colors" : _h, _j = _a.showPredefinedColors, showPredefinedColors = _j === void 0 ? true : _j, _k = _a.translations, translations = _k === void 0 ? {} : _k, _l = _a.className, className = _l === void 0 ? "" : _l, id = _a.id, name = _a.name;
1810
+ var generatedId = useId();
1811
+ var inputId = id || generatedId;
1812
+ var t = __assign(__assign({}, defaultTranslations$e), translations);
1813
+ // Local state for text input — holds the hex digits WITHOUT the leading "#".
1814
+ // The "#" is rendered as a fixed startContent prefix.
1815
+ var _m = useState(stripHash(value)), textValue = _m[0], setTextValue = _m[1];
1816
+ var _o = useState(false), isInvalidFormat = _o[0], setIsInvalidFormat = _o[1];
1817
+ // Recent colors state
1818
+ var _p = useState([]), recentColors = _p[0], setRecentColors = _p[1];
1819
+ // Load recent colors from localStorage on mount
1820
+ useEffect(function () {
1821
+ if (!enableRecentColors)
1822
+ return;
1823
+ try {
1824
+ var stored = localStorage.getItem(recentColorsStorageKey);
1825
+ if (stored) {
1826
+ var colors = JSON.parse(stored);
1827
+ setRecentColors(colors);
1828
+ }
1829
+ }
1830
+ catch (error) {
1831
+ console.error("Error loading recent colors:", error);
1832
+ }
1833
+ }, [enableRecentColors, recentColorsStorageKey]);
1834
+ // Save to recent colors when value changes
1835
+ useEffect(function () {
1836
+ if (!enableRecentColors || !value || !isValidHexColor(value))
1837
+ return;
1838
+ var normalizedValue = normalizeHexColor(value);
1839
+ // Add to recent colors if not already present
1840
+ setRecentColors(function (prev) {
1841
+ // Remove if already exists
1842
+ var filtered = prev.filter(function (c) { return c !== normalizedValue; });
1843
+ // Add to beginning
1844
+ var updated = __spreadArray([normalizedValue], filtered, true).slice(0, maxRecentColors);
1845
+ // Save to localStorage
1846
+ try {
1847
+ localStorage.setItem(recentColorsStorageKey, JSON.stringify(updated));
1848
+ }
1849
+ catch (error) {
1850
+ console.error("Error saving recent colors:", error);
1851
+ }
1852
+ return updated;
1853
+ });
1854
+ }, [value, enableRecentColors, maxRecentColors, recentColorsStorageKey]);
1855
+ // Sync text value when prop value changes
1856
+ useEffect(function () {
1857
+ setTextValue(stripHash(value));
1858
+ setIsInvalidFormat(false);
1859
+ }, [value]);
1860
+ /**
1861
+ * Handle color picker (native input) change
1862
+ */
1863
+ var handleColorPickerChange = function (e) {
1864
+ var newColor = normalizeHexColor(e.target.value);
1865
+ setTextValue(stripHash(newColor));
1866
+ setIsInvalidFormat(false);
1867
+ onChange(newColor);
1868
+ };
1869
+ /**
1870
+ * Handle text input change — passive: no validation, normalization, or
1871
+ * onChange propagation while typing. We only update local state and clear
1872
+ * any stale error so the user can correct an invalid value without the
1873
+ * red border lingering. Validation (and stripping of the leading "#")
1874
+ * runs on blur.
1875
+ *
1876
+ * While typing we let the user see whatever they pressed — including a
1877
+ * leading "#" — so the input feels responsive. To prevent a double "#"
1878
+ * on screen, the fixed prefix in `startContent` is hidden while
1879
+ * `textValue` already starts with "#". The cap is `7` (1 "#" + 6 hex)
1880
+ * when the user opted into a leading "#", otherwise `6`.
1881
+ */
1882
+ var handleTextChange = function (newValue) {
1883
+ var max = newValue.startsWith("#") ? 7 : 6;
1884
+ setTextValue(newValue.slice(0, max));
1885
+ setIsInvalidFormat(false);
1886
+ };
1887
+ /**
1888
+ * Validate the current hex input. Updates `isInvalidFormat` and, when
1889
+ * the input is a valid hex, normalizes the display and propagates via
1890
+ * `onChange`. Returns whether the input is acceptable so a caller can
1891
+ * decide to block submission.
1892
+ *
1893
+ * Empty + not required → valid (no error, no propagation).
1894
+ * Empty + required → invalid (error).
1895
+ * Valid (3 or 6 hex chars, with or without leading "#") → normalize, sync
1896
+ * display to canonical form, propagate, valid.
1897
+ * Otherwise → invalid (error, no propagation).
1898
+ */
1899
+ var validate = useCallback(function () {
1900
+ // User may have typed a leading "#" — strip it so it doesn't end up
1901
+ // as "##" once we prepend "#" for the regex check.
1902
+ var trimmed = stripHash(textValue.trim());
1903
+ if (trimmed === "") {
1904
+ var valid = !required;
1905
+ setIsInvalidFormat(!valid);
1906
+ // Drop any residual "#" the user typed but never followed up on,
1907
+ // so the field reads as truly empty after blur.
1908
+ setTextValue("");
1909
+ return valid;
1910
+ }
1911
+ var candidate = "#".concat(trimmed);
1912
+ if (!isValidHexColor(candidate)) {
1913
+ setIsInvalidFormat(true);
1914
+ return false;
1915
+ }
1916
+ var normalized = normalizeHexColor(candidate);
1917
+ setIsInvalidFormat(false);
1918
+ setTextValue(stripHash(normalized));
1919
+ onChange(normalized);
1920
+ return true;
1921
+ }, [textValue, required, onChange]);
1922
+ useImperativeHandle(ref, function () { return ({ validate: validate }); }, [validate]);
1923
+ var handleTextBlur = function () {
1924
+ validate();
1925
+ };
1926
+ /**
1927
+ * Handle predefined color selection
1928
+ */
1929
+ var handlePredefinedColorClick = function (colorValue) {
1930
+ if (disabled)
1931
+ return;
1932
+ var normalized = normalizeHexColor(colorValue);
1933
+ setTextValue(stripHash(normalized));
1934
+ setIsInvalidFormat(false);
1935
+ onChange(normalized);
1936
+ };
1937
+ /**
1938
+ * Render a color circle button
1939
+ */
1940
+ var renderColorCircle = function (colorValue, colorName, isSelected) { return (jsx("button", { type: "button", disabled: disabled, onClick: function () { return handlePredefinedColorClick(colorValue); }, className: "\n\t\t\t\tw-8 h-8 rounded-full border-2 cursor-pointer transition-all\n\t\t\t\tfocus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-1\n\t\t\t\t".concat(disabled ? "opacity-50 cursor-not-allowed" : "hover:scale-110", "\n\t\t\t\t").concat(isSelected
1941
+ ? "border-primary-500 scale-110 ring-2 ring-primary-500 ring-offset-1"
1942
+ : "border-default-700", "\n\t\t\t"), style: { backgroundColor: colorValue }, title: colorName, "aria-label": colorName }, colorValue)); };
1943
+ return (jsxs("div", { className: "flex flex-col gap-3 ".concat(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: "#".concat(stripHash(textValue)), onChange: handleColorPickerChange, disabled: disabled, className: "\n\t\t\t\t\t\t\tw-10 h-10 rounded-lg cursor-pointer border-2 flex-shrink-0\n\t\t\t\t\t\t\ttransition-colors appearance-none bg-transparent p-0.5\n\t\t\t\t\t\t\tfocus:border-primary-500\n\t\t\t\t\t\t\t".concat(disabled ? "opacity-50 cursor-not-allowed" : "hover:border-default-400", "\n\t\t\t\t\t\t\t").concat(error
1944
+ ? "border-danger dark:border-danger-400"
1945
+ : "border-default-300 dark:border-default-700", "\n\t\t\t\t\t\t"), "aria-label": t.customColorLabel, title: t.customColorLabel }), jsx(Input$1, { type: "text", value: textValue, onValueChange: handleTextChange, onBlur: handleTextBlur, placeholder: t.placeholder, disabled: disabled, isInvalid: error || isInvalidFormat, size: "sm", variant: "bordered", classNames: {
1946
+ input: "uppercase font-mono text-small",
1947
+ inputWrapper: "min-h-8 h-8 focus-within:!border-primary-500",
1948
+ }, startContent: textValue.startsWith("#") ? null : (jsx("span", { className: "text-default-400 text-sm", children: "#" })) })] }), (error || isInvalidFormat) && (jsx("p", { className: "text-tiny 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(function (color) {
1949
+ return renderColorCircle(color.value, color.name, normalizeHexColor(value) === normalizeHexColor(color.value));
1950
+ }) })] })), 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(function (color) {
1951
+ return renderColorCircle(color, color, normalizeHexColor(value) === color);
1952
+ }) })] }))] }));
1953
+ });
1954
+ ColorPicker.displayName = "ColorPicker";
1955
+
1956
+ var ThemeContext = createContext({
1957
+ mode: "light",
1958
+ color: "blue",
1959
+ customHex: null,
1960
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
1961
+ setMode: function () { },
1962
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: <explanation>
1963
+ setColor: function () { },
1964
+ });
1965
+ var useThemeContext = function () {
1966
+ var context = useContext(ThemeContext);
1967
+ if (!context) {
1968
+ throw new Error("useThemeContext debe ser usado dentro de un ThemeProvider");
1969
+ }
1970
+ return context;
1971
+ };
1972
+
1855
1973
  /**
1856
1974
  * @file This file contains the theme configurations for the application.
1857
1975
  */
@@ -3536,6 +3654,277 @@ var LindaIcon = function (_a) {
3536
3654
  return (jsx("svg", __assign({ 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" })] }) })));
3537
3655
  };
3538
3656
 
3657
+ var LINDA_MASCOT_STATES = [
3658
+ "idle",
3659
+ "processing",
3660
+ "working",
3661
+ "listening",
3662
+ "talking",
3663
+ "ready",
3664
+ ];
3665
+ /** px de cada talla con nombre. Cada una cae en su propio nivel de detalle. */
3666
+ var LINDA_MASCOT_SIZE_PX = {
3667
+ xs: 20,
3668
+ sm: 32,
3669
+ md: 72,
3670
+ lg: 144,
3671
+ };
3672
+ /** Variable CSS que lleva la intensidad de voz (0–1). Parte del contrato público. */
3673
+ var LINDA_MASCOT_LEVEL_VAR = "--linda-mascot-level";
3674
+ /** id de la `<style>` que el componente deja en `<head>`. */
3675
+ var LINDA_MASCOT_STYLE_ID = "aurora-linda-mascot-styles";
3676
+ /** Paleta de la hoja de marca. */
3677
+ var LINDA_MASCOT_PALETTE = {
3678
+ coreLight: "#2A2D4A",
3679
+ coreDark: "#0B0C18",
3680
+ eye: "#EAF2FF",
3681
+ eyeGlow: "#8FB8FF",
3682
+ pink: "#FF8AD8",
3683
+ violet: "#A48BFF",
3684
+ cyan: "#6FE3FF",
3685
+ amber: "#FFD08A",
3686
+ };
3687
+ var resolveMascotPx = function (size) {
3688
+ var _a;
3689
+ if (typeof size === "number") {
3690
+ return Number.isFinite(size) && size > 0 ? size : LINDA_MASCOT_SIZE_PX.md;
3691
+ }
3692
+ return (_a = LINDA_MASCOT_SIZE_PX[size !== null && size !== void 0 ? size : "md"]) !== null && _a !== void 0 ? _a : LINDA_MASCOT_SIZE_PX.md;
3693
+ };
3694
+ /** ≤20 xs · 21–40 sm · 41–95 md · ≥96 lg. */
3695
+ var resolveMascotTier = function (px) {
3696
+ if (px <= 20) {
3697
+ return "xs";
3698
+ }
3699
+ if (px <= 40) {
3700
+ return "sm";
3701
+ }
3702
+ if (px < 96) {
3703
+ return "md";
3704
+ }
3705
+ return "lg";
3706
+ };
3707
+ var clampLevel = function (level) {
3708
+ if (typeof level !== "number" || Number.isNaN(level)) {
3709
+ return 0;
3710
+ }
3711
+ return Math.min(1, Math.max(0, level));
3712
+ };
3713
+ var LINDA_MASCOT_GEOMETRY = {
3714
+ xs: {
3715
+ coreRx: 40,
3716
+ coreCy: 61,
3717
+ eyeWidth: 17,
3718
+ eyeHeight: 8,
3719
+ eyeStroke: 9,
3720
+ eyeGap: 31,
3721
+ rings: [{ r: 57, squash: 0.3, tilt: -16, strokePx: 1.2, opacity: 0.95 }],
3722
+ halo: false,
3723
+ specular: false,
3724
+ blur: false,
3725
+ ringGlow: "none",
3726
+ },
3727
+ sm: {
3728
+ coreRx: 36,
3729
+ coreCy: 61,
3730
+ eyeWidth: 14,
3731
+ eyeHeight: 6.5,
3732
+ eyeStroke: 6,
3733
+ eyeGap: 28,
3734
+ rings: [
3735
+ { r: 56, squash: 0.3, tilt: -16, strokePx: 1.1, opacity: 0.9 },
3736
+ { r: 52, squash: 0.36, tilt: 20, strokePx: 1, opacity: 0.7 },
3737
+ ],
3738
+ halo: true,
3739
+ specular: false,
3740
+ blur: false,
3741
+ ringGlow: "none",
3742
+ },
3743
+ md: {
3744
+ coreRx: 33,
3745
+ coreCy: 61,
3746
+ eyeWidth: 12.5,
3747
+ eyeHeight: 5.5,
3748
+ eyeStroke: 4.4,
3749
+ eyeGap: 25,
3750
+ rings: [
3751
+ { r: 56, squash: 0.3, tilt: -16, strokePx: 1.5, opacity: 0.85 },
3752
+ { r: 52, squash: 0.38, tilt: 20, strokePx: 1.2, opacity: 0.7 },
3753
+ { r: 58, squash: 0.2, tilt: -3, strokePx: 1, opacity: 0.55 },
3754
+ ],
3755
+ halo: true,
3756
+ specular: true,
3757
+ blur: true,
3758
+ ringGlow: "flat",
3759
+ },
3760
+ lg: {
3761
+ coreRx: 32,
3762
+ coreCy: 61,
3763
+ eyeWidth: 12,
3764
+ eyeHeight: 5.2,
3765
+ eyeStroke: 3.8,
3766
+ eyeGap: 24,
3767
+ rings: [
3768
+ { r: 56, squash: 0.3, tilt: -16, strokePx: 2, opacity: 0.85 },
3769
+ { r: 52, squash: 0.38, tilt: 20, strokePx: 1.6, opacity: 0.72 },
3770
+ { r: 58, squash: 0.2, tilt: -3, strokePx: 1.3, opacity: 0.58 },
3771
+ ],
3772
+ halo: true,
3773
+ specular: true,
3774
+ blur: true,
3775
+ ringGlow: "blur",
3776
+ },
3777
+ };
3778
+
3779
+ var LEVEL = "var(".concat(LINDA_MASCOT_LEVEL_VAR, ")");
3780
+ var AUTO_THEME = themeScopeSelectors('.aurora-linda-mascot[data-appearance="auto"]');
3781
+ /** Curva de los movimientos que responden a la voz: sale rápido, llega suave. */
3782
+ var EASE_OUT = "cubic-bezier(0.22, 0.7, 0.3, 1)";
3783
+ /**
3784
+ * Reglas de la mascota. Viajan con el componente (se inyectan en `<head>`, ver
3785
+ * `useInjectedStyle`) para que funcione en un microfrontend que no carga `styles.css`.
3786
+ *
3787
+ * Todo se anima con `transform` u `opacity`. Cada grupo animado es un `<g>` SIN atributo
3788
+ * `transform`: en SVG la propiedad CSS `transform` reemplaza al atributo, así que la
3789
+ * geometría (posición, inclinación, aplastamiento) vive en grupos padres y el movimiento
3790
+ * en grupos hijos. Por la misma razón, lo que sigue a la voz (`--linda-mascot-level`,
3791
+ * con `transition`) y lo que late en bucle (con `animation`) van en grupos distintos: una
3792
+ * animación CSS anula la transición de la misma propiedad.
3793
+ */
3794
+ /** Reglas de movimiento reducido bajo la raíz \`root\` (clase o clase+atributo). */
3795
+ var reducedMotionBody = function (root) { return "\n\t".concat(root, " .aurora-lm-spin,\n\t").concat(root, " .aurora-lm-boost,\n\t").concat(root, " .aurora-lm-orbit,\n\t").concat(root, " .aurora-lm-eyes,\n\t").concat(root, " .aurora-lm-breathe,\n\t").concat(root, " .aurora-lm-halo,\n\t").concat(root, " .aurora-lm-sparkle {\n\t\tanimation: none !important;\n\t}\n\t").concat(root, " .aurora-lm-level-body,\n\t").concat(root, " .aurora-lm-level-rings,\n\t").concat(root, " .aurora-lm-level-halo {\n\t\ttransform: none !important;\n\t}\n\t").concat(root, ".aurora-linda-mascot--listening .aurora-lm-level-rings,\n\t").concat(root, ".aurora-linda-mascot--talking .aurora-lm-level-rings {\n\t\topacity: calc(0.55 + ").concat(LEVEL, " * 0.45);\n\t}\n\t").concat(root, ".aurora-linda-mascot--processing .aurora-lm-halo {\n\t\tanimation: aurora-lm-glow 1.6s ease-in-out infinite !important;\n\t}\n\t").concat(root, ".aurora-linda-mascot--working .aurora-lm-halo {\n\t\topacity: 1 !important;\n\t}\n\t").concat(root, ".aurora-linda-mascot--listening .aurora-lm-level-halo,\n\t").concat(root, ".aurora-linda-mascot--talking .aurora-lm-level-halo {\n\t\topacity: calc(0.4 + ").concat(LEVEL, " * 0.6) !important;\n\t}\n\t").concat(root, ".aurora-linda-mascot--ready .aurora-lm-sparkle {\n\t\tanimation: aurora-lm-sparkle-fade 700ms ease-out 1 both !important;\n\t}\n"); };
3796
+ var reducedMotionRules = function (root) { return "\n@media (prefers-reduced-motion: reduce) {".concat(reducedMotionBody(root), "}\n").concat(reducedMotionBody("".concat(root, "[data-motion=\"reduce\"]")), "\n"); };
3797
+ var LINDA_MASCOT_CSS = "\n.aurora-linda-mascot {\n\t".concat(LINDA_MASCOT_LEVEL_VAR, ": 0;\n\t--lm-halo: 0.5;\n\t--lm-shadow: 1;\n\t--lm-rim: 0.85;\n\t--lm-sparkle: #F2B441;\n\tdisplay: inline-block;\n\tflex-shrink: 0;\n\toverflow: visible;\n\tvertical-align: middle;\n}\n/* En lg la mascota es escenario (bienvenida, llamada): m\u00E1s halo, como en la hoja de marca.\n Multiplicador aparte para no competir en especificidad con las reglas de tema. */\n.aurora-linda-mascot--tier-lg {\n\t--lm-halo-boost: 1.4;\n}\n/*\n * Tema. `auto` sigue al ancestro claro/oscuro m\u00E1s cercano, incluidos los temas de aurora\n * (`blue-dark`\u2026); ver `themeScopeSelectors`.\n */\n").concat(AUTO_THEME.dark, ",\n.aurora-linda-mascot[data-appearance=\"dark\"] {\n\t--lm-halo: 0.95;\n\t--lm-shadow: 0;\n\t--lm-rim: 1;\n\t--lm-sparkle: #FFF1C9;\n}\n").concat(AUTO_THEME.light, " {\n\t--lm-halo: 0.5;\n\t--lm-shadow: 1;\n\t--lm-rim: 0.85;\n\t--lm-sparkle: #F2B441;\n}\n\n/* Cuerpo entero: respiraci\u00F3n en bucle + escala por voz (grupos distintos). */\n.aurora-lm-breathe,\n.aurora-lm-level-body,\n.aurora-lm-level-rings {\n\ttransform-box: view-box;\n\ttransform-origin: 60px 61px;\n}\n.aurora-lm-breathe {\n\tanimation: aurora-lm-breathe 2s ease-in-out infinite alternate;\n}\n.aurora-lm-level-body,\n.aurora-lm-level-rings,\n.aurora-lm-level-halo {\n\ttransition: transform 140ms ").concat(EASE_OUT, ", opacity 240ms ").concat(EASE_OUT, ";\n}\n\n/* Halo y sombra de contacto. */\n.aurora-lm-halo,\n.aurora-lm-level-halo {\n\ttransform-box: fill-box;\n\ttransform-origin: center;\n}\n.aurora-lm-halo {\n\topacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));\n\ttransition: opacity 400ms ease;\n}\n.aurora-lm-shadow {\n\topacity: var(--lm-shadow);\n}\n.aurora-lm-rim {\n\topacity: var(--lm-rim);\n}\n\n/*\n * Anillos. El c\u00EDrculo gira dentro de su grupo aplastado: la elipse no cambia de forma y\n * lo que recorre el trazo es el color, como un anillo que gira en profundidad.\n * `--lm-spin-duration` y `--lm-spin-direction` llegan por anillo desde el marcado.\n */\n.aurora-lm-spin {\n\ttransform-box: view-box;\n\ttransform-origin: 0 0;\n\tanimation: aurora-lm-spin var(--lm-spin-duration, 24s) linear infinite\n\t\tvar(--lm-spin-direction, normal);\n}\n/* Segundo giro encadenado: parado salvo en working, donde dobla la velocidad sin saltos\n (pausar conserva el \u00E1ngulo; cambiar la duraci\u00F3n lo har\u00EDa saltar). */\n.aurora-lm-boost {\n\tanimation-play-state: paused;\n}\n/* Cometa del anillo principal: orbita siempre, se ve solo al pensar o trabajar. */\n.aurora-lm-orbit {\n\tanimation-play-state: paused;\n}\n.aurora-lm-comet,\n.aurora-lm-glint {\n\topacity: 0;\n\ttransition: opacity 320ms ease;\n}\n\n/* Ojos: solo parpadean (sin expresiones faciales). Dos parpadeos por ciclo, a 4,8 y 6,2 s. */\n.aurora-lm-eyes {\n\ttransform-box: fill-box;\n\ttransform-origin: center;\n\tanimation: aurora-lm-blink 11s ease-in-out infinite;\n}\n\n/* Chispas de fin de turno. */\n/* Dorado en claro (el blanco desaparece sobre fondo claro), casi blanco en oscuro. */\n.aurora-lm-sparkle {\n\ttransform-box: fill-box;\n\ttransform-origin: center;\n\topacity: 0;\n\tfill: var(--lm-sparkle);\n}\n\n/* \u2500\u2500 Estados \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* idle no a\u00F1ade nada: es el movimiento base de arriba (giro, respiraci\u00F3n, parpadeo). */\n\n.aurora-linda-mascot--processing .aurora-lm-orbit {\n\tanimation-play-state: running;\n}\n.aurora-linda-mascot--processing .aurora-lm-comet {\n\topacity: 1;\n}\n.aurora-linda-mascot--processing .aurora-lm-halo {\n\tanimation: aurora-lm-pulse 1.6s ease-in-out infinite;\n}\n\n.aurora-linda-mascot--working .aurora-lm-boost,\n.aurora-linda-mascot--working .aurora-lm-orbit {\n\tanimation-play-state: running;\n}\n.aurora-linda-mascot--working .aurora-lm-glint {\n\topacity: 1;\n}\n\n.aurora-linda-mascot--listening .aurora-lm-level-rings {\n\ttransform: scale(calc(0.86 + ").concat(LEVEL, " * 0.16));\n}\n.aurora-linda-mascot--listening .aurora-lm-level-halo {\n\ttransform: scale(calc(0.92 + ").concat(LEVEL, " * 0.2));\n}\n\n.aurora-linda-mascot--talking .aurora-lm-level-body {\n\ttransform: scale(calc(1 + ").concat(LEVEL, " * 0.07));\n}\n.aurora-linda-mascot--talking .aurora-lm-level-halo {\n\ttransform: scale(calc(1 + ").concat(LEVEL, " * 0.32));\n\topacity: calc(0.75 + ").concat(LEVEL, " * 0.25);\n}\n\n.aurora-linda-mascot--ready .aurora-lm-sparkle {\n\tanimation: aurora-lm-sparkle 700ms cubic-bezier(0.2, 0.8, 0.3, 1) 1 both;\n\tanimation-delay: var(--lm-sparkle-delay, 0ms);\n}\n\n/* \u2500\u2500 Keyframes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n@keyframes aurora-lm-spin {\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n@keyframes aurora-lm-breathe {\n\tfrom {\n\t\ttransform: scale(1);\n\t}\n\tto {\n\t\ttransform: scale(1.03);\n\t}\n}\n@keyframes aurora-lm-blink {\n\t0%, 42%, 45%, 97.5%, 100% {\n\t\ttransform: scaleY(1);\n\t}\n\t43.5%, 98.8% {\n\t\ttransform: scaleY(0.12);\n\t}\n}\n@keyframes aurora-lm-pulse {\n\t0%, 100% {\n\t\ttransform: scale(1);\n\t\topacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));\n\t}\n\t50% {\n\t\ttransform: scale(1.12);\n\t\topacity: 1;\n\t}\n}\n@keyframes aurora-lm-glow {\n\t0%, 100% {\n\t\topacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));\n\t}\n\t50% {\n\t\topacity: 1;\n\t}\n}\n@keyframes aurora-lm-sparkle {\n\t0% {\n\t\topacity: 0;\n\t\ttransform: scale(0.2) rotate(0deg);\n\t}\n\t35% {\n\t\topacity: 1;\n\t\ttransform: scale(1) rotate(45deg);\n\t}\n\t100% {\n\t\topacity: 0;\n\t\ttransform: scale(0.5) rotate(90deg);\n\t}\n}\n@keyframes aurora-lm-sparkle-fade {\n\t0%, 100% {\n\t\topacity: 0;\n\t}\n\t35% {\n\t\topacity: 1;\n\t}\n}\n\n/*\n * Movimiento reducido: nada gira, parpadea, respira ni crece. El estado se sigue leyendo\n * sin movimiento: al pensar o trabajar el cometa o el destello se quedan quietos sobre el\n * anillo (as\u00ED se distingue tambi\u00E9n en `xs`, que no tiene halo) y el halo late en opacidad\n * o se enciende; con la voz sube la opacidad del halo y de los anillos; las chispas\n * aparecen y se desvanecen sin moverse.\n *\n * Las mismas reglas se aplican con la preferencia del sistema y con `motion=\"reduce\"`\n * (`data-motion`), que el consumidor usa para listas largas o para forzarlo. `!important`\n * porque las reglas por estado de arriba tienen m\u00E1s especificidad y `@media` no la sube.\n */\n").concat(reducedMotionRules(".aurora-linda-mascot"), "\n");
3798
+
3799
+ var CX = 60;
3800
+ var STYLE_ID = styleIdFor(LINDA_MASCOT_STYLE_ID, LINDA_MASCOT_CSS);
3801
+ /** Velocidad de giro por anillo (s por vuelta) y sentido. */
3802
+ var RING_MOTION = [
3803
+ { duration: "24s", direction: "normal" },
3804
+ { duration: "30s", direction: "reverse" },
3805
+ { duration: "36s", direction: "normal" },
3806
+ ];
3807
+ /** Chispas de `ready`: posición en el viewBox, tamaño y retardo. */
3808
+ var SPARKLES = [
3809
+ { x: 90, y: 17, s: 9, delay: "0ms" },
3810
+ { x: 104, y: 35, s: 5.5, delay: "90ms" },
3811
+ { x: 73, y: 7, s: 4.5, delay: "170ms" },
3812
+ ];
3813
+ var sparklePath = function (s) {
3814
+ var k = s * 0.18;
3815
+ return "M0 ".concat(-s, "C").concat(k, " ").concat(-k, " ").concat(k, " ").concat(-k, " ").concat(s, " 0C").concat(k, " ").concat(k, " ").concat(k, " ").concat(k, " 0 ").concat(s, "C").concat(-k, " ").concat(k, " ").concat(-k, " ").concat(k, " ").concat(-s, " 0C").concat(-k, " ").concat(-k, " ").concat(-k, " ").concat(-k, " 0 ").concat(-s, "Z");
3816
+ };
3817
+ /**
3818
+ * Perímetro en px de pantalla de la elipse de un anillo. Con `non-scaling-stroke` los
3819
+ * guiones se miden en px de pantalla (no en unidades del viewBox ni en `pathLength`), así
3820
+ * que el cometa se dimensiona como fracción de este perímetro para medir lo mismo a
3821
+ * cualquier talla.
3822
+ */
3823
+ var ringPerimeterPx = function (ring, px) {
3824
+ var a = (ring.r * px) / 120;
3825
+ var b = a * ring.squash;
3826
+ var h = Math.pow(((a - b) / (a + b)), 2);
3827
+ return Math.PI * (a + b) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)));
3828
+ };
3829
+ /**
3830
+ * Cometa con estela sobre un anillo: cola de `steps` tramos consecutivos con el
3831
+ * iridiscente del anillo, cada uno más opaco y más grueso que el anterior, y una cabeza
3832
+ * redonda y brillante al final. Todo es `stroke-dasharray` sobre el mismo círculo que el
3833
+ * anillo, así que gira con `transform` y se recorta delante/detrás igual que él. El giro
3834
+ * es horario: la cabeza va al final del trazo, por delante de su cola.
3835
+ */
3836
+ var Comet = function (_a) {
3837
+ var className = _a.className, r = _a.r, perimeter = _a.perimeter, tail = _a.tail, strokePx = _a.strokePx, headPx = _a.headPx, steps = _a.steps, ringPaint = _a.ringPaint, headPaint = _a.headPaint;
3838
+ var tailPx = perimeter * tail;
3839
+ var seg = tailPx / steps;
3840
+ return (jsxs("g", { className: className, "data-part": "comet", children: [Array.from({ length: steps }, function (_, i) {
3841
+ var t = (i + 1) / steps;
3842
+ return (jsx("circle", { r: r, fill: "none", stroke: ringPaint, strokeWidth: strokePx * (0.8 + 1.6 * t), strokeOpacity: Math.pow(t, 1.5), strokeDasharray: "".concat((seg + 0.4).toFixed(2), " ").concat((perimeter - seg - 0.4).toFixed(2)), strokeDashoffset: (-seg * i).toFixed(2), vectorEffect: "non-scaling-stroke" }, i));
3843
+ }), jsx("circle", { r: r, fill: "none", stroke: headPaint, strokeWidth: headPx * 1.5, strokeOpacity: 0.3, strokeLinecap: "round", strokeDasharray: "0.01 ".concat((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 ".concat((perimeter - 0.01).toFixed(2)), strokeDashoffset: (-tailPx).toFixed(2), vectorEffect: "non-scaling-stroke" })] }));
3844
+ };
3845
+ /** Arco «∩» de un ojo centrado en (x, y): ancho w, alto h. */
3846
+ var eyePath = function (x, y, w, h) {
3847
+ var half = w / 2;
3848
+ var base = y + h / 2;
3849
+ var control = y - h * 0.8333;
3850
+ return "M".concat(x - half, " ").concat(base, "C").concat(x - half, " ").concat(control, " ").concat(x + half, " ").concat(control, " ").concat(x + half, " ").concat(base);
3851
+ };
3852
+ /**
3853
+ * `useId` devuelve `:r0:` (React 18), `«r0»` o `_r_0_` (19): fuera lo que no vale en un
3854
+ * id referenciado desde `url(#…)`.
3855
+ */
3856
+ var safeId = function (raw) {
3857
+ return "lm".concat(raw.replace(/[^a-zA-Z0-9_-]/g, ""));
3858
+ };
3859
+ /**
3860
+ * LindaMascot — la cara de Linda: un orbe de tinta con ojos luminosos y anillos
3861
+ * iridiscentes, en SVG + CSS (sin imágenes, fuentes ni WebGL).
3862
+ *
3863
+ * Se anima según lo que Linda está haciendo (`state`) y, en la llamada de voz, según el
3864
+ * volumen (`level`), sin preguntar nada al modelo. Pinta más o menos detalle según la
3865
+ * talla para leerse igual a 16 px que a 200 px. Ver README.
3866
+ */
3867
+ var LindaMascot = forwardRef(function LindaMascot(_a, ref) {
3868
+ var _b;
3869
+ var _c = _a.state, state = _c === void 0 ? "idle" : _c, _d = _a.size, size = _d === void 0 ? "md" : _d, level = _a.level, label = _a.label, _e = _a.appearance, appearance = _e === void 0 ? "auto" : _e, _f = _a.motion, motion = _f === void 0 ? "auto" : _f, className = _a.className, style = _a.style, svgProps = __rest(_a, ["state", "size", "level", "label", "appearance", "motion", "className", "style"]);
3870
+ useInjectedStyle(STYLE_ID, LINDA_MASCOT_CSS);
3871
+ var uid = safeId(useId());
3872
+ var px = resolveMascotPx(size);
3873
+ var tier = resolveMascotTier(px);
3874
+ var g = LINDA_MASCOT_GEOMETRY[tier];
3875
+ var coreRy = g.coreRx * 0.92;
3876
+ var eyeY = g.coreCy - coreRy + coreRy * 2 * 0.45;
3877
+ var eyes = [CX - g.eyeGap / 2, CX + g.eyeGap / 2];
3878
+ // Recorte delante/detrás: en lg los velos desenfocados salen más allá del anillo.
3879
+ var clipHalf = g.ringGlow === "blur" ? 120 : 80;
3880
+ var id = {
3881
+ core: "".concat(uid, "-core"),
3882
+ coreClip: "".concat(uid, "-core-clip"),
3883
+ rim: "".concat(uid, "-rim"),
3884
+ ring: "".concat(uid, "-ring"),
3885
+ halo: "".concat(uid, "-halo"),
3886
+ shadow: "".concat(uid, "-shadow"),
3887
+ specular: "".concat(uid, "-specular"),
3888
+ back: "".concat(uid, "-back"),
3889
+ front: "".concat(uid, "-front"),
3890
+ soft: "".concat(uid, "-soft"),
3891
+ eyeGlow: "".concat(uid, "-eye-glow"),
3892
+ aura: "".concat(uid, "-aura"),
3893
+ veil: "".concat(uid, "-veil"),
3894
+ tail: "".concat(uid, "-tail"),
3895
+ };
3896
+ var a11y = label
3897
+ ? { role: "img", "aria-label": label }
3898
+ : { "aria-hidden": true };
3899
+ var renderRing = function (ring, index, half) {
3900
+ var motion = RING_MOTION[index];
3901
+ var spinStyle = {
3902
+ "--lm-spin-duration": motion.duration,
3903
+ "--lm-spin-direction": motion.direction,
3904
+ };
3905
+ var isMain = index === 0;
3906
+ var perimeter = ringPerimeterPx(ring, px);
3907
+ return (jsx("g", { "data-ring": index + 1, "data-ring-half": half, transform: "translate(".concat(CX, " ").concat(g.coreCy, ") rotate(").concat(ring.tilt, ")"), opacity: half === "back" ? ring.opacity * 0.62 : ring.opacity, children: jsx("g", { clipPath: "url(#".concat(half === "back" ? id.back : id.front, ")"), children: jsxs("g", { transform: "scale(1 ".concat(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(#".concat(id.ring, ")"), strokeWidth: ring.strokePx * 16, strokeOpacity: 0.3, vectorEffect: "non-scaling-stroke", filter: "url(#".concat(id.veil, ")") })), g.ringGlow !== "none" && (jsx("circle", { r: ring.r, fill: "none", stroke: "url(#".concat(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(#".concat(id.soft, ")") : undefined })), g.ringGlow !== "none" && (jsx("circle", { r: ring.r + 2.2, fill: "none", stroke: "url(#".concat(id.ring, ")"), strokeWidth: ring.strokePx * 0.55, strokeOpacity: 0.55, vectorEffect: "non-scaling-stroke" })), jsx("circle", { r: ring.r, fill: "none", stroke: "url(#".concat(id.ring, ")"), strokeWidth: ring.strokePx, vectorEffect: "non-scaling-stroke" })] }) }), isMain && (jsxs("g", { className: "aurora-lm-spin aurora-lm-orbit", style: {
3908
+ "--lm-spin-duration": "1.6s",
3909
+ }, 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(#".concat(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(#".concat(id.tail, ")"), headPaint: LINDA_MASCOT_PALETTE.eyeGlow })] }))] }) }) }, "".concat(half, "-").concat(index)));
3910
+ };
3911
+ var ringHalves = function (half) {
3912
+ return g.rings.map(function (ring, index) { return renderRing(ring, index, half); });
3913
+ };
3914
+ return (
3915
+ // 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`.
3916
+ jsxs("svg", __assign({ ref: ref, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 120 120", width: px, height: px, focusable: "false", className: [
3917
+ "aurora-linda-mascot",
3918
+ "aurora-linda-mascot--".concat(state),
3919
+ "aurora-linda-mascot--tier-".concat(tier),
3920
+ className,
3921
+ ]
3922
+ .filter(Boolean)
3923
+ .join(" "), "data-state": state, "data-tier": tier, "data-appearance": appearance, "data-motion": motion, style: __assign(__assign({}, style), (_b = {}, _b[LINDA_MASCOT_LEVEL_VAR] = clampLevel(level), _b)) }, 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(#".concat(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(#".concat(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(#".concat(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(#".concat(id.aura, ")") : undefined })), jsxs("g", { "data-part": "core", children: [jsx("ellipse", { cx: CX, cy: g.coreCy, rx: g.coreRx, ry: coreRy, fill: "url(#".concat(id.core, ")") }), jsx("g", { clipPath: "url(#".concat(id.coreClip, ")"), children: jsx("ellipse", { className: "aurora-lm-rim", cx: CX, cy: g.coreCy, rx: g.coreRx, ry: coreRy, fill: "none", stroke: "url(#".concat(id.rim, ")"), strokeWidth: tier === "xs" ? 5 : g.blur ? 7 : 5, filter: g.blur ? "url(#".concat(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 ".concat(CX - g.coreRx * 0.36, " ").concat(g.coreCy - coreRy * 0.5, ")"), fill: "url(#".concat(id.specular, ")") }))] }), jsxs("g", { className: "aurora-lm-eyes", "data-part": "eyes", children: [eyes.map(function (x) { return (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(#".concat(id.eyeGlow, ")") : undefined }, "glow-".concat(x))); }), eyes.map(function (x) { return (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-".concat(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(function (s) { return (jsx("g", { transform: "translate(".concat(s.x, " ").concat(s.y, ")"), children: jsx("path", { className: "aurora-lm-sparkle", d: sparklePath(s.s), style: {
3924
+ "--lm-sparkle-delay": s.delay,
3925
+ } }) }, "".concat(s.x, "-").concat(s.y))); }) }))] }) })] })));
3926
+ });
3927
+
3539
3928
  var defaultTranslations$8 = {
3540
3929
  previewAlt: "Vista previa de imagen",
3541
3930
  removeButtonAriaLabel: "Eliminar imagen",
@@ -10139,4 +10528,4 @@ var NavigationLoadingProvider = function (_a) {
10139
10528
  return (jsxs(NavigationLoadingContext.Provider, { value: value, children: [children, jsx(NavigationLoadingOverlay, { isVisible: isVisible })] }));
10140
10529
  };
10141
10530
 
10142
- export { ALL_THEMES, AURORA_THEME_FAMILIES, AURORA_THEME_REGISTRY, AccordionList, AddHolidayForm, AnalyticsCard, AreaLineChart, AuraAutocomplete, AuraTable, AuraToastProvider, BEWEOS_THEME_MODE_COOKIE_NAME, BreadcrumbsComponent, Button, CONTAINER_ATTRIBUTE, Card, Chip, ColorPicker, ColorSelector, ContentCarousel, Currency, DEFAULT_DONUT_COLORS, DEFAULT_PREDEFINED_COLORS, DEFAULT_RANKED_BAR_COLORS, DISMISS_CONTROL_ATTRIBUTE, DatePicker, DateRangePicker, DateSelector, DonutChart, DrawerFilters, EmailPreview, EnumMenuNavListItem, GlobalToast, H1, H2, H3, H4, HeaderComponent, HolidayType, IconComponent, ImagePreview, Input, InputPassword, Kanban, KanbanCard, KanbanColumn, LINDA_TONE_PROPERTIES, LindaIcon, MenuClaw, MenuComponent, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, MultiStepWizard, NavigationLoadingContext, NavigationLoadingOverlay, NavigationLoadingProvider, P, Pagination, Phone, PromotionalBanner, REGISTERED_THEME_COLORS, RangeFilter, RankedBarList, RowSteps, DEFAULT_TRANSLATIONS$1 as SEGMENTATION_DEFAULT_TRANSLATIONS, ScheduleRow, SearchInput, SegmentationBuilder, Select, SimpleLineChart, SocialMediaBar, SocialMediaCarousel, SocialMediaPreview, StatTile, StepIndicator, Switch as SwitchComponent, THEME_COLOR_HEX_MAP, TagsFilter, Textarea, ThemeContext, ThemePicker, ThemeProvider, TimeInput as TimeInputComponent, ToastContext, Tooltip, TwoColumnLayoutAgent, UploadFile, VerticalSteps, ViolinPlot, WhatsAppPreview, Wizard, WizardNavigation, WizardSidebar, applyCustomPrimaryColor, applyLindaTones, computeBars, computeMax, computeSlices, computeTotal, containerProps, createCurrencyFormatter, uniqueCountries as defaultCountries, defaultCurrencyOptions, defaultTranslations$5 as defaultTranslations, deriveLindaTones, dismissControlProps, forceLightOnlyThemeBeforeReact, formatAuroraThemeTooltip, formatDonutPercent, generateThemeColorScale, getContrastForeground, getRegisteredThemeColorBases, getSelectedKeyFromPath, hexToThemeColor, hslToCssValue, isAuroraFullThemeId, isDismissControl, isDonutEmpty, isExactThemeColor, isGroupState, isHexColor, isInsideDismissContainer, isRankedBarListEmpty, isSegmentationGroup, parseHslTriplet, removeCustomPrimaryColor, removeLindaTones, shouldClosePopoverOnInteractOutside, sizeMap, themeColors, useAuraToast, useCloseOnAncestorScroll, useMediaQuery, useNavigationLoading, useThemeContext, withPopoverDismissDefaults };
10531
+ export { ALL_THEMES, AURORA_THEME_FAMILIES, AURORA_THEME_REGISTRY, AccordionList, AddHolidayForm, AnalyticsCard, AreaLineChart, AuraAutocomplete, AuraTable, AuraToastProvider, BEWEOS_THEME_MODE_COOKIE_NAME, BetaBadge, BreadcrumbsComponent, Button, CONTAINER_ATTRIBUTE, Card, Chip, ColorPicker, ColorSelector, ContentCarousel, Currency, DEFAULT_DONUT_COLORS, DEFAULT_PREDEFINED_COLORS, DEFAULT_RANKED_BAR_COLORS, DISMISS_CONTROL_ATTRIBUTE, DatePicker, DateRangePicker, DateSelector, DonutChart, DrawerFilters, EmailPreview, EnumMenuNavListItem, GlobalToast, H1, H2, H3, H4, HeaderComponent, HolidayType, IconComponent, 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, PromotionalBanner, REGISTERED_THEME_COLORS, RangeFilter, RankedBarList, RowSteps, DEFAULT_TRANSLATIONS$1 as SEGMENTATION_DEFAULT_TRANSLATIONS, ScheduleRow, SearchInput, SegmentationBuilder, Select, SimpleLineChart, SocialMediaBar, SocialMediaCarousel, SocialMediaPreview, StatTile, StepIndicator, Switch as SwitchComponent, THEME_COLOR_HEX_MAP, TagsFilter, Textarea, ThemeContext, ThemePicker, ThemeProvider, TimeInput as TimeInputComponent, ToastContext, Tooltip, TwoColumnLayoutAgent, UploadFile, VerticalSteps, ViolinPlot, WhatsAppPreview, Wizard, WizardNavigation, WizardSidebar, applyCustomPrimaryColor, applyLindaTones, computeBars, computeMax, computeSlices, computeTotal, containerProps, createCurrencyFormatter, uniqueCountries as defaultCountries, defaultCurrencyOptions, defaultTranslations$5 as defaultTranslations, deriveLindaTones, dismissControlProps, forceLightOnlyThemeBeforeReact, formatAuroraThemeTooltip, formatDonutPercent, generateThemeColorScale, getContrastForeground, getRegisteredThemeColorBases, getSelectedKeyFromPath, hexToThemeColor, hslToCssValue, isAuroraFullThemeId, isDismissControl, isDonutEmpty, isExactThemeColor, isGroupState, isHexColor, isInsideDismissContainer, isRankedBarListEmpty, isSegmentationGroup, parseHslTriplet, removeCustomPrimaryColor, removeLindaTones, shouldClosePopoverOnInteractOutside, sizeMap, themeColors, useAuraToast, useCloseOnAncestorScroll, useMediaQuery, useNavigationLoading, useThemeContext, withPopoverDismissDefaults };