diff --git a/SPEC.md b/SPEC.md index 3cdbd51..298d937 100644 --- a/SPEC.md +++ b/SPEC.md @@ -54,7 +54,8 @@ de `WAM.svgPlaceholder(texto)`. Botones con `url` no vacía se renderizan como ` `WAM.normalizar(o)` rellena campos faltantes por tipo y devuelve el estado válido (import/upgrade). Campo opcional `autoPulsar` (entero ≥ 0) en `template`/`buttons`/`list`/`carousel` (también en respuestas anidadas): índice del botón, de la fila aplanada de la lista o de la card que «Reproducir demo» pulsa sola -~1 s después de revelar el mensaje. `normalizar` lo omite si no es válido. +~1 s después de revelar el mensaje. `normalizar` lo omite si no es válido. El editor lo mantiene al +reordenar o borrar botones / filas / cards (sigue al elemento; se quita si se borró el pulsado). **Guion frente a sesión.** `estado.mensajes` es el guion (persistente). Lo que se pulsa o escribe en el teléfono es la sesión: `WAM.sesion` (array en memoria, IDs `s1`, `s2`…), pintada con `anadirMensajeDOM` @@ -124,7 +125,8 @@ cancela demo y flujos (interactivity.js envuelve `WAM.render`). nombre = slug de la demo guardada activa o de `cuenta.nombre`, p. ej. `cafe-aurora.json`; `wam-demo.json` si vacío) - `WAM.importarJSON(archivo)` → Promise (parse + `normalizar` sin reservar los IDs del estado vivo + guardar + re-render total; deja punto de deshacer) -- `WAM.toast(texto, {tipo:"error", ms, accion:{texto, fn}})` → fn cerrar: aviso `#ed-toasts` fijo abajo a la izquierda +- `WAM.toast(texto, {tipo:"error", ms, accion:{texto, fn}})` → fn cerrar: aviso `#ed-toasts` fijo abajo, centrado + sobre la vista previa. Solo hay UN aviso con acción a la vista: uno nuevo con acción retira los anteriores con acción - `WAM.enfocarEnChat(id)` → bool: centra y resalta 1,2 s (`.ed-resaltado`) la burbuja en `#chat-cuerpo`; lo usa el editor al abrir/enfocar una tarjeta · `WAM.abrirTarjeta(id)` → bool: abre y enfoca la tarjeta (desde el chat) - Validación propia (no pública): chip ⚠ por tarjeta, caja «La Cloud API rechazaría…» y `#ed-avisos-global`; @@ -145,7 +147,10 @@ cancela demo y flujos (interactivity.js envuelve `WAM.render`). - `WAM.marcarEditado()` → indicador `#estado-guardado` («Guardando…» → «Guardado · hace N s»; rojo con `WAM.onErrorGuardar`, que ux.js sustituye por toast con «Exportar JSON») - `WAM.setVistaMovil("editor"|"vista")` (≤ 900 px; `body.vista-movil`, `wam-ui-vista`) · `WAM.recordarEnfoque(id)` -- Atajos globales (ignorados en campos): P, Espacio, T, F, N, Esc, Ctrl+S, Ctrl+Z, ?; Alt+↑/↓ mueve en el editor. +- Deshacer / rehacer conservan el tema actual (el tema no forma parte del historial de contenido); cambiar el + tema pasa por `WAM.marcarEditado()`. Cargar escenario / demo / Café Aurora deja SIEMPRE punto de deshacer. +- Atajos globales (ignorados en campos): P, Espacio, T, F, N, G, Esc, Ctrl+S, Ctrl+Z, ?; F6 también en campos; + G / F6 y el enlace `#saltar-vista` mueven el foco entre el editor y `#chat-cuerpo`; Alt+↑/↓ mueve en el editor. Alt+clic o doble clic en una burbuja abre su tarjeta. Envuelve `WAM.anadirMensajeDOM` para anunciar el mensaje en `#wam-anuncios` (sr-only) y quita `aria-live` de `#chat-cuerpo`. @@ -189,7 +194,8 @@ cancela demo y flujos (interactivity.js envuelve `WAM.render`). | `editor-cuenta` | C | form identidad: `cuenta-nombre`, `cuenta-subtitulo`, `cuenta-verificado`, `cuenta-avatar-vista`, `cuenta-avatar-archivo`, `cuenta-avatar-url` | | `nuevo-tipo` (paleta `role=toolbar` de los 13 tipos: un clic AÑADE), `nuevo-tipo-valor` (hidden), `btn-anadir` («+ Otro …»), `ed-destino-alta`, `lista-mensajes` | C | alta por paleta (el último tipo usado vive en `#nuevo-tipo-valor` y `data-valor`) y tarjetas de mensajes | | `bloque-cuenta` (`
`), `cuenta-resumen`, `ed-avisos-global`, `btn-ver-telefono` | C | cuenta plegable, contador de avisos, salto a la vista previa (≤ 900 px) | -| `btn-deshacer`, `btn-rehacer`, `btn-demos`, `btn-atajos`, `btn-mas` + `tb-menu`, `estado-guardado` | C (ux.js) | toolbar: historial, demos, atajos, menú «⋯» (≤ 900 px), indicador de guardado | +| `btn-deshacer`, `btn-rehacer`, `btn-demos`, `btn-atajos`, `btn-mas` + `tb-menu`, `estado-guardado` | C (ux.js) | toolbar: historial, «Nueva demo» (primario, junto a la marca), atajos, menú «⋯» (siempre visible; `#btn-reset` «Volver al ejemplo Café Aurora» solo vive dentro del menú; ≤ 900 px agrupa además Exportar / Importar / Atajos), indicador de guardado | +| `saltar-vista` (enlace), `ed-lista-herr`, `body[data-wam-vacia]` | C | salto de teclado a la vista previa; herramientas de lista (ocultas sin mensajes); demo vacía → pista en el chat | | `tabs-movil`, `tab-editor`, `tab-vista` | C (ux.js) | pestañas Editor / Vista previa (≤ 900 px) | | `barra-movil`, `btn-reproducir` | A | barra sobre el teléfono (Reproducir demo) | | `iphone`, `pantalla` (class `wa`), `isla`, `statusbar` ("9:41" + señal/wifi/batería SVG), `home-indicator` | A | marco iPhone 393×852 | diff --git a/css/base.css b/css/base.css index 40c27b3..ea7552c 100644 --- a/css/base.css +++ b/css/base.css @@ -187,9 +187,43 @@ body { border-color: var(--wam-acento); color: var(--wam-acento-hover); } -#btn-reset:hover { color: var(--wam-peligro); border-color: var(--wam-peligro); } -#btn-mas { display: none; } +/* «Nueva demo»: punto de partida (botón primario junto a la marca) */ +.tb-btn-primario { + margin-left: 4px; + background: var(--wam-primario); + border-color: var(--wam-primario); + color: #fff; +} +.tb-btn-primario:hover { background: var(--wam-primario-hover); border-color: var(--wam-primario-hover); } +.tb-kbd { + display: inline-block; + min-width: 18px; + padding: 1px 5px; + border: 1px solid rgba(255, 255, 255, .45); + border-radius: 5px; + font: 600 11px/1.3 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + text-align: center; + opacity: .9; +} +/* Acción destructiva: siempre dentro del menú «⋯», al final */ +.tb-btn-peligro { color: var(--wam-peligro); } +.tb-btn-peligro:hover { color: var(--wam-peligro); border-color: var(--wam-peligro); background: rgba(185, 58, 46, .08); } +.tb-menu-sep { display: none; } .tb-solo-menu { display: none; } +/* Escritorio: el grupo secundario va en línea y «⋯» despliega + «Volver al ejemplo Café Aurora» como un menú de una opción. */ +#btn-reset { display: none; } +.toolbar.tb-menu-abierto #btn-reset { + display: inline-flex; + position: absolute; + top: calc(100% + 6px); + right: 10px; + z-index: 40; + min-height: 40px; + padding: 10px 14px; + border-color: var(--wam-borde); + box-shadow: var(--wam-sombra); +} /* --- Editor (columna izquierda · cascarón; contenido: editor.js) -------- */ #panel-editor { @@ -375,6 +409,20 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 .wam-esc-nombre { font-size: 14px; font-weight: 700; } .wam-esc-desc { font-size: 12.5px; line-height: 1.4; color: var(--wam-texto-suave); } .wam-esc-meta { font-size: 11.5px; font-weight: 600; color: var(--wam-acento-hover); } +.wam-esc-tipos { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; } +.wam-esc-tipo { + padding: 1px 7px; + border: 1px solid var(--wam-borde); + border-radius: 999px; + font-size: 11px; + font-weight: 600; + color: var(--wam-texto-suave); + background: var(--wam-panel-alt); +} +@media (min-width: 1280px) { + .wam-dlg-grande { width: min(1040px, calc(100vw - 64px)); max-height: min(92vh, 860px); } + .wam-dlg-grande .wam-esc-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } +} /* Demos guardadas */ .wam-demos-lista { list-style: none; display: grid; gap: 6px; } @@ -429,8 +477,12 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 .tb-guardado-rel { display: none; } } @media (max-width: 1100px) { - .toolbar-acciones .tb-btn > span:not(.tb-solo-menu) { display: none; } - .toolbar-acciones .tb-btn { padding: 7px 9px; } + /* Iconos sin texto, salvo en «Nueva demo» y «Presentación» */ + .toolbar-acciones .tb-grupo-sec .tb-btn > span:not(.tb-solo-menu) { display: none; } + .toolbar-acciones .tb-grupo-sec .tb-btn { padding: 7px 9px; } + .toolbar.tb-menu-abierto #btn-reset > span { display: inline; } + .toolbar.tb-menu-abierto #btn-reset { padding: 10px 14px; } + .tb-kbd { display: none; } } /* --- Ventana estrecha (≤ 900 px): una columna con pestañas -------------- */ @@ -489,9 +541,12 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 .tab-movil:focus-visible { outline-offset: -4px; } /* «Ver teléfono»: botón flotante dentro del editor */ + /* centrado: nunca tapa las acciones (derecha) ni el asa (izquierda) de + las tarjetas; #lista-mensajes reserva su hueco al final (editor.css) */ .ed-ver-telefono { position: fixed; - right: 16px; + left: 50%; + transform: translateX(-50%); bottom: calc(var(--wam-tabs-alto) + 14px + env(safe-area-inset-bottom, 0px)); z-index: 25; display: inline-flex; @@ -515,10 +570,15 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 .toolbar-logo { width: 30px; height: 30px; } .toolbar h1 { font-size: 14px; } .tb-guardado { padding: 4px 8px; margin-left: 2px; } - .tb-guardado-txt { display: none; } - .tb-guardado[data-estado="error"] .tb-guardado-txt { display: inline; } - #btn-mas { display: inline-flex; } + /* el texto sigue disponible para lectores de pantalla (y en el title) */ + .tb-guardado-txt { + position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; + overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; + } + .tb-guardado[data-estado="error"] .tb-guardado-txt { position: static; width: auto; height: auto; margin: 0; clip: auto; } .tb-sep-sec { display: none; } + .toolbar-acciones #btn-presentacion > span { display: none; } + #btn-presentacion { padding: 7px 9px; } .tb-grupo-sec { display: none; position: absolute; @@ -536,15 +596,26 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 box-shadow: var(--wam-sombra); } .toolbar.tb-menu-abierto .tb-grupo-sec { display: flex; } - .tb-grupo-sec .tb-btn { + .toolbar-acciones .tb-grupo-sec .tb-btn { justify-content: flex-start; border-color: transparent; padding: 10px 12px; min-height: 40px; } - .toolbar-acciones .tb-grupo-sec .tb-btn > span, - .tb-grupo-sec .tb-solo-menu { display: inline; } + .toolbar-acciones .tb-grupo-sec .tb-btn > span:not(.tb-solo-menu), + .toolbar-acciones .tb-grupo-sec .tb-solo-menu { display: inline; } .tb-grupo-sec .tb-btn:hover { border-color: transparent; } + .tb-grupo-sec .tb-btn-peligro:hover { background: rgba(185, 58, 46, .08); } + .tb-menu-sep { display: block; height: 1px; margin: 4px 6px; background: var(--wam-borde); } + /* dentro del menú desplegable «Volver al ejemplo» es una fila más */ + #btn-reset, + .toolbar.tb-menu-abierto #btn-reset { + display: inline-flex; + position: static; + padding: 10px 12px; + box-shadow: none; + border-color: transparent; + } /* Escala del teléfono con el ancho completo (sin restar el editor) y la altura real de la toolbar + barra de vista previa + pestañas. */ @@ -566,10 +637,19 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 } } +@media (max-width: 560px) { + #btn-demos > span { display: none; } + #btn-demos { padding: 7px 9px; } +} + @media (max-width: 520px) { /* la pestaña ya dice «Vista previa»: se gana una fila para el teléfono */ #barra-movil .barra-titulo { display: none; } #barra-movil { justify-content: center; } + #barra-movil .barra-etq-txt { + position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; + overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; + } } @media (max-width: 420px) { @@ -577,6 +657,60 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 .toolbar-marca { flex: 1; } } +/* --- Enlace «Saltar a la vista previa» (visible solo con el foco) ------ */ +.wam-saltar { + position: fixed; + left: 12px; + top: 8px; + z-index: 200; + padding: 10px 14px; + border-radius: 10px; + background: var(--wam-primario); + color: #fff; + font-size: 14px; + font-weight: 700; + text-decoration: none; + transform: translateY(-160%); + transition: transform .15s ease; +} +.wam-saltar:focus { transform: none; outline: 2px solid #fff; outline-offset: -4px; } +#chat-cuerpo:focus { outline: none; } +#chat-cuerpo:focus-visible { outline: 2px solid var(--wam-acento); outline-offset: -3px; } +#lista-mensajes:focus { outline: none; } + +/* --- Etiqueta de la velocidad en la barra de la vista previa ---------- */ +#barra-movil .barra-etq { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 12px; + font-weight: 600; + color: var(--wam-texto-suave); + cursor: pointer; +} +#barra-movil #btn-reiniciar { display: inline-flex; align-items: center; gap: 6px; } +#barra-movil #btn-reiniciar svg { flex: none; } + +/* --- Chat vacío: pista dentro del teléfono ----------------------------- + body[data-wam-vacia] lo pone js/editor.js cuando la demo no tiene + mensajes (así no parpadea al arrancar «Reproducir demo»). */ +body[data-wam-vacia] #chat-cuerpo:not(:has(> .wa-row))::after { + content: "Añade mensajes desde el editor"; + display: block; + width: max-content; + max-width: 80%; + margin: 16px auto; + padding: 6px 12px; + border-radius: 8px; + background: rgba(255, 255, 255, .92); + color: #54656f; + font-size: 12.5px; + text-align: center; + box-shadow: 0 1px .5px rgba(11, 20, 26, .13); +} +body[data-wam-vacia] .pantalla.oscuro #chat-cuerpo:not(:has(> .wa-row))::after { background: #182229; color: #8696a0; } +body.presentacion[data-wam-vacia] #chat-cuerpo:not(:has(> .wa-row))::after { content: "Sin mensajes todavía"; } + /* Destinos táctiles más grandes */ @media (pointer: coarse) { .tb-btn { min-height: 40px; } @@ -585,5 +719,5 @@ button.wam-dlg-peligro.wam-dlg-btn:not(.wam-dlg-mini):hover { background: #9c2f2 /* --- Accesibilidad: menos movimiento ------------------------------------ */ @media (prefers-reduced-motion: reduce) { #chat-cuerpo { scroll-behavior: auto; } - .tb-btn, .wam-btn-anadir, .wam-esc { transition: none; } + .tb-btn, .wam-btn-anadir, .wam-esc, .wam-saltar { transition: none; } } diff --git a/css/editor.css b/css/editor.css index 34c3744..0e9b2af 100644 --- a/css/editor.css +++ b/css/editor.css @@ -276,6 +276,7 @@ textarea.ed-input { resize: vertical; min-height: 46px; } .ed-cab-principal { flex: 1; min-width: 0; + overflow: hidden; display: flex; align-items: center; gap: 6px; @@ -293,14 +294,22 @@ textarea.ed-input { resize: vertical; min-height: 46px; } flex: 0 0 auto; min-width: 18px; height: 18px; - display: inline-grid; - place-items: center; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 1px; + padding: 0 5px 0 4px; font-size: 11px; font-weight: 700; + font-variant-numeric: tabular-nums; color: var(--ed-acento-hondo); background: var(--ed-acento-suave); border-radius: 999px; } +/* Dirección: flecha ↙ entrada / ↗ salida (además del color) */ +.ed-num-dir { font-size: 11px; line-height: 1; } +.ed-num.ed-num-in { color: var(--ed-entrada); background: var(--ed-entrada-suave); } +.ed-num.ed-num-resp { padding: 0 5px; } .ed-dir { flex: 0 0 auto; @@ -321,19 +330,28 @@ textarea.ed-input { resize: vertical; min-height: 46px; } } .ed-badge { - flex: 0 0 auto; - padding: 1px 6px; + flex: 0 1 auto; + min-width: 0; + display: inline-flex; + align-items: center; + gap: 3px; + padding: 1px 6px 1px 4px; + overflow: hidden; font-size: 11px; font-weight: 600; letter-spacing: 0.3px; text-transform: uppercase; + white-space: nowrap; color: var(--wam-texto, var(--ed-texto-suave)); border: 1px solid var(--wam-borde, var(--ed-borde)); border-radius: 999px; } +.ed-badge .ed-ico { flex: none; display: inline-grid; place-items: center; color: var(--wam-texto-suave, var(--ed-texto-suave)); } +.ed-badge .ed-ico svg { display: block; width: 13px; height: 13px; } +.ed-badge-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .ed-resumen { - flex: 1; + flex: 1 1 60px; min-width: 0; overflow: hidden; text-overflow: ellipsis; @@ -341,6 +359,26 @@ textarea.ed-input { resize: vertical; min-height: 46px; } font-size: 12px; color: var(--wam-texto, var(--ed-texto-suave)); } +/* Tarjeta abierta: el resumen baja a su propia línea bajo la cabecera + (así siempre se lee qué mensaje se está editando) */ +.ed-tarjeta { --ed-acc-w: 146px; } /* + ↑ ↓ ⧉ ✕ (26 px) + huecos */ +.ed-tarjeta.ed-anidada { --ed-acc-w: 88px; } /* ↑ ↓ ✕ */ +.ed-tarjeta.ed-abierta > .ed-tarjeta-cab { align-items: flex-start; } +.ed-tarjeta.ed-abierta > .ed-tarjeta-cab > .ed-asa { margin-top: 2px; } +.ed-tarjeta.ed-abierta > .ed-tarjeta-cab > .ed-cab-principal { flex-wrap: wrap; row-gap: var(--ed-acc-h, 8px); overflow: visible; } +/* la 2.ª línea pasa por debajo de las acciones: usa todo el ancho de la tarjeta */ +.ed-tarjeta.ed-abierta > .ed-tarjeta-cab > .ed-cab-principal > .ed-resumen { + order: 10; + flex: 0 0 calc(100% + var(--ed-acc-w)); /* tamaño exterior = 100 %: fuerza la 2.ª línea */ + max-width: none; + margin-right: calc(-1 * var(--ed-acc-w)); + white-space: normal; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + line-clamp: 2; + padding-left: 2px; +} .ed-acciones { flex: 0 0 auto; @@ -825,15 +863,22 @@ textarea.ed-input { resize: vertical; min-height: 46px; } font-size: 12.5px; } .ed-paleta .ed-tipo-card .ed-tipo-card-e { flex: none; overflow: visible; } -.ed-paleta .ed-tipo-card.ed-seleccionada { - /* último tipo usado: marca sutil (la paleta añade al hacer clic) */ - background: var(--wam-panel, var(--ed-panel)); - color: var(--wam-texto, var(--ed-texto)); - font-weight: 500; - box-shadow: none; - border-color: var(--ed-seleccion); -} +/* Sin estado «seleccionado»: cada clic añade. El «+» aparece con hover/foco. */ .ed-paleta .ed-tipo-card:hover { background: var(--ed-seleccion-suave); } +.ed-tipo-mas { + display: inline-block; + width: 0; + overflow: hidden; + font-weight: 800; + line-height: 1; + opacity: 0; + transition: width 0.12s ease, opacity 0.12s ease; +} +.ed-paleta .ed-tipo-card:hover .ed-tipo-mas, +.ed-paleta .ed-tipo-card:focus-visible .ed-tipo-mas { width: 0.7em; opacity: 1; } +@media (hover: none) { + .ed-tipo-mas { width: 0.7em; opacity: 0.55; } +} .ed-alta-pie { display: flex; flex-wrap: wrap; @@ -845,6 +890,52 @@ textarea.ed-input { resize: vertical; min-height: 46px; } font-size: 12px; color: var(--wam-texto-suave, var(--ed-texto-suave)); } +/* Chip visible del destino del próximo alta */ +.ed-destino-alta.ed-destino-chip { + display: inline-flex; + align-items: center; + gap: 4px; + min-height: 26px; + padding: 2px 10px; + border: 1px solid var(--wam-borde, var(--ed-borde)); + border-radius: 999px; + background: var(--ed-fondo-suave); + font-weight: 600; + color: var(--wam-texto, var(--ed-texto)); +} +.ed-destino-alta.ed-destino-chip::before { + content: "↧"; + font-weight: 700; + color: var(--ed-seleccion); +} +.ed-destino-alta.ed-destino-dentro { + border-color: var(--ed-seleccion); + background: var(--ed-seleccion-suave); + color: var(--ed-seleccion); + padding-right: 3px; +} +.ed-destino-quitar { + display: inline-grid; + place-items: center; + width: 22px; + height: 22px; + padding: 0; + border: 0; + border-radius: 50%; + background: transparent; + color: inherit; + font: inherit; + font-size: 15px; + line-height: 1; + cursor: pointer; +} +.ed-destino-quitar:hover { background: rgba(43, 107, 228, 0.18); } +.ed-destino-quitar:focus-visible { outline: 2px solid var(--ed-seleccion); outline-offset: 1px; } +.ed-destino-cambio { animation: ed-destino-cambio 0.9s ease-out; } +@keyframes ed-destino-cambio { + 0% { box-shadow: 0 0 0 3px var(--ed-seleccion-suave), 0 0 0 1px var(--ed-seleccion); } + 100% { box-shadow: 0 0 0 0 transparent; } +} .ed-enlace { padding: 0; border: 0; @@ -955,20 +1046,43 @@ textarea.ed-input { resize: vertical; min-height: 46px; } } .ed-chip-aviso { color: var(--ed-ambar); background: rgba(180, 83, 9, 0.12); } .ed-chip-flujo { color: var(--ed-acento-hondo); background: var(--ed-acento-suave); } +.ed-chip-auto { color: var(--ed-seleccion); background: var(--ed-seleccion-suave); } + +/* «Se pulsa sola en la demo»: select arriba del formulario y casilla por elemento */ +.ed-campo-auto { max-width: 320px; } +.ed-check-auto { + justify-self: start; + padding: 3px 8px 3px 6px; + border: 1px dashed var(--ed-seleccion); + border-radius: 999px; + font-size: 12px; + color: var(--ed-seleccion); +} +.ed-check-auto input { accent-color: var(--ed-seleccion); } +.ed-check-auto:has(input:checked) { border-style: solid; background: var(--ed-seleccion-suave); font-weight: 600; } .ed-chip-flujo-incompleto { color: var(--ed-entrada); background: var(--ed-entrada-suave); } .ed-num-resp { font-size: 12px; } /* Las flechas ↑/↓ se muestran al abrir, al pasar el ratón o con el foco - dentro (siguen en el orden de Tab: el foco las hace visibles) */ + dentro. Su hueco se reserva siempre (visibility, no display): el hover no + provoca saltos de layout ni recorta el resumen. Con el foco en la + cabecera se vuelven visibles y entran en el orden de Tab. */ .ed-tarjeta { position: relative; } .ed-tarjeta:not(.ed-abierta):not(:hover):not(:focus-within) > .ed-tarjeta-cab .ed-mov { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip: rect(0 0 0 0); - padding: 0; - border: 0; + visibility: hidden; +} + +/* Editor estrecho (contenido < 400 px, p. ej. ventanas de 1024 y 1280): en plegadas las + flechas no ocupan sitio (se reordena con el asa o Alt+↑/↓) y aparecen + al abrir la tarjeta, cuando el resumen ya va en su propia línea. */ +.ed-bloque-mensajes { container-type: inline-size; container-name: ed-mensajes; } +@container ed-mensajes (max-width: 400px) { + .ed-tarjeta:not(.ed-abierta) > .ed-tarjeta-cab .ed-mov { display: none; } +} +/* Muy estrecho (editor < 380 px, contenido ~330): la etiqueta de tipo queda solo como icono */ +@container ed-mensajes (max-width: 330px) { + .ed-tarjeta-cab .ed-badge-txt { display: none; } + .ed-tarjeta-cab .ed-badge { padding: 2px 4px; } } .ed-acciones .ed-btn-mini { min-width: 26px; min-height: 26px; padding: 2px 6px; } .ed-btn-mini:disabled { opacity: 0.35; } @@ -1033,16 +1147,23 @@ textarea.ed-input { resize: vertical; min-height: 46px; } .ed-vacio-acciones { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 4px; } /* ---------- Toasts (fuera del scroll del panel) ---------- */ +/* Abajo, centrados sobre la columna de la vista previa: no tapan las + tarjetas ni sus acciones mientras se trabaja en el editor. */ .ed-toasts { + --ed-col-editor: clamp(340px, 34vw, 480px); /* = columna del editor (base.css) */ position: fixed; - left: 16px; + left: calc(var(--ed-col-editor) + (100vw - var(--ed-col-editor)) / 2); bottom: 16px; z-index: 1000; display: grid; + justify-items: center; gap: 8px; - max-width: min(440px, calc(100vw - 32px)); + width: max-content; + max-width: min(440px, calc(100vw - var(--ed-col-editor) - 32px)); + transform: translateX(-50%); pointer-events: none; } +body.presentacion .ed-toasts { left: 50%; max-width: min(440px, calc(100vw - 32px)); } .ed-toast { display: flex; align-items: center; @@ -1090,7 +1211,14 @@ textarea.ed-input { resize: vertical; min-height: 46px; } to { opacity: 1; transform: none; } } @media (max-width: 900px) { - .ed-toasts { bottom: calc(var(--wam-tabs-alto, 58px) + 70px); } + .ed-toasts { + left: 50%; + max-width: min(440px, calc(100vw - 32px)); + bottom: calc(var(--wam-tabs-alto, 58px) + 64px + env(safe-area-inset-bottom, 0px)); + } + body.vista-movil .ed-toasts { bottom: calc(var(--wam-tabs-alto, 58px) + 12px + env(safe-area-inset-bottom, 0px)); } + /* hueco al final de la lista para el botón flotante «Ver teléfono» */ + #lista-mensajes { padding-bottom: 56px; } } /* ---------- Enlace con la vista previa ---------- */ @@ -1108,6 +1236,8 @@ body.presentacion #chat-cuerpo .wa-row.ed-resaltado { outline: 0; } /* ---------- Destinos táctiles ---------- */ @media (pointer: coarse) { + .ed-tarjeta { --ed-acc-w: 176px; --ed-acc-h: 14px; } + .ed-tarjeta.ed-anidada { --ed-acc-w: 106px; } .ed-btn-mini, .ed-acciones .ed-btn-mini { min-width: 32px; min-height: 32px; } .ed-fmt-btn { min-width: 32px; height: 32px; } @@ -1116,14 +1246,12 @@ body.presentacion #chat-cuerpo .wa-row.ed-resaltado { outline: 0; } } @media (max-width: 480px) { - /* cabecera de tarjeta: la dirección se lee en el color del número */ - .ed-tarjeta-cab .ed-dir { display: none; } - .ed-num.ed-num-in { color: var(--ed-entrada); background: var(--ed-entrada-suave); } .ed-paleta-grupo { grid-template-columns: 1fr; gap: 4px; } .ed-paleta-titulo { padding-top: 0; } } @media (prefers-reduced-motion: reduce) { - .ed-toast, .ed-tarjeta.ed-destello { animation: none; } + .ed-toast, .ed-tarjeta.ed-destello, .ed-destino-cambio { animation: none; } + .ed-tipo-mas { transition: none; } .ed-bloque-cuenta > .ed-cuenta-sumario::before, .ed-seg-op span { transition: none; } } diff --git a/index.html b/index.html index adc60ae..4ffe91a 100644 --- a/index.html +++ b/index.html @@ -16,6 +16,9 @@ + + Saltar a la vista previa +
@@ -28,6 +31,12 @@

WhatsApp Cloud API

Mockup visual · demo estática
+ + @@ -44,24 +53,18 @@ - - - - + +
- - + +
+ @@ -103,19 +110,20 @@
- +
- + +
-
+
-
+
@@ -130,12 +138,19 @@
Vista previa
- - +