/*
 * app.css — Armazón y contenido de la web corporativa de ZAALEN.
 *
 * El armazón (topbar oscuro + barra lateral colapsable + área de trabajo)
 * es una reimplementación en CSS plano del shell que comparten DEZIMI,
 * OCTABI, SETIMI y QUMERIQ: mismo alto de barra (56 px), mismos anchos de
 * sidebar (220 px expandida / 56 px colapsada), mismo comportamiento de
 * drawer en móvil y mismos tooltips cuando está colapsada.
 *
 * La diferencia funcional con las apps es deliberada: allí la barra
 * lateral navega entre PANTALLAS de una aplicación; aquí navega entre
 * SECCIONES de una sola página estática. El visitante ve el mismo mueble
 * que verá dentro del producto, y eso es justamente el argumento de
 * venta: la web es una demo silenciosa de la interfaz.
 *
 * Todos los colores salen de las variables de theme.css. No hay ni un hex
 * suelto fuera de este comentario, para que el conmutador de tema alcance
 * de verdad a toda la página.
 */

/* ════════════════════════════════════════════════════════════════════════
   Base
   ════════════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  /* El desplazamiento suave lo pide la navegación por anclas de la barra
     lateral: al pulsar una sección la página se desliza hasta ella en vez
     de saltar, que es lo que hace legible el cambio de contexto. */
  scroll-behavior: smooth;
  /* Sin esto, el ancla de cada sección queda tapada por la barra fija. */
  scroll-padding-top: var(--topbar-h);
}
/* Se corta el desplazamiento suave y las transiciones decorativas a quien
   ha pedido al sistema que no le animen la interfaz.

   El tambor del hero y el grano quedan excluidos a propósito: giran
   igualmente (es decisión de producto, ver app.js), y sin su transición
   el relevo sería un salto seco en vez de un giro. Aquí la animación no
   es el problema, es lo que hace el cambio soportable. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *:not(.drum-strip):not(.drum-line):not(.hero-grain), *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* El `display:none` que el navegador da a [hidden] viene de su hoja de
   estilos, así que cualquier regla de autor que fije un display lo pisa:
   .grid{display:grid} y .plan-billing{display:flex} dejaban a la vista
   elementos marcados como ocultos. Con !important se zanja para todos. */
[hidden] { display: none !important; }

body {
  font-family: var(--font);
  font-size: var(--fs-md);
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-dark); text-decoration: underline; }

/* Foco visible y homogéneo en todo lo interactivo: es requisito de
   accesibilidad (WCAG 2.4.7) y la web tiene que cumplirlo igual que las
   apps, que son producto sanitario y lo tienen auditado. */
:where(a, button, [role="button"], [tabindex]):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Salto al contenido — el primer tabulador de un usuario de teclado.
   Oculto visualmente hasta que recibe el foco. */
.skip-link {
  position: fixed;
  top: 8px; left: 8px;
  z-index: 400;
  transform: translateY(-200%);
  background: var(--surface);
  color: var(--text);
  border: var(--frame-border);
  border-radius: var(--radius);
  padding: 10px 16px;
  font-size: var(--fs-sm);
  font-weight: 600;
  transition: transform var(--transition);
}
.skip-link:focus { transform: translateY(0); text-decoration: none; }

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Utilidad de sólo-lectores-de-pantalla. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* ════════════════════════════════════════════════════════════════════════
   TOPBAR — barra superior oscura, idéntica en altura y sangrado a la de
   las apps.
   ════════════════════════════════════════════════════════════════════════ */
.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--topbar-h);
  background: var(--topbar);
  border-bottom: var(--frame-border);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
}

/* ── Botón hamburguesa ──
   Ocupa el hueco que en las apps ocupa el waffle del lanzador. En la web
   corporativa no hay que lanzar aplicaciones desde la barra (las apps son
   una sección con su propia ficha), así que ese sitio —el más previsible
   de la pantalla para "abrir el menú"— se le da al conmutador de la barra
   lateral, que es lo que el visitante necesita ahí. */
.icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: var(--radius);
  background: none;
  color: rgba(255, 255, 255, 0.8);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.icon-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.icon-btn[aria-expanded="true"] { border-color: rgba(255, 255, 255, 0.55); color: #fff; }
.icon-btn svg { display: block; }

/* Las tres barras de la hamburguesa se dibujan con <span> para poder
   animarlas hacia una "X" cuando el menú está abierto: el propio icono
   dice en qué estado está el menú, sin depender del color. */
.burger { width: 18px; height: 14px; position: relative; }
.burger span {
  position: absolute;
  left: 0; width: 100%; height: 2px;
  background: currentColor;
  border-radius: 1px;
  transition: transform var(--transition), opacity var(--transition);
}
.burger span:nth-child(1) { top: 0; }
.burger span:nth-child(2) { top: 6px; }
.burger span:nth-child(3) { top: 12px; }
.icon-btn[aria-expanded="true"] .burger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.icon-btn[aria-expanded="true"] .burger span:nth-child(2) { opacity: 0; }
.icon-btn[aria-expanded="true"] .burger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ── Logotipo de la barra ── */
.topbar-logo {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-shrink: 0;
  cursor: pointer;
  text-decoration: none;
}
.topbar-logo:hover { text-decoration: none; }
/* La "respiración" al pasar por encima es el mismo gesto que hace el logo
   en el Topbar de OCTABI: un parpadeo suave de opacidad, no un
   desplazamiento, para que no empuje al texto de al lado. */
@keyframes zln-breathe { 0% { opacity: 1; } 42% { opacity: 0.45; } 100% { opacity: 1; } }
.topbar-logo:hover .topbar-logo-anim { animation: zln-breathe 0.62s ease-in-out forwards; }
.topbar-logo-anim { display: flex; align-items: center; gap: 9px; }
.topbar-logo svg { display: block; }
/* El logotipo se dimensiona por el alto (la barra manda) y deja que el
   ancho lo ponga la relacion de aspecto 550:150 del original. El color lo
   toma de --topbar-text a traves de currentColor, asi que cada tema pinta
   su propio blanco sin que haya que tocar el SVG. */
.topbar-mark {
  height: 30px;
  width: auto;
  color: var(--topbar-text);
}
/* El descriptor corporativo que acompaña al logotipo dentro de la barra.
   Se esconde en pantallas estrechas: ahí la barra tiene que priorizar el
   nombre y los dos botones de la derecha. */
.topbar-tagline {
  font-size: var(--fs-xxs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
  white-space: nowrap;
}

/* El sprite de <symbol> no pinta nada por sí mismo: sólo guarda la
   definición del nombre de QUMERIQ para que los <use> la instancien.
   Fuera del flujo, sin tamaño y sin que ningún lector lo recorra. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── Barra: el producto, a la derecha de la marca de la casa ── */
/* Un filete y no un punto ni una barra tipográfica: separa las dos marcas
   sin añadir un glifo que el lector de pantalla tendría que decidir si
   pronuncia. El alto es el de la caja de texto, no el de la barra. */
.topbar-sep {
  width: 1px;
  height: 22px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.22);
}
.topbar-product {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-shrink: 0;
  text-decoration: none;
}
.topbar-product:hover { text-decoration: none; }
.topbar-product:hover .topbar-product-name { opacity: 0.72; }
/* El icono conserva sus dos colores de marca —es lo que lo hace
   reconocible— y sólo el nombre hereda el blanco de la barra. */
.topbar-product-mark { height: 27px; width: auto; display: block; }
/* 20 px de altura de mayúscula, no 15: el nombre es lo que dice de quién
   es esta página, y a 15 px se leía como un pie de foto al lado del
   logotipo de zaalen. Con 20 px sobre una barra de 56 iguala el peso
   óptico de la marca de la casa sin llegar a taparla. */
.topbar-product-name {
  height: 20px;
  width: auto;
  display: block;
  color: var(--topbar-text);
  transition: opacity 0.18s ease;
}

.topbar-spacer { flex: 1; }

.topbar-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

/* Botón de idioma: muestra el código ISO en versales, que ocupa poco y se
   reconoce sin traducir. */
.lang-btn {
  width: auto;
  padding: 0 10px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}


/* ════════════════════════════════════════════════════════════════════════
   SIDEBAR — barra lateral colapsable
   ════════════════════════════════════════════════════════════════════════ */
.sidebar {
  position: fixed;
  top: var(--topbar-h);
  left: 0;
  bottom: 0;
  z-index: 90;
  width: var(--sidebar-w);
  background: var(--sidebar-bg);
  border-right: var(--frame-border);
  display: flex;
  flex-direction: column;
  padding: 12px 8px;
  gap: 4px;
  transition: width var(--transition), transform var(--transition);
  overflow-x: hidden;
  overflow-y: auto;
}
/* Colapsada: sólo iconos. El ancho de 56 px es el mismo que usan las apps
   y está calculado para que un icono de 20 px quede ópticamente centrado
   con el sangrado de 8 px del contenedor. */
body.sidebar-collapsed .sidebar { width: var(--sidebar-w-min); }

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 40px;
  padding: 0 10px;
  border-radius: var(--radius);
  color: var(--text-2);
  font-size: var(--fs-base);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background var(--transition), color var(--transition);
}
.nav-item:hover { background: var(--sidebar-hover); color: var(--text); text-decoration: none; }
.nav-item svg { flex-shrink: 0; width: 20px; height: 20px; }

/* Sección activa: barra de acento a la izquierda + tinte de marca. Se
   marca con color Y con la barra, nunca sólo con color, porque en el tema
   oscuro y para un daltónico el tinte solo no basta. */
.nav-item.active {
  background: var(--brand-bg);
  color: var(--brand);
}
.nav-item.active::before {
  content: "";
  position: absolute;
  left: 0; top: 8px; bottom: 8px;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--brand);
}

.nav-label { overflow: hidden; text-overflow: ellipsis; }
body.sidebar-collapsed .nav-label { display: none; }
body.sidebar-collapsed .nav-item { justify-content: center; padding: 0; }

/* Tooltip para el estado colapsado: sin él, la barra en modo icono es
   ilegible para quien no conoce ya la aplicación. */
.nav-tooltip {
  position: absolute;
  left: calc(100% + 8px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--topbar);
  color: var(--topbar-text);
  font-size: var(--fs-xs);
  font-weight: 600;
  padding: 5px 10px;
  border-radius: var(--radius);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
  z-index: 120;
}
body.sidebar-collapsed .nav-item:hover .nav-tooltip,
body.sidebar-collapsed .nav-item:focus-visible .nav-tooltip { opacity: 1; }
/* Con la barra expandida el rótulo ya se ve: el tooltip sobraría. */
body:not(.sidebar-collapsed) .nav-tooltip { display: none; }

.sidebar-spacer { flex: 1; }

/* Pie de la barra lateral: el contacto directo. Es el sitio donde las
   apps ponen "pedir ayuda humana", y cumple aquí la misma función —
   siempre visible, sin tener que buscar el pie de página. */
