/* ============================================================
   SUPER SERVICE 4X4 — «LA ORDEN DE TRABAJO»
   Sistema v2 tras tribunal adversarial. Ver DISENO.md.
   Papel técnico frío · tinta-navy · señal amarilla · ángulo 65°.
   Cero dependencias. Solo transform/opacity en animación.
   ============================================================ */

/* ---------- 0 · TIPOS (autoalojados) ----------
   Antes venían de fonts.googleapis.com/fonts.gstatic.com en cada página: dos
   dominios externos (DNS+TLS aparte) solo para el CSS, más el propio archivo.
   Con el cache particionado por sitio de los navegadores desde ~2023, ya no
   había ahorro real de compartir el CDN de Google entre sitios — así que
   autoalojar es puro ahorro, sin contrapartida. Un único .woff2 variable por
   familia (recorte a "latin": cubre español entero, U+0000-00FF) en vez de
   los ~10 subconjuntos (cirílico, griego, vietnamita…) que Google manda por
   si acaso. */
@font-face{
  font-family:"Archivo";font-style:normal;font-weight:100 900;font-stretch:62% 125%;
  font-display:swap;src:url("fuentes/archivo-variable.woff2") format("woff2");
}
@font-face{
  font-family:"Roboto Mono";font-style:normal;font-weight:100 700;
  font-display:swap;src:url("fuentes/roboto-mono-variable.woff2") format("woff2");
}
/* Instancia estática (peso 700, el único que usan los precios) del mismo
   Roboto Mono con un solo cambio: el glifo del cero sin la barra cruzada.
   El .woff2 variable de arriba no trae features de GSUB (subconjunto de
   Google sin ellas) — sin "zero" que activar/desactivar, la barra viene
   soldada al contorno del glifo. Se editó el contorno directamente con
   fontTools (se le quitó el tercer contorno, la barra) y se generó esta
   instancia aparte en vez de tocar la variable de arriba, para no arriesgar
   el resto de pesos/usos de --mono (SKUs, horas…) que sí quieren distinguir
   0 de O (feedback del director, precios ilegibles con la barra). */
@font-face{
  font-family:"Roboto Mono Precio";font-style:normal;font-weight:700;
  font-display:swap;src:url("fuentes/roboto-mono-700-cero-limpio.woff2") format("woff2");
}

/* ---------- 1 · TOKENS ---------- */
:root{
  --papel:#EDEEF1;
  --papel-2:#E3E4E7;
  /* Quinto escalón (tabla/formulario/resumen de cotización): --placa →
     --papel-2 (rechazado, "se ve mucho") → --papel (rechazado, idéntico
     al fondo, "no se distingue") → #EAEBEE (rechazado, "sube poco") →
     este, otro empujón, todavía lejos de --papel-2. */
  --papel-3:#E8E9EC;
  --placa:#F5F6F8;
  --tinta:#12181F;
  --tinta-2:#3A4350;
  --panel:#05182E;
  --navy:#002856;
  --senal:#E8AD0A;
  --ok:#2E5E3A;
  --no:#8C2F23;
  --linea:rgba(18,24,31,.16);
  --linea-f:rgba(18,24,31,.34);
  /* Más suave aún que --linea: separadores internos de listas densas (filas
     de la tabla de cotización), donde --linea ya se sentía como una regla
     de verdad en vez de un simple corte entre partidas (feedback del
     director: "líneas divisorias... más finas y discretas"). */
  --linea-xf:rgba(18,24,31,.09);
  --linea-clara:rgba(246,246,243,.14);
  --linea-clara-f:rgba(246,246,243,.32);
  /* Criterio de forma en móvil (feedback del director, opción «Suave»): botones
     grandes y controles cuadrados a 12px; chips y filtros en píldora. Se usa en
     @media(max-width:720px) — el escritorio conserva su esquina recta. */
  --r-boton:12px;
  --r-chip:999px;

  --sans:"Archivo",system-ui,sans-serif;
  /* Roboto Mono, no IBM Plex Mono: el cero de Plex lleva un punto en el centro
     (rasgo propio del tipo, no un font-feature activable) — sin utilidad real
     aquí (precios, horas, teléfonos, sin riesgo de confundir 0 con O) y se leía
     recargado. Roboto Mono tiene el mismo peso/caja pero el cero va limpio. */
  --mono:"Roboto Mono",ui-monospace,monospace;

  /* Ángulo del sistema: 65°, medido del contorno del rino. tan(65°)≈2.14 */
  --corte-x:14px;
  --corte-y:30px;

  --ancho:1360px;
  --e-out:cubic-bezier(0.22,1,0.36,1);
  --e-swift:cubic-bezier(0.32,0.72,0,1);
  --masthead:68px;

  /* compat intro.css (secuencia de entrada validada) */
  --negro:#05070a;
  --blanco:#fff;
  --fuente:var(--sans);
}

/* ---------- 2 · BASE ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* text-size-adjust:100%: iOS Safari en horizontal INFLA el texto de los bloques que
   considera «pequeños» (font boosting): el copyright del pie, de 14px, salía a ~20px en
   un iPhone apaisado (director, 25-sep-2026). Sin esto los tamaños del CSS no mandan.
   Solo se nota en un iPhone real: ni el WebKit de escritorio ni el headless lo aplican. */
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%}
html,body{overflow-x:clip}
/* Móvil: la página se desplaza dentro de <body>, no en la ventana («raíz 2»,
   24-sep-2026). Al desplazar la ventana, Safari (iOS 26) y Chrome encogen sus
   barras y lo fijo abajo —pestaña del vehículo, barra de precio— se despega o
   queda tapado; así las barras no se mueven y lo de abajo queda pegado (medido
   en vídeo: iPhone en los tres modos de Safari y Android con Chrome y Firefox,
   barra arriba y abajo). El 1px de menos evita que Chrome tome <body> por la
   ventana y vuelva a esconder su barra. Coste asumido: las barras se ven siempre
   y no hay «tirar para recargar». Quien escuche el scroll usa SS.despY y
   SS.alDesplazar (sistema.js), que valen para los dos casos. :where() deja la
   especificidad en la de «body»: el bloqueo de intro.css sigue mandando. En modo
   QA (?directo) no se aplica, para que las capturas de página entera y
   ?scroll=N sigan funcionando. */
@media (max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){
  html:not(.qa){height:100%;overflow:hidden}
  :where(html:not(.qa)) body{height:calc(100% - 1px);overflow-x:hidden;overflow-y:auto;scroll-behavior:smooth}
}
/* --masthead-total lo fija sistema.js (ResizeObserver sobre .masthead real):
   el token --masthead se queda fijo en 68px, pero la cabecera mide menos al
   condensar (56px) y más con la píldora del vehículo activo (~48px extra) —
   sin esto los anclajes caían bajo el riel o dejaban un hueco de más. El
   fallback a --masthead cubre el instante antes de que corra el JS. */
[id]{scroll-margin-top:calc(var(--masthead-total, var(--masthead)) + 16px)}
body{
  font-family:var(--sans);
  font-variation-settings:"wdth" 100;
  background:var(--papel);
  color:var(--tinta);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img{max-width:100%;display:block}
/* Fundido de entrada de las fotos con loading="lazy" — sistema.js añade
   .cargada en cuanto termina de cargar. Sin esto, entran de golpe al hacer
   scroll (hueco en blanco → foto, se nota). */
img[loading="lazy"],img.precarga{opacity:0;transition:opacity .25s var(--e-swift)}
img[loading="lazy"].cargada,img.precarga.cargada{opacity:1}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
::selection{background:var(--navy);color:var(--papel)}
:focus-visible{outline:2px solid var(--navy);outline-offset:3px}
.en-panel :focus-visible,.pie :focus-visible{outline-color:var(--senal)}
.oculto{display:none!important}

.salto{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--navy);color:var(--papel);padding:10px 18px;
  font:600 13px/1 var(--sans);letter-spacing:.06em;
}
.salto:focus{left:0}

.contenedor{max-width:var(--ancho);margin:0 auto;padding-inline:clamp(18px,4vw,44px)}

/* ---------- 3 · TIPOGRAFÍA ---------- */
h1,h2,h3{font-weight:800;text-wrap:balance}
.display{
  font-size:clamp(2.6rem,6.4vw,6rem);
  font-variation-settings:"wdth" 125;
  font-weight:800;line-height:.92;letter-spacing:-.01em;
  text-transform:uppercase;
}
.t-h2{
  font-size:clamp(1.9rem,3.6vw,3.2rem);
  font-variation-settings:"wdth" 110;
  line-height:.98;letter-spacing:-.01em;text-transform:uppercase;
}
.t-h3{font-size:clamp(1.15rem,1.6vw,1.4rem);font-weight:700;line-height:1.15}
p{max-width:62ch;text-wrap:pretty}
.parrafo{color:var(--tinta-2);font-size:1rem}
.label{
  font:600 11px/1.2 var(--sans);
  letter-spacing:.14em;text-transform:uppercase;color:var(--tinta-2);
}
.dato{font-family:var(--mono);font-variant-numeric:tabular-nums}
.folio{
  font:500 11px/1 var(--mono);letter-spacing:.12em;
  color:var(--tinta-2);font-variant-numeric:tabular-nums;
}
.condensado{font-variation-settings:"wdth" 80}

/* ---------- 4 · GEOMETRÍA ---------- */
.corte{clip-path:polygon(0 0,calc(100% - var(--corte-x)) 0,100% var(--corte-y),100% 100%,0 100%)}
.corte-suave{--corte-x:9px;--corte-y:19px}
/* El corte por defecto (14/30) se calibró contra cajas chicas (.lamina,
   .bloque-totales, ~150-280px de alto): en una caja grande el mismo corte se
   ve minúsculo, un nick sin querer más que un ángulo de marca (hallazgo
   propio, .lead-form en cotización — "sigue fallando"). Mismo ratio que ya
   usa .mapa en contacto.astro para su propia caja grande, en vez de inventar
   un tercer valor. */
.corte-grande{--corte-x:20px;--corte-y:43px}
.regla{border:none;border-top:1px solid var(--linea-f);position:relative;overflow:visible}
.regla::after{ /* remate a 65° de cada regla de sección */
  content:"";position:absolute;right:0;top:-1px;width:14px;height:30px;
  border-right:1px solid var(--linea-f);
  transform-origin:top right;transform:skewX(-25deg);
}

/* ---------- 5 · MASTHEAD (riel de cajetín) ---------- */
.masthead{
  position:sticky;top:0;z-index:60;
  background:color-mix(in srgb,var(--panel) 94%,transparent);
  backdrop-filter:blur(10px);
  border-bottom:1px solid var(--linea-clara);
  color:var(--papel);
}
.masthead-fila{
  max-width:var(--ancho);margin:0 auto;
  display:flex;align-items:stretch;
  height:var(--masthead);
  padding-inline:clamp(18px,4vw,44px);
  transition:height .42s var(--e-swift);
}
.masthead.condensa .masthead-fila{height:56px}
.masthead .celda{
  display:flex;align-items:center;
  padding-inline:clamp(12px,1.6vw,22px);
}
.masthead .celda:first-child{padding-left:0}
.masthead .celda:last-child{padding-right:0}
.masthead-logo img{height:34px;width:auto;transition:height .42s var(--e-swift)}
.masthead.condensa .masthead-logo img{height:27px}
/* Nav: en el fallback flex (móvil) crece y centra su contenido en el hueco libre;
   en escritorio (media query más abajo) queda centrado de verdad en todo el riel. */
.masthead-nav{flex:1;justify-content:center;gap:clamp(14px,2vw,30px)}
.masthead-nav a{
  font:600 12.5px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;
  color:rgba(246,246,243,.78);padding:6px 2px;position:relative;
  transition:color .24s var(--e-swift);
}
/* Ampliación invisible de diana táctil (::before, no ::after: el ::after ya lo usa
   la rayita de abajo). Vertical generosa (dentro del propio masthead-fila, sin
   vecino arriba/abajo); horizontal contenida a -4px porque el gap entre enlaces
   baja hasta 14px en viewports estrechos — con -4px por lado nunca llega a
   solaparse (8px < 14px). Visible en tablet táctil (721-920, nav sigue en el
   riel) y en portátiles/iPads con puntero fino sobre el nav de escritorio. */
.masthead-nav a::before{content:"";position:absolute;inset:-11px -4px}
@media(hover:hover){.masthead-nav a:hover{color:var(--papel)}}
.masthead-nav a[aria-current]{color:var(--papel)}
/* Con el mega-panel de Productos abierto, el trigger se queda "encendido" con
   el mismo tratamiento que la página activa — sin esto, en cuanto el cursor
   baja del link hacia el panel, Productos se apaga y el panel se ve como un
   bloque suelto, sin dueño (feedback del director). */
.masthead-nav a[aria-expanded="true"]{color:var(--papel)}
/* Rayita bajo el enlace: tenue y solo al pasar el cursor; sólida y blanca en
   la página activa — mismo lenguaje, dos intensidades distintas. Blanca y no
   ámbar: el ámbar es la señal reservada para llamadas a la acción, no para
   "estás aquí". */
.masthead-nav a::after{
  content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;
  background:rgba(246,246,243,.5);transform:scaleX(0);transform-origin:left;
  transition:transform .24s var(--e-swift);
}
@media(hover:hover){.masthead-nav a:hover::after{transform:scaleX(1)}}
.masthead-nav a[aria-current]::after,
.masthead-nav a[aria-expanded="true"]::after{background:var(--papel);transform:scaleX(1)}
/* Bloque de acciones: buscar · cotización, agrupados y pegados al borde
   derecho — el mismo borde donde cae la placa ARB del hero. */
.masthead-acciones{display:flex;align-items:stretch;gap:clamp(10px,1.2vw,16px)}
.masthead-cotizacion{
  font:600 12px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;
  display:flex;align-items:center;gap:7px;color:var(--papel);
  padding-left:clamp(12px,1.6vw,18px);
}
/* Mismo subrayado que el resto del riel (.masthead-nav a::after), en vez del
   contador virando a navy sólido al pasar el mouse — quedaba demasiado
   golpeado para un simple hover (feedback del director).
   El ::after cuelga de este span interno, no del <a>: el <a> se estira a toda
   la altura del riel (align-items:stretch del bloque de acciones), así que
   "abajo" ahí es el borde del header entero, no el texto — el subrayado
   aparecía flotando muy por debajo de COTIZACIÓN (hallazgo del director).
   Mismo truco que .celda-buscar-texto, que ya lo hacía bien. */
.masthead-cotizacion-texto{position:relative}
.masthead-cotizacion-texto::after{
  content:"";position:absolute;left:0;right:0;bottom:-8px;height:2px;
  background:rgba(246,246,243,.5);transform:scaleX(0);transform-origin:left;
  transition:transform .24s var(--e-swift);
}
@media(hover:hover){.masthead-cotizacion:hover .masthead-cotizacion-texto::after{transform:scaleX(1)}}
/* Contador entre corchetes, sin caja: mono y discreto — no un badge sólido
   (feedback del director: "más elegante, como un 3 entre []"). */
.masthead-cotizacion b{
  font:500 12px/1 var(--mono);font-weight:500;
  color:rgba(246,246,243,.68);transition:color .2s var(--e-swift);
}
.masthead-cotizacion b::before{content:"["}
.masthead-cotizacion b::after{content:"]"}
@media(hover:hover){.masthead-cotizacion:hover b{color:var(--papel)}}
/* especificidad > .masthead .celda (que pone display:flex) */
.masthead .celda.btn-menu{
  display:none;justify-content:center;width:44px;padding:0;margin-right:-11px;
  color:var(--papel);
}
.btn-menu svg{width:24px;height:24px;stroke:currentColor;stroke-width:2;stroke-linecap:round;fill:none;overflow:visible}
.btn-menu svg path{transform-box:fill-box;transform-origin:center;transition:transform .32s var(--e-swift)}
/* dos rayas que se cruzan en ✕ al abrir (la clase va en <html>, ver sistema.js) */
.menu-abierto .btn-menu .raya-1{transform:translateY(4px) rotate(45deg)}
.menu-abierto .btn-menu .raya-2{transform:translateY(-4px) rotate(-45deg)}
/* el riel pasa por encima del velo mientras el menú está abierto: el botón
   (ya ✕) sigue siendo tocable; antes el velo lo tapaba entero */
.menu-abierto .masthead{z-index:100}

/* Escritorio: riel en grid de 3 pistas — logo | nav centrado de verdad | acciones.
   Las pistas laterales son iguales (1fr/1fr), así que la del medio (auto) queda
   centrada en todo el ancho del riel, sin importar que el bloque de acciones
   pese más que el logo. */
@media(min-width:921px) and (min-height:501px),(min-width:1001px){
  .masthead-fila{display:grid;grid-template-columns:1fr auto 1fr}
  .masthead-logo{justify-self:start}
  .masthead-nav{justify-self:center}
  .masthead-acciones{justify-self:end}
}

/* ---------- Mega-panel de productos (despliegue del expediente) ---------- */
.mega{
  position:absolute;left:0;right:0;top:100%;
  background:var(--papel);border-bottom:1px solid var(--linea-f);
  border-top:1px solid var(--linea);
  opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:opacity .24s var(--e-swift),transform .24s var(--e-swift),visibility .24s;
}
.mega.abierta{opacity:1;visibility:visible;transform:none}
/* Pico que liga el panel con su trigger — sin él el panel se lee como un
   bloque suelto en vez de un desplegable de "Productos" (feedback del
   director). --pico-x lo fija JS con la posición real del trigger, porque el
   nav se centra en el hueco libre del riel y no cae siempre en el mismo x. */
.mega::before{
  content:"";position:absolute;top:-7px;left:var(--pico-x,50%);
  width:14px;height:14px;background:var(--papel);
  border-left:1px solid var(--linea);border-top:1px solid var(--linea);
  transform:translateX(-50%) rotate(45deg);
}
.mega-interior{
  max-width:var(--ancho);margin:0 auto;
  padding:30px clamp(18px,4vw,44px) 42px;
}
/* Más peso que .mega-todo ("ver todos los productos"): a 14px/700/.14em
   heredado de .label quedaban casi al mismo nivel — letra más suelta y
   negrita de verdad para que se lea como el título de la sección, no como
   otro kicker más (hallazgo del director). */
.mega-eyebrow{font-size:15px;font-weight:800;letter-spacing:.06em;color:var(--tinta);margin-bottom:20px}
.mega-grid{
  --mega-gap:clamp(30px,4vw,72px);
  display:grid;grid-template-columns:repeat(3,1fr);gap:0 var(--mega-gap);
}
/* Cierre del panel, no cabecera (feedback del director): tras escanear las
   categorías, "ver todos" es la salida general — por eso vive al final, con
   línea y margen arriba en vez de abajo, en espejo de cuando abría el panel.
   Más padding-top que abajo: separa el link de su propia raya de cierre tanto
   como el aire que ya hay entre filas de categorías (feedback del director). */
.mega-todo{
  display:flex;align-items:center;gap:8px;
  padding:28px 4px 12px;margin-top:14px;border-top:1px solid var(--linea-f);
  font:600 13.5px/1 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--tinta-2);
  transition:padding-left .22s var(--e-swift),color .18s;
}
.mega-todo .flecha{font-family:var(--mono);transition:transform .22s var(--e-swift)}
@media(hover:hover){.mega-todo:hover{padding-left:11px;color:var(--navy)}}
@media(hover:hover){.mega-todo:hover .flecha{transform:translateX(3px)}}
.mega a.mega-cat{
  position:relative;display:flex;align-items:center;gap:14px;
  padding:33px 4px;
  font:600 16.5px/1.2 var(--sans);font-variation-settings:"wdth" 96;color:var(--tinta);
  transition:padding-left .22s var(--e-swift),color .18s;
}
.mega a.mega-cat .frag{width:20px;height:20px;flex-shrink:0;color:var(--tinta-2);transition:color .18s}
.mega-nombre{flex:1}
.mega-chevron{font:400 20px/1 var(--sans);color:var(--tinta-2);transition:color .18s}
/* Línea arriba (no abajo) desde la 2ª fila en adelante: con border-bottom, la
   última fila (a veces incompleta, p.ej. 13 categorías / 3 columnas deja
   "Suspensión" sola) dibuja su propia raya justo encima del cierre del panel
   y se ven dos líneas pegadas (feedback del director). Así solo hay tantas
   líneas como fronteras entre filas. */
.mega a.mega-cat:nth-child(n+4){border-top:1px solid var(--linea)}
/* Raya vertical entre columnas: ::before propio (no border real en el item)
   para poder centrarla en el hueco entre columnas sin desplazar el texto; con
   row-gap:0 los tramos de cada fila empalman en una sola línea continua. */
.mega a.mega-cat:nth-child(3n+2)::before,
.mega a.mega-cat:nth-child(3n)::before{
  content:"";position:absolute;top:0;bottom:0;left:calc(var(--mega-gap) / -2);
  width:1px;background:var(--linea);
}
@media(hover:hover){.mega a.mega-cat:hover{padding-left:11px;color:var(--navy)}}
@media(hover:hover){.mega a.mega-cat:hover .frag,.mega a.mega-cat:hover .mega-chevron{color:var(--navy)}}
/* En el masthead sobre-hero (portada) el panel sigue siendo papel/tinta: es opaco */
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){.mega{display:none}}

/* Velo: desenfoca el resto de la página mientras un panel del riel está abierto.
   Elemento fijo: único sitio donde el blur está permitido. */
.velo-riel{
  position:fixed;inset:0;z-index:55;
  backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);
  background:rgba(5,24,46,.22);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .28s var(--e-swift),visibility .28s;
}
.velo-riel.activo{opacity:1;visibility:visible;pointer-events:auto}

/* ---------- Buscador del riel ---------- */
/* Única raya del riel: separa cotización (la acción) del resto de celdas,
   que ahora solo se distancian con aire (sin rayas entre logo/nav/buscar). */
.masthead .celda-buscar{
  position:relative;display:flex;align-items:center;gap:9px;transition:color .2s;
  margin-left:clamp(20px,2.6vw,36px);
  padding-right:clamp(10px,1.2vw,16px);border-right:1px solid var(--linea-clara);
}
/* Ampliación táctil sin engordar el riel: en móvil el botón mide 68px de alto
   (hereda .celda) pero solo ~27px de ancho — con la lupa sola (el texto se
   oculta en ≤920px) es el objetivo más estrecho de la cabecera. */
.masthead .celda-buscar::after{content:"";position:absolute;inset:-8px}
.celda-buscar svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.8;fill:none;flex-shrink:0}
@media(hover:hover){.celda-buscar:hover{color:var(--papel)}}
/* Con el panel de búsqueda abierto, Buscar toma el mismo tratamiento "encendido"
   que el trigger de Productos (.masthead-nav a[aria-expanded]) — sin esto, la
   página actual (p.ej. Nosotros) se queda con la única rayita visible del riel
   mientras lo que en verdad está abierto es Buscar (hallazgo del director). */
.celda-buscar[aria-expanded="true"]{color:var(--papel)}
/* Con Buscar abierto, la página actual (aria-current) suelta su rayita: solo
   una cosa "encendida" a la vez en el riel, la que en verdad está pasando. */
