---
name: gambooza-design
description: "Diseñar, construir o mejorar cualquier página, documento, informe, propuesta, presentación, artifact o app firmada por Gambooza: informes de descuadre para clientes, propuestas comerciales, notas internas de estado, dashboards, visores. Da la identidad (Fira Sans + Archivo, verde bosque sobre menta), el criterio de composición y la CSS pública con tokens y primitivas .gz-*."
---

# Diseña como Gambooza

Actúa como diseñador, editor y responsable de datos de Gambooza. Convierte el material
disponible en una página que un lector reconozca como nuestra en el primer vistazo y entienda
en tres segundos. Da forma al argumento y a la página a la vez: no "restyles" un volcado de
datos ni ensambles componentes genéricos.

Fuente única de criterio: este fichero. Fuente única de estilos: la CSS pública.

| Recurso | URL |
|---|---|
| Esta guía | `https://gambooza-design.web.app/DESIGN.md` |
| Estilos completos (tokens + primitivas `.gz-*`) | `https://gambooza-design.web.app/gambooza.css` |
| Solo tokens (variables `--gz-*`, para apps con CSS propia) | `https://gambooza-design.web.app/tokens.css` |
| Modo oscuro (opcional, solo apps) | `https://gambooza-design.web.app/tokens-dark.css` |
| Logo | `https://gambooza-design.web.app/logo.svg` |
| Guía visual con ejemplos de marcado | `https://gambooza-design.web.app/` |

## Qué cargar en cada caso

| Vas a hacer… | Lee | Carga |
|---|---|---|
| **Página o visor nuevo** (desde cero) | esta guía | `<link>` a `gambooza.css` y construye con las clases `.gz-*` |
| **Página o visor que ya existe** (tiene su CSS) | esta guía | `<link>` a `tokens.css` y mapea sus variables a `--gz-*`; no toques su maquetación |
| **Artifact de Claude** (claude.ai, Claude Code) | esta guía | el `<style>` íntegro del Apéndice A (el sandbox no admite CSS externa) |

En los tres casos, además, el `<link>` de Google Fonts de la sección "Cómo cargar los estilos".

## Contexto de Gambooza

Gambooza pone **una cámara** con inteligencia artificial en la barra o la cocina de un
restaurante (una cámara normal: no es una "microcámara", ni un sensor, ni un dispositivo en
el grifo), cuenta lo que se sirve (cervezas por grifo, platos), lo cruza con el TPV y enseña
**en euros** lo que se sirve y no se cobra.

**Diferencial, y es lo primero que debe entenderse en cualquier página comercial:** el TPV
solo sabe lo que se cobró; la cámara ve lo que se sirvió. Por eso *somos los únicos que te
decimos lo que realmente ocurre en tu negocio.* Todo lo demás (informes, vídeos, manager
virtual) existe porque tenemos ese dato.

Qué recibe el cliente (hechos, no los adornes ni los cambies):

- **Informe semanal**, no diario: cervezas servidas y no cobradas, malas praxis detectadas,
  peor día, desglose por grifo y por turno. Llega por WhatsApp con enlace al dashboard.
- **Vídeo de cada mala praxis** (clip de unos segundos, a velocidad normal) y resúmenes en
  vídeo del día.
- **El conteo es agregado, nunca cerveza a cerveza**: la cámara cuenta lo servido y se compara
  con lo cobrado por día, turno y grifo. **No se identifica qué cerveza concreta no se
  pagó**; nunca dibujes ni escribas «esta caña no pasó por caja». Las malas praxis son
  acciones visibles en vídeo: **cerveza tirada por el sumidero**, vaso mal tirado, etc.
- **Manager Virtual**: un agente en WhatsApp al que el dueño le pregunta en lenguaje
  natural. Con el plan de cervezas: cuántas se sirvieron sin cobrar y qué día fue el peor,
  qué malas praxis se repiten y en qué turno, el gráfico de la semana o de un día, los vídeos
  de una praxis. Con el TPV conectado, además: qué pasó ayer en el local, ticket medio, qué
  se vendió más y menos, y un resumen de ventas cada mañana (por franjas horarias o lo que
  pida) sin tener que preguntar.

**No prometas plazos ni condiciones comerciales** (tiempo de instalación, cuándo llega el
primer informe, permanencia, precios) salvo que te los den en el material: comprometen a
Gambooza. Si faltan, se omiten.

Dos lectores, y el diseño cambia según cuál sea:

- **Dueño o encargado de restaurante** (cliente). Lee en el móvil, con prisa, no es técnico.
  Quiere saber cuánto pierde, dónde y qué hacer mañana. Una cifra grande en euros primero,
  frases cortas, cero jerga. **Nunca** aparece vocabulario interno: ni nombres de modelos,
  ni "anotador", ni "recall", ni "motion", ni identificadores de vídeo.
- **Equipo Gambooza** (operaciones, ventas, anotación, ingeniería). Quiere estado,
  decisiones y evidencia. Se permiten términos internos, pero cada cifra se explica. Las
  tablas densas están bien.

La página debe ser **precisa, tranquila, directa y concreta**. La confianza sale de la
claridad y de las cifras, nunca de adjetivos, adornos o certezas fingidas.

## Orden de prioridades

Cuando dos exigencias choquen, protege en este orden:

1. Los hechos, cifras, unidades, periodos y restricciones de privacidad que te han dado.
2. El framework, rutas y estructura del proyecto que ya exista (no impongas un HTML suelto
   si hay una app).
3. Que la pregunta del lector, la respuesta mejor sostenida y la evidencia se vean al momento.
4. La autoría Gambooza inconfundible: cabecera con logo y wordmark, Fira Sans + Archivo,
   menta de fondo, contención.
5. Una composición específica para este material, ni la plantilla de siempre ni el reflejo
   genérico del modelo.
6. Responsive, interacción y detalle, sin debilitar la jerarquía.

Pregunta (una sola tanda de preguntas) solo si seguir adelante cambiaría el significado
comercial, una cifra, un periodo, la identidad del cliente, una recomendación o una llamada
a la acción. Si no, omite lo desconocido, márcalo como "sin dato" y sigue.

## Cómo cargar los estilos

