@beweco/aurora-ui 1.0.3 → 1.0.4

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/index.cjs.js +1262 -403
  2. package/dist/index.esm.js +1245 -404
  3. package/dist/types/components/linda-mascot/LindaMascot.d.ts +7 -11
  4. package/dist/types/components/linda-mascot/LindaMascot.d.ts.map +1 -1
  5. package/dist/types/components/linda-mascot/LindaMascot.types.d.ts +44 -26
  6. package/dist/types/components/linda-mascot/LindaMascot.types.d.ts.map +1 -1
  7. package/dist/types/components/linda-mascot/character/character-color.d.ts +15 -0
  8. package/dist/types/components/linda-mascot/character/character-color.d.ts.map +1 -0
  9. package/dist/types/components/linda-mascot/character/character-css-vars.d.ts +29 -0
  10. package/dist/types/components/linda-mascot/character/character-css-vars.d.ts.map +1 -0
  11. package/dist/types/components/linda-mascot/character/character-normalize.d.ts +16 -0
  12. package/dist/types/components/linda-mascot/character/character-normalize.d.ts.map +1 -0
  13. package/dist/types/components/linda-mascot/character/character-palette.d.ts +78 -0
  14. package/dist/types/components/linda-mascot/character/character-palette.d.ts.map +1 -0
  15. package/dist/types/components/linda-mascot/character/character-platform.d.ts +26 -0
  16. package/dist/types/components/linda-mascot/character/character-platform.d.ts.map +1 -0
  17. package/dist/types/components/linda-mascot/character/character-themes.d.ts +51 -0
  18. package/dist/types/components/linda-mascot/character/character-themes.d.ts.map +1 -0
  19. package/dist/types/components/linda-mascot/character/fixtures/brand-example-character.d.ts +23 -0
  20. package/dist/types/components/linda-mascot/character/fixtures/brand-example-character.d.ts.map +1 -0
  21. package/dist/types/components/linda-mascot/character/index.d.ts +10 -0
  22. package/dist/types/components/linda-mascot/character/index.d.ts.map +1 -0
  23. package/dist/types/components/linda-mascot/index.d.ts +3 -2
  24. package/dist/types/components/linda-mascot/index.d.ts.map +1 -1
  25. package/dist/types/components/linda-mascot/linda-mascot.constants.d.ts +7 -44
  26. package/dist/types/components/linda-mascot/linda-mascot.constants.d.ts.map +1 -1
  27. package/dist/types/components/linda-mascot/linda-mascot.styles.d.ts +1 -0
  28. package/dist/types/components/linda-mascot/linda-mascot.styles.d.ts.map +1 -1
  29. package/package.json +1 -1