.masthead:has(#panelBuscar.abierta) .masthead-nav a[aria-current]{color:rgba(246,246,243,.78)}
.masthead:has(#panelBuscar.abierta) .masthead-nav a[aria-current]::after{transform:scaleX(0)}
/* Mismo criterio con el mega-panel de Productos abierto: sin esto, en
   Nosotros/Contacto con el cursor sobre Productos quedaban DOS rayitas
   encendidas en el riel a la vez (la de la página activa y la del trigger
   con el panel abierto), compitiendo entre sí (feedback del director). */
.masthead:has(.masthead-nav a[aria-expanded="true"]) .masthead-nav a[aria-current]{color:rgba(246,246,243,.78)}
.masthead:has(.masthead-nav a[aria-expanded="true"]) .masthead-nav a[aria-current]::after{transform:scaleX(0)}
/* Etiqueta junto a la lupa: sin subrayado (es un botón que abre el panel de
   búsqueda, no un link de texto — el subrayado es lenguaje de .enlace) y algo
   más apagada que el icono en reposo, para no competir con él. La rayita de
   "encendido" vive en el texto, no en todo el botón: la lupa no se subraya
   en ningún otro sitio del riel (hallazgo del director, comparándolo con
   Productos/Nosotros/Contacto, que solo tienen texto). */
.celda-buscar-texto{
  position:relative;
  font:600 12px/1 var(--sans);letter-spacing:.09em;text-transform:uppercase;
  color:rgba(246,246,243,.55);transition:color .2s var(--e-swift);
}
.celda-buscar[aria-expanded="true"] .celda-buscar-texto{color:var(--papel)}
@media(hover:hover){.celda-buscar:hover .celda-buscar-texto{color:var(--papel)}}
.celda-buscar-texto::after{
  content:"";position:absolute;left:0;right:0;bottom:-8px;height:2px;
  background:var(--papel);transform:scaleX(0);transform-origin:left;
  transition:transform .24s var(--e-swift);
}
.celda-buscar[aria-expanded="true"] .celda-buscar-texto::after{transform:scaleX(1)}
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){.celda-buscar-texto{display:none}}
.buscar-form{
  max-width:var(--ancho);margin:0 auto;
  padding:30px clamp(18px,4vw,44px) 32px;
  display:flex;flex-direction:column;gap:10px;
}
.buscar-fila{display:flex;align-items:center;gap:22px}
.buscar-form svg{width:20px;height:20px;stroke:var(--tinta-2);stroke-width:1.8;fill:none;flex-shrink:0}
.buscar-form input{
  flex:1;min-width:0;background:transparent;border:none;border-bottom:1px solid var(--linea-f);
  font:600 clamp(1.2rem,2.2vw,1.7rem)/1.3 var(--sans);color:var(--tinta);
  padding:8px 2px;border-radius:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.buscar-form input:focus{outline:none;border-bottom-color:var(--navy)}
.buscar-form input::placeholder{color:var(--tinta-2);opacity:.55;font-weight:500}
/* "Ejemplos" aparte y discreto, no dentro del placeholder — opción "con
   separador" de las tres que se compararon (feedback del director). Alineado
   con el texto del input, no con la lupa: mismo margen que ocupan
   svg+gap arriba. */
.buscar-ejemplos{
  margin:0 0 0 calc(20px + 22px);
  font:500 11.5px/1.4 var(--sans);color:var(--tinta-2);opacity:.72;
}
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){.buscar-ejemplos{margin-left:0}}
/* Sugerencias: mismo margen que .buscar-ejemplos (alineadas con el texto del
   input, no con la lupa) — sustituye a "Ejemplos…" en cuanto hay algo escrito.
   Miniatura real (laminaHTML) en vez de un icono genérico: el director quiere
   reconocer el producto de un vistazo, no solo leer el nombre. */
/* Ronda 5 (pedido del director, hallazgo en vivo con captura: la barra de
   scroll nativa se posaba justo sobre el precio, tapando el último dígito).
   overflow-y:auto pone la barra al borde exterior de la caja sin importar
   el padding — un padding-right aparta el contenido de ese borde, dejando
   la barra su propio carril en vez de montarse sobre el texto. */
.buscar-sugerencias{
  display:flex;flex-direction:column;gap:2px;
  margin:0 calc(20px + 22px);max-height:min(340px,60dvh);overflow-y:auto;padding-right:14px;
}
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){.buscar-sugerencias{margin-left:0;margin-right:0}}
/* Grid, no flex: .lamina resuelve su padding en % contra el ancho de su
   containing block (spec de CSS, no del propio elemento) — en un item de
   flex con ancho "auto" eso es circular y Chromium cae a un tamaño de
   respaldo enorme (hallazgo propio, viendo la miniatura salirse del panel).
   Con grid + columna fija la miniatura hereda un ancho definido, igual que ya
   hace .fila-ledger (más abajo) con la suya. 58px, no los
   44px originales: a ese tamaño la miniatura se leía como un sello diminuto,
   no como una foto reconocible del producto (feedback del director, viéndolo
   en vivo) — más cerca de los 96px de .fila-ledger sin llegar a ese peso,
   este panel es un vistazo rápido, no una lista de cotización. Margen
   simétrico en .buscar-sugerencias (arriba): con solo margin-left el
   resaltado de :hover quedaba a ras del borde derecho del panel, un
   rectángulo asimétrico que se leía como un glitch (mismo hallazgo). */
.buscar-sugerencia{
  display:grid;grid-template-columns:58px 1fr auto;align-items:center;gap:14px;width:100%;
  padding:9px 10px;border-radius:10px;text-align:left;
  transition:background .16s var(--e-swift),padding-left .18s var(--e-swift);
}
/* Ronda 1 (pedido del director: "el hover no se nota, blanco sobre blanco
   casi"): --placa (#F5F6F8) es MÁS claro que el fondo del panel, --papel
   (#EDEEF1) — iba en la dirección contraria, casi sin contraste perceptible
   cerca del blanco. Mismo criterio que .selector-opcion (línea 591): un paso
   más oscuro (--papel-2) más el nudge de padding-left, ya probado en ese
   mismo patrón de lista. */
.buscar-sugerencia.activa{background:var(--papel-2);padding-left:16px}
@media(hover:hover){.buscar-sugerencia:hover{background:var(--papel-2);padding-left:16px}}
.buscar-sugerencia .lamina{aspect-ratio:4/3}
.buscar-sugerencia-nombre{
  min-width:0;font:600 14px/1.35 var(--sans);color:var(--tinta);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Ronda 1 (pedido del director: "no me gusta cómo se ven los resultados"):
   antes solo cambiaba de color (700 sobre una base ya en 600 — casi no se
   notaba el peso) y con una consulta de una sola letra leía como una letra
   suelta pintada de azul en medio de la palabra, no como un match resaltado.
   Un fondo tenue (chip) hace que se lea como resaltado de verdad, sin
   depender solo del color. */
.buscar-sugerencia-nombre mark{
  background:color-mix(in srgb,var(--navy) 12%,transparent);
  color:var(--navy);font-weight:700;border-radius:3px;padding:0 1px;margin:0 -1px;
}
.buscar-sugerencia-precio{font:600 12.5px/1 var(--mono);color:var(--tinta-2)}
/* Ronda 2: enlace de salida a "todos los resultados" (catalogo.html?q=),
   no una sugerencia más — separado con su propio borde y centrado, para que
   no se confunda con una fila de producto (sin miniatura ni precio). */
/* Ronda 2c (pedido del director: "más elegante lo de la barra del final" —
   un enlace de puro texto subrayado (más el amarillo heredado de --senal,
   el mismo problema resuelto en .resumen-cambiar) leía flojo comparado con
   las filas de arriba, que sí tienen ícono. Mismo lenguaje de flecha que el
   resto de CTAs del sitio, sin amarillo. */
.buscar-ver-todos{
  display:flex;align-items:center;justify-content:center;gap:8px;
  margin-top:4px;padding:14px 10px;border-top:1px solid var(--linea-f);
  font:600 13px/1 var(--sans);color:var(--navy);text-decoration:none;
}
.buscar-ver-todos svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;flex:none;transition:transform .2s var(--e-swift)}
/* Ronda 2d (pedido del director: "el efecto de hover... tiene que ser un
   subrayado en ese mismo color" — ni fondo (2b) ni amarillo, un subrayado
   navy que aparece al pasar el mouse, mismo idioma que .enlace sitewide). */
@media(hover:hover){.buscar-ver-todos:hover{text-decoration:underline;text-decoration-color:var(--navy);text-underline-offset:4px;text-decoration-thickness:1px}}
@media(hover:hover){.buscar-ver-todos:hover svg{transform:translateX(3px)}}
.buscar-sin-resultados{margin:2px 0 0 calc(20px + 22px);font:500 12.5px/1.4 var(--sans);color:var(--tinta-2)}
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){.buscar-sin-resultados{margin-left:0}}
/* Panel de búsqueda: flotante y centrado (como el buscador de Spotlight en
   macOS), no un desplegable a todo el ancho pegado al riel como el mega-menú
   de Productos — id, no clase, para no tocar .mega en el resto de usos
   (feedback del director: "algo más flotante, sin romper la UI"). Sin .pico
   (el ::before de .mega): un panel centrado no apunta a ningún trigger.
   760px, no 600: a 600 se leía angosto/apretado con el placeholder largo
   (feedback del director tras verlo en vivo). */
#panelBuscar{
  left:50%;right:auto;top:calc(100% + 14px);
  width:min(760px,calc(100% - 40px));
  border-radius:16px;border:1px solid var(--linea-f);
  box-shadow:0 24px 60px -14px rgba(5,24,46,.42),0 8px 20px -8px rgba(5,24,46,.2);
  transform:translate(-50%,-8px);
}
#panelBuscar.abierta{transform:translate(-50%,0)}
#panelBuscar::before{content:none}
/* Bajo 921px, #panelBuscar quedaba invisible de verdad: comparte la clase
   .mega (línea 349, display:none en este tramo) pensada para el mega-menú de
   Productos, que sí tiene un sustituto — .celda-buscar es un <button>, no un
   <a>, sin sitio al que "caer" navegando. Tocar la lupa atenuaba toda la
   pantalla (.velo-riel) sin mostrar ningún panel: callejón sin salida, mismo
   patrón que el hallazgo de Productos, pero sin fix de una guarda posible
   porque aquí no hay guarda que ajustar — el disparador nunca tuvo ninguna
   (hallazgo del director, auditoría en vivo tras FE-T011). Con
   `#panelBuscar.abierta{display:block}` (id+clase, gana a `.mega` por
   especificidad) el panel flotante y centrado de arriba, ya preparado para
   este ancho (`width:calc(100% - 24px)`, línea siguiente), vuelve a
   alcanzarse — sin inventar un patrón nuevo, la propia regla de ancho ya
   esperaba esto. */
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){
  #panelBuscar.abierta{display:block}
  #panelBuscar{width:calc(100% - 24px)}
}


/* Menú overlay (móvil). Grid+place-items, no flex+justify-content:center:
   con 5 enlaces grandes, en un teléfono en horizontal (~360px de alto) el
   contenido no cabe — overflow:hidden lo recortaba por arriba y por abajo
   sin ninguna vía de scroll. overflow-y:auto + grid sí deja alcanzar lo que
   sobra (mismo patrón que .lightbox, más abajo).
   Diseño (opción A del director): solo los destinos, grandes y a la
   izquierda; la página actual lleva una raya amarilla de 44px debajo y el
   resto va atenuado (COTIZACIÓN lleva además su contador «[3]»). Sin folios, sin coordenadas, sin «Cerrar» (el riel, por
   encima del velo, lleva el ✕). El relleno de arriba libra el riel. */
.velo-menu{
  position:fixed;inset:0;z-index:90;background:var(--panel);color:var(--papel);
  overflow-y:auto;
  display:grid;place-items:center start;
  padding:calc(var(--masthead-total,68px) + 12px) clamp(24px,7vw,60px) 32px;
  opacity:0;visibility:hidden;
  transition:opacity .42s var(--e-swift),visibility .42s;
}
.velo-menu.abierto{opacity:1;visibility:visible}
/* Fondo K (elección del director, ronda 6): bloque diagonal con el corte de
   65° de la marca (dy/dx ≈ 2,145) y un cuerno asomando dentro. Se mide en vw
   —no en % de la pantalla— para que el ángulo sea 65° en cualquier teléfono.
   Va por detrás del texto (z-index:-1 dentro del contexto del velo). */
.velo-fondo,.velo-corte{
  position:fixed;right:0;bottom:0;width:74vw;height:158.7vw;z-index:-1;pointer-events:none;
}
.velo-fondo{
  overflow:hidden;
  clip-path:polygon(0 100%,100% 0,100% 100%);
  background:linear-gradient(180deg,rgba(0,40,86,.2),rgba(0,40,86,.7));
}
.velo-fondo i{
  position:absolute;left:18vw;bottom:-46px;width:124vw;aspect-ratio:56/26;
  background:#6EA8F0;opacity:.36;filter:blur(.5px);
  -webkit-mask:url(img/rino-blanco.png) no-repeat center/contain;
  mask:url(img/rino-blanco.png) no-repeat center/contain;
}
.velo-corte{display:block;overflow:visible}
.velo-menu nav{display:flex;flex-direction:column;gap:clamp(8px,2.2vw,16px)}
.velo-menu a{
  display:block;overflow:hidden;
  font:800 clamp(24px,8.8vw,38px)/1.05 var(--sans);
  font-variation-settings:"wdth" 90;text-transform:uppercase;letter-spacing:.01em;
  color:rgba(246,246,243,.5);
  transition:color .2s var(--e-swift);
}
/* la raya (44px, debajo de la palabra) reserva su hueco en TODOS los
   destinos: el ritmo vertical no salta según cuál sea la página actual */
.velo-menu a::after{content:"";display:block;width:44px;height:3px;margin-top:7px;background:transparent}
.velo-menu a[aria-current="page"]{color:var(--papel)}
.velo-menu a[aria-current="page"]::after{background:var(--senal)}
/* contador «[3]»: mono, pegado a la palabra, sobre su línea de base */
.velo-menu .cnt{
  margin-left:.4em;font:500 12px/1 var(--mono);font-variation-settings:normal;
  letter-spacing:.04em;text-transform:none;color:rgba(246,246,243,.68);
}
.velo-menu .cnt::before{content:"["}
.velo-menu .cnt::after{content:"]"}
.velo-menu .cnt[hidden]{display:none}
.velo-menu a:focus-visible{outline:2px solid var(--senal);outline-offset:6px}
.velo-menu a span.txt{display:block;transform:translateY(110%);transition:transform .6s var(--e-out)}
.velo-menu.abierto a span.txt{transform:none}
.velo-menu.abierto a:nth-child(2) span.txt{transition-delay:.06s}
.velo-menu.abierto a:nth-child(3) span.txt{transition-delay:.12s}
.velo-menu.abierto a:nth-child(4) span.txt{transition-delay:.18s}
.velo-menu.abierto a:nth-child(5) span.txt{transition-delay:.24s}

/* ---------- 6 · COMANDOS ---------- */
.comando{
  display:inline-flex;align-items:stretch;
  background:var(--tinta);color:var(--papel);
  font:600 13px/1 var(--sans);letter-spacing:.08em;text-transform:uppercase;
  border-radius:2px;overflow:hidden;
  transition:transform .24s var(--e-swift),background .24s var(--e-swift);
}
.comando .txt{padding:15px 20px;display:flex;align-items:center}
.comando .flecha{
  width:46px;display:grid;place-items:center;
  border-left:1px solid var(--linea-clara);
  position:relative;overflow:hidden;
}
.comando .flecha svg{width:15px;height:15px;stroke:currentColor;stroke-width:2;fill:none;
  transition:transform .3s var(--e-swift)}
.comando .flecha::before{
  content:"";position:absolute;inset:0;background:var(--senal);
  transform:translateY(101%);transition:transform .3s var(--e-swift);
}
.comando:active{transform:translateY(1px) scale(.985)}
.comando.registro{background:transparent;color:var(--tinta);box-shadow:inset 0 0 0 1px var(--linea-f)}
.comando.registro .flecha{border-left-color:var(--linea)}
.comando.navy{background:var(--navy)}
/* Amarillo solo con ratón real: en iPhone ":hover" se dispara con el toque y
   se queda pegado hasta el siguiente tap en cualquier otro sitio — el botón
   parecía roto (hallazgo del director, banner ARB de la portada). El toque ya
   tiene su propio feedback real en .comando:active, arriba. */
@media(hover:hover){
  .comando:hover .flecha::before{transform:none}
  .comando:hover .flecha svg{transform:translateX(3px);stroke:var(--tinta);position:relative;z-index:1}
  .comando:hover{transform:translateY(-1px)}
  .comando.registro:hover .flecha svg{stroke:var(--tinta)}
  /* Mismo efecto que el CTA fantasma del hero (.hero-pie .comando.claro): el
     borde "recorre" a amarillo en hover, no solo la flecha (feedback del
     director — quería esa consonancia en todos los comandos fantasma). */
  .comando.registro:hover{background:rgba(18,24,31,.05);box-shadow:inset 0 0 0 1px var(--senal)}
  /* Mismo "el borde entero recorre a amarillo" del hero (.comando.claro) y de
     .comando.registro — antes solo se coloreaba la flecha (feedback del
     director: quería la consonancia en todo el botón, no solo ahí). El fondo
     navy no cambia: solo se suma el aro. */
  .comando.navy:hover{box-shadow:inset 0 0 0 1px var(--senal)}
}
.comando.whatsapp{background:var(--navy)}
.comando.whatsapp .txt{gap:10px}
.comando.claro{background:var(--papel);color:var(--tinta)}
.comando.claro .flecha{border-left-color:var(--linea)}
.comando.bloque{display:flex;width:100%;justify-content:space-between}
.enlace{
  font-weight:600;text-decoration:underline;
  text-underline-offset:4px;text-decoration-thickness:1px;
  transition:text-decoration-color .24s;
}
@media(hover:hover){.enlace:hover{text-decoration-color:var(--senal);text-decoration-thickness:2px}}

/* ---------- 6b · ESTADO VACÍO (sin resultados / no encontrado) ----------
   Compartido, no local a catalogo.astro: vivía solo ahí y "producto no
   encontrado" (producto.astro) se quedó con el estilo viejo — recuadro
   punteado y .comando oscuro — sin que nadie se acordara de tocarlo
   también (hallazgo del director, "esta se había colado"). Un solo lugar
   para los dos. */
.vacio{
  padding:64px 22px;text-align:center;color:var(--tinta-2);
}
.vacio-icono{display:block;margin:0 auto 22px;width:52px;height:52px;stroke:var(--tinta-2);stroke-width:1.5;fill:none}
/* margin:0 auto: .t-h3 (a diferencia de .parrafo) no trae ese auto-centrado
   de fábrica — sin esto su max-width (heredado del <p> genérico) lo dejaba
   con la caja pegada a la izquierda aunque el texto adentro se leyera
   centrado (hallazgo del director, "no está centrado como todo lo demás"). */
.vacio .t-h3{font-size:clamp(1.5rem,2.6vw,1.9rem);margin:0 auto}
.vacio .parrafo{font-size:1.1rem}
/* Link de texto sin caja ni flecha — el patrón más reconocido de la web —
   con subrayado permanente y sutil: sin depender del hover para leerse
   como clicable, la mitad de las visitas son táctiles y nunca lo ven.
   Navy, no --senal (el ámbar es la señal reservada para llamadas a la
   acción, no para "aquí no hay nada, prueba otra cosa"). */
.vacio-cta{
  font:700 16.5px/1 var(--sans);letter-spacing:.02em;color:var(--navy);
  text-decoration:underline;text-decoration-color:rgba(0,40,86,.35);text-underline-offset:3px;
  transition:text-decoration-color .18s var(--e-swift);
}
@media(hover:hover){.vacio-cta:hover{text-decoration-color:var(--navy)}}

/* ---------- 7 · REGISTRO DEL VEHÍCULO ---------- */
/* La caja recta con corte de esquina (.registro-vehiculo) y el grid de campos
   con línea inferior (.registro-form/.campo-registro) salieron del sistema:
   tras varias rondas, el director pidió una cadena de pasos con flecha
   (referencia externa, recoloreada a navy) — vive solo en catalogo.html/astro,
   como .registro-paso/.paso, porque todavía no está probado en más sitios. */
.selector,.selector-boton{min-width:0}

/* ---------- 7b · SELECTOR DE EXPEDIENTE (sustituye al <select> nativo) ----------
   El desplegable del sistema operativo rompe el lenguaje: este panel es papel,
   hairlines y mono, con la esquina cortada al ángulo del sistema. El <select>
   nativo queda oculto debajo manteniendo la semántica del formulario. */
