ATOM
Components (registry)Actions

WhatsApp Button

Opens a WhatsApp chat — Atom’s contact path, never a form. Inline, pill, or icon with a sliding icon on hover.

Preview

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>
ClasePropósito
elementor-kit-Nroot

Tokens resueltos

Valores finales tras seguir la cadena de tokens. Derivados del source: si un token cambia, esta tabla cambia sola.

VariantePropValorToken
allfg#fafafawhatsapp.foreground
allhover-fg#fafafawhatsapp.foreground
allfocused-fg#fafafawhatsapp.foreground
allpressed-fg#fafafawhatsapp.foreground
allbg#25d366whatsapp
allbordernone(unparsed)
allhover-bg#25d366whatsapp
allpressed-bg#25d366whatsapp

Animaciones

PropiedadDuraciónEasing
box-shadow0.3scubic-bezier(0.32
0.72
0
1)
background-color0.3scubic-bezier(0
0
0.2
1)
scale0.15scubic-bezier(0.4
0
0.2
1)
translate0.5scubic-bezier(0.32
0.72
0
1)
opacity0.15sease-out
translate0.5scubic-bezier(0.32
0.72
0
1)
translate0.5s0.075s cubic-bezier(0.32
0.72
0
1)
translate0.5s0.075s cubic-bezier(0.32
0.72
0
1)
opacity0.15s0.075s ease-out
translate0.5s0.05s cubic-bezier(0.32
0.72
0
1)
opacity0.15s0.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

styles/components/whatsapp-button.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: 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; }
}

On this page

Detalles

Publicado14 de mayo de 2026
Categoriaactions
Lectura...
Visitas...
Ayuda?Slack

Componente

WhatsappButton

Source

components-react / cssDisponible via MCP: atom_uikit_source("whatsapp-button")
Abrir en Storybook