.sidebar-cta {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 40px;
  padding: 0 10px;
  border: var(--frame-border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 700;
  white-space: nowrap;
  text-decoration: none;
  transition: background var(--transition), color var(--transition);
}
.sidebar-cta:hover { background: var(--brand); color: #fff; text-decoration: none; }
.sidebar-cta:hover svg { color: #fff; }
.sidebar-cta svg { flex-shrink: 0; width: 18px; height: 18px; color: var(--brand); }
body.sidebar-collapsed .sidebar-cta { justify-content: center; padding: 0; }
body.sidebar-collapsed .sidebar-cta .nav-label { display: none; }

/* Velo del drawer móvil. En escritorio no existe. */
.scrim {
  position: fixed;
  inset: var(--topbar-h) 0 0 0;
  z-index: 89;
  background: rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
}


/* ════════════════════════════════════════════════════════════════════════
   PANEL DERECHO — idioma y tema
   Réplica del UserPanel de las apps: cajón de 320 px, superficie propia,
   subpaneles que reemplazan la lista principal deslizándose.
   ════════════════════════════════════════════════════════════════════════ */
.panel {
  position: fixed;
  top: var(--topbar-h);
  right: 0;
  bottom: 0;
  z-index: 110;
  width: 320px;
  max-width: 88vw;
  background: var(--surface);
  border-left: var(--frame-border);
  box-shadow: var(--shadow-md);
  transform: translateX(105%);
  transition: transform var(--transition);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: 16px;
  gap: 4px;
}
.panel.open { transform: translateX(0); }
/* En árabe el cajón entra por el lado contrario, o taparía el inicio de
   la línea de lectura. */
html[dir="rtl"] .panel { right: auto; left: 0; border-left: none; border-right: var(--frame-border); transform: translateX(-105%); }
html[dir="rtl"] .panel.open { transform: translateX(0); }

.panel-title {
  font-size: var(--fs-xxs);
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 12px 8px 6px;
}
.panel-title:first-child { padding-top: 0; }

.panel-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 38px;
  padding: 8px 10px;
  border: none;
  border-radius: var(--radius);
  background: none;
  color: var(--text);
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: 600;
  text-align: start;
  cursor: pointer;
  transition: background var(--transition);
}
.panel-row:hover { background: var(--surface-2); }
.panel-row.selected { background: var(--brand-bg); color: var(--brand); }
/* La marca de selección va después del rótulo y empuja hacia el final de
   la línea, así funciona igual en árabe (RTL) sin reglas extra. */
.panel-row .tick { margin-inline-start: auto; font-weight: 900; opacity: 0; }
.panel-row.selected .tick { opacity: 1; }
.panel-row .row-hint {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--text-3);
  line-height: 1.35;
}
.panel-row.selected .row-hint { color: var(--brand); opacity: 0.8; }

/* Rejilla de idiomas: 13 entradas caben en tres columnas sin scroll. */
.lang-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px; }


/* ════════════════════════════════════════════════════════════════════════
   ÁREA DE TRABAJO
   ════════════════════════════════════════════════════════════════════════ */
.main {
  margin-top: var(--topbar-h);
  margin-left: var(--sidebar-w);
  transition: margin-left var(--transition);
  min-height: calc(100vh - var(--topbar-h));
}
body.sidebar-collapsed .main { margin-left: var(--sidebar-w-min); }
html[dir="rtl"] .main { margin-left: 0; margin-right: var(--sidebar-w); }
html[dir="rtl"] body.sidebar-collapsed .main { margin-right: var(--sidebar-w-min); }
html[dir="rtl"] .sidebar { left: auto; right: 0; border-right: none; border-left: var(--frame-border); }
html[dir="rtl"] .nav-tooltip { left: auto; right: calc(100% + 8px); }
html[dir="rtl"] .nav-item.active::before { left: auto; right: 0; border-radius: 2px 0 0 2px; }


/* ════════════════════════════════════════════════════════════════════════
   HERO — el "dashboard" con fondo animado
   ════════════════════════════════════════════════════════════════════════ */
.hero {
  position: relative;
  min-height: calc(100vh - var(--topbar-h));
  display: flex;
  align-items: center;
  overflow: hidden;
  /* El lienzo pinta sobre este fondo; fijarlo aquí evita que se vea el
     --bg de la página por los bordes durante el redimensionado. Los temas
     que no declaran --hero-bg caen en su --bg y no cambian.

     El viñeteado va AQUÍ, en el fondo del hero, y no en una capa por
     encima: el lienzo es transparente salvo donde hay una célula, así que
     el degradado se ve igual a través de él. Medido: como capa superpuesta
     costaba 8 fps porque hay que recomponerla en cada fotograma; como
     fondo se pinta una vez y sale gratis. */
  background-color: var(--hero-bg, var(--bg));
  /* Sobre el papel claro de antes bastaba un 14% para insinuar el borde.
     Sobre el gris de campo hace falta más para que el viñeteado haga su
     trabajo —cerrar la mirada hacia el centro, donde está el texto— pero
     no tanto como sobre negro: al 46% las esquinas se iban a carbón y
     rompían la lectura de campo uniforme que se busca. Al 30% se nota el
     cierre y el gris sigue siendo gris de un lado a otro. */
  background-image: radial-gradient(118% 88% at 50% 42%, transparent 34%, rgba(0, 0, 0, 0.30) 100%);
}

/* ── Los textos del hero, sobre su propia superficie oscura ──
   Van con los tokens --hero-* y no con --text/--text-2 porque el hero es
   la única superficie oscura del scroll: si tomaran la tinta del tema,
   saldrían en negro sobre negro en los tres temas claros. Todo lo que
   sigue está acotado a .hero, así que la misma clase fuera del hero
   conserva el color del tema. */
.hero-brand-name,
.hero .hero-h1,
.hero .drum-line { color: var(--hero-text); }
.hero .hero-desc { color: var(--hero-text-2); }
.hero .hero-curiosity { color: var(--hero-accent); }
/* El botón fantasma se dibujaba con la tinta del tema y un borde de
   marco pensado para fondo claro: sobre carbón desaparecían los dos. */
.hero .btn-ghost {
  color: var(--hero-text);
  border-color: var(--hero-border);
}
.hero .btn-ghost:hover {
  background: var(--hero-hover);
  color: var(--hero-text);
}

/* El lienzo del fondo animado. aria-hidden en el HTML: es decoración, y
   un lector de pantalla no debe anunciarlo. */
#bg-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.hero-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  padding: 56px 40px;
  display: flex;
  align-items: center;
}
/* Una sola columna. El texto ocupa poco más de la mitad y deja el resto
   del hero al cultivo, que es donde se forman la marca y los signos. */
.hero-copy { width: 100%; max-width: 60rem; }

