# CSS & JavaScript Conventions ## Estructura del módulo - Genera HTML + CSS + JS (o Vue 3 si es necesario) - Define una clase raíz en kebab-case: `product-card`, `hero-section`, etc. - Todo el CSS y JS scopeado bajo esa clase raíz --- ## CSS ### Tailwind First Usar TailwindCSS como método principal. Solo CSS custom cuando Tailwind no cubra el estilo o se necesiten estados complejos/transiciones específicas. ```html

Title

``` ### BEM para CSS Custom Cuando se necesite CSS personalizado, siempre scopeado bajo la clase raíz con BEM: ```css .hero-section { } .hero-section__title { } .hero-section__image { } .hero-section--dark { } ``` Nunca usar clases globales sin prefijo de módulo. ### CSS Variables del tema ```css var(--main-color) /* Color de marca primario */ var(--main-color-light) /* Variante clara */ var(--main-color-dark) /* Variante oscura */ ``` ### Estilos inline con fallbacks Patrón para colores configurables por el usuario: ```html

``` ### Clases utilitarias de Acai | Clase | Descripción | |-------|-------------| | `transition3s` | Transición suave 0.3s | | `click-a-child` | Hace el padre clickeable via primer `` hijo | | `line-clamp2` / `line-clamp3` / `line-clamp5` | Truncar texto a N líneas | | `filter-white` | Filtro CSS para hacer imágenes/iconos blancos | | `lazyload` | Lazy loading (usar con `data-src`) | | `text-shadow` | Sombra de texto para legibilidad sobre imágenes | | `wysiwyg` | Wrapper para contenido de texto enriquecido | | `bg-main-color` / `bg-main-color-light` / `bg-main-color-dark` | Fondos con color primario | | `text-main-color` / `text-main-color-light` / `text-main-color-dark` | Texto con color primario | --- ## JavaScript ### Module Scripts (`script.js`) JavaScript scopeado al módulo usando `section_id`: ```js const section = document.getElementById('{{ section_id }}'); if (section) { const buttons = section.querySelectorAll('.btn'); // ... } ``` ### CmsApi (Client-Side) ```js // Callback CmsApi.hook('/hooks/module_id/', { action: 'getData', id: 123 }, function(response) { console.log(response); }); // Promise CmsApi.hook('/hooks/module_id/', { action: 'getData', id: 123 }).then(function(res) { console.log(res); }).catch(function(err) { console.error(err); }); ``` ### Traducción en JavaScript Todo texto visible al usuario debe usar `CmsApi.t_var()`: ```js CmsApi.t_var('Inicia sesión para guardar favoritos'); ``` ### Cuándo usar Vue 3 Usar Vue 3 CDN cuando la lógica requiera: - Doble binding / reactividad - Solicitudes asíncronas complejas - Componentes reutilizables - Gestión de estado local - Ciclos de vida Para lógica simple, usar JavaScript vanilla. ### Vue 3 Integration ```html

${ message }

``` Siempre usar `'${'` y `'}'` como delimitadores Vue para evitar conflicto con Twig. **IMPORTANTE: JS Vue SIEMPRE en `script.js`, nunca inline.** Twig también interpreta `${ }`. Si el JS con Vue está inline en `