.selector{position:relative}
.selector>select{
  position:absolute!important;inset:0;opacity:0!important;pointer-events:none;
  border:none!important;
}
.selector-boton{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px;
  background:transparent;border-bottom:1px solid var(--linea-f);
  font:500 clamp(1.05rem,1.4vw,1.3rem)/1.2 var(--sans);color:var(--tinta);
  padding:8px 2px;text-align:left;cursor:pointer;
  transition:border-color .2s;
}
.selector-boton .valor{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.selector-boton .valor.sin-valor{color:var(--tinta-2);opacity:.75}
.selector-boton svg{
  width:14px;height:14px;flex-shrink:0;stroke:var(--tinta-2);stroke-width:1.5;fill:none;
  transition:transform .3s var(--e-swift);
}
.selector.abierto .selector-boton{border-bottom-color:var(--navy)}
.selector.abierto .selector-boton svg{transform:rotate(180deg)}
.selector-boton:disabled{opacity:.38;cursor:not-allowed}
.selector-panel{
  position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:40;
  display:flex;flex-direction:column;max-height:min(296px,55dvh);
  opacity:0;transform:translateY(-6px);visibility:hidden;pointer-events:none;
  transition:opacity .24s var(--e-swift),transform .24s var(--e-swift),visibility .24s;
}
.selector.abierto .selector-panel{opacity:1;transform:none;visibility:visible;pointer-events:auto}
/* El filtro de categoría (Dropdown F, ver .filtro-panel más abajo) sigue con
   su muesca/placa/borde de siempre — esto es SOLO para marca/modelo/año. */
.filtro-panel{
  background:var(--placa);border:1px solid var(--linea-f);
  clip-path:polygon(0 0,calc(100% - 11px) 0,100% 23px,100% 100%,0 100%);
}
/* Dropdown B (mockup ronda 2, "B · Combobox con búsqueda — encontrar en vez
   de escanear", file:///Users/jorgepais/Desktop/vehiculo-dropdowns-ronda2.html):
   tarjeta blanca flotante, sin muesca ni borde — sombra sola la separa del
   fondo. Sitewide en marca/modelo/año — mejorarSelector() en sistema.js lo
   omite en .compacto. */
.selector-panel:not(.filtro-panel){
  background:#fff;border-radius:16px;overflow:hidden;
  box-shadow:0 24px 48px -28px rgba(5,15,30,.3);
}
.selector-buscar-cont{flex:none;display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid rgba(18,24,31,.08)}
.selector-buscar-cont svg{flex:none;width:16px;height:16px;stroke:#8A93A0;stroke-width:2;fill:none;pointer-events:none}
.selector-buscar{
  flex:1;min-width:0;border:none;background:none;padding:0;
  font:500 14px/1 var(--sans);color:var(--tinta);
}
.selector-buscar::placeholder{color:var(--tinta-2);opacity:.75}
.selector-buscar:focus{outline:none}
.selector-lista{flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain}
.selector-panel:not(.filtro-panel) .selector-lista{padding:6px 6px 8px}
.selector-opcion{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  width:100%;text-align:left;min-height:44px;padding:10px 14px;
  font:500 14.5px/1.3 var(--sans);border-bottom:1px solid var(--linea);
  cursor:pointer;transition:background .15s,padding-left .18s var(--e-swift);
}
.selector-opcion:last-child{border-bottom:none}
.selector-opcion.hidden{display:none}
.selector-opcion.activa{background:var(--papel-2);padding-left:19px}
@media(hover:hover){.selector-opcion:hover{background:var(--papel-2);padding-left:19px}}
.selector-opcion[aria-selected="true"]{
  background:var(--navy);color:var(--papel);
}
/* Fila de opción "fuera de la familia .selector" clásica: sin divisores, con
   radio de píldora propio en vez de heredar el ancho completo de la fila. */
.selector-panel:not(.filtro-panel) .selector-opcion{
  min-height:0;padding:11px 10px;border-radius:9px;border-bottom:none;
  transition:background .15s;
}
.selector-panel:not(.filtro-panel) .selector-opcion.activa,
.selector-panel:not(.filtro-panel) .selector-opcion[aria-selected="true"]{
  background:var(--placa);color:var(--navy);font-weight:700;padding-left:10px;
}
@media(hover:hover){.selector-panel:not(.filtro-panel) .selector-opcion:hover{background:var(--placa);padding-left:10px}}
.selector-tick{flex:none;width:15px;height:15px;stroke:var(--navy);stroke-width:2.4;fill:none}
.selector-vacio{padding:16px 14px;font:500 13.5px/1.4 var(--sans);color:var(--tinta-2)}
.selector-lista::-webkit-scrollbar{width:8px}
.selector-lista::-webkit-scrollbar-thumb{background:var(--linea-f)}
/* variante compacta: riel del inventario (orden) */
.selector.compacto .selector-boton{
  border-bottom:none;font:600 11.5px/1 var(--sans);letter-spacing:.1em;
  color:var(--tinta-2);text-transform:uppercase;padding:6px 0;width:auto;gap:8px;
}
.selector.compacto{display:inline-block;min-width:190px}
.selector.compacto .selector-panel{left:auto;right:0;min-width:230px}

/* ---------- 8 · PLANCHA DE INVENTARIO ---------- */
/* Tarjetas sueltas con aire real entre ellas, no la plancha de bordes
   compartidos de antes (gap 1px + fondo haciendo de regla): a 4 columnas se
   sentía denso, un listado de compra impulsiva más que un catálogo de
   compra considerada (feedback del director). 380px de mínimo cabe 3 veces
   en el ancho de --ancho (1360px menos padding) y nunca 4, aunque el
   monitor sea ancho — mismo criterio de tope que antes, recalibrado. */
.plancha{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(380px,1fr));
  gap:18px;
}
/* Si tocas esta tarjeta (o .entrada de aquí abajo): en 19 · MÓVIL,
   #plancha.vista-destacada la reutiliza a propósito (duplicando estos
   valores, no heredándolos — revert/unset no llegan a otra regla) para el
   modo "Una" del selector de densidad del catálogo. Revísalo también. */
.entrada{
  /* Blanco, no --papel: sin esto la tarjeta se fundía con el fondo de la
     página (mismo tono) y no se leía como una pieza propia. Borde propio
     (antes lo daba el gap-como-regla de la plancha) + el navy de
     "activo/elegido" del resto del sistema en hover, con un realce suave
     para que la tarjeta se despegue del papel. Segunda pasada: menos aire
     interior y foto menos alta — a 3 columnas con el aire de la primera
     pasada la tarjeta se sentía vacía y editorial, no un selector de
     productos. Tercera pasada: aún un poco de sobra. Cuarta pasada: esquinas
     redondeadas y una sombra propia en reposo (no solo en hover), para que
     se lea como pieza elevada sobre el fondo, no como un recuadro plano
     (feedback del director). */
  background:var(--blanco);padding:18px 18px 16px;
  border:1px solid rgba(0,40,86,.14);border-radius:10px;
  box-shadow:0 1px 3px rgba(18,24,31,.06);
  display:flex;flex-direction:column;gap:10px;
  transition:box-shadow .24s var(--e-swift),border-color .24s var(--e-swift),transform .24s var(--e-swift);
  position:relative;
}
@media(hover:hover){.entrada:hover{
  /* Quinta pasada: el cambio de borde (.14→.4 de opacidad) y la sombra
     apenas se notaban al lado de la sombra propia que la tarjeta ya lleva
     en reposo — border-color sólido (no tenue) + una elevación real
     (translateY, no solo sombra) para que el hover se sienta, no solo se
     intuya (feedback del director). */
  border-color:var(--navy);
  box-shadow:0 16px 30px -16px rgba(18,24,31,.4);
  transform:translateY(-3px);
}}
/* min-height explícito (no 2.4em en el propio h3): el nombre corto queda
   pegado a la línea de abajo, con el hueco de reserva (para nombres largos
   de 2 líneas) absorbido arriba, entre categoría y nombre — al revés
   (min-height en h3) el hueco caía siempre debajo del nombre, aunque fuera
   de una sola línea, y ahí es donde el director lo veía como "gran vacío"
   (feedback del director, referencia "ARB pinnacle"). Quinta pasada: el
   propio min-height (pensado como reserva de 2 líneas) era él mismo el
   hueco que sobraba entre categoría y nombre en el caso normal de 1 línea —
   ahora reserva solo 1 línea (24px → 22px de fuente, 1.2 de interlineado). */
.entrada-titulo{display:flex;flex-direction:column;gap:4px;flex:1;justify-content:flex-end;min-height:26.4px}
.lamina{
  background:var(--placa);
  /* Ronda 4 (pedido del director, repetido en varias fotos: "las quiero
     normales" — sin el corte facetado en la esquina). Ya se había quitado
     puntualmente en la lámina grande de la ficha (.ficha-split .lamina) y en
     el thumbnail del buscador — ahora se quita en la fuente para todo el
     sitio (catálogo, relacionados, buscador, ficha), en vez de sumar un
     tercer override puntual a la lista. */
  clip-path:none;
  /* 8/5 (segunda pasada) recortaba de más: en sujetos altos (la silla) dejaba
     el producto pegado a los bordes, y en fotos .fotografica (la correa) el
     cover se comía más foto al bajar la caja — 4/3 es el punto donde cada
     producto entra completo con encuadre parejo (feedback del director). */
  aspect-ratio:4/3;position:relative;overflow:hidden;
  border:1px solid var(--linea);
  /* Marco por padding (no max-height/max-width en el img): un max-height en
     % dentro de un grid con aspect-ratio no se resuelve fiable en Chromium
     (queda "none"), así que solo mandaba el max-width y la imagen quedaba
     pegada a la izquierda con todo el aire sobrando a la derecha. Con
     padding aquí + width/height:100% en el img, object-fit:contain centra
     de verdad en los dos ejes (feedback del director, referencia "ARB
     pinnacle"). */
  padding:6% 18%;
  transition:transform .24s var(--e-swift);
}
@media(hover:hover){.entrada:hover .lamina{transform:translateY(-2px)}}
/* <picture> (envuelve el img, ver sistema.js fotoHTML) en flujo normal, NO
   position:absolute;inset:0 (lo que había antes): inset:0 posiciona contra
   el PADDING BOX del ancestro (spec de CSS), es decir que el <picture>
   ocupaba el hueco del padding en vez de respetarlo — el 6%/18% (o
   cualquier .zoom-*/.holgado) de .lamina quedaba completamente ignorado, la
   foto siempre salía a caja completa sin importar el % declarado (hallazgo
   al revisar por qué "arb-recovery-strap-17600lbs" con .holgado seguía
   saliendo igual de grande: medido en vivo, el <img> medía el mismo tamaño
   con zoom-max que con zoom-suave). display:block + width/height:100% en
   flujo normal sí hereda el content-box ya reducido por el padding — y no
   reintroduce el bug circular que motivó el position:absolute en primer
   lugar, porque ese bug era de .lamina{display:grid} (ya no existe: ahora
   es position:relative, un bloque normal cuyo alto sale de aspect-ratio
   sobre su PROPIO ancho, sin depender del contenido). */
.lamina picture{display:block;width:100%;height:100%}
.lamina img{width:100%;height:100%;object-fit:contain;mix-blend-mode:multiply}
/* Antes .fotografica llenaba el recuadro entero (padding:0, cover): con solo
   1 de 123 productos con foto recortada (foto_recorte), esa era la portada
   de casi todo el catálogo — cada foto "real" (sin fondo blanco de estudio)
   salía pegada a los bordes y con un zoom/recorte distinto según su encuadre
   propio, mientras el único producto recortado (la silla) se veía chico y
   con aire de sobra al lado — el catálogo no leía como un solo sistema
   (feedback del director, comparando cards lado a lado). mix-blend-mode
   normal en vez de multiply es lo único que sigue distinto: estas fotos
   traen su propio fondo real (no blanco/transparente), y multiply oscurecería
   el producto entero, no solo el fondo. */
.lamina.fotografica img{mix-blend-mode:normal}
/* .fondo-limpio (solo portadas, la marca sistema.js/laminaHTML): fotos
   .fotografica cuyo fondo real SÍ es blanco de estudio, como la silla —
   aquí multiply funciona igual de bien que en foto_recorte y evita la
   costura de un rectángulo blanco puro flotando dentro del gris de la
   lámina (feedback del director, "ARB recovery strap"/"Adventure light").
   No se toca --placa ni el resto de fotos de ambiente reales. */
.lamina.fotografica.fondo-limpio img{mix-blend-mode:multiply}
/* .zoom / .completa (solo portadas, la marca sistema.js/laminaHTML): el
   padding 6%/18% se calibró para la silla (referencia "ARB pinnacle"), pero
   muchas fotos ya vienen con su propio margen — sumado al padding, el
   producto quedaba chico dos veces. Encaje revisado producto por producto
   por el director, no por script (ahí no hay atajo fiable: cada foto trae
   su propio encuadre). .zoom acerca el marco; .completa lo quita del todo
   (llena el recuadro igual que hacía .fotografica antes de la Ronda de
   consistencia — aquí sí es lo correcto porque el encuadre ya viene bien
   así en el origen). */
.lamina.zoom{padding:2% 8%}
/* Ajuste fino sobre .zoom, producto por producto (segunda pasada del
   director): algunos pedían un poco más de aire, otros un poco menos —
   .zoom-suave/.zoom-firme/.zoom-alto/.zoom-max en vez de tocar el 2%/8%
   base, que sigue sirviendo para el resto del grupo .zoom sin retocar. */
.lamina.zoom-suave{padding:4% 12%}
.lamina.zoom-firme{padding:1% 6%}
.lamina.zoom-alto{padding:.5% 4%}
.lamina.zoom-max{padding:0 2%}
/* Caso inverso a .zoom (ver sistema.js, Set HOLGADO): la foto ya viene sin
   margen propio y el 6%/18% base de .fotografica no le da aire suficiente. */
.lamina.holgado{padding:12% 26%}
/* Portada de estudio sobre blanco encuadrada por su caja (sistema.js, encuadreEstudio): --enc trae el
   translate+scale que centra el producto y lo acerca. El resto de la foto es blanco y, con multiply,
   se pierde en el fondo de la tarjeta; lo que sale de la lámina lo corta su overflow. */
.lamina.encuadre{padding:0}
.lamina.encuadre img{transform:var(--enc);transform-origin:center}
.lamina.completa{padding:0}
.lamina.completa img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover}
.lamina.completa.completa-arriba img{object-position:center 100%}
.lamina.completa.completa-arriba-suave img{object-position:center 90%}
.lamina.completa.completa-media img{object-position:center 50%}
/* Artículo sin foto (bitácora frontend-web 0011, 30-sep-2026; sistema.js, marcadorHTML): 373 de
   los 593 artículos de Office aún no la tienen, y se pintaba un <img src=""> con el nombre en un
   recuadro vacío. Ahora es un hueco reservado y rotulado, como .hueco-foto (DISENO.md: «la
   honestidad como parte del diseño»): la placa de siempre, un filete discontinuo, el icono de
   su categoría (el de los filtros y el menú) y «Foto pendiente». Callado a propósito: en
   categorías enteras (Köster, Graco) es la mayoría de la rejilla y no puede gritar más que las
   fotos. Lo mide el propio hueco (container query): en la tarjeta y la ficha, icono y rótulo;
   en el buscador (58 px) y la cotización, solo el icono, sin filete. */
.lamina.sin-foto{padding:0}
.sin-foto-marca{
  position:absolute;inset:0;container-type:size;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  color:var(--tinta-2);
}
.sin-foto-filete{
  position:absolute;inset:clamp(8px,6cqmin,18px);
  border:1px dashed var(--linea-f);opacity:.7;pointer-events:none;
}
.sin-foto-marca .frag{width:clamp(20px,22cqmin,64px);height:auto;opacity:.55}
.sin-foto-marca svg.frag[viewBox^="0 0 622"]{width:clamp(22px,26cqmin,84px);opacity:.45}
.sin-foto-texto{
  margin-top:clamp(8px,4.5cqmin,16px);
  font:600 10.5px/1 var(--sans);letter-spacing:.14em;text-transform:uppercase;opacity:.8;
}
/* La tarjeta a dos columnas del móvil (~125 px) aún lleva el rótulo, más pequeño; el buscador
   (58 px) y la fila de la cotización, solo el icono. */
@container (max-width:150px){
  .sin-foto-texto{font-size:9px;letter-spacing:.1em;margin-top:7px}
}
@container (max-width:109px){
  .sin-foto-texto{display:none}
}
@container (max-width:150px) or (max-height:110px){
  .sin-foto-filete{display:none}
}
.galeria .lamina.sin-foto{background:var(--placa);cursor:default}
/* Ronda 21 (pedido del director: "muy fino y mucha separación, prueba otra
   cosa"): heredaba de .folio (mono, .12em de tracking) y encima le sumaba
   más tracking propio (.16em) — mono + muy espaciado + gris se leía frágil
   pese al peso 800. Chip con wash de navy, mismo recurso que .chip-filtro
   (filtros activos) — más presencia, ya no compite en fragilidad con el
   nombre de abajo, compite en peso visual distinto (chip vs texto). */
/* Minúsculas, no versalitas: mismo pill que .chip-filtro (misma familia
   visual que un filtro activo), pero en mayúscula sostenida competía más
   con el nombre del producto y, con categorías largas ("Equipo de
   recuperación"), se leía más lento que en altas y bajas (decisión del
   director, comparando propuestas en artefacto). */