/* Titular a la izquierda, tambor a la derecha. minmax(0,·) en las dos
   columnas es lo que impide que una línea larga del tambor —el ruso y el
   alemán son los peores— ensanche su columna y aplaste al titular: sin
   eso, una celda de rejilla no baja de su contenido mínimo. */
.hero-headline {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  gap: clamp(22px, 3.2vw, 52px);
  align-items: center;
  margin-bottom: 26px;
}

/* La marca del producto, justo encima del titular. Los tres valores
   —icono, nombre y el aire entre ellos— crecen con el MISMO factor: si
   sólo subieran los dos dibujos, el hueco se quedaría corto y el bloque se
   apretaría. El nombre toma --text, o sea negro sobre el hero claro, por
   el currentColor del <symbol>. */
.hero-brand {
  display: flex;
  align-items: center;
  gap: clamp(15px, 1.8vw, 24px);
  /* Sube con el bloque: un conjunto un 50% más alto contra los 16 px de
     antes dejaba el titular pegado al nombre. */
  margin: 0 0 24px;
}
.hero-brand-mark {
  height: clamp(3.15rem, 6.45vw, 5.03rem);
  width: auto;
  display: block;
  /* Pastilla clara bajo el icono, para despegarlo del campo gris. */
  padding: 20px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 5px;
  /* content-box a propósito, contra el border-box global de la línea 24.
     Con border-box el padding se descuenta del alto declarado: los 20 px de
     arriba y abajo dejarían el dibujo en 40 px menos que el clamp, o sea
     encogido justo al ponerle la pastilla. Con content-box el clamp sigue
     midiendo el icono y el relleno crece hacia fuera, que es lo pedido. */
  box-sizing: content-box;
}
.hero-brand-name {
  /* El trazado no lleva ascendentes ni descendentes: su alto ES la altura
     de mayúscula.

     Hasta el 26-08-2026 se igualaba a la del titular de debajo (≈0,72 de
     su cuerpo) para que las dos líneas se leyeran como un bloque. Ahora va
     un 50% por encima de aquello, deliberadamente: el hero anuncia la
     MARCA antes que la frase, así que el nombre domina al titular en vez
     de acompañarlo. Ojo al revisar alemán y ruso, donde el titular ya se
     iba a tres líneas: es ahí donde la primera pantalla queda más justa. */
  height: clamp(2.06rem, 4.2vw, 3.3rem);
  width: auto;
  display: block;
}

.hero-h1 {
  /* Más contenido que el lema de dos palabras que había antes: ahora es
     una frase entera que en alemán o en ruso se va a tres líneas. El
     cuerpo se acota con clamp para que el titular, el tambor, el
     descriptor y los botones quepan juntos en la primera pantalla. */
  font-size: clamp(1.9rem, 3.9vw, 3.05rem);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 0;
  max-width: 13em;
}
/* Los temas datarams* ponen versales a todos los h1/h2; el titular es la
   excepción: en japonés, chino, coreano, ruso y árabe las versales o no
   existen o deforman el trazo. */
[data-theme="datarams"] .hero-h1,
[data-theme="dataramslight"] .hero-h1 {
  text-transform: none;
  letter-spacing: -0.02em;
}

/* ── El tambor ──
   Cinco huecos en vertical. El del centro va al mismo color y opacidad
   que el titular, y a cada lado asoman dos líneas atenuadas: es lo que
   da la sensación de rodillo, de que hay más detrás y delante.

   El alto de hueco lo fija --drum-slot y app.js lo lee del propio
   elemento (offsetHeight de una línea), en vez de llevar el número
   duplicado en el JavaScript. */