Enlaza la hoja pública **una vez**, en el `<head>`, junto con las fuentes de Google. Así, si
cambiamos un color, cambia en todos los documentos a la vez:

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800&family=Fira+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://gambooza-design.web.app/gambooza.css">
```

- **Artifact de Claude (claude.ai o Claude Code)**: su sandbox bloquea hojas de estilo
  externas salvo Google Fonts. Mantén el `<link>` de fuentes y, en vez del `<link>` a
  `gambooza.css`, pega **íntegro y sin tocar** el `<style>` del Apéndice A (es la misma
  hoja, generada desde ella). No lo resumas, no lo "adaptes", no lo traduzcas a Tailwind.
- **App existente con su propia CSS** (visores, dashboards): enlaza solo `tokens.css` y
  mapea sus variables a las `--gz-*`. No copies valores hexadecimales.
- Nunca `@import` en la página, nunca `file://`, nunca un placeholder de URL.
- La red permitida por defecto: la CSS pública, el logo, Google Fonts y los datos que te
  hayan dado. Sin librerías de iconos, sin analítica, sin fuentes de stock. Chart.js desde
  cdnjs **solo** si hay una serie temporal que las barras CSS no puedan contar.

## Trabaja en cuatro pasadas

### 1. Encuadra el trabajo del lector

Antes de diseñar, responde en privado:

- ¿Quién abre esto, dónde (móvil, correo, WhatsApp, reunión) y para decidir qué?
- ¿Cuál es la respuesta mejor sostenida por los datos?
- ¿Qué evidencia la hace creíble?
- ¿Qué límite o incertidumbre cambiaría su interpretación?
- ¿Qué debe quedar consultable sin dominar la primera lectura?

Normaliza cifras, unidades, fechas y fuentes. Distingue lo observado (la cámara contó 356),
lo derivado (25 sin cobrar), lo proyectado (≈ 4.500 € al año) y lo recomendado. No inventes
intención, urgencia, culpables ni plazos.

Ordena por necesidad del lector, no por el orden de la fuente. Da dos velocidades:

- **Lectura rápida**: cabecera, título, cifras decisivas, pies y conclusión cuentan el
  argumento solos. Un lector que solo lea los títulos debe entender el documento.
- **Lectura de auditoría**: tablas exactas, método, límites y fuentes conservan el registro,
  al final y en pequeño.

Simplifica el lenguaje, nunca la afirmación: conserva cada periodo, base y condición que
cambie el significado. "25 cervezas servidas y no cobradas en la barra, del 1 al 7 de
septiembre" y no "una desviación importante".

Cada sección responde una pregunta nueva del lector. Fusiona duplicados. Una sola casa
para cada evidencia: una tabla posterior puede dar la consulta exacta, pero no un segundo
resumen, gráfico o conclusión que repita lo mismo con la misma prominencia.

### 2. Elige la composición

El primer viewport es el argumento, no una portada seguida de preámbulo. Si el lector solo
viera esa pantalla, debería recordar la cifra o la decisión, no solo el título.

Antes de diseñar, nombra en privado la maqueta obvia que sugiere el tipo de documento
(cabecera → 4 KPIs iguales → tabla → conclusión) y recházala salvo que el material la
merezca. Compara dos estructuras distintas de verdad (topología, densidad, dónde va la
evidencia), no dos paletas.

Empareja la apertura con el trabajo:

- **Una conclusión o recomendación**: la respuesta y su base decisiva, co-protagonistas.
- **Una comparación** (semana vs semana, grifo vs grifo, servido vs cobrado): las
  alternativas sobre la misma base visual, para que la diferencia se vea y no se reconstruya.
- **Una tendencia**: la relación o la excepción manda; el registro exacto debajo.
- **Un estado sin decisión** (nota interna): el estado mejor sostenido, su implicación y la
  pregunta abierta, sin inventar una llamada a la acción.

Elige la geometría antes que los componentes: magnitud → longitud sobre una escala común;
cambio en el tiempo → orden horizontal; composición → proporción; umbral → distancia a un
límite; alternativas → filas alineadas. Tablas para consulta exacta, prosa para una
conclusión, gráfico solo cuando la relación se entiende antes en imagen. No pongas barras
solo porque hay números.

Compón la página como un campo, no como una pila de componentes: un hilo por página y una
relación focal por sección, con pocos objetos de apoyo y espacio alrededor. Varía densidad y
calma manteniendo una sola gramática visual. Termina con la decisión, la acción o la
pregunta abierta; después, fuentes y pie, en silencio. La página no "se acaba" tras una tabla.

Da a cada documento **un movimiento organizador que sea suyo** (una comparación, un umbral,
una secuencia por turnos, un ritmo de evidencia) y que no se pudiera trasplantar a otro
documento sin cambiarlo. Debe aclarar, no decorar.

Prueba del entrecerrar de ojos: la afirmación dominante y el camino de lectura deben ser
obvios de un vistazo. Si todos los bloques pesan igual, rediseña antes de programar.

Cuando la página parezca "demasiado segura", refuerza una relación focal con proporción o
densidad y silencia lo demás. Cuando el material sea escaso, mejora selección y explicación
y deja los huecos honestos; nunca los rellenes con paneles, iconos, colores o efectos.

### 3. Sistema visual de Gambooza (autoridad)

Esta sección decide. La CSS ejecuta los tokens, roles tipográficos, estados y primitivas;
estas instrucciones deciden composición, jerarquía y cuándo procede cada primitiva. No
introduzcas un sistema paralelo.

#### Marca y cabecera

- **Nombre**: en texto corriente, **Gambooza**. La grafía **gamb00za** (dos ceros) es el
  *wordmark*: solo en el logotipo, la cabecera y el pie, nunca dentro de una frase. Nada
  debajo del wordmark: no hay claim.
- **Logo**: una "g" verde bosque dentro de un círculo menta (`logo.svg`). Tal cual: sin
  recolorear, estirar, sombrear ni reconstruir en CSS. Mínimo 24 px. Un solo logo por
  página, en la cabecera. Sobre fondo oscuro o foto va igual, su círculo ya lo aísla.
- **Cabecera de documento** (`.gz-header`): a la izquierda, eyebrow opcional + título h1 +
  metadatos (`.gz-meta`: cliente · periodo · fecha, máximo tres campos, todos reales); a la
  derecha, `.gz-brand` con logo y wordmark. Separación con espacio y una línea de 1 px.
- **Pie** (`.gz-footer`): "Gambooza" a la izquierda y una sola línea de
  fecha de generación o contacto a la derecha.

Esqueleto de un documento independiente (conserva este orden de hijos directos):

