Files

235 lines
7.8 KiB
HTML
Raw Permalink Normal View History

2026-05-26 10:52:29 -06:00
<style>
.fake {
background-image: url('img/mo.png');
background-size: cover;
background-position: center;
}
/* --- Contenedor de la Burbuja --- */
.speech-bubble {
position: relative;
background: #ffffff; /* Fondo blanco */
color: #333333; /* Texto oscuro para legibilidad */
border-radius: 0.5em;
padding: 1.5rem;
font-size: 1.1rem;
min-height: 120px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); /* Sombra para resaltar sobre el fondo */
transition: all 0.3s ease-in-out;
}
.bubble-text {
line-height: 1.5;
}
/* --- Animaciones de Personajes (Foco visual) --- */
.speaker-active {
transform: scale(1.05);
filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.2));
transition: all 0.3s ease;
}
.speaker-inactive {
opacity: 0.6;
transform: scale(0.95);
transition: all 0.3s ease;
}
/* --- COMPORTAMIENTO MOBILE (Apilamiento vertical de Bootstrap) --- */
@media (max-width: 767.98px) {
/* Apunta hacia arriba (al Médico) */
.speech-bubble-left::after {
content: '';
position: absolute;
left: 50%;
top: -20px;
transform: translateX(-50%);
border: 20px solid transparent;
border-width: 0 20px 20px 20px;
border-bottom-color: #ffffff; /* Coincide con el fondo blanco */
margin: 0;
}
/* Apunta hacia abajo (al Representante) */
.speech-bubble-right::after {
content: '';
position: absolute;
left: 50%;
top: auto;
bottom: -20px;
transform: translateX(-50%);
border: 20px solid transparent;
border-width: 20px 20px 0 20px;
border-top-color: #ffffff; /* Coincide con el fondo blanco */
margin: 0;
}
}
/* --- COMPORTAMIENTO DESKTOP (md y superior) --- */
@media (min-width: 768px) {
/* Apunta hacia la izquierda */
.speech-bubble-left::after {
content: '';
position: absolute;
left: 0;
top: 50%;
width: 0;
height: 0;
border: 20px solid transparent;
border-right-color: #ffffff; /* Coincide con el fondo blanco */
border-left: 0;
margin-top: -20px;
margin-left: -20px;
transform: none;
}
/* Apunta hacia la derecha */
.speech-bubble-right::after {
content: '';
position: absolute;
right: 0;
left: auto;
top: 50%;
width: 0;
height: 0;
border: 20px solid transparent;
border-left-color: #ffffff; /* Coincide con el fondo blanco */
border-right: 0;
margin-top: -20px;
margin-right: -20px;
transform: none;
}
}
</style>
</style>
<div class='page-sco py-3 py-md-4 bg-transparent'>
<div class='container'>
<div class='row justify-content-center align-items-center'>
<div class='col-12 anim0'>
<div class='row justify-content-center align-items-center'>
<div class='col-12 text-center'>
<h2 class='mb-4 fw-semibold text-center'>Manejo de Objeciones</h2>
</div>
<!-- Avatar Médico -->
<div class='col-6 col-md-3 text-center'>
<img src='img/med.png' class='img-fluid speaker-inactive' alt='Médico' id="medico">
</div>
<!-- Contenedor Dinámico de Diálogo -->
<div class='col-12 col-md-6 text-center'>
<div id="dialogue-bubble" class="speech-bubble">
<div id="dialogue-text" class="bubble-text">
<!-- El texto se inyecta dinámicamente mediante JS -->
</div>
</div>
</div>
<!-- Avatar Representante -->
<div class='col-6 col-md-3 text-center'>
<img src='img/rep.png' class='img-fluid speaker-inactive' alt='Representante' id="rep">
</div>
</div>
</div>
</div>
</div>
</div>
<script>
/**
* Módulo de Diálogo Interactivo
* Orquesta la secuencia de texto y audio, manipulando el DOM según el hablante activo.
*/
$(function () {
"use strict";
$('body').addClass('fake');
// Configuración de la secuencia del diálogo
const mo = [
{
text: "¿Por qué en la formulación de OGestan<sup>®</sup> Pré no observo los omegas?",
sound: typeof CourseNav !== 'undefined' ? CourseNav.createSound('audio/mo/0031-ogestanpre.mp3') : null,
img: '#medico'
},
{
text: "Doctor, es una muy buena observación. De hecho, la ausencia de omegas en OGestan<sup>®</sup> Pré responde a una decisión en la composición de la fórmula completamente intencionada.",
sound: typeof CourseNav !== 'undefined' ? CourseNav.createSound('audio/mo/mo01.mp3') : null,
img: '#rep'
},
{
text: "La clave está en el posicionamiento de OGestan<sup>®</sup> Pré, el cual fue diseñado específicamente para la etapa preconcepcional, que representa una verdadera ventana crítica de oportunidad biológica. ",
sound: typeof CourseNav !== 'undefined' ? CourseNav.createSound('audio/mo/mo02.mp3') : null,
img: '#rep'
},
{
text: "En esa etapa, la prioridad clínica absoluta no es todavía el soporte estructural del neurodesarrollo avanzado —donde los omegas tienen un papel más protagónico—, sino asegurar las condiciones necesarias para una correcta organogénesis temprana y, sobre todo, la prevención de malformaciones congénitas. Por ello, prioriza los micronutrientes esenciales para esta etapa.",
sound: typeof CourseNav !== 'undefined' ? CourseNav.createSound('audio/mo/mo03.mp3') : null,
img: '#rep'
},
];
// Caché de elementos del DOM
const $bubble = $('#dialogue-bubble');
const $text = $('#dialogue-text');
const $medico = $('#medico');
const $rep = $('#rep');
/**
* Ejecuta un nodo de diálogo recursivamente hasta finalizar el array.
* @param {number} index - Índice actual de la conversación.
*/
function playDialogueStep(index) {
// Condición de cierre: Secuencia terminada
if (index >= mo.length) {
if (typeof CourseNav !== 'undefined' && typeof CourseNav.completeLesson === 'function') {
CourseNav.setSlideVisited();
}
return;
}
const currentStep = mo[index];
// 1. Actualizar texto con transición limpia
$text.hide().html(`<p class="mb-0 m-0">${currentStep.text}</p>`).fadeIn(300);
// 2. Gestionar la orientación de la burbuja y el foco en los personajes
if (currentStep.img === '#medico') {
$bubble.removeClass('speech-bubble-right').addClass('speech-bubble-left');
$medico.removeClass('speaker-inactive').addClass('speaker-active');
$rep.removeClass('speaker-active').addClass('speaker-inactive');
} else if (currentStep.img === '#rep') {
$bubble.removeClass('speech-bubble-left').addClass('speech-bubble-right');
$rep.removeClass('speaker-inactive').addClass('speaker-active');
$medico.removeClass('speaker-active').addClass('speaker-inactive');
}
// 3. Reproducir audio e instanciar el listener recursivo
if (typeof CourseNav !== 'undefined' && CourseNav.audioController && currentStep.sound) {
CourseNav.audioController.stopAllSoundsAndPlay(currentStep.sound);
// Asumiendo que CourseNav utiliza Howler.js u otra API basada en eventos (on/once)
currentStep.sound.once("end", function () {
playDialogueStep(index + 1);
});
} else {
// Fallback para entornos de desarrollo donde el audio no esté cargado
console.warn(`[Modo Desarrollo]: Simulando delay para el audio de: ${currentStep.img}`);
setTimeout(() => {
playDialogueStep(index + 1);
}, 4000);
}
}
// Inicializar el diálogo
playDialogueStep(0);
});
</script>