.drum {
  --drum-slot: 1.85em;
  position: relative;
  height: calc(var(--drum-slot) * 5);
  overflow: hidden;
  margin: 0;
  font-size: clamp(1.05rem, 1.85vw, 1.55rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  /* Difumina los extremos además de la opacidad por hueco: sin esto, la
     línea de arriba se corta en seco contra el borde. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
}
.drum-strip {
  position: absolute;
  inset: 0;
  will-change: transform;
}
.drum-line {
  height: var(--drum-slot);
  line-height: var(--drum-slot);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hero-desc {
  font-size: var(--fs-md);
  line-height: 1.65;
  color: var(--text-2);
  max-width: 34em;
  margin: 0 0 26px;
}
.hero-curiosity {
  color: var(--brand);
  font-weight: 700;
}

/* ── Grano y viñeteado ──
   Van como capas CSS y no pintados dentro del lienzo a propósito: el
   grano hay que moverlo en cada fotograma para que tiemble, y una capa
   que sólo se desplaza la compone la GPU casi gratis, mientras que
   rellenar la pantalla entera de ruido desde el bucle de dibujo cuesta
   fotogramas. El ruido es feTurbulence en un SVG incrustado —sin fichero
   que servir— y se dessatura para que sea grano y no confeti. */
.hero-grain {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  /* Sobresale por los cuatro lados para poder temblar sin descubrir el
     borde del hero. */
  inset: -80px;
  /* Sin mix-blend-mode a propósito, y esto no es un descuido estético:
     medido, el grano multiplicado costaba 26 fps —de 56 a 30— porque
     cualquier modo de fusión obliga al compositor a leer de vuelta la
     capa de debajo en cada fotograma, y debajo hay un lienzo que se
     repinta sesenta veces por segundo. Superpuesto sin fusión cuesta
     cero y la diferencia visual, a esta opacidad, es mínima. */
  opacity: 0.22;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='170' height='170' filter='url(%23g)'/%3E%3C/svg%3E");
  animation: hero-grain 760ms steps(1) infinite;
}
/* Sobre carbón el mismo grano gris se come el negro: ahí, más flojo. */
[data-theme="datarams"] .hero-grain { opacity: 0.10; }
@keyframes hero-grain {
  0%   { transform: translate(0, 0); }
  16%  { transform: translate(-9px, 5px); }
  32%  { transform: translate(6px, -8px); }
  48%  { transform: translate(-5px, -7px); }
  64%  { transform: translate(8px, 6px); }
  80%  { transform: translate(-7px, 3px); }
  100% { transform: translate(4px, -4px); }
}
[data-theme="datarams"] .hero {
  background-image: radial-gradient(118% 88% at 50% 42%, transparent 38%, rgba(0, 0, 0, 0.45) 100%);
}

.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; }


/* ════════════════════════════════════════════════════════════════════════
   Botones
   ════════════════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border: var(--frame-border);
  border-radius: var(--radius);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transition), color var(--transition), transform var(--transition);
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); color: #fff; }
.btn-ghost { background: transparent; color: var(--text); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }
/* En el tema oscuro --brand ya es un azul claro; el texto blanco encima
   no llegaría a 4,5:1, así que el botón primario invierte la tinta. */
[data-theme="datarams"] .btn-primary { color: #101014; }
[data-theme="datarams"] .btn-primary:hover { color: #101014; }


/* ════════════════════════════════════════════════════════════════════════
   Secciones de contenido
   ════════════════════════════════════════════════════════════════════════ */
.section {
  max-width: 1240px;
  margin: 0 auto;
  padding: 88px 40px;
  border-top: 1px solid var(--border-dim);
}
.section-head { max-width: 760px; margin-bottom: 44px; }
.section-kicker {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 14px;
}
.section-head h2 {
  font-size: var(--fs-3xl);
  font-weight: 800;
  line-height: 1.15;
  color: var(--text);
  margin-bottom: 16px;
}
.section-head p {
  font-size: var(--fs-lg);
  line-height: 1.6;
  color: var(--text-2);
}
.section-sub {
  font-size: var(--fs-xl);
  font-weight: 700;
  color: var(--text);
  margin: 56px 0 22px;
}

/* ── Rejillas de tarjetas ── */
.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

.card {
  background: var(--surface);
  border: var(--frame-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 26px;
  transition: box-shadow var(--transition), transform var(--transition), border-color var(--transition);
}
.card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.card h3 {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--text);
  margin-bottom: 10px;
  letter-spacing: 0;
}
.card p { font-size: var(--fs-base); line-height: 1.6; color: var(--text-2); }

.card-icon {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius);
  background: var(--brand-bg);
  color: var(--brand);
  margin-bottom: 16px;
}
.card-icon svg { width: 20px; height: 20px; }

/* ── El problema del cliente, en primera persona ──
   Esta tira va antes que cualquier explicación de método: el visitante
   tiene que reconocerse en una de estas frases en los primeros segundos,
   o no leerá el resto. */
.pain-list { display: grid; gap: 12px; margin-top: 8px; }
.pain {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px;
  background: var(--surface);
  border: var(--frame-border);
  border-inline-start: 3px solid var(--accent);
  border-radius: var(--radius);
  font-size: var(--fs-base);
  color: var(--text-2);
}
.pain q { color: var(--text); font-weight: 600; font-style: italic; }

/* ── Pasos del método ── */
.steps { counter-reset: step; display: grid; gap: 20px; }
.step {
  position: relative;
  padding-inline-start: 62px;
}
.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  width: 42px; height: 42px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: 800;
  color: var(--brand);
  background: var(--brand-bg);
  border: 1px solid var(--brand-mid);
  border-radius: var(--radius);
}
.step h3 { font-size: var(--fs-md); font-weight: 700; margin-bottom: 6px; letter-spacing: 0; }
.step p { font-size: var(--fs-base); color: var(--text-2); line-height: 1.6; }


/* ── Fichas de aplicación ── */
.app-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: var(--frame-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow var(--transition), transform var(--transition);
}
.app-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
/* Banda superior con el color de marca de cada app. Es la única
   concesión cromática fuera de la paleta ZAALEN, y es intencionada: es
   así como el visitante reconoce después cada producto por su color. */
.app-card-band { height: 4px; background: var(--app-color, var(--brand)); }
.app-card-body { padding: 26px; display: flex; flex-direction: column; flex: 1; gap: 12px; }
.app-card-head { display: flex; align-items: center; gap: 14px; }
/* Las tres fichas llevan ya su logotipo-icono real, así que el hueco de
   la cabecera se dimensiona por el alto y deja que el ancho lo ponga cada
   relación de aspecto: los de DEZIMI y OCTABI son algo más anchos que
   altos, y recortarlos a un cuadrado los deformaría. */
.app-mark {
  height: 68px;
  width: auto;
  max-width: 80px;
  flex-shrink: 0;
  display: block;
}
.app-card h3 {
  font-size: var(--fs-lg);
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0;
}
.app-kicker {
  font-family: var(--font-mono);
  font-size: var(--fs-xxs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}
.app-card p { font-size: var(--fs-base); color: var(--text-2); line-height: 1.6; }
.app-for {
  font-size: var(--fs-sm);
  color: var(--text-2);
  padding-top: 12px;
  margin-top: auto;
  border-top: 1px solid var(--border-dim);
}
.app-for strong { color: var(--text); }
/* El enlace de salida hereda --app-color de la ficha, igual que la banda
   y la inicial: es el tercer sitio donde el visitante ve el color del
   producto antes de entrar en él. La flecha se voltea en RTL. */
.app-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--app-color, var(--brand));
  text-decoration: none;
  transition: gap var(--transition);
}
.app-cta:hover { text-decoration: underline; gap: 12px; color: var(--app-color, var(--brand)); }
.app-cta::after { content: '\2192'; font-size: var(--fs-sm); }
html[dir="rtl"] .app-cta::after { content: '\2190'; }


/* ── Planes ── */
/* Pestañas Individual / Equipos y conmutador de facturación. Comparten
   aspecto: una cápsula con el seleccionado en relieve, igual que las
   filas del panel de ajustes, para que se reconozca el mismo mueble. */