```html
<body>
<main class="gz-page">
  <header class="gz-header">
    <div>
      <p class="gz-eyebrow">Informe semanal · barra</p>
      <h1>El grifo 3 pierde 87 € a la semana</h1>
      <p class="gz-meta"><span>Bar Ejemplo</span><span>1–7 sep 2026</span><span>generado el 8 sep</span></p>
    </div>
    <a class="gz-brand" href="https://gambooza.com">
      <img src="https://gambooza-design.web.app/logo.svg" alt="Gambooza">
      <span class="gz-wordmark">gamb00za</span>
    </a>
  </header>
  <p class="gz-lead">…</p>
  …
  <footer class="gz-footer"><span>Gambooza</span><span>Generado el 8 sep 2026</span></footer>
</main>
</body>
```

#### Rejilla y alineación

- **Documentos**: una columna de 880 px (`.gz-page`), 24 px de margen lateral (16 en móvil).
  La prosa ocupa como mucho 68 caracteres; **las tablas, barras y comparaciones ocupan todo
  el ancho** del documento.
- **Apps y dashboards**: 1200 px (`.gz-page--wide`), rejillas de 2 o 3 (`.gz-grid--2/--3`),
  1 columna por debajo de 640 px.
- Todo objeto se alinea a un borde compartido. Bloques equivalentes comparten rol
  tipográfico, posición del valor y alineación. Los pares de una misma fila tienen la misma
  altura visual.
- Un rectángulo vacío grande (una división a medias, un tercer elemento huérfano) es un
  fallo: reagrupa o apila.
- No metas hallazgos desiguales en celdas iguales: si una cifra decide, dale más peso.

#### Tipografía y ritmo

Dos familias, las de gambooza.com:

| Rol | Familia | Peso | Tamaño | Clase / regla |
|---|---|---|---|---|
| Título de página | Fira Sans | 700 | 40 px | `.gz-header h1` (`--gz-text-display`) |
| h1 normal / h2 / h3 | Fira Sans | 700 / 700 / 600 | 32 / 24 / 19 px | etiquetas HTML, `letter-spacing −0.02em` |
| Entradilla | Fira Sans | 500 | 19 px | `.gz-lead` |
| Cifra de KPI | Fira Sans | 700 | 38 px, tabular | `.gz-stat-value` |
| Cuerpo | Archivo | 400 (énfasis 600) | 16 px, interlínea 1,5 | `p`, `li` |
| Tablas, botones, etiquetas | Archivo | 400–600 | 14 px | `.gz-table`, `.gz-btn`, `.gz-badge` |
| Pie de dato, ejes, eyebrow | Archivo | 400–600 | 12,5 px | `.gz-caption`, `.gz-eyebrow` |
| Código, identificadores | monoespaciada | 400 | 0,9 em | solo documentos internos |

- Usa los roles publicados. **No inventes tamaños ni pesos**: máximo tres tamaños por
  página además del cuerpo.
- El cuerpo nunca baja de 14 px; los pies, de 12,5. No hagas caber densidad con letra gris
  diminuta: reescribe.
- Cifras alineadas en tabular (la CSS ya lo hace en stats, tablas y barras). Pares
  equivalentes comparten tamaño aunque una cifra sea mayor o una cadena más larga.
- Ritmo vertical por relación, con un solo dueño por hueco: título → su primer párrafo,
  cerca (12 px); párrafo → párrafo, 16; grupo → grupo, 24; sección → sección, 48. No
  repares una transición con un margen suelto: repara la agrupación.
- Títulos en frase (mayúscula inicial) que **afirman algo concreto**: "El grifo 3 pierde
  87 € a la semana", no "Análisis grifo 3". Sin numeración decorativa, sin cadencia
  repetitiva, sin lenguaje de autoría ("en esta sección analizamos").
- Sin cursiva para énfasis: peso 600 o `--gz-ink-muted` para des-enfatizar. Sin texto
  justificado, sin sangría de primera línea. Sin rayas largas (—) en el copy: coma o punto.
- El eyebrow (`.gz-eyebrow`, mayúsculas espaciadas) existe, pero **solo uno** por página,
  encima del h1 de la cabecera. No es una etiqueta de sección.

#### Color, superficies y bordes

La paleta es **verde bosque sobre menta claro**. Es tranquila a propósito: el color fuerte se
reserva para lo que significa algo.

| Token | Valor | Uso |
|---|---|---|
| `--gz-ink` | `#2E3D34` | Todo el texto. Botón *outline*. |
| `--gz-ink-muted` | `#557260` | Texto secundario, etiquetas, pies (pasa AA en las tres superficies). |
| `--gz-ink-soft` | `#87AB95` | Solo decorativo o texto ≥ 24 px. **Nunca** letra pequeña (2,5:1). |
| `--gz-bg` | `#DDF6F3` | Fondo de página. |
| `--gz-surface` | `#F4FFF8` | Hero, contenedores grandes, callouts. |
| `--gz-surface-2` | `#E5F5E3` | Cabeceras de tabla, chips, código. |
| `--gz-white` | `#FFFFFF` | Tarjetas de datos y tablas (máximo contraste para cifras). |
| `--gz-mint` | `#A8D4B9` | Primario de marca: logo, rellenos suaves, bordes fuertes. |
| `--gz-sage` | `#87AB95` | Tarjeta sólida con texto blanco (`.gz-card--solid`), una por página. |
| `--gz-teal` | `#87ACA7` | Info, anillo de foco. |
| `--gz-border` | `#C9DCC2` | Todos los bordes, siempre de 1 px. |

Semántico (lo que significan los números):

| Significado | Relleno / barra | Texto sobre claro |
|---|---|---|
| Cuadra, cobrado, mejoró | `--gz-good` `#79BA6A` | `--gz-good-strong` `#357A43` |
| Descuadre, servido y no cobrado, pérdida | `--gz-bad` `#FF4242` | `--gz-bad-strong` `#C53030` |
| Atención, pendiente, revisar (ámbar cerveza) | `--gz-warn` `#E8A93A` | `--gz-warn-strong` `#8A5A0B` |
| Sin dato, deshabilitado | `--gz-neutral` `#B9C9BD` | `--gz-ink-muted` |

- **El rojo es escaso**: solo euros perdidos, descuadres, errores. Más de una zona roja
  grande por página es jerarquía mal hecha: destaca la peor y deja el resto en texto.
- **El verde bueno no adorna**: una cifra verde es porque cuadra o mejoró. Una
  recomendación o un ahorro no se ponen en verde por ser favorables.
- **El color nunca va solo**: cada estado lleva texto ("−25", "sin cobrar", "cuadra") o
  una etiqueta `.gz-badge`.
