/*
 * Telemax — styles.css
 * Componentes base usados por las pantallas del hub.
 * Fuente: design/DESIGN.md §7.
 *
 * Este archivo se irá poblando vertical por vertical. Cada nueva ejecución del plan
 * puede AÑADIR clases que falten pero no debe MODIFICAR las existentes sin nota.
 */

/* ============================================================
 * Reset + base
 * ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; overflow-x: clip; }
body {
  margin: 0;
  /* Red de seguridad: evita scroll/"movimiento lateral" en móvil (p. ej. nav-drawer
     oculto con translateX). overflow-x:clip no crea contenedor de scroll, así que
     no rompe position:sticky (a diferencia de overflow-x:hidden). */
  overflow-x: clip;
  max-width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--color-ink);
  background: var(--color-white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
}
h1 { font-size: var(--text-h1); line-height: 1.1; }
h2 { font-size: var(--text-h2); line-height: 1.15; }
h3 { font-size: var(--text-h3); line-height: 1.2; }
h4 { font-size: var(--text-h4); line-height: 1.3; }

p { margin: 0 0 var(--space-4); }
a { color: var(--color-brand-orange); text-decoration: none; }
a:hover { color: var(--color-brand-red); }
a:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }

img { max-width: 100%; height: auto; display: block; }

:where(.wp-site-blocks) > * {
  margin-block-start: 0;
}

.container { max-width: var(--container-max); margin: 0 auto; padding: 0 var(--container-padding-desktop); }
@media (max-width: 767.98px) {
  .container { padding: 0 var(--container-padding-mobile); }
}

.container-narrow { max-width: var(--container-narrow); margin: 0 auto; padding: 0 var(--container-padding-mobile); }
/* Modificador para reemplazar style="" inline (single-product.html, tab FAQ):
   un style="" inline en el div que envuelve un bloque nativo no lo genera
   el soporte "spacing" del bloque group y el editor lo marca como
   contenido inválido. */
.container-narrow--pad-desktop { padding: 0 var(--container-padding-desktop); }

.text-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.text-overline { font-size: var(--text-caption); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }

/* ============================================================
 * Button — DESIGN.md §7.1
 * ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-weight: 600;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  transition: background .15s, color .15s, transform .05s, box-shadow .15s;
  white-space: nowrap;
}
.btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn.is-disabled { opacity: 0.4; cursor: not-allowed; }
/* En pantallas estrechas el `nowrap` de arriba deja de ser una ayuda: las
   etiquetas largas se salen del botón. El cliente lo fotografió el 6-oct-2026
   con "Pedir presupuesto sin compromiso", que desborda por debajo de 390px
   (su captura es un navegador dentro de una app, con menos ancho útil que la
   pantalla). El min-height de los tamaños ya contempla dos líneas. */
@media (max-width: 480px) {
  .btn {
    white-space: normal;
    text-wrap: balance;
  }
}

/* Tamaños.
   min-height en vez de height: con height fija, una etiqueta que parte en dos
   líneas (ver .btn--wrappable más abajo, móvil estrecho) se sale de la caja del
   botón. Con contenido de una sola línea el resultado es idéntico, porque el
   contenido nunca supera la altura. */
.btn--lg { min-height: 56px; padding: 0 24px; font-size: var(--text-body-lg); }
.btn--md { min-height: 48px; padding: 0 20px; font-size: var(--text-body); }
.btn--sm { min-height: 40px; padding: 0 16px; font-size: var(--text-small); }

/* Variantes */
.btn--primary { background: var(--color-brand-orange); color: var(--color-white); }
.btn--primary:hover { background: var(--color-brand-red); color: var(--color-white); }

.btn--secondary { background: var(--color-ink); color: var(--color-white); }
.btn--secondary:hover { background: var(--color-steel); color: var(--color-white); }

.btn--outline { background: transparent; color: var(--color-ink); box-shadow: inset 0 0 0 2px var(--color-ink); }
.btn--outline:hover { background: var(--color-ink); color: var(--color-white); }

.btn--ghost { background: transparent; color: var(--color-ink); }
.btn--ghost:hover { background: var(--color-mist); color: var(--color-ink); }

/* core/button reutilizando .btn (CTAs de plantillas fallback: 404, sin
   resultados de búsqueda; también CTAs de la Home: hero-mandos, big-section,
   banner-cta). Gutenberg aplica el className del bloque al
   <div class="wp-block-button">, no al <a> interno; sin esto el padding y
   el radio de píldora por defecto de .wp-block-button__link se sumarían al
   de .btn y el botón se vería doblemente abultado. También reforzamos
   display:inline-flex en el wrapper (Gutenberg lo pone a inline-block por
   defecto vía ".wp-block-buttons > .wp-block-button") para que el <a>
   interno quede perfectamente centrado como antes, y color:inherit para que
   el texto tome el color de la variante (.btn--primary/--outline/
   --outline-white) en vez del naranja de enlace por defecto (a{color:...}).
   background-color:inherit es imprescindible: el baseline de Gutenberg
   (:where(.wp-element-button, .wp-block-button__link){background-color:
   #32373c}) sigue aplicando porque nada lo sobreescribía, así que el <a>
   interno pintaba un recuadro gris oscuro encajado dentro de la píldora ya
   coloreada del wrapper .btn/.btn--primary. */
.wp-block-buttons .wp-block-button.btn { display: inline-flex; position: relative; }
/* theme.json fija blockGap "0" (a propósito, para no meter huecos en las
   plantillas), así que el layout flex de core/buttons resolvía gap:0 y los dos
   botones del 404 y de la búsqueda sin resultados quedaban pegados: con el
   ::after estirado de abajo sus áreas pulsables se solapaban. */
.page-hero .wp-block-buttons { gap: var(--space-4); flex-wrap: wrap; }
.wp-block-button.btn > .wp-block-button__link { padding: 0; height: auto; color: inherit; background-color: transparent; }
/* El padding del botón vive en el wrapper .wp-block-button.btn, pero el enlace
   real es el <a> interno, al que aquí se le quita el padding: el área pulsable
   quedaba en 29px de alto frente a los 48-56px que se ven, y el borde del botón
   no respondía al clic. Este ::after estira el enlace sobre todo el wrapper
   (patrón "stretched link") sin tocar el layout. */
.wp-block-button.btn > .wp-block-button__link::after { content: ""; position: absolute; inset: 0; }

/* Grupos de CTAs de la Home que ya tenían su propio flex container con
   gap/wrap propios (hero-mandos__ctas, big-section, banner-cta__ctas):
   el <div class="wp-block-buttons"> que añade Gutenberg se vuelve invisible
   para el layout (display:contents) y sus botones pasan a comportarse como
   hijos directos de ese contenedor, conservando el gap/wrap/orden responsive
   ya existentes sin duplicar reglas. */
.hero-mandos__ctas .wp-block-buttons,
.big-section .wp-block-buttons,
.banner-cta__ctas .wp-block-buttons { display: contents; }

/* tlx/hero-mandos, tlx/personaliza-mando y tlx/banner-cta usan InnerBlocks
   reales para los CTA: el editor inserta wrappers propios
   (.block-editor-inner-blocks > .block-editor-block-list__layout) entre el
   contenedor de CTAs y .wp-block-buttons, igual que en .hero-carousel__track
   (ver más abajo). display:contents los saca del árbol de cajas solo en el
   editor, así los botones vuelven a alinearse en fila como en el front. */
.hero-mandos__ctas .block-editor-inner-blocks,
.hero-mandos__ctas .block-editor-block-list__layout,
.big-section .block-editor-inner-blocks,
.big-section .block-editor-block-list__layout,
.banner-cta__ctas .block-editor-inner-blocks,
.banner-cta__ctas .block-editor-block-list__layout { display: contents; }

/* Desbordamiento horizontal en móviles estrechos (≤ 400px).
 *
 * Estos grupos de CTAs apilan los botones en columna en móvil, y por el
 * display:contents de arriba los .wp-block-button son ítems flex DIRECTOS del
 * contenedor. Un ítem flex tiene min-width:auto, es decir, nunca encoge por
 * debajo de su ancho de contenido mínimo; y .btn lleva white-space:nowrap, así
 * que ese mínimo es la etiqueta ENTERA en una línea más el padding. Con
 * etiquetas largas ("MANDOS PARA PORTAVEHÍCULOS", "VER TELEMANDOS
 * INDUSTRIALES") el botón medía 363-366px dentro de un contenedor de 328px y
 * se salía de la pantalla a 360px de ancho. No se veía como scroll lateral
 * porque html/body llevan overflow-x:clip, que lo recorta en vez de evitarlo.
 *
 * Solución: cuando el botón va estirado a todo el ancho, dejarle partir la
 * etiqueta en dos líneas y encoger (min-width:0). En desktop no cambia nada,
 * porque ahí los botones caben de sobra en una línea. */
@media (max-width: 767.98px) {
  .hero-mandos__ctas .btn,
  .big-section .btn,
  .banner-cta__ctas .btn,
  .pdp-ctas .btn,
  .pdp-ctas .single_add_to_cart_button {
    white-space: normal;
    min-width: 0;
    text-align: center;
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
  }
}

/* ============================================================
 * Field (input + label + helper) — DESIGN.md §7.2
 * ============================================================ */
.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field__label { font-size: var(--text-small); font-weight: 600; color: var(--color-ink); }
.field__input,
.field__select,
.field__textarea {
  height: 48px;
  padding: 12px 16px;
  font-family: var(--font-body);
  font-size: var(--text-body);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-ink);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.field__textarea { min-height: 120px; padding: 12px 16px; line-height: 1.5; resize: vertical; }
/* El chevron nativo del select se apoya en el borde y queda descentrado en
   Safari/Chrome (revisión del cliente: "flecha mal alineada en el formulario
   y en todos los de este tipo"). Se sustituye por el icono propio, colocado
   con background-position, y se reserva el hueco con padding-right. */
.field__select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 44px;
  background-image: var(--icon-chevron-down);
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 16px 16px;
  cursor: pointer;
}
.field__input:focus,
.field__select:focus,
.field__textarea:focus {
  border-color: var(--color-brand-orange);
  box-shadow: var(--shadow-focus);
}
.field--error .field__input,
.field--error .field__textarea,
.field--error .field__select { border-color: var(--color-danger); }
.field__helper { font-size: var(--text-caption); color: var(--color-steel); }
.field--error .field__helper { color: var(--color-danger); }

/* ============================================================
 * Chip — DESIGN.md §7.3
 * ============================================================ */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-caption);
  font-weight: 600;
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  background: var(--color-mist);
  color: var(--color-ink);
  white-space: nowrap;
}
/* El texto va un tono más oscuro que --color-success / --color-danger, que están
   pensados para bordes e iconos: sobre sus fondos "soft" y a 12px daban 3,00:1 y
   3,95:1, por debajo del 4,5:1 que exige AA para texto pequeño. Los fondos y la
   semántica del color no cambian. Afecta también a "En stock"/"Agotado" de la
   tarjeta de producto y de la ficha, que usan estos mismos chips. */
.chip--success { background: var(--color-success-soft); color: var(--color-success-text); }
.chip--danger { background: var(--color-danger-soft); color: var(--color-danger-text); }
.chip--warning { background: var(--color-warning-soft); color: #92400E; }
.chip--overline { text-transform: uppercase; letter-spacing: 0.05em; background: var(--color-ink); color: var(--color-white); }
.chip--brand { background: var(--color-brand-peach); color: var(--color-brand-red); }

/* ============================================================
 * Pilar / Trust / Spec utilities — placeholders
 * Cada vertical extiende aquí lo que necesite.
 * ============================================================ */

/* ============================================================
 * V1 Home — Topbar, Header, Nav, Hero, Sections, Footer
 * Añadido en iteración V1-home-mobile + V1-home-desktop
 * ============================================================ */

/* --- Topbar --- */
.topbar {
  background: var(--color-ink);
  color: var(--color-white);
  font-size: var(--text-caption);
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: .5rem var(--container-padding-desktop);
  height: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.topbar a { color: var(--color-white); text-decoration: none; }
/* Los dos datos van con su icono naranja delante (revisión del cliente). El
   gap sustituye al "·" que separaba antes teléfono y email. */
.topbar__right { display: flex; align-items: center; gap: var(--space-4); }
.topbar__link { display: inline-flex; align-items: center; gap: var(--space-2); }
.topbar__icon { color: var(--color-brand-orange); flex-shrink: 0; }
.topbar__link:hover .topbar__icon { color: var(--color-brand-peach); }
.topbar a:hover { color: var(--color-brand-peach); }
/* Revisión del cliente: "fallos en el responsive, mejor eliminar en formato
   móvil". Antes solo se ocultaba .topbar__right, así que el mensaje de la
   izquierda se quedaba partido en dos líneas y recortado por el height fijo
   de 28px. Se oculta la barra completa. */
@media (max-width: 767.98px) {
  .topbar { display: none; }
}

/* --- Site Header --- */
/* El wrapper <header> lo pone core/template-part y solo mide topbar+header+nav-main de alto:
   sin display:contents, ese wrapper es el containing block del sticky de abajo y el sticky
   se suelta en cuanto se pasa esa altura. Con display:contents el sticky pasa a medir contra
   .wp-site-blocks (altura de toda la página) sin romper el <header> semántico. */
header.wp-block-template-part { display: contents; }
/* En editor (post/site editor iframe) el wrapper mete .editor-styles-wrapper: si queda
   display:contents no genera caja y el bloque header deja de ser seleccionable con clic
   (no hay bounding rect que detectar). Se revierte solo ahí; en front sigue con contents. */
.editor-styles-wrapper header.wp-block-template-part { display: block; }
:root {
  /* Altura real de lo único que queda sticky (.site-header, desde el commit
     "Fix header sticky"): .site-header__inner (72px) + border-bottom (1px).
     Topbar y nav-main NO son sticky, así que no cuentan aquí. Usado por los
     asides sticky de desktop (filter-sidebar, pdp-info, desc-trust-card,
     cart-summary) para no quedar tapados por el header. Si .site-header__inner
     cambia de altura, actualizar este valor. */
  --header-sticky-offset: 73px;
}
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}
.site-header__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-padding-desktop);
  height: 72px;
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
@media (max-width: 767.98px) {
  .site-header__inner { padding: 0 var(--container-padding-mobile); gap: 0; height: 64px; }
}
.site-header__logo { flex-shrink: 0; }
.site-header__logo img { height: 32px; width: auto; }
.site-header__search {
  flex: 1;
  max-width: 480px;
  position: relative;
}
.site-header__search input {
  width: 100%;
  height: 44px;
  padding: 0 44px 0 16px;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--color-ink);
  background: var(--color-mist);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.site-header__search input:focus {
  border-color: var(--color-brand-orange);
  box-shadow: var(--shadow-focus);
  background: var(--color-white);
}
.site-header__search input::placeholder { color: var(--color-steel); }
/* display:flex es lo que centra el icono: como <span> inline la caja tomaba
   la altura de línea de la fuente y no la del SVG, así que el
   translateY(-50%) dejaba la lupa descuadrada (revisión del cliente).
   7-oct-2026: pasa de <span> decorativo a <button type="submit">, porque en
   móvil la lupa sí era un botón y en escritorio no hacía nada. Mide 44x44
   (mínimo de zona pulsable, WCAG 2.5.8) y va a right:1px para que el centro
   del SVG caiga donde caía antes (1+22 = 23px, igual que el 14+9 anterior);
   el padding-right:44px del input sigue dejando el texto por delante. */
.site-header__search-icon {
  position: absolute;
  right: 1px;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  border-radius: var(--radius-md);
  color: var(--color-steel);
  cursor: pointer;
  transition: color .15s, background .15s;
}
.site-header__search-icon:hover { color: var(--color-brand-orange); }
.site-header__search-icon:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-shrink: 0;
}
.site-header__phone {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.site-header__phone:hover { color: var(--color-brand-orange); }
@media (max-width: 1023.98px) {
  .site-header__phone { display: none; }
}
.site-header__cart {
  position: relative;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  color: var(--color-ink);
  text-decoration: none;
  transition: background .15s;
}
.site-header__cart:hover { background: var(--color-mist); }
.site-header__cart-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 16px;
  height: 16px;
  background: var(--color-brand-orange);
  color: var(--color-white);
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.site-header__hamburger {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-ink);
  border-radius: var(--radius-md);
  margin-left: auto;
}
.site-header__hamburger:focus-visible { box-shadow: var(--shadow-focus); outline: none; }
@media (max-width: 767.98px) {
  .site-header__search { display: none; }
  .site-header__hamburger { display: flex; }
}

/* --- Nav Principal (desktop) --- */
.nav-main {
  background: var(--color-mist);
  border-bottom: 1px solid var(--color-border);
}
.nav-main__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-padding-desktop);
  height: 44px;
  display: flex;
  align-items: center;
  gap: 0;
}
.nav-main a {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding: 0 var(--space-4);
  font-size: var(--text-small);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-ink);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color .15s, border-color .15s;
}
.nav-main a:hover { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
.nav-main a.is-active { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
@media (max-width: 767.98px) {
  .nav-main { display: none; }
}

/* --- Nav Drawer (mobile) --- */
.nav-drawer {
  position: fixed;
  top: 0;
  right: 0;
  width: 280px;
  height: 100vh;
  background: var(--color-white);
  box-shadow: var(--shadow-lg);
  z-index: 200;
  transform: translateX(100%);
  transition: transform .25s ease;
  display: flex;
  flex-direction: column;
}
.nav-drawer.is-open { transform: translateX(0); }
.nav-drawer__backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15, 25, 35, 0.5);
  z-index: 199;
}
.nav-drawer__backdrop.is-open { display: block; }
.nav-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  height: 72px;
}
.nav-drawer__close {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-ink);
  border-radius: var(--radius-md);
}
.nav-drawer__close:focus-visible { box-shadow: var(--shadow-focus); outline: none; }
.nav-drawer__search {
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.nav-drawer__search input {
  width: 100%;
  height: 44px;
  padding: 0 16px;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-body);
  outline: none;
}
.nav-drawer__search input:focus { border-color: var(--color-brand-orange); box-shadow: var(--shadow-focus); }
.nav-drawer__links {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4) 0;
}
.nav-drawer__links a {
  display: flex;
  align-items: center;
  height: 52px;
  padding: 0 var(--space-6);
  font-size: var(--text-body);
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: background .15s, border-color .15s;
}
.nav-drawer__links a:hover { background: var(--color-mist); border-color: var(--color-brand-orange); }
.nav-drawer__links a.is-active { background: var(--color-mist); border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
.nav-drawer__footer {
  padding: var(--space-4);
  border-top: 1px solid var(--color-border);
}

/* --- Hero Split — DESIGN.md §7.11 --- */
.hero-split {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 520px;
}
@media (min-width: 768px) {
  .hero-split {
    grid-template-columns: 60fr 40fr;
    min-height: 600px;
  }
}
.hero-split__text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-12) var(--container-padding-desktop);
  background: var(--color-white);
}
@media (max-width: 767.98px) {
  .hero-split__text {
    padding: var(--space-8) var(--container-padding-mobile);
    order: 1;
  }
}
.hero-split__overline {
  display: inline-block;
  font-size: var(--text-caption);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-brand-orange);
  margin-bottom: var(--space-3);
}
.hero-split__title {
  font-family: var(--font-display);
  font-size: var(--text-h1);
  font-weight: 700;
  line-height: 1.1;
  color: var(--color-ink);
  margin: 0 0 var(--space-4);
  letter-spacing: -0.02em;
}
@media (max-width: 767.98px) {
  .hero-split__title { font-size: var(--text-h2); }
}
.hero-split__sub {
  font-size: var(--text-body-lg);
  line-height: 1.5;
  color: var(--color-steel);
  margin: 0 0 var(--space-6);
  max-width: 540px;
}
@media (max-width: 767.98px) {
  .hero-split__sub { font-size: var(--text-body); }
}
.hero-split__search {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
  max-width: 560px;
}
.hero-split__search input {
  flex: 1;
  height: 52px;
  padding: 0 16px;
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--color-ink);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.hero-split__search input:focus { border-color: var(--color-brand-orange); box-shadow: var(--shadow-focus); }
.hero-split__search input::placeholder { color: var(--color-steel); }
.hero-split__ctas {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.hero-split__media {
  background: var(--color-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8);
  position: relative;
  overflow: hidden;
  min-height: 300px;
}
@media (max-width: 767.98px) {
  .hero-split__media {
    order: 2;
    min-height: 260px;
    padding: var(--space-6);
  }
}
.hero-split__media img {
  max-height: 420px;
  width: auto;
  max-width: 100%;
  position: relative;
  z-index: 1;
  filter: drop-shadow(0 8px 32px rgba(0,0,0,0.4));
}
.hero-split__media-bg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.06;
}
.hero-split__media-bg svg { width: 120%; height: 120%; }

/* --- Trust Bar --- */
.trust-bar {
  background: var(--color-brand-peach);
  padding: var(--space-4) var(--container-padding-desktop);
}
.trust-bar__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  flex-wrap: wrap;
}
.trust-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
}
/* Naranja de marca, no el rojo: el cliente pidió el 22-sep que estos iconos
   fueran naranjas como el resto de la web. */
.trust-item svg { color: var(--color-brand-orange); flex-shrink: 0; }
@media (max-width: 767.98px) {
  .trust-bar { padding: var(--space-4) var(--container-padding-mobile); }
  .trust-bar__inner { gap: var(--space-4); justify-content: flex-start; }
  .trust-item { font-size: var(--text-caption); }
}

/* --- Section base --- */
.section {
  padding: var(--space-24) 0;
}
.section--mist { background: var(--color-mist); }
.section--peach { background: var(--color-brand-peach); }
.section--ink { background: var(--color-ink); color: var(--color-white); }
.section--pt-8 { padding-top: var(--space-8); }
.section__header {
  text-align: center;
  margin-bottom: var(--space-12);
}
.section__header h2 { margin-bottom: var(--space-4); }
.section__header p { color: var(--color-steel); max-width: 600px; margin: 0 auto; }
.section--ink .section__header p { color: var(--color-brand-peach); opacity: 0.85; }
/* Modificadores para reemplazar style="" inline en wrappers convertidos a
   core/group (page-nuestra-historia.html): un style="" inline en el div no
   lo genera el soporte "spacing" del bloque group y el editor lo marca
   como contenido inválido, igual que .section--pt-8 de arriba. */
.section__header--left { text-align: left; }
.section__header--left p { max-width: none; margin: 0; }
.section__header--mb-8 { margin-bottom: var(--space-8); }
.section__header--mb-4 { margin-bottom: var(--space-4); }
@media (max-width: 767.98px) {
  .section { padding: var(--space-16) 0; }
  .section__header { margin-bottom: var(--space-8); }
}

