La IA en el Campo de la Veterinaria

Guía Práctica y Técnica para Asistentes y Profesionales

Índice de Contenidos

1. Definición y Concepto Clave

La Inteligencia Artificial (IA) en veterinaria no es una entidad pensante, sino un conjunto de algoritmos de aprendizaje automático (Machine Learning). Estos sistemas analizan miles de datos previos (fotos, historias clínicas, análisis de sangre) para identificar patrones y predecir resultados con alta precisión.

Dato importante: La IA no sustituye al humano; funciona como un "Copiloto de Inteligencia" que ayuda al técnico a trabajar más rápido y con menos errores.

2. Áreas de Aplicación para el Asistente

3. La Ética y la "Regla de Oro"

El uso de IA en la clínica conlleva responsabilidades:

4. El Prompting: El lenguaje del futuro

Para que la IA sea útil, el asistente debe saber darle órdenes. Esto se llama Prompt Engineering. Un buen comando siempre debe incluir:

🧠 Cuestionario de Repaso (Capítulos 1 al 4)

1. ¿Cuál es la función principal de la IA en la labor diaria de un asistente veterinario?

2. ¿Qué se entiende por "alucinación" en un sistema de IA?

3. En la fórmula de "Prompting" (R-C-T-F), ¿qué significa la letra "R"?

4. ¿Cuál es la regla de oro respecto a la privacidad de los datos?

5. ¿Cómo ayuda la IA en el área de comunicación con el cliente?

5. Conceptos Complementarios de IA en Veterinaria

Para dominar la IA, es fundamental entender las ramas que la componen y cómo se aplican en el día a día de la clínica:

6. Ecosistema de Herramientas Recomendadas