- Texto siempre en `--gz-ink` o `--gz-ink-muted`; los `*-strong` solo en la cifra de un KPI
  semántico, en la columna de diferencia y en etiquetas. Nunca texto menta o verde claro
  sobre fondo claro.
- Superficies: el fondo de página es menta; las **tarjetas blancas son para datos** (cifras,
  tablas), no para envolver cada sección. Prefiere espacio y tipografía a cajas; nada de
  tarjetas dentro de tarjetas. Una sombra suave (`--gz-shadow-sm`) en tarjetas, otra
  (`--gz-shadow-md`) solo en un hero de portada.
- **Rechazo firme**: gradientes, texto degradado, brillos, blobs, texturas, cristal
  esmerilado, rieles de color laterales, sombras de color, profundidad falsa, azul o violeta
  corporativos como acento.
- **Modo oscuro**: los documentos van siempre en claro (se imprimen y se mandan por
  WhatsApp) y **no enlazan** `tokens-dark.css`. Solo las apps lo soportan, enlazando
  `https://gambooza-design.web.app/tokens-dark.css` después de la hoja principal (sigue a
  `prefers-color-scheme` y a `data-theme="dark"`), nunca con colores nuevos. Sin
  interruptor visible.

#### Datos y evidencia

- **Orden de un documento con datos**: cabecera → una frase con la conclusión (`.gz-lead`)
  → 2–4 cifras clave (`.gz-stats`) → la evidencia (tabla o barras a ancho completo) → qué
  hacer ahora (`.gz-callout`) → método, límites y fuentes al final, en pequeño.
- **Una cifra manda.** El lector sabe en 3 segundos cuál es la cifra del documento. Solo
  ella lleva color semántico; el resto de KPI van en `--gz-ink`. Nunca más de 4 KPI.
- **Cada cifra dice de qué periodo es y de dónde sale** (`.gz-stat-delta`, `.gz-caption`):
  "1–7 sep · cámara vs TPV".
- **Comparar es mostrar la diferencia**: servido / cobrado / **diferencia**, en su propia
  columna, alineada a la derecha, con signo, y es lo único coloreado.
- **Los euros van primero**, después unidades, después porcentaje. "25 cervezas sin cobrar
  (≈ 87 €)", no "7 %". Proyecciones (al mes, al año) siempre marcadas como tales ("≈",
  "al ritmo de esta semana").
- **Formato es-ES**: `1.234 €`, `12,5 %` (espacio antes de € y %), sin decimales por encima
  de 100 €, dos por debajo; fechas `lun 8 sep` o `08/09/2026`; horas `14:30`.
- **Tablas**: `<table class="gz-table">` semántica dentro de `.gz-table-wrap`, a ancho
  completo, con `<thead>` y, si hay total, fila `.total`. Texto a la izquierda; **números y
  sus cabeceras a la derecha con `.num` en `<th>` y en cada `<td>`**. Máximo 7 columnas en
  documento (más es un dashboard). Ordenadas por lo que importa (mayor descuadre arriba),
  no alfabéticamente. Sin zebra. Sin columna que repita la misma categoría fila tras fila,
  ni columna en la que la mayoría de filas digan "sin dato": quítala y cuenta el hueco en
  el pie. Precisión coherente en cada columna. En móvil, scroll local, nunca columnas rotas.
- **Barras** (`.gz-bars` > `.gz-bar`): todas comparten escala (100 % = el máximo del
  conjunto o una base declarada); un carril de etiqueta, uno de barra y uno de valor,
  iguales en todas las filas. Color: `--gz-good` por defecto, `--gz-bad` solo en las que
  son problema, `--gz-neutral` en las irrelevantes. **Nunca un color por categoría, nunca
  arcoíris, nunca tarta ni donut, nada apilado ni 3D.** Etiquetas directas, sin leyenda.
- **Cada gráfico o tabla tiene título que afirma algo** y un `.gz-caption` con fuente y
  periodo, y con lo que el dato NO demuestra si hace falta.
- **Vídeo**: un enlace o botón "ver vídeo ↘"; nunca un reproductor incrustado en un documento.
- Si falta un dato: "sin dato" en `--gz-ink-muted`. Nunca "lorem ipsum" ni datos inventados
  presentados como reales.

#### Movimiento, medios e iconos

Quietud por defecto. Sin animaciones al cargar, sin revelar secciones al hacer scroll, sin
contadores que suben, sin marquesinas ni cursores simulados. El movimiento solo explica un
cambio de estado en una app, y respeta `prefers-reduced-motion`.

Fotos solo si son evidencia (un fotograma de la barra, una captura real). Sin imágenes de
stock, ilustraciones generadas ni iconos decorativos delante de cada título. Sin librerías
de iconos. Prefiere una etiqueta de texto.

### 4. Inspecciona y corrige en privado

Si tienes cómo renderizar, renderiza. Mira el primer viewport, la página completa y 400 px
de ancho. Revisa en este orden y corrige el defecto sistémico mayor antes de volver a mirar:

1. **Primera lectura**: ¿es Gambooza al instante (cabecera, fuentes, menta)? ¿Se recuerda
   la cifra o la decisión, no solo el título?
2. **Lenguaje**: ¿el lector menos técnico puede repetir la conclusión tras leer títulos y
   pies? ¿Se conserva cada periodo y base? ¿Hay vocabulario interno en un documento para
   cliente?
3. **Composición**: ¿hay un objeto dominante? ¿Cada sección avanza el argumento? ¿Hay
   espacio vacío accidental?
4. **Tipografía**: ¿roles publicados, pares iguales, ritmo por relación, prosa ≤ 68
   caracteres?
5. **Evidencia**: ¿la geometría prueba la afirmación? ¿Tablas a ancho completo, números a
   la derecha con su cabecera, barras con una escala? ¿Algo se repite sin pregunta nueva?
6. **Contención**: ¿se puede quitar alguna tarjeta, borde, etiqueta, color o párrafo sin
   perder significado? Quítalo.
7. **Reflow**: ¿a 400 px no hay scroll horizontal del cuerpo ni palabras partidas?
8. **Confianza y acceso**: ¿h1 único, orden de títulos, tabla semántica, `alt` en el logo,
   contraste AA, fuentes y límites declarados?

Entrega la página, no un diario del proceso ni una autocrítica.

## Reflejos de diseño generado que se rechazan

- Fondo blanco plano de página, o fondo oscuro / hero negro en un documento.
- Gradientes, degradados de marca, cristal, brillos, sombras de color, bordes de 2 px.
- Azul corporativo o violeta como acento. Inter, Roboto, Poppins, Montserrat o la fuente
  del sistema como titular.