/* --- Bloque "Qué es" --- */
.what-is {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: center;
}
@media (min-width: 768px) {
  .what-is { grid-template-columns: 1fr 1fr; gap: var(--space-16); }
}
.what-is__specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* --- Pilares block — DESIGN.md §7.11 --- */
.pilares {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
}
@media (min-width: 768px) {
  .pilares { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); align-items: stretch; }
}
.pilar {
  padding: var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-white);
  position: relative;
}
.pilar__num {
  font-family: var(--font-mono);
  font-size: 72px;
  font-weight: 700;
  line-height: 1;
  color: var(--color-brand-peach);
  margin-bottom: var(--space-2);
  letter-spacing: -0.04em;
}
.pilar__title {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  margin-bottom: var(--space-3);
  color: var(--color-ink);
}
.pilar__text {
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--color-steel);
  margin-bottom: var(--space-4);
}
.pilar__link {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-brand-orange);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.pilar__link:hover { color: var(--color-brand-red); }
@media (max-width: 767.98px) {
  .pilar__num { font-size: 56px; }
}

/* --- Personalización block --- */
.personalizacion {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: center;
}
@media (min-width: 768px) {
  .personalizacion { grid-template-columns: 1fr 1fr; gap: var(--space-16); }
}
.personalizacion__media {
  background: var(--color-mist);
  border-radius: var(--radius-lg);
  aspect-ratio: 4/3;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.personalizacion__media img { width: 100%; height: 100%; object-fit: contain; padding: var(--space-6); }

/* --- FAQ accordion --- */
.faq-list {
  max-width: var(--container-narrow);
  margin: 0 auto;
}
.faq-item {
  border-bottom: 1px solid var(--color-border);
}
.faq-item:first-child { border-top: 1px solid var(--color-border); }
.faq-item__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-display);
  font-size: var(--text-body-lg);
  font-weight: 700;
  color: var(--color-ink);
  min-height: 52px;
}
.faq-item__trigger:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }
.faq-item__icon {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-brand-orange);
  transition: transform .2s;
}
.faq-item.is-open .faq-item__icon { transform: rotate(45deg); }
/* La respuesta de una FAQ de producto se escribe en un textarea y se pinta con
   wpautop, así que llega envuelta en <p>: sin esto, el primer párrafo empujaba el
   bloque hacia abajo y el último dejaba doble hueco antes del borde. */
.faq-item__body p:first-child { margin-top: 0; }
.faq-item__body p:last-child { margin-bottom: 0; }
.faq-item__body {
  display: none;
  padding-bottom: var(--space-4);
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--color-steel);
}
.faq-item.is-open .faq-item__body { display: block; }
@media (max-width: 767.98px) {
  .faq-item__trigger { font-size: var(--text-body); }
}

/* --- Banner CTA full-bleed naranja — DESIGN.md §7.11 --- */
.banner-cta {
  background: var(--color-brand-orange);
  padding: var(--space-16) var(--container-padding-desktop);
  text-align: center;
}
.banner-cta__inner {
  max-width: var(--container-narrow);
  margin: 0 auto;
}
.banner-cta__title {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: 700;
  color: var(--color-white);
  margin-bottom: var(--space-4);
  line-height: 1.15;
}
.banner-cta__text {
  font-size: var(--text-body-lg);
  color: rgba(255,255,255,0.88);
  margin-bottom: var(--space-8);
  line-height: 1.5;
}
.banner-cta__ctas {
  display: flex;
  gap: var(--space-4);
  justify-content: center;
  flex-wrap: wrap;
}
.btn--white {
  background: var(--color-white);
  color: var(--color-brand-orange);
  font-weight: 700;
}
.btn--white:hover { background: var(--color-brand-peach); color: var(--color-brand-red); }
.btn--outline-white {
  background: transparent;
  color: var(--color-white);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,0.7);
}
.btn--outline-white:hover { background: rgba(255,255,255,0.12); }
@media (max-width: 767.98px) {
  .banner-cta { padding: var(--space-12) var(--container-padding-mobile); }
  .banner-cta__title { font-size: var(--text-h3); }
  .banner-cta__text { font-size: var(--text-body); }
  .banner-cta__ctas { flex-direction: column; align-items: stretch; }
}

/* --- Site Footer — DESIGN.md §7.9 --- */
/* Negro puro por petición del cliente ("color de fondo en negro mejor"), no
   --color-ink: es el único sitio del proyecto que se sale de la paleta de
   neutros, y por eso el token vive en tokens.css como --color-black. */
.site-footer {
  background: var(--color-black);
  color: var(--color-white);
  padding: var(--space-16) var(--container-padding-desktop) 0;
}
.site-footer__grid {
  max-width: var(--container-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr 1.5fr 1.5fr;
  gap: var(--space-8);
  padding-bottom: var(--space-12);
}
@media (max-width: 900px) {
  .site-footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 639.98px) {
  .site-footer { padding: var(--space-12) var(--container-padding-mobile) 0; }
  .site-footer__grid { grid-template-columns: 1fr; gap: var(--space-6); padding-bottom: var(--space-8); }
}
.site-footer__col-title {
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-white);
  margin-bottom: var(--space-4);
}
.site-footer__logo { margin-bottom: var(--space-6); }
/* Se dimensiona por ANCHO, no por alto. La columna del footer mide 248px y el
   `img { max-width: 100% }` global recortaba ahí el ancho mientras la altura
   seguía clavada en 88px: el logo salía estirado al doble de alto. Con el SVG
   ya recortado a la marca (proporción 5,54:1) 240px de ancho dan 43px de alto
   y la marca se ve bastante más grande que antes, cuando el dibujo ocupaba
   solo una parte del SVG. */
.site-footer__logo img { width: 100%; max-width: 240px; height: auto; }
.site-footer__copy {
  font-size: var(--text-small);
  color: rgba(255,255,255,0.6);
  line-height: 1.6;
  margin-bottom: var(--space-4);
}
.site-footer__links { list-style: none; padding: 0; margin: 0; }
.site-footer__links li { margin-bottom: var(--space-2); }
.site-footer__links a {
  font-size: var(--text-small);
  color: rgba(255,255,255,0.7);
  text-decoration: none;
  transition: color .15s;
}
.site-footer__links a:hover { color: var(--color-brand-orange); }
.site-footer__contact-item {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  font-size: var(--text-small);
  color: rgba(255,255,255,0.7);
  margin-bottom: var(--space-3);
  line-height: 1.5;
}
/* Los teléfonos, el email y la dirección llevaban el color en un style=""
   inline dentro del render del bloque; ahora vive aquí. La dirección es un
   enlace a Google Maps desde la revisión del cliente. */
.site-footer__contact-item a { color: rgba(255,255,255,0.7); text-decoration: none; }
.site-footer__contact-item a:hover { color: var(--color-brand-orange); }
.site-footer__address-link:hover { text-decoration: underline; }
.site-footer__contact-item svg { flex-shrink: 0; margin-top: 2px; color: var(--color-brand-orange); }
.site-footer__bottom {
  max-width: var(--container-max);
  margin: 0 auto;
  border-top: 1px solid rgba(255,255,255,0.1);
  padding: var(--space-4) 0 calc(var(--space-4) + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-caption);
  color: rgba(255,255,255,0.45);
}
.site-footer__bottom a { color: rgba(255,255,255,0.5); text-decoration: none; }
.site-footer__bottom a:hover { color: var(--color-white); }

/* --- Sticky Mobile Bar — DESIGN.md §7.10 --- */
.sticky-mobile-bar {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 150;
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -4px 16px rgba(15, 25, 35, 0.08);
  padding: var(--space-3) var(--container-padding-mobile);
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
  gap: var(--space-2);
  align-items: center;
}
/* En fila, no en columna. La columna apilaba cada hijo en su propia línea
   (teléfono encima de "Pedir presupuesto" en Contacto, precio encima del
   formulario en la ficha) y la barra crecía hasta 129-232px. Como va fija
   abajo, eso tapaba el final de la página: el aviso legal del footer quedaba
   siempre debajo de ella (cliente, 15-oct-2026). */
@media (max-width: 1023px) {
  .sticky-mobile-bar { display: flex; flex-direction: row; align-items: center; }
}
/* El padding solo se reserva si la página realmente tiene una sticky-mobile-bar
   (p. ej. .sticky-mobile-bar--plp del catálogo) — evita un hueco en blanco bajo
   el footer en páginas sin este componente. Breakpoint simétrico con
   .filter-sidebar (min-width:1024px) para no dejar hueco 769-1023px sin
   ningún disparador de filtros visible. */
/* --sticky-bar-h lo publica assets/js/sticky-bar.js con el alto real medido;
   80px es solo el respaldo sin JS. */
@media (max-width: 1023px) {
  body:has(.sticky-mobile-bar) { padding-bottom: var(--sticky-bar-h, 80px); }
}
.sticky-mobile-bar__phone {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  border: 1.5px solid var(--color-border);
  color: var(--color-ink);
  text-decoration: none;
  transition: background .15s;
}
.sticky-mobile-bar__phone:hover { background: var(--color-mist); }
.sticky-mobile-bar__cta { flex: 1; }

/* ============================================================
 * V2 Aplicaciones — Breadcrumb, PageHero, CategoryCard, AppGrid
 * Añadido en iteración V2-aplicaciones-mobile + V2-aplicaciones-desktop
 * ============================================================ */

/* --- Breadcrumb --- */
.breadcrumb {
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border);
}
.breadcrumb__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-3) var(--container-padding-desktop);
}
.breadcrumb__list {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: var(--text-small);
  flex-wrap: wrap;
}
.breadcrumb__list li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-steel);
}
.breadcrumb__list a {
  color: var(--color-steel);
  text-decoration: none;
  transition: color .15s;
}
.breadcrumb__list a:hover { color: var(--color-brand-orange); }
.breadcrumb__list a:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }
.breadcrumb__list [aria-current="page"] { color: var(--color-ink); font-weight: 600; }
.breadcrumb__sep { color: var(--color-border-strong); }
@media (max-width: 767.98px) {
  .breadcrumb__inner { padding: var(--space-3) var(--container-padding-mobile); }
}

/* --- Page Hero (páginas internas) --- */
.page-hero {
  background: var(--color-mist);
  padding: var(--space-12) 0;
  border-bottom: 1px solid var(--color-border);
}
/* La cabecera de Contacto va en blanco, como el resto de páginas de contenido
   (petición del cliente, 22-sep). Va después de la regla base para ganarle. */
body.page-contacto .page-hero {
  background: var(--color-white);
}
.page-hero__overline {
  display: block;
  font-size: var(--text-caption);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-brand-orange);
  margin-bottom: var(--space-3);
}
.page-hero h1 { margin: 0 0 var(--space-4); }
.page-hero__sub {
  font-size: var(--text-body-lg);
  color: var(--color-steel);
  max-width: 640px;
  line-height: 1.5;
  margin: 0;
}
@media (max-width: 767.98px) {
  .page-hero { padding: var(--space-8) 0; }
  .page-hero__sub { font-size: var(--text-body); }
}
/* Modificador para reemplazar style="text-align:center" inline (404.html):
   un style="" inline en el div no lo genera el soporte "spacing" del
   bloque group y el editor lo marca como contenido inválido. */
.page-hero__container--center { text-align: center; }
.page-hero__container--center .page-hero__sub { margin-left: auto; margin-right: auto; }
/* En la plantilla de categoría el subtítulo lo pinta core/term-description, que
   envuelve el texto en un <p> propio: sin esto el párrafo interior se quedaba
   con la tipografía por defecto. */
.page-hero__sub > p { margin: 0; font-size: inherit; color: inherit; line-height: inherit; }
.page-hero__sub > p + p { margin-top: var(--space-3); }

/* --- Category Card — DESIGN.md §7.5 --- */
.category-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-white);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: box-shadow .15s, transform .15s;
}
.category-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.category-card__label {
  padding: var(--space-4) var(--space-6) 0;
}
.category-card__media {
  background: var(--color-brand-peach);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-12);
  min-height: 220px;
}
.category-card__media img {
  max-height: 180px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  display: block;
}
.category-card__media--icon {
  background: var(--color-mist);
  min-height: 180px;
  padding: var(--space-8);
}
.category-card__media--icon svg {
  width: 72px;
  height: 72px;
}
.category-card__body {
  padding: var(--space-6);
  flex: 1;
  display: flex;
  flex-direction: column;
}
.category-card__title {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-3);
  line-height: 1.15;
}
.category-card__desc {
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--color-steel);
  margin: 0 0 var(--space-4);
  flex: 1;
}
.category-card__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.category-card__more {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-brand-orange);
}
.category-card__cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  font-size: var(--text-body);
  font-weight: 600;
  color: var(--color-brand-orange);
  text-decoration: none;
  transition: color .15s;
  min-height: 48px;
}
.category-card__cta:hover { color: var(--color-brand-red); }
.category-card__cta:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }
@media (max-width: 767.98px) {
  .category-card__title { font-size: var(--text-h3); }
  .category-card__media { min-height: 180px; padding: var(--space-6) var(--space-8); }
}

/* --- App Grid (V2 Aplicaciones) --- */
.app-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 768px) {
  .app-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-8);
    align-items: stretch;
  }
}

/* ============================================================
 * V3 Catálogo (PLP) — ProductCard, FilterSidebar, PLPLayout
 * Añadido en iteración V3-catalogo-mobile + V3-catalogo-desktop
 * ============================================================ */

/* --- PLP Tabs (categorías horizontales) --- */
.plp-tabs {
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.plp-tabs::-webkit-scrollbar { display: none; }
.plp-tabs__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-padding-desktop);
  display: flex;
  flex-wrap: wrap;
  /* min-width: max-content; */
}
@media (max-width: 767.98px) {
  .plp-tabs__inner { padding: 0 var(--container-padding-mobile); }
}
.plp-tabs__link {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding: 0 var(--space-4);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-steel);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color .15s, border-color .15s;
}
.plp-tabs__link:hover { color: var(--color-ink); }
.plp-tabs__link.is-active { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
.plp-tabs__link:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* --- PLP Layout (sidebar + main) --- */
.plp-layout {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-8) var(--container-padding-desktop);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: start;
}
@media (min-width: 1024px) {
  .plp-layout { grid-template-columns: 260px 1fr; }
}
@media (max-width: 767.98px) {
  .plp-layout { padding: var(--space-6) var(--container-padding-mobile); gap: var(--space-6); }
}

/* --- Filter Sidebar (desktop sticky) --- */
.filter-sidebar {
  display: none;
  position: sticky;
  top: var(--header-sticky-offset);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  max-height: calc(100vh - var(--header-sticky-offset) - var(--space-6));
  overflow-y: auto;
}
@media (min-width: 1024px) { .filter-sidebar { display: block; } }

.filter-sidebar__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.filter-sidebar__title {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: 700;
}
.filter-sidebar__clear {
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-brand-orange);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  min-height: 36px;
}
.filter-sidebar__clear:hover { color: var(--color-brand-red); }
.filter-sidebar__clear:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }

/* --- Filter Group (shared sidebar + drawer) --- */
.filter-group {
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border);
}
.filter-group:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
.filter-group__title {
  font-size: var(--text-caption);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-ink);
  margin-bottom: var(--space-3);
}
/* --- Filter Drawer (mobile bottom sheet) --- */
.filter-drawer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 300;
  background: var(--color-white);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-lg);
  max-height: 88vh;
  overflow-y: auto;
  transform: translateY(100%);
  transition: transform .28s ease;
}
.filter-drawer.is-open { transform: translateY(0); }
/* Candado explícito, simétrico con .filter-sidebar (min-width:1024px): no
   fiar el ocultamiento solo a position:fixed + transform — dentro del
   iframe del editor (u otro ancestro con transform) ese contexto se rompe
   y el drawer deja de quedar fuera de pantalla, mostrándose junto al aside
   de escritorio. */
@media (min-width: 1024px) {
  .filter-drawer,
  .filter-drawer__backdrop { display: none; }
}
.filter-drawer__backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15, 25, 35, 0.5);
  z-index: 299;
}
.filter-drawer__backdrop.is-open { display: block; }
.filter-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  background: var(--color-white);
  z-index: 1;
}
.filter-drawer__title { font-family: var(--font-display); font-size: var(--text-body); font-weight: 700; }
.filter-drawer__close {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-ink);
  border-radius: var(--radius-md);
}
.filter-drawer__close:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.filter-drawer__body { padding: var(--space-4) var(--space-6); }
.filter-drawer__footer {
  padding: var(--space-4) var(--space-6);
  padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  border-top: 1px solid var(--color-border);
  display: flex;
  gap: var(--space-3);
  position: sticky;
  bottom: 0;
  background: var(--color-white);
}

/* --- PLP Toolbar --- */
.plp-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.plp-toolbar__count { font-size: var(--text-small); color: var(--color-steel); margin: 0; }
.plp-toolbar__count strong { font-weight: 700; color: var(--color-ink); }
.plp-toolbar__right { display: flex; align-items: center; gap: var(--space-3); }
.plp-sort {
  height: 40px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 500;
  color: var(--color-ink);
  background: var(--color-white);
  cursor: pointer;
  outline: none;
  transition: border-color .15s;
}
.plp-sort:focus { border-color: var(--color-brand-orange); box-shadow: var(--shadow-focus); }
.plp-view-toggle { display: flex; border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; }
.plp-view-btn {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--color-steel);
  transition: background .15s, color .15s;
}
.plp-view-btn.is-active { background: var(--color-ink); color: var(--color-white); }
.plp-view-btn:hover:not(.is-active) { background: var(--color-mist); }

/* --- Active Filters Bar --- */
.active-filters {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
  min-height: 28px;
}
.active-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px 8px 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-brand-peach);
  color: var(--color-brand-red);
  font-size: var(--text-caption);
  font-weight: 600;
}
.active-filter-chip__remove {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-brand-red);
  padding: 0;
  border-radius: 50%;
  flex-shrink: 0;
}
.active-filter-chip__remove:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* --- Product Grid --- */
/* Doble clase a propósito: woocommerce/product-template emite
   .wc-block-product-template__responsive.columns-3 cuando displayLayout tiene
   shrinkColumns:true, y su regla (especificidad 0,2,0) machacaba a
   .product-grid (0,1,0) imponiendo
   minmax(max(150px, 33.33% - .83em), 1fr) + grid-gap:1.25em.
   A 390px eso daba 2 columnas de ~169px con las tarjetas cortadas, que es el
   bug que reportó el cliente. Empatamos especificidad para recuperar el grid
   del tema; NO se toca shrinkColumns para no tener que editar además las
   copias de plantilla en BD. */
.product-grid,
.product-grid.wc-block-product-template__responsive.columns-3 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  grid-gap: var(--space-4);
}
@media (min-width: 480px) {
  .product-grid,
  .product-grid.wc-block-product-template__responsive.columns-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .plp-layout .product-grid,
  .plp-layout .product-grid.wc-block-product-template__responsive.columns-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1200px) {
  .plp-layout .product-grid,
  .plp-layout .product-grid.wc-block-product-template__responsive.columns-3 { grid-template-columns: repeat(3, 1fr); }
}

/* --- Product Card — DESIGN.md §7.4 --- */
.product-card {
  /* position:relative no es decorativo: los .screen-reader-text de
     .product-card__ctas y .qty-selector son position:absolute y, sin un
     ancestro posicionado, su bloque contenedor era el documento. Dentro del
     carrusel de .cart-related (que SÍ es un contenedor con scroll) escapaban
     de él y estiraban la página: el carrito medía 827px de ancho a 390px de
     pantalla y se podía arrastrar en horizontal hasta un hueco en blanco. */
  position: relative;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-white);
  display: flex;
  flex-direction: column;
  transition: box-shadow .15s, transform .15s;
  overflow: hidden;
  height: 100%;
}
@media (min-width: 768px) {
  .product-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
}
.product-card__media {
  background: var(--color-mist);
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  position: relative;
}
.product-card__media img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.product-card__badge {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
}
.product-card__body {
  padding: var(--space-4);
  flex: 1;
  display: flex;
  flex-direction: column;
}
.product-card__name {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-3);
  line-height: 1.3;
}
.product-card__chips {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
.product-card__price {
  font-family: var(--font-mono);
  font-size: var(--text-h3);
  font-weight: 700;
  color: var(--color-ink);
  line-height: 1;
  margin: 0;
}
.product-card__price del {
  font-size: var(--text-small);
  color: var(--color-steel);
  margin-right: var(--space-1);
}
.product-card__price ins {
  text-decoration: none;
}
.product-card__price ins,
.product-card__price sup {
  vertical-align: middle;
}
/* El cliente pidió el IVA "en negrita o más visible": sube de caption a small,
   peso 600 y color de texto en vez del gris de apoyo. */
.product-card__price-iva {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  margin: var(--space-1) 0 var(--space-4);
}
.product-card__price--pending {
  font-size: var(--text-small);
  font-family: var(--font-body);
  color: var(--color-steel);
  font-weight: 500;
  margin-bottom: var(--space-4);
}

/* "Precio bajo consulta": producto sin precio relleno, que por eso no es
   purchasable y muestra el CTA de presupuesto en vez de añadir al carrito
   (ver telemax_price_on_request_html() en functions.php). */
.price-on-request {
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-steel);
  white-space: nowrap;
}
/* Fila: selector de cantidad + "Añadir al carrito". El enlace secundario y el
   "Ver carrito" que inyecta WooCommerce tras el AJAX ocupan su propia línea.
   El selector de cantidad lo pidió el cliente en la revisión. */
.product-card__ctas {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: auto;
  margin-bottom: var(--space-3);
}
/* Compacto: la tarjeta mide ~265px en el grid de 3 columnas y con el selector
   a tamaño de carrito (130px) el botón de añadir se caía a la línea de abajo.
   Se mantienen los 44px de alto de zona pulsable en los botones. */
.product-card__qty { flex: 0 0 auto; height: 40px; }
.product-card__qty .qty-selector__btn { width: 32px; }
.product-card__qty .qty-selector__input { width: 34px; }
.product-card__ctas .product-card__cta-secondary,
.product-card__ctas .added_to_cart.wc-forward { flex: 1 0 100%; }
.product-card__cta-secondary,
.product-card__ctas .added_to_cart.wc-forward {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-brand-orange);
  text-decoration: none;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}
.product-card__cta-secondary:hover,
.product-card__cta-secondary:focus-visible,
.product-card__ctas .added_to_cart.wc-forward:hover,
.product-card__ctas .added_to_cart.wc-forward:focus-visible {
  text-decoration: underline;
}
.product-card__cta-primary {
  display: flex;
  /* Ocupa el resto de la fila junto al selector de cantidad; con width:100%
     empujaba el selector a la línea de abajo. La base de 120px es lo que cabe
     al lado del selector compacto en una tarjeta de 265px. */
  flex: 1 1 120px;
  min-width: 0;
  justify-content: center;
}
.product-card__expand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) 0 0;
  border-top: 1px solid var(--color-border);
  border-left: none;
  border-right: none;
  border-bottom: none;
  background: none;
  width: 100%;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-brand-orange);
  text-align: left;
  min-height: 44px;
  transition: color .15s;
}
.product-card__expand:hover { color: var(--color-brand-red); }
.product-card__expand:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }
.product-card__expand-icon { transition: transform .2s; flex-shrink: 0; }
.product-card.is-expanded .product-card__expand-icon { transform: rotate(180deg); }

/* --- Spec Table inline — DESIGN.md §7.6 --- */
.spec-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--space-3);
  display: none;
}
.product-card.is-expanded .spec-table { display: table; }
.spec-table td {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  font-size: var(--text-small);
  line-height: 1.5;
  vertical-align: top;
}
.spec-table td:first-child {
  color: var(--color-steel);
  font-weight: 500;
  padding-right: var(--space-4);
  width: 48%;
}
.spec-table td:last-child { font-family: var(--font-mono); color: var(--color-ink); }
.spec-table tr:last-child td { border-bottom: none; }