.entrada .categoria{
  display:inline-block;font:600 12.5px/1 var(--sans);letter-spacing:.01em;
  color:var(--navy);background:rgba(0,40,86,.08);
  padding:5px 10px;border-radius:4px;
}
.entrada h3{
  font:800 22px/1.2 var(--sans);font-variation-settings:"wdth" 88;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
/* Línea muy sutil que separa el nombre del precio/botón, con aire parecido
   a ambos lados: la pasada anterior sobrecorrigió y dejó el precio
   demasiado lejos de la línea (feedback del director, referencia "ARB
   pinnacle"). */
.entrada .pie-celda{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  /* margin-top propio (no el gap de .entrada, compartido con lámina→título):
     el nombre necesitaba más aire antes de la línea sin tocar la separación
     categoría/lámina→título, que ya estaba bien (feedback del director,
     referencia "ARB pinnacle"). +2px y +6px no se notaban en pantalla — +12px
     sí se lee como aire real sin desplazar mucho el bloque de precio/botón
     hacia abajo. */
  margin-top:12px;padding-top:10px;border-top:1px solid rgba(18,24,31,.1);
}
/* "Roboto Mono Precio", no var(--mono): el .woff2 variable no trae GSUB
   (subconjunto de Google sin features), así que "zero" 0 no tenía nada que
   apagar — el cero cruzado viene soldado al contorno del glifo. Esta es una
   instancia estática aparte (mismo dibujo, un solo contorno menos: la
   barra) para no arriesgar el resto de usos de --mono, donde distinguir 0
   de O sí importa (feedback del director, precios ilegibles con la barra).
   Fallback a --mono si el .woff2 no carga: mismo cero cruzado de siempre,
   nunca un precio sin fuente. */
.precio{font:700 2rem/1 "Roboto Mono Precio",var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.precio .divisa{font-size:.45em;font-weight:700;color:var(--tinta-2);margin-right:6px}
/* La coma en su propia celda monoespaciada (misma anchura que un dígito)
   quedaba con mucho aire a los lados — display:inline-block + márgenes
   negativos para acercar el dígito anterior y el siguiente sin tocar el
   interletraje del resto del número. Segunda pasada: quedó demasiado
   apretada, a mitad de camino entre la separación original y esta
   (feedback del director). */
.precio .miles{display:inline-block;margin:0 -.11em 0 -.15em}
/* dato, no pildora: el tribunal movil cazo que competia con el boton real */
/* Ronda 31 (pedido del director: "a cotizar se ve muy pequeño... un poco más
   grande y de color más oscuro"): 11px/500 gris (--tinta-2) → 14px/600 en
   --tinta, el mismo tono que el precio de las tarjetas con precio. Sigue
   siendo un dato, no un botón: sin fondo ni borde. */
.chip-cotizar{
  font:600 14px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;
  color:var(--tinta);
}
/* El sello de añadir */
.sello{
  display:inline-flex;align-items:center;gap:7px;
  min-height:34px;padding:0 12px;
  font:600 11px/1 var(--sans);letter-spacing:.1em;
  box-shadow:inset 0 0 0 1px var(--linea-f);border-radius:2px;
  position:relative;transition:transform .18s var(--e-swift),background .24s var(--e-swift),color .24s,box-shadow .24s;
}
.sello::after{ /* área táctil ≥48px sin engordar el dibujo */
  content:"";position:absolute;inset:-8px;
}
@media(hover:hover){.sello:hover{background:var(--senal);box-shadow:inset 0 0 0 1px var(--senal);color:var(--tinta)}}
.sello:active{transform:scale(.92)}
.sello.sellado{background:var(--navy);color:var(--papel);box-shadow:inset 0 0 0 1px var(--navy)}
@media(hover:hover){.sello.sellado:hover{background:var(--navy)}}
/* Solo en la tarjeta del catálogo: crece con el resto de la tarjeta (foto y
   tipografía más grandes) y el "+" respira frente al texto — en el ledger
   móvil y en cotización sigue siendo el .sello compacto de arriba, no se
   toca esa regla (feedback del director, referencia "ARB pinnacle"). */
.entrada .sello{
  min-height:32px;padding:0 14px;font-size:13px;border-radius:6px;
  word-spacing:.5em;
  box-shadow:inset 0 0 0 1.5px rgba(0,40,86,1);
}
/* Ronda 30 (pedido del director: "tiene muy poco trazo... más visibilidad en
   conjunto, y un poco más al +"): borde 1→1.5px (mismo grosor que ya usa
   .filtro-icono seleccionado, más arriba, para un estado marcado) y el "+"
   aislado en su propio span (textoSello, sistema.js) para crecer solo él,
   sin tocar "Cotizar". */
.sello-mas{font-size:1.3em;font-weight:700}
/* Ronda 31 (pedido del director: "cotizar y quitar, el mismo ancho... genera
   tensión"): el .sello de la tarjeta cambia de texto en tres estados —
   "+ Cotizar" (99px), "En cotización ✓" (155px) y, al pasar el ratón por
   el ya cotizado, "Quitar ✕" (94px)— y al ir alineado a la derecha del pie
   el borde izquierdo saltaba 61px justo bajo el cursor. Un ancho común
   (el del texto más largo, con margen para otra fuente/navegador) lo deja
   quieto en los tres. Solo escritorio: en móvil el sello ya ocupa todo el
   ancho de la tarjeta (regla de más abajo) y un min-width fijo desbordaría
   tarjetas de 150px.
   Mock v19 (director, 24-sep-2026: «A, 116 px»): esos 160px los marcaba solo
   «En cotización ✓» y el botón se veía demasiado ancho. En el escritorio dice
   «Añadido ✓» (textoSello pinta los dos textos y aquí se enseña uno), el más
   largo de los tres pasa a ser «+ Cotizar» y el ancho común baja a 116px. En
   el móvil sigue «En cotización ✓»: allí el botón ya ocupa toda la tarjeta. */
.sello-corto{display:none}
@media(min-width:921px) and (min-height:501px),(min-width:1001px){
  .entrada .sello{min-width:116px;justify-content:center}
  .entrada .sello .sello-largo{display:none}
  .entrada .sello .sello-corto{display:inline}
}
/* :not(.sellado): el texto azul (a juego con el borde) es solo del estado de
   reposo — .sello.sellado ya pone fondo navy + texto papel (blanco) para el
   "En cotización ✓", y con la misma especificidad un color plano aquí lo
   habría pisado, dejando texto navy sobre fondo navy (feedback del
   director). */
.entrada .sello:not(.sellado){color:var(--navy)}
/* Toda la tarjeta abre la ficha, menos «Cotizar» (director, 24-sep-2026: en móvil,
   mockup «qué parte se toca»; en escritorio, E1). El enlace del nombre se estira
   sobre la tarjeta entera (::after, que no recorta el overflow del h3 porque su
   bloque contenedor es .entrada) y el sello queda por encima. Sigue siendo un
   enlace normal: ⌘-clic o la rueda la abren en otra pestaña. */
.entrada h3 a{-webkit-tap-highlight-color:transparent}
.entrada h3 a::after{content:"";position:absolute;inset:0}
.entrada .sello{z-index:1}
/* Escritorio: al pasar el ratón el nombre se subraya, para que se sepa adónde lleva
   el clic; sobre «Cotizar» no, porque ese clic hace otra cosa. */
@media(hover:hover){
  .entrada:hover:not(:has(.sello:hover)) h3 a{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:3px}
}

/* Ledger (filas): móvil del inventario, cotización, listas de portada */
.ledger{border-top:1px solid var(--linea-f)}
.fila-ledger{
  display:grid;grid-template-columns:auto 96px 1fr auto auto;
  gap:clamp(12px,2vw,22px);align-items:center;
  padding:13px 4px;border-bottom:1px solid var(--linea);
  position:relative;transition:background .24s var(--e-swift);
}
@media(hover:hover){.fila-ledger:hover{background:var(--placa)}}
.fila-ledger .lamina{aspect-ratio:4/3;width:96px}
.fila-ledger h3{font:600 14.5px/1.3 var(--sans);font-variation-settings:"wdth" 86;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ---------- 9 · BARRA DE FILTROS ----------
   Sustituye al rail fijo de categorías: con 142 productos en ~14 categorías
   forzar una columna de navegación permanente pesaba de más, y duplicaba la
   categoría (rail + cabecera de sección) en la vista sin filtrar. Categoría
   pasa a ser un filtro más (desplegable), no una jerarquía de navegación —
   el vehículo registrado arriba sigue siendo el filtro principal. */
.frag{width:14px;height:14px;flex-shrink:0}
.barra-filtros{
  display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px 18px;
  /* Antes vivía como style inline en el propio elemento (catalogo.astro):
     subido aquí para que la cabecera compartida de 19 · MÓVIL pueda anularlo
     con una regla normal — un margin-top inline gana siempre a cualquier
     regla de clase, sin importar su especificidad. */
  margin-top:clamp(44px,5.2vw,64px);
  padding-bottom:10px;margin-bottom:28px;border-bottom:1px solid var(--linea-f);
}
.filtro-grupo{display:flex;align-items:center;flex-wrap:wrap;gap:10px 26px}
.filtro{position:relative}
.filtro-boton{
  display:inline-flex;align-items:center;gap:10px;
  /* 14px, no 13px: el director lo quiso "un poquito más grande que las 123
     entradas" (#conteo, 12.5px) — antes eran casi el mismo tamaño y no se
     distinguía a simple vista qué era el control y qué el resultado. */
  font:600 14px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--tinta);
  padding:9px 2px;transition:color .2s;
}
.filtro.abierto .filtro-boton{color:var(--navy)}
/* Ordenar (30-sep-2026): a diferencia de Categoría, que ya se ve reflejado
   en los chips de al lado, no muestra nada más junto al botón — sin esto,
   con el panel cerrado no había forma de saber que quedó un orden distinto
   de Relevancia. Precio tuvo el mismo problema mientras existió; se quitó
   del todo en una ronda posterior. */
.filtro-boton.filtro-boton-activo{color:var(--navy)}
@media(hover:hover){.filtro-boton:hover{color:var(--navy)}}
.filtro-boton svg{width:19px;height:19px;stroke:currentColor;flex-shrink:0}
.filtro-panel{
  position:absolute;top:calc(100% + 8px);left:0;z-index:40;min-width:260px;
  opacity:0;transform:translateY(-6px);visibility:hidden;pointer-events:none;
  transition:opacity .24s var(--e-swift),transform .24s var(--e-swift),visibility .24s;
}
.filtro.abierto .filtro-panel{opacity:1;transform:none;visibility:visible;pointer-events:auto}
/* Ronda 4 — Dropdown F, decidido hace tiempo y nunca aplicado al código
   real (ver nota "decision-dropdowns" del artefacto de comparación):
   "iconos reales, calmado — sin búsqueda, sin recuento, sin tick", esfera
   siempre gris con icono gris oscuro (mismos iconos que .mega-cat en el
   hover de "Producto" del nav — .frag/fragmento() es la misma función en
   los dos sitios). Sustituye al margen suelto de la ronda 6: ahora el
   icono vive dentro de .filtro-icono, no como hijo suelto del <span> de
   texto. Scoped a .filtro-panel a propósito: el selector de marca/modelo/
   año (mejorarSelector, familia .selector genérica) sigue con su propio
   criterio de "elegida" (fondo navy sólido), sin tocar. */
/* .selector-opcion genérico es justify-content:space-between (icono+nombre
   a un lado, el tick de "elegida" al otro; el badge de recuento que también
   vivía ahí se quitó en la ronda 7) — aquí no hay tick que empujar al
   extremo, así que con space-between el nombre quedaba pegado al borde
   derecho del panel en vez de al lado del icono. */
.filtro-panel .selector-opcion{justify-content:flex-start}
.filtro-panel .filtro-icono{
  flex:none;width:34px;height:34px;border-radius:50%;background:var(--papel-2);
  color:var(--tinta);display:grid;place-items:center;margin-right:12px;
  box-shadow:inset 0 0 0 0 var(--navy);transition:box-shadow .15s;
}
/* 23-sep-2026 (director: «el icono dentro de la esfera sí [se ve pequeño]…
   preferiría subir el icono, sin la esfera»): 16px→20px en la misma esfera de
   34px. El coche R2 («Acc. para vagón») es más ancho que alto: a 20px de ancho
   se quedaba más bajo que el resto, así que va a 24px para igualarlo a ojo. */
.filtro-panel .filtro-icono .frag{width:20px;height:20px}
.filtro-panel .filtro-icono .frag[viewBox^="0 0 622"]{width:24px;height:24px}
.filtro-panel .filtro-nombre{font:500 14.5px/1.2 var(--sans);color:var(--tinta)}
/* La elegida no lleva tick ni fondo navy sólido: fondo sutil + texto navy
   (mismo "esto está elegido" que .filtro-boton.abierto) y un contorno
   navy alrededor de su esfera — la esfera y el icono se quedan grises,
   calmados, igual que el resto ("elegida, contorno oscurecido": pedido
   del director, voz). */
.filtro-panel .selector-opcion[aria-selected="true"]{
  background:var(--placa);color:var(--tinta);border-radius:11px;
}
.filtro-panel .selector-opcion[aria-selected="true"] .filtro-nombre{color:var(--navy);font-weight:700}
.filtro-panel .selector-opcion[aria-selected="true"] .filtro-icono{box-shadow:inset 0 0 0 1.5px var(--navy)}
/* Ordenar vive al final de .filtro-grupo-derecha, pegado al margen derecho
   de la página: el left:0 de .filtro-panel de arriba (pensado para
   Categoría, que sí tiene sitio de sobra a su derecha) hacía que este panel
   creciera hacia la derecha y se saliera del margen (director, captura en
   iPhone/tablet, 30-sep-2026). Se ancla al lado contrario, igual que ya hace
   #ordenListaMovil en la píldora del teléfono. */
#ordenListaDesktop{left:auto;right:0}

.chips-filtro{display:flex;flex-wrap:wrap;gap:8px}
/* Antes: caja blanca sin relleno, misma línea que el borde general — se
   leía como un campo de formulario, no como "esto es lo que elegiste".
   Relleno --placa + texto navy la emparienta con el resto de estados
   "activo/elegido" del sistema (.entrada:hover, .filtro-boton.abierto).
   Segunda pasada: fuera también el borde — con solo el relleno se lee aún
   menos a caja de formulario y más a "píldora elegida" (feedback del
   director, comparando variantes con/sin borde). Tercera pasada: --placa es
   casi blanco y la fila de tarjetas de producto es blanco puro justo debajo
   — el chip se fundía con las cartas. Wash de navy muy tenue en su lugar:
   sigue leyéndose ligero, pero con identidad de marca propia, no "otra
   tarjeta blanca más" (feedback del director). */
/* Carril de categorías con foto: SOLO teléfono (activado en 19 · ≤720px,
   más abajo) — en escritorio el desplegable de texto ya resuelve esto bien
   (pedido del director, tras comparar variantes en un artefacto). Oculto
   aquí por defecto para que ningún ancho de escritorio/tablet lo enseñe. */
.rail-categorias{display:none}
.franja-filtros{display:none}
/* Cabecera compartida y selector de densidad: mismo criterio que el carril
   de arriba, ocultos aquí por defecto (activados en 19 · ≤720px). La
   envoltura .cabecera-compartida en sí no necesita regla propia aquí — es un
   <div> sin estilo fuera del media query, transparente para el layout de
   escritorio/tablet. */
.vista-densidad{display:none}
.chip-filtro{
  display:inline-flex;align-items:center;gap:8px;
  padding:7px 7px 7px 14px;border-radius:4px;
  background:rgba(0,40,86,.08);
  font:600 12px/1 var(--sans);color:var(--navy);
}
.chip-filtro button{
  position:relative;
  display:grid;place-items:center;width:20px;height:20px;color:var(--tinta-2);border-radius:50%;
  transition:color .18s,background .18s;
}
.chip-filtro button::after{content:"";position:absolute;inset:-10px}
/* Antes: relleno --no sólido + icono blanco — mucho para una × de quitar un
   filtro, competía con el rojo de verdad (badges de stock, etc). Wash tenue
   del mismo rojo: se entiende igual que "esto borra" sin gritar (feedback
   del director). */
@media(hover:hover){.chip-filtro button:hover{color:var(--no);background:rgba(140,47,35,.14)}}
.chip-filtro button svg{width:11px;height:11px;stroke:currentColor;stroke-width:2}
/* Un toque más grande que el resto de .folio (11px): es el único dato
   duro de la barra, se lee de reojo para saber "cuánto hay". */
#conteo{font-size:12.5px;letter-spacing:.14em}
/* Más aire en escritorio (pedido del director): la barra entera leía
   apretada para el ancho disponible. Solo espaciado — el tamaño del texto
   se subió aquí mismo una ronda y el director lo devolvió el mismo día
   ("está muy grande el texto... es texto secundario, antes lo tenía bien"):
   .filtro-boton/.chip-filtro/#conteo se quedan en su tamaño base (14px/
   12px/12.5px, ver arriba), solo cambia el hueco entre elementos. Solo
   desde 921px: en tablet/móvil se queda exactamente igual que antes. */
@media(min-width:921px) and (min-height:501px),(min-width:1001px){
  .barra-filtros{gap:12px 22px;padding-bottom:14px;margin-bottom:32px}
  .filtro-grupo{gap:12px 30px}
}
/* .barra-filtros ya es space-between: con dos .filtro-grupo como únicos
   hijos directos, "Ordenar" queda solo en el extremo derecho sin nada
   más — flex-shrink:0 evita que se comprima si la categoría o los chips
   crecen mucho a la izquierda. */
.filtro-grupo-derecha{flex-shrink:0}
/* El conteo se probó pegado a Ordenar (30-sep-2026) y el director lo quitó
   de ahí ese mismo día, voz: "el 123 entradas ahí no me gusta... buscar un
   sitio natural, en pequeñito a la derecha, debajo" — pasa a su propia
   línea bajo toda la barra, ya fuera de .filtro-grupo-derecha. Mismo #conteo
   de siempre (pintar() no cambia): el clip-rect que lo oculta en móvil (ver
   19 · MÓVIL) sigue aplicando igual, esté donde esté en el DOM. max-width:none
   porque es un <p>: sin esto hereda el 62ch de la prosa (línea ~168) y el
   text-align:right solo alinea dentro de esa caja angosta, no contra el
   borde de la barra — quedaba centrado en vez de a la derecha. */
/* margin-bottom 20px→32px (pedido del director: "un poco más de aire debajo
   de 123 entradas y la primera fila de productos") — .plancha no añade nada
   propio de su lado, así que este margen es todo el hueco entre ambos. */
.conteo-linea{text-align:right;margin:-16px 0 32px;color:var(--tinta-2);max-width:none}
/* El panel lateral de "Filtros" (drawer con velo+hoja, mock "F2 — drawer
   bajo demanda", 30-sep-2026) vivió aquí un rato: con Precio como única
   sección real, el propio director lo notó en la misma sesión ("al final lo
   que estamos haciendo es eliminar el drawer, ¿no?... si solo va a ser una o
   dos filas no tiene sentido") — de acuerdo, se quita entero. Precio pasó
   entonces a ser un desplegable más (#precioDesktop, junto a Categoría/
   Ordenar) y, en la ronda siguiente, el director lo descartó del todo
   ("eso no lo quiero ver ni en escritorio ni en móvil") — #precioDesktop ya
   no existe en catalogo.astro. Todo lo de esta sección (.drawer-velo/
   .drawer/.drawer-cab/.drawer-cuerpo/.drawer-seccion/.drawer-pie/.drawer-
   limpiar/.drawer-ver, y el markup+JS que los usaba, más el propio
   desplegable de Precio) queda recuperable en el historial de git de esta
   rama (commits c9102ea y 4e5d17a, y el commit que introdujo el
   desplegable) si hiciera falta retomarlo. */

/* Paginador: números fijos, no "cargar más" — acota el scroll en cada
   vista, no solo en la primera. Chip navy relleno solo en la página activa
   — mismo lenguaje de "esto está elegido" que .selector-opcion[aria-selected]
   y .paso.activo — sin borde ni caja en el resto (tres rondas con el
   director: caja cuadrada de más, tipografía sola de menos, círculo en cada
   número de más; este punto medio — relleno solo en el activo — fue el que
   se quedó). */
.paginador{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:clamp(6px,1vw,14px);margin-top:clamp(24px,3.5vw,40px)}
.pagina-boton{
  position:relative;
  min-width:0;height:auto;padding:8px 12px;display:grid;place-items:center;border-radius:3px;
  font:600 15px/1 var(--mono);color:var(--tinta-2);
  border:none;background:none;
  transition:color .18s var(--e-swift),background .18s var(--e-swift);
}
/* Ampliación invisible, no padding real: un padding mayor movía 8px la
   altura de la página en ESCRITORIO también (regla que no se rompe). El
   gap se abre aparte en móvil (§19) para que esta ampliación no se solape
   entre botones vecinos cuando el hueco real es de 6px. */
.pagina-boton::after{content:"";position:absolute;inset:-6px}
.pagina-boton svg{width:17px;height:17px;stroke:currentColor}
@media(hover:hover){.pagina-boton:not(:disabled):hover{color:var(--tinta)}}
.pagina-boton:disabled{opacity:.3;pointer-events:none}
.pagina-num.activa{background:var(--navy);color:var(--papel)}
/* D1 (confirmado ronda 4, escritorio): línea fina arriba, "‹ Anterior
   1 2 3 4 5 6 Siguiente ›" con la página actual subrayada (no la
   píldora navy de arriba, que en desktop ya no se usa — solo queda
   activa para P1 en móvil, ver @media abajo) + rango de productos. */
/* Ronda 8 (pedido del director, sobre el caso más común —pocas páginas—:
   "se ve con muchísimo aire y mal espaciado... no dijimos que la Opción A"):
   el grid 1fr/auto/gap/1fr con justify-self:start/end en Anterior/Siguiente
   los empujaba a los BORDES del contenedor (1200px+ en escritorio) sin
   importar cuántos números hubiera en medio — con pocas páginas eso dejaba
   un hueco enorme y descentrado. La Opción A aprobada (artefacto) es UN
   bloque centrado como conjunto — Anterior, números y Siguiente pegados
   entre sí, no repartidos a los extremos del ancho disponible. */
.paginador-d1{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:clamp(10px,1.6vw,22px);width:100%;border-top:1px solid var(--linea-f);padding-top:22px}
/* Sans en vez de mono + navy: el mono de .pagina-boton (base, pensado para
   P1 en móvil) leía plano contra la referencia confirmada — ahí "Anterior"/
   "Siguiente" van en negrita navy, no en gris mono. */
/* Ronda 9 (pedido del director, voz: "las flechas un poco más de tamaño, en
   conjunto, a todo este componente"): «‹ Anterior»/«Siguiente ›» iban a 15px,
   MÁS PEQUEÑO que los números de página que rodean (18px) — ahí es donde más
   se notaban chicas las flechas, embebidas en ese texto. Sube el componente
   entero un paso (15→16, 18→19, 13→14), no solo las flechas sueltas. */
.paginador-d1 .pagina-boton{font:700 16px/1 var(--sans);color:var(--navy)}
/* Ronda 26 (pedido del director: "más trazo, solo la flecha, no la línea") —
   ‹/› es texto suelto dentro del mismo botón que "Anterior"/"Siguiente", así
   que para engordar solo el glifo (sin tocar el tamaño, ya resuelto en la
   Ronda 9) se aísla en su propio span y sube de peso; la palabra se queda en
   700. Archivo es variable (100–900), así que el salto no trae un corte de
   fuente aparte. */
.pagina-flecha{font-weight:900}
.pd1-numeros{display:flex;align-items:center;justify-content:center;gap:clamp(14px,2.2vw,24px)}
.pd1-numeros .pagina-num{padding:5px 2px 9px;border-radius:0;border-bottom:2px solid transparent;font:600 19px/1 var(--sans);color:var(--tinta-2)}
.paginador-d1 .pagina-num.activa{background:none;color:var(--navy);font-weight:800;border-bottom-color:var(--navy)}
/* Ronda 8 (regla de puntos suspensivos, aprobada junto con la Opción A pero
   nunca escrita): entre huecos de la ventana 1…actual-1,actual,actual+1…
   total — mismo tono apagado que un número sin elegir, sin interacción (no
   es un botón, no lleva página a la que ir).
   30-sep-2026: el "…" tipográfico (glifo único) flotaba visiblemente más
   alto que la línea de base de los números vecinos — no es un desajuste de
   padding, es cómo Archivo dibuja ese carácter. Probadas varias correcciones
   (bajarlo con transform, subir/bajar el padding): todas dejaban los puntos
   descolgados por debajo de la línea en vez de resolverlo. Tres puntos
   reales ("•••") con letter-spacing propio se apoyan solos en el centro de
   la línea, igual que un número, sin depender de dónde decida el font
   dibujar el glifo de elipsis. */
.pd1-puntos{padding:5px 2px 9px;font:600 15px/1 var(--sans);color:var(--tinta-2);letter-spacing:3px}
.pd1-rango{width:100%;margin-top:10px;text-align:center;font:500 14px/1.2 var(--sans);color:var(--tinta-2)}
/* "Ir a la página" — Opción D (mock "paginación y filtro", 30-sep-2026,
   elegida para escritorio). Siempre visible bajo el rango, no escondida en
   un popover: con la ventana dinámica (primeras/últimas 3 + vecinas de la
   actual) saltar lejos sigue necesitando más de un clic sin esto. */
.pd1-salto{
  width:100%;display:flex;align-items:center;justify-content:center;gap:10px;
  margin-top:14px;
}
.pd1-salto label{font:500 13px/1 var(--sans);color:var(--tinta-2)}
.pd1-salto input{
  width:64px;height:34px;padding:0 10px;border:1px solid var(--linea-f);border-radius:4px;
  background:var(--blanco);color:var(--tinta);font:600 14px/1 var(--sans);text-align:center;
  font-variant-numeric:tabular-nums;
}
.pd1-salto input:focus-visible{outline:2px solid var(--navy);outline-offset:1px}
.pd1-salto button{
  height:34px;padding:0 16px;border:1px solid var(--navy);border-radius:4px;background:none;
  color:var(--navy);font:700 12px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;
  cursor:pointer;transition:background .18s var(--e-swift),color .18s var(--e-swift);
}
@media(hover:hover){.pd1-salto button:hover{background:var(--navy);color:var(--papel)}}
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){
  /* Paginador móvil, Opción B2 (director, 30-sep-2026, mock "paginación y
     filtro" — sustituye a la Opción C del 25-sep, que abría un menú
     flotante con una rejilla de números; código recuperable en el
     historial de esta rama). Flechas redondas de contorno a los lados
     (igual que en C, sin tocar) y en medio: número de página grande, el
     rango de productos debajo y un riel deslizable con una burbuja que se
     ve mientras arrastras — un solo toque en cualquier punto del riel
     también salta ahí mismo. El driver (pointer events + teclado) está en
     configurarRielMovil(), en catalogo.astro. */
  .paginador-p1{position:relative;display:flex;align-items:center;gap:14px;width:100%}
  .paginador-p1 .pagina-boton,.paginador-p1 .pagina-boton:hover{
    width:44px;min-width:44px;height:44px;padding:0;border-radius:50%;
    background:none;color:var(--navy);box-shadow:inset 0 0 0 1.5px rgba(0,40,86,.34);
  }
  .paginador-p1 .pagina-boton svg{width:20px;height:20px;stroke-width:2.4;fill:none;stroke-linecap:round;stroke-linejoin:round}
  .p1-centro{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:8px}
  .numero-grande{font:800 38px/1 var(--sans);color:var(--navy);font-variant-numeric:tabular-nums}
  .p1-subt{font:500 13px/1 var(--sans);color:var(--tinta-2)}
  /* El padding-top reserva sitio a la burbuja, que flota por encima del riel
     sin empujar el resto del componente cuando aparece. */
  .p1-riel-envoltura{width:100%;position:relative;padding-top:32px}
  .riel{
    position:relative;width:100%;height:10px;border-radius:6px;
    background:rgba(0,40,86,.12);cursor:pointer;touch-action:none;-webkit-tap-highlight-color:transparent;
  }
  /* La pista se ve fina (10px) a propósito, pero pointerdown/move/up están
     enganchados al propio .riel: sin esto, acertar con el dedo en esa franja
     tan estrecha costaba (director, iPhone, 30-sep). ::after solo amplía el
     área que recibe el toque, no el ancho — calcular() en configurarRielMovil()
     usa rect.left/width, así que la ampliación vertical no desplaza el cálculo. */
  .riel::after{content:"";position:absolute;top:-16px;bottom:-16px;left:0;right:0}
  .riel:focus-visible{outline:2px solid var(--navy);outline-offset:4px}
  .riel-relleno{position:absolute;top:0;left:0;height:100%;border-radius:6px;background:var(--navy);pointer-events:none}
  .riel-pulgar{
    position:absolute;top:50%;width:22px;height:22px;border-radius:50%;background:var(--papel);
    border:3px solid var(--navy);box-shadow:0 2px 8px rgba(18,24,31,.28);
    transform:translate(-50%,-50%);pointer-events:none;
  }
  .riel-burbuja{
    position:absolute;top:0;left:0;transform:translateX(-50%);background:var(--navy);color:var(--papel);
    font:800 14px/1 var(--sans);padding:6px 11px;border-radius:9px;white-space:nowrap;
    font-variant-numeric:tabular-nums;opacity:0;transition:opacity .12s var(--e-swift);pointer-events:none;
  }
  .riel-burbuja::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);border:5px solid transparent;border-top-color:var(--navy)}
  .riel-burbuja.visible{opacity:1}
  @media(hover:none){
    .paginador-p1 .pagina-boton{transition:transform .16s var(--e-out)}
    .paginador-p1 .pagina-boton:active{transform:scale(.94)}
  }
  @media(prefers-reduced-motion:reduce){.riel-burbuja{transition:none}}
  /* De aquí para abajo ya es teléfono de verdad, no tablet (el resto del
     bloque cubre hasta 920px de un tirón) — mismo componente, un poco más
     comedido: en el iPhone del director se veía "enorme entero" (captura,
     30-sep-2026). Los botones se quedan en 40px, por encima del mínimo táctil
     de 44pt de Apple lo justo para no sentirse apretados. */
  @media(max-width:480px),(orientation:landscape) and (max-height:500px){
    .paginador-p1{gap:10px}
    .paginador-p1 .pagina-boton,.paginador-p1 .pagina-boton:hover{width:40px;min-width:40px;height:40px}
    .paginador-p1 .pagina-boton svg{width:18px;height:18px}
    .p1-centro{gap:6px}
    .numero-grande{font-size:30px}
    .p1-subt{font-size:12px}
    .p1-riel-envoltura{padding-top:28px}
    .riel{height:8px}
    .riel-pulgar{width:18px;height:18px;border-width:2.5px}
    .riel-burbuja{font-size:12.5px;padding:5px 9px}
  }
}

/* ---------- 10 · FICHA ---------- */
/* La celda de la foto es de alto fijo (el del marco, ver .galeria .lamina) y va arriba: con
   align-self:start (en .ficha-lamina) su position:sticky sí tiene recorrido y la foto te
   acompaña mientras bajas por el texto, que suele ser más alto. Antes la lámina se estiraba
   hasta el final de la columna de texto y rellenaba con la propia foto difuminada. */
/* minmax(0,560px) a secas exprimía la columna de texto a 54-225px medidos en
   vivo entre 921 y ~1150px (tablet apaisada / portátil pequeño) — la pista
   crecía hasta 560px sin importar cuánto quedara libre. min(50%,560px) la
   tapa en la mitad del contenedor: nunca se come más de lo que sobra. */
.ficha-split{display:grid;grid-template-columns:minmax(0,min(50%,560px)) minmax(280px,1fr);gap:clamp(26px,5vw,72px)}
/* min-width:0: como ítem del grid, su mínimo automático es el min-content de
   sus hijos — con muchas miniaturas eso puede superar el ancho del track y
   forzar todo el grid a desbordar (hallado en vivo con 9 fotos en móvil). */