package/dist/index.cjs.js CHANGED
@@ -6949,14 +6949,394 @@ const LindaIcon = ({ size = 24, className, ...nativeProps }) => {
6949
6949
  return (jsxRuntime.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: jsxRuntime.jsxs("g", { fill: "currentColor", children: [jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" })] }) }));
6950
6950
  };
6951
6951
 
6952
+ /** Aritmética mínima de color del personaje. TS puro: sin DOM ni React. */
6953
+ const HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
6954
+ /**
6955
+ * Un color en HEX normalizado a `#RRGGBB` en mayúsculas, o `null` si no lo es.
6956
+ *
6957
+ * Acepta `#RGB` y `#RRGGBB` en cualquier caja y con espacios alrededor; cualquier otra
6958
+ * cosa (un nombre, `rgb()`, un hex con alfa, un no-texto) devuelve `null` para que quien
6959
+ * llama decida el respaldo en vez de pintar un color que el navegador no entiende.
6960
+ */
6961
+ const normalizeHex = (value) => {
6962
+ if (typeof value !== "string") {
6963
+ return null;
6964
+ }
6965
+ const trimmed = value.trim();
6966
+ if (!HEX.test(trimmed)) {
6967
+ return null;
6968
+ }
6969
+ const digits = trimmed.slice(1);
6970
+ const full = digits.length === 3
6971
+ ? digits
6972
+ .split("")
6973
+ .map((digit) => digit + digit)
6974
+ .join("")
6975
+ : digits;
6976
+ return `#${full.toUpperCase()}`;
6977
+ };
6978
+ /**
6979
+ * Aclara un color hacia el blanco canal a canal: `0` lo deja igual y `1` es blanco.
6980
+ * Espera un HEX ya normalizado.
6981
+ */
6982
+ const tintHex = (hex, amount) => {
6983
+ const value = Number.parseInt(hex.slice(1), 16);
6984
+ const channels = [(value >> 16) & 255, (value >> 8) & 255, value & 255];
6985
+ return `#${channels
6986
+ .map((channel) => Math.round(channel + (255 - channel) * amount)
6987
+ .toString(16)
6988
+ .padStart(2, "0"))
6989
+ .join("")
6990
+ .toUpperCase()}`;
6991
+ };
6992
+
6993
+ /**
6994
+ * Los temas del personaje de Linda: el dato de color del agente.
6995
+ *
6996
+ * Un tema son **9 colores con rol** del lienzo de diseño. La anatomía, los estados y las
6997
+ * animaciones son los mismos en todos; lo único que cambia son estos colores. Aquí está
6998
+ * el único sitio de la librería donde se escriben los hex de un tema: el componente los
6999
+ * recibe por variables CSS (ver `character-css-vars.ts`).
7000
+ *
7001
+ * Las claves de los roles son las mismas que guarda y sirve el backend de agencias, para
7002
+ * que lo que llega por la API se pueda pasar tal cual a `characterPaletteFromTheme`.
7003
+ */
7004
+ /** Los 9 roles de un tema, en el orden de la tabla del diseño. */
7005
+ const CHARACTER_THEME_COLOR_KEYS = [
7006
+ /** Accent AI: scoring y micro-detalles de inteligencia. */
7007
+ "accent",
7008
+ /** Primary: acción principal y control humano. */
7009
+ "primary",
7010
+ /** Cian de navegación: fondos destacados y navegación activa. */
7011
+ "navigation",
7012
+ /** Aqua suave: fondo general y contenedores amplios. */
7013
+ "soft",
7014
+ /** Teal neutro: apoyo, divisores y estados neutros. */
7015
+ "neutral",
7016
+ /** Secondary (verde de crecimiento): éxito, clientes activos, automatizaciones. */
7017
+ "secondary",
7018
+ /** Contexto AI: propuestas proactivas. */
7019
+ "context",
7020
+ /** Superficie profunda: tarjetas oscuras y datos secundarios. */
7021
+ "surface",
7022
+ /** Base oscura: núcleo, tipografía, encabezados y menús. */
7023
+ "base",
7024
+ ];
7025
+ const CHARACTER_THEME_IDS = [
7026
+ "linda",
7027
+ "luna",
7028
+ "purple",
7029
+ "coral",
7030
+ "green",
7031
+ "ocean",
7032
+ "sky",
7033
+ "yellow",
7034
+ ];
7035
+ /** El tema de Bewe y el que se usa cuando no hay otro. */
7036
+ const DEFAULT_CHARACTER_THEME_ID = "linda";
7037
+ const theme = (id, name, values, outline) => {
7038
+ const hexes = values.split(" ");
7039
+ const colors = Object.fromEntries(CHARACTER_THEME_COLOR_KEYS.map((key, index) => [key, hexes[index]]));
7040
+ return Object.freeze({
7041
+ id,
7042
+ name,
7043
+ colors: Object.freeze({ ...colors, outline }),
7044
+ });
7045
+ };
7046
+ /**
7047
+ * Los 8 temas del lienzo. Valores en el orden de `CHARACTER_THEME_COLOR_KEYS`; el último
7048
+ * argumento es el filo del aro de cada tema (`.rimline` en las páginas de Estados).
7049
+ * Congelados en profundidad: son el respaldo de toda paleta incompleta.
7050
+ */
7051
+ const CHARACTER_THEMES = Object.freeze({
7052
+ linda: theme("linda", "Linda", "#FAD19E #60A5FA #67E8F9 #CCFBF1 #75C9C8 #34D399 #FEF3C7 #355452 #0A2540", "#B4E1FC"),
7053
+ luna: theme("luna", "Luna", "#D29EF6 #A133EB #C27AF2 #F2E4F9 #ACA0B1 #7F6D87 #F2E4F9 #534758 #262128", "#E3C2F9"),
7054
+ purple: theme("purple", "Purple", "#A773DB #7828C8 #59A1F4 #EEE4F8 #86BBF7 #006FEE #DFEDFD #39135F #240C3C", "#B3D4FA"),
7055
+ coral: theme("coral", "Coral", "#FF6E6E #FF4F4F #FF8D8D #FFE9E9 #FFABAB #D24141 #FFCACA #792626 #4C1818", "#FFCACA"),
7056
+ green: theme("green", "Green", "#7E91FB #16C964 #68DC9A #E2F8EC #90E5B5 #3956F9 #E6EAFE #1B2976 #111A4B", "#B9EFD0"),
7057
+ ocean: theme("ocean", "Ocean", "#6AF5BB #26A5E5 #72C4EE #E4F4FC #98D4F3 #1AEF96 #E2FDF2 #124E6D #0B3245", "#BEE4F7"),
7058
+ sky: theme("sky", "Sky", "#FAD19E #60A5FA #98C5FC #EBF4FE #7CB5FB #7ACA97 #FEF1E2 #2E4E77 #1D324B", "#CFE4FE"),
7059
+ yellow: theme("yellow", "Yellow", "#FFD505 #4561BD #6D83CB #FFFAE0 #94A4D9 #D2B004 #FFF2B4 #0E1E53 #091334", "#BCC6E7"),
7060
+ });
7061
+ /**
7062
+ * Los colores fijos del personaje, iguales en todos los temas: el aviso (naranja, su
7063
+ * tono suave y el rojo del borde) y el blanco de ojos y brillos.
7064
+ */
7065
+ const CHARACTER_FIXED_COLORS = {
7066
+ alert: "#F97316",
7067
+ alertSoft: "#FB923C",
7068
+ alertDeep: "#EF4444",
7069
+ light: "#FFFFFF",
7070
+ };
7071
+
7072
+ /** Cuánto se aclara el Primary para el filo del aro cuando los colores son propios. */
7073
+ const OUTLINE_TINT = 0.7;
7074
+ /**
7075
+ * Valida los colores de un tema y completa lo que falte con los de Linda, rol a rol.
7076
+ *
7077
+ * Una configuración incompleta (un rol sin enviar, un color mal escrito) nunca deja el
7078
+ * personaje sin color: ese rol sale como el de Linda y se informa en `issues`. El filo
7079
+ * (`outline`) solo se conserva si es un HEX válido; si no, se omite y lo resuelve la
7080
+ * derivación.
7081
+ */
7082
+ const normalizeCharacterThemeColors = (input) => {
7083
+ const source = input !== null && typeof input === "object"
7084
+ ? input
7085
+ : {};
7086
+ const fallback = CHARACTER_THEMES[DEFAULT_CHARACTER_THEME_ID].colors;
7087
+ const issues = [];
7088
+ const colors = {};
7089
+ for (const key of CHARACTER_THEME_COLOR_KEYS) {
7090
+ const hex = normalizeHex(source[key]);
7091
+ if (hex) {
7092
+ colors[key] = hex;
7093
+ }
7094
+ else {
7095
+ colors[key] = fallback[key];
7096
+ issues.push({
7097
+ key,
7098
+ reason: source[key] === undefined ? "missing" : "invalid",
7099
+ });
7100
+ }
7101
+ }
7102
+ const outline = normalizeHex(source.outline);
7103
+ if (outline) {
7104
+ colors.outline = outline;
7105
+ }
7106
+ else if (source.outline !== undefined && source.outline !== null) {
7107
+ issues.push({ key: "outline", reason: "invalid" });
7108
+ }
7109
+ return { colors, issues };
7110
+ };
7111
+ /**
7112
+ * El filo del aro de un tema del lienzo si los 9 colores son exactamente los suyos.
7113
+ *
7114
+ * El backend guarda 9 colores y no el filo, que el diseño ajusta a mano por tema y no sale
7115
+ * de ninguna regla. Así un tema elegido en el panel se pinta igual que en el lienzo.
7116
+ */
7117
+ const outlineOfMatchingTheme = (colors) => {
7118
+ const match = CHARACTER_THEME_IDS.find((id) => CHARACTER_THEME_COLOR_KEYS.every((key) => CHARACTER_THEMES[id].colors[key] === colors[key]));
7119
+ return match ? CHARACTER_THEMES[match].colors.outline : undefined;
7120
+ };
7121
+ /**
7122
+ * Los 9 colores de un tema repartidos por las piezas del dibujo.
7123
+ *
7124
+ * Es la regla del lienzo: el aro recorre Primary → Cian → Secondary → Accent y vuelve; al
7125
+ * pensar se enfría hacia Teal y Aqua; el núcleo es la Base; la película de la pompa pasa
7126
+ * por Aqua, Contexto, Accent, Primary y Cian. El aviso y el blanco son fijos, salvo el
7127
+ * tercer tono del aro de aviso, que es el Accent del tema.
7128
+ *
7129
+ * Tolera entradas incompletas o inválidas: cada rol que no se entienda sale como el de
7130
+ * Linda (ver `normalizeCharacterThemeColors`).
7131
+ */
7132
+ const characterPaletteFromTheme = (input) => {
7133
+ const { colors } = normalizeCharacterThemeColors(input);
7134
+ const { accent, primary, navigation, soft, neutral, secondary, context, base, } = colors;
7135
+ const { alert, alertSoft, alertDeep, light } = CHARACTER_FIXED_COLORS;
7136
+ return {
7137
+ ring: [
7138
+ primary,
7139
+ navigation,
7140
+ secondary,
7141
+ accent,
7142
+ secondary,
7143
+ navigation,
7144
+ primary,
7145
+ ],
7146
+ thinkingRing: [navigation, primary, neutral, soft, navigation],
7147
+ alertRing: [alert, alertSoft, accent, alert, alertDeep, alert],
7148
+ core: base,
7149
+ film: [soft, context, accent, primary, navigation],
7150
+ light,
7151
+ mint: soft,
7152
+ glow: navigation,
7153
+ deep: primary,
7154
+ spark: secondary,
7155
+ warm: accent,
7156
+ outline: colors.outline ??
7157
+ outlineOfMatchingTheme(colors) ??
7158
+ tintHex(primary, OUTLINE_TINT),
7159
+ alert,
7160
+ alertDeep,
7161
+ };
7162
+ };
7163
+ const lindaPalette = characterPaletteFromTheme(CHARACTER_THEMES[DEFAULT_CHARACTER_THEME_ID].colors);
7164
+ for (const value of Object.values(lindaPalette)) {
7165
+ if (Array.isArray(value)) {
7166
+ Object.freeze(value);
7167
+ }
7168
+ }
7169
+ /**
7170
+ * La paleta de Linda: el respaldo de todo lo que no se entienda. Congelada, porque todas
7171
+ * las mascotas caen a ella: modificarla desde fuera cambiaría el respaldo de todas.
7172
+ */
7173
+ const DEFAULT_CHARACTER_PALETTE = Object.freeze(lindaPalette);
7174
+
7175
+ const LIST_KEYS = ["ring", "thinkingRing", "alertRing", "film"];
7176
+ /**
7177
+ * Tonos mínimos de cada lista. Un aro es un degradado que da la vuelta: con un solo tono
7178
+ * no hay degradado (y hay navegadores que descartan uno de una sola parada, dejando el aro
7179
+ * sin pintar). La película sí admite uno: los huecos repiten su primer tono.
7180
+ */
7181
+ const MIN_LENGTH = {
7182
+ ring: 2,
7183
+ thinkingRing: 2,
7184
+ alertRing: 2,
7185
+ film: 1,
7186
+ };
7187
+ const COLOR_KEYS = [
7188
+ "core",
7189
+ "light",
7190
+ "mint",
7191
+ "glow",
7192
+ "deep",
7193
+ "spark",
7194
+ "warm",
7195
+ "outline",
7196
+ "alert",
7197
+ "alertDeep",
7198
+ ];
7199
+ /**
7200
+ * Valida una paleta ya repartida (la de la app, una guardada, la que llega por props) y
7201
+ * la completa con la de Linda pieza por pieza.
7202
+ *
7203
+ * Un campo suelto que no sea un HEX cae al de Linda. Una lista que no sea un array de HEX
7204
+ * válidos (al menos dos en los aros) cae ENTERA a la de Linda: mezclar tonos de dos temas en el mismo
7205
+ * aro se ve como un error, no como un tema. Nunca lanza.
7206
+ */
7207
+ const normalizeCharacterPalette = (input) => {
7208
+ const source = input !== null && typeof input === "object"
7209
+ ? input
7210
+ : {};
7211
+ const issues = [];
7212
+ const palette = { ...DEFAULT_CHARACTER_PALETTE };
7213
+ for (const key of LIST_KEYS) {
7214
+ const value = source[key];
7215
+ const hexes = Array.isArray(value) ? value.map(normalizeHex) : [];
7216
+ if (hexes.length >= MIN_LENGTH[key] && hexes.every((hex) => hex !== null)) {
7217
+ palette[key] = hexes;
7218
+ }
7219
+ else {
7220
+ palette[key] = [...DEFAULT_CHARACTER_PALETTE[key]];
7221
+ issues.push({ key, reason: value === undefined ? "missing" : "invalid" });
7222
+ }
7223
+ }
7224
+ for (const key of COLOR_KEYS) {
7225
+ const hex = normalizeHex(source[key]);
7226
+ if (hex) {
7227
+ palette[key] = hex;
7228
+ }
7229
+ else {
7230
+ issues.push({
7231
+ key,
7232
+ reason: source[key] === undefined ? "missing" : "invalid",
7233
+ });
7234
+ }
7235
+ }
7236
+ return { palette, issues };
7237
+ };
7238
+ /** `true` si la paleta está completa y todos sus colores son HEX válidos. */
7239
+ const isCompleteCharacterPalette = (input) => normalizeCharacterPalette(input).issues.length === 0;
7240
+
7241
+ /**
7242
+ * Las variables CSS que lee `LindaMascot`. Las listas (`--lm-ring`…) van separadas por
7243
+ * comas para entrar tal cual en un `conic-gradient`. `--lm-teal` y `--lm-alert-soft` no
7244
+ * son campos de la paleta: salen de ella (el tercer tono del aro de pensar y el segundo
7245
+ * del de aviso), igual que hace la app con las órbitas.
7246
+ */
7247
+ const CHARACTER_CSS_VARS = [
7248
+ "--lm-ring",
7249
+ "--lm-thinking-ring",
7250
+ "--lm-alert-ring",
7251
+ "--lm-core",
7252
+ "--lm-film-1",
7253
+ "--lm-film-2",
7254
+ "--lm-film-3",
7255
+ "--lm-film-4",
7256
+ "--lm-film-5",
7257
+ "--lm-light",
7258
+ "--lm-mint",
7259
+ "--lm-glow",
7260
+ "--lm-deep",
7261
+ "--lm-spark",
7262
+ "--lm-warm",
7263
+ "--lm-outline",
7264
+ "--lm-alert",
7265
+ "--lm-alert-deep",
7266
+ "--lm-teal",
7267
+ "--lm-alert-soft",
7268
+ ];
7269
+ /**
7270
+ * Una paleta como variables CSS, lista para un `style` o para `setProperty`. Normaliza
7271
+ * antes: lo que no se entienda sale con los colores de Linda.
7272
+ */
7273
+ const characterPaletteToCssVars = (input) => {
7274
+ const { palette } = normalizeCharacterPalette(input);
7275
+ const film = (index) => palette.film[index] ?? palette.film[0];
7276
+ return {
7277
+ "--lm-ring": palette.ring.join(", "),
7278
+ "--lm-thinking-ring": palette.thinkingRing.join(", "),
7279
+ "--lm-alert-ring": palette.alertRing.join(", "),
7280
+ "--lm-core": palette.core,
7281
+ "--lm-film-1": film(0),
7282
+ "--lm-film-2": film(1),
7283
+ "--lm-film-3": film(2),
7284
+ "--lm-film-4": film(3),
7285
+ "--lm-film-5": film(4),
7286
+ "--lm-light": palette.light,
7287
+ "--lm-mint": palette.mint,
7288
+ "--lm-glow": palette.glow,
7289
+ "--lm-deep": palette.deep,
7290
+ "--lm-spark": palette.spark,
7291
+ "--lm-warm": palette.warm,
7292
+ "--lm-outline": palette.outline,
7293
+ "--lm-alert": palette.alert,
7294
+ "--lm-alert-deep": palette.alertDeep,
7295
+ "--lm-teal": palette.thinkingRing[2] ?? palette.thinkingRing[0],
7296
+ "--lm-alert-soft": palette.alertRing[1],
7297
+ };
7298
+ };
7299
+ /**
7300
+ * Escribe la paleta del personaje en un elemento, típicamente
7301
+ * `document.documentElement.style` para que todas las mascotas de la página la hereden.
7302
+ */
7303
+ const applyCharacterPalette = (style, palette) => {
7304
+ for (const [name, value] of Object.entries(characterPaletteToCssVars(palette))) {
7305
+ style.setProperty(name, value);
7306
+ }
7307
+ };
7308
+ /** Quita la paleta: las mascotas vuelven a pintarse con la de Linda. */
7309
+ const removeCharacterPalette = (style) => {
7310
+ for (const name of CHARACTER_CSS_VARS) {
7311
+ style.removeProperty(name);
7312
+ }
7313
+ };
7314
+
7315
+ /** Los estados que se pintan, en el orden del lienzo de diseño. */
6952
7316
  const LINDA_MASCOT_STATES = [
6953
- "idle",
6954
- "processing",
7317
+ "ready",
7318
+ "thinking",
6955
7319
  "working",
6956
7320
  "listening",
7321
+ "alert",
7322
+ "loading",
6957
7323
  "talking",
6958
- "ready",
6959
7324
  ];
7325
+ /** Nombres anteriores de estado y el estado con el que se pintan ahora. */
7326
+ const LINDA_MASCOT_STATE_ALIASES = {
7327
+ idle: "ready",
7328
+ processing: "thinking",
7329
+ };
7330
+ /** El estado que se pinta. Un nombre anterior se traduce; uno desconocido, reposo. */
7331
+ const resolveMascotState = (state) => {
7332
+ if (state === undefined) {
7333
+ return "ready";
7334
+ }
7335
+ if (state === "idle" || state === "processing") {
7336
+ return LINDA_MASCOT_STATE_ALIASES[state];
7337
+ }
7338
+ return LINDA_MASCOT_STATES.includes(state) ? state : "ready";
7339
+ };
6960
7340
  /** px de cada talla con nombre. Cada una cae en su propio nivel de detalle. */
6961
7341
  const LINDA_MASCOT_SIZE_PX = {
6962
7342
  xs: 20,
@@ -6968,17 +7348,6 @@ const LINDA_MASCOT_SIZE_PX = {
6968
7348
  const LINDA_MASCOT_LEVEL_VAR = "--linda-mascot-level";
6969
7349
  /** id de la `<style>` que el componente deja en `<head>`. */
6970
7350
  const LINDA_MASCOT_STYLE_ID = "aurora-linda-mascot-styles";
6971
- /** Paleta de la hoja de marca. */
6972
- const LINDA_MASCOT_PALETTE = {
6973
- coreLight: "#2A2D4A",
6974
- coreDark: "#0B0C18",
6975
- eye: "#EAF2FF",
6976
- eyeGlow: "#8FB8FF",
6977
- pink: "#FF8AD8",
6978
- violet: "#A48BFF",
6979
- cyan: "#6FE3FF",
6980
- amber: "#FFD08A",
6981
- };
6982
7351
  const resolveMascotPx = (size) => {
6983
7352
  if (typeof size === "number") {
6984
7353
  return Number.isFinite(size) && size > 0 ? size : LINDA_MASCOT_SIZE_PX.md;
@@ -7004,480 +7373,952 @@ const clampLevel = (level) => {
7004
7373
  }
7005
7374
  return Math.min(1, Math.max(0, level));
7006
7375
  };
7007
- const LINDA_MASCOT_GEOMETRY = {
7008
- xs: {
7009
- coreRx: 40,
7010
- coreCy: 61,
7011
- eyeWidth: 17,
7012
- eyeHeight: 8,
7013
- eyeStroke: 9,
7014
- eyeGap: 31,
7015
- rings: [{ r: 57, squash: 0.3, tilt: -16, strokePx: 1.2, opacity: 0.95 }],
7016
- halo: false,
7017
- specular: false,
7018
- blur: false,
7019
- ringGlow: "none",
7020
- },
7021
- sm: {
7022
- coreRx: 36,
7023
- coreCy: 61,
7024
- eyeWidth: 14,
7025
- eyeHeight: 6.5,
7026
- eyeStroke: 6,
7027
- eyeGap: 28,
7028
- rings: [
7029
- { r: 56, squash: 0.3, tilt: -16, strokePx: 1.1, opacity: 0.9 },
7030
- { r: 52, squash: 0.36, tilt: 20, strokePx: 1, opacity: 0.7 },
7031
- ],
7032
- halo: true,
7033
- specular: false,
7034
- blur: false,
7035
- ringGlow: "none",
7036
- },
7037
- md: {
7038
- coreRx: 33,
7039
- coreCy: 61,
7040
- eyeWidth: 12.5,
7041
- eyeHeight: 5.5,
7042
- eyeStroke: 4.4,
7043
- eyeGap: 25,
7044
- rings: [
7045
- { r: 56, squash: 0.3, tilt: -16, strokePx: 1.5, opacity: 0.85 },
7046
- { r: 52, squash: 0.38, tilt: 20, strokePx: 1.2, opacity: 0.7 },
7047
- { r: 58, squash: 0.2, tilt: -3, strokePx: 1, opacity: 0.55 },
7048
- ],
7049
- halo: true,
7050
- specular: true,
7051
- blur: true,
7052
- ringGlow: "flat",
7053
- },
7054
- lg: {
7055
- coreRx: 32,
7056
- coreCy: 61,
7057
- eyeWidth: 12,
7058
- eyeHeight: 5.2,
7059
- eyeStroke: 3.8,
7060
- eyeGap: 24,
7061
- rings: [
7062
- { r: 56, squash: 0.3, tilt: -16, strokePx: 2, opacity: 0.85 },
7063
- { r: 52, squash: 0.38, tilt: 20, strokePx: 1.6, opacity: 0.72 },
7064
- { r: 58, squash: 0.2, tilt: -3, strokePx: 1.3, opacity: 0.58 },
7065
- ],
7066
- halo: true,
7067
- specular: true,
7068
- blur: true,
7069
- ringGlow: "blur",
7070
- },
7071
- };
7072
7376
 
7377
+ /**
7378
+ * La hoja del personaje: el lienzo de diseño (variante «pompa de jabón») aplanado.
7379
+ *
7380
+ * El lienzo es HTML + CSS con una cascada larga de refinados; aquí está solo lo que de
7381
+ * verdad se ve, resuelto regla a regla, con tres cambios:
7382
+ *
7383
+ * - **Ningún color escrito.** Cada color de tema sale de una variable `--_lm-*`, que lee la
7384
+ * pública `--lm-*` (la escribe `applyCharacterPalette` o la prop `palette`) con la paleta
7385
+ * de Linda como respaldo, generada desde el dato del tema. Los tonos con transparencia
7386
+ * del lienzo (`rgba(<rol>, .35)`) son `color-mix` de esas variables. Solo el blanco y el
7387
+ * negro de brillos y sombras van escritos.
7388
+ * - **Mide en `cqmin`.** El lienzo multiplica todo por `--s` (el lado). Aquí el lado es la
7389
+ * caja de la raíz (`container-type: size`), así que el dibujo sigue a la caja aunque el
7390
+ * consumidor la cambie por CSS (`size-full` en la llamada de Claw). La talla de la prop va
7391
+ * en \`@layer base\` para que esa clase gane.
7392
+ * - **Sin `!important` en las animaciones.** El lienzo resolvía su cascada con `!important`
7393
+ * y selectores de id; aquí cada estado gana por especificidad y el único `!important` es
7394
+ * el del movimiento reducido, que así para todo.
7395
+ */
7396
+ const ROOT = ".aurora-linda-mascot";
7073
7397
  const LEVEL = `var(${LINDA_MASCOT_LEVEL_VAR})`;
7074
- const AUTO_THEME = themeScopeSelectors('.aurora-linda-mascot[data-appearance="auto"]');
7075
- /** Curva de los movimientos que responden a la voz: sale rápido, llega suave. */
7076
- const EASE_OUT = "cubic-bezier(0.22, 0.7, 0.3, 1)";
7077
- /**
7078
- * Reglas de la mascota. Viajan con el componente (se inyectan en `<head>`, ver
7079
- * `useInjectedStyle`) para que funcione en un microfrontend que no carga `styles.css`.
7080
- *
7081
- * Todo se anima con `transform` u `opacity`. Cada grupo animado es un `<g>` SIN atributo
7082
- * `transform`: en SVG la propiedad CSS `transform` reemplaza al atributo, así que la
7083
- * geometría (posición, inclinación, aplastamiento) vive en grupos padres y el movimiento
7084
- * en grupos hijos. Por la misma razón, lo que sigue a la voz (`--linda-mascot-level`,
7085
- * con `transition`) y lo que late en bucle (con `animation`) van en grupos distintos: una
7086
- * animación CSS anula la transición de la misma propiedad.
7087
- */
7088
- /** Reglas de movimiento reducido bajo la raíz \`root\` (clase o clase+atributo). */
7089
- const reducedMotionBody = (root) => `
7090
- ${root} .aurora-lm-spin,
7091
- ${root} .aurora-lm-boost,
7092
- ${root} .aurora-lm-orbit,
7093
- ${root} .aurora-lm-eyes,
7094
- ${root} .aurora-lm-breathe,
7095
- ${root} .aurora-lm-halo,
7096
- ${root} .aurora-lm-sparkle {
7398
+ /** Una medida del lienzo: fracción del lado. */
7399
+ const s = (k) => `calc(var(--_lm-s) * ${k})`;
7400
+ /** Un color de tema con transparencia. */
7401
+ const mix = (name, percent) => `color-mix(in srgb, var(--_lm-${name}) ${percent}%, transparent)`;
7402
+ const white = (alpha) => `rgba(255, 255, 255, ${alpha})`;
7403
+ const black = (alpha) => `rgba(0, 0, 0, ${alpha})`;
7404
+ /** Huevo del aro y del núcleo. */
7405
+ const EGG = "50% 50% 46% 46% / 54% 54% 46% 46%";
7406
+ /** La pompa en reposo. */
7407
+ const BUBBLE_SHAPE = "63% 37% 54% 46% / 43% 60% 40% 57%";
7408
+ /** Máscara que deja solo el borde de una caja (el aro). */
7409
+ const BORDER_ONLY = `-webkit-mask: linear-gradient(black 0 0) padding-box, linear-gradient(black 0 0);
7410
+ -webkit-mask-composite: xor;
7411
+ mask: linear-gradient(black 0 0) padding-box, linear-gradient(black 0 0);
7412
+ mask-composite: exclude;`;
7413
+ const SOFT_EASE = "cubic-bezier(0.45, 0.05, 0.55, 0.95)";
7414
+ /**
7415
+ * `--_lm-x: var(--lm-x, <Linda>);` por cada variable pública. Una línea por variable: el
7416
+ * test que vigila que no haya colores escritos se salta exactamente estas líneas.
7417
+ */
7418
+ const paletteFallbacks = () => {
7419
+ const linda = characterPaletteToCssVars(DEFAULT_CHARACTER_PALETTE);
7420
+ return CHARACTER_CSS_VARS.map((name) => `\t--_lm-${name.slice(5)}: var(${name}, ${linda[name]});`).join("\n");
7421
+ };
7422
+ const AUTO_THEME = themeScopeSelectors(`${ROOT}[data-appearance="auto"]`);
7423
+ const reducedMotion = (root) => `
7424
+ ${root},
7425
+ ${root}::after,
7426
+ ${root} *,
7427
+ ${root} *::before,
7428
+ ${root} *::after {
7097
7429
  animation: none !important;
7430
+ transition: none !important;
7098
7431
  }
7099
- ${root} .aurora-lm-level-body,
7100
- ${root} .aurora-lm-level-rings,
7101
- ${root} .aurora-lm-level-halo {
7102
- transform: none !important;
7103
- }
7104
- ${root}.aurora-linda-mascot--listening .aurora-lm-level-rings,
7105
- ${root}.aurora-linda-mascot--talking .aurora-lm-level-rings {
7106
- opacity: calc(0.55 + ${LEVEL} * 0.45);
7107
- }
7108
- ${root}.aurora-linda-mascot--processing .aurora-lm-halo {
7109
- animation: aurora-lm-glow 1.6s ease-in-out infinite !important;
7110
- }
7111
- ${root}.aurora-linda-mascot--working .aurora-lm-halo {
7112
- opacity: 1 !important;
7113
- }
7114
- ${root}.aurora-linda-mascot--listening .aurora-lm-level-halo,
7115
- ${root}.aurora-linda-mascot--talking .aurora-lm-level-halo {
7116
- opacity: calc(0.4 + ${LEVEL} * 0.6) !important;
7432
+ ${root}.aurora-linda-mascot--loading .aurora-lm-load {
7433
+ opacity: 1;
7117
7434
  }
7118
- ${root}.aurora-linda-mascot--ready .aurora-lm-sparkle {
7119
- animation: aurora-lm-sparkle-fade 700ms ease-out 1 both !important;
7435
+ ${root}.aurora-linda-mascot--loading .aurora-lm-body {
7436
+ opacity: 0;
7120
7437
  }
7121
7438
  `;
7122
- const reducedMotionRules = (root) => `
7123
- @media (prefers-reduced-motion: reduce) {${reducedMotionBody(root)}}
7124
- ${reducedMotionBody(`${root}[data-motion="reduce"]`)}
7125
- `;
7439
+ /** Tiempo de respiración y grosor del aro por estado (`--breath` y `--rw` del lienzo). */
7126
7440
  const LINDA_MASCOT_CSS = `
7127
- .aurora-linda-mascot {
7441
+ @property --aurora-lm-a {
7442
+ syntax: "<angle>";
7443
+ inherits: false;
7444
+ initial-value: 0deg;
7445
+ }
7446
+
7447
+ /*
7448
+ * La talla de la prop, en la capa \`base\` y con especificidad 0: cualquier clase del
7449
+ * consumidor la pisa, también las utilidades de Tailwind 4, que van en \`@layer utilities\`
7450
+ * y perderían contra una regla sin capa. Una capa con nombre propio no vale: inyectada
7451
+ * después de Tailwind quedaría detrás de \`utilities\` y volvería a ganar.
7452
+ */
7453
+ @layer base {
7454
+ :where(${ROOT}) {
7455
+ width: var(--_lm-size, 72px);
7456
+ height: var(--_lm-size, 72px);
7457
+ }
7458
+ }
7459
+
7460
+ ${ROOT} {
7461
+ ${paletteFallbacks()}
7462
+ --_lm-s: 100cqmin;
7463
+ --_lm-rw: ${s(0.036)};
7464
+ --_lm-rb: var(--_lm-ring);
7465
+ --_lm-c1: var(--_lm-glow);
7466
+ --_lm-c2: var(--_lm-deep);
7467
+ --_lm-c3: var(--_lm-spark);
7468
+ --_lm-c4: var(--_lm-warm);
7469
+ --_lm-breath: 6s;
7470
+ --_lm-shadow-display: block;
7128
7471
  ${LINDA_MASCOT_LEVEL_VAR}: 0;
7129
- --lm-halo: 0.5;
7130
- --lm-shadow: 1;
7131
- --lm-rim: 0.85;
7132
- --lm-sparkle: #F2B441;
7472
+ position: relative;
7133
7473
  display: inline-block;
7134
7474
  flex-shrink: 0;
7135
- overflow: visible;
7475
+ container-type: size;
7136
7476
  vertical-align: middle;
7477
+ overflow: visible;
7137
7478
  }
7138
- /* En lg la mascota es escenario (bienvenida, llamada): más halo, como en la hoja de marca.
7139
- Multiplicador aparte para no competir en especificidad con las reglas de tema. */
7140
- .aurora-linda-mascot--tier-lg {
7141
- --lm-halo-boost: 1.4;
7479
+
7480
+ /* Reflejo claro en el suelo, bajo la pompa. */
7481
+ ${ROOT}::after {
7482
+ content: "";
7483
+ position: absolute;
7484
+ left: 28%;
7485
+ right: 28%;
7486
+ bottom: -14%;
7487
+ height: 6%;
7488
+ border-radius: 50%;
7489
+ background: radial-gradient(closest-side, ${white(0.7)}, ${mix("mint", 30)} 55%, transparent);
7490
+ filter: blur(${s(0.01)});
7491
+ pointer-events: none;
7142
7492
  }
7143
- /*
7144
- * Tema. \`auto\` sigue al ancestro claro/oscuro más cercano, incluidos los temas de aurora
7145
- * (\`blue-dark\`…); ver \`themeScopeSelectors\`.
7146
- */
7147
- ${AUTO_THEME.dark},
7148
- .aurora-linda-mascot[data-appearance="dark"] {
7149
- --lm-halo: 0.95;
7150
- --lm-shadow: 0;
7151
- --lm-rim: 1;
7152
- --lm-sparkle: #FFF1C9;
7493
+
7494
+ /* ── Estados: colores y ritmo ─────────────────────────────────────────────── */
7495
+
7496
+ .aurora-linda-mascot--ready,
7497
+ .aurora-linda-mascot--talking {
7498
+ --_lm-breath: 5s;
7153
7499
  }
7154
- ${AUTO_THEME.light} {
7155
- --lm-halo: 0.5;
7156
- --lm-shadow: 1;
7157
- --lm-rim: 0.85;
7158
- --lm-sparkle: #F2B441;
7500
+ .aurora-linda-mascot--listening {
7501
+ --_lm-breath: 6.5s;
7502
+ --_lm-rw: ${s(0.055)};
7159
7503
  }
7160
-
7161
- /* Cuerpo entero: respiración en bucle + escala por voz (grupos distintos). */
7162
- .aurora-lm-breathe,
7163
- .aurora-lm-level-body,
7164
- .aurora-lm-level-rings {
7165
- transform-box: view-box;
7166
- transform-origin: 60px 61px;
7504
+ .aurora-linda-mascot--thinking {
7505
+ --_lm-rb: var(--_lm-thinking-ring);
7506
+ --_lm-c3: var(--_lm-teal);
7507
+ --_lm-c4: var(--_lm-deep);
7508
+ --_lm-breath: 5s;
7167
7509
  }
7168
- .aurora-lm-breathe {
7169
- animation: aurora-lm-breathe 2s ease-in-out infinite alternate;
7510
+ .aurora-linda-mascot--working {
7511
+ --_lm-breath: 1.8s;
7512
+ --_lm-rw: ${s(0.042)};
7170
7513
  }
7171
- .aurora-lm-level-body,
7172
- .aurora-lm-level-rings,
7173
- .aurora-lm-level-halo {
7174
- transition: transform 140ms ${EASE_OUT}, opacity 240ms ${EASE_OUT};
7514
+ .aurora-linda-mascot--alert {
7515
+ --_lm-rb: var(--_lm-alert-ring);
7516
+ --_lm-c1: var(--_lm-alert);
7517
+ --_lm-c2: var(--_lm-alert-deep);
7518
+ --_lm-c3: var(--_lm-alert-soft);
7519
+ --_lm-c4: var(--_lm-warm);
7520
+ --_lm-breath: 1.3s;
7175
7521
  }
7176
7522
 
7177
- /* Halo y sombra de contacto. */
7178
- .aurora-lm-halo,
7179
- .aurora-lm-level-halo {
7180
- transform-box: fill-box;
7181
- transform-origin: center;
7523
+ /* ── Tema: en oscuro la sombra de contacto (tinta de la base) no se ve ───── */
7524
+
7525
+ ${AUTO_THEME.dark},
7526
+ ${ROOT}[data-appearance="dark"] {
7527
+ --_lm-shadow-display: none;
7182
7528
  }
7183
- .aurora-lm-halo {
7184
- opacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));
7185
- transition: opacity 400ms ease;
7529
+ ${AUTO_THEME.light} {
7530
+ --_lm-shadow-display: block;
7186
7531
  }
7532
+
7533
+ /* ── Capas ────────────────────────────────────────────────────────────────── */
7534
+
7535
+ .aurora-lm-pulse,
7536
+ .aurora-lm-shadow,
7537
+ .aurora-lm-load,
7538
+ .aurora-lm-level,
7539
+ .aurora-lm-body,
7540
+ .aurora-lm-body > span,
7541
+ .aurora-lm-orbit,
7542
+ .aurora-lm-soap > span,
7543
+ .aurora-lm-headphones > span {
7544
+ position: absolute;
7545
+ box-sizing: border-box;
7546
+ }
7547
+
7548
+ /* Ondas: solo al escuchar y en aviso. */
7549
+ .aurora-lm-pulse {
7550
+ inset: 4%;
7551
+ border-radius: 50%;
7552
+ border: ${s(0.01)} solid var(--_lm-c1);
7553
+ opacity: 0;
7554
+ pointer-events: none;
7555
+ }
7556
+
7187
7557
  .aurora-lm-shadow {
7188
- opacity: var(--lm-shadow);
7558
+ display: var(--_lm-shadow-display);
7559
+ left: 18%;
7560
+ right: 18%;
7561
+ bottom: -12%;
7562
+ height: 9%;
7563
+ border-radius: 50%;
7564
+ background: radial-gradient(closest-side, ${mix("core", 28)}, ${mix("core", 8)} 60%, transparent);
7565
+ filter: blur(${s(0.012)});
7566
+ animation: aurora-lm-shadow var(--_lm-breath) ease-in-out infinite;
7567
+ }
7568
+
7569
+ /* Cargando: cuadrícula de 9 puntos, oculta en el resto de estados. */
7570
+ .aurora-lm-load {
7571
+ display: none;
7572
+ left: 50%;
7573
+ top: 44%;
7574
+ width: 52%;
7575
+ aspect-ratio: 1;
7576
+ translate: -50% -50%;
7577
+ grid-template-columns: repeat(3, 1fr);
7578
+ grid-template-rows: repeat(3, 1fr);
7579
+ place-items: center;
7580
+ opacity: 0;
7581
+ z-index: 5;
7582
+ }
7583
+ .aurora-lm-dot {
7584
+ --_lm-dot: var(--_lm-c2);
7585
+ display: block;
7586
+ width: 58%;
7587
+ aspect-ratio: 1;
7588
+ border-radius: 50%;
7589
+ background: var(--_lm-dot);
7590
+ box-shadow: 0 0 ${s(0.03)} var(--_lm-dot), inset 0 ${s(-6e-3)} ${s(0.01)} ${black(0.12)}, inset 0 ${s(0.006)} ${s(0.008)} ${white(0.6)};
7591
+ opacity: 0.25;
7592
+ }
7593
+ .aurora-lm-dot--1 { --_lm-dot: var(--_lm-c2); animation-delay: 1.6s; }
7594
+ .aurora-lm-dot--2 { --_lm-dot: var(--_lm-c1); animation-delay: 1.75s; }
7595
+ .aurora-lm-dot--3 { --_lm-dot: var(--_lm-c3); animation-delay: 1.9s; }
7596
+ .aurora-lm-dot--6 { --_lm-dot: var(--_lm-c4); animation-delay: 2.05s; }
7597
+ .aurora-lm-dot--9 { --_lm-dot: var(--_lm-c2); animation-delay: 2.2s; }
7598
+ .aurora-lm-dot--8 { --_lm-dot: var(--_lm-c1); animation-delay: 2.35s; }
7599
+ .aurora-lm-dot--7 { --_lm-dot: var(--_lm-c3); animation-delay: 2.5s; }
7600
+ .aurora-lm-dot--4 { --_lm-dot: var(--_lm-c4); animation-delay: 2.65s; }
7601
+
7602
+ /* Envoltorio que solo escala con la voz: separado de las animaciones del cuerpo. */
7603
+ .aurora-lm-level {
7604
+ inset: 0;
7605
+ transition: scale 140ms cubic-bezier(0.22, 0.7, 0.3, 1);
7606
+ }
7607
+
7608
+ .aurora-lm-body {
7609
+ inset: 0;
7610
+ animation: aurora-lm-float var(--_lm-breath) ease-in-out infinite;
7611
+ }
7612
+
7613
+ /* Aro: borde cónico que gira el color; su resplandor, el mismo aro desenfocado. */
7614
+ .aurora-lm-rimglow {
7615
+ inset: 0;
7616
+ filter: blur(${s(0.028)}) saturate(1.8) brightness(1.45);
7617
+ }
7618
+ .aurora-lm-rim-glow,
7619
+ .aurora-lm-rim {
7620
+ border-style: solid;
7621
+ border-color: transparent;
7622
+ background: conic-gradient(from var(--aurora-lm-a), var(--_lm-rb)) border-box;
7623
+ ${BORDER_ONLY}
7624
+ animation: aurora-lm-hue 8s linear infinite, aurora-lm-squish var(--_lm-breath) ease-in-out infinite;
7625
+ }
7626
+ .aurora-lm-rim-glow {
7627
+ position: absolute;
7628
+ box-sizing: border-box;
7629
+ inset: 10.5% 10.5% 20.5% 18.5%;
7630
+ border-radius: ${EGG};
7631
+ border-width: calc(var(--_lm-rw) * 1.4) calc(var(--_lm-rw) * 1.3) calc(var(--_lm-rw) * 2) calc(var(--_lm-rw) * 1.9);
7189
7632
  }
7190
7633
  .aurora-lm-rim {
7191
- opacity: var(--lm-rim);
7634
+ inset: 12% 12% 22% 20%;
7635
+ border-radius: ${EGG};
7636
+ border-width: calc(var(--_lm-rw) * 0.7) calc(var(--_lm-rw) * 0.6) calc(var(--_lm-rw) * 1.3) calc(var(--_lm-rw) * 1.25);
7637
+ filter: blur(${s(0.0015)}) saturate(1.9) brightness(1.35);
7638
+ }
7639
+ .aurora-lm-rimline {
7640
+ inset: 12% 12% 22% 20%;
7641
+ border-radius: ${EGG};
7642
+ box-shadow: 0 0 0 ${s(0.004)} ${mix("outline", 95)}, 0 0 0 ${s(0.007)} ${mix("outline", 40)};
7643
+ pointer-events: none;
7644
+ animation: aurora-lm-squish var(--_lm-breath) ease-in-out infinite;
7645
+ }
7646
+
7647
+ /* Núcleo oscuro con su reflejo. */
7648
+ .aurora-lm-core {
7649
+ inset: 12% 12% 22% 20%;
7650
+ border-radius: ${EGG};
7651
+ background: radial-gradient(ellipse at 30% 80%, ${mix("deep", 28)}, transparent 45%), radial-gradient(ellipse at 80% 60%, ${mix("glow", 12)}, transparent 40%), var(--_lm-core);
7652
+ box-shadow: inset 0 0 ${s(0.03)} ${mix("glow", 25)};
7653
+ scale: 0.975;
7654
+ animation: aurora-lm-squish var(--_lm-breath) ease-in-out infinite;
7655
+ }
7656
+ .aurora-lm-core::before {
7657
+ content: "";
7658
+ position: absolute;
7659
+ right: 10%;
7660
+ top: 7%;
7661
+ width: 46%;
7662
+ height: 26%;
7663
+ border-radius: 50%;
7664
+ background: linear-gradient(200deg, ${white(0.55)}, ${white(0)} 75%);
7665
+ transform: rotate(28deg);
7666
+ filter: blur(${s(0.008)});
7667
+ z-index: 1;
7668
+ }
7669
+
7670
+ /* Órbitas de pensar: tres luces girando dentro del núcleo. */
7671
+ .aurora-lm-orbits {
7672
+ inset: 22% 18% 30% 26%;
7673
+ opacity: 0;
7674
+ transition: opacity 0.6s;
7192
7675
  }
7193
-
7194
- /*
7195
- * Anillos. El círculo gira dentro de su grupo aplastado: la elipse no cambia de forma y
7196
- * lo que recorre el trazo es el color, como un anillo que gira en profundidad.
7197
- * \`--lm-spin-duration\` y \`--lm-spin-direction\` llegan por anillo desde el marcado.
7198
- */
7199
- .aurora-lm-spin {
7200
- transform-box: view-box;
7201
- transform-origin: 0 0;
7202
- animation: aurora-lm-spin var(--lm-spin-duration, 24s) linear infinite
7203
- var(--lm-spin-direction, normal);
7204
- }
7205
- /* Segundo giro encadenado: parado salvo en working, donde dobla la velocidad sin saltos
7206
- (pausar conserva el ángulo; cambiar la duración lo haría saltar). */
7207
- .aurora-lm-boost {
7208
- animation-play-state: paused;
7209
- }
7210
- /* Cometa del anillo principal: orbita siempre, se ve solo al pensar o trabajar. */
7211
7676
  .aurora-lm-orbit {
7212
- animation-play-state: paused;
7677
+ inset: 0;
7213
7678
  }
7214
- .aurora-lm-comet,
7215
- .aurora-lm-glint {
7216
- opacity: 0;
7217
- transition: opacity 320ms ease;
7679
+ .aurora-lm-orbit::before {
7680
+ content: "";
7681
+ position: absolute;
7682
+ top: 0;
7683
+ left: 50%;
7684
+ width: ${s(0.034)};
7685
+ height: ${s(0.034)};
7686
+ margin-left: ${s(-0.017)};
7687
+ border-radius: 50%;
7688
+ background: var(--_lm-light);
7689
+ box-shadow: 0 0 ${s(0.04)} var(--_lm-c1);
7690
+ }
7691
+ .aurora-lm-orbit--2 {
7692
+ inset: 14%;
7693
+ }
7694
+ .aurora-lm-orbit--2::before {
7695
+ background: var(--_lm-c3);
7696
+ }
7697
+ .aurora-lm-orbit--3 {
7698
+ inset: -10%;
7699
+ }
7700
+ .aurora-lm-orbit--3::before {
7701
+ background: var(--_lm-c4);
7702
+ width: ${s(0.024)};
7703
+ height: ${s(0.024)};
7218
7704
  }
7219
7705
 
7220
- /* Ojos: solo parpadean (sin expresiones faciales). Dos parpadeos por ciclo, a 4,8 y 6,2 s. */
7706
+ /* Ojos: dos cápsulas de luz que parpadean. */
7221
7707
  .aurora-lm-eyes {
7222
- transform-box: fill-box;
7223
- transform-origin: center;
7224
- animation: aurora-lm-blink 11s ease-in-out infinite;
7708
+ left: 54%;
7709
+ top: 50%;
7710
+ width: 42%;
7711
+ height: 22%;
7712
+ transform: translate(-50%, -50%);
7713
+ display: flex;
7714
+ justify-content: space-between;
7715
+ align-items: center;
7716
+ transition: transform 0.6s ease;
7225
7717
  }
7226
-
7227
- /* Chispas de fin de turno. */
7228
- /* Dorado en claro (el blanco desaparece sobre fondo claro), casi blanco en oscuro. */
7229
- .aurora-lm-sparkle {
7230
- transform-box: fill-box;
7231
- transform-origin: center;
7232
- opacity: 0;
7233
- fill: var(--lm-sparkle);
7718
+ .aurora-lm-eye {
7719
+ display: block;
7720
+ box-sizing: border-box;
7721
+ width: 24%;
7722
+ height: 60%;
7723
+ border-radius: 999px;
7724
+ background: linear-gradient(180deg, var(--_lm-light) 0%, var(--_lm-light) 55%, var(--_lm-mint) 100%);
7725
+ box-shadow: 0 0 ${s(0.025)} var(--_lm-light), 0 0 ${s(0.08)} var(--_lm-glow);
7726
+ animation: aurora-lm-blink 5s infinite;
7727
+ transition: scale 0.5s ease, rotate 0.5s ease;
7728
+ }
7729
+
7730
+ /* Gafas de trabajar: ojo de gato en línea, del color de los ojos. */
7731
+ .aurora-lm-glasses {
7732
+ position: absolute;
7733
+ left: -16%;
7734
+ top: -12%;
7735
+ width: 132%;
7736
+ height: 124%;
7737
+ overflow: visible;
7738
+ filter: drop-shadow(0 0 ${s(0.006)} var(--_lm-light)) drop-shadow(0 0 ${s(0.016)} ${mix("light", 60)});
7739
+ }
7740
+ .aurora-lm-glasses g {
7741
+ fill: none;
7742
+ stroke: var(--_lm-light);
7743
+ stroke-width: 7;
7744
+ stroke-linejoin: round;
7745
+ stroke-linecap: round;
7746
+ }
7747
+
7748
+ /* Pompa de jabón: la burbuja que envuelve al personaje. */
7749
+ .aurora-lm-bubble {
7750
+ inset: -3% -2% -1% -4%;
7751
+ overflow: hidden;
7752
+ border-radius: ${BUBBLE_SHAPE};
7753
+ background: radial-gradient(circle at 38% 32%, ${white(0.12)} 0%, transparent 45%), radial-gradient(circle at 50% 50%, transparent 66%, ${mix("core", 4)} 78%, ${mix("core", 10)} 87%, ${white(0.28)} 93%, ${white(0.4)} 96%, ${white(0.12)} 99%, transparent 100%);
7754
+ box-shadow: inset ${s(-0.03)} ${s(-0.04)} ${s(0.07)} ${mix("core", 14)}, inset ${s(0.02)} ${s(0.025)} ${s(0.06)} ${white(0.4)}, 0 0 ${s(0.05)} ${white(0.35)}, 0 0 ${s(0.12)} ${mix("mint", 30)};
7755
+ filter: blur(${s(0.006)});
7756
+ animation: aurora-lm-jabon 11s ${SOFT_EASE} infinite, aurora-lm-breathe 7.3s ${SOFT_EASE} infinite, aurora-lm-drift 16s linear infinite;
7757
+ }
7758
+ .aurora-lm-bubble::before {
7759
+ content: "";
7760
+ position: absolute;
7761
+ inset: 0;
7762
+ border-radius: inherit;
7763
+ background: conic-gradient(from var(--aurora-lm-a), var(--_lm-film-1) 0deg, var(--_lm-film-2) 80deg, var(--_lm-film-3) 130deg, var(--_lm-film-4) 185deg, var(--_lm-film-5) 225deg, var(--_lm-film-1) 290deg, var(--_lm-film-1) 360deg);
7764
+ -webkit-mask: radial-gradient(closest-side, transparent 52%, ${black(0.6)} 78%, black 100%);
7765
+ mask: radial-gradient(closest-side, transparent 52%, ${black(0.6)} 78%, black 100%);
7766
+ opacity: 0.4;
7767
+ animation: aurora-lm-hue 36s linear infinite;
7768
+ }
7769
+
7770
+ /* Reflejos y película de la pompa. */
7771
+ .aurora-lm-soap {
7772
+ left: -4%;
7773
+ top: -3%;
7774
+ right: -2%;
7775
+ bottom: -1%;
7776
+ overflow: hidden;
7777
+ border-radius: ${BUBBLE_SHAPE};
7778
+ -webkit-mask: radial-gradient(closest-side, black 92%, transparent 100%);
7779
+ mask: radial-gradient(closest-side, black 92%, transparent 100%);
7780
+ animation: aurora-lm-jabon 11s ${SOFT_EASE} infinite, aurora-lm-breathe 7.3s ${SOFT_EASE} infinite, aurora-lm-drift 40s linear infinite;
7781
+ }
7782
+ .aurora-lm-soap > span:nth-child(1) {
7783
+ left: 17%;
7784
+ right: 13%;
7785
+ top: 1.2%;
7786
+ height: 34%;
7787
+ border-radius: 50% 50% 40% 46% / 80% 80% 20% 28%;
7788
+ background: radial-gradient(ellipse 120% 150% at 50% 135%, ${mix("deep", 0)} 52%, ${mix("deep", 55)} 60%, ${mix("glow", 80)} 68%, ${mix("spark", 80)} 76%, ${mix("film-2", 85)} 83%, ${mix("warm", 90)} 90%, ${white(0.95)} 97%);
7789
+ mix-blend-mode: screen;
7790
+ opacity: 0.45;
7791
+ filter: blur(${s(0.008)});
7792
+ }
7793
+ .aurora-lm-soap > span:nth-child(2) {
7794
+ left: 18%;
7795
+ width: 46%;
7796
+ bottom: 6%;
7797
+ height: 26%;
7798
+ border-radius: 45% 55% 50% 50% / 55% 45% 55% 45%;
7799
+ background: radial-gradient(ellipse 130% 110% at 50% -10%, ${mix("glow", 0)} 40%, ${mix("glow", 60)} 55%, ${mix("deep", 55)} 70%, ${mix("warm", 65)} 85%, ${white(0.35)} 100%);
7800
+ mix-blend-mode: screen;
7801
+ opacity: 0.38;
7802
+ filter: blur(${s(0.014)});
7803
+ }
7804
+ .aurora-lm-soap > span:nth-child(3) {
7805
+ left: 42%;
7806
+ right: 12%;
7807
+ bottom: 8%;
7808
+ height: 24%;
7809
+ border-radius: 55% 45% 45% 55% / 50% 60% 40% 50%;
7810
+ background: radial-gradient(ellipse 120% 110% at 40% -5%, ${mix("glow", 0)} 38%, ${mix("glow", 70)} 52%, ${mix("warm", 70)} 72%, ${mix("warm", 60)} 88%, ${white(0.3)} 100%);
7811
+ mix-blend-mode: screen;
7812
+ opacity: 0.38;
7813
+ filter: blur(${s(0.014)});
7814
+ }
7815
+ .aurora-lm-soap > span:nth-child(4) {
7816
+ inset: 0;
7817
+ border-radius: inherit;
7818
+ box-shadow: inset ${s(0.015)} ${s(-0.02)} ${s(0.02)} ${mix("core", 18)}, inset ${s(-0.01)} ${s(0.01)} ${s(0.03)} ${white(0.35)};
7819
+ }
7820
+ .aurora-lm-soap > span:nth-child(5) {
7821
+ left: 16%;
7822
+ top: 15%;
7823
+ width: 15%;
7824
+ height: 10%;
7825
+ border-radius: 40%;
7826
+ background: linear-gradient(160deg, ${white(0.95)}, ${white(0.35)});
7827
+ rotate: -35deg;
7828
+ filter: blur(${s(0.004)});
7829
+ }
7830
+ .aurora-lm-soap > span:nth-child(6) {
7831
+ left: 14%;
7832
+ top: 28%;
7833
+ width: 6%;
7834
+ height: 4%;
7835
+ border-radius: 50%;
7836
+ background: ${white(0.9)};
7837
+ rotate: -35deg;
7838
+ filter: blur(${s(0.003)});
7839
+ }
7840
+ .aurora-lm-soap > span:nth-child(7) {
7841
+ right: 14%;
7842
+ top: 12%;
7843
+ width: 5%;
7844
+ height: 5%;
7845
+ border-radius: 50%;
7846
+ background: radial-gradient(closest-side, ${white(1)}, ${white(0)});
7847
+ filter: blur(${s(0.002)});
7848
+ }
7849
+ .aurora-lm-soap > span:nth-child(8) {
7850
+ inset: 1.2%;
7851
+ border-radius: inherit;
7852
+ border: ${s(0.012)} solid transparent;
7853
+ border-left-color: ${white(0.85)};
7854
+ border-bottom-color: ${white(0.55)};
7855
+ rotate: 20deg;
7856
+ filter: blur(${s(0.012)});
7857
+ opacity: 0.8;
7858
+ }
7859
+ .aurora-lm-soap > span:nth-child(9) {
7860
+ inset: 2.5%;
7861
+ border-radius: inherit;
7862
+ border: ${s(0.008)} solid transparent;
7863
+ border-right-color: ${white(0.7)};
7864
+ border-top-color: ${white(0.3)};
7865
+ rotate: -15deg;
7866
+ filter: blur(${s(0.01)});
7867
+ opacity: 0.7;
7868
+ }
7869
+ .aurora-lm-soap > span:nth-child(10) {
7870
+ left: 24%;
7871
+ right: 18%;
7872
+ top: 1.4%;
7873
+ height: 6%;
7874
+ border-radius: 50% 50% 0 0 / 100% 100% 0 0;
7875
+ border-top: ${s(0.01)} solid ${white(0.95)};
7876
+ filter: blur(${s(0.006)});
7877
+ }
7878
+ .aurora-lm-soap > span:nth-child(11) {
7879
+ right: 20%;
7880
+ bottom: 10%;
7881
+ width: 8%;
7882
+ height: 3%;
7883
+ border-radius: 50%;
7884
+ background: ${white(0.85)};
7885
+ rotate: -20deg;
7886
+ filter: blur(${s(0.004)});
7887
+ }
7888
+ .aurora-lm-soap > span:nth-child(12) {
7889
+ left: 34%;
7890
+ right: 26%;
7891
+ bottom: 3.5%;
7892
+ height: 9%;
7893
+ border-radius: 50%;
7894
+ background: radial-gradient(closest-side, ${white(0.9)}, ${mix("mint", 55)} 45%, transparent);
7895
+ filter: blur(${s(0.008)});
7896
+ }
7897
+ .aurora-lm-soap > span:nth-child(13) {
7898
+ inset: 0;
7899
+ border-radius: inherit;
7900
+ background: radial-gradient(circle at 70% 78%, ${mix("core", 12)}, transparent 38%);
7901
+ }
7902
+
7903
+ /* Auriculares de escuchar. */
7904
+ .aurora-lm-headphones {
7905
+ inset: 9% 9% 19% 17%;
7906
+ rotate: -6deg;
7907
+ transform-origin: 50% 55%;
7908
+ }
7909
+ .aurora-lm-headphones-arc {
7910
+ left: 4%;
7911
+ right: 4%;
7912
+ top: -6%;
7913
+ height: 58%;
7914
+ border: ${s(0.03)} solid var(--_lm-core);
7915
+ border-bottom: 0;
7916
+ border-radius: 50% 50% 0 0 / 100% 100% 0 0;
7917
+ filter: drop-shadow(0 ${s(0.01)} ${s(0.015)} ${mix("core", 25)});
7918
+ }
7919
+ .aurora-lm-headphones-cup {
7920
+ top: 32%;
7921
+ width: 20%;
7922
+ height: 36%;
7923
+ border-radius: 50% 50% 46% 46% / 50% 50% 50% 50%;
7924
+ background: radial-gradient(circle at 35% 28%, var(--_lm-teal), color-mix(in srgb, var(--_lm-teal) 45%, var(--_lm-core)) 50%, var(--_lm-core) 100%);
7925
+ box-shadow: inset 0 0 0 ${s(0.018)} var(--_lm-glow), 0 ${s(0.02)} ${s(0.03)} ${mix("core", 30)};
7926
+ }
7927
+ .aurora-lm-headphones-cup--left {
7928
+ left: -5%;
7929
+ rotate: 10deg;
7930
+ }
7931
+ .aurora-lm-headphones-cup--right {
7932
+ right: -5%;
7933
+ rotate: -10deg;
7934
+ }
7935
+
7936
+ /* ── Estados: movimiento, ojos y accesorios ───────────────────────────────── */
7937
+
7938
+ /* Lista (reposo) y hablando: flota sereno y una luz blanca recorre el aro. */
7939
+ .aurora-linda-mascot--ready .aurora-lm-body,
7940
+ .aurora-linda-mascot--talking .aurora-lm-body {
7941
+ animation: aurora-lm-ready 4s ease-in-out infinite;
7942
+ }
7943
+ .aurora-linda-mascot--ready .aurora-lm-rim,
7944
+ .aurora-linda-mascot--talking .aurora-lm-rim {
7945
+ background: conic-gradient(from var(--aurora-lm-a), transparent 0deg 150deg, ${white(0.6)} 270deg, ${white(1)} 320deg, ${white(1)} 355deg, transparent 360deg) border-box, conic-gradient(from var(--aurora-lm-a), var(--_lm-rb)) border-box;
7946
+ animation: aurora-lm-hue 2.6s linear infinite;
7947
+ }
7948
+ .aurora-linda-mascot--ready .aurora-lm-rim-glow,
7949
+ .aurora-linda-mascot--talking .aurora-lm-rim-glow {
7950
+ background: conic-gradient(from var(--aurora-lm-a), transparent 0deg 200deg, ${mix("glow", 90)} 300deg, ${white(1)} 350deg, transparent 360deg) border-box, conic-gradient(from var(--aurora-lm-a), var(--_lm-rb)) border-box;
7951
+ animation: aurora-lm-hue 2.6s linear infinite;
7952
+ }
7953
+ .aurora-linda-mascot--ready .aurora-lm-eye,
7954
+ .aurora-linda-mascot--talking .aurora-lm-eye {
7955
+ scale: 1.15 1;
7956
+ -webkit-mask: radial-gradient(ellipse 66% 74% at 50% 104%, transparent 98%, black 100%);
7957
+ mask: radial-gradient(ellipse 66% 74% at 50% 104%, transparent 98%, black 100%);
7958
+ }
7959
+ .aurora-linda-mascot--talking .aurora-lm-level {
7960
+ scale: calc(1 + ${LEVEL} * 0.07);
7961
+ }
7962
+
7963
+ /* Escuchando: auriculares, asiente y lanza ondas en azul y verde. */
7964
+ .aurora-linda-mascot--listening .aurora-lm-body {
7965
+ animation: aurora-lm-float var(--_lm-breath) ease-in-out infinite, aurora-lm-nod 2.8s ease-in-out infinite;
7966
+ }
7967
+ .aurora-linda-mascot--listening .aurora-lm-level {
7968
+ scale: calc(1 + ${LEVEL} * 0.05);
7969
+ }
7970
+ .aurora-linda-mascot--listening .aurora-lm-rim,
7971
+ .aurora-linda-mascot--listening .aurora-lm-rim-glow {
7972
+ animation: aurora-lm-hue 3.5s linear infinite;
7973
+ }
7974
+ .aurora-linda-mascot--listening .aurora-lm-eyes {
7975
+ transform: translate(-50%, -50%) rotate(-7deg);
7976
+ animation: aurora-lm-nod-eyes 2.8s ease-in-out infinite;
7977
+ }
7978
+ .aurora-linda-mascot--listening .aurora-lm-eye {
7979
+ scale: 1.12 1.22;
7980
+ }
7981
+ .aurora-linda-mascot--listening .aurora-lm-pulse {
7982
+ border-color: var(--_lm-deep);
7983
+ box-shadow: 0 0 ${s(0.03)} ${mix("deep", 45)}, inset 0 0 ${s(0.02)} ${mix("glow", 35)};
7984
+ filter: blur(${s(0.002)});
7985
+ animation: aurora-lm-listen-wave 2.8s cubic-bezier(0.22, 0.61, 0.36, 1) 0.12s infinite;
7986
+ }
7987
+ .aurora-linda-mascot--listening .aurora-lm-pulse--2 {
7988
+ border-color: var(--_lm-spark);
7989
+ box-shadow: 0 0 ${s(0.03)} ${mix("spark", 45)}, inset 0 0 ${s(0.02)} ${mix("mint", 40)};
7990
+ animation-delay: 0.58s;
7991
+ }
7992
+ .aurora-linda-mascot--listening .aurora-lm-bubble {
7993
+ box-shadow: inset ${s(-0.03)} ${s(-0.04)} ${s(0.07)} ${mix("core", 14)}, inset 0 0 ${s(0.06)} ${mix("deep", 35)}, 0 0 ${s(0.06)} ${mix("deep", 35)}, 0 0 ${s(0.14)} ${mix("spark", 20)};
7234
7994
  }
7235
7995
 
7236
- /* ── Estados ─────────────────────────────────────────────────────────────── */
7237
-
7238
- /* idle no añade nada: es el movimiento base de arriba (giro, respiración, parpadeo). */
7239
-
7240
- .aurora-linda-mascot--processing .aurora-lm-orbit {
7241
- animation-play-state: running;
7996
+ /* Pensando: el aro se enfría, mira arriba de un lado a otro y entrecierra los ojos. */
7997
+ .aurora-linda-mascot--thinking .aurora-lm-body {
7998
+ animation: aurora-lm-float var(--_lm-breath) ease-in-out infinite, aurora-lm-tilt 9s ease-in-out infinite;
7242
7999
  }
7243
- .aurora-linda-mascot--processing .aurora-lm-comet {
8000
+ .aurora-linda-mascot--thinking .aurora-lm-orbits {
7244
8001
  opacity: 1;
7245
8002
  }
7246
- .aurora-linda-mascot--processing .aurora-lm-halo {
7247
- animation: aurora-lm-pulse 1.6s ease-in-out infinite;
8003
+ /* Solo aquí giran: invisibles en el resto de estados, no gastan animación. */
8004
+ .aurora-linda-mascot--thinking .aurora-lm-orbit {
8005
+ animation: aurora-lm-spin 1.9s linear infinite;
8006
+ }
8007
+ .aurora-linda-mascot--thinking .aurora-lm-orbit--2 {
8008
+ animation-duration: 2.6s;
8009
+ animation-direction: reverse;
8010
+ }
8011
+ .aurora-linda-mascot--thinking .aurora-lm-orbit--3 {
8012
+ animation-duration: 3.8s;
8013
+ }
8014
+ .aurora-linda-mascot--thinking .aurora-lm-eyes {
8015
+ transform: translate(-50%, -58%);
8016
+ animation: aurora-lm-think 5s ease-in-out infinite;
8017
+ }
8018
+ .aurora-linda-mascot--thinking .aurora-lm-eye {
8019
+ animation: aurora-lm-squint 3.6s ease-in-out infinite;
7248
8020
  }
7249
8021
 
7250
- .aurora-linda-mascot--working .aurora-lm-boost,
7251
- .aurora-linda-mascot--working .aurora-lm-orbit {
7252
- animation-play-state: running;
8022
+ /* Trabajando: gafas, vibra y los ojos recorren de lado a lado. */
8023
+ .aurora-linda-mascot--working .aurora-lm-body {
8024
+ animation: aurora-lm-buzz 0.45s linear infinite;
7253
8025
  }
7254
- .aurora-linda-mascot--working .aurora-lm-glint {
7255
- opacity: 1;
8026
+ .aurora-linda-mascot--working .aurora-lm-core {
8027
+ animation: aurora-lm-squish 1.8s ease-in-out infinite, aurora-lm-flicker 0.9s ease-in-out infinite;
8028
+ }
8029
+ .aurora-linda-mascot--working .aurora-lm-eyes {
8030
+ transform: translate(-50%, -44%);
8031
+ justify-content: space-around;
8032
+ animation: aurora-lm-scan 1.4s ease-in-out infinite;
8033
+ }
8034
+ .aurora-linda-mascot--working .aurora-lm-eye {
8035
+ scale: 0.64 0.52;
7256
8036
  }
7257
8037
 
7258
- .aurora-linda-mascot--listening .aurora-lm-level-rings {
7259
- transform: scale(calc(0.86 + ${LEVEL} * 0.16));
8038
+ /* Alerta: tiembla, ojos redondos de aviso y ondas naranjas. */
8039
+ .aurora-linda-mascot--alert .aurora-lm-body {
8040
+ animation: aurora-lm-float var(--_lm-breath) ease-in-out infinite, aurora-lm-shake 2.6s ease-in-out infinite;
8041
+ }
8042
+ .aurora-linda-mascot--alert .aurora-lm-eyes {
8043
+ transform: translate(-50%, -50%) scale(1.08);
8044
+ }
8045
+ .aurora-linda-mascot--alert .aurora-lm-eye {
8046
+ height: auto;
8047
+ aspect-ratio: 1;
8048
+ border-radius: 50%;
8049
+ box-shadow: 0 0 ${s(0.025)} var(--_lm-light), 0 0 ${s(0.08)} var(--_lm-alert);
8050
+ animation: aurora-lm-alert-pop 1.6s ease-out infinite;
8051
+ }
8052
+ .aurora-linda-mascot--alert .aurora-lm-pulse {
8053
+ border-color: var(--_lm-alert);
8054
+ animation: aurora-lm-ping 1.6s ease-out infinite;
7260
8055
  }
7261
- .aurora-linda-mascot--listening .aurora-lm-level-halo {
7262
- transform: scale(calc(0.92 + ${LEVEL} * 0.2));
8056
+ .aurora-linda-mascot--alert .aurora-lm-pulse--2 {
8057
+ animation-delay: 0.8s;
8058
+ }
8059
+ .aurora-linda-mascot--alert .aurora-lm-bubble {
8060
+ box-shadow: inset ${s(-0.03)} ${s(-0.04)} ${s(0.07)} ${mix("core", 14)}, inset 0 0 ${s(0.06)} ${mix("alert", 35)}, 0 0 ${s(0.06)} ${mix("alert", 35)}, 0 0 ${s(0.14)} ${mix("alert-deep", 20)};
7263
8061
  }
7264
8062
 
7265
- .aurora-linda-mascot--talking .aurora-lm-level-body {
7266
- transform: scale(calc(1 + ${LEVEL} * 0.07));
8063
+ /* Cargando: rebota una vez y en el segundo salto se vuelve 9 puntos que giran. */
8064
+ .aurora-linda-mascot--loading .aurora-lm-body {
8065
+ transform-origin: 50% 90%;
8066
+ animation: aurora-lm-load-body 6s cubic-bezier(0.45, 0, 0.35, 1) infinite;
8067
+ }
8068
+ .aurora-linda-mascot--loading .aurora-lm-shadow {
8069
+ animation: aurora-lm-load-shadow 6s ease-in-out infinite;
8070
+ }
8071
+ .aurora-linda-mascot--loading .aurora-lm-pulse {
8072
+ opacity: 0;
7267
8073
  }
7268
- .aurora-linda-mascot--talking .aurora-lm-level-halo {
7269
- transform: scale(calc(1 + ${LEVEL} * 0.32));
7270
- opacity: calc(0.75 + ${LEVEL} * 0.25);
8074
+ .aurora-linda-mascot--loading .aurora-lm-load {
8075
+ display: grid;
8076
+ animation: aurora-lm-load-grid 6s ease-in-out infinite;
8077
+ }
8078
+ .aurora-linda-mascot--loading .aurora-lm-dot {
8079
+ animation-name: aurora-lm-load-dot;
8080
+ animation-duration: 1.2s;
8081
+ animation-timing-function: ease-in-out;
8082
+ animation-iteration-count: infinite;
8083
+ }
8084
+ .aurora-linda-mascot--loading .aurora-lm-dot--5 {
8085
+ animation: none;
8086
+ opacity: 0.3;
7271
8087
  }
7272
8088
 
7273
- .aurora-linda-mascot--ready .aurora-lm-sparkle {
7274
- animation: aurora-lm-sparkle 700ms cubic-bezier(0.2, 0.8, 0.3, 1) 1 both;
7275
- animation-delay: var(--lm-sparkle-delay, 0ms);
8089
+ /* ── Talla avatar: fuera lo que a 20 px es ruido ─────────────────────────── */
8090
+
8091
+ .aurora-linda-mascot--tier-xs::after,
8092
+ .aurora-linda-mascot--tier-xs .aurora-lm-shadow {
8093
+ display: none;
7276
8094
  }
7277
8095
 
7278
8096
  /* ── Keyframes ───────────────────────────────────────────────────────────── */
7279
8097
 
8098
+ @keyframes aurora-lm-hue {
8099
+ to { --aurora-lm-a: 360deg; }
8100
+ }
7280
8101
  @keyframes aurora-lm-spin {
7281
- to {
7282
- transform: rotate(360deg);
7283
- }
8102
+ to { transform: rotate(360deg); }
7284
8103
  }
7285
- @keyframes aurora-lm-breathe {
7286
- from {
7287
- transform: scale(1);
7288
- }
7289
- to {
7290
- transform: scale(1.03);
7291
- }
8104
+ @keyframes aurora-lm-float {
8105
+ 0%, 100% { transform: translateY(0); }
8106
+ 50% { transform: translateY(${s(-0.025)}); }
7292
8107
  }
7293
- @keyframes aurora-lm-blink {
7294
- 0%, 42%, 45%, 97.5%, 100% {
7295
- transform: scaleY(1);
7296
- }
7297
- 43.5%, 98.8% {
7298
- transform: scaleY(0.12);
7299
- }
8108
+ @keyframes aurora-lm-squish {
8109
+ 0%, 100% { transform: scale(1, 1); }
8110
+ 50% { transform: scale(1.035, 0.965) translateY(1.5%); }
7300
8111
  }
7301
- @keyframes aurora-lm-pulse {
7302
- 0%, 100% {
7303
- transform: scale(1);
7304
- opacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));
7305
- }
7306
- 50% {
7307
- transform: scale(1.12);
7308
- opacity: 1;
7309
- }
7310
- }
7311
- @keyframes aurora-lm-glow {
7312
- 0%, 100% {
7313
- opacity: calc(var(--lm-halo) * var(--lm-halo-boost, 1));
7314
- }
7315
- 50% {
7316
- opacity: 1;
7317
- }
8112
+ @keyframes aurora-lm-shadow {
8113
+ 0%, 100% { transform: scale(1); opacity: 1; }
8114
+ 50% { transform: scale(0.86); opacity: 0.7; }
7318
8115
  }
7319
- @keyframes aurora-lm-sparkle {
7320
- 0% {
7321
- opacity: 0;
7322
- transform: scale(0.2) rotate(0deg);
7323
- }
7324
- 35% {
7325
- opacity: 1;
7326
- transform: scale(1) rotate(45deg);
7327
- }
7328
- 100% {
7329
- opacity: 0;
7330
- transform: scale(0.5) rotate(90deg);
7331
- }
8116
+ @keyframes aurora-lm-blink {
8117
+ 0%, 93%, 100% { transform: scaleY(1); }
8118
+ 96% { transform: scaleY(0.08); }
8119
+ }
8120
+ @keyframes aurora-lm-ping {
8121
+ 0% { transform: scale(0.92); opacity: 0.85; }
8122
+ 100% { transform: scale(1.55); opacity: 0; }
8123
+ }
8124
+ @keyframes aurora-lm-flicker {
8125
+ 0%, 100% { opacity: 1; }
8126
+ 50% { opacity: 0.72; }
8127
+ }
8128
+ @keyframes aurora-lm-tilt {
8129
+ 0%, 100% { rotate: -9deg; }
8130
+ 50% { rotate: 9deg; }
8131
+ }
8132
+ @keyframes aurora-lm-think {
8133
+ 0%, 100% { translate: -16% -10%; }
8134
+ 40% { translate: 16% -20%; }
8135
+ 70% { translate: 0 -6%; }
8136
+ }
8137
+ @keyframes aurora-lm-scan {
8138
+ 0%, 100% { translate: -18% 0; }
8139
+ 50% { translate: 18% 0; }
8140
+ }
8141
+ @keyframes aurora-lm-buzz {
8142
+ 0%, 100% { translate: 0 0; }
8143
+ 25% { translate: 0 ${s(-0.025)}; }
8144
+ 75% { translate: 0 ${s(0.015)}; }
8145
+ }
8146
+ @keyframes aurora-lm-shake {
8147
+ 0%, 65%, 100% { rotate: 0deg; }
8148
+ 70% { rotate: -12deg; }
8149
+ 76% { rotate: 12deg; }
8150
+ 82% { rotate: -8deg; }
8151
+ 88% { rotate: 5deg; }
8152
+ 94% { rotate: -2deg; }
8153
+ }
8154
+ @keyframes aurora-lm-ready {
8155
+ 0%, 100% { translate: 0 0; }
8156
+ 50% { translate: 0 ${s(-0.018)}; }
8157
+ }
8158
+ @keyframes aurora-lm-squint {
8159
+ 0%, 22%, 100% { scale: 1 1; }
8160
+ 34%, 70% { scale: 1.06 0.38; }
8161
+ 82% { scale: 1 1.06; }
8162
+ }
8163
+ @keyframes aurora-lm-alert-pop {
8164
+ 0%, 100% { scale: 1.22 1.22; }
8165
+ 12% { scale: 1.38 1.38; }
8166
+ 24% { scale: 1.22 1.22; }
8167
+ }
8168
+ @keyframes aurora-lm-listen-wave {
8169
+ 0% { scale: 0.97; opacity: 0; border-width: ${s(0.014)}; }
8170
+ 18% { opacity: 0.75; }
8171
+ 100% { scale: 1.42; opacity: 0; border-width: ${s(0.002)}; }
8172
+ }
8173
+ @keyframes aurora-lm-nod {
8174
+ 0%, 55%, 100% { translate: 0 0; rotate: 0deg; }
8175
+ 8% { translate: 0 ${s(0.06)}; rotate: 3deg; }
8176
+ 16% { translate: 0 ${s(-0.018)}; rotate: 0deg; }
8177
+ 24% { translate: 0 ${s(0.06)}; rotate: 3deg; }
8178
+ 32% { translate: 0 0; rotate: 0deg; }
8179
+ }
8180
+ @keyframes aurora-lm-nod-eyes {
8181
+ 0%, 55%, 100% { translate: 0 0; }
8182
+ 8% { translate: 0 26%; }
8183
+ 16% { translate: 0 -8%; }
8184
+ 24% { translate: 0 26%; }
8185
+ 32% { translate: 0 0; }
8186
+ }
8187
+ @keyframes aurora-lm-jabon {
8188
+ 0%, 100% { border-radius: 62% 38% 56% 44% / 44% 60% 40% 56%; }
8189
+ 17% { border-radius: 52% 48% 64% 36% / 38% 54% 46% 62%; }
8190
+ 33% { border-radius: 40% 60% 50% 50% / 56% 44% 60% 40%; }
8191
+ 50% { border-radius: 46% 54% 38% 62% / 62% 50% 50% 38%; }
8192
+ 67% { border-radius: 58% 42% 44% 56% / 50% 62% 38% 50%; }
8193
+ 83% { border-radius: 66% 34% 52% 48% / 42% 48% 52% 58%; }
7332
8194
  }
7333
- @keyframes aurora-lm-sparkle-fade {
7334
- 0%, 100% {
7335
- opacity: 0;
7336
- }
7337
- 35% {
7338
- opacity: 1;
7339
- }
8195
+ @keyframes aurora-lm-breathe {
8196
+ 0%, 100% { scale: 1.05 0.96; }
8197
+ 25% { scale: 0.98 1.03; }
8198
+ 50% { scale: 0.95 1.06; }
8199
+ 75% { scale: 1.03 0.98; }
8200
+ }
8201
+ @keyframes aurora-lm-drift {
8202
+ from { rotate: 0deg; }
8203
+ to { rotate: 360deg; }
8204
+ }
8205
+ @keyframes aurora-lm-load-body {
8206
+ 0%, 100% { translate: 0 0; scale: 1 1; opacity: 1; filter: blur(0); }
8207
+ 5% { translate: 0 ${s(0.04)}; scale: 1.1 0.86; opacity: 1; }
8208
+ 13% { translate: 0 ${s(-0.22)}; scale: 0.94 1.06; opacity: 1; }
8209
+ 20% { translate: 0 ${s(0.03)}; scale: 1.08 0.9; opacity: 1; }
8210
+ 24% { translate: 0 0; scale: 1 1; opacity: 1; }
8211
+ 28% { translate: 0 ${s(0.04)}; scale: 1.1 0.86; opacity: 1; }
8212
+ 37% { translate: 0 ${s(-0.3)}; scale: 0.92 1.08; opacity: 1; }
8213
+ 44% { translate: 0 ${s(-0.05)}; scale: 0.25 0.25; opacity: 0; }
8214
+ 80% { translate: 0 ${s(-0.28)}; scale: 0.45 0.45; opacity: 0; filter: blur(${s(0.02)}); }
8215
+ 86% { translate: 0 ${s(-0.14)}; scale: 0.92 1.06; opacity: 1; filter: blur(0); }
8216
+ 90% { translate: 0 ${s(0.04)}; scale: 1.14 0.84; opacity: 1; }
8217
+ 94% { translate: 0 ${s(-0.09)}; scale: 0.95 1.06; opacity: 1; }
8218
+ 97% { translate: 0 ${s(0.015)}; scale: 1.05 0.95; opacity: 1; }
8219
+ }
8220
+ @keyframes aurora-lm-load-shadow {
8221
+ 0%, 24%, 100% { opacity: 1; scale: 1; }
8222
+ 13% { opacity: 0.5; scale: 0.7; }
8223
+ 37% { opacity: 0.4; scale: 0.6; }
8224
+ 44%, 84% { opacity: 0.5; scale: 0.5; }
8225
+ }
8226
+ @keyframes aurora-lm-load-grid {
8227
+ 0%, 41% { opacity: 0; scale: 0.3; rotate: -30deg; }
8228
+ 49% { opacity: 1; scale: 1.08; rotate: 0deg; }
8229
+ 54%, 76% { opacity: 1; scale: 1; rotate: 0deg; filter: blur(0); }
8230
+ 90%, 100% { opacity: 0; scale: 0.55; rotate: 12deg; filter: blur(${s(0.02)}); }
8231
+ }
8232
+ @keyframes aurora-lm-load-dot {
8233
+ 0%, 100% { opacity: 0.35; scale: 0.8; }
8234
+ 12%, 30% { opacity: 1; scale: 1.08; }
8235
+ 48% { opacity: 0.35; scale: 0.8; }
7340
8236
  }
7341
8237
 
7342
8238
  /*
7343
- * Movimiento reducido: nada gira, parpadea, respira ni crece. El estado se sigue leyendo
7344
- * sin movimiento: al pensar o trabajar el cometa o el destello se quedan quietos sobre el
7345
- * anillo (así se distingue también en \`xs\`, que no tiene halo) y el halo late en opacidad
7346
- * o se enciende; con la voz sube la opacidad del halo y de los anillos; las chispas
7347
- * aparecen y se desvanecen sin moverse.
7348
- *
7349
- * Las mismas reglas se aplican con la preferencia del sistema y con \`motion="reduce"\`
7350
- * (\`data-motion\`), que el consumidor usa para listas largas o para forzarlo. \`!important\`
7351
- * porque las reglas por estado de arriba tienen más especificidad y \`@media\` no la sube.
8239
+ * Movimiento reducido: nada se mueve. Cada estado se sigue leyendo por sus colores, sus
8240
+ * ojos y sus accesorios (gafas, auriculares, órbitas); cargando se queda en la cuadrícula.
8241
+ * Las mismas reglas con la preferencia del sistema y con \`motion="reduce"\`.
7352
8242
  */
7353
- ${reducedMotionRules(".aurora-linda-mascot")}
8243
+ @media (prefers-reduced-motion: reduce) {${reducedMotion(ROOT)}}
8244
+ ${reducedMotion(`${ROOT}[data-motion="reduce"]`)}
7354
8245
  `;
7355
8246
 
7356
- const CX = 60;
7357
8247
  const STYLE_ID = styleIdFor(LINDA_MASCOT_STYLE_ID, LINDA_MASCOT_CSS);
7358
- /** Velocidad de giro por anillo (s por vuelta) y sentido. */
7359
- const RING_MOTION = [
7360
- { duration: "24s", direction: "normal" },
7361
- { duration: "30s", direction: "reverse" },
7362
- { duration: "36s", direction: "normal" },
7363
- ];
7364
- /** Chispas de `ready`: posición en el viewBox, tamaño y retardo. */
7365
- const SPARKLES = [
7366
- { x: 90, y: 17, s: 9, delay: "0ms" },
7367
- { x: 104, y: 35, s: 5.5, delay: "90ms" },
7368
- { x: 73, y: 7, s: 4.5, delay: "170ms" },
7369
- ];
7370
- const sparklePath = (s) => {
7371
- const k = s * 0.18;
7372
- 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`;
7373
- };
8248
+ /** Los 9 puntos de cargando, en el orden de la cuadrícula (fila a fila). */
8249
+ const LOAD_DOTS = [1, 2, 3, 4, 5, 6, 7, 8, 9];
8250
+ /** Las 13 capas de reflejos de la pompa; cada una se dibuja por su posición. */
8251
+ const SOAP_LAYERS = Array.from({ length: 13 }, (_, index) => index + 1);
7374
8252
  /**
7375
- * Perímetro en px de pantalla de la elipse de un anillo. Con `non-scaling-stroke` los
7376
- * guiones se miden en px de pantalla (no en unidades del viewBox ni en `pathLength`), así
7377
- * que el cometa se dimensiona como fracción de este perímetro para medir lo mismo a
7378
- * cualquier talla.
8253
+ * Las gafas de trabajar: dos ojos de gato y un puente, en la caja de 200 × 90 del lienzo.
8254
+ * Van en línea, dibujadas aquí, para no depender de ningún recurso externo.
7379
8255
  */
7380
- const ringPerimeterPx = (ring, px) => {
7381
- const a = (ring.r * px) / 120;
7382
- const b = a * ring.squash;
7383
- const h = ((a - b) / (a + b)) ** 2;
7384
- return Math.PI * (a + b) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)));
7385
- };
8256
+ const Glasses = () => (jsxRuntime.jsx("svg", { className: "aurora-lm-glasses", "data-part": "glasses", viewBox: "0 0 200 90", "aria-hidden": "true", focusable: "false", children: jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("ellipse", { cx: "51", cy: "45", rx: "38", ry: "34" }), jsxRuntime.jsx("ellipse", { cx: "149", cy: "45", rx: "38", ry: "34" }), jsxRuntime.jsx("path", { d: "M89 40 Q 100 32 111 40" })] }) }));
7386
8257
  /**
7387
- * Cometa con estela sobre un anillo: cola de `steps` tramos consecutivos con el
7388
- * iridiscente del anillo, cada uno más opaco y más grueso que el anterior, y una cabeza
7389
- * redonda y brillante al final. Todo es `stroke-dasharray` sobre el mismo círculo que el
7390
- * anillo, así que gira con `transform` y se recorta delante/detrás igual que él. El giro
7391
- * es horario: la cabeza va al final del trazo, por delante de su cola.
7392
- */
7393
- const Comet = ({ className, r, perimeter, tail, strokePx, headPx, steps, ringPaint, headPaint, }) => {
7394
- const tailPx = perimeter * tail;
7395
- const seg = tailPx / steps;
7396
- return (jsxRuntime.jsxs("g", { className: className, "data-part": "comet", children: [Array.from({ length: steps }, (_, i) => {
7397
- const t = (i + 1) / steps;
7398
- return (jsxRuntime.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));
7399
- }), jsxRuntime.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" }), jsxRuntime.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" })] }));
7400
- };
7401
- /** Arco «∩» de un ojo centrado en (x, y): ancho w, alto h. */
7402
- const eyePath = (x, y, w, h) => {
7403
- const half = w / 2;
7404
- const base = y + h / 2;
7405
- const control = y - h * 0.8333;
7406
- return `M${x - half} ${base}C${x - half} ${control} ${x + half} ${control} ${x + half} ${base}`;
7407
- };
7408
- /**
7409
- * `useId` devuelve `:r0:` (React 18), `«r0»` o `_r_0_` (19): fuera lo que no vale en un
7410
- * id referenciado desde `url(#…)`.
7411
- */
7412
- const safeId = (raw) => `lm${raw.replace(/[^a-zA-Z0-9_-]/g, "")}`;
7413
- /**
7414
- * LindaMascot — la cara de Linda: un orbe de tinta con ojos luminosos y anillos
7415
- * iridiscentes, en SVG + CSS (sin imágenes, fuentes ni WebGL).
8258
+ * LindaMascot — el personaje del agente: un núcleo oscuro con dos ojos de luz, un aro
8259
+ * iridiscente y una pompa de jabón alrededor, en HTML + CSS (sin imágenes ni fuentes).
7416
8260
  *
7417
- * Se anima según lo que Linda está haciendo (`state`) y, en la llamada de voz, según el
7418
- * volumen (`level`), sin preguntar nada al modelo. Pinta más o menos detalle según la
7419
- * talla para leerse igual a 16 px que a 200 px. Ver README.
8261
+ * Sus colores son dato: los lee de las variables `--lm-*` que escribe
8262
+ * `applyCharacterPalette` (o de la prop `palette`) y, sin ellas, se pinta como Linda.
8263
+ * Se anima según lo que está haciendo (`state`) y, en la llamada de voz, según el volumen
8264
+ * (`level`). Ver README.
7420
8265
  */
7421
- const LindaMascot = $8WNJc$react.forwardRef(function LindaMascot({ state = "idle", size = "md", level, label, appearance = "auto", motion = "auto", className, style, ...svgProps }, ref) {
8266
+ const LindaMascot = $8WNJc$react.forwardRef(function LindaMascot({ state, size = "md", level, label, appearance = "auto", motion = "auto", palette, className, style, ...spanProps }, ref) {
7422
8267
  useInjectedStyle(STYLE_ID, LINDA_MASCOT_CSS);
7423
- const uid = safeId($8WNJc$react.useId());
8268
+ const visualState = resolveMascotState(state);
7424
8269
  const px = resolveMascotPx(size);
7425
8270
  const tier = resolveMascotTier(px);
7426
- const g = LINDA_MASCOT_GEOMETRY[tier];
7427
- const coreRy = g.coreRx * 0.92;
7428
- const eyeY = g.coreCy - coreRy + coreRy * 2 * 0.45;
7429
- const eyes = [CX - g.eyeGap / 2, CX + g.eyeGap / 2];
7430
- // Recorte delante/detrás: en lg los velos desenfocados salen más allá del anillo.
7431
- const clipHalf = g.ringGlow === "blur" ? 120 : 80;
7432
- const id = {
7433
- core: `${uid}-core`,
7434
- coreClip: `${uid}-core-clip`,
7435
- rim: `${uid}-rim`,
7436
- ring: `${uid}-ring`,
7437
- halo: `${uid}-halo`,
7438
- shadow: `${uid}-shadow`,
7439
- specular: `${uid}-specular`,
7440
- back: `${uid}-back`,
7441
- front: `${uid}-front`,
7442
- soft: `${uid}-soft`,
7443
- eyeGlow: `${uid}-eye-glow`,
7444
- aura: `${uid}-aura`,
7445
- veil: `${uid}-veil`,
7446
- tail: `${uid}-tail`,
7447
- };
8271
+ const paletteVars = $8WNJc$react.useMemo(() => (palette ? characterPaletteToCssVars(palette) : undefined), [palette]);
7448
8272
  const a11y = label
7449
8273
  ? { role: "img", "aria-label": label }
7450
8274
  : { "aria-hidden": true };
7451
- const renderRing = (ring, index, half) => {
7452
- const motion = RING_MOTION[index];
7453
- const spinStyle = {
7454
- "--lm-spin-duration": motion.duration,
7455
- "--lm-spin-direction": motion.direction,
7456
- };
7457
- const isMain = index === 0;
7458
- const perimeter = ringPerimeterPx(ring, px);
7459
- return (jsxRuntime.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: jsxRuntime.jsx("g", { clipPath: `url(#${half === "back" ? id.back : id.front})`, children: jsxRuntime.jsxs("g", { transform: `scale(1 ${ring.squash})`, children: [jsxRuntime.jsx("g", { className: "aurora-lm-spin", style: spinStyle, children: jsxRuntime.jsxs("g", { className: "aurora-lm-spin aurora-lm-boost", style: spinStyle, children: [g.ringGlow === "blur" && (jsxRuntime.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" && (jsxRuntime.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" && (jsxRuntime.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" })), jsxRuntime.jsx("circle", { r: ring.r, fill: "none", stroke: `url(#${id.ring})`, strokeWidth: ring.strokePx, vectorEffect: "non-scaling-stroke" })] }) }), isMain && (jsxRuntime.jsxs("g", { className: "aurora-lm-spin aurora-lm-orbit", style: {
7460
- "--lm-spin-duration": "1.6s",
7461
- }, children: [jsxRuntime.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 }), jsxRuntime.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}`));
7462
- };
7463
- const ringHalves = (half) => g.rings.map((ring, index) => renderRing(ring, index, half));
7464
- return (
7465
- // 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`.
7466
- jsxRuntime.jsxs("svg", { ref: ref, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 120 120", width: px, height: px, focusable: "false", className: [
8275
+ return (jsxRuntime.jsxs("span", { ref: ref, className: [
7467
8276
  "aurora-linda-mascot",
7468
- `aurora-linda-mascot--${state}`,
8277
+ `aurora-linda-mascot--${visualState}`,
7469
8278
  `aurora-linda-mascot--tier-${tier}`,
7470
8279
  className,
7471
8280
  ]
7472
8281
  .filter(Boolean)
7473
- .join(" "), "data-state": state, "data-tier": tier, "data-appearance": appearance, "data-motion": motion, style: {
8282
+ .join(" "), "data-state": visualState, "data-tier": tier, "data-appearance": appearance, "data-motion": motion, style: {
8283
+ ...paletteVars,
7474
8284
  ...style,
8285
+ "--_lm-size": `${px}px`,
7475
8286
  [LINDA_MASCOT_LEVEL_VAR]: clampLevel(level),
7476
- }, ...a11y, ...svgProps, children: [jsxRuntime.jsxs("defs", { children: [jsxRuntime.jsxs("radialGradient", { id: id.core, cx: "0.4", cy: "0.34", r: "0.72", children: [jsxRuntime.jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.coreLight }), jsxRuntime.jsx("stop", { offset: "0.6", stopColor: "#15172B" }), jsxRuntime.jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.coreDark })] }), jsxRuntime.jsxs("linearGradient", { id: id.ring, x1: "0", y1: "0", x2: "1", y2: "1", children: [jsxRuntime.jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.pink }), jsxRuntime.jsx("stop", { offset: "0.36", stopColor: LINDA_MASCOT_PALETTE.violet }), jsxRuntime.jsx("stop", { offset: "0.68", stopColor: LINDA_MASCOT_PALETTE.cyan }), jsxRuntime.jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.amber })] }), jsxRuntime.jsxs("linearGradient", { id: id.tail, x1: "0", y1: "0", x2: "1", y2: "1", children: [jsxRuntime.jsx("stop", { offset: "0", stopColor: "#FFC4EC" }), jsxRuntime.jsx("stop", { offset: "0.36", stopColor: "#D4C8FF" }), jsxRuntime.jsx("stop", { offset: "0.68", stopColor: "#B8F1FF" }), jsxRuntime.jsx("stop", { offset: "1", stopColor: "#FFE6BF" })] }), jsxRuntime.jsxs("linearGradient", { id: id.rim, x1: "0.2", y1: "0", x2: "0.5", y2: "1", children: [jsxRuntime.jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.violet }), jsxRuntime.jsx("stop", { offset: "0.42", stopColor: LINDA_MASCOT_PALETTE.cyan }), jsxRuntime.jsx("stop", { offset: "0.74", stopColor: LINDA_MASCOT_PALETTE.pink }), jsxRuntime.jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.amber })] }), jsxRuntime.jsx("clipPath", { id: id.coreClip, children: jsxRuntime.jsx("ellipse", { cx: CX, cy: g.coreCy, rx: g.coreRx, ry: coreRy }) }), jsxRuntime.jsx("clipPath", { id: id.back, children: jsxRuntime.jsx("rect", { x: -clipHalf, y: -clipHalf, width: clipHalf * 2, height: clipHalf }) }), jsxRuntime.jsx("clipPath", { id: id.front, children: jsxRuntime.jsx("rect", { x: -clipHalf, y: 0, width: clipHalf * 2, height: clipHalf }) }), g.halo && (jsxRuntime.jsxs("radialGradient", { id: id.halo, children: [jsxRuntime.jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.violet, stopOpacity: "0.7" }), jsxRuntime.jsx("stop", { offset: tier === "lg" ? "0.48" : "0.42", stopColor: LINDA_MASCOT_PALETTE.pink, stopOpacity: tier === "lg" ? "0.36" : "0.28" }), jsxRuntime.jsx("stop", { offset: tier === "lg" ? "0.78" : "0.7", stopColor: LINDA_MASCOT_PALETTE.cyan, stopOpacity: tier === "lg" ? "0.14" : "0.08" }), jsxRuntime.jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.cyan, stopOpacity: "0" })] })), g.halo && (jsxRuntime.jsxs("radialGradient", { id: id.shadow, children: [jsxRuntime.jsx("stop", { offset: "0", stopColor: LINDA_MASCOT_PALETTE.coreDark, stopOpacity: "0.28" }), jsxRuntime.jsx("stop", { offset: "1", stopColor: LINDA_MASCOT_PALETTE.coreDark, stopOpacity: "0" })] })), g.specular && (jsxRuntime.jsxs("radialGradient", { id: id.specular, children: [jsxRuntime.jsx("stop", { offset: "0", stopColor: "#FFFFFF", stopOpacity: "0.2" }), jsxRuntime.jsx("stop", { offset: "1", stopColor: "#FFFFFF", stopOpacity: "0" })] })), g.blur && (jsxRuntime.jsx("filter", { id: id.eyeGlow, filterUnits: "userSpaceOnUse", x: "-20", y: "-20", width: "160", height: "160", children: jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "2.2" }) })), g.blur && (jsxRuntime.jsx("filter", { id: id.aura, filterUnits: "userSpaceOnUse", x: "-20", y: "-20", width: "160", height: "160", children: jsxRuntime.jsx("feGaussianBlur", { stdDeviation: tier === "lg" ? 5.5 : 4 }) })), g.ringGlow === "blur" && (jsxRuntime.jsx("filter", { id: id.soft, filterUnits: "userSpaceOnUse", x: "-90", y: "-90", width: "180", height: "180", children: jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "2.6" }) })), g.ringGlow === "blur" && (jsxRuntime.jsx("filter", { id: id.veil, filterUnits: "userSpaceOnUse", x: "-100", y: "-100", width: "200", height: "200", children: jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "5" }) }))] }), jsxRuntime.jsx("g", { className: "aurora-lm-level-body", children: jsxRuntime.jsxs("g", { className: "aurora-lm-breathe", children: [g.halo && (jsxRuntime.jsx("g", { className: "aurora-lm-level-halo", children: jsxRuntime.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 && (jsxRuntime.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})` })), jsxRuntime.jsx("g", { className: "aurora-lm-rings aurora-lm-level-rings", children: ringHalves("back") }), tier !== "xs" && (jsxRuntime.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 })), jsxRuntime.jsxs("g", { "data-part": "core", children: [jsxRuntime.jsx("ellipse", { cx: CX, cy: g.coreCy, rx: g.coreRx, ry: coreRy, fill: `url(#${id.core})` }), jsxRuntime.jsx("g", { clipPath: `url(#${id.coreClip})`, children: jsxRuntime.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 && (jsxRuntime.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})` }))] }), jsxRuntime.jsxs("g", { className: "aurora-lm-eyes", "data-part": "eyes", children: [eyes.map((x) => (jsxRuntime.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) => (jsxRuntime.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}`)))] }), jsxRuntime.jsx("g", { className: "aurora-lm-rings aurora-lm-level-rings", children: ringHalves("front") }), state === "ready" && tier !== "xs" && (jsxRuntime.jsx("g", { "data-part": "sparkles", children: SPARKLES.map((s) => (jsxRuntime.jsx("g", { transform: `translate(${s.x} ${s.y})`, children: jsxRuntime.jsx("path", { className: "aurora-lm-sparkle", d: sparklePath(s.s), style: {
7477
- "--lm-sparkle-delay": s.delay,
7478
- } }) }, `${s.x}-${s.y}`))) }))] }) })] }));
8287
+ }, ...a11y, ...spanProps, children: [jsxRuntime.jsx("span", { className: "aurora-lm-pulse", "data-part": "pulse" }), jsxRuntime.jsx("span", { className: "aurora-lm-pulse aurora-lm-pulse--2", "data-part": "pulse" }), tier !== "xs" && (jsxRuntime.jsx("span", { className: "aurora-lm-shadow", "data-part": "shadow" })), jsxRuntime.jsx("span", { className: "aurora-lm-load", "data-part": "load", children: LOAD_DOTS.map((dot) => (jsxRuntime.jsx("span", { className: `aurora-lm-dot aurora-lm-dot--${dot}`, "data-part": "load-dot" }, dot))) }), jsxRuntime.jsx("span", { className: "aurora-lm-level", "data-part": "level", children: jsxRuntime.jsxs("span", { className: "aurora-lm-body", "data-part": "body", children: [jsxRuntime.jsx("span", { className: "aurora-lm-rimglow", children: jsxRuntime.jsx("span", { className: "aurora-lm-rim-glow", "data-part": "rim-glow" }) }), jsxRuntime.jsx("span", { className: "aurora-lm-core", "data-part": "core" }), jsxRuntime.jsx("span", { className: "aurora-lm-rim", "data-part": "rim" }), jsxRuntime.jsx("span", { className: "aurora-lm-rimline", "data-part": "rimline" }), jsxRuntime.jsxs("span", { className: "aurora-lm-orbits", "data-part": "orbits", children: [jsxRuntime.jsx("span", { className: "aurora-lm-orbit", "data-part": "orbit" }), jsxRuntime.jsx("span", { className: "aurora-lm-orbit aurora-lm-orbit--2", "data-part": "orbit" }), jsxRuntime.jsx("span", { className: "aurora-lm-orbit aurora-lm-orbit--3", "data-part": "orbit" })] }), jsxRuntime.jsxs("span", { className: "aurora-lm-eyes", "data-part": "eyes", children: [jsxRuntime.jsx("span", { className: "aurora-lm-eye", "data-part": "eye" }), jsxRuntime.jsx("span", { className: "aurora-lm-eye", "data-part": "eye" }), visualState === "working" && jsxRuntime.jsx(Glasses, {})] }), jsxRuntime.jsx("span", { className: "aurora-lm-bubble", "data-part": "bubble" }), jsxRuntime.jsx("span", { className: "aurora-lm-soap", "data-part": "soap", children: SOAP_LAYERS.map((layer) => (jsxRuntime.jsx("span", {}, layer))) }), visualState === "listening" && tier !== "xs" && (jsxRuntime.jsxs("span", { className: "aurora-lm-headphones", "data-part": "headphones", children: [jsxRuntime.jsx("span", { className: "aurora-lm-headphones-arc" }), jsxRuntime.jsx("span", { className: "aurora-lm-headphones-cup aurora-lm-headphones-cup--left" }), jsxRuntime.jsx("span", { className: "aurora-lm-headphones-cup aurora-lm-headphones-cup--right" })] }))] }) })] }));
7479
8288
  });
7480
8289
 
8290
+ /**
8291
+ * El tema del personaje que ve una agencia que no ha elegido ninguno: el que corresponde a
8292
+ * su tema de color de la plataforma. `blue` es el de Bewe y se pinta como Linda; los
8293
+ * otros seis tienen un tema del personaje con el mismo color. Luna no aparece: es un tema
8294
+ * propio de Gurú, no uno de plataforma.
8295
+ */
8296
+ const PLATFORM_THEME_TO_CHARACTER_THEME = {
8297
+ blue: "linda",
8298
+ purple: "purple",
8299
+ coral: "coral",
8300
+ green: "green",
8301
+ oceanMint: "ocean",
8302
+ skyBlue: "sky",
8303
+ yellow: "yellow",
8304
+ };
8305
+ /**
8306
+ * El tema del personaje para un tema de plataforma.
8307
+ *
8308
+ * Acepta el color solo (`purple`) y el nombre con modo que usa el tema de aurora
8309
+ * (`purple-dark`). Todo lo demás —vacío, un hex a medida, `light`/`dark` sueltos (el azul
8310
+ * de siempre) o un nombre desconocido— cae a Linda.
8311
+ */
8312
+ const characterThemeForPlatformTheme = (value) => {
8313
+ if (typeof value !== "string") {
8314
+ return DEFAULT_CHARACTER_THEME_ID;
8315
+ }
8316
+ const color = value.trim().replace(/-(light|dark)$/, "");
8317
+ return Object.prototype.hasOwnProperty.call(PLATFORM_THEME_TO_CHARACTER_THEME, color)
8318
+ ? PLATFORM_THEME_TO_CHARACTER_THEME[color]
8319
+ : DEFAULT_CHARACTER_THEME_ID;
8320
+ };
8321
+
7481
8322
  const defaultTranslations$8 = {
7482
8323
  previewAlt: "Vista previa de imagen",
7483
8324
  removeButtonAriaLabel: "Eliminar imagen",
@@ -19856,6 +20697,11 @@ exports.BetaBadge = BetaBadge;
19856
20697
  exports.BreadcrumbItem = BreadcrumbItem;
19857
20698
  exports.BreadcrumbsComponent = BreadcrumbsComponent;
19858
20699
  exports.Button = Button;
20700
+ exports.CHARACTER_CSS_VARS = CHARACTER_CSS_VARS;
20701
+ exports.CHARACTER_FIXED_COLORS = CHARACTER_FIXED_COLORS;
20702
+ exports.CHARACTER_THEMES = CHARACTER_THEMES;
20703
+ exports.CHARACTER_THEME_COLOR_KEYS = CHARACTER_THEME_COLOR_KEYS;
20704
+ exports.CHARACTER_THEME_IDS = CHARACTER_THEME_IDS;
19859
20705
  exports.CONTAINER_ATTRIBUTE = CONTAINER_ATTRIBUTE;
19860
20706
  exports.Card = Card;
19861
20707
  exports.CardBody = CardBody;
@@ -19865,6 +20711,8 @@ exports.ColorPicker = ColorPicker;
19865
20711
  exports.ColorSelector = ColorSelector;
19866
20712
  exports.ContentCarousel = ContentCarousel;
19867
20713
  exports.Currency = Currency;
20714
+ exports.DEFAULT_CHARACTER_PALETTE = DEFAULT_CHARACTER_PALETTE;
20715
+ exports.DEFAULT_CHARACTER_THEME_ID = DEFAULT_CHARACTER_THEME_ID;
19868
20716
  exports.DEFAULT_DONUT_COLORS = DEFAULT_DONUT_COLORS;
19869
20717
  exports.DEFAULT_PREDEFINED_COLORS = DEFAULT_PREDEFINED_COLORS;
19870
20718
  exports.DEFAULT_RANKED_BAR_COLORS = DEFAULT_RANKED_BAR_COLORS;
@@ -19900,6 +20748,7 @@ exports.KanbanCard = KanbanCard;
19900
20748
  exports.KanbanColumn = KanbanColumn;
19901
20749
  exports.LINDA_MASCOT_LEVEL_VAR = LINDA_MASCOT_LEVEL_VAR;
19902
20750
  exports.LINDA_MASCOT_STATES = LINDA_MASCOT_STATES;
20751
+ exports.LINDA_MASCOT_STATE_ALIASES = LINDA_MASCOT_STATE_ALIASES;
19903
20752
  exports.LINDA_TONE_PROPERTIES = LINDA_TONE_PROPERTIES;
19904
20753
  exports.LindaIcon = LindaIcon;
19905
20754
  exports.LindaMascot = LindaMascot;
@@ -19915,6 +20764,7 @@ exports.NavigationLoadingContext = NavigationLoadingContext;
19915
20764
  exports.NavigationLoadingOverlay = NavigationLoadingOverlay;
19916
20765
  exports.NavigationLoadingProvider = NavigationLoadingProvider;
19917
20766
  exports.P = P;
20767
+ exports.PLATFORM_THEME_TO_CHARACTER_THEME = PLATFORM_THEME_TO_CHARACTER_THEME;
19918
20768
  exports.Pagination = Pagination;
19919
20769
  exports.Phone = Phone;
19920
20770
  exports.Progress = Progress;
@@ -19959,8 +20809,12 @@ exports.WhatsAppPreview = WhatsAppPreview;
19959
20809
  exports.Wizard = Wizard;
19960
20810
  exports.WizardNavigation = WizardNavigation;
19961
20811
  exports.WizardSidebar = WizardSidebar;
20812
+ exports.applyCharacterPalette = applyCharacterPalette;
19962
20813
  exports.applyCustomPrimaryColor = applyCustomPrimaryColor;
19963
20814
  exports.applyLindaTones = applyLindaTones;
20815
+ exports.characterPaletteFromTheme = characterPaletteFromTheme;
20816
+ exports.characterPaletteToCssVars = characterPaletteToCssVars;
20817
+ exports.characterThemeForPlatformTheme = characterThemeForPlatformTheme;
19964
20818
  exports.cn = cn;
19965
20819
  exports.computeBars = computeBars;
19966
20820
  exports.computeMax = computeMax;
@@ -19984,6 +20838,7 @@ exports.hexToHsl = hexToHsl;
19984
20838
  exports.hexToThemeColor = hexToThemeColor;
19985
20839
  exports.hslToCssValue = hslToCssValue;
19986
20840
  exports.isAuroraFullThemeId = isAuroraFullThemeId;
20841
+ exports.isCompleteCharacterPalette = isCompleteCharacterPalette;
19987
20842
  exports.isDismissControl = isDismissControl;
19988
20843
  exports.isDonutEmpty = isDonutEmpty;
19989
20844
  exports.isExactThemeColor = isExactThemeColor;
@@ -19991,9 +20846,13 @@ exports.isGroupState = isGroupState;
19991
20846
  exports.isHexColor = isHexColor;
19992
20847
  exports.isRankedBarListEmpty = isRankedBarListEmpty;
19993
20848
  exports.isSegmentationGroup = isSegmentationGroup;
20849
+ exports.normalizeCharacterPalette = normalizeCharacterPalette;
20850
+ exports.normalizeCharacterThemeColors = normalizeCharacterThemeColors;
19994
20851
  exports.parseColorToHsl = parseColorToHsl;
20852
+ exports.removeCharacterPalette = removeCharacterPalette;
19995
20853
  exports.removeCustomPrimaryColor = removeCustomPrimaryColor;
19996
20854
  exports.removeLindaTones = removeLindaTones;
20855
+ exports.resolveMascotState = resolveMascotState;
19997
20856
  exports.shouldClosePopoverOnInteractOutside = shouldClosePopoverOnInteractOutside;
19998
20857
  exports.sizeMap = sizeMap;
19999
20858
  exports.themeColors = themeColors;