/* --- PLP Pagination --- */
.plp-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-8);
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border);
}
.plp-page-btn {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  text-decoration: none;
  transition: background .15s, border-color .15s, color .15s;
  font-family: var(--font-mono);
}
.plp-page-btn:hover { border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
.plp-page-btn.is-active { background: var(--color-ink); color: var(--color-white); border-color: var(--color-ink); }
.plp-page-btn--arrow { color: var(--color-steel); }
.plp-page-btn--arrow:hover { color: var(--color-ink); background: var(--color-mist); border-color: var(--color-border); }
/* core/query-pagination-numbers pinta .page-numbers (y .current en la página
   activa), no las clases del mockup, así que .plp-page-btn* era CSS muerto y
   la paginación salía como texto suelto ("1 2 3 Siguiente"). Aquí se mapea a
   la misma estética, en naranja como pidió el cliente. */
.plp-pagination .page-numbers,
.plp-pagination .wp-block-query-pagination-previous,
.plp-pagination .wp-block-query-pagination-next {
  min-width: 40px;
  height: 40px;
  padding: 0 var(--space-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-family: var(--font-mono);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
  transition: background .15s, border-color .15s, color .15s;
}
.plp-pagination .page-numbers:hover,
.plp-pagination .wp-block-query-pagination-previous:hover,
.plp-pagination .wp-block-query-pagination-next:hover {
  border-color: var(--color-brand-orange);
  color: var(--color-brand-orange);
}
.plp-pagination .page-numbers.current {
  background: var(--color-brand-orange);
  border-color: var(--color-brand-orange);
  color: var(--color-white);
}
/* Los puntos suspensivos de paginate_links() no son un botón. */
.plp-pagination .page-numbers.dots {
  border-color: transparent;
  background: transparent;
  color: var(--color-steel);
}
.plp-pagination .page-numbers.dots:hover { color: var(--color-steel); }
/* Prev/next como píldora con la flecha por delante/detrás del texto. */
.plp-pagination .wp-block-query-pagination-previous,
.plp-pagination .wp-block-query-pagination-next {
  font-family: var(--font-body);
  padding: 0 var(--space-4);
}
.plp-pagination .wp-block-query-pagination-previous::before { content: "\2190"; }
.plp-pagination .wp-block-query-pagination-next::after { content: "\2192"; }
.plp-pagination .page-numbers:focus-visible,
.plp-pagination .wp-block-query-pagination-previous:focus-visible,
.plp-pagination .wp-block-query-pagination-next:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* --- Sticky Mobile Bar: PLP variant --- */
.sticky-mobile-bar--plp { justify-content: space-between; }
.sticky-mobile-bar__filter-btn {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: 48px;
  padding: 0 var(--space-4);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  transition: border-color .15s;
  flex-shrink: 0;
}
.sticky-mobile-bar__filter-btn:hover { border-color: var(--color-ink); }
.sticky-mobile-bar__filter-btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.filter-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  background: var(--color-brand-orange);
  color: var(--color-white);
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
}

/* ============================================================
 * V4 Ficha de producto (PDP) — Layout, Gallery, Info, Tabs, Manual
 * Añadido en iteración V4-ficha-mobile + V4-ficha-desktop
 * ============================================================ */

/* --- PDP main layout (2 col desktop) --- */
.pdp-layout {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-8) var(--container-padding-desktop);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: start;
}
/* En móvil el cliente pidió ver la imagen justo debajo del título (22-sep).
   El título y el bloque de información son hermanos dentro de la segunda
   columna, así que esa columna pasa a display:contents y sus hijos se ordenan
   como ítems del propio grid: título, galería, resto. */
@media (max-width: 1023.98px) {
  /* Los hijos de .pdp-layout son ítems de grid y heredan min-width:auto, que es
     el min-content de lo que llevan dentro. Sin esto, la galería imponía una
     columna de 344px en pantallas de 288-320px. Mismo motivo que el
     `.cart-layout > div { min-width: 0 }` del carrito. */
  .pdp-layout > *,
  .pdp-layout > * > * { min-width: 0; }
  .pdp-layout > :nth-child(2) { display: contents; }
  .pdp-layout .pdp-info-title { order: 1; margin-bottom: 0; }
  .pdp-layout > :first-child { order: 2; }
  .pdp-layout .pdp-info { order: 3; }
}
@media (min-width: 1024px) {
  /* Galería en la columna ancha de la izquierda e información en la de 420px,
     que es el orden del DOM. El 1-oct-2026 se invirtieron por petición del
     cliente y el 2-oct pidió volver atrás, así que aquí NO debe haber reglas
     de `order`: cualquier orden por .flex-column-product-N daría además
     resultados opuestos en local y en staging, porque la copia de
     single-product guardada en su BD lleva esas dos clases intercambiadas
     respecto al fichero del tema. */
  .pdp-layout { grid-template-columns: minmax(0, 1fr) 420px; gap: var(--space-12); }
}
@media (max-width: 767.98px) {
  .pdp-layout { padding: 0; }
}

/* --- Gallery --- */
.pdp-gallery__main {
  background: var(--color-mist);
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
}
@media (max-width: 1023px) {
  .pdp-gallery__main { border-radius: 0; }
}
.pdp-gallery__main img {
  max-width: 72%;
  max-height: 72%;
  object-fit: contain;
  position: relative;
  z-index: 1;
}
.pdp-gallery__main { cursor: zoom-in; }
/* El deslizamiento lateral para cambiar de foto lo lleva view.js (15-oct-2026);
   pan-y deja al navegador solo el scroll vertical, así el gesto horizontal no
   arrastra la página y llega entero al script. */
.pdp-gallery__main, .pdp-gallery__lightbox-img { touch-action: pan-y; }
.pdp-gallery__main:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.pdp-gallery__zoom-hint {
  position: absolute;
  bottom: var(--space-3);
  right: var(--space-3);
  font-size: var(--text-caption);
  color: var(--color-steel);
  background: rgba(255,255,255,0.85);
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  gap: var(--space-1);
  pointer-events: none;
}
.pdp-gallery__thumbs {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
  overflow-x: auto;
  /* overflow-x:auto pone también overflow-y en auto: se cierra para que la tira
     solo se mueva en horizontal (mismo caso que .pdp-tab-nav). */
  overflow-y: hidden;
  scrollbar-width: none;
  padding: var(--space-1) var(--container-padding-desktop);
  /* El `overflow-x: auto` por sí solo no basta: como ítem de un contenedor flex
     o grid, esta fila conserva el `min-width: auto` por defecto, que se calcula
     como la suma de las cuatro miniaturas (344px). Por debajo de ~360px eso
     ensanchaba la columna de la ficha y la página desbordaba a lo ancho. Con
     min-width:0 la fila puede encoger y el scroll horizontal hace su trabajo. */
  min-width: 0;
}
.pdp-gallery__thumbs::-webkit-scrollbar { display: none; }
@media (max-width: 767.98px) {
  .pdp-gallery__thumbs { padding: var(--space-1) var(--container-padding-mobile); }
}
.pdp-gallery__thumb {
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  border-radius: var(--radius-md);
  border: 2px solid var(--color-border);
  background: var(--color-mist);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: border-color .15s;
  padding: 0;
}
.pdp-gallery__thumb.is-active { border-color: var(--color-brand-orange); }
.pdp-gallery__thumb:hover:not(.is-active) { border-color: var(--color-border-strong); }
.pdp-gallery__thumb:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.pdp-gallery__thumb img { width: 100%; height: 100%; object-fit: contain; }
.pdp-gallery__thumb span {
  font-size: 10px;
  color: var(--color-steel);
  text-align: center;
  padding: var(--space-1);
  line-height: 1.2;
}

/* --- Gallery lightbox --- */
.pdp-gallery__lightbox {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: none;
  align-items: center;
  justify-content: center;
}
.pdp-gallery__lightbox.is-open { display: flex; }
.has-lightbox-open { overflow: hidden; }
.pdp-gallery__lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: var(--overlay-ink-strong);
}
.pdp-gallery__lightbox-dialog {
  position: relative;
  z-index: 1;
  max-width: min(90vw, 1100px);
  max-height: 90vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pdp-gallery__lightbox-img {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: var(--radius-md);
  background: var(--color-white, #fff);
}
.pdp-gallery__lightbox-close,
.pdp-gallery__lightbox-nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  border: none;
  background: rgba(255,255,255,0.92);
  color: var(--color-ink);
  cursor: pointer;
  box-shadow: var(--shadow-lg);
}
.pdp-gallery__lightbox-close:hover,
.pdp-gallery__lightbox-nav:hover { background: #fff; }
.pdp-gallery__lightbox-close:focus-visible,
.pdp-gallery__lightbox-nav:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.pdp-gallery__lightbox-close {
  top: var(--space-4);
  right: var(--space-4);
  z-index: 2;
}
.pdp-gallery__lightbox-nav--prev { left: var(--space-4); }
.pdp-gallery__lightbox-nav--next { right: var(--space-4); }
@media (max-width: 767.98px) {
  .pdp-gallery__lightbox-close { top: var(--space-2); right: var(--space-2); }
  .pdp-gallery__lightbox-nav--prev { left: var(--space-2); }
  .pdp-gallery__lightbox-nav--next { right: var(--space-2); }
}

/* --- Info column --- */
.pdp-info {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
@media (min-width: 1024px) {
  .pdp-info { position: sticky; top: var(--header-sticky-offset); }
}
@media (max-width: 1023px) {
  .pdp-info { padding: var(--space-6) var(--container-padding-mobile); }
}

/* --- H1 de la ficha (core/post-title con className, ver single-product.html) --- */
.pdp-info-title {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
@media (max-width: 767.98px) {
  .pdp-info-title { font-size: var(--text-h3); line-height: 1.2; letter-spacing: normal; }
}

/* --- Product chips (PDP) --- */
.pdp-chips {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
}

/* --- Selector de variaciones en botones --- */
/* El <select> nativo se queda en el DOM (lo necesita
   add-to-cart-variation.js) pero fuera de la vista; los botones que pinta
   assets/js/variation-swatches.js escriben en él. */
.variation-swatches { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.variation-swatches__item {
  min-width: 64px;
  min-height: 44px;
  padding: 0 var(--space-3);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-family: var(--font-mono);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.variation-swatches__item:hover:not( :disabled ) { border-color: var(--color-brand-orange); color: var(--color-brand-orange); }
.variation-swatches__item.is-selected {
  border-color: var(--color-brand-orange);
  background: var(--color-brand-orange);
  color: var(--color-white);
}
.variation-swatches__item:disabled { opacity: 0.4; cursor: not-allowed; }
.variation-swatches__item:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
/* El select se oculta sin display:none: así sigue siendo un control real para
   el JS de WooCommerce y para quien navegue con teclado desde el label. */
.variation-swatches__select {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
/* Tabla de variaciones de WooCommerce: se quita la maqueta de tabla para que
   cada fila sea etiqueta + botones, en columna. */
.variations_form .variations,
.variations_form .variations tbody,
.variations_form .variations tr,
.variations_form .variations th,
.variations_form .variations td {
  display: block;
  width: auto;
  padding: 0;
  border: none;
  text-align: left;
}
.variations_form .variations tr + tr { margin-top: var(--space-4); }
.variations_form .variations label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
}
.variations_form .reset_variations {
  display: inline-block;
  margin-top: var(--space-2);
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-steel);
}
.variations_form .single_variation_wrap { margin-top: var(--space-4); }
.variations_form .woocommerce-variation-price { margin-bottom: var(--space-3); }


/* --- Campos propios de la ficha (nº de serie, carátula) --- */
/* Los pide la revisión del cliente: nº de serie obligatorio en transmisores y
   carátula numérica/personalizada con archivo en vehículos industriales. */
.pdp-addon {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: var(--space-4);
  background: var(--color-mist);
  border-radius: var(--radius-md);
}
.pdp-addon__label {
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
}
.pdp-addon__label--sub { font-weight: 600; }
/* Ancla del enlace "Configurar y añadir" de la barra fija móvil: el offset
   evita que el header sticky tape los campos al saltar. */
.pdp-addon__anchor { display: block; scroll-margin-top: calc(var(--header-sticky-offset) + var(--space-4)); }
.pdp-addon__required {
  color: var(--color-danger-text);
  text-decoration: none;
  border: none;
  margin-left: 2px;
}
.pdp-addon__input { width: 100%; font-family: var(--font-mono); letter-spacing: 0.08em; }
.pdp-addon__help {
  margin: 0;
  font-size: var(--text-caption);
  color: var(--color-steel);
  line-height: 1.5;
}
.pdp-addon__choices { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.pdp-addon__choice {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  min-height: 44px;
}
.pdp-addon__choice:has( input:checked ) { border-color: var(--color-brand-orange); }
.pdp-addon__choice input { accent-color: var(--color-brand-orange); }
.pdp-addon__custom {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.pdp-addon__custom[hidden] { display: none; }
.pdp-addon__file { font-size: var(--text-small); }
.pdp-addon__examples-title {
  margin: var(--space-2) 0 var(--space-2);
  font-size: var(--text-caption);
  font-weight: 700;
  color: var(--color-ink);
}
.pdp-addon__examples-grid { display: flex; flex-wrap: wrap; gap: var(--space-2); }
/* Sin recortar: `contain` y caja algo mayor, para que se vea el mando entero y
   no un trozo (petición del cliente, 6-oct-2026). */
.pdp-addon__example {
  width: 88px;
  height: 88px;
  padding: 4px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-white);
  cursor: zoom-in;
  display: block;
  transition: border-color .15s, box-shadow .15s;
}
.pdp-addon__example:hover { border-color: var(--color-brand-orange); }
.pdp-addon__example:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.pdp-addon__examples-grid img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* Visor de los ejemplos. Mismo <dialog> nativo que .tlx-confirm: el navegador
   ya resuelve Escape, el foco y el ::backdrop. */
.tlx-zoom {
  border: none;
  padding: 0;
  background: transparent;
  max-width: min(92vw, 900px);
  max-height: 92vh;
}
.tlx-zoom::backdrop { background: var(--overlay-ink-soft, rgba(15, 25, 35, 0.72)); }
.tlx-zoom img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 88vh;
  object-fit: contain;
  border-radius: var(--radius-md);
  background: var(--color-white);
}
.tlx-zoom__close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 999px;
  background: var(--color-white);
  color: var(--color-ink);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.tlx-zoom__close:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* --- Price block --- */
.pdp-price-block { display: flex; flex-direction: column; gap: var(--space-1); }
.pdp-price-block__main {
  font-family: var(--font-mono);
  font-size: var(--text-h2);
  font-weight: 700;
  color: var(--color-ink);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 767.98px) {
  .pdp-price-block__main { font-size: var(--text-h3); }
}
/* Mismo motivo que .product-card__price-iva. */
.pdp-price-block__iva { font-size: var(--text-small); font-weight: 600; color: var(--color-ink); }
.pdp-price-block__shipping {
  margin-top: var(--space-2);
  font-size: var(--text-small);
  font-weight: 600;
  /* --color-success es un verde de relleno: como texto de 14px sobre blanco se
     queda en 3,29:1. Para texto está --color-success-text (6,15:1). */
  color: var(--color-success-text);
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.pdp-price-block__main del {
  font-size: var(--text-h3);
}

/* --- CTA block --- */
.pdp-ctas { display: flex; flex-direction: column; gap: var(--space-2); }
/* Destino del enlace "Elegir opciones" de la barra fija (producto variable). */
#tlx-pdp-ctas { scroll-margin-top: calc(var(--header-sticky-offset) + var(--space-4)); }

/* Formulario nativo de WooCommerce (single add-to-cart), usado dentro de
   .pdp-ctas y de .sticky-mobile-bar--pdp: la plantilla nativa de WooCommerce
   para el add-to-cart de producto simple no admite pasar clases propias como
   argumento (a diferencia de woocommerce_template_loop_add_to_cart(), que sí
   acepta {"class": "..."}), así que aquí se revisten sus clases nativas para
   que visualmente sea igual que .btn.btn--primary.btn--lg. */
.pdp-ctas .cart,
.sticky-mobile-bar--pdp .cart {
  display: flex;
  align-items: stretch;
  gap: var(--space-2);
  width: 100%;
}
/* Los campos propios (nº de serie, carátula) los inyecta
   woocommerce_before_add_to_cart_button, o sea DENTRO de esta fila flex: sin
   esto quedaban en la misma línea que la cantidad y el botón y el ancho mínimo
   del input desbordaba la ficha en móvil (413px sobre un viewport de 390). */
.pdp-ctas .cart { flex-wrap: wrap; }
.pdp-ctas .cart .pdp-addon { flex: 1 0 100%; min-width: 0; }
.pdp-ctas .cart .pdp-addon__anchor { flex: 1 0 100%; height: 0; }

/* En un producto VARIABLE el botón no cuelga de form.cart: WooCommerce lo
   envuelve en .single_variation_wrap > .woocommerce-variation-add-to-cart, y los
   campos propios caen dentro de esa capa. Ese contenedor es flex SIN wrap, así
   que el `flex: 1 0 100%` de arriba no bajaba de línea: empujaba a los hermanos
   y el panel de carátula se salía de la columna (499px dentro de 420). El
   cliente lo fotografió el 6-oct-2026: "al añadir los atributos se descoloca el
   carrito". Aquí se le da a esa capa el mismo comportamiento que al form. */
.pdp-ctas .cart .single_variation_wrap { flex: 1 0 100%; min-width: 0; }
.pdp-ctas .cart .woocommerce-variation-add-to-cart {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: var(--space-2);
  min-width: 0;
}
.pdp-ctas .cart .woocommerce-variation-add-to-cart > * { min-width: 0; }
.pdp-ctas .cart .quantity,
.sticky-mobile-bar--pdp .cart .quantity { display: flex; flex-shrink: 0; }
.pdp-ctas .cart .qty,
.sticky-mobile-bar--pdp .cart .qty {
  width: 64px;
  height: 56px;
  padding: 0 var(--space-2);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--text-body);
  text-align: center;
}
.sticky-mobile-bar--pdp .cart .quantity { display: none; }
.pdp-ctas .cart .single_add_to_cart_button,
.sticky-mobile-bar--pdp .cart .single_add_to_cart_button {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 56px;
  padding: 0 24px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-body-lg);
  background: var(--color-brand-orange);
  color: var(--color-white);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background .15s;
}
.pdp-ctas .cart .single_add_to_cart_button:hover,
.sticky-mobile-bar--pdp .cart .single_add_to_cart_button:hover { background: var(--color-brand-red); }
/* La regla de arriba fija white-space:nowrap con especificidad (0,3,0), y el
   bloque responsive que deja partir los botones (`.pdp-ctas .btn`,
   `.pdp-ctas .single_add_to_cart_button`) es (0,2,0) y además va ANTES en el
   fichero, así que perdía por partida doble. A 288px —el ancho útil del
   navegador dentro de app que usa el cliente— "Añadir al carrito" pedía 195px
   en una caja de 164 y se cortaba. Detectado por el QA el 8-oct-2026. Esta
   excepción tiene que quedarse DESPUÉS de la regla base. */
@media (max-width: 767.98px) {
  .pdp-ctas .cart .single_add_to_cart_button {
    white-space: normal;
    min-width: 0;
    height: auto;
    min-height: 56px;
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
    line-height: 1.2;
  }
}
.pdp-ctas .cart .stock,
.sticky-mobile-bar--pdp .cart .stock { display: none; }

/* --- Compatibility block --- */
.pdp-compat {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  background: var(--color-mist);
}
.pdp-compat__title {
  font-size: var(--text-caption);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-ink);
  margin: 0 0 var(--space-2);
}
.pdp-compat__brands {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: var(--space-2);
}
.pdp-compat__ref-hint {
  font-size: var(--text-small);
  color: var(--color-steel);
  line-height: 1.5;
  margin: 0 0 var(--space-3);
}
.pdp-compat__cta {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-brand-orange);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.pdp-compat__cta:hover { color: var(--color-brand-red); }
.pdp-compat__cta:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }
@media (min-width: 1024px) {
  .pdp-layout .pdp-info .pdp-compat { padding: var(--space-3) var(--space-4); }
}

/* --- Certification badges row --- */
.pdp-cert-row {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.pdp-cert-badge {
  flex: 1;
  min-width: 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  text-align: center;
  padding: var(--space-3) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-size: var(--text-caption);
  font-weight: 700;
  color: var(--color-ink);
  line-height: 1.2;
}
.pdp-cert-badge svg { color: var(--color-brand-orange); }

/* --- Tabs section (PDP) --- */
.pdp-tabs-section {
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-8);
  background: var(--color-white);
}
@media (max-width: 767.98px) {
  .pdp-tabs-section { margin-top: 0; border-top: 4px solid var(--color-mist); }
}
.pdp-tab-nav {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-padding-desktop);
  display: flex;
  /* La línea gris de abajo va como sombra interior y no como border-bottom.
     Con el borde, cada botón llevaba margin-bottom:-1px para pisarlo con su
     subrayado: el contenido medía 52px en una caja de 51, y como
     overflow-x:auto convierte también overflow-y en auto, la fila tenía 1px de
     scroll vertical. En el móvil del cliente eso hacía que las pestañas "se
     movieran hacia todos los lados" (15-oct-2026). Ahora no sobra nada en
     vertical, overflow-y queda cerrado y el gesto solo desplaza en horizontal. */
  box-shadow: inset 0 -1px 0 var(--color-border);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.pdp-tab-nav::-webkit-scrollbar { display: none; }
@media (max-width: 767.98px) {
  .pdp-tab-nav { padding: 0 var(--container-padding-mobile); }
}
.pdp-tab-btn {
  flex-shrink: 0;
  height: 52px;
  padding: 0 var(--space-6);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-steel);
  cursor: pointer;
  white-space: nowrap;
  transition: color .15s, border-color .15s;
}
@media (max-width: 767.98px) {
  .pdp-tab-btn { padding: 0 var(--space-4); }
}
.pdp-tab-btn:hover { color: var(--color-ink); }
.pdp-tab-btn.is-active { color: var(--color-brand-orange); border-color: var(--color-brand-orange); }
/* Anillo de foco hacia dentro: la fila recorta en vertical (overflow-y:hidden)
   y el --shadow-focus de siempre, que sale 3px hacia fuera, quedaría cortado. */
.pdp-tab-btn:focus-visible { outline: none; box-shadow: inset 0 0 0 3px rgba(254, 80, 0, 0.25); }
.pdp-tab-panel { padding: var(--space-12) 0; }
@media (max-width: 767.98px) {
  .pdp-tab-panel { padding: var(--space-8) 0; }
}
.pdp-tab-panel[hidden] { display: none; }

/* --- Standalone spec table (PDP) --- */
.pdp-spec-table {
  width: 100%;
  border-collapse: collapse;
}
.pdp-spec-table tr { border-bottom: 1px solid var(--color-border); }
.pdp-spec-table tr:last-child { border-bottom: none; }
.pdp-spec-table th {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-steel);
  text-align: left;
  padding: var(--space-3) var(--space-6) var(--space-3) 0;
  width: 40%;
  vertical-align: top;
}
.pdp-spec-table td {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--color-ink);
  padding: var(--space-3) 0;
  vertical-align: top;
  line-height: 1.5;
}
.pdp-spec-table .spec-highlight td {
  font-weight: 700;
  color: var(--color-ink);
}
/* Los valores de certificación iban en naranja de marca, que sobre blanco a
   14 px se queda en 3,3:1. El énfasis lo da el peso, no el color. */
