/* ==========================================================================
   CasaVeta — sistema visual
   Dirección: los materiales y los artefactos reales de la planta.
   Piso de concreto, alma de MDF crudo, nogal, y el amarillo del flexómetro.
   El elemento firma es EL DESPIECE: el diagrama de corte. Es lo que una
   fábrica puede enseñar y un revendedor no.
   ========================================================================== */

/* --- Tokens --------------------------------------------------------------- */
:root {
  /* Materiales */
  --mdf: #D2B183;          /* alma de MDF crudo — campo del hero */
  --mdf-hondo: #BE9A69;
  --mdf-claro: #E2C9A3;
  --nogal: #6B4522;
  --nogal-claro: #8A5C31;
  --melamina-negra: #1A1815;
  --melamina-blanca: #F1EDE4;

  /* Superficies */
  --concreto: #E8E5DE;     /* piso de planta — fondo general */
  --concreto-hondo: #DBD7CD;
  --papel: #FBF9F5;        /* tarjetas y paneles */
  --tinta: #1F1811;        /* café-negro: texto y bandas oscuras */
  --tinta-2: #2E251A;

  /* Texto */
  --txt: #241C13;
  --txt-medio: #574B3D;
  --txt-tenue: #857868;
  --sobre-tinta: #E6DFD2;
  --sobre-tinta-tenue: #9C8F7C;
  --sobre-mdf-tenue: #6E5433;

  /* Acento: amarillo de flexómetro. Marca el canto sellado y las acciones. */
  --flexo: #F0A81E;
  --flexo-hondo: #D08D08;
  --alerta: #A33418;

  /* Líneas */
  --linea: #CFC9BC;
  --linea-tenue: #DFDACE;
  --linea-tinta: rgba(230, 223, 210, .16);

  /* Tipografía */
  --display: 'Bricolage Grotesque', 'Archivo', sans-serif;
  --texto: 'Archivo', Helvetica, sans-serif;
  --dato: 'Azeret Mono', ui-monospace, monospace;

  /* Métrica */
  --r: 3px;                /* radio discreto: no somos un periódico */
  --px: clamp(20px, 5vw, 64px);
  --py: clamp(56px, 8vw, 108px);
  --ancho: 1300px;
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--concreto);
  color: var(--txt);
  font: 400 16px/1.55 var(--texto);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font-family: inherit; color: inherit; }
h1, h2, h3, h4 { margin: 0; font-family: var(--display); font-weight: 700; letter-spacing: -.02em; }
p { margin: 0; }

:focus-visible { outline: 2px solid var(--flexo-hondo); outline-offset: 3px; border-radius: 2px; }

/* --- Tipografía ----------------------------------------------------------- */
.d1 { font-size: clamp(44px, 7.4vw, 92px); line-height: .94; letter-spacing: -.035em; text-wrap: balance; }
.d2 { font-size: clamp(32px, 4.6vw, 54px); line-height: 1.02; letter-spacing: -.03em; text-wrap: balance; }
.d3 { font-size: clamp(24px, 2.8vw, 34px); line-height: 1.1; letter-spacing: -.02em; }
.d4 { font-size: clamp(18px, 2vw, 23px); line-height: 1.15; letter-spacing: -.015em; }

.dato {
  font: 500 11px/1.5 var(--dato);
  letter-spacing: .11em;
  text-transform: uppercase;
}
.dato-suave { font: 400 12px/1.6 var(--dato); letter-spacing: .02em; text-transform: none; }

.plomo { color: var(--txt-medio); }
.tenue { color: var(--txt-tenue); }
.amarillo { color: var(--flexo); }

.parrafo { font-size: clamp(15px, 1.3vw, 17.5px); line-height: 1.62; color: var(--txt-medio); text-wrap: pretty; }
.parrafo-g { font-size: clamp(17px, 1.7vw, 21px); line-height: 1.5; color: var(--txt-medio); text-wrap: pretty; }

/* --- Estructura ----------------------------------------------------------- */
.cont { max-width: var(--ancho); margin: 0 auto; padding-left: var(--px); padding-right: var(--px); }
.banda { padding-top: var(--py); padding-bottom: var(--py); }
.banda-papel { background: var(--papel); }
.banda-tinta { background: var(--tinta); color: var(--sobre-tinta); }
.banda-tinta h1, .banda-tinta h2, .banda-tinta h3 { color: var(--papel); }
.banda-tinta .parrafo, .banda-tinta .parrafo-g { color: var(--sobre-tinta); }
.banda-tinta .tenue { color: var(--sobre-tinta-tenue); }

.encabezado-seccion {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap; margin-bottom: clamp(28px, 4vw, 48px);
}
/* El titular manda: se queda con el ancho y el enlace se acomoda al lado.
   Sin el flex-basis, el titular se comprime en una columna de dos palabras. */
/* Ojo: aquí no va `ch`. La unidad se calcula con la fuente de ESTE div (16px),
   no con la del h2, y el titular acababa en una columna de 270px. */
.encabezado-seccion .titulo { flex: 1 1 min(100%, 620px); min-width: 0; max-width: 780px; }
/* El enlace se alinea al BORDE inferior del bloque del título, que con un
   titular de dos líneas cae bastante abajo de su última base y se leía como si
   se hubiera resbalado. El respiro lo sube a la altura de la última línea. */
.encabezado-seccion > .enlace { flex: 0 0 auto; margin-bottom: clamp(4px, .7vw, 11px); }
.eyebrow { display: block; color: var(--flexo-hondo); margin-bottom: 14px; }
.banda-tinta .eyebrow { color: var(--flexo); }

/* --- Botones -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 52px; padding: 15px 28px;
  border: 1px solid transparent; border-radius: 99px;
  font: 600 15px/1 var(--texto); letter-spacing: -.01em;
  cursor: pointer; text-align: center;
  transition: background 180ms ease, color 180ms ease, border-color 180ms ease, transform 180ms ease;
}
.btn:active { transform: translateY(1px); }
.btn-acento { background: var(--flexo); color: var(--tinta); }
.btn-acento:hover { background: var(--flexo-hondo); }
.btn-tinta { background: var(--tinta); color: var(--papel); }
.btn-tinta:hover { background: var(--nogal); }
.btn-linea { border-color: currentColor; color: var(--txt); }
.btn-linea:hover { background: var(--tinta); border-color: var(--tinta); color: var(--papel); }
.banda-tinta .btn-linea { color: var(--sobre-tinta); }
.banda-tinta .btn-linea:hover { background: var(--papel); border-color: var(--papel); color: var(--tinta); }
.btn-bloque { width: 100%; }
.btn-ch { min-height: 44px; padding: 12px 20px; font-size: 14px; }

.enlace {
  display: inline-flex; align-items: center; gap: 7px;
  font: 600 14px var(--texto); color: var(--txt);
  border-bottom: 2px solid var(--flexo); padding-bottom: 2px;
  transition: gap 180ms ease, color 180ms ease;
}
.enlace:hover { gap: 12px; color: var(--nogal); }
.banda-tinta .enlace { color: var(--papel); }

/* Ligas de 20-25 px de alto —«Ver todo», el wordmark, la miga— que en celular
   quedaban abajo del mínimo táctil de 44. NO se agrandan con padding: el
   subrayado amarillo de `.enlace` es parte del dibujo y bajarlo 24 px lo
   despega del texto, y el wordmark movería el pie. Se les cuelga un blanco
   invisible encima, así que crece lo que se toca y no cambia un pixel de lo
   que se ve. El `inset` negativo lo desborda: por eso va el z-index, para que
   quede debajo de cualquier cosa que pase por ahí y no se coma sus clics. */
@media (max-width: 900px) {
  .enlace, .marca, .miga a { position: relative; }
  .enlace::after, .marca::after, .miga a::after {
    content: ""; position: absolute; inset: -12px -10px; z-index: 0;
  }
  /* La miga crece solo a lo alto: sus ligas van seguidas en un renglón
     separadas por " / ", y ensanchándolas los blancos se encimarían entre sí
     —tocarías «Catálogo» queriendo «Inicio»—, que es peor que quedarse corto. */
  .miga a::after { inset: -15px 0; }
}

/* --- Marca ---------------------------------------------------------------- */
/* El bloque de marca son DOS piezas apiladas: el logotipo y, debajo, el dominio
   en tipografía de datos. El canto sellado —el 4 px amarillo que antes llevaba
   el iconito del wordmark— vive a escala de página en el borde del pie.

   El logotipo dice «casa veta», sin guion y sin .com, y está bien que así sea:
   es la firma de la marca. Pero el dominio se compró CON GUION —`casaveta.com`
   sin él es de otro— y buena parte del tráfico llega tecleándolo de un QR
   impreso en la caja. Por eso el renglón de abajo no es adorno: es el trabajo
   que el wordmark de texto hacía solo y que el logotipo no puede hacer. */
/* `align-items: flex-start` NO ES OPCIONAL. En un flex en COLUMNA el eje
   transversal es el horizontal, y `align-items` vale `stretch` por omisión: el
   `<img>`, que tiene `width: auto`, se estiraba hasta el ancho del elemento más
   ancho de la columna —el renglón `casa-veta.com` en mono— con el alto fijo en
   su sitio. El logotipo salió publicado **+58% de ancho a 390 px y +32% a
   1440**. Ver la trampa 35. */
.marca { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 3px; }
/* La altura la manda el CSS y el ancho lo saca del `aspect-ratio` que dan los
   atributos width/height del <img>. Van puestos a propósito: sin ellos el
   header brinca al cargar la imagen, y es lo primero que se ve de la página. */
.marca-logo { height: 46px; width: auto; }
/* El renglón se dimensiona para NO ser más ancho que el logotipo que lleva
   encima. Un descriptor más largo que la marca deja el bloque pesado abajo y
   se lee como si el dominio fuera el logotipo. El ancho del logotipo es
   `alto × 1.727` (su proporción), así que cada vez que cambia el alto hay que
   volver a medir este renglón — lo hace `logo_prop.py`. */
.marca-dom {
  font: 400 9.1px/1 var(--dato); letter-spacing: .01em;
  color: var(--txt-tenue); white-space: nowrap;
}
/* En el pie va sobre tinta: la imagen ya viene en claro (logo.py genera las dos
   versiones), pero el renglón del dominio sí necesita su tono de aquí. */
.footer .marca-dom { color: var(--sobre-tinta-tenue); }