/* El riel de miniaturas sigue el alto de la lámina vía JS (ajustarAltoMinis). */
.ficha-lamina{position:sticky;top:calc(var(--masthead-total, var(--masthead)) + 22px);align-self:start;min-width:0;display:flex;flex-direction:column}
/* Miniaturas verticales a la izquierda + lámina principal a la derecha
   (referencia del director). El alto real del riel de miniaturas lo fija
   JS (montarGaleria) igualándolo al alto ya renderizado de la lámina, con
   scroll interno si no caben todas — así manda la lámina, no la lista. */
.galeria-bloque{display:flex;gap:10px;align-items:flex-start;flex:1;min-height:0}
.galeria-minis{display:flex;flex-direction:column;width:72px;flex-shrink:0;position:relative}
.galeria-minis-riel{display:flex;flex-direction:column;gap:8px;overflow-y:auto;scrollbar-width:none}
.galeria-minis-riel::-webkit-scrollbar{display:none}
/* background:var(--blanco), mismo motivo que .galeria .lamina (más abajo):
   con contain, cualquier foto que no sea cuadrada deja aire dentro del
   botón y ese aire tiene que ser blanco puro, no el --placa gris de las
   tarjetas del catálogo. */
.galeria-minis-riel button{
  width:72px;height:72px;flex-shrink:0;background:var(--blanco);border:1px solid var(--linea);
  display:grid;place-items:center;padding:5px;transition:border-color .2s;overflow:hidden;
}
.galeria-minis-riel button img{max-height:100%;max-width:100%;object-fit:contain;mix-blend-mode:multiply}
.galeria-minis-riel button.fotografica{padding:0}
.galeria-minis-riel button.fotografica img{width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;mix-blend-mode:normal}
.galeria-minis-riel button.fotografica picture{display:block;width:100%;height:100%}
/* Escritorio: la miniatura de una fotografía toma la forma de la foto (sin bandas blancas arriba y abajo). */
@media(min-width:921px) and (min-height:501px){
  .galeria-minis-riel button.fotografica{height:auto}
  .galeria-minis-riel button.fotografica picture{height:auto}
  .galeria-minis-riel button.fotografica img{height:auto}
}
.galeria-minis-riel button[aria-current]{border-color:var(--navy)}
/* Miniatura cuya foto no cargó ni con su respaldo (SS.fotoFallo): el icono de su categoría
   sobre la placa, sin rótulo (72 px no dan para «Foto pendiente»). */
.galeria-minis-riel button.sin-foto{background:var(--placa)}
.galeria-minis-riel button.sin-foto .frag{width:40%;height:40%;color:var(--tinta-2);opacity:.55}
@media(hover:hover){.galeria-minis-riel button:hover{border-color:var(--navy)}}
/* Flechas arriba/abajo del riel de miniaturas: sobre el propio riel, nunca lo hacen crecer. */
.galeria-minis-flecha{
  position:absolute;left:50%;width:30px;height:30px;margin-left:-15px;border-radius:50%;z-index:2;display:grid;place-items:center;
  background:rgba(255,255,255,.8);color:var(--tinta-2);box-shadow:0 1px 3px rgba(18,24,31,.14);
  opacity:0;pointer-events:none;transition:opacity .25s var(--e-swift),background .2s var(--e-swift);
}
/* Como IKEA: medio círculo sobre el borde del riel, hacia donde quedan más fotos. */
.galeria-minis-flecha.arriba{top:-12px}
.galeria-minis-flecha.abajo{bottom:-12px}
.galeria-minis-flecha svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.2;fill:none}
@media(hover:hover){
  .galeria-minis:hover .galeria-minis-flecha:not(.oculto){opacity:1;pointer-events:auto}
  .galeria-minis-flecha:hover{background:rgba(255,255,255,.96);color:var(--tinta)}
}
@media(hover:none){.galeria-minis-flecha:not(.oculto){opacity:1;pointer-events:auto}}
.galeria{position:relative;flex:1;min-width:0;display:flex;flex-direction:column}
/* Marco fijo por producto (25-sep-2026, mock «Galería sin relleno», opción A): la lámina
   ya NO se estira a la altura de la columna de texto ni rellena con un fondo difuminado
   (al director no le gusta que se rellenen las fotos). Su forma es --marco (de 1 a 1,5, la
   pone sistema.js/galeriaHTML desde scripts/medir-fotos.mjs; 1 si no hay), igual en móvil
   y en escritorio y igual en todas las fotos del producto: así ni el texto de debajo ni la
   página saltan al pasar de foto. Qué se hace con cada foto dentro del marco: ver .recorte,
   .lienzo y .de-color más abajo. */
/* padding:0 anula el "marco por padding" del catálogo (.lamina, más
   arriba): esa regla es genérica a .lamina y aquí se colaba sin querer,
   comiéndose parte de la caja antes de que el img (más abajo) calculara su
   propio %. La ficha ya controla su propio margen con max-width/max-height
   en el img. */
/* background:var(--blanco), no el --placa gris que hereda de .lamina (más
   arriba, pensado para las tarjetas del catálogo): con contain (más abajo)
   sobra aire dentro de la caja siempre que la foto no sea 4:3 exacto, y ese
   aire quedaba con un tinte gris visible en vez de blanco puro — más notorio
   cuanto más apaisada la foto (feedback del director, "ARB recovery strap").
   Blanco puro además hace innecesario cualquier mix-blend-mode para las
   fotos de estudio normales: su fondo ya es blanco, coincide exacto. */
.galeria .lamina{aspect-ratio:var(--marco,1);height:auto;max-height:none;min-height:0;padding:0;background:var(--blanco)}
/* .lamina es grid con place-items:center: por defecto un grid item se
   encoge a su contenido con "center" (no hace stretch), así que <picture>
   quedaba con su propio tamaño intrínseco y el max-height/max-width en % del
   img de abajo no tenían una caja real contra la que resolver — de ahí la
   franja/costura vacía cuando la lámina se estiraba más que el ancho de la
   foto (feedback del director, ronda 5). Forzando la caja del <picture> al
   100% del área del grid, el contain de siempre (.lamina img, más abajo) ya
   calcula bien el 86%/88% contra el alto real. */
.galeria .lamina picture{display:block;width:100%;height:100%}
/* A propósito NO cover aquí (probado en ronda 5 y descartado): con la lámina
   estirándose al alto de la columna de texto ("Leer más", vehículo
   confirmado…), cover iba recortando cada vez más apretado y la silla se
   veía "creciendo" — contain dentro del mismo % de ancho fijo (.lamina img
   más abajo) mantiene el tamaño aparente del producto siempre igual; el
   sobrante de alto queda como aire, no como zoom (referencia del director). */
/* Ronda 7: la silla se veía chica dentro de tanto blanco — más zoom, sin
   recortar nada. El % va en el propio img (no como padding en .lamina): a
   diferencia del catálogo, esta lámina no tiene aspect-ratio fijo (se
   estira al alto de la columna de texto), y el padding porcentual siempre
   resuelve contra el ANCHO de la caja, incluso en el eje vertical (así lo
   define CSS) — con una caja que cambia de alto y no de ancho, ese padding
   daba un marco vertical mínimo e impredecible. max-width/max-height sí
   resuelven cada uno contra su propio eje real, y el ancho (fijo pase lo
   que pase con "Leer más") sigue mandando: la silla no cambia de tamaño
   aparente, solo gana presencia dentro de su marco (referencia del
   director: la silla ocupando ~70-75% del alto del visor). */
/* Ronda 7: la foto en sí (cuadrada, 1000x1000) ya trae su propio margen de
   estudio alrededor de la silla — con la lámina más alta que ancha, el %
   máximo que cabe sin recortar nada lo marca el ancho (aquí, ~96% de 478px),
   así que el % de alto que realmente llena varía con la altura de la
   lámina en cada momento (min-height, "Leer más"…): no hay forma de fijar
   un % de alto exacto sin recortar la silla o ensanchar la lámina — ninguna
   de las dos pedida (referencia del director, pero "sin recortar ninguna
   parte" manda primero). Aquí, al máximo que permite el ancho sin tocar
   los bordes. */
.galeria .lamina img{max-width:96%;max-height:96%}
/* .lamina.fotografica (foto real, sin fondo blanco: correas, mantas…) usa
   cover en el catálogo, pensado para su caja de aspect-ratio fijo (4/3). Aquí
   la caja no es fija: se estira al alto de la columna de texto, así que
   cualquier foto cuya proporción no cuadre con la del momento (apaisada,
   pero también cuadrada como una foto de estilo de vida) quedaba recortada
   por cover — primero se vio con la correa (feedback del director: "ARB
   recovery strap", entraba cortada por los dos lados), luego con fotos
   cuadradas de estilo de vida (p.ej. "tienda techo flinders": el cover se
   comía el título y la parte de abajo). Contain siempre, sin distinguir
   orientación, es la única forma de no recortar nunca ningún producto en
   esta caja de alto variable; el fondo blanco de .galeria .lamina (más
   arriba) hace que el aire sobrante no se note. */
.galeria .lamina.fotografica img{object-fit:contain;mix-blend-mode:normal}
/* Foto de ambiente (sistema.js, tratoFoto): recortada a la forma del marco mirando a su
   sujeto — --pos es el object-position que sale del foco medido (o de
   scripts/focos-manuales.json). Nada se pierde de verdad: el visor (lupa) la abre entera.
   Sustituye a la franja difuminada de la misma foto que había antes. */
.galeria .lamina.recorte img{
  width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;object-position:var(--pos,50% 50%);
  mix-blend-mode:normal;
}
/* Foto de ambiente que habría que recortar más de un tercio para que case con el marco:
   entera, centrada, sobre un lienzo liso — no se recorta ni se rellena con la propia foto. */
.galeria .lamina.lienzo{background:var(--lienzo,#D6D8DD)}
.galeria .lamina.lienzo img{max-width:100%;max-height:100%;object-fit:contain;mix-blend-mode:normal}
/* Foto de estudio sobre un fondo liso que no es blanco (sistema.js, tratoFoto):
   la lámina toma ese color y la foto va sin fundir, o el multiply la
   oscurecería contra su propio fondo (Nitroplus sobre negro, Pureview sobre gris). */
.galeria .lamina.de-color img{mix-blend-mode:normal}
.galeria-riel{
  display:flex;flex:1;min-height:0;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
}
.galeria-riel::-webkit-scrollbar{display:none}
.galeria-riel>.lamina{flex:0 0 100%;scroll-snap-align:start}
/* Sin placa visible: integradas en la foto, no leen como un botón aparte
   (feedback del director) — el contraste lo da la sombra blanca del icono,
   no un fondo. El área de toque real la da ::after, no el tamaño visible. */
.galeria-nav{
  position:absolute;top:50%;margin-top:-17px;width:34px;height:34px;
  display:grid;place-items:center;color:var(--tinta);opacity:.65;
  transition:opacity .2s var(--e-swift);
}
.galeria-nav::after{content:"";position:absolute;inset:-11px} /* área táctil ≥48px sin agrandar el icono */
.galeria-nav svg{
  width:22px;height:22px;stroke:currentColor;stroke-width:1.8;fill:none;
  filter:drop-shadow(0 1px 2px rgba(255,255,255,.9)) drop-shadow(0 0 5px rgba(255,255,255,.75));
}
@media(hover:hover){.galeria-nav:hover{opacity:1}}
.galeria-nav.prev{left:10px}
.galeria-nav.next{right:10px}
/* Flechas de la foto principal: círculo blanco con sombra, bien visibles sobre cualquier foto
   (director: «se ven demasiado poco»). El visor grande (.lightbox) conserva las suyas. */
.galeria .galeria-nav{
  width:32px;height:32px;margin-top:-16px;border-radius:50%;background:rgba(255,255,255,.78);
  color:var(--tinta-2);box-shadow:0 1px 3px rgba(18,24,31,.14);opacity:0;
  transition:opacity .25s var(--e-swift),background .2s var(--e-swift),transform .2s var(--e-swift);
}
.galeria .galeria-nav svg{width:17px;height:17px;stroke-width:2;filter:none}
/* Con ratón, las flechas aparecen al pasar por la foto; en táctil (sin hover) se quedan visibles. */
@media(hover:hover){.galeria:hover .galeria-nav,.galeria .galeria-nav:focus-visible{opacity:1}}
@media(hover:none){.galeria .galeria-nav{opacity:1}}
@media(hover:hover){.galeria .galeria-nav:hover{background:rgba(255,255,255,.96);color:var(--tinta);transform:scale(1.06)}}
/* Lupa: clic en la foto abre el visor grande (feedback del director) — el
   cursor zoom-in es la única pista, sin icono propio superpuesto (leía
   redundante junto al propio cursor — feedback del director, ronda 2). */
.galeria .lamina{cursor:zoom-in;overflow:hidden}
/* Lupa en el sitio (escritorio): la foto se acerca dentro de su propio marco y sigue al ratón. */
.galeria .lamina img{transition:transform .25s var(--e-swift);transform-origin:var(--zx,50%) var(--zy,50%)}
.galeria .lamina.lupa{cursor:zoom-out}
.galeria .lamina.lupa img{transform:scale(var(--zoom,2.4));transition:transform .25s var(--e-swift)}
@media(prefers-reduced-motion:reduce){.galeria .lamina img{transition:none}}
.lightbox{
  position:fixed;inset:0;background:rgba(18,24,31,.92);z-index:200;
  display:grid;place-items:center;padding:clamp(20px,6vw,60px);
  opacity:0;pointer-events:none;transition:opacity .22s var(--e-swift);
}
.lightbox.activa{opacity:1;pointer-events:auto}
/* La foto flotando directa sobre el velo oscuro leía "sin encajar" (feedback
   del director): una lámina clara (mismo --placa que el resto del catálogo)
   le da marco propio y un tope de tamaño cómodo — no hace falta más resolución
   real para verse bien, solo un encaje digno en vez de forzarla a pantalla completa. */
.lightbox-marco{
  max-width:100%;max-height:100%;background:var(--placa);border-radius:10px;
  padding:clamp(14px,3vw,28px);box-shadow:0 30px 70px -24px rgba(0,0,0,.55);
  display:grid;place-items:center;
}
.lightbox-marco img{display:block;max-width:min(70vw,720px);max-height:70dvh;object-fit:contain;cursor:zoom-in}
/* Comportamiento habitual de lupa (feedback del director): un clic más sobre
   la foto ya encajada la lleva a su tamaño real y el marco pasa a scroll —
   sin más resolución que ofrecer, "zoom" es verla nativa en vez de reducida. */
.lightbox-marco.zoom{
  width:min(96vw,1400px);height:min(92dvh,1400px);max-width:96vw;max-height:92dvh;
  display:block;overflow:auto;padding:0;
}
.lightbox-marco.zoom img{max-width:none;max-height:none;width:auto;height:auto;cursor:zoom-out;margin:auto}
/* 44px, no 40: y con margen de seguridad — en horizontal con notch, el
   rincón superior derecho es justo donde vive el recorte de la cámara. */
.lightbox-cerrar{
  position:absolute;top:max(16px,env(safe-area-inset-top));right:max(16px,env(safe-area-inset-right));
  width:44px;height:44px;display:grid;place-items:center;color:var(--papel);
}
.lightbox-cerrar svg{width:22px;height:22px;stroke:currentColor;stroke-width:1.8;fill:none}
.lightbox .galeria-nav{color:var(--papel);opacity:.8}
.lightbox .galeria-nav svg{filter:none}
/* Teléfono apaisado con Dynamic Island / notch: las flechas van dentro de la zona segura
   (--zs-i / --zs-d valen 0 donde no hay), o la isla tapa una (director, iPhone Pro Max). */
.lightbox .galeria-nav.prev{left:max(clamp(6px,3vw,26px),calc(var(--zs-i,0px) + 8px))}
.lightbox .galeria-nav.next{right:max(clamp(6px,3vw,26px),calc(var(--zs-d,0px) + 8px))}
.bloque-totales{
  /* --blanco, no --placa: mismo criterio que .paso::before/.resumen-vehiculo
     en catalogo.astro (feedback del director) — el panel de "Tu cotización"
     (incluida la fila del vehículo) se leía casi fundido con el fondo de
     la página. */
  border:1px solid var(--linea-f);
  clip-path:polygon(0 0,calc(100% - var(--corte-x)) 0,100% var(--corte-y),100% 100%,0 100%);
  padding:18px 20px;background:var(--blanco);
}
.bloque-totales .fila{display:flex;justify-content:space-between;align-items:baseline;padding:5px 0}
/* Misma "Roboto Mono Precio" que .precio (más arriba): .precio-grande es el
   mismo tipo de cifra (precio de referencia, subtotal) en ficha de producto
   y cotización — se quedó en var(--mono) al crear la fuente sin cero cruzado
   y el 0 volvía a salir con la barra ahí (feedback del director). */
.precio-grande{font:700 2.1rem/1 "Roboto Mono Precio",var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.03em}
/* Misma receta que .ayuda-tip (producto.astro, ronda 19): fondo claro, borde
   --linea-f, esquina recta — no el doble contorno (border+outline) que había
   aquí antes, que no casaba con .bloque-totales justo encima (mismo --placa,
   un solo borde) y se leía como una caja suelta de otro sistema (feedback
   del director: "recuadros... rompe muchísimo"). */
.nota{
  background:var(--placa);border:1px solid var(--linea-f);
  padding:13px 16px;font-size:13.5px;color:var(--tinta-2);max-width:none;
}
.nota b{color:var(--tinta)}
.veredicto{
  display:inline-flex;align-items:center;gap:10px;
  font:500 12px/1 var(--mono);letter-spacing:.06em;
  background:var(--navy);color:var(--papel);padding:10px 14px;
}
/* Verde solo cuando la compatibilidad está confirmada de verdad (universal o
   vehículo real coincidente) — navy es el estado por defecto/neutral de
   siempre, no cambia mientras no haya confirmación. */
.veredicto.confirmado{background:var(--ok)}

/* ---------- 11 · COTIZACIÓN ---------- */
/* .g-hoja: tabla de partidas + total, en una sola tarjeta (Ronda 5,
   27-sep-2026 — decisión cerrada del director: "quiero que quede como P2").
   Antes eran dos piezas separadas: .cot-tabla (panel con la lista de
   partidas) al lado de .resumen (aside con position:sticky, columnas fijas y
   tope de alto — el resumen del carrito, repetido). Con el sticky fuera
   (dejó de tener sentido sin dos columnas que llenar), ambas piezas se
   funden en una: la lista arriba, el total abajo, todo en el flujo normal
   del documento — un carrito largo simplemente alarga la tarjeta y la
   página, como el resto del sitio.
   Esta ronda probó varias familias de líneas (C1: cuatro datos sueltos a la
   derecha · C2: tres columnas repartidas · C3/C4: variaciones de la fila de
   móvil ensanchada) y de pie (ejes B de ancho de botón, R de qué alineación
   lleva el total, N de cómo se reparten las notas, U de dónde va "USD")
   probándolas todas en vivo con clases de <body> y variables CSS para
   alternar sin recargar. Aquí solo queda la combinación elegida — C2 en
   escritorio, pie "P2" (r:2,u:2,b:3,n:2,sin icono) — ya fija, sin ejes ni
   clases de variante. */
.g-hoja{--fil:#D5D8DE;--th:88px;--py:26px;--nf:17px;--tenue:#5B6573;font-family:var(--sans);color:var(--tinta);display:block}
.g-lista{display:contents}
.g-hoja .cot-usd{font-size:.56em;font-weight:600;color:var(--tinta-2);margin-right:5px;letter-spacing:.03em;vertical-align:.08em}
/* Kerning de la coma de millar: "Roboto Mono Precio" es monoespaciada, así
   que la coma del separador de miles deja un hueco más ancho que cualquier
   dígito — font-style:normal (es un <i>, para no heredar cursiva) + margen
   negativo le quitan ese aire sin tocar el resto de la cifra. Hallazgo
   propio, midiendo el pie a lupa en esta ronda — tipografía más cuidada,
   no texto nuevo. */
.g-co{font-style:normal;margin:0 -.14em}
.g-regla{display:none}

/* cabecera: "Tu carrito" + recuento, filete grueso arriba (mismo tratamiento
   que "Total estimado" al final — la tarjeta abre y cierra con el mismo
   trazo). */
.g-h{border-top:2px solid var(--tinta);padding:20px 0 16px}
.g-ht{margin:0;display:flex;align-items:baseline;justify-content:space-between;gap:14px;width:100%;font:700 clamp(1.15rem,1.6vw,1.4rem)/1.15 var(--sans)}
.g-cnt{font:500 14px/1 var(--sans);color:var(--tinta-2)}
.g-cols{display:none}

/* líneas (móvil y tablet estrecha, <921px): foto | nombre + total / cantidad + quitar */
.g-l{list-style:none;margin:0;padding:0;border-top:1px solid var(--fil)}
.g-i{display:grid;grid-template-columns:var(--th) minmax(0,1fr) auto;grid-template-areas:"f t s" "f c c";column-gap:14px;row-gap:10px;align-items:start;padding:var(--py) 0;border-bottom:1px solid var(--fil)}
.g-f{grid-area:f;display:block;width:var(--th);height:var(--th)}
.g-f .lamina{width:100%;height:100%;aspect-ratio:1/1;clip-path:none;border-radius:10px;flex:none}
/* Mismo acercamiento que .zoom (2%/8%) para lo que no llena ya el marco
   (.completa lo clasifica sistema.js/laminaHTML producto por producto): el
   padding holgado que calibró el catálogo a 380px deja el objeto minúsculo
   en una miniatura de este tamaño. */
.g-f .lamina:not(.completa){padding:.5% 4%}
.g-t{grid-area:t;min-width:0;display:flex;flex-direction:column;gap:3px}
.g-n{font:600 var(--nf)/1.25 var(--sans);color:var(--tinta);text-decoration:none;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
@media(hover:hover){.g-n:hover{text-decoration:underline;text-underline-offset:3px}}
.g-c{font:500 13.5px/1.3 var(--sans);color:var(--tinta-2)}
.g-s{grid-area:s;text-align:right;display:flex;flex-direction:column;align-items:flex-end;gap:4px}
.g-sp{font:700 19px/1.15 "Roboto Mono Precio",var(--mono);letter-spacing:-.02em;white-space:nowrap;font-variant-numeric:tabular-nums}
/* "A cotizar" no es un precio: sans (no mono) y 600/tinta-2 (no 700/tinta) —
   la propia palabra ya la distingue de una cifra real, sin necesitar además
   su mismo peso/color (pasó por --senal ámbar y un naranja propio, los dos
   rechazados: "se veía mal", "me lía"). Misma decisión en todos los sitios
   donde aparece "A cotizar" en esta pantalla. */
.g-s.cot .g-sp{font:600 16px/1.2 var(--sans);letter-spacing:0;color:var(--tinta-2)}
.g-un{font:500 11.5px/1.2 var(--sans);color:var(--tenue);letter-spacing:0;white-space:nowrap}
.g-ctl{grid-area:c;display:flex;align-items:center;justify-content:space-between;min-width:0}
.g-q{display:inline-flex;align-items:center;justify-content:space-between;width:132px;height:44px;border:0;box-shadow:inset 0 0 0 1px #BFC5CE;border-radius:8px;flex:none}
.g-q button{position:relative;width:44px;height:44px;border:0;background:none;color:var(--tinta);display:grid;place-items:center;cursor:pointer;border-radius:7px;padding:0}
.g-q button svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.2;fill:none}
@media(hover:hover){
  .g-q button{transition:background .2s}
  .g-q button:hover{background:rgba(18,24,31,.06)}
}
/* Con 1 unidad, "−" no debe poder llegar a 0 desde el propio stepper — quitar
   la partida es una acción distinta y ya explícita (el botón "×"), no un
   efecto secundario de seguir bajando la cantidad (hallazgo propio: bajar a
   0 con el stepper borraba la fila sin más aviso). pointer-events:none quita
   también el :hover, no solo el click. */
.g-q button:disabled{color:var(--tinta-2);opacity:.35;pointer-events:none}
.g-q output{min-width:44px;text-align:center;font:600 15px/1 var(--sans)}
/* Vuelve a ser una "×" de trazo, no la papelera (feedback explícito de nuevo:
   cambia el icono, una cruz fina y cuidada). Siempre visible, no solo al
   hover — sobre todo porque en móvil no hay hover. Ya es un botón de 44px
   real (no un icono suelto con zona de toque ampliada por ::after, como el
   antiguo .quitar): no hace falta compensar nada aparte. */
.g-x{width:44px;height:44px;margin-right:-12px;padding:0;border:0;background:none;display:grid;place-items:center;color:var(--tenue);border-radius:8px;cursor:pointer;flex:none}
.g-x svg{width:21px;height:21px;stroke:currentColor;stroke-width:1.7;fill:none}
@media(hover:hover){.g-x:hover{color:var(--tinta)}}

.g-seguir{margin:0;max-width:none;padding:20px 0 6px;font-size:15px;line-height:1.2}
.g-seguir a{font:600 15px/1.2 var(--sans);color:var(--navy);text-decoration:none}
@media(hover:hover){.g-seguir a:hover{text-decoration:underline;text-underline-offset:3px}}

/* pie (base: móvil y tablet estrecha): total · nota pendiente · botón · "sin
   cargo", uno debajo de otro en ese orden fijo vía "order" (no el orden del
   propio marcado: en escritorio cambia sin tocar el HTML, ver más abajo). */
.g-tot{margin-top:18px;border-top:2px solid var(--tinta);padding-top:24px;display:flex;flex-direction:column}
.g-notas{display:contents}
.g-tr{order:1;display:flex;align-items:baseline;justify-content:space-between;gap:16px}
.g-tl{font:600 15px/1.3 var(--sans);color:var(--tinta-2)}
.g-tp{font:700 40px/1 "Roboto Mono Precio",var(--mono);letter-spacing:-.03em;white-space:nowrap;font-variant-numeric:tabular-nums}
.g-tp .cot-usd{font-size:.4em;margin-right:6px;vertical-align:.2em}
/* Con TODO el carrito a cotizar (ningún precio real todavía), el total es la
   propia palabra "A cotizar" — sans, no mono, y más chica: a 40px/mono se
   leía como una cifra enorme justo donde nunca puede haber una cifra
   (precio_usd:null no es 0, ver Trampa 1 en cotizacion.astro).
   OJO al tocar esto: esta regla tiene 2 clases (especificidad 0,2,0) y por
   eso le gana a la de arriba (.g-tp a secas, 0,1,0) SIEMPRE, sin importar el
   orden de las reglas ni si hay una media query de por medio. El bug real de
   esta ronda ("a cotizar sale enorme en escritorio") era justo al revés: una
   regla de escritorio con un prefijo de más delante de ".g-tp" (un
   selector con 2 clases + 1 elemento, especificidad 0,2,1) le ganaba a ESTA
   por especificidad. La regla: ".g-tp" nunca lleva un prefijo de elemento
   por delante (nunca algo como "body .g-tp{font-size:...}") — así se queda
   siempre en 0,1,0 y ".g-tp.txt" gana siempre, sin necesitar un !important
   ni una tercera regla de "arreglo". */
.g-tp.txt{font:700 30px/1.05 var(--sans);letter-spacing:-.01em}
.g-tn{order:2;display:flex;align-items:flex-start;gap:7px;margin:14px 0 0;max-width:none;font:500 14px/1.4 var(--sans);color:var(--tinta-2)}
.g-tot .comando{order:3;margin:22px 0 0;min-height:52px}
/* "Sin cargo. Solo es una solicitud.": reemplaza al candado con icono de
   antes (.cot-candado) — mismo lenguaje discreto y sin caja, pero sin icono
   (decisión de esta ronda): "Sin cargo." en negrita ya avisa por sí solo,
   sin necesitar además un dibujo. */
.g-ts{order:4;display:flex;align-items:center;justify-content:center;gap:6px;margin:14px 0 0;max-width:none;text-align:center;font:500 13px/1.4 var(--sans);color:var(--tinta-2)}
.g-ts b{font-weight:600;color:var(--tinta)}

/* hueco de 921 a 1100px: la línea de móvil, más ancha, y el total a la derecha */
@media(min-width:921px) and (max-width:1100px){
  .g-hoja{--th:96px;--py:28px;--nf:18px}
  .g-tot{max-width:440px;margin-left:auto}
  .g-n{font-size:var(--nf)}
  .g-ctl{justify-content:flex-start;gap:14px}
  .g-x{margin-right:0}
}

/* ---------- escritorio (≥1101px): líneas "C2" + pie "P2" ---------- */
@media(min-width:1101px){
  .g-hoja{
    --th:96px;--py:28px;--nf:18px;--cg:40px;--bw:208px;--seg:45px;--gap:80px;
    /* C2: Producto · Cantidad · Total — sin columna de precio unitario suelta
       (esa era C1, descartada por "lío de columnas"; el unitario vive bajo
       el total como "c/u", ver .g-un más abajo). */
    --cols:var(--th) minmax(0,1.25fr) minmax(240px,1fr) 176px;--areas:"f t c s";
    display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:56px;
    grid-template-areas:"h h" "l l" "r r" "s t";align-items:start;
  }
  .g-h{grid-area:h;align-self:baseline;display:flex;align-items:baseline;padding:24px 0 20px}
  .g-ht{justify-content:flex-start;width:auto}
  .g-cols{grid-area:h;align-self:baseline;display:grid;grid-template-columns:var(--cols);grid-template-areas:var(--areas);column-gap:var(--cg);align-items:baseline;padding:24px 0 20px;pointer-events:none}
  .g-col{font:600 11.5px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--tinta-2)}
  /* "CANTIDAD" centrada sobre el propio selector (132px, mismo ancho que
     .g-q), no sobre toda la columna "c" (minmax(240px,1fr)): antes ocupaba
     todo el ancho de esa columna con text-align:left, así que coincidía con
     el borde del selector pero "flotaba" sobre un hueco mucho más ancho que
     él — de ahí que el director lo viera descuadrado (feedback 29-sep-2026).
     justify-self:start evita que el grid la estire a lo ancho de la columna. */
  .g-col.c-q{grid-area:c;justify-self:start;width:132px;text-align:center}
  .g-col.c-s{grid-area:s;text-align:right}
  .g-l{grid-area:l}
  .g-l .g-i:last-child{border-bottom:0}
  .g-regla{display:block;grid-area:r;height:0;border-top:2px solid var(--tinta)}
  .g-i{grid-template-columns:var(--cols);grid-template-areas:var(--areas);column-gap:var(--cg);align-items:center;row-gap:0}
  .g-t{gap:4px}
  .g-c{font-size:14.5px}
  .g-sp{font-size:22px}
  .g-s.cot .g-sp{font-size:17px}
  .g-s{align-self:center}
  .g-un{display:block;font-size:12.5px}
  /* X más separada del selector (28px, antes 14px) para que se lea como una
     acción aparte, no como parte de lo que "CANTIDAD" describe — mismo
     feedback de arriba. */
  .g-ctl{justify-content:flex-start;align-self:center;gap:28px}
  .g-x{margin-right:0}
  .g-seguir{grid-area:s;padding:0;margin-top:var(--seg);align-self:baseline}
  .g-tot{grid-area:t;margin:28px 0 0;padding:0;border:0;align-self:baseline;justify-self:end}

  /* Pie P2: total a la izquierda (centro óptico, no línea base — ver --dy,
     puesta por cotizacion.astro tras medir con canvas), botón de 208px a la
     derecha, notas debajo justificadas al ancho del bloque (la nota
     pendiente a la izquierda, "Sin cargo" a la derecha; si falta la
     pendiente — carrito sin nada a cotizar — la de "Sin cargo" se va sola al
     borde derecho, ver :only-child).
     30-sep-2026: el feedback original era "el total y el botón se ven
     juntos" — las vueltas anteriores subieron por error el margen de ARRIBA
     de toda esta fila (.g-seguir/.g-tot vía --seg, que en realidad ya
     gustaba tal cual estaba y queda revertido a su valor de siempre, 45px/
     28px). El hueco que había que tocar era este column-gap, entre la
     propia cifra ("tr") y el botón ("btn"): --gap 44px→80px. */
  .g-tot{display:grid;grid-template-columns:auto var(--bw);grid-template-areas:"tr btn" "nt nt";column-gap:var(--gap);row-gap:14px;align-items:center;align-self:start;justify-self:end}
  .g-tr{grid-area:tr;display:flex;align-items:baseline;justify-content:flex-end;gap:22px;position:relative;top:-1px}
  .g-hoja.cot-todo .g-tr{top:1px}
  .g-tl{position:relative;top:calc(var(--dy,8px) * -1)}
  .g-tp .cot-usd{vertical-align:baseline}
  .g-tot .comando{grid-area:btn;margin:0;width:var(--bw);justify-self:end}
  .g-notas{grid-area:nt;display:flex;justify-content:space-between;flex-wrap:nowrap;gap:0 26px;white-space:nowrap}
  .g-ts:only-child{margin-left:auto}
  .g-tn,.g-ts{margin:0;font-size:13.5px;line-height:1.3;color:var(--tenue);white-space:nowrap}
}

/* ---------- 12 · PANELES FOTOGRÁFICOS ---------- */
.panel-foto{
  position:relative;background:var(--panel);color:var(--papel);
  overflow:hidden;
  clip-path:polygon(0 0,calc(100% - 28px) 0,100% 60px,100% 100%,0 100%);
}
.panel-foto>img,.panel-foto>video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.85;
}
.panel-foto::after{ /* grano */
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.06;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)'/%3E%3C/svg%3E");
}
.panel-foto .contenido{position:relative;z-index:2;
  background:linear-gradient(to top,rgba(5,24,46,.88) 0%,rgba(5,24,46,.28) 55%,rgba(5,24,46,.55) 100%)}
.hueco-foto{
  border:1px dashed var(--linea-clara-f);
  display:grid;place-items:center;text-align:center;
  aspect-ratio:4/3;padding:20px;color:rgba(246,246,243,.62);
  font:600 10.5px/1.8 var(--sans);letter-spacing:.14em;text-transform:uppercase;
}
.en-papel .hueco-foto{border-color:var(--linea-f);color:var(--tinta-2)}

/* ---------- 13 · PIE ---------- */
.pie{
  position:relative;background:var(--panel);color:rgba(246,246,243,.78);
  overflow:hidden;margin-top:clamp(70px,9vw,130px);
}
.pie::before{ /* rino solo (sin letras) como marca de agua: rino-blanco.png es
  la silueta aislada, no el lockup con texto (logo-navy.png) — el director no
  quería letras de fondo detrás del texto real del pie (hallazgo propio). */
  content:"";position:absolute;right:-7%;bottom:-6%;width:min(560px,60vw);aspect-ratio:56/26;
  background:var(--navy);
  -webkit-mask:url(img/rino-blanco.png) no-repeat center/contain;
  mask:url(img/rino-blanco.png) no-repeat center/contain;
  opacity:.55;pointer-events:none;
}
.pie .interior{
  position:relative;z-index:2;
  padding-block:clamp(52px,7vw,88px) clamp(30px,4.5vw,52px);
}
.pie a{color:inherit;text-decoration:none;transition:color .2s}
@media(hover:hover){.pie a:hover{color:var(--papel)}}

/* flex, no grid: con columnas fr el contenido corto de cada celda (p.ej.
   "Sáb: 08:00 – 13:00") dejaba mucho hueco vacío antes del margen derecho.
   Con flex + space-between cada columna ocupa solo lo que su contenido
   pide y la última sí llega al borde (hallazgo propio). */
.pie-rejilla{
  display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:clamp(32px,4.5vw,64px) clamp(24px,3.5vw,48px);
}
/* Contacto y Horario van juntos dentro de .agrupa, que es el último ítem del
   flex de arriba: su borde derecho SIEMPRE queda a ras del contenedor (así
   Horario llega al margen), sin importar nada de lo que pase a su izquierda.
   Ensanchar el gap interno (Información↔Horario) no mueve a Horario — solo
   empuja a Información hacia la izquierda, y de paso, al pesar más .agrupa,
   space-between le quita sitio a los huecos de la izquierda y acerca de
   paso Navegación a la marca (feedback del director: "solo información y
   navegación se mueven, horario no" — probado en vivo con getBoundingClientRect,
   no a ojo). */
.pie .agrupa{display:flex;flex-wrap:wrap;gap:clamp(32px,4.5vw,64px) clamp(64px,8vw,120px)}
/* ≤920px: Marca+Navegación cabían en una fila pero .agrupa no, así que
   space-between lo bajaba solo a una segunda fila — sin nadie más ahí,
   quedaba pegado a la izquierda con un hueco vacío bajo Navegación (hallazgo
   propio, capturado en vivo). Columna única y explícita en vez de dejarlo al
   wrap: mismo ancho de página que .agrupa ya usa a su vez para partir
   Información/Horario si hiciera falta. */
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){
  .pie-rejilla{flex-direction:column}
}
/* Antes era un icono del rino solo, a 40px — repetía el del nav y, sin texto
   visible al lado (el nombre solo iba en el alt, invisible para quien ve),
   no cerraba como firma. Icono pequeño + "Super Service" en texto real: se
   lee como firma del pie, no como un segundo logo. */