.plan-switch,
.plan-billing {
  display: flex;
  align-items: center;
  gap: 4px;
  width: fit-content;
  margin: 0 auto 26px;
  padding: 4px;
  border: var(--frame-border);
  border-radius: var(--radius);
  background: var(--surface);
}
.plan-billing { gap: 8px; }
.plan-tab,
.plan-bill {
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-2);
  padding: 8px 20px;
  border-radius: calc(var(--radius) - 2px);
  transition: background var(--transition), color var(--transition);
}
.plan-tab:hover,
.plan-bill:hover { color: var(--text); }
.plan-tab.selected,
.plan-bill.selected { background: var(--brand); color: #fff; }
.plan-save {
  font-family: var(--font-mono);
  font-size: var(--fs-xxs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  padding-inline-end: 10px;
}

.plan {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: var(--frame-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 28px;
  gap: 14px;
}
/* El plan destacado no se marca sólo con color: lleva borde de marca Y
   una etiqueta con texto, para que también se distinga en escala de
   grises o para un daltónico. */
.plan.featured { border-color: var(--brand); border-width: 2px; box-shadow: var(--shadow-md); }
.plan-badge {
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: var(--fs-xxs);
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: var(--radius-sm);
  background: var(--brand-bg);
  color: var(--brand);
}
.plan h3 { font-size: var(--fs-xl); font-weight: 800; letter-spacing: 0.04em; margin: 0; }
.plan-price { font-family: var(--font-mono); font-size: var(--fs-2xl); font-weight: 800; color: var(--text); line-height: 1; }
.plan-price small { font-family: var(--font); font-size: var(--fs-sm); font-weight: 600; color: var(--text-3); letter-spacing: 0; }
.plan-desc { font-size: var(--fs-base); color: var(--text-2); line-height: 1.6; }
.plan ul { list-style: none; display: grid; gap: 9px; margin-top: 4px; }
.plan li {
  position: relative;
  padding-inline-start: 24px;
  font-size: var(--fs-base);
  color: var(--text-2);
  line-height: 1.5;
}
.plan li::before {
  content: "";
  position: absolute;
  inset-inline-start: 4px;
  top: 0.55em;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--brand-mid);
}
.plan .btn { margin-top: auto; justify-content: center; }

/* ── Recargas (Espresso / Doppio) ── */
.topups {
  margin-top: 28px;
  background: var(--cream);
  border: var(--frame-border);
  border-radius: var(--radius-lg);
  padding: 30px;
}
.topups h3 { font-size: var(--fs-xl); font-weight: 800; margin-bottom: 8px; }
.topups > p { font-size: var(--fs-base); color: var(--text-2); max-width: 70ch; margin-bottom: 22px; }
.topup-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; max-width: 720px; }
.topup {
  background: var(--surface);
  border: var(--frame-border);
  border-radius: var(--radius);
  padding: 20px 22px;
  display: grid;
  gap: 6px;
}
.topup-name { font-size: var(--fs-md); font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; }
.topup-price { font-family: var(--font-mono); font-size: var(--fs-2xl); font-weight: 800; line-height: 1.1; }
.topup-units { font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: 700; color: var(--brand); }
.topup-note { font-size: var(--fs-sm); color: var(--text-2); line-height: 1.5; }
.topup.best { border-color: var(--brand); }
.legal-note { font-size: var(--fs-xs); color: var(--text-3); line-height: 1.55; margin-top: 20px; max-width: 80ch; }


/* ── Contacto ── */
.contact-grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 24px; align-items: start; }
.contact-box {
  background: var(--surface);
  border: var(--frame-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 30px;
}
.contact-box h3 { font-size: var(--fs-md); font-weight: 700; margin-bottom: 14px; letter-spacing: 0; }
.contact-mail {
  font-family: var(--font-mono);
  font-size: var(--fs-xl);
  font-weight: 700;
  word-break: break-all;
}
.contact-data { font-size: var(--fs-base); color: var(--text-2); line-height: 1.8; }
.contact-data dt {
  font-size: var(--fs-xxs);
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-top: 12px;
}
.contact-data dt:first-child { margin-top: 0; }
.contact-data dd { color: var(--text); }


/* ── Pie ── */
.footer {
  border-top: var(--frame-border);
  background: var(--surface-2);
  padding: 32px 40px;
}
.footer-inner {
  max-width: 1240px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  font-size: var(--fs-sm);
  color: var(--text-2);
}
/* El lema cierra el pie, bajo la línea de la sociedad. */
.footer-motto {
  display: block;
  margin-top: 6px;
  color: var(--brand);
  font-weight: 700;
}
.footer-links { display: flex; flex-wrap: wrap; gap: 16px; margin-inline-start: auto; }
.link-btn {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  color: var(--brand);
  cursor: pointer;
  text-decoration: none;
}
.link-btn:hover { text-decoration: underline; }


/* ════════════════════════════════════════════════════════════════════════
   Modal legal + banner de cookies
   (Contenido heredado de la web anterior: los textos jurídicos siguen
   siendo válidos y no se tocan.)

   La FORMA, en cambio, es la de la suite: visor y aviso reproducen los de
   DEZIMI, OCTABI y QUMERIQ (unificados el 19-07-2026, ver
   PLAN_SUITE_REFINEMENT_v1.md fase 2.2). Los valores duros —700 px de
   visor, 600 px de tarjeta, 80vh, el fondo rgba(26,31,46,0.55)— vienen de
   los `style` en línea de LegalModal.tsx y CookieBanner.tsx; están puestos
   a pelo allí, así que aquí tampoco se abstraen: si cambian en el
   componente, hay que cambiarlos aquí, y un token propio sólo escondería
   que las dos copias tienen que moverse a la vez.
   ════════════════════════════════════════════════════════════════════════ */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(26, 31, 46, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.overlay.open { display: flex; }

.modal {
  background: var(--surface);
  border: var(--frame-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  width: min(700px, 92vw);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  color: var(--text);
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
/* Sin versalitas ni interletraje: el visor de las apps titula en redonda
   a --fs-md, y la mayúscula forzada haría que el mismo documento se
   leyera distinto según por dónde se abriera. */
.modal-head h2 {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--text);
}
[data-theme="datarams"] .modal-head h2::after,
[data-theme="dataramslight"] .modal-head h2::after { display: none; }
.modal-close {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  padding: 0;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-3);
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.modal-close:hover { background: var(--brand-light); color: var(--brand-dark); }

.tabs { display: flex; border-bottom: 1px solid var(--border-dim); background: var(--surface-2); overflow-x: auto; }
.tab {
  flex: 1;
  min-width: max-content;
  padding: 12px 16px;
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-2);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.tab:hover { background: var(--brand-bg); color: var(--brand); }
.tab.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: 800; }

.modal-body {
  padding: 20px 24px;
  overflow-y: auto;
  flex: 1;
  font-size: var(--fs-sm);
  color: var(--text-2);
  line-height: 1.75;
}
.modal-body h3 {
  font-size: var(--fs-md);
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brand);
  margin: 20px 0 8px;
}
.modal-body h3:first-child { margin-top: 0; }
.modal-body h4 { font-size: var(--fs-base); font-weight: 700; color: var(--text); margin: 14px 0 6px; }
.modal-body p { margin-bottom: 10px; color: var(--text-2); }
.modal-body ul { margin: 6px 0 12px; padding-inline-start: 22px; color: var(--text-2); }
.modal-body li { margin-bottom: 4px; }
.datos-box {
  background: var(--brand-bg);
  border-inline-start: 3px solid var(--brand);
  border-radius: var(--radius-sm);
  padding: 14px 18px;
  margin: 10px 0 16px;
  font-size: var(--fs-sm);
  color: var(--text);
}
.legal-section { display: none; }
.legal-section.active { display: block; }

/* ── Aviso de cookies ──
   Tarjeta flotante centrada abajo, no una barra a todo lo ancho: es lo
   que enseñan las tres apps, y ahí la razón era que un aviso que ocupa
   todo el borde inferior se lee como un muro y no como una pregunta.
   Ahora que la decisión se comparte entre la web y las apps (una cookie
   de dominio, ver assets/app.js §6), tienen que ser además el MISMO
   objeto: quien acepta aquí reconoce lo que ya contestó si vuelve a
   aparecer, y quien lo ve dos veces sabe que es lo mismo. */
.cookie-banner {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  width: min(600px, 92vw);
  z-index: 500;
  display: none;
  align-items: flex-start;
  gap: 16px;
  padding: 18px 22px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}
.cookie-banner.show { display: flex; }

/* Cuadrado tintado con el glifo. El radio de 8 px va a pelo, como en el
   componente: es el único sitio de la web donde una esquina no obedece a
   --radius, y obedecerlo lo haría cuadrado en el tema datafox, donde
   --radius es 0, mientras en las apps sigue redondeado. */
.cookie-icon {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--brand-light);
  color: var(--brand-dark);
  border-radius: 8px;
}