/* --- Header --------------------------------------------------------------- */
.header {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--concreto) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid var(--linea);
}
.header-fila {
  max-width: var(--ancho); margin: 0 auto;
  padding: 13px var(--px);
  display: flex; align-items: center; gap: 22px;
}
.nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
/* 44 px de alto y sin partirse: es el mínimo táctil del proyecto y no cuesta
   header —la pastilla del carrito ya mide 44 y es la que manda la altura de la
   fila—. El nowrap es porque abajo de 340 px «A tu medida» caía en dos
   renglones y estiraba el header justo donde menos espacio hay. */
.nav a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 13px; border-radius: 99px; white-space: nowrap;
  font: 500 14.5px var(--texto); color: var(--txt-medio);
  transition: background 160ms ease, color 160ms ease;
}
.nav a:hover { background: var(--concreto-hondo); color: var(--txt); }
.nav a.destacado { color: var(--nogal); font-weight: 600; }
.nav-fila { display: flex; align-items: center; gap: 4px; }

/* OJO CON EL SELECTOR: va `.nav a.nav-carrito`, no `.nav-carrito` a secas.
   Estuvo publicado con el corto y la pastilla salía con el texto café oscuro
   (#574B3D) sobre el fondo casi negro (#1F1811) — ilegible, en el único control
   del header que lleva un número. No era el color mal elegido: `.nav a` vale
   (0,1,1) de especificidad y `.nav-carrito` solo (0,1,0), así que el color de
   las ligas le ganaba al de la pastilla. Es la trampa 26 por otra vía: no una
   media query mal puesta, sino una regla de una clase perdiendo contra una de
   clase + elemento. Si se toca esto, se comprueba el color computado. */
.nav a.nav-carrito {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 10px 18px; border-radius: 99px;
  background: var(--tinta); color: var(--papel);
  font: 600 14px var(--texto);
  transition: background 160ms ease;
}
.nav a.nav-carrito:hover { background: var(--nogal); color: var(--papel); }
.nav a.nav-carrito .num {
  min-width: 21px; height: 21px; padding: 0 6px; border-radius: 99px;
  background: var(--flexo); color: var(--tinta);
  font: 700 12px/21px var(--dato); text-align: center;
}

/* --- la hamburguesa ---------------------------------------------------- */
/* Escondida en escritorio; abajo de 640 px se cambia por la fila de ligas. */
.nav-menu { display: none; position: relative; }
.nav-menu > summary {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 99px; cursor: pointer;
  list-style: none;                 /* mata el triangulito */
  transition: background 160ms ease;
}
.nav-menu > summary::-webkit-details-marker { display: none; }
.nav-menu > summary:hover { background: var(--concreto-hondo); }
.nav-menu > summary:focus-visible { outline: 2px solid var(--flexo); outline-offset: 2px; }
/* Tres rayas con una sola caja: la de en medio es el fondo, las otras dos son
   los pseudoelementos. Al abrir se cruzan en X. */
.hamburguesa, .hamburguesa::before, .hamburguesa::after {
  display: block; width: 19px; height: 2px; border-radius: 2px;
  background: var(--txt); transition: transform 200ms ease, opacity 140ms ease;
}
.hamburguesa { position: relative; }
.hamburguesa::before, .hamburguesa::after { content: ""; position: absolute; left: 0; }
.hamburguesa::before { top: -6px; }
.hamburguesa::after { top: 6px; }
.nav-menu[open] .hamburguesa { background: transparent; }
.nav-menu[open] .hamburguesa::before { transform: translateY(6px) rotate(45deg); }
.nav-menu[open] .hamburguesa::after { transform: translateY(-6px) rotate(-45deg); }

.nav-panel {
  position: absolute; z-index: 40; right: 0; top: calc(100% + 8px);
  min-width: 208px; padding: 8px; display: flex; flex-direction: column;
  background: var(--papel); border: 1px solid var(--linea);
  border-radius: var(--r); box-shadow: 0 20px 44px -20px rgba(31, 24, 17, .4);
}
.nav-panel a { justify-content: flex-start; padding: 0 14px; font-size: 15px; }

@media (max-width: 860px) {
  /* De la FILA solo se va "La fábrica". Catálogo, A tu medida y el carrito se
     quedan: ocultar el carrito lo dejaba inalcanzable en celular. Dentro de la
     hamburguesa sí va, que ahí sobra espacio. */
  .nav { gap: 2px; }
  .nav-fila .solo-escritorio { display: none; }
  .nav-fila a { padding: 0 10px; font-size: 13.5px; }
}
/* Abajo de 640 px la fila de ligas se cambia por la hamburguesa. El corte es
   ahí y no más abajo porque está medido: tres textos junto al carrito dan 47-69
   px de scroll horizontal a 320/360/390 y **empujan la pastilla del carrito
   fuera de la pantalla** — las trampas 5 y 29 a la vez.
   El carrito NO entra al menú: es el que lleva el número y el que no puede
   quedar a dos toques. */
@media (max-width: 639px) {
  .nav-fila { display: none; }
  .nav-menu { display: block; }
}
@media (max-width: 639px) {
  /* Con la hamburguesa puesta sobra ancho, así que el logotipo encoge por
     ALTURA, no por falta de sitio. Los dos valores van juntos: si se baja el
     logotipo sin bajar el renglón, el dominio pasa a ser más ancho que la
     marca. */
  .header .marca-logo { height: 42px; }
  .header .marca-dom { font-size: 8.4px; }
}
@media (max-width: 400px) {
  .header-fila { padding-left: 16px; padding-right: 16px; gap: 10px; }
  .header .marca-logo { height: 40px; }
  .header .marca-dom { font-size: 8px; }
  .nav a { padding: 0 7px; font-size: 13px; }
  .nav-carrito { padding: 9px 12px; }
}
/* Entre 340 y 380 px el renglón va al límite: marca + dos ligas + la pastilla
   del carrito suman más de lo que hay. Antes no se veía porque «A tu medida»
   partía en dos renglones y estiraba el header; ahora que va de una pieza, lo
   que cede es el aire de los costados. Se aprieta el nav, no el carrito: es el
   único que lleva número y es el que no puede quedar fuera de pantalla
   (trampa 5). */
@media (max-width: 380px) {
  .header-fila { gap: 7px; padding-left: 13px; padding-right: 13px; }
  .nav a { padding: 0 4px; font-size: 12.5px; }
  .nav-carrito { padding: 0 11px; }
}
@media (max-width: 339px) {
  /* Abajo de 340 px el dominio completo ya no cabe junto al nav y empujaba
     scroll horizontal. En el header se queda la marca; el dominio entero
     sigue visible en el pie, que tiene todo el ancho para él. */
  .header .marca-dom { display: none; }
  .nav a { padding-left: 5px; padding-right: 5px; }
}