.pie-firma{display:inline-flex;align-items:center;gap:11px;margin-bottom:16px}
/* El rinoceronte (silueta con orejas/cuerno arriba, punta abajo) pesa
   visualmente más arriba de su propio bounding-box — centrado por caja
   (align-items:center) quedaba "flotando" alto sobre el texto en vez de
   asentado junto a él (feedback del director: "mejor alineado con el
   logo"). Un pequeño translateY reancla el peso óptico a la línea de
   base del texto sin tocar el tamaño. */
.pie-firma img{height:19px;width:auto;transform:translateY(1px)}
.pie-firma span{font:700 15px/1 var(--sans);letter-spacing:.04em;text-transform:uppercase;color:var(--papel)}
.pie .claim{font-size:16px;max-width:34ch;color:rgba(246,246,243,.6);line-height:1.6}
/* Ronda 4 (pedido del director, captura a 960px): entre 921 y 1005px .agrupa ya
   no cabía junto a Marca+Navegación y bajaba sola a una segunda fila, dejando a
   Navegación suelta a la derecha y un hueco grande. Opción A: todo en una fila,
   como en pantallas anchas, con la frase de la marca algo más estrecha y menos
   aire entre Información y Horario. */
@media(min-width:921px) and (min-height:501px) and (max-width:1005px),(min-width:1001px) and (max-width:1005px){
  .pie .agrupa{column-gap:40px}
  .pie .claim{max-width:28ch}
}
/* headers planos, sin versalitas ni tracking (feedback del director sobre una
   referencia): esta cabecera no comparte el lenguaje de folio del resto del
   sitio — es un remate, no una sección numerada. */
/* h2, no h4 (hallazgo de auditoría UX): el footer es un componente
   compartido (montarPie(), sistema.js) montado igual en las 6 páginas, cada
   una con su propia jerarquía de encabezados antes de llegar aquí —
   cotizacion.astro va de h1 directo a esto; index/contacto van de h2;
   catalogo/producto van de h1/h2 a h3 (tarjetas) según haya o no
   resultados/relacionados. h4 fijo saltaba niveles en la mayoría de esos
   casos. h2 es la única opción que nunca salta un nivel hacia delante en
   NINGÚN estado real (comprobado en vivo, incluidos catálogo sin resultados
   y ficha sin relacionados): un heading más profundo (h2/h3) seguido de un
   h2 vuelve a un nivel ya visto — nunca invalido, solo una nueva sección
   hermana — mientras que saltar hacia delante (h1→h4, h2→h4) sí lo es. */
.pie h2{margin:0}
/* El heading semántico (<h2>, ya en el nivel correcto — ver arriba) envuelve
   un <button> real: mismo patrón de "disclosure" que .selector-boton, no un
   div con onclick. Reset de botón explícito, sin all:unset — cursor:default
   en vez de quitarlo, position:relative + ::before es la diana táctil
   invisible de siempre (mismo criterio que .enlaces a de abajo). */
.pie-toggle{
  /* flex-start, no space-between: con etiquetas cortas ("Navegación") la
     flecha quedaba empujada al borde derecho de toda la columna del pie,
     lejos del texto — hallazgo del director en vivo ("el toggle muy
     separado"). El botón entero sigue siendo la diana táctil completa
     (width:100% se queda), solo cambia dónde se ven texto+flecha dentro de
     ella. A ≥921px el propio CSS ya oculta el svg del todo (ver abajo,
     "≥921px: .pie-rejilla ya cabe entera en una fila"), así que este cambio
     no tiene efecto visible en escritorio. */
  position:relative;display:flex;align-items:center;justify-content:flex-start;gap:10px;
  width:100%;background:none;border:none;padding:0;margin-bottom:12px;font-family:inherit;
  font-size:18px;font-weight:700;font-variation-settings:"wdth" 100;
  color:var(--papel);text-align:left;cursor:pointer;
}
.pie-toggle::before{content:"";position:absolute;inset:-12px -4px}
.pie-toggle svg{
  width:16px;height:16px;flex-shrink:0;stroke:currentColor;stroke-width:2;fill:none;
  transition:transform .3s var(--e-swift);
}
.pie-toggle[aria-expanded="true"] svg{transform:rotate(180deg)}
/* ≥921px: .pie-rejilla ya cabe entera en una fila (ver más abajo) — el
   acordeón es solo para el tramo estrecho. pointer-events:none en vez de
   quitar el botón: nace abierto (montarPie, colapsaPie) y el panel se queda
   visible pase lo que pase con el atributo, así que un resize en vivo sin
   recargar (DevTools, plegable) nunca puede dejarlo cerrado sin salida. */
@media(min-width:921px) and (min-height:501px),(min-width:1001px){
  .pie-toggle{cursor:default;pointer-events:none}
  .pie-toggle svg{display:none}
  .pie .pie-panel[hidden]{display:block}
}
/* ≤920px — filas con filete (opción A del director): Navegación, Información
   y Horario son tres filas a todo el ancho, separadas por una línea fina, con
   la flecha a la derecha; la fila entera es el botón. Va tras las reglas base
   de .pie-toggle para ganarles por orden. */
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){
  .pie-rejilla{gap:0}
  .pie .marca-col{padding-bottom:28px}
  .pie .agrupa{flex-direction:column;flex-wrap:nowrap;gap:0;width:100%}
  .pie .enlaces,.pie .contacto,.pie .horario{width:100%;border-top:1px solid var(--linea-clara)}
  .pie .horario{border-bottom:1px solid var(--linea-clara)}
  .pie-toggle{justify-content:space-between;min-height:56px;margin-bottom:0;font-size:16px}
  .pie-toggle::before{inset:0}
  .pie .pie-panel{padding-bottom:14px}
}
.pie .enlaces a,.pie .contacto p,.pie .horario p{
  display:block;font-size:15px;line-height:1.9;color:rgba(246,246,243,.68);
}
/* misma especificidad que ".pie .enlaces a" (dos clases + tag) — sin esto
   ".pie a:hover" pierde el empate por orden de aparición y el link nunca
   cambia de color al pasar el cursor (hallazgo propio). */
@media(hover:hover){.pie .enlaces a:hover{color:var(--papel)}}
/* Mismo criterio que .contacto p a de abajo: line-height:1.9 deja interlineado
   real entre cada enlace apilado, -5px se queda dentro sin tocar al vecino. */
.pie .enlaces a{position:relative}
.pie .enlaces a::before{content:"";position:absolute;inset:-5px -10px}
/* Ampliación invisible de diana táctil en teléfono/correo/dirección: cada <p>
   de .contacto es un bloque de 28.5px (line-height:1.9) pegado al siguiente,
   sin margen — -5px vertical se queda dentro del propio interlineado, sin
   invadir el enlace vecino. Horizontal generoso (-10px): a la derecha del
   texto solo hay columna vacía. */
.pie .contacto p a{position:relative}
.pie .contacto p a::before{content:"";position:absolute;inset:-5px -10px}

/* remate: centrado, copyright+legal en una línea, redes debajo. max-width:none
   pisa el tope global de párrafo (62ch, pensado para cuerpo de texto) — sin
   esto el texto quedaba centrado dentro de una caja angosta pegada a la
   izquierda, no centrado de verdad en el pie (hallazgo propio). */
.pie .remate{margin-top:40px;text-align:center}
.pie .remate .linea-legal{font-size:14px;color:rgba(246,246,243,.55);max-width:none}
/* Privacidad/Términos: mismo subrayado sutil que ya usaba esta regla antes de
   quitarse (ver historial de git) — vuelve porque los dos enlaces ahora
   llevan a páginas reales, no a "#". */
.pie .remate .linea-legal a{
  position:relative;padding:0 2px;text-decoration:underline;text-decoration-color:rgba(246,246,243,.3);
}
/* Vecinos son separadores "·" y texto plano, no otro enlace — modesto en
   horizontal para no comerse el punto de al lado, generoso en vertical (la
   línea entera va sola, sin nada arriba ni abajo). */
.pie .remate .linea-legal a::before{content:"";position:absolute;inset:-10px -3px}
/* redes bajo la marca (antes en el remate, centradas abajo del todo) */
.pie .marca-col .redes{display:flex;justify-content:flex-start;gap:20px;margin-top:18px}
/* sin redondel: solo el glifo, blanco, sin caja. Logos oficiales (Simple
   Icons, CC0) en vez del dibujo a mano de antes — varios no se leían como
   la marca real (Facebook, sobre todo). fill, no stroke: son las siluetas
   originales, no un trazo. */
.pie .icono-social{
  position:relative;
  width:26px;height:26px;color:var(--papel);
  display:grid;place-items:center;transition:color .2s;flex:none;
}
/* -10px, no -11 (que llegaría a los 48px del estándar interno): el gap real
   entre iconos es 20px (.redes) — a -11px por lado el hit-area de dos iconos
   vecinos se solaparía 2px. -10px es el máximo sin solape (10+10=20). */
.pie .icono-social::after{content:"";position:absolute;inset:-10px}
@media(hover:hover){.pie .icono-social:hover{color:var(--senal)}}
.pie .icono-social svg{width:100%;height:100%}

/* ---------- 14 · SECCIONES Y FOLIOS DE MARGEN ---------- */
.seccion{padding-block:clamp(64px,9vw,140px) clamp(50px,7vw,112px)}
.seccion-cabecera{display:grid;grid-template-columns:auto 1fr auto;gap:18px;align-items:end;margin-bottom:clamp(26px,4vw,52px)}
.seccion-cabecera .folio{transform:translateY(-4px)}
.con-margen{display:grid;grid-template-columns:56px 1fr;gap:clamp(14px,2vw,30px)}
.con-margen>.folio{writing-mode:vertical-rl;transform:rotate(180deg);align-self:start;letter-spacing:.2em}
@media(max-width:900px){.con-margen{grid-template-columns:1fr}.con-margen>.folio{writing-mode:horizontal-tb;transform:none}}