- Iconos o emojis delante de cada título o viñeta; tiles de icono; iconos 3D.
- Portada centrada seguida de una rejilla de tarjetas iguales; KPIs centrados con icono
  grande a la izquierda; más de 4 KPI; KPI sin unidad ni periodo.
- Tarjeta dentro de tarjeta; cada sección envuelta en una caja; bordes para arreglar una
  jerarquía floja.
- Píldoras o badges para metadatos corrientes o etiquetas editoriales.
- Tarta, donut, leyenda de 8 colores, barras sin escala común, gráfico decorativo,
  visualización redundante, animación al cargar.
- Formato inglés (`1,234.56`), `$`, `€` pegado sin espacio, porcentaje antes que euros.
- Texto justificado, letra gris diminuta, párrafos de más de 5 líneas para cliente.
- Secciones "Resumen", "Conclusión" y "Recomendación" que dicen lo mismo tres veces.
- Narración del proceso ("en este informe hemos organizado…").
- "gamb00za" dentro de una frase; logo recoloreado; cabecera sin logo.
- Botón relleno en cada tarjeta (solo hay una acción principal por página).
- Vocabulario interno en un documento para cliente (modelo, recall, motion, anotador, ID).
- Scroll horizontal del cuerpo en móvil; tablas rotas a 400 px.

No compenses evitando todo esto con una plantilla estéril. La contención Gambooza es
jerarquía precisa, buena tipografía, evidencia clara y una tensión deliberada: una cifra
grande, una menta tranquila, un rojo que cuenta.

## API pública de la CSS

Usa HTML semántico y **solo las primitivas que el material se gane**. Estas son las únicas
clases públicas; si ninguna encaja, compón con HTML semántico y una clase propia con
prefijo `gz-custom-*` que solo toque maquetación (grid, posiciones) y lea tokens
`--gz-*`. Nunca inspecciones la hoja para buscar selectores internos, nunca inventes un
nombre `gz-*` por analogía, nunca redeclares un token.

**Maquetación y armazón**: `gz-page`, `gz-page--wide`, `gz-header`, `gz-brand`,
`gz-wordmark`, `gz-meta`, `gz-section`, `gz-grid`, `gz-grid--2`, `gz-grid--3`, `gz-stack`,
`gz-row`, `gz-divider`, `gz-footer`.

**Tipo y texto**: `gz-eyebrow`, `gz-lead`, `gz-caption`, `gz-muted`, `gz-small`, `up`,
`down` (color semántico en una cifra de diferencia).

**Cifras**: `gz-stats` > `gz-stat` (`gz-stat--good`, `gz-stat--bad`, `gz-stat--warn`,
`gz-stat--soft`) con hijos `gz-stat-label`, `gz-stat-value` (la unidad va en un `<small>`
dentro), `gz-stat-delta`.

**Contenedores**: `gz-card`, `gz-card--soft`, `gz-card--solid`, `gz-hero`.

**Tablas**: `gz-table-wrap` > `table.gz-table` (`gz-table--compact`), `num` en `<th>` y
`<td>` numéricos, `total` en la fila de total.

**Avisos y estados**: `gz-callout` (`gz-callout--good`, `gz-callout--bad`,
`gz-callout--warn`) con `gz-callout-title`; `gz-badge` (`gz-badge--good`, `gz-badge--bad`,
`gz-badge--warn`, `gz-badge--info`).

**Acciones**: `gz-btn`, `gz-btn--primary`, `gz-btn--arrow`, `gz-btn--small`. Un solo
`--primary` por página.

**Barras**: `gz-bars` > `gz-bar` (`gz-bar--bad`, `gz-bar--warn`, `gz-bar--muted`,
`gz-bar--brand`) con `style="--v:62%"` y tres hijos en este orden: `<span>` etiqueta,
`<i>` barra, `<b>` valor.

```html
<div class="gz-stats">
  <div class="gz-stat gz-stat--bad">
    <p class="gz-stat-label">Servido y no cobrado</p>
    <p class="gz-stat-value">87<small>€</small></p>
    <p class="gz-stat-delta">25 cervezas · 1–7 sep</p>
  </div>
</div>

<div class="gz-bars">
  <div class="gz-bar gz-bar--bad" style="--v:72%"><span>Grifo 3 · Lager</span><i></i><b>18</b></div>
  <div class="gz-bar" style="--v:16%"><span>Grifo 1 · Lager</span><i></i><b>4</b></div>
</div>
```

**Tokens que puede leer la CSS propia de una página o app** (con `var()`, nombres exactos):

- Color: `--gz-ink`, `--gz-ink-muted`, `--gz-ink-soft`, `--gz-bg`, `--gz-surface`,
  `--gz-surface-2`, `--gz-white`, `--gz-mint`, `--gz-mint-2`, `--gz-sage`, `--gz-teal`,
  `--gz-border`, `--gz-border-strong`, `--gz-good`, `--gz-good-strong`, `--gz-bad`,
  `--gz-bad-strong`, `--gz-warn`, `--gz-warn-strong`, `--gz-info`, `--gz-neutral`.
- Tipo: `--gz-font-head`, `--gz-font-body`, `--gz-font-mono`, `--gz-text-display`,
  `--gz-text-h1`, `--gz-text-h2`, `--gz-text-h3`, `--gz-text-body`, `--gz-text-small`,
  `--gz-text-caption`, `--gz-text-stat`, `--gz-leading-tight`, `--gz-leading-head`,
  `--gz-leading-body`, `--gz-tracking-head`.
- Espacio y forma: `--gz-space-1` … `--gz-space-8` (4, 8, 12, 16, 24, 32, 48, 64),
  `--gz-measure`, `--gz-measure-wide`, `--gz-radius-sm`, `--gz-radius`, `--gz-radius-lg`,
  `--gz-radius-pill`, `--gz-shadow-sm`, `--gz-shadow-md`, `--gz-focus`.

## Apps y visores (no documentos)

- Enlaza `tokens.css` y mapea las variables existentes de la app a `--gz-*` (por ejemplo
  `--bg: var(--gz-surface)`, `--text: var(--gz-ink)`, `--muted: var(--gz-ink-muted)`).
  No copies hexadecimales: el objetivo es que un cambio en `tokens.css` llegue a la app.
- Cuerpo de 14 px permitido en apps densas; nunca menos de 12,5.
- Ancho 1200 (`.gz-page--wide`) o fluido; modo oscuro enlazando `tokens-dark.css`, sin
  interruptor.