/* --- Placeholders de foto ------------------------------------------------- */
/* Tono de kraft y MDF, no gris. Cada uno carga la instrucción de qué foto va. */
.foto {
  position: relative; overflow: hidden; border-radius: var(--r);
  background:
    linear-gradient(135deg, rgba(255,255,255,.30), rgba(0,0,0,.06)),
    repeating-linear-gradient(118deg, #D9C4A3 0 26px, #D2BB98 26px 52px);
  display: flex; align-items: center; justify-content: center;
}
.foto::after {
  content: ''; position: absolute; inset: 0;
  background-image: radial-gradient(rgba(107, 69, 34, .12) 1px, transparent 1px);
  background-size: 5px 5px; opacity: .55;
}
.foto-nota {
  position: relative; z-index: 2; max-width: 84%; text-align: center;
  font: 400 11px/1.85 var(--dato); letter-spacing: .06em; color: #6B5335;
}
.foto-nota b { display: block; font: 500 11px var(--dato); letter-spacing: .14em; text-transform: uppercase; color: #4E3A1E; }
.foto-oscura {
  background:
    linear-gradient(135deg, rgba(255,255,255,.07), rgba(0,0,0,.22)),
    repeating-linear-gradient(118deg, #34291C 0 26px, #2A2116 26px 52px);
}
.foto-oscura::after { background-image: radial-gradient(rgba(240,168,30,.14) 1px, transparent 1px); }
.foto-oscura .foto-nota { color: #B2A085; }
/* Cuando ya hay foto real, el macro escupe un <img> con la misma clase.
   OJO con `height: 100%`: en las tarjetas la imagen se estiraba a todo el alto
   de la tarjeta y se comía el pie (nombre y precio). La altura la marca el
   `aspect-ratio` de cada contexto, o los `inset` cuando va absoluta. */
img.foto { display: block; width: 100%; height: auto; object-fit: cover; }
img.foto::after { content: none; }

.foto-4x3 { aspect-ratio: 4 / 3; }
.foto-3x4 { aspect-ratio: 3 / 4; }
.foto-oscura .foto-nota b { color: var(--flexo); }

/* --- HERO ----------------------------------------------------------------- */
/* Campo de MDF crudo a sangre: el material antes que la fotografía. */
.hero { background: var(--mdf); position: relative; overflow: hidden; }
.hero::before {
  content: ''; position: absolute; inset: 0;
  background: repeating-linear-gradient(96deg, rgba(107,69,34,.05) 0 2px, transparent 2px 7px);
  pointer-events: none;
}
.hero-grid {
  max-width: var(--ancho); margin: 0 auto;
  display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
  align-items: stretch; gap: 0;
}
.hero-txt {
  position: relative; z-index: 2;
  padding: clamp(44px, 7vw, 96px) clamp(24px, 4vw, 60px) clamp(44px, 7vw, 96px) var(--px);
  display: flex; flex-direction: column; justify-content: center; gap: 26px;
}
.hero h1 { color: var(--tinta); }
.hero h1 .medida {
  position: relative; white-space: nowrap;
  border-bottom: 6px solid var(--flexo);
  padding-bottom: 2px;
}
.hero .parrafo-g { color: var(--sobre-mdf-tenue); max-width: 46ch; }
.hero-eyebrow { color: var(--nogal); }
.hero-ctas { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 4px; }

.hero-foto { position: relative; min-height: clamp(320px, 46vw, 620px); }
.hero-foto .foto { position: absolute; inset: 0; border-radius: 0; }

/* La rejilla va centrada a --ancho, así que en pantallas anchas quedaba una
   franja de MDF a la derecha de la foto. Se sangra hasta el borde. */
@media (min-width: 901px) {
  .hero-foto { margin-right: calc(-1 * max(0px, (100vw - var(--ancho)) / 2)); }
}

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-txt { padding: clamp(40px, 9vw, 64px) var(--px); }
  .hero-foto { min-height: 360px; }   /* en celular la foto merece más aire */
}

/* Cinta de datos bajo el hero */
.cinta {
  background: var(--tinta); color: var(--sobre-tinta-tenue);
  border-bottom: 3px solid var(--flexo);
}
.cinta-fila {
  max-width: var(--ancho); margin: 0 auto; padding: 15px var(--px);
  display: flex; gap: clamp(18px, 4vw, 52px); flex-wrap: wrap; align-items: center;
}
.cinta-fila span { display: inline-flex; align-items: center; gap: 9px; }
.cinta-fila b { color: var(--papel); font: 500 11px var(--dato); letter-spacing: .11em; text-transform: uppercase; }
.punto { width: 5px; height: 5px; border-radius: 99px; background: var(--flexo); flex: none; }

/* --- Categorías ----------------------------------------------------------- */
.rejilla-cat { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 14px; }
/* Columna flex para que el pie llene lo que sobre: en la rejilla todas las
   tarjetas quedan del mismo alto y un nombre de dos líneas dejaba una franja
   de fondo asomando abajo. */
.cat {
  position: relative; display: flex; flex-direction: column;
  border-radius: var(--r); overflow: hidden;
  background: var(--papel);
  transition: transform 260ms cubic-bezier(.2,.7,.3,1), box-shadow 260ms ease;
}
.cat:hover { transform: translateY(-4px); box-shadow: 0 18px 40px -18px rgba(36, 28, 19, .45); }
.cat .foto { border-radius: 0; aspect-ratio: 4 / 3; flex: none; }
/* Nombre y «desde» en dos renglones, no uno.
   Estaban en la misma línea con `space-between`: «Libreros y muebles» chocaba
   con «desde $1,890» y cada tarjeta partía por un lado distinto, así que la
   fila quedaba dentada abajo. Apilados, todas las tarjetas leen igual. Que la
   categoría del corte a medida ya traiga «desde» —sale del tabulador— es la
   otra mitad del arreglo: era la única sin él. */
.cat-pie {
  flex: 1; padding: 18px 20px 20px;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 5px;
}
.cat-nombre { font: 700 18px var(--display); letter-spacing: -.02em; text-wrap: balance; }
.cat-desde { font: 500 12px var(--dato); color: var(--txt-tenue); white-space: nowrap; }
.cat.proxima .cat-pie { background: var(--concreto-hondo); }
.cat-etiqueta {
  position: absolute; top: 12px; left: 12px; z-index: 3;
  padding: 6px 10px; border-radius: 99px;
  background: var(--tinta); color: var(--papel);
  font: 500 10px var(--dato); letter-spacing: .12em; text-transform: uppercase;
}
.cat-etiqueta.viva { background: var(--flexo); color: var(--tinta); }

/* --- EL DESPIECE (elemento firma) ---------------------------------------- */
.despiece-seccion { position: relative; overflow: hidden; }
.despiece-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(32px, 5vw, 72px); align-items: center;
}
@media (max-width: 940px) { .despiece-grid { grid-template-columns: 1fr; } }

.tablero {
  position: relative; width: 100%; aspect-ratio: 244 / 122;
  background: linear-gradient(160deg, #33291C, #262016);
  border: 1px solid var(--linea-tinta); border-radius: var(--r);
  padding: 1.4%;
}
.pieza {
  position: absolute; border-radius: 1px;
  background: linear-gradient(150deg, var(--mdf-claro), var(--mdf-hondo));
  border-bottom: 3px solid var(--flexo);   /* el canto sellado */
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transform: scale(.82);
  animation: encajar 520ms cubic-bezier(.18,.8,.28,1) forwards;
}
.pieza span {
  font: 500 9.5px var(--dato); letter-spacing: .04em; color: #533A1C;
  white-space: nowrap; pointer-events: none;
}
.pieza.merma {
  background: repeating-linear-gradient(45deg, rgba(230,223,210,.09) 0 5px, transparent 5px 10px);
  border-bottom-color: transparent; border: 1px dashed rgba(230,223,210,.22);
}
.pieza.merma span { color: var(--sobre-tinta-tenue); }

@keyframes encajar {
  from { opacity: 0; transform: scale(.82); }
  to   { opacity: 1; transform: scale(1); }
}

.tablero-pie {
  display: flex; gap: 22px; flex-wrap: wrap; margin-top: 16px;
  font: 400 11.5px var(--dato); color: var(--sobre-tinta-tenue);
}
.tablero-pie b { color: var(--papel); font-weight: 500; }

.leyenda { display: flex; flex-direction: column; gap: 14px; margin-top: 26px; }
.leyenda-fila { display: flex; align-items: flex-start; gap: 13px; }
.leyenda-muestra { width: 26px; height: 15px; flex: none; margin-top: 3px; border-radius: 1px; }
.leyenda-muestra.cara { background: linear-gradient(150deg, var(--mdf-claro), var(--mdf-hondo)); }
.leyenda-muestra.canto { background: var(--tinta-2); border-bottom: 4px solid var(--flexo); }
.leyenda-muestra.merma { background: repeating-linear-gradient(45deg, rgba(230,223,210,.14) 0 4px, transparent 4px 8px); border: 1px dashed rgba(230,223,210,.3); }
.leyenda-txt { font-size: 14.5px; line-height: 1.5; color: var(--sobre-tinta); }
.leyenda-txt b { color: var(--papel); font-weight: 600; }

/* --- Tarjetas de producto ------------------------------------------------- */
/* `auto-fit`, NO `auto-fill`. Con auto-fill la rejilla reserva las columnas que
   quepan aunque estén vacías: con los 2 productos publicados hoy, las tarjetas
   se quedaban chicas a la izquierda y media fila salía en blanco. La tienda se
   veía vacía justo donde tenía que verse surtida. auto-fit colapsa las columnas
   sin contenido y lo que hay ocupa la fila. */
.rejilla-prod { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 14px; }
.prod {
  display: flex; flex-direction: column;
  background: var(--papel); border-radius: var(--r); overflow: hidden;
  transition: transform 240ms cubic-bezier(.2,.7,.3,1), box-shadow 240ms ease;
}
.prod:hover { transform: translateY(-3px); box-shadow: 0 16px 34px -18px rgba(36,28,19,.4); }

/* --- «Arma el tuyo»: la tarjeta que no es un producto --------------------- */
.prod-medida { background: var(--tinta); color: var(--sobre-tinta); }
.prod-medida .prod-nombre { color: var(--papel); text-wrap: balance; }
.prod-medida .prod-medidas { color: var(--sobre-tinta-tenue); }
.prod-medida .prod-precio { color: var(--papel); }
.prod-medida .prod-precio small { color: var(--sobre-tinta-tenue); }

/* Tres tiras de tablero con su canto sellado: el mismo dibujo del despiece
   reducido a lo mínimo que sigue siendo reconocible. Ocupa el lugar de la foto,
   así que lleva su misma proporción o la tarjeta rompe la fila. */
.prod-medida-lienzo {
  aspect-ratio: 1 / 1; display: flex; flex-direction: column;
  align-items: flex-start; justify-content: center; gap: 13%;
  padding: 0 12%;
  background: linear-gradient(160deg, #33291C, #262016);
}
.prod-medida-lienzo i {
  height: 11px; border-radius: 1px;
  background: linear-gradient(150deg, var(--mdf-claro), var(--mdf-hondo));
  border-bottom: 3px solid var(--flexo);
  transition: width 320ms cubic-bezier(.2,.7,.3,1);
}
/* Al pasar encima las tiras se acomodan a otra medida: es la promesa de la
   tarjeta en un gesto, sin texto. Solo con movimiento permitido, y se declara
   en positivo para no tener que deshacerlo después. */
@media (prefers-reduced-motion: no-preference) {
  .prod-medida:hover .prod-medida-lienzo i:nth-child(1) { width: 92%; }
  .prod-medida:hover .prod-medida-lienzo i:nth-child(2) { width: 74%; }
  .prod-medida:hover .prod-medida-lienzo i:nth-child(3) { width: 58%; }
}
.prod .foto { border-radius: 0; aspect-ratio: 1 / 1; }
.prod-cuerpo { padding: 16px 18px 20px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
/* `pretty` para que no quede una palabra sola en el último renglón: los nombres
   partían en «…flotantes de 30 / cm» y las medidas en «…MDF 15 / mm». Una
   palabra huérfana es de lo que más delata que nadie miró la tarjeta. */
.prod-nombre { font: 600 15.5px/1.3 var(--texto); text-wrap: pretty; }
.prod-medidas { font: 400 11.5px/1.45 var(--dato); color: var(--txt-tenue); text-wrap: pretty; }
.prod-precio { margin-top: auto; padding-top: 8px; font: 700 19px var(--display); letter-spacing: -.02em; }
.prod-precio small { font: 400 11px var(--dato); color: var(--txt-tenue); letter-spacing: .06em; }
.prod-tag {
  position: absolute; top: 11px; left: 11px; z-index: 3;
  padding: 5px 9px; border-radius: 99px; background: var(--flexo); color: var(--tinta);
  font: 500 10px var(--dato); letter-spacing: .1em; text-transform: uppercase;
}

/* --- Objeciones (FAQ) ----------------------------------------------------- */
.objeciones { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 12px; }
.objecion {
  background: var(--papel); border-radius: var(--r);
  padding: 24px 26px 26px; border-left: 3px solid var(--flexo);
}
.objecion h3 { font: 700 17.5px/1.3 var(--display); margin-bottom: 9px; }
.objecion p { font-size: 14.8px; line-height: 1.62; color: var(--txt-medio); }

/* --- Reseñas -------------------------------------------------------------- */
.resenas { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.resena { background: var(--papel); border-radius: var(--r); padding: 26px; display: flex; flex-direction: column; gap: 14px; }
.resena-txt { font-size: 15.5px; line-height: 1.6; }
.resena-quien { display: flex; align-items: center; gap: 11px; margin-top: auto; }
.resena-ini {
  width: 36px; height: 36px; flex: none; border-radius: 99px;
  background: var(--mdf); color: var(--nogal);
  font: 700 14px/36px var(--texto); text-align: center;
}
.resena-nombre { font: 600 14px var(--texto); }
.resena-lugar { font: 400 11.5px var(--dato); color: var(--txt-tenue); }
.estrellas { color: var(--flexo-hondo); font-size: 14px; letter-spacing: 2px; }

/* --- Franja "a tu medida" ------------------------------------------------- */
.medida-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 60px); align-items: center;
}
/* `minmax(0, 1fr)` y NO `1fr` a secas. `1fr` es `minmax(auto, 1fr)`: la pista
   no puede encoger por debajo del min-content de su hijo, así que un solo
   elemento ancho —una placa con un valor que no se parte, por ejemplo— estira
   la columna y saca scroll horizontal a toda la página. Con `minmax(0, ...)`
   la pista sí puede encoger y el que se ajusta es el contenido.
   Costó 188 px de scroll a 390 en /negocios. */
@media (max-width: 940px) { .medida-grid { grid-template-columns: minmax(0, 1fr); } }
.medida-pasos { display: flex; flex-direction: column; gap: 4px; margin: 26px 0; }
.medida-paso { display: flex; gap: 15px; align-items: baseline; padding: 13px 0; border-bottom: 1px solid var(--linea-tenue); }
.medida-paso:last-child { border-bottom: 0; }
.medida-paso b { font: 500 11px var(--dato); color: var(--flexo-hondo); letter-spacing: .1em; flex: none; width: 26px; }
.medida-paso span { font-size: 15.5px; color: var(--txt-medio); }
.medida-paso span i { font-style: normal; color: var(--txt); font-weight: 600; }

/* --- Footer --------------------------------------------------------------- */
/* El pie es el tablero visto de canto: el 4 px amarillo de arriba es el canto
   sellado, el mismo gesto que llevaba el iconito del wordmark. */
.footer {
  background: var(--tinta); color: var(--sobre-tinta-tenue);
  border-top: 4px solid var(--flexo);
  padding-top: clamp(44px, 5.5vw, 70px);
}
.footer-grid {
  display: grid; grid-template-columns: 1.4fr .8fr .8fr 1fr 1.3fr;
  gap: clamp(26px, 3vw, 42px);
}
/* En el pie el logotipo puede respirar: no compite con el nav ni con el
   carrito, y es donde queda la firma al final de la página. */
.footer .marca-logo { height: 54px; }
.footer-desc {
  font-size: 14px; line-height: 1.7; color: var(--sobre-tinta-tenue);
  max-width: 34ch; margin-top: 18px;
}
.footer-millora {
  margin-top: 14px;
  font: 500 10.5px var(--dato); letter-spacing: .15em; text-transform: uppercase;
  color: var(--sobre-tinta-tenue);
}
.footer h4 { font: 500 11px var(--dato); letter-spacing: .13em; text-transform: uppercase; color: var(--flexo); margin-bottom: 15px; }
.footer-lista { display: flex; flex-direction: column; align-items: flex-start; gap: 11px; font-size: 14.5px; }
.footer-lista a, .footer-lista span { color: var(--sobre-tinta); }
/* Apiladas, cada liga medía 22 px de alto contra 11 de separación: el blanco
   táctil era la mitad de lo que pide el proyecto y las ligas de contacto —el
   WhatsApp y el correo— son justo las que se tocan con el teléfono en la mano.
   Sube el alto de cada renglón y baja el gap: el bloque queda casi igual. */
@media (max-width: 900px) {
  .footer-lista { gap: 2px; }
  .footer-lista a, .footer-lista span { display: inline-flex; align-items: center; min-height: 44px; }
}
.footer-lista a { transition: color 160ms ease; }
.footer-lista a:hover { color: var(--flexo); }

/* La placa de datos de la fábrica */
.placa {
  border: 1px solid var(--linea-tinta); border-top: 2px solid var(--flexo);
  border-radius: 3px; padding: 15px 17px 17px;
  background: rgba(255, 255, 255, .028);
}
.placa-tit { margin-bottom: 12px; }
.placa-datos { font: 400 11.5px var(--dato); }
/* Cada renglón es un div dentro del dl: así el filete cruza etiqueta y valor
   de un solo trazo (con dt/dd sueltos en grid quedaba partido en el gap). */
.placa-datos > div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  padding: 7.5px 0; border-bottom: 1px solid var(--linea-tinta);
}
.placa-datos > div:last-child { border-bottom: 0; padding-bottom: 0; }
.placa-datos dt { color: var(--sobre-tinta-tenue); }
/* Son medidas: no se parten en dos renglones. */
.placa-datos dd { color: var(--papel); white-space: nowrap; }

/* La misma placa, sobre fondo claro (el admin). Sin esto hereda el texto casi
   blanco que le sirve al pie oscuro, y los valores quedan ilegibles: era
   justo el dato que se venía a leer. */
.placa-clara {
  background: rgba(0, 0, 0, .028);
  border-color: var(--linea-tenue);
}
.placa-clara .placa-tit { color: var(--flexo-hondo); }
.placa-clara .placa-datos > div { border-bottom-color: var(--linea-tenue); }
.placa-clara .placa-datos dt { color: var(--txt-tenue); }
.placa-clara .placa-datos dd { color: var(--txt); font-weight: 500; }

/* --- WhatsApp flotante ----------------------------------------------------- */
/* Una sección de tablero vista de canto: cara oscura y el canto sellado en
   amarillo arriba, igual que el logotipo y que el pie. Deliberadamente NO es la
   burbuja verde: ese verde no sale de ningún material de la planta y sería lo
   único genérico de la página. El glifo y la palabra cargan el reconocimiento. */
.wa {
  position: fixed; right: 18px; z-index: 60;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 48px; padding: 0 16px;      /* 48 + 3 de canto: sobra el mínimo táctil */
  background: var(--tinta); color: var(--sobre-tinta);
  border-radius: var(--r); border-top: 3px solid var(--flexo);
  box-shadow: 0 10px 28px rgba(31, 24, 17, .3);
  font: 500 14px var(--texto); text-decoration: none; white-space: nowrap;
  transition: transform .18s ease, box-shadow .18s ease, opacity .22s ease;
}
.wa:hover { transform: translateY(-2px); box-shadow: 0 15px 34px rgba(31, 24, 17, .36); }
.wa:focus-visible { outline: 3px solid var(--flexo); outline-offset: 3px; }
.wa-glifo { width: 20px; height: 20px; flex: none; fill: var(--flexo); }
.wa-num { font: 400 12px var(--dato); color: var(--sobre-tinta-tenue); }

/* Se aparta cuando ya hay otra acción principal en pantalla —el pie, que lleva
   esta misma liga, o el botón de agregar al carrito—. Dos llamados a la acción
   encimados compiten, y en móvil además se tapan. Lo pone y lo quita el JS: sin
   JS el botón se queda puesto, nunca al revés (trampa 2). */
.wa.wa-fuera { opacity: 0; pointer-events: none; transform: translateY(10px); }

/* En celular y tableta se queda solo el glifo. La pastilla completa mide 128 px
   de ancho sobre una columna de texto de 350: fija en la esquina, tapaba el
   precio de la ficha —sin bajar, en la primera pantalla—, renglones de las
   preguntas frecuentes y la tarjeta «Set de 3» del configurador, que además es
   un control que hay que poder tocar. Cuadrado de 52 px: tapa la esquina y ya.

   El corte va en 900 y no en 700 porque es donde el sitio ya apila catálogo,
   producto y carrito en una columna: a 768 —un iPad de pie— la pastilla entera
   volvía y se paraba encima del campo de «fondo» del configurador.

   El nombre del canal no se pierde: va en el aria-label, en el pie y en el copy
   de todo el pedido. En escritorio la pastilla se queda tal cual. */
@media (max-width: 900px) {
  .wa-num { display: none; }
  .wa {
    width: 52px; height: 52px; min-height: 0; padding: 0;
    justify-content: center; gap: 0;
    right: 14px; bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
  .wa-txt { display: none; }
  .wa-glifo { width: 24px; height: 24px; }
}
@media (prefers-reduced-motion: reduce) {
  .wa { transition: opacity .01ms; }
  .wa:hover, .wa.wa-fuera { transform: none; }
}

/* La ficha de la planta: la misma placa del pie, pero a escala de sección y
   con el canto sellado arriba, como la etiqueta que la fábrica pega en la caja.
   Los valores van en dos renglones cuando hace falta —«Estado de México, zona
   norte» no cabe en una celda angosta— y por eso aquí sí pueden partirse, al
   revés que en el pie, donde son medidas y no deben. */
.ficha-planta { border-top: 4px solid var(--flexo); padding: clamp(22px, 3vw, 32px); }
.ficha-planta .placa-tit { margin-bottom: 6px; }
.ficha-planta .placa-datos { font-size: 12.5px; }
.ficha-planta .placa-datos > div { padding: 12px 0; align-items: flex-start; }
.ficha-planta .placa-datos dd { white-space: normal; text-align: right; }

.footer-barra {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; align-items: center;
  margin-top: clamp(34px, 4vw, 52px); padding: 20px 0 28px;
  border-top: 1px solid var(--linea-tinta);
  font: 400 11.5px var(--dato); color: var(--sobre-tinta-tenue);
}
.footer-barra a:hover { color: var(--flexo); }
.pagos { color: var(--sobre-tinta-tenue); }
.pagos i {
  font-style: normal; font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--flexo); margin-right: 9px;
}

@media (max-width: 1040px) {
  /* La placa baja a su propio renglón. Con `max-width` no se estira a todo el
     ancho: una ficha de 900 px de largo deja de leerse como placa.

     VA ACOTADA AL PIE. Escrita como `.placa` a secas alcanzaba a todas las
     placas del sitio: la de la home y la de /garantias viven dentro de un
     `.medida-grid`, que entre 941 y 1040 px todavía es de dos columnas, y ahí
     `grid-column: 1 / -1` las mandaba a cruzar las dos columnas en vez de
     quedarse al lado del texto. Es la familia de las trampas 26 y 30: la regla
     era correcta, el alcance no. */
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; }
  .footer .placa { grid-column: 1 / -1; max-width: 440px; }
}
@media (max-width: 720px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-marca { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .footer-grid { grid-template-columns: 1fr; }
  .footer-barra { justify-content: flex-start; }
}

/* --- Entrar al admin ------------------------------------------------------ */
.entrar-caja {
  max-width: 380px; margin: clamp(24px, 6vw, 64px) auto;
  background: var(--papel); border-radius: var(--r);
  padding: clamp(26px, 4vw, 38px);
}
.entrar-error {
  background: color-mix(in srgb, var(--alerta) 12%, transparent);
  border-left: 3px solid var(--alerta);
  padding: 12px 15px; border-radius: 3px; margin-bottom: 22px;
  font-size: 14px; color: var(--txt);
}

/* --- Páginas internas ----------------------------------------------------- */
.pagina { padding: clamp(26px, 3.5vw, 44px) 0 clamp(56px, 7vw, 92px); }
.miga { font: 400 11.5px var(--dato); color: var(--txt-tenue); margin-bottom: 18px; }
.miga a:hover { color: var(--nogal); }

/* Catálogo */
.catalogo-grid { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: clamp(24px, 3vw, 44px); align-items: start; }
.filtros { position: sticky; top: 84px; display: flex; flex-direction: column; gap: 26px; }
/* En una sola columna el sticky TIENE que apagarse. Chromium no confina un
   elemento sticky a su celda de grid sino al contenedor entero, así que con los
   filtros arriba de la rejilla el panel viajaba ~676 px hacia abajo y quedaba
   montado sobre las tarjetas: los círculos de acabado y la perilla del precio
   encima de los nombres y de los montos. En dos columnas no se nota porque la
   celda de al lado es la larga; al apilarse, la larga queda debajo. */
.filtro-grupo h4 { font: 500 11px var(--dato); letter-spacing: .12em; text-transform: uppercase; color: var(--txt-tenue); margin-bottom: 13px; }
.filtro-op { display: flex; align-items: center; gap: 10px; padding: 7px 0; font-size: 14.5px; color: var(--txt-medio); cursor: pointer; }
.filtro-op input { accent-color: var(--flexo-hondo); width: 17px; height: 17px; }
.filtro-colores { display: flex; gap: 9px; }
.filtro-color { width: 32px; height: 32px; border-radius: 99px; border: 1px solid var(--linea); cursor: pointer; }

/* Va DESPUÉS de las reglas base a propósito: una media query no suma
   especificidad, así que puesta antes la ganaba `.filtro-color { width: 32px }`
   y los círculos se quedaban chicos sin que se notara en el CSS. */
@media (max-width: 900px) {
  .catalogo-grid { grid-template-columns: 1fr; }
  .filtros { position: static; top: auto; }
  /* La casilla mide 17 px y el renglón quedaba en 31: abajo del mínimo táctil,
     y con cuatro categorías seguidas es donde más fácil se marca la de al lado. */
  .filtro-op { min-height: 44px; padding: 0; }
  .filtro-color { width: 44px; height: 44px; }
}
.barra-orden { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }

/* Producto */
.prod-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: clamp(28px, 4vw, 60px); align-items: start; }
@media (max-width: 900px) { .prod-grid { grid-template-columns: 1fr; } }
.galeria-mini { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; margin-top: 9px; }
.galeria-mini .foto { aspect-ratio: 1/1; cursor: pointer; outline: 2px solid transparent; outline-offset: -2px; }
.galeria-mini .foto.activa { outline-color: var(--flexo); }
.ficha { display: flex; flex-direction: column; gap: 20px; }
.ficha-precio { font: 700 clamp(30px, 3.6vw, 40px) var(--display); letter-spacing: -.03em; }
.ficha-precio small { font: 400 12px var(--dato); color: var(--txt-tenue); letter-spacing: .06em; }
.campo-titulo { font: 500 11px var(--dato); letter-spacing: .12em; text-transform: uppercase; color: var(--txt-tenue); margin-bottom: 12px; }

.acabados { display: flex; gap: 13px; flex-wrap: wrap; }
.acabado { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; cursor: pointer; }
.acabado input { position: absolute; opacity: 0; width: 0; height: 0; }
.acabado .muestra {
  width: 54px; height: 54px; border-radius: 99px; border: 1px solid var(--linea);
  transition: box-shadow 180ms ease, transform 180ms ease;
}
.acabado:hover .muestra { transform: scale(1.05); }
.acabado input:checked + .muestra { box-shadow: 0 0 0 2px var(--papel), 0 0 0 4px var(--flexo); }
.acabado .etq { font: 400 11.5px var(--dato); color: var(--txt-tenue); }
.acabado input:checked ~ .etq { color: var(--txt); font-weight: 500; }
.acabado input:focus-visible + .muestra { outline: 2px solid var(--flexo-hondo); outline-offset: 4px; }

.stepper { display: inline-flex; align-items: center; background: var(--papel); border: 1px solid var(--linea); border-radius: 99px; }
.stepper form { display: contents; }
.stepper button {
  width: 46px; height: 46px; border: 0; background: none; cursor: pointer;
  font: 400 19px var(--texto); border-radius: 99px;
  transition: background 160ms ease;
}
.stepper button:hover { background: var(--concreto-hondo); }
.stepper .valor { width: 40px; text-align: center; font: 500 15px var(--dato); border: 0; background: none; padding: 0; }

.crossell {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 20px 22px; border-radius: var(--r);
  background: var(--mdf-claro); color: var(--nogal);
  transition: background 200ms ease;
}
.crossell:hover { background: var(--mdf); }
.crossell b { display: block; font: 700 16px var(--display); color: var(--tinta); letter-spacing: -.02em; }
.crossell span { font-size: 14px; color: var(--sobre-mdf-tenue); }
.crossell .flecha { font-size: 22px; flex: none; }

.especs { border-top: 1px solid var(--linea); padding-top: 20px; }
.especs dl { display: grid; grid-template-columns: auto 1fr; gap: 10px 24px; margin: 0; font: 400 13px var(--dato); }
.especs dt { color: var(--txt-tenue); }
.especs dd { margin: 0; color: var(--txt); }

/* --- Configurador --------------------------------------------------------- */
.conf-cabeza { display: flex; align-items: flex-end; justify-content: space-between; gap: 22px; flex-wrap: wrap; padding-bottom: 22px; }
.conf-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 0; align-items: stretch; }
@media (max-width: 940px) { .conf-grid { grid-template-columns: 1fr; } }

.conf-vista { background: var(--tinta); padding: clamp(20px, 2.6vw, 34px); display: flex; flex-direction: column; gap: 16px; }
.vista-tabs { display: inline-flex; gap: 3px; padding: 3px; background: rgba(230,223,210,.09); border-radius: 99px; align-self: flex-start; }
.vista-tab {
  padding: 9px 17px; border: 0; border-radius: 99px; background: none; cursor: pointer;
  font: 500 12.5px var(--texto); color: var(--sobre-tinta-tenue);
  transition: background 180ms ease, color 180ms ease;
}
.vista-tab[aria-selected="true"] { background: var(--flexo); color: var(--tinta); }
/* En celular las dos vistas suben al mínimo táctil. En escritorio se quedan
   chicas: ahí se apunta con el ratón y son un conmutador, no una acción. */
@media (max-width: 940px) {
  .vista-tab { min-height: 44px; padding-top: 0; padding-bottom: 0; }
}

.lienzo {
  position: relative; flex: 1;
  min-height: clamp(300px, 40vw, 430px); max-height: 560px;
  /* Muro claro: una repisa de nogal sobre fondo oscuro no se veía. */
  background: linear-gradient(168deg, #F1ECE2, #DFD8CA);
  border-radius: var(--r); overflow: hidden;
}
.lienzo-muro {
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(107, 69, 34, .05) 1px, transparent 1px);
  background-size: 4px 4px;
}
.lienzo-piso {
  position: absolute; left: 0; right: 0; bottom: 0; height: 46px;
  background: linear-gradient(#D5CEC0, #C6BEAE);
  border-top: 1px solid #B7AE9D;
}
#pila {
  position: absolute; left: 0; right: 0; top: 46px; bottom: 96px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
#pila .repisa { box-sizing: content-box; border-radius: 1px; }
#cota { position: absolute; left: 50%; bottom: 58px; transform: translateX(-50%); }
#cota .linea { height: 1px; background: var(--flexo-hondo); position: relative; }
#cota .linea i { position: absolute; top: -4px; width: 1px; height: 9px; background: var(--flexo-hondo); }
#cota .linea i.a { left: 0; } #cota .linea i.b { right: 0; }
#cota .val { text-align: center; margin-top: 6px; font: 500 11.5px var(--dato); color: var(--flexo-hondo); }
.lienzo-etq { position: absolute; top: 15px; font: 400 10.5px var(--dato); letter-spacing: .1em; color: #8A8071; }
.lienzo-etq.a { left: 15px; } .lienzo-etq.b { right: 15px; color: var(--nogal); font-weight: 500; }
.lienzo-despiece {
  position: absolute; inset: clamp(16px, 3vw, 32px);
  display: none; align-items: center; justify-content: center; overflow: hidden;
}
/* El plano sí va sobre el tablero oscuro: es el material, no el muro. */
.lienzo-despiece .tablero { max-height: 100%; }
.lienzo[data-vista="despiece"] .lienzo-muro,
.lienzo[data-vista="despiece"] #pila,
.lienzo[data-vista="despiece"] #cota,
.lienzo[data-vista="despiece"] .lienzo-piso { display: none; }
.lienzo[data-vista="despiece"] .lienzo-despiece { display: flex; }

.fichas { display: flex; gap: 7px; flex-wrap: wrap; }
.fichas span {
  padding: 8px 12px; border-radius: 99px;
  background: rgba(230,223,210,.08); color: var(--sobre-tinta);
  font: 400 11.5px var(--dato);
}

.conf-controles { background: var(--papel); padding: clamp(22px, 3vw, 38px); display: flex; flex-direction: column; gap: 28px; }
.tipos { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 9px; }
.tipo {
  position: relative; cursor: pointer; padding: 15px 16px; border-radius: var(--r);
  background: var(--concreto); border: 1px solid transparent;
  transition: background 180ms ease, border-color 180ms ease, color 180ms ease;
}
.tipo:hover { border-color: var(--linea); }
.tipo input { position: absolute; opacity: 0; width: 0; height: 0; }
.tipo b { display: block; font: 600 14.5px var(--texto); }
.tipo span { display: block; margin-top: 4px; font: 400 11.5px var(--dato); color: var(--txt-tenue); }
.tipo.activo { background: var(--tinta); border-color: var(--tinta); }
.tipo.activo b { color: var(--papel); }
.tipo.activo span { color: var(--flexo); }

.medida + .medida { margin-top: 22px; }
.medida-fila { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 10px; }
.medida-fila > label { font: 600 15px var(--texto); }
/* La caja entera es el blanco táctil, no el input: tocando el borde de arriba
   o el «cm» también entra el foco al número. Por eso min-height va aquí y el
   input se estira al alto completo en vez de quedarse en sus 19 px de texto. */
.medida-caja { display: inline-flex; align-items: center; gap: 5px; min-height: 44px; background: var(--concreto); border-radius: 99px; padding: 0 16px; }
.medida-caja input { width: 52px; align-self: stretch; border: 0; background: none; font: 500 16px var(--dato); color: var(--txt); text-align: right; padding: 0; }
.medida-caja span { font: 400 12px var(--dato); color: var(--txt-tenue); }
/* Fuera las flechitas del `number`: al enfocar el campo aparecían encima de la
   unidad y se leía «12⇕zs» en vez de «12 pzs». No hacen falta —abajo de cada
   campo va su deslizador, que es como se sube y se baja— y con el dedo son un
   blanco de 10 px, la mitad del mínimo del proyecto. */
.medida-caja input::-webkit-outer-spin-button,
.medida-caja input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.medida-caja input[type=number] { -moz-appearance: textfield; appearance: textfield; }
.medida-topes { display: flex; justify-content: space-between; font: 400 11px var(--dato); color: var(--txt-tenue); margin-top: 2px; }

input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 32px;
  background: transparent; margin: 0; cursor: pointer;
}
/* La perilla mide 26 px pero el blanco que atiende es el alto del input: con 32
   había que atinarle con el dedo a la barra. La barra sigue dibujándose de 5 px
   y centrada, así que sube el área de toque y no cambia nada de lo que se ve. */
@media (max-width: 940px) { input[type=range] { height: 44px; } }
input[type=range]::-webkit-slider-runnable-track { height: 5px; border-radius: 99px; background: var(--concreto-hondo); }
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 26px; height: 26px; margin-top: -10.5px;
  border-radius: 99px; background: var(--flexo); border: 3px solid var(--papel);
  box-shadow: 0 2px 8px rgba(36,28,19,.32); cursor: grab;
}
input[type=range]::-moz-range-track { height: 5px; border-radius: 99px; background: var(--concreto-hondo); }
input[type=range]::-moz-range-thumb {
  width: 20px; height: 20px; border-radius: 99px; background: var(--flexo);
  border: 3px solid var(--papel); box-shadow: 0 2px 8px rgba(36,28,19,.32); cursor: grab;
}

.panel-precio { background: var(--tinta); border-radius: var(--r); padding: 24px; color: var(--sobre-tinta); }
.panel-precio .fila { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.panel-precio .etq { font: 500 11px var(--dato); letter-spacing: .13em; text-transform: uppercase; color: var(--flexo); }
.panel-precio .monto {
  font: 700 clamp(38px, 5.4vw, 52px)/1 var(--display); letter-spacing: -.035em;
  color: var(--papel); margin-top: 10px;
  font-variant-numeric: tabular-nums;
}
.panel-precio .unit { font: 400 12px var(--dato); color: var(--sobre-tinta-tenue); margin-top: 8px; }
.panel-precio .stepper { background: transparent; border-color: rgba(230,223,210,.24); }
.panel-precio .stepper button:hover { background: rgba(230,223,210,.1); }
.panel-precio .stepper .valor { color: var(--papel); }
.panel-precio .qty { display: flex; flex-direction: column; align-items: flex-end; gap: 9px; }
.panel-precio .qty > span { font: 400 11px var(--dato); color: var(--sobre-tinta-tenue); }
.panel-precio .datos {
  display: flex; gap: 18px; flex-wrap: wrap; margin-top: 20px; padding-top: 17px;
  border-top: 1px solid var(--linea-tinta); font: 400 12px var(--dato); color: var(--sobre-tinta);
}
.panel-precio .acciones { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.panel-precio .acciones .btn-acento { flex: 1; min-width: 180px; }

@media (max-width: 640px) {
  .panel-precio {
    position: sticky; bottom: 0; z-index: 40; border-radius: var(--r) var(--r) 0 0;
    margin: 0 calc(-1 * clamp(22px, 3vw, 38px)) calc(-1 * clamp(22px, 3vw, 38px));
    box-shadow: 0 -10px 30px -12px rgba(31, 24, 17, .5);
  }
}

/* --- Carrito y checkout --------------------------------------------------- */
.carrito-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(min(100%, 310px), .8fr); gap: clamp(20px, 3vw, 36px); align-items: start; }
@media (max-width: 900px) { .carrito-grid { grid-template-columns: 1fr; } }
.lista { background: var(--papel); border-radius: var(--r); overflow: hidden; }
.renglon { display: flex; gap: 18px; padding: 20px 22px; flex-wrap: wrap; align-items: flex-start; }
.renglon + .renglon { border-top: 1px solid var(--linea-tenue); }
.renglon .foto { width: 92px; height: 92px; flex: none; }
.renglon .info { flex: 1; min-width: 170px; display: flex; flex-direction: column; gap: 7px; }
.renglon .nombre { font: 600 15.5px var(--texto); }
.renglon .specs { font: 400 12px var(--dato); color: var(--txt-tenue); }
.renglon .acciones { display: flex; align-items: center; gap: 16px; margin-top: 6px; flex-wrap: wrap; }
.renglon .monto { font: 700 18px var(--display); letter-spacing: -.02em; margin-left: auto; }
.quitar { border: 0; background: none; padding: 0; cursor: pointer; font: 400 13px var(--texto); color: var(--txt-tenue); border-bottom: 1px solid var(--linea); }
.quitar:hover { color: var(--alerta); border-bottom-color: var(--alerta); }
.lista-pie { padding: 18px 22px; border-top: 1px solid var(--linea-tenue); display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; }

.resumen { background: var(--papel); border-radius: var(--r); padding: 26px; position: sticky; top: 84px; }
/* Mismo apagado del sticky que en los filtros del catálogo, y por la misma
   razón: apilado, el resumen se despega de su celda y flota sobre lo de abajo.
   Después de la regla base, que si no la media query no gana (no suma
   especificidad). */
@media (max-width: 900px) { .resumen { position: static; top: auto; } }
.resumen h3 { font: 500 11px var(--dato); letter-spacing: .12em; text-transform: uppercase; color: var(--txt-tenue); margin-bottom: 18px; }
.res-fila { display: flex; justify-content: space-between; gap: 14px; font-size: 14.5px; color: var(--txt-medio); margin-bottom: 11px; }
.res-fila b { font-weight: 500; color: var(--txt); }
.res-aviso { background: var(--mdf-claro); border-radius: var(--r); padding: 12px 14px; font: 400 12px/1.6 var(--dato); color: var(--nogal); margin: 14px 0; }
.res-total { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; padding-top: 16px; border-top: 1px solid var(--linea); margin-bottom: 18px; }
.res-total span { font: 600 15px var(--texto); }
.res-total b { font: 700 30px var(--display); letter-spacing: -.03em; }
.res-nota { font: 400 11.5px/1.6 var(--dato); color: var(--txt-tenue); margin-top: 13px; text-align: center; }
.res-item { display: flex; justify-content: space-between; gap: 14px; padding-bottom: 13px; margin-bottom: 13px; border-bottom: 1px solid var(--linea-tenue); }
.res-item .n { font: 500 14px var(--texto); }
.res-item .s { font: 400 11px var(--dato); color: var(--txt-tenue); margin-top: 4px; }
.res-item .m { font: 600 14.5px var(--texto); white-space: nowrap; }

.vacio { background: var(--papel); border-radius: var(--r); padding: clamp(48px, 8vw, 80px) 28px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 16px; }

.tarjeta { background: var(--papel); border-radius: var(--r); padding: 26px; }
.tarjeta + .tarjeta { margin-top: 16px; }
.tarjeta > h3 { font: 500 11px var(--dato); letter-spacing: .12em; text-transform: uppercase; color: var(--txt-tenue); margin-bottom: 20px; }
.campos { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
.campo { display: flex; flex-direction: column; gap: 7px; font: 500 13px var(--texto); color: var(--txt-medio); }
.campo input {
  min-height: 50px; padding: 13px 15px; border-radius: var(--r);
  border: 1px solid var(--linea); background: var(--concreto);
  font: 400 15px var(--texto); color: var(--txt);
  transition: border-color 160ms ease, background 160ms ease;
}
.campo input::placeholder { color: var(--txt-tenue); }
.campo input:focus { background: #fff; border-color: var(--flexo); outline: none; }
.campo.malo input { border-color: var(--alerta); }

/* --- cupones ------------------------------------------------------------
   El descuento va en NOGAL, no en verde. La paleta sale de los materiales de
   la planta y no tiene un verde; meter uno aquí sería lo mismo que se rechazó
   para la burbuja de WhatsApp: el único color templado de la página, puesto
   justo donde el ojo va a buscar el total. El nogal ya es el color de las
   buenas noticias del resumen (.res-aviso usa el mismo par). */
.res-descuento b { color: var(--nogal); }

.cupon { margin: 14px 0; }
.cupon-form { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.cupon-form .campo { flex: 1 1 150px; min-width: 0; }
/* El código se lee y se dicta: va en la tipografía de datos y en mayúsculas,
   como las medidas y los folios. */
.cupon-form input { font-family: var(--dato); text-transform: uppercase; letter-spacing: .06em; }
.cupon-form input::placeholder { text-transform: none; letter-spacing: 0; }

/* Un cupón puesto va con el canto sellado en amarillo, el mismo gesto que el
   despiece y el flotante de WhatsApp. NO se le pone el fondo de .res-aviso
   aunque las dos sean buenas noticias: en el carrito quedan una encima de otra
   —«te faltan $161» y el cupón— y dos paneles idénticos seguidos se leen como
   un solo bloque de aviso, que es justo lo que hace que no se lea ninguno. */
.cupon-puesto {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--concreto); border-radius: var(--r); padding: 12px 14px;
  border-left: 3px solid var(--flexo);
}
.cupon-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cupon-cod { font: 500 13px var(--dato); letter-spacing: .08em; color: var(--nogal); }
.cupon-que { font: 400 11.5px var(--dato); color: var(--txt-medio); }
.cupon-quitar {
  position: relative; border: 0; background: none; padding: 0; cursor: pointer;
  font: 400 12.5px var(--texto); color: var(--txt-medio);
  border-bottom: 1px solid currentColor; flex: none;
}
.cupon-quitar:hover { color: var(--alerta); }
/* El blanco táctil crece con un ::after invisible, no con padding: el texto
   mide 12.5 px y subirlo a 44 con relleno movería el recuadro entero y
   despegaría el subrayado. Es la trampa 28. */
.cupon-quitar::after { content: ""; position: absolute; inset: -15px -10px; }

.cupon-recado { margin: 10px 0 0; font: 400 12.5px/1.55 var(--texto); color: var(--nogal); }
.cupon-recado.malo { color: var(--alerta); }

/* Las casillas del alta de cupones, en el admin. NO se llaman .marca: ese
   nombre ya es el bloque de logotipo + dominio del header, y reusarlo sería
   la trampa 33 otra vez — una regla correcta con el alcance mal puesto. */
.cupon-banderas { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 18px; }
.cupon-marca {
  display: flex; align-items: center; gap: 9px; cursor: pointer;
  font: 400 13.5px var(--texto); color: var(--txt-medio); min-height: 44px;
}
.cupon-marca input { width: 19px; height: 19px; accent-color: var(--flexo-hondo); }

/* El <select> del admin, con la misma piel que los <input> de al lado. */
.campo select {
  min-height: 50px; padding: 13px 15px; border-radius: var(--r);
  border: 1px solid var(--linea); background: var(--concreto);
  font: 400 15px var(--texto); color: var(--txt);
}
.campo select:focus { background: #fff; border-color: var(--flexo); outline: none; }

/* --- buscador de direcciones ------------------------------------------- */
.dir-buscar { position: relative; margin-bottom: 18px; }
.dir-ayuda { margin: 7px 0 0; font: 400 12.5px var(--texto); color: var(--txt-tenue); }
.dir-lista {
  position: absolute; z-index: 30; left: 0; right: 0; top: 100%; margin: 6px 0 0;
  padding: 6px; list-style: none; max-height: 300px; overflow-y: auto;
  background: #fff; border: 1px solid var(--linea); border-radius: var(--r);
  box-shadow: 0 18px 40px -18px rgba(31, 24, 17, .35);
}
.dir-op {
  display: block; padding: 10px 12px; border-radius: calc(var(--r) - 4px);
  cursor: pointer; min-height: 44px;   /* el dedo, no el texto */
}
.dir-op b { display: block; font: 500 14.5px var(--texto); color: var(--txt); }
.dir-op span { display: block; font: 400 12px var(--dato); color: var(--txt-tenue); }
.dir-op.marcada, .dir-op:hover { background: var(--concreto); }
/* El campo que acaba de llenarse solo: se marca un momento para que el cliente
   vea QUÉ se movió abajo. Sin esto, elegir en el buscador parece que no hizo
   nada — los campos están fuera de la vista en un celular. */
.campo.lleno input { border-color: var(--flexo); }

.pagos-lista { display: grid; gap: 9px; }
.pago {
  position: relative; display: flex; align-items: center; gap: 13px; cursor: pointer;
  padding: 16px 18px; border-radius: var(--r); background: var(--concreto);
  border: 1px solid transparent; font: 500 14.5px var(--texto); color: var(--txt-medio);
  transition: border-color 180ms ease, background 180ms ease, color 180ms ease;
}
.pago input { position: absolute; opacity: 0; width: 0; height: 0; }
.pago .radio { width: 18px; height: 18px; flex: none; border-radius: 99px; border: 1.5px solid var(--linea); background: #fff; transition: all 180ms ease; }
.pago.activa { background: #fff; border-color: var(--flexo); color: var(--txt); }
.pago.activa .radio { border-color: var(--flexo); background: var(--flexo); box-shadow: inset 0 0 0 3.5px #fff; }
.pago-txt { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 12px; }
.pago-nota { margin-left: auto; font: 400 11px var(--dato); color: var(--txt-tenue); text-align: right; }

/* La nota deja de pelearse por el ancho con el nombre. Con un solo método con
   nota —«Pago en OXXO · se confirma en 1 h»— no se notaba; con «Tarjeta de
   crédito o débito · Visa, Mastercard, AmEx» y «Mercado Pago · con tu saldo o
   tus tarjetas guardadas» el nombre se quedaba sin ancho y «Mercado Pago»
   partía en dos renglones. Un nombre de marca partido se lee como un error.
   Va DESPUÉS de la regla base: una media query no suma especificidad (trampa 26). */
@media (max-width: 560px) {
  .pago-txt { display: block; }
  .pago-nota { display: block; margin: 3px 0 0; text-align: left; }
}

.nota-envio { font: 400 12px/1.6 var(--dato); color: var(--txt-tenue); margin-top: 14px; text-align: center; }
.nota-envio.error { color: var(--alerta); }

/* --- Confirmación --------------------------------------------------------- */
.gracias { max-width: 720px; margin: 0 auto; padding: clamp(50px, 8vw, 96px) var(--px) clamp(60px, 9vw, 110px); text-align: center; display: flex; flex-direction: column; align-items: center; gap: 20px; }
.gracias .sello { width: 62px; height: 46px; border-radius: 3px; background: linear-gradient(var(--mdf-claro), var(--mdf-hondo)); border-bottom: 7px solid var(--flexo); }
.gracias-folio { font-family: var(--dato); font-weight: 500; color: var(--txt); }
/* Cuatro datos, no tres: desde que hay cobro también se dice cómo va el pago.
   El mínimo baja a 120px para que quepan los 4 en una fila en escritorio y
   caigan en 2×2 en celular. Con 150px se iba uno solo al segundo renglón y
   dejaba media franja de fondo asomando, que parecía un error de carga. */
.gracias-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 2px; width: 100%; background: var(--linea-tenue); border-radius: var(--r); overflow: hidden; margin-top: 10px; }
.gracias-datos > div { background: var(--papel); padding: 22px 18px; }
.gracias-datos .e { font: 400 11px var(--dato); color: var(--txt-tenue); }
.gracias-datos .v { font: 700 19px var(--display); letter-spacing: -.02em; margin-top: 7px; }

/* --- Admin ---------------------------------------------------------------- */
.tabla-caja { background: var(--papel); border-radius: var(--r); overflow-x: auto; }
.tabla { min-width: 640px; width: 100%; border-collapse: collapse; }
.tabla th {
  text-align: left; padding: 15px 20px; background: var(--concreto);
  font: 500 11px var(--dato); letter-spacing: .1em; text-transform: uppercase; color: var(--txt-tenue);
}
.tabla td { padding: 11px 20px; border-top: 1px solid var(--linea-tenue); font-size: 14.5px; }
.tabla td.p { font-weight: 500; }
.tabla td.u, .tabla td.o { font: 400 12px var(--dato); color: var(--txt-tenue); }
.tabla input {
  width: 100px; padding: 10px 12px; border-radius: var(--r);
  border: 1px solid var(--linea); background: var(--concreto);
  font: 500 14px var(--dato); color: var(--txt);
}
.tabla input:focus { background: #fff; border-color: var(--flexo); outline: none; }
.tabla-pie { padding: 20px; display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }

/* Estado de un pedido frente a Odoo. El color no es el único indicador: el
   texto ya lo dice, para quien no distinga los tonos. */
.sello-estado {
  display: inline-block; padding: 4px 9px; border-radius: var(--r);
  font: 500 10.5px var(--dato); letter-spacing: .07em; text-transform: uppercase;
  white-space: nowrap;
}
.sello-estado.enviado  { background: rgba(107, 69, 34, .10); color: var(--nogal); }
.sello-estado.pendiente { background: rgba(240, 168, 30, .20); color: var(--flexo-hondo); }
.sello-estado.atorado  { background: rgba(163, 52, 24, .12); color: var(--alerta); }
/* Sin pagar todavía: ni bueno ni malo, es la sala de espera. */
.sello-estado.esperando_pago { background: rgba(0, 0, 0, .06); color: var(--txt-tenue); }
.sello-estado.cancelado { background: rgba(0, 0, 0, .05); color: var(--txt-tenue);
                          text-decoration: line-through; }
.tabla td.motivo {
  font: 400 12px var(--dato); color: var(--alerta);
  white-space: normal; max-width: 42ch;
}
.tabla td.folio { font: 500 13px var(--dato); white-space: nowrap; }

/* Las dos placas del admin, lado a lado mientras quepan. */
.placas-fila {
  display: grid; gap: 18px; margin-bottom: 34px;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  max-width: 900px;
}

/* Un renglón del tabulador que estás probando y todavía no publicas. La franja
   amarilla en el canto es la misma señal que el canto sellado del despiece. */
/* Cabecera de grupo dentro de la tabla del tabulador. Los parámetros ya no son
   números sueltos: unos salen de una factura del proveedor y otros son una
   decisión comercial, y conviene no confundirlos al editar. Va más chica y sin
   el fondo de la cabecera real para que se lea como subtítulo, no como otra
   tabla que empieza. */
.tabla tr.grupo th {
  background: transparent; border-top: 1px solid var(--linea-tenue);
  padding: 20px 20px 7px; font-size: 10px; color: var(--flexo-hondo);
}
.tabla tr.grupo:first-child th { border-top: 0; padding-top: 14px; }

.tabla tr.probando td { background: rgba(240, 168, 30, .07); }
.tabla tr.probando td:first-child { box-shadow: inset 3px 0 0 var(--flexo); }
.marca-prueba {
  color: var(--flexo-hondo); font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; white-space: nowrap;
}

/* Recado del admin tras una acción: qué pasó, sin regañar. */
.recado {
  margin: 0 0 20px; padding: 13px 17px; border-radius: var(--r);
  background: rgba(240, 168, 30, .14); border-left: 3px solid var(--flexo);
  font: 400 14px/1.5 var(--texto); color: var(--txt);
  max-width: 78ch;
}
.recado.malo {
  background: rgba(163, 52, 24, .09); border-left-color: var(--alerta);
  color: var(--alerta);
}

/* --- Movimiento ----------------------------------------------------------- */
/* Un solo momento orquestado (el despiece encajando). El resto, reveals cortos. */
/* Se esconde SOLO si hay JS (la clase .js la pone el <head>). Sin JS el
   contenido se ve completo: nunca dejamos texto colgando de un observer. */
.js [data-reveal] {
  opacity: 0; transform: translateY(18px);
  transition: opacity 620ms cubic-bezier(.2,.7,.3,1), transform 620ms cubic-bezier(.2,.7,.3,1);
}
.js [data-reveal].visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
  .pieza { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   Pago de demostración (/pago/demo). Solo existe con PAGO_DEMO=1.

   No se disfraza de pasarela de banco: se disfraza de lo que es, una pantalla
   de taller. El aviso va en la banda de canto sellado —el mismo gesto del
   logotipo, el pie y el botón de WhatsApp— para que no se pueda confundir con
   un cobro de verdad ni de reojo.
--------------------------------------------------------------------------- */
.demo { max-width: 980px; margin: 0 auto; padding: clamp(28px, 5vw, 56px) var(--px) var(--py); }

/* La sección de tablero: cara oscura, canto sellado en amarillo arriba. */
.demo-canto {
  background: var(--tinta);
  color: var(--sobre-tinta);
  border-top: 6px solid var(--flexo);
  border-radius: var(--r);
  padding: clamp(18px, 3vw, 26px) clamp(20px, 3.5vw, 32px);
}
.demo-canto-et {
  display: inline-block;
  font: 500 11px/1 var(--dato);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--flexo);
  margin-bottom: 10px;
}
.demo-canto-tx {
  margin: 0;
  max-width: 62ch;                /* en el propio elemento: ver trampa 1 */
  font-size: 15px;
  line-height: 1.55;
  color: var(--sobre-tinta);
}

.demo-cuerpo {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(260px, 1fr);
  gap: clamp(20px, 3vw, 36px);
  margin-top: clamp(22px, 3.5vw, 34px);
  align-items: start;
}
.demo-col > * + * { margin-top: 14px; }

/* Los datos de la tarjeta inventada, como placa de especificación. Sobre fondo
   claro, así que NO se usa `.placa`, que está hecha para el pie oscuro
   (trampa 14). */
.demo-placa {
  margin: 22px 0 0;
  display: grid;
  /* Dos columnas fijas, no `auto-fit`: son tres celdas y la primera ocupa la
     fila entera, así que en cualquier ancho la rejilla queda llena. */
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--linea);
  border: 1px solid var(--linea);
  border-radius: var(--r);
  overflow: hidden;
}
.demo-placa > div { background: var(--mdf-claro); padding: 12px 14px; }
.demo-placa-ancha { grid-column: 1 / -1; }
.demo-placa-ancha dd { font-size: 17px; letter-spacing: .06em; }
.demo-placa dt {
  font: 500 10px/1 var(--dato);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sobre-mdf-tenue);
}
.demo-placa dd {
  margin: 6px 0 0;
  font: 500 14px/1.2 var(--dato);
  color: var(--nogal);
  word-break: break-word;
}

.demo-cobro {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--r);
  padding: clamp(18px, 2.6vw, 24px);
}
.demo-monto { display: block; padding-bottom: 16px; border-bottom: 1px solid var(--linea-tenue); }
.demo-monto .e {
  display: block;
  font: 500 10px/1 var(--dato);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--txt-tenue);
}
.demo-monto .v {
  display: block;
  margin-top: 8px;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(30px, 4vw, 40px);
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--txt);
}
.demo-monto-nota { display: block; margin-top: 8px; font: 400 12px/1.5 var(--dato); color: var(--txt-tenue); }

/* Se apilan en el orden en que están escritos: rechazar arriba, aprobar abajo.
   Nada de `column-reverse` — dejaría el foco del teclado saltando al revés de
   lo que se ve, y en una pantalla de dos botones eso se nota. */
.demo-cobro form { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.demo-btn { width: 100%; justify-content: center; }

@media (max-width: 760px) {
  .demo-cuerpo { grid-template-columns: 1fr; }
}

/* ==========================================================================
   PÁGINAS DE CONTENIDO — Inspírate · Garantías · Negocios
   Tres secciones que no venden un SKU: venden la idea, la tranquilidad y la
   capacidad de la planta. Comparten la cabecera y el cierre, y de ahí en
   adelante cada una tiene su forma.
   ========================================================================== */

/* Cabecera de página. Es `.pagina` sin el respiro de abajo: estas vistas
   siguen con una banda de color, y el padding inferior de `.pagina` metía un
   hueco de casi 200 px entre el título y la primera tarjeta. */
.pagina-cabecera { padding: clamp(26px, 3.5vw, 44px) 0 clamp(30px, 4vw, 52px); }
/* En PÍXELES, no en `ch`. El `ch` se calcula con la fuente del elemento donde
   se pone —16 px aquí—, no con la de sus hijos: `max-width: 46ch` daba 410 px
   y partía un titular de 92 px en tres renglones, dejando una palabra suelta
   en medio. Es la trampa 1. El límite en `ch` va en el párrafo, que sí se
   mide con su propia fuente. */
.pagina-intro { max-width: 860px; }
.pagina-intro .parrafo-g { max-width: 52ch; }

/* Cierre de página: el bloque de «y si nada de esto es lo tuyo». */
.cierre { max-width: 62ch; }
.cierre-ctas { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 28px; }

/* --- Inspírate: la rejilla de espacios ------------------------------------ */
/* `auto-fit` y no `auto-fill`: con `auto-fill` la rejilla reserva las columnas
   que quepan aunque estén vacías, y bastaría quitar dos espacios para que la
   página enseñara media fila en blanco. Es la trampa 18. */
.espacios { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }

/* Columna flex con el cuerpo en `flex: 1`: si no, un gancho de dos renglones
   estira su tarjeta y deja una franja de fondo asomando bajo las demás
   (trampa 8). */
.espacio {
  display: flex; flex-direction: column;
  background: var(--papel); border-radius: var(--r); overflow: hidden;
  transition: transform 240ms cubic-bezier(.2,.7,.3,1), box-shadow 240ms ease;
}
.espacio:hover { transform: translateY(-3px); box-shadow: 0 16px 34px -18px rgba(36,28,19,.4); }

.espacio-foto { position: relative; }
/* Nada de `height: 100%` en la foto: la altura la marca el aspect-ratio de
   este contexto, no el alto de la tarjeta (trampa 7). */
.espacio-foto .foto { border-radius: 0; aspect-ratio: 4 / 3; }
/* El nombre del cuarto va SOBRE la foto y no en el cuerpo: es la etiqueta que
   deja escanear la página de un vistazo, que es como se lee una galería. */
.espacio-etq {
  position: absolute; left: 12px; bottom: 12px;
  padding: 7px 12px; border-radius: 99px;
  background: var(--tinta); color: var(--papel);
  font: 500 11px var(--dato); letter-spacing: .1em; text-transform: uppercase;
}

.espacio-cuerpo { flex: 1; display: flex; flex-direction: column; padding: 22px 24px 24px; gap: 10px; }
.espacio-txt { font-size: 14.8px; line-height: 1.62; color: var(--txt-medio); }

/* Las medidas en tipografía de datos: es el idioma del despiece y es el dato
   que convierte «se ve bonito» en «esto puedo pedirlo». */
.espacio-medidas {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 14px;
  border-top: 1px solid var(--linea-tenue);
}
.espacio-medidas span {
  padding: 5px 9px; border-radius: 2px;
  background: var(--concreto); color: var(--txt-medio);
  font: 500 11.5px var(--dato); letter-spacing: .02em; white-space: nowrap;
}
.espacio-cta {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 14px;
  font: 600 14px var(--texto); color: var(--nogal);
  transition: gap 180ms ease;
}
.espacio:hover .espacio-cta { gap: 12px; }

/* --- Garantías: la lista palomeada --------------------------------------- */
/* `<ol>` sin numeración a la vista: el orden importa —de lo que pasa antes de
   pagar a lo que pasa después— pero unos números grandes competirían con los
   títulos, que es lo que hay que leer. */
.garantias { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.garantia {
  display: flex; gap: clamp(16px, 2.2vw, 28px); align-items: flex-start;
  background: var(--papel); padding: clamp(22px, 2.8vw, 32px) clamp(20px, 2.6vw, 34px);
}
.garantia:first-child { border-top-left-radius: var(--r); border-top-right-radius: var(--r); }
.garantia:last-child { border-bottom-left-radius: var(--r); border-bottom-right-radius: var(--r); }

/* La palomita va en un cuadro con el canto sellado arriba, el mismo gesto del
   pie y del flotante de WhatsApp. No un círculo verde de «check»: ese es el
   default de cualquier página de garantías y no dice nada de esta fábrica. */
.palomita {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 2px;
  background: var(--tinta); color: var(--flexo);
  border-top: 3px solid var(--flexo);
}
.palomita svg { width: 19px; height: 19px; }

.garantia-cuerpo { min-width: 0; }
.garantia-resumen { margin-top: 8px; font-size: 15.5px; line-height: 1.55; color: var(--txt); }
.garantia-detalle { margin-top: 10px; font-size: 14.6px; line-height: 1.65; color: var(--txt-medio); max-width: 62ch; }

/* --- Negocios ------------------------------------------------------------- */
/* El hero es de concreto y no de MDF: el de la home ya usa el campo de MDF y
   repetirlo aquí haría que las dos páginas se leyeran como la misma. */
.negocios-hero { padding: clamp(26px, 3.5vw, 44px) 0 clamp(40px, 5vw, 68px); }
.negocios-hero-grid {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(28px, 4vw, 56px); align-items: center;
}
.negocios-hero-foto .foto { border-radius: var(--r); }

.giros { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
/* Cada tarjeta abre WhatsApp con el mensaje ya escrito. El borde de la
   izquierda en amarillo es el canto sellado: marca que esto es una acción y no
   una ficha que se lee. */
.giro {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--papel); border-radius: var(--r);
  border-left: 3px solid var(--flexo);
  padding: 22px 24px 20px;
  transition: transform 200ms cubic-bezier(.2,.7,.3,1), box-shadow 200ms ease;
}
.giro:hover { transform: translateY(-3px); box-shadow: 0 16px 34px -18px rgba(36,28,19,.4); }
.giro-nombre { font: 700 19px/1.2 var(--display); letter-spacing: -.02em; color: var(--txt); }
.giro-txt { font-size: 14.5px; line-height: 1.6; color: var(--txt-medio); }
.giro-cta {
  display: inline-flex; align-items: center; gap: 7px; margin-top: auto; padding-top: 12px;
  font: 600 13.5px var(--texto); color: var(--nogal);
  transition: gap 180ms ease;
}
.giro:hover .giro-cta { gap: 12px; }

/* --- Responsivo ----------------------------------------------------------
   VA AL FINAL, después de las reglas que corrige: una media query NO suma
   especificidad, y puesta antes pierde sin que se vea nada raro en la hoja.
   Es la trampa 26. */
@media (max-width: 940px) {
  .negocios-hero-grid { grid-template-columns: 1fr; }
  /* La foto primero en el DOM leería antes que el titular en un lector de
     pantalla, así que se queda abajo y aquí solo se apila. */
  .negocios-hero-foto { order: 2; }
}
@media (max-width: 620px) {
  /* La palomita se sale del renglón del título: a este ancho, 38 px de cuadro
     más el gap dejaban el título en columnas de dos palabras. */
  .garantia { flex-direction: column; gap: 14px; }
  .palomita { width: 34px; height: 34px; }
}
