Files
cataRio/nuxt4/app/components/cata/BotonNubeCaustica.vue
josedario87 6c9ad356b1
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m6s
Fix: Actualizar modal a sintaxis Nuxt UI v4 y aplicar estilos consistentes
- Actualizar ModalAsignacionRapida a sintaxis correcta de Nuxt UI v4
  - Usar v-model:open en lugar de v-model
  - Usar slots #body y #footer directamente
  - Eliminar UCard (deprecado)

- Aplicar clases cata-* para mantener consistencia con el resto de la app
  - Usar cata-text para textos
  - Usar cata-button para botones
  - Usar cata-input para inputs
  - Usar cata-outline-box para bordes

- Respetar colores personalizados del usuario mediante variables CSS
  - selected-category usa var(--cata-primary)
  - Soporte para modo oscuro con efectos de sombra

- Eliminar icono de estrella/rayo del BotonNubeCaustica
  - Simplificar diseño dejando solo la nube con patrones cáusticos
  - Eliminar animación sparkle asociada

- Integrar modal correctamente en FormularioMuestra
  - Mover botón dentro del slot por defecto del modal
  - Eliminar modal duplicado del template
2025-10-19 01:01:55 -06:00

234 lines
5.3 KiB
Vue

<template>
<button
type="button"
class="boton-nube-caustica"
@click="$emit('click')"
>
<svg
viewBox="0 0 100 60"
xmlns="http://www.w3.org/2000/svg"
class="nube-svg"
>
<defs>
<!-- Gradiente animado para efecto cáustica -->
<linearGradient id="caustic-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" class="caustic-stop-1">
<animate
attributeName="stop-color"
values="#60A5FA;#3B82F6;#60A5FA"
dur="3s"
repeatCount="indefinite"
/>
</stop>
<stop offset="50%" class="caustic-stop-2">
<animate
attributeName="stop-color"
values="#3B82F6;#60A5FA;#93C5FD;#3B82F6"
dur="2.5s"
repeatCount="indefinite"
/>
</stop>
<stop offset="100%" class="caustic-stop-3">
<animate
attributeName="stop-color"
values="#93C5FD;#60A5FA;#93C5FD"
dur="3.5s"
repeatCount="indefinite"
/>
</stop>
</linearGradient>
<!-- Filtro para efecto de brillo suave -->
<filter id="glow">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<!-- Patrón de ondas cáusticas -->
<pattern id="caustic-pattern" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="8" fill="rgba(255,255,255,0.15)">
<animate
attributeName="r"
values="6;10;6"
dur="2s"
repeatCount="indefinite"
/>
<animate
attributeName="opacity"
values="0.1;0.3;0.1"
dur="2s"
repeatCount="indefinite"
/>
</circle>
<circle cx="30" cy="25" r="6" fill="rgba(255,255,255,0.1)">
<animate
attributeName="r"
values="4;8;4"
dur="2.5s"
repeatCount="indefinite"
/>
<animate
attributeName="opacity"
values="0.05;0.25;0.05"
dur="2.5s"
repeatCount="indefinite"
/>
</circle>
</pattern>
</defs>
<!-- Forma de nube -->
<path
d="M 25,40
C 25,35 20,30 25,25
C 25,20 30,15 35,15
C 40,15 45,17 47,20
C 50,17 55,15 60,15
C 70,15 75,20 75,28
C 80,28 85,32 85,38
C 85,44 80,48 75,48
L 30,48
C 27,48 25,45 25,40 Z"
class="nube-base"
fill="url(#caustic-gradient)"
filter="url(#glow)"
/>
<!-- Capa de patrones cáusticos -->
<path
d="M 25,40
C 25,35 20,30 25,25
C 25,20 30,15 35,15
C 40,15 45,17 47,20
C 50,17 55,15 60,15
C 70,15 75,20 75,28
C 80,28 85,32 85,38
C 85,44 80,48 75,48
L 30,48
C 27,48 25,45 25,40 Z"
fill="url(#caustic-pattern)"
class="caustic-layer"
/>
</svg>
<!-- Texto del botón -->
<span class="boton-texto">Asignación Rápida</span>
</button>
</template>
<script setup lang="ts">
defineEmits<{
click: []
}>()
</script>
<style scoped>
.boton-nube-caustica {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
padding: 0.5rem;
background: transparent;
border: none;
cursor: pointer;
transition: transform 0.2s ease;
}
.boton-nube-caustica:hover {
transform: scale(1.1);
}
.boton-nube-caustica:active {
transform: scale(1.05);
}
.nube-svg {
width: 80px;
height: 48px;
filter: drop-shadow(0 4px 8px rgba(59, 130, 246, 0.3));
transition: filter 0.3s ease;
}
.boton-nube-caustica:hover .nube-svg {
filter: drop-shadow(0 6px 12px rgba(59, 130, 246, 0.5));
}
/* Animación de la capa cáustica */
.caustic-layer {
animation: caustic-flow 4s ease-in-out infinite;
}
@keyframes caustic-flow {
0%, 100% {
opacity: 0.6;
transform: translateX(0) translateY(0);
}
25% {
opacity: 0.8;
transform: translateX(2px) translateY(-1px);
}
50% {
opacity: 0.5;
transform: translateX(-1px) translateY(1px);
}
75% {
opacity: 0.9;
transform: translateX(1px) translateY(-2px);
}
}
.boton-texto {
font-size: 0.625rem;
font-weight: 600;
color: rgb(59 130 246);
text-transform: uppercase;
letter-spacing: 0.05em;
white-space: nowrap;
transition: color 0.3s ease;
}
.dark .boton-texto {
color: rgb(147 197 253);
}
.boton-nube-caustica:hover .boton-texto {
color: rgb(37 99 235);
}
.dark .boton-nube-caustica:hover .boton-texto {
color: rgb(191 219 254);
}
/* Efecto de ondas al hacer hover */
.boton-nube-caustica:hover .nube-base {
animation: wave-pulse 1s ease-in-out;
}
@keyframes wave-pulse {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
}
/* Modo oscuro - ajustar colores del gradiente */
.dark .nube-svg .caustic-stop-1 {
stop-color: #3B82F6;
}
.dark .nube-svg .caustic-stop-2 {
stop-color: #60A5FA;
}
.dark .nube-svg .caustic-stop-3 {
stop-color: #93C5FD;
}
</style>