- Los mismos significados de color: verde cuadra, rojo descuadre, ámbar atención, gris sin
  dato. Los estados llevan texto además de color.
- Cabecera de app: logo + nombre de la app en Fira Sans 600, sin eyebrow.
- Controles nativos con etiqueta visible, foco visible (`--gz-focus`), altura mínima 36 px
  (44 en táctil). Un solo botón `--primary` por vista.
- Un cambio de estilo de una app se hace en `tokens.css` si afecta a la marca, y en la app
  si solo afecta a esa vista.

## Accesibilidad y responsive

Landmarks (`header`, `main`, `footer`), un solo `h1`, títulos en orden, tablas
semánticas, `alt` en el logo, foco visible, contraste AA, nunca color solo. Orden del DOM =
orden de lectura. Hijos de grid y flex con `min-width: 0`; reflow antes que encoger. Todo
funciona a 400 px sin scroll horizontal del cuerpo; solo tablas y código pueden desplazarse
localmente. Funciona impreso (la CSS ya quita fondo y botones).

El objetivo es el criterio Gambooza, no la decoración Gambooza.

---

## Apéndice A · Hoja de estilo completa (para pegar en un artifact)

Generado automáticamente desde `tokens.css` + `gambooza.css` por `build.py`. **No editar
aquí**: edita los `.css` y ejecuta `python build.py`. Mantén el `<link>` de Google Fonts de
la sección "Cómo cargar los estilos" y pega este bloque entero dentro de `<head>`.