(Consulta el material en: https://asoeduca.edu.co/inteligencia/)

No todas las IAs sirven para lo mismo. Aquí tienes un kit de herramientas clave para el entorno veterinario y educativo:

Texto y Análisis General:

Generación de Imágenes y Multimedia:

Gestión del Conocimiento y Estudio: NotebookLM (ahora Cuadernos de Gemini / Gemini Notebook)

NotebookLM (Google) — Actualmente integrado como "Cuadernos de Gemini" (Gemini Notebook):

Es la herramienta definitiva para estudiar y cruzar información de múltiples fuentes cerradas (tus propios apuntes, protocolos clínicos, PDFs de vademécum, enlaces de Google Docs, diapositivas o videos de YouTube), creando un asistente experto personalizado que solo responde basándose en tus documentos, reduciendo a cero el riesgo de alucinaciones médicas.

¿Cómo crear y usar tu Cuaderno en NotebookLM / Cuadernos de Gemini?

  1. Ingresa a https://notebooklm.google.com/ o accede desde tu ecosistema de Google / Gemini en la sección de Cuadernos (Notebooks).
  2. Haz clic en "Nuevo Cuaderno" (Create Notebook) y asígnale un título (ej. "Protocolos de Urgencias y Dosificación Clínica").
  3. Agrega tus Fuentes (Sources): Sube tus archivos PDF (manuales de farmacología, guías WSAVA), documentos de Google Drive, textos pegados o enlaces web.
  4. Consulta e Interactúa: Hazle preguntas específicas en el chat del cuaderno (te mostrará citas exactas de la página de tu PDF de donde sacó el dato) o genera resúmenes de estudio, guías de preguntas frecuentes y hasta resúmenes en formato de audio tipo podcast para estudiar de camino a la clínica.

7. Talleres Prácticos y Ejercicios de Aplicación

La mejor forma de aprender es haciendo. Estos talleres están diseñados para ejecutarse utilizando herramientas como Gemini (https://gemini.google.com/) y el administrador de Gems (https://gemini.google.com/gems/view).

Taller 1: Generación de Material Educativo (Texto e Imagen)

Objetivo: Crear un folleto visual para explicar un procedimiento a los tutores de mascotas.

Ejercicio Textual: Abre Gemini y utiliza la fórmula R-C-T-F.

Prompt de Texto (R-C-T-F)
Actúa como un médico veterinario especialista. El contexto es que los dueños de mascotas tienen dudas sobre la identificación electrónica. Tu tarea es redactar una guía amigable sobre cómo funciona el microchip estándar ISO 11784/85 y por qué no duele. El formato debe ser un texto de 3 párrafos con viñetas y un tono tranquilizador.

Ejercicio Visual: Pídele a la IA que genere una imagen de apoyo.

Prompt de Imagen
Genera una ilustración vectorial, estilo infografía médica moderna y limpia, que muestre a un perro de perfil y resalte con un punto luminoso la zona interescapular, indicando el lugar correcto para la implantación de un microchip. Fondo blanco.

Taller 2: Programación Asistida para la Clínica (Web Interactiva)

Objetivo: Crear una herramienta web sencilla sin necesidad de ser un programador experto, ideal para la recepción o la página web de la clínica.

Ejercicio: Pídele a la IA que escriba el código (HTML/JS) para una calculadora básica.

Prompt de Programación
Actúa como un desarrollador web experto (PHP/HTML/JS). Necesito el código completo en un solo archivo (HTML, CSS y JavaScript) para una 'Calculadora de Hidratación Básica para Perros'. Debe tener un campo para ingresar el peso del perro en Kg, y al presionar 'Calcular', debe multiplicar el peso por 50 ml para dar un requerimiento de mantenimiento diario aproximado. Diseño limpio, profesional y responsivo.

Resultado: Copia el código generado, guárdalo en un bloc de notas como calculadora.html y ábrelo en tu navegador. ¡Ya tienes una herramienta funcional!

Taller 3: Creando tu Clínica Virtual Interactiva (Google Sites, Forms e IA)

Objetivo: Aprender a construir una página web médica básica desde cero. Enseñar al estudiante a digitalizar la recepción (captura de datos), integrar elementos multimedia educativos y conectar un asistente de Inteligencia Artificial en tiempo real.

Paso 1: Digitalizando la Recepción (Creación del Google Forms)

Antes de hacer la página web, necesitamos el sistema que recibirá a los pacientes.

  1. Ve a https://forms.google.com/ y crea un formulario "En blanco".
  2. Título: "Recepción y Agendamiento Clínico".

Ejemplos de preguntas para Agendar una Cita:

  • Nombre completo del Tutor (Respuesta corta).
  • Teléfono (Respuesta corta).
  • Nombre del paciente (Respuesta corta).
  • Especie (Respuesta corta).
  • Tipo de servicio requerido (Opción múltiple: Consulta general, Vacunación, Desparasitación, Peluquería).
  • Fecha (Fecha).
  • Jornada preferida (Opción múltiple: Mañana o Tarde).

Ejemplos de preguntas para Pre-triaje (Consultorio Virtual):

  • Describe detalladamente los síntomas que presenta la mascota (Responde solo si es para consulta) (Párrafo).
  • ¿Hace cuánto tiempo iniciaron los síntomas? (Responde solo si es para consulta) (Respuesta corta).
  • Nivel de gravedad percibida (Responde solo si es para consulta) (Escala lineal del 1 al 5, donde 5 es Urgencia Vital).

(Nota: Cierra la pestaña del formulario cuando termines, se guardará automáticamente en tu Google Drive).

Paso 2: Construcción del Sitio Web (Google Sites)

  1. Ingresa a https://sites.google.com/ e inicia sesión.
  2. Haz clic en el botón "En blanco" para iniciar un nuevo proyecto.
  3. Personaliza el encabezado principal con un nombre profesional, por ejemplo: "Centro Veterinario Innova".

Creando el Banner Perfecto con IA: No necesitas saber diseñar, solo necesitas saber dar instrucciones. Usa este prompt en tu generador de imágenes:

Prompt Diseñador Gráfico (Banner)
Actúa como un experto diseñador gráfico. Estoy creando una página para mi clínica veterinaria llamada patita quebrada en google sites, crea una imagen que represente mis servicios como veterinaria por ejemplo una recepción amplia acompañada de artículos de lujo que representen la buena atención, el excelente servicio, la calidad humana, deja un espacio en una de las paredes para mi logo, necesito que generes el tamaño compatible para google sites que sea responsivo.

Página de colores hexadecimales recomendada: https://htmlcolorcodes.com/es/

Bloque HTML de ejemplo (Sección Hero con botón Agendar Cita):

HTML - Hero Section
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<style>
  body {
    margin: 0;
    padding: 0;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  }
  .hero-section {
    position: relative;
    width: 100%;
    height: 450px; /* Puedes ajustar la altura si lo deseas */
    /* Aquí va el enlace de tu imagen de fondo. He puesto una de prueba muy bonita de mascotas. */
    background-image: url('https://images.unsplash.com/photo-1543852786-1cf6624b9987?ixlib=rb-4.0.3&auto=format&fit=crop&w=1920&q=80');
    background-size: cover;
    background-position: center;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .overlay {
    /* Una capa oscura semi-transparente para que el texto blanco resalte */
    background-color: rgba(0, 0, 0, 0.55);
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0 20px;
  }
  h1 {
    color: #ffffff;
    font-size: 2.8rem;
    margin: 0 0 10px 0;
    text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
  }
  .slogan {
    color: #f1f1f1;
    font-size: 1.2rem;
    max-width: 650px;
    margin-bottom: 30px;
    line-height: 1.5;
    text-shadow: 1px 1px 3px rgba(0,0,0,0.5);
  }
  .btn-agendar {
    background-color: #2761F5; /* El color azul que solicitaste */
    color: #ffffff;
    padding: 15px 35px;
    text-decoration: none;
    font-size: 1.1rem;
    font-weight: bold;
    border-radius: 8px;
    transition: background-color 0.3s ease, transform 0.2s ease;
    box-shadow: 0 4px 6px rgba(0,0,0,0.3);
  }
  .btn-agendar:hover {
    background-color: #1e4bbd; /* Un tono un poco más oscuro al pasar el ratón */
    transform: translateY(-2px);
  }
  /* Ajustes para teléfonos móviles */
  @media (max-width: 600px) {
    h1 { font-size: 2rem; }
    .slogan { font-size: 1rem; }
  }
</style>
</head>
<body>
<div class="hero-section">
  <div class="overlay">
    <h1>Bienvenid@s a mi Veterinaria</h1>
    <p class="slogan">Protegiendo el bienestar de tu mejor amigo, porque su amor incondicional merece la mejor salud.</p>
    <a href="https://forms.gle/MFLiVbPJorcC2nqo6" target="_blank" class="btn-agendar">Agendar Cita</a>
  </div>
</div>
</body>
</html>

Prompt Alternativo para Fotografía Panorámica 8K en 16:9:

Prompt Fotografía 8K 16:9
Fotografía fotorrealista panorámica en 8k de 16:9 del interior de una clínica veterinaria ultra moderna, limpia e intensamente iluminada con luz natural. El diseño debe ser minimalista, profesional y acogedor, transmitiendo confianza y tecnología avanzada. En el fondo, se observan equipos médicos de última generación desenfocados. La paleta de colores debe ser dominada por blanco puro, azul turquesa suave y toques de verde menta claro. Composición limpia con amplio espacio vacío en el centro para futura superposición de texto. Atmósfera de bienestar animal y ciencia. No incluyas ningún texto o logotipo en la imagen.
  • Configura el Formato: Antes de generar, busca el menú de configuración de tamaño y selecciona la opción "Panorámico" o "16:9".
  • Sube y Ajusta en Sites: Sube la imagen a Google Sites. Si tu imagen ya tiene texto, haz clic en el icono de las "estrellitas mágicas" en la esquina inferior derecha del encabezado para quitar el filtro oscuro automático.

Paso 3: Integrar el Formulario, Imágenes y Videos (Diseño Visual)

En el menú derecho de Google Sites (pestaña "Insertar"), haremos lo siguiente:

  • Insertar el Formulario: Baja en el menú derecho hasta el icono de "Formularios". Selecciónalo e inserta el formulario que creaste en el Paso 1.
  • Insertar Imágenes: Sube el logotipo de tu clínica imaginaria, una foto de las instalaciones o infografías médicas.
  • Insertar Videos Educativos: Haz clic en "YouTube". Busca un video útil (ej. "Cómo identificar una urgencia veterinaria") e insértalo para informar a los clientes mientras esperan.

Paso 4: Insertar el Cerebro de la IA (El Asistente Clínico)

Vamos a darle vida a la clínica conectando nuestro Copiloto de IA.

  1. En el menú de la derecha, selecciona "Incorporar" (Embed), y elige la pestaña "Código incorporado".
  2. Copia exactamente todo el siguiente bloque de código y pégalo. Haz clic en "Siguiente" e "Insertar".
HTML - Asistente Clínico AURA IA
<!-- ESTILOS VISUALES -->
<style>
  :root {
    --color-fondo-principal: #f8f9fa; 
    --color-borde: #dee2e6;           
    --color-primario: #0d6efd;        
    --color-boton-hover: #0b5ed7;     
    --color-texto-titulo: #2c3e50;    
    --color-texto-general: #333333;   
  }
  #contenedor-chat {
    font-family: sans-serif; padding: 20px; background: var(--color-fondo-principal); 
    border-radius: 8px; border: 1px solid var(--color-borde); max-width: 500px; margin: 0 auto;
    box-shadow: 0 4px 6px rgba(0,0,0,0.05);
  }
  #btn-enviar {
    background: var(--color-primario); color: white; border: none; padding: 10px 15px; 
    border-radius: 4px; cursor: pointer; width: 100%; font-weight: bold; font-size: 16px;
    transition: background 0.3s;
  }
  #btn-enviar:hover { background: var(--color-boton-hover); }
  #btn-enviar:disabled { background: #6c757d; cursor: not-allowed; }
  #resultado {
    margin-top: 15px; padding: 15px; background: white; border-radius: 4px; 
    border-left: 4px solid var(--color-primario); min-height: 50px; 
    white-space: pre-wrap; color: var(--color-texto-general); line-height: 1.5; overflow-wrap: break-word;
  }
  .creditos { text-align: center; font-size: 11px; color: #6c757d; margin-top: 15px; font-style: italic; }
</style>

<!-- INTERFAZ DEL CHAT -->
<div id="contenedor-chat">
  <h3 id="titulo-bot" style="color: var(--color-texto-titulo); margin-top: 0; text-align: center;">Cargando asistente...</h3>
  
  <textarea id="prompt" rows="3" onkeydown="manejarEnter(event)" style="width: 100%; box-sizing: border-box; padding: 10px; margin-bottom: 10px; border-radius: 4px; border: 1px solid var(--color-borde); resize: none; font-family: inherit;" placeholder="Escribe tu consulta aquí..."></textarea>
  
  <button onclick="consultarIA()" id="btn-enviar">Enviar Consulta</button>
  
  <div id="resultado">Esperando tu consulta...</div>
  <div class="creditos">Desarrollado con Tecnología AURA IA</div>
</div>

<!-- LÓGICA Y CONEXIÓN AL BACKEND -->
<script>
  // ==========================================
  // ⚙️ ZONA DE CONFIGURACIÓN PARA EL ESTUDIANTE
  // ==========================================
  const CONFIG = {
    // 1. Ponle un nombre y un emoji a tu asistente
    nombreAsistente: "🐶 Dr. Pelos - Asistente Clínico",
    
    // 2. Define cómo debe comportarse la IA (Personalidad)
    instruccionesSistema: "Eres un veterinario experto. Respondes con un tono muy amigable, usa metáforas divertidas sobre animales, pero mantén la precisión médica.",
    
    // 3. ENLACE  
    urlServidor: "https://asoeduca.edu.co/aura/ia_html.php" 
  };
  // ==========================================

  document.getElementById('titulo-bot').innerText = CONFIG.nombreAsistente;

  function manejarEnter(event) {
    if (event.key === 'Enter' && !event.shiftKey) {
      event.preventDefault(); 
      consultarIA(); 
    }
  }

  async function consultarIA() {
    const promptInput = document.getElementById('prompt');
    const resDiv = document.getElementById('resultado');
    const btn = document.getElementById('btn-enviar');
    
    const p = promptInput.value.trim();
    if(!p) {
      resDiv.innerText = "Por favor, escribe una consulta.";
      return;
    }

    resDiv.innerText = "Conectando con el servidor central...";
    btn.disabled = true;
    
    // Empaquetamos la personalidad y la pregunta del usuario
    const payload = {
        system_prompt: CONFIG.instruccionesSistema,
        prompt: p
    };

    try {
      const response = await fetch(CONFIG.urlServidor, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
      
      const textoCrudo = await response.text();
      
      try {
        const data = JSON.parse(textoCrudo);
        resDiv.innerText = data.respuesta || "Respuesta vacía del servidor.";
        promptInput.value = ""; 
      } catch (jsonError) {
        resDiv.innerText = "Error de formato. Servidor respondió:\n" + textoCrudo;
      }
      
    } catch (e) {
      resDiv.innerText = "Error de red/CORS: " + e.message;
    } finally {
      btn.disabled = false;
    }
  }
</script>

CÓDIGO SOLO WHATSAPP

HTML - Botón Directo WhatsApp
<div style="text-align: center; padding: 15px; background-color: #f8f9fa; border-radius: 8px; border: 1px solid #dee2e6; max-width: 500px; margin: 0 auto; margin-top: 15px;">
  <p style="font-family: sans-serif; color: #333; margin-top: 0; font-size: 14px; font-weight: bold;">¿Necesitas hablar con un humano?</p>
  
  <a href="https://wa.me/573163001221?text=Hola,%20quisiera%20agendar%20una%20cita%20veterinaria" target="_blank" style="display: inline-flex; align-items: center; justify-content: center; background-color: #25D366; color: white; text-decoration: none; padding: 12px 25px; border-radius: 5px; font-family: sans-serif; font-weight: bold; font-size: 16px; width: 100%; box-sizing: border-box; transition: background-color 0.3s;">
    
    <svg style="width: 24px; height: 24px; margin-right: 10px; fill: white;" viewBox="0 0 24 24">
      <path d="M12.031 0C5.385 0 0 5.385 0 12.031c0 2.12.551 4.183 1.597 6.002L.03 24l6.115-1.602A11.966 11.966 0 0012.031 24c6.646 0 12.031-5.385 12.031-12.031S18.677 0 12.031 0zm3.834 17.291c-.281.794-1.637 1.545-2.261 1.62-.577.069-1.294.225-4.103-1.428-3.385-1.992-5.59-5.46-5.759-5.688-.169-.228-1.378-1.834-1.378-3.497 0-1.663.858-2.484 1.167-2.822.309-.338.675-.422.9-.422.225 0 .45.006.647.013.203.006.475-.075.74.563.338.816 1.097 2.672 1.197 2.869.1.197.169.428.028.694-.141.266-.213.431-.422.684-.209.253-.44.55-.631.763-.209.231-.431.484-.181.913.25.428 1.113 1.838 2.394 2.981 1.656 1.478 3.031 1.938 3.475 2.147.444.209.703.178.966-.119.263-.297 1.144-1.331 1.453-1.788.309-.456.619-.381 1.025-.225.406.156 2.569 1.209 3.013 1.434.444.225.741.338.847.525.106.188.106 1.088-.175 1.881z"/>
    </svg>
    Hablar por WhatsApp
  </a>
</div>

NOTA: Para seleccionar todo el código en el bloque de Google Sites pulsa Ctrl + A.

Paso 5: ¡Conviértete en Diseñador! (Uso de Códigos Hexadecimales)

Si observas la parte superior del código de tu Asistente, verás una lista de colores con códigos como #0d6efd. Como ejercicio, cambia el valor de --color-primario por uno de estos colores y observa cómo cambia tu asistente al instante:

Verde Quirúrgico: #198754
Naranja Adopción: #fd7e14
Rojo Urgencias / UCI: #dc3545
Azul Profesional: #0a58ca

(Nota: Puedes consultar la web https://htmlcolorcodes.com/es/ para más referencias).

Paso 6: Crea tu propio Pie de Página con IA

Copia el siguiente texto, llena los espacios entre corchetes [ ] y envíaselo a tu Inteligencia Artificial para que programe tu diseño a medida.

Prompt - Pie de Página (Footer)
Rol: Actúa como un desarrollador web experto en Frontend (HTML y CSS).
Contexto: Estoy creando una página web médica en Google Sites para mi proyecto veterinario llamado [Escribe el nombre de tu clínica]. La identidad de mi marca transmite un estilo [Ej. moderno y científico / cálido y amigable / de urgencias 24h].
Tarea: Escribe el código HTML y CSS en un solo bloque para un pie de página (footer) profesional. Debe ser responsivo y contener 3 columnas flexibles: 1. Descripción de la clínica. 2. Contacto. 3. Botón "Urgencias WhatsApp".
Formato: Entrégame únicamente el código listo para copiar y pegar. 
Reglas: Usa el color [Escribe un código Hexadecimal] para el botón y títulos. Texto general blanco o gris claro. MUY IMPORTANTE: El background-color del contenedor principal debe ser exactamente transparent para que funcione en Google Sites.

Paso 7: Creando la Sala de Espera Virtual (Música de Fondo desde Drive)

Nuestra aplicación web tendrá su propia sala de espera virtual:

  1. Sube tu archivo de audio (.mp3) a tu Google Drive. Asegúrate de compartirlo para "Cualquier usuario que tenga el vínculo".
  2. Copia el enlace y extrae el ID (la cadena larga de letras y números entre /d/ y /view).
  3. Ve a Google Sites > Insertar > Incorporar > Código incorporado, pega esto y reemplaza TU_ID_DE_DRIVE_AQUÍ:
HTML - Audio Sala de Espera
<div style="width: 100%; max-width: 500px; margin: 0 auto; text-align: center; padding: 10px;">
  <p style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-size: 14px; color: #64748b; margin-bottom: 10px; font-weight: 500;">
    🔊 Reproducir audio ambiental para la sala de espera virtual:
  </p>
  <iframe src="https://drive.google.com/file/d/TU_ID_DE_DRIVE_AQUÍ/preview" 
          width="100%" height="60" frameborder="0" allow="autoplay" 
          style="border: none; border-radius: 8px; background: transparent; box-shadow: 0 2px 8px rgba(0,0,0,0.05);">
  </iframe>
</div>

Chat Bot Personalizado (Árbol de Decisiones)

Copia todo este Prompt Maestro (que incluye las reglas estrictas y la plantilla HTML completa) y pégalo en tu IA junto con el tipo de negocio o especialidad veterinaria para que te devuelva el chatbot listo:

Prompt Maestro Completo + Plantilla HTML
Eres "Bot Builder", un Ingeniero Frontend Senior. 
El usuario te dará un tipo de negocio (ej: "Pizzería", "Ferretería", "Colegio", "Clínica Veterinaria").
Tu ÚNICA tarea es devolver un archivo HTML completo con un Chatbot de Árbol de Decisiones (basado en botones) funcional para ese negocio.

REGLAS ESTRICTAS (HARD RULES):
1. NUNCA expliques el código ni saludes. Devuelve SOLO el bloque de código empezando por ```html y terminando en ```.
2. TIENES PROHIBIDO TRUNCAR EL CÓDIGO. No uses comentarios de relleno. Debes escribir el CSS y el JS completos.
3. INVENTA los datos: Título del negocio, Avatar (emoji), Color Principal (Hexadecimal que pegue con el negocio), 3 Servicios (con precio, título, beneficios, recomendación y texto de WhatsApp) y 3 Consejos.

UTILIZA EXACTAMENTE ESTA PLANTILLA (Reemplaza los textos en MAYÚSCULAS entre corchetes con los datos inventados):

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat - [NOMBRE_DEL_NEGOCIO]</title>
<style>
  * { box-sizing: border-box; font-family: 'Segoe UI', sans-serif; }
  body { margin: 0; padding: 10px; background-color: transparent; display: flex; justify-content: center; }
  .chat-wrapper { width: 100%; max-width: 450px; height: 600px; background-color: #ffffff; border-radius: 16px; box-shadow: 0 8px 24px rgba(0,0,0,0.15); display: flex; flex-direction: column; overflow: hidden; border: 1px solid #d1d5db; color: #000000; }
  .chat-header { background-color: [COLOR_PRINCIPAL]; color: #ffffff !important; padding: 15px; display: flex; align-items: center; gap: 12px; }
  .chat-header .avatar { width: 42px; height: 42px; background-color: #ffffff; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; box-shadow: 0 2px 5px rgba(0,0,0,0.2); }
  .chat-header .info h4 { margin: 0; font-size: 1.1rem; font-weight: 700; color: #ffffff !important; }
  .chat-header .info span { font-size: 0.85rem; color: #f1faee !important; display: flex; align-items: center; gap: 5px; font-weight: 500; }
  .chat-header .info span::before { content: ''; width: 8px; height: 8px; background-color: #2ecc71; border-radius: 50%; display: inline-block; }
  .chat-messages { flex: 1; padding: 15px; overflow-y: auto; background-color: #f8f9fa; display: flex; flex-direction: column; gap: 12px; }
  .msg { max-width: 85%; padding: 12px 16px; border-radius: 14px; font-size: 0.95rem; line-height: 1.4; animation: fadeIn 0.3s ease forwards; word-wrap: break-word; }
  @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
  .msg.bot { background-color: #ffffff; color: #000000 !important; align-self: flex-start; border-bottom-left-radius: 4px; border: 1px solid #cbd5e1; box-shadow: 0 1px 3px rgba(0,0,0,0.05); }
  .msg.user { background-color: [COLOR_PRINCIPAL]; color: #ffffff !important; align-self: flex-end; border-bottom-right-radius: 4px; font-weight: 500; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
  .info-block { margin-top: 10px; background: #f1f5f9; padding: 10px 12px; border-radius: 8px; font-size: 0.9rem; border-left: 4px solid [COLOR_PRINCIPAL]; color: #1a1a1a !important; }
  .info-block b { color: #000000 !important; }
  .price-tag { font-weight: 800; color: #d62828 !important; font-size: 1.1rem; }
  .chat-options { padding: 12px; background-color: #ffffff; border-top: 1px solid #cbd5e1; display: flex; flex-direction: column; gap: 8px; }
  .btn { width: 100%; background-color: #ffffff; color: [COLOR_PRINCIPAL] !important; border: 2px solid [COLOR_PRINCIPAL]; padding: 12px 14px; font-size: 0.95rem; font-weight: 700; border-radius: 8px; cursor: pointer; text-align: left; transition: all 0.2s ease; display: flex; align-items: center; justify-content: space-between; }
  .btn:hover { background-color: [COLOR_PRINCIPAL]; color: #ffffff !important; }
  .btn-action { background-color: [COLOR_PRINCIPAL]; color: #ffffff !important; border: none; justify-content: center; text-transform: uppercase; font-weight: 800; letter-spacing: 0.5px; box-shadow: 0 4px 6px rgba(0,0,0,0.25); }
  .btn-action:hover { filter: brightness(0.85); }
  .btn-secondary { color: #333333 !important; border-color: #666666; justify-content: center; }
  .btn-secondary:hover { background-color: #f1f5f9; color: #000000 !important; }
  .typing-indicator { display: flex; gap: 4px; padding: 8px 12px; }
  .typing-indicator span { width: 8px; height: 8px; background-color: #475569; border-radius: 50%; animation: bounce 1.3s infinite both; }
  .typing-indicator span:nth-child(2) { animation-delay: 0.15s; }
  .typing-indicator span:nth-child(3) { animation-delay: 0.3s; }
  @keyframes bounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } }
</style>
</head>
<body>
<div class="chat-wrapper">
  <div class="chat-header">
    <div class="avatar">[EMOJI]</div>
    <div class="info">
      <h4>[NOMBRE_DEL_NEGOCIO]</h4>
      <span>En línea ahora</span>
    </div>
  </div>
  <div class="chat-messages" id="chatMessages"></div>
  <div class="chat-options" id="chatOptions"></div>
</div>
<script>
  const WHATSAPP_NUMBER = "573163001221";

  const SERVICIOS = {
    srv1: {
      titulo: "[EMOJI] [NOMBRE_SERVICIO_1]",
      precio: "$[PRECIO_1]",
      beneficios: "[DESCRIPCION_1]",
      recomendacion: "[TIP_1]",
      mensajeWA: "Hola, me interesa [NOMBRE_SERVICIO_1]."
    },
    srv2: {
      titulo: "[EMOJI] [NOMBRE_SERVICIO_2]",
      precio: "$[PRECIO_2]",
      beneficios: "[DESCRIPCION_2]",
      recomendacion: "[TIP_2]",
      mensajeWA: "Hola, me interesa [NOMBRE_SERVICIO_2]."
    },
    srv3: {
      titulo: "[EMOJI] [NOMBRE_SERVICIO_3]",
      precio: "$[PRECIO_3]",
      beneficios: "[DESCRIPCION_3]",
      recomendacion: "[TIP_3]",
      mensajeWA: "Hola, me interesa [NOMBRE_SERVICIO_3]."
    }
  };

  const CONSEJOS = [
    "[CONSEJO_INVENTADO_1]",
    "[CONSEJO_INVENTADO_2]",
    "[CONSEJO_INVENTADO_3]"
  ];

  const chatMessages = document.getElementById('chatMessages');
  const chatOptions = document.getElementById('chatOptions');

  // Ejecución directa para evitar fallos de window.onload
  setTimeout(() => {
    mostrarMensajeBot("¡Hola! Bienvenido a <b>[NOMBRE_DEL_NEGOCIO]</b>. Soy tu asistente virtual, ¿en qué te puedo ayudar hoy?", 0);
    setTimeout(mostrarMenuPrincipal, 600);
  }, 100);

  function agregarBurbuja(texto, remitente) {
    const burbuja = document.createElement('div');
    burbuja.classList.add('msg', remitente);
    burbuja.innerHTML = texto;
    chatMessages.appendChild(burbuja);
    chatMessages.scrollTop = chatMessages.scrollHeight;
  }

  function mostrarMensajeBot(texto, delay = 1000) {
    if (delay === 0) { agregarBurbuja(texto, 'bot'); return; }
    const indicador = document.createElement('div');
    indicador.classList.add('msg', 'bot', 'typing-container');
    indicador.innerHTML = `<div class="typing-indicator"><span></span><span></span><span></span></div>`;
    chatMessages.appendChild(indicador);
    chatMessages.scrollTop = chatMessages.scrollHeight;
    setTimeout(() => { indicador.remove(); agregarBurbuja(texto, 'bot'); }, delay);
  }

  function registrarEleccionUsuario(texto) { agregarBurbuja(texto, 'user'); chatOptions.innerHTML = ''; }

  function mostrarMenuPrincipal() {
    chatOptions.innerHTML = `
      <button class="btn" onclick="seleccionarMenuPrincipal('servicios')">📋 Ver Servicios <span>➔</span></button>
      <button class="btn" onclick="seleccionarMenuPrincipal('contacto')">📞 Contacto <span>➔</span></button>
      <button class="btn" onclick="seleccionarMenuPrincipal('consejo')">💡 Información <span>➔</span></button>
    `;
  }

  function seleccionarMenuPrincipal(opcion) {
    if (opcion === 'servicios') {
      registrarEleccionUsuario("Quiero ver los servicios");
      mostrarMensajeBot("¡Claro! Aquí tienes nuestras opciones principales:", 800);
      setTimeout(mostrarMenuServicios, 1000);
    } else if (opcion === 'contacto') {
      registrarEleccionUsuario("Necesito los datos de contacto");
      const infoContacto = `<b>📍 Ubicación y Contacto:</b><br><br>🏢 <b>Dirección:</b> Sede Principal<br>📱 <b>WhatsApp:</b> +57 316 300 1221<br>⏰ <b>Horarios:</b> Lunes a Sábado de 8:00 AM - 6:00 PM`;
      mostrarMensajeBot(infoContacto, 800);
      setTimeout(mostrarMenuVolver, 1200);
    } else if (opcion === 'consejo') {
      registrarEleccionUsuario("Dime algo útil");
      const consejoAleatorio = CONSEJOS[Math.floor(Math.random() * CONSEJOS.length)];
      mostrarMensajeBot(`💡 <b>Dato útil:</b><br><br>${consejoAleatorio}`, 800);
      setTimeout(mostrarMenuVolver, 1200);
    }
  }

  function mostrarMenuServicios() {
    let htmlBotones = '';
    for (let clave in SERVICIOS) {
      htmlBotones += `<button class="btn" onclick="verDetalleServicio('${clave}')">${SERVICIOS[clave].titulo} <span>➔</span></button>`;
    }
    htmlBotones += `<button class="btn btn-secondary" onclick="volverAlInicio()">🏠 Volver al Menú Principal</button>`;
    chatOptions.innerHTML = htmlBotones;
  }

  function verDetalleServicio(clave) {
    const servicio = SERVICIOS[clave];
    registrarEleccionUsuario(`Saber más sobre ${servicio.titulo}`);
    const respuestaBot = `<b>${servicio.titulo}</b><br><div class="info-block">💵 <span class="price-tag">Precio:</span> <b>${servicio.precio}</b></div><div class="info-block">✨ <b>Detalles:</b><br>${servicio.beneficios}</div><div class="info-block">💡 <b>Nota:</b><br>${servicio.recomendacion}</div><br>¿Te interesa?`;
    mostrarMensajeBot(respuestaBot, 1000);
    const urlWhatsApp = `https://wa.me/${WHATSAPP_NUMBER}?text=${encodeURIComponent(servicio.mensajeWA)}`;
    setTimeout(() => {
      chatOptions.innerHTML = `
        <button class="btn btn-action" onclick="window.open('${urlWhatsApp}', '_blank')">✅ Solicitar por WhatsApp</button>
        <button class="btn btn-secondary" onclick="irAtrasServicios()">🔙 Volver atrás</button>
        <button class="btn btn-secondary" onclick="volverAlInicio()">🏠 Menú Principal</button>
      `;
    }, 1400);
  }

  function irAtrasServicios() { registrarEleccionUsuario("Volver a servicios"); mostrarMenuServicios(); }
  function volverAlInicio() { registrarEleccionUsuario("Volver al inicio"); mostrarMensajeBot("¿En qué más te ayudo?", 600); setTimeout(mostrarMenuPrincipal, 800); }
  function mostrarMenuVolver() { chatOptions.innerHTML = `<button class="btn btn-secondary" onclick="volverAlInicio()">🏠 Volver al Menú Principal</button>`; }
</script>
</body>
</html>

Creación de Canciones en MP3 (Gemini y Treblo)

Crea canciones en MP3 en Gemini desde la caja de herramientas "Crear música"

Usa el siguiente prompt estructurado para componer letras y estilos musicales especializados para mascotas:

Prompt Productor Musical para Mascotas
Actúa como un productor musical y compositor experto.
Tu objetivo es crear la musica
La temática de la canción es musica especializada para mascotas . El género principal es ritmos adaptados para perros y gatos, enfocado en instrumentos como [piano violin percusión]. La vibra general debe ser [ej: tranquila etc.
Entrega el resultado exactamente con el siguiente formato:
Style Tags: [Máximo 120 caracteres con géneros e instrumentos separados por comas]
Title: [Nombre llamativo]
Lyrics: [Intro: Instrumental] [Verse 1] (4 líneas de letra) [Pre-Chorus] (2 líneas de letra para subir la energía) [Chorus] (4 líneas muy pegadizas, ritmo alto) [Bridge] (Cambio de ritmo y melodía) [Chorus] [Outro: Fade Out]

Plataforma adicional para crear las canciones: Puedes usar https://treblo.com/

Incrustar Playlist Oficial de Spotify en Google Sites

Para incrustar una playlist de Spotify directamente en tu página de Google Sites (de forma totalmente independiente a otros reproductores), debes usar el código de inserción (iframe) oficial que proporciona la plataforma.

Obtener el código en Spotify:

  1. Abre la playlist que deseas compartir en la aplicación o en la versión web de Spotify.
  2. Haz clic en los tres puntos horizontales (...) ubicados debajo del título y la portada.
  3. Selecciona Compartir y luego haz clic en Insertar lista.
  4. Ajusta las opciones visuales (color, tamaño) si lo deseas y presiona el botón Copiar código.

Estructura del Código Oficial de Inserción (iframe) de Spotify:
(Pégalo en Google Sites > Insertar > Incorporar > Código incorporado)

HTML Oficial de Spotify (Iframe Embed)
<iframe style="border-radius:12px" 
        src="https://open.spotify.com/embed/playlist/37i9dQZF1DX4sWSpwq3LiO?utm_source=generator" 
        width="100%" 
        height="352" 
        frameBorder="0" 
        allowfullscreen="" 
        allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" 
        loading="lazy">
</iframe>

Reproductor de MP3 Personalizado (WebAmp v2.1)

Estructura completa para pedirle a Gemini que actualice las pistas de tu reproductor MP3 estilo Winamp, o para copiar directamente el reproductor ya actualizado:

1. Estructura completa con el prompt para Gemini (Código Base + Instrucción de cambio de canciones):

Prompt + Código Reproductor MP3 Original
Estructura para gemini ayudame a agregar a este reproductor
  
Inicio del Código

<style>
  :root { --theme-color: #0f0; --bg-dark: #222; --bg-black: #000; }
  .winamp-container { background: var(--bg-dark); border: 2px solid #555; border-right-color: #111; border-bottom-color: #111; padding: 10px; width: 340px; color: var(--theme-color); font-family: monospace; user-select: none; }
  .header-tools { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; font-size: 11px; color: #aaa; }
  .color-picker { background: transparent; border: 1px solid #555; cursor: pointer; height: 20px; width: 25px; padding: 0; }
  .screen { background: var(--bg-black); border: 2px solid #555; border-top-color: #111; border-left-color: #111; padding: 5px; margin-bottom: 10px; position: relative; }
  
  /* Nuevo contenedor para título y tiempo */
  .track-info-bar { display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 14px; font-weight: bold; }
  .track-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 70%; }
  .time-display { color: #aaa; font-size: 12px; font-weight: normal; margin-top: 2px; }
  
  #visualizer { width: 100%; height: 60px; background: var(--bg-black); display: block; }
  .controls { display: flex; gap: 5px; margin-top: 5px; margin-bottom: 10px; justify-content: center; }
  .controls button { background: #444; color: #ddd; border: 2px solid #666; border-bottom-color: #222; border-right-color: #222; cursor: pointer; padding: 5px 10px; font-weight: bold; font-size: 12px; }
  .controls button:active { border-color: #222 #666 #666 #222; background: #333; }
  .controls button.active-btn { color: var(--theme-color); } 
  .playlist { max-height: 120px; overflow-y: auto; background: var(--bg-black); border: 2px solid #555; border-top-color: #111; border-left-color: #111; padding: 2px; }
  .playlist-item-wrapper { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #111; }
  .playlist-item { cursor: pointer; padding: 6px 4px; font-size: 12px; color: var(--theme-color); flex-grow: 1; opacity: 0.8; }
  .playlist-item:hover { background: #111; opacity: 1; }
  .playlist-item-wrapper.active .playlist-item { background: #0000aa; color: #fff; opacity: 1; }
  .dl-btn { text-decoration: none; padding: 2px 6px; font-size: 14px; margin-left: 5px; opacity: 0.7; }
  .dl-btn:hover { opacity: 1; transform: scale(1.1); }
  .playlist::-webkit-scrollbar { width: 10px; }
  .playlist::-webkit-scrollbar-track { background: var(--bg-dark); }
  .playlist::-webkit-scrollbar-thumb { background: #555; border: 1px solid #777; }
</style>

<div class="winamp-container">
  <div class="header-tools">
    <span>WebAmp v2.1</span>
    <label>Color: <input type="color" id="theme-color" class="color-picker" value="#00ff00"></label>
  </div>

  <div class="screen">
    <div class="track-info-bar">
      <div class="track-title" id="current-track">Cargando...</div>
      <div class="time-display" id="time-display">0:00 / 0:00</div>
    </div>
    <canvas id="visualizer" width="300" height="60"></canvas>
  </div>
  
  <audio id="audio-player" controls crossorigin="anonymous" style="width: 100%; height: 30px; outline: none;"></audio>
  
  <div class="controls">
    <button onclick="prevTrack()" title="Anterior">|&lt;&lt;</button>
    <button onclick="nextTrack()" title="Siguiente">&gt;&gt;|</button>
    <button id="btn-shuffle" onclick="toggleShuffle()" title="Aleatorio">SHUFFLE</button>
  </div>
  
  <div class="playlist" id="playlist-container"></div>
</div>

<script>
  const proxyUrl = 'https://asoeduca.edu.co/stream.php?id=';
  
  // Agrega la duración (duration) manualmente a cada pista
  const tracks = [
    { title: "Canción 1 - Demo", duration: "3:45", id: "1BtPp9WuuADsQJbpSPgtwHKv2S5sm6ZmP" },
    { title: "Canción 2 - Beat", duration: "2:30", id: "1AOY-7SpKOjphUD_cn6Xa1MpfCtmB_4RP" },
    { title: "Canción 3 - Groove", duration: "4:12", id: "1BEB8uwczAPDZQwChhw4tiJO2OHEeWpo_" },
    { title: "Canción 4 - Final", duration: "3:05", id: "1AzsNev-hQUBT9ihrji5CeqSelx7f2mkD" }
  ];

  const player = document.getElementById('audio-player');
  const playlistContainer = document.getElementById('playlist-container');
  const currentTrackLabel = document.getElementById('current-track');
  const timeDisplay = document.getElementById('time-display');
  const btnShuffle = document.getElementById('btn-shuffle');
  const themeInput = document.getElementById('theme-color');
  const canvas = document.getElementById('visualizer');
  const ctx = canvas.getContext('2d');
  
  let currentIndex = 0;
  let isShuffle = false;
  let currentHexColor = '#00ff00';

  themeInput.addEventListener('input', (e) => {
    currentHexColor = e.target.value;
    document.documentElement.style.setProperty('--theme-color', currentHexColor);
  });

  let audioCtx, analyser, source;
  let isAnalyzerReady = false;

  function initAnalyzer() {
    if (isAnalyzerReady) return;
    audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    analyser = audioCtx.createAnalyser();
    
    source = audioCtx.createMediaElementSource(player);
    source.connect(analyser);
    analyser.connect(audioCtx.destination);
    
    analyser.fftSize = 256; 
    const bufferLength = analyser.frequencyBinCount;
    const dataArray = new Uint8Array(bufferLength);
    
    function draw() {
      requestAnimationFrame(draw);
      analyser.getByteFrequencyData(dataArray);
      
      ctx.fillStyle = '#000';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      
      const barWidth = (canvas.width / bufferLength) * 2.5;
      let x = 0;
      
      for(let i = 0; i < bufferLength; i++) {
        let barHeight = dataArray[i] / 4.2; 
        ctx.fillStyle = currentHexColor;
        ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
        x += barWidth + 1; 
      }
    }
    draw();
    isAnalyzerReady = true;
  }

  function loadTrack(index) {
    initAnalyzer();
    if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume();

    currentIndex = index;
    const track = tracks[index];
    currentTrackLabel.innerText = track.title;
    player.src = proxyUrl + track.id;
    player.play();
    
    Array.from(playlistContainer.children).forEach((wrapper, i) => {
        wrapper.className = i === index ? 'playlist-item-wrapper active' : 'playlist-item-wrapper';
    });
  }

  function nextTrack() {
    let nextIndex = isShuffle ? Math.floor(Math.random() * tracks.length) : (currentIndex + 1) % tracks.length;
    loadTrack(nextIndex);
  }

  function prevTrack() {
    let prevIndex = currentIndex - 1;
    if (prevIndex < 0) prevIndex = tracks.length - 1;
    loadTrack(prevIndex);
  }

  function toggleShuffle() {
    isShuffle = !isShuffle;
    btnShuffle.className = isShuffle ? 'active-btn' : '';
  }

  // Formateador de segundos a minutos:segundos
  function formatTime(seconds) {
    if (isNaN(seconds)) return "0:00";
    const min = Math.floor(seconds / 60);
    const sec = Math.floor(seconds % 60);
    return `${min}:${sec < 10 ? '0' : ''}${sec}`;
  }

  // Actualizar el reloj superior mientras suena la canción
  player.addEventListener('timeupdate', () => {
    const current = formatTime(player.currentTime);
    const total = player.duration ? formatTime(player.duration) : tracks[currentIndex].duration;
    timeDisplay.innerText = `${current} / ${total}`;
  });

  player.addEventListener('ended', nextTrack);

  tracks.forEach((track, index) => {
    const wrapper = document.createElement('div');
    wrapper.className = 'playlist-item-wrapper';
    
    const trackDiv = document.createElement('div');
    trackDiv.className = 'playlist-item';
    // Se inserta el título y la duración harcodeada
    trackDiv.innerText = `${index + 1}. ${track.title} (${track.duration})`;
    trackDiv.onclick = () => loadTrack(index);

    const downloadLink = document.createElement('a');
    downloadLink.className = 'dl-btn';
    downloadLink.innerText = '💾';
    downloadLink.title = 'Descargar pista';
    downloadLink.href = proxyUrl + track.id + '&dl=1'; 
    downloadLink.target = '_blank';
    downloadLink.download = track.title + '.mp3';

    wrapper.appendChild(trackDiv);
    wrapper.appendChild(downloadLink);
    playlistContainer.appendChild(wrapper);
  });
</script>
las siguientes canciones eliminando las existentes https://drive.google.com/file/d/1AusMyXoamGQPzMiNOv_RhphFFRqFM9--/view?usp=drive_link se llama cola sin control y esta https://drive.google.com/file/d/10x0HNqN7ehAXx6Glh4tpLgG7SiNEp4YC/view?usp=drive_link se llama el calor del hogar

Fin del Código

2. Código HTML ya actualizado con "Cola sin control" y "El calor del hogar" listo para Google Sites:

HTML WebAmp v2.1 (Con tus 2 canciones nuevas)
<style>
  :root { --theme-color: #0f0; --bg-dark: #222; --bg-black: #000; }
  .winamp-container { background: var(--bg-dark); border: 2px solid #555; border-right-color: #111; border-bottom-color: #111; padding: 10px; width: 340px; color: var(--theme-color); font-family: monospace; user-select: none; margin: 0 auto; }
  .header-tools { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; font-size: 11px; color: #aaa; }
  .color-picker { background: transparent; border: 1px solid #555; cursor: pointer; height: 20px; width: 25px; padding: 0; }
  .screen { background: var(--bg-black); border: 2px solid #555; border-top-color: #111; border-left-color: #111; padding: 5px; margin-bottom: 10px; position: relative; }
  .track-info-bar { display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 14px; font-weight: bold; }
  .track-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 70%; }
  .time-display { color: #aaa; font-size: 12px; font-weight: normal; margin-top: 2px; }
  #visualizer { width: 100%; height: 60px; background: var(--bg-black); display: block; }
  .controls { display: flex; gap: 5px; margin-top: 5px; margin-bottom: 10px; justify-content: center; }
  .controls button { background: #444; color: #ddd; border: 2px solid #666; border-bottom-color: #222; border-right-color: #222; cursor: pointer; padding: 5px 10px; font-weight: bold; font-size: 12px; }
  .controls button:active { border-color: #222 #666 #666 #222; background: #333; }
  .controls button.active-btn { color: var(--theme-color); } 
  .playlist { max-height: 120px; overflow-y: auto; background: var(--bg-black); border: 2px solid #555; border-top-color: #111; border-left-color: #111; padding: 2px; }
  .playlist-item-wrapper { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #111; }
  .playlist-item { cursor: pointer; padding: 6px 4px; font-size: 12px; color: var(--theme-color); flex-grow: 1; opacity: 0.8; }
  .playlist-item:hover { background: #111; opacity: 1; }
  .playlist-item-wrapper.active .playlist-item { background: #0000aa; color: #fff; opacity: 1; }
  .dl-btn { text-decoration: none; padding: 2px 6px; font-size: 14px; margin-left: 5px; opacity: 0.7; }
  .dl-btn:hover { opacity: 1; transform: scale(1.1); }
</style>

<div class="winamp-container">
  <div class="header-tools">
    <span>WebAmp v2.1</span>
    <label>Color: <input type="color" id="theme-color" class="color-picker" value="#00ff00"></label>
  </div>
  <div class="screen">
    <div class="track-info-bar">
      <div class="track-title" id="current-track">Cargando...</div>
      <div class="time-display" id="time-display">0:00 / 0:00</div>
    </div>
    <canvas id="visualizer" width="300" height="60"></canvas>
  </div>
  <audio id="audio-player" controls crossorigin="anonymous" style="width: 100%; height: 30px; outline: none;"></audio>
  <div class="controls">
    <button onclick="prevTrack()" title="Anterior">|&lt;&lt;</button>
    <button onclick="nextTrack()" title="Siguiente">&gt;&gt;|</button>
    <button id="btn-shuffle" onclick="toggleShuffle()" title="Aleatorio">SHUFFLE</button>
  </div>
  <div class="playlist" id="playlist-container"></div>
</div>

<script>
  const proxyUrl = 'https://asoeduca.edu.co/stream.php?id=';
  
  const tracks = [
    { title: "Cola sin control", duration: "3:15", id: "1AusMyXoamGQPzMiNOv_RhphFFRqFM9--" },
    { title: "El calor del hogar", duration: "3:30", id: "10x0HNqN7ehAXx6Glh4tpLgG7SiNEp4YC" }
  ];

  const player = document.getElementById('audio-player');
  const playlistContainer = document.getElementById('playlist-container');
  const currentTrackLabel = document.getElementById('current-track');
  const timeDisplay = document.getElementById('time-display');
  const btnShuffle = document.getElementById('btn-shuffle');
  const themeInput = document.getElementById('theme-color');
  const canvas = document.getElementById('visualizer');
  const ctx = canvas.getContext('2d');
  
  let currentIndex = 0; let isShuffle = false; let currentHexColor = '#00ff00';

  themeInput.addEventListener('input', (e) => {
    currentHexColor = e.target.value;
    document.documentElement.style.setProperty('--theme-color', currentHexColor);
  });

  let audioCtx, analyser, source; let isAnalyzerReady = false;

  function initAnalyzer() {
    if (isAnalyzerReady) return;
    audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    analyser = audioCtx.createAnalyser();
    source = audioCtx.createMediaElementSource(player);
    source.connect(analyser);
    analyser.connect(audioCtx.destination);
    analyser.fftSize = 256; 
    const bufferLength = analyser.frequencyBinCount;
    const dataArray = new Uint8Array(bufferLength);
    function draw() {
      requestAnimationFrame(draw);
      analyser.getByteFrequencyData(dataArray);
      ctx.fillStyle = '#000'; ctx.fillRect(0, 0, canvas.width, canvas.height);
      const barWidth = (canvas.width / bufferLength) * 2.5; let x = 0;
      for(let i = 0; i < bufferLength; i++) {
        let barHeight = dataArray[i] / 4.2; 
        ctx.fillStyle = currentHexColor;
        ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
        x += barWidth + 1; 
      }
    }
    draw(); isAnalyzerReady = true;
  }

  function loadTrack(index) {
    initAnalyzer(); if (audioCtx && audioCtx.state === 'suspended') audioCtx.resume();
    currentIndex = index; const track = tracks[index];
    currentTrackLabel.innerText = track.title;
    player.src = proxyUrl + track.id; player.play();
    Array.from(playlistContainer.children).forEach((wrapper, i) => {
        wrapper.className = i === index ? 'playlist-item-wrapper active' : 'playlist-item-wrapper';
    });
  }

  function nextTrack() {
    let nextIndex = isShuffle ? Math.floor(Math.random() * tracks.length) : (currentIndex + 1) % tracks.length;
    loadTrack(nextIndex);
  }
  function prevTrack() {
    let prevIndex = currentIndex - 1; if (prevIndex < 0) prevIndex = tracks.length - 1;
    loadTrack(prevIndex);
  }
  function toggleShuffle() {
    isShuffle = !isShuffle; btnShuffle.className = isShuffle ? 'active-btn' : '';
  }
  function formatTime(seconds) {
    if (isNaN(seconds)) return "0:00";
    const min = Math.floor(seconds / 60); const sec = Math.floor(seconds % 60);
    return `${min}:${sec < 10 ? '0' : ''}${sec}`;
  }

  player.addEventListener('timeupdate', () => {
    const current = formatTime(player.currentTime);
    const total = player.duration ? formatTime(player.duration) : tracks[currentIndex].duration;
    timeDisplay.innerText = `${current} / ${total}`;
  });
  player.addEventListener('ended', nextTrack);

  tracks.forEach((track, index) => {
    const wrapper = document.createElement('div'); wrapper.className = 'playlist-item-wrapper';
    const trackDiv = document.createElement('div'); trackDiv.className = 'playlist-item';
    trackDiv.innerText = `${index + 1}. ${track.title} (${track.duration})`;
    trackDiv.onclick = () => loadTrack(index);
    const downloadLink = document.createElement('a'); downloadLink.className = 'dl-btn';
    downloadLink.innerText = '💾'; downloadLink.title = 'Descargar pista';
    downloadLink.href = proxyUrl + track.id + '&dl=1'; downloadLink.target = '_blank';
    downloadLink.download = track.title + '.mp3';
    wrapper.appendChild(trackDiv); wrapper.appendChild(downloadLink);
    playlistContainer.appendChild(wrapper);
  });
</script>

Paso 8: Código QR de Acceso Rápido

Por último, generamos un código QR para que los clientes entren fácil desde su celular. Puedes crearlo gratuitamente en la web oficial: https://asoeduca.edu.co/qr/

8. Profundización: La Ética en la Era de la IA Veterinaria

Más allá de la privacidad de los datos, el uso avanzado de IA requiere un marco ético riguroso:

9. De Usuarios a Creadores: Diseñando Agentes Especializados (Gems)

Un Gem es una versión de la IA que configuras una sola vez con un conjunto de instrucciones directivas, un tono específico y un rol permanente. Queda guardado en tu panel y actúa como un "empleado virtual".

10. Taller Práctico 5: Construyendo tu Primer "Gem" Veterinario

Objetivo: Crear un Gem en Gemini llamado "Traductor Clínico a Tutor".

⚙️ Nuevo Proceso de Ingreso a Gems (Desde Cuentas Gratuitas y Cuentas Pro):

  1. Ingresa a https://gemini.google.com/ con tu cuenta de Google (actualmente habilitado también para cuentas gratuitas).
  2. Dirígete al botón de engranaje o Configuración (⚙️) ubicado en la parte inferior izquierda (o en el panel lateral izquierdo) y selecciona la opción "Gems" (o entra directo a https://gemini.google.com/gems/view).
  3. Dentro del Gestor de Gems (Administrador de Gems), haz clic en el botón "+ Nuevo Gem" (Crear un Gem).
  4. En el campo Nombre, escribe: Traductor Clínico a Tutor.
  5. En el cuadro de Instrucciones, pega el bloque de abajo. Además, en la sección inferior de Conocimientos (Archivos), puedes agregar documentos (PDFs de cuidados postoperatorios, manuales de la clínica, etc.) para que tu Gem responda basándose en ellos.
  6. Haz clic en Guardar.

Instrucciones de configuración (Pega esto en tu Gem):

Instrucciones del Gem (Traductor Clínico a Tutor)
Eres un Técnico Veterinario Experto especializado en comunicación y atención al cliente. Tu único objetivo es tomar diagnósticos o indicaciones médicas complejas proporcionadas por el veterinario, y transformarlas en explicaciones claras, empáticas y tranquilizadoras para los dueños de las mascotas. Nunca debes diagnosticar ni recetar. Tu tono debe ser cálido, profesional y siempre debes incluir un recordatorio de que, ante cualquier duda, deben contactar a la clínica. El formato de salida siempre debe ser: 1. Un resumen sencillo de la situación. 2. Los pasos a seguir en viñetas. 3. Signos de alarma a vigilar. Agrega documentos etc

11. El presente: Bases de Datos e Integración

El siguiente nivel es conectar estas inteligencias directamente a los sistemas de la clínica a través de APIs. Esto permitirá que la IA lea el historial alojado en los servidores y guarde resúmenes automáticamente, todo en un entorno seguro y encriptado. Un ejemplo real en producción es ALFI (Asistente Local Financiero); puedes verlo aquí: https://alfi.mascotascolombia.org/

🧠 Cuestionario de Repaso (Capítulos 5 al 11)

1. ¿Qué rama de la IA permite que un sistema "lea" un historial clínico desordenado?

2. Si necesitas crear una ilustración médica profesional, ¿qué herramienta usarías?

3. ¿Cuál es la principal ventaja de NotebookLM (Cuadernos de Gemini) frente a buscar información en internet?

4. ¿Qué es un "Gem" o Agente Personalizado?

5. Desde una perspectiva ética, ¿qué se debe hacer al usar IA para analizar datos médicos?

12. Privacidad Absoluta y Rendimiento: IA en la Nube vs. IA Local

13. Expansión y Comunidad: IA en Marketing Veterinario

14. Análisis Predictivo: La IA como Gerente de la Clínica

15. Taller Práctico 6: Diseñando una Campaña Solidaria Multimedia

Paso 1: Escribe este comando en tu IA de texto:

Prompt Director de Marketing
Actúa como un Director de Marketing experto en el sector veterinario. Diseña una campaña para redes sociales llamada 'Lazos de Cuidado' para fomentar donaciones en refugios. Necesito: 1. Eslogan emotivo. 2. Guion de 30 seg para Instagram (indicando cámara y voz en off). 3. Sugerencia musical.

Paso 2: Toma la sugerencia musical y llévala a Suno:

Prompt Musical en Suno
Crea una pista acústica, emotiva y esperanzadora, usando guitarra y piano suave, ideal para un video sobre rescate y cuidado animal.

🧠 Cuestionario de Repaso (Capítulos 12 al 15)

1. ¿Cuál es la ventaja principal de utilizar una "IA Local"?

2. ¿Para qué requeriría una clínica estaciones con tarjetas gráficas (GPUs) potentes?

3. ¿Cómo puede ayudar la IA en una campaña solidaria?

4. ¿Qué es el Análisis Predictivo aplicado a la gestión?

16. La Revolución del Video y la IA en la Educación

17. Ecosistema de Herramientas para Creación Multimedia

18. Taller Práctico 7: Produciendo una Campaña para Carreras Técnicas

Ejercicio: Diseñar la estructura de un video promocional.

Prompt Guion TikTok (Tabla 2 Columnas)
Actúa como un director creativo de campañas educativas. Queremos invitar a jóvenes a estudiar Auxiliar Veterinario. Escribe un guion para TikTok (máx 45 seg). El formato debe ser una tabla de dos columnas: izquierda para imágenes/clips, derecha para la voz en off.

19. Taller Práctico 8: Dando Vida al Video (Banda Sonora)

Paso 1: Crea la letra en tu IA de texto:

Prompt Letra Corta
Escribe una letra corta de 4 líneas, alegre y motivadora, sobre cuidar a los animales y estudiar veterinaria.

Paso 2: Pégala en Suno usando este estilo:

Estilo Musical Suno
Pop acústico, alegre, guitarra rápida, inspirador, ritmo enérgico.

20. Ética Visual y Transparencia en Redes

🧠 Cuestionario de Repaso (Capítulos 16 al 20)

1. ¿Qué significa "Text-to-Video"?

2. Para crear una canción alegre para adopciones, usarías:

3. Regla ética importante al usar imágenes de IA:

4. ¿Cómo ayuda CapCut en la edición de video con celular?

21. Meta AI: El Asistente de Bolsillo en WhatsApp e Instagram

Meta AI ha integrado la IA directamente en WhatsApp. Funciona como un contacto más para preguntas rápidas, resúmenes de audios largos de clientes ansiosos y generación rápida de imágenes de apoyo mediante el comando /imagina.

22. Gamma App: Creando Presentaciones de Alto Impacto

Plataforma para crear presentaciones en segundos. Solo escribes el tema y la IA genera la estructura, redacta textos, elige colores y acomoda las imágenes, eliminando el "Síndrome de la Página en Blanco".

23. Taller Práctico 9: Tu Primera Exposición Generada con IA

Entra a gamma.app y utiliza este prompt:

Prompt Gamma App
Crea una presentación de 6 diapositivas titulada 'Guía Básica de Vacunación para Cachorros'. El público son dueños primerizos, por lo que el tono debe ser educativo, claro y amigable. Incluye una diapositiva explicando por qué es peligroso sacar al perro al parque sin completar su esquema. Estilo visual limpio, tonos azules y verdes.

🧠 Cuestionario de Repaso Final (Capítulos 21 al 23)

1. ¿Ventaja principal de utilizar Meta AI?

2. ¿Cómo usar Meta AI si un cliente te envía un audio muy largo?

3. ¿Para qué está diseñada Gamma App?

4. ¿Gemma y Gamma son lo mismo?

Taller 10: Nivel Maestro - Creando tu propia Gema Arquitecta Web

Automatiza el diseño creando tu propio asistente "Director de Proyecto".

  1. En Gemini (tanto en cuentas gratuitas desde el botón de engranaje / Configuración ⚙️ > Gems > Gestor de Gems, como en Gemini Advanced), selecciona "Administrador de Gems" y haz clic en "Nuevo Gem" / "Crear una Gema".
  2. Ponle un nombre: Arquitecto Web Veterinario.
  3. En las "Instrucciones" copia exactamente este bloque:
Prompt Gema: Arquitecto Web Veterinario
Rol: Eres un Senior Full-Stack Web Developer y experto en Experiencia de Usuario (UX) en el sector veterinario.

Objetivo: Tu tarea es guiar a un estudiante paso a paso para crear la página web de su clínica en Google Sites. No debes darle todo el código de golpe. Debes actuar como un consultor, haciendo UNA pregunta a la vez y esperando la respuesta antes de avanzar.

Flujo de la Entrevista (Obligatorio):
- Pregunta 1: "¡Hola! Soy tu Arquitecto Web. Para empezar a diseñar, ¿cuál es el nombre de tu clínica virtual y cuál es su especialidad (ej. felinos, urgencias 24/7, exóticos)?"
- Pregunta 2: (Tras su respuesta) "Excelente. ¿Qué emociones quieres que transmita tu clínica y cuáles son tus 2 colores favoritos para la marca?"
- Pregunta 3: (Tras su respuesta) "Perfecto. ¿Cuál es la dirección física imaginaria y el número de WhatsApp para urgencias?"

Entrega del Proyecto Final:
Una vez que el estudiante responda la Pregunta 3, no hagas más preguntas. Debes compilar y entregarle su "Kit de Construcción Web" estructurado en estas 4 partes:
1. Paleta de Colores: Dale 3 códigos Hexadecimales basados en sus gustos.
2. El Banner Panorámico: Entrégale un prompt visual optimizado ("Fotografía fotorrealista panorámica en 8k de 16:9...") incorporando la especialidad y colores.
3. El Código del Footer Transparente: Genera el código HTML/CSS del pie de página (background-color: transparent;) con sus colores, el nombre de su clínica, dirección y su enlace de WhatsApp integrado.
4. El Prompt del Asistente Clínico: Redacta las instrucciones exactas de personalidad (const identidad = "...") para el asistente virtual.

Tono: Profesional, alentador, tecnológico y muy enfocado en el bienestar animal.

La Prueba de Fuego: Guarda tu Gema e inicia un chat diciendo: "Hola, quiero crear mi clínica". Observa cómo te entrevista y genera todo tu código a medida.

Reflexión Final: El Verdadero Corazón de la Tecnología Veterinaria

Hemos navegado por algoritmos, inteligencias generativas, automatizaciones y diseño de herramientas. Pero al cerrar este cuaderno, es vital recordar por qué elegimos esta vocación.

La Inteligencia Artificial es asombrosamente rápida, eficiente y erudita. Puede procesar historiales clínicos en segundos, redactar campañas brillantes y optimizar la administración de una clínica. Sin embargo, la IA no tiene manos para acariciar y calmar a un paciente asustado antes de una cirugía, ni corazón para consolar a un tutor que se despide de su mejor amigo.

El mayor riesgo de la tecnología no es que nos reemplace, sino que nos haga olvidar nuestra humanidad. Para ustedes, la nueva generación de profesionales y técnicos veterinarios, el verdadero desafío es usar todas estas herramientas como un amplificador de su empatía.

Utilicen la IA para liberarse de las tareas repetitivas y administrativas, para que así tengan más tiempo real y de calidad para mirar a los ojos a sus pacientes. Úsenla para construir redes solidarias, conectando a la comunidad con los refugios locales y fomentando modelos de economía colaborativa donde la tecnología sirva para proteger a los animales más vulnerables. Utilicen sus nuevos conocimientos para tejer lazos inquebrantables entre la innovación tecnológica y el bienestar animal.

La enseñanza definitiva es esta: La Inteligencia Artificial puede ser el cerebro del futuro, pero ustedes siempre serán el corazón de la medicina veterinaria. Dominen la máquina, usen la tecnología para ser los profesionales más eficientes del mundo, pero nunca, bajo ninguna circunstancia, dejen que apague su compasión.