- Toolbar: «Nueva demo» primaria junto a la marca (N); Tema como icono; «Volver al ejemplo Café Aurora» (peligro) solo dentro del menú «⋯»; etiquetas de Nueva demo y Presentación visibles entre 900 y 1100 px. - Tarjetas: flecha de dirección en el número (↙/↗), badge con icono (solo icono en editor estrecho), resumen en 2.ª línea al abrir, hueco de ↑/↓ reservado (sin saltos al pasar el ratón), container queries. - Borrar (mensaje, botón, fila, tarjeta, respuesta) nunca deja el foco en otro botón ✕. - autoPulsar sigue al elemento al mover/borrar/arrastrar; opción inexistente visible y aviso; casilla «Se pulsa sola» por elemento, chip «▶ auto» y select arriba del formulario. - Deshacer/rehacer conservan el tema; el tema marca «Guardando…». - Escenarios: siempre punto de deshacer, un único aviso con acción y foco al nombre de la cuenta; chips de tipos en el diálogo Demos, rejilla de 4 columnas en >= 1280 y sin nombre precargado. - Paleta sin estado seleccionado, «+» en hover/foco, chip de destino y «+ Otro» solo tras el primer alta. - Avisos abajo al centro sobre la vista previa; tel: válido en plantillas (máx. 1); interruptor «Mostrar cabecera» fijo (role=switch). - Teclado: enlace «Saltar a la vista previa» y G / F6; atajos con ⌘ en Mac; etiqueta «Velocidad»; «Repetir desde el inicio». - Demo vacía: herramientas ocultas y pista dentro del chat. Co-Authored-By: Claude Opus 5.5 <[email protected]>
285 lines
21 KiB
HTML
285 lines
21 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="description" content="Mockup visual 100 % estático de los mensajes de la WhatsApp Cloud API renderizados en un iPhone.">
|
|
<meta name="referrer" content="no-referrer">
|
|
<title>WhatsApp Cloud API · Mockup</title>
|
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect width='24' height='24' rx='6' fill='%2300a884'/%3E%3Cpath fill='%23fff' d='M7.1 3.8c.5-.1 1 .2 1.2.7l1.3 3c.2.4.1.9-.3 1.2l-1.6 1.4a13.3 13.3 0 0 0 6.2 6.2l1.4-1.6c.3-.4.8-.5 1.2-.3l3 1.3c.5.2.8.7.7 1.2l-.5 2.6c-.1.5-.6.9-1.1.9C10.4 20.4 3.6 13.6 3.6 5.4c0-.5.4-1 .9-1.1z'/%3E%3C/svg%3E">
|
|
<!-- Orden EXACTO de la SPEC §2/§4 -->
|
|
<link rel="stylesheet" href="css/base.css">
|
|
<link rel="stylesheet" href="css/iphone.css">
|
|
<link rel="stylesheet" href="css/whatsapp.css">
|
|
<link rel="stylesheet" href="css/editor.css">
|
|
<link rel="stylesheet" href="css/interactividad.css">
|
|
</head>
|
|
<body data-tema="claro">
|
|
|
|
<!-- Teclado: salta las tarjetas del editor directo al teléfono (atajo G / F6) -->
|
|
<a id="saltar-vista" class="wam-saltar" href="#chat-cuerpo">Saltar a la vista previa</a>
|
|
|
|
<div id="app">
|
|
|
|
<!-- ============ Barra superior de la app (shell A) ============ -->
|
|
<header id="toolbar" class="toolbar">
|
|
<div class="toolbar-marca">
|
|
<span class="toolbar-logo" aria-hidden="true">
|
|
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M7.1 3.8c.5-.1 1 .2 1.2.7l1.3 3c.2.4.1.9-.3 1.2l-1.6 1.4a13.3 13.3 0 0 0 6.2 6.2l1.4-1.6c.3-.4.8-.5 1.2-.3l3 1.3c.5.2.8.7.7 1.2l-.5 2.6c-.1.5-.6.9-1.1.9C10.4 20.4 3.6 13.6 3.6 5.4c0-.5.4-1 .9-1.1z"/></svg>
|
|
</span>
|
|
<div class="toolbar-titulos">
|
|
<h1>WhatsApp Cloud API</h1>
|
|
<span class="toolbar-subtitulo">Mockup visual · demo estática</span>
|
|
</div>
|
|
<!-- Punto de partida del consultor: escenarios por industria y demos guardadas -->
|
|
<button id="btn-demos" class="tb-btn tb-btn-primario" type="button" title="Nueva demo: escenarios por industria y demos guardadas (N)" aria-keyshortcuts="N">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3.5" y="3.5" width="7" height="7" rx="1.6"/><rect x="13.5" y="3.5" width="7" height="7" rx="1.6"/><rect x="3.5" y="13.5" width="7" height="7" rx="1.6"/><path d="M17 14v6M14 17h6"/></svg>
|
|
<span>Nueva demo</span>
|
|
<kbd class="tb-kbd" aria-hidden="true">N</kbd>
|
|
</button>
|
|
<!-- Estado del guardado local (lo pinta js/ux.js) -->
|
|
<span id="estado-guardado" class="tb-guardado" data-estado="ok" title="Guardado en este navegador">
|
|
<span class="tb-guardado-punto" aria-hidden="true"></span>
|
|
<span class="tb-guardado-txt">Guardado</span>
|
|
<span class="tb-guardado-rel" aria-hidden="true"></span>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="toolbar-acciones">
|
|
<button id="btn-deshacer" class="tb-btn tb-btn-icono" type="button" title="Deshacer (Ctrl+Z)" aria-label="Deshacer" disabled>
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 0 11H11"/></svg>
|
|
</button>
|
|
<button id="btn-rehacer" class="tb-btn tb-btn-icono" type="button" title="Rehacer (Ctrl+Mayús+Z)" aria-label="Rehacer" disabled>
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 14 5-5-5-5"/><path d="M20 9H9.5a5.5 5.5 0 0 0 0 11H13"/></svg>
|
|
</button>
|
|
<span class="tb-separador" aria-hidden="true"></span>
|
|
<button id="btn-presentacion" class="tb-btn" type="button" title="Modo presentación: oculta el editor (P · Esc para salir)" aria-pressed="false">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="currentColor" fill-rule="evenodd" aria-hidden="true"><path d="M3 4.5h18a1 1 0 0 1 1 1V16a1 1 0 0 1-1 1h-6.4v2.1h1.9a.9.9 0 1 1 0 1.8H7.5a.9.9 0 1 1 0-1.8h1.9V17H3a1 1 0 0 1-1-1V5.5a1 1 0 0 1 1-1zm8 3.4v5.7l4.6-2.85z"/></svg>
|
|
<span>Presentación</span>
|
|
</button>
|
|
<button id="btn-tema" class="tb-btn tb-btn-icono" type="button" title="Alternar tema claro / oscuro (T)" aria-label="Tema oscuro" aria-pressed="false">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="currentColor" aria-hidden="true"><path d="M12 2.6a9.4 9.4 0 1 0 0 18.8 9.4 9.4 0 0 0 0-18.8zm0 16.9V4.5a7.5 7.5 0 0 1 0 15z"/></svg>
|
|
</button>
|
|
<span class="tb-separador tb-sep-sec" aria-hidden="true"></span>
|
|
<!-- Acciones secundarias: en línea en escritorio; en ventana estrecha
|
|
forman el menú «⋯». «Volver al ejemplo» (destructiva) vive siempre
|
|
dentro del menú «⋯», al final y con estilo de peligro. -->
|
|
<div id="tb-menu" class="tb-grupo-sec">
|
|
<button id="btn-exportar" class="tb-btn" type="button" title="Exportar la demo a JSON (Ctrl+S)">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="currentColor" aria-hidden="true"><path d="M12 3.2c.5 0 .9.4.9.9v8.2l2.7-2.7a.9.9 0 1 1 1.3 1.3l-4.2 4.2a.9.9 0 0 1-1.3 0L7.2 11a.9.9 0 1 1 1.3-1.3l2.7 2.7V4.1c0-.5.4-.9.9-.9zM4.9 18.5h14.2a.9.9 0 1 1 0 1.8H4.9a.9.9 0 1 1 0-1.8z"/></svg>
|
|
<span>Exportar</span>
|
|
</button>
|
|
<button id="btn-importar" class="tb-btn" type="button" title="Importar una demo desde JSON (sustituye la actual)">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="currentColor" aria-hidden="true"><path d="M12 15.6c-.5 0-.9-.4-.9-.9V6.5L8.4 9.2A.9.9 0 1 1 7.1 7.9l4.2-4.2a.9.9 0 0 1 1.3 0l4.2 4.2a.9.9 0 1 1-1.3 1.3l-2.7-2.7v8.2c0 .5-.4.9-.9.9zM4.9 18.5h14.2a.9.9 0 1 1 0 1.8H4.9a.9.9 0 1 1 0-1.8z"/></svg>
|
|
<span>Importar</span>
|
|
</button>
|
|
<input type="file" id="importar-archivo" accept="application/json,.json" hidden>
|
|
<button id="btn-atajos" class="tb-btn tb-btn-icono" type="button" title="Atajos de teclado (?)" aria-label="Atajos de teclado">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2.5" y="6" width="19" height="12" rx="2.2"/><path d="M6 10h.01M10 10h.01M14 10h.01M18 10h.01M7.5 14h9"/></svg>
|
|
<span class="tb-solo-menu">Atajos</span>
|
|
</button>
|
|
<span class="tb-menu-sep" aria-hidden="true"></span>
|
|
<button id="btn-reset" class="tb-btn tb-btn-peligro" type="button" title="Sustituye la demo actual por el ejemplo Café Aurora (pide confirmación y se puede deshacer)">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="currentColor" aria-hidden="true"><path d="M12 5V2.8a.7.7 0 0 0-1.13-.55L6.9 5.2a.7.7 0 0 0 0 1.1l3.97 2.95A.7.7 0 0 0 12 8.7V6.5a5.5 5.5 0 1 1-5.5 5.5H4.75A7.25 7.25 0 1 0 12 5z"/></svg>
|
|
<span>Volver al ejemplo Café Aurora</span>
|
|
</button>
|
|
</div>
|
|
<button id="btn-mas" class="tb-btn tb-btn-icono" type="button" aria-label="Más acciones" aria-expanded="false" aria-controls="tb-menu" title="Más acciones">
|
|
<svg viewBox="0 0 24 24" width="17" height="17" fill="currentColor" aria-hidden="true"><circle cx="5" cy="12" r="1.9"/><circle cx="12" cy="12" r="1.9"/><circle cx="19" cy="12" r="1.9"/></svg>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- ============ Panel editor (columna izquierda · contenido: módulo C) ============ -->
|
|
<aside id="panel-editor" aria-label="Editor del mockup">
|
|
<!-- Cuenta: se edita una vez por demo; plegada si ya hay mensajes -->
|
|
<details id="bloque-cuenta" class="wam-bloque ed-bloque-cuenta" open>
|
|
<summary class="ed-cuenta-sumario">
|
|
<span class="wam-bloque-titulo">Cuenta</span>
|
|
<span id="cuenta-resumen" class="ed-cuenta-resumen"></span>
|
|
</summary>
|
|
<!-- El formulario de identidad lo pinta js/editor.js (C) en runtime -->
|
|
<div id="editor-cuenta"></div>
|
|
</details>
|
|
|
|
<section class="wam-bloque ed-bloque-mensajes" aria-labelledby="titulo-mensajes">
|
|
<div class="ed-bloque-cab">
|
|
<h2 id="titulo-mensajes" class="wam-bloque-titulo">Mensajes</h2>
|
|
<button id="ed-avisos-global" class="ed-avisos-global" type="button" data-acc="ir-aviso" hidden></button>
|
|
</div>
|
|
<div class="wam-alta">
|
|
<!-- Paleta de los 13 tipos (la rellena js/editor.js): un clic AÑADE el mensaje.
|
|
El último tipo usado queda en #nuevo-tipo-valor (hidden) y en data-valor. -->
|
|
<div id="nuevo-tipo" class="ed-paleta" role="toolbar" aria-label="Añadir un mensaje: cada tipo añade uno"></div>
|
|
<input type="hidden" id="nuevo-tipo-valor" value="text">
|
|
<div class="ed-alta-pie">
|
|
<span id="ed-destino-alta" class="ed-destino-alta" aria-live="polite"></span>
|
|
<!-- «Repetir último»: aparece tras el primer alta de la sesión -->
|
|
<button id="btn-anadir" class="wam-btn-anadir" type="button" hidden>+ Otro «Texto»</button>
|
|
</div>
|
|
</div>
|
|
<div class="ed-lista-herr" id="ed-lista-herr">
|
|
<button type="button" class="ed-btn ed-btn-mini" data-acc="horas-secuencia" title="Reparte las horas desde la del primer mensaje, +1 min por mensaje">Horas en secuencia</button>
|
|
<button type="button" class="ed-btn ed-btn-mini" data-acc="plegar-todo">Plegar todo</button>
|
|
</div>
|
|
<!-- Una tarjeta colapsable por mensaje la pinta js/editor.js (C) -->
|
|
<div id="lista-mensajes" tabindex="-1" aria-label="Tarjetas de mensajes"></div>
|
|
</section>
|
|
|
|
<!-- Solo en ventana estrecha: salta a la vista previa del mensaje en edición -->
|
|
<button id="btn-ver-telefono" class="ed-ver-telefono" type="button">
|
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><rect x="6.5" y="2.5" width="11" height="19" rx="2.5"/><path d="M11 18.5h2"/></svg>
|
|
Ver teléfono
|
|
</button>
|
|
</aside>
|
|
|
|
<!-- ============ Panel móvil (columna derecha · shell A) ============ -->
|
|
<section id="panel-movil" aria-label="Vista previa en un iPhone">
|
|
<div id="barra-movil">
|
|
<span class="barra-titulo">Vista previa</span>
|
|
<div class="barra-acciones">
|
|
<label class="barra-etq" for="sel-velocidad" title="Velocidad de la reproducción">
|
|
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="13" r="8"/><path d="M12 13V9M10 2.8h4"/></svg>
|
|
<span class="barra-etq-txt">Velocidad</span>
|
|
</label>
|
|
<select id="sel-velocidad" title="Velocidad de la reproducción">
|
|
<option value="0.5">0,5x</option>
|
|
<option value="1" selected>1x</option>
|
|
<option value="2">2x</option>
|
|
</select>
|
|
<button id="btn-reiniciar" type="button" title="Descarta lo pulsado y escrito en el teléfono y vuelve al guion desde el primer mensaje">
|
|
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 12a8.5 8.5 0 1 0 2.6-6.1"/><path d="M3.5 4v4.5H8"/></svg>
|
|
<span>Repetir desde el inicio</span>
|
|
</button>
|
|
<button id="btn-reproducir" type="button" title="Reproducir la demo paso a paso (clic de nuevo para detener)">
|
|
<svg viewBox="0 0 24 24" width="15" height="15" fill="currentColor" aria-hidden="true"><path d="M8.4 5.6v12.8c0 .8.9 1.3 1.6.9l10-6.4c.6-.4.6-1.4 0-1.8l-10-6.4c-.7-.4-1.6.1-1.6.9z"/></svg>
|
|
<span>Reproducir demo</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="iphone-escena">
|
|
<div id="iphone" class="iphone">
|
|
<div id="pantalla" class="pantalla wa">
|
|
|
|
<!-- Hardware -->
|
|
<div id="isla" class="island" aria-hidden="true"></div>
|
|
<div id="statusbar" class="statusbar" aria-hidden="true">
|
|
<span class="sb-hora">9:41</span>
|
|
<span class="sb-iconos">
|
|
<svg class="sb-svg sb-senal" width="18" height="12" viewBox="0 0 18 12" fill="currentColor" aria-hidden="true">
|
|
<rect x="0" y="7.4" width="3" height="4.6" rx="1"/>
|
|
<rect x="4.7" y="5.2" width="3" height="6.8" rx="1"/>
|
|
<rect x="9.4" y="2.8" width="3" height="9.2" rx="1"/>
|
|
<rect x="14.1" y="0.4" width="3" height="11.6" rx="1"/>
|
|
</svg>
|
|
<svg class="sb-svg sb-wifi" width="17" height="12" viewBox="0 0 17 12" fill="none" aria-hidden="true">
|
|
<path d="M1.2 4.1a11 11 0 0 1 14.6 0" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/>
|
|
<path d="M3.9 7a7 7 0 0 1 9.2 0" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/>
|
|
<circle cx="8.5" cy="10.2" r="1.7" fill="currentColor"/>
|
|
</svg>
|
|
<svg class="sb-svg sb-bateria" width="28" height="13" viewBox="0 0 28 13" fill="none" aria-hidden="true">
|
|
<rect x="0.75" y="0.75" width="22.5" height="11.5" rx="3.5" stroke="currentColor" stroke-width="1.2" opacity="0.45"/>
|
|
<path d="M25.3 4.4v4.2c1.2-.3 2-1.1 2-2.1s-.8-1.8-2-2.1z" fill="currentColor" opacity="0.45"/>
|
|
<rect x="2.5" y="2.5" width="15.5" height="8" rx="2" fill="currentColor"/>
|
|
</svg>
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Header del chat (estructura A · contenido B) -->
|
|
<header id="chat-header" class="header">
|
|
<svg class="back-chevron" viewBox="0 0 24 24" width="24" height="24" fill="none" aria-hidden="true">
|
|
<path d="M15 4.5 7.5 12l7.5 7.5" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
</svg>
|
|
<img id="chat-avatar" class="avatar" alt="Avatar de la cuenta">
|
|
<div class="header-title">
|
|
<span class="header-linea">
|
|
<span id="chat-nombre"></span>
|
|
<span id="chat-verificado" class="header-verificado" title="Cuenta verificada">
|
|
<svg class="verificado-svg" viewBox="0 0 24 24" width="15" height="15" aria-hidden="true">
|
|
<path fill="currentColor" d="M12 1.7l2.1 1.6 2.6-.5 1.1 2.4 2.4 1.1-.5 2.6 1.6 2.1-1.6 2.1.5 2.6-2.4 1.1-1.1 2.4-2.6-.5-2.1 1.6-2.1-1.6-2.6.5-1.1-2.4-2.4-1.1.5-2.6L2.7 12l1.6-2.1-.5-2.6 2.4-1.1 1.1-2.4 2.6.5z"/>
|
|
<path fill="#fff" d="M10.7 15.1l-3-3 1.3-1.3 1.7 1.7 4.3-4.3 1.3 1.3z"/>
|
|
</svg>
|
|
</span>
|
|
</span>
|
|
<span id="chat-subtitulo" class="header-sub"></span>
|
|
</div>
|
|
<svg class="icon-video" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" aria-hidden="true">
|
|
<path d="M4.5 5.5h9A2.5 2.5 0 0 1 16 8v8a2.5 2.5 0 0 1-2.5 2.5h-9A2.5 2.5 0 0 1 2 16V8a2.5 2.5 0 0 1 2.5-2.5z"/>
|
|
<path d="M17.5 10.2l3.6-2.6c.5-.4 1.2 0 1.2.6v7.6c0 .6-.7 1-1.2.6l-3.6-2.6z"/>
|
|
</svg>
|
|
<svg class="icon-call" viewBox="0 0 24 24" width="21" height="21" fill="currentColor" aria-hidden="true">
|
|
<path d="M7.1 3.8c.5-.1 1 .2 1.2.7l1.3 3c.2.4.1.9-.3 1.2l-1.6 1.4a13.3 13.3 0 0 0 6.2 6.2l1.4-1.6c.3-.4.8-.5 1.2-.3l3 1.3c.5.2.8.7.7 1.2l-.5 2.6c-.1.5-.6.9-1.1.9C10.4 20.4 3.6 13.6 3.6 5.4c0-.5.4-1 .9-1.1z"/>
|
|
</svg>
|
|
</header>
|
|
|
|
<!-- Scroll de mensajes (estructura A · filas li.wa-row de B) -->
|
|
<ul id="chat-cuerpo" aria-live="polite" tabindex="-1" aria-label="Conversación"></ul>
|
|
|
|
<!-- Indicador "escribiendo…" (estructura A · contenido y animación de B) -->
|
|
<div id="chat-escribiendo"></div>
|
|
|
|
<!-- Composer (estructura A · lógica D) -->
|
|
<form id="composer" class="compose" autocomplete="off">
|
|
<button type="button" class="attach" aria-label="Adjuntar" tabindex="-1">
|
|
<svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" aria-hidden="true"><path d="M12 4v16M4 12h16"/></svg>
|
|
</button>
|
|
<div class="field">
|
|
<input id="composer-input" type="text" placeholder=" " aria-label="Mensaje" autocomplete="off" enterkeyhint="send">
|
|
<svg class="sticker" viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" aria-hidden="true"><path d="M20 12.8V8a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v8a4 4 0 0 0 4 4h4.8Z"/><path d="M20 12.8h-3.4a3.8 3.8 0 0 0-3.8 3.8V20"/></svg>
|
|
</div>
|
|
<button type="button" class="cmp-icono cmp-camara" aria-label="Cámara" tabindex="-1">
|
|
<svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" aria-hidden="true"><path d="M3 8.6A2.1 2.1 0 0 1 5.1 6.5h2.3l1.5-2h6.2l1.5 2h2.3A2.1 2.1 0 0 1 21 8.6v8.8a2.1 2.1 0 0 1-2.1 2.1H5.1A2.1 2.1 0 0 1 3 17.4Z"/><circle cx="12" cy="12.8" r="3.7"/></svg>
|
|
</button>
|
|
<button type="button" class="cmp-icono cmp-mic" aria-label="Nota de voz" tabindex="-1">
|
|
<svg viewBox="0 0 24 24" width="24" height="26" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><rect x="8.6" y="2.8" width="6.8" height="11.6" rx="3.4"/><path d="M5.6 11a6.4 6.4 0 0 0 12.8 0M12 17.4v3.8"/></svg>
|
|
</button>
|
|
<button id="composer-enviar" class="enviar" type="submit" aria-label="Enviar mensaje">
|
|
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M4.4 19.6 21 12 4.4 4.4l.1 5.9L15 12 4.5 13.7Z"/></svg>
|
|
</button>
|
|
</form>
|
|
|
|
<!-- Sheet de lista (estructura A · ciclo crear/destruir y contenido: B) -->
|
|
<div id="sheet" class="sheet" hidden>
|
|
<div id="sheet-fondo" class="sheet-fondo"></div>
|
|
<div class="sheet-panel" role="dialog" aria-modal="true" aria-labelledby="sheet-titulo">
|
|
<div id="sheet-titulo" class="sheet-titulo"></div>
|
|
<ul id="sheet-opciones" class="sheet-opciones"></ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="home-indicator" class="home-indicator" aria-hidden="true"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Ventana estrecha (≤ 900 px): pestañas fijas Editor / Vista previa (js/ux.js) -->
|
|
<nav id="tabs-movil" class="tabs-movil" role="tablist" aria-label="Vista">
|
|
<button id="tab-editor" class="tab-movil" type="button" role="tab" aria-selected="false" aria-controls="panel-editor" tabindex="-1">
|
|
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="m13.5 6.5 4 4"/></svg>
|
|
<span>Editor</span>
|
|
</button>
|
|
<button id="tab-vista" class="tab-movil" type="button" role="tab" aria-selected="true" aria-controls="panel-movil">
|
|
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" aria-hidden="true"><rect x="6.5" y="2.5" width="11" height="19" rx="2.5"/><path d="M11 18.5h2"/></svg>
|
|
<span>Vista previa</span>
|
|
</button>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
<noscript><p class="wam-noscript">Esta demo necesita JavaScript habilitado.</p></noscript>
|
|
|
|
<!-- Orden EXACTO de la SPEC §3 (todos al final del body, sin defer/module;
|
|
el único efecto al cargar es WAM.init() desde main.js) -->
|
|
<script src="js/store.js"></script> <!-- D: WAM.CLAVE/estado/normalizar; NO toca DOM al cargar -->
|
|
<script src="js/render.js"></script> <!-- B: render del chat; NO toca DOM al cargar -->
|
|
<script src="js/editor.js"></script> <!-- C: formularios del editor; NO toca DOM al cargar -->
|
|
<script src="js/interactivity.js"></script> <!-- D: flujos/typing/demo; NO toca DOM al cargar -->
|
|
<script src="js/escenarios.js"></script> <!-- C: escenarios por industria (datos); NO toca DOM al cargar -->
|
|
<script src="js/ux.js"></script> <!-- C: deshacer, diálogos, atajos, pestañas; WAM.initUX() lo llama renderEditor -->
|
|
<script src="js/main.js"></script> <!-- D: única ejecución — WAM.init() -->
|
|
|
|
</body>
|
|
</html>
|