<!-- css:start -->
```html
<style>
/* ==========================================================================
   Gambooza · design tokens  (fuente única: https://gambooza-design.web.app/tokens.css)
   Solo variables. Se puede importar en cualquier app sin que choque con su CSS:
     <link rel="stylesheet" href="https://gambooza-design.web.app/tokens.css">
   Cambiar un valor aquí lo cambia en todo lo que importe este fichero.
   Extraídos de gambooza.com (Elementor globals) y de los visores en producción.
   ========================================================================== */
:root {
  color-scheme: light;

  /* --- Color: marca ----------------------------------------------------- */
  --gz-ink:            #2E3D34;   /* texto principal (verde bosque) */
  --gz-ink-muted:      #557260;   /* texto secundario; pasa AA sobre las 3 superficies */
  --gz-ink-soft:       #87AB95;   /* decorativo / texto grande solo; NO para letra pequeña (2,5:1) */
  --gz-bg:             #DDF6F3;   /* fondo de página (menta-agua de gambooza.com) */
  --gz-surface:        #F4FFF8;   /* superficie 1: contenedores, hero */
  --gz-surface-2:      #E5F5E3;   /* superficie 2: cabeceras de tabla, chips */
  --gz-white:          #FFFFFF;   /* tarjetas de datos */
  --gz-mint:           #A8D4B9;   /* primario de marca: rellenos suaves, logo */
  --gz-mint-2:         #A8D4CF;   /* secundario: variante fría del menta */
  --gz-sage:           #87AB95;   /* tarjetas sólidas con texto blanco */
  --gz-teal:           #87ACA7;   /* enlaces, info */
  --gz-border:         #C9DCC2;
  --gz-border-strong:  #A8D4B9;

  /* --- Color: semántico (lo que significan los números) ------------------ */
  --gz-good:           #79BA6A;   /* lo que va bien / cuadra: rellenos, barras */
  --gz-good-strong:    #357A43;   /* texto "bien" y CTA rellena (blanco encima 4,7:1) */
  --gz-bad:            #FF4242;   /* descuadre, pérdida: rellenos, trazos */
  --gz-bad-strong:     #C53030;   /* texto "mal" sobre claro */
  --gz-warn:           #E8A93A;   /* atención, ámbar-cerveza: rellenos */
  --gz-warn-strong:    #8A5A0B;   /* texto "atención" sobre claro */
  --gz-info:           #87ACA7;
  --gz-neutral:        #B9C9BD;   /* sin dato, deshabilitado */

  /* --- Tipografía --------------------------------------------------------- */
  --gz-font-head:      "Fira Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --gz-font-body:      "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --gz-font-mono:      ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --gz-text-display:   2.5rem;    /* 40px  · portada / hero */
  --gz-text-h1:        2rem;      /* 32px */
  --gz-text-h2:        1.5rem;    /* 24px */
  --gz-text-h3:        1.1875rem; /* 19px */
  --gz-text-body:      1rem;      /* 16px */
  --gz-text-small:     0.875rem;  /* 14px */
  --gz-text-caption:   0.78rem;   /* 12.5px · pies, ejes */
  --gz-text-stat:      2.375rem;  /* 38px  · cifra de KPI */
  --gz-leading-tight:  1.1;
  --gz-leading-head:   1.2;
  --gz-leading-body:   1.5;
  --gz-tracking-head:  -0.02em;

  /* --- Espacio (base 4) --------------------------------------------------- */
  --gz-space-1:  4px;
  --gz-space-2:  8px;
  --gz-space-3:  12px;
  --gz-space-4:  16px;
  --gz-space-5:  24px;
  --gz-space-6:  32px;
  --gz-space-7:  48px;
  --gz-space-8:  64px;
  --gz-measure:  880px;  /* ancho máximo de un documento */
  --gz-measure-wide: 1200px; /* apps / dashboards */

  /* --- Forma ---------------------------------------------------------------- */
  --gz-radius-sm:  8px;
  --gz-radius:     12px;
  --gz-radius-lg:  20px;
  --gz-radius-pill: 999px;
  --gz-shadow-sm:  0 1px 2px rgba(46,61,52,.05), 0 2px 6px rgba(46,61,52,.06);
  --gz-shadow-md:  0 4px 10px rgba(46,61,52,.06), 0 16px 32px rgba(46,61,52,.10);
  --gz-focus:      0 0 0 3px rgba(135,172,167,.55);
}

/* ==========================================================================
   Gambooza · hoja de estilo para documentos y páginas generadas
   https://gambooza-design.web.app/gambooza.css
   Incluye los tokens (tokens.css) + tipografía base + un conjunto ACOTADO de
   primitivas con prefijo .gz-. No hay más componentes que estos; si un
   documento necesita algo que no está aquí, se compone con estos, no se inventa.
   Guía de uso: https://gambooza-design.web.app/DESIGN.md
   ========================================================================== */

/* --- Base ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--gz-bg);
  color: var(--gz-ink);
  font-family: var(--gz-font-body);
  font-size: var(--gz-text-body);
  line-height: var(--gz-leading-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 {
  font-family: var(--gz-font-head);
  font-weight: 700;
  line-height: var(--gz-leading-head);
  letter-spacing: var(--gz-tracking-head);
  color: var(--gz-ink);
  margin: 0 0 var(--gz-space-3);
  text-wrap: balance;
}
h1 { font-size: var(--gz-text-h1); }
h2 { font-size: var(--gz-text-h2); margin-top: var(--gz-space-7); }
h3 { font-size: var(--gz-text-h3); font-weight: 600; margin-top: var(--gz-space-5); }
h4 { font-size: var(--gz-text-body); font-weight: 600; margin-top: var(--gz-space-4); }
h2:first-child, h3:first-child { margin-top: 0; }
p, ul, ol { margin: 0 0 var(--gz-space-4); max-width: 68ch; }
li { margin-bottom: var(--gz-space-1); }
a { color: var(--gz-good-strong); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--gz-ink); }
strong { font-weight: 600; }
small, .gz-small { font-size: var(--gz-text-small); }
code, kbd, pre { font-family: var(--gz-font-mono); font-size: 0.9em; }
code { background: var(--gz-surface-2); padding: 1px 5px; border-radius: 4px; }
pre { background: var(--gz-surface-2); padding: var(--gz-space-4); border-radius: var(--gz-radius-sm); overflow-x: auto; }
img, video { max-width: 100%; height: auto; }
hr, .gz-divider { border: 0; border-top: 1px solid var(--gz-border); margin: var(--gz-space-6) 0; }
:focus-visible { outline: none; box-shadow: var(--gz-focus); border-radius: 4px; }

/* --- Layout ---------------------------------------------------------------- */
/* .gz-page: envoltorio de un DOCUMENTO (informe, propuesta, nota). Ancho 880. */
.gz-page {
  max-width: var(--gz-measure);
  margin: 0 auto;
  padding: var(--gz-space-6) var(--gz-space-5) var(--gz-space-8);
}
.gz-page--wide { max-width: var(--gz-measure-wide); }   /* dashboards, apps */
.gz-section { margin-top: var(--gz-space-7); }
.gz-section > h2 { margin-top: 0; }
.gz-grid { display: grid; gap: var(--gz-space-4); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.gz-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.gz-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.gz-stack { display: flex; flex-direction: column; gap: var(--gz-space-4); }
.gz-row { display: flex; flex-wrap: wrap; gap: var(--gz-space-3); align-items: center; }
.gz-muted { color: var(--gz-ink-muted); }
.gz-caption { font-size: var(--gz-text-caption); color: var(--gz-ink-muted); line-height: 1.4; margin: var(--gz-space-2) 0 0; }
.gz-eyebrow {
  font-family: var(--gz-font-body); font-size: var(--gz-text-caption); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--gz-ink-muted); margin: 0 0 var(--gz-space-2);
}
.gz-lead { font-size: var(--gz-text-h3); font-family: var(--gz-font-head); font-weight: 500; letter-spacing: -0.01em; line-height: 1.35; max-width: 60ch; }

/* --- Cabecera de documento --------------------------------------------------- */
.gz-header {
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--gz-space-4);
  padding-bottom: var(--gz-space-5); margin-bottom: var(--gz-space-6);
  border-bottom: 1px solid var(--gz-border);
}
/* El bloque de título se lleva el ancho sobrante y la marca queda a la derecha en la
   misma fila aunque el h1 sea largo; solo baja de fila por debajo de ~560 px. */
.gz-header > :first-child { flex: 1 1 360px; min-width: 0; }
.gz-header > .gz-brand { flex: none; }
.gz-header h1 { margin: 0 0 var(--gz-space-2); font-size: var(--gz-text-display); line-height: var(--gz-leading-tight); }
.gz-header .gz-meta { font-size: var(--gz-text-small); color: var(--gz-ink-muted); }
.gz-header .gz-meta span + span::before { content: "·"; margin: 0 var(--gz-space-2); }
.gz-brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; color: var(--gz-ink); }
.gz-brand img, .gz-brand svg { width: 36px; height: 36px; flex: none; }
.gz-wordmark { font-family: var(--gz-font-head); font-weight: 700; font-size: 1.25rem; letter-spacing: -0.02em; line-height: 1; }

/* --- Cifras clave (stat strip) ------------------------------------------------ */
.gz-stats {
  display: grid; gap: var(--gz-space-3);
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  margin: var(--gz-space-5) 0;
}
.gz-stat {
  background: var(--gz-white); border: 1px solid var(--gz-border); border-radius: var(--gz-radius);
  padding: var(--gz-space-4) var(--gz-space-4) var(--gz-space-3);
  box-shadow: var(--gz-shadow-sm);
}
.gz-stat .gz-stat-label { font-size: var(--gz-text-caption); font-weight: 600; color: var(--gz-ink-muted); margin: 0 0 var(--gz-space-2); line-height: 1.3; }
.gz-stat .gz-stat-value {
  font-family: var(--gz-font-head); font-size: var(--gz-text-stat); font-weight: 700; line-height: 1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; margin: 0;
}
.gz-stat .gz-stat-value small { font-size: 0.45em; font-weight: 500; color: var(--gz-ink-muted); margin-left: 2px; letter-spacing: 0; }
.gz-stat .gz-stat-delta { font-size: var(--gz-text-caption); margin: var(--gz-space-2) 0 0; color: var(--gz-ink-muted); font-variant-numeric: tabular-nums; }
.gz-stat--good { background: rgba(121,186,106,.14); }
.gz-stat--good .gz-stat-value { color: var(--gz-good-strong); }
.gz-stat--bad  { background: rgba(255,66,66,.10); }
.gz-stat--bad  .gz-stat-value { color: var(--gz-bad-strong); }
.gz-stat--warn { background: rgba(232,169,58,.14); }
.gz-stat--warn .gz-stat-value { color: var(--gz-warn-strong); }
.gz-stat--soft { background: var(--gz-surface-2); }
.up   { color: var(--gz-good-strong); }
.down { color: var(--gz-bad-strong); }

/* --- Tarjetas ------------------------------------------------------------------ */
.gz-card {
  background: var(--gz-white); border: 1px solid var(--gz-border); border-radius: var(--gz-radius);
  padding: var(--gz-space-5); box-shadow: var(--gz-shadow-sm);
}
.gz-card > :first-child { margin-top: 0; }
.gz-card > :last-child { margin-bottom: 0; }
.gz-card--soft { background: var(--gz-surface); box-shadow: none; }
.gz-card--solid { background: var(--gz-sage); border-color: var(--gz-sage); color: #fff; }
.gz-card--solid h2, .gz-card--solid h3, .gz-card--solid h4, .gz-card--solid .gz-eyebrow, .gz-card--solid .gz-caption { color: #fff; }
.gz-card--solid a { color: #fff; }
.gz-hero {
  background: var(--gz-surface); border-radius: var(--gz-radius-lg); padding: var(--gz-space-7) var(--gz-space-6);
  box-shadow: var(--gz-shadow-md);
}

/* --- Tablas ------------------------------------------------------------------ */
.gz-table-wrap { overflow-x: auto; border: 1px solid var(--gz-border); border-radius: var(--gz-radius); background: var(--gz-white); }
.gz-table { width: 100%; border-collapse: collapse; font-size: var(--gz-text-small); font-variant-numeric: tabular-nums; }
.gz-table th, .gz-table td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--gz-border); vertical-align: top; }
.gz-table thead th { background: var(--gz-surface-2); color: var(--gz-ink-muted); font-weight: 600; font-size: var(--gz-text-caption); letter-spacing: 0.02em; white-space: nowrap; }
.gz-table tbody tr:last-child td { border-bottom: 0; }
.gz-table tbody tr:hover { background: var(--gz-bg); }
.gz-table .num, .gz-table th.num { text-align: right; }
.gz-table tfoot td, .gz-table .total td { font-weight: 700; background: var(--gz-surface); border-top: 2px solid var(--gz-border-strong); }
.gz-table--compact th, .gz-table--compact td { padding: 6px 10px; }

/* --- Avisos (callouts) ------------------------------------------------------ */
.gz-callout {
  border-left: 4px solid var(--gz-teal); background: var(--gz-surface); border-radius: var(--gz-radius-sm);
  padding: var(--gz-space-3) var(--gz-space-4); margin: var(--gz-space-4) 0;
}
.gz-callout > :last-child { margin-bottom: 0; }
.gz-callout--good { border-left-color: var(--gz-good); background: rgba(121,186,106,.12); }
.gz-callout--bad  { border-left-color: var(--gz-bad);  background: rgba(255,66,66,.08); }
.gz-callout--warn { border-left-color: var(--gz-warn); background: rgba(232,169,58,.12); }
.gz-callout-title { display: block; font-weight: 600; font-family: var(--gz-font-head); margin-bottom: 2px; }

/* --- Etiquetas y botones ---------------------------------------------------- */
.gz-badge {
  display: inline-block; padding: 2px 10px; border-radius: var(--gz-radius-pill);
  font-size: var(--gz-text-caption); font-weight: 600; line-height: 1.6; white-space: nowrap;
  background: var(--gz-surface-2); color: var(--gz-ink-muted); border: 1px solid transparent;
}
.gz-badge--good { background: rgba(121,186,106,.18); color: var(--gz-good-strong); }
.gz-badge--bad  { background: rgba(255,66,66,.12);  color: var(--gz-bad-strong); }
.gz-badge--warn { background: rgba(232,169,58,.18); color: var(--gz-warn-strong); }
.gz-badge--info { background: rgba(135,172,167,.22); color: var(--gz-ink); }
.gz-btn {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; text-decoration: none;
  font-family: var(--gz-font-body); font-size: var(--gz-text-body); font-weight: 600; line-height: 1;
  padding: 10px 18px; border-radius: var(--gz-radius-pill);
  border: 1px solid var(--gz-ink); background: transparent; color: var(--gz-ink);
  transition: background .15s, color .15s;
}
.gz-btn:hover { background: var(--gz-ink); color: var(--gz-surface); }
.gz-btn--primary { background: var(--gz-good-strong); border-color: var(--gz-good-strong); color: #fff; }
.gz-btn--primary:hover { background: var(--gz-ink); border-color: var(--gz-ink); color: #fff; }
.gz-btn--small { font-size: var(--gz-text-small); padding: 7px 14px; }
.gz-btn::after { content: none; }
.gz-btn--arrow::after { content: "↘"; font-size: 0.9em; }

/* --- Gráfico de barras (sin librería) --------------------------------------- */
/* <div class="gz-bars"><div class="gz-bar" style="--v:62%"><span>Grifo 1</span><i></i><b>62 %</b></div>… */
/* Las tres calles (etiqueta · barra · valor) son COMPARTIDAS por todas las filas: el
   contenedor es la rejilla y cada .gz-bar aporta sus tres hijos (display: contents).
   La etiqueta nunca se trunca; se lleva lo que necesite hasta el 40 % del ancho. */
.gz-bars { display: grid; grid-template-columns: fit-content(40%) 1fr auto; column-gap: var(--gz-space-3); row-gap: 6px; align-items: center; margin: var(--gz-space-4) 0; font-size: var(--gz-text-small); }
.gz-bar { display: contents; }
.gz-bar > span { color: var(--gz-ink-muted); line-height: 1.25; }
.gz-bar > i { display: block; height: 14px; border-radius: 4px; background: var(--gz-good); width: var(--v, 0%); min-width: 2px; }
.gz-bar > b { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 4ch; text-align: right; }
.gz-bar--bad > i  { background: var(--gz-bad); }
.gz-bar--warn > i { background: var(--gz-warn); }
.gz-bar--muted > i { background: var(--gz-neutral); }
.gz-bar--brand > i { background: var(--gz-mint); }

/* --- Pie de documento -------------------------------------------------------- */
.gz-footer {
  margin-top: var(--gz-space-8); padding-top: var(--gz-space-4); border-top: 1px solid var(--gz-border);
  font-size: var(--gz-text-caption); color: var(--gz-ink-muted);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--gz-space-3);
}

/* --- Responsive e impresión --------------------------------------------------- */
@media (max-width: 640px) {
  .gz-page { padding: var(--gz-space-5) var(--gz-space-4) var(--gz-space-7); }
  .gz-header h1 { font-size: var(--gz-text-h1); }
  .gz-grid--2, .gz-grid--3 { grid-template-columns: 1fr; }
  .gz-hero { padding: var(--gz-space-5) var(--gz-space-4); border-radius: var(--gz-radius); }
  .gz-stat .gz-stat-value { font-size: 1.75rem; }
}
@media print {
  body { background: #fff; }
  .gz-page { max-width: none; padding: 0; }
  .gz-card, .gz-stat, .gz-table-wrap, .gz-hero { box-shadow: none; break-inside: avoid; }
  .gz-btn { display: none; }
  a { color: inherit; text-decoration: none; }
}
</style>
```
<!-- css:end -->