/* ---------- 15 · REVELADO EN SCROLL ---------- */
/* Guardia sin-JS: si el script no corre, nada queda invisible. La clase
   'js' la pone un one-liner en el <head> de cada página. */
html:not(.js) .rev{opacity:1;transform:none;filter:none}
.rev{opacity:0;transform:translateY(22px);filter:blur(5px)}
.rev.visto{
  opacity:1;transform:none;filter:none;
  transition:opacity .7s var(--e-out),transform .7s var(--e-out),filter .7s var(--e-out);
  transition-delay:calc(var(--rev-i,0)*70ms);
}
/* Lo que ya se ve al llegar, directo (sistema.js, observarRevelados). */
.rev.visto.directo{transition:none}

/* ---------- 16 · TRANSICIÓN DE VISTA (mejora progresiva) ---------- */
@view-transition{navigation:auto}
::view-transition-old(root){animation:vt-sale .28s var(--e-swift) forwards}
::view-transition-new(root){animation:vt-entra .28s var(--e-out)}
@keyframes vt-sale{to{opacity:0;transform:translateX(-1.5%) }}
@keyframes vt-entra{from{opacity:0;clip-path:polygon(0 0,0 0,-14% 100%,0 100%)}
  to{opacity:1;clip-path:polygon(0 0,114% 0,100% 100%,0 100%)}}

/* ---------- 16b · EL RINO CRUZA (cambio de vista) ----------
   Veredicto del tribunal: la marca cruza en NAVY (su tinta de sello, 12:1
   sobre papel), via máscara CSS — un solo asset, color tokenizado. Sin
   sombras (prohibidas) salvo el canto de 1px en papel que la dibuja sobre
   paneles oscuros. Sin skew: la marca no se distorsiona. A ~60% de altura
   para despejar la zona de lectura. Solo navegación interna, con freno. */
.rino-cruce{
  position:fixed;inset:0;z-index:120;pointer-events:none;
  overflow:hidden;
  padding-top:calc(60dvh - 70px);
}
.rino-cruce i{
  display:block;width:min(300px,30vw);aspect-ratio:560/260;
  background:var(--navy);
  -webkit-mask:url(img/rino-blanco.png) center/contain no-repeat;
  mask:url(img/rino-blanco.png) center/contain no-repeat;
  filter:drop-shadow(0 1px 0 rgba(233,232,227,.85));
  animation:rino-cruza .7s var(--e-swift) both;
  will-change:transform;
}
@keyframes rino-cruza{
  from{transform:translateX(105vw) translateZ(0)}
  to{transform:translateX(-130%) translateZ(0)}
}

/* ---------- 17 · TABLET (721-920px) ----------
   Hasta ahora esta franja heredaba el layout de teléfono entero (ver §19):
   un iPad vertical recibía el ledger de una columna. Aquí es su propio
   tramo: nav visible en el riel (§18 no toca `.masthead-nav`, así que la
   regla base de fuera de medios ya la muestra), catálogo en 2 columnas de
   tarjeta de escritorio, y la ficha usa la fórmula responsiva de arriba
   (minmax(0,min(50%,560px)) 1fr) en vez de apilarse. */
@media(min-width:721px) and (max-width:920px),(orientation:landscape) and (max-height:500px) and (min-width:921px) and (max-width:1000px){
  .plancha{grid-template-columns:repeat(2,1fr)}
}

/* ---------- 18 · TÁCTIL Y TABLET COMPARTIDO (≤920px) ---------- */
@media(max-width:920px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){
  /* .bloque-totales, .fila-ledger y .comando.movil-bloque no tienen
     consumidor en los 7 HTML (CSS muerto, no se toca en esta rama — ver
     plan de responsive, sección Riesgos). */
  .bloque-totales .fila{flex-wrap:wrap;row-gap:4px}
  .precio-grande{font-size:1.55rem}
  .display{font-variation-settings:"wdth" 100}
  .t-h2{font-size:clamp(1.5rem,7.2vw,3.2rem)}
  .comando.movil-bloque{display:flex;width:100%;justify-content:space-between}
  .fila-ledger{
    grid-template-columns:96px minmax(0,1fr) auto;
    grid-template-areas:"lam nom nom" "lam pre sel";row-gap:8px;
  }
  .fila-ledger>.folio{display:none}
  .fila-ledger>a{grid-area:lam}
  .fila-ledger>h3{grid-area:nom}
  .fila-ledger>.precio{grid-area:pre;align-self:center}
  .fila-ledger>.sello{grid-area:sel;justify-self:end}
  .seccion-cabecera{grid-template-columns:1fr;align-items:start;gap:8px}
}

/* ---------- 19 · MÓVIL (≤720px) ----------
   El umbral baja de 920 a 720: de 721 a 920 ya es tablet (§17) y conserva
   la navegación del riel — antes desaparecía de golpe en 920 y un iPad
   vertical se quedaba sin nav visible. */
@media(max-width:720px){
  .masthead .celda.masthead-nav{display:none}
  /* Sin raya propia (la única raya del riel es la de .celda-buscar — feedback
     del director), así que aquí el único recurso para no leerse pegado a
     COTIZACIÓN es más aire: el padding-inline general de .celda (clamp hasta
     12px en este ancho) se queda corto entre dos etiquetas con la misma
     tipografía y peso (hallazgo propio, ver BITACORA). */
  .masthead .celda.btn-menu{display:flex;margin-left:clamp(8px,2.4vw,14px)}
  .masthead-logo{flex:1;border-right:none!important}
}
/* Las tarjetas compactas (y el carrusel de la ficha) valen también en móvil apaisado (721–1000px de
   ancho pero ~300–430 de alto): sin esto, en apaisado salía la tarjeta de escritorio, con «+ Cotizar»
   en texto, apretada en columnas de ~160px. Mismo bloque, una sola definición. */
