WhatsApp Button
Opens a WhatsApp chat — Atom’s contact path, never a form. Inline, pill, or icon with a sliding icon on hover.
Variants: inlinepillicon (default: inline)
Sizes: xssmlxl (default: xs)
Editorial
<!-- F12c editorial — non-derivable only. Review: Karen. -->
## Ejemplos
```html <!-- Un script tag, cero dependencias --> <script src="https://atom-whatsapp-buttons.vercel.app/v1/loader.js" data-company-token="<token-de-la-cuenta-AtomChat>" data-phone="521XXXXXXXXXX" data-cta="Hola, quiero informacion" defer ></script> ```
## Criterio de uso
- Es un canal de contacto, no un CTA decorativo: ponlo donde la conversacion es el siguiente paso natural, no en cada pagina por inercia. - El mensaje pre-llenado (`data-cta`) debe dar contexto de DONDE viene el lead; un "Hola" generico pierde la unica atribucion gratis que da el canal. - El numero incluye codigo de pais sin signos: la cascada por idioma/region se resuelve en la configuracion del widget, no duplicando botones.
## Accesibilidad
- El boton flotante no debe tapar acciones fijas del layout (barras inferiores en movil); revisa la superposicion antes de publicar. - Como abre una aplicacion externa, el destino debe ser evidente desde el rotulo: quien lo pulsa esta saliendo del sitio.
## Gotchas
- **Nota**: `data-company-token` identifica la cuenta de AtomChat que recibe los leads. Un cliente externo usa el token que AtomChat le asigne, no el de Atom. - **Nota**: el webhook de atribucion se envia fire-and-forget. Si falla, WhatsApp abre igual — el usuario nunca ve el error. - **Ojo**: el SDK se sirve desde dominio propio a proposito (inmune a adblockers). Reempaquetarlo en un bundle de terceros pierde esa propiedad. - **Ojo**: en Webflow el loader engancha `[data-atom-button]`; un boton del DS que no lleve ese atributo no queda cableado aunque se vea igual.
## Cuándo no usar
- Formularios de captura con datos estructurados → un form real; WhatsApp no valida ni almacena campos. - Soporte con SLA o historial de tickets → herramienta de soporte, no un chat personal. - Publico sin WhatsApp instalado (desktop sin sesion web) → ofrece ademas correo o telefono; el enlace no degrada solo.
Uso
<!-- Prefer published CSS + anchor from the registry item for marketing pages --> <a class="whatsapp-button whatsapp-button--pill whatsapp-button--m" href="https://wa.me/15551234567">Chat on WhatsApp</a>
Gotchas
- react
WhatsApp Button is CSS/registry oriented for marketing embeds; prefer LinkButton or Button patterns in app React when you need full TS props.
- a11y
Link must open a real wa.me / api.whatsapp.com URL; never fake the chat with javascript:void.
Anatomía CSS
<div class="elementor-kit-N"> </div>
| Clase | Propósito |
|---|---|
elementor-kit-N | root |
Tokens resueltos
Valores finales tras seguir la cadena de tokens. Derivados del source: si un token cambia, esta tabla cambia sola.
| Variante | Prop | Valor | Token |
|---|---|---|---|
| all | fg | #fafafa | whatsapp.foreground |
| all | hover-fg | #fafafa | whatsapp.foreground |
| all | focused-fg | #fafafa | whatsapp.foreground |
| all | pressed-fg | #fafafa | whatsapp.foreground |
| all | bg | #25d366 | whatsapp |
| all | border | none | (unparsed) |
| all | hover-bg | #25d366 | whatsapp |
| all | pressed-bg | #25d366 | whatsapp |
Animaciones
| Propiedad | Duración | Easing |
|---|---|---|
box-shadow | 0.3s | cubic-bezier(0.32 |
0.72 | | |
0 | | |
1) | | |
background-color | 0.3s | cubic-bezier(0 |
0 | | |
0.2 | | |
1) | | |
scale | 0.15s | cubic-bezier(0.4 |
0 | | |
0.2 | | |
1) | | |
translate | 0.5s | cubic-bezier(0.32 |
0.72 | | |
0 | | |
1) | | |
opacity | 0.15s | ease-out |
translate | 0.5s | cubic-bezier(0.32 |
0.72 | | |
0 | | |
1) | | |
translate | 0.5s | 0.075s cubic-bezier(0.32 |
0.72 | | |
0 | | |
1) | | |
translate | 0.5s | 0.075s cubic-bezier(0.32 |
0.72 | | |
0 | | |
1) | | |
opacity | 0.15s | 0.075s ease-out |
translate | 0.5s | 0.05s cubic-bezier(0.32 |
0.72 | | |
0 | | |
1) | | |
opacity | 0.15s | 0.075s ease-out |
CSS mínimo funcional
Autocontenido: sin imports ni tokens. Para previews y prototipos — en producción se consume el CSS del DS (@atom-uikit/css/components.css</code>, <code>@atom-uikit/tokens/tokens.css).
/* ============================================================================
ARCHIVO GENERADO — NO EDITAR A MANO.
Fuente única de verdad: https://atom-whatsapp-buttons.vercel.app/v1/styles.css
(repo AtomGrowth/atom_whatsapp_buttons — su spec/ documenta cada decisión)
Para actualizar: pnpm --filter @atom-uikit/css sync:whatsapp
============================================================================ */
/* -------------------------------------------------------------------------
WhatsApp Button — hoja de estilos
Atom convierte por WhatsApp, nunca por formulario. Este es el CTA de contacto
para CUALQUIER accion de "hablar con nosotros / agendar demo / ventas / soporte".
Fuente unica de verdad de la capa visual: la consumen los DOS caminos.
- El SDK (src/ui/render.ts) genera este mismo markup por JS.
- Un landing puede escribir el <a> a mano y cargar solo este CSS, sin JS.
Variantes: --inline (estatico, en el flujo) | --pill (flotante fijo) | --icon
(flotante fijo, circulo, solo icono). Tamanos: xs s m l xl.
--animated agrega el deslizamiento del icono en hover (patron button-009).
Uso estatico (inline, el CTA del landing):
<a class="atom-wa-btn atom-wa-btn--inline atom-wa-btn--m atom-wa-btn--animated"
href="https://wa.me/<PHONE>?text=<MENSAJE_URL_ENCODED>"
data-atom-button
aria-label="Hablar por WhatsApp">
<span class="atom-wa-btn__inner">
<span class="atom-wa-btn__icon is--left"><svg>...</svg></span>
<span class="atom-wa-btn__label">Hablar por WhatsApp</span>
<span class="atom-wa-btn__icon is--right"><svg>...</svg></span>
</span>
<span class="atom-wa-btn__bg"></span>
</a>
El data-atom-button es lo que engancha el tracking cuando el SDK corre en
modo attach. Sin el, el boton sigue funcionando pero el lead no se atribuye.
------------------------------------------------------------------------- */
/* --whatsapp y --whatsapp-foreground viven en la capa semantica desde 2026-08-17
(semantic/light.json y dark.json). Estaban declarados aqui como literales, asi
que no entraban en el plan de sync y no existian como Variables en Webflow: el
canal reconstruia el boton con success/success-foreground y el texto salia
negro. Los fallbacks conservan el boton si alguien carga SOLO este archivo. */
/* -- Blindaje contra kits de tema --
Los site kits (Elementor: `.elementor-kit-N a:hover`, etc.) estilan TODOS los <a> del sitio con
especificidad (0,2,1), que gana a `.atom-wa-btn` (0,1,0) y pinta el texto del boton del color
del tema. La clase doblada + el tipo sube a (0,3,x) y recupera las propiedades heredables en
todos los estados. Sin !important: un host que necesite ganar a proposito, puede. */
a.atom-wa-btn.atom-wa-btn,
a.atom-wa-btn.atom-wa-btn:hover,
a.atom-wa-btn.atom-wa-btn:focus,
a.atom-wa-btn.atom-wa-btn:active,
a.atom-wa-btn.atom-wa-btn:visited {
color: #fafafa;
text-decoration: none;
}
/* -- Base: grid para la capa de fondo -- */
.atom-wa-btn {
color: #fafafa;
-webkit-user-select: none;
user-select: none;
background-color: transparent;
outline-style: none;
padding: 0;
border: none;
line-height: 1;
text-decoration: none;
display: inline-grid;
position: relative;
-webkit-tap-highlight-color: transparent;
cursor: pointer;
font-family: 'inter tight', -apple-system, blinkmacsystemfont, 'segoe ui', roboto, helvetica, arial, sans-serif, ui-sans-serif, system-ui, sans-serif;
font-weight: 500;
}
/* -- Anillo de foco (pseudo, por fuera del bg) -- */
.atom-wa-btn::after {
content: '';
display: block;
position: absolute;
inset: -2px;
border-radius: 0.75em;
transition: box-shadow 0.3s cubic-bezier(0.32, 0.72, 0, 1);
pointer-events: none;
z-index: 1;
}
.atom-wa-btn:focus-visible::after {
box-shadow: 0 0 0 2px #25d366;
}
/* -- Capa de fondo -- */
.atom-wa-btn__bg {
background-color: #25d366;
border-radius: 0.625em;
grid-area: 1 / 1;
width: 100%;
height: 100%;
transition: background-color 0.3s cubic-bezier(0, 0, 0.2, 1);
}
.atom-wa-btn:hover .atom-wa-btn__bg {
background-color: color-mix(in srgb, #25d366 88%, #000);
}
.atom-wa-btn:active:not([aria-busy='true']) .atom-wa-btn__bg {
background-color: color-mix(in srgb, #25d366 78%, #000);
}
/* -- Inner: contenedor del contenido con recorte -- */
.atom-wa-btn__inner {
pointer-events: none;
gap: 0.375em;
padding: 0.75em 0.75em 0.75em 1em;
z-index: 1;
border-radius: 0.625em;
overflow: clip;
grid-area: 1 / 1;
justify-content: center;
align-items: center;
display: flex;
position: relative;
}
/* -- Icono -- */
.atom-wa-btn__icon {
width: 0.875em;
height: 0.875em;
flex: none;
}
.atom-wa-btn__icon svg {
width: 100%;
height: 100%;
}
/* -- Label -- */
.atom-wa-btn__label {
flex: none;
white-space: nowrap;
}
/* -- Tamanos (en em, escalan con el font-size) -- */
.atom-wa-btn--xs { font-size: 11px; }
.atom-wa-btn--s { font-size: 13px; }
.atom-wa-btn--m { font-size: 14px; }
.atom-wa-btn--l { font-size: 16px; }
.atom-wa-btn--xl { font-size: 18px; }
/* -- Variante: pill (fija, flotante) -- */
.atom-wa-btn--pill {
position: fixed;
right: 20px;
bottom: 20px;
z-index: 9999;
}
.atom-wa-btn--pill .atom-wa-btn__bg {
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
}
.atom-wa-btn--pill:hover .atom-wa-btn__bg {
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
}
/* -- Variante: icon (fija, flotante, circulo, solo icono) -- */
.atom-wa-btn--icon {
position: fixed;
right: 20px;
bottom: 20px;
z-index: 9999;
}
.atom-wa-btn--icon .atom-wa-btn__bg {
border-radius: 999px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
}
.atom-wa-btn--icon:hover .atom-wa-btn__bg {
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
}
.atom-wa-btn--icon .atom-wa-btn__inner {
border-radius: 999px;
padding: 0.75em;
}
.atom-wa-btn--icon .atom-wa-btn__label,
.atom-wa-btn--icon .atom-wa-btn__icon.is--left {
display: none;
}
/* -- Variante: inline (estatica, en el flujo del documento — el CTA del landing) -- */
.atom-wa-btn--inline {
position: static;
z-index: auto;
}
/* -- Modificador: flotante anclado a la izquierda -- */
.atom-wa-btn--left {
right: auto;
left: 20px;
}
/* ================================================================
ANIMATED — deslizamiento del icono (patron button-009)
Reposo: [texto] [icono-derecha visible]
Hover: [icono-izquierda entra] [texto se desplaza]
================================================================ */
/* Sin animacion: icono a la IZQUIERDA del texto (sobra el derecho). Se excluye --icon, que ya
tiene su propia logica de un solo icono. */
.atom-wa-btn:not(.atom-wa-btn--animated):not(.atom-wa-btn--icon) .atom-wa-btn__icon.is--right {
display: none;
}
/* El padding base (1em izquierda) esta pensado para [texto][icono]; invertido, se refleja. */
.atom-wa-btn:not(.atom-wa-btn--animated):not(.atom-wa-btn--icon) .atom-wa-btn__inner {
padding: 0.75em 1em 0.75em 0.75em;
}
.atom-wa-btn--animated {
transition: scale 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}
.atom-wa-btn--animated:active:not([aria-busy='true']) {
scale: 0.955 0.925;
}
.atom-wa-btn--animated .atom-wa-btn__icon {
transition: translate 0.5s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s ease-out;
}
.atom-wa-btn--animated .atom-wa-btn__label {
transition: translate 0.5s cubic-bezier(0.32, 0.72, 0, 1);
}
.atom-wa-btn--animated .atom-wa-btn__icon.is--left {
position: absolute;
left: 1em;
opacity: 0;
translate: -1.5em 0 0;
}
.atom-wa-btn--animated .atom-wa-btn__icon.is--right {
opacity: 1;
translate: 0 0 0;
}
.atom-wa-btn--animated:is(:hover, :focus-visible) .atom-wa-btn__label {
translate: calc(0.875em + 0.375em + 0.75em - 1em) 0 0;
transition: translate 0.5s 0.075s cubic-bezier(0.32, 0.72, 0, 1);
}
.atom-wa-btn--animated:is(:hover, :focus-visible) .atom-wa-btn__icon.is--left {
translate: 0 0 0;
opacity: 1;
transition: translate 0.5s 0.075s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s 0.075s ease-out;
}
.atom-wa-btn--animated:is(:hover, :focus-visible) .atom-wa-btn__icon.is--right {
translate: 1.5em 0 0;
opacity: 0;
transition: translate 0.5s 0.05s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s 0.075s ease-out;
}
/* -- Responsive: el pill flotante colapsa a icono en movil -- */
@media (max-width: 480px) {
.atom-wa-btn--pill .atom-wa-btn__label { display: none; }
.atom-wa-btn--pill .atom-wa-btn__icon.is--left { display: none; }
.atom-wa-btn--pill .atom-wa-btn__inner { padding: 0.75em; }
.atom-wa-btn--pill .atom-wa-btn__bg { border-radius: 999px; }
/* Pill sin animacion: su icono visible es el izquierdo (regla de arriba), asi que el colapso
movil lo recupera — sin esto quedaria un circulo vacio. */
.atom-wa-btn--pill:not(.atom-wa-btn--animated) .atom-wa-btn__icon.is--left { display: flex; }
}
/* -- Movimiento reducido -- */
@media (prefers-reduced-motion: reduce) {
.atom-wa-btn,
.atom-wa-btn .atom-wa-btn__icon,
.atom-wa-btn .atom-wa-btn__label { transition-duration: 0ms !important; }
.atom-wa-btn--animated:active { scale: 1; }
}
Codigo fuente
/* ============================================================================ ARCHIVO GENERADO — NO EDITAR A MANO. Fuente única de verdad: https://atom-whatsapp-buttons.vercel.app/v1/styles.css (repo AtomGrowth/atom_whatsapp_buttons — su spec/ documenta cada decisión) Para actualizar: pnpm --filter @atom-uikit/css sync:whatsapp ============================================================================ */ /* ------------------------------------------------------------------------- WhatsApp Button — hoja de estilos Atom convierte por WhatsApp, nunca por formulario. Este es el CTA de contacto para CUALQUIER accion de "hablar con nosotros / agendar demo / ventas / soporte". Fuente unica de verdad de la capa visual: la consumen los DOS caminos. - El SDK (src/ui/render.ts) genera este mismo markup por JS. - Un landing puede escribir el <a> a mano y cargar solo este CSS, sin JS. Variantes: --inline (estatico, en el flujo) | --pill (flotante fijo) | --icon (flotante fijo, circulo, solo icono). Tamanos: xs s m l xl. --animated agrega el deslizamiento del icono en hover (patron button-009). Uso estatico (inline, el CTA del landing): <a class="atom-wa-btn atom-wa-btn--inline atom-wa-btn--m atom-wa-btn--animated" href="https://wa.me/<PHONE>?text=<MENSAJE_URL_ENCODED>" data-atom-button aria-label="Hablar por WhatsApp"> <span class="atom-wa-btn__inner"> <span class="atom-wa-btn__icon is--left"><svg>...</svg></span> <span class="atom-wa-btn__label">Hablar por WhatsApp</span> <span class="atom-wa-btn__icon is--right"><svg>...</svg></span> </span> <span class="atom-wa-btn__bg"></span> </a> El data-atom-button es lo que engancha el tracking cuando el SDK corre en modo attach. Sin el, el boton sigue funcionando pero el lead no se atribuye. ------------------------------------------------------------------------- */ /* --whatsapp y --whatsapp-foreground viven en la capa semantica desde 2026-08-17 (semantic/light.json y dark.json). Estaban declarados aqui como literales, asi que no entraban en el plan de sync y no existian como Variables en Webflow: el canal reconstruia el boton con success/success-foreground y el texto salia negro. Los fallbacks conservan el boton si alguien carga SOLO este archivo. */ /* -- Blindaje contra kits de tema -- Los site kits (Elementor: `.elementor-kit-N a:hover`, etc.) estilan TODOS los <a> del sitio con especificidad (0,2,1), que gana a `.atom-wa-btn` (0,1,0) y pinta el texto del boton del color del tema. La clase doblada + el tipo sube a (0,3,x) y recupera las propiedades heredables en todos los estados. Sin !important: un host que necesite ganar a proposito, puede. */ a.atom-wa-btn.atom-wa-btn, a.atom-wa-btn.atom-wa-btn:hover, a.atom-wa-btn.atom-wa-btn:focus, a.atom-wa-btn.atom-wa-btn:active, a.atom-wa-btn.atom-wa-btn:visited { color: var(--whatsapp-foreground, #ffffff); text-decoration: none; } /* -- Base: grid para la capa de fondo -- */ .atom-wa-btn { color: var(--whatsapp-foreground, #ffffff); -webkit-user-select: none; user-select: none; background-color: transparent; outline-style: none; padding: 0; border: none; line-height: 1; text-decoration: none; display: inline-grid; position: relative; -webkit-tap-highlight-color: transparent; cursor: pointer; font-family: var(--font-family-sans, 'Inter'), ui-sans-serif, system-ui, sans-serif; font-weight: var(--font-weight-medium, 500); } /* -- Anillo de foco (pseudo, por fuera del bg) -- */ .atom-wa-btn::after { content: ''; display: block; position: absolute; inset: -2px; border-radius: 0.75em; transition: box-shadow 0.3s cubic-bezier(0.32, 0.72, 0, 1); pointer-events: none; z-index: 1; } .atom-wa-btn:focus-visible::after { box-shadow: 0 0 0 2px var(--whatsapp, #25d366); } /* -- Capa de fondo -- */ .atom-wa-btn__bg { background-color: var(--whatsapp, #25d366); border-radius: 0.625em; grid-area: 1 / 1; width: 100%; height: 100%; transition: background-color 0.3s cubic-bezier(0, 0, 0.2, 1); } .atom-wa-btn:hover .atom-wa-btn__bg { background-color: color-mix(in srgb, var(--whatsapp, #25d366) 88%, #000); } .atom-wa-btn:active:not([aria-busy='true']) .atom-wa-btn__bg { background-color: color-mix(in srgb, var(--whatsapp, #25d366) 78%, #000); } /* -- Inner: contenedor del contenido con recorte -- */ .atom-wa-btn__inner { pointer-events: none; gap: 0.375em; padding: 0.75em 0.75em 0.75em 1em; z-index: 1; border-radius: 0.625em; overflow: clip; grid-area: 1 / 1; justify-content: center; align-items: center; display: flex; position: relative; } /* -- Icono -- */ .atom-wa-btn__icon { width: 0.875em; height: 0.875em; flex: none; } .atom-wa-btn__icon svg { width: 100%; height: 100%; } /* -- Label -- */ .atom-wa-btn__label { flex: none; white-space: nowrap; } /* -- Tamanos (en em, escalan con el font-size) -- */ .atom-wa-btn--xs { font-size: 11px; } .atom-wa-btn--s { font-size: 13px; } .atom-wa-btn--m { font-size: 14px; } .atom-wa-btn--l { font-size: 16px; } .atom-wa-btn--xl { font-size: 18px; } /* -- Variante: pill (fija, flotante) -- */ .atom-wa-btn--pill { position: fixed; right: 20px; bottom: 20px; z-index: 9999; } .atom-wa-btn--pill .atom-wa-btn__bg { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16); } .atom-wa-btn--pill:hover .atom-wa-btn__bg { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); } /* -- Variante: icon (fija, flotante, circulo, solo icono) -- */ .atom-wa-btn--icon { position: fixed; right: 20px; bottom: 20px; z-index: 9999; } .atom-wa-btn--icon .atom-wa-btn__bg { border-radius: 999px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16); } .atom-wa-btn--icon:hover .atom-wa-btn__bg { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); } .atom-wa-btn--icon .atom-wa-btn__inner { border-radius: 999px; padding: 0.75em; } .atom-wa-btn--icon .atom-wa-btn__label, .atom-wa-btn--icon .atom-wa-btn__icon.is--left { display: none; } /* -- Variante: inline (estatica, en el flujo del documento — el CTA del landing) -- */ .atom-wa-btn--inline { position: static; z-index: auto; } /* -- Modificador: flotante anclado a la izquierda -- */ .atom-wa-btn--left { right: auto; left: 20px; } /* ================================================================ ANIMATED — deslizamiento del icono (patron button-009) Reposo: [texto] [icono-derecha visible] Hover: [icono-izquierda entra] [texto se desplaza] ================================================================ */ /* Sin animacion: icono a la IZQUIERDA del texto (sobra el derecho). Se excluye --icon, que ya tiene su propia logica de un solo icono. */ .atom-wa-btn:not(.atom-wa-btn--animated):not(.atom-wa-btn--icon) .atom-wa-btn__icon.is--right { display: none; } /* El padding base (1em izquierda) esta pensado para [texto][icono]; invertido, se refleja. */ .atom-wa-btn:not(.atom-wa-btn--animated):not(.atom-wa-btn--icon) .atom-wa-btn__inner { padding: 0.75em 1em 0.75em 0.75em; } .atom-wa-btn--animated { transition: scale 0.15s cubic-bezier(0.4, 0, 0.2, 1); } .atom-wa-btn--animated:active:not([aria-busy='true']) { scale: 0.955 0.925; } .atom-wa-btn--animated .atom-wa-btn__icon { transition: translate 0.5s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s ease-out; } .atom-wa-btn--animated .atom-wa-btn__label { transition: translate 0.5s cubic-bezier(0.32, 0.72, 0, 1); } .atom-wa-btn--animated .atom-wa-btn__icon.is--left { position: absolute; left: 1em; opacity: 0; translate: -1.5em 0 0; } .atom-wa-btn--animated .atom-wa-btn__icon.is--right { opacity: 1; translate: 0 0 0; } .atom-wa-btn--animated:is(:hover, :focus-visible) .atom-wa-btn__label { translate: calc(0.875em + 0.375em + 0.75em - 1em) 0 0; transition: translate 0.5s 0.075s cubic-bezier(0.32, 0.72, 0, 1); } .atom-wa-btn--animated:is(:hover, :focus-visible) .atom-wa-btn__icon.is--left { translate: 0 0 0; opacity: 1; transition: translate 0.5s 0.075s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s 0.075s ease-out; } .atom-wa-btn--animated:is(:hover, :focus-visible) .atom-wa-btn__icon.is--right { translate: 1.5em 0 0; opacity: 0; transition: translate 0.5s 0.05s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s 0.075s ease-out; } /* -- Responsive: el pill flotante colapsa a icono en movil -- */ @media (max-width: 480px) { .atom-wa-btn--pill .atom-wa-btn__label { display: none; } .atom-wa-btn--pill .atom-wa-btn__icon.is--left { display: none; } .atom-wa-btn--pill .atom-wa-btn__inner { padding: 0.75em; } .atom-wa-btn--pill .atom-wa-btn__bg { border-radius: 999px; } /* Pill sin animacion: su icono visible es el izquierdo (regla de arriba), asi que el colapso movil lo recupera — sin esto quedaria un circulo vacio. */ .atom-wa-btn--pill:not(.atom-wa-btn--animated) .atom-wa-btn__icon.is--left { display: flex; } } /* -- Movimiento reducido -- */ @media (prefers-reduced-motion: reduce) { .atom-wa-btn, .atom-wa-btn .atom-wa-btn__icon, .atom-wa-btn .atom-wa-btn__label { transition-duration: 0ms !important; } .atom-wa-btn--animated:active { scale: 1; } }