/* ===================================================================== WhatsApp Cloud API Mockup — css/iphone.css (Módulo A · shell) Columna de vista previa (#panel-movil, #barra-movil) y marco iPhone 393×852 (radio 55, negro) con Dynamic Island, status bar de 54 pt e indicador home. Escalado 100 % CSS (transform + var --wam-escala) para caber siempre en la pantalla. Geometría según docs/research-ui.md §7. ===================================================================== */ /* --- Escala del teléfono ---------------------------------------------- Fallback por pasos (media queries) y ajuste exacto con aritmética tipada de CSS (@supports), que calcula escala = espacio disponible / tamaño natural. El escenario reserva el tamaño YA escalado para que el layout no deje huecos ni recortes. */ :root { --wam-escala: 1; } @media (max-height: 1030px) { :root { --wam-escala: .9; } } @media (max-height: 940px) { :root { --wam-escala: .82; } } @media (max-height: 860px) { :root { --wam-escala: .74; } } @media (max-height: 780px) { :root { --wam-escala: .66; } } @media (max-height: 700px) { :root { --wam-escala: .58; } } @media (max-height: 620px) { :root { --wam-escala: .5; } } @supports (scale: calc(1vh / 1px)) { :root { /* 150 px = toolbar + barra-movil + aire; 352 px = editor mínimo + aire. px/px → número (requisito de scale()); min/max solo comparan números. */ --wam-escala: max(.3, min( 1, (100vh - 150px) / 852px, (100vw - 352px) / 393px )); } body.presentacion { /* sin editor ni barra de vista previa: solo resta la toolbar (~57 px) + aire */ --wam-escala: max(.3, min( 1, (100vh - 96px) / 852px, (100vw - 64px) / 393px )); } } /* Presentación: se oculta la barra "Vista previa / Reproducir demo" para que el teléfono crezca (en 1280×720 pasa de .67 a ~.73). */ body.presentacion #barra-movil { display: none; } /* Presentación en escritorio (ratón + teclado): captura limpia, sin toolbar. Se sale con Esc o P (js/ux.js); una pista flotante lo recuerda. */ @media (min-width: 901px) and (hover: hover) and (pointer: fine) { body.presentacion #toolbar { display: none; } body.presentacion #panel-movil { position: relative; } body.presentacion #panel-movil::before { content: "Esc para salir"; position: absolute; top: 12px; right: 16px; padding: 5px 10px; border-radius: 999px; background: rgba(11, 20, 26, .55); color: #fff; font-size: 12px; font-weight: 600; pointer-events: none; opacity: .75; z-index: 5; } @supports (scale: calc(1vh / 1px)) { body.presentacion { --wam-escala: max(.3, min(1, (100vh - 32px) / 852px, (100vw - 64px) / 393px)); } } } /* Zoom manual (lo fija js/ux.js con body[data-wam-zoom]; sin atributo = "Ajustar", el cálculo automático). Con zoom fijo el panel hace scroll. */ html body[data-wam-zoom="100"] { --wam-escala: 1; } html body[data-wam-zoom="125"] { --wam-escala: 1.25; } body[data-wam-zoom="100"] #panel-movil, body[data-wam-zoom="125"] #panel-movil { overflow: auto; } body[data-wam-zoom="100"] .iphone-escena, body[data-wam-zoom="125"] .iphone-escena { margin: 0 auto; } /* --- Columna de vista previa (#panel-movil) ---------------------------- */ #panel-movil { min-width: 0; min-height: 0; display: flex; flex-direction: column; align-items: center; padding: 14px 16px 18px; overflow: auto; background: radial-gradient(1200px 500px at 50% -10%, rgba(0, 168, 132, .08), transparent 60%), var(--wam-fondo); } /* Barra sobre el teléfono */ #barra-movil { flex: none; width: 100%; max-width: 560px; display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; } #barra-movil .barra-titulo { font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--wam-texto-suave); } #btn-reproducir { display: inline-flex; align-items: center; gap: 8px; padding: 9px 16px; border: 0; border-radius: 999px; background: var(--wam-acento); color: #fff; font-size: 13px; font-weight: 700; cursor: pointer; box-shadow: 0 4px 14px rgba(0, 168, 132, .35); transition: background-color .15s ease, transform .05s ease; } #btn-reproducir:hover { background: var(--wam-acento-hover); } #btn-reproducir:active { transform: translateY(1px); } /* Escenario: reserva el tamaño ya escalado */ .iphone-escena { flex: none; margin: auto; /* centra con espacio sobrante; sin clipping si no cabe */ width: calc(393px * var(--wam-escala)); height: calc(852px * var(--wam-escala)); } /* --- Marco iPhone: 393×852 pt, radio 55, negro (research-ui §7) -------- */ .iphone { position: relative; width: 393px; height: 852px; border-radius: 55px; background: #000; overflow: hidden; transform: scale(var(--wam-escala)); transform-origin: top left; box-shadow: 0 0 0 2px #3d4348, /* aro de titanio */ 0 0 0 3.5px #1b1f22, 0 30px 60px rgba(4, 12, 10, .45); } /* Pantalla: llena el marco; el look del chat lo gobierna .wa (módulo B) */ .pantalla { position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden; border-radius: 47px; background: #efeae2; /* valor de arranque (claro); .wa / .wa.oscuro mandan */ padding-top: 54px; /* status bar de 54 pt: el header arranca debajo */ } /* Dynamic Island: 126×37, top 11 */ .island { position: absolute; top: 11px; left: 50%; transform: translateX(-50%); width: 126px; height: 37px; border-radius: 20px; background: #000; z-index: 40; } .island::after { /* lente de la cámara frontal */ content: ""; position: absolute; top: 50%; right: 11px; transform: translateY(-50%); width: 9px; height: 9px; border-radius: 50%; background: radial-gradient(circle at 35% 32%, #223244 0 22%, #05080c 62%); } /* Status bar: 54 pt; hora "9:41" + señal / wifi / batería */ .statusbar { position: absolute; top: 0; left: 0; right: 0; height: 54px; display: flex; align-items: center; justify-content: space-between; padding: 18px 30px 0 34px; color: #000; /* en claro, status bar negra */ font-size: 15px; font-weight: 600; letter-spacing: .02em; z-index: 30; pointer-events: none; } .sb-hora { min-width: 44px; font-variant-numeric: tabular-nums; } .statusbar .sb-iconos { display: flex; align-items: center; gap: 7px; } #pantalla.oscuro .statusbar { color: #fff; } /* Indicador home: 139×5, bottom 8 */ .home-indicator { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); width: 134px; height: 5px; border-radius: 3px; background: #fff; /* en oscuro */ z-index: 70; /* encima de la hoja inferior (.sheet z 60), como en iOS */ pointer-events: none; } #pantalla:not(.oscuro) .home-indicator { background: #000; } /* en claro, negro */ /* --- Colocación del chat (estructura A; la estética es css/whatsapp.css B) */ #chat-header { flex: none; } .header-linea { display: flex; align-items: center; gap: 4px; min-width: 0; } #chat-verificado { display: inline-flex; flex: none; } #chat-cuerpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; list-style: none; padding: 8px 0 14px; scroll-behavior: auto; /* el suave solo en enfocarEnChat (behavior explícito) */ overscroll-behavior: contain; } #chat-escribiendo { flex: none; } #composer { flex: none; } /* Composer: solo valores de arranque con var(--wa-*) de B (con fallback); whatsapp.css (cargado después) prevalece en caso de empate. */ #composer .attach, #composer .enviar { display: inline-flex; padding: 2px; border: 0; background: none; cursor: pointer; } #composer .attach { color: var(--wa-chrome-text, #000); } #composer .field svg { flex: none; } #composer-input { flex: 1 1 auto; min-width: 0; padding: 0; border: 0; outline: none; background: transparent; color: inherit; font-size: 16px; } #composer-input::placeholder { color: var(--wa-text-meta, #667781); } /* Color de arranque de los iconos del header (B puede reestilarlos) */ #chat-header .back-chevron { color: var(--wa-accent, #00a884); } #chat-header .icon-video, #chat-header .icon-call { color: var(--wa-chrome-text, #111b21); } /* --- Modo presentación: el iPhone se centra y respira más --------------- */ body.presentacion #panel-movil { padding: 14px 20px 22px; } /* --- Móvil real (≤ 520 px): sin marco ---------------------------------- En el propio teléfono del consultor sobra el iPhone dibujado: la pantalla ocupa el ancho y el alto disponibles a escala 1 (sin isla, status bar ni indicador home duplicados). body.con-marco lo desactiva. */ @media (max-width: 520px) { html body:not(.con-marco) { --wam-escala: 1; } body:not(.con-marco) #panel-movil { padding-left: 0; padding-right: 0; } body:not(.con-marco) #barra-movil { padding: 0 16px; margin-bottom: 8px; } body:not(.con-marco) .iphone-escena { flex: 1 1 auto; width: 100%; height: auto; min-height: 420px; margin: 0; } body:not(.con-marco) .iphone { width: 100%; height: 100%; border-radius: 0; transform: none; box-shadow: none; background: transparent; } body:not(.con-marco) .pantalla { border-radius: 0; padding-top: 0; } body:not(.con-marco) .island, body:not(.con-marco) .statusbar, body:not(.con-marco) .home-indicator { display: none; } body:not(.con-marco) .wa #composer { padding-bottom: 8px; } body:not(.con-marco) .wa .sheet-panel { padding-bottom: 12px; } } /* --- Accesibilidad: menos movimiento ------------------------------------- */ @media (prefers-reduced-motion: reduce) { #btn-reproducir { transition: none; } }