# CSS y JavaScript — Convenciones del Módulo Este documento define cómo escribir CSS, JavaScript y, cuando hace falta, Vue 3 dentro de un módulo Acai. Cubre la regla "Tailwind first" + BEM para CSS custom, las clases utilitarias propias de Acai (`transition3s`, `click-a-child`, `line-clamp2`, `lazyload`, `bg-main-color`, etc.), las CSS variables del tema (`--main-color`), el patrón obligatorio de **scoping** vía la clase raíz del módulo, la regla dura de que `script.js` y `style.css` son **archivos estáticos** (sin Twig dentro), cómo pasar valores dinámicos desde `index-base.tpl` a JS vía `data-*`, cuándo usar Vue 3 y cómo integrarlo evitando conflicto de delimiters con Twig, y los componentes nativos del builder (Carousel `c-tns-wrapper`, Lightbox, Breadcrumb, AOS, Lazy loading). Léelo antes de escribir cualquier `style.css` o `script.js`. ## Estructura del módulo - Cada módulo genera HTML + CSS + JS (y opcionalmente Vue 3). - Define una **clase raíz en kebab-case** específica del módulo: `product-card`, `hero-section`, `buscador-apartados`. - **Todo el CSS y JS deben quedar scopeados bajo esa clase raíz.** ## CSS ### Tailwind first Usa TailwindCSS como método principal. Reserva CSS custom solo cuando Tailwind no cubra el caso (estados complejos, transiciones específicas, animaciones). ```html
```
### Clases utilitarias de Acai
| Clase | Descripción |
|-------|-------------|
| `transition3s` | Transición suave 0.3s |
| `click-a-child` | Hace al padre clickeable vía el primer `` hijo |
| `line-clamp2` / `line-clamp3` / `line-clamp5` | Truncar texto a N líneas |
| `filter-white` | Filtro CSS para teñir imágenes/iconos en blanco |
| `lazyload` | Activa lazy loading (usar con `data-src`) |
| `text-shadow` | Sombra de texto para legibilidad sobre imágenes |
| `wysiwyg` | Wrapper para contenido rico (estilos coherentes) |
| `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 |
| `titulo-main-color` / `titulo-white` | Estilos de título resaltado |
| `c-tns-wrapper` / `c-tns-container` / `c-tns-nav-container` | Carousel built-in |
| `glightbox` | Activa lightbox |
### Reglas para `style.css`
`style.css` es **estático**. Reglas duras:
- **NO** uses sintaxis Twig (`{{ ... }}`, `{% ... %}`) ni atributos builder (`c-if`, `c-for`).
- **NO** escribas selectores que dependan de `{{ section_id }}` — scopea con la clase raíz del módulo.
```css
/* CORRECTO — scopeado con clase raíz */
.product-card { }
.product-card__title { color: var(--main-color); }
/* INCORRECTO — Twig inside */
#{{ section_id }} h3 { }
```
## JavaScript
### `script.js` es estático
Igual que `style.css`: **NO** uses sintaxis Twig dentro. Si necesitas valores dinámicos, pásalos desde `index-base.tpl` vía atributos `data-*`.
#### Patrón correcto
`index-base.tpl`:
```html
```
### Breadcrumb
```html
```
## Reglas críticas
1. `script.js` y `style.css` son **estáticos** — sin sintaxis Twig dentro.
2. Para valores dinámicos en JS, pásalos desde `index-base.tpl` vía atributos `data-*`.
3. Define una **clase raíz en kebab-case** por módulo. Scopea TODO el CSS/JS bajo ella.
4. Tailwind first; CSS custom solo donde Tailwind no llegue, siempre con BEM.
5. Vue 3: redefine `delimiters: ['${', '}']` para evitar conflicto con Twig.
6. Mountea Vue sobre `#app-{{ section_id }}`.
7. Usa las clases utilitarias de Acai (`transition3s`, `lazyload`, `bg-main-color`, etc.) antes de inventar utilidades.
8. NO embebas lógica `