.pdp-spec-table .spec-cert td {
  font-weight: 700;
  color: var(--color-ink);
}

/* --- Manual download card --- */
.pdp-manual-card {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-mist);
  max-width: 580px;
  text-decoration: none;
  color: inherit;
  transition: box-shadow .15s, transform .15s;
}
.pdp-manual-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.pdp-manual-card:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.pdp-manual-card__icon {
  flex-shrink: 0;
  width: 56px;
  height: 56px;
  background: var(--color-brand-orange);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-white);
}
.pdp-manual-card__info { flex: 1; min-width: 0; }
.pdp-manual-card__name {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-1);
}
.pdp-manual-card__meta { font-size: var(--text-caption); color: var(--color-steel); }
.pdp-manual-card__arrow { flex-shrink: 0; color: var(--color-brand-orange); }

/* --- Soporte técnico block --- */
.pdp-support-block {
  background: var(--color-brand-peach);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
@media (min-width: 768px) {
  .pdp-support-block {
    display: flex;
    align-items: center;
    gap: var(--space-8);
  }
}
.pdp-support-block__text { flex: 1; margin-bottom: var(--space-4); }
@media (min-width: 768px) { .pdp-support-block__text { margin-bottom: 0; } }
.pdp-support-block__title {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-2);
}
.pdp-support-block__sub {
  font-size: var(--text-small);
  color: var(--color-steel);
  line-height: 1.5;
  margin: 0;
}
.pdp-support-block__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* --- Tabs: layouts de grid por pestaña (Descripción / Especificaciones) --- */
.tab-desc-grid,
.tab-specs-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: start;
}
/* Un accesorio sin certificaciones deja una sola tabla: que ocupe el ancho en vez
   de quedarse a media columna con el hueco al lado. */
.tab-specs-grid > div:only-child { grid-column: 1 / -1; }
@media (min-width: 1024px) {
  .tab-desc-grid { grid-template-columns: 1fr 340px; gap: var(--space-16); }
  .tab-specs-grid { grid-template-columns: 1fr 1fr; gap: var(--space-12); }
}
.tab-manual-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 1024px) {
  .tab-manual-grid { grid-template-columns: 1fr 1fr; }
}

/* --- Descripción: trust card lateral --- */
.desc-trust-card {
  background: var(--color-mist);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  border: 1px solid var(--color-border);
}
@media (min-width: 1024px) {
  .desc-trust-card { position: sticky; top: var(--header-sticky-offset); }
}
.desc-trust-card__title {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: 700;
  margin: 0 0 var(--space-4);
}
.desc-trust-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.desc-trust-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--text-small);
  line-height: 1.5;
  color: var(--color-steel);
}
.desc-trust-list li svg { color: var(--color-brand-orange); flex-shrink: 0; margin-top: 2px; }
/* Pie de la tarjeta: antes iba con style="" inline en el render.php del bloque. */
.desc-trust-card__footer {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.desc-trust-card__cta { width: 100%; }

/* --- Especificaciones: visor PDF embebido (sin archivo real todavía) --- */
.pdp-spec-pdf {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-white);
}
.pdp-spec-pdf__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-mist);
  border-bottom: 1px solid var(--color-border);
}
.pdp-spec-pdf__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
}
.pdp-spec-pdf__title svg { color: var(--color-brand-orange); }
.pdp-spec-pdf__open {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-small);
  font-weight: 600;
  white-space: nowrap;
}
/* Con archivo real la tarjeta es solo la barra con el enlace: no hay visor que
   rellenar, así que se le quita el borde inferior que separaba del fallback. */
.pdp-spec-pdf--available { margin-top: var(--space-10); }
.pdp-spec-pdf--available .pdp-spec-pdf__bar { border-bottom: none; }
.pdp-spec-pdf__open {
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.pdp-spec-pdf__open:hover { text-decoration-thickness: 2px; }

/* Cabecera y nota de la pestaña: antes iban con style="" inline en el render. */
.pdp-specs__heading {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-8);
}
.pdp-specs__note {
  margin-top: var(--space-8);
  font-size: var(--text-small);
  line-height: 1.5;
  color: var(--color-steel);
}
.pdp-specs__note a {
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.pdp-specs__note a:hover { text-decoration-thickness: 2px; }

/* --- Documentación (tab Manual): item destacado + cards de descarga --- */
.pdp-docs { display: flex; flex-direction: column; gap: var(--space-8); }
/* Cabecera y pie de la pestaña Documentación: antes iban con style="" inline en
   el render.php del bloque. */
.pdp-docs__heading {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-4);
}
.pdp-docs__intro {
  font-size: var(--text-body);
  line-height: 1.6;
  color: var(--color-steel);
  margin: 0 0 var(--space-8);
  max-width: 640px;
}
.pdp-docs__contact {
  margin-top: var(--space-8);
  font-size: var(--text-small);
  line-height: 1.5;
  color: var(--color-steel);
}
/* Ink + subrayado y no naranja de marca: son 14px sobre blanco, y #FE5000 solo
   llega a 3,3:1 ahí. Mismo criterio que los enlaces de Mi cuenta. */
.pdp-docs__contact a {
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.pdp-docs__contact a:hover { text-decoration-thickness: 2px; }
.pdp-doc-item--featured {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-white);
  max-width: 720px;
}
.pdp-doc-item__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-mist);
  border-bottom: 1px solid var(--color-border);
}
.pdp-doc-item__name {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
}
.pdp-doc-item__name svg { color: var(--color-brand-orange); }
.pdp-doc-item__open {
  font-size: var(--text-small);
  font-weight: 600;
  white-space: nowrap;
}
.pdp-doc-item__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 200px;
  padding: var(--space-8);
  text-align: center;
  color: var(--color-steel);
  font-size: var(--text-small);
}
.pdp-doc-item__body svg { color: var(--color-border-strong); }
.pdp-doc-item__meta {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-caption);
  color: var(--color-steel);
  border-top: 1px solid var(--color-border);
}

/* --- Puede interesarte: rejilla compacta tipo catálogo --- */
.product-grid--compact {
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}
@media (min-width: 640px) {
  .product-grid--compact { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1200px) {
  .product-grid--compact { grid-template-columns: repeat(4, 1fr); }
}
/* Las reglas de arriba, de una sola clase, no llegan a aplicarse nunca: la
   rejilla de la PLP (línea ~1531) usa
   .product-grid.wc-block-product-template__responsive.columns-3 para ganarle a
   WooCommerce, y ese selector es (0,3,0) y también casa con esta rejilla, así
   que la dejaba en 2 columnas a cualquier ancho. Hay que repetir el patrón de
   tres clases para superarlo. Son 3 productos (perPage: 3), así que 3 columnas
   en escritorio, no 4. */
.product-grid--compact.wc-block-product-template__responsive.columns-3 {
  /* Una sola columna en móvil (6-oct-2026). A dos columnas, en un teléfono de
     390px cada tarjeta se quedaba en ~155px y se cortaban el botón "Añadir al
     carrito" y la tabla de la ficha técnica: el cliente lo mandó en tres
     capturas. */
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 560px) {
  .product-grid--compact.wc-block-product-template__responsive.columns-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 900px) {
  .product-grid--compact.wc-block-product-template__responsive.columns-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.product-grid--compact .product-card__media { padding: var(--space-4); }
.product-grid--compact .product-card__body { padding: var(--space-3) var(--space-4) var(--space-4); }
.product-grid--compact .product-card__name { font-size: var(--text-small); line-height: 1.25; margin-bottom: var(--space-2); }
.product-grid--compact .product-card__chips { gap: 4px; margin-bottom: var(--space-2); }
.product-grid--compact .product-card__price { font-size: var(--text-body-lg); }
.product-grid--compact .product-card__price-iva { margin: 2px 0 var(--space-3); }

/* --- Sticky bar PDP variant — DESIGN.md §7.10 --- */
.sticky-mobile-bar--pdp { justify-content: space-between; gap: var(--space-3); }
/* El bloque de precio era flex:0 0 auto (nunca encoge) y el form.cart de al
   lado tiene el min-width:auto por defecto de todo ítem flex (tampoco encoge).
   En un producto rebajado el precio ocupa "50,00 € 15,00 €", y a 360px los dos
   sumaban 383px dentro de los 328px útiles de la barra: el botón "Añadir al
   carrito" se salía de pantalla. Ahora el precio puede encoger y partir en dos
   líneas, y el formulario es el que absorbe el espacio restante. */
.sticky-mobile-bar--pdp .sticky-mobile-bar__price-block { flex: 0 1 auto; min-width: 0; }
.sticky-mobile-bar--pdp .cart { flex: 1 1 auto; min-width: 0; }
.sticky-mobile-bar--pdp .cart .single_add_to_cart_button { min-width: 0; white-space: normal; }
.sticky-mobile-bar__price-block { display: flex; flex-direction: column; }
.sticky-mobile-bar__price-main { display: flex; flex-wrap: wrap; gap: 0 var(--space-2); }
.sticky-mobile-bar__price-main {
  font-family: var(--font-mono);
  font-size: var(--text-h4);
  font-weight: 700;
  color: var(--color-ink);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.sticky-mobile-bar__price-iva { font-size: var(--text-caption); color: var(--color-steel); }

/* ============================================================
 * V5 Carrito — CartLayout, CartItem, CartSummary, CartRelated
 * Añadido en iteración V5-carrito-mobile + V5-carrito-desktop
 * ============================================================ */

/* --- Cart page layout (items + summary) --- */
.cart-layout {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-padding-desktop) var(--space-8) var(--container-padding-desktop);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: start;
}
/* Los dos hijos directos (columna izquierda/derecha) son un grid item cada uno:
   sin min-width:0 heredan el min-width:auto por defecto, que se calcula como el
   max-content de TODO lo que haya dentro — incluido .cart-related__scroll, un
   carrusel de tarjetas con flex-shrink:0 que nunca encoge. Sin esto, esas
   tarjetas reventaban la columna de 1fr y el carrito salía con scroll
   horizontal en móvil. Mismo "grid blowout" que documenta .cart-item. */
.cart-layout > div { min-width: 0; }
@media (min-width: 1199px) {
  .cart-layout { grid-template-columns: 1fr minmax(0, 380px); gap: var(--space-12); }
}
@media (max-width: 767.98px) {
  .cart-layout { padding: var(--space-6) var(--container-padding-mobile); }
}

/* --- WooCommerce native notices (cart page) --- */
.woocommerce-notices-wrapper:empty {
  display: none;
}
.woocommerce-notices-wrapper {
  max-width: var(--container-max);
  margin: 0 auto var(--space-6);
  padding: var(--space-4) var(--container-padding-desktop) 0;
}
@media (max-width: 767.98px) {
  .woocommerce-notices-wrapper { padding: var(--space-4) var(--container-padding-mobile) 0; }
}
/* Fuera de .container (ficha de producto, archivos) el bloque de avisos es hijo
   directo de <main>. Core le pone `alignwide`, que le da max-width pero NO
   márgenes automáticos, así que la caja se quedaba pegada al borde izquierdo y
   el aviso salía 80px desplazado respecto a las columnas del producto. Se le da
   aquí la misma geometría que a .container y se anula el max-width/padding del
   envoltorio de dentro para no sumarlos dos veces. */
.wp-block-woocommerce-store-notices {
  max-width: var(--container-max);
  margin-inline: auto;
  padding: 0 var(--container-padding-desktop);
}
.wp-block-woocommerce-store-notices .woocommerce-notices-wrapper {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}
@media (max-width: 767.98px) {
  .wp-block-woocommerce-store-notices { padding: 0 var(--container-padding-mobile); }
}
/* En page-cart.html el bloque ya va DENTRO de .container, así que ahí no debe
   repetir ni el max-width ni el padding: se sumaban a los del contenedor y el
   aviso salía 160px más estrecho que la franja de envío de debajo. */
.container > .woocommerce-notices-wrapper,
.container > .wp-block-woocommerce-store-notices,
.container > .wp-block-woocommerce-store-notices .woocommerce-notices-wrapper {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.wc-block-components-notice-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin: var(--space-6) 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-small);
  font-weight: 600;
  line-height: 1.5;
}
/* .wc-block-components-notice-banner:last-child { margin-bottom: 0; } */
.wc-block-components-notice-banner svg { flex-shrink: 0; width: 20px; height: 20px; fill: currentColor; }

.wc-block-components-notice-banner.is-success { background: var(--color-success-soft); color: var(--color-success); }
.wc-block-components-notice-banner.is-error { background: var(--color-danger-soft); color: var(--color-danger); }
.wc-block-components-notice-banner.is-info { background: var(--color-mist); color: var(--color-steel); }

.wc-block-components-notice-banner.is-success>svg {
  color: white;
}
/* wc-blocks enfoca el aviso por JS para que lo anuncien los lectores de
   pantalla, y Chrome le pinta encima su anillo azul por defecto: el cliente lo
   reportó como "cuadro verde" mal el 2-oct-2026. Es un contenedor no
   interactivo, así que el anillo no aporta nada y se quita; el foco sigue
   llegando igual a la tecnología de apoyo. */
.wc-block-components-notice-banner:focus,
.wc-block-components-notice-banner:focus-visible,
.woocommerce-message:focus,
.woocommerce-message:focus-visible,
.woocommerce-notices-wrapper [tabindex="-1"]:focus,
.woocommerce-notices-wrapper [tabindex="-1"]:focus-visible {
  outline: none;
  box-shadow: none;
}

.wc-block-components-notice-banner__content a {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
}

/* --- Cart heading area --- */
.cart-heading {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.cart-heading h1 { font-size: var(--text-h2); margin: 0; }
.cart-heading__count {
  font-size: var(--text-body);
  color: var(--color-steel);
  font-weight: 400;
}

/* --- Cart items list --- */
.cart-items {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

/* --- Column headers (desktop) — ver V5-carrito-desktop.html, bloque
   "Table header": misma grid-template-columns que .cart-item a 1024px para
   que las etiquetas queden alineadas con sus valores. --- */
.cart-table-head { display: none; }
@media (min-width: 1024px) {
  .cart-table-head {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr) 80px 136px 96px 32px;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-5);
    border: 1px solid var(--color-border);
    border-bottom: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    background: var(--color-mist);
    font-size: var(--text-caption);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-steel);
  }
  /* La cabecera pega directamente encima de .cart-items (sin separación) —
     sin esto, sus esquinas redondeadas se ven duplicadas contra las de la
     cabecera justo encima. */
  .cart-table-head + .cart-items { border-top-left-radius: 0; border-top-right-radius: 0; }
}
.cart-th { display: flex; align-items: center; }
.cart-th--center { justify-content: center; }
.cart-th--right { justify-content: flex-end; }
.cart-th--product { grid-column: 1 / span 2; padding-left: var(--space-2); }

/* --- Single cart item row --- */
.cart-item {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border);
  align-items: start;
}
.cart-item:last-child { border-bottom: none; }
@media (min-width: 768px) {
  .cart-item {
    /* minmax(0, 1fr), no 1fr a secas: sin el 0 explícito, el ancho mínimo
       automático de esta columna se calcula como el max-content de TODOS
       los hijos que caen en ella en cualquier fila — incluido
       .cart-item__mobile-row (grid-column:1/-1, con el subtotal en
       white-space:nowrap). Ese nowrap "inflaba" la columna del nombre/chips
       hasta casi 0 en viewports estrechos ("grid blowout"): el nombre
       envolvía palabra por palabra en vez de recibir su ancho real. */
    grid-template-columns: 100px minmax(0, 1fr) auto auto auto auto;
    align-items: center;
    padding: var(--space-6);
  }
  .cart-item__media { width: 100px; height: 100px; }
}
@media (min-width: 1024px) {
  /* Columnas fijas (thumb / info / precio unit. / cantidad / subtotal /
     eliminar) en vez de "auto" — mismo ancho que .cart-table-head arriba
     para que cada valor quede bajo su etiqueta. */
  .cart-item { grid-template-columns: 72px minmax(0, 1fr) 80px 136px 96px 32px; }
  .cart-item__media { width: 72px; height: 72px; }
  .cart-item__name { font-size: var(--text-small); line-height: 1.3; margin-bottom: var(--space-2); }
  .cart-item__chips { gap: 4px; margin-bottom: var(--space-2); }
  .cart-item__chips .chip { font-size: 10px; padding: 2px 6px; }
  .cart-item__price { text-align: center; }
  .cart-item__subtotal { justify-content: flex-end; width: 100%; }
  /* .qty-selector no tiene ancho propio (crece al contenido: 40+48+40 =
     128px) — sin centrarlo, quedaba pegado al borde izquierdo de su celda
     de 136px en vez de bajo la etiqueta "Cantidad". */
  .cart-item__mobile-row .qty-selector { justify-self: center; }
  /* El item de grid real es .product-remove (el <span> que envuelve el
     <a>, ver cart.php) — .cart-item__remove va dentro y no es en sí mismo
     hijo directo del grid, así que justify-self en él no haría nada. */
  .cart-item__mobile-row .product-remove { justify-self: end; }
}

/* Thumbnail */
.cart-item__media {
  max-width: 88px;
  aspect-ratio: 1;
  background: var(--color-mist);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}
@media (min-width: 768px) {
  .cart-item__media { padding: 5px; }
}
.cart-item__media img { max-width: 100%; max-height: 100%; object-fit: contain; }
.cart-item__media-placeholder {
  font-size: 10px;
  color: var(--color-steel);
  text-align: center;
  line-height: 1.3;
  padding: var(--space-2);
}

/* Info column */
.cart-item__info { flex: 1; min-width: 0; }
.cart-item__name {
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-2);
  line-height: 1.3;
  text-decoration: none;
}
.cart-item__name:hover { color: var(--color-brand-orange); }
.cart-item__chips {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
.cart-item__mobile-row {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
@media (min-width: 768px) { .cart-item__mobile-row { display: contents; } }

/* Quantity selector */
.qty-selector {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  height: 40px;
  flex-shrink: 0;
}
.qty-selector__btn {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-mist);
  border: none;
  cursor: pointer;
  font-size: 18px;
  font-weight: 700;
  color: var(--color-ink);
  line-height: 1;
  transition: background .15s;
  flex-shrink: 0;
}
.qty-selector__btn:hover { background: var(--color-border); }
.qty-selector__btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.qty-selector__input {
  width: 48px;
  height: 40px;
  border: none;
  border-left: 1px solid var(--color-border);
  border-right: 1px solid var(--color-border);
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-body);
  font-weight: 700;
  color: var(--color-ink);
  background: var(--color-white);
  outline: none;
  -moz-appearance: textfield;
}
.qty-selector__input::-webkit-outer-spin-button,
.qty-selector__input::-webkit-inner-spin-button { -webkit-appearance: none; }
.qty-selector__input:focus { border-color: var(--color-brand-orange); }

/* Unit price + subtotal */
.cart-item__price {
  font-size: var(--text-small);
  color: var(--color-steel);
  white-space: nowrap;
  font-family: var(--font-mono);
}
@media (max-width: 767.98px) { .cart-item__price { display: none; } }

.cart-item__subtotal {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  flex-wrap: wrap;
  justify-content: flex-end;
}
.cart-item__subtotal .woocommerce-Price-amount {
  font-family: var(--font-mono);
  font-size: var(--text-body);
  font-weight: 700;
  color: var(--color-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Nota "(incl. impuestos)" que añade wc_price() — sin esto heredaba el
   mismo peso/tamaño del importe y, en nowrap, era uno de los disparadores
   del "grid blowout" de arriba. */
.cart-item__subtotal small,
.cart-item__subtotal .tax_label {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 400;
  color: var(--color-steel);
  white-space: nowrap;
}

/* Remove button */
.cart-item__remove {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-steel);
  border-radius: var(--radius-sm);
  transition: color .15s, background .15s;
  flex-shrink: 0;
}
.cart-item__remove:hover { color: var(--color-danger); background: var(--color-danger-soft); }
.cart-item__remove:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* --- Acciones bajo la tabla ("Vaciar carrito") --- */
.cart-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.cart-actions a {
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-steel);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color .15s;
}
.cart-actions a:hover { color: var(--color-brand-orange); }

/* --- Coupon block --- */
.cart-coupon {
  margin-top: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-white);
}
.cart-coupon__title {
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-3);
}
.cart-coupon__form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.cart-coupon__input {
  flex: 1;
  height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--text-body);
  color: var(--color-ink);
  outline: none;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  transition: border-color .15s, box-shadow .15s;
}
.cart-coupon__input::placeholder { text-transform: none; letter-spacing: 0; color: var(--color-steel); font-family: var(--font-body); }
.cart-coupon__input:focus { border-color: var(--color-brand-orange); box-shadow: var(--shadow-focus); }
.cart-coupon__input.has-error { border-color: var(--color-danger); }

/* .coupon-error-notice: inyectado por cart.js (assets/js/frontend/cart.js
   show_coupon_error) cuando el cupón es inválido — sin estilos propios de
   WooCommerce porque sus reglas nativas exigen ancestro table.cart, que
   este layout no tiene. */
.coupon-error-notice {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-danger);
}

/* --- Shipping strip --- */
.cart-shipping-strip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  /* Neutro, no verde: encima aparece el aviso de WooCommerce ("Carrito
     actualizado", "se ha añadido a tu carrito"), que sí es verde, y las dos
     bandas seguidas se leían como un mensaje duplicado (petición del 22-sep).
     El verde se queda solo en el icono y en el titular. */
  background: var(--color-mist);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
/* El cliente pidió más aire entre el recuadro verde y la tabla. Hace falta el
   selector con el grupo y margin-block-end: los estilos globales de WordPress
   emiten `:root :where(.is-layout-flow) > :last-child { margin-block-end: 0 }`,
   que empata en especificidad con .cart-shipping-strip y va después en la
   cascada, así que un margin-bottom suelto se perdía. */
.wp-block-group > .cart-shipping-strip {
  margin-block-end: var(--space-12);
}
.cart-shipping-strip svg { color: var(--color-success); flex-shrink: 0; }
.cart-shipping-strip__text { font-size: var(--text-small); font-weight: 600; color: var(--color-success); }
.cart-shipping-strip__sub { font-size: var(--text-caption); color: var(--color-steel); font-weight: 400; }

/* --- Casilla de newsletter (checkout y registro) --- */
/* ".form-row.tlx-newsletter-optin" para ganarle en especificidad al grid de dos
   columnas de ".form-row": este <p> es un único campo y ocupa todo el ancho. */
.form-row.tlx-newsletter-optin { display: block; }
.tlx-newsletter-optin { margin: var(--space-4) 0 0; }
/* La geometría de esta casilla vive con la de las otras dos del checkout, en la
   sección "Terms & conditions checkboxes". El selector de allí lleva "label" y
   el contexto de WooCommerce porque `.woocommerce form .form-row label` fuerza
   display:block (0,3,1). Aquí solo queda lo propio del boletín, que también se
   usa fuera del checkout (alta de cuenta). */