.cookie-body { flex: 1; min-width: 0; }
.cookie-title {
  font-weight: 700;
  font-size: var(--fs-sm);
  margin-bottom: 4px;
  color: var(--text);
}
.cookie-text { font-size: var(--fs-xs); color: var(--text-2); line-height: 1.55; }

.cookie-more {
  display: inline-block;
  margin-top: 8px;
  padding: 0;
  background: none;
  border: none;
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--brand-dark);
  text-decoration: underline;
  cursor: pointer;
}
.cookie-more:hover { color: var(--brand); }

.cookie-actions { display: flex; gap: 8px; margin-top: 12px; }
.cookie-btn {
  padding: 8px 18px;
  font-family: inherit;
  font-size: var(--fs-sm);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
/* Aceptar y rechazar tienen el mismo tamaño y la misma caja a propósito:
   la AEPD considera práctica engañosa que rechazar cueste más que
   aceptar. Lo que cambia es el relleno, no el peso del botón. */
.cookie-btn.primary {
  background: var(--brand);
  color: #fff;
  border: none;
  font-weight: 700;
}
.cookie-btn.primary:hover { background: var(--brand-dark); }
.cookie-btn.secondary {
  background: transparent;
  color: var(--text-2);
  border: 1px solid var(--border);
  font-weight: 400;
}
.cookie-btn.secondary:hover { background: var(--brand-light); color: var(--brand-dark); }


/* ════════════════════════════════════════════════════════════════════════
   Adaptación a pantallas pequeñas
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .hero-inner { padding: 48px 32px; }
  /* Ya no caben dos columnas: el tambor vuelve a su sitio bajo el titular. */
  .hero-headline { grid-template-columns: 1fr; gap: 14px; }
  .contact-grid { grid-template-columns: 1fr; }
  /* El descriptor corporativo cede el sitio al nombre del producto: entre
     los dos, el que dice de quién es esta página es QUMERIQ. */
  .topbar-tagline { display: none; }
}

@media (max-width: 767px) {
  /* Con dos marcas y dos botones, la barra se queda sin ancho: el nombre
     de QUMERIQ se retira y queda su icono, que es lo que de verdad se
     reconoce de un vistazo. El aria-label del enlace sigue diciéndolo. */
  .topbar-product-name { display: none; }
  .topbar-product-mark { height: 24px; }
  .topbar-sep { height: 18px; }

  /* En móvil la barra lateral deja de empujar el contenido y pasa a ser
     un cajón sobre él: con 360 px de ancho no hay sitio para las dos
     cosas, y es exactamente lo que hacen las apps. */
  .sidebar {
    width: var(--sidebar-w);
    transform: translateX(-105%);
    box-shadow: var(--shadow-md);
  }
  body.sidebar-collapsed .sidebar { width: var(--sidebar-w); }
  body.drawer-open .sidebar { transform: translateX(0); }
  html[dir="rtl"] .sidebar { transform: translateX(105%); }
  html[dir="rtl"] body.drawer-open .sidebar { transform: translateX(0); }
  /* Dentro del cajón los rótulos SIEMPRE se ven, aunque el estado global
     sea "colapsada": un cajón de sólo iconos no tendría ningún sentido. */
  body.sidebar-collapsed .sidebar .nav-label,
  body.sidebar-collapsed .sidebar .sidebar-cta .nav-label { display: block; }
  body.sidebar-collapsed .sidebar .nav-item,
  body.sidebar-collapsed .sidebar .sidebar-cta { justify-content: flex-start; padding: 0 10px; }
  .nav-tooltip { display: none !important; }

  body.drawer-open .scrim { opacity: 1; pointer-events: auto; }

  .main,
  body.sidebar-collapsed .main { margin-left: 0; }
  html[dir="rtl"] .main,
  html[dir="rtl"] body.sidebar-collapsed .main { margin-right: 0; }

  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .topup-grid { grid-template-columns: 1fr; }
  .section { padding: 56px 22px; }
  .hero-inner { padding: 44px 22px; }
  .drum { --drum-slot: 2.15em; }
  .section-head h2 { font-size: var(--fs-2xl); }
  .footer { padding: 26px 22px; }
  .footer-links { margin-inline-start: 0; }
  .modal-body { padding: 20px; }
  .cookie-banner { bottom: 12px; width: calc(100vw - 24px); padding: 16px; gap: 12px; }
  .cookie-actions { flex-wrap: wrap; }
}