@media(max-width:720px),(orientation:landscape) and (max-height:500px) and (max-width:1000px){
  /* Tarjeta real también en móvil (feedback del director, iPhone real): ya no
     hay "fila de ledger". "Dos" = dos tarjetas por fila, la misma tarjeta de
     "Una" (foto, categoría, nombre, línea, precio + botón) dividida en dos
     anchos; y "También te puede interesar" (ficha) usa esa misma tarjeta en
     un carrusel que se desliza. Una sola definición para las dos superficies
     (:is), así no pueden separarse. "Una" (más abajo) la vuelve a agrandar. */
  .plancha{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada{padding:10px 10px 12px;gap:8px}
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .categoria{font-size:11px;line-height:1.15;padding:4px 8px}
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada-titulo{min-height:0;justify-content:flex-start}
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada h3{
    min-height:0;font-size:15px;line-height:1.2;-webkit-line-clamp:3;
  }
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .pie-celda{
    flex-direction:row;align-items:center;gap:6px;margin-top:4px;padding-top:8px;
  }
  /* Misma altura para «precio» y «A cotizar»: si no, la línea de arriba queda a
     distinta altura entre dos tarjetas de la misma fila. */
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .precio{font-size:1.35rem;line-height:1.2}
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .chip-cotizar{display:flex;align-items:center;min-height:26px}
  /* «Cotizar» junto al precio, pegado a la derecha (director, 24-sep-2026, B1 del
     mockup): con la palabra no cabe en 151px, así que es un cuadrado de 40px con
     el «+» o, ya en la cotización, el «✓». Dibujados con máscara, no con letras:
     un carácter cae más arriba o más abajo según la fuente de cada teléfono; el
     dibujo queda centrado siempre. El texto sigue dentro del botón (a tamaño 0)
     para quien usa lector de pantalla. Responde en 48×56px (::after). */
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .sello{
    flex:none;width:40px;min-width:0;height:40px;min-height:0;padding:0;border-radius:9px;
    font-size:0;letter-spacing:0;word-spacing:0;
    --ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E");
  }
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .sello.sellado{--ico:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.3l4.6 4.5L19 7.2'/%3E%3C/svg%3E")}
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .sello .sello-mas{display:none}
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .sello::before{
    content:"";position:absolute;inset:0;margin:auto;width:20px;height:20px;background:currentColor;
    -webkit-mask:var(--ico) center/contain no-repeat;mask:var(--ico) center/contain no-repeat;
  }
  :is(#plancha:not(.vista-destacada),.relacionados .plancha) .entrada .sello::after{inset:-4px -8px}
  /* Ficha: los relacionados se deslizan en horizontal (sin flechas, táctil).
     Un poco más estrechas que las de "Dos" para que asome la siguiente y se
     entienda que hay más. */
  .relacionados .plancha{
    display:flex;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;
    scrollbar-width:none;gap:12px;
    /* sangra hasta el borde de la pantalla: mismo margen que .contenedor */
    --g-x:clamp(18px,4vw,44px);
    margin-inline:calc(var(--g-x) * -1);padding:2px var(--g-x) 6px;scroll-padding-inline:var(--g-x);
  }
  .relacionados .plancha::-webkit-scrollbar{display:none}
  .relacionados .plancha>.entrada{flex:0 0 clamp(150px,42vw,190px);scroll-snap-align:start}
}
@media(max-width:720px){
  #plancha.vista-destacada{grid-template-columns:1fr;gap:18px;background:transparent;border:none}
  /* Tarjeta U2 (mock v19; director, 24-sep-2026: «Más junta y el producto más
     grande»): menos aire entre foto, nombre y precio (gap 10→8, sin el alto
     mínimo del título, pie 12→4px más cerca) y el producto ocupa más de su
     lámina: la mitad de margen interior en cada encaje, así cada foto conserva
     su proporción de siempre. Va con la portada grande de la tarjeta
     (laminaHTML, sistema.js): con la miniatura de 200px, más grande era más
     borroso. */
  #plancha.vista-destacada .entrada{
    display:flex;flex-direction:column;align-items:stretch;gap:8px;
    background:var(--blanco);padding:18px 18px 14px;
    border:1px solid rgba(0,40,86,.14);border-radius:10px;
    box-shadow:0 1px 3px rgba(18,24,31,.06);
  }
  #plancha.vista-destacada .entrada:hover{
    border-color:var(--navy);box-shadow:0 16px 30px -16px rgba(18,24,31,.4);transform:translateY(-3px);
  }
  #plancha.vista-destacada .entrada .cabecera{order:0}
  #plancha.vista-destacada .entrada > a:first-child{margin-bottom:2px}
  #plancha.vista-destacada .entrada .lamina{padding:3% 10%}
  #plancha.vista-destacada .entrada .lamina.holgado{padding:7% 15%}
  #plancha.vista-destacada .entrada .lamina.zoom{padding:1% 4%}
  #plancha.vista-destacada .entrada .lamina.zoom-suave{padding:2% 6%}
  #plancha.vista-destacada .entrada .lamina.zoom-firme{padding:.5% 3%}
  #plancha.vista-destacada .entrada .lamina.zoom-alto{padding:.25% 2%}
  #plancha.vista-destacada .entrada .lamina.zoom-max{padding:0 1%}
  #plancha.vista-destacada .entrada .lamina.completa{padding:0}
  #plancha.vista-destacada .entrada-titulo{min-height:0;justify-content:flex-end}
  #plancha.vista-destacada .entrada h3{min-height:auto;font-size:22px}
  #plancha.vista-destacada .entrada .pie-celda{
    flex-direction:row;align-items:center;gap:10px;
    margin-top:4px;padding-top:12px;border-top:1px solid rgba(18,24,31,.1);
  }
  #plancha.vista-destacada .entrada .precio{font-size:2rem}
  /* «+ Cotizar» / «En cotización ✓» un poco más grandes (director, 24-sep-2026,
     «Un poco más» del mockup): de 32 a 36px de alto y letra de 13 a 14. El
     margen de la tarjeta se queda en 18px, alineado con los filtros. */
  #plancha.vista-destacada .entrada .sello{
    min-height:36px;padding:0 16px;font-size:14px;border-radius:6px;
    word-spacing:.5em;box-shadow:inset 0 0 0 1.5px rgba(0,40,86,1);
  }
  .ficha-split{grid-template-columns:1fr}
  .ficha-lamina{position:static}
  /* Apilado, la lámina sigue con su marco (--marco, ver .galeria .lamina): a lo ancho de la
     pantalla, sin tope de alto (antes 16/10 con max-height:42svh, que la producto.astro
     ya pisaba en móvil). */
  /* Miniaturas verticales a la izquierda es un lujo de escritorio: en 390px
     vuelven a ser una fila horizontal bajo la foto, como antes de la
     referencia de escritorio (§9 del DISENO.md: el móvil se diseña primero). */
  .galeria-bloque{flex-direction:column;align-items:stretch}
  /* min-width:0 en los dos niveles: por defecto un hijo flex no encoge por
     debajo del ancho de su contenido (min-width:auto), así que sin esto la
     fila de miniaturas empuja a toda la ficha en vez de desbordar hacia
     dentro con su propio scroll (desborde horizontal real, hallado en vivo
     con 9 fotos). */
  .galeria-minis{width:auto;min-width:0;order:2}
  .galeria-minis-riel{flex-direction:row;flex:none;min-width:0;overflow-x:auto;overflow-y:hidden}
  .galeria-minis-riel button{width:58px;height:58px}
  .galeria-minis-flecha{display:none}
  /* Hueco real mayor: con el gap de escritorio (hasta 6px en 360px) la
     ampliación invisible de .pagina-boton::after (-6px) se solaparía con
     la del vecino. */
  .paginador{gap:16px}

  /* Carril de categorías con foto (pedido del director, tras comparar
     variantes en un artefacto: tira de chips, no rejilla ni editorial).
     Diana táctil real: es el <button> entero el que mide ≥48px en los dos
     ejes (foto 60px + texto + padding), no solo el círculo de la foto. */
  /* Cabecera compartida (pedido del director, artefacto "U3"): el carril de
     categorías, el selector de densidad y la fila de filtro/chips leían como
     tres piezas sueltas encima de la rejilla — ahora comparten una sola
     tarjeta plana (fondo --placa, la misma superficie "ligeramente distinta
     de la página" que ya usa .chip-filtro/.selector-panel) y la rejilla de
     productos, justo debajo, es la única que conserva sombra propia: "plano
     = herramienta de filtrado" / "con sombra = el contenido". El margin-top
     que antes tenía .rail-categorias se sube aquí (es el borde superior de
     todo el bloque, no solo del carril). */
  .cabecera-compartida{
    /* Tinte frío propio, más oscuro que la página (--papel) y que --placa: con
       --placa (casi igual al fondo) la cabecera no se distinguía en el iPhone
       real (feedback del director). Las esferas van en blanco encima. Ronda
       21-sep: #DCE3EC «destaca demasiado» → punto medio entre --placa y ese
       tinte, más un filete interior casi invisible: se distingue de la página
       sin llamar la atención. Ronda 21-sep (2): aún se veía azul → gris casi
       neutro (#E7E9EC, ~2 puntos sobre --papel) con filete neutro. Prueba
       24-sep (director, «por curiosidad»): grises cambiados con la mini-píldora
       (cabecera #D4D6DA) → «muy oscuro»; elegida la opción 1 de un mock: la
       cabecera vuelve a #E7E9EC y la píldora pasa a ser MÁS CLARA que ella
       (#F4F5F7), para que se lea como pieza encima y no como hueco. */
    background:#E7E9EC;box-shadow:inset 0 0 0 1px rgba(18,24,31,.05);border-radius:16px;padding:16px 14px 12px;
    margin-top:clamp(20px,4vw,32px);margin-bottom:20px;
  }
  .cabecera-compartida .barra-filtros{margin-top:0;margin-bottom:0;border-bottom:none;padding-bottom:2px}
  .rail-categorias{
    display:flex;gap:12px;overflow-x:auto;overscroll-behavior-x:contain;
    padding:0 2px 10px;
    scrollbar-width:none;
  }
  .rail-categorias::-webkit-scrollbar{display:none}
  /* Selector de densidad "Dos"/"Una": centrado, en su propio renglón —
     decisión explícita del director (el artefacto recomendaba alinearlo a
     la derecha del carril, por consistencia con el resto del sitio; pedido
     directo: centrado). Diana táctil real ≥48px sin agrandar el dibujo,
     mismo patrón que .chip-filtro button::after — con solo 2px entre los
     dos botones, sus áreas ampliadas se solapan un poco en el centro: se
     acepta porque los dos lados del control son opciones válidas y
     reversibles del mismo selector, no hay un objetivo ajeno cerca que un
     solape pudiera robar. 24-sep-2026 (director, opción 1 de un mock: «misma
     forma, bien ajustada»): el hueco medía igual por los cuatro lados, pero
     la sombra caía hacia abajo y dejaba a la vista solo el de arriba, y las
     esquinas no casaban → hueco de 3px, radio del botón = radio de la
     píldora − hueco (11−3=8) y sombra casi centrada. */
  .vista-densidad{display:flex;justify-content:center;padding:9px 0 1px}
  .mini-densidad{display:inline-flex;gap:0;background:#F4F5F7;border-radius:11px;padding:3px;flex:none}
  .mini-densidad button{
    position:relative;width:34px;height:28px;display:grid;place-items:center;
    border:none;background:transparent;border-radius:8px;cursor:pointer;padding:0;
  }
  .mini-densidad button::after{content:"";position:absolute;inset:-13px}
  .mini-densidad button svg{width:17px;height:17px;stroke:var(--tinta-2);fill:none;stroke-width:1.8}
  .mini-densidad button.activo{background:var(--blanco);box-shadow:0 0 0 .5px rgba(18,24,31,.1),0 1px 4px -1px rgba(18,24,31,.22)}
  .mini-densidad button.activo svg{stroke:var(--navy)}
  /* Píldora compacta de densidad + Orden (30-sep-2026, pedido del director
     sobre el mock de paginación/filtro: el reparto anterior en tres esquinas
     — Filtros a la izquierda, densidad al centro, Ordenar a la derecha —
     "no convencía"; esto los une en un solo objeto visual, mismo fondo y
     radio que ya tenía .mini-densidad, ahora compartido). Precio vivió aquí
     también, como tercer control, hasta que el director lo quitó del todo
     ("eso no lo quiero ver ni en escritorio ni en móvil", misma sesión) —
     código recuperable en el historial de esta rama. Los controles miden
     34×28 (mismo tamaño que los botones de densidad) para que la fila quede
     pareja de punta a punta, con un filete fino separando cada grupo en vez
     de espacio suelto (eso es lo que se veía "desordenado" en la variante
     anterior). */
  .tira-controles{
    display:inline-flex;align-items:center;gap:2px;
    background:#F4F5F7;border-radius:11px;padding:3px;
  }
  /* Dentro de la píldora, el selector de densidad pierde su propio fondo —
     si no, quedaba una píldora gris dentro de otra píldora gris. */
  .tira-controles .mini-densidad{background:none;padding:0}
  .tira-separador{width:1px;height:18px;background:rgba(18,24,31,.14);flex:none}
  .tira-desplegable{position:relative}
  .tira-icono{
    position:relative;width:34px;height:28px;display:grid;place-items:center;
    border:none;background:transparent;border-radius:8px;cursor:pointer;padding:0;
    color:var(--tinta-2);
  }
  .tira-icono::after{content:"";position:absolute;inset:-13px}
  .tira-icono svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.6}
  .tira-icono[aria-expanded="true"]{
    background:var(--blanco);box-shadow:0 0 0 .5px rgba(18,24,31,.1),0 1px 4px -1px rgba(18,24,31,.22);
    color:var(--navy);
  }
  /* Con selección pero el panel cerrado (mismo caso que .filtro-boton-activo
     en escritorio, ver estilo arriba): el icono se queda navy para que se
     note sin tener que abrir el desplegable. */
  .tira-icono.tira-icono-activo{color:var(--navy)}
  /* .tira-insignia (badge numérico sobre el icono) se quitó de aquí: era
     exclusiva de #precioInsigniaMovil, y con Precio fuera de la píldora
     (el director: "eso no lo quiero ver ni en escritorio ni en móvil") no
     queda ningún control que la use. Recuperable en el historial de esta
     rama junto con el resto del desplegable de Precio. */
  /* El panel de Ordenar reutiliza .selector-panel (misma tarjeta blanca
     flotante que el combobox de marca/modelo/año) pero SIN .filtro-panel:
     aquí no hace falta la muesca de categoría, y la píldora es angosta —
     ancla al lado de su icono, no al ancho del botón (34px, insuficiente
     para el texto). Crece hacia la izquierda (right:0) para no salirse del
     borde de la pantalla, al ser el último control de la píldora. */
  .tira-desplegable .selector-panel{min-width:216px}
  #ordenListaMovil{left:auto;right:0}
  .tira-desplegable.abierto .selector-panel{opacity:1;transform:none;visibility:visible;pointer-events:auto}
  .chip-cat{
    display:flex;flex-direction:column;align-items:center;gap:7px;flex:none;width:84px;
    background:none;border:none;padding:4px 0;cursor:pointer;
  }
  .chip-cat-foto{
    display:block;width:76px;height:76px;border-radius:50%;overflow:hidden;
    background:#fff;border:2px solid transparent;transition:border-color .18s var(--e-swift);
  }
  .chip-cat-foto picture,.chip-cat-foto img{width:100%;height:100%;object-fit:cover;display:block}
  .chip-cat[aria-pressed="true"] .chip-cat-foto{border-color:var(--navy)}
  /* "Todos" (chip fijo, sin categoría ni producto que fotografiar): icono
     de marca, no una foto — elección deliberada (ver artefacto), no un
     descuido. Rhino Linings usaba este mismo tratamiento hasta que el
     director pidió foto real de catálogo propio en vez del icono
     genérico; ahora tiene su curada en FOTO_CATEGORIA_CURADA (catalogo.astro)
     como cualquier otra categoría, y esta clase vuelve a ser solo de "Todos".
     Invertido a petición del director (22-sep-2026): antes navy sólido +
     icono blanco; ahora fondo gris (--papel-3) + contorno y trazo navy —
     "al revés", su preferencia explícita sobre blanco. */
  /* 24-sep-2026 (director): con el aro navy fijo, «Todos» parecía elegido
     aunque no lo estuviera y al tocar otra categoría no se sabía cuál
     mandaba. Fondo blanco como las demás esferas y aro gris; el navy queda
     solo para cuando está elegido (regla aria-pressed de .chip-cat-foto). */
  .chip-cat-icono .chip-cat-foto{background:var(--blanco);border-color:#C9CED6;display:grid;place-items:center}
  .chip-cat-icono[aria-pressed="true"] .chip-cat-foto{border-color:var(--navy)}
  /* 56 % (antes 46 %) y más hueco entre cuadrados, que casi se tocaban; el trazo
     del SVG (1.3) baja en proporción para seguir en ~2,2 px — artefacto de
     iconos, opción C (23-sep-2026) */
  .chip-cat-icono .chip-cat-foto svg{width:56%;height:56%;color:var(--navy)}
  .chip-cat-nombre{font:600 12px/1.2 var(--sans);color:var(--tinta-2);text-align:center;max-width:100%;overflow-wrap:break-word}
  .chip-cat[aria-pressed="true"] .chip-cat-nombre{color:var(--navy)}
  /* Hallazgo del director en vivo ("los filtros son categorías... hay una
     repetición"): #filtroLista es SOLO categorías (aria-label="Categorías",
     confirmado leyendo el JS — ni precio ni marca ni ningún otro filtro), y
     el carril de arriba ya ofrece exactamente ese mismo picker con foto en
     este mismo tramo (≤720px). El botón "Filtros" + su listbox se ocultan
     aquí; encima de 720px (donde el carril no se ve) siguen exactamente
     igual que siempre. El carril ya reutiliza el mismo Set `cats` y la misma
     alternarCategoria() que #filtroLista (ver catalogo.astro) — selección
     múltiple incluida, sin regresión funcional. Los chips de filtro
     aplicado (.chips-filtro, también usados por el chip de búsqueda) y el
     contador de entradas se quedan: siguen aportando algo que el carril no
     da (ver qué está activo sin desplazar el carril, y limpiar de un tap).
     El contador es la excepción: "sin contador" (pedido del director sobre
     el artefacto "U3") — pintar() lo sigue calculando (útil si más adelante
     hace falta, p.ej. lógica de "sin resultados"), pero deja de pintarse en
     la cabecera compartida. Oculto visualmente sin display:none (que lo
     sacaría del árbol de accesibilidad): sigue como región aria-live, así
     que un lector de pantalla lo anuncia igual al cambiar de filtro. */
  .filtro{display:none}
  #conteo{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
  }
  /* Franja de filtros activos (24-sep-2026, director eligió la «A» de un mock
     de cinco: «ensucia mucho y si sigo poniendo filtros se ocupa toda la
     tarjeta»). Las píldoras salen de la tarjeta y van debajo, en UNA línea
     que se desliza de lado: la tarjeta ya no crece con cada filtro. La
     búsqueda va la primera (llega de fuera —buscador del menú, placa ARB del
     inicio— y no se ve en ningún otro sitio); blancas con el aro navy de la
     categoría elegida en el carril; «Limpiar» solo con dos filtros o más. */
  .cabecera-compartida .chips-filtro{display:none}
  .franja-filtros:not([hidden]){display:flex;align-items:center;gap:12px;margin:-4px 0 16px}
  .franja-carril{
    flex:1;min-width:0;display:flex;gap:8px;overflow-x:auto;overscroll-behavior-x:contain;
    scrollbar-width:none;padding:4px 3px;margin:-4px -3px;
  }
  .franja-carril::-webkit-scrollbar{display:none}
  /* Degradado solo en el borde por el que queda más (clases desde catalogo.astro) */
  .franja-carril.sigue-der{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent)}
  .franja-carril.sigue-izq{-webkit-mask-image:linear-gradient(90deg,transparent,#000 32px);mask-image:linear-gradient(90deg,transparent,#000 32px)}
  .franja-carril.sigue-izq.sigue-der{-webkit-mask-image:linear-gradient(90deg,transparent,#000 32px,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,transparent,#000 32px,#000 calc(100% - 32px),transparent)}
  .chip-activo{
    flex:none;display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 10px 0 14px;
    border:0;border-radius:var(--r-chip);background:var(--blanco);box-shadow:inset 0 0 0 1.5px var(--navy);
    font:600 13px/1 var(--sans);color:var(--navy);white-space:nowrap;cursor:pointer;
  }
  .chip-activo svg{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round}
  .chip-activo .x{width:14px;height:14px;stroke-width:2.3}
  .chip-activo .lupa{width:15px;height:15px;stroke-width:2.2;margin-left:-3px}
  .franja-limpiar{
    flex:none;position:relative;border:0;background:none;padding:8px 0;cursor:pointer;
    font:600 13px/1 var(--sans);color:var(--tinta-2);
    text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;
  }
  .franja-limpiar::after{content:"";position:absolute;inset:-6px -8px}
}
/* Vista de una en teléfonos estrechos: con el botón a 36px/letra 14, «USD 6,170»
   y «En cotización ✓» ya no caben juntos por debajo de 375px (se partían los
   dos). Entre 360 y 374 el precio baja un punto y el botón aprieta su relleno,
   sin partirse nunca; por debajo de 360 (SE de 1.ª generación) el botón pasa a
   su propia fila y a todo el ancho, en los dos estados, para que al tocarlo no
   salte de sitio. */
@media(max-width:374px){
  #plancha.vista-destacada .entrada .precio{font-size:1.75rem;white-space:nowrap}
  #plancha.vista-destacada .entrada .pie-celda{gap:8px}
  #plancha.vista-destacada .entrada .sello{padding:0 12px;white-space:nowrap}
}
@media(max-width:359px){
  #plancha.vista-destacada .entrada .pie-celda{flex-direction:column;align-items:stretch;gap:10px}
  #plancha.vista-destacada .entrada .sello{justify-content:center}
}

/* ---------- 19b · TELÉFONO EN HORIZONTAL (alto corto) ----------
   Un solo caso apaisado existía en todo el proyecto antes de esta rama
   (verifica-descubre.mjs). Aquí no se rediseña nada — la regla que no se
   rompe es "que no se rompa": la cabecera se condensa siempre, el hero no
   impone un suelo más alto que la pantalla, y los desplegables con techo
   fijo (buscador, selector) ya usan dvh arriba en vez de un px/vh fijo. */
@media(max-height:480px){
  .masthead-fila{height:56px}
  .masthead-logo img{height:27px}
  /* Menú en horizontal: menos aire arriba y entre destinos, para que quepan
     los cinco sin scroll en la mayoría de teléfonos. */
  .velo-menu{padding-top:calc(var(--masthead-total,56px) + 4px);padding-bottom:16px}
  .velo-menu nav{gap:2px}
  .velo-menu a{font-size:26px}
}

/* ---------- 19d · MÓVIL EN HORIZONTAL (pedido del director, 25-sep-2026) ----------
   Un iPhone apaisado da ~760–930px de ancho y solo 300–430px de alto útil:
   proporciones de «escritorio» en una ventana de 300px. Aquí se compacta todo
   lo que come alto (cabecera, titulares, aire entre secciones) y se aprovecha
   el ancho (dos columnas donde antes se apilaba). Una sola condición para
   todo el sitio: apaisado + alto ≤500 + ancho ≤1000 — un iPad apaisado (≥744
   de alto) o un portátil (≥600) nunca entran, y en vertical no se aplica nada
   de este bloque.
   Zona segura (notch / Dynamic Island): el script del <head> de cada página escribe
   viewport-fit=cover SOLO en este caso, para que el fondo llegue a los bordes de la pantalla; --zs-i /
   --zs-d son los márgenes que el contenido debe respetar a cada lado (valen 0
   si no hay zona segura, así que fuera de iOS no cambian nada). */
:root{--zs-i:env(safe-area-inset-left,0px);--zs-d:env(safe-area-inset-right,0px)}
@media (orientation:landscape) and (max-height:500px) and (max-width:1000px){
  :root{--masthead:44px;--lado:clamp(16px,3vw,28px)}
  .contenedor{
    padding-left:max(var(--lado),var(--zs-i));padding-right:max(var(--lado),var(--zs-d));
  }
  /* cabecera: 44px en vez de 56–68 (era el ~19% de la pantalla) */
  .masthead-fila,.masthead.condensa .masthead-fila{
    height:44px;
    padding-left:max(var(--lado),var(--zs-i));padding-right:max(var(--lado),var(--zs-d));
  }
  .masthead-logo img,.masthead.condensa .masthead-logo img{height:22px}
  .masthead-nav{gap:clamp(12px,1.8vw,22px)}
  .masthead-nav a{font-size:11px}
  .masthead-cotizacion{font-size:11px;padding-left:12px}
  .masthead-cotizacion b{font-size:11px}
  .masthead-acciones{gap:8px}
  .masthead .celda.btn-menu{margin-right:-11px}
  /* mega-panel y buscador: sin el aire de escritorio y sin salirse de la zona segura */
  .mega-interior{padding:14px max(var(--lado),var(--zs-d)) 16px max(var(--lado),var(--zs-i))}
  .buscar-form{padding:12px max(var(--lado),var(--zs-d)) 14px max(var(--lado),var(--zs-i))}
  /* menú a pantalla completa: los cinco destinos en dos columnas si hace falta */
  .velo-menu{
    padding:calc(var(--masthead-total,44px) + 6px) max(var(--lado),var(--zs-d)) 14px max(var(--lado),var(--zs-i));
  }
  .velo-menu nav{gap:0}
  .velo-menu a{font-size:clamp(20px,7.5svh,28px)}
  .velo-menu a::after{margin-top:4px}

  /* titulares y aire entre secciones a la medida del alto, no del ancho: con
     vw un titular «t-h2» salía de ~50px en una pantalla de 300 de alto.
     !important en .seccion porque varias páginas fijan su padding en línea. */
  .display{font-size:clamp(1.8rem,min(11svh,5.4vw),3.4rem)}
  .t-h2{font-size:clamp(1.35rem,min(8.5svh,4.4vw),2.4rem)}
  .seccion{padding-block:clamp(22px,7svh,36px) clamp(20px,6svh,32px)!important}
  .seccion-cabecera{margin-bottom:clamp(14px,4svh,22px)}
  .pie{margin-top:clamp(28px,8svh,44px)}
  .pie .interior{padding-block:clamp(26px,8svh,38px) clamp(18px,5svh,26px)}
  .pie .remate{margin-top:18px}

  /* rejilla del catálogo: la misma tarjeta compacta del móvil vertical (~170px),
     pero cuatro por fila en vez de dos; «Una» (destacada) pasa a tarjeta
     apaisada —foto a la izquierda, texto a la derecha— y dos por fila, para que
     ninguna tarjeta mida más que la pantalla. */
  .plancha{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px}
  #plancha.vista-destacada{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  #plancha.vista-destacada .entrada{
    display:grid;grid-template-columns:clamp(96px,34%,150px) minmax(0,1fr);
    grid-template-areas:"foto cab" "foto tit" "foto pie";grid-template-rows:auto 1fr auto;
    column-gap:14px;row-gap:4px;padding:12px;
  }
  #plancha.vista-destacada .entrada > a:first-child{grid-area:foto;margin:0;align-self:center}
  #plancha.vista-destacada .entrada .cabecera{grid-area:cab}
  #plancha.vista-destacada .entrada-titulo{grid-area:tit;justify-content:flex-start;align-self:center}
  #plancha.vista-destacada .entrada h3{font-size:17px}
  #plancha.vista-destacada .entrada .pie-celda{grid-area:pie;margin-top:0;padding-top:10px}
  #plancha.vista-destacada .entrada .precio{font-size:1.5rem}
  #plancha.vista-destacada .entrada .sello{min-height:34px;padding:0 12px;font-size:13px}
}
/* móvil apaisado pequeño (≤720 de ancho: iPhone SE/mini, Android compactos): aquí sí sale
   el carril de categorías con foto y la tarjeta de cabecera del catálogo, pensados para
   vertical — con esferas de 76px se comían la pantalla entera (~300 de 375px de alto) antes
   de ver un solo producto. Misma pieza, más baja. */
@media (orientation:landscape) and (max-height:500px) and (max-width:720px){
  .cabecera-compartida{margin-top:10px;margin-bottom:14px;padding:10px 12px 6px}
  .rail-categorias{gap:8px;padding:0 2px 6px}
  .chip-cat{width:78px;gap:4px;padding:2px 0}
  .chip-cat-foto{width:52px;height:52px}
  .chip-cat-nombre{font-size:11px}
  .vista-densidad{padding:4px 0 0}
}
/* carrusel «Del mismo cajón» de la ficha: sangra hasta el borde de la pantalla
   respetando la zona segura de cada lado (antes, un margen fijo) */
@media (orientation:landscape) and (max-height:500px) and (max-width:1000px){
  .relacionados .plancha{
    margin-left:calc(-1 * max(var(--lado),var(--zs-i)));margin-right:calc(-1 * max(var(--lado),var(--zs-d)));
    padding-left:max(var(--lado),var(--zs-i));padding-right:max(var(--lado),var(--zs-d));
    scroll-padding-left:max(var(--lado),var(--zs-i));
  }
}

/* ---------- 19c · FORMA Y TOQUE EN MÓVIL (feedback del director, 19-sep-2026) ----------
   Botones grandes a 12px y chips en píldora (--r-boton / --r-chip, ver tokens);
   los controles cuadrados de catálogo y ficha heredarán el mismo criterio
   cuando se toquen esas pantallas. */
@media(max-width:720px){
  .comando{border-radius:var(--r-boton)}
}
/* Feedback al toque, «hundir»: el elemento se encoge un 3,5 % y se oscurece
   mientras el dedo lo toca. Solo en pantallas sin hover (en escritorio el
   feedback sigue siendo el hover). Las filas a todo el ancho (menú, pie) se
   encogen menos: un 3,5 % de 350px se notaría como un tirón. */
@media(hover:none){
  .comando,.sello,.chip-filtro,.pagina-boton,.chip-cat,
  .placa-arb,.tarjeta-vehiculo,.celda-registro,.btn-menu,.celda-buscar,.masthead-cotizacion,
  .pie-toggle,.velo-menu a{
    -webkit-tap-highlight-color:transparent;
    transition-property:transform,filter,background-color,color,border-color,box-shadow;
    transition-duration:.16s;transition-timing-function:var(--e-out);
  }
  .comando:active,.sello:active,.chip-filtro:active,
  .pagina-boton:not(:disabled):active,.chip-cat:active,.placa-arb:active,.tarjeta-vehiculo:active,
  .celda-registro:active,.btn-menu:active,.celda-buscar:active,.masthead-cotizacion:active{
    transform:scale(.965);filter:brightness(.9);
  }
  .pie-toggle:active,.velo-menu a:active{transform:scale(.985);filter:brightness(.9)}
  /* La tarjeta entera es un enlace (≤920px): al tocarla toma el tono del papel,
     sin encogerse (su transform ya lo anima la entrada, .rev, con 0,7s y retardo). */
  .entrada:active:not(:has(.sello:active)){background:var(--papel)}
}

/* ---------- 16d · AVISO DE COMPATIBILIDAD (toast) ----------
   Se dispara desde sistema.js al añadir a cotización un producto no-universal
   sin vehículo guardado (feedback del director, 28-sep-2026): el CTA de la
   ficha ("¿Es compatible?") es pasivo, esto avisa en el momento. Vive fuera
   de cualquier página (se inyecta en <body>): sirve igual en catalogo.astro
   y en producto.astro, un único componente para el único punto de "añadir"
   (sistema.js). Deliberadamente NO existe un equivalente en cotizacion.astro:
   ese aviso ya se vio aquí; cotización se queda "Todo fuera" (PR #54). */
/* 29-sep-2026 (feedback del director, con captura): en móvil el aviso se
   posaba a 18px del fondo de la PANTALLA, justo donde ya está la barra de
   precio fija de la ficha — quedaban pegados. --aviso-elevar (sistema.js mide
   la barra de precio en tiempo real y lo sube cuando esa barra existe y está
   fija) lo levanta por encima de ella. overflow:hidden recorta el hilo de
   tiempo de abajo a las esquinas redondeadas.
   30-sep-2026 (feedback del director, ya viéndolo en el móvil real): el ancho
   fijo por márgenes (16px a cada lado) — "se ve raro" — pasó a abrazar su
   contenido (fit-content) con un mínimo, y ni así: "sigue estando enano",
   "lo veo tan poco". El techo era el propio formato: una tarjeta flotante
   y centrada, por ancha que sea, siempre lee como una notificación menor.
   30-sep-2026, cuarta vuelta (mockup con 3 vías, elegido "sin duda" — ver
   PR #54): banner de ancho completo anclado abajo, de punta a punta de la
   pantalla — el mismo lenguaje de fila (icono+título+CTA, subtítulo debajo)
   que ya usa la versión de escritorio, pero ocupando todo el ancho en vez
   de flotar. Gana presencia sin agrandar cada pieza suelta. */
.aviso-compat{
  position:fixed;left:32px;right:32px;bottom:calc(var(--aviso-elevar,0px) + 14px);z-index:150;
  width:auto;min-width:0;max-width:none;
  box-sizing:border-box;overflow:hidden;
  padding:16px 14px;padding-bottom:max(14px,env(safe-area-inset-bottom,0px));
  background:var(--navy);color:var(--papel);border-radius:16px;
  box-shadow:0 8px 24px rgba(0,40,86,.32);
  opacity:0;pointer-events:none;
  /* visibility:hidden al salir: Safari 26 tiñe la barra de abajo con el color
     de lo fijo pegado al borde aunque tenga opacity:0 (dejaba azul la franja
     bajo la pestaña «Elige tu vehículo»). */
  visibility:hidden;
  transform:translateY(16px);
  transition:opacity .22s var(--e-out),transform .22s var(--e-out),bottom .22s var(--e-out),visibility 0s linear .22s;
}
.aviso-compat.on{opacity:1;pointer-events:auto;transform:translateY(0);visibility:visible;transition-delay:0s}
/* Cerrado a mano (✕ o botón): desaparece al instante, sin fundido. */
.aviso-compat.instante{transition:none}
/* Hilo de 2px que se vacía durante los AVISO_MS que el aviso está en pantalla
   — no es una barra de progreso "de verdad" (sin fondo ni bordes propios),
   solo el mismo indicio de tiempo que ya daba el cierre automático, ahora
   visible (referencia del director, 29-sep-2026). La duración la fija
   sistema.js al crear/relanzar el aviso (misma constante AVISO_MS que el
   setTimeout, nunca un número aparte aquí que se pudiera desincronizar). */
.aviso-compat-tiempo{
  position:absolute;left:0;right:0;bottom:0;height:2px;
  background:rgba(246,246,243,.4);transform-origin:left;
}
/* Mismo criterio que ya pausaba el cierre automático (mouseenter/mouseleave
   en sistema.js): al pasar el ratón por encima, también se detiene el hilo. */
.aviso-compat:hover .aviso-compat-tiempo{animation-play-state:paused}
@keyframes aviso-compat-vaciar{from{transform:scaleX(1)}to{transform:scaleX(0)}}
.aviso-compat-cerrar{
  position:absolute;top:6px;right:6px;
  background:none;border:0;padding:8px;margin:0;
  font:600 14px var(--sans);line-height:1;color:rgba(246,246,243,.55);cursor:pointer;
}
/* Grid en vez de filas anidadas: icono, título, subtítulo y CTA son celdas
   nombradas que cada media query recoloca a su gusto sin duplicar HTML por
   tamaño — solo el subtítulo tiene dos versiones (larga/corta), como
   .sello-largo/.sello-corto.
   30-sep-2026, cuarta vuelta: móvil deja de apilar el CTA debajo de todo y
   pasa a compartir la misma estructura que ya usaba escritorio — icono y
   título en la fila de arriba, subtítulo debajo, el botón a la derecha
   ocupando las dos filas (mismo grid-template-areas que el de abajo, solo
   con columnas más estrechas). Menos texto envuelto en más aire vertical
   inútil; más lectura en una sola fila, que es justo lo que pedía "más
   presencia". */
.aviso-compat-cuerpo{
  display:grid;
  grid-template-columns:34px 1fr auto;
  grid-template-rows:auto auto;
  grid-template-areas:"icono titulo cta" ".     sub   cta";
  /* 6-oct-2026 (mockup del director, opción D): más aire entre título y
     subtítulo, y el botón baja lo bastante para dejar sitio a la ✕ encima. */
  column-gap:8px;row-gap:10px;padding-bottom:6px;padding-right:20px;
  align-items:center;
}
.aviso-compat-icono{grid-area:icono;width:22px;height:22px;align-self:start;margin-top:2px;color:var(--papel)}
.aviso-compat-titulo{grid-area:titulo;align-self:center;margin:0;font:700 15px/1.2 var(--sans);color:var(--papel)}
.aviso-compat-sub{grid-area:sub;margin:0;padding-left:0;font:500 12px/1.4 var(--sans);color:rgba(237,238,241,.78)}
.aviso-compat-sub-larga{display:none}
/* Fondo papel, texto navy — el fantasma (borde traslúcido) es justo lo que
   "chocaba" con el fondo navy y no se distinguía de un texto cualquiera; el
   ámbar de --senal quedaba descartado por el director por "destacar
   demasiado" en un aviso que no es la acción principal de la pantalla.
   30-sep-2026, cuarta vuelta: al vivir ahora en su propia columna "auto"
   (no ya una fila "cta cta" compartida y más ancha que el botón), no hace
   falta stretch para llenarla — la columna ya se ajusta sola a él. */
.aviso-compat-cta{
  grid-area:cta;justify-self:end;align-self:center;margin:14px 0 0;
  background:var(--papel);border:0;border-radius:8px;
  padding:10px 12px;
  font:700 10.5px var(--sans);letter-spacing:.03em;text-transform:uppercase;color:var(--navy);
  text-align:center;
  cursor:pointer;white-space:nowrap;
  transition:transform .2s var(--e-swift);
}
@media(hover:hover){
  /* Consistencia con el resto de botones del sitio (feedback del director,
     29-sep-2026): el "raro" era que este no tuviera el mismo movimiento que
     cualquier .comando — mismo translateY(-1px), sin el aro ámbar (ese solo
     va en .comando.navy/.registro; este botón es claro, como .comando.claro,
     que tampoco lo lleva). */
  .aviso-compat-cta:hover{background:#fff;transform:translateY(-1px)}
  .aviso-compat-cerrar:hover{color:var(--papel)}
}
/* Escritorio real (excluye el móvil en apaisado — mismo corte que MQ_MOVIL
   en sistema.js): abajo a la derecha, no centrado, y el componente que trajo
   el director tal cual — ancho amplio y esquinas de 14px, ya no la esquina
   recta de 2px que llevaba antes (decisión anterior, superada por esta
   referencia). */
@media(min-width:921px) and (min-height:501px),(min-width:1001px){
  .aviso-compat{
    left:auto;right:24px;bottom:24px;
    max-width:min(620px,calc(100vw - 48px));
    border-radius:14px;
    padding:20px 24px;
    transform:translateY(10px);
  }
  .aviso-compat.on{transform:translateY(0)}
  .aviso-compat-cerrar{top:14px;right:14px;font-size:15px}
  .aviso-compat-cuerpo{
    grid-template-columns:24px 1fr auto;
    grid-template-rows:auto auto;
    grid-template-areas:"icono titulo cta" ".     sub   cta";
    column-gap:14px;row-gap:3px;
    padding-right:20px;padding-bottom:0;
  }
  .aviso-compat-icono{width:24px;height:24px;align-self:start;margin-top:2px}
  .aviso-compat-titulo{font-size:15px}
  .aviso-compat-sub{padding-left:0;font-size:13px;line-height:1.4}
  .aviso-compat-sub-larga{display:block}
  .aviso-compat-sub-corta{display:none}
  .aviso-compat-cta{
    align-self:center;margin:0;border-radius:8px;font-size:10.5px;padding:10px 16px;
  }
  .aviso-compat-cta::after{content:" →"}
}

/* ---------- 17b · MODO QA (?directo): estados finales, cero espera ---------- */
html.qa{scroll-behavior:auto!important}
html.qa *,html.qa *::before,html.qa *::after{
  transition:none!important;
  animation-duration:0s!important;animation-delay:0s!important;
}
html.qa .rev{opacity:1;transform:none;filter:none}

/* ---------- 18 · MOVIMIENTO REDUCIDO ---------- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  html,body{scroll-behavior:auto}
  .rev{opacity:1;transform:none;filter:none}
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}

/* Primera página de la visita, antes de que lleguen los datos (ver sistema.js): el pie no se pinta ni salta. */
html.sin-datos .pie{visibility:hidden}