.tlx-newsletter-optin__label a { color: var(--color-brand-orange); }

/* --- Diálogo de confirmación (eliminar del carrito) --- */
/* <dialog> nativo: showModal() ya aporta el atrapado de foco, el cierre con
   Escape y el ::backdrop, así que no hace falta gestión de foco propia. */
.tlx-confirm {
  border: none;
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  max-width: 420px;
  width: calc(100% - var(--space-8));
  background: var(--color-white);
  color: var(--color-ink);
  box-shadow: var(--shadow-lg);
}
.tlx-confirm::backdrop { background: rgba(15, 25, 35, 0.55); }
.tlx-confirm__title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
}
.tlx-confirm__text { margin: 0 0 var(--space-6); font-size: var(--text-small); color: var(--color-steel); }
.tlx-confirm__actions { display: flex; gap: var(--space-3); justify-content: flex-end; flex-wrap: wrap; }

/* --- Cart summary card (sticky desktop) --- */
.cart-summary {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-white);
  overflow: hidden;
}
@media (min-width: 1024px) {
  .cart-summary { position: sticky; top: var(--header-sticky-offset); }
}
.cart-summary__header {
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-mist);
}
.cart-summary__header h2 {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  margin: 0;
}
.cart-summary__body { padding: var(--space-6); }
.cart-summary__rows { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-6); }
.cart-summary__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  font-size: var(--text-small);
}
.cart-summary__label { color: var(--color-steel); flex-shrink: 0; white-space: nowrap; }
.cart-summary__value {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.cart-summary__value--free { color: var(--color-success); font-weight: 700; font-family: var(--font-body); }
/* Lista de métodos de envío — ver themes/telemax/woocommerce/cart/cart-shipping.php
   (override sin <tr>/<th>/<td>, ver comentario ahí). Con un solo método el
   <input> va type="hidden" (invisible), así que solo se ve la label. */
.cart-summary__shipping-methods {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
}
.cart-summary__shipping-methods li { display: flex; align-items: center; gap: var(--space-2); }
/* Nota de impuesto que WooCommerce añade tras el importe (wc_price() con
   "mostrar precios con impuesto incluido") — sin esto hereda el tamaño/peso
   del importe y revienta el layout (ver .checkout-order-item__price abajo). */
.cart-summary__value small,
.cart-summary__value .tax_label,
.cart-summary__value .includes_tax {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 400;
  color: var(--color-steel);
  white-space: nowrap;
}
.cart-summary__divider { border: none; border-top: 1px solid var(--color-border); margin: var(--space-2) 0; }
.cart-summary__total-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-top: 2px solid var(--color-ink);
}
.cart-summary__total-label {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: 700;
  color: var(--color-ink);
  flex-shrink: 0;
  white-space: nowrap;
  padding-top: var(--space-1);
}
.cart-summary__total-value {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.cart-summary__total-value > strong,
.cart-summary__total-value > .woocommerce-Price-amount {
  font-family: var(--font-mono);
  font-size: var(--text-h3);
  font-weight: 700;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cart-summary__total-value small,
.cart-summary__total-value .tax_label,
.cart-summary__total-value .includes_tax {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 400;
  color: var(--color-steel);
  white-space: nowrap;
}
.cart-summary__iva-note {
  font-size: var(--text-caption);
  color: var(--color-steel);
  text-align: right;
  margin: calc(-1 * var(--space-2)) 0 var(--space-4);
}
.cart-summary__ctas { display: flex; flex-direction: column; gap: var(--space-2); }
.cart-summary__trust {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.cart-summary__trust-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-caption);
  color: var(--color-steel);
}
.cart-summary__trust-item svg { color: var(--color-brand-orange); flex-shrink: 0; }

/* --- Related / cross-sell section --- */
.cart-related {
  margin-top: var(--space-8);
}

.cart-related__head {
  margin-bottom: var(--space-4);
}
.cart-related__title {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 700;
  margin: 0 0 var(--space-6);
}
.cart-related__scroll {
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: var(--space-2);
}
.cart-related__scroll::-webkit-scrollbar { display: none; }
.cart-related__scroll .product-card {
  flex-shrink: 0;
  width: 240px;
}
@media (min-width: 1024px) {
  /* 2 columnas: la sección vive dentro de la columna izquierda del carrito, no
     a lo ancho de la página. Por debajo sigue siendo un carrusel horizontal con
     scroll-snap, así que ahí no hay nada que cortar. */
  .cart-related__scroll { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); overflow-x: visible; }
  .cart-related__scroll .product-card { width: auto; }
}

/* --- Sticky Mobile Bar: cart variant --- */
.sticky-mobile-bar--cart { justify-content: space-between; gap: var(--space-3); }
.sticky-mobile-bar__cart-total { display: flex; flex-direction: column; }
.sticky-mobile-bar__cart-amount {
  font-family: var(--font-mono);
  font-size: var(--text-h4);
  font-weight: 700;
  color: var(--color-ink);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.sticky-mobile-bar__cart-iva { font-size: var(--text-caption); color: var(--color-steel); }

/* ============================================================
 * V6 Checkout B2B — Stepper, Blocks, Payment, Summary
 * Añadido en iteración V6-checkout-mobile + V6-checkout-desktop
 * ============================================================ */

/* --- Checkout page layout (form left + summary right) --- */
.checkout-layout {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-8) var(--container-padding-desktop);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: start;
}
@media (min-width: 1024px) {
  .checkout-layout { grid-template-columns: 1fr 380px; gap: var(--space-12); }
}
@media (max-width: 767.98px) {
  .checkout-layout { padding: 0; gap: 0; }
}

/* --- Checkout stepper (progress indicator) --- */
.checkout-stepper {
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border);
}
.checkout-stepper__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-4) var(--container-padding-desktop);
  display: flex;
  align-items: center;
}
@media (max-width: 767.98px) {
  .checkout-stepper__inner { padding: var(--space-4) var(--container-padding-mobile); }
}
.checkout-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
}
.checkout-step__num {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--color-border);
  color: var(--color-steel);
  background: var(--color-white);
  transition: background .15s, border-color .15s, color .15s;
}
.checkout-step.is-active .checkout-step__num {
  background: var(--color-brand-orange);
  color: var(--color-white);
  border-color: var(--color-brand-orange);
}
.checkout-step.is-done .checkout-step__num {
  background: var(--color-success);
  color: var(--color-white);
  border-color: var(--color-success);
}
.checkout-step__label {
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-steel);
  white-space: nowrap;
}
.checkout-step.is-active .checkout-step__label { color: var(--color-ink); }
.checkout-step__line {
  flex: 1;
  height: 2px;
  background: var(--color-border);
  margin: 0 var(--space-2);
  align-self: flex-start;
  margin-top: 15px;
}
.checkout-step__line.is-done { background: var(--color-success); }

/* --- Checkout form blocks (sections 01/02/03) --- */
.checkout-block {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.checkout-block + .checkout-block { margin-top: var(--space-4); }
@media (max-width: 767.98px) {
  .checkout-block {
    border-radius: 0;
    border-left: none;
    border-right: none;
    margin-top: var(--space-3);
  }
  .checkout-block + .checkout-block { margin-top: var(--space-3); }
}
.checkout-block__header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  background: var(--color-mist);
  border-bottom: 1px solid var(--color-border);
}
@media (max-width: 767.98px) {
  .checkout-block__header { padding: var(--space-4) var(--container-padding-mobile); }
}
.checkout-block__num {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: 700;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-brand-orange);
  color: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.checkout-block__title {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0;
}
.checkout-block__body {
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
@media (max-width: 767.98px) {
  .checkout-block__body { padding: var(--space-4) var(--container-padding-mobile); gap: var(--space-4); }
}

/* --- Form row: 2 columns for paired fields --- */
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

/* --- Required field helpers --- */
.field__required-mark {
  color: var(--color-danger);
  margin-left: 2px;
  font-weight: 700;
}
.field__optional {
  font-weight: 400;
  color: var(--color-steel);
}

/* --- Payment methods radio cards --- */
.checkout-payment-hint {
  font-size: var(--text-small);
  color: var(--color-steel);
  background: var(--color-warning-soft);
  border: 1px solid var(--color-warning-soft-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin: 0;
  line-height: 1.5;
}
.checkout-payment-methods {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.checkout-payment-card {
  display: block;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
  overflow: hidden;
}
.checkout-payment-card:hover { border-color: var(--color-border-strong); }
.checkout-payment-card:has(input:checked),
.checkout-payment-card.is-selected {
  border-color: var(--color-brand-orange);
  box-shadow: 0 0 0 1px var(--color-brand-orange);
}
.checkout-payment-card__radio {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.checkout-payment-card__inner {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  min-height: 56px;
}
.checkout-payment-card__icon {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  background: var(--color-mist);
  color: var(--color-ink);
  flex-shrink: 0;
}
.checkout-payment-card:has(input:checked) .checkout-payment-card__icon,
.checkout-payment-card.is-selected .checkout-payment-card__icon {
  background: var(--color-brand-peach);
  color: var(--color-brand-orange);
}
.checkout-payment-card__name {
  flex: 1;
  font-size: var(--text-body);
  font-weight: 600;
  color: var(--color-ink);
}
.checkout-payment-card__check {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  flex-shrink: 0;
  transition: background .15s, border-color .15s, color .15s;
}
.checkout-payment-card:has(input:checked) .checkout-payment-card__check,
.checkout-payment-card.is-selected .checkout-payment-card__check {
  background: var(--color-brand-orange);
  border-color: var(--color-brand-orange);
  color: var(--color-white);
}
.checkout-card-form,
.checkout-transfer-info {
  border-top: 1px solid var(--color-border);
  padding: var(--space-4);
  background: var(--color-mist);
}
.checkout-card-form[hidden],
.checkout-transfer-info[hidden] { display: none; }
.checkout-transfer-info__text {
  font-size: var(--text-small);
  color: var(--color-steel);
  line-height: 1.6;
  margin: 0;
}

/* --- Terms & conditions checkboxes --- */
/* El recuadro con el texto de las condiciones no tenía estilos propios, así que
   heredaba los titulares de la web: dentro de una caja con scroll de 200px
   salía un "1. Datos identificativos" a tamaño de titular de página. El cliente
   lo fotografió el 6-oct-2026. Aquí se acotan tamaños y aire. */
.woocommerce-terms-and-conditions {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-white);
  font-size: var(--text-small);
  line-height: 1.6;
  color: var(--color-steel);
}
.woocommerce-terms-and-conditions h1,
.woocommerce-terms-and-conditions h2,
.woocommerce-terms-and-conditions h3,
.woocommerce-terms-and-conditions h4 {
  font-size: var(--text-body);
  line-height: 1.35;
  color: var(--color-ink);
  margin: var(--space-4) 0 var(--space-2);
}
.woocommerce-terms-and-conditions > :first-child { margin-top: 0; }
.woocommerce-terms-and-conditions p { margin: 0 0 var(--space-3); }
.woocommerce-terms-and-conditions > :last-child { margin-bottom: 0; }
.woocommerce-terms-and-conditions ul,
.woocommerce-terms-and-conditions ol { margin: 0 0 var(--space-3); padding-left: var(--space-6); }
.woocommerce-terms-and-conditions li { margin-bottom: var(--space-1); }
.woocommerce-terms-and-conditions a { color: var(--color-brand-orange); }

.checkout-terms-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
/* Las tres casillas del checkout (condiciones, CIF y boletín) comparten
   geometría a propósito: el cliente las fotografió el 6-oct-2026 con guías
   porque no arrancaban en la misma vertical. Tenían tres line-height distintos
   (28, 21 y 24,5px) y el cuadro del boletín salía 4px a la derecha por el
   margen por defecto que el navegador da a input[type=checkbox]. Si se toca
   una, hay que tocar las tres. */
.checkout-terms__label,
.tlx-newsletter-optin__label,
.woocommerce form .form-row label.tlx-newsletter-optin__label {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  cursor: pointer;
  font-size: var(--text-small);
  color: var(--color-steel);
  line-height: 1.5;
}
.checkout-terms__label { min-height: 44px; }
/* La casilla de condiciones no tiene la misma estructura que las otras dos: el
   marcado de WooCommerce mete el input y el texto dentro de un <label> propio,
   así que el flex del <p> solo ve un hijo y la alineación se decidía dentro de
   ese label, con su propio line-height heredado (28px frente a 21px). Se le da
   la misma caja para que las tres coincidan. */
.checkout-terms__label > label.checkbox,
.woocommerce form .form-row.checkout-terms__label > label.checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  line-height: inherit;
  margin: 0;
}
/* Los selectores van cualificados con el contexto de WooCommerce porque su
   hoja fija `margin: -2px 8px 0 0` en estas casillas con más especificidad: ese
   margen de 8px era el que separaba de más el texto de la primera casilla
   respecto a las otras dos, y el -2px el que descolgaba el cuadro. */
.checkout-terms__check,
.tlx-newsletter-optin__label input[type="checkbox"],
.woocommerce form .form-row .checkout-terms__check,
.woocommerce form .form-row .tlx-newsletter-optin__label input[type="checkbox"] {
  width: 20px;
  height: 20px;
  /* El cuadro se centra ópticamente con la PRIMERA línea del texto: media línea
     menos medio cuadro. Centrarlo contra el bloque entero lo dejaría flotando a
     media altura en las casillas de dos y tres líneas. */
  margin: calc((1.5em - 20px) / 2) 0 0;
  accent-color: var(--color-brand-orange);
  cursor: pointer;
  flex-shrink: 0;
}
.checkout-terms__link { color: var(--color-brand-orange); text-decoration: underline; }
.checkout-terms__link:hover { color: var(--color-brand-red); }
.checkout-pending {
  display: inline-block;
  font-size: var(--text-caption);
  color: var(--color-steel);
  background: var(--color-warning-soft);
  border-radius: var(--radius-sm);
  padding: 2px 6px;
}

/* --- Order items list (in summary) --- */
.checkout-order-items {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: var(--space-4);
}
.checkout-order-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border);
}
.checkout-order-item:last-child { border-bottom: none; }
.checkout-order-item__thumb {
  position: relative;
  width: 56px;
  height: 56px;
}
.checkout-order-item__img-placeholder {
  width: 56px;
  height: 56px;
  background: var(--color-mist);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  color: var(--color-steel);
  text-align: center;
  line-height: 1.3;
  padding: 4px;
}
.checkout-order-item__qty {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 18px;
  height: 18px;
  background: var(--color-ink);
  color: var(--color-white);
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
}
.checkout-order-item__info { min-width: 0; }
.checkout-order-item__name {
  font-family: var(--font-display);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-1);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.checkout-order-item__meta {
  font-size: var(--text-caption);
  color: var(--color-steel);
  margin: 0;
  line-height: 1.3;
}
.checkout-order-item__price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  flex-shrink: 0;
}
.checkout-order-item__price > .woocommerce-Price-amount {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Nota "(incl. impuestos)" que añade wc_price() — sin esto heredaba el
   tamaño/peso del importe y forzaba la columna "auto" del grid a ser
   enorme, dejando la columna del nombre casi sin espacio (ver captura:
   nombre truncado a "T.." y meta partido palabra por palabra). */
.checkout-order-item__price small,
.checkout-order-item__price .tax_label {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 400;
  color: var(--color-steel);
  white-space: nowrap;
}

/* --- Checkout summary card (desktop sticky right column) --- */
.checkout-summary {
  position: sticky;
  top: 120px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-white);
  overflow: hidden;
}
@media (max-width: 1023px) {
  /* El checkout clásico pinta el resumen una sola vez (ver review-order.php:
     duplicarlo para .checkout-summary-mobile obligaría a un segundo
     id="place_order" y a que la AJAX de recálculo reemplace 2 nodos con el
     mismo fragment key) — en mobile pasa a estático a ancho completo en vez
     de ocultarse. */
  .checkout-summary { position: static; }
}
.checkout-summary__heading {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  margin: 0;
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-mist);
}
.checkout-summary__body { padding: var(--space-6); }
.checkout-summary__divider {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-4) 0;
}

/* --- Checkout summary mobile section (inline, below form) --- */
.checkout-summary-mobile {
  padding: var(--space-8) var(--container-padding-mobile);
  background: var(--color-mist);
  border-top: 4px solid var(--color-border);
}
@media (min-width: 1024px) {
  .checkout-summary-mobile { display: none; }
}
.checkout-summary-mobile .checkout-summary__heading {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 700;
  margin: 0 0 var(--space-4);
  background: none;
  border: none;
  padding: 0;
}

/* --- Checkout trust block (desktop summary) --- */
.checkout-trust-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.checkout-trust-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-caption);
  color: var(--color-steel);
}
.checkout-trust-item svg { color: var(--color-brand-orange); flex-shrink: 0; }

/* --- Resumen sticky: totales + CTA siempre visibles al hacer scroll del
   formulario (checkout clásico, themes/telemax/woocommerce/checkout/) --- */
.checkout-summary--sticky-fit {
  margin-top: var(--space-8);
}

@media (min-width: 1024px) {
  .checkout-summary--sticky-fit {
    max-height: calc(100vh - 140px);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
    margin-top: 0;
  }
}

/* --- Pares de campos en los bloques 01/02 del checkout clásico. Nombre
   propio (no ".form-row"): esa clase ya la usa WooCommerce para su propio
   wrapper <p> de campo único (terms.php, el <select> de provincia vía
   woocommerce_form_field) — reutilizarla aquí colisionaría con ese uso
   nativo. Ver el neutralizador ".checkout-block .form-row" más abajo. --- */
.checkout-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
.checkout-2col--wide {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-4);
}
@media (max-width: 767.98px) {
  .checkout-2col,
  .checkout-2col--wide { grid-template-columns: 1fr; }
}

/* Neutraliza el grid de 2 columnas que ".form-row" tiene en el resto del
   proyecto (ver arriba, "Form row: 2 columns for paired fields") allí donde
   WooCommerce pinta su propio wrapper <p class="form-row"> de UN solo campo
   (terms.php, woocommerce_form_field() para el <select> de provincia) — sin
   esto, ese <p> heredaría un grid de 2 columnas con la segunda vacía. NO se
   le quita la clase "form-row": checkout.js la usa para resaltar errores
   (.woocommerce-invalid) y para el estado guardado/restaurado de #terms. */
.checkout-block .form-row { display: block; }

.checkout-closing-note {
  font-size: var(--text-small);
  color: var(--color-steel);
  line-height: 1.5;
  margin: var(--space-6) 0 0;
}

/* Microcopy de plazo bajo el CTA del resumen */
.checkout-cta-deadline {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-success);
  line-height: 1.3;
  margin-top: var(--space-2);
}
.checkout-cta-deadline svg { flex-shrink: 0; }

/* Nota de seguridad bajo el CTA del resumen */
.checkout-security-note {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-size: var(--text-caption);
  color: var(--color-steel);
  margin-top: var(--space-3);
}
.checkout-security-note svg { color: var(--color-steel); }

/* --- Sticky Mobile Bar: checkout variant --- */
.sticky-mobile-bar--checkout { justify-content: space-between; gap: var(--space-3); }
.sticky-mobile-bar--checkout .checkout-cta-deadline { font-size: 11px; margin-bottom: 2px; margin-top: 0; }

/* ============================================================
 * V7 Manuales — ManualCard, ManualsHeroSearch, ManualsFilterBar
 * Añadido en iteración V7-manuales-mobile + V7-manuales-desktop
 * ============================================================ */

/* --- Manuals hero search form --- */
.manuals-hero-search {
  margin-top: var(--space-6);
  max-width: 600px;
}
.manuals-hero-search form {
  display: flex;
  gap: var(--space-2);
}
.manuals-hero-search input {
  flex: 1;
  height: 52px;
  padding: 0 var(--space-4);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--color-ink);
  background: var(--color-white);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.manuals-hero-search input:focus {
  border-color: var(--color-brand-orange);
  box-shadow: var(--shadow-focus);
}
.manuals-hero-search input::placeholder { color: var(--color-steel); }
.manuals-hero-search button {
  height: 52px;
  padding: 0 var(--space-6);
  background: var(--color-brand-orange);
  color: var(--color-white);
  border: none;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  white-space: nowrap;
  flex-shrink: 0;
  transition: background .15s;
}
.manuals-hero-search button:hover { background: var(--color-brand-red); }
.manuals-hero-search button:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* --- Search box card (desktop hero right column) --- */
.page-hero__search-box {
  background: var(--color-white);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-md);
  border: 1px solid var(--color-border);
}
.page-hero__search-box-title {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-4);
}
.page-hero__search-box .manuals-hero-search {
  margin-top: 0;
  max-width: none;
}
.page-hero__search-box-label {
  display: block;
  font-size: var(--text-caption);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-steel);
  margin: var(--space-3) 0 var(--space-2);
}
.page-hero__search-box-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

/* --- Manuals filter bar (horizontal scroll chips) --- */
.manuals-filter-bar {
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}
.manuals-filter-bar__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-3) var(--container-padding-desktop);
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.manuals-filter-bar__inner::-webkit-scrollbar { display: none; }
@media (max-width: 767.98px) {
  .manuals-filter-bar__inner { padding: var(--space-3) var(--container-padding-mobile); }
}

/* --- Manuals results count --- */
.manuals-count {
  font-size: var(--text-small);
  color: var(--color-steel);
  margin: 0 0 var(--space-6);
}
.manuals-count strong { color: var(--color-ink); }

/* --- Manual grid (3 columns desktop, 2 tablet, 1 mobile) --- */
.manual-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
@media (min-width: 640px) {
  .manual-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .manual-grid { grid-template-columns: repeat(3, 1fr); align-items: stretch; }
  .manual-card { min-height: 220px; }
}