/* ── El nombre de MOCCA:Lab ────────────────────────────────────────────
   El tema de Braun pone versales a todos los h3, y en los nombres de
   DEZIMI, OCTABI y QUMERIQ eso da igual —ya se escriben así—, pero el
   del laboratorio no: es MOCCA:Lab, con el sufijo en caja baja, y en
   versales quedaba MOCCA:LAB, que no es su nombre. */
#app-mocca-name { text-transform: none; letter-spacing: 0.01em; }

/* ════════════════════════════════════════════════════════════════════════
   DESPLEGABLES DE LA BARRA — waffle y acceso
   ════════════════════════════════════════════════════════════════════════

   Las mismas dos piezas que lleva la portada, con el mismo aspecto, para
   que quien va y viene entre index.html y esta página se encuentre lo
   mismo. Aquí no se pueden reutilizar: aquella hoja es home.css y ésta es
   app.css, y las dos páginas no comparten más que theme.css.

   Cuelgan de la barra, que es position:fixed, así que van en absoluto
   respecto a ella y con un z-index por encima del contenido pero por
   debajo del panel de ajustes, que es un cajón entero y manda más.  */
.pop {
  position: absolute;
  top: calc(var(--topbar-h) - 8px);
  right: 16px;
  z-index: 95;
  min-width: 230px;
  padding: 10px;
  background: var(--surface);
  color: var(--text);
  border: var(--frame-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.pop-title {
  padding: 4px 10px 10px;
  font-size: var(--fs-xxs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--text-3);
}

/* El ancho es el del lanzador de las apps. Sin él, el panel se encoge a
   su min-width y las descripciones salen en tiras de tres palabras. */
.pop-waffle { width: 420px; max-width: calc(100vw - 32px); }

.waffle-suite {
  display: grid;
  justify-items: center;
  gap: 9px;
  padding: 14px 10px 12px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  transition: background var(--transition);
}
.waffle-suite:hover { background: var(--brand-bg, var(--teal-bg)); text-decoration: none; }
/* La aplicación en la que ya se está va marcada, como en el lanzador de
   las apps: ahorra el clic que no lleva a ninguna parte. */
.waffle-suite[aria-current="true"] {
  background: var(--brand-bg, var(--teal-bg));
  border-color: var(--brand, var(--teal));
}
.waffle-suite img { width: 34px; height: 34px; }

.waffle-rule { height: 1px; margin: 8px 4px; background: var(--border-dim); }

/* 1fr 2fr, como en las apps: la identidad ocupa un tercio y la
   descripción dos. */
.waffle-app {
  display: grid;
  grid-template-columns: 1fr 2fr;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  text-align: start;
  transition: background var(--transition), border-color var(--transition);
}
.waffle-app:hover {
  background: var(--brand-bg, var(--teal-bg));
  border-color: var(--brand-mid, var(--border));
  text-decoration: none;
}
.waffle-app-id { display: grid; justify-items: center; gap: 6px; }
.waffle-app img { width: 30px; height: 30px; }
.waffle-name { height: 11px; width: auto; color: var(--text); display: block; }
.waffle-app-desc { font-size: var(--fs-xxs); line-height: 1.4; color: var(--text-2); }

/* ── Aviso del acceso ────────────────────────────────────────────────── */
.pop-signin { max-width: 300px; }
.pop-signin p {
  margin: 6px 10px 10px;
  font-size: var(--fs-xs);
  line-height: 1.55;
  color: var(--text-2);
}
.pop-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0 10px 6px;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--brand, var(--teal));
}
.pop-link svg { width: 12px; height: 12px; }

/* ── Iniciar sesión ───────────────────────────────────────────────────
   La barra de esta página es oscura SIEMPRE —no hay estado transparente
   sobre vídeo como en la portada—, así que el botón sólo tiene una
   versión: contorno claro sobre el carbón, y al pasar por encima se
   rellena de blanco. Y entonces el rótulo TIENE que irse a oscuro, que
   es exactamente el fallo que la portada tenía y que se acaba de
   corregir en home.css: currentColor pinta el fondo, y si el texto
   también hereda currentColor, el botón se queda vacío. */
.signin-btn {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding-inline: 16px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  background: none;
  color: rgba(255, 255, 255, 0.9);
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.signin-btn:hover { background: #fff; border-color: #fff; }
.signin-btn:hover .signin-label { color: #14161a; }
.signin-btn[aria-expanded="true"] { border-color: rgba(255, 255, 255, 0.55); color: #fff; }

/* En pantalla estrecha la barra ya va justa con la hamburguesa, la
   marca, el producto y el idioma: el acceso es lo primero que sobra. El
   waffle se queda, que es el que lleva a las otras aplicaciones. */
@media (max-width: 767px) {
  .signin-btn { display: none; }
  .pop-waffle { right: 8px; }
}
