@magicfeedback/popup-sdk 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -1
- package/dist/assets/assets/style.css +63 -14
- package/dist/{chunk-AN7JIVWB.mjs → chunk-W6MPSWMS.mjs} +352 -15
- package/dist/chunk-W6MPSWMS.mjs.map +1 -0
- package/dist/{chunk-Z3LLJMSH.mjs → chunk-WNIUIOKF.mjs} +332 -15
- package/dist/chunk-WNIUIOKF.mjs.map +1 -0
- package/dist/index.d.mts +99 -1
- package/dist/index.d.ts +99 -1
- package/dist/index.js +1647 -1366
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +200 -28
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +13 -0
- package/dist/react-native.d.ts +13 -0
- package/dist/react-native.js +550 -55
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +189 -28
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-SELXQ3UE.mjs → renderPopup-EWGKG53W.mjs} +42 -18
- package/dist/renderPopup-EWGKG53W.mjs.map +1 -0
- package/dist/renderPopup-HHQMAW3G.mjs +3114 -0
- package/dist/renderPopup-HHQMAW3G.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-AN7JIVWB.mjs.map +0 -1
- package/dist/chunk-Z3LLJMSH.mjs.map +0 -1
- package/dist/renderPopup-M6MKTDEH.mjs +0 -3330
- package/dist/renderPopup-M6MKTDEH.mjs.map +0 -1
- package/dist/renderPopup-SELXQ3UE.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magicfeedback/popup-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "TypeScript SDK to render and manage survey popups for MagicFeedback",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
}
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@magicfeedback/native": "^2.2.
|
|
78
|
+
"@magicfeedback/native": "^2.2.22",
|
|
79
79
|
"@playwright/test": "^1.60.0",
|
|
80
80
|
"@types/node": "^20.10.0",
|
|
81
81
|
"@types/react": "^18.3.31",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracking/tracking-manager.ts","../src/ui/font.ts","../src/assets/style.css","../src/util/logger.ts"],"sourcesContent":["/**\n * Identidad + sesión para el tracking de navegación (Fase 1).\n * Implementa el \"Contrato común Web+KMP\".\n *\n * Modelo: el SDK gestiona el `user_id` (persistente). El `session_id` es propiedad\n * del BACKEND: llega en la respuesta de `POST /sdk/popups` y se cachea; el backend\n * cose sesiones por `user_id` + ventana. El SDK NO genera ni expira sesiones.\n *\n * Sin dependencias de DOM: recibe el storage y (opcionalmente) el reloj y el\n * generador de uuid por inyección. El binding a `localStorage` vive en `createDefaultStorage`.\n */\n\n/** Store clave/valor mínimo (espejo conceptual del `KeyValueStorage` de KMP). */\nexport interface KeyValueStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\n/** Impl en memoria — usada en tests y como fallback sin `localStorage`. */\nexport class InMemoryStorage implements KeyValueStorage {\n private map = new Map<string, string>();\n getItem(key: string): string | null {\n return this.map.has(key) ? (this.map.get(key) as string) : null;\n }\n setItem(key: string, value: string): void {\n this.map.set(key, value);\n }\n removeItem(key: string): void {\n this.map.delete(key);\n }\n}\n\n/** Storage por defecto en Web: `localStorage` si está disponible, si no in-memory. */\nexport function createDefaultStorage(): KeyValueStorage {\n try {\n if (typeof window !== 'undefined' && window.localStorage) {\n const ls = window.localStorage;\n const probe = '__deepdots_probe__';\n ls.setItem(probe, '1');\n ls.removeItem(probe);\n return {\n getItem: (k) => ls.getItem(k),\n setItem: (k, v) => ls.setItem(k, v),\n removeItem: (k) => ls.removeItem(k),\n };\n }\n } catch {\n // cae a in-memory\n }\n return new InMemoryStorage();\n}\n\n/** Claves de storage — namespace `deepdots.*`. Solo identidad (la sesión no se persiste). */\nexport const STORAGE_KEYS = {\n userId: 'deepdots.user_id',\n firstSeen: 'deepdots.user.first_seen',\n contactAttributes: 'deepdots.contact.attributes',\n} as const;\n\n/** Par clave/valor con el formato `NativeAnswer` que espera `@magicfeedback/native`. */\nexport interface IdentityAnswer {\n key: string;\n value: string[];\n}\n\n/**\n * Construye el `profile` y el `metadata` de identidad para inyectar en el survey\n * (`magicfeedback.form(appId, publicKey, profile, metadata)`), según el contrato §5.\n * `session_id` solo se incluye si el backend ya lo proveyó.\n */\nexport function buildSurveyIdentity(\n userId: string | null,\n sessionId: string | null,\n miniService: string | null = null,\n analyticsFeedbackSessionId: string | null = null,\n): { profile: IdentityAnswer[]; metadata: IdentityAnswer[] } {\n const profile: IdentityAnswer[] = userId ? [{ key: 'external-user-id', value: [userId] }] : [];\n const metadata: IdentityAnswer[] = [];\n if (sessionId) metadata.push({ key: 'session_id', value: [sessionId] });\n if (userId) metadata.push({ key: 'user_id', value: [userId] });\n if (miniService) metadata.push({ key: 'mini_service', value: [miniService] });\n if (analyticsFeedbackSessionId) metadata.push({ key: 'deepdots_analytics_feedback_session_id', value: [analyticsFeedbackSessionId] });\n return { profile, metadata };\n}\n\nexport interface TrackingManagerOptions {\n storage: KeyValueStorage;\n /** Id provisto por el cliente; si existe se usa y NO se persiste. */\n clientUserId?: string;\n /** Reloj inyectable (default `Date.now`). */\n now?: () => number;\n /** Generador de uuid inyectable (default uuid v4). */\n uuid?: () => string;\n /** Estado inicial del tracking (default `true`). */\n enabled?: boolean;\n}\n\nfunction defaultUuid(): string {\n const g = (typeof globalThis !== 'undefined' ? globalThis : {}) as {\n crypto?: { randomUUID?: () => string; getRandomValues?: (a: Uint8Array) => Uint8Array };\n };\n if (g.crypto?.randomUUID) return g.crypto.randomUUID();\n const bytes = new Uint8Array(16);\n if (g.crypto?.getRandomValues) {\n g.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0'));\n return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex\n .slice(6, 8)\n .join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10, 16).join('')}`;\n}\n\nexport class TrackingManager {\n private storage: KeyValueStorage;\n private clientUserId?: string;\n private now: () => number;\n private uuid: () => string;\n private enabled: boolean;\n\n /** session_id cacheado, provisto por el backend (no se genera ni se persiste). */\n private sessionId: string | null = null;\n private userWasJustCreated = false;\n\n constructor(options: TrackingManagerOptions) {\n this.storage = options.storage;\n this.clientUserId = options.clientUserId;\n this.now = options.now ?? (() => Date.now());\n this.uuid = options.uuid ?? defaultUuid;\n this.enabled = options.enabled ?? true;\n }\n\n isTrackingEnabled(): boolean {\n return this.enabled;\n }\n\n setTrackingEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n /** Resuelve el user_id según la regla: cliente > persistido > generar+persistir. */\n getUserId(): string | null {\n if (!this.enabled) return null;\n if (this.clientUserId) return this.clientUserId;\n\n const persisted = this.storage.getItem(STORAGE_KEYS.userId);\n if (persisted) return persisted;\n\n const id = this.uuid();\n this.storage.setItem(STORAGE_KEYS.userId, id);\n this.storage.setItem(STORAGE_KEYS.firstSeen, String(this.now()));\n this.userWasJustCreated = true;\n return id;\n }\n\n /** `true` solo en la primera sesión tras crear el user_id propio del SDK. */\n isNewUser(): boolean {\n return this.userWasJustCreated;\n }\n\n /** session_id actual provisto por el backend, o null si aún no llegó. */\n getSessionId(): string | null {\n if (!this.enabled) return null;\n return this.sessionId;\n }\n\n /** Cachea el session_id devuelto por el backend (respuesta de POST /sdk/popups). */\n setSessionId(sessionId: string | null): void {\n if (!this.enabled) return;\n this.sessionId = sessionId;\n }\n}\n","/**\n * Helpers puros (sin DOM) para la fuente personalizable del popup/survey.\n * Espejo exacto en KMP: `ui/Font.kt`. Cualquier cambio aquí se replica allí.\n */\n\nconst FORMAT_BY_EXT: Record<string, string> = {\n woff2: 'woff2',\n woff: 'woff',\n ttf: 'truetype',\n otf: 'opentype',\n};\n\n/** Deriva el `format()` del `@font-face` a partir de la extensión de la URL. */\nexport function fontFormatFromUrl(url: string): string | undefined {\n const clean = url.split('?')[0].split('#')[0];\n const ext = clean.slice(clean.lastIndexOf('.') + 1).toLowerCase();\n return FORMAT_BY_EXT[ext];\n}\n\n// family/url provienen de la API y se interpolan en CSS y en el <style> del HTML del WebView.\n// Saneamos para evitar romper el string/rule (CSS injection) o cerrar </style> (script injection).\nfunction sanitizeFamily(family: string): string {\n return family.replace(/[^A-Za-z0-9 ._-]/g, '').trim();\n}\n\nfunction isSafeFontUrl(url: string): boolean {\n // Solo http(s)/data y sin caracteres que rompan url(\"...\") o el <style>:\n // comillas, <>, backslash, y cualquier whitespace o carácter de control.\n if (!/^(https?:|data:)/i.test(url)) return false;\n // eslint-disable-next-line no-control-regex\n return !/[\\x00-\\x20\"<>\\\\]/.test(url);\n}\n\n/** Valor a aplicar en `font-family`: nombre custom + fallback de sistema. */\nexport function buildFontFamilyValue(family: string): string {\n const safe = sanitizeFamily(family);\n return `\"${safe}\", -apple-system, system-ui, sans-serif`;\n}\n\n/** CSS del `@font-face`. Devuelve \"\" si no hay url (o no es segura). */\nexport function buildFontFaceCss(family: string, url?: string): string {\n if (!url || !isSafeFontUrl(url)) return '';\n const safe = sanitizeFamily(family);\n const fmt = fontFormatFromUrl(url);\n const src = fmt ? `url(\"${url}\") format(\"${fmt}\")` : `url(\"${url}\")`;\n return `@font-face{font-family:\"${safe}\";src:${src};font-display:swap;}`;\n}\n","/**\n * NO EDITAR A MANO — generado por scripts/vendor-survey-css.mjs\n *\n * Copia de @magicfeedback/native@2.2.8 → dist/styles/magicfeedback-default.css\n * (la hoja canónica del paquete, la que apunta su campo \"style\"), con estos cambios locales:\n *\n * 1. Sin el @import de Google Fonts (Nunito): no queremos una petición externa desde la\n * página del host, y la tipografía la decide el popup.\n * 2. .magicfeedback-container hereda la fuente del popup (var(--deepdots-font, inherit)).\n * 3. Los selectores desnudos (h2, p, input, textarea, select, ::placeholder, .error) van\n * acotados a .deepdots-popup: este CSS se inyecta en el <head> del host y sin acotar\n * repintaría su web.\n * 4. El grupo .magicfeedback-radio se cualifica como div.magicfeedback-radio (la clase acaba\n * también en el <input> del boolean).\n * 5. Al final, un bloque de reglas propias del popup (fuente en los controles y padding del\n * radio nativo).\n *\n * Las variables --mf-* se dejan en :root a propósito: el modal del priority-list se portea a\n * <body>, fuera de .deepdots-popup, y ahí las necesita.\n *\n * Para subir de versión: npm i @magicfeedback/native@<v> && node scripts/vendor-survey-css.mjs\n */\n\n/**\n * @magicfeedback/native - Default Styles\n * Clean, minimal, and elegant survey rendering\n */\n\n/* @import de Google Fonts (Nunito) eliminado al vendorizar: la fuente la pone el popup. */\n\n/* ========================================\n CSS VARIABLES - Design SYSTEM\n ======================================== */\n:root {\n /* Colors - Minimal Pastel */\n /* --mf-primary is the one source of truth for brand/accent color —\n every token below derives from it via color-mix() (or references\n it directly) so changing this single value, here or via a\n per-integration override, keeps hover/light/border states in\n sync automatically instead of going stale independently. Scoped\n to genuinely interactive/accent surfaces (buttons, selected\n chips, focus rings) — general body text stays on its own neutral\n scale below, not tied to the brand color. */\n --mf-primary: #5d7bad;\n --mf-primary-hover: color-mix(in srgb, var(--mf-primary) 85%, black);\n --mf-primary-light: color-mix(in srgb, var(--mf-primary) 15%, white);\n /* a translucent tint — mixed with transparent (opacity), not white,\n so it reads as a soft shadow of the brand color rather than a\n pastel of it. */\n --mf-primary-border: color-mix(in srgb, var(--mf-primary) 35%, transparent);\n\n --mf-text-primary: #1E293B;\n --mf-text-secondary: #475569;\n --mf-text-muted: #94A3B8;\n\n --mf-bg-primary: #F8FAFC;\n --mf-bg-secondary: #FFFFFF;\n --mf-bg-hover: #EEF2F6;\n\n --mf-border: #E2E8F0;\n --mf-border-focus: var(--mf-primary);\n\n --mf-success: #16A34A;\n --mf-error: #EF4444;\n --mf-warning: #F59E0B;\n\n --mf-surface: #FFFFFF;\n --mf-surface-alt: #F1F5F9;\n --mf-accent: #38BDF8;\n\n /* Spacing */\n --mf-space-xs: 0.25rem;\n --mf-space-sm: 0.5rem;\n --mf-space-md: 0.75rem;\n --mf-space-lg: 1rem;\n --mf-space-xl: 1.5rem;\n\n /* Border Radius */\n --mf-radius-sm: 0.5rem;\n --mf-radius-md: 0.75rem;\n --mf-radius-lg: 1.25rem;\n --mf-radius-full: 9999px;\n\n /* Shadows */\n --mf-shadow-sm: 0 1px 2px 0 rgba(15, 23, 42, 0.06);\n --mf-shadow-md: 0 8px 20px rgba(15, 23, 42, 0.08);\n --mf-shadow-lg: 0 16px 30px rgba(15, 23, 42, 0.12);\n --mf-shadow-focus: 0 0 0 3px rgba(30, 41, 59, 0.15);\n --mf-shadow-card: 0 18px 40px rgba(15, 23, 42, 0.08);\n\n /* Typography */\n --mf-font-sans: \"Nunito\", \"Quicksand\", \"Avenir Next\", \"Trebuchet MS\", sans-serif;\n --mf-font-size-sm: 0.875rem;\n --mf-font-size-base: 1rem;\n --mf-font-size-lg: 1.125rem;\n --mf-font-size-xl: 1.25rem;\n --mf-line-height: 1.6;\n\n /* Font Weights */\n --mf-font-weight-normal: 400;\n --mf-font-weight-medium: 500;\n --mf-font-weight-semibold: 600;\n --mf-font-weight-bold: 700;\n --mf-font-weight-extrabold: 800;\n\n /* Transitions */\n --mf-transition: all 0.2s ease;\n --mf-transition-fast: all 0.15s ease;\n}\n\n/* ========================================\n ANIMATIONS\n ======================================== */\n@keyframes mf-fade-in {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes mf-slide-in {\n from {\n opacity: 0;\n transform: translateX(-16px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes mf-scale-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes mf-pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.8;\n }\n}\n\n/* ========================================\n BASE CONTAINER\n ======================================== */\n.magicfeedback-container {\n /* Local: hereda la fuente del popup; --deepdots-font viene de PopupStyle.font. */\n font-family: var(--deepdots-font, inherit);\n color: var(--mf-text-primary);\n line-height: var(--mf-line-height);\n animation: mf-fade-in 0.4s ease-out;\n border-radius: var(--mf-radius-lg);\n}\n\n/* ========================================\n MESSAGES\n ======================================== */\n.magicfeedback-success-message,\n.magicfeedback-info-message,\n.magicfeedback-start-message {\n padding: var(--mf-space-lg);\n margin: var(--mf-space-lg) 0;\n animation: mf-scale-in 0.3s ease-out;\n}\n\n/* .magicfeedback-info-message/-start-message are set via innerHTML (see\n renderInfoPage.ts / questions.service.ts's renderStartMessage) — whatever\n rich text a survey author writes lands here as real HTML, not just the\n <p>/<img> pair this used to style. Covering the rest of what a rich-text\n editor commonly outputs (headings, lists, links, emphasis, quotes, code,\n rules) keeps that content on the same type scale and palette as the rest\n of the widget instead of falling back to unstyled browser defaults. */\n.magicfeedback-success-message > :first-child,\n.magicfeedback-info-message > :first-child,\n.magicfeedback-start-message > :first-child {\n margin-top: 0;\n}\n\n.magicfeedback-success-message > :last-child,\n.magicfeedback-info-message > :last-child,\n.magicfeedback-start-message > :last-child {\n margin-bottom: 0;\n}\n\n.magicfeedback-success-message p,\n.magicfeedback-info-message p,\n.magicfeedback-start-message p {\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-secondary);\n margin: 0 0 var(--mf-space-md);\n line-height: var(--mf-line-height);\n}\n\n.magicfeedback-info-message h1,\n.magicfeedback-info-message h2,\n.magicfeedback-info-message h3,\n.magicfeedback-info-message h4,\n.magicfeedback-info-message h5,\n.magicfeedback-info-message h6,\n.magicfeedback-start-message h1,\n.magicfeedback-start-message h2,\n.magicfeedback-start-message h3,\n.magicfeedback-start-message h4,\n.magicfeedback-start-message h5,\n.magicfeedback-start-message h6 {\n color: var(--mf-text-primary);\n font-weight: var(--mf-font-weight-bold);\n line-height: 1.3;\n margin: var(--mf-space-lg) 0 var(--mf-space-sm);\n text-align: left;\n}\n\n.magicfeedback-info-message h1, .magicfeedback-start-message h1 { font-size: var(--mf-font-size-xl); }\n.magicfeedback-info-message h2, .magicfeedback-start-message h2 { font-size: var(--mf-font-size-lg); }\n.magicfeedback-info-message h3,\n.magicfeedback-info-message h4,\n.magicfeedback-info-message h5,\n.magicfeedback-info-message h6,\n.magicfeedback-start-message h3,\n.magicfeedback-start-message h4,\n.magicfeedback-start-message h5,\n.magicfeedback-start-message h6 { font-size: var(--mf-font-size-base); }\n\n.magicfeedback-info-message strong,\n.magicfeedback-info-message b,\n.magicfeedback-start-message strong,\n.magicfeedback-start-message b {\n font-weight: var(--mf-font-weight-bold);\n color: var(--mf-text-primary);\n}\n\n.magicfeedback-info-message a,\n.magicfeedback-start-message a {\n color: var(--mf-primary);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.magicfeedback-info-message a:hover,\n.magicfeedback-start-message a:hover {\n color: var(--mf-primary-hover);\n}\n\n.magicfeedback-info-message ul,\n.magicfeedback-info-message ol,\n.magicfeedback-start-message ul,\n.magicfeedback-start-message ol {\n margin: 0 0 var(--mf-space-md);\n padding-left: var(--mf-space-xl);\n color: var(--mf-text-secondary);\n line-height: var(--mf-line-height);\n}\n\n.magicfeedback-info-message li + li,\n.magicfeedback-start-message li + li {\n margin-top: var(--mf-space-xs);\n}\n\n.magicfeedback-info-message blockquote,\n.magicfeedback-start-message blockquote {\n margin: 0 0 var(--mf-space-md);\n padding: var(--mf-space-sm) var(--mf-space-md);\n border-left: 3px solid var(--mf-primary-border);\n color: var(--mf-text-secondary);\n font-style: italic;\n}\n\n.magicfeedback-info-message code,\n.magicfeedback-start-message code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.9em;\n background: var(--mf-bg-hover);\n padding: 0.15em 0.4em;\n border-radius: var(--mf-radius-sm);\n}\n\n.magicfeedback-info-message pre,\n.magicfeedback-start-message pre {\n margin: 0 0 var(--mf-space-md);\n padding: var(--mf-space-md);\n background: var(--mf-bg-hover);\n border-radius: var(--mf-radius-md);\n overflow-x: auto;\n}\n\n.magicfeedback-info-message pre code,\n.magicfeedback-start-message pre code {\n background: none;\n padding: 0;\n}\n\n.magicfeedback-info-message hr,\n.magicfeedback-start-message hr {\n border: none;\n border-top: 1px solid var(--mf-border);\n margin: var(--mf-space-lg) 0;\n}\n\n.magicfeedback-success-message img,\n.magicfeedback-info-message img,\n.magicfeedback-start-message img {\n max-width: 100%;\n height: auto;\n margin: var(--mf-space-lg) auto;\n display: block;\n border-radius: var(--mf-radius-md);\n}\n\n.magicfeedback-image {\n max-height: 400px;\n height: auto;\n max-width: 100%;\n margin: var(--mf-space-lg) auto;\n display: block;\n border-radius: var(--mf-radius-md);\n}\n\n/* ========================================\n FORM STRUCTURE\n ======================================== */\n.magicfeedback-form {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-lg);\n padding: clamp(16px, 2.5vw, 28px);\n}\n\n.magicfeedback-questions {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-xl);\n width: 100%;\n}\n\n.magicfeedback-div {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-sm);\n animation: mf-slide-in 0.3s ease-out;\n background: var(--mf-bg-secondary);\n border-radius: var(--mf-radius-md);\n}\n\n/* ========================================\n LABELS & TYPOGRAPHY\n ======================================== */\n.magicfeedback-label {\n font-size: var(--mf-font-size-lg);\n font-weight: var(--mf-font-weight-bold);\n color: var(--mf-text-primary);\n line-height: var(--mf-line-height);\n text-align: left;\n letter-spacing: -0.01em;\n}\n\n.magicfeedback-sublabel {\n font-size: var(--mf-font-size-base);\n font-weight: var(--mf-font-weight-normal);\n color: var(--mf-text-secondary);\n margin-bottom: var(--mf-space-sm);\n}\n\n.deepdots-popup h2 {\n font-size: var(--mf-font-size-xl);\n font-weight: 600;\n color: var(--mf-text-primary);\n margin: 0 0 var(--mf-space-xl) 0;\n text-align: center;\n letter-spacing: -0.01em;\n}\n\n.deepdots-popup p {\n margin: 0;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-secondary);\n}\n\n/* ========================================\n FORM INPUTS\n ======================================== */\n.deepdots-popup input[type=\"date\"],\n.deepdots-popup input[type=\"text\"],\n.deepdots-popup input[type=\"number\"],\n.deepdots-popup input[type=\"email\"],\n.deepdots-popup input[type=\"password\"],\n.deepdots-popup textarea,\n.deepdots-popup select {\n padding: 0.75rem 0.9rem;\n font-size: var(--mf-font-size-base);\n font-family: inherit;\n color: var(--mf-text-primary);\n background-color: var(--mf-surface);\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n outline: none;\n transition: var(--mf-transition);\n -webkit-appearance: none;\n appearance: none;\n box-shadow: var(--mf-shadow-sm);\n}\n\n.deepdots-popup textarea {\n min-height: 100px;\n resize: vertical;\n}\n\n.deepdots-popup input::placeholder,\n.deepdots-popup textarea::placeholder {\n color: var(--mf-text-muted);\n}\n\n/* Remove number input spinners */\n.deepdots-popup input::-webkit-outer-spin-button,\n.deepdots-popup input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.deepdots-popup input[type=\"number\"] {\n /* -moz-appearance: textfield; removed for lint compatibility */\n}\n\n/* Custom Select Arrow */\n.deepdots-popup select {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 9L1 4h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right var(--mf-space-md) center;\n padding-right: var(--mf-space-xl);\n}\n\n/* Error State */\n.deepdots-popup input.error,\n.deepdots-popup select.error,\n.deepdots-popup textarea.error {\n border-color: var(--mf-error);\n}\n\n.magicfeedback-error {\n margin-top: var(--mf-space-xs);\n font-size: var(--mf-font-size-sm);\n color: var(--mf-error);\n}\n\n/* ========================================\n CHECKBOX & RADIO OPTIONS\n ======================================== */\n.magicfeedback-checkbox,\ndiv.magicfeedback-radio {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-sm);\n width: 100%;\n}\n\n.magicfeedback-checkbox-container,\n.magicfeedback-radio-container {\n display: flex;\n align-items: center;\n gap: var(--mf-space-sm);\n padding: var(--mf-space-md);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-checkbox-container:hover,\n.magicfeedback-radio-container:hover {\n background-color: var(--mf-bg-hover);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-checkbox-container:has(input:checked),\n.magicfeedback-radio-container:has(input:checked) {\n background-color: var(--mf-primary-light);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-checkbox input[type=\"checkbox\"],\n.magicfeedback-radio-container input[type=\"radio\"] {\n width: 18px;\n height: 18px;\n margin: 0;\n cursor: pointer;\n flex-shrink: 0;\n accent-color: var(--mf-primary);\n}\n\n.magicfeedback-checkbox label,\n.magicfeedback-radio-container label {\n font-size: var(--mf-font-size-base);\n text-align: left;\n color: var(--mf-text-primary);\n cursor: pointer;\n margin: 0;\n flex: 1;\n}\n\n/* ========================================\n BOOLEAN OPTIONS\n ======================================== */\n.magicfeedback-boolean-container {\n display: flex;\n gap: var(--mf-space-md);\n width: 100%;\n}\n\n.magicfeedback-boolean-option {\n flex: 1;\n position: relative;\n}\n\n.magicfeedback-boolean-option input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-boolean-option label {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--mf-space-md);\n font-size: var(--mf-font-size-base);\n font-weight: 500;\n color: var(--mf-text-secondary);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n margin: 0;\n width: -webkit-fill-available;\n height: inherit;\n}\n\n.magicfeedback-boolean-option label:hover {\n background-color: var(--mf-bg-hover);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-boolean-option input[type=\"radio\"]:checked + label {\n color: var(--mf-primary);\n background-color: var(--mf-primary-light);\n border-color: var(--mf-primary);\n font-weight: 600;\n}\n\n/* ========================================\n RATING SYSTEMS\n ======================================== */\n.magicfeedback-rating,\n.magicfeedback-rating-number,\n.magicfeedback-rating-star {\n width: 100%;\n}\n\n.magicfeedback-rating-container,\n.magicfeedback-rating-number-container,\n.magicfeedback-rating-star-container {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mf-space-sm);\n justify-content: center;\n align-items: center;\n padding: var(--mf-space-md) 0;\n list-style: none;\n margin: 0;\n}\n\n/* Caption line below the row — min on one side, max on the other (swapped\n for order: \"rtl\") — same simple, non-responsive pattern as the\n rating-number row caption. Used by rating-star and rating-emoji. */\n.magicfeedback-rating-placeholder {\n display: flex;\n justify-content: space-between;\n gap: var(--mf-space-md);\n width: 100%;\n margin-top: var(--mf-space-sm);\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-secondary);\n}\n\n.magicfeedback-rating-placeholder-value {\n overflow-wrap: anywhere;\n}\n\n.magicfeedback-rating-placeholder-value:last-child {\n text-align: right;\n}\n\n/* Rating with Images */\n.magicfeedback-rating-option-label-container input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-rating-option-label-container img {\n width: 56px;\n height: 56px;\n cursor: pointer;\n transition: var(--mf-transition-fast);\n border-radius: var(--mf-radius-full);\n border: 2px solid transparent;\n}\n\n.magicfeedback-rating-option-label-container img:hover {\n transform: scale(1.1);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-rating-option-label-container input[type=\"radio\"]:checked + img {\n border-color: var(--mf-primary);\n box-shadow: 0 0 0 3px var(--mf-primary-light);\n}\n\n.magicfeedback-rating-option-label-container label {\n display: block;\n text-align: center;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-secondary);\n margin-top: var(--mf-space-xs);\n cursor: pointer;\n}\n\n/* Rating Numbers — each option is its own outlined chip in the survey's\n primary color, with a gap between them. Row and column use the same\n chip; column additionally has room to show each option's own text\n plainly next to its number. */\n\n/* Every size here is width:100%/flex:1 combined with the chip's own\n padding and border. Without border-box, the browser's default\n content-box adds that padding/border on TOP of the declared size, so\n the chip quietly overflows past its flex slot — reading as \"not quite\n full width\" or, worse, pushing into the next chip. */\n.magicfeedback-rating-number-container,\n.magicfeedback-rating-number-option,\n.magicfeedback-rating-number-option-label-container,\n.magicfeedback-rating-number-value {\n box-sizing: border-box;\n}\n\n/* The shared rating-container rule (above, reused by star rating) sets\n align-items:center for its row-of-chips layout — in a stacked column\n that still nudges a 100%-wide chip inward instead of a true 0 offset.\n Force stretch so every chip fills the exact same width, flush on\n both sides. */\n.magicfeedback-rating-number-container-column,\n.magicfeedback-rating-number-container-column-reverse {\n align-items: stretch;\n}\n\n/* Caption line below the row — the single place min/max labels live\n for row mode, shared by mobile and desktop. */\n.magicfeedback-rating-number-scale-labels {\n display: flex;\n justify-content: space-between;\n gap: var(--mf-space-md);\n margin-top: var(--mf-space-sm);\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-secondary);\n}\n\n.magicfeedback-rating-number-scale-label {\n overflow-wrap: anywhere;\n}\n\n.magicfeedback-rating-number-scale-label:last-child {\n text-align: right;\n}\n\n/* Column, no per-option text: each row is its own separated chip, so\n the min/max labels bookend the stack from outside it — one line\n above the first chip, one below the last. Margin goes on whichever\n side actually faces the list — the \"before\" label (always the first\n child) gets space below it, the \"after\" one (always right after the\n container, extra option row or not) gets space above it — so both\n sit the same distance from the chips regardless of which one it is. */\n.magicfeedback-rating-number-scale-label-block {\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-secondary);\n text-align: center;\n}\n\n.magicfeedback-rating-number-scale-label-block:first-child {\n margin-bottom: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-container + .magicfeedback-rating-number-scale-label-block {\n margin-top: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option {\n display: flex;\n}\n\n.magicfeedback-rating-number-option-label-container {\n position: relative;\n width: 100%;\n display: flex;\n cursor: pointer;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-rating-number-value {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n transition: var(--mf-transition-fast);\n color: var(--mf-text-secondary);\n font-weight: var(--mf-font-weight-semibold);\n}\n\n/* Row: individual outlined chips in the survey's own primary color —\n var(--mf-primary) so whatever brand color a given survey sets carries\n through automatically, no color hardcoded here. */\n.magicfeedback-rating-number-container-row,\n.magicfeedback-rating-number-container-row-reverse {\n flex-wrap: nowrap;\n gap: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option-row,\n.magicfeedback-rating-number-option-row-reverse {\n flex: 1 1 0;\n min-width: 0;\n}\n\n.magicfeedback-rating-number-option-row .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-value {\n min-height: 56px;\n padding: var(--mf-space-sm);\n border: 2px solid var(--mf-primary-border);\n border-radius: var(--mf-radius-md);\n background: var(--mf-bg-secondary);\n color: var(--mf-primary);\n font-size: var(--mf-font-size-lg);\n font-weight: var(--mf-font-weight-bold);\n}\n\n/* More than 6 options (e.g. a 0-10 NPS scale): still one row, never\n wraps — but scaled down on purpose, so it reads as a compact chip\n rather than the same 56px button stretched thin. */\n.magicfeedback-rating-number-container-row--dense .magicfeedback-rating-number-option-row .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-container-row--dense .magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-value {\n min-height: 36px;\n padding: var(--mf-space-xs);\n border-radius: var(--mf-radius-sm);\n font-size: 0.8rem;\n}\n\n.magicfeedback-rating-number-option-row .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value {\n background: var(--mf-primary-light);\n}\n\n.magicfeedback-rating-number-option-row .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n/* Extra option: always its own row below the scale, and styled like every\n other chip now — \"doesn't apply\" is still not a point on the 1..N\n continuum, but it no longer needs a different border style to say so. */\n.magicfeedback-rating-number-extra-row {\n display: flex;\n justify-content: center;\n margin-top: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option--extra {\n flex: 0 1 auto;\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-option-label-container {\n width: auto;\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-value {\n min-height: 36px;\n padding: 0 var(--mf-space-md);\n border: 2px solid var(--mf-primary-border);\n border-radius: var(--mf-radius-md);\n background: var(--mf-bg-secondary);\n color: var(--mf-primary);\n font-size: var(--mf-font-size-sm);\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value {\n background: var(--mf-primary-light);\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n/* Column: the same separated chips as row, just stacked — each option is\n its own outlined chip with a gap between them, not one shared box. */\n.magicfeedback-rating-number-container-column,\n.magicfeedback-rating-number-container-column-reverse {\n gap: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option-column,\n.magicfeedback-rating-number-option-column-reverse {\n width: 100%;\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-value {\n justify-content: flex-start;\n gap: var(--mf-space-sm);\n min-height: 48px;\n padding: var(--mf-space-sm) var(--mf-space-md);\n border: 2px solid var(--mf-primary-border);\n border-radius: var(--mf-radius-md);\n background: var(--mf-bg-secondary);\n color: var(--mf-primary);\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value {\n background: var(--mf-primary-light);\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-rating-number-value-num {\n font-weight: var(--mf-font-weight-bold);\n}\n\n/* Column with per-option text: a min-width so \"1\"..\"9\" and \"10\" line up,\n with the label text starting at the same x. Skipped entirely when the\n column has no per-option text at all (--bare below) — with nothing to\n align against, the same left-shift bug from row mode would resurface. */\n.magicfeedback-rating-number-container-column:not(.magicfeedback-rating-number-container-column--bare) .magicfeedback-rating-number-value-num,\n.magicfeedback-rating-number-container-column-reverse:not(.magicfeedback-rating-number-container-column--bare) .magicfeedback-rating-number-value-num {\n flex: none;\n min-width: 1.4em;\n}\n\n/* Column, no per-option text at all (only min/max, or nothing): a bare\n numbered list has nothing to left-align against, so center each\n number instead of stranding it on the left with blank space beside it. */\n.magicfeedback-rating-number-container-column--bare .magicfeedback-rating-number-value {\n justify-content: center;\n}\n\n.magicfeedback-rating-number-value-label {\n font-weight: var(--mf-font-weight-medium);\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n}\n\n/* Star Rating */\n.magicfeedback-rating-star-container {\n justify-content: center;\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star {\n font-size: 40px;\n color: var(--mf-border);\n cursor: pointer;\n margin: 0 var(--mf-space-xs);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover,\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover ~ span {\n color: #fbbf24;\n transform: scale(1.1);\n}\n\n.magicfeedback-rating-star-selected {\n color: #fbbf24 !important;\n}\n\n/* ========================================\n MULTIPLE CHOICE WITH IMAGES\n ======================================== */\n.magicfeedback-multiple-choice-image-option {\n display: flex;\n border-radius: var(--mf-radius-md);\n overflow: hidden;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-image-option-label-container {\n cursor: pointer;\n border-radius: var(--mf-radius-md);\n overflow: hidden;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-image-option-label-container input[type=\"radio\"],\n.magicfeedback-image-option-label-container input[type=\"checkbox\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-image-option-label-container img {\n width: 100%;\n height: auto;\n display: block;\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-image-option-label-container:hover img {\n border-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-image-option-label-container input:checked + img {\n border-color: var(--mf-primary);\n box-shadow: 0 0 0 3px var(--mf-primary-light);\n}\n\n/* ========================================\n MATRIX QUESTIONS\n ======================================== */\n.magicfeedback-multi-question-matrix-container {\n width: 100%;\n overflow-x: auto;\n border-radius: var(--mf-radius-md);\n}\n\n.magicfeedback-multi-question-matrix-table {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0 var(--mf-space-xs);\n}\n\n.magicfeedback-multi-question-matrix-table th {\n padding: var(--mf-space-md);\n text-align: center;\n font-size: var(--mf-font-size-sm);\n font-weight: 500;\n color: var(--mf-text-secondary);\n}\n\n.magicfeedback-multi-question-matrix-row-tr {\n background-color: var(--mf-bg-primary);\n border-radius: var(--mf-radius-md);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-multi-question-matrix-row-tr:nth-child(even) {\n background-color: var(--mf-bg-secondary);\n}\n\n.magicfeedback-multi-question-matrix-row-tr:hover {\n background-color: var(--mf-bg-hover);\n box-shadow: var(--mf-shadow-sm);\n}\n\n.magicfeedback-multi-question-matrix-table td {\n padding: var(--mf-space-md);\n text-align: center;\n}\n\n.magicfeedback-multi-question-matrix-label {\n text-align: left;\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-primary);\n}\n\n.magicfeedback-multi-question-matrix-table input[type=\"radio\"] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mf-primary);\n}\n\n/* ========================================\n PRIORITY LIST\n ======================================== */\n.magicfeedback-priority-list-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mf-space-md);\n margin: var(--mf-space-sm) 0;\n background-color: var(--mf-bg-primary);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-priority-list-item:hover {\n box-shadow: var(--mf-shadow-sm);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-priority-list-item-label {\n flex: 1;\n font-size: var(--mf-font-size-base);\n text-align: left;\n color: var(--mf-text-primary);\n margin: 0;\n}\n\n.magicfeedback-priority-list-arrow-up,\n.magicfeedback-priority-list-arrow-down {\n padding: var(--mf-space-xs);\n font-size: var(--mf-font-size-lg);\n color: var(--mf-text-secondary);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n user-select: none;\n}\n\n.magicfeedback-priority-list-arrow-up:hover,\n.magicfeedback-priority-list-arrow-down:hover {\n color: var(--mf-primary);\n transform: scale(1.2);\n}\n\n/* ========================================\n POINT SYSTEM\n ======================================== */\n.magicfeedback-point-system-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mf-space-md);\n margin: var(--mf-space-sm) 0;\n background-color: var(--mf-bg-primary);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n min-height: 45px;\n}\n\n.magicfeedback-point-system-item label {\n flex: 1;\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-primary);\n margin: 0;\n}\n\n.magicfeedback-point-system-input-container {\n display: flex;\n align-items: center;\n gap: var(--mf-space-sm);\n}\n\n.magicfeedback-point-system-item input {\n width: 80px;\n min-width: 80px;\n padding: var(--mf-space-sm);\n text-align: center;\n font-size: var(--mf-font-size-base);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n margin: 0;\n}\n\n.magicfeedback-point-system-total {\n display: flex;\n justify-content: flex-end;\n margin-top: var(--mf-space-md);\n font-size: var(--mf-font-size-base);\n font-weight: 600;\n color: var(--mf-text-primary);\n}\n\n/* ========================================\n CONSENT\n ======================================== */\n.magicfeedback-consent-container {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--mf-space-sm);\n padding: var(--mf-space-md);\n background-color: var(--mf-bg-secondary);\n border-radius: var(--mf-radius-md);\n margin: var(--mf-space-md) 0;\n}\n\n.magicfeedback-consent-container input[type=\"checkbox\"] {\n margin-top: 2px;\n flex-shrink: 0;\n accent-color: var(--mf-primary);\n}\n\n.magicfeedback-consent-container label {\n flex: 1;\n font-size: var(--mf-font-size-sm);\n text-align: left;\n color: var(--mf-text-secondary);\n line-height: var(--mf-line-height);\n cursor: pointer;\n margin-bottom: 0;\n}\n\n/* ========================================\n ACTION BUTTONS\n ======================================== */\n.magicfeedback-action-container {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mf-space-md);\n margin-top: var(--mf-space-xl);\n padding-top: var(--mf-space-lg);\n border-top: 1px solid var(--mf-border);\n}\n\n.magicfeedback-submit {\n padding: 0.8rem 1.6rem;\n font-size: var(--mf-font-size-base);\n font-weight: 800;\n color: #FFFFFF;\n background-color: var(--mf-primary);\n border: 2px solid var(--mf-primary);\n border-radius: var(--mf-radius-full);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-submit:hover {\n background-color: var(--mf-primary-hover);\n box-shadow: var(--mf-shadow-lg);\n transform: translateY(-2px);\n}\n\n.magicfeedback-submit:active {\n transform: translateY(0);\n box-shadow: var(--mf-shadow-sm);\n}\n\n.magicfeedback-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.magicfeedback-back {\n padding: 0.65rem 1rem;\n font-size: var(--mf-font-size-base);\n font-weight: 700;\n color: var(--mf-primary);\n background-color: var(--mf-bg-secondary);\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-full);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-back:hover {\n border-color: var(--mf-primary);\n background-color: var(--mf-bg-hover);\n}\n\n/* ========================================\n SKIP & COUNTER\n ======================================== */\n.magicfeedback-skip-container {\n display: flex;\n align-items: center;\n gap: var(--mf-space-xs);\n padding: 0;\n margin: 0;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-muted);\n background: transparent;\n border: none;\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-skip-container:hover {\n color: var(--mf-primary);\n}\n\n.magicfeedback-skip-container input[type=\"checkbox\"] {\n margin: 0;\n cursor: pointer;\n accent-color: var(--mf-primary);\n}\n\n.magicfeedback-counter {\n display: flex;\n justify-content: flex-end;\n margin-top: var(--mf-space-md);\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-muted);\n}\n\n/* ========================================\n MODAL STYLES\n ======================================== */\n/* Modal backdrop */\n.magicfeedback-modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0,0,0,0.4);\n display: none; /* toggled to flex when open */\n align-items: center;\n justify-content: center;\n z-index: 9999;\n}\n\n/* Modal container */\n.magicfeedback-modal {\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.2);\n max-width: 520px;\n width: 90%;\n max-height: 80vh;\n /* Flex column so the options list scrolls while the actions footer\n (counter + confirm button) stays pinned and always visible. */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n position: relative;\n /* Portalled to document.body (see renderPriorityList.ts) to escape the\n host page's overflow/z-index — so it never inherits\n .magicfeedback-container's neutral text color and instead inherits\n whatever color the host page's own <body> happens to set. Needs its\n own explicit baseline rather than relying on that inheritance. */\n color: var(--mf-text-primary);\n}\n\n/* Modal actions */\n.magicfeedback-modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 12px;\n flex-shrink: 0;\n}\n\n.magicfeedback-modal-counter {\n margin-right: auto;\n display: flex;\n align-items: center;\n font-size: 14px;\n color: var(--mf-text-secondary);\n}\n\n/* Modal list */\n.magicfeedback-modal-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n /* Scrollable area; footer stays fixed below it. */\n flex: 1 1 auto;\n overflow-y: auto;\n min-height: 0;\n}\n\n.magicfeedback-modal-row {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n}\n\n/* Priority list header */\n.magicfeedback-priority-list-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.magicfeedback-priority-list-reorder {\n margin-top: 8px;\n}\n\n.magicfeedback-priority-list-list {\n padding: 0;\n list-style: none;\n}\n\n.magicfeedback-priority-list-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin: 5px 0;\n}\n\n.magicfeedback-priority-list-item-label {\n font-size: 15px;\n}\n\n.magicfeedback-priority-list-arrows {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Buttons */\n.magicfeedback-button {\n appearance: none;\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-full);\n background: var(--mf-bg-secondary);\n color: var(--mf-text-primary);\n padding: 0.6rem 1rem;\n font-size: 14px;\n font-weight: 700;\n cursor: pointer;\n box-shadow: var(--mf-shadow-sm);\n}\n\n.magicfeedback-button:hover {\n background: var(--mf-bg-hover);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-button:active {\n transform: translateY(1px);\n}\n\n.magicfeedback-button-primary {\n border-color: var(--mf-primary);\n background: var(--mf-primary);\n color: #fff;\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-button-primary:hover {\n background: var(--mf-primary-hover);\n}\n\n.magicfeedback-button-primary:active {\n background: var(--mf-primary-hover);\n}\n\n/* Warning flash */\n.magicfeedback-warning {\n color: #C70039;\n}\n\n/* Start message button */\n.magicfeedback-start-message-button {\n appearance: none;\n border: 2px solid var(--mf-primary);\n border-radius: var(--mf-radius-full);\n background: var(--mf-primary);\n color: #fff;\n padding: 0.8rem 1.4rem;\n font-size: 15px;\n font-weight: 800;\n cursor: pointer;\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-start-message-button:hover {\n background: var(--mf-primary-hover);\n}\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n@media (max-width: 768px) {\n :root {\n --mf-space-lg: 1.25rem;\n --mf-space-xl: 1.5rem;\n }\n\n .magicfeedback-container {\n padding: 12px;\n border-radius: var(--mf-radius-md);\n }\n\n .magicfeedback-form {\n padding: 14px;\n border-radius: var(--mf-radius-md);\n }\n\n .magicfeedback-div {\n padding: 12px;\n gap: var(--mf-space-lg)\n }\n\n .magicfeedback-label {\n font-size: var(--mf-font-size-base);\n }\n\n .deepdots-popup input[type=\"date\"],\n .deepdots-popup input[type=\"text\"],\n .deepdots-popup input[type=\"number\"],\n .deepdots-popup input[type=\"email\"],\n .deepdots-popup input[type=\"password\"],\n .deepdots-popup textarea,\n .deepdots-popup select {\n padding: 0.85rem 0.95rem;\n font-size: 1rem;\n min-height: 46px;\n }\n\n /*\n .magicfeedback-radio-container,\n .magicfeedback-checkbox-container,\n .magicfeedback-boolean-container,\n .magicfeedback-consent-container {\n width: 100%;\n }\n */\n\n .magicfeedback-radio-container,\n .magicfeedback-checkbox-container {\n padding: 10px 12px;\n border-radius: var(--mf-radius-md);\n border: 1px solid var(--mf-border);\n gap: 10px;\n }\n\n .magicfeedback-rating-container,\n .magicfeedback-rating-number-container,\n .magicfeedback-rating-star-container {\n gap: 10px;\n }\n\n .magicfeedback-boolean-container {\n flex-direction: column;\n gap: 10px;\n }\n\n .magicfeedback-rating-number-container-row,\n .magicfeedback-rating-number-container-row-reverse {\n gap: 6px;\n }\n\n .magicfeedback-rating-number-option-row .magicfeedback-rating-number-value,\n .magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-value {\n min-height: 44px;\n padding: var(--mf-space-xs);\n font-size: 0.9rem;\n }\n\n .magicfeedback-action-container {\n flex-direction: column-reverse;\n }\n\n .magicfeedback-submit,\n .magicfeedback-back {\n width: 100%;\n text-align: center;\n min-height: 48px;\n }\n}\n\n/* ========================================\n ACCESSIBILITY\n ======================================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n\n/* ========================================\n UTILITY CLASSES\n ======================================== */\n.magicfeedback-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n\n.magicfeedback-modal-close {\n position: absolute;\n top: 8px;\n right: 8px;\n background: transparent;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n color: #666;\n}\n\n.magicfeedback-modal-close:hover,\n.magicfeedback-modal-close:focus {\n color: #000;\n outline: none;\n}\n\n/* ========================================\n FILE / IMAGE UPLOAD\n ======================================== */\n.magicfeedback-upload {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-md);\n width: 100%;\n margin: 10px 0;\n}\n\n/* The native input is an invisible, focusable overlay covering the dropzone. */\n.magicfeedback-upload-native {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n opacity: 0;\n cursor: pointer;\n z-index: 2;\n}\n\n.magicfeedback-upload-dropzone {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mf-space-sm);\n box-sizing: border-box;\n width: 100%;\n min-height: 150px;\n padding: var(--mf-space-xl);\n text-align: center;\n border: 2px dashed var(--mf-border);\n border-radius: var(--mf-radius-md);\n background-color: var(--mf-surface-alt);\n cursor: pointer;\n transition: var(--mf-transition);\n}\n\n.magicfeedback-upload-dropzone:hover {\n border-color: var(--mf-primary);\n background-color: var(--mf-bg-hover);\n}\n\n.magicfeedback-upload-dropzone:focus-within {\n border-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-focus);\n}\n\n.magicfeedback-upload-dropzone.is-dragover {\n border-color: var(--mf-primary);\n border-style: solid;\n background-color: var(--mf-primary-light);\n box-shadow: var(--mf-shadow-focus);\n}\n\n.magicfeedback-upload-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 46px;\n height: 46px;\n color: var(--mf-primary);\n background-color: var(--mf-surface);\n border-radius: var(--mf-radius-full);\n box-shadow: var(--mf-shadow-sm);\n pointer-events: none;\n}\n\n.magicfeedback-upload-icon svg {\n width: 24px;\n height: 24px;\n}\n\n.magicfeedback-upload-cta {\n font-family: inherit;\n font-weight: var(--mf-font-weight-semibold);\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-primary);\n pointer-events: none;\n}\n\n.magicfeedback-upload-hint {\n font-family: inherit;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-muted);\n pointer-events: none;\n}\n\n.magicfeedback-upload-list {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-sm);\n width: 100%;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.magicfeedback-upload-list:empty {\n display: none;\n}\n\n.magicfeedback-upload-file-item {\n display: flex;\n align-items: center;\n gap: var(--mf-space-md);\n padding: var(--mf-space-sm) var(--mf-space-md);\n background-color: var(--mf-surface);\n border: 1px solid var(--mf-border);\n border-radius: var(--mf-radius-sm);\n box-shadow: var(--mf-shadow-sm);\n animation: mf-scale-in 0.2s ease-out;\n}\n\n.magicfeedback-upload-thumb {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n overflow: hidden;\n color: var(--mf-text-secondary);\n background-color: var(--mf-surface-alt);\n border-radius: var(--mf-radius-sm);\n}\n\n.magicfeedback-upload-thumb img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.magicfeedback-upload-thumb svg {\n width: 20px;\n height: 20px;\n}\n\n.magicfeedback-upload-file-info {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-width: 0;\n text-align: start;\n}\n\n.magicfeedback-upload-file-name {\n font-family: inherit;\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.magicfeedback-upload-file-size {\n font-family: inherit;\n font-size: 0.75rem;\n color: var(--mf-text-muted);\n}\n\n.magicfeedback-upload-remove {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n color: var(--mf-text-muted);\n background-color: transparent;\n border: none;\n border-radius: var(--mf-radius-full);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-upload-remove:hover,\n.magicfeedback-upload-remove:focus-visible {\n color: var(--mf-error);\n background-color: var(--mf-primary-light);\n outline: none;\n}\n\n.magicfeedback-upload-remove svg {\n width: 16px;\n height: 16px;\n}\n\n.magicfeedback-upload-error {\n display: none;\n font-family: inherit;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-error);\n}\n\n.magicfeedback-upload-error.is-visible {\n display: block;\n}\n\n/* ========================================\n LOCAL — reglas del popup, no vienen del paquete\n ======================================== */\n\n/* Los controles de formulario no heredan font-family: cuando el popup trae fuente propia\n (clase deepdots-has-font), se les fuerza la del contenedor. */\n.deepdots-popup.deepdots-has-font button,\n.deepdots-popup.deepdots-has-font input,\n.deepdots-popup.deepdots-has-font textarea,\n.deepdots-popup.deepdots-has-font select {\n font-family: var(--deepdots-font, inherit);\n}\n\n/* WebKit sí aplica el padding al radio nativo: con padding el control se dibuja enorme (se vio\n en iOS, WebView de RN y Safari, no en Chrome). El paquete ya no lo pone, pero la regla es\n barata y evita que vuelva. */\n.deepdots-popup input[type=\"radio\"] {\n padding: 0;\n}\n","import type { DeepdotsLogger } from '../types';\n\n/**\n * Logger de módulo compartido: el core lo fija en init() con el logger inyectado\n * por el host (o `console` por defecto), y los módulos que no reciben `this`\n * (renderPopup, renderers) enrutan por aquí. `warn`/`error` caen a `log` si el\n * logger del host no los provee (solo `log` es obligatorio en DeepdotsLogger).\n */\nlet active: DeepdotsLogger = console;\n\nexport function setLogger(logger: DeepdotsLogger | undefined): void {\n active = logger ?? console;\n}\n\nexport function sdkLog(...args: unknown[]): void {\n active.log(...args);\n}\n\nexport function sdkWarn(...args: unknown[]): void {\n (active.warn ?? active.log)(...args);\n}\n\nexport function sdkError(...args: unknown[]): void {\n (active.error ?? active.log)(...args);\n}\n"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQA,IAAI,SAAyB;AAEtB,SAAS,UAAU,QAA0C;AAClE,WAAS,UAAU;AACrB;AAEO,SAAS,UAAU,MAAuB;AAC/C,SAAO,IAAI,GAAG,IAAI;AACpB;AAEO,SAAS,WAAW,MAAuB;AAChD,GAAC,OAAO,QAAQ,OAAO,KAAK,GAAG,IAAI;AACrC;AAEO,SAAS,YAAY,MAAuB;AACjD,GAAC,OAAO,SAAS,OAAO,KAAK,GAAG,IAAI;AACtC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracking/tracking-manager.ts","../src/ui/font.ts","../src/assets/style.css","../src/util/logger.ts"],"sourcesContent":["/**\n * Identidad + sesión para el tracking de navegación (Fase 1).\n * Implementa el \"Contrato común Web+KMP\".\n *\n * Modelo: el SDK gestiona el `user_id` (persistente). El `session_id` es propiedad\n * del BACKEND: llega en la respuesta de `POST /sdk/popups` y se cachea; el backend\n * cose sesiones por `user_id` + ventana. El SDK NO genera ni expira sesiones.\n *\n * Sin dependencias de DOM: recibe el storage y (opcionalmente) el reloj y el\n * generador de uuid por inyección. El binding a `localStorage` vive en `createDefaultStorage`.\n */\n\n/** Store clave/valor mínimo (espejo conceptual del `KeyValueStorage` de KMP). */\nexport interface KeyValueStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\n/** Impl en memoria — usada en tests y como fallback sin `localStorage`. */\nexport class InMemoryStorage implements KeyValueStorage {\n private map = new Map<string, string>();\n getItem(key: string): string | null {\n return this.map.has(key) ? (this.map.get(key) as string) : null;\n }\n setItem(key: string, value: string): void {\n this.map.set(key, value);\n }\n removeItem(key: string): void {\n this.map.delete(key);\n }\n}\n\n/** Storage por defecto en Web: `localStorage` si está disponible, si no in-memory. */\nexport function createDefaultStorage(): KeyValueStorage {\n try {\n if (typeof window !== 'undefined' && window.localStorage) {\n const ls = window.localStorage;\n const probe = '__deepdots_probe__';\n ls.setItem(probe, '1');\n ls.removeItem(probe);\n return {\n getItem: (k) => ls.getItem(k),\n setItem: (k, v) => ls.setItem(k, v),\n removeItem: (k) => ls.removeItem(k),\n };\n }\n } catch {\n // cae a in-memory\n }\n return new InMemoryStorage();\n}\n\n/** Claves de storage — namespace `deepdots.*`. Solo identidad (la sesión no se persiste). */\nexport const STORAGE_KEYS = {\n userId: 'deepdots.user_id',\n firstSeen: 'deepdots.user.first_seen',\n contactAttributes: 'deepdots.contact.attributes',\n} as const;\n\n/** Par clave/valor con el formato `NativeAnswer` que espera `@magicfeedback/native`. */\nexport interface IdentityAnswer {\n key: string;\n value: string[];\n}\n\n/**\n * Construye el `profile` y el `metadata` de identidad para inyectar en el survey\n * (`magicfeedback.form(appId, publicKey, profile, metadata)`), según el contrato §5.\n * `session_id` solo se incluye si el backend ya lo proveyó.\n */\nexport function buildSurveyIdentity(\n userId: string | null,\n sessionId: string | null,\n miniService: string | null = null,\n analyticsFeedbackSessionId: string | null = null,\n): { profile: IdentityAnswer[]; metadata: IdentityAnswer[] } {\n const profile: IdentityAnswer[] = userId ? [{ key: 'external-user-id', value: [userId] }] : [];\n const metadata: IdentityAnswer[] = [];\n if (sessionId) metadata.push({ key: 'session_id', value: [sessionId] });\n if (userId) metadata.push({ key: 'user_id', value: [userId] });\n if (miniService) metadata.push({ key: 'mini_service', value: [miniService] });\n if (analyticsFeedbackSessionId) metadata.push({ key: 'deepdots_analytics_feedback_session_id', value: [analyticsFeedbackSessionId] });\n return { profile, metadata };\n}\n\nexport interface TrackingManagerOptions {\n storage: KeyValueStorage;\n /** Id provisto por el cliente; si existe se usa y NO se persiste. */\n clientUserId?: string;\n /** Reloj inyectable (default `Date.now`). */\n now?: () => number;\n /** Generador de uuid inyectable (default uuid v4). */\n uuid?: () => string;\n /** Estado inicial del tracking (default `true`). */\n enabled?: boolean;\n}\n\nfunction defaultUuid(): string {\n const g = (typeof globalThis !== 'undefined' ? globalThis : {}) as {\n crypto?: { randomUUID?: () => string; getRandomValues?: (a: Uint8Array) => Uint8Array };\n };\n if (g.crypto?.randomUUID) return g.crypto.randomUUID();\n const bytes = new Uint8Array(16);\n if (g.crypto?.getRandomValues) {\n g.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0'));\n return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex\n .slice(6, 8)\n .join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10, 16).join('')}`;\n}\n\nexport class TrackingManager {\n private storage: KeyValueStorage;\n private clientUserId?: string;\n private now: () => number;\n private uuid: () => string;\n private enabled: boolean;\n\n /** session_id cacheado, provisto por el backend (no se genera ni se persiste). */\n private sessionId: string | null = null;\n private userWasJustCreated = false;\n\n constructor(options: TrackingManagerOptions) {\n this.storage = options.storage;\n this.clientUserId = options.clientUserId;\n this.now = options.now ?? (() => Date.now());\n this.uuid = options.uuid ?? defaultUuid;\n this.enabled = options.enabled ?? true;\n }\n\n isTrackingEnabled(): boolean {\n return this.enabled;\n }\n\n setTrackingEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n /** Resuelve el user_id según la regla: cliente > persistido > generar+persistir. */\n getUserId(): string | null {\n if (!this.enabled) return null;\n if (this.clientUserId) return this.clientUserId;\n\n const persisted = this.storage.getItem(STORAGE_KEYS.userId);\n if (persisted) return persisted;\n\n const id = this.uuid();\n this.storage.setItem(STORAGE_KEYS.userId, id);\n this.storage.setItem(STORAGE_KEYS.firstSeen, String(this.now()));\n this.userWasJustCreated = true;\n return id;\n }\n\n /** `true` solo en la primera sesión tras crear el user_id propio del SDK. */\n isNewUser(): boolean {\n return this.userWasJustCreated;\n }\n\n /** session_id actual provisto por el backend, o null si aún no llegó. */\n getSessionId(): string | null {\n if (!this.enabled) return null;\n return this.sessionId;\n }\n\n /** Cachea el session_id devuelto por el backend (respuesta de POST /sdk/popups). */\n setSessionId(sessionId: string | null): void {\n if (!this.enabled) return;\n this.sessionId = sessionId;\n }\n}\n","/**\n * Helpers puros (sin DOM) para la fuente personalizable del popup/survey.\n * Espejo exacto en KMP: `ui/Font.kt`. Cualquier cambio aquí se replica allí.\n */\n\nconst FORMAT_BY_EXT: Record<string, string> = {\n woff2: 'woff2',\n woff: 'woff',\n ttf: 'truetype',\n otf: 'opentype',\n};\n\n/** Deriva el `format()` del `@font-face` a partir de la extensión de la URL. */\nexport function fontFormatFromUrl(url: string): string | undefined {\n const clean = url.split('?')[0].split('#')[0];\n const ext = clean.slice(clean.lastIndexOf('.') + 1).toLowerCase();\n return FORMAT_BY_EXT[ext];\n}\n\n// family/url provienen de la API y se interpolan en CSS y en el <style> del HTML del WebView.\n// Saneamos para evitar romper el string/rule (CSS injection) o cerrar </style> (script injection).\nfunction sanitizeFamily(family: string): string {\n return family.replace(/[^A-Za-z0-9 ._-]/g, '').trim();\n}\n\nfunction isSafeFontUrl(url: string): boolean {\n // Solo http(s)/data y sin caracteres que rompan url(\"...\") o el <style>:\n // comillas, <>, backslash, y cualquier whitespace o carácter de control.\n if (!/^(https?:|data:)/i.test(url)) return false;\n // eslint-disable-next-line no-control-regex\n return !/[\\x00-\\x20\"<>\\\\]/.test(url);\n}\n\n/** Valor a aplicar en `font-family`: nombre custom + fallback de sistema. */\nexport function buildFontFamilyValue(family: string): string {\n const safe = sanitizeFamily(family);\n return `\"${safe}\", -apple-system, system-ui, sans-serif`;\n}\n\n/** CSS del `@font-face`. Devuelve \"\" si no hay url (o no es segura). */\nexport function buildFontFaceCss(family: string, url?: string): string {\n if (!url || !isSafeFontUrl(url)) return '';\n const safe = sanitizeFamily(family);\n const fmt = fontFormatFromUrl(url);\n const src = fmt ? `url(\"${url}\") format(\"${fmt}\")` : `url(\"${url}\")`;\n return `@font-face{font-family:\"${safe}\";src:${src};font-display:swap;}`;\n}\n","/**\n * NO EDITAR A MANO — generado por scripts/vendor-survey-css.mjs\n *\n * Copia de @magicfeedback/native@2.2.8 → dist/styles/magicfeedback-default.css\n * (la hoja canónica del paquete, la que apunta su campo \"style\"), con estos cambios locales:\n *\n * 1. Sin el @import de Google Fonts (Nunito): no queremos una petición externa desde la\n * página del host, y la tipografía la decide el popup.\n * 2. .magicfeedback-container hereda la fuente del popup (var(--deepdots-font, inherit)).\n * 3. Los selectores desnudos (h2, p, input, textarea, select, ::placeholder, .error) van\n * acotados a .deepdots-popup: este CSS se inyecta en el <head> del host y sin acotar\n * repintaría su web.\n * 4. El grupo .magicfeedback-radio se cualifica como div.magicfeedback-radio (la clase acaba\n * también en el <input> del boolean).\n * 5. Al final, un bloque de reglas propias del popup (fuente en los controles y padding del\n * radio nativo).\n *\n * Las variables --mf-* se dejan en :root a propósito: el modal del priority-list se portea a\n * <body>, fuera de .deepdots-popup, y ahí las necesita.\n *\n * Para subir de versión: npm i @magicfeedback/native@<v> && node scripts/vendor-survey-css.mjs\n */\n\n/**\n * @magicfeedback/native - Default Styles\n * Clean, minimal, and elegant survey rendering\n */\n\n/* @import de Google Fonts (Nunito) eliminado al vendorizar: la fuente la pone el popup. */\n\n/* ========================================\n CSS VARIABLES - Design SYSTEM\n ======================================== */\n:root {\n /* Colors - Minimal Pastel */\n /* --mf-primary is the one source of truth for brand/accent color —\n every token below derives from it via color-mix() (or references\n it directly) so changing this single value, here or via a\n per-integration override, keeps hover/light/border states in\n sync automatically instead of going stale independently. Scoped\n to genuinely interactive/accent surfaces (buttons, selected\n chips, focus rings) — general body text stays on its own neutral\n scale below, not tied to the brand color. */\n --mf-primary: #5d7bad;\n --mf-primary-hover: color-mix(in srgb, var(--mf-primary) 85%, black);\n --mf-primary-light: color-mix(in srgb, var(--mf-primary) 15%, white);\n /* a translucent tint — mixed with transparent (opacity), not white,\n so it reads as a soft shadow of the brand color rather than a\n pastel of it. */\n --mf-primary-border: color-mix(in srgb, var(--mf-primary) 35%, transparent);\n\n --mf-text-primary: #1E293B;\n --mf-text-secondary: #475569;\n --mf-text-muted: #94A3B8;\n\n --mf-bg-primary: #F8FAFC;\n --mf-bg-secondary: #FFFFFF;\n --mf-bg-hover: #EEF2F6;\n\n --mf-border: #E2E8F0;\n --mf-border-focus: var(--mf-primary);\n\n --mf-success: #16A34A;\n --mf-error: #EF4444;\n --mf-warning: #F59E0B;\n\n --mf-surface: #FFFFFF;\n --mf-surface-alt: #F1F5F9;\n --mf-accent: #38BDF8;\n\n /* Spacing */\n --mf-space-xs: 0.25rem;\n --mf-space-sm: 0.5rem;\n --mf-space-md: 0.75rem;\n --mf-space-lg: 1rem;\n --mf-space-xl: 1.5rem;\n\n /* Border Radius */\n --mf-radius-sm: 0.5rem;\n --mf-radius-md: 0.75rem;\n --mf-radius-lg: 1.25rem;\n --mf-radius-full: 9999px;\n\n /* Shadows */\n --mf-shadow-sm: 0 1px 2px 0 rgba(15, 23, 42, 0.06);\n --mf-shadow-md: 0 8px 20px rgba(15, 23, 42, 0.08);\n --mf-shadow-lg: 0 16px 30px rgba(15, 23, 42, 0.12);\n --mf-shadow-focus: 0 0 0 3px rgba(30, 41, 59, 0.15);\n --mf-shadow-card: 0 18px 40px rgba(15, 23, 42, 0.08);\n\n /* Typography */\n --mf-font-sans: \"Nunito\", \"Quicksand\", \"Avenir Next\", \"Trebuchet MS\", sans-serif;\n --mf-font-size-sm: 0.875rem;\n --mf-font-size-base: 1rem;\n --mf-font-size-lg: 1.125rem;\n --mf-font-size-xl: 1.25rem;\n --mf-line-height: 1.6;\n\n /* Font Weights */\n --mf-font-weight-normal: 400;\n --mf-font-weight-medium: 500;\n --mf-font-weight-semibold: 600;\n --mf-font-weight-bold: 700;\n --mf-font-weight-extrabold: 800;\n\n /* Transitions */\n --mf-transition: all 0.2s ease;\n --mf-transition-fast: all 0.15s ease;\n}\n\n/* ========================================\n ANIMATIONS\n ======================================== */\n@keyframes mf-fade-in {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes mf-slide-in {\n from {\n opacity: 0;\n transform: translateX(-16px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes mf-scale-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes mf-pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.8;\n }\n}\n\n/* ========================================\n BASE CONTAINER\n ======================================== */\n.magicfeedback-container {\n /* Local: hereda la fuente del popup; --deepdots-font viene de PopupStyle.font. */\n font-family: var(--deepdots-font, inherit);\n color: var(--mf-text-primary);\n line-height: var(--mf-line-height);\n animation: mf-fade-in 0.4s ease-out;\n border-radius: var(--mf-radius-lg);\n}\n\n/* ========================================\n MESSAGES\n ======================================== */\n.magicfeedback-success-message,\n.magicfeedback-info-message,\n.magicfeedback-start-message {\n padding: var(--mf-space-lg);\n margin: var(--mf-space-lg) 0;\n animation: mf-scale-in 0.3s ease-out;\n}\n\n/* .magicfeedback-info-message/-start-message are set via innerHTML (see\n renderInfoPage.ts / questions.service.ts's renderStartMessage) — whatever\n rich text a survey author writes lands here as real HTML, not just the\n <p>/<img> pair this used to style. Covering the rest of what a rich-text\n editor commonly outputs (headings, lists, links, emphasis, quotes, code,\n rules) keeps that content on the same type scale and palette as the rest\n of the widget instead of falling back to unstyled browser defaults. */\n.magicfeedback-success-message > :first-child,\n.magicfeedback-info-message > :first-child,\n.magicfeedback-start-message > :first-child {\n margin-top: 0;\n}\n\n.magicfeedback-success-message > :last-child,\n.magicfeedback-info-message > :last-child,\n.magicfeedback-start-message > :last-child {\n margin-bottom: 0;\n}\n\n.magicfeedback-success-message p,\n.magicfeedback-info-message p,\n.magicfeedback-start-message p {\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-secondary);\n margin: 0 0 var(--mf-space-md);\n line-height: var(--mf-line-height);\n}\n\n.magicfeedback-info-message h1,\n.magicfeedback-info-message h2,\n.magicfeedback-info-message h3,\n.magicfeedback-info-message h4,\n.magicfeedback-info-message h5,\n.magicfeedback-info-message h6,\n.magicfeedback-start-message h1,\n.magicfeedback-start-message h2,\n.magicfeedback-start-message h3,\n.magicfeedback-start-message h4,\n.magicfeedback-start-message h5,\n.magicfeedback-start-message h6 {\n color: var(--mf-text-primary);\n font-weight: var(--mf-font-weight-bold);\n line-height: 1.3;\n margin: var(--mf-space-lg) 0 var(--mf-space-sm);\n text-align: left;\n}\n\n.magicfeedback-info-message h1, .magicfeedback-start-message h1 { font-size: var(--mf-font-size-xl); }\n.magicfeedback-info-message h2, .magicfeedback-start-message h2 { font-size: var(--mf-font-size-lg); }\n.magicfeedback-info-message h3,\n.magicfeedback-info-message h4,\n.magicfeedback-info-message h5,\n.magicfeedback-info-message h6,\n.magicfeedback-start-message h3,\n.magicfeedback-start-message h4,\n.magicfeedback-start-message h5,\n.magicfeedback-start-message h6 { font-size: var(--mf-font-size-base); }\n\n.magicfeedback-info-message strong,\n.magicfeedback-info-message b,\n.magicfeedback-start-message strong,\n.magicfeedback-start-message b {\n font-weight: var(--mf-font-weight-bold);\n color: var(--mf-text-primary);\n}\n\n.magicfeedback-info-message a,\n.magicfeedback-start-message a {\n color: var(--mf-primary);\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n\n.magicfeedback-info-message a:hover,\n.magicfeedback-start-message a:hover {\n color: var(--mf-primary-hover);\n}\n\n.magicfeedback-info-message ul,\n.magicfeedback-info-message ol,\n.magicfeedback-start-message ul,\n.magicfeedback-start-message ol {\n margin: 0 0 var(--mf-space-md);\n padding-left: var(--mf-space-xl);\n color: var(--mf-text-secondary);\n line-height: var(--mf-line-height);\n}\n\n.magicfeedback-info-message li + li,\n.magicfeedback-start-message li + li {\n margin-top: var(--mf-space-xs);\n}\n\n.magicfeedback-info-message blockquote,\n.magicfeedback-start-message blockquote {\n margin: 0 0 var(--mf-space-md);\n padding: var(--mf-space-sm) var(--mf-space-md);\n border-left: 3px solid var(--mf-primary-border);\n color: var(--mf-text-secondary);\n font-style: italic;\n}\n\n.magicfeedback-info-message code,\n.magicfeedback-start-message code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.9em;\n background: var(--mf-bg-hover);\n padding: 0.15em 0.4em;\n border-radius: var(--mf-radius-sm);\n}\n\n.magicfeedback-info-message pre,\n.magicfeedback-start-message pre {\n margin: 0 0 var(--mf-space-md);\n padding: var(--mf-space-md);\n background: var(--mf-bg-hover);\n border-radius: var(--mf-radius-md);\n overflow-x: auto;\n}\n\n.magicfeedback-info-message pre code,\n.magicfeedback-start-message pre code {\n background: none;\n padding: 0;\n}\n\n.magicfeedback-info-message hr,\n.magicfeedback-start-message hr {\n border: none;\n border-top: 1px solid var(--mf-border);\n margin: var(--mf-space-lg) 0;\n}\n\n.magicfeedback-success-message img,\n.magicfeedback-info-message img,\n.magicfeedback-start-message img {\n max-width: 100%;\n height: auto;\n margin: var(--mf-space-lg) auto;\n display: block;\n border-radius: var(--mf-radius-md);\n}\n\n.magicfeedback-image {\n max-height: 400px;\n height: auto;\n max-width: 100%;\n margin: var(--mf-space-lg) auto;\n display: block;\n border-radius: var(--mf-radius-md);\n}\n\n/* ========================================\n FORM STRUCTURE\n ======================================== */\n.magicfeedback-form {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-lg);\n padding: clamp(16px, 2.5vw, 28px);\n}\n\n.magicfeedback-questions {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-xl);\n width: 100%;\n}\n\n.magicfeedback-div {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-sm);\n animation: mf-slide-in 0.3s ease-out;\n background: var(--mf-bg-secondary);\n border-radius: var(--mf-radius-md);\n}\n\n/* ========================================\n LABELS & TYPOGRAPHY\n ======================================== */\n.magicfeedback-label {\n font-size: var(--mf-font-size-lg);\n font-weight: var(--mf-font-weight-bold);\n color: var(--mf-text-primary);\n line-height: var(--mf-line-height);\n text-align: left;\n letter-spacing: -0.01em;\n}\n\n.magicfeedback-sublabel {\n font-size: var(--mf-font-size-base);\n font-weight: var(--mf-font-weight-normal);\n color: var(--mf-text-secondary);\n margin-bottom: var(--mf-space-sm);\n}\n\n.deepdots-popup h2 {\n font-size: var(--mf-font-size-xl);\n font-weight: 600;\n color: var(--mf-text-primary);\n margin: 0 0 var(--mf-space-xl) 0;\n text-align: center;\n letter-spacing: -0.01em;\n}\n\n.deepdots-popup p {\n margin: 0;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-secondary);\n}\n\n/* ========================================\n FORM INPUTS\n ======================================== */\n.deepdots-popup input[type=\"date\"],\n.deepdots-popup input[type=\"text\"],\n.deepdots-popup input[type=\"number\"],\n.deepdots-popup input[type=\"email\"],\n.deepdots-popup input[type=\"password\"],\n.deepdots-popup textarea,\n.deepdots-popup select {\n padding: 0.75rem 0.9rem;\n font-size: var(--mf-font-size-base);\n font-family: inherit;\n color: var(--mf-text-primary);\n background-color: var(--mf-surface);\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n outline: none;\n transition: var(--mf-transition);\n -webkit-appearance: none;\n appearance: none;\n box-shadow: var(--mf-shadow-sm);\n}\n\n.deepdots-popup textarea {\n min-height: 100px;\n resize: vertical;\n}\n\n.deepdots-popup input::placeholder,\n.deepdots-popup textarea::placeholder {\n color: var(--mf-text-muted);\n}\n\n/* Remove number input spinners */\n.deepdots-popup input::-webkit-outer-spin-button,\n.deepdots-popup input::-webkit-inner-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.deepdots-popup input[type=\"number\"] {\n /* -moz-appearance: textfield; removed for lint compatibility */\n}\n\n/* Custom Select Arrow */\n.deepdots-popup select {\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 9L1 4h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right var(--mf-space-md) center;\n padding-right: var(--mf-space-xl);\n}\n\n/* Error State */\n.deepdots-popup input.error,\n.deepdots-popup select.error,\n.deepdots-popup textarea.error {\n border-color: var(--mf-error);\n}\n\n.magicfeedback-error {\n margin-top: var(--mf-space-xs);\n font-size: var(--mf-font-size-sm);\n color: var(--mf-error);\n}\n\n/* ========================================\n CHECKBOX & RADIO OPTIONS\n ======================================== */\n.magicfeedback-checkbox,\ndiv.magicfeedback-radio {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-sm);\n width: 100%;\n}\n\n.magicfeedback-checkbox-container,\n.magicfeedback-radio-container {\n display: flex;\n align-items: center;\n gap: var(--mf-space-sm);\n padding: var(--mf-space-md);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-checkbox-container:hover,\n.magicfeedback-radio-container:hover {\n background-color: var(--mf-bg-hover);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-checkbox-container:has(input:checked),\n.magicfeedback-radio-container:has(input:checked) {\n background-color: var(--mf-primary-light);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-checkbox input[type=\"checkbox\"],\n.magicfeedback-radio-container input[type=\"radio\"] {\n width: 18px;\n height: 18px;\n margin: 0;\n cursor: pointer;\n flex-shrink: 0;\n accent-color: var(--mf-primary);\n}\n\n.magicfeedback-checkbox label,\n.magicfeedback-radio-container label {\n font-size: var(--mf-font-size-base);\n text-align: left;\n color: var(--mf-text-primary);\n cursor: pointer;\n margin: 0;\n flex: 1;\n}\n\n/* ========================================\n BOOLEAN OPTIONS\n ======================================== */\n.magicfeedback-boolean-container {\n display: flex;\n gap: var(--mf-space-md);\n width: 100%;\n}\n\n.magicfeedback-boolean-option {\n flex: 1;\n position: relative;\n}\n\n.magicfeedback-boolean-option input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-boolean-option label {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--mf-space-md);\n font-size: var(--mf-font-size-base);\n font-weight: 500;\n color: var(--mf-text-secondary);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n margin: 0;\n width: -webkit-fill-available;\n height: inherit;\n}\n\n.magicfeedback-boolean-option label:hover {\n background-color: var(--mf-bg-hover);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-boolean-option input[type=\"radio\"]:checked + label {\n color: var(--mf-primary);\n background-color: var(--mf-primary-light);\n border-color: var(--mf-primary);\n font-weight: 600;\n}\n\n/* ========================================\n RATING SYSTEMS\n ======================================== */\n.magicfeedback-rating,\n.magicfeedback-rating-number,\n.magicfeedback-rating-star {\n width: 100%;\n}\n\n.magicfeedback-rating-container,\n.magicfeedback-rating-number-container,\n.magicfeedback-rating-star-container {\n display: flex;\n flex-wrap: wrap;\n gap: var(--mf-space-sm);\n justify-content: center;\n align-items: center;\n padding: var(--mf-space-md) 0;\n list-style: none;\n margin: 0;\n}\n\n/* Caption line below the row — min on one side, max on the other (swapped\n for order: \"rtl\") — same simple, non-responsive pattern as the\n rating-number row caption. Used by rating-star and rating-emoji. */\n.magicfeedback-rating-placeholder {\n display: flex;\n justify-content: space-between;\n gap: var(--mf-space-md);\n width: 100%;\n margin-top: var(--mf-space-sm);\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-secondary);\n}\n\n.magicfeedback-rating-placeholder-value {\n overflow-wrap: anywhere;\n}\n\n.magicfeedback-rating-placeholder-value:last-child {\n text-align: right;\n}\n\n/* Rating with Images */\n.magicfeedback-rating-option-label-container input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-rating-option-label-container img {\n width: 56px;\n height: 56px;\n cursor: pointer;\n transition: var(--mf-transition-fast);\n border-radius: var(--mf-radius-full);\n border: 2px solid transparent;\n}\n\n.magicfeedback-rating-option-label-container img:hover {\n transform: scale(1.1);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-rating-option-label-container input[type=\"radio\"]:checked + img {\n border-color: var(--mf-primary);\n box-shadow: 0 0 0 3px var(--mf-primary-light);\n}\n\n.magicfeedback-rating-option-label-container label {\n display: block;\n text-align: center;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-secondary);\n margin-top: var(--mf-space-xs);\n cursor: pointer;\n}\n\n/* Rating Numbers — each option is its own outlined chip in the survey's\n primary color, with a gap between them. Row and column use the same\n chip; column additionally has room to show each option's own text\n plainly next to its number. */\n\n/* Every size here is width:100%/flex:1 combined with the chip's own\n padding and border. Without border-box, the browser's default\n content-box adds that padding/border on TOP of the declared size, so\n the chip quietly overflows past its flex slot — reading as \"not quite\n full width\" or, worse, pushing into the next chip. */\n.magicfeedback-rating-number-container,\n.magicfeedback-rating-number-option,\n.magicfeedback-rating-number-option-label-container,\n.magicfeedback-rating-number-value {\n box-sizing: border-box;\n}\n\n/* The shared rating-container rule (above, reused by star rating) sets\n align-items:center for its row-of-chips layout — in a stacked column\n that still nudges a 100%-wide chip inward instead of a true 0 offset.\n Force stretch so every chip fills the exact same width, flush on\n both sides. */\n.magicfeedback-rating-number-container-column,\n.magicfeedback-rating-number-container-column-reverse {\n align-items: stretch;\n}\n\n/* Caption line below the row — the single place min/max labels live\n for row mode, shared by mobile and desktop. */\n.magicfeedback-rating-number-scale-labels {\n display: flex;\n justify-content: space-between;\n gap: var(--mf-space-md);\n margin-top: var(--mf-space-sm);\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-secondary);\n}\n\n.magicfeedback-rating-number-scale-label {\n overflow-wrap: anywhere;\n}\n\n.magicfeedback-rating-number-scale-label:last-child {\n text-align: right;\n}\n\n/* Column, no per-option text: each row is its own separated chip, so\n the min/max labels bookend the stack from outside it — one line\n above the first chip, one below the last. Margin goes on whichever\n side actually faces the list — the \"before\" label (always the first\n child) gets space below it, the \"after\" one (always right after the\n container, extra option row or not) gets space above it — so both\n sit the same distance from the chips regardless of which one it is. */\n.magicfeedback-rating-number-scale-label-block {\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-secondary);\n text-align: center;\n}\n\n.magicfeedback-rating-number-scale-label-block:first-child {\n margin-bottom: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-container + .magicfeedback-rating-number-scale-label-block {\n margin-top: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option {\n display: flex;\n}\n\n.magicfeedback-rating-number-option-label-container {\n position: relative;\n width: 100%;\n display: flex;\n cursor: pointer;\n}\n\n.magicfeedback-rating-number-option-label-container input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-rating-number-value {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n transition: var(--mf-transition-fast);\n color: var(--mf-text-secondary);\n font-weight: var(--mf-font-weight-semibold);\n}\n\n/* Row: individual outlined chips in the survey's own primary color —\n var(--mf-primary) so whatever brand color a given survey sets carries\n through automatically, no color hardcoded here. */\n.magicfeedback-rating-number-container-row,\n.magicfeedback-rating-number-container-row-reverse {\n flex-wrap: nowrap;\n gap: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option-row,\n.magicfeedback-rating-number-option-row-reverse {\n flex: 1 1 0;\n min-width: 0;\n}\n\n.magicfeedback-rating-number-option-row .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-value {\n min-height: 56px;\n padding: var(--mf-space-sm);\n border: 2px solid var(--mf-primary-border);\n border-radius: var(--mf-radius-md);\n background: var(--mf-bg-secondary);\n color: var(--mf-primary);\n font-size: var(--mf-font-size-lg);\n font-weight: var(--mf-font-weight-bold);\n}\n\n/* More than 6 options (e.g. a 0-10 NPS scale): still one row, never\n wraps — but scaled down on purpose, so it reads as a compact chip\n rather than the same 56px button stretched thin. */\n.magicfeedback-rating-number-container-row--dense .magicfeedback-rating-number-option-row .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-container-row--dense .magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-value {\n min-height: 36px;\n padding: var(--mf-space-xs);\n border-radius: var(--mf-radius-sm);\n font-size: 0.8rem;\n}\n\n.magicfeedback-rating-number-option-row .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value {\n background: var(--mf-primary-light);\n}\n\n.magicfeedback-rating-number-option-row .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n/* Extra option: always its own row below the scale, and styled like every\n other chip now — \"doesn't apply\" is still not a point on the 1..N\n continuum, but it no longer needs a different border style to say so. */\n.magicfeedback-rating-number-extra-row {\n display: flex;\n justify-content: center;\n margin-top: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option--extra {\n flex: 0 1 auto;\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-option-label-container {\n width: auto;\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-value {\n min-height: 36px;\n padding: 0 var(--mf-space-md);\n border: 2px solid var(--mf-primary-border);\n border-radius: var(--mf-radius-md);\n background: var(--mf-bg-secondary);\n color: var(--mf-primary);\n font-size: var(--mf-font-size-sm);\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value {\n background: var(--mf-primary-light);\n}\n\n.magicfeedback-rating-number-option--extra .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n/* Column: the same separated chips as row, just stacked — each option is\n its own outlined chip with a gap between them, not one shared box. */\n.magicfeedback-rating-number-container-column,\n.magicfeedback-rating-number-container-column-reverse {\n gap: var(--mf-space-sm);\n}\n\n.magicfeedback-rating-number-option-column,\n.magicfeedback-rating-number-option-column-reverse {\n width: 100%;\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-value {\n justify-content: flex-start;\n gap: var(--mf-space-sm);\n min-height: 48px;\n padding: var(--mf-space-sm) var(--mf-space-md);\n border: 2px solid var(--mf-primary-border);\n border-radius: var(--mf-radius-md);\n background: var(--mf-bg-secondary);\n color: var(--mf-primary);\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-option-label-container:hover .magicfeedback-rating-number-value {\n background: var(--mf-primary-light);\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-rating-number-value-num {\n font-weight: var(--mf-font-weight-bold);\n}\n\n/* Column with per-option text: a min-width so \"1\"..\"9\" and \"10\" line up,\n with the label text starting at the same x. Skipped entirely when the\n column has no per-option text at all (--bare below) — with nothing to\n align against, the same left-shift bug from row mode would resurface. */\n.magicfeedback-rating-number-container-column:not(.magicfeedback-rating-number-container-column--bare) .magicfeedback-rating-number-value-num,\n.magicfeedback-rating-number-container-column-reverse:not(.magicfeedback-rating-number-container-column--bare) .magicfeedback-rating-number-value-num {\n flex: none;\n min-width: 1.4em;\n}\n\n/* Column, no per-option text at all (only min/max, or nothing): a bare\n numbered list has nothing to left-align against, so center each\n number instead of stranding it on the left with blank space beside it. */\n.magicfeedback-rating-number-container-column--bare .magicfeedback-rating-number-value {\n justify-content: center;\n}\n\n.magicfeedback-rating-number-value-label {\n font-weight: var(--mf-font-weight-medium);\n}\n\n.magicfeedback-rating-number-option-column .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value,\n.magicfeedback-rating-number-option-column-reverse .magicfeedback-rating-number-option-label-container input[type=\"radio\"]:checked + .magicfeedback-rating-number-value {\n color: #fff;\n background-color: var(--mf-primary);\n}\n\n/* Star Rating */\n.magicfeedback-rating-star-container {\n justify-content: center;\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star {\n font-size: 40px;\n color: var(--mf-border);\n cursor: pointer;\n margin: 0 var(--mf-space-xs);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover,\n.magicfeedback-rating-star-option:not(:checked) > .rating__star:hover ~ span {\n color: #fbbf24;\n transform: scale(1.1);\n}\n\n.magicfeedback-rating-star-selected {\n color: #fbbf24 !important;\n}\n\n/* ========================================\n MULTIPLE CHOICE WITH IMAGES\n ======================================== */\n.magicfeedback-multiple-choice-image-option {\n display: flex;\n border-radius: var(--mf-radius-md);\n overflow: hidden;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-image-option-label-container {\n cursor: pointer;\n border-radius: var(--mf-radius-md);\n overflow: hidden;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-image-option-label-container input[type=\"radio\"],\n.magicfeedback-image-option-label-container input[type=\"checkbox\"] {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.magicfeedback-image-option-label-container img {\n width: 100%;\n height: auto;\n display: block;\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-image-option-label-container:hover img {\n border-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-image-option-label-container input:checked + img {\n border-color: var(--mf-primary);\n box-shadow: 0 0 0 3px var(--mf-primary-light);\n}\n\n/* ========================================\n MATRIX QUESTIONS\n ======================================== */\n.magicfeedback-multi-question-matrix-container {\n width: 100%;\n overflow-x: auto;\n border-radius: var(--mf-radius-md);\n}\n\n.magicfeedback-multi-question-matrix-table {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0 var(--mf-space-xs);\n}\n\n.magicfeedback-multi-question-matrix-table th {\n padding: var(--mf-space-md);\n text-align: center;\n font-size: var(--mf-font-size-sm);\n font-weight: 500;\n color: var(--mf-text-secondary);\n}\n\n.magicfeedback-multi-question-matrix-row-tr {\n background-color: var(--mf-bg-primary);\n border-radius: var(--mf-radius-md);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-multi-question-matrix-row-tr:nth-child(even) {\n background-color: var(--mf-bg-secondary);\n}\n\n.magicfeedback-multi-question-matrix-row-tr:hover {\n background-color: var(--mf-bg-hover);\n box-shadow: var(--mf-shadow-sm);\n}\n\n.magicfeedback-multi-question-matrix-table td {\n padding: var(--mf-space-md);\n text-align: center;\n}\n\n.magicfeedback-multi-question-matrix-label {\n text-align: left;\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-primary);\n}\n\n.magicfeedback-multi-question-matrix-table input[type=\"radio\"] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mf-primary);\n}\n\n/* ========================================\n PRIORITY LIST\n ======================================== */\n.magicfeedback-priority-list-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mf-space-md);\n margin: var(--mf-space-sm) 0;\n background-color: var(--mf-bg-primary);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-priority-list-item:hover {\n box-shadow: var(--mf-shadow-sm);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-priority-list-item-label {\n flex: 1;\n font-size: var(--mf-font-size-base);\n text-align: left;\n color: var(--mf-text-primary);\n margin: 0;\n}\n\n.magicfeedback-priority-list-arrow-up,\n.magicfeedback-priority-list-arrow-down {\n padding: var(--mf-space-xs);\n font-size: var(--mf-font-size-lg);\n color: var(--mf-text-secondary);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n user-select: none;\n}\n\n.magicfeedback-priority-list-arrow-up:hover,\n.magicfeedback-priority-list-arrow-down:hover {\n color: var(--mf-primary);\n transform: scale(1.2);\n}\n\n/* ========================================\n POINT SYSTEM\n ======================================== */\n.magicfeedback-point-system-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mf-space-md);\n margin: var(--mf-space-sm) 0;\n background-color: var(--mf-bg-primary);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n min-height: 45px;\n}\n\n.magicfeedback-point-system-item label {\n flex: 1;\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-primary);\n margin: 0;\n}\n\n.magicfeedback-point-system-input-container {\n display: flex;\n align-items: center;\n gap: var(--mf-space-sm);\n}\n\n.magicfeedback-point-system-item input {\n width: 80px;\n min-width: 80px;\n padding: var(--mf-space-sm);\n text-align: center;\n font-size: var(--mf-font-size-base);\n border: 1.5px solid var(--mf-border);\n border-radius: var(--mf-radius-md);\n margin: 0;\n}\n\n.magicfeedback-point-system-total {\n display: flex;\n justify-content: flex-end;\n margin-top: var(--mf-space-md);\n font-size: var(--mf-font-size-base);\n font-weight: 600;\n color: var(--mf-text-primary);\n}\n\n/* ========================================\n CONSENT\n ======================================== */\n.magicfeedback-consent-container {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--mf-space-sm);\n padding: var(--mf-space-md);\n background-color: var(--mf-bg-secondary);\n border-radius: var(--mf-radius-md);\n margin: var(--mf-space-md) 0;\n}\n\n.magicfeedback-consent-container input[type=\"checkbox\"] {\n margin-top: 2px;\n flex-shrink: 0;\n accent-color: var(--mf-primary);\n}\n\n.magicfeedback-consent-container label {\n flex: 1;\n font-size: var(--mf-font-size-sm);\n text-align: left;\n color: var(--mf-text-secondary);\n line-height: var(--mf-line-height);\n cursor: pointer;\n margin-bottom: 0;\n}\n\n/* ========================================\n ACTION BUTTONS\n ======================================== */\n.magicfeedback-action-container {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mf-space-md);\n margin-top: var(--mf-space-xl);\n padding-top: var(--mf-space-lg);\n border-top: 1px solid var(--mf-border);\n}\n\n.magicfeedback-submit {\n padding: 0.8rem 1.6rem;\n font-size: var(--mf-font-size-base);\n font-weight: 800;\n color: #FFFFFF;\n background-color: var(--mf-primary);\n border: 2px solid var(--mf-primary);\n border-radius: var(--mf-radius-full);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-submit:hover {\n background-color: var(--mf-primary-hover);\n box-shadow: var(--mf-shadow-lg);\n transform: translateY(-2px);\n}\n\n.magicfeedback-submit:active {\n transform: translateY(0);\n box-shadow: var(--mf-shadow-sm);\n}\n\n.magicfeedback-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.magicfeedback-back {\n padding: 0.65rem 1rem;\n font-size: var(--mf-font-size-base);\n font-weight: 700;\n color: var(--mf-primary);\n background-color: var(--mf-bg-secondary);\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-full);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-back:hover {\n border-color: var(--mf-primary);\n background-color: var(--mf-bg-hover);\n}\n\n/* ========================================\n SKIP & COUNTER\n ======================================== */\n.magicfeedback-skip-container {\n display: flex;\n align-items: center;\n gap: var(--mf-space-xs);\n padding: 0;\n margin: 0;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-muted);\n background: transparent;\n border: none;\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-skip-container:hover {\n color: var(--mf-primary);\n}\n\n.magicfeedback-skip-container input[type=\"checkbox\"] {\n margin: 0;\n cursor: pointer;\n accent-color: var(--mf-primary);\n}\n\n.magicfeedback-counter {\n display: flex;\n justify-content: flex-end;\n margin-top: var(--mf-space-md);\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-muted);\n}\n\n/* ========================================\n MODAL STYLES\n ======================================== */\n/* Modal backdrop */\n.magicfeedback-modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0,0,0,0.4);\n display: none; /* toggled to flex when open */\n align-items: center;\n justify-content: center;\n z-index: 9999;\n}\n\n/* Modal container */\n.magicfeedback-modal {\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.2);\n max-width: 520px;\n width: 90%;\n max-height: 80vh;\n /* Flex column so the options list scrolls while the actions footer\n (counter + confirm button) stays pinned and always visible. */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n position: relative;\n /* Portalled to document.body (see renderPriorityList.ts) to escape the\n host page's overflow/z-index — so it never inherits\n .magicfeedback-container's neutral text color and instead inherits\n whatever color the host page's own <body> happens to set. Needs its\n own explicit baseline rather than relying on that inheritance. */\n color: var(--mf-text-primary);\n}\n\n/* Modal actions */\n.magicfeedback-modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 12px;\n flex-shrink: 0;\n}\n\n.magicfeedback-modal-counter {\n margin-right: auto;\n display: flex;\n align-items: center;\n font-size: 14px;\n color: var(--mf-text-secondary);\n}\n\n/* Modal list */\n.magicfeedback-modal-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n /* Scrollable area; footer stays fixed below it. */\n flex: 1 1 auto;\n overflow-y: auto;\n min-height: 0;\n}\n\n.magicfeedback-modal-row {\n display: flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n}\n\n/* Priority list header */\n.magicfeedback-priority-list-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 8px;\n}\n\n.magicfeedback-priority-list-reorder {\n margin-top: 8px;\n}\n\n.magicfeedback-priority-list-list {\n padding: 0;\n list-style: none;\n}\n\n.magicfeedback-priority-list-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin: 5px 0;\n}\n\n.magicfeedback-priority-list-item-label {\n font-size: 15px;\n}\n\n.magicfeedback-priority-list-arrows {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* Buttons */\n.magicfeedback-button {\n appearance: none;\n border: 2px solid var(--mf-border);\n border-radius: var(--mf-radius-full);\n background: var(--mf-bg-secondary);\n color: var(--mf-text-primary);\n padding: 0.6rem 1rem;\n font-size: 14px;\n font-weight: 700;\n cursor: pointer;\n box-shadow: var(--mf-shadow-sm);\n}\n\n.magicfeedback-button:hover {\n background: var(--mf-bg-hover);\n border-color: var(--mf-primary);\n}\n\n.magicfeedback-button:active {\n transform: translateY(1px);\n}\n\n.magicfeedback-button-primary {\n border-color: var(--mf-primary);\n background: var(--mf-primary);\n color: #fff;\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-button-primary:hover {\n background: var(--mf-primary-hover);\n}\n\n.magicfeedback-button-primary:active {\n background: var(--mf-primary-hover);\n}\n\n/* Warning flash */\n.magicfeedback-warning {\n color: #C70039;\n}\n\n/* Start message button */\n.magicfeedback-start-message-button {\n appearance: none;\n border: 2px solid var(--mf-primary);\n border-radius: var(--mf-radius-full);\n background: var(--mf-primary);\n color: #fff;\n padding: 0.8rem 1.4rem;\n font-size: 15px;\n font-weight: 800;\n cursor: pointer;\n box-shadow: var(--mf-shadow-md);\n}\n\n.magicfeedback-start-message-button:hover {\n background: var(--mf-primary-hover);\n}\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n@media (max-width: 768px) {\n :root {\n --mf-space-lg: 1.25rem;\n --mf-space-xl: 1.5rem;\n }\n\n .magicfeedback-container {\n padding: 12px;\n border-radius: var(--mf-radius-md);\n }\n\n .magicfeedback-form {\n padding: 14px;\n border-radius: var(--mf-radius-md);\n }\n\n .magicfeedback-div {\n padding: 12px;\n gap: var(--mf-space-lg)\n }\n\n .magicfeedback-label {\n font-size: var(--mf-font-size-base);\n }\n\n .deepdots-popup input[type=\"date\"],\n .deepdots-popup input[type=\"text\"],\n .deepdots-popup input[type=\"number\"],\n .deepdots-popup input[type=\"email\"],\n .deepdots-popup input[type=\"password\"],\n .deepdots-popup textarea,\n .deepdots-popup select {\n padding: 0.85rem 0.95rem;\n font-size: 1rem;\n min-height: 46px;\n }\n\n /*\n .magicfeedback-radio-container,\n .magicfeedback-checkbox-container,\n .magicfeedback-boolean-container,\n .magicfeedback-consent-container {\n width: 100%;\n }\n */\n\n .magicfeedback-radio-container,\n .magicfeedback-checkbox-container {\n padding: 10px 12px;\n border-radius: var(--mf-radius-md);\n border: 1px solid var(--mf-border);\n gap: 10px;\n }\n\n .magicfeedback-rating-container,\n .magicfeedback-rating-number-container,\n .magicfeedback-rating-star-container {\n gap: 10px;\n }\n\n .magicfeedback-boolean-container {\n flex-direction: column;\n gap: 10px;\n }\n\n .magicfeedback-rating-number-container-row,\n .magicfeedback-rating-number-container-row-reverse {\n gap: 6px;\n }\n\n .magicfeedback-rating-number-option-row .magicfeedback-rating-number-value,\n .magicfeedback-rating-number-option-row-reverse .magicfeedback-rating-number-value {\n min-height: 44px;\n padding: var(--mf-space-xs);\n font-size: 0.9rem;\n }\n\n .magicfeedback-action-container {\n flex-direction: column-reverse;\n }\n\n .magicfeedback-submit,\n .magicfeedback-back {\n width: 100%;\n text-align: center;\n min-height: 48px;\n }\n}\n\n/* ========================================\n ACCESSIBILITY\n ======================================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n\n/* ========================================\n UTILITY CLASSES\n ======================================== */\n.magicfeedback-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n\n.magicfeedback-modal-close {\n position: absolute;\n top: 8px;\n right: 8px;\n background: transparent;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n color: #666;\n}\n\n.magicfeedback-modal-close:hover,\n.magicfeedback-modal-close:focus {\n color: #000;\n outline: none;\n}\n\n/* ========================================\n FILE / IMAGE UPLOAD\n ======================================== */\n.magicfeedback-upload {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-md);\n width: 100%;\n margin: 10px 0;\n}\n\n/* The native input is an invisible, focusable overlay covering the dropzone. */\n.magicfeedback-upload-native {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n opacity: 0;\n cursor: pointer;\n z-index: 2;\n}\n\n.magicfeedback-upload-dropzone {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mf-space-sm);\n box-sizing: border-box;\n width: 100%;\n min-height: 150px;\n padding: var(--mf-space-xl);\n text-align: center;\n border: 2px dashed var(--mf-border);\n border-radius: var(--mf-radius-md);\n background-color: var(--mf-surface-alt);\n cursor: pointer;\n transition: var(--mf-transition);\n}\n\n.magicfeedback-upload-dropzone:hover {\n border-color: var(--mf-primary);\n background-color: var(--mf-bg-hover);\n}\n\n.magicfeedback-upload-dropzone:focus-within {\n border-color: var(--mf-primary);\n box-shadow: var(--mf-shadow-focus);\n}\n\n.magicfeedback-upload-dropzone.is-dragover {\n border-color: var(--mf-primary);\n border-style: solid;\n background-color: var(--mf-primary-light);\n box-shadow: var(--mf-shadow-focus);\n}\n\n.magicfeedback-upload-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 46px;\n height: 46px;\n color: var(--mf-primary);\n background-color: var(--mf-surface);\n border-radius: var(--mf-radius-full);\n box-shadow: var(--mf-shadow-sm);\n pointer-events: none;\n}\n\n.magicfeedback-upload-icon svg {\n width: 24px;\n height: 24px;\n}\n\n.magicfeedback-upload-cta {\n font-family: inherit;\n font-weight: var(--mf-font-weight-semibold);\n font-size: var(--mf-font-size-base);\n color: var(--mf-text-primary);\n pointer-events: none;\n}\n\n.magicfeedback-upload-hint {\n font-family: inherit;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-text-muted);\n pointer-events: none;\n}\n\n.magicfeedback-upload-list {\n display: flex;\n flex-direction: column;\n gap: var(--mf-space-sm);\n width: 100%;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.magicfeedback-upload-list:empty {\n display: none;\n}\n\n.magicfeedback-upload-file-item {\n display: flex;\n align-items: center;\n gap: var(--mf-space-md);\n padding: var(--mf-space-sm) var(--mf-space-md);\n background-color: var(--mf-surface);\n border: 1px solid var(--mf-border);\n border-radius: var(--mf-radius-sm);\n box-shadow: var(--mf-shadow-sm);\n animation: mf-scale-in 0.2s ease-out;\n}\n\n.magicfeedback-upload-thumb {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n overflow: hidden;\n color: var(--mf-text-secondary);\n background-color: var(--mf-surface-alt);\n border-radius: var(--mf-radius-sm);\n}\n\n.magicfeedback-upload-thumb img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.magicfeedback-upload-thumb svg {\n width: 20px;\n height: 20px;\n}\n\n.magicfeedback-upload-file-info {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-width: 0;\n text-align: start;\n}\n\n.magicfeedback-upload-file-name {\n font-family: inherit;\n font-size: var(--mf-font-size-sm);\n font-weight: var(--mf-font-weight-semibold);\n color: var(--mf-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.magicfeedback-upload-file-size {\n font-family: inherit;\n font-size: 0.75rem;\n color: var(--mf-text-muted);\n}\n\n.magicfeedback-upload-remove {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n color: var(--mf-text-muted);\n background-color: transparent;\n border: none;\n border-radius: var(--mf-radius-full);\n cursor: pointer;\n transition: var(--mf-transition-fast);\n}\n\n.magicfeedback-upload-remove:hover,\n.magicfeedback-upload-remove:focus-visible {\n color: var(--mf-error);\n background-color: var(--mf-primary-light);\n outline: none;\n}\n\n.magicfeedback-upload-remove svg {\n width: 16px;\n height: 16px;\n}\n\n.magicfeedback-upload-error {\n display: none;\n font-family: inherit;\n font-size: var(--mf-font-size-sm);\n color: var(--mf-error);\n}\n\n.magicfeedback-upload-error.is-visible {\n display: block;\n}\n\n/* ========================================\n LOCAL — reglas del popup, no vienen del paquete\n ======================================== */\n\n/* Los controles de formulario no heredan font-family: cuando el popup trae fuente propia\n (clase deepdots-has-font), se les fuerza la del contenedor. */\n.deepdots-popup.deepdots-has-font button,\n.deepdots-popup.deepdots-has-font input,\n.deepdots-popup.deepdots-has-font textarea,\n.deepdots-popup.deepdots-has-font select {\n font-family: var(--deepdots-font, inherit);\n}\n\n/* WebKit sí aplica el padding al radio nativo: con padding el control se dibuja enorme (se vio\n en iOS, WebView de RN y Safari, no en Chrome). El paquete ya no lo pone, pero la regla es\n barata y evita que vuelva. */\n.deepdots-popup input[type=\"radio\"] {\n padding: 0;\n}\n","import type { DeepdotsLogger } from '../types';\n\n/**\n * Logger de módulo compartido: el core lo fija en init() con el logger inyectado\n * por el host (o `console` por defecto), y los módulos que no reciben `this`\n * (renderPopup, renderers) enrutan por aquí. `warn`/`error` caen a `log` si el\n * logger del host no los provee (solo `log` es obligatorio en DeepdotsLogger).\n */\nlet active: DeepdotsLogger = console;\n\nexport function setLogger(logger: DeepdotsLogger | undefined): void {\n active = logger ?? console;\n}\n\nexport function sdkLog(...args: unknown[]): void {\n active.log(...args);\n}\n\nexport function sdkWarn(...args: unknown[]): void {\n (active.warn ?? active.log)(...args);\n}\n\nexport function sdkError(...args: unknown[]): void {\n (active.error ?? active.log)(...args);\n}\n"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQA,IAAI,SAAyB;AAEtB,SAAS,UAAU,QAA0C;AAClE,WAAS,UAAU;AACrB;AAEO,SAAS,UAAU,MAAuB;AAC/C,SAAO,IAAI,GAAG,IAAI;AACpB;AAEO,SAAS,WAAW,MAAuB;AAChD,GAAC,OAAO,QAAQ,OAAO,KAAK,GAAG,IAAI;AACrC;AAEO,SAAS,YAAY,MAAuB;AACjD,GAAC,OAAO,SAAS,OAAO,KAAK,GAAG,IAAI;AACtC;","names":[]}
|