/* --- Manual card --- */
.manual-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-white);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: box-shadow .15s, transform .15s;
}
@media (min-width: 768px) {
  .manual-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
}
.manual-card__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-mist);
  border-bottom: 1px solid var(--color-border);
}
.manual-card__icon {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  background: var(--color-brand-orange);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-white);
}
.manual-card__title-block { flex: 1; min-width: 0; }
.manual-card__type {
  font-size: var(--text-caption);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-steel);
  margin: 0 0 var(--space-1);
  line-height: 1.2;
}
.manual-card__name {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0;
  line-height: 1.3;
}
.manual-card__body {
  padding: var(--space-4);
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.manual-card__chips {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.manual-card__meta {
  font-size: var(--text-small);
  color: var(--color-steel);
  font-family: var(--font-mono);
  margin: 0;
  line-height: 1.4;
}
.manual-card__ctas {
  display: flex;
  gap: var(--space-2);
  margin-top: auto;
}
.manual-card__ctas .btn { flex: 1; justify-content: center; }

/* --- Manual card CE variant (dark header to signal official document) --- */
.manual-card--ce .manual-card__header {
  background: var(--color-ink);
  border-bottom-color: rgba(255,255,255,0.1);
}
.manual-card--ce .manual-card__type { color: rgba(255,255,255,0.5); }
.manual-card--ce .manual-card__name { color: var(--color-white); }

/* --- Sticky Mobile Bar: manuales variant --- */
.sticky-mobile-bar--manuales { justify-content: space-between; }

/* ============================================================
 * Utility — img-placeholder (A1) + pending (A3)
 * Añadidos en FASE 0 del proceso de validación (2026-05-20)
 * ============================================================ */

.img-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  text-align: center;
  padding: var(--space-6);
  background: var(--color-mist);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  color: var(--color-steel);
  min-height: 160px;
  aspect-ratio: 1 / 1;
}
.img-placeholder--landscape { aspect-ratio: 4 / 3; }
.img-placeholder--portrait { aspect-ratio: 3 / 4; }
.img-placeholder--cover { aspect-ratio: auto; height: 100%; }
.img-placeholder--brand { background: var(--color-brand-peach); border-color: var(--color-brand-orange); color: var(--color-brand-red); }
.img-placeholder--dark { background: var(--color-ink); border-color: var(--color-steel); color: rgba(255,255,255,0.6); }
.img-placeholder svg { color: var(--color-border-strong); }
.img-placeholder--dark svg { color: rgba(255,255,255,0.4); }
.img-placeholder__label {
  font-size: var(--text-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.img-placeholder__detail {
  font-size: var(--text-caption);
  max-width: 80%;
  line-height: 1.4;
  opacity: 0.85;
}

.pending {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  background: repeating-linear-gradient(45deg, var(--color-mist), var(--color-mist) 4px, var(--color-border) 4px, var(--color-border) 5px);
  color: var(--color-steel);
  font-family: var(--font-mono);
  font-size: 0.9em;
  cursor: help;
}
.pending::after {
  content: attr(data-pending);
  margin-left: 6px;
  font-size: var(--text-caption);
  text-transform: lowercase;
  letter-spacing: 0.02em;
}

/* ============================================================
 * V1 Header mobile refactor — nuevas clases para layout hamburger-left
 * Especificación VALIDATION-REPORT §V1 cabecera
 * ============================================================ */

/* Zona de acciones derecha en mobile (lupa + carrito) */
.site-header__mobile-actions {
  display: none;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
  width: 88px;
  justify-content: flex-end;
}
@media (max-width: 767.98px) {
  .site-header__mobile-actions { display: flex; }
  /* Complemento de .site-header__actions (regla base en la línea ~285: display:flex sin
     media query). Se declara aquí, junto a la de mobile-actions, en vez de en su propio
     @media suelto más abajo, para que ambos lados del toggle desktop/mobile vivan en el
     mismo bloque y no puedan desincronizarse. */
  .site-header__actions { display: none; }
}

/* Botón lupa para abrir search drawer en mobile */
.site-header__search-toggle {
  /* 44x44: mínimo de zona pulsable (WCAG 2.5.8), igual que .site-header__cart. */
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-ink);
  border-radius: var(--radius-md);
  transition: background .15s;
  flex-shrink: 0;
}
.site-header__search-toggle:hover { background: var(--color-mist); }
.site-header__search-toggle:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Search drawer top (mobile — aparece bajo header al pulsar lupa) */
.search-drawer {
  display: none;
  position: fixed;
  top: 64px; /* solo el header: la topbar está oculta en móvil */
  left: 0;
  right: 0;
  z-index: 101;
  background: var(--color-white);
  border-bottom: 2px solid var(--color-border);
  padding: var(--space-3) var(--container-padding-mobile);
  box-shadow: var(--shadow-md);
}
.search-drawer.is-open { display: flex; }
.search-drawer__form {
  display: flex;
  gap: var(--space-2);
  width: 100%;
}
.search-drawer__input {
  flex: 1;
  height: 44px;
  padding: 0 var(--space-4);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--color-ink);
  background: var(--color-mist);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.search-drawer__input:focus {
  border-color: var(--color-brand-orange);
  box-shadow: var(--shadow-focus);
  background: var(--color-white);
}
.search-drawer__input::placeholder { color: var(--color-steel); }

/* ============================================================
 * ITERACIÓN 2 — Ajustes reunión cliente 10-jun-2026
 * Línea industrial/profesional (ref. UTECH): menos naranja saturado,
 * más gris estructural, contraste AA, hover inequívoco.
 * Regla dura: SOLO clases modificadoras nuevas. No se redefinen
 * tokens globales ni reglas base compartidas.
 * ============================================================ */

/* --- Banner CTA en grafito (suaviza el naranja del cierre) --- */
.banner-cta--graphite {
  background: var(--color-graphite);
}
.banner-cta--graphite .btn--white {
  background: var(--color-brand-orange);
  color: var(--color-white);
}
.banner-cta--graphite .btn--white:hover {
  background: var(--color-white);
  color: var(--color-brand-orange);
}

/* --- Overlay de legibilidad sobre vídeo/foto/naranja (AA) --- */
.media-overlay {
  position: relative;
  isolation: isolate;
}
.media-overlay > .media-overlay__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
}
.media-overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--overlay-ink-strong);
  z-index: -1;
}
.media-overlay--soft::before { background: var(--overlay-ink-soft); }
@media (prefers-reduced-motion: reduce) {
  .media-overlay__media[autoplay] { display: none; }
}

/* --- Iconos de redes sociales en footer (se omitieron en V1) --- */
.site-footer__social {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.site-footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.75);
  transition: background .15s, color .15s, transform .15s;
}
.site-footer__social a:hover {
  background: var(--color-brand-orange);
  color: var(--color-white);
  transform: translateY(-2px);
}
.site-footer__social svg { width: 18px; height: 18px; }

/* --- Hover/focus inequívocos (público con poca competencia digital) --- */
.u-hover-lift { transition: box-shadow .18s, transform .18s; }
.u-hover-lift:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.u-strong { font-weight: 700; }
.u-reset-margin { margin: 0; }

/* --- Banda de respiro gris antes del footer --- */
.section--graphite {
  background: var(--color-graphite);
  color: var(--color-white);
}
.section--graphite h2 { color: var(--color-white); }

/* ============================================================
 * V1 Header — combinación en un único DOM responsive (parts/header.html)
 * Añadido en la construcción real del tema. En el hub, el layout
 * "hamburguer izq · logo centro · acciones der" de V1-home-mobile.html
 * vivía en un <style> inline propio de esa página (no en este styles.css
 * compartido), porque el hub sirve desktop/mobile como páginas estáticas
 * separadas. El tema, en cambio, sirve un único HTML en todos los anchos,
 * así que esas reglas mobile-only tienen que existir aquí. Solo AÑADE
 * reglas nuevas (selectores ya existentes, contexto @media nuevo); no
 * modifica ninguna declaración previa.
 * ============================================================ */
@media (max-width: 767.98px) {
  .site-header__hamburger { margin-left: 0; }
  .site-header__logo { flex: 1; display: flex; justify-content: center; }
}

/* ============================================================
 * V1 Home — Hero carousel, Mandos, Qué-es, Fabricantes, Personaliza, FAQ
 * Añadido en la construcción real de la Home (templates/front-page.html).
 * CSS específico de esta vertical, portado de los <style> inline de
 * docs/pages/V1-home-desktop.html y V1-home-mobile.html. Se fusionan ambos
 * breakpoints con el mismo convenio del resto del archivo: reglas base
 * (valores desktop) + @media (max-width: 767.98px) con los valores mobile.
 *
 * Carrusel de aplicaciones (.hero-carousel*): en el hub, desktop usaba
 * transform + flechas con autoavance y mobile usaba scroll nativo
 * (scroll-snap) sin flechas — dos mecanismos distintos porque el hub sirve
 * cada breakpoint como página estática separada. Aquí se unifican en UNO
 * SOLO: .hero-carousel__track usa scroll nativo con scroll-snap en todos los
 * anchos; las flechas existen siempre en el marcado pero se ocultan por CSS
 * en mobile. El JS (plugins/telemax-blocks/blocks/hero-carousel/view.js) usa
 * scrollTo/scrollLeft tanto para los clics de flechas/pills como para
 * sincronizar los pills durante el swipe táctil, y solo activa el
 * autoavance en dispositivos con hover + puntero fino (equivalente a
 * "desktop"), para no competir con el gesto de swipe en mobile.
 * ============================================================ */

/* --- Nivel 1: cabecera dinámica (carrusel de aplicaciones) --- */
.hero-carousel { background: var(--color-white); border-bottom: 1px solid var(--color-border); }
.hero-carousel__viewport { position: relative; overflow: hidden; }
.hero-carousel__track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.hero-carousel__track::-webkit-scrollbar { display: none; }
/* El editor de bloques inserta wrappers propios (.block-editor-inner-blocks >
   .block-editor-block-list__layout) entre .hero-carousel__track y cada
   diapositiva, rompiendo el flex (los hijos directos dejan de ser los
   .hero-carousel__slide). display:contents los saca del árbol de cajas para
   que los slides vuelvan a ser hijos flex directos, solo afecta al editor
   porque estas clases no existen en el HTML del front-end. */
.hero-carousel__track .block-editor-inner-blocks,
.hero-carousel__track .block-editor-block-list__layout {
  display: contents;
}
.hero-carousel__slide { flex: 0 0 100%; scroll-snap-align: start; }
.hero-carousel__media {
  position: relative;
  height: 440px;
  background: var(--color-mist);
  overflow: hidden;
}
/* El <video>/<img> real del cliente ocupa este mismo frame (object-fit
   cover, nunca background-image). El scrim inferior garantiza texto legible
   sobre vídeo o foto (accesibilidad). */
.hero-carousel__media video,
.hero-carousel__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-carousel__scrim {
  position: absolute; left: 0; right: 0; bottom: 0; height: 60%;
  background: linear-gradient(180deg, rgba(15,25,35,0) 0%, rgba(15,25,35,0.55) 100%);
  pointer-events: none; z-index: 1;
}
.hero-carousel__caption {
  position: absolute; left: 0; right: 0; bottom: 40px; z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  text-align: center; padding: 0 24px;
}
.hero-carousel__caption-text {
  /* Texto totalmente editable desde el gestor (petición cliente) */
  font-family: var(--font-display); font-weight: 700; font-size: 24px;
  color: var(--color-white); text-shadow: 0 1px 8px rgba(15,25,35,0.5); margin: 0;
}
.hero-carousel__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 48px; height: 48px; border-radius: 50%;
  border: 1.5px solid var(--color-border); background: rgba(255,255,255,0.92);
  color: var(--color-ink); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s, border-color .15s;
}
.hero-carousel__arrow:hover { background: var(--color-brand-orange); border-color: var(--color-brand-orange); color: #fff; }
.hero-carousel__arrow:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.hero-carousel__arrow--prev { left: 24px; }
.hero-carousel__arrow--next { right: 24px; }

.hero-carousel__apps {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 10px;
  max-width: 1200px; margin: 0 auto; padding: 22px 40px 26px;
}
.hero-carousel__app {
  border: 1.5px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-white); color: var(--color-ink);
  font-family: var(--font-display); font-weight: 700; font-size: 13px;
  padding: 10px 16px; cursor: pointer;
  min-height: 44px; /* zona pulsable mínima (WCAG 2.5.8); antes 36px */
  display: inline-flex; align-items: center; gap: 8px;
  transition: background .15s, color .15s, border-color .15s;
}
.hero-carousel__app svg { width: 18px; height: 18px; color: var(--color-brand-orange); transition: color .15s; }
.hero-carousel__app:hover,
.hero-carousel__app:active,
.hero-carousel__app.is-active { background: var(--color-brand-orange); border-color: var(--color-brand-orange); color: #fff; }
.hero-carousel__app:hover svg,
.hero-carousel__app:active svg,
.hero-carousel__app.is-active svg { color: #fff; }
.hero-carousel__app:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

@media (max-width: 767.98px) {
  .hero-carousel__arrow { display: none; }
  .hero-carousel__media { height: 320px; }
  .hero-carousel__scrim { height: 65%; background: linear-gradient(180deg, rgba(15,25,35,0) 0%, rgba(15,25,35,0.6) 100%); }
  .hero-carousel__caption { bottom: 20px; gap: 10px; padding: 0 20px; }
  .hero-carousel__caption-text { font-size: 17px; }
  .hero-carousel__caption .btn { width: 100%; max-width: 340px; }
  .hero-carousel__apps {
    justify-content: flex-start; flex-wrap: nowrap;
    max-width: none; margin: 0; gap: 8px;
    overflow-x: auto; scrollbar-width: none;
    padding: 14px 20px 18px;
  }
  .hero-carousel__apps::-webkit-scrollbar { display: none; }
  .hero-carousel__app { flex: 0 0 auto; padding: 9px 14px; }
  .hero-carousel__app svg { width: 16px; height: 16px; }
}

/* --- Sección 1: cabecera de la Home (vídeo/foto a sangre, NO carrusel) ---
   Requisito expreso del cliente: la cabecera es un único panel con vídeo (o
   foto) a fondo completo, H1 y CTAs encima. El media va como <video>/<img>
   con object-fit:cover, nunca background-image, para que WordPress pueda
   servir el archivo de la biblioteca de medios y el vídeo se pueda reproducir.
   El grid de 2 filas mantiene el contenido centrado ópticamente y la banda de
   sellos pegada al borde inferior sin recurrir a position:absolute. */
.hero-mandos {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--color-ink);
  color: #fff;
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: clamp(520px, 76vh, 760px);
}
.hero-mandos__media { position: absolute; inset: 0; z-index: 0; }
.hero-mandos__media video,
.hero-mandos__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* El scrim garantiza el contraste del titular sobre cualquier fotograma
   (accesibilidad). --hero-overlay lo emite render.php desde el atributo
   overlayOpacity, así que la intensidad es editable sin duplicar reglas.
   El alfa se mantiene PLANO en toda la franja donde cae el texto: con un
   gradiente que arrancaba en overlay*0.5 el alfa efectivo a la altura del H1
   bajaba a 0,38 y el subtítulo se quedaba en 3,5:1 sobre foto clara. Con alfa
   plano 0,65 el blanco puro da 5,5:1 incluso sobre un fotograma blanco. Solo
   se refuerza el último tramo, bajo la banda de sellos. */
.hero-mandos__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(15,25,35,var(--hero-overlay, 0.65)) 0%,
    rgba(15,25,35,var(--hero-overlay, 0.65)) 70%,
    rgba(15,25,35,min(1, calc(var(--hero-overlay, 0.65) * 1.25))) 100%
  );
}

.hero-mandos__content {
  position: relative; z-index: 2;
  /* Mismo ancho que .container (1280, no 1200): así el titular arranca en la
     misma vertical que el resto de secciones de la página. Con 1200 se quedaba
     40px más adentro y el cliente pidió el 2-oct-2026 llevarlo más a la
     izquierda. */
  width: 100%; max-width: var(--container-max); margin: 0 auto;
  padding: var(--space-12) var(--container-padding-desktop) var(--space-8);
  /* Anclado abajo a la izquierda (petición del cliente, 2-oct-2026: "el título
     del inicio debe de estar en la esquina inferior izquierda para que no
     choque con el vídeo"). Antes iba centrado y subido respecto al centro
     óptico. El bloque sigue dentro del grid-template-rows del hero, así que la
     banda de sellos no se mueve. */
  display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start;
  text-align: left;
}
/* Titular deliberadamente contenido: el bloque de texto + CTAs no debe comerse
   la banda, porque lo que se tiene que ver es el vídeo. El design hub fijó 48px
   (commit "H1 hero a 48px"), pero el cliente pidió reducirlo para que el fondo
   respire; se deja en clamp para que además no dé el salto brusco de 48 a 29px
   en el breakpoint. */
.hero-mandos__title {
  font-family: var(--font-display); font-weight: 700;
  /* Un punto más grande a petición del cliente (22-sep); sigue en clamp para
     no dar el salto brusco en el breakpoint. */
  font-size: clamp(27px, 3.1vw, 44px); line-height: 1.12;
  /* Sin `auto` en los márgenes laterales: con el bloque alineado a la
     izquierda, `margin: 0 auto` lo recentraba dentro de su propia caja. */
  color: var(--color-white); margin: 0 0 12px;
  max-width: 720px;
  text-shadow: 0 2px 12px var(--overlay-ink-soft);
}
.hero-mandos__highlight { color: var(--color-brand-orange); font-style: normal; }
/* Blanco puro, no rgba(255,255,255,0.9): con el alfa el subtítulo se quedaba
   en 4,2:1 y no llegaba al 4,5:1 que exige AA. A 16px el mínimo sigue siendo
   4,5:1 y el velo del hero da 5,5:1 en el peor caso, así que cumple igual. */
.hero-mandos__sub {
  font-size: var(--text-body); line-height: 1.55; color: var(--color-white);
  margin: 0 0 20px; max-width: 560px;
  text-shadow: 0 1px 8px rgba(15,25,35,0.5);
}
/* Sin CTAs el subtítulo es el último elemento: su margen inferior dejaría un
   hueco muerto que descentra el bloque de texto. */
.hero-mandos__sub:last-child { margin-bottom: 0; }
.hero-mandos__ctas { display: flex; gap: 10px; flex-wrap: wrap; }
.hero-mandos__trust {
  position: relative; z-index: 2;
  border-top: 1px solid rgba(255,255,255,0.22);
  background: var(--overlay-ink-soft);
}
.hero-mandos__trust-inner {
  max-width: 1200px; margin: 0 auto; padding: 18px 80px;
  /* Centrada igual que el titular (petición del cliente, 22-sep). */
  display: flex; gap: 36px; flex-wrap: wrap; justify-content: center;
}
.hero-mandos__trust-item {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 700; color: rgba(255,255,255,0.9);
}
.hero-mandos__trust-item svg { width: 16px; height: 16px; color: var(--color-brand-orange); }
/* WCAG 2.2.2: un vídeo en autoplay+loop no se puede pausar. Misma guarda que
   .media-overlay__media[autoplay] (más arriba en este archivo): con
   prefers-reduced-motion se oculta el vídeo y queda el fondo ink del hero. */
@media (prefers-reduced-motion: reduce) {
  .hero-mandos__media video[autoplay] { display: none; }
}

@media (max-width: 767.98px) {
  .hero-mandos { min-height: clamp(460px, 82vh, 620px); }
  /* El padding lateral usa el token del contenedor: con 20px el H1 arrancaba
     4px por delante del contenido de las secciones siguientes. */
  .hero-mandos__content { padding: var(--space-12) var(--container-padding-mobile) var(--space-6); }
  /* El font-size lo resuelve ya el clamp de la regla base; aquí solo el ancho. */
  .hero-mandos__title { max-width: none; }
  .hero-mandos__sub { font-size: var(--text-small); margin: 0 0 16px; max-width: none; }
  .hero-mandos__ctas { flex-direction: column; gap: 8px; align-self: stretch; }
  .hero-mandos__trust-inner { padding: 16px var(--container-padding-mobile); display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
  .hero-mandos__trust-item { font-size: var(--text-caption); }
  .hero-mandos__trust-item svg { width: 15px; height: 15px; flex: 0 0 auto; }
}

/* --- Sección 3: categorías destacadas (.cat-showcase) ---
   Requisitos expresos del cliente: imagen de FONDO (no icono), SIN
   recuadro/tarjeta, efecto hover que NUNCA use el rojo de marca
   (--color-brand-red), y número de tarjetas configurable. La rejilla se limita
   a 3 columnas: --cat-cols lo emite render.php como min(count, 3), así que 6
   tarjetas se reparten en dos filas de 3 en vez de una fila ilegible.
   Prefijo BEM nuevo porque esta sección no tiene equivalente en las maquetas
   del design hub (.category-card de DESIGN.md §7.5 lleva recuadro y sirve a
   otra pantalla, así que no se reutiliza aquí). */
/* El CTA "BUSCA POR APLICACIÓN" del hero salta a #cat-showcase-title. El header
   es sticky y mide --header-sticky-offset, así que sin scroll-margin-top el
   titular acaba tapado por la cabecera al llegar. */
#cat-showcase-title { scroll-margin-top: calc(var(--header-sticky-offset) + var(--space-6)); }
.cat-showcase__grid { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }
.cat-showcase__card {
  /* Sin border, sin background y sin box-shadow a propósito: el cliente pidió
     quitar el recuadro. Lo único que redondea es el recorte de la imagen. */
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 4 / 3;
  text-decoration: none;
  color: var(--color-white);
}
.cat-showcase__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform .35s ease;
}
/* El scrim alcanza su alfa máximo ANTES de la franja del título (que cae al
   ~74% de la tarjeta) y se mantiene: arrancando en 35% el alfa efectivo a esa
   altura era 0,43 y el título daba 2,75:1 sobre una foto clara. */
.cat-showcase__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(15,25,35,0) 28%, rgba(15,25,35,0.72) 62%, rgba(15,25,35,0.82) 100%);
  transition: background .25s ease;
}
.cat-showcase__body {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-6);
}
.cat-showcase__label {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--text-h3); line-height: 1.15;
  color: var(--color-white); margin: 0;
  text-shadow: 0 1px 8px rgba(15,25,35,0.5);
}
.cat-showcase__cta {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-small); font-weight: 700;
  color: var(--color-white);
  transition: color .2s ease;
}
.cat-showcase__cta svg { transition: transform .2s ease; }
/* PROHIBIDO EL ROJO DE MARCA en cualquier estado de esta tarjeta (petición
   expresa del cliente). La regla global `a:hover { color: var(--color-brand-red) }`
   tiene especificidad 0-1-1 y ganaba a `.cat-showcase__card` (0-1-0), así que el
   `color` heredado de la tarjeta computaba #E10600 en hover y foco. Se fija el
   blanco doblando la clase para subir la especificidad a 0-2-1. */
.cat-showcase__card.cat-showcase__card:hover,
.cat-showcase__card.cat-showcase__card:focus-visible,
.cat-showcase__card.cat-showcase__card:active { color: var(--color-white); }
/* El hover se nota por el zoom de la imagen, el tinte naranja del scrim y el
   subrayado del CTA. El CTA NO cambia a naranja: sobre el scrim oscurecido el
   naranja daba 2,99:1 y quedaba menos legible que en reposo (5,32:1). */
.cat-showcase__card:hover .cat-showcase__img,
.cat-showcase__card:focus-visible .cat-showcase__img,
.cat-showcase__card:active .cat-showcase__img { transform: scale(1.05); }
.cat-showcase__card:hover .cat-showcase__scrim,
.cat-showcase__card:focus-visible .cat-showcase__scrim,
.cat-showcase__card:active .cat-showcase__scrim {
  background: linear-gradient(180deg, rgba(254,80,0,0.14) 0%, rgba(15,25,35,0.6) 45%, rgba(15,25,35,0.88) 100%);
}
.cat-showcase__card:hover .cat-showcase__cta,
.cat-showcase__card:focus-visible .cat-showcase__cta,
.cat-showcase__card:active .cat-showcase__cta { text-decoration: underline; text-underline-offset: 3px; }
.cat-showcase__card:hover .cat-showcase__cta svg,
.cat-showcase__card:focus-visible .cat-showcase__cta svg,
.cat-showcase__card:active .cat-showcase__cta svg { transform: translateX(3px); }
/* Foco: el anillo global --shadow-focus (naranja al 25%) daba 1,37:1 sobre el
   fondo blanco de la sección, prácticamente invisible. Se usa un contorno ink,
   que contrasta en cualquier fondo, y se repite el border-radius porque
   `a:focus-visible` global lo bajaba a --radius-sm y con overflow:hidden el
   recorte de la imagen daba un salto visible. */
.cat-showcase__card:focus-visible {
  outline: 3px solid var(--color-ink);
  outline-offset: 3px;
  box-shadow: none;
  border-radius: var(--radius-lg);
}

@media (min-width: 600px) {
  .cat-showcase__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .cat-showcase__grid { grid-template-columns: repeat(var(--cat-cols, 3), 1fr); }
}
@media (max-width: 767.98px) {
  .cat-showcase__card { aspect-ratio: 16 / 10; }
  .cat-showcase__body { padding: var(--space-4); }
}
@media (prefers-reduced-motion: reduce) {
  .cat-showcase__img,
  .cat-showcase__cta,
  .cat-showcase__cta svg { transition: none; }
  .cat-showcase__card:hover .cat-showcase__img,
  .cat-showcase__card:focus-visible .cat-showcase__img,
  .cat-showcase__card:active .cat-showcase__img { transform: none; }
}

/* --- Sección 4: carrusel de mandos (.mandos-carousel) ---
   El cliente pidió que "se pueda desplazar arrastrando en móvil, no solo con
   la barra/flechas". Se resuelve con scroll nativo + scroll-snap, el mismo
   mecanismo ya probado en .hero-carousel__track: el gesto táctil lo maneja el
   navegador, sin listeners de pointer/touch que puedan bloquearlo. view.js
   solo mueve las flechas de escritorio. Las tarjetas son tlx/product-card
   reutilizado tal cual, igual que en .cart-related__scroll. */
.mandos-carousel__viewport { position: relative; }
.mandos-carousel__track {
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  /* overflow-x:auto convierte también overflow-y en auto, así que el
     translateY(-2px) + sombra del :hover de .product-card se recortaba arriba.
     El padding vertical le deja sitio. */
  padding-top: var(--space-2);
  padding-bottom: var(--space-3);
}
.mandos-carousel__track::-webkit-scrollbar { display: none; }
/* height:auto anula el height:100% de .product-card: con una altura explícita
   el ítem flex deja de estirarse (el porcentaje no resuelve contra un
   contenedor de altura automática) y las tarjetas quedaban desiguales. */
.mandos-carousel__track > .product-card { flex: 0 0 260px; scroll-snap-align: start; height: auto; }
.mandos-carousel__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 44px; height: 44px; border-radius: 50%;
  border: 1.5px solid var(--color-border); background: rgba(255,255,255,0.94);
  color: var(--color-ink); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
  transition: background .15s, color .15s, border-color .15s;
}
.mandos-carousel__arrow:hover:not([disabled]) { background: var(--color-brand-orange); border-color: var(--color-brand-orange); color: var(--color-white); }
.mandos-carousel__arrow:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.mandos-carousel__arrow[disabled] { opacity: 0.35; cursor: default; }
/* Fuera de la fila de tarjetas: con left/right:8px la flecha izquierda caía
   encima de la primera tarjeta y tapaba su título (revisión del cliente:
   "debe verse como la de la derecha, no debe tapar ningún texto"). Los 80px
   de padding de .container dejan sitio para los 44px del botón.
   El -6px del top compensa el padding asimétrico del track (8px arriba,
   12px abajo), que descentraba el top:50%. */
.mandos-carousel__arrow { margin-top: -2px; }
.mandos-carousel__arrow--prev { left: -56px; }
.mandos-carousel__arrow--next { right: -56px; }
/* Entre 1024 y 1279px el viewport ya toca los bordes del contenedor: se
   vuelven adentro, pero alineadas con la foto del producto (no con el
   título), que es lo que pedía el cliente. */
@media (min-width: 1024px) and (max-width: 1279.98px) {
  .mandos-carousel__arrow { top: 130px; transform: none; margin-top: 0; }
  .mandos-carousel__arrow--prev { left: 4px; }
  .mandos-carousel__arrow--next { right: 4px; }
}
/* Sin desbordamiento no hay nada que recorrer: view.js marca is-static. */
.mandos-carousel__viewport.is-static .mandos-carousel__arrow { display: none; }
/* Las flechas solo por encima de 1024px. Entre 768 y 1023px quedaban encima de
   la primera y la última tarjeta tapando la foto del producto, y ahí el
   dispositivo es táctil: el arrastre ya cubre la navegación. */
@media (max-width: 1023.98px) {
  .mandos-carousel__arrow { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .mandos-carousel__track { scroll-behavior: auto; }
}

@media (max-width: 767.98px) {
  /* Menos de una tarjeta completa a la vista: deja asomar la siguiente y hace
     evidente que el carrusel se arrastra. */
  .mandos-carousel__track > .product-card { flex: 0 0 76%; }
}

/* --- ¿Qué es un telemando industrial? --- */
.section--que-es { padding: 88px 0; }
.que-es__grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 64px; align-items: center; }
.que-es__title { font-size: var(--text-h2); margin: 0 0 20px; }
.que-es__text { color: var(--color-steel); font-size: 17px; line-height: 1.7; margin: 0 0 16px; }
.que-es__chips { display: flex; gap: 10px; flex-wrap: wrap; margin: 20px 0 24px; }
.que-es__media { position: relative; border-radius: var(--radius-lg); overflow: hidden; height: 400px; }
.que-es__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.que-es__media .wp-block-image { height: 100%; margin: 0; display: block; }
.que-es__badge {
  position: absolute; right: 16px; bottom: 16px; z-index: 2;
  background: var(--color-brand-orange); color: #fff;
  border-radius: var(--radius-md); padding: 10px 16px;
  font-size: 12px; font-weight: 700; line-height: 1.25; text-align: center;
}
.que-es__badge strong { display: block; font-size: 18px; }
.que-es__link { color: var(--color-brand-orange); font-weight: 700; text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }
.que-es__link:hover { text-decoration: underline; }

@media (max-width: 767.98px) {
  .section--que-es { padding: 48px 0; }
  .que-es__grid { display: flex; flex-direction: column; gap: 24px; }
  .que-es__title { font-size: 24px; margin: 0 0 14px; }
  .que-es__text { font-size: 15px; line-height: 1.65; margin: 0 0 12px; }
  .que-es__chips { gap: 8px; margin: 14px 0 18px; }
  .que-es__media { height: 260px; }
  .que-es__badge { right: 12px; bottom: 12px; padding: 8px 12px; font-size: 11px; }
  .que-es__badge strong { font-size: 16px; }
  .que-es__link { font-size: 14px; }
}

/* --- Fabricantes especializados: 3 cards --- */
.section--feature { padding: 72px 0; }
.feature-section__header { text-align: center; max-width: 760px; margin: 0 auto 40px; }
.feature-section__header h2 { font-size: var(--text-h2); }
.feature-section__header p { color: var(--color-steel); font-size: var(--text-body-lg); margin-top: 12px; }
.feature-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.feature-card { background: var(--color-white); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: 28px 24px; display: flex; flex-direction: column; gap: 12px; transition: box-shadow .15s, transform .15s; }
.feature-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.feature-card__icon { width: 40px; height: 40px; color: var(--color-brand-orange); }
.feature-card__icon svg { width: 100%; height: 100%; display: block; }
.feature-card__title { font-family: var(--font-display); font-weight: 700; font-size: 22px; color: var(--color-ink); margin: 0; }
.feature-card__text { color: var(--color-steel); font-size: var(--text-body); margin: 0; line-height: 1.6; flex: 1; }
.feature-card__link { color: var(--color-brand-orange); font-weight: 700; text-decoration: none; font-size: var(--text-small); display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; }
.feature-card__link:hover { text-decoration: underline; }

@media (max-width: 1023.98px) {
  .feature-cards { grid-template-columns: 1fr; }
}
@media (max-width: 767.98px) {
  .section--feature { padding: 40px 0; }
  .feature-section__header { margin: 0 0 24px; }
  .feature-section__header h2 { font-size: var(--text-h3); }
  .feature-section__header p { font-size: 15px; margin-top: 10px; }
  .feature-cards { gap: 16px; }
  .feature-card { padding: 22px 18px; gap: 10px; }
  .feature-card__icon { width: 36px; height: 36px; }
  .feature-card__title { font-size: 19px; }
  .feature-card__text { font-size: 15px; line-height: 1.6; }
  .feature-card__link { font-size: 14px; }
}

/* --- Personaliza tu mando --- */
.section--flush { padding: 0; }
.big-section {
  display: grid; grid-template-columns: 1fr 1fr; align-items: center;
  gap: 64px; padding: 88px 0;
}
.big-section__title { font-family: var(--font-display); font-weight: 700; font-size: 38px; line-height: 1.12; margin: 0 0 16px; color: var(--color-ink); }
.big-section__text { color: var(--color-steel); font-size: 18px; line-height: 1.7; margin: 0 0 20px; }
.big-section__media { border-radius: var(--radius-lg); overflow: hidden; height: 360px; }
.big-section__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.big-section__media .wp-block-image { height: 100%; margin: 0; display: block; }

@media (max-width: 767.98px) {
  .big-section { display: flex; flex-direction: column; gap: 20px; padding: 48px 0; }
  .big-section__media { order: -1; height: 220px; }
  .big-section .btn { width: 100%; }
}

/* --- FAQ centrado --- */
.faq-centered { max-width: 840px; margin: 0 auto; }
.faq-centered__header { text-align: center; margin-bottom: 36px; }
.faq-centered__header p { color: var(--color-steel); font-size: var(--text-body-lg); margin-top: 12px; }
.faq-centered__footer { text-align: center; margin-top: 36px; display: flex; flex-direction: column; gap: 32px; align-items: center; }
.faq-centered__footer p { color: var(--color-steel); margin: 0; }

@media (max-width: 767.98px) {
  .faq-centered__header { margin-bottom: 24px; }
  .faq-centered__header h2 { font-size: 22px; }
  .faq-centered__header p { font-size: 15px; margin-top: 8px; }
  .faq-centered__footer { margin-top: 28px; gap: 14px; }
  .faq-centered__footer p { font-size: 14px; }
  .faq-centered__footer .btn { width: 100%; }
}

/* --- CTA final en claro (corrección "suavizar naranjas", propuesta cliente) --- */
.banner-cta--light { background: var(--color-white); }
.banner-cta--light .banner-cta__title { color: var(--color-ink); }
.banner-cta--light .banner-cta__text { color: var(--color-steel); }
.banner-cta__trust {
  display: flex; justify-content: center; gap: 28px; flex-wrap: wrap;
  margin-top: 28px; font-size: 13px; font-weight: 700; color: var(--color-steel);
}
.banner-cta__trust span { display: inline-flex; align-items: center; gap: 6px; }
.banner-cta__trust svg { width: 15px; height: 15px; color: var(--color-brand-orange); }

@media (max-width: 767.98px) {
  .banner-cta__trust { flex-direction: column; align-items: center; gap: 10px; }
  .banner-cta__trust svg { width: 14px; height: 14px; }
}

/* ============================================================
 * V3 Catálogo (PLP) — reskin de bloques NATIVOS de WooCommerce
 * (woocommerce/attribute-filter, woocommerce/stock-filter,
 * woocommerce/active-filters, woocommerce/catalog-sorting) para que
 * encajen visualmente en .filter-group/.filter-check/.active-filter-chip
 * ya existentes, sin tocar el marcado que generan (son bloques con
 * hidratación vía Interactivity API: en el servidor no pintan su lista de
 * checkboxes/chips, solo un contenedor que el JS del propio bloque rellena
 * en el navegador — por eso aquí solo se apuntan sus clases reales, no se
 * puede verificar visualmente en este entorno sin navegador; revisar en
 * una vista previa real).
 * ============================================================ */

/* Filtros del catálogo — bloques woocommerce/product-filter-* (Interactivity
   API). Sustituyen a los antiguos attribute-filter/stock-filter/active-filters,
   que recargaban la página entera en cada clic; estos actualizan la rejilla sin
   recargar. Las clases cambiaron por completo, así que estas reglas son nuevas.
   WooCommerce ya trae su propio CSS: aquí solo se ajusta lo que choca con el
   diseño del tema. */

/* El wrapper del bloque es un flex en COLUMNA con align-items:center por el
   soporte de layout: sin esto sus hijos salen centrados y encogidos al ancho de
   su contenido en vez de ocupar la columna. El gap se anula porque el ritmo
   vertical ya lo llevan los .filter-group. */
.filter-sidebar__filters,
.filter-drawer__body,
.active-filters {
  gap: 0;
  align-items: stretch;
}
.wc-block-product-filters__content { display: contents; }

/* WooCommerce envuelve cada lista en un <fieldset> sin clase, y su propia regla
   (.wc-block-product-filter-checkbox-list fieldset) no llega porque el fieldset
   es ancestro, no descendiente: quedaba con el borde "2px groove" por defecto
   del navegador alrededor de cada grupo. */
.filter-group fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;
}

.filter-group .wc-block-product-filter-checkbox-list__items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.filter-group .wc-block-product-filter-checkbox-list__label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  cursor: pointer;
  padding: var(--space-2) 0;
  min-height: 40px;
  width: 100%;
  font-size: var(--text-small);
  color: var(--color-ink);
}
/* El tamaño de la casilla se fija con font-size, NO con width/height: tanto el
   input como la marca de verificación (un ::before absoluto en top:0 left:0)
   miden 1em en el CSS de WooCommerce. Al forzar 18px solo en el input, la marca
   se quedaba en 14px y descuadrada hacia la esquina superior izquierda. */
.filter-group .wc-block-product-filter-checkbox-list__input-wrapper {
  font-size: 18px;
  flex-shrink: 0;
}
.filter-group input[type="checkbox"].wc-block-product-filter-checkbox-list__input {
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-white);
  cursor: pointer;
}
.filter-group input[type="checkbox"].wc-block-product-filter-checkbox-list__input:checked {
  border-color: var(--color-brand-orange);
  background: var(--color-brand-orange);
}
.filter-group input[type="checkbox"].wc-block-product-filter-checkbox-list__input:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
}
/* WooCommerce pinta un cuadrado de relleno (currentColor al 10%) detrás del
   input con un ::before del wrapper. Aquí el input ya lleva borde y fondo
   propios, así que ese relleno solo hacía que las casillas sin marcar
   parecieran marcadas. */
.filter-group .wc-block-product-filter-checkbox-list__input-wrapper::before { display: none; }
/* La marca de verificación la pinta WooCommerce en un <svg> hermano del input. */
.filter-group .wc-block-product-filter-checkbox-list__mark { color: var(--color-white); }
.filter-group .wc-block-product-filter-checkbox-list__count { color: var(--color-steel); }
/* Botón "Mostrar más" cuando la lista se recorta. */
.filter-group .wc-block-product-filter-checkbox-list__show-more-button {
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-brand-orange);
  margin-top: var(--space-2);
}

/* Chips de filtros activos (woocommerce/product-filter-active): chips y botón
   de limpiar en una sola fila alineada a la izquierda, no centrados y en
   líneas distintas como los deja el layout flex del bloque. */
.active-filters .wp-block-woocommerce-product-filter-active {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-2) var(--space-3);
}
.active-filters .wc-block-product-filter-removable-chips { justify-content: flex-start; }
.active-filters .wc-block-product-filter-removable-chips__items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}
.active-filters .wc-block-product-filter-removable-chips__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px 6px 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-mist);
  color: var(--color-ink);
  font-size: var(--text-caption);
  font-weight: 600;
}
.active-filters .wc-block-product-filter-removable-chips__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-steel);
  cursor: pointer;
  flex-shrink: 0;
}
.active-filters .wc-block-product-filter-removable-chips__remove:hover { color: var(--color-ink); }
.active-filters .wc-block-product-filter-removable-chips__remove-icon { width: 16px; height: 16px; }
/* El bloque del botón anida .wp-block-button, que trae text-align:center de
   core y lo sacaba del flujo de la fila. */
.active-filters .wp-block-woocommerce-product-filter-clear-button,
.active-filters .wp-block-woocommerce-product-filter-clear-button .wp-block-button {
  margin: 0;
  text-align: left;
}

/* Ordenación (woocommerce/catalog-sorting) — el className del bloque cae en
   el <div> exterior; el <select> real va anidado dentro de un <form>. */
.plp-toolbar__right .wc-block-catalog-sorting,
.sticky-mobile-bar .wc-block-catalog-sorting {
  display: flex;
}
.plp-toolbar__right .wc-block-catalog-sorting select,
.sticky-mobile-bar .wc-block-catalog-sorting select {
  min-height: 44px; /* zona pulsable mínima (WCAG 2.5.8); antes height:40px */
  /* Mismo chevron propio que .field__select, por el mismo motivo. */
  appearance: none;
  -webkit-appearance: none;
  background-image: var(--icon-chevron-down);
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 16px 16px;
  padding: 0 44px 0 var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 500;
  color: var(--color-ink);
  /* background-color, NO el atajo `background`: al ir después de
     background-image lo reseteaba a none y el chevron propio no se veía. */
  background-color: var(--color-white);
  cursor: pointer;
  outline: none;
}
.sticky-mobile-bar .wc-block-catalog-sorting { flex: 1; min-width: 0; }
.sticky-mobile-bar .wc-block-catalog-sorting select { width: 100%; }

/* Resultado de página vacío (woocommerce/product-collection-no-results) */
[data-block-name="woocommerce/product-collection-no-results"] {
  padding: var(--space-8) 0;
  color: var(--color-steel);
}

/* Sin resultados de búsqueda de producto (product-search-results.html) */
.search-results-main { padding-top: var(--space-8); padding-bottom: var(--space-8); }
@media (max-width: 767.98px) {
  .search-results-main { padding-top: var(--space-6); padding-bottom: var(--space-6); }
}
.search-empty { padding: var(--space-4) 0 var(--space-8); }
.search-empty__search { margin-left: auto; margin-right: auto; margin-bottom: var(--space-6); }

/* ============================================================
 * V7 — Nuestra historia
 * Fuente: diseño del cliente "Telemax - Nuestra Historia" (2026-08-17).
 * El mockup venía con paleta y tipografía propias; aquí se mapea a los tokens
 * del proyecto por decisión de proyecto: #D13B00 → --color-brand-orange,
 * #1a1512 → --color-ink, #5d554f/#6b625c → --color-steel,
 * #ded8d3/#e9e4e0 → --color-border, 1440px → --container-max, Archivo →
 * --font-display. #F4F4F4 ya coincide con --color-mist. No se añaden tokens
 * nuevos ni webfonts.
 * El mockup era solo desktop (medidas fijas: H1 70px, testimonio 54px,
 * tarjetas de 329px); el comportamiento responsive se ha autorado aquí con
 * clamp() y breakpoints del proyecto.
 * ============================================================ */

/* --- Sección 1: cabecera a sangre (tlx/historia-hero) ---
   Mismo mecanismo que .hero-mandos de la Home: media como <img>/<video> con
   object-fit:cover (nunca background-image, para que la foto salga de la
   biblioteca de medios), velo con alfa PLANO en la franja de texto —un
   gradiente que arranca bajo deja el subtítulo por debajo de 4,5:1— y el
   degradado lateral naranja del diseño encima. */
.historia-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--color-ink);
  color: var(--color-white);
  display: grid;
  align-items: center;
  min-height: clamp(420px, 62vh, 702px);
}
.historia-hero__media { position: absolute; inset: 0; z-index: 0; }
.historia-hero__media img,
.historia-hero__media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.historia-hero__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(254,80,0,0.55) 0%, rgba(254,80,0,0.12) 62%, rgba(254,80,0,0) 100%),
    linear-gradient(180deg, rgba(15,25,35,var(--hero-overlay, 0.65)) 0%, rgba(15,25,35,var(--hero-overlay, 0.65)) 100%);
}
.historia-hero__content {
  position: relative; z-index: 2;
  width: 100%; max-width: var(--container-max); margin: 0 auto;
  padding: var(--space-24) var(--container-padding-desktop);
}
.historia-hero__title {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(30px, 4.6vw, 64px); line-height: 1.06;
  letter-spacing: -0.025em;
  color: var(--color-white); margin: 0;
  max-width: 900px;
  text-shadow: 0 2px 12px var(--overlay-ink-soft);
}
.historia-hero__sub {
  font-size: clamp(16px, 1.6vw, 24px); line-height: 1.4;
  color: var(--color-white);
  margin: var(--space-6) 0 0; max-width: 820px;
  text-shadow: 0 1px 8px var(--overlay-ink-soft);
}
/* WCAG 2.2.2: un vídeo en autoplay+loop no se puede pausar. Misma guarda que
   .media-overlay__media[autoplay] y .hero-mandos__media video[autoplay]. */
@media (prefers-reduced-motion: reduce) {
  .historia-hero__media video[autoplay] { display: none; }
}
@media (max-width: 767.98px) {
  .historia-hero__content { padding: var(--space-16) var(--container-padding-mobile); }
  /* En móvil el degradado lateral no aporta (no hay ancho para el desvanecido)
     y resta contraste: se deja solo el velo plano. */
  .historia-hero__scrim {
    background: linear-gradient(180deg, rgba(15,25,35,var(--hero-overlay, 0.65)) 0%, rgba(15,25,35,var(--hero-overlay, 0.65)) 100%);
  }
}

/* El editor de bloques inserta wrappers propios (.block-editor-inner-blocks >
   .block-editor-block-list__layout) entre cada contenedor y sus hijos, y eso
   rompe el grid/flex: los hijos directos dejan de ser las tarjetas. Con
   display:contents esos wrappers salen del árbol de cajas y las tarjetas vuelven
   a ser hijas directas. Solo afecta al editor: estas clases no existen en el
   HTML del front. Mismo arreglo que .hero-carousel__track y .hero-mandos__ctas. */
.historia-valores__grid .block-editor-inner-blocks,
.historia-valores__grid .block-editor-block-list__layout,
.historia-equipo__grid .block-editor-inner-blocks,
.historia-equipo__grid .block-editor-block-list__layout,
.historia-timeline .block-editor-inner-blocks,
.historia-timeline .block-editor-block-list__layout {
  display: contents;
}

/* --- Sección 2: valores (tlx/valores-grid + tlx/valor-item) --- */
.historia-valores__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 600px) { .historia-valores__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .historia-valores__grid { grid-template-columns: repeat(4, 1fr); } }
/* Tarjeta blanca sobre la banda mist, radio pequeño y sin borde ni sombra: el
   contraste con el fondo ya la separa, igual que en el diseño. */
.valor-card {
  margin: 0;
  background: var(--color-white);
  border-radius: var(--radius-sm);
  padding: var(--space-12) var(--space-8);
  display: flex;
  flex-direction: column;
}
.valor-card__icon {
  width: 46px;
  height: 46px;
  flex: 0 0 auto;
  color: var(--color-brand-orange);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 0 var(--space-8);
}
.valor-card__icon svg { width: 100%; height: 100%; }
/* Cuando el editor sustituye el SVG por una imagen propia, se respeta su
   relación de aspecto dentro de la misma caja de 46px. */
.valor-card__icon--image { object-fit: contain; display: block; }
.valor-card__title {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  line-height: 1.25;
  color: var(--color-ink);
  margin: 0 0 var(--space-4);
}
.valor-card__text {
  font-size: var(--text-small);
  line-height: 1.5;
  color: var(--color-steel);
  margin: 0;
}
@media (max-width: 599.98px) {
  .valor-card { padding: var(--space-8) var(--space-6); }
  .valor-card__icon { margin-bottom: var(--space-4); }
}

/* --- Sección 3: equipo (tlx/equipo-grid + tlx/equipo-item) --- */
.historia-equipo__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-12);
}
@media (min-width: 768px) { .historia-equipo__grid { grid-template-columns: repeat(3, 1fr); } }
.equipo-card {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.equipo-card__photo {
  width: 100%;
  max-width: 259px;
  aspect-ratio: 1;
  border-radius: var(--radius-pill);
  object-fit: cover;
  background: var(--color-mist);
}
/* El placeholder del editor comparte la clase para ocupar el mismo hueco. */
.equipo-card__photo.img-placeholder { min-height: 0; }
.equipo-card__name {
  font-family: var(--font-display);
  font-size: var(--text-h4);
  font-weight: 700;
  color: var(--color-ink);
  margin: var(--space-12) 0 0;
}
/* El cargo va en ink, no en el naranja de marca del mockup: #FE5000 sobre
   blanco a 12px da 3,3:1 y AA exige 4,5:1 para texto pequeño. El acento visual
   lo mantienen las mayúsculas y el letter-spacing. */
.equipo-card__role {
  font-family: var(--font-display);
  font-size: var(--text-caption);
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-ink);
  margin: var(--space-3) 0 0;
}
.equipo-card__quote {
  font-size: var(--text-small);
  line-height: 1.55;
  font-style: italic;
  color: var(--color-steel);
  margin: var(--space-6) 0 0;
  max-width: 330px;
  border: 0;
  padding: 0;
}
@media (max-width: 767.98px) {
  .equipo-card__name { margin-top: var(--space-6); }
}

/* --- Sección 4: trayectoria (tlx/timeline + tlx/timeline-item) ---
   Desde 1024px los hitos alternan lado sobre una línea central. Por debajo pasa
   a una columna simple SIN línea: el mockup era solo desktop y una regla
   vertical sin marcador por hito, separada 48px de las tarjetas, se leía como un
   trazo suelto y además les robaba ancho en 390px. La alternancia es CSS puro
   (:nth-child(even)): el PHP no sabe la paridad del hito, así que reordenar
   hitos en el editor no la rompe. */
.historia-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
/* Columna única por defecto (móvil y tablet): año encima de la tarjeta, a todo
   el ancho. El año NUNCA se posiciona en absoluto, ni aquí ni en desktop: así la
   pastilla no puede solaparse con la tarjeta por larga que sea su etiqueta —hoy
   es "[PENDIENTE CLIENTE — año]", tres veces más ancha que el "2006" que asumía
   el diseño. */
.historia-timeline__item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}
.historia-timeline__year {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 76px;
  height: 34px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-brand-orange);
  /* Texto en ink, no blanco: blanco sobre #FE5000 son 3,3:1 y a 14px hace falta
     4,5:1. Ink sobre el mismo naranja da 5,38:1 y la pastilla sigue siendo
     naranja como en el diseño. */
  color: var(--color-ink);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-small);
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.historia-timeline__card {
  background: var(--color-white);
  border-radius: var(--radius-sm);
  padding: var(--space-8);
  align-self: stretch;
}
.historia-timeline__tag {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-h4);
  line-height: 1.25;
  color: var(--color-ink);
  margin: 0;
}
.historia-timeline__hito {
  font-size: var(--text-small);
  line-height: 1.55;
  color: var(--color-steel);
  margin: var(--space-3) 0 0;
}
@media (min-width: 1024px) {
  /* Desde 1024px los hitos alternan lado sobre una línea central. El año tiene
     su PROPIA columna (1fr auto 1fr), no va superpuesto: la columna central se
     ensancha con la etiqueta y las tarjetas se apartan solas, así que la
     pastilla nunca las pisa. La alternancia es CSS puro (:nth-child(even)), de
     modo que reordenar hitos en el editor no la rompe. */
  .historia-timeline { gap: var(--space-16); }
  .historia-timeline::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0; left: 50%;
    margin-left: -1px;
    width: 2px;
    background: var(--color-border-strong);
  }
  .historia-timeline__item {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    column-gap: var(--space-8);
    align-items: start;
  }
  .historia-timeline__year {
    grid-column: 2;
    grid-row: 1;
    margin-top: var(--space-8);
  }
  /* Impares a la izquierda, con el texto alineado hacia el eje central. */
  .historia-timeline__item .historia-timeline__card {
    grid-column: 1;
    grid-row: 1;
    text-align: right;
  }
  /* Pares a la derecha. */
  .historia-timeline__item:nth-child(even) .historia-timeline__card {
    grid-column: 3;
    text-align: left;
  }
}

/* --- Sección 5: testimonio (tlx/testimonio) --- */
/* Banda invertida (petición del cliente, 1-oct): fondo gris oscuro y texto en
   naranja, al revés de como salió del mockup. El naranja sobre grafito da
   4,69:1, así que la cita cumple AA incluso a tamaño de texto normal. */
.historia-testimonio {
  background: var(--color-graphite);
  color: var(--color-brand-orange);
}
.historia-testimonio__figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.historia-testimonio__mark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(80px, 10vw, 150px);
  line-height: 0.62;
  color: var(--color-brand-orange);
  /* Alto recortado a propósito: la comilla es ornamental y no debe abrir un
     hueco proporcional a su tamaño de fuente. */
  height: clamp(40px, 5vw, 74px);
}
.historia-testimonio__quote {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(22px, 3.4vw, 48px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--color-brand-orange);
  margin: var(--space-8) 0 0;
  border: 0;
  padding: 0;
}
/* La atribución NO va en naranja: a 15-20px exige 4,5:1 y el naranja se queda
   en 4,69:1, demasiado justo para texto secundario, además de que en naranja
   competiría con la cita. En mist sobre grafito da 14,6:1 y mantiene la
   jerarquía. */
.historia-testimonio__attribution {
  font-size: clamp(15px, 1.5vw, 20px);
  font-weight: 600;
  color: var(--color-mist);
  margin: var(--space-12) 0 0;
}

/* --- Sección 6: cierre (tlx/historia-cta-banner) ---
   BEM propio, NO .banner-cta: esas clases las comparten cuatro bloques más y
   tres plantillas, y darles este estilo habría cambiado la Home y la ficha de
   producto de rebote. */
/* La sección lleva id="contacto" para poder enlazarla; la cabecera es sticky, así
   que sin scroll-margin-top el titular acaba tapado al llegar al ancla. Mismo
   caso que #cat-showcase-title en la Home. */
#contacto { scroll-margin-top: calc(var(--header-sticky-offset) + var(--space-6)); }
.historia-cta__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.historia-cta__title {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--color-ink);
  margin: 0;
}
.historia-cta__text {
  font-size: var(--text-body-lg);
  line-height: 1.6;
  color: var(--color-steel);
  margin: var(--space-6) 0 0;
  max-width: 820px;
}
.historia-cta__btn { margin-top: var(--space-12); letter-spacing: 0.09em; }

/* ============================================================
 * Contacto (V8) — layout 2 columnas (formularios / datos de contacto)
 * ============================================================ */
.contact-layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
@media (min-width: 1024px) {
  .contact-layout {
    display: grid;
    grid-template-columns: 1fr 380px;
    gap: var(--space-16);
    align-items: start;
  }
  /* Sin sticky: el cliente pidió que los datos de contacto se queden
     estáticos y no se muevan con la pantalla. */
}

/* Tarjeta de formulario */
.contact-form-card {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.contact-form-card + .contact-form-card { margin-top: var(--space-6); }
@media (min-width: 1024px) {
  .contact-form-card { padding: var(--space-8); }
  .contact-form-card + .contact-form-card { margin-top: var(--space-8); }
}
.contact-form-card__title {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-2);
}
.contact-form-card__intro {
  font-size: var(--text-small);
  color: var(--color-steel);
  margin: 0 0 var(--space-6);
  line-height: 1.5;
}

/* Rejilla de campos del formulario: 1 columna en móvil, 2 en desktop */
.form-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
@media (min-width: 1024px) {
  .form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  .form-grid .field--full { grid-column: 1 / -1; }
}
.form-actions { margin-top: var(--space-6); }
@media (max-width: 1023px) {
  .form-actions .btn { width: 100%; justify-content: center; }
}
.field__label .req { color: var(--color-brand-orange); margin-left: 2px; }

.field p {
  margin: 0;
}

/* --- Formulario unificado: selector de motivo + campos condicionales ---
   Un solo formulario cubre presupuesto, reparación y consulta general; el
   desplegable "motivo" decide qué campos se ven (assets/js/contact-form.js).
   El selector se separa del resto para que se lea como el primer paso. */
.contact-form__motivo {
  padding-bottom: var(--space-6);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border);
}
@media (min-width: 1024px) {
  .contact-form__motivo .field { max-width: 420px; }
}
/* El atributo hidden por sí solo no gana a `display:flex` de .field ni a los
   display de los textos de ayuda, así que hay que declararlo por selector. */
.field[hidden],
.field__helper[hidden],
.field__label .req[hidden] { display: none; }

/* Ancla de destino sin contenido: existe solo para que #reparacion y #general
   sigan llevando a la tarjeta única (hay enlaces a esas anclas por toda la web).
   Se compensa el alto de la cabecera sticky, igual que en el resto de anclas. */
.u-anchor {
  display: block;
  height: 0;
  scroll-margin-top: calc(var(--header-sticky-offset) + var(--space-6));
}
#presupuesto { scroll-margin-top: calc(var(--header-sticky-offset) + var(--space-6)); }

/* Contact Form 7 envuelve cada control en <span class="wpcf7-form-control-wrap">;
   al ser hijo directo de ".field" (flex column) ese span se estira a todo el
   ancho, pero el <input>/<textarea> real que hay dentro necesita su propio
   width:100% para ocupar ese ancho (si no, conserva el tamaño intrínseco). */
.field .wpcf7-form-control-wrap { display: block; width: 100%; }
.field__input,
.field__select,
.field__textarea { width: 100%; }
/* CF7 mete un <br> detrás de cada control con su formateo automático. Dentro de
   .field, que ya es un flex column con gap, ese salto de línea añade un hueco
   extra entre el campo y su texto de ayuda. */
.field br { display: none; }

/* Campos ocultos de Contact Form 7 */
.wpcf7 .hidden-fields-container {
  display: none;
}

/* Mensajes de validación/envío nativos de CF7 */
.wpcf7-response-output {
  margin: var(--space-4) 0 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-small);
  border: 1px solid var(--color-border);
}
.wpcf7-form.sent .wpcf7-response-output { border-color: var(--color-success); color: var(--color-ink); }
.wpcf7-form.invalid .wpcf7-response-output,
.wpcf7-form.unaccepted .wpcf7-response-output,
.wpcf7-form.spam .wpcf7-response-output,
.wpcf7-form.failed .wpcf7-response-output,
.wpcf7-form.aborted .wpcf7-response-output { border-color: var(--color-danger); color: var(--color-danger); }
.wpcf7-not-valid-tip { display: block; margin-top: var(--space-1); font-size: var(--text-caption); color: var(--color-danger); }

/* Aside con datos de contacto */
.contact-info-card {
  background: var(--color-mist);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
@media (min-width: 1024px) {
  .contact-info-card { padding: var(--space-8); }
}
.contact-info-card__title {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 var(--space-4);
}
@media (min-width: 1024px) {
  .contact-info-card__title { margin: 0 0 var(--space-6); }
}
.contact-info-item {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4) 0;
  border-top: 1px solid var(--color-border);
}
.contact-info-item:first-of-type { border-top: none; padding-top: 0; }
.contact-info-item__icon {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-brand-orange);
}
@media (min-width: 1024px) {
  .contact-info-item__icon { width: 36px; height: 36px; }
}
.contact-info-item__label {
  font-size: var(--text-caption);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-steel);
  margin: 0 0 2px;
}
.contact-info-item__value {
  font-size: var(--text-body);
  color: var(--color-ink);
  line-height: 1.4;
  margin: 0;
}
.contact-info-item__value a { color: var(--color-ink); font-weight: 600; }
.contact-info-item__value a:hover { color: var(--color-brand-orange); }

/* Hueco del mapa en la tarjeta de contacto: se pinta como marcador rayado
   mientras no haya imagen asignada (mapImageUrl); con imagen, la variante
   --image lo sustituye. Ver blocks/contact-info-card. */
.contact-map-placeholder {
  margin-top: var(--space-4);
  height: 180px;
  border-radius: var(--radius-md);
  background: repeating-linear-gradient(45deg, var(--color-mist), var(--color-mist) 12px, #EAEAEA 12px, #EAEAEA 24px);
  border: 1px dashed var(--color-graphite-soft);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  color: var(--color-steel);
  text-align: center;
  padding: var(--space-4);
}
@media (min-width: 1024px) {
  .contact-map-placeholder { margin-top: var(--space-6); height: 200px; }
}
.contact-map-placeholder span { font-size: var(--text-small); font-weight: 600; }

/* --- Mapa de Google con carga por consentimiento --- */
/* El iframe existe en el DOM sin src: hasta que se pulsa "Ver mapa" solo se ve
   el botón. Al cargar, .is-loaded lo revela y esconde el botón. */
.contact-map {
  position: relative;
  margin-top: var(--space-4);
  height: 220px;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-mist);
}
@media (min-width: 1024px) {
  .contact-map { margin-top: var(--space-6); height: 260px; }
}
.contact-map__consent {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  width: 100%;
  padding: var(--space-4);
  border: none;
  background: var(--color-mist);
  color: var(--color-steel);
  font-family: var(--font-body);
  text-align: center;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.contact-map__consent:hover { background: var(--color-white); color: var(--color-ink); }
.contact-map__consent:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.contact-map__consent-title { font-size: var(--text-small); font-weight: 700; color: var(--color-ink); }
.contact-map__consent-note { font-size: var(--text-caption); max-width: 260px; line-height: 1.4; }
.contact-map__frame { width: 100%; height: 100%; border: 0; display: block; }
.contact-map.is-loaded .contact-map__consent { display: none; }
/* Enlace de respaldo: es lo único que queda si no hay JS, y por eso se
   mantiene visible bajo el mapa una vez cargado. */
.contact-map__link {
  position: absolute;
  right: var(--space-2);
  bottom: var(--space-2);
  z-index: 3;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-white);
  font-size: var(--text-caption);
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
  box-shadow: var(--shadow-sm);
}
.contact-map__link:hover { color: var(--color-brand-orange); }
.contact-map-placeholder--image {
  /* Desde la revisión del cliente es un <a> a Google Maps, no un <div>. */
  display: block;
  background: none;
  border: none;
  padding: 0;
  overflow: hidden;
}
.contact-map-placeholder--image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* ============================================================
 * V7 — Checkout (reskin de bloques nativos de WooCommerce)
  * Fuente: telemax-design-hub/docs/pages/V7-checkout-{desktop,mobile}.
 * ============================================================ */
.wc-block-components-address-form__telemax-cif::after {
  line-height: 1;
}

.wp-block-woocommerce-checkout-order-summary-block .wc-block-components-checkout-order-summary__title {
  margin-top: 0;
}

.wp-block-woocommerce-checkout-order-summary-block .wc-block-components-checkout-order-summary__title .wc-block-components-checkout-order-summary__title-text {
  margin: 0;
}

/* ============================================================
 * Páginas legales (post-content genérico vía index.html: términos,
 * privacidad, devoluciones...).
 * Scope explícito a body.page, excluyendo cart/checkout/my-account
 * (mismas clases wp-block-post-title/-content pero con su propia
 * plantilla page-*.html y layout ya maquetado) para no tocarlas.
 * Sin bloques propios -> blockGap global "0" las deja sin espaciado.
 * ============================================================ */
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-title {
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding-inline: var(--container-padding-desktop);
  padding-block-start: var(--wp--preset--spacing--24);
}

body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content {
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding-inline: var(--container-padding-desktop);
  padding-block: var(--wp--preset--spacing--8) var(--wp--preset--spacing--32);
}

@media (max-width: 767.98px) {
  body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-title {
    padding-inline: var(--container-padding-mobile);
    padding-block-start: var(--wp--preset--spacing--12);
  }

  body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content {
    padding-inline: var(--container-padding-mobile);
    padding-block: var(--wp--preset--spacing--6) var(--wp--preset--spacing--16);
  }
}

body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > * {
  margin-block: 0;
}

/* Tamaños de las páginas legales: el texto corrido salía al tamaño por defecto
   y el cliente lo pidió distinto (22-sep). Cuerpo algo mayor y jerarquía clara
   entre los apartados numerados. */
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content {
  font-size: var(--text-body-lg);
  line-height: 1.7;
  color: var(--color-steel);
}
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content h2 {
  font-size: var(--text-h3);
  color: var(--color-ink);
}
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content h3 {
  font-size: var(--text-h4);
  color: var(--color-ink);
}
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content strong {
  color: var(--color-ink);
}

body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > * + * {
  margin-block-start: var(--wp--preset--spacing--8);
}

body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > h1 + *,
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > h2 + *,
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > h3 + *,
body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > h4 + * {
  margin-block-start: var(--wp--preset--spacing--4);
}

body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > h2 {
  margin-block-start: var(--wp--preset--spacing--16);
}

body.page:not(.woocommerce-cart):not(.woocommerce-checkout):not(.woocommerce-account) .wp-block-post-content > :first-child {
  margin-block-start: 0;
}

/* Las reglas de arriba están scopeadas a body.page y la ficha de producto es
   body.single-product, así que el contenido del producto (pestaña Descripción)
   se quedaba sin espaciado: con blockGap "0", "Aplicaciones" y "Funciones"
   salían pegadas a la lista anterior. El cliente pidió más aire entre esos
   títulos. Solo espaciado: el ancho y el padding los da .tab-desc-grid. */
.pdp-tab-panel .wp-block-post-content > * { margin-block: 0; }
.pdp-tab-panel .wp-block-post-content > * + * { margin-block-start: var(--space-4); }
.pdp-tab-panel .wp-block-post-content > h2,
.pdp-tab-panel .wp-block-post-content > h3 { margin-block-start: var(--space-8); }
.pdp-tab-panel .wp-block-post-content > h2 + *,
.pdp-tab-panel .wp-block-post-content > h3 + *,
.pdp-tab-panel .wp-block-post-content > h4 + * { margin-block-start: var(--space-3); }
.pdp-tab-panel .wp-block-post-content > :first-child { margin-block-start: 0; }
.pdp-tab-panel .wp-block-post-content ul,
.pdp-tab-panel .wp-block-post-content ol { padding-left: var(--space-6); }
.pdp-tab-panel .wp-block-post-content li + li { margin-top: var(--space-1); }

/* Caja "Fabricado en España" de la ficha: antes iba con estilos inline en el
   wp:html de la plantilla y el SVG se comprimía porque no tenía flex-shrink:0,
   lo que dejaba el icono descentrado y desplazado (revisión del cliente). */
.pdp-made-in {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  background: var(--color-mist);
  border-radius: var(--radius-md);
}
.pdp-made-in__icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-brand-orange);
}
.pdp-made-in__title {
  margin: 0 0 var(--space-1);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
}
.pdp-made-in__text {
  margin: 0;
  font-size: var(--text-caption);
  color: var(--color-steel);
  line-height: 1.5;
}

/* Descargo de marcas registradas, justo debajo de las fotos del producto (el
   cliente lo situó ahí el 8-oct-2026). Lo inyecta
   includes/product-legal-notice.php del plugin detrás de tlx/pdp-gallery, solo
   en la categoría `plataformas`. Es un aviso legal, no una llamada a la acción:
   tipografía pequeña y color de apoyo, sin fondo de color que compita con la
   caja "Fabricado en España" que tiene justo debajo. */
.pdp-legal-notice {
  margin-top: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.pdp-legal-notice__title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
}
.pdp-legal-notice__text {
  margin: 0;
  font-size: var(--text-caption);
  color: var(--color-steel);
  line-height: 1.6;
}
@media (max-width: 767.98px) {
  /* .pdp-layout pierde el padding lateral por debajo de 768px y la columna va a
     sangre; un recuadro con borde pegado a los bordes de la pantalla queda mal,
     así que se quedan solo las líneas de arriba y abajo. */
  .pdp-legal-notice {
    border-inline: none;
    border-radius: 0;
  }
}

/* --- Aviso flotante al añadir al carrito ---------------------------------
   El cliente reportó el 8-oct-2026 que "el carrito no funciona" al añadir desde
   la tienda: sí funcionaba, pero la única señal era el enlace "Ver carrito" que
   deja add-to-cart.js. Esto es la confirmación visible; el contador del header
   lo repinta el fragmento de includes/cart-fragments.php.

   z-index 200: por encima de la barra fija de móvil (150) y del header
   (100/101), y por debajo del cajón de filtros (299/300) y del visor de la
   galería (400), que si están abiertos deben taparlo. */
.tlx-cart-toast {
  position: fixed;
  z-index: 200;
  right: var(--space-6);
  bottom: var(--space-6);
  max-width: 340px;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-success);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity .2s ease, transform .2s ease, visibility 0s linear .2s;
}
.tlx-cart-toast.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity .2s ease, transform .2s ease, visibility 0s;
}
.tlx-cart-toast__icon {
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--color-success-text);
}
.tlx-cart-toast__body { flex: 1; min-width: 0; }
.tlx-cart-toast__title {
  margin: 0;
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--color-ink);
}
.tlx-cart-toast__link {
  display: inline-block;
  margin-top: var(--space-1);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-brand-orange);
  text-decoration: none;
}
.tlx-cart-toast__link:hover { text-decoration: underline; }
.tlx-cart-toast__close {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--color-steel);
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.tlx-cart-toast__close:hover { background: var(--color-mist); color: var(--color-ink); }
@media (max-width: 767.98px) {
  .tlx-cart-toast {
    left: var(--space-4);
    right: var(--space-4);
    max-width: none;
  }
  /* Por encima de la barra fija de la ficha (su alto real lo mide
     assets/js/sticky-bar.js en --sticky-bar-h). */
  body:has(.sticky-mobile-bar) .tlx-cart-toast {
    bottom: calc(var(--sticky-bar-h, 80px) + var(--space-3));
  }
}
@media (prefers-reduced-motion: reduce) {
  .tlx-cart-toast,
  .tlx-cart-toast.is-visible {
    transform: none;
    transition: opacity .01ms, visibility .01ms;
  }
}

/* ============================================================
 * Impresión — ocultar header/footer
 * ============================================================ */
@media print {
  header.wp-block-template-part,
  footer.wp-block-template-part,
  .sticky-mobile-bar {
    display: none !important;
  }
}
/* ============================================================
 * CookieYes (plugin de consentimiento, instalado en la revisión)
 * ============================================================ */
/* Su botón flotante de "preferencias" se coloca fijo abajo a la izquierda y
   caía justo encima de la barra fija de filtros de la tienda y de la de compra
   de la ficha. Se sube por encima de ellas en móvil. */
@media (max-width: 1023.98px) {
  body .cky-btn-revisit-wrapper { bottom: 84px; left: 90%; }
}
@media (max-width: 768px) {
  body .cky-btn-revisit-wrapper { left: